Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

LTD: Prepare API for multiple end_users #2342

Draft
wants to merge 6 commits into
base: dev
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 16 additions & 11 deletions api/applications/creators.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,23 +96,28 @@ def check_party_error(party, object_not_found_error, is_mandatory, is_document_m
return document_error


def _validate_end_user(draft, errors, is_mandatory, open_application=False):
def _validate_end_users(draft, errors, is_mandatory, open_application=False):
"""Validates end user. If a document is mandatory, this is also validated."""

# Document is only mandatory if application is standard permanent or HMRC query
is_document_mandatory = (
draft.case_type.sub_type == CaseTypeSubTypeEnum.STANDARD
and draft.export_type == ApplicationExportType.PERMANENT
) or draft.case_type.sub_type == CaseTypeSubTypeEnum.HMRC

end_user_errors = check_party_error(
draft.end_user.party if draft.end_user else None,
object_not_found_error=strings.Applications.Standard.NO_END_USER_SET,
is_mandatory=is_mandatory,
is_document_mandatory=is_document_mandatory,
)
if end_user_errors:
errors["end_user"] = [end_user_errors]
error_messages = []

for end_user in draft.end_users:
end_user_errors = check_party_error(
end_user.party if end_user else None,
object_not_found_error=strings.Applications.Standard.NO_END_USER_SET,
is_mandatory=is_mandatory,
is_document_mandatory=is_document_mandatory,
)
if end_user_errors:
error_messages.append(end_user_errors)

if error_messages:
errors["end_user"] = error_messages

return errors

Expand Down Expand Up @@ -263,7 +268,7 @@ def _validate_standard_licence(draft, errors):
"""Checks that a standard licence has all party types & goods"""

errors = _validate_siel_locations(draft, errors)
errors = _validate_end_user(draft, errors, is_mandatory=True)
errors = _validate_end_users(draft, errors, is_mandatory=True)
errors = _validate_security_approvals(draft, errors, is_mandatory=True)
errors = _validate_consignee(draft, errors, is_mandatory=True)
errors = _validate_third_parties(draft, errors, is_mandatory=False)
Expand Down
4 changes: 2 additions & 2 deletions api/applications/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -161,8 +161,8 @@ def delete_uploaded_document(data):

def auto_match_sanctions(application):
parties = []
if application.end_user:
parties.append(application.end_user.party)
if application.end_users[0]:
parties.append(application.end_users[0].party)

for item in application.ultimate_end_users:
parties.append(item.party)
Expand Down
9 changes: 8 additions & 1 deletion api/applications/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,14 @@ def end_user(self):
Standard and HMRC Query applications
"""
try:
return self.active_parties.get(party__type=PartyType.END_USER)
return self.active_parties.filter(party__type=PartyType.END_USER).first()
except PartyOnApplication.DoesNotExist:
pass

@property
def end_users(self):
try:
return self.active_parties.filter(party__type=PartyType.END_USER)
except PartyOnApplication.DoesNotExist:
pass

Expand Down
20 changes: 18 additions & 2 deletions api/data_workspace/v2/tests/bdd/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from django.urls import reverse
from freezegun import freeze_time
from moto import mock_aws
from operator import itemgetter
from pytest_bdd import (
given,
parsers,
Expand All @@ -23,6 +24,7 @@
from api.applications.tests.factories import (
DraftStandardApplicationFactory,
GoodOnApplicationFactory,
EndUserFactory,
PartyOnApplicationFactory,
StandardApplicationFactory,
)
Expand Down Expand Up @@ -439,6 +441,20 @@ def add_end_user_to_application(draft_standard_application, country):
end_user.party.save()


@given(parsers.parse("a new end-user added to the application of `{country}`"))
def add_new_end_user_to_application(draft_standard_application, country):
country = Country.objects.get(name=country)
end_user = PartyOnApplicationFactory(
application=draft_standard_application,
party=EndUserFactory(country=country, organisation=draft_standard_application.organisation),
)
PartyDocumentFactory(
party=end_user.party,
s3_key="party-document-second",
safe=True,
)


@when(
"the application is submitted",
target_fixture="submitted_standard_application",
Expand Down Expand Up @@ -522,8 +538,8 @@ def check_rows(client, parse_table, unpage_data, table_name, rows):
for row in parsed_rows[1:]:
expected_data.append({key: value for key, value in zip(keys, row)})
expected_data = cast_to_types(expected_data, table_metadata["fields"])
actual_data = sorted(actual_data, key=lambda item, keys=keys: item[keys[0]])
expected_data = sorted(expected_data, key=lambda item, keys=keys: item[keys[0]])
actual_data = sorted(actual_data, key=itemgetter(*keys))
expected_data = sorted(expected_data, key=itemgetter(*keys))
assert actual_data == expected_data


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,12 @@ Scenario: Check that the country code and type are included in the extract
| id | 03fb08eb-1564-4b68-9336-3ca8906543f9 |
And a consignee added to the application in `Australia`
And an end-user added to the application of `New Zealand`
And a new end-user added to the application of `South Korea`
When the application is submitted
And the application is issued at 2024-11-22T13:35:15
Then the `destinations` table has the following rows:
| application_id | country_code | type |
| 03fb08eb-1564-4b68-9336-3ca8906543f9 | KR | end_user |
| 03fb08eb-1564-4b68-9336-3ca8906543f9 | NZ | end_user |
| 03fb08eb-1564-4b68-9336-3ca8906543f9 | AU | consignee |

Expand Down
9 changes: 4 additions & 5 deletions api/letter_templates/context_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -737,6 +737,7 @@ def get_document_context(case, addressee=None):
appeal_deadline = timezone.localtime() + timedelta(days=APPEAL_DAYS)
exporter_reference = ""
date_application_submitted = ""
end_users = []

if base_application:
if base_application.name:
Expand All @@ -745,6 +746,8 @@ def get_document_context(case, addressee=None):
if base_application.submitted_at:
date_application_submitted = base_application.submitted_at.strftime("%d %B %Y")

end_users = base_application.end_users

return {
"case_reference": case.reference_code,
"case_submitted_at": case.submitted_at,
Expand All @@ -756,11 +759,7 @@ def get_document_context(case, addressee=None):
"addressee": AddresseeSerializer(addressee).data,
"organisation": OrganisationSerializer(case.organisation).data,
"licence": LicenceSerializer(licence).data if licence else None,
"end_user": (
PartySerializer(base_application.end_user.party).data
if base_application and base_application.end_user
else None
),
"end_user": (PartySerializer(end_users[0].party).data if end_users else None),
"consignee": (
PartySerializer(base_application.consignee.party).data
if base_application and base_application.consignee
Expand Down
Loading