fix: deduct available stock before production yield adjustment

This commit is contained in:
ar51
2026-10-12 11:57:24 +08:00
parent de6656dfe0
commit edefe52082
6 changed files with 246 additions and 80 deletions

View File

@@ -14,7 +14,7 @@ Expected:
- model parses successfully;
- quantity is accepted;
- the original demand of 10 remains visible in the reply and record, while the baseline and every recommended candidate call the API with 15 after dividing by 95% yield and rounding to a batch of five;
- original demand 10 remains visible; read each model's own stock first, then deduct it before applying 95% yield and rounding to five. With zero stock production is 15; stock of at least 10 gives zero production and retains the first stock-delivery result;
- the bot immediately adds the Feishu `OnIt` (typing) reaction to the original message after the valid trigger is accepted and before the API query starts;
- the controlled script uses the macOS system trust store and keeps TLS verification enabled;
- no temporary TLS-bypass parameter is required for the normal happy path;
@@ -84,7 +84,7 @@ Expected:
- the bot immediately adds the Feishu `OnIt` (typing) reaction to the original message after the continuation and active-context gates pass;
- the bot reuses the active model and quantity only for that same sender and chat;
- the continuation retains original demand 10 and again uses forecast quantity 15; it never compounds the adjustment to 20;
- continuation retains original demand 10 and computes each new candidate from its own current stock; with zero stock production is 15. It never compounds an earlier adjustment or reuses baseline stock;
- the bot queries candidate positions 5-8 in the unchanged rule order;
- the original model and candidate positions 1-4 are not queried or displayed again;
- unavailable candidates still consume their original positions and are summarized under `不可用候选`;
@@ -268,3 +268,13 @@ Expected:
```text
以上为内部候选方案,不构成客户正式交期承诺;需 AR516 或授权责任人结合库存、生产、采购、客户优先级和最新系统数据人工复核后使用。
```
## Stock-First Production Quantity Acceptance
- D=24, S=6: query D=24 to read stock, calculate net demand 18 and production 20, query with 20. Display shortage gap 18 and use the final API workdays/date and shortage details.
- D=24, S=0: production 30; D=25, S=6: net demand 19 and production exactly 20.
- D=24, S>=24: production 0, retain original-query stock-delivery result, no quantity=0 request. D=5, S=1: production 5, so reuse the first query.
- Different candidates use different stock and production quantities; initial and continuation batches retain original demand and never compound yield allowance.
- Missing/invalid stock is unavailable, never zero; changed stock between the two queries invalidates that model's result without an automatic retry.
- D=24, S=20: calculate net demand 4, production 5, but report delivery unavailable because the current API would take the stock shortcut with quantity=5; never claim full coverage or invent a date.
- New record metadata preserves each model's net/production/API quantities without changing existing table columns or historical records.

View File

@@ -1,36 +1,57 @@
# 交期预测数量口径
# 交期预测数量规则
用户输入为原始需求数量。交期回复机器人在查询原型号、候选型号及后续批次前,统一按以下规则计算 API 输入数量:
可用成品库存已视为100%可用,只对需要新生产的缺口考虑合格率。
```text
排产测算数量 = 5 × ceil(原始需求数量 ÷ 0.95 ÷ 5)
D = 原始需求数量
S = 该型号可用库存(API字段:可用库存(扣除了待产数量))
净需求 = max(D - max(S, 0), 0)
最终排产测算数量 P = 5 × ceil(净需求 ÷ 0.95 ÷ 5)
```
固定不良率为 5%,对应良率 95%。先除以良率,再向上取到 5 的倍数。代码使用整数运算,避免恰好落在倍数边界时因浮点误差多加一个批次。
净需求为0时,P为0;固定不良率5%,对应合格率95%。先扣库存,再除以合格率,最后向上取5的倍数。使用整数运算,避免边界浮点误差。库存缺失或不是有效整数时不能视作0;负整数余额按无可用库存参与计算。
| 原始需求 | 除以95%良率 | 排产测算数量 / API quantity |
|---:|---:|---:|
| 5 | 5.263… | 10 |
| 10 | 10.526… | 15 |
| 19 | 20 | 20 |
| 20 | 21.052… | 25 |
| 25 | 26.315… | 30 |
| 95 | 100 | 100 |
| 原始需求 | 可用库存 | 净需求 | 排产测算数量 |
|---:|---:|---:|---:|
| 24 | 6 | 18 | 20 |
| 24 | 0 | 24 | 30 |
| 24 | 24 | 0 | 0 |
| 24 | 30 | 0 | 0 |
| 25 | 6 | 19 | 20 |
| 5 | 1 | 4 | 5 |
| 95 | 0 | 95 | 100 |
回复示例中的数量部分:
每个候选使用自己的库存,不累计多个候选的库存。续批保留原始需求,对新候选重新读取库存及计算,不对已折算数量重复折算。
报告示例(需求24,可用库存6):
```text
输入需求:eRob70H120I-BHM-18CT[V5],5台
排产测算数量:10台(不良率5%,按5台的倍数向上取整)
库存覆盖口径:按排产测算数量判断
1. eRob70H120I-BHM-18CT[V5](原型号,DZ)
- 需求数量:5台
- 排产测算数量:10台
需求数量:24台
扣库存后净需求:18台
排产测算数量:20台
可用库存/覆盖情况:整机可用库存6台(部分覆盖,仍需补齐18台)
```
实际交期继续读取 API 返回的工作日交期和最终交货日期。库存覆盖也以本次 API 使用的排产测算数量判断,例如原始需求 5、API 数量 10、库存 7 时,显示部分覆盖,仍需补齐 3 台。
库存覆盖始终比较原始需求,不能比较排产量。各型号排产量可能不同,报告顶部显示计算规则,各型号明细及新记录元数据分别显示数量;历史记录不改写,候选表列不改变。
对话上下文和本地记录保留原始需求;记录元数据另列排产测算数量和计算规则。继续推荐仍从原始需求重新计算一次,不把 10 台再次放大为 15 台。低层受控脚本的 `--quantity` 参数就是最终发送给 API 的数量,不在脚本内重复换算。
## 受控API查询
本机通过相应测试后,运行电脑需要同步这次代码和规则变更,并重启交期回复机器人;另一个后台物料名称刷新服务不因数量规则变化而需要重新安装。
1. 先以D调用受控脚本,读取该型号库存。
2. 库存足量:P=0,沿用第一次查询的现货交期;不发送quantity=0。
3. 库存不足且P=D:第一次查询已符合排产数量,不重复查询。
4. 库存不足且P与D不同:以P调用同一受控脚本,交期、缺料明细及主导因素取第二次响应。两次库存必须一致,否则结果不可用,需要重新查询。
5. 第一响应无有效库存或必需工作日/日期字段时,结果不可用。
低层脚本仍原样传递quantity。日期与工作日仍直接使用API返回值,不在本地推算。
## 现有接口限制
现有WithTransit交接口径中,quantity同时参与成品现货判断和本次生产/BOM数量测算。若 `0 < P <= S < D`,传P会误判现货。例如D=24、S=20,净需求4、P=5,但20台库存不能覆盖24台需求。此时本地能计算正确排产量,却不能从现有单数量参数获得可靠生产交期;明确报交期不可用,原型号停止出具报告,候选列入不可用清单。需要AR836接口支持分别输入原需求和排产量后解除该限制。
不能改传S+P:这会使API按包含库存的数量测算物料和生产。也不能使用第一次D查询的交期充当P的交期。该限制依据既有接口交接说明,尚未完成当前服务端的实时验证;本次本机测试使用模拟响应。
## 运行电脑同步验收
运行电脑须拉取包含桥接代码、项目内Skill、测试及说明的完整版本并重启交期回复机器人。无需新增依赖、配置或重装物料名称刷新服务。
执行 `python3 -m unittest discover -s tests -q`,并在既有API审批及功能测试授权范围内检查需求24/库存6、库存完全覆盖、不同候选库存、续批,以及部分库存误走现货分支样例。核对数量、实际API参数、库存变化处理与API最终日期。推送成功不代表运行电脑已生效。

View File

@@ -9,7 +9,7 @@
5. If that domain-and-permission record is absent, stop before any outbound request; a general functional-test approval is insufficient by itself.
6. Use model recommendation rules to generate the complete ordered internal candidate pool.
7. Immediately add the Feishu `OnIt` (typing) reaction to the original message to acknowledge the valid request.
8. Run the controlled script for the original model baseline and only the first four candidate models.
8. For the baseline and first four candidate models, follow [stock-first quantity rules](production_quantity.md): read each model's own stock with original demand, deduct it, then divide the net gap by 95% yield and round up to five. Query production quantity when required; do not send zero, mix changed stock snapshots or accept a false stock shortcut.
9. Read `data.交期汇总.AM516工作日交期` and `data.交期汇总.AM516最终交货日期` directly. Require a nonnegative whole-number workday count and a valid `YYYY-MM-DD` date; missing or invalid fields make the result unavailable. Do not convert natural days or recalculate dates locally.
10. Summarize the current batch with the API workdays and final delivery date, for example `AM516预测交期:8个工作日,最终交货日期:2026-10-08`; state how many candidates remain and invite the same sender to ask naturally for more when candidates remain. Newly appended records use the same form; historical records are unchanged.
11. Append a non-secret record.