75 lines
2.9 KiB
Python
75 lines
2.9 KiB
Python
# ============================================================
|
|
# EX-05 / EX-09 MES 下发与报工黄金测试
|
|
# ============================================================
|
|
from __future__ import annotations
|
|
|
|
from pathlib import Path
|
|
|
|
from server.agent_core.intent import parse_fast
|
|
from server.aps_domain.flex import run_flex_schedule
|
|
from server.aps_domain.mes import apply_dispatch, apply_report, list_execution, preview_dispatch
|
|
from server.integrations.mes_stub import reset_mes_client
|
|
from server.state.seed import seed_world
|
|
|
|
|
|
class _MemStore:
|
|
def __init__(self, data):
|
|
self.data = data
|
|
|
|
def next_id(self, kind: str) -> int:
|
|
key = f"_c_{kind}"
|
|
self.data[key] = self.data.get(key, 4000) + 1
|
|
return self.data[key]
|
|
|
|
def save(self):
|
|
pass
|
|
|
|
|
|
def test_dispatch_idempotent(tmp_path: Path):
|
|
reset_mes_client(tmp_path / "mes_mirror.json")
|
|
store = _MemStore(seed_world())
|
|
run_flex_schedule(store, sort_mode="BOTTLENECK", actor="test")
|
|
prev = preview_dispatch(store.data, "flex")
|
|
assert prev["newCount"] >= 1
|
|
r1 = apply_dispatch(store, track="flex", actor="test")
|
|
assert r1["created"]
|
|
assert len(r1["duplicates"]) == 0
|
|
w = next(w for w in store.data["flexWorkOrders"] if w.get("mesExternalId"))
|
|
assert w["mesExternalId"].startswith("MES-WO-")
|
|
ver = store.data["flexScheduleVersions"][-1]
|
|
assert ver["status"] == "DISPATCHED"
|
|
r2 = apply_dispatch(store, track="flex", actor="test")
|
|
assert len(r2["created"]) == 0
|
|
assert len(r2["duplicates"]) >= len(r1["created"])
|
|
|
|
|
|
def test_report_progress_and_order_complete(tmp_path: Path):
|
|
reset_mes_client(tmp_path / "mes_mirror.json")
|
|
store = _MemStore(seed_world())
|
|
run_flex_schedule(store, sort_mode="BOTTLENECK", actor="test")
|
|
apply_dispatch(store, track="flex", actor="test")
|
|
ex = list_execution(store.data, "flex")
|
|
assert ex["total"] >= 1
|
|
row = ex["rows"][0]
|
|
r = apply_report(store, row["woId"], track="flex", progress_pct=50, actor="test")
|
|
assert r["progressPct"] == 50
|
|
wo = next(w for w in store.data["flexWorkOrders"] if w["id"] == row["woId"])
|
|
assert wo["status"] == "RUNNING"
|
|
# 同订单全部完工
|
|
order_no = row["orderNo"]
|
|
vid = store.data["flexScheduleVersions"][-1]["id"]
|
|
sibs = [w for w in store.data["flexWorkOrders"]
|
|
if w.get("flexOrderNo") == order_no and w.get("versionId") == vid]
|
|
for s in sibs:
|
|
apply_report(store, s["id"], track="flex", finish=True, actor="test")
|
|
fo = next(o for o in store.data["flexOrders"] if o["orderNo"] == order_no)
|
|
assert fo["status"] == "COMPLETED"
|
|
|
|
|
|
def test_intent_mes_phrases():
|
|
world = seed_world()
|
|
assert parse_fast("下发MES", world).intent == "mes.dispatch"
|
|
assert parse_fast("MES状态", world).intent == "mes.status"
|
|
assert parse_fast("模拟报工", world).intent == "mes.report"
|
|
assert parse_fast("一键模拟报工完工", world).params.get("finishAll") is True
|