diff --git a/local_units/enums.py b/local_units/enums.py index 38dd0f83e..a4ddaea1f 100644 --- a/local_units/enums.py +++ b/local_units/enums.py @@ -2,4 +2,6 @@ enum_register = { "deprecate_reason": models.LocalUnit.DeprecateReason, + "validation_status": models.LocalUnitChangeRequest.Status, + "validators": models.LocalUnitChangeRequest.Validator, } diff --git a/local_units/serializers.py b/local_units/serializers.py index 1629e7d4c..6576e9066 100644 --- a/local_units/serializers.py +++ b/local_units/serializers.py @@ -550,3 +550,32 @@ class Meta: "created_by_details", "previous_data", ) + + +class LocalUnitDeprecateSerializer(serializers.ModelSerializer): + deprecated_reason = serializers.ChoiceField(choices=LocalUnit.DeprecateReason, required=True) + deprecated_reason_overview = serializers.CharField(required=True, allow_blank=False) + + class Meta: + model = LocalUnit + fields = ("deprecated_reason", "deprecated_reason_overview") + + def create(self, _): + raise serializers.ValidationError({"non_field_errors": gettext("Create is not allowed")}) + + def validate(self, attrs): + instance = self.instance + + if instance and instance.is_deprecated: + raise serializers.ValidationError({"non_field_errors": gettext("This object is already depricated")}) + + return attrs + + def update(self, instance, validated_data): + instance.is_deprecated = True + instance.deprecated_reason = validated_data.get("deprecated_reason", instance.deprecated_reason) + instance.deprecated_reason_overview = validated_data.get( + "deprecated_reason_overview", instance.deprecated_reason_overview + ) + instance.save(update_fields=["is_deprecated", "deprecated_reason", "deprecated_reason_overview"]) + return instance diff --git a/local_units/test_views.py b/local_units/test_views.py index 541c82939..b28cf964a 100644 --- a/local_units/test_views.py +++ b/local_units/test_views.py @@ -2,6 +2,7 @@ import factory from django.contrib.gis.geos import Point +from factory import fuzzy from api.models import Country, Region from deployments.factories.user import UserFactory @@ -25,7 +26,7 @@ class LocalUnitFactory(factory.django.DjangoModelFactory): location = Point(12, 38) - date_of_data = factory.fuzzy.FuzzyDate(datetime.date(2024, 1, 2)) + date_of_data = fuzzy.FuzzyDate(datetime.date(2024, 1, 2)) class Meta: model = LocalUnit @@ -64,6 +65,40 @@ def test_list(self): # self.assertEqual(response.data['results'][0]['type_details']['name'], 'Code 0') # self.assertEqual(response.data['results'][0]['type_details']['code'], 0) + def test_deprecate_local_unit(self): + country = Country.objects.all().first() + type = LocalUnitType.objects.all().first() + local_unit_obj = LocalUnitFactory.create( + country=country, type=type, draft=True, validated=False, date_of_data="2023-09-09" + ) + + self.authenticate() + url = f"/api/v2/local-units/{local_unit_obj.id}/deprecate/" + data = { + "deprecated_reason": LocalUnit.DeprecateReason.INCORRECTLY_ADDED, + "deprecated_reason_overview": "test reason", + } + response = self.client.post(url, data=data) + local_unit_obj = LocalUnit.objects.get(id=local_unit_obj.id) + + self.assert_200(response) + self.assertEqual(local_unit_obj.is_deprecated, True) + self.assertEqual(local_unit_obj.deprecated_reason, LocalUnit.DeprecateReason.INCORRECTLY_ADDED) + + # Test for validation + response = self.client.post(url, data=data) + self.assert_400(response) + + # test revert deprecate + data = {} + url = f"/api/v2/local-units/{local_unit_obj.id}/revert-deprecate/" + response = self.client.post(url, data=data) + local_unit_obj = LocalUnit.objects.get(id=local_unit_obj.id) + self.assert_200(response) + self.assertEqual(local_unit_obj.is_deprecated, False) + self.assertEqual(local_unit_obj.deprecated_reason, None) + self.assertEqual(local_unit_obj.deprecated_reason_overview, "") + def test_filter(self): self.authenticate() response = self.client.get("/api/v2/local-units/?country__name=Nepal") diff --git a/local_units/views.py b/local_units/views.py index 10d624dba..c4d424095 100644 --- a/local_units/views.py +++ b/local_units/views.py @@ -30,6 +30,7 @@ from local_units.serializers import ( DelegationOfficeSerializer, LocalUnitChangeRequestSerializer, + LocalUnitDeprecateSerializer, LocalUnitDetailSerializer, LocalUnitOptionsSerializer, LocalUnitSerializer, @@ -214,6 +215,42 @@ def get_latest_changes(self, request, pk=None, version=None): serializer = LocalUnitChangeRequestSerializer(change_request, context={"request": request}) return response.Response(serializer.data) + @extend_schema(request=LocalUnitDeprecateSerializer, responses=None) + @action( + detail=True, + methods=["post"], + url_path="deprecate", + serializer_class=LocalUnitDeprecateSerializer, + permission_classes=[permissions.IsAuthenticated, DenyGuestUserPermission], + ) + def deprecate(self, request, pk=None): + """Deprecate local unit object object""" + instance = self.get_object() + serializer = LocalUnitDeprecateSerializer(instance, data=request.data) + serializer.is_valid(raise_exception=True) + serializer.save() + return response.Response( + {"message": "Local unit object deprecated successfully."}, + status=status.HTTP_200_OK, + ) + + @extend_schema(request=None, responses=PrivateLocalUnitSerializer) + @action( + detail=True, + methods=["post"], + url_path="revert-deprecate", + permission_classes=[permissions.IsAuthenticated, DenyGuestUserPermission], + ) + def revert_deprecate(self, request, pk=None): + """Revert the deprecate local unit object.""" + local_unit = self.get_object() + local_unit.is_deprecated = False + local_unit.deprecated_reason = None + local_unit.deprecated_reason_overview = "" + local_unit.save(update_fields=["is_deprecated", "deprecated_reason", "deprecated_reason_overview"]) + serializer = PrivateLocalUnitSerializer(local_unit, context={"request": request}) + return response.Response(serializer.data) + class LocalUnitViewSet(viewsets.ModelViewSet): queryset = LocalUnit.objects.select_related(