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.
This commit is contained in:
ixgadmin 2026-09-17 16:03:11 +00:00
parent 5e201b2035
commit dae025f600

View file

@ -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