import datetime from django.core.cache import cache from django.db.models import Sum from django.utils import timezone from typing import Union from django.core.exceptions import ObjectDoesNotExist, MultipleObjectsReturned from rest_framework.exceptions import ParseError from apps.system.models import User from apps.inm.models import MIO, MIOItem, MIOItemA from apps.pm.models import Mtask from apps.mtm.models import Mgroup, Shift, Material, Route from .models import SfLog, SfLogExp, WMaterial, Mlog, Mlogb, Handover 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: action_list = [] mias = MIOItemA.objects.filter(mioitem=item) if mias.exists(): # 组合件入库 mias_list = list(mias.values_list('material', 'batch', 'rate')) for i in range(len(mias_list)): material, batch, rate = mias_list[i] new_count = rate * item.count # 假设 item.count 存在 action_list.append([material, batch, new_count]) else: action_list = [[item.material, item.batch, item.count]] for al in action_list: xmaterial, xbatch, xcount = al try: wm = WMaterial.objects.get( batch=xbatch, material=xmaterial, belong_dept=belong_dept) except ObjectDoesNotExist: raise ParseError('车间物料不存在!') except MultipleObjectsReturned: raise ParseError('存在多行车间物料!') new_count = wm.count - xcount if new_count > 0: wm.count = new_count wm.update_by = do_user wm.save() elif new_count == 0: pass else: raise ParseError('车间物料不足') def mlog_submit(mlog: Mlog, user: User, now: Union[datetime.datetime, None]): """ 生产日志提交后需要执行的操作 """ if mlog.submit_time is not None: # 说明已经做过操作了 return if now is None: now = timezone.now() belong_dept = mlog.mgroup.belong_dept material_out = mlog.material_out material_in = mlog.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: # 需要入车间库存 # 有多个产物的情况 if material_out.brothers and Mlogb.objects.filter(mlog=mlog).exists(): for item in Mlogb.objects.filter(mlog=mlog): wmaterial, _ = WMaterial.objects.get_or_create(batch=mlog.batch, material=item.material_out, belong_dept=belong_dept, defaults={ 'batch': mlog.batch, 'material': item.material_out, 'belong_dept': belong_dept }) wmaterial.count = wmaterial.count + item.count_ok wmaterial.save() else: 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() mlog.submit_time = now mlog.submit_user = user mlog.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.utask if utask and mtask.is_count_utask: res2 = Mtask.objects.filter(utask=utask, mgroup=mtask.mgroup).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 if Mtask.objects.filter(utask=utask).exclude(state=Mtask.MTASK_DONE).count() == 0: utask.state = Mtask.MTASK_DONE utask.save() def handover_submit(handover: Handover, user: User, now: Union[datetime.datetime, None]): """ 交接提交后需要执行的操作 """ if handover.submit_time is not None: return now = timezone.now() if handover.wm: wm = handover.wm count_x = wm.count - handover.count if count_x < 0: raise ParseError('车间库存不足!') else: wm.count = count_x wm.save() wm_to, _ = WMaterial.objects.get_or_create(batch=handover.batch, material=handover.material, belong_dept=handover.send_dept, defaults={ 'batch': handover.batch, 'material': handover.material, 'belong_dept': handover.send_dept }) wm_to.count = wm_to.count + handover.count wm_to.save() handover.submit_user = user handover.submit_time = now handover.save()