add: contract create serializer, TODO: fix errors with owners create and test

This commit is contained in:
2025-08-05 15:49:53 +05:00
parent e77f799802
commit 5630429974
6 changed files with 283 additions and 110 deletions

View File

@@ -1,22 +1,19 @@
from rest_framework import serializers
from rest_framework import serializers # type: ignore
from rest_framework.exceptions import ValidationError # type: ignore
from core.apps.contracts.models import (
ContractOwnerModel,
LegalEntityModel,
IndividualModel,
)
from django.utils.translation import gettext as _
from django.db import transaction
# from core.apps.contracts.serializers.attached_files import (
# BaseContractAttachedFileSerializer,
# )
# from core.apps.contracts.serializers.file_contents import (
# BaseContractFileContentSerializer
# )
#! TODO fix: BaseContractOwnerSerializer (.create/.update) fix
###########################################################
# Base Serializers
###########################################################
class BaseIndividualSerializer(serializers.ModelSerializer):
class Meta:
model = IndividualModel
@@ -25,26 +22,7 @@ class BaseIndividualSerializer(serializers.ModelSerializer):
"id",
"created_at",
"updated_at",
)
extra_kwargs = {
"iin_code": {
"required": False
},
"person_code": {
"required": False
}
}
class ListIndividualSerializer(BaseIndividualSerializer):
class Meta(BaseIndividualSerializer.Meta):
fields = (
"id",
"full_name",
"phone",
"created_at",
"updated_at",
"owner",
)
@@ -56,26 +34,7 @@ class BaseLegalEntitySerializer(serializers.ModelSerializer):
"id",
"created_at",
"updated_at",
)
extra_kwargs = {
"bin_code": {
"required": False
},
"identifier": {
"required": False
}
}
class ListLegalEntitySerializer(BaseLegalEntitySerializer):
class Meta(BaseLegalEntitySerializer.Meta):
fields = (
"id",
"name",
"phone",
"created_at",
"updated_at",
"owner",
)
@@ -92,62 +51,35 @@ class BaseContractOwnerSerializer(serializers.ModelSerializer):
"updated_at",
)
extra_kwargs = {
"legal_entity": {
"required": False
},
"individual": {
"required": False
}
'legal_entity': {'required': False, 'allow_null': True},
'individual': {'required': False, 'allow_null': True},
}
def create(self, validated_data):
legal_entity_data = validated_data.pop("legal_entity", None)
individual_data = validated_data.pop("individual", None)
with transaction.atomic():
if legal_entity_data is not None:
legal_entity_serializer = BaseLegalEntitySerializer(data=legal_entity_data)
legal_entity_serializer.is_valid(raise_exception=True)
validated_data["legal_entity"] = legal_entity_serializer.save()
###########################################################
# List Serializers
###########################################################
class ListIndividualSerializer(BaseIndividualSerializer):
class Meta(BaseIndividualSerializer.Meta):
fields = (
"id",
"full_name",
"phone",
"created_at",
"updated_at",
)
if individual_data is not None:
individual_serializer = BaseIndividualSerializer(data=individual_data)
individual_serializer.is_valid(raise_exception=True)
validated_data["individual"] = individual_serializer.save()
contract_owner = ContractOwnerModel.objects.create(**validated_data)
return contract_owner
def update(self, instance, validated_data):
legal_entity_data = validated_data.pop("legal_entity", None)
individual_data = validated_data.pop("individual", None)
class ListLegalEntitySerializer(BaseLegalEntitySerializer):
class Meta(BaseLegalEntitySerializer.Meta):
fields = (
"id",
"name",
"phone",
"created_at",
"updated_at",
)
with transaction.atomic():
if legal_entity_data is not None:
if instance.legal_entity:
for attr, value in legal_entity_data.items():
setattr(instance.legal_entity, attr, value)
instance.legal_entity.save()
else:
legal_entity = LegalEntityModel.objects.create(**legal_entity_data)
instance.legal_entity = legal_entity
if individual_data is not None:
if instance.individual:
for attr, value in individual_data.items():
setattr(instance.individual, attr, value)
instance.individual.save()
else:
individual = IndividualModel.objects.create(**individual_data)
instance.individual = individual
# Update ContractOwnerModel fields
for attr, value in validated_data.items():
setattr(instance, attr, value)
instance.save()
return instance
class ListContractOwnerSerializer(BaseContractOwnerSerializer):
legal_entity = ListLegalEntitySerializer(read_only=True)
@@ -156,19 +88,125 @@ class ListContractOwnerSerializer(BaseContractOwnerSerializer):
class Meta(BaseContractOwnerSerializer.Meta): ...
###########################################################
# Detail/Retrieve Serializers
###########################################################
class RetrieveContractOwnerSerializer(BaseContractOwnerSerializer):
class Meta(BaseContractOwnerSerializer.Meta): ...
class CreateContractOwnerSerializer(BaseContractOwnerSerializer):
class Meta(BaseContractOwnerSerializer.Meta): ...
###########################################################
# Update Serializers
###########################################################
class UpdateIndividualSeriailzer(BaseIndividualSerializer):
class Meta(BaseIndividualSerializer.Meta): ...
class UpdateLegalEntitySerializer(BaseLegalEntitySerializer):
class Meta(BaseLegalEntitySerializer.Meta): ...
class UpdateContractOwnerSerializer(BaseContractOwnerSerializer):
individual = UpdateIndividualSeriailzer(required=False, partial=True)
legal_entity = UpdateLegalEntitySerializer(required=False, partial=True)
class Meta(BaseContractOwnerSerializer.Meta): ...
def update(self, instance: Meta.model, validated_data: dict[str, object]):
individual_data = validated_data.pop("individual", None)
legal_entity_data = validated_data.pop("legal_entity", None)
if instance.individual is not None:
if individual_data is not None:
individual_serializer = UpdateIndividualSeriailzer(
instance=instance.individual,
data=individual_data,
partial=True,
)
individual_serializer.is_valid(raise_exception=True)
individual_serializer.save() # type: ignore
elif instance.legal_entity is not None:
if legal_entity_data is not None:
legal_entity_serializer = UpdateLegalEntitySerializer(
instance=instance.legal_entity,
data=legal_entity_data,
partial=True
)
legal_entity_serializer.is_valid(raise_exception=True)
legal_entity_serializer.save() # type: ignore
return super().update(instance, validated_data) # type: ignore
###########################################################
# Delete/Destroy Serializers
###########################################################
class DestroyContractOwnerSerializer(BaseContractOwnerSerializer):
class Meta(BaseContractOwnerSerializer.Meta):
fields = ["id"]
###########################################################
# Create Serializers
###########################################################
class CreateIndividualSerializer(BaseIndividualSerializer):
class Meta(BaseIndividualSerializer.Meta): ...
class CreateLegalEntitySerializer(BaseLegalEntitySerializer):
class Meta(BaseLegalEntitySerializer.Meta): ...
class CreateContractOwnerSerializer(BaseContractOwnerSerializer): #! TODO: problem: individual or legal entity can not be null
individual = CreateIndividualSerializer(required=False, allow_null=True, default=None)
legal_entity = CreateLegalEntitySerializer(required=False, allow_null=True, default=None)
class Meta(BaseContractOwnerSerializer.Meta):
read_only_fields = (
*BaseContractOwnerSerializer.Meta.read_only_fields,
"status"
)
def create(self, validated_data: dict[str, object]) -> Meta.model:
individual_data = validated_data.pop("individual", None)
legal_entity_data = validated_data.pop("legal_entity", None)
with transaction.atomic():
if individual_data is not None:
individual_serializer = CreateIndividualSerializer(data=individual_data)
individual_serializer.is_valid(raise_exception=True)
validated_data["individual"] = individual_serializer.save() # type: ignore
if legal_entity_data is not None:
legal_entity_serializer = CreateLegalEntitySerializer(data=legal_entity_data)
legal_entity_serializer.is_valid(raise_exception=True)
validated_data["legal_entity"] = legal_entity_serializer.save() # type: ignore
owner = self.Meta.model(**validated_data)
owner.save()
return owner
def to_internal_value(self, data: dict[str, object]) -> dict[str, object]:
data = data.copy()
if "legal_entity" in data and data["legal_entity"] in [None, ""]:
data["legal_entity"] = None
if "individual" in data and data["individual"] in [None, ""]:
data["individual"] = None
return super().to_internal_value(data) # type: ignore
def validate(self, attrs: dict[str, object]):
legal = attrs.get("legal_entity")
individual = attrs.get("individual")
# Optional: enforce at least one must be provided
if not legal and not individual:
raise serializers.ValidationError(
"Either legal_entity or individual must be provided."
)
return attrs