patch_pr3_api_calls.py 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. #!/usr/bin/env python3
  2. """为 quote/contract 路由 CRUD 调用补全 user_info=user_info。"""
  3. from __future__ import annotations
  4. import re
  5. from pathlib import Path
  6. ROOT = Path(__file__).resolve().parents[1]
  7. QUOTE_FUNCS = (
  8. "get_quote_detail",
  9. "update_quote",
  10. "soft_delete_quotes",
  11. "submit_quote",
  12. "save_template",
  13. "get_template",
  14. "generate_pdf",
  15. "generate_share",
  16. "accept_quote",
  17. "reject_quote",
  18. "to_contract",
  19. "create_new_version",
  20. "query_versions",
  21. "withdraw_quote_approval",
  22. "invalid_quote",
  23. "statistics_overview",
  24. "statistics_status",
  25. "statistics_trend",
  26. "list_quote_approvals",
  27. "approve_quote",
  28. "withdraw_approval",
  29. "refresh_approver_names",
  30. "list_quote_products",
  31. "insert_quote_product",
  32. "update_quote_product",
  33. "soft_delete_quote_products",
  34. "list_share_logs",
  35. "share_log_statistics",
  36. )
  37. CONTRACT_FUNCS = (
  38. "get_contract_detail",
  39. "get_contract",
  40. "update_contract",
  41. "soft_delete_contracts",
  42. "submit_contract_approval",
  43. "withdraw_contract_approval",
  44. "sign_contract",
  45. "start_execute",
  46. "finish_contract",
  47. "invalid_contract",
  48. "renew_contract",
  49. "batch_assign_owner",
  50. "batch_submit_contract_approval",
  51. "upload_attachments",
  52. "upload_attachments_with_category",
  53. "upload_file",
  54. "save_template",
  55. "get_template",
  56. "download_contract_pdf",
  57. "create_from_quote",
  58. "create_from_opportunity",
  59. "export_contracts",
  60. "query_expiring",
  61. "statistics_overview",
  62. "statistics_by_status",
  63. "statistics_by_type",
  64. "statistics_trend",
  65. "list_contract_approvals",
  66. "approve_contract_by_contract_id",
  67. "list_contract_changes",
  68. "get_contract_change_detail",
  69. "update_contract_change",
  70. "soft_delete_contract_changes",
  71. "list_contract_templates",
  72. "update_contract_template",
  73. "soft_delete_contract_templates",
  74. )
  75. def _add_user_info_kwarg(content: str, func_names: tuple[str, ...]) -> str:
  76. for fn in func_names:
  77. pattern = rf"({re.escape(fn)}\([^)]*?)(\n\s*\))"
  78. while True:
  79. m = re.search(pattern, content, re.DOTALL)
  80. if not m:
  81. break
  82. call = m.group(1)
  83. if "user_info=" in call:
  84. content = content[: m.start()] + call + m.group(2) + content[m.end() :]
  85. break
  86. new_call = call.rstrip() + ",\n user_info=user_info,"
  87. content = content[: m.start()] + new_call + m.group(2) + content[m.end() :]
  88. return content
  89. def patch_file(rel: str, funcs: tuple[str, ...]):
  90. path = ROOT / rel
  91. c = path.read_text()
  92. if "crm_user_info" not in c:
  93. c = c.replace(
  94. "from app.core.tenant_context import get_tenant_no\n",
  95. "from app.core.tenant_context import get_tenant_no\n"
  96. "from app.crud.crm.data_scope_helpers import crm_user_info\n",
  97. )
  98. c2 = _add_user_info_kwarg(c, funcs)
  99. path.write_text(c2)
  100. print(f"patched {rel}")
  101. if __name__ == "__main__":
  102. patch_file("app/api/crm_quote_routes.py", QUOTE_FUNCS)
  103. patch_file("app/api/crm_contract_routes.py", CONTRACT_FUNCS)
  104. sub = ROOT / "app/api/crm_contract_sub_routes.py"
  105. if sub.exists():
  106. patch_file("app/api/crm_contract_sub_routes.py", CONTRACT_FUNCS)