12. Order 服务
通过 client.order() 进行访问。工作指令 (Work Order) 从创建 → 开始 → 中断/恢复 → 结束的整个生命周期由基于 ISA-88 的状态机进行管理。
11.1 工作指令状态 (基于 ISA-88)
CREATE → WAIT ──start()──► START ──pause()──► PAUSED
│ │
│ resume()
│ │
▼ ▼
END ◄──end()──── START
│
└─ (또는) ──abort()──► ABORTED
状态 (status) | 含义 | 迁移方法 | ISA-95 状态 (isa95_state) |
|---|---|---|---|
WAIT | 等待 (创建后的初始状态) | create() 结果 | Ready |
START | 进行中 | start(), resume() | Running |
PAUSED | 暂停 | pause() | Held |
END | 正常完成 | end() | Completed |
ABORTED | 异常结束 | abort() | Aborted |
status 为存储值本身,仅限上述五种。未开始即取消的工作指令并非新状态,而是 ABORTED + abort_code=CANCELLED。工作指令行 (/order·列表·/order/query)、业绩文档和 plantpulse.order.* 事件在此基础上附加 ISA-95 Part 4 工作指令状态 isa95_state — 其对应关系见上表,所有路径产生相同的值。
无法进行状态迁移的调用(例如:在已处于
START状态时重新调用start()),服务器将发送 OK +data.success=false响应,V5 方法将返回false。
11.2 方法一览
CRUD
| 方法 | 返回类型 | HTTP | 端点 |
|---|---|---|---|
create(OrderRequestV5) | OrderResponseV5 或 null | POST | /api/v5/order |
update(order_id, OrderRequestV5) | OrderResponseV5 或 null | PUT | /api/v5/order/{id} |
delete(order_id) | boolean | DELETE | /api/v5/order/{id} |
get(order_id) | OrderResponseV5 或 null | GET | /api/v5/order/{id} |
list() | List<OrderResponseV5> | GET | /api/v5/order |
exists(order_id) | boolean | GET | /api/v5/order/{id}/exists |
生命周期 (均返回 boolean)
| 方法 | HTTP | 端点 |
|---|---|---|
start(order_id) | POST | /api/v5/order/{id}/start |
end(order_id) | POST | /api/v5/order/{id}/end |
pause(order_id) | POST | /api/v5/order/{id}/pause |
resume(order_id) | POST | /api/v5/order/{id}/resume |
abort(order_id) | POST | /api/v5/order/{id}/abort |
11.3 OrderRequestV5 / OrderResponseV5
| 字段 | 类型 | 说明 |
|---|---|---|
order_id | String | 工作指令 ID (PK) |
order_name | String | 工作指令名称 — 必填,不可为空 (422 order.name.required)。B2MML JobOrder 的名称 |
description | String | 说明 |
site_id | String | 所属站点 |
asset_id | String | 目标资产 (Equipment) |
customer_id | String | 客户 (可选) |
product_id | String | 生产产品 |
employee_id | String | 负责员工 (可选) |
planned_quantity | Quantity | 计划数量 — ISA-95 / B2MML QuantityValueType。详见下方 11.5 数量 |
time_per_unit_in_ms | long | 单位标准时间 |
planned_start_timestamp | long | 计划开始时间 (毫秒) |
planned_end_timestamp | long | 计划结束时间 (毫秒) |
external_id | String | 外部系统 (MES·ERP) 的工作指令编号 (最高 100 字)。与 external_system 构成配对进行识别 — 11.6 |
external_system | String | 发布该工作指令的外部系统名称 (最高 50 字) — 外部识别配对的另一半 |
customer_po_id | String | 此工作指令对应的客户采购订单 (PO) 编号 (可选) |
status | String | (仅响应) 当前状态 — 存储值 WAIT·START·PAUSED·END·ABORTED |
isa95_state | String | (仅响应) ISA-95 工作指令状态 — Ready·Running·Held·Completed·Aborted (11.1) |
title → order_name, fix_start_timestamp·fix_end_timestamp → planned_start_timestamp·planned_end_timestamp,
external_order_id → external_id, external_po_id → customer_po_id。旧名称将不再在请求中读取,也不会在响应中出现 —
升级指南。
11.4 使用示例
创建工作指令
import plantpulse.api.v5.dto.Quantity;
import plantpulse.api.v5.dto.request.OrderRequestV5;
import plantpulse.api.v5.dto.response.OrderResponseV5;
OrderRequestV5 req = new OrderRequestV5();
req.setOrder_id("ORDER_000001");
req.setOrder_name("5월 14일 1교대 생산");
req.setDescription("PROD_A001 500개 생산");
req.setSite_id("SITE_DJ");
req.setAsset_id("ASSET_DJ_M_0001");
req.setProduct_id("PROD_A001");
req.setCustomer_id("CUST_001");
req.setEmployee_id("EMP_E12345");
req.setPlanned_quantity(Quantity.of("500", "EA")); // 값은 10진 «문자열», 단위는 UN/ECE Rec 20 코드
req.setTime_per_unit_in_ms(5_000);
long now = System.currentTimeMillis();
req.setPlanned_start_timestamp(now);
req.setPlanned_end_timestamp(now + 4 * 3600_000L);
req.setExternal_id("MES-2026-0514-001");
req.setExternal_system("MES");
OrderResponseV5 created = client.order().create(req);
标准生命周期
String orderId = "ORDER_000001";
// WAIT → START
if (!client.order().start(orderId)) {
System.err.println("시작 실패 — planned_start_timestamp가 미래이거나 이미 진행중");
return;
}
// 잠시 후 — 일시중지
client.order().pause(orderId);
// 재개
client.order().resume(orderId);
// 정상 종료
client.order().end(orderId);
异常结束
// abort 는 별도 인자 없이 호출. 상세 사유는 update() 로 description/notes 에 기록.
if (!client.order().abort("ORDER_000001")) {
System.err.println("중단 실패");
}
单条查询 / 存在确认
OrderResponseV5 o = client.order().get("ORDER_000001");
if (o != null) {
System.out.println("상태: " + o.getStatus());
Quantity planned = o.getPlanned_quantity(); // {quantity_string, data_type, unit_of_measure}
System.out.println("계획: " + planned.getQuantity_string() + " " + planned.getUnit_of_measure());
java.math.BigDecimal value = planned.toBigDecimal(); // 계산은 BigDecimal 로 — double 로 바꾸지 않는다
}
boolean exists = client.order().exists("ORDER_000001");
全部列表
import java.util.List;
List<OrderResponseV5> all = client.order().list();
for (OrderResponseV5 o : all) {
System.out.printf("[%s] %s — %s%n",
o.getStatus(), o.getOrder_id(), o.getOrder_name());
}
仅进行中的工作指令 (客户端侧过滤)
import java.util.stream.Collectors;
List<OrderResponseV5> active = client.order().list().stream()
.filter(o -> "START".equals(o.getStatus())
|| "PAUSE".equals(o.getStatus()))
.collect(Collectors.toList());
按资产查询工作指令
String assetId = "ASSET_DJ_M_0001";
List<OrderResponseV5> assetOrders = client.order().list().stream()
.filter(o -> assetId.equals(o.getAsset_id()))
.collect(Collectors.toList());
按状态统计
import java.util.Map;
Map<String, Long> byStatus = client.order().list().stream()
.collect(Collectors.groupingBy(
OrderResponseV5::getStatus,
Collectors.counting()));
byStatus.forEach((status, count) ->
System.out.printf("%s: %d건%n", status, count));
修改 / 删除
// 수정 (계획 시간 연장)
OrderRequestV5 update = new OrderRequestV5();
update.setOrder_id("ORDER_000001");
update.setOrder_name("5월 14일 1교대 생산 (연장)");
// ... 모든 필드 다시 세팅 ...
update.setPlanned_end_timestamp(System.currentTimeMillis() + 8 * 3600_000L);
client.order().update("ORDER_000001", update);
// 삭제 (취소 처리)
client.order().delete("ORDER_000001");
11.5 数量 — ISA-95 Quantity
工作指令的数量(计划·生产·良品·报废·返工 …)并非单一数字,而是包含值和单位的对象。
其形式与 ISA-95 (IEC 62264) / B2MML V0700 的 QuantityValueType 保持 1:1 对应。
基于 V5 API (OpenAPI info.version 5.0) · 数量协议 2026-10-30 · 名称 Wave 2026-10-31 · Platform 2026.11 版本 (server-web 974891b4)。
事件为 plantpulse.order.*·plantpulse.calendar.* 架构 major 2, plantpulse.kpi.oee.finalized major 1, DB 为 Flyway V99·V100·V103 及 core 迁移 V12V16·V21V23 —
升级指南。
[
{ "quantity_string": "1250.5", "data_type": "decimal", "unit_of_measure": "KGM" },
{ "quantity_string": "1200", "data_type": "integer", "unit_of_measure": "EA" }
]
| 字段 | B2MML | 类型 | 规则 |
|---|---|---|---|
quantity_string | QuantityString | string | 采用 10 进制表示 — 禁止指数表示,小数点为 .,最高保留至小数点后第四位。计数单位必须为整数 |
data_type | DataType | string | integer (计数单位) 或 decimal (其他)。由服务器根据单位确定 — 请求中可省略,若提供则必须与单位匹配 |
unit_of_measure | UnitOfMeasure | string | UN/ECE Recommendation 20 通用代码 — 见下方允许列表 |
因为 B2MML 将其定义为 QuantityString,且大多数 JSON 解析器将数字读取为 double 导致失去 10 进制精度。在 SDK 中请使用 Quantity.toBigDecimal() 读取并进行计算。在创建请求时,
Quantity.of("1250.5", "KGM") — 若 data_type 为空,服务器将自动填充。
单位 — 允许列表 (UN/ECE Rec 20)
| 代码 | 含义 | data_type | 界面符号 |
|---|---|---|---|
EA | each — 个数 | integer | EA |
H87 | piece | integer | pc |
C62 | one (unit) | integer | unit |
BX | box — 箱数 | integer | box |
SET | set — 套/组件数 | integer | set |
KGM | kilogram | decimal | kg |
GRM | gram | decimal | g |
TNE | tonne | decimal | t |
LTR | litre | decimal | L |
MLT | millilitre | decimal | mL |
MTQ | cubic metre | decimal | m³ |
MTR | metre | decimal | m |
MTK | square metre | decimal | m² |
- 允许单位共 13 个,其中计数单位为
EA·H87·C62·BX·SET这五个。列表之外的代码将被拒绝 (quantity.unit_invalid)。 代码比对区分大小写 —ea,KG,PCS均非允许代码。 - 若输入列表中不存在的界面符号代码(例如旧数据),将原样显示代码。
- 不进行单位换算(单位主数据及换算由 MES 负责)。不同单位的数量不得相加。
- 界面符号与语言无关 — 即使在中文界面中也显示
EA而非 «个»。符号始终紧跟数值(包括个数)。
字段名称 — ISO 22400
字段名称遵循 ISA-95 和 ISO 22400-2 (IEC 62264 的 KPI 对应项) 的术语。旧名称不再出现在响应中(无兼容字段)。
| 含义 | 字段 (Quantity) | 旧字段 | 依据 |
|---|---|---|---|
| 计划数量 | planned_quantity | target_units + unit | ISA-95 MaterialRequirement.Quantity · ISO 22400 POQ |
| 生产数量 | produced_quantity | total_production_count | ISO 22400 PQ |
| 良品数量 | good_quantity | total_good_count · good_count | ISO 22400 GQ |
| 报废数量 | scrap_quantity | total_bad_count · bad_count — 含义收窄: 旧字段指全部不良,新字段仅指报废 | ISO 22400 SQ |
| 返工数量 | rework_quantity | (无 — 新字段) | ISO 22400 RQ |
| 计划外良品 / 不良 | good_quantity_out_of_plan / scrap_quantity_out_of_plan | out_of_plan_good_count / out_of_plan_bad_count | |
| 测量良品 / 不良 (PLC) | measured_good_quantity / measured_scrap_quantity | measured_good_count / measured_bad_count | |
| 修正增减 | good_quantity_delta / scrap_quantity_delta | good_delta / bad_delta | |
| 修正输入值 | entered_good_quantity / entered_scrap_quantity | entered_good / entered_bad | |
| 检验数量 | inspected_quantity | inspected_count | |
| 检验不良合计 | inspected_scrap_quantity | inspected_bad_count | |
| 按处置记录不良 | scrap_quantity / rework_quantity | scrap_count / rework_count | ISO 22400 SQ / RQ |
变更的响应:/order, /order/query(include=oee), /order/{id}/oee, /order/{id}/quantity (含修订记录),
/defects, /order/performance, /kpi/oee/history, /asset/{id}/status, MCP 工作指令工具, 生产事件 OEE_CALCULATED。
/asset/{id}/status的planned_quantity·good_quantity·scrap_quantity将显示为进行中工作指令的单位。若无进行中的工作指令,则为 null。- 比例字段 (
total_good_rate,production_rate, 可用性·性能·质量·OEE) 为无量纲,因此直接使用数值。 /asset/{id}/status中同样包含rework_quantity(进行中工作指令的返工)。- PLC 计数记录 (
GET /api/v5/kpi/oee/count的good_quantity·scrap_quantity) 和 MCPget_asset_kpi的按原因报废 (scrap_quantity) 同样采用该时刻工作指令单位的 Quantity。由于计数器为整数计数,因此 计数 1 = 工作指令单位 1 — 若在 kg 单位工作指令中连接整数计数器,则仅按 1 kg 单位计数。小数业绩应通过数量修正或业绩输入,而非计数器。
报废与返工 — «不良» 为两者之和
按照 ISO 22400 将不良分为报废 (SQ) 与返工 (RQ)。
- 不良 = 报废 + 返工, 生产 = 良品 + 报废 + 返工 (
produced_quantity=good_quantity+scrap_quantity+rework_quantity)。 scrap_quantity仅限报废。由于 PLC 计数的不良未知其处置方式,故计为报废。返工仅在处置方式为REWORK的不良记录中产生。- 质量 Q 为 良品 ÷ 生产,因此返工也会降低质量 — 仅为分类记录,不影响 OEE 值。
- 界面通过文字维持此区分:仅指报废的区域(生产历史列、数量修正栏)标注为 «报废»,显示合计的区域标注为 «不良»,若存在返工则附加详情,如 «14 kg (报废 12.75 · 返工 1.25)» — 生产管理 — 数量与单位。
- 若联动需要 «不良合计»,请将
scrap_quantity+rework_quantity在相同单位下以 10 进制相加。请勿将单个scrap_quantity视为不良合计。
字段数量承载 — 计数器表
| 来源 (存储) | V5 字段 / 事件字段 | 承载数量 |
|---|---|---|
PLC 计数器原账 tm_kpi_oee_count | /kpi/oee/count 的 good_quantity · scrap_quantity | PLC 计数的良品·不良增量。由于未知处置方式,不良计为报废 (SQ) |
工作指令 OEE 行 mm_order_oee.total_production_count | produced_quantity · 事件 pq/pq_quantity | 生产 (PQ) = 良品 + 报废 + 返工 |
mm_order_oee.total_good_count | good_quantity · gq/gq_quantity | 良品 (GQ) |
mm_order_oee.total_bad_count − total_rework_count | scrap_quantity · sq/sq_quantity | 报废 (SQ)。total_bad_count 本身 (不良合) 不在传输线路中 |
mm_order_oee.total_rework_count | rework_quantity · rq/rq_quantity | 返工 (RQ) |
mm_order_oee.out_of_plan_good_count / out_of_plan_bad_count | good_quantity_out_of_plan / scrap_quantity_out_of_plan · gq_out_of_plan/sq_out_of_plan(+_quantity) | 计划停机期间产生的量 — 包含在上述良品·报废中,但在效率计算中剔除 |
数量修正 mm_order_quantity_correction | /order/{id}/quantity 的 measured_*_quantity · good_quantity_delta/scrap_quantity_delta · (历史) entered_*_quantity | PLC 测量值, 修正增减, REPLACE 输入值。报废栏仅限报废 |
不良记录 mm_defect_record (处置 SCRAP/REWORK) | /defects 的 quantity·inspected_quantity, 业绩文档 defects.scrap_quantity / rework_quantity / inspected_scrap_quantity | 按处置的报废·返工, 检验不良合计 (SCRAP + REWORK) |
mm_order.planned_quantity | planned_quantity · 事件 planned_quantity | 计划 (POQ) |
请求规则与拒绝
在业绩·修正·不良记录中填写的数量必须与工作指令 planned_quantity 的单位一致。服务器不进行换算,直接拒绝。
值·单位拒绝属于 422 E1002 (非 400),响应 (application/problem+json) 的 code 为 E1002,
reason 字段为下列原因代码。detail 是调用者语言的句子,因此请使用 reason 进行分支判断。
| 原因代码 | 触发场景 |
|---|---|
quantity.unit_mismatch | 发送了与工作指令单位不同的单位 |
quantity.not_integer | 在计数单位 (EA·H87·C62·BX·SET) 中发送了小数 |
quantity.unit_invalid | 单位缺失或在允许列表 13 个单位之外 |
quantity.format | quantity_string 不是 10 进制表示字符串 (如指数表示·前导 0·+ 符号·数字类型),或 data_type 与单位不符 |
quantity.scale | 小数点第五位及以上 |
quantity.negative | 负数 (仅修正增减栏接受负数) |
quantity.range | 绝对值 ≥ 10^14 — 超出存储 numeric(18,4) 范围 |
- 若在数量栏提供非对象的值 (如数字
500等) 或输入quantity_string·data_type·unit_of_measure之外的键,则返回 400E1000(格式错误)。 - 工作指令的计划数量必须大于 0。
期间 KPI — 单位混合时不合计
像 /kpi/period·/kpi/daily 这样合并多个工作指令的响应,仅在单位统一时计算合计。
数量合计栏位于 /kpi/period 的 oee 对象内 good_count·total_count·in_plan_count, 以及 /kpi/daily 的 good_count·bad_count·planned_count。
/kpi/daily 的 bad_count 为 生产 − 良品,即不良合 (报废 + 返工)。
- 单位统一 — 数量合计栏像目前一样为数字,并附带其单位
unit_of_measure。 - 单位混合 — 数量合计栏与
unit_of_measure为 null,改为在quantities_by_unit中按单位列出良品·生产数量 (Quantity)。
{
"good_count": null,
"total_count": null,
"in_plan_count": null,
"unit_of_measure": null,
"quantities_by_unit": [
{ "unit_of_measure": "EA",
"good_quantity": { "quantity_string": "2671", "data_type": "integer", "unit_of_measure": "EA" },
"produced_quantity": { "quantity_string": "2700", "data_type": "integer", "unit_of_measure": "EA" } },
{ "unit_of_measure": "KGM",
"good_quantity": { "quantity_string": "1250.5", "data_type": "decimal", "unit_of_measure": "KGM" },
"produced_quantity": { "quantity_string": "1302", "data_type": "decimal", "unit_of_measure": "KGM" } }
]
}
比例 (可用性·性能·质量·OEE) 为无量纲,即使单位混合也直接显示。
EMS 单位值 — 分母单位
energy_per_unit_kwh·co2_per_unit_kg 的分母为工作指令的良品数量,因此响应中将一同显示该单位 unit_of_measure
(/order/{id}/ems, /order/ems/*, /order/query?include=ems)。界面标注为 «kWh/EA», «kWh/kg» 等。
在合并多个工作指令的汇总中,若单位混合,则单位值与单位均返回 null。
事件
事件架构仅允许«向末尾追加」,因此在不改变类型的情况下增加了字段。
| 事件 | 数量栏 |
|---|---|
plantpulse.order.* | planned_quantity (number) + planned_quantity_unit_of_measure (Rec 20 代码) |
plantpulse.kpi.oee.finalized | 正本为 gq_quantity·sq_quantity·rq_quantity·pq_quantity·gq_out_of_plan_quantity·sq_out_of_plan_quantity (number) + unit_of_measure。sq 仅限报废,返工在 rq (pq = gq + sq + rq)。整数栏 gq·sq·rq·pq·… 仅在计数单位时承载,小数单位则不存在 — 将在下一个 major 版本中移除 |
生产事件 OEE_CALCULATED | good_quantity·scrap_quantity (仅报废)·rework_quantity = Quantity 对象 |
11.6 MES 联动 — 业绩馈送与 B2MML 对应
外部工作指令识别 — (external_system, external_id) 配对
客户系统 (MES·ERP) 的工作指令通过发布系统名称及其在该系统中的编号这两项的配对进行识别 — 形式与员工·维修订单的外部识别一致。
- 配对在入口和出口路径中均同步存在。V5
POST·PUT·PATCH /api/v5/order接收external_system(50 字)·external_id(100 字), 且GET /order/{id}·列表·/order/query·业绩文档始终承载该配对 (若无则为 null)。控制台表单中无external_system栏,请通过 V5 输入。 - 空值或仅含空格的值存储为 null。超出长度或包含控制字符时返回 422
order.external_ref.invalid。 - 当两项均非空时,配对具有唯一性。若将相同配对赋予第二个工作指令,返回 409
order.external.duplicate。 PUT将替换整个请求栏 — 缺失的external_system·external_id将被删除。若仅修改部分,请使用PATCH。- 目前仍接收仅有
external_id而无external_system的工作指令,但由于不构成配对,无法通过下述 «配对查找» 找到。 - 事件同样承载配对:
plantpulse.order.*(架构 major 2) 的created·updated·startedaborted承载external_id·external_system,迁移事件 (startedaborted) 承载customer_po_id。 - 通过配对读取单个工作指令请使用
GET /api/v5/order/by-external/{system}/{external_id}— 若不存在返回 404,若其中一项为空返回 422order.external_ref.invalid。/order/query的过滤器为external_id+external_system。发送旧参数external_order_id时将不予忽略,直接以 422 拒绝。
业绩馈送路径
| HTTP | 路径 | 行为 |
|---|---|---|
| GET | /api/v5/order/performance | 业绩馈送 — cursor·site_id·limit。业绩发生变更的工作指令其 performance_revision 递增,并再次出现在末尾 |
| GET | /api/v5/order/{order_id}/performance | 单个工作指令的业绩文档 |
| GET | /api/v5/order/performance/by-external/{external_system}/{external_id} | 配对查找 — 数组 (由于配对唯一,最多一个),若无则为空数组 |
/api/v5/order/performance/by-external/{external_order_id} (无系统仅编号) 已删除。无兼容路径。
业绩文档的数量键
| 位置 | 键 (均为 Quantity) | 旧键 |
|---|---|---|
plan | planned_quantity | target_units |
quantity | measured_good_quantity / measured_scrap_quantity | measured_good / measured_bad |
quantity | good_quantity / scrap_quantity | good / bad |
quantity.correction | good_quantity_delta / scrap_quantity_delta | good_delta / bad_delta |
oee | good_quantity / scrap_quantity | total_good_count / total_bad_count |
defects | inspected_scrap_quantity / scrap_quantity / rework_quantity | inspected_bad_count / scrap_count / rework_count |
quantity.correction_version, progress.expected_now_units·pace_units 的名称保持不变 (小数单位为小数数值)。
quantity.scrap_quantity 仅限报废 (PLC 不良 + SCRAP 记录),与 defects.scrap_quantity 含义相同。quantity.rework_quantity 与 defects.rework_quantity 的值相同。defects.inspected_scrap_quantity 为检验不良合计 (SCRAP + REWORK)。
业绩文档状态 — 如何读取变更内容
单个业绩文档包含工作指令的当前状态,状态变更时版本号递增。
| 字段 | 含义 |
|---|---|
actual.status | 存储状态 WAIT·START·PAUSED·END·ABORTED — 11.1。取消为 ABORTED + actual.abort_code=CANCELLED |
actual.isa95_state | ISA-95 工作指令状态 Ready·Running·Held·Completed·Aborted |
performance_revision | 业绩变更次数。每次变更递增 1,馈送将该工作指令重新置于末尾。0 为尚未结束的工作指令 — 不在馈送中,仅通过 /order/{id}/performance 读取 |
quantity.correction_version | 数量修正版本。无修正时为测量值,每次修正递增 — 历史记录见 /order/{id}/quantity 的修订记录 |
changed_at · change_cause | 最近变更时间及其原因 — ENDED·QUANTITY (数量修正)·STOP_REASON·OEE_FINAL·DEFECT (不良记录)·PROGRESS·BASELINE |
数量仅以 «值 + 单位» 承载,未计算的字段为 null 而非 0。MES 仅需用一个更新的 order_id 的 performance_revision 文档整体替换前一文档即可。
B2MML 对应表
单个业绩文档对应 ISA-95 Part 4 的 Job Response (Segment Response),其数量对应 Material Actual (Produced) 的 Quantity。
| ISA-95 / B2MML | PlantPulse V5 | 备注 |
|---|---|---|
QuantityValueType — QuantityString · DataType · UnitOfMeasure | Quantity — quantity_string · data_type · unit_of_measure | 1:1。不使用 B2MML 的可选字段 Key |
UnitOfMeasure 值 | UN/ECE Rec 20 代码 | 允许列表见 11.5 |
| Job Order 的 ID | external_id | 发布系统名称为 external_system — 二者为配对 |
| Job Order · MaterialRequirement 的 Quantity | planned_quantity | ISO 22400 POQ |
| Job Order 的名称 | order_name | |
| Job Order 的 StartTime · EndTime | planned_start_timestamp · planned_end_timestamp | 计划时间。实际时间为 actual_start_timestamp · actual_end_timestamp |
| Job Response | 单个业绩文档 (/order/{id}/performance) | |
| MaterialActual(Produced) 的 Quantity | produced_quantity | ISO 22400 PQ |
| 其中良品 | good_quantity | ISO 22400 GQ |
| 其中报废 | scrap_quantity | ISO 22400 SQ |
| 其中返工 | defects.rework_quantity | ISO 22400 RQ |
11.7 应用场景
场景 — MES 联动工作指令自动创建
import java.text.SimpleDateFormat;
import java.util.Date;
SimpleDateFormat df = new SimpleDateFormat("yyyyMMdd");
String today = df.format(new Date());
// 외부 MES 큐에서 받은 주문을 V5 Order로 변환
for (MesOrder mes : mesQueue) {
OrderRequestV5 req = new OrderRequestV5();
req.setOrder_id("ORDER_" + today + "_" + String.format("%03d", mes.seq));
req.setSite_id("SITE_DJ");
req.setAsset_id(mes.equipId);
req.setProduct_id(mes.productId);
// MES 수량을 그대로 — 단위 환산은 하지 않는다. 단위는 허용 목록(11.5) 안의 Rec 20 코드여야 한다
req.setPlanned_quantity(Quantity.of(mes.qty.toPlainString(), mes.unitCode));
req.setExternal_id(mes.mesOrderId);
req.setExternal_system("MES");
req.setPlanned_start_timestamp(mes.plannedStart);
req.setPlanned_end_timestamp(mes.plannedEnd);
client.order().create(req);
}
场景 — 安全状态迁移辅助工具
public static boolean safeStart(APIClient_V5 client, String orderId) {
OrderResponseV5 o = client.order().get(orderId);
if (o == null) {
log.warn("작업지시 없음: " + orderId);
return false;
}
if (!"WAIT".equals(o.getStatus())) {
log.warn("WAIT 상태가 아님: " + o.getStatus());
return false;
}
return client.order().start(orderId);
}
下一步
- Customer 服务, Employee 服务, Product 服务 — 挂载至 Order 的主数据
- Calendar 服务 — 工作指令与巡检日程冲突检查
- 升级指南 — 数量 Quantity 转换时联动需修改事项