Skip to content

Commit

Permalink
Merge pull request #2379 from uktrade/uat
Browse files Browse the repository at this point in the history
PROD Release
  • Loading branch information
depsiatwal authored Jan 17, 2025
2 parents 615efc2 + 7d3409e commit 397e2b9
Show file tree
Hide file tree
Showing 12 changed files with 148 additions and 50 deletions.
4 changes: 2 additions & 2 deletions Pipfile
Original file line number Diff line number Diff line change
Expand Up @@ -64,12 +64,12 @@ django-log-formatter-ecs = "==0.0.5"
whitenoise = "~=5.3.0"
django-audit-log-middleware = "~=0.0.4"
django-extensions = "~=3.2.3"
ipython = "~=7.34.0"
ipython = "~=8.10.0"
celery = "~=5.3.0"
redis = "~=4.4.4"
django-test-migrations = "~=1.2.0"
django-silk = "~=5.0.3"
django = "~=4.2.15"
django = "~=4.2.17"
django-queryable-properties = "~=1.9.1"
database-sanitizer = ">=1.1.0"
django-reversion = ">=5.0.12"
Expand Down
68 changes: 50 additions & 18 deletions Pipfile.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions api/cases/managers.py
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,7 @@ def search( # noqa
"queues",
"queues__team",
"baseapplication__licences",
"flags",
Prefetch(
"baseapplication__parties",
to_attr="end_user_parties",
Expand Down
3 changes: 3 additions & 0 deletions api/cases/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@
from api.compliance.serializers.ComplianceVisitCaseSerializers import ComplianceVisitSerializer
from api.core.serializers import KeyValueChoiceField, PrimaryKeyRelatedSerializerField
from api.documents.libraries.process_document import process_document
from api.flags.serializers import CaseListFlagSerializer
from api.flags.models import Flag
from api.gov_users.serializers import GovUserSimpleSerializer
from api.organisations.models import Organisation
from api.organisations.serializers import TinyOrganisationViewSerializer
Expand Down Expand Up @@ -122,6 +124,7 @@ class CaseListSerializer(serializers.Serializer):
intended_end_use = serializers.SerializerMethodField()
end_users = serializers.SerializerMethodField()
sub_status = CaseSubStatusSerializer()
flags = PrimaryKeyRelatedSerializerField(many=True, queryset=Flag.objects.all(), serializer=CaseListFlagSerializer)

def __init__(self, *args, **kwargs):
self.team = kwargs.pop("team", None)
Expand Down
21 changes: 1 addition & 20 deletions api/cases/views/search/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
from api.applications.serializers.advice import AdviceSearchViewSerializer
from api.cases.models import Case, EcjuQuery, Advice
from api.common.dates import working_days_in_range, number_of_days_since
from api.flags.models import Flag
from api.flags.serializers import CaseListFlagSerializer
from api.organisations.models import Organisation
from api.staticdata.statuses.enums import CaseStatusEnum
Expand Down Expand Up @@ -50,27 +51,7 @@ def get_advice_types_list():
return AdviceType.to_representation()


def populate_other_flags(cases: List[Dict]):
from api.flags.models import Flag

case_ids = [case["id"] for case in cases]

union_flags = set(
[
*Flag.objects.filter(cases__id__in=case_ids).annotate(case_id=F("cases__id")),
*Flag.objects.filter(organisations__cases__id__in=case_ids).annotate(case_id=F("organisations__cases__id")),
]
)

for case in cases:
case_id = str(case["id"])
flags = [flag for flag in union_flags if str(flag.case_id) == case_id]
case["flags"] = CaseListFlagSerializer(flags, many=True).data


def populate_goods_flags(cases: List[Dict]):
from api.flags.models import Flag

case_ids = [case["id"] for case in cases]
qs1 = Flag.objects.filter(goods__goods_on_application__application_id__in=case_ids).annotate(
case_id=F("goods__goods_on_application__application_id"),
Expand Down
Empty file.
Original file line number Diff line number Diff line change
Expand Up @@ -910,7 +910,7 @@ def setUp(self):
super().setUp()

self.other_team = self.create_team("other team")
self.other_team_gov_user = self.create_gov_user("[email protected]", self.other_team)
self.other_team_gov_user = self.create_gov_user("[email protected]", self.other_team) # /PS-IGNORE
self.queue = self.create_queue("my new queue", self.team)
self.case = self.create_standard_application_case(self.organisation)
self.case.queues.set([self.queue])
Expand Down Expand Up @@ -1011,7 +1011,7 @@ def test_api_success(self):
self._create_data()
self.advice = FinalAdviceFactory(user=self.gov_user, case=self.case, type=AdviceType.APPROVE, good=self.good)
self.gov_user2 = self.create_gov_user(
team=self.create_team(name="other_team"), email="[email protected]"
team=self.create_team(name="other_team"), email="[email protected]" # /PS-IGNORE
)
self.group_advice = FinalAdviceFactory(
user=self.gov_user2, case=self.case, type=AdviceType.REFUSE, good=self.good
Expand Down Expand Up @@ -1148,12 +1148,33 @@ def test_api_success(self):
],
)

# Reflect rest framework's way of rendering datetime objects... https://github.com/encode/django-rest-framework/blob/c9e7b68a4c1db1ac60e962053380acda549609f3/rest_framework/utils/encoders.py#L29
# Reflect rest framework's way of rendering datetime objects... https://github.com/encode/django-rest-framework/blob/c9e7b68a4c1db1ac60e962053380acda549609f3/rest_framework/utils/encoders.py#L29 /PS-IGNORE
expected_submitted_at = self.case.submitted_at.isoformat()
if expected_submitted_at.endswith("+00:00"):
expected_submitted_at = expected_submitted_at[:-6] + "Z"
self.assertEqual(case_api_result["submitted_at"], expected_submitted_at)

def test_api_multiple_cases_flags_correct(self):
# Create two cases..
self._create_data()
self._create_data()
# Add a case flag to each case..
flag_alias = "REFER_TO_FCDO_MEUC_CONCERNS"
flag = Flag.objects.get(alias=flag_alias)
all_cases = Case.objects.all()
for case in all_cases:
case.flags.add(flag)

# Perform the search
response = self.client.get(self.url, **self.gov_headers)
response_data = response.json()["results"]

self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(len(response_data["cases"]), 2)
for search_result in response_data["cases"]:
self.assertEqual(len(search_result["flags"]), 1)
self.assertEqual(search_result["flags"][0]["alias"], flag_alias)

def test_api_no_advice(self):
self._create_data()
response = self.client.get(self.url, **self.gov_headers)
Expand Down
1 change: 0 additions & 1 deletion api/cases/views/search/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,6 @@ def get(self, request, *args, **kwargs):
# Populate certain fields outside of the serializer for performance improvements
service.populate_goods_flags(cases)
service.populate_destinations_flags(cases)
service.populate_other_flags(cases)
service.populate_organisation(cases)
service.populate_is_recently_updated(cases)
service.populate_activity_updates(case_map)
Expand Down
2 changes: 1 addition & 1 deletion api/conf/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -404,7 +404,7 @@
{
"un_sanctions_file": "https://scsanctions.un.org/resources/xml/en/consolidated.xml",
"office_financial_sanctions_file": "https://ofsistorage.blob.core.windows.net/publishlive/2022format/ConList.xml",
"uk_sanctions_file": "https://assets.publishing.service.gov.uk/media/65ca02639c5b7f0012951caf/UK_Sanctions_List.xml", # /PS-IGNORE
"uk_sanctions_file": "https://assets.publishing.service.gov.uk/media/6776a7d49d03f12136308d1c/UK_Sanctions_List.xml", # /PS-IGNORE
},
)
LITE_INTERNAL_NOTIFICATION_EMAILS = env.json("LITE_INTERNAL_NOTIFICATION_EMAILS", {})
Expand Down
12 changes: 10 additions & 2 deletions api/organisations/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,11 @@ def validate_registration_number(self, value):

# Check for uniqueness only when creating a new Organisation
if not self.instance:
if Organisation.objects.filter(registration_number=value).exists():
if (
Organisation.objects.filter(registration_number=value)
.exclude(status__in=[OrganisationStatus.REJECTED, OrganisationStatus.DRAFT])
.exists()
):
raise serializers.ValidationError("This registration number is already in use.")

return value
Expand Down Expand Up @@ -502,7 +506,11 @@ class OrganisationRegistrationNumberSerializer(serializers.Serializer):
def validate_registration_number(self, value):
# Check for uniqueness only when creating a new Organisation
if not self.instance:
if Organisation.objects.filter(registration_number=value).exists():
if (
Organisation.objects.filter(registration_number=value)
.exclude(status__in=[OrganisationStatus.REJECTED, OrganisationStatus.DRAFT])
.exists()
):
raise serializers.ValidationError("This registration number is already in use.")

return value
Loading

0 comments on commit 397e2b9

Please sign in to comment.