hberp/hb_server/apps/inm/services.py

147 lines
6.7 KiB
Python

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
import logging
logger = logging.getLogger('log')
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, FIFO.FIFO_TYPE_OTHER_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
if o2.expiration_date is None:
o2.expiration_date = i.expiration_date
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).aggregate(total=Sum('count')).get('total', 0)
iv.save()
material.count = MaterialBatch.objects.filter(material=material).aggregate(total=Sum('count')).get('total', 0)
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, FIFO.FIFO_TYPE_OTHER_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).aggregate(total=Sum('count')).get('total', 0)
iv.save()
material.count = MaterialBatch.objects.filter(material=
material).aggregate(total=Sum('count')).get('total', 0)
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()