from rest_framework import serializers from rest_framework.exceptions import ValidationError, ParseError from apps.mtm.serializers import MaterialSerializer from apps.pum.models import PuOrder from apps.sam.models import Order from apps.system.models import Dept, User from apps.utils.constants import EXCLUDE_FIELDS_BASE, EXCLUDE_FIELDS_DEPT, EXCLUDE_FIELDS from apps.utils.serializers import CustomModelSerializer from .models import MIO, MaterialBatch, MIOItem, WareHouse, MIOItemA, MaterialBatchA from django.db import transaction class WareHourseSerializer(CustomModelSerializer): class Meta: model = WareHouse fields = '__all__' read_only_fields = EXCLUDE_FIELDS_DEPT class MaterialBatchAListSerializer(CustomModelSerializer): material_ = MaterialSerializer(source='material', read_only=True) class Meta: model = MaterialBatchA fields = ['material', 'batch', 'rate', 'mb', 'id', 'material_'] class MaterialBatchSerializer(CustomModelSerializer): warehouse_name = serializers.CharField( source='warehouse.name', read_only=True) material_name = serializers.CharField( source='material.name', read_only=True) material_ = MaterialSerializer(source='material', read_only=True) class Meta: model = MaterialBatch fields = '__all__' read_only_fields = EXCLUDE_FIELDS_BASE class MaterialBatchDetailSerializer(CustomModelSerializer): warehouse_name = serializers.CharField( source='warehouse.name', read_only=True) material_name = serializers.CharField( source='material.name', read_only=True) material_ = MaterialSerializer(source='material', read_only=True) assemb = MaterialBatchAListSerializer( source='a_mb', read_only=True, many=True) class Meta: model = MaterialBatch fields = '__all__' class MIOListSerializer(CustomModelSerializer): create_by_name = serializers.CharField( source='create_by.name', read_only=True) submit_user_name = serializers.CharField( source='submit_user.name', read_only=True) do_user_name = serializers.CharField( source='do_user.name', read_only=True) belong_dept_name = serializers.CharField( source='belong_dept.name', read_only=True) supplier_name = serializers.CharField( source='supplier.name', read_only=True) customer_name = serializers.CharField( source='customer.name', read_only=True) order_number = serializers.CharField(source='order.number', read_only=True) pu_order_number = serializers.CharField( source='pu_order.name', read_only=True) class Meta: model = MIO fields = '__all__' read_only_fields = EXCLUDE_FIELDS + \ ['state', 'submit_time', 'submit_user'] # def validate(self, attrs): # if 'pu_order' in attrs and attrs['pu_order']: # attrs['supplier'] = attrs['pu_order'].supplier # if attrs['pu_order'].belong_dept: # attrs['belong_dept'] = attrs['pu_order'].belong_dept # elif 'order' in attrs and attrs['order']: # attrs['customer'] = attrs['order'].customer # return super().validate(attrs) # def create(self, validated_data): # type = validated_data['type'] # if type == MIO.MIO_TYPE_PUR_IN: # pu_order = validated_data.get('pu_order', None) # if pu_order and pu_order.state in [PuOrder.PUORDER_SUBMITED, PuOrder.PUORDER_SHIP]: # pass # else: # raise ValidationError('该采购订单不可选') # return super().create(validated_data) # def update(self, instance, validated_data): # validated_data.pop('type') # return super().update(instance, validated_data) class MIOItemACreateSerializer(CustomModelSerializer): class Meta: model = MIOItem fields = ['material', 'batch'] class MIOItemCreateSerializer(CustomModelSerializer): assemb = MIOItemACreateSerializer( label='组合件信息', many=True, write_only=True, required=False) class Meta: model = MIOItem fields = ['mio', 'warehouse', 'material', 'batch', 'count', 'assemb'] def create(self, validated_data): mio = validated_data['mio'] material = validated_data['material'] if mio.state != MIO.MIO_CREATE: raise ValidationError('出入库记录非创建中不可新增') with transaction.atomic(): assemb = validated_data.pop('assemb', []) instance = super().create(validated_data) assemb_dict = {} for i in assemb: assemb_dict[i['material'].id] = i if material.is_assemb and '_in' in mio.type: # 仅入库且是组合件的时候需要填写下一级 components = material.components for k, v in components.items(): if k in assemb_dict: mia = assemb_dict[k] MIOItemA.objects.create( mioitem=instance, material=mia['material'], batch=mia['batch'], rate=v) else: raise ParseError('缺少组合件') return instance class MIOItemAListSerializer(CustomModelSerializer): material_ = MaterialSerializer(source='material', read_only=True) class Meta: model = MIOItemA fields = ['material', 'batch', 'rate', 'mioitem', 'id', 'material_'] class MIOItemSerializer(CustomModelSerializer): warehouse_name = serializers.CharField( source='warehouse.name', read_only=True) material_ = MaterialSerializer(source='material', read_only=True) assemb = MIOItemAListSerializer( source='a_mioitem', read_only=True, many=True) class Meta: model = MIOItem fields = '__all__' class MIODoSerializer(CustomModelSerializer): belong_dept = serializers.PrimaryKeyRelatedField( label="车间", queryset=Dept.objects.all(), required=True) do_user = serializers.PrimaryKeyRelatedField( label="执行人", queryset=User.objects.all(), required=True) note = serializers.CharField( required=False, allow_blank=True) class Meta: model = MIO fields = ['id', 'number', 'note', 'do_user', 'belong_dept', 'type', 'inout_date'] def create(self, validated_data): if validated_data['type'] not in [MIO.MIO_TYPE_DO_OUT, MIO.MIO_TYPE_DO_IN]: raise ValidationError('出入库类型错误') return super().create(validated_data) def update(self, instance, validated_data): validated_data.pop('type') return super().update(instance, validated_data) class MIOSaleSerializer(CustomModelSerializer): order = serializers.PrimaryKeyRelatedField( label="订单", queryset=Order.objects.all(), required=True) note = serializers.CharField( required=False, allow_blank=True) class Meta: model = MIO fields = ['id', 'number', 'note', 'order', 'inout_date'] def create(self, validated_data): validated_data['type'] = MIO.MIO_TYPE_SALE_OUT order = validated_data['order'] validated_data['customer'] = order.customer if order.belong_dept: validated_data['belong_dept'] = order.belong_dept return super().create(validated_data) def update(self, instance, validated_data): validated_data.pop('type') return super().update(instance, validated_data) class MIOPurSerializer(CustomModelSerializer): pu_order = serializers.PrimaryKeyRelatedField( label="采购订单", queryset=PuOrder.objects.all(), required=True) note = serializers.CharField( required=False, allow_blank=True) class Meta: model = MIO fields = ['id', 'number', 'note', 'pu_order', 'inout_date'] def create(self, validated_data): validated_data['type'] = MIO.MIO_TYPE_PUR_IN pu_order = validated_data['pu_order'] validated_data['supplier'] = pu_order.supplier if pu_order.belong_dept: validated_data['belong_dept'] = pu_order.belong_dept return super().create(validated_data) def update(self, instance, validated_data): validated_data.pop('type') return super().update(instance, validated_data) class MIOOtherSerializer(CustomModelSerializer): note = serializers.CharField( required=False, allow_blank=True) class Meta: model = MIO fields = ['id', 'number', 'note', 'supplier', 'customer', 'type', 'inout_date'] def create(self, validated_data): if validated_data['type'] not in [MIO.MIO_TYPE_OTHER_OUT, MIO.MIO_TYPE_OTHER_IN]: raise ValidationError('出入库类型错误') return super().create(validated_data) def update(self, instance, validated_data): validated_data.pop('type') return super().update(instance, validated_data)