Skip to content

Commit

Permalink
Merge pull request #2121 from uktrade/LTD-5083-Update-quantity-value-…
Browse files Browse the repository at this point in the history
…endpoint

LTD-5083: Add endpoint to allow update of quantity value fields only
  • Loading branch information
saruniitr authored Aug 8, 2024
2 parents 50dce49 + bb52c0f commit 1ef94c0
Show file tree
Hide file tree
Showing 5 changed files with 154 additions and 1 deletion.
10 changes: 10 additions & 0 deletions api/applications/serializers/good.py
Original file line number Diff line number Diff line change
Expand Up @@ -424,3 +424,13 @@ class GoodOnApplicationInternalDocumentViewSerializer(serializers.Serializer):

def get_s3_key(self, instance):
return instance.s3_key if instance.safe else "File not ready"


class GoodOnApplicationQuantityValueSerializer(serializers.ModelSerializer):

class Meta:
model = GoodOnApplication
fields = (
"quantity",
"value",
)
92 changes: 91 additions & 1 deletion api/applications/tests/test_edit_good_on_applications.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

from api.applications.libraries.case_status_helpers import get_case_statuses
from api.applications.enums import NSGListType
from api.applications.tests.factories import GoodOnApplicationFactory
from api.applications.tests.factories import DraftStandardApplicationFactory, GoodOnApplicationFactory
from api.goods.tests.factories import GoodFactory, FirearmFactory
from api.staticdata.statuses.enums import CaseStatusEnum
from api.staticdata.statuses.libraries.get_case_status import get_case_status_by_status
Expand All @@ -15,6 +15,18 @@


class EditGoodOnApplicationsTests(DataTestClient):

def setUp(self):
super().setUp()

self.draft = DraftStandardApplicationFactory(organisation=self.organisation)
self.good_on_application = self.draft.goods.first()

self.edit_quantity_value_url = reverse(
"applications:application_goods_quantity_value",
kwargs={"pk": self.draft.id, "good_on_application_pk": self.good_on_application.id},
)

def test_edit_a_good_on_applicaton(self):
application = self.create_draft_standard_application(self.organisation)
good_on_application = application.goods.first()
Expand Down Expand Up @@ -117,6 +129,84 @@ def test_edit_a_good_on_applicaton_invalid_organisation(self):
original_calibre,
)

@parameterized.expand(
[
[
{"quantity": 5, "value": 10.00},
{"value": 10000.00},
{"quantity": 5, "value": 10000.00},
],
[
{"quantity": 5, "value": 10.00},
{"quantity": 500},
{"quantity": 500, "value": 10.00},
],
[
{"quantity": 5, "value": 10.00},
{"quantity": 500, "value": 100000.00},
{"quantity": 500, "value": 100000.00},
],
]
)
def test_exporter_edit_quantity_value(self, initial, data, expected):
self.good_on_application.quantity = initial["quantity"]
self.good_on_application.value = initial["value"]
self.good_on_application.save()

response = self.client.patch(self.edit_quantity_value_url, data=data, **self.exporter_headers)
self.assertEqual(response.status_code, status.HTTP_200_OK)

self.good_on_application.refresh_from_db()
self.assertEqual(self.good_on_application.quantity, expected["quantity"])
self.assertEqual(self.good_on_application.value, expected["value"])

@parameterized.expand(
[
[
{"report_summary": "optical equipment", "quantity": 5, "value": 10.00},
{"report_summary": "aircraft engines", "value": 10000.00},
{"report_summary": "optical equipment", "quantity": 5, "value": 10000.00},
],
[
{"report_summary": "optical equipment", "quantity": 5, "value": 10.00},
{"report_summary": "aircraft engines", "quantity": 500},
{"report_summary": "optical equipment", "quantity": 500, "value": 10.00},
],
[
{"report_summary": "optical equipment", "quantity": 5, "value": 10.00},
{"report_summary": "aircraft engines", "quantity": 500, "value": 100000.00},
{"report_summary": "optical equipment", "quantity": 500, "value": 100000.00},
],
]
)
def test_exporter_only_editing_quantity_value_allowed(self, initial, data, expected):
self.good_on_application.report_summary = initial["report_summary"]
self.good_on_application.quantity = initial["quantity"]
self.good_on_application.value = initial["value"]
self.good_on_application.save()

response = self.client.patch(self.edit_quantity_value_url, data=data, **self.exporter_headers)
self.assertEqual(response.status_code, status.HTTP_200_OK)

self.good_on_application.refresh_from_db()
self.assertEqual(self.good_on_application.report_summary, expected["report_summary"])
self.assertEqual(self.good_on_application.quantity, expected["quantity"])
self.assertEqual(self.good_on_application.value, expected["value"])

def test_exporter_edit_invalid_application_raises_error(self):
url = reverse(
"applications:application_goods_quantity_value",
kwargs={"pk": self.good_on_application.id, "good_on_application_pk": self.good_on_application.id},
)
response = self.client.patch(url, data={"quantity": 20}, **self.exporter_headers)
self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND)

def test_exporter_edit_invalid_data_raises_error(self):
response = self.client.patch(
self.edit_quantity_value_url, data={"quantity": "invalid value"}, **self.exporter_headers
)
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)


class GovUserEditGoodOnApplicationsTests(DataTestClient):
def test_edit_trigger_list_assessment_and_nca(self):
Expand Down
8 changes: 8 additions & 0 deletions api/applications/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
amendments,
)

from api.exporter.applications.views import ApplicationQuantityValueUpdateView

app_name = "applications"

urlpatterns = [
Expand Down Expand Up @@ -144,4 +146,10 @@
amendments.CreateApplicationAmendment.as_view(),
name="create_amendment",
),
# Exporter specific endpoints
path(
"<uuid:pk>/good-on-application/<uuid:good_on_application_pk>/quantity-value/",
ApplicationQuantityValueUpdateView.as_view(),
name="application_goods_quantity_value",
),
]
9 changes: 9 additions & 0 deletions api/exporter/applications/permissions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
from rest_framework import permissions

from api.staticdata.statuses.enums import CaseStatusEnum


class IsApplicationEditable(permissions.BasePermission):
def has_permission(self, request, view):
application = view.application
return application.status.status in CaseStatusEnum.major_editable_statuses()
36 changes: 36 additions & 0 deletions api/exporter/applications/views.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
from django.http import Http404
from rest_framework.generics import UpdateAPIView

from api.core.authentication import ExporterAuthentication
from api.core.permissions import IsExporterInOrganisation
from api.applications.serializers.good import GoodOnApplicationQuantityValueSerializer
from api.applications.models import BaseApplication, GoodOnApplication
from api.exporter.applications.permissions import IsApplicationEditable


class BaseExporterApplication:
authentication_classes = (ExporterAuthentication,)
permission_classes = (IsExporterInOrganisation,)

def setup(self, request, *args, **kwargs):
super().setup(request, *args, **kwargs)

try:
self.application = BaseApplication.objects.get(pk=self.kwargs["pk"])
except BaseApplication.DoesNotExist:
raise Http404()

def get_organisation(self):
return self.application.organisation


class ApplicationQuantityValueUpdateView(BaseExporterApplication, UpdateAPIView):
permission_classes = (
IsExporterInOrganisation,
IsApplicationEditable,
)
lookup_url_kwarg = "good_on_application_pk"
serializer_class = GoodOnApplicationQuantityValueSerializer

def get_queryset(self):
return GoodOnApplication.objects.filter(application_id=self.kwargs["pk"])

0 comments on commit 1ef94c0

Please sign in to comment.