Skip to content

Commit 4583ef3

Browse files
committed
fix(eap): return non-field error for duplicate eap registration
- update on email notification
1 parent 038d7f8 commit 4583ef3

5 files changed

Lines changed: 69 additions & 11 deletions

File tree

assets

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# Generated by Django 4.2.30 on 2026-05-22 03:24
2+
3+
from django.db import migrations, models
4+
5+
6+
class Migration(migrations.Migration):
7+
dependencies = [
8+
("eap", "0004_emailrecipient_and_more"),
9+
]
10+
11+
operations = [
12+
migrations.RemoveConstraint(
13+
model_name="fulleap",
14+
name="unique_full_eap_version",
15+
),
16+
migrations.RemoveConstraint(
17+
model_name="simplifiedeap",
18+
name="unique_simplified_eap_version",
19+
),
20+
migrations.AddConstraint(
21+
model_name="fulleap",
22+
constraint=models.UniqueConstraint(
23+
fields=("eap_registration", "version"),
24+
name="unique_full_eap_version",
25+
violation_error_message="A Full EAP for this EAP Registration with this version already exists.",
26+
),
27+
),
28+
migrations.AddConstraint(
29+
model_name="simplifiedeap",
30+
constraint=models.UniqueConstraint(
31+
fields=("eap_registration", "version"),
32+
name="unique_simplified_eap_version",
33+
violation_error_message="A Simplified EAP for this EAP Registration with this version already exists.",
34+
),
35+
),
36+
]

eap/models.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1331,6 +1331,9 @@ class Meta:
13311331
models.UniqueConstraint(
13321332
fields=["eap_registration", "version"],
13331333
name="unique_simplified_eap_version",
1334+
violation_error_message=_(
1335+
"A Simplified EAP for this EAP Registration with this version already exists.",
1336+
),
13341337
)
13351338
]
13361339

@@ -1880,6 +1883,9 @@ class Meta:
18801883
models.UniqueConstraint(
18811884
fields=["eap_registration", "version"],
18821885
name="unique_full_eap_version",
1886+
violation_error_message=_(
1887+
"A Full EAP for this EAP Registration with this version already exists.",
1888+
),
18831889
)
18841890
]
18851891

eap/serializers.py

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
from django.utils.translation import gettext
1010
from rest_framework import serializers
1111
from rest_framework.exceptions import PermissionDenied
12+
from rest_framework.validators import UniqueTogetherValidator
1213

1314
from api.serializers import (
1415
Admin2Serializer,
@@ -557,6 +558,7 @@ class SimplifiedEAPSerializer(
557558
):
558559

559560
# FILES
561+
version = serializers.IntegerField(default=1, read_only=True)
560562
hazard_impact_images = EAPFileUpdateSerializer(required=False, many=True)
561563
selected_early_actions_images = EAPFileUpdateSerializer(required=False, many=True, allow_null=True)
562564
risk_selected_protocols_images = EAPFileUpdateSerializer(required=False, many=True, allow_null=True)
@@ -585,6 +587,13 @@ class Meta:
585587
"created_by",
586588
"modified_by",
587589
]
590+
validators = [
591+
UniqueTogetherValidator(
592+
queryset=SimplifiedEAP.objects.all(),
593+
fields=["eap_registration", "version"],
594+
message="EAP for this registration has already been created.",
595+
)
596+
]
588597
exclude = ("cover_image",)
589598

590599
def _validate_timeframe(self, data: dict[str, typing.Any]) -> None:
@@ -636,11 +645,6 @@ def _validate_timeframe(self, data: dict[str, typing.Any]) -> None:
636645
{"operational_timeframe": gettext("operational timeframe value is not valid for Months unit.")}
637646
)
638647

639-
def validate_eap_registration(self, eap_registration: EAPRegistration) -> EAPRegistration:
640-
if not self.instance and eap_registration.has_eap_application:
641-
raise serializers.ValidationError("EAP for this registration has already been created.")
642-
return eap_registration
643-
644648
def validate(self, data: dict[str, typing.Any]) -> dict[str, typing.Any]:
645649
original_eap_registration = getattr(self.instance, "eap_registration", None) if self.instance else None
646650
eap_registration: EAPRegistration | None = data.get("eap_registration", original_eap_registration)
@@ -649,6 +653,9 @@ def validate(self, data: dict[str, typing.Any]) -> dict[str, typing.Any]:
649653
if self.instance and original_eap_registration != eap_registration:
650654
raise serializers.ValidationError("EAP Registration cannot be changed for existing EAP.")
651655

656+
if not self.instance and eap_registration.has_eap_application:
657+
raise serializers.ValidationError(gettext("EAP for this registration has already been created."))
658+
652659
if self.instance and eap_registration.get_status_enum not in [
653660
EAPRegistration.Status.UNDER_DEVELOPMENT,
654661
EAPRegistration.Status.NS_ADDRESSING_COMMENTS,
@@ -690,6 +697,7 @@ class FullEAPSerializer(
690697
CommonEAPFieldsSerializer,
691698
):
692699

700+
version = serializers.IntegerField(default=1, read_only=True)
693701
# admins
694702
key_actors = KeyActorSerializer(many=True, required=True)
695703

@@ -795,6 +803,13 @@ class Meta:
795803
"created_by",
796804
"modified_by",
797805
]
806+
validators = [
807+
UniqueTogetherValidator(
808+
queryset=FullEAP.objects.all(),
809+
fields=["eap_registration", "version"],
810+
message="EAP for this registration has already been created.",
811+
)
812+
]
798813
exclude = ("cover_image",)
799814

800815
def _validate_timeframe(self, data: dict[str, typing.Any]) -> None:
@@ -811,11 +826,6 @@ def _validate_timeframe(self, data: dict[str, typing.Any]) -> None:
811826
if lead_unit is not None and lead_time_value is not None and lead_unit != TimeFrame.DAYS:
812827
raise serializers.ValidationError({"lead_timeframe_unit": gettext("lead timeframe unit must be Days for Full EAP.")})
813828

814-
def validate_eap_registration(self, eap_registration: EAPRegistration) -> EAPRegistration:
815-
if not self.instance and eap_registration.has_eap_application:
816-
raise serializers.ValidationError("EAP for this registration has already been created.")
817-
return eap_registration
818-
819829
def validate(self, data: dict[str, typing.Any]) -> dict[str, typing.Any]:
820830
original_eap_registration = getattr(self.instance, "eap_registration", None) if self.instance else None
821831
eap_registration: EAPRegistration | None = data.get("eap_registration", original_eap_registration)
@@ -824,6 +834,9 @@ def validate(self, data: dict[str, typing.Any]) -> dict[str, typing.Any]:
824834
if self.instance and original_eap_registration != eap_registration:
825835
raise serializers.ValidationError("EAP Registration cannot be changed for existing EAP.")
826836

837+
if not self.instance and eap_registration.has_eap_application:
838+
raise serializers.ValidationError(gettext("EAP for this registration has already been created."))
839+
827840
if self.instance and eap_registration.get_status_enum not in [
828841
EAPRegistration.Status.UNDER_DEVELOPMENT,
829842
EAPRegistration.Status.NS_ADDRESSING_COMMENTS,

notifications/notification.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,9 @@ def send_notification(subject, recipients, html, mailtype="", cc_recipients=None
8888
print("-" * 22, "EMAIL END -", "-" * 22)
8989
return
9090

91+
recipients = recipients if isinstance(recipients, list) else [recipients]
92+
cc_recipients = cc_recipients if isinstance(cc_recipients, list) else [cc_recipients]
93+
9194
to_addresses = clean_emails(recipients)
9295
cc_addresses = clean_emails(cc_recipients)
9396
addresses = to_addresses + cc_addresses

0 commit comments

Comments
 (0)