run_uata_closed_loop_gap_fill.py 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525
  1. #!/usr/bin/env python3
  2. """Fill A-suite (UATTEST_CHL) start-state rows for the 100-case closed-loop UAT.
  3. Tenant 838257186181189 only. Idempotent by business keys.
  4. Does not change UATA-WO-001..009, existing IQC PASS MDP, B/Demo, KPI, kit, or schedule results.
  5. """
  6. from __future__ import annotations
  7. import json
  8. from datetime import datetime
  9. from typing import Any
  10. from apply_sql_file import connect
  11. TENANT = 838257186181189
  12. FACTORY = 838257186320453
  13. NOW = datetime.now().replace(microsecond=0)
  14. BATCH = "UATA-GAPFILL-20260824"
  15. WO_SRC = "UATA-WO-001"
  16. WO_NEW = "UATA-A01-WO-P01"
  17. MES_ID = 9206082410003001
  18. IQC_A01_HDR = 9206082410001001
  19. IQC_A01_ENT = 9206082410001002
  20. IQC_A04_HDR = 9206082410001003
  21. IQC_A04_ENT = 9206082410001004
  22. IQC_A01_NO = "UATA-A01-IQC-001"
  23. IQC_A04_NO = "UATA-A04-IQC-NG"
  24. IPQC_A01_ID = 9206082410002001
  25. IPQC_A01_ZB = 9206082410002002
  26. IPQC_A05_ZB = 9206082410002003
  27. IPQC_A01_NO = "UATA-A01-IPQC-001"
  28. IPQC_A05_NO = "UATA-A05-IPQC-001"
  29. DEMAND_ID = 9206082410004001
  30. CUS_CODE = "UATA-A01-CUS"
  31. S0_CUS_ID = 9206082410005001
  32. S0_MAT_ID = 9206082410005002
  33. S0_BOM_ID = 9206082410005003
  34. S0_RTE_ID = 9206082410005004
  35. S0_LINE_ID = 9206082410005005
  36. S0_SUP_ID = 9206082410005006
  37. DS_CODE = "UATA-A01-DS"
  38. RULE_CODE = "UATA-A01-WATCH-01"
  39. EX_CODE = "UATA-A03-EX-NEW"
  40. def cols(cur, table: str) -> list[str]:
  41. cur.execute(
  42. """
  43. SELECT COLUMN_NAME, EXTRA
  44. FROM information_schema.COLUMNS
  45. WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME=%s
  46. ORDER BY ORDINAL_POSITION
  47. """,
  48. (table,),
  49. )
  50. return [r["COLUMN_NAME"] for r in cur.fetchall() if "auto_increment" not in (r.get("EXTRA") or "")]
  51. def exists(cur, sql: str, args: tuple) -> bool:
  52. cur.execute(sql, args)
  53. row = cur.fetchone()
  54. return bool(row and list(row.values())[0])
  55. def clone_work_order(cur) -> str:
  56. if exists(cur, "SELECT 1 FROM WorkOrdMaster WHERE tenant_id=%s AND WorkOrd=%s", (TENANT, WO_NEW)):
  57. return "exists"
  58. wo_cols = cols(cur, "WorkOrdMaster")
  59. select_exprs = []
  60. for c in wo_cols:
  61. if c == "WorkOrd":
  62. select_exprs.append("%s")
  63. elif c == "Status":
  64. select_exprs.append("%s")
  65. elif c in ("ReleaseDate", "LotSerial", "Batch"):
  66. select_exprs.append("NULL")
  67. elif c == "CreateUser":
  68. select_exprs.append("%s")
  69. elif c == "UpdateUser":
  70. select_exprs.append("%s")
  71. elif c in ("CreateTime", "UpdateTime"):
  72. select_exprs.append("%s")
  73. else:
  74. select_exprs.append(f"`{c}`")
  75. sql = (
  76. f"INSERT INTO WorkOrdMaster ({', '.join('`'+c+'`' for c in wo_cols)}) "
  77. f"SELECT {', '.join(select_exprs)} FROM WorkOrdMaster "
  78. f"WHERE tenant_id=%s AND WorkOrd=%s LIMIT 1"
  79. )
  80. params: list[Any] = []
  81. for c in wo_cols:
  82. if c == "WorkOrd":
  83. params.append(WO_NEW)
  84. elif c == "Status":
  85. params.append("p")
  86. elif c in ("CreateUser", "UpdateUser"):
  87. params.append("UATA-GAPFILL")
  88. elif c in ("CreateTime", "UpdateTime"):
  89. params.append(NOW)
  90. params.extend([TENANT, WO_SRC])
  91. cur.execute(sql, params)
  92. for table, wo_col in (("WorkOrdDetail", "WorkOrd"), ("WorkOrdRouting", "WorkOrd")):
  93. dcols = cols(cur, table)
  94. select_exprs = []
  95. extra: list[Any] = []
  96. for c in dcols:
  97. if c == wo_col:
  98. select_exprs.append("%s")
  99. extra.append(WO_NEW)
  100. else:
  101. select_exprs.append(f"`{c}`")
  102. cur.execute(
  103. f"INSERT INTO `{table}` ({', '.join('`'+c+'`' for c in dcols)}) "
  104. f"SELECT {', '.join(select_exprs)} FROM `{table}` "
  105. f"WHERE {wo_col}=%s AND (tenant_id=%s OR tenant_id IS NULL)",
  106. extra + [WO_SRC, TENANT],
  107. )
  108. if not exists(cur, "SELECT 1 FROM mes_morder WHERE tenant_id=%s AND morder_no=%s", (TENANT, WO_NEW)):
  109. mcols = cols(cur, "mes_morder")
  110. select_exprs = []
  111. extra = []
  112. for c in mcols:
  113. if c == "Id":
  114. select_exprs.append("%s")
  115. extra.append(MES_ID)
  116. elif c == "morder_no":
  117. select_exprs.append("%s")
  118. extra.append(WO_NEW)
  119. elif c == "morder_state":
  120. select_exprs.append("%s")
  121. extra.append("新建")
  122. elif c == "create_by_name":
  123. select_exprs.append("%s")
  124. extra.append("UATA-GAPFILL")
  125. elif c == "update_by_name":
  126. select_exprs.append("%s")
  127. extra.append("UATA-GAPFILL")
  128. elif c in ("create_time", "update_time"):
  129. select_exprs.append("%s")
  130. extra.append(NOW)
  131. else:
  132. select_exprs.append(f"`{c}`")
  133. cur.execute(
  134. f"INSERT INTO mes_morder ({', '.join('`'+c+'`' for c in mcols)}) "
  135. f"SELECT {', '.join(select_exprs)} FROM mes_morder "
  136. f"WHERE tenant_id=%s AND morder_no=%s LIMIT 1",
  137. extra + [TENANT, WO_SRC],
  138. )
  139. return "inserted"
  140. def seed_iqc(cur) -> str:
  141. if exists(cur, "SELECT 1 FROM qms_qcp_inspecapplyn WHERE tenant_id=%s AND FBILLNO=%s", (TENANT, IQC_A01_NO)):
  142. return "exists"
  143. cur.execute(
  144. """
  145. INSERT INTO qms_qcp_inspecapplyn (id, tenant_id, FBILLNO, FBILLTYPE, FAPPLYTIME, FCOMMENT)
  146. VALUES (%s, %s, %s, 'UAT', %s, 'A套UAT合格路径待认领')
  147. """,
  148. (IQC_A01_HDR, TENANT, IQC_A01_NO, NOW),
  149. )
  150. cur.execute(
  151. """
  152. INSERT INTO qms_qcp_insappnentry
  153. (id, tenant_id, glid, FSEQ, FMATERIALCFG, wlmc, FLOTNUMBER, FAPPLYQTY,
  154. FSRCORDERTYPE, FSRCORDERNUM, FSUPPLIER, gysbm, gysmc, FINSPECTSTATUS, jyfzr, shdh)
  155. VALUES
  156. (%s, %s, %s, 1, '3121C0035', '上底(45PUL)', 'UATA-A01-LOT', 100,
  157. 'po', 'UATA-PO-001', 'SUP-A01', 'SUP-A01', 'A01试验供应商', '未检验', NULL, 'UATA-A01-RCV')
  158. """,
  159. (IQC_A01_ENT, TENANT, IQC_A01_HDR),
  160. )
  161. cur.execute(
  162. """
  163. INSERT INTO qms_qcp_inspecapplyn (id, tenant_id, FBILLNO, FBILLTYPE, FAPPLYTIME, FCOMMENT)
  164. VALUES (%s, %s, %s, 'UAT', %s, 'A套UAT不合格路径待认领,勿改已有PASS')
  165. """,
  166. (IQC_A04_HDR, TENANT, IQC_A04_NO, NOW),
  167. )
  168. cur.execute(
  169. """
  170. INSERT INTO qms_qcp_insappnentry
  171. (id, tenant_id, glid, FSEQ, FMATERIALCFG, wlmc, FLOTNUMBER, FAPPLYQTY,
  172. FSRCORDERTYPE, FSRCORDERNUM, FSUPPLIER, gysbm, gysmc, FINSPECTSTATUS, jyfzr, shdh)
  173. VALUES
  174. (%s, %s, %s, 1, '1AB9275', '-IM60IL', 'UATA-A04-LOT', 80,
  175. 'po', 'UATA-PO-004', 'SUP-A04', 'SUP-A04', 'A04试验供应商', '未检验', NULL, 'UATA-A04-RCV')
  176. """,
  177. (IQC_A04_ENT, TENANT, IQC_A04_HDR),
  178. )
  179. return "inserted"
  180. def seed_ipqc(cur) -> str:
  181. if not exists(cur, "SELECT 1 FROM qms_gcjyd WHERE tenant_id=%s AND djbh=%s", (TENANT, IPQC_A01_NO)):
  182. cur.execute(
  183. """
  184. INSERT INTO qms_gcjyd
  185. (id, tenant_id, djbh, cplx, scph, lydjbh, jgpd, jyhgsl, jybhgsl, bz, jyr,
  186. gxbm, gxmc, ybl, sxrq, wlbm, wlmc, title, status)
  187. VALUES
  188. (%s, %s, %s, 'A01产品', 'UATA-A01-BATCH', %s, NULL, NULL, NULL,
  189. 'A套UAT合格路径待提交', NULL, 'OP10', '注塑', 20, %s,
  190. '3121C0035', '上底(45PUL)', 'UAT A01 IPQC', '待检验')
  191. """,
  192. (IPQC_A01_ID, TENANT, IPQC_A01_NO, WO_NEW, NOW),
  193. )
  194. if not exists(cur, "SELECT 1 FROM qms_gcjydzb WHERE id=%s", (IPQC_A01_ZB,)):
  195. cur.execute(
  196. """
  197. INSERT INTO qms_gcjydzb
  198. (id, tenant_id, glid, jyxm, jyyj, jyff, ProcessCode, ProcessName, ybl, jysl, bhgsl, pd)
  199. VALUES
  200. (%s, %s, %s, '外观', '目视无裂纹', '目视', 'OP10', '注塑', 20, NULL, NULL, NULL)
  201. """,
  202. (IPQC_A01_ZB, TENANT, IPQC_A01_ID),
  203. )
  204. cur.execute("SELECT id FROM qms_gcjyd WHERE tenant_id=%s AND djbh=%s", (TENANT, IPQC_A05_NO))
  205. a05 = cur.fetchone()
  206. if a05 and not exists(cur, "SELECT 1 FROM qms_gcjydzb WHERE tenant_id=%s AND glid=%s", (TENANT, a05["id"])):
  207. cur.execute(
  208. """
  209. INSERT INTO qms_gcjydzb
  210. (id, tenant_id, glid, jyxm, jyyj, jyff, ProcessCode, ProcessName, ybl, jysl, bhgsl, pd)
  211. VALUES
  212. (%s, %s, %s, '装配尺寸', '卡尺', '测量', 'OP20', '装配', 20, 20, 2, 0)
  213. """,
  214. (IPQC_A05_ZB, TENANT, a05["id"]),
  215. )
  216. cur.execute(
  217. """
  218. INSERT INTO mdp_std_ipqc_inspection
  219. (tenant_id, factory_id, source_system, bill_no, product_model, production_batch_no,
  220. production_work_order, result_judgement, remark, inspector, process_code, process_name,
  221. sample_qty, material_code, material_name, inspection_status,
  222. source_row_id, source_biz_key, sync_batch_id, sync_time)
  223. SELECT
  224. g.tenant_id, 1, 'AIDOP', g.djbh, g.cplx, g.scph, g.lydjbh,
  225. CAST(g.jgpd AS CHAR), g.bz, g.jyr, g.gxbm, g.gxmc, g.ybl, g.wlbm, g.wlmc, g.status,
  226. CAST(g.id AS CHAR), g.djbh, %s, %s
  227. FROM qms_gcjyd g
  228. WHERE g.tenant_id=%s
  229. AND NOT EXISTS (
  230. SELECT 1 FROM mdp_std_ipqc_inspection s
  231. WHERE s.tenant_id=g.tenant_id AND s.source_row_id=CAST(g.id AS CHAR)
  232. )
  233. """,
  234. (BATCH, NOW, TENANT),
  235. )
  236. return "upserted"
  237. def seed_s8(cur) -> str:
  238. if not exists(
  239. cur,
  240. "SELECT 1 FROM ado_s8_data_source WHERE tenant_id=%s AND factory_id=%s AND data_source_code=%s",
  241. (TENANT, FACTORY, DS_CODE),
  242. ):
  243. cur.execute(
  244. """
  245. INSERT INTO ado_s8_data_source
  246. (tenant_id, factory_id, data_source_code, type, endpoint, auth_type, enabled, created_at, updated_at)
  247. VALUES
  248. (%s, %s, %s, 'SQL', 'aidopdev.local/uat', 'NONE', 1, %s, %s)
  249. """,
  250. (TENANT, FACTORY, DS_CODE, NOW, NOW),
  251. )
  252. cur.execute(
  253. "SELECT id FROM ado_s8_data_source WHERE tenant_id=%s AND factory_id=%s AND data_source_code=%s",
  254. (TENANT, FACTORY, DS_CODE),
  255. )
  256. ds_id = cur.fetchone()["id"]
  257. if not exists(
  258. cur,
  259. "SELECT 1 FROM ado_s8_watch_rule WHERE tenant_id=%s AND factory_id=%s AND rule_code=%s",
  260. (TENANT, FACTORY, RULE_CODE),
  261. ):
  262. cur.execute(
  263. """
  264. INSERT INTO ado_s8_watch_rule
  265. (tenant_id, factory_id, rule_code, scene_code, data_source_id, watch_object_type,
  266. expression, severity, poll_interval_seconds, enabled, created_at, updated_at,
  267. consecutive_failure_count, trigger_count_required, recover_count_required, rule_mechanism)
  268. VALUES
  269. (%s, %s, %s, 'S3', %s, 'ORDER',
  270. 'UATA closed-loop watch', 'HIGH', 300, 1, %s, %s,
  271. 0, 1, 1, 'RULE')
  272. """,
  273. (TENANT, FACTORY, RULE_CODE, ds_id, NOW, NOW),
  274. )
  275. if not exists(
  276. cur,
  277. "SELECT 1 FROM ado_s8_exception WHERE tenant_id=%s AND exception_code=%s",
  278. (TENANT, EX_CODE),
  279. ):
  280. cur.execute(
  281. """
  282. INSERT INTO ado_s8_exception
  283. (tenant_id, factory_id, exception_code, title, description, scene_code, source_type,
  284. status, severity, priority_score, priority_level,
  285. occurrence_dept_id, responsible_dept_id, timeout_flag,
  286. created_at, updated_at, is_deleted,
  287. created_by, updated_by, related_object_code, module_code,
  288. exception_type_code, source_payload, dedup_key,
  289. consecutive_hit_count, consecutive_miss_count, rule_mechanism)
  290. VALUES
  291. (%s, %s, %s, %s, %s, 'S3', 'MANUAL',
  292. 'NEW', 'HIGH', 80, 'P1',
  293. 1, 1, 0,
  294. %s, %s, 0,
  295. 'UATA-GAPFILL', 'UATA-GAPFILL', 'UATA-A03-SO', 'S3',
  296. 'SUPPLIER_ETA_ISSUE', %s, %s,
  297. 1, 0, 'MANUAL')
  298. """,
  299. (
  300. TENANT,
  301. FACTORY,
  302. EX_CODE,
  303. "UATA-A03 供应回复交期异常(待认领)",
  304. "A套UAT主动提报起点,状态NEW,供认领→处理→复检",
  305. NOW,
  306. NOW,
  307. json.dumps({"source": "uata-gapfill", "so": "UATA-A03-SO"}, ensure_ascii=False),
  308. EX_CODE,
  309. ),
  310. )
  311. return "upserted"
  312. def seed_s0(cur) -> str:
  313. if not exists(cur, "SELECT 1 FROM CustMaster WHERE tenant_id=%s AND Cust=%s", (TENANT, CUS_CODE)):
  314. rec_extra = None
  315. cur.execute(
  316. "SELECT EXTRA FROM information_schema.COLUMNS WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME='CustMaster' AND COLUMN_NAME='RecID'"
  317. )
  318. rec_extra = (cur.fetchone() or {}).get("EXTRA") or ""
  319. if "auto_increment" in rec_extra:
  320. cur.execute(
  321. """
  322. INSERT INTO CustMaster
  323. (company_ref_id, factory_ref_id, Domain, Cust, SortName, TaxIn, IsActive, IsConfirm,
  324. CreateUser, CreateTime, UpdateUser, UpdateTime, tenant_id, CustFullName, Remarks)
  325. VALUES
  326. (%s, %s, '2410', %s, 'UATAA01CUS', 0, 1, 1,
  327. 'UATA-GAPFILL', %s, 'UATA-GAPFILL', %s, %s, 'A套UAT客户', 'UAT A01')
  328. """,
  329. (FACTORY, FACTORY, CUS_CODE, NOW, NOW, TENANT),
  330. )
  331. else:
  332. cur.execute("SELECT COALESCE(MAX(RecID),0)+1 AS n FROM CustMaster")
  333. rec = cur.fetchone()["n"]
  334. cur.execute(
  335. """
  336. INSERT INTO CustMaster
  337. (RecID, company_ref_id, factory_ref_id, Domain, Cust, SortName, TaxIn, IsActive, IsConfirm,
  338. CreateUser, CreateTime, UpdateUser, UpdateTime, tenant_id, CustFullName, Remarks)
  339. VALUES
  340. (%s, %s, %s, '2410', %s, 'UATAA01CUS', 0, 1, 1,
  341. 'UATA-GAPFILL', %s, 'UATA-GAPFILL', %s, %s, 'A套UAT客户', 'UAT A01')
  342. """,
  343. (rec, FACTORY, FACTORY, CUS_CODE, NOW, NOW, TENANT),
  344. )
  345. if not exists(cur, "SELECT 1 FROM ado_s0_sales_customer WHERE Code=%s AND CompanyRefId=%s", (CUS_CODE, FACTORY)):
  346. cur.execute(
  347. """
  348. INSERT INTO ado_s0_sales_customer
  349. (Id, CompanyRefId, FactoryRefId, Code, Name, ForbidStatus, IsTaxIncluded, CustomerLevel, IsEnabled, CreatedAt)
  350. VALUES
  351. (%s, %s, %s, %s, 'A套UAT客户', 0, 0, 1, 1, %s)
  352. """,
  353. (S0_CUS_ID, FACTORY, FACTORY, CUS_CODE, NOW),
  354. )
  355. if not exists(cur, "SELECT 1 FROM ado_s0_sales_material WHERE Code=%s AND CompanyRefId=%s", ("3121C0035", FACTORY)):
  356. cur.execute(
  357. """
  358. INSERT INTO ado_s0_sales_material
  359. (Id, CompanyRefId, FactoryRefId, Code, Name,
  360. IsOnDemand, IsInspectionRequired, IsKeyMaterial, IsMainMaterial, IsPreprocess,
  361. IsAutoBatch, IsLabelRequired, IsBatchFifoReminder, IsBatchFifoStrict,
  362. ForbidStatus, IsEnabled, CreatedAt)
  363. VALUES
  364. (%s, %s, %s, '3121C0035', '上底(45PUL)',
  365. 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, %s)
  366. """,
  367. (S0_MAT_ID, FACTORY, FACTORY, NOW),
  368. )
  369. if not exists(cur, "SELECT 1 FROM ado_s0_mfg_bom WHERE Code=%s AND CompanyRefId=%s", ("UATA-A01-BOM", FACTORY)):
  370. cur.execute(
  371. """
  372. INSERT INTO ado_s0_mfg_bom
  373. (Id, CompanyRefId, FactoryRefId, Code, Name, MaterialId, BizVersion, DocStatus, IsEnabled, CreatedAt)
  374. VALUES
  375. (%s, %s, %s, 'UATA-A01-BOM', 'A01标准BOM', %s, '1.0', '生效', 1, %s)
  376. """,
  377. (S0_BOM_ID, FACTORY, FACTORY, S0_MAT_ID, NOW),
  378. )
  379. if not exists(cur, "SELECT 1 FROM ado_s0_mfg_routing WHERE Code=%s AND CompanyRefId=%s", ("UATA-A01-RTE", FACTORY)):
  380. cur.execute(
  381. """
  382. INSERT INTO ado_s0_mfg_routing
  383. (Id, CompanyRefId, FactoryRefId, Code, Name, BizVersion, DocStatus, IsEnabled, CreatedAt)
  384. VALUES
  385. (%s, %s, %s, 'UATA-A01-RTE', 'A01标准工艺', '1.0', '生效', 1, %s)
  386. """,
  387. (S0_RTE_ID, FACTORY, FACTORY, NOW),
  388. )
  389. if not exists(cur, "SELECT 1 FROM ado_s0_mfg_production_line WHERE Code=%s AND CompanyRefId=%s", ("UATA-A01-LINE", FACTORY)):
  390. cur.execute(
  391. """
  392. INSERT INTO ado_s0_mfg_production_line
  393. (Id, CompanyRefId, FactoryRefId, Code, Name, IsEnabled, CreatedAt)
  394. VALUES
  395. (%s, %s, %s, 'UATA-A01-LINE', 'A01产线', 1, %s)
  396. """,
  397. (S0_LINE_ID, FACTORY, FACTORY, NOW),
  398. )
  399. cur.execute(
  400. "SELECT COLUMN_NAME FROM information_schema.COLUMNS WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME='srm_supplier' ORDER BY ORDINAL_POSITION"
  401. )
  402. scols = [r["COLUMN_NAME"] for r in cur.fetchall()]
  403. code_col = next((c for c in ("supplier_code", "code", "Supp", "supplier_no", "FNumber") if c in scols), None)
  404. name_col = next((c for c in ("supplier_name", "name", "SuppName", "fname", "FName") if c in scols), None)
  405. if code_col and name_col and not exists(
  406. cur,
  407. f"SELECT 1 FROM srm_supplier WHERE tenant_id=%s AND `{code_col}`=%s",
  408. (TENANT, "UATA-A01-SUP"),
  409. ):
  410. cur.execute(
  411. f"""
  412. INSERT INTO srm_supplier (Id, tenant_id, IsDeleted, `{code_col}`, `{name_col}`)
  413. VALUES (%s, %s, 0, %s, %s)
  414. """,
  415. (S0_SUP_ID, TENANT, "UATA-A01-SUP", "A01试验供应商"),
  416. )
  417. return "upserted"
  418. def seed_demand(cur) -> str:
  419. if exists(cur, "SELECT 1 FROM ic_demandschedule WHERE tenant_id=%s AND Id=%s", (TENANT, DEMAND_ID)):
  420. return "exists"
  421. if exists(
  422. cur,
  423. "SELECT 1 FROM ic_demandschedule WHERE tenant_id=%s AND itemnum=%s AND IFNULL(status,'')='' AND IFNULL(IsDeleted,0)=0 AND remarks LIKE %s",
  424. (TENANT, "3121C0035", "%UATA-A01%"),
  425. ):
  426. return "exists"
  427. cur.execute(
  428. """
  429. INSERT INTO ic_demandschedule
  430. (Id, itemnum, fversion, requestdate, arrivaldate, shortqty, mesqty, locqty,
  431. sechedqty, tosechedqty, status, remarks, create_by_name, create_time,
  432. tenant_id, factory_id, IsDeleted, wolist)
  433. VALUES
  434. (%s, '3121C0035', '1.0', %s, %s, 50, 0, 0,
  435. 0, 50, '', 'UATA-A01 未发布需求,供勾选发布', 'UATA-GAPFILL', %s,
  436. %s, %s, 0, %s)
  437. """,
  438. (DEMAND_ID, NOW, NOW, NOW, TENANT, FACTORY, WO_NEW),
  439. )
  440. return "inserted"
  441. def verify(cur) -> dict[str, int]:
  442. checks = {
  443. "wo_p": "SELECT COUNT(*) c FROM WorkOrdMaster WHERE tenant_id=%s AND WorkOrd=%s AND LOWER(TRIM(Status))='p'",
  444. "iqc_apply_entry": "SELECT COUNT(*) c FROM qms_qcp_insappnentry WHERE tenant_id=%s",
  445. "ipqc_std": "SELECT COUNT(*) c FROM mdp_std_ipqc_inspection WHERE tenant_id=%s",
  446. "s8_watch_a": "SELECT COUNT(*) c FROM ado_s8_watch_rule WHERE tenant_id=%s AND enabled=1",
  447. "s8_exc_new": "SELECT COUNT(*) c FROM ado_s8_exception WHERE tenant_id=%s AND status='NEW'",
  448. "wo_released": "SELECT COUNT(*) c FROM mes_morder WHERE tenant_id=%s AND IsDeleted=0 AND morder_state='Released'",
  449. "s0_customer": "SELECT COUNT(*) c FROM ado_s0_sales_customer",
  450. "s0_material": "SELECT COUNT(*) c FROM ado_s0_sales_material",
  451. "s0_bom": "SELECT COUNT(*) c FROM ado_s0_mfg_bom",
  452. "s0_routing": "SELECT COUNT(*) c FROM ado_s0_mfg_routing",
  453. "cust_picker": "SELECT COUNT(*) c FROM CustMaster WHERE tenant_id=%s",
  454. "demand_writable": "SELECT COUNT(*) c FROM ic_demandschedule WHERE tenant_id=%s AND IFNULL(IsDeleted,0)=0",
  455. }
  456. out: dict[str, int] = {}
  457. for k, sql in checks.items():
  458. args = (TENANT,) if "%s" in sql else ()
  459. if k == "wo_p":
  460. args = (TENANT, WO_NEW)
  461. cur.execute(sql, args)
  462. out[k] = int(cur.fetchone()["c"])
  463. return out
  464. def main() -> None:
  465. conn = connect()
  466. result: dict[str, Any] = {"tenant": TENANT, "factory": FACTORY, "batch": BATCH}
  467. try:
  468. conn.autocommit(False)
  469. conn.begin()
  470. with conn.cursor() as cur:
  471. result["wo"] = clone_work_order(cur)
  472. result["iqc"] = seed_iqc(cur)
  473. result["ipqc"] = seed_ipqc(cur)
  474. result["s8"] = seed_s8(cur)
  475. result["s0"] = seed_s0(cur)
  476. result["demand"] = seed_demand(cur)
  477. result["verify"] = verify(cur)
  478. conn.commit()
  479. except Exception:
  480. conn.rollback()
  481. raise
  482. finally:
  483. conn.close()
  484. print(json.dumps(result, ensure_ascii=False, indent=2, default=str))
  485. if __name__ == "__main__":
  486. main()