Skip to content

Commit 8a0c922

Browse files
Add API to deprecate local unit (#2340)
* WIP : Add api for deprecation of local unit. * Add api and test case for deprecate api for local unit. * Revert the depricated local-unit. * Add api and test case for deprecate api for local unit. * Fix test for local unit. * Clean up after rebase. * Remove duplicate deprecate function. * Fix typo for deprecate. * Pr fixes. * Add validation for already existing local unit object. * Modify test case for local unit. * Add validation test for deprecate local unit. * PR fixes. * Fix failed test case for local unit. * Add validation for deprecated_reason field in local unit. * Change in deprecate api and serializer --------- Co-authored-by: Sushil Tiwari <[email protected]>
1 parent 8997f7e commit 8a0c922

File tree

4 files changed

+104
-1
lines changed

4 files changed

+104
-1
lines changed

local_units/enums.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,6 @@
22

33
enum_register = {
44
"deprecate_reason": models.LocalUnit.DeprecateReason,
5+
"validation_status": models.LocalUnitChangeRequest.Status,
6+
"validators": models.LocalUnitChangeRequest.Validator,
57
}

local_units/serializers.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -550,3 +550,32 @@ class Meta:
550550
"created_by_details",
551551
"previous_data",
552552
)
553+
554+
555+
class LocalUnitDeprecateSerializer(serializers.ModelSerializer):
556+
deprecated_reason = serializers.ChoiceField(choices=LocalUnit.DeprecateReason, required=True)
557+
deprecated_reason_overview = serializers.CharField(required=True, allow_blank=False)
558+
559+
class Meta:
560+
model = LocalUnit
561+
fields = ("deprecated_reason", "deprecated_reason_overview")
562+
563+
def create(self, _):
564+
raise serializers.ValidationError({"non_field_errors": gettext("Create is not allowed")})
565+
566+
def validate(self, attrs):
567+
instance = self.instance
568+
569+
if instance and instance.is_deprecated:
570+
raise serializers.ValidationError({"non_field_errors": gettext("This object is already depricated")})
571+
572+
return attrs
573+
574+
def update(self, instance, validated_data):
575+
instance.is_deprecated = True
576+
instance.deprecated_reason = validated_data.get("deprecated_reason", instance.deprecated_reason)
577+
instance.deprecated_reason_overview = validated_data.get(
578+
"deprecated_reason_overview", instance.deprecated_reason_overview
579+
)
580+
instance.save(update_fields=["is_deprecated", "deprecated_reason", "deprecated_reason_overview"])
581+
return instance

local_units/test_views.py

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import factory
44
from django.contrib.gis.geos import Point
5+
from factory import fuzzy
56

67
from api.models import Country, Region
78
from deployments.factories.user import UserFactory
@@ -25,7 +26,7 @@
2526

2627
class LocalUnitFactory(factory.django.DjangoModelFactory):
2728
location = Point(12, 38)
28-
date_of_data = factory.fuzzy.FuzzyDate(datetime.date(2024, 1, 2))
29+
date_of_data = fuzzy.FuzzyDate(datetime.date(2024, 1, 2))
2930

3031
class Meta:
3132
model = LocalUnit
@@ -64,6 +65,40 @@ def test_list(self):
6465
# self.assertEqual(response.data['results'][0]['type_details']['name'], 'Code 0')
6566
# self.assertEqual(response.data['results'][0]['type_details']['code'], 0)
6667

68+
def test_deprecate_local_unit(self):
69+
country = Country.objects.all().first()
70+
type = LocalUnitType.objects.all().first()
71+
local_unit_obj = LocalUnitFactory.create(
72+
country=country, type=type, draft=True, validated=False, date_of_data="2023-09-09"
73+
)
74+
75+
self.authenticate()
76+
url = f"/api/v2/local-units/{local_unit_obj.id}/deprecate/"
77+
data = {
78+
"deprecated_reason": LocalUnit.DeprecateReason.INCORRECTLY_ADDED,
79+
"deprecated_reason_overview": "test reason",
80+
}
81+
response = self.client.post(url, data=data)
82+
local_unit_obj = LocalUnit.objects.get(id=local_unit_obj.id)
83+
84+
self.assert_200(response)
85+
self.assertEqual(local_unit_obj.is_deprecated, True)
86+
self.assertEqual(local_unit_obj.deprecated_reason, LocalUnit.DeprecateReason.INCORRECTLY_ADDED)
87+
88+
# Test for validation
89+
response = self.client.post(url, data=data)
90+
self.assert_400(response)
91+
92+
# test revert deprecate
93+
data = {}
94+
url = f"/api/v2/local-units/{local_unit_obj.id}/revert-deprecate/"
95+
response = self.client.post(url, data=data)
96+
local_unit_obj = LocalUnit.objects.get(id=local_unit_obj.id)
97+
self.assert_200(response)
98+
self.assertEqual(local_unit_obj.is_deprecated, False)
99+
self.assertEqual(local_unit_obj.deprecated_reason, None)
100+
self.assertEqual(local_unit_obj.deprecated_reason_overview, "")
101+
67102
def test_filter(self):
68103
self.authenticate()
69104
response = self.client.get("/api/v2/local-units/?country__name=Nepal")

local_units/views.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
from local_units.serializers import (
3131
DelegationOfficeSerializer,
3232
LocalUnitChangeRequestSerializer,
33+
LocalUnitDeprecateSerializer,
3334
LocalUnitDetailSerializer,
3435
LocalUnitOptionsSerializer,
3536
LocalUnitSerializer,
@@ -214,6 +215,42 @@ def get_latest_changes(self, request, pk=None, version=None):
214215
serializer = LocalUnitChangeRequestSerializer(change_request, context={"request": request})
215216
return response.Response(serializer.data)
216217

218+
@extend_schema(request=LocalUnitDeprecateSerializer, responses=None)
219+
@action(
220+
detail=True,
221+
methods=["post"],
222+
url_path="deprecate",
223+
serializer_class=LocalUnitDeprecateSerializer,
224+
permission_classes=[permissions.IsAuthenticated, DenyGuestUserPermission],
225+
)
226+
def deprecate(self, request, pk=None):
227+
"""Deprecate local unit object object"""
228+
instance = self.get_object()
229+
serializer = LocalUnitDeprecateSerializer(instance, data=request.data)
230+
serializer.is_valid(raise_exception=True)
231+
serializer.save()
232+
return response.Response(
233+
{"message": "Local unit object deprecated successfully."},
234+
status=status.HTTP_200_OK,
235+
)
236+
237+
@extend_schema(request=None, responses=PrivateLocalUnitSerializer)
238+
@action(
239+
detail=True,
240+
methods=["post"],
241+
url_path="revert-deprecate",
242+
permission_classes=[permissions.IsAuthenticated, DenyGuestUserPermission],
243+
)
244+
def revert_deprecate(self, request, pk=None):
245+
"""Revert the deprecate local unit object."""
246+
local_unit = self.get_object()
247+
local_unit.is_deprecated = False
248+
local_unit.deprecated_reason = None
249+
local_unit.deprecated_reason_overview = ""
250+
local_unit.save(update_fields=["is_deprecated", "deprecated_reason", "deprecated_reason_overview"])
251+
serializer = PrivateLocalUnitSerializer(local_unit, context={"request": request})
252+
return response.Response(serializer.data)
253+
217254

218255
class LocalUnitViewSet(viewsets.ModelViewSet):
219256
queryset = LocalUnit.objects.select_related(

0 commit comments

Comments
 (0)