87 lines
3.5 KiB
Python
87 lines
3.5 KiB
Python
|
|
# ============================================================
|
|||
|
|
# 默认空世界:不造演示厂假数据;SQL 投影到主数据页
|
|||
|
|
# ============================================================
|
|||
|
|
from __future__ import annotations
|
|||
|
|
|
|||
|
|
import os
|
|||
|
|
|
|||
|
|
from server.state.seed import build_demo_world, empty_world, purge_demo_residue, seed_world
|
|||
|
|
|
|||
|
|
|
|||
|
|
def test_seed_world_default_empty(monkeypatch):
|
|||
|
|
monkeypatch.delenv("APS_SEED_DEMO", raising=False)
|
|||
|
|
monkeypatch.delenv("APS_SEED_PACK", raising=False)
|
|||
|
|
w = seed_world()
|
|||
|
|
assert w["materials"] == []
|
|||
|
|
assert w["routings"] == []
|
|||
|
|
assert w["flexOrders"] == []
|
|||
|
|
assert (w.get("flexParams") or {}).get("demoDataCleared") is True
|
|||
|
|
assert not any(m.get("code") == "CTRL-A" for m in w["materials"])
|
|||
|
|
|
|||
|
|
|
|||
|
|
def test_purge_demo_residue_strips_controllers():
|
|||
|
|
w = build_demo_world()
|
|||
|
|
assert any(m["code"] == "CTRL-A" for m in w["materials"])
|
|||
|
|
assert purge_demo_residue(w) is True
|
|||
|
|
assert w["materials"] == []
|
|||
|
|
assert w["routings"] == []
|
|||
|
|
assert w["factories"] == []
|
|||
|
|
assert (w.get("flexParams") or {}).get("demoDataCleared") is True
|
|||
|
|
|
|||
|
|
|
|||
|
|
def test_purge_keeps_site_flex_when_classic_is_demo():
|
|||
|
|
"""经典表是演示控制器,但 flex 已是现场订单时,不得清空 flex。"""
|
|||
|
|
w = build_demo_world()
|
|||
|
|
w["flexOrders"] = [{
|
|||
|
|
"id": 1, "orderNo": "SYS202309210001", "productCode": "030129001",
|
|||
|
|
"quantity": 10, "dueDate": "2026-08-01", "status": "RELEASED",
|
|||
|
|
}]
|
|||
|
|
w["flexMaterials"] = [{
|
|||
|
|
"id": 1, "code": "030129001", "name": "支重轮", "type": "FINISHED_PRODUCT",
|
|||
|
|
"unit": "件", "stock": 0, "inTransit": 0, "safetyStock": 0, "procurementLeadTime": 0,
|
|||
|
|
}]
|
|||
|
|
w["flexRoutings"] = [{
|
|||
|
|
"productCode": "030129001", "seq": 10, "operationCode": "NZ0011",
|
|||
|
|
"operationName": "粗车", "stdTimePerUnit": 30,
|
|||
|
|
}]
|
|||
|
|
assert purge_demo_residue(w) is True
|
|||
|
|
assert w["materials"] == [] # 演示经典已剥
|
|||
|
|
assert len(w["flexOrders"]) == 1
|
|||
|
|
assert w["flexOrders"][0]["orderNo"] == "SYS202309210001"
|
|||
|
|
assert w["flexMaterials"][0]["code"] == "030129001"
|
|||
|
|
|
|||
|
|
|
|||
|
|
def test_sql_projects_to_classic_master():
|
|||
|
|
from server.importers.sql_pack import apply_sql_pack_to_world, sql_pack_to_flex
|
|||
|
|
|
|||
|
|
flex = sql_pack_to_flex({
|
|||
|
|
"rowsByTable": {
|
|||
|
|
"pl_order": [{
|
|||
|
|
"code": "ORD1", "material_code": "FG001", "material_name": "成品A",
|
|||
|
|
"quantity": 10, "planned_end_time": "2026-08-01", "is_delete": "0",
|
|||
|
|
"craftl_code": "CRAFT-9", "level": 5,
|
|||
|
|
}],
|
|||
|
|
"md_craftl": [{"code": "CRAFT-9", "product_code": "FG001"}],
|
|||
|
|
"r_production_craftl": [{
|
|||
|
|
"craftl_code": "CRAFT-9", "procedure_code": "OP10", "procedure_name": "粗车",
|
|||
|
|
"output_material_code": "WIP-X", "sort_no": 10, "working_hours": 0.5,
|
|||
|
|
"is_delete": "0",
|
|||
|
|
}],
|
|||
|
|
"md_material": [],
|
|||
|
|
"md_equipment": [{"code": "EQ1", "name": "车床", "is_delete": "0"}],
|
|||
|
|
},
|
|||
|
|
"counts": {},
|
|||
|
|
})
|
|||
|
|
world = empty_world()
|
|||
|
|
# 先塞演示垃圾,确认会被替换掉
|
|||
|
|
world["materials"] = [{
|
|||
|
|
"id": 1, "code": "CTRL-A", "name": "智能控制器A型", "type": "FINISHED_PRODUCT",
|
|||
|
|
"unit": "件", "stock": 1, "inTransit": 0, "safetyStock": 0, "procurementLeadTime": 0,
|
|||
|
|
}]
|
|||
|
|
apply_sql_pack_to_world(world, flex, replace=True)
|
|||
|
|
codes = {m["code"] for m in world["materials"]}
|
|||
|
|
assert "CTRL-A" not in codes
|
|||
|
|
assert "FG001" in codes
|
|||
|
|
assert any(r.get("productId") for r in world["routings"])
|
|||
|
|
assert len(world["routingSteps"]) >= 1
|