from rest_framework import serializers, exceptions from rest_framework.serializers import ModelSerializer from apps.inm.models import FIFO, FIFOItem, FIFOItemProduct, IProduct, MaterialBatch, WareHouse from apps.inm.signals import update_inm from apps.mtm.models import Material, RecordForm, Step, SubprodctionMaterial from apps.mtm.serializers import MaterialSimpleSerializer, StepSimpleSerializer from apps.pm.models import SubProductionPlan, SubProductionProgress from django.utils import timezone from django.utils.translation import gettext_lazy as _ from apps.pm.serializers import SubproductionPlanSimpleSerializer from apps.qm.models import TestRecord, TestRecordItem from apps.system.serializers import UserSimpleSerializer from apps.wpm.models import Operation, OperationWproduct, WMaterial, WProduct, OperationRecord, OperationRecordItem from django.db import transaction class PickHalfSerializer(serializers.Serializer): id = serializers.PrimaryKeyRelatedField(queryset=SubProductionProgress.objects.all(), label='子计划进度ID') wproducts = serializers.ListField(child=serializers.PrimaryKeyRelatedField(queryset=WProduct.objects.all(), label='半成品ID'), required=False) # 从半成品表里直接修改状态 class PickDetailSerializer(serializers.Serializer): material = serializers.PrimaryKeyRelatedField(queryset=Material.objects.all(), label="物料ID") batch = serializers.CharField(label='物料批次', allow_blank=True) warehouse = serializers.PrimaryKeyRelatedField(queryset=WareHouse.objects.all(), label="仓库ID") pick_count = serializers.IntegerField(label="领料数量", required=False) iproducts = serializers.ListField(child=serializers.PrimaryKeyRelatedField(queryset=IProduct.objects.all(), label='库存半成品ID'), required=False) class PickSerializer(serializers.Serializer): subproduction_plan=serializers.PrimaryKeyRelatedField(queryset=SubProductionPlan.objects.all(), label="子计划ID") picks = PickDetailSerializer(many=True) # 从库存里拿 def create(self, validated_data): picks = validated_data.pop('picks') sp = validated_data.pop('subproduction_plan') if sp.state not in [SubProductionPlan.SUBPLAN_STATE_ASSGINED, SubProductionPlan.SUBPLAN_STATE_ACCEPTED, SubProductionPlan.SUBPLAN_STATE_WORKING]: raise exceptions.ValidationError('该子计划状态错误') # if sp.is_picked: # raise exceptions.ValidationError('该子计划已领料') # for i in picks: # try: # instance = MaterialBatch.objects.get(material=i['material'], batch=i['batch']) # if instance.count < i['pick_count']: # raise exceptions.ValidationError('物料不足') # except: # raise exceptions.ValidationError('物料不存在') # 创建出库记录 with transaction.atomic(): fifo = FIFO.objects.create(type=FIFO.FIFO_TYPE_DO_OUT, inout_date=timezone.now(), create_by=self.context['request'].user) for i in picks: isLowLevel = False # 更新出库详情 i['count'] = i.pop('pick_count', 0) # 是否勾选每一个 if 'iproducts' in i and len(i['iproducts'])>0: i['count'] = len(i['iproducts']) isLowLevel = True if i['count']>0: if isLowLevel: iproducts = i.pop('iproducts') i['fifo'] = fifo i['is_testok'] = True # 默认检测合格 i['subproduction_plan'] = sp fifoitem = FIFOItem.objects.create(**i) # 创建再下一个层级 if isLowLevel: mls = [] for m in iproducts: ml = {} ml['material'] = m.material ml['number'] = m.number ml['wproduct'] = m.wproduct ml['fifoitem'] = fifoitem mls.append(FIFOItemProduct(**ml)) FIFOItemProduct.objects.bulk_create(mls) # 更新车间物料 wm, _ = WMaterial.objects.get_or_create(material=i['material'], batch=i['batch'], \ subproduction_plan=sp,defaults={ 'material':i['material'], 'batch':i['batch'], 'subproduction_plan':sp, 'count':0 }) wm.count = wm.count + i['count'] wm.save() # 更新子计划物料情况 spp = SubProductionProgress.objects.get(material=i['material'], subproduction_plan=sp, type=SubprodctionMaterial.SUB_MA_TYPE_IN) spp.count_pick = spp.count_pick + i['count'] spp.save() if spp.count_pick > spp.count: raise exceptions.APIException('超过计划需求数') if isLowLevel: # 更新半成品表 wids = IProduct.objects.filter(pk__in=[x.id for x in iproducts]).values_list('wproduct', flat=True) wproducts = WProduct.objects.filter(pk__in=wids) first_step = Step.objects.get(pk=sp.steps[0]['id']) wproducts.update(step=first_step, is_executed=False, act_state=WProduct.WPR_ACT_STATE_DOING, is_hidden=False, warehouse=None, subproduction_plan=sp, production_plan=sp.production_plan) sp.is_picked=True sp.state = SubProductionPlan.SUBPLAN_STATE_WORKING #生产中 sp.state_date_real = timezone.now() #实际开工日期 sp.save() # 更新库存 fifo.is_audited = True fifo.save() update_inm(fifo) return fifo class WMaterialListSerializer(serializers.ModelSerializer): """ 车间物料 """ material_ = MaterialSimpleSerializer(source='material', read_only=True) class Meta: model = WMaterial fields = '__all__' class WProductListSerializer(serializers.ModelSerializer): """ 半成品列表 """ material_ = MaterialSimpleSerializer(source='material', read_only=True) step_ = StepSimpleSerializer(source='step', read_only=True) class Meta: model = WProduct fields = '__all__' class OperationDetailSerializer(serializers.ModelSerializer): create_by_ = UserSimpleSerializer(source='create_by', read_only=True) step_ = StepSimpleSerializer(source='step', read_only=True) class Meta: model = Operation fields = '__all__' class OperationListSerializer(serializers.ModelSerializer): create_by_ = UserSimpleSerializer(source='create_by', read_only=True) step_ = StepSimpleSerializer(source='step', read_only=True) class Meta: model = Operation fields = '__all__' class OperationCreateSerializer(serializers.Serializer): """ 操作创建 """ step = serializers.PrimaryKeyRelatedField(queryset=Step.objects.all(), label="子工序ID") # subproduction_plan = serializers.PrimaryKeyRelatedField(queryset=SubProductionPlan.objects.all(), label="子计划ID", required=False) wproducts = serializers.ListField(child= serializers.PrimaryKeyRelatedField(queryset=WProduct.objects.all()), label="半成品ID列表", required=False) def validate(self, data): # subproduction_plan = data['subproduction_plan'] step = data['step'] # stepIds=[i['id'] for i in subproduction_plan.steps] # if step.id not in stepIds: # raise exceptions.ValidationError('请选择正确的子工序操作') if 'wproducts' in data and data['wproducts']: if step.type == Step.STEP_TYPE_DIV: raise exceptions.ValidationError(_('不可进行此操作')) for i in data['wproducts']: if i.is_executed: raise exceptions.ValidationError('不可进行操作') # if i.subproduction_plan != subproduction_plan: # raise exceptions.ValidationError('半成品所属子计划不一致') if i.step != step: raise exceptions.ValidationError('半成品所属子工序不一致') else: if step.type != Step.STEP_TYPE_DIV: raise exceptions.ValidationError(_('请选择半成品进行操作')) return data class OperationInitSerializer(serializers.Serializer): step = serializers.PrimaryKeyRelatedField(queryset=Step.objects.all(), label="子工序ID") subproduction_plan = serializers.PrimaryKeyRelatedField(queryset=SubProductionPlan.objects.all(), label="子计划ID", required=False) wproducts = serializers.ListField(child= serializers.PrimaryKeyRelatedField(queryset=WProduct.objects.all()), label="半成品ID列表", required=False) def validate(self, data): # subproduction_plan = data['subproduction_plan'] step = data['step'] # stepIds=[i['id'] for i in subproduction_plan.steps] # if step.id not in stepIds: # raise exceptions.ValidationError('请选择正确的子工序操作') if 'wproducts' in data and data['wproducts']: if step.type == Step.STEP_TYPE_DIV: raise exceptions.ValidationError(_('不可进行此操作')) for i in data['wproducts']: if i.is_executed: raise exceptions.ValidationError('不可进行操作') # if i.subproduction_plan != subproduction_plan: # raise exceptions.ValidationError('半成品所属子计划不一致') if i.step != step: raise exceptions.ValidationError('半成品所属子工序不一致') else: if step.type != Step.STEP_TYPE_DIV: raise exceptions.ValidationError(_('请选择半成品进行操作')) return data class DoInputSerializer(serializers.Serializer): id = serializers.PrimaryKeyRelatedField(queryset=WMaterial.objects.all(), label='车间物料ID') count_input = serializers.IntegerField(min_value=0, label='消耗数量') class DoOutputSerializer(serializers.Serializer): subproduction_plan = serializers.PrimaryKeyRelatedField(queryset=SubProductionPlan.objects.all(), label="子计划ID", required=False) material = serializers.PrimaryKeyRelatedField(queryset=Material.objects.all(), label='物料ID') count_output = serializers.IntegerField(min_value=0, label='产出数量') class OperationRecordItemSerializer(serializers.ModelSerializer): class Meta: model = OperationRecordItem fields = ['form_field', 'field_value'] class OperationRecordSerializer(serializers.ModelSerializer): record_data = OperationRecordItemSerializer(many=True) class Meta: model = OperationRecord fields = ['form', 'record_data'] class OperationWproductListSerializer(serializers.ModelSerializer): material_ = MaterialSimpleSerializer(source='material', read_only=True) subproduction_plan_ = SubproductionPlanSimpleSerializer(source='subproduction_plan', read_only=True) class Meta: model = OperationWproduct fields = '__all__' class OperationSubmitSerializer(serializers.Serializer): step = serializers.PrimaryKeyRelatedField(queryset=Step.objects.all(), label="子工序ID") subproduction_plan = serializers.PrimaryKeyRelatedField(queryset=SubProductionPlan.objects.all(), label="子计划ID", required=False) wproducts = serializers.ListField(child= serializers.PrimaryKeyRelatedField(queryset=WProduct.objects.all()), label="半成品ID列表", required=False) input = DoInputSerializer(many=True, required=False) output = DoOutputSerializer(many=True, required=False) forms = OperationRecordSerializer(many=True, required=False) remark = serializers.CharField(required=False, label='操作备注', allow_blank=True, allow_null=True) use_scrap = serializers.BooleanField(required=False, default=False) class WpmTestRecordItemCreateSerializer(serializers.ModelSerializer): class Meta: model = TestRecordItem fields = ['form_field', 'field_value', 'is_testok'] class WpmTestRecordCreateSerializer(serializers.ModelSerializer): record_data = WpmTestRecordItemCreateSerializer(many=True) wproduct = serializers.PrimaryKeyRelatedField(queryset=WProduct.objects.all(), required=True) is_testok = serializers.BooleanField(required=False) class Meta: model = TestRecord fields = ['form', 'record_data', 'is_testok', 'wproduct'] class WproductPutInSerializer(serializers.Serializer): """ 半成品入库序列化 """ class WplanPutInSerializer(serializers.Serializer): warehouse = serializers.PrimaryKeyRelatedField(queryset=WareHouse.objects.all(), label="仓库ID") remark = serializers.CharField(label="入库备注", required =False) class WproductPutInSerializer(serializers.Serializer): warehouse = serializers.PrimaryKeyRelatedField(queryset=WareHouse.objects.all(), label="仓库ID") remark = serializers.CharField(label="入库备注", required =False)