factory/apps/wpm/services.py

160 lines
6.5 KiB
Python

import datetime
from django.core.cache import cache
from django.db.models import Sum
from django.utils.timezone import localtime
from django.core.exceptions import ObjectDoesNotExist, MultipleObjectsReturned
from rest_framework.exceptions import ParseError
from apps.inm.models import MIO, MIOItem
from apps.pm.models import Mtask
from apps.mtm.models import Mgroup, Shift, Material
from .models import SfLog, SfLogExp, WMaterial, Mlog
def make_sflogs(mgroup: Mgroup, start_date: datetime.date, end_date: datetime.date):
for shift in Shift.objects.all():
start_time_o = shift.start_time_o
end_time_o = shift.end_time_o
current_date = start_date
while current_date <= end_date:
start_time = datetime.datetime.combine(current_date, start_time_o)
end_time = datetime.datetime.combine(current_date, end_time_o)
if start_time > end_time:
start_time -= datetime.timedelta(days=1)
SfLog.objects.get_or_create(mgroup=mgroup, shift=shift, start_time=start_time, defaults={
"mgroup": mgroup,
"shift": shift,
"start_time": start_time,
"end_time": end_time,
"total_hour_now": 12
})
current_date = current_date + datetime.timedelta(days=1)
def get_pcoal_heat(year_s: int, month_s: int, day_s: int):
"""
获取煤粉热值
只有回转窑需要录入煤粉热值
"""
key = f'pgoal_val_{year_s}_{month_s}_{day_s}'
pcoal_heat = cache.get(key, None)
if pcoal_heat is not None:
return pcoal_heat
else:
try:
qs = SfLog.objects.get(end_time__year=year_s, end_time__month=month_s, end_time__day=day_s,
mgroup__name='回转窑', shift__name='白班')
if qs.pcoal_heat is None:
qs.pcoal_heat = 0
qs.save()
cache.set(f'pgoal_val_{year_s}_{month_s}_{day_s}', qs.pcoal_heat)
return qs.pcoal_heat
except Exception:
return 0
def do_out(mio: MIO):
"""
生产领料到车间
"""
belong_dept = mio.belong_dept
do_user = mio.do_user
mioitems = MIOItem.objects.filter(mio=mio)
for item in mioitems:
wm, new_create = WMaterial.objects.get_or_create(batch=item.batch, material=item.material,
belong_dept=belong_dept, defaults={
"batch": item.batch,
"material": item.material,
"count": item.count,
"create_by": do_user,
"belong_dept": belong_dept
})
if not new_create:
wm.count = wm.count + item.count
wm.update_by = do_user
wm.save()
def do_in(mio: MIO):
"""
生产入库
"""
belong_dept = mio.belong_dept
do_user = mio.do_user
mioitems = MIOItem.objects.filter(mio=mio)
for item in mioitems:
try:
wm = WMaterial.objects.get(
batch=item.batch, material=item.material, belong_dept=belong_dept)
except ObjectDoesNotExist:
raise ParseError('车间物料不存在!')
except MultipleObjectsReturned:
raise ParseError('存在多行车间物料!')
new_count = wm.count - item.count
if new_count > 0:
wm.count = new_count
wm.update_by = do_user
wm.save()
elif new_count == 0:
wm.delete()
else:
raise ParseError('车间物料不足')
def mlog_confirm(mlog: Mlog):
"""
生产日志创建后需要执行的操作
"""
mtask = mlog.mtask
belong_dept = mtask.mgroup.belong_dept
material_out = mtask.material_out
material_in = mtask.material_in
if material_in and material_in.is_hidden is False: # 需要进行车间库存管理
# 需要判断领用数是否合理
material_has_qs = WMaterial.objects.filter(
batch=mlog.batch, material=material_in, belong_dept=belong_dept)
count_x = material_has_qs.count()
if count_x == 1:
material_has = material_has_qs.first()
elif count_x == 0:
raise ParseError(f'{material_in.name}-{mlog.batch}-批次库存不存在!')
else:
raise ParseError(f'{material_in.name}-{mlog.batch}-存在多个相同批次!')
if mlog.count_use > material_has.count:
raise ParseError(f'{material_in.name}-{mlog.batch}-该批次车间库存不足!')
else:
material_has.count = material_has.count - mlog.count_use
material_has.save()
if material_out.is_hidden is False: # 需要入库
wmaterial, _ = WMaterial.objects.get_or_create(batch=mlog.batch, material=material_out, belong_dept=belong_dept, defaults={
'batch': mlog.batch, 'material': material_out, 'belong_dept': belong_dept
})
wmaterial.count = wmaterial.count + mlog.count_ok
wmaterial.save()
def update_mtask(mtask: Mtask):
from apps.pm.models import Utask
res = Mlog.objects.filter(mtask=mtask).aggregate(sum_count_real=Sum(
'count_real'), sum_count_ok=Sum('count_ok'), sum_count_notok=Sum('count_notok'))
mtask.count_real = res['sum_count_real'] if res['sum_count_real'] else 0
mtask.count_ok = res['sum_count_ok'] if res['sum_count_ok'] else 0
mtask.count_notok = res['sum_count_notok'] if res['sum_count_notok'] else 0
mtask.save()
utask = mtask
if utask and mtask.material_out == utask.material:
res2 = Mtask.objects.filter(utask=utask, material_out=utask.material_out).aggregate(sum_count_real=Sum(
'count_real'), sum_count_ok=Sum('count_ok'), sum_count_notok=Sum('count_notok'))
utask.count_real = res2['sum_count_real'] if res2['sum_count_real'] else 0
utask.count_ok = res2['sum_count_ok'] if res2['sum_count_ok'] else 0
utask.count_notok = res2['sum_count_notok'] if res2['sum_count_notok'] else 0
if utask.count_ok > 0 and utask.state == Utask.UTASK_ASSGINED:
utask.state = Utask.UTASK_WORKING
utask.save()
if Mtask.objects.filter(utask=utask).exclude(state=Mtask.MTASK_DONE).count() == 0:
utask.state = Mtask.MTASK_DONE
utask.save()