diff --git a/assets b/assets index 89f0cafef..7747f77a1 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit 89f0cafef25573986740aaee3a4ca6c224f87309 +Subproject commit 7747f77a1a969017154ab632828edbc4263bdeb5 diff --git a/eap/serializers.py b/eap/serializers.py index 0dc131ed8..cfca5588a 100644 --- a/eap/serializers.py +++ b/eap/serializers.py @@ -95,26 +95,80 @@ def update(self, instance, validated_data: dict[str, typing.Any]): return super().update(instance, validated_data) +class EAPFileInputSerializer(serializers.Serializer): + file = serializers.ListField(child=serializers.FileField(required=True)) + + +class EAPGlobalFilesSerializer(serializers.Serializer): + url = serializers.URLField(read_only=True) + + +class EAPFileSerializer(BaseEAPSerializer): + id = serializers.IntegerField(required=False) + file = serializers.FileField(required=True) + + class Meta: + model = EAPFile + fields = "__all__" + read_only_fields = ( + "created_by", + "modified_by", + ) + + def validate_file(self, file): + validate_file_type(file) + return file + + +# NOTE: Separate serializer for partial updating EAPFile instance +class EAPFileUpdateSerializer(BaseEAPSerializer): + id = serializers.IntegerField(required=True) + file = serializers.FileField(required=False) + + class Meta: + model = EAPFile + fields = "__all__" + read_only_fields = ( + "created_by", + "modified_by", + ) + + def validate_id(self, id: int) -> int: + try: + EAPFile.objects.get(id=id) + except EAPFile.DoesNotExist: + raise serializers.ValidationError(gettext("Invalid pk '%s' - object does not exist.") % id) + return id + + def validate_file(self, file): + validate_file_type(file) + return file + + # NOTE: Mini Serializers used for basic listing purpose class MiniSimplifiedEAPSerializer( serializers.ModelSerializer, ): + updated_checklist_file_details = EAPFileSerializer(source="updated_checklist_file", read_only=True) + budget_file_details = EAPFileSerializer(source="budget_file", read_only=True) + class Meta: model = SimplifiedEAP fields = [ "id", - "eap_registration", "total_budget", "readiness_budget", "pre_positioning_budget", "early_action_budget", "seap_timeframe", "budget_file", + "budget_file_details", "version", "is_locked", - "updated_checklist_file", + "review_checklist_file", + "updated_checklist_file_details", "created_at", "modified_at", ] @@ -123,19 +177,23 @@ class Meta: class MiniFullEAPSerializer( serializers.ModelSerializer, ): + updated_checklist_file_details = EAPFileSerializer(source="updated_checklist_file", read_only=True) + budget_file_details = EAPFileSerializer(source="budget_file", read_only=True) + class Meta: model = FullEAP fields = [ "id", - "eap_registration", "total_budget", "readiness_budget", "pre_positioning_budget", "early_action_budget", "budget_file", + "budget_file_details", "version", "is_locked", - "updated_checklist_file", + "review_checklist_file", + "updated_checklist_file_details", "created_at", "modified_at", ] @@ -199,6 +257,7 @@ class Meta: "latest_simplified_eap", "latest_full_eap", "deadline", + "summary_file", ] def create(self, validated_data: dict[str, typing.Any]): @@ -241,56 +300,6 @@ def validate(self, validated_data: dict[str, typing.Any]) -> dict[str, typing.An return validated_data -class EAPFileInputSerializer(serializers.Serializer): - file = serializers.ListField(child=serializers.FileField(required=True)) - - -class EAPGlobalFilesSerializer(serializers.Serializer): - url = serializers.URLField(read_only=True) - - -class EAPFileSerializer(BaseEAPSerializer): - id = serializers.IntegerField(required=False) - file = serializers.FileField(required=True) - - class Meta: - model = EAPFile - fields = "__all__" - read_only_fields = ( - "created_by", - "modified_by", - ) - - def validate_file(self, file): - validate_file_type(file) - return file - - -# NOTE: Separate serializer for partial updating EAPFile instance -class EAPFileUpdateSerializer(BaseEAPSerializer): - id = serializers.IntegerField(required=True) - file = serializers.FileField(required=False) - - class Meta: - model = EAPFile - fields = "__all__" - read_only_fields = ( - "created_by", - "modified_by", - ) - - def validate_id(self, id: int) -> int: - try: - EAPFile.objects.get(id=id) - except EAPFile.DoesNotExist: - raise serializers.ValidationError(gettext("Invalid pk '%s' - object does not exist.") % id) - return id - - def validate_file(self, file): - validate_file_type(file) - return file - - ALLOWED_MAP_TIMEFRAMES_VALUE = { TimeFrame.YEARS: list(YearsTimeFrameChoices.values), TimeFrame.MONTHS: list(MonthsTimeFrameChoices.values), @@ -303,6 +312,7 @@ class OperationActivitySerializer( serializers.ModelSerializer, ): id = serializers.IntegerField(required=False) + previous_id = serializers.IntegerField(read_only=True) timeframe = serializers.ChoiceField( choices=TimeFrame.choices, required=True, @@ -340,6 +350,7 @@ class IndicatorSerializer( serializers.ModelSerializer, ): id = serializers.IntegerField(required=False) + previous_id = serializers.IntegerField(read_only=True) class Meta: model = Indicator @@ -352,6 +363,7 @@ class PlannedOperationSerializer( serializers.ModelSerializer, ): id = serializers.IntegerField(required=False) + previous_id = serializers.IntegerField(read_only=True) sector_display = serializers.CharField(source="get_sector_display", read_only=True) indicators = IndicatorSerializer(many=True, required=True) @@ -372,6 +384,7 @@ class EnableApproachSerializer( serializers.ModelSerializer, ): id = serializers.IntegerField(required=False) + previous_id = serializers.IntegerField(read_only=True) approach_display = serializers.CharField(source="get_approach_display", read_only=True) indicators = IndicatorSerializer(many=True, required=True) @@ -384,16 +397,13 @@ class EnableApproachSerializer( class Meta: model = EnableApproach fields = "__all__" - read_only_fields = ( - "created_by", - "modified_by", - ) class EAPSourceInformationSerializer( serializers.ModelSerializer, ): id = serializers.IntegerField(required=False) + previous_id = serializers.IntegerField(read_only=True) class Meta: model = SourceInformation @@ -404,6 +414,7 @@ class KeyActorSerializer( serializers.ModelSerializer, ): id = serializers.IntegerField(required=False) + previous_id = serializers.IntegerField(read_only=True) national_society_details = MiniCountrySerializer(source="national_society", read_only=True) class Meta: @@ -413,6 +424,7 @@ class Meta: class EAPActionSerializer(serializers.ModelSerializer): id = serializers.IntegerField(required=False) + previous_id = serializers.IntegerField(read_only=True) class Meta: model = EAPAction @@ -421,6 +433,7 @@ class Meta: class ImpactSerializer(serializers.ModelSerializer): id = serializers.IntegerField(required=False) + previous_id = serializers.IntegerField(read_only=True) class Meta: model = EAPImpact @@ -429,6 +442,7 @@ class Meta: class EAPContactSerializer(serializers.ModelSerializer): id = serializers.IntegerField(required=False) + previous_id = serializers.IntegerField(read_only=True) class Meta: model = EAPContact @@ -449,6 +463,7 @@ class CommonEAPFieldsSerializer(serializers.ModelSerializer): admin2_details = Admin2Serializer(source="admin2", many=True, read_only=True) budget_file = serializers.PrimaryKeyRelatedField(queryset=EAPFile.objects.all(), required=True) budget_file_details = EAPFileSerializer(source="budget_file", read_only=True) + updated_checklist_file_details = EAPFileSerializer(source="updated_checklist_file", read_only=True) def get_fields(self): fields = super().get_fields() @@ -460,6 +475,7 @@ def get_fields(self): fields["enable_approaches"] = EnableApproachSerializer(many=True, required=True) fields["budget_file"] = serializers.PrimaryKeyRelatedField(queryset=EAPFile.objects.all(), required=True) fields["budget_file_details"] = EAPFileSerializer(source="budget_file", read_only=True) + fields["updated_checklist_file_details"] = EAPFileSerializer(source="updated_checklist_file", read_only=True) return fields def validate_budget_file(self, file: typing.Optional[EAPFile]) -> typing.Optional[EAPFile]: diff --git a/eap/views.py b/eap/views.py index 27bd0cb61..0fb232c09 100644 --- a/eap/views.py +++ b/eap/views.py @@ -104,7 +104,22 @@ def get_queryset(self) -> QuerySet[EAPRegistration]: ) .prefetch_related( "partners", - "simplified_eap", + Prefetch( + "simplified_eap", + queryset=SimplifiedEAP.objects.select_related( + "budget_file__created_by", + "budget_file__modified_by", + "updated_checklist_file__created_by", + "updated_checklist_file__modified_by", + ), + ), + Prefetch( + "full_eap", + queryset=FullEAP.objects.select_related( + "budget_file__created_by", + "budget_file__modified_by", + ), + ), ) )