factory/apps/wpm/scripts/batch_gxerp.md

8.4 KiB
Raw Blame History

batch_gxerp.py 批次统计计算规则

apps/wpm/scripts/batch_gxerp.py 用于按 批次号 (batch) 汇总该批次在各工序组下的生产/检验数据,写入 BatchSt.data (JSON),同时维护 first_time / last_time


一、入参与前置条件

参数 说明
batch 批次号
mgroup_obj 工序组对象(当前实现未直接使用,仅作为入口签名)
  • 必须存在 BatchSt.objects.get(batch=batch, version=1),否则报错并退出。
  • 遍历 Mgroup.objects.all().order_by("sort"),对每个工序组分别统计。
  • 仅统计已提交且已出库的报工单:mlog.submit_time__isnull=Falsematerial_out__isnull=False,并要求 need_inout=True

二、字段命名约定

输出 JSON data 的 key 形式如下(<G> 代表工序组名):

Key 模式 含义
批次号 批次号
<G>_日期 该工序组所有报工日期,去重后 ; 拼接
<G>_小日期 / <G>_大日期 该工序组最早 / 最晚日期(YYYY-MM-DD
<G>_操作人 操作人姓名去重后 ; 拼接
<G>_班次 班次名去重后 ; 拼接
<G>_count_use 领用数(来自上游 mlogb_from
<G>_count_real 实际生产数
<G>_count_ok 合格数
<G>_count_notok 不合格数
<G>_count_ok_full 完全合格数
<G>_count_pn_jgqbl 加工前不良数(来自上游 mlogb_from
<G>_合格率 合格率(%
<G>_完全合格率 完全合格率(%
<G>_缺陷_<缺陷名> 该工序组的缺陷数量(按缺陷名汇总)
<G>_缺陷_<缺陷名>_比例 缺陷数 / count_real × 100单位 %
<G>_加工前_缺陷_<缺陷名> 上游 mlogb_from 上的缺陷数量
<G>_加工前_缺陷_<缺陷名>_比例 加工前缺陷数 / count_use × 100单位 %

三、主流程:按工序组汇总(普通报工,is_fix=False

数据源 mlogb1_qs

Mlogb where mlog.submit_time IS NOT NULL
        and material_out IS NOT NULL
        and mlog.mgroup = <G>
        and mlog.is_fix = False
        and batch = <batch>
        and need_inout = True

1. 累加规则

对每条 Mlogb

字段 累加来源
count_use mlogb_from.count_use(上游报工子项;若无 mlogb_from 则跳过)
count_pn_jgqbl mlogb_from.count_pn_jgqbl
count_real 当前 item.count_real
count_ok 当前 item.count_ok
count_ok_full 当前 item.count_ok_full or 0
count_notok 当前 item.count_notok or 0
操作人 mlog.handle_user(最终去重,按 name 拼接)
日期 mlog.handle_date(最终去重排序)
班次 mlog.shift.name

并记录所有上游 mlogb_from.idmlogb_q_ids,用于"加工前缺陷"统计。

2. 合格率计算

完全合格率 = round(count_ok_full / count_real * 100, 2)
合格率     = round(count_ok      / count_real * 100, 2)

decimal.InvalidOperation 异常时(如分母为 00

3. 缺陷统计

  • 当前工序缺陷:MlogbDefect.filter(mlogb__in=mlogb1_qs, count__gt=0).values('defect__name').annotate(total=Sum('count'))
    • <G>_缺陷_<name> = total
    • <G>_缺陷_<name>_比例 = round(total / count_real * 100, 2)
  • 加工前(上游)缺陷:MlogbDefect.filter(mlogb__id__in=mlogb_q_ids, count__gt=0)...
    • <G>_加工前_缺陷_<name> = total
    • <G>_加工前_缺陷_<name>_比例 = round(total / count_use * 100, 2)

4. 日期字段

data[f"{G}_小日期"] = min(日期列表).strftime("%Y-%m-%d")  # 最早日期
data[f"{G}_大日期"] = max(日期列表).strftime("%Y-%m-%d")  # 最晚日期

最终 <G>_日期 被覆写为去重排序后的字符串(; 拼接)。


四、外观检验返修(is_fix=True

数据源 mlogb2_qs

Mlogb where mlog.submit_time IS NOT NULL
        and material_out IS NOT NULL
        and mlog.mgroup.name = '外观检验'
        and mlog.is_fix = True
        and batch = <batch>
        and need_inout = True

输出字段:

Key 计算
外观检验_返修_日期 报工日期,去重 ; 拼接
外观检验_返修_操作人 操作人姓名,去重 ; 拼接
外观检验_返修_count_real Σ count_real
外观检验_返修_count_ok Σ count_ok
外观检验_返修_count_ok_full Σ count_ok_full or 0
外观检验_返修_缺陷_<name> MlogbDefect 按缺陷名汇总
外观检验_返修_缺陷_<name>_比例 round(total / 外观检验_返修_count_real * 100, 2)

五、外观检验车间库存抽检

数据源 ft_qs

FtestWork where type2 = TYPE2_SOME
          and wm.mgroup.name = '外观检验'
          and batch = <batch>
          and submit_time IS NOT NULL

输出字段:

Key 计算
外观检验_车间库存抽检_日期 test_date 去重 ; 拼接
外观检验_车间库存抽检_操作人 test_user.name 去重 ; 拼接
外观检验_车间库存抽检_count_notok Σ count_notok or 0
外观检验_车间库存抽检_缺陷_<name> FtestworkDefect 按缺陷名汇总(无比例字段)

六、外观检验汇总指标(仅当存在 外观检验_count_ok 时计算)

Key 公式
外观检验_总合格数 外观检验_count_ok + 外观检验_返修_count_ok默认0
外观检验_总合格率 round(外观检验_总合格数 / 外观检验_count_real * 100, 2)
外观检验_完全总合格数 外观检验_count_ok_full + 外观检验_返修_count_ok_full默认0
外观检验_完全总合格率 round(外观检验_完全总合格数 / 外观检验_count_real * 100, 2)
外观检验_直通合格数 外观检验_总合格数 - 外观检验_车间库存抽检_count_notok默认0

直通合格率(依赖尺寸检验)

仅当 尺寸检验_合格率 存在时:

外观检验_直通合格率  = round(外观检验_总合格率 * 尺寸检验_合格率 / 100, 2)
外观检验_直通合格率2 = round(外观检验_直通合格数 / 尺寸检验_count_use * 100, 2)

仅当 尺寸检验_完全合格率 存在时:

外观检验_完全直通合格率 = round(外观检验_完全总合格率 * 尺寸检验_完全合格率 / 100, 2)

异常(InvalidOperation / ZeroDivisionError)回退为 0


七、写回 BatchSt

  1. dataMyJSONEncoder 序列化后回填 batchst.data
  2. get_f_l_date(data):扫描所有以 _日期 结尾的字段,按 ; 拆开后逐个 datetime.strptime("%Y-%m-%d") 解析为 date 对象,再取最小/最大并转成上海时区的 00:00:00 / 23:59:59,得到 first_time / last_time。无法解析的片段会写日志并跳过。
  3. 仅当现有 first_time 为空或新值更早时更新;last_time 反之。
  4. 调用 batchst.save() 持久化。

八、关键依赖与字段含义速查

模型字段 中文释义 来源
Mlogb.count_use 领用数 报工子项(来自 mlogb_from
Mlogb.count_real 实际生产数 报工子项
Mlogb.count_ok 合格数 count_real - count_notok
Mlogb.count_ok_full 完全合格数 count_real - count_notok_full
Mlogb.count_notok 不合格数 缺陷 okcate=30 求和
Mlogb.count_pn_jgqbl 加工前不良 MlogbDefect 中加工前不良求和
Mlogb.need_inout 是否需出入库 True 参与统计
Mlogb.mlogb_from 上游报工子项 用于追溯领用与加工前缺陷

九、已知潜在问题

  1. mgroup_obj 入参未使用:当前实现忽略该参数,对所有 Mgroup 全量遍历。

十、修订记录

  • 修复 小日期 / 大日期 命名与含义反向,小日期 取最早日期、大日期 取最晚日期;同步修正 batch_bxerp.pybatch_gzerp.py 中所有同类字段。
  • get_f_l_date 改为先 datetime.strptime 解析为 date 对象再比较,移除对字符串字典序的隐式依赖;非法日期片段记录日志后跳过。
  • 所有合格率/直通率计算的兜底 except 同时捕获 decimal.InvalidOperationZeroDivisionError,以兼容 Decimal 与原生数值的除零场景;batch_bxerp.pybatch_gzerp.py 中仅捕获 decimal.InvalidOperation 的合格率分支也同步扩展。