Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions api/migrations/0229_alter_export_export_type.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Generated by Django 4.2.26 on 2025-12-04 09:06

from django.db import migrations, models


class Migration(migrations.Migration):
dependencies = [
("api", "0228_alter_export_export_type"),
]

operations = [
migrations.AlterField(
model_name="export",
name="export_type",
field=models.CharField(
choices=[
("dref-applications", "DREF Application"),
("dref-operational-updates", "DREF Operational Update"),
("dref-final-reports", "DREF Final Report"),
("old-dref-final-reports", "Old DREF Final Report"),
("per", "Per"),
("simplified", "Simplified EAP"),
("full", "Full EAP"),
],
max_length=255,
verbose_name="Export Type",
),
),
]
4 changes: 2 additions & 2 deletions api/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -2560,8 +2560,8 @@ class ExportType(models.TextChoices):
FINAL_REPORT = "dref-final-reports", _("DREF Final Report")
OLD_FINAL_REPORT = "old-dref-final-reports", _("Old DREF Final Report")
PER = "per", _("Per")
SIMPLIFIED_EAP = "simplified-eap", _("Simplified EAP")
FULL_EAP = "full-eap", _("Full EAP")
SIMPLIFIED_EAP = "simplified", _("Simplified EAP")
FULL_EAP = "full", _("Full EAP")

export_id = models.IntegerField(verbose_name=_("Export Id"))
export_type = models.CharField(verbose_name=_("Export Type"), max_length=255, choices=ExportType.choices)
Expand Down
55 changes: 52 additions & 3 deletions api/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
from api.utils import CountryValidator, RegionValidator
from deployments.models import EmergencyProject, Personnel, PersonnelDeployment
from dref.models import Dref, DrefFinalReport, DrefOperationalUpdate
from eap.models import FullEAP, SimplifiedEAP
from eap.models import EAPRegistration, FullEAP, SimplifiedEAP
from lang.models import String
from lang.serializers import ModelSerializer
from local_units.models import DelegationOffice
Expand Down Expand Up @@ -2544,6 +2544,11 @@ class ExportSerializer(serializers.ModelSerializer):
status_display = serializers.CharField(source="get_status_display", read_only=True)
# NOTE: is_pga is used to determine if the export contains PGA or not
is_pga = serializers.BooleanField(default=False, required=False, write_only=True)
# NOTE: diff is used to determine if the export is requested for diff view or not
# Currently only used for EAP exports
diff = serializers.BooleanField(default=False, required=False, write_only=True)
# NOTE: Version of a EAP export being requested, only applicable for full and simplified EAP exports
version = serializers.IntegerField(required=False, write_only=True)

class Meta:
model = Export
Expand All @@ -2559,6 +2564,7 @@ def create(self, validated_data):
export_id = validated_data.get("export_id")
export_type = validated_data.get("export_type")
country_id = validated_data.get("per_country")
version = validated_data.pop("version", None)
if export_type == Export.ExportType.DREF:
title = Dref.objects.filter(id=export_id).first().title
elif export_type == Export.ExportType.OPS_UPDATE:
Expand All @@ -2569,19 +2575,62 @@ def create(self, validated_data):
overview = Overview.objects.filter(id=export_id).first()
title = f"{overview.country.name}-preparedness-{overview.get_phase_display()}"
elif export_type == Export.ExportType.SIMPLIFIED_EAP:
simplified_eap = SimplifiedEAP.objects.filter(id=export_id).first()
if version:
simplified_eap = SimplifiedEAP.objects.filter(
eap_registration=export_id,
version=version,
).first()
if not simplified_eap:
raise serializers.ValidationError("No Simplified EAP found for the given EAP Registration ID and version")
else:
eap_registration = EAPRegistration.objects.filter(id=export_id).first()
if not eap_registration:
raise serializers.ValidationError("No EAP Registration found for the given ID")

simplified_eap = eap_registration.latest_simplified_eap
if not simplified_eap:
serializers.ValidationError("No Simplified EAP found for the given EAP Registration ID")

title = (
f"{simplified_eap.eap_registration.national_society.name}-{simplified_eap.eap_registration.disaster_type.name}"
)
elif export_type == Export.ExportType.FULL_EAP:
full_eap = FullEAP.objects.filter(id=export_id).first()
if version:
full_eap = FullEAP.objects.filter(
eap_registration=export_id,
version=version,
).first()
if not full_eap:
raise serializers.ValidationError("No Full EAP found for the given EAP Registration ID and version")
else:
eap_registration = EAPRegistration.objects.filter(id=export_id).first()
if not eap_registration:
raise serializers.ValidationError("No EAP Registration found for the given ID")

full_eap = eap_registration.latest_full_eap
if not full_eap:
serializers.ValidationError("No Full EAP found for the given EAP Registration ID")

title = f"{full_eap.eap_registration.national_society.name}-{full_eap.eap_registration.disaster_type.name}"
else:
title = "Export"
user = self.context["request"].user

if export_type == Export.ExportType.PER:
validated_data["url"] = f"{settings.GO_WEB_INTERNAL_URL}/countries/{country_id}/{export_type}/{export_id}/export/"

elif export_type in [
Export.ExportType.SIMPLIFIED_EAP,
Export.ExportType.FULL_EAP,
]:
validated_data["url"] = f"{settings.GO_WEB_INTERNAL_URL}/eap/{export_id}/{export_type}/export/"
# NOTE: EAP exports with diff view only for EAPs exports
if version:
validated_data["url"] += f"?version={version}"
diff = validated_data.pop("diff")
if diff:
validated_data["url"] += "&diff=true" if version else "?diff=true"

else:
validated_data["url"] = f"{settings.GO_WEB_INTERNAL_URL}/{export_type}/{export_id}/export/"

Expand Down
2 changes: 1 addition & 1 deletion assets
Submodule assets updated 1 files
+48 −4 openapi-schema.yaml
6 changes: 6 additions & 0 deletions eap/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,8 @@ class Meta:
"version",
"is_locked",
"updated_checklist_file",
"created_at",
"modified_at",
]


Expand All @@ -118,6 +120,8 @@ class Meta:
"version",
"is_locked",
"updated_checklist_file",
"created_at",
"modified_at",
]


Expand All @@ -143,6 +147,8 @@ class Meta:
"requirement_cost",
"activated_at",
"approved_at",
"created_at",
"modified_at",
]


Expand Down
117 changes: 103 additions & 14 deletions eap/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -1614,8 +1614,11 @@ def setUp(self):
self.partner2 = CountryFactory.create(name="partner2", iso3="AAA", iso="AA")

self.user = UserFactory.create()
self.url = "/api/v2/pdf-export/"

self.eap_registration = EAPRegistrationFactory.create(
@mock.patch("api.serializers.generate_url.delay")
def test_simplified_eap_export(self, mock_generate_url):
eap_registration = EAPRegistrationFactory.create(
eap_type=EAPType.SIMPLIFIED_EAP,
country=self.country,
national_society=self.national_society,
Expand All @@ -1624,13 +1627,8 @@ def setUp(self):
created_by=self.user,
modified_by=self.user,
)

self.url = "/api/v2/pdf-export/"

@mock.patch("api.serializers.generate_url.delay")
def test_simplified_eap_export(self, mock_generate_url):
self.simplified_eap = SimplifiedEAPFactory.create(
eap_registration=self.eap_registration,
simplified_eap = SimplifiedEAPFactory.create(
eap_registration=eap_registration,
created_by=self.user,
modified_by=self.user,
national_society_contact_title="NS Title Example",
Expand All @@ -1639,9 +1637,12 @@ def test_simplified_eap_export(self, mock_generate_url):
modified_by=self.user,
),
)
eap_registration.latest_simplified_eap = simplified_eap
eap_registration.save()

data = {
"export_type": Export.ExportType.SIMPLIFIED_EAP,
"export_id": self.simplified_eap.id,
"export_id": eap_registration.id,
"is_pga": False,
}

Expand All @@ -1652,7 +1653,7 @@ def test_simplified_eap_export(self, mock_generate_url):
self.assert_201(response)
self.assertIsNotNone(response.data["id"], response.data)

expected_url = f"{settings.GO_WEB_INTERNAL_URL}/{Export.ExportType.SIMPLIFIED_EAP}/{self.simplified_eap.id}/export/"
expected_url = f"{settings.GO_WEB_INTERNAL_URL}/eap/{eap_registration.id}/{Export.ExportType.SIMPLIFIED_EAP}/export/"
self.assertEqual(response.data["url"], expected_url)
self.assertEqual(response.data["status"], Export.ExportStatus.PENDING)

Expand All @@ -1666,20 +1667,55 @@ def test_simplified_eap_export(self, mock_generate_url):
django_get_language(),
)

# Test Export Snapshot

# create a new snapshot
simplfied_eap_snapshot = simplified_eap.generate_snapshot()
assert simplfied_eap_snapshot.version == 2, "Snapshot version should be 2"

data = {
"export_type": Export.ExportType.SIMPLIFIED_EAP,
"export_id": eap_registration.id,
"version": 2,
}

with self.capture_on_commit_callbacks(execute=True):
response = self.client.post(self.url, data, format="json")
self.assert_201(response)
self.assertIsNotNone(response.data["id"], response.data)

expected_url = (
f"{settings.GO_WEB_INTERNAL_URL}/eap/{eap_registration.id}/{Export.ExportType.SIMPLIFIED_EAP}/export/?version=2"
)
self.assertEqual(response.data["url"], expected_url)

@mock.patch("api.serializers.generate_url.delay")
def test_full_eap_export(self, mock_generate_url):
self.full_eap = FullEAPFactory.create(
eap_registration=self.eap_registration,
eap_registration = EAPRegistrationFactory.create(
eap_type=EAPType.FULL_EAP,
country=self.country,
national_society=self.national_society,
disaster_type=self.disaster_type,
created_by=self.user,
modified_by=self.user,
)

full_eap = FullEAPFactory.create(
eap_registration=eap_registration,
created_by=self.user,
modified_by=self.user,
budget_file=EAPFileFactory._create_file(
created_by=self.user,
modified_by=self.user,
),
)

eap_registration.latest_full_eap = full_eap
eap_registration.save()

data = {
"export_type": Export.ExportType.FULL_EAP,
"export_id": self.full_eap.id,
"export_id": eap_registration.id,
"is_pga": False,
}

Expand All @@ -1689,7 +1725,7 @@ def test_full_eap_export(self, mock_generate_url):
response = self.client.post(self.url, data, format="json")
self.assert_201(response)
self.assertIsNotNone(response.data["id"], response.data)
expected_url = f"{settings.GO_WEB_INTERNAL_URL}/{Export.ExportType.FULL_EAP}/{self.full_eap.id}/export/"
expected_url = f"{settings.GO_WEB_INTERNAL_URL}/eap/{eap_registration.id}/{Export.ExportType.FULL_EAP}/export/"
self.assertEqual(response.data["url"], expected_url)
self.assertEqual(response.data["status"], Export.ExportStatus.PENDING)

Expand All @@ -1703,6 +1739,59 @@ def test_full_eap_export(self, mock_generate_url):
django_get_language(),
)

@mock.patch("api.serializers.generate_url.delay")
def test_diff_export_eap(self, mock_generate_url):
eap_registration = EAPRegistrationFactory.create(
eap_type=EAPType.SIMPLIFIED_EAP,
country=self.country,
national_society=self.national_society,
disaster_type=self.disaster_type,
created_by=self.user,
modified_by=self.user,
)

simplified_eap = SimplifiedEAPFactory.create(
eap_registration=eap_registration,
created_by=self.user,
modified_by=self.user,
budget_file=EAPFileFactory._create_file(
created_by=self.user,
modified_by=self.user,
),
)

eap_registration.latest_simplified_eap = simplified_eap
eap_registration.save()

self.authenticate(self.user)
data = {
"export_type": Export.ExportType.SIMPLIFIED_EAP,
"export_id": eap_registration.id,
"diff": True,
}

self.authenticate(self.user)

with self.capture_on_commit_callbacks(execute=True):
response = self.client.post(self.url, data, format="json")
self.assert_201(response)
self.assertIsNotNone(response.data["id"], response.data)

expected_url = (
f"{settings.GO_WEB_INTERNAL_URL}/eap/{eap_registration.id}/{Export.ExportType.SIMPLIFIED_EAP}/export/?diff=true"
)
self.assertEqual(response.data["url"], expected_url)

self.assertEqual(mock_generate_url.called, True)
title = f"{self.national_society.name}-{self.disaster_type.name}"
mock_generate_url.assert_called_once_with(
expected_url,
response.data["id"],
self.user.id,
title,
django_get_language(),
)


class EAPFullTestCase(APITestCase):
def setUp(self):
Expand Down
1 change: 0 additions & 1 deletion eap/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,6 @@ def get_queryset(self) -> QuerySet[EAPRegistration]:
"partners",
"simplified_eap",
)
.order_by("id")
)

@action(
Expand Down
Loading