Skip to content

Commit

Permalink
Merge pull request #2330 from uktrade/uat
Browse files Browse the repository at this point in the history
PROD Release
  • Loading branch information
depsiatwal authored Dec 5, 2024
2 parents 4903b0d + 7c297a4 commit 912fb82
Show file tree
Hide file tree
Showing 24 changed files with 816 additions and 265 deletions.
19 changes: 19 additions & 0 deletions api/cases/migrations/0073_licencedecision_denial_reasons.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Generated by Django 4.2.16 on 2024-11-28 11:07

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
("denial_reasons", "0006_populate_uuid_field"),
("cases", "0072_alter_decision_populate_issued_on_appeal"),
]

operations = [
migrations.AddField(
model_name="licencedecision",
name="denial_reasons",
field=models.ManyToManyField(to="denial_reasons.denialreason"),
),
]
24 changes: 18 additions & 6 deletions api/cases/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -342,7 +342,7 @@ def no_licence_required(self):
notify_exporter_no_licence_required(self)

@transaction.atomic
def finalise(self, request, decisions):
def finalise(self, user, decisions, note):
from api.audit_trail import service as audit_trail_service
from api.cases.libraries.finalise import remove_flags_on_finalisation, remove_flags_from_audit_trail
from api.licences.models import Licence
Expand All @@ -361,7 +361,7 @@ def finalise(self, request, decisions):

if Licence.objects.filter(case=self).count() > 1:
audit_trail_service.create(
actor=request.user,
actor=user,
verb=AuditType.REINSTATED_APPLICATION,
target=self,
payload={
Expand All @@ -376,12 +376,12 @@ def finalise(self, request, decisions):
self.save()

audit_trail_service.create(
actor=request.user,
actor=user,
verb=AuditType.UPDATED_STATUS,
target=self,
payload={
"status": {"new": self.status.status, "old": old_status},
"additional_text": request.data.get("note"),
"additional_text": note,
},
)
logging.info("Case is now finalised")
Expand Down Expand Up @@ -410,16 +410,27 @@ def finalise(self, request, decisions):
if previous_licence_decision.decision == current_decision:
previous_decision = previous_licence_decision

LicenceDecision.objects.create(
licence_decision = LicenceDecision.objects.create(
case=self,
decision=current_decision,
licence=licence,
previous_decision=previous_decision,
)
if advice_type == AdviceType.REFUSE:
denial_reasons = (
self.advice.filter(
level=AdviceLevel.FINAL,
type=AdviceType.REFUSE,
)
.only("denial_reasons__id")
.distinct()
.values_list("denial_reasons__id", flat=True)
)
licence_decision.denial_reasons.set(denial_reasons)

licence_reference = licence.reference_code if licence and advice_type == AdviceType.APPROVE else ""
audit_trail_service.create(
actor=request.user,
actor=user,
verb=AuditType.CREATED_FINAL_RECOMMENDATION,
target=self,
payload={
Expand Down Expand Up @@ -846,6 +857,7 @@ class LicenceDecision(TimestampableModel):
licence = models.ForeignKey(
"licences.Licence", on_delete=models.DO_NOTHING, related_name="licence_decisions", null=True, blank=True
)
denial_reasons = models.ManyToManyField(DenialReason)
excluded_from_statistics_reason = models.TextField(default=None, blank=True, null=True)
previous_decision = models.ForeignKey(
"self", related_name="previous_decisions", default=None, null=True, on_delete=models.DO_NOTHING
Expand Down
23 changes: 19 additions & 4 deletions api/cases/tests/test_finalise_advice.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,12 @@
from api.audit_trail.enums import AuditType
from api.audit_trail.models import Audit
from api.audit_trail import service as audit_trail_service
from api.cases.enums import AdviceType, CaseTypeEnum, LicenceDecisionType
from api.cases.models import LicenceDecision
from api.cases.enums import (
AdviceLevel,
AdviceType,
CaseTypeEnum,
LicenceDecisionType,
)
from api.cases.tests.factories import FinalAdviceFactory
from api.cases.libraries.get_case import get_case
from api.cases.generated_documents.models import GeneratedCaseDocument
Expand Down Expand Up @@ -65,8 +69,19 @@ def test_refuse_standard_application_success(self, send_exporter_notifications_f
payload__decision=AdviceType.REFUSE,
).exists()
)
self.assertTrue(
LicenceDecision.objects.filter(case=self.application, decision=LicenceDecisionType.REFUSED).exists()

licence_decision = case.licence_decisions.get(decision=LicenceDecisionType.REFUSED)

advice = case.advice.get(
level=AdviceLevel.FINAL,
type=AdviceType.REFUSE,
)

self.assertTrue(licence_decision.denial_reasons.exists())

self.assertQuerySetEqual(
licence_decision.denial_reasons.all(),
advice.denial_reasons.all(),
)

@mock.patch("api.cases.notify.notify_exporter_licence_refused")
Expand Down
2 changes: 1 addition & 1 deletion api/cases/views/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -894,7 +894,7 @@ def put(self, request, pk):
)

# finalises case, grants licence and publishes decision documents
licence_id = case.finalise(request, required_decisions)
licence_id = case.finalise(request.user, required_decisions, request.data.get("note"))

return JsonResponse({"case": pk, "licence": licence_id}, status=status.HTTP_201_CREATED)

Expand Down
44 changes: 44 additions & 0 deletions api/data_workspace/v2/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,10 @@
)
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.denial_reasons.models import DenialReason
from api.staticdata.report_summaries.models import ReportSummary


Expand Down Expand Up @@ -96,6 +99,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 @@ -129,3 +141,35 @@ def get_first_closed_at(self, application) -> typing.Optional[datetime.datetime]
return application.baseapplication_ptr.case_ptr.closed_status_updates[0].created_at

return None


class UnitSerializer(serializers.Serializer):
code = serializers.CharField()
description = serializers.CharField()


class FootnoteSerializer(serializers.Serializer):
footnote = serializers.CharField()
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",
)


class LicenceRefusalCriteriaSerializer(serializers.ModelSerializer):
criteria = serializers.CharField(source="display_value")
licence_decision_id = serializers.UUIDField()

class Meta:
model = DenialReason
fields = ("criteria", "licence_decision_id")
Loading

0 comments on commit 912fb82

Please sign in to comment.