Skip to content

Commit

Permalink
Merge branch 'dev' into LTD-5688-productionise-footnotes-endpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
saruniitr committed Nov 29, 2024
2 parents 26ade23 + 6a2824f commit b59e46f
Show file tree
Hide file tree
Showing 17 changed files with 392 additions and 142 deletions.
2 changes: 1 addition & 1 deletion .InstallPackages
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,4 @@ swig
imagemagick
poppler-utils
libsqlite3-dev
postgresql-client-14

1 change: 1 addition & 0 deletions .copilot/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ builder:
version: 0.3.339
packs:
- acodeninja/install
- acodeninja/psql
2 changes: 2 additions & 0 deletions Procfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
web: SWIG_LIB=/home/vcap/deps/0/apt/usr/share/swig4.0 CFLAGS=-I/home/vcap/deps/1/python/include/python3.9.18m pip3 install endesive==1.5.9 && python manage.py migrate && gunicorn --worker-class gevent -c api/conf/gconfig.py -b 0.0.0.0:$PORT api.conf.wsgi
web-dbt-platform: python manage.py migrate && gunicorn -c api/conf/gconfig-dbt-platform.py -b 0.0.0.0:$PORT api.conf.wsgi
dump-and-anonymise: python manage.py dump_and_anonymise
rebuild-search-index: python manage.py search_index --rebuild -f
seed-internal-users: ./bin/seed_internal_users.sh
celeryworker: celery -A api.conf worker -l info
celeryscheduler: celery -A api.conf beat
5 changes: 4 additions & 1 deletion api/conf/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -491,7 +491,10 @@ def _build_redis_url(base_url, db_number, **query_args):
LITE_API_ENABLE_ES = env.bool("LITE_API_ENABLE_ES", False)
if LITE_API_ENABLE_ES:
ELASTICSEARCH_DSL = {
"default": {"hosts": env.str("OPENSEARCH_ENDPOINT")},
"default": {
"hosts": env.str("OPENSEARCH_ENDPOINT"),
"timeout": 30,
},
}

ENABLE_SPIRE_SEARCH = env.bool("ENABLE_SPIRE_SEARCH", False)
Expand Down
22 changes: 22 additions & 0 deletions api/data_workspace/v2/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
)
from api.cases.enums import LicenceDecisionType
from api.cases.models import LicenceDecision
from api.licences.models import GoodOnLicence
from api.staticdata.control_list_entries.models import ControlListEntry
from api.staticdata.countries.models import Country
from api.staticdata.report_summaries.models import ReportSummary

Expand Down Expand Up @@ -96,6 +98,15 @@ class Meta:
)


class GoodOnLicenceSerializer(serializers.ModelSerializer):
good_id = serializers.UUIDField()
licence_id = serializers.UUIDField()

class Meta:
model = GoodOnLicence
fields = ("good_id", "licence_id")


class ApplicationSerializer(serializers.ModelSerializer):
licence_type = serializers.CharField(source="case_type.reference")
status = serializers.CharField(source="status.status")
Expand Down Expand Up @@ -136,3 +147,14 @@ class FootnoteSerializer(serializers.Serializer):
team_name = serializers.CharField(source="team__name")
application_id = serializers.CharField(source="case__pk")
type = serializers.CharField()


class AssessmentSerializer(serializers.ModelSerializer):
good_id = serializers.UUIDField()

class Meta:
model = ControlListEntry
fields = (
"good_id",
"rating",
)
123 changes: 123 additions & 0 deletions api/data_workspace/v2/tests/bdd/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@
PartyOnApplicationFactory,
StandardApplicationFactory,
)
from api.cases.enums import (
AdviceType,
)
from api.cases.tests.factories import FinalAdviceFactory
from api.cases.enums import CaseTypeEnum
from api.cases.models import CaseType
from api.core.constants import (
Expand All @@ -33,11 +37,16 @@
Roles,
)
from api.goods.tests.factories import GoodFactory
from api.flags.enums import SystemFlags
from api.documents.libraries.s3_operations import init_s3_client
from api.letter_templates.models import LetterTemplate
from api.parties.tests.factories import PartyDocumentFactory
from api.organisations.tests.factories import OrganisationFactory
from api.staticdata.letter_layouts.models import LetterLayout
from api.staticdata.report_summaries.models import (
ReportSummaryPrefix,
ReportSummarySubject,
)
from api.staticdata.statuses.enums import CaseStatusEnum
from api.staticdata.statuses.models import CaseStatus
from api.staticdata.units.enums import Units
Expand Down Expand Up @@ -380,9 +389,75 @@ 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 d, key=keys[0]: d[key])
expected_data = sorted(expected_data, key=lambda d, key=keys[0]: d[key])
assert actual_data == expected_data


@given(parsers.parse("the application has the following goods:{goods}"))
def given_the_application_has_the_following_goods(parse_table, draft_standard_application, goods):
draft_standard_application.goods.all().delete()
good_attributes = parse_table(goods)[1:]
for id, name in good_attributes:
GoodOnApplicationFactory(
application=draft_standard_application,
id=id,
good__name=name,
)


@when(parsers.parse("the goods are assessed by TAU as:{assessments}"))
def when_the_goods_are_assessed_by_tau(
parse_table,
submitted_standard_application,
assessments,
api_client,
lu_case_officer,
gov_headers,
):
assessments = parse_table(assessments)[1:]
url = reverse("assessments:make_assessments", kwargs={"case_pk": submitted_standard_application.pk})

assessment_payload = []
for good_on_application_id, control_list_entry, report_summary_prefix, report_summary_subject in assessments:
data = {
"id": good_on_application_id,
"comment": "Some comment",
}

if control_list_entry == "NLR":
data.update(
{
"control_list_entries": [],
"is_good_controlled": False,
}
)
else:
if report_summary_prefix:
prefix = ReportSummaryPrefix.objects.get(name=report_summary_prefix)
else:
prefix = None
subject = ReportSummarySubject.objects.get(name=report_summary_subject)
data.update(
{
"control_list_entries": [control_list_entry],
"report_summary_prefix": prefix.pk if prefix else None,
"report_summary_subject": subject.pk,
"is_good_controlled": True,
"regime_entries": [],
}
)
assessment_payload.append(data)

response = api_client.put(
url,
assessment_payload,
**gov_headers,
)
assert response.status_code == 200, response.content


@pytest.fixture()
def parse_attributes(parse_table):
def _parse_attributes(attributes):
Expand Down Expand Up @@ -412,3 +487,51 @@ def given_a_draft_standard_application_with_attributes(organisation, parse_attri
)

return application


@pytest.fixture()
def issue_licence(api_client, lu_case_officer, gov_headers, siel_template):
def _issue_licence(application):
data = {"action": AdviceType.APPROVE, "duration": 24}
for good_on_app in application.goods.all():
good_on_app.quantity = 100
good_on_app.value = 10000
good_on_app.save()
data[f"quantity-{good_on_app.id}"] = str(good_on_app.quantity)
data[f"value-{good_on_app.id}"] = str(good_on_app.value)
# create final advice for controlled goods; skip NLR goods
if good_on_app.is_good_controlled == False:
continue
FinalAdviceFactory(user=lu_case_officer, case=application, good=good_on_app.good)

issue_date = datetime.datetime.now()
data.update({"year": issue_date.year, "month": issue_date.month, "day": issue_date.day})

application.flags.remove(SystemFlags.ENFORCEMENT_CHECK_REQUIRED)

url = reverse("applications:finalise", kwargs={"pk": application.pk})
response = api_client.put(url, data=data, **gov_headers)
assert response.status_code == 200, response.content
response = response.json()

data = {
"template": str(siel_template.id),
"text": "",
"visible_to_exporter": False,
"advice_type": AdviceType.APPROVE,
}
url = reverse(
"cases:generated_documents:generated_documents",
kwargs={"pk": str(application.pk)},
)
response = api_client.post(url, data=data, **gov_headers)
assert response.status_code == 201, response.content

url = reverse(
"cases:finalise",
kwargs={"pk": str(application.pk)},
)
response = api_client.put(url, data={}, **gov_headers)
assert response.status_code == 201

return _issue_licence
Original file line number Diff line number Diff line change
Expand Up @@ -29,5 +29,5 @@ Scenario: Assess application
| 4dad5dc6-38ef-4bf7-99fd-0c6bc5d86048 | NLR | | |
Then the `goods_descriptions` table has the following rows:
| good_id | description |
| 118a003c-7191-4a2c-97e9-be243722cbb2 | composite laminates |
| 8fa8dc3c-c103-42f5-ba94-2d9098b8821d | accessories for composite laminates |
| 118a003c-7191-4a2c-97e9-be243722cbb2 | composite laminates |
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
@db
Feature: Goods On Licences

Scenario: Issue a licence
Given a standard application with the following goods:
| id | name |
| 61d193bd-a4d8-4f7d-8c07-1ac5e03ea2c7 | A controlled good |
And a draft licence with attributes:
| name | value |
| id | 962b4948-b87a-42fe-9c2b-61bdefd9cd21 |
When the licence is issued
Then the `goods_on_licences` table has the following rows:
| good_id | licence_id |
| 61d193bd-a4d8-4f7d-8c07-1ac5e03ea2c7 | 962b4948-b87a-42fe-9c2b-61bdefd9cd21 |

Scenario: NLR goods not on licence
Given a standard application with the following goods:
| id | name |
| aa9736f9-48f5-4d44-ace9-e4b8738591a5 | Another controlled good |
| 56f562f6-b554-4bb3-923b-8695ab15afca | An NLR good |
And the goods are assessed by TAU as:
| id | Control list entry | Report summary prefix | Report summary subject |
| aa9736f9-48f5-4d44-ace9-e4b8738591a5 | ML5b | accessories for | network analysers |
| 56f562f6-b554-4bb3-923b-8695ab15afca | NLR | | |
And a draft licence with attributes:
| name | value |
| id | 847a9a03-c35f-4036-ab8c-8b58d13482ab |
When the licence is issued
Then the `goods_on_licences` table has the following rows:
| good_id | licence_id |
| aa9736f9-48f5-4d44-ace9-e4b8738591a5 | 847a9a03-c35f-4036-ab8c-8b58d13482ab |

Scenario: Draft licences
Given a standard application with the following goods:
| id | name |
| f7c674b1-cd5e-4a6d-a1f5-d6ab58149d05 | A controlled good 2 |
And a draft licence with attributes:
| name | value |
| id | 297e89b9-fc93-4f38-be46-c2ab38914007 |
Then the `goods_on_licences` table is empty

Scenario: Draft applications
Given a draft standard application with the following goods:
| id | name |
| 8262dcf7-d932-4a33-978d-b5aa8a7878ee | A controlled good 3 |
And a draft licence with attributes:
| name | value |
| id | 2078827b-6d67-406c-becc-41c423720cfc |
Then the `goods_on_licences` table is empty
33 changes: 33 additions & 0 deletions api/data_workspace/v2/tests/bdd/scenarios/goods_ratings.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
@db
Feature: goods_ratings Table

Scenario: Draft application
Given a draft standard application
Then the `goods_ratings` table is empty

Scenario: Submitted application
Given a draft standard application
And the application has the following goods:
| id | name |
| 8fa8dc3c-c103-42f5-ba94-2d9098b8821d | A controlled good |
| 4dad5dc6-38ef-4bf7-99fd-0c6bc5d86048 | An NLR good |
When the application is submitted
Then the `goods_ratings` table is empty

Scenario: Assess application
Given a draft standard application
And the application has the following goods:
| id | name |
| 8fa8dc3c-c103-42f5-ba94-2d9098b8821d | A controlled good |
| 118a003c-7191-4a2c-97e9-be243722cbb2 | Another controlled good |
| 4dad5dc6-38ef-4bf7-99fd-0c6bc5d86048 | An NLR good |
When the application is submitted
And the goods are assessed by TAU as:
| id | Control list entry | Report summary prefix | Report summary subject |
| 8fa8dc3c-c103-42f5-ba94-2d9098b8821d | ML22a | accessories for | composite laminates |
| 118a003c-7191-4a2c-97e9-be243722cbb2 | PL9010 | | composite laminates |
| 4dad5dc6-38ef-4bf7-99fd-0c6bc5d86048 | NLR | | |
Then the `goods_ratings` table has the following rows:
| good_id | rating |
| 8fa8dc3c-c103-42f5-ba94-2d9098b8821d | ML22a |
| 118a003c-7191-4a2c-97e9-be243722cbb2 | PL9010 |
Loading

0 comments on commit b59e46f

Please sign in to comment.