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()