8.4 KiB
8.4 KiB
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=False且material_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.id 到 mlogb_q_ids,用于"加工前缺陷"统计。
2. 合格率计算
完全合格率 = round(count_ok_full / count_real * 100, 2)
合格率 = round(count_ok / count_real * 100, 2)
decimal.InvalidOperation 异常时(如分母为 0)记 0。
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
data经MyJSONEncoder序列化后回填batchst.data。- 调
get_f_l_date(data):扫描所有以_日期结尾的字段,按;拆开后逐个datetime.strptime("%Y-%m-%d")解析为date对象,再取最小/最大并转成上海时区的00:00:00/23:59:59,得到first_time/last_time。无法解析的片段会写日志并跳过。 - 仅当现有
first_time为空或新值更早时更新;last_time反之。 - 调用
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 |
上游报工子项 | 用于追溯领用与加工前缺陷 |
九、已知潜在问题
mgroup_obj入参未使用:当前实现忽略该参数,对所有Mgroup全量遍历。
十、修订记录
- 修复
小日期 / 大日期命名与含义反向,小日期取最早日期、大日期取最晚日期;同步修正batch_bxerp.py、batch_gzerp.py中所有同类字段。 get_f_l_date改为先datetime.strptime解析为date对象再比较,移除对字符串字典序的隐式依赖;非法日期片段记录日志后跳过。- 所有合格率/直通率计算的兜底
except同时捕获decimal.InvalidOperation与ZeroDivisionError,以兼容Decimal与原生数值的除零场景;batch_bxerp.py与batch_gzerp.py中仅捕获decimal.InvalidOperation的合格率分支也同步扩展。