From dae025f600d4712f875756083bfd888bf41b1766 Mon Sep 17 00:00:00 2001 From: ixgadmin Date: Thu, 17 Sep 2026 16:03:11 +0000 Subject: [PATCH] Enforce the shipment form's rules in the API The ops form refuses a shipment with no vessel, container, ETD or ETA, and one whose departure is after its arrival. The serializer now requires the same fields and refuses the same contradiction, so the API cannot accept a record the portal would reject. Partial updates stay partial: a status change alone does not require the other fields, and the date check falls back to the stored values. --- apps/shipments/serializers.py | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/apps/shipments/serializers.py b/apps/shipments/serializers.py index 29de367..b49fe17 100644 --- a/apps/shipments/serializers.py +++ b/apps/shipments/serializers.py @@ -1,9 +1,35 @@ from rest_framework import serializers + from .models import Shipment class ShipmentSerializer(serializers.ModelSerializer): + """Mirror the ops form's rules, so the API cannot accept what the portal refuses. + + The model tolerates a blank vessel or container and a missing date, because + records also arrive through this API. But a shipment is what the buyer's page + shows, so the fields the buyer reads are required here too, and a departure + after the arrival is refused. The bill of lading and the forwarder stay + optional; the ports keep their model defaults. + """ + class Meta: model = Shipment fields = "__all__" read_only_fields = ["id", "created_at"] + extra_kwargs = { + "status": {"required": True}, + "vessel_name": {"required": True, "allow_blank": False}, + "container_ref": {"required": True, "allow_blank": False}, + "etd_nigeria": {"required": True, "allow_null": False}, + "eta_uk": {"required": True, "allow_null": False}, + } + + def validate(self, attrs): + etd = attrs.get("etd_nigeria", getattr(self.instance, "etd_nigeria", None)) + eta = attrs.get("eta_uk", getattr(self.instance, "eta_uk", None)) + if etd and eta and etd > eta: + raise serializers.ValidationError( + {"eta_uk": "The ETA cannot be before the ETD. Check the two dates."} + ) + return attrs