from itertools import count from rest_framework.exceptions import ValidationError from apps.inm.models import FIFOItemProduct, IProduct, Inventory, MaterialBatch, FIFO, FIFOItem, WareHouse from apps.mtm.models import Material from apps.sam.models import SalePack, SaleProduct from django.db.models import Count from django.db.models.aggregates import Sum class InmService: @classmethod def update_inm(cls, instance:FIFO, type:int=1): """ 更新库存(正反) """ if instance.type in [FIFO.FIFO_TYPE_PUR_IN, FIFO.FIFO_TYPE_DO_IN]: # 采购入库, 生产入库 # 更新相关表 for i in FIFOItem.objects.filter(fifo=instance): material = i.material warehouse = i.warehouse o2, _ = MaterialBatch.objects.get_or_create(material=material, warehouse=warehouse, batch=i.batch,\ defaults={'material':material, 'warehouse':warehouse, 'count':0, 'batch':i.batch}) o2.count = o2.count + i.count o2.save() iv, _= Inventory.objects.get_or_create(material=material, warehouse=warehouse, \ defaults={'material':material, 'warehouse':warehouse, 'count':0}) iv.count = MaterialBatch.objects.filter(material=material, warehouse=warehouse).count() iv.save() material.count = MaterialBatch.objects.filter(material=material).count() material.save() # 创建IProduct ips2 = [] for m in FIFOItemProduct.objects.filter(fifoitem=i): ip = {} ip['warehouse'] = warehouse ip['batch'] = i.batch wp = m.wproduct ip['wproduct'] = wp ip['number'] = m.number ip['material'] = m.material ips2.append(IProduct(**ip)) IProduct.objects.bulk_create(ips2) # 如果是采购入库更新采购订单表 if instance.type == FIFO.FIFO_TYPE_PUR_IN: pu_order_item = i.pu_order_item delivered_count = pu_order_item.delivered_count + i.count if delivered_count > pu_order_item.count: raise ValidationError('超出采购订单所需量') pu_order_item.delivered_count = delivered_count pu_order_item.save() elif instance.type in [FIFO.FIFO_TYPE_DO_OUT, FIFO.FIFO_TYPE_SALE_OUT]: # 生产领料 销售出库 # 更新相关表 for i in FIFOItem.objects.filter(fifo=instance): material = i.material warehouse = i.warehouse mb = MaterialBatch.objects.get(material=material, warehouse=warehouse, batch=i.batch) temp_count = mb.count - i.count if temp_count < 0: raise ValidationError('批次库存不足,操作失败') mb.count = temp_count mb.save() iv = Inventory.objects.get(material=material, warehouse=warehouse) iv.count = MaterialBatch.objects.filter(material=material, warehouse=warehouse).count() iv.save() material.count = MaterialBatch.objects.filter(material=material).count() material.save() # 删除IProduct if instance.type == FIFO.FIFO_TYPE_DO_OUT: # 生产领料的情况直接从IProduct中删除 numbers = FIFOItemProduct.objects.filter(fifoitem=i).values_list('number', flat=True) IProduct.objects.filter(number__in=numbers).delete() # 销售的话已经处理了 # elif instance.type == FIFO.FIFO_TYPE_SALE_OUT: # ips = FIFOItemProduct.objects.filter(fifoitem=i).values_list('iproduct', flat=True) # IProduct.objects.filter(id__in=ips).update(state=IProduct.SALED) @classmethod def sale_out_audit(cls, fifo:FIFO): sale = fifo.sale saleps = SaleProduct.objects.filter(sale=sale, packnum__isnull=True, remark__isnull=True) if saleps.exists(): raise ValidationError('存在未装箱的产品') # 创建出库条目 ips = IProduct.objects.filter(sale_iproduct__sale=sale, sale_iproduct__packnum__isnull=False) ips.update(state=IProduct.SALED) items = ips.values('warehouse', 'material', 'batch').annotate(total=Count('id')) for i in items: warehouse = WareHouse.objects.get(id=i['warehouse']) material = Material.objects.get(id=i['material']) fifoitem = FIFOItem() fifoitem.need_test = False fifoitem.warehouse = warehouse fifoitem.material = material fifoitem.count = i['total'] fifoitem.batch = i['batch'] fifoitem.fifo = fifo fifoitem.save() items_p = ips.filter(warehouse=warehouse, batch=i['batch']) ipxs = [] for i in items_p: # 创建出库明细半成品 ip = {} ip['fifoitem'] = fifoitem ip['number'] = i.number ip['material'] = i.material ip['iproduct'] = i ipxs.append(FIFOItemProduct(**ip)) FIFOItemProduct.objects.bulk_create(ipxs) # 装箱附件处理 # ml = SalePack.objects.filter(sale_product__iproduct = ips # ).values('packitem__material').annotate(count=Sum('count')) # for i in ml: # material = Material.objects.get(id=i['material']) # 更新动态产品表情况 from apps.wpm.models import WProduct WProduct.objects.filter(id__in=ips.values_list('wproduct', flat=True)).update( act_state=WProduct.WPR_ACT_STATE_SELLED) # 变更销售记录实际发货数 sale.count_real = ips.count() sale.save() # 变更订单状态 order = sale.order if order: order.delivered_count = IProduct.objects.filter(sale_iproduct__sale__order=order , sale_iproduct__packnum__isnull=False).count() order.save()