@@ -429,6 +429,7 @@ class Meta:
429429 "modified_by" ,
430430 "created_by" ,
431431 "budget_file_preview" ,
432+ "is_dref_imminent_v2" ,
432433 )
433434 exclude = (
434435 "cover_image" ,
@@ -1083,6 +1084,7 @@ def update(self, instance, validated_data):
10831084
10841085class DrefFinalReportSerializer (NestedUpdateMixin , NestedCreateMixin , ModelSerializer ):
10851086 MAX_NUMBER_OF_PHOTOS = 4
1087+ SUB_TOTAL_COST = 75000
10861088 national_society_actions = NationalSocietyActionSerializer (many = True , required = False )
10871089 needs_identified = IdentifiedNeedSerializer (many = True , required = False )
10881090 planned_interventions = PlannedInterventionSerializer (many = True , required = False )
@@ -1105,13 +1107,15 @@ class DrefFinalReportSerializer(NestedUpdateMixin, NestedCreateMixin, ModelSeria
11051107 modified_by_details = UserNameSerializer (source = "modified_by" , read_only = True )
11061108 disaster_type_details = DisasterTypeSerializer (source = "disaster_type" , read_only = True )
11071109 source_information = SourceInformationSerializer (many = True , required = False )
1110+ proposed_action = ProposedActionSerializer (many = True , required = False )
11081111
11091112 class Meta :
11101113 model = DrefFinalReport
11111114 read_only_fields = (
11121115 "modified_by" ,
11131116 "created_by" ,
11141117 "financial_report_preview" ,
1118+ "is_dref_imminent_v2" ,
11151119 )
11161120 exclude = (
11171121 "images" ,
@@ -1123,7 +1127,7 @@ class Meta:
11231127
11241128 def validate (self , data ):
11251129 dref = data .get ("dref" )
1126- # check if dref is published and operational_update associated with it is also published
1130+ # Check if dref is published and operational_update associated with it is also published
11271131 if not self .instance and dref :
11281132 if not dref .is_published :
11291133 raise serializers .ValidationError (gettext ("Can't create Final Report for not published dref %s." % dref .id ))
@@ -1141,6 +1145,68 @@ def validate(self, data):
11411145
11421146 if self .instance and self .instance .is_published :
11431147 raise serializers .ValidationError (gettext ("Can't update published final report %s." % self .instance .id ))
1148+
1149+ # NOTE: Validation for type DREF Imminent
1150+ if self .instance and self .instance .is_dref_imminent_v2 and data .get ("type_of_dref" ) == Dref .DrefType .IMMINENT :
1151+ sub_total_cost = data .get ("sub_total_cost" )
1152+ sub_total_expenditure_cost = data .get ("sub_total_expenditure_cost" )
1153+ surge_deployment_expenditure_cost = data .get ("surge_deployment_expenditure_cost" ) or 0
1154+ indirect_cost = data .get ("indirect_cost" )
1155+ indirect_expenditure_cost = data .get ("indirect_expenditure_cost" )
1156+ total_cost = data .get ("total_cost" )
1157+ total_expenditure_cost = data .get ("total_expenditure_cost" )
1158+ proposed_actions = data .get ("proposed_action" , [])
1159+
1160+ if not proposed_actions :
1161+ raise serializers .ValidationError (
1162+ {"proposed_action" : gettext ("Proposed Action is required for type DREF Imminent" )}
1163+ )
1164+ if not sub_total_cost :
1165+ raise serializers .ValidationError ({"sub_total_cost" : gettext ("Sub-total is required for Imminent DREF" )})
1166+ if not sub_total_expenditure_cost :
1167+ raise serializers .ValidationError (
1168+ {"sub_total_expenditure_cost" : gettext ("Sub-total Expenditure is required for Imminent DREF" )}
1169+ )
1170+ if sub_total_cost != self .SUB_TOTAL_COST :
1171+ raise serializers .ValidationError (
1172+ {"sub_total" : gettext ("Sub-total should be equal to %s for Imminent DREF" % self .SUB_TOTAL_COST )}
1173+ )
1174+ if not indirect_cost :
1175+ raise serializers .ValidationError ({"indirect_cost" : gettext ("Indirect Cost is required for Imminent DREF" )})
1176+ if not indirect_expenditure_cost :
1177+ raise serializers .ValidationError (
1178+ {"indirect_expenditure_cost" : gettext ("Indirect Expenditure is required for Imminent DREF" )}
1179+ )
1180+ if not total_cost :
1181+ raise serializers .ValidationError ({"total_cost" : gettext ("Total is required for Imminent DREF" )})
1182+ if not total_expenditure_cost :
1183+ raise serializers .ValidationError (
1184+ {"total_expenditure_cost" : gettext ("Total Expenditure is required for Imminent DREF" )}
1185+ )
1186+
1187+ total_proposed_budget : int = 0
1188+ total_proposed_expenditure : int = 0
1189+ for action in proposed_actions :
1190+ total_proposed_budget += action .get ("total_budget" , 0 )
1191+ total_proposed_expenditure += action .get ("total_expenditure" , 0 )
1192+ if total_proposed_budget != sub_total_cost :
1193+ raise serializers .ValidationError ({"sub_total_cost" : gettext ("Sub-total should be equal to proposed budget." )})
1194+ if total_proposed_expenditure != sub_total_expenditure_cost :
1195+ raise serializers .ValidationError (
1196+ {"sub_total_expenditure_cost" : gettext ("Sub-total Expenditure should be equal to proposed expenditure." )}
1197+ )
1198+ expected_total_expenditure_cost : int = (
1199+ sub_total_expenditure_cost + surge_deployment_expenditure_cost + indirect_expenditure_cost
1200+ )
1201+ if expected_total_expenditure_cost != total_expenditure_cost :
1202+ raise serializers .ValidationError (
1203+ {
1204+ "total_expenditure_cost" : gettext (
1205+ "Total Expenditure Cost should be equal to sum of Sub-total Expenditure, "
1206+ "Surge Deployment Expenditure and Indirect Expenditure Cost."
1207+ )
1208+ }
1209+ )
11441210 return data
11451211
11461212 def validate_photos (self , photos ):
@@ -1274,11 +1340,6 @@ def create(self, validated_data):
12741340 if validated_data ["type_of_dref" ] == Dref .DrefType .LOAN :
12751341 raise serializers .ValidationError (gettext ("Can't create final report for dref type %s" % Dref .DrefType .LOAN ))
12761342
1277- # TODO: Remove me! After final report is implemented for drefs IMMINENT
1278- if validated_data ["type_of_dref" ] == Dref .DrefType .IMMINENT and dref .is_dref_imminent_v2 :
1279- raise serializers .ValidationError (
1280- gettext ("Can't create final report for newly created dref type %s" % Dref .DrefType .IMMINENT .label )
1281- )
12821343 dref_final_report = super ().create (validated_data )
12831344 # XXX: Copy files from DREF (Only nested serialized fields)
12841345 nested_serialized_file_fields = [
@@ -1395,12 +1456,26 @@ def create(self, validated_data):
13951456 raise serializers .ValidationError (
13961457 gettext ("Can't create final report for dref type %s" % Dref .DrefType .LOAN .label )
13971458 )
1398-
1399- # TODO: Remove me! After final report is implemented for drefs IMMINENT
1459+ # NOTE: Checks for the new dref final reports of new dref imminents
14001460 if validated_data ["type_of_dref" ] == Dref .DrefType .IMMINENT and dref .is_dref_imminent_v2 :
1401- raise serializers .ValidationError (
1402- gettext ("Can't create final report for newly created dref type %s" % Dref .DrefType .IMMINENT .label )
1403- )
1461+ validated_data ["is_dref_imminent_v2" ] = True
1462+ validated_data ["sub_total_cost" ] = dref .sub_total_cost
1463+ validated_data ["surge_deployment_cost" ] = dref .surge_deployment_cost
1464+ validated_data ["surge_deployment_expenditure_cost" ] = dref .surge_deployment_cost
1465+ validated_data ["indirect_cost" ] = dref .indirect_cost
1466+ validated_data ["indirect_expenditure_cost" ] = dref .indirect_cost
1467+ validated_data ["total_cost" ] = dref .total_cost
1468+
1469+ # NOTE: Checks for the new dref final reports of new dref imminents
1470+ if validated_data ["type_of_dref" ] == Dref .DrefType .IMMINENT and dref .is_dref_imminent_v2 :
1471+ validated_data ["is_dref_imminent_v2" ] = True
1472+ validated_data ["sub_total_cost" ] = dref .sub_total_cost
1473+ validated_data ["surge_deployment_cost" ] = dref .surge_deployment_cost
1474+ validated_data ["surge_deployment_expenditure_cost" ] = dref .surge_deployment_cost
1475+ validated_data ["indirect_cost" ] = dref .indirect_cost
1476+ validated_data ["indirect_expenditure_cost" ] = dref .indirect_cost
1477+ validated_data ["total_cost" ] = dref .total_cost
1478+
14041479 dref_final_report = super ().create (validated_data )
14051480 # XXX: Copy files from DREF (Only nested serialized fields)
14061481 nested_serialized_file_fields = [
@@ -1420,6 +1495,8 @@ def create(self, validated_data):
14201495 dref_final_report .users .add (* dref .users .all ())
14211496 dref_final_report .national_society_actions .add (* dref .national_society_actions .all ())
14221497 dref_final_report .source_information .add (* dref .source_information .all ())
1498+ if dref_final_report .type_of_dref == Dref .DrefType .IMMINENT and dref_final_report .is_dref_imminent_v2 :
1499+ dref_final_report .proposed_action .add (* dref .proposed_action .all ())
14231500 # also update is_final_report_created for dref
14241501 dref .is_final_report_created = True
14251502 dref .save (update_fields = ["is_final_report_created" ])
0 commit comments