from decimal import Decimal from rest_framework import serializers from apps.utils.serializers import CustomModelSerializer from apps.utils.constants import EXCLUDE_FIELDS_DEPT, EXCLUDE_FIELDS_BASE, EXCLUDE_FIELDS from rest_framework.exceptions import ValidationError, ParseError from apps.pum.models import Supplier, PuPlan, PuPlanItem, PuOrder, PuOrderItem, SupplierAudit, QuotationApply, PuContract, PuContractRecord from apps.mtm.serializers import MaterialSerializer, MaterialSimpleSerializer from django.db import transaction from .services import PumService from apps.wf.serializers import TicketSimpleSerializer from apps.system.serializers import FileSerializer class SupplierSerializer(CustomModelSerializer): class Meta: model = Supplier fields = '__all__' read_only_fields = EXCLUDE_FIELDS_DEPT class PuPlanSerializer(CustomModelSerializer): class Meta: model = PuPlan fields = '__all__' read_only_fields = EXCLUDE_FIELDS_DEPT + ['state', 'submit_time', 'total_price'] def update(self, instance, validated_data): if instance.state != PuPlan.PUPLAN_CREATE: raise ValidationError('该状态下不可编辑') return super().update(instance, validated_data) class PuPlanItemSerializer(CustomModelSerializer): material_ = MaterialSerializer(source='material', read_only=True) pu_plan_number = serializers.CharField( source='pu_plan.number', read_only=True) create_by_name = serializers.CharField( source='create_by.name', read_only=True) belong_dept_name = serializers.CharField( source='belong_dept.name', read_only=True) note = serializers.CharField(required=False, allow_blank=True) class Meta: model = PuPlanItem fields = '__all__' read_only_fields = EXCLUDE_FIELDS + ['pu_order'] def create(self, validated_data): pu_plan = validated_data['pu_plan'] if pu_plan.state != PuPlan.PUPLAN_CREATE: raise ValidationError('该状态下不可添加需求') material = validated_data['material'] self.complete_belong_dept(validated_data) if PuPlanItem.objects.filter(material=material, belong_dept=validated_data['belong_dept']).exists(): raise ValidationError('同部门已提交该物料需求,请确认!') ins = super().create(validated_data) PumService.cal_pu_plan_total_price(pu_plan) return ins def complete_belong_dept(self, validated_data): belong_dept = validated_data.get('belong_dept', None) if belong_dept is None: belong_dept = self.context['request'].user.belong_dept if belong_dept is None: raise ValidationError('所属部门不可为空') else: validated_data['belong_dept'] = belong_dept def update(self, instance, validated_data): validated_data.pop('pu_plan') pu_plan = instance.pu_plan if pu_plan.state != PuPlan.PUPLAN_CREATE: raise ValidationError('该状态下不可编辑需求') material = validated_data['material'] user = self.context['request'].user if instance.create_by != user: raise ValidationError('非创建人不可编辑') self.complete_belong_dept(validated_data) if PuPlanItem.objects.exclude(id=instance.id).filter(material=material, belong_dept=validated_data['belong_dept']).exists(): raise ValidationError('同部门已提交该物料需求,请确认!') ins = super().update(instance, validated_data) PumService.cal_pu_plan_total_price(pu_plan) return ins class PuOrderSerializer(CustomModelSerializer): supplier_name = serializers.CharField( source='supplier.name', read_only=True) create_by_name = serializers.CharField( source='create_by.name', read_only=True) update_by_name = serializers.CharField( source='update_by.name', read_only=True) materials_ = MaterialSimpleSerializer( source='materials', many=True, read_only=True) class Meta: model = PuOrder fields = '__all__' read_only_fields = EXCLUDE_FIELDS_DEPT + ['state', 'submit_time', 'total_price'] def validate(self, attrs): contract = attrs.get('contract', None) if contract: attrs['supplier'] = contract.supplier if attrs.get('supplier', None) is None: raise ValidationError('未选择供应商') return attrs def update(self, instance, validated_data): validated_data.pop('supplier') if instance.state != PuOrder.PUORDER_CREATE: raise ValidationError('该状态下不可编辑') return super().update(instance, validated_data) class PuOrderItemSerializer(CustomModelSerializer): material_ = MaterialSerializer(source='material', read_only=True) class Meta: model = PuOrderItem fields = '__all__' read_only_fields = EXCLUDE_FIELDS_BASE + ['delivered_count'] def create(self, validated_data): pu_order = validated_data['pu_order'] material = validated_data['material'] if pu_order.state != PuOrder.PUORDER_CREATE: raise ValidationError('采购订单该状态下不可添加明细') if PuOrderItem.objects.filter(pu_order=pu_order, material=material).exists(): raise ValidationError('该物料已添加') ins = super().create(validated_data) PumService.cal_pu_order_total_price(pu_order) return ins def update(self, instance, validated_data): validated_data.pop('material') validated_data.pop('pu_order') pu_order = instance.pu_order if pu_order.state != PuOrder.PUORDER_CREATE: raise ValidationError('采购订单该状态下不可编辑') ins = super().update(instance, validated_data) PumService.cal_pu_order_total_price(pu_order) return ins class AddSerializer(serializers.Serializer): pu_order = serializers.PrimaryKeyRelatedField( label='采购订单ID', queryset=PuOrder.objects.all()) pu_planitems = serializers.PrimaryKeyRelatedField( label='计划明细ID', queryset=PuPlanItem.objects.all(), many=True) class SupplierAuditSerializer(CustomModelSerializer): survery_form_ = FileSerializer(source="survery_form", read_only=True) business_license_ = FileSerializer(source="business_license", read_only=True) quality_certificate_ = FileSerializer(source="quality_certificate", read_only=True) ticket_ = TicketSimpleSerializer(source="ticket", read_only=True) class Meta: model = SupplierAudit fields = "__all__" read_only_fields = EXCLUDE_FIELDS_BASE + ['ticket'] def create(self, validated_data): name = validated_data["name"] if Supplier.objects.filter(name=name).exists(): raise ParseError('供应商名称已存在') return super().create(validated_data) class QuotationApplySerializer(CustomModelSerializer): ticket_ = TicketSimpleSerializer(source='ticket', read_only=True) class Meta: model = QuotationApply fields = "__all__" read_only_fields = EXCLUDE_FIELDS class PuContractSerializer(CustomModelSerializer): supplier_name = serializers.CharField(source='supplier.name', read_only=True) create_by_name = serializers.CharField(source='create_by.name', read_only=True) update_by_name = serializers.CharField(source='update_by.name', read_only=True) class Meta: model = PuContract fields = '__all__' read_only_fields = EXCLUDE_FIELDS + ['belong_dept', 'paid_amount', 'unpaid_amount', 'pay_progress', 'settlement_status'] class PuContractRecordSerializer(CustomModelSerializer): contract_number = serializers.CharField(source='contract.number', read_only=True) supplier_name = serializers.CharField(source='contract.supplier.name', read_only=True) class Meta: model = PuContractRecord fields = '__all__' read_only_fields = EXCLUDE_FIELDS + ['belong_dept'] def validate(self, attrs): contract = attrs.get('contract', getattr(self.instance, 'contract', None)) amount = attrs.get('amount', getattr(self.instance, 'amount', None)) if contract is None or amount is None: return attrs if contract.status == PuContract.STATUS_TERMINATED: raise ValidationError('合同已终止,不可操作付款流水') qs = PuContractRecord.objects.filter(contract=contract) if self.instance is not None: qs = qs.exclude(id=self.instance.id) total = sum((item.amount for item in qs), Decimal('0.00')) + amount if total > contract.contract_amount: raise ValidationError('累计付款金额不可超过合同金额') return attrs