diff --git a/apps/wpm/services.py b/apps/wpm/services.py index 8309a8ea..b7f38915 100644 --- a/apps/wpm/services.py +++ b/apps/wpm/services.py @@ -190,57 +190,59 @@ def mlog_submit(mlog: Mlog, user: User, now: Union[datetime.datetime, None]): exclude_batchst_ids.append(target.id) BatchLog.g_create(source=source, target=target, mlog=mlog) - if material_in or is_fix: # 需要进行车间库存管理 - m_ins_list = [] - m_ins = Mlogb.objects.filter(mlog=mlog, material_in__isnull=False) - if m_ins.exists(): - m_ins = m_ins.filter(need_inout=True) - m_ins_list = [(mi.material_in, mi.batch if mi.batch else mi.batch, mi.count_use, None, mi) for mi in m_ins.all()] - for item in m_ins: - mbd_qs = MlogbDefect.get_defect_qs_from_mlogb(item) - for itemx in mbd_qs: - if itemx.defect: - m_ins_bl_list.append((item.material_in, item.batch, itemx.count, itemx.defect, item)) + # 消耗物料处理 + m_ins_list = [] + m_ins = Mlogb.objects.filter(mlog=mlog, material_in__isnull=False) + if m_ins.exists(): + m_ins = m_ins.filter(need_inout=True) + m_ins_list = [(mi.material_in, mi.batch if mi.batch else mi.batch, mi.count_use, None, mi) for mi in m_ins.all()] + for item in m_ins: + mbd_qs = MlogbDefect.get_defect_qs_from_mlogb(item) + for itemx in mbd_qs: + if itemx.defect: + m_ins_bl_list.append((item.material_in, item.batch, itemx.count, itemx.defect, item)) + else: + m_ins_list = [(material_in, mlog.batch, mlog.count_use, None, mlog)] + for mi in m_ins_list: + mi_ma, mi_batch, mi_count, defect, mlog_or_b = mi + if mi_ma is None: + continue + if mi_count <= 0: + raise ParseError('存在非正数!') + # 需要判断领用数是否合理 + # 优先使用工段库存 + if isinstance(mlog_or_b, Mlogb) and mlog_or_b.wm_in: + wm_qs = WMaterial.objects.filter(id=mlog_or_b.wm_in.id) else: - m_ins_list = [(material_in, mlog.batch, mlog.count_use, None, mlog)] - for mi in m_ins_list: - mi_ma, mi_batch, mi_count, defect, mlog_or_b = mi - if mi_count <= 0: - raise ParseError('存在非正数!') - # 需要判断领用数是否合理 - # 优先使用工段库存 - if isinstance(mlog_or_b, Mlogb) and mlog_or_b.wm_in: - wm_qs = WMaterial.objects.filter(id=mlog_or_b.wm_in.id) - else: - wm_qs = WMaterial.objects.filter(batch=mi_batch, material=mi_ma, mgroup=mgroup, state=WMaterial.WM_OK) - if not wm_qs.exists(): - wm_qs = WMaterial.objects.filter(batch=mi_batch, material=mi_ma, - belong_dept=belong_dept, mgroup=None, state=WMaterial.WM_OK) - count_x = wm_qs.count() - if count_x == 1: - wm = wm_qs.first() - elif count_x == 0: - raise ParseError( - f'{str(mi_ma)}-{mi_batch}-批次库存不存在!') - else: - raise ParseError( - f'{str(mi_ma)}-{mi_batch}-存在多个相同批次!') - - if mi_count > wm.count: - raise ParseError( - f'{str(mi_ma)}-{mi_batch}-该批次车间库存不足!') - else: - wm.count = wm.count - mi_count - wm.update_by = user - wm.save() - if mi_ma.tracking == Material.MA_TRACKING_SINGLE: - mlogbws = Mlogbw.objects.filter(mlogb=mlog_or_b) - if mlogbws.count() != mi_count: - raise ParseError("日志与明细数量不一致,操作失败") - for item in mlogbws: - if item.ftest: - raise ParseError("不支持消耗物料的检验") - Wpr.change_or_new(wpr=item.wpr, old_wm=wm) + wm_qs = WMaterial.objects.filter(batch=mi_batch, material=mi_ma, mgroup=mgroup, state=WMaterial.WM_OK) + if not wm_qs.exists(): + wm_qs = WMaterial.objects.filter(batch=mi_batch, material=mi_ma, + belong_dept=belong_dept, mgroup=None, state=WMaterial.WM_OK) + count_x = wm_qs.count() + if count_x == 1: + wm = wm_qs.first() + elif count_x == 0: + raise ParseError( + f'{str(mi_ma)}-{mi_batch}-批次库存不存在!') + else: + raise ParseError( + f'{str(mi_ma)}-{mi_batch}-存在多个相同批次!') + + if mi_count > wm.count: + raise ParseError( + f'{str(mi_ma)}-{mi_batch}-该批次车间库存不足!') + else: + wm.count = wm.count - mi_count + wm.update_by = user + wm.save() + if mi_ma.tracking == Material.MA_TRACKING_SINGLE: + mlogbws = Mlogbw.objects.filter(mlogb=mlog_or_b) + if mlogbws.count() != mi_count: + raise ParseError("日志与明细数量不一致,操作失败") + for item in mlogbws: + if item.ftest: + raise ParseError("不支持消耗物料的检验") + Wpr.change_or_new(wpr=item.wpr, old_wm=wm) # 针对加工前不良的暂时额外处理 if need_store_notok: @@ -261,114 +263,115 @@ def mlog_submit(mlog: Mlog, user: User, now: Union[datetime.datetime, None]): raise ParseError("加工前不良的物料暂不支持单件追踪") - if material_out or is_fix: # 需要入车间库存 - mlogb_out_qs = Mlogb.objects.filter(mlog=mlog, material_out__isnull=False) - stored_notok = need_store_notok - stored_mgroup = need_store_notok - if mlogb_out_qs.exists(): - mlogb_out_qs = mlogb_out_qs.filter(need_inout=True) - m_outs_list = [(mo.material_out, mo.batch if mo.batch else mlog.batch, mo.count_ok_full if mo.count_ok_full is not None else mo.count_ok, mlog.count_real_eweight, None, mo) for mo in mlogb_out_qs.all()] - if need_store_notok: - for item in mlogb_out_qs: - mbd_qs = MlogbDefect.get_defect_qs_from_mlogb(item) - if item.qct is not None or mbd_qs.exists(): - # if item.material_out.tracking == Material.MA_TRACKING_SINGLE: - # Mlogbw.cal_count_notok(item) - for itemx in mbd_qs: - m_outs_list.append((item.material_out, item.batch, itemx.count, 0, itemx.defect, item)) - # # 获取所有主要的不合格项/先暂时保留 - # bw_qs = Mlogbw.objects.filter(mlogb=item) - # defectIds= Ftest.objects.filter(mlogbw_ftest__in=bw_qs).exclude(defect_main=None).values_list("defect_main__id", flat=True).distinct() - # defects_map = {d.id: d for d in Defect.objects.filter(id__in=defectIds)} - # # 过滤并统计相关数据 - # filtered_bw_qs = bw_qs.filter( - # ftest__defect_main__id__in=defects_map.keys() - # ).values('ftest__defect_main__id').annotate(xcount=Count('id')) - # # 整理结果 - # for defect_data in filtered_bw_qs: - # defect_id = defect_data['ftest__defect_main__id'] - # xcount = defect_data['xcount'] - # if xcount > 0: - # defect = defects_map[defect_id] - # m_outs_list.append((item.material_out, item.batch, xcount, 0, defect, item)) - else: - for f in Mlogb._meta.fields: - if 'count_n_' in f.name and getattr(item, f.name) > 0: - notok_sign = f.name.replace('count_n_', '') - m_outs_list.append( (item.material_out, item.batch if item.batch else mlog.batch, getattr(item, f.name), mlog.count_real_eweight, notok_sign, item)) - stored_notok = True - # 这里有一个漏洞,在产出物为兄弟件的情况下,不合格品的数量是记录在mlog上的, - # 而不是mlogb上,以上的额外处理就没有效果了, 不过光子不记录不合格品 - else: - m_outs_list = [(material_out, mlog.batch, mlog.count_ok, mlog.count_real_eweight, None, mlog)] - # 一次填写的暂时不处理不合格品 - for mo in m_outs_list: - mo_ma, mo_batch, mo_count, mo_count_eweight, notok_sign_or_defect, mlog_or_b = mo - if mo_count < 0: - raise ParseError('存在负数!') - elif mo_count == 0: - continue - if is_fix: - wm_state = WMaterial.WM_REPAIRED - if mo_ma.id in can_matoutIds: - wm_state = WMaterial.WM_OK if notok_sign_or_defect is None or ( - isinstance(notok_sign_or_defect, Defect) and notok_sign_or_defect.okcate in [Defect.DEFECT_OK, Defect.DEFECT_OK_B] - ) else WMaterial.WM_NOTOK - else: - wm_state = WMaterial.WM_OK if notok_sign_or_defect is None or ( - isinstance(notok_sign_or_defect, Defect) and notok_sign_or_defect.okcate in [Defect.DEFECT_OK, Defect.DEFECT_OK_B] - ) else WMaterial.WM_NOTOK - lookup = {'batch': mo_batch, 'material': mo_ma, 'mgroup': None, - 'notok_sign': None, 'defect': None, 'state': wm_state} - if isinstance(notok_sign_or_defect, Defect): - lookup['defect'] = notok_sign_or_defect - elif notok_sign_or_defect is not None: - lookup['notok_sign'] = notok_sign_or_defect - if into_wm_mgroup: - lookup['mgroup'] = mgroup - stored_mgroup = True - else: - lookup['belong_dept'] = belong_dept - - wm, is_create2 = WMaterial.objects.get_or_create(**lookup, defaults={**lookup, "belong_dept": belong_dept}) - wm.count = wm.count + mo_count - wm.count_eweight = mo_count_eweight - wm.update_by = user - if supplier is not None: - wm.supplier = supplier - if is_create2: - wm.create_by = user - if isinstance(mlog_or_b, Mlog) and mlog_or_b.wm_in: - wm.batch_ofrom = mlog_or_b.wm_in.batch_ofrom - wm.material_ofrom = mlog_or_b.wm_in.material_ofrom - elif isinstance(mlog_or_b, Mlogb): - wm.batch_ofrom = mlog_or_b.batch_ofrom - wm.material_ofrom = mlog_or_b.material_ofrom - if isinstance(mlog_or_b, Mlogb): - if mlog_or_b.number_from and wm.number_from is not None and wm.number_from != mlog_or_b.number_from: - raise ParseError(f'{wm.batch}-该批号现有库存来源于个号{wm.number_from}') - wm.number_from = mlog_or_b.number_from - wm.save() - if mo_ma.tracking == Material.MA_TRACKING_SINGLE: - if notok_sign_or_defect: - mlogbws = Mlogbw.objects.filter(mlogb=mlog_or_b, ftest__is_ok=False, ftest__defect_main=notok_sign_or_defect) + mlogb_out_qs = Mlogb.objects.filter(mlog=mlog, material_out__isnull=False) + stored_notok = need_store_notok + stored_mgroup = need_store_notok + if mlogb_out_qs.exists(): + mlogb_out_qs = mlogb_out_qs.filter(need_inout=True) + m_outs_list = [(mo.material_out, mo.batch if mo.batch else mlog.batch, mo.count_ok_full if mo.count_ok_full is not None else mo.count_ok, mlog.count_real_eweight, None, mo) for mo in mlogb_out_qs.all()] + if need_store_notok: + for item in mlogb_out_qs: + mbd_qs = MlogbDefect.get_defect_qs_from_mlogb(item) + if item.qct is not None or mbd_qs.exists(): + # if item.material_out.tracking == Material.MA_TRACKING_SINGLE: + # Mlogbw.cal_count_notok(item) + for itemx in mbd_qs: + m_outs_list.append((item.material_out, item.batch, itemx.count, 0, itemx.defect, item)) + # # 获取所有主要的不合格项/先暂时保留 + # bw_qs = Mlogbw.objects.filter(mlogb=item) + # defectIds= Ftest.objects.filter(mlogbw_ftest__in=bw_qs).exclude(defect_main=None).values_list("defect_main__id", flat=True).distinct() + # defects_map = {d.id: d for d in Defect.objects.filter(id__in=defectIds)} + # # 过滤并统计相关数据 + # filtered_bw_qs = bw_qs.filter( + # ftest__defect_main__id__in=defects_map.keys() + # ).values('ftest__defect_main__id').annotate(xcount=Count('id')) + # # 整理结果 + # for defect_data in filtered_bw_qs: + # defect_id = defect_data['ftest__defect_main__id'] + # xcount = defect_data['xcount'] + # if xcount > 0: + # defect = defects_map[defect_id] + # m_outs_list.append((item.material_out, item.batch, xcount, 0, defect, item)) else: - mlogbws = Mlogbw.objects.filter(Q(ftest=None) | Q(ftest__is_ok=True), mlogb=mlog_or_b) - mlogbws_count = mlogbws.count() - if mlogbws_count != mo_count: - raise ParseError("日志与明细数量不一致,操作失败") - for item in mlogbws: - if item.wpr: - Wpr.change_or_new(wpr=item.wpr, wm=wm, ftest=item.ftest) - else: - wpr_from = None - if item.mlogbw_from: - wpr_from = item.mlogbw_from.wpr - wpr = Wpr.change_or_new(number=item.number, - wm=wm, ftest=item.ftest, - wpr_from=wpr_from) - item.wpr = wpr - item.save() + for f in Mlogb._meta.fields: + if 'count_n_' in f.name and getattr(item, f.name) > 0: + notok_sign = f.name.replace('count_n_', '') + m_outs_list.append( (item.material_out, item.batch if item.batch else mlog.batch, getattr(item, f.name), mlog.count_real_eweight, notok_sign, item)) + stored_notok = True + # 这里有一个漏洞,在产出物为兄弟件的情况下,不合格品的数量是记录在mlog上的, + # 而不是mlogb上,以上的额外处理就没有效果了, 不过光子不记录不合格品 + else: + m_outs_list = [(material_out, mlog.batch, mlog.count_ok, mlog.count_real_eweight, None, mlog)] + # 一次填写的暂时不处理不合格品 + for mo in m_outs_list: + mo_ma, mo_batch, mo_count, mo_count_eweight, notok_sign_or_defect, mlog_or_b = mo + if mo_ma is None: + continue + if mo_count < 0: + raise ParseError('存在负数!') + elif mo_count == 0: + continue + if is_fix: + wm_state = WMaterial.WM_REPAIRED + if mo_ma.id in can_matoutIds: + wm_state = WMaterial.WM_OK if notok_sign_or_defect is None or ( + isinstance(notok_sign_or_defect, Defect) and notok_sign_or_defect.okcate in [Defect.DEFECT_OK, Defect.DEFECT_OK_B] + ) else WMaterial.WM_NOTOK + else: + wm_state = WMaterial.WM_OK if notok_sign_or_defect is None or ( + isinstance(notok_sign_or_defect, Defect) and notok_sign_or_defect.okcate in [Defect.DEFECT_OK, Defect.DEFECT_OK_B] + ) else WMaterial.WM_NOTOK + lookup = {'batch': mo_batch, 'material': mo_ma, 'mgroup': None, + 'notok_sign': None, 'defect': None, 'state': wm_state} + if isinstance(notok_sign_or_defect, Defect): + lookup['defect'] = notok_sign_or_defect + elif notok_sign_or_defect is not None: + lookup['notok_sign'] = notok_sign_or_defect + if into_wm_mgroup: + lookup['mgroup'] = mgroup + stored_mgroup = True + else: + lookup['belong_dept'] = belong_dept + + wm, is_create2 = WMaterial.objects.get_or_create(**lookup, defaults={**lookup, "belong_dept": belong_dept}) + wm.count = wm.count + mo_count + wm.count_eweight = mo_count_eweight + wm.update_by = user + if supplier is not None: + wm.supplier = supplier + if is_create2: + wm.create_by = user + if isinstance(mlog_or_b, Mlog) and mlog_or_b.wm_in: + wm.batch_ofrom = mlog_or_b.wm_in.batch_ofrom + wm.material_ofrom = mlog_or_b.wm_in.material_ofrom + elif isinstance(mlog_or_b, Mlogb): + wm.batch_ofrom = mlog_or_b.batch_ofrom + wm.material_ofrom = mlog_or_b.material_ofrom + if isinstance(mlog_or_b, Mlogb): + if mlog_or_b.number_from and wm.number_from is not None and wm.number_from != mlog_or_b.number_from: + raise ParseError(f'{wm.batch}-该批号现有库存来源于个号{wm.number_from}') + wm.number_from = mlog_or_b.number_from + wm.save() + if mo_ma.tracking == Material.MA_TRACKING_SINGLE: + if notok_sign_or_defect: + mlogbws = Mlogbw.objects.filter(mlogb=mlog_or_b, ftest__is_ok=False, ftest__defect_main=notok_sign_or_defect) + else: + mlogbws = Mlogbw.objects.filter(Q(ftest=None) | Q(ftest__is_ok=True), mlogb=mlog_or_b) + mlogbws_count = mlogbws.count() + if mlogbws_count != mo_count: + raise ParseError("日志与明细数量不一致,操作失败") + for item in mlogbws: + if item.wpr: + Wpr.change_or_new(wpr=item.wpr, wm=wm, ftest=item.ftest) + else: + wpr_from = None + if item.mlogbw_from: + wpr_from = item.mlogbw_from.wpr + wpr = Wpr.change_or_new(number=item.number, + wm=wm, ftest=item.ftest, + wpr_from=wpr_from) + item.wpr = wpr + item.save() mlog.submit_time = now mlog.submit_user = user @@ -411,169 +414,171 @@ def mlog_revert(mlog: Mlog, user: User, now: Union[datetime.datetime, None]): if is_fix: can_matoutIds = process.get_canout_mat_ids() # 先回退产物 - if material_out or is_fix: # 产物退回 - # 有多个产物的情况 - # 需要考虑不合格品退回的情况 - mlogb_out_qs = Mlogb.objects.filter(mlog=mlog, material_out__isnull=False) - if mlogb_out_qs.exists(): - mlogb_out_qs = mlogb_out_qs.filter(need_inout=True) - m_outs_list = [ - (mo.material_out, mo.batch if mo.batch else mlog.batch, mo.count_ok_full if mo.count_ok_full is not None else mo.count_ok, mlog.count_real_eweight, None, mo) - for mo in mlogb_out_qs.all()] - if stored_notok: - for item in mlogb_out_qs: - mbd_qs = MlogbDefect.get_defect_qs_from_mlogb(item) - if item.qct is not None or mbd_qs.exists(): - # if item.material_out.tracking == Material.MA_TRACKING_SINGLE: - # Mlogbw.cal_count_notok(item) - for itemx in mbd_qs: - m_outs_list.append((item.material_out, item.batch, itemx.count, 0, itemx.defect, item)) + # 有多个产物的情况 + # 需要考虑不合格品退回的情况 + mlogb_out_qs = Mlogb.objects.filter(mlog=mlog, material_out__isnull=False) + if mlogb_out_qs.exists(): + mlogb_out_qs = mlogb_out_qs.filter(need_inout=True) + m_outs_list = [ + (mo.material_out, mo.batch if mo.batch else mlog.batch, mo.count_ok_full if mo.count_ok_full is not None else mo.count_ok, mlog.count_real_eweight, None, mo) + for mo in mlogb_out_qs.all()] + if stored_notok: + for item in mlogb_out_qs: + mbd_qs = MlogbDefect.get_defect_qs_from_mlogb(item) + if item.qct is not None or mbd_qs.exists(): # if item.material_out.tracking == Material.MA_TRACKING_SINGLE: - # # 获取所有主要的不合格项 - # bw_qs = Mlogbw.objects.filter(mlogb=item) - # defectIds= Ftest.objects.filter(mlogbw_ftest__in=bw_qs).exclude(defect_main=None).values_list("defect_main__id", flat=True).distinct() - # defects_map = {d.id: d for d in Defect.objects.filter(id__in=defectIds)} - # # 过滤并统计相关数据 - # filtered_bw_qs = bw_qs.filter( - # ftest__defect_main__id__in=defects_map.keys() - # ).values('ftest__defect_main__id').annotate(xcount=Count('id')) - # # 整理结果 - # for defect_data in filtered_bw_qs: - # defect_id = defect_data['ftest__defect_main__id'] - # xcount = defect_data['xcount'] - # if xcount > 0: - # defect = defects_map[defect_id] - # m_outs_list.append((item.material_out, item.batch, xcount, 0, defect, item)) - else: - for f in Mlogb._meta.fields: - if 'count_n_' in f.name and getattr(item, f.name) > 0: - notok_sign = f.name.replace('count_n_', '') - m_outs_list.append((item.material_out, item.batch if item.batch else mlog.batch, - getattr(item, f.name), mlog.count_real_eweight, notok_sign, item)) - else: - m_outs_list = [(material_out, mlog.batch, mlog.count_ok, mlog.count_real_eweight, None, mlog)] - # 一次填写的暂时不处理不合格品 + # Mlogbw.cal_count_notok(item) + for itemx in mbd_qs: + m_outs_list.append((item.material_out, item.batch, itemx.count, 0, itemx.defect, item)) + # if item.material_out.tracking == Material.MA_TRACKING_SINGLE: + # # 获取所有主要的不合格项 + # bw_qs = Mlogbw.objects.filter(mlogb=item) + # defectIds= Ftest.objects.filter(mlogbw_ftest__in=bw_qs).exclude(defect_main=None).values_list("defect_main__id", flat=True).distinct() + # defects_map = {d.id: d for d in Defect.objects.filter(id__in=defectIds)} + # # 过滤并统计相关数据 + # filtered_bw_qs = bw_qs.filter( + # ftest__defect_main__id__in=defects_map.keys() + # ).values('ftest__defect_main__id').annotate(xcount=Count('id')) + # # 整理结果 + # for defect_data in filtered_bw_qs: + # defect_id = defect_data['ftest__defect_main__id'] + # xcount = defect_data['xcount'] + # if xcount > 0: + # defect = defects_map[defect_id] + # m_outs_list.append((item.material_out, item.batch, xcount, 0, defect, item)) + else: + for f in Mlogb._meta.fields: + if 'count_n_' in f.name and getattr(item, f.name) > 0: + notok_sign = f.name.replace('count_n_', '') + m_outs_list.append((item.material_out, item.batch if item.batch else mlog.batch, + getattr(item, f.name), mlog.count_real_eweight, notok_sign, item)) + else: + m_outs_list = [(material_out, mlog.batch, mlog.count_ok, mlog.count_real_eweight, None, mlog)] + # 一次填写的暂时不处理不合格品 - for mo in m_outs_list: - mo_ma, mo_batch, mo_count, _, notok_sign_or_defect, mlog_or_b = mo - if mo_count < 0: - raise ParseError('存在负数!') - elif mo_count == 0: - continue - if is_fix: - wm_state = WMaterial.WM_REPAIRED - if mo_ma.id in can_matoutIds: - wm_state = WMaterial.WM_OK if notok_sign_or_defect is None or ( - isinstance(notok_sign_or_defect, Defect) and notok_sign_or_defect.okcate in [Defect.DEFECT_OK, Defect.DEFECT_OK_B] - ) else WMaterial.WM_NOTOK - else: + for mo in m_outs_list: + mo_ma, mo_batch, mo_count, _, notok_sign_or_defect, mlog_or_b = mo + if mo_ma is None: + continue + if mo_count < 0: + raise ParseError('存在负数!') + elif mo_count == 0: + continue + if is_fix: + wm_state = WMaterial.WM_REPAIRED + if mo_ma.id in can_matoutIds: wm_state = WMaterial.WM_OK if notok_sign_or_defect is None or ( - isinstance(notok_sign_or_defect, Defect) and notok_sign_or_defect.okcate in [Defect.DEFECT_OK, Defect.DEFECT_OK_B] - ) else WMaterial.WM_NOTOK - lookup = {'batch': mo_batch, 'material': mo_ma, 'mgroup': None, 'notok_sign': None, 'defect': None, 'state': wm_state} - if isinstance(notok_sign_or_defect, Defect): - lookup['defect'] = notok_sign_or_defect - else: - lookup['notok_sign'] = notok_sign_or_defect - if stored_mgroup: + isinstance(notok_sign_or_defect, Defect) and notok_sign_or_defect.okcate in [Defect.DEFECT_OK, Defect.DEFECT_OK_B] + ) else WMaterial.WM_NOTOK + else: + wm_state = WMaterial.WM_OK if notok_sign_or_defect is None or ( + isinstance(notok_sign_or_defect, Defect) and notok_sign_or_defect.okcate in [Defect.DEFECT_OK, Defect.DEFECT_OK_B] + ) else WMaterial.WM_NOTOK + lookup = {'batch': mo_batch, 'material': mo_ma, 'mgroup': None, 'notok_sign': None, 'defect': None, 'state': wm_state} + if isinstance(notok_sign_or_defect, Defect): + lookup['defect'] = notok_sign_or_defect + else: + lookup['notok_sign'] = notok_sign_or_defect + if stored_mgroup: + lookup['mgroup'] = mgroup + else: + lookup['belong_dept'] = belong_dept + wm_qs = WMaterial.objects.filter(**lookup) + count_x = wm_qs.count() + if count_x == 1: + wm = wm_qs.first() + elif count_x == 0: + raise ParseError( + f'{str(mo_ma)}-{mo_batch}-批次库存不存在!') + else: + raise ParseError( + f'{str(mo_ma)}-{mo_batch}-存在多个相同批次!') + wm.count = wm.count - mo_count + if wm.count < 0: + raise ParseError(f'{wm.batch} 车间库存不足, 产物无法回退') + elif wm.count >= 0: + if isinstance(mlog_or_b, Mlogb): + if mlog_or_b.number_from == wm.number_from: + wm.number_from = None + wm.update_by = user + wm.save() + if mo_ma.tracking == Material.MA_TRACKING_SINGLE: + if notok_sign_or_defect: + mlogbws = Mlogbw.objects.filter(mlogb=mlog_or_b, ftest__is_ok=False, ftest__defect_main=notok_sign_or_defect) + else: + mlogbws = Mlogbw.objects.filter(Q(ftest=None) | Q(ftest__is_ok=True), mlogb=mlog_or_b) + if mlogbws.count() != mo_count: + raise ParseError("日志与明细数量不一致,操作失败") + for item in mlogbws: + Wpr.change_or_new(wpr=item.wpr, old_wm=wm) + + # 再生成消耗 + m_ins_list = [] + m_ins_bl_list = [] + into_wm_mgroup = process.into_wm_mgroup + m_ins = Mlogb.objects.filter(mlog=mlog, material_in__isnull=False) + if m_ins.exists(): + m_ins = m_ins.filter(need_inout=True) + for mi in m_ins.all(): + m_ins_list.append((mi.material_in, mi.batch, mi.count_use, None, mi)) + for item in m_ins: + mbd_qs = MlogbDefect.get_defect_qs_from_mlogb(item) + for itemx in mbd_qs: + if itemx.defect: + m_ins_bl_list.append((item.material_in, item.batch, itemx.count, itemx.defect, item)) + else: + m_ins_list = [(material_in, mlog.batch, mlog.count_use, mlog.wm_in, mlog)] + for mi in m_ins_list: + mi_ma, mi_batch, mi_count, defect_or, mlog_or_b = mi + if mi_ma is None: + continue + if mi_count <= 0: + raise ParseError('存在非正数!') + if isinstance(mlog_or_b, Mlogb) and mlog_or_b.wm_in: + wm = WMaterial.objects.get(id=mlog_or_b.wm_in.id) + else: + # 针对光子的情况,实际上必须需要wm_in + lookup = {'batch': mi_batch, 'material': mi_ma, 'mgroup': None, 'state': WMaterial.WM_OK} + if into_wm_mgroup: + # 退回到本工段 lookup['mgroup'] = mgroup else: lookup['belong_dept'] = belong_dept - wm_qs = WMaterial.objects.filter(**lookup) - count_x = wm_qs.count() - if count_x == 1: - wm = wm_qs.first() - elif count_x == 0: - raise ParseError( - f'{str(mo_ma)}-{mo_batch}-批次库存不存在!') - else: - raise ParseError( - f'{str(mo_ma)}-{mo_batch}-存在多个相同批次!') - wm.count = wm.count - mo_count - if wm.count < 0: - raise ParseError(f'{wm.batch} 车间库存不足, 产物无法回退') - elif wm.count >= 0: - if isinstance(mlog_or_b, Mlogb): - if mlog_or_b.number_from == wm.number_from: - wm.number_from = None - wm.update_by = user - wm.save() - if mo_ma.tracking == Material.MA_TRACKING_SINGLE: - if notok_sign_or_defect: - mlogbws = Mlogbw.objects.filter(mlogb=mlog_or_b, ftest__is_ok=False, ftest__defect_main=notok_sign_or_defect) - else: - mlogbws = Mlogbw.objects.filter(Q(ftest=None) | Q(ftest__is_ok=True), mlogb=mlog_or_b) - if mlogbws.count() != mo_count: - raise ParseError("日志与明细数量不一致,操作失败") - for item in mlogbws: - Wpr.change_or_new(wpr=item.wpr, old_wm=wm) - # 再生成消耗 - if material_in or is_fix: # 领用数退回 - m_ins_list = [] - m_ins_bl_list = [] - into_wm_mgroup = process.into_wm_mgroup - m_ins = Mlogb.objects.filter(mlog=mlog, material_in__isnull=False) - if m_ins.exists(): - m_ins = m_ins.filter(need_inout=True) - for mi in m_ins.all(): - m_ins_list.append((mi.material_in, mi.batch, mi.count_use, None, mi)) - for item in m_ins: - mbd_qs = MlogbDefect.get_defect_qs_from_mlogb(item) - for itemx in mbd_qs: - if itemx.defect: - m_ins_bl_list.append((item.material_in, item.batch, itemx.count, itemx.defect, item)) - else: - m_ins_list = [(material_in, mlog.batch, mlog.count_use, mlog.wm_in, mlog)] - for mi in m_ins_list: - mi_ma, mi_batch, mi_count, defect_or, mlog_or_b = mi - if mi_count <= 0: + wm, _ = WMaterial.objects.get_or_create(**lookup, defaults={**lookup, "belong_dept": belong_dept}) + wm.count = wm.count + mi_count + wm.update_by = user + wm.save() + if mi_ma.tracking == Material.MA_TRACKING_SINGLE: + mlogbws = Mlogbw.objects.filter(mlogb=mlog_or_b) + if mlogbws.count() != mi_count: + raise ParseError("日志与明细数量不一致,操作失败") + for item in mlogbws: + # if item.wpr: + Wpr.change_or_new(wpr=item.wpr, wm=wm) + # else: + # wpr = Wpr.change_or_new(number=item.number, wm=wm) + # item.wpr = wpr + # item.save() + + # 针对加工前不良的暂时额外处理 + if stored_notok: + for item in m_ins_bl_list: + material, batch, count, defect, mi_ = item + if count <= 0: raise ParseError('存在非正数!') - if isinstance(mlog_or_b, Mlogb) and mlog_or_b.wm_in: - wm = WMaterial.objects.get(id=mlog_or_b.wm_in.id) + lookup = {'batch': batch, 'material': material, 'mgroup': mgroup, 'defect': defect, 'state': WMaterial.WM_NOTOK} + wm, is_create = WMaterial.objects.get_or_create(**lookup, defaults={**lookup, "belong_dept": belong_dept}) + wm.count = wm.count - count + if wm.count < 0: + raise ParseError('加工前不良数量大于库存量') + if is_create: + wm.create_by = user else: - # 针对光子的情况,实际上必须需要wm_in - lookup = {'batch': mi_batch, 'material': mi_ma, 'mgroup': None, 'state': WMaterial.WM_OK} - if into_wm_mgroup: - # 退回到本工段 - lookup['mgroup'] = mgroup - else: - lookup['belong_dept'] = belong_dept - - wm, _ = WMaterial.objects.get_or_create(**lookup, defaults={**lookup, "belong_dept": belong_dept}) - wm.count = wm.count + mi_count - wm.update_by = user + wm.update_by = user wm.save() - if mi_ma.tracking == Material.MA_TRACKING_SINGLE: - mlogbws = Mlogbw.objects.filter(mlogb=mlog_or_b) - if mlogbws.count() != mi_count: - raise ParseError("日志与明细数量不一致,操作失败") - for item in mlogbws: - # if item.wpr: - Wpr.change_or_new(wpr=item.wpr, wm=wm) - # else: - # wpr = Wpr.change_or_new(number=item.number, wm=wm) - # item.wpr = wpr - # item.save() - - # 针对加工前不良的暂时额外处理 - if stored_notok: - for item in m_ins_bl_list: - material, batch, count, defect, mi_ = item - if count <= 0: - raise ParseError('存在非正数!') - lookup = {'batch': batch, 'material': material, 'mgroup': mgroup, 'defect': defect, 'state': WMaterial.WM_NOTOK} - wm, is_create = WMaterial.objects.get_or_create(**lookup, defaults={**lookup, "belong_dept": belong_dept}) - wm.count = wm.count - count - if wm.count < 0: - raise ParseError('加工前不良数量大于库存量') - if is_create: - wm.create_by = user - else: - wm.update_by = user - wm.save() - if material.tracking == Material.MA_TRACKING_SINGLE: - raise ParseError("加工前不良的物料暂不支持单件回退") + if material.tracking == Material.MA_TRACKING_SINGLE: + raise ParseError("加工前不良的物料暂不支持单件回退") mlog.submit_time = None mlog.submit_user = None