run_approval_flow_tenant_isolate.py 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. #!/usr/bin/env python3
  2. """Stamp and clone ApprovalFlow definitions so each operational tenant has its own published set.
  3. No global TenantId=NULL fallback after this. Idempotent.
  4. """
  5. from __future__ import annotations
  6. import json
  7. from datetime import datetime
  8. from apply_sql_file import connect
  9. TENANTS = (
  10. (838257186181189, 838257186320453, "UATA"),
  11. (838257212780613, 838257212858437, "UATB"),
  12. (838257237606469, 838257237676101, "DEMO"),
  13. )
  14. BIZ_TYPES = (
  15. "CONTRACT_REVIEW",
  16. "ORDER_REVIEW",
  17. "ORDER_CHANGE_REVIEW",
  18. "EXCEPTION_REPORT",
  19. "EXCEPTION_ESCALATION",
  20. "EXCEPTION_CLOSURE",
  21. "MATERIAL_SHORTAGE",
  22. "S5_IQC_INSPBILL",
  23. "IPQC_INSPECTION",
  24. "S7_FQC_INSPBILL",
  25. "SMART_OPS_IMPROVEMENT",
  26. )
  27. ID_BASE = 9206082610000000
  28. def main() -> None:
  29. conn = connect()
  30. conn.autocommit(False)
  31. result = {"stamped": 0, "cloned": []}
  32. try:
  33. with conn.cursor() as cur:
  34. cur.execute(
  35. """
  36. UPDATE ApprovalFlow f
  37. INNER JOIN SysOrg o ON o.Id = f.OrgId
  38. SET f.TenantId = o.TenantId
  39. WHERE (f.TenantId IS NULL OR f.TenantId = 0)
  40. AND f.OrgId > 0
  41. AND o.TenantId IS NOT NULL
  42. AND o.TenantId > 0
  43. """
  44. )
  45. result["stamped"] = cur.rowcount
  46. next_id = ID_BASE
  47. now = datetime.now().replace(microsecond=0)
  48. for tenant_id, org_id, prefix in TENANTS:
  49. for biz in BIZ_TYPES:
  50. cur.execute(
  51. """
  52. SELECT Id FROM ApprovalFlow
  53. WHERE TenantId=%s AND BizType=%s AND IsPublished=1 AND IFNULL(IsDelete,0)=0
  54. LIMIT 1
  55. """,
  56. (tenant_id, biz),
  57. )
  58. if cur.fetchone():
  59. continue
  60. cur.execute(
  61. """
  62. SELECT Id, Code, Name FROM ApprovalFlow
  63. WHERE BizType=%s AND IsPublished=1 AND IFNULL(IsDelete,0)=0
  64. AND (BizType NOT LIKE 'E2E%%')
  65. ORDER BY CASE WHEN TenantId IS NOT NULL AND TenantId>0 THEN 0 ELSE 1 END,
  66. Version DESC, Id DESC
  67. LIMIT 1
  68. """,
  69. (biz,),
  70. )
  71. src = cur.fetchone()
  72. if not src:
  73. result["cloned"].append({"tenant": prefix, "biz": biz, "status": "no-source"})
  74. continue
  75. new_id = next_id
  76. next_id += 1
  77. new_code = f"{prefix}-{src['Code']}"[:64]
  78. cur.execute(
  79. "SELECT 1 FROM ApprovalFlow WHERE Code=%s AND TenantId=%s LIMIT 1",
  80. (new_code, tenant_id),
  81. )
  82. if cur.fetchone():
  83. result["cloned"].append({"tenant": prefix, "biz": biz, "status": "code-exists"})
  84. continue
  85. cur.execute(
  86. """
  87. INSERT INTO ApprovalFlow
  88. (Id, Code, Name, FormJson, FlowJson, Status, Remark, BizType,
  89. Version, IsPublished, OrgId, TenantId, CreateTime, UpdateTime,
  90. CreateUserName, IsDelete)
  91. SELECT
  92. %s, %s, Name, FormJson, FlowJson, Status, Remark, BizType,
  93. Version, 1, %s, %s, %s, %s,
  94. 'TENANT-ISOLATE', 0
  95. FROM ApprovalFlow WHERE Id=%s
  96. """,
  97. (new_id, new_code, org_id, tenant_id, now, now, src["Id"]),
  98. )
  99. result["cloned"].append(
  100. {
  101. "tenant": prefix,
  102. "biz": biz,
  103. "status": "cloned",
  104. "from": src["Code"],
  105. "to": new_code,
  106. "id": new_id,
  107. }
  108. )
  109. cur.execute(
  110. """
  111. SELECT TenantId, COUNT(*) c FROM ApprovalFlow
  112. WHERE IFNULL(IsDelete,0)=0 AND IsPublished=1
  113. AND TenantId IN (838257186181189,838257212780613,838257237606469)
  114. GROUP BY TenantId
  115. """
  116. )
  117. result["publishedByTenant"] = cur.fetchall()
  118. conn.commit()
  119. except Exception:
  120. conn.rollback()
  121. raise
  122. finally:
  123. conn.close()
  124. print(json.dumps(result, ensure_ascii=False, indent=2, default=str))
  125. if __name__ == "__main__":
  126. main()