from rest_framework import exceptions from rest_framework import serializers from apps.inm.models import FIFO, FIFOItem, FIFOItemProduct, IProduct, MaterialBatch, WareHouse, Inventory from apps.mtm.models import Material from apps.pum.models import PuOrder, Vendor from apps.qm.models import TestRecord, TestRecordItem from apps.sam.serializers import OrderSimpleSerializer from apps.system.serializers import FileSimpleSerializer, UserSimpleSerializer from apps.mtm.serializers import MaterialSimpleSerializer from django.db import transaction from utils.mixins import DynamicFieldsSerializerMixin from utils.tools import ranstr from rest_framework.exceptions import ValidationError class WareHouseSerializer(serializers.ModelSerializer): create_by_ = UserSimpleSerializer('create_by', read_only=True) class Meta: model = WareHouse fields = '__all__' class WareHouseCreateUpdateSerializer(serializers.ModelSerializer): class Meta: model = WareHouse fields = ['name', 'number', 'place'] class WareHouseSimpleSerializer(serializers.ModelSerializer): class Meta: model = WareHouse fields = ['name', 'number', 'place'] class InventorySerializer(serializers.ModelSerializer): material_ = MaterialSimpleSerializer(source='material', read_only=True) warehouse_ = WareHouseSimpleSerializer(source='warehouse', read_only=True) class Meta: model = Inventory fields = '__all__' class MaterialBatchSerializer(DynamicFieldsSerializerMixin, serializers.ModelSerializer): material_ = MaterialSimpleSerializer(source='material', read_only=True) warehouse_ = WareHouseSimpleSerializer(source='warehouse', read_only=True) class Meta: model = MaterialBatch fields = '__all__' class IProductListSerializer(DynamicFieldsSerializerMixin, serializers.ModelSerializer): material_ = MaterialSimpleSerializer(source='material', read_only=True) warehouse_ = WareHouseSimpleSerializer(source='warehouse', read_only=True) need_to_order = serializers.BooleanField(source='wproduct.need_to_order', read_only=True) is_mtestok = serializers.BooleanField(source='wproduct.is_mtestok', read_only=True) remark_mtest = serializers.CharField(source='wproduct.remark_mtest', read_only=True) to_order_ = OrderSimpleSerializer(source='wproduct.to_order', read_only=True) order_ = OrderSimpleSerializer( source='wproduct.subproduction_plan.production_plan.order', read_only=True) class Meta: model = IProduct fields = '__all__' class FIFOListSerializer(serializers.ModelSerializer): auditor_ = UserSimpleSerializer(source='auditor', read_only=True) create_by_ = UserSimpleSerializer(source='create_by', read_only=True) class Meta: model = FIFO fields = '__all__' class FIFOItemCreateSerializer(serializers.ModelSerializer): material_batch = serializers.PrimaryKeyRelatedField(queryset=MaterialBatch.objects.all(), label="物料批次ID", required=False) class Meta: model = FIFOItem fields = ['warehouse', 'material', 'batch', 'fifo', 'files', 'pu_order_item', 'count', 'expiration_date', 'material_batch'] def create(self, validated_data): fifo = validated_data['fifo'] if fifo.is_audited: raise ValidationError('该出入库记录已审核') pu_order_item = validated_data.get('pu_order_item', None) material_batch = validated_data.pop('material_batch', None) if fifo.type == FIFO.FIFO_TYPE_PUR_IN and pu_order_item is None: raise ValidationError('采购入库需关联采购项') else: if fifo.pu_order != pu_order_item.pu_order: raise ValidationError('项目与采购订单不一致') validated_data['material']=pu_order_item.material if fifo.type == FIFO.FIFO_TYPE_OTHER_OUT and material_batch is None: raise ValidationError('其他出库需关联批次号') if material_batch: validated_data['material'] = material_batch.material validated_data['batch'] = material_batch.batch validated_data['warehouse'] = material_batch.warehouse return super().create(validated_data) def validate_batch(self, value): if value == '': return value elif len(value) > 6: return value raise ValidationError('批次号错误') class FIFOItemUpdateSerializer(serializers.ModelSerializer): class Meta: model = FIFOItem fields = ['files', 'count', 'expiration_date'] class FIFOItemSerializer(serializers.ModelSerializer): warehouse_ = WareHouseSimpleSerializer(source='warehouse', read_only=True) material_ = MaterialSimpleSerializer(source='material', read_only=True) files_ = FileSimpleSerializer(source='files', many=True, read_only=True) test = serializers.PrimaryKeyRelatedField(source='test_fifoitem', read_only=True, many=True) class Meta: model = FIFOItem fields = '__all__' class FIFOItemProductCreateSerializer(serializers.ModelSerializer): class Meta: model = IProduct fields = ['number'] class FIFODetailInPurSerializer(serializers.ModelSerializer): details = FIFOItemProductCreateSerializer(many=True, required=False) class Meta: model = FIFOItem fields = ['material', 'count', 'batch', 'details', 'warehouse', 'expiration_date'] def validate_batch(self, value): if value == '': return value elif len(value) > 6: return value raise ValidationError('批次号错误') class MaterialBatchQuerySerializer(serializers.Serializer): warehouse = serializers.IntegerField(label="仓库ID", required=False) materials = serializers.ListField(child=serializers.IntegerField(label="物料ID"), required=False) class FIFODetailOutOtherSerializer(serializers.Serializer): material_batch = serializers.PrimaryKeyRelatedField(queryset=MaterialBatch.objects.all(), label="物料批次ID") count = serializers.IntegerField(label="数量", min_value=0) class FIFOOutOtherSerializer(serializers.ModelSerializer): """ 其他出库序列化 """ details = FIFODetailOutOtherSerializer(many=True, required=True) class Meta: model = FIFO fields = ['details'] def create(self, validated_data): details = validated_data.pop('details') with transaction.atomic(): validated_data['type'] = FIFO.FIFO_TYPE_OTHER_OUT validated_data['number'] = 'CK' + ranstr(7) obj = FIFO(**validated_data) obj.save() for i in details: mb = i.pop('material_batch') if mb.material.type in [Material.MA_TYPE_GOOD, Material.MA_TYPE_HALFGOOD]: raise ValidationError('不可直接出成品或半成品') i['material'] = mb.material i['batch'] = mb.batch i['warehouse'] = mb.warehouse i['fifo'] = obj FIFOItem.objects.create(**i) return obj class FIFOInOtherSerializer(serializers.ModelSerializer): """ 其他入库序列化 """ details = FIFODetailInPurSerializer(many=True, required=True) vendor = serializers.PrimaryKeyRelatedField(label='供应商ID', queryset=Vendor.objects.all()) class Meta: model = FIFO fields = ['details', 'vendor'] def create(self, validated_data): details = validated_data.pop('details') with transaction.atomic(): validated_data['type'] = FIFO.FIFO_TYPE_OTHER_IN validated_data['number'] = 'RK' + ranstr(7) obj = FIFO(**validated_data) obj.save() for i in details: if 'details' in i: p_details = i.pop('details') if len(p_details) != i['count']: raise serializers.ValidationError('数目对不上') else: i['fifo'] = obj fifoitem = FIFOItem.objects.create(**i) p_list0 = [] for x in p_details: x['material'] = i['material'] x['fifoitem'] = fifoitem p_list0.append(FIFOItemProduct(**x)) FIFOItemProduct.objects.bulk_create(p_list0) else: i['fifo'] = obj FIFOItem.objects.create(**i) return obj class FIFOInPurSerializer(serializers.ModelSerializer): """ 采购入库序列化 """ pu_order = serializers.PrimaryKeyRelatedField(label='采购订单ID', queryset = PuOrder.objects.filter(is_audited=True)) class Meta: model = FIFO fields = ['pu_order'] def create(self, validated_data): pu_order = validated_data['pu_order'] if not pu_order.is_audited: raise ValidationError('该采购订单未审核') validated_data['vendor'] = pu_order.vendor validated_data['number'] = 'RK' + ranstr(7) validated_data['type'] = FIFO.FIFO_TYPE_PUR_IN obj = FIFO.objects.create(**validated_data) return obj class InmTestRecordItemCreateSerializer(serializers.ModelSerializer): class Meta: model = TestRecordItem fields = ['form_field', 'field_value', 'is_testok'] class InmTestRecordCreateSerializer(serializers.ModelSerializer): record_data = InmTestRecordItemCreateSerializer(many=True) fifo_item = serializers.PrimaryKeyRelatedField(queryset=FIFOItem.objects.all(), required=True) is_testok = serializers.BooleanField() class Meta: model = TestRecord fields = ['form', 'record_data', 'is_testok', 'fifo_item'] class FIFOItemUpdateSerializer(serializers.ModelSerializer): class Meta: model = FIFOItem fields = ['need_test', 'files'] def validate(self, attrs): ins = self.instance fifo = ins.fifo if fifo.is_audited: raise exceptions.APIException('该记录已审核') if ins.is_testok is not None: attrs.pop('need_test') return super().validate(attrs)