S4ReadPathConsistencyService.cs 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. namespace Admin.NET.Plugin.AiDOP.Supply;
  2. /// <summary>S4 采购闭环后读路径一致性检查(运行表 vs DWD)。</summary>
  3. public class S4ReadPathConsistencyService : ITransient
  4. {
  5. private readonly ISqlSugarClient _db;
  6. public S4ReadPathConsistencyService(ISqlSugarClient db)
  7. {
  8. _db = db;
  9. }
  10. public async Task<S4ReadPathConsistencyResult> CheckTenantAsync(long tenantId)
  11. {
  12. var runtimePr = await CountAsync(
  13. """
  14. SELECT COUNT(*) FROM srm_pr_main
  15. WHERE tenant_id = @TenantId AND IFNULL(IsDeleted, 0) = 0
  16. """,
  17. tenantId);
  18. var runtimePo = await CountAsync(
  19. """
  20. SELECT COUNT(*) FROM PurOrdMaster
  21. WHERE tenant_id = @TenantId AND IFNULL(IsActive, 1) = 1
  22. """,
  23. tenantId);
  24. var runtimeDelivery = await CountAsync(
  25. """
  26. SELECT COUNT(*) FROM srm_polist_ds
  27. WHERE tenant_id = @TenantId AND IFNULL(isactive, 1) = 1
  28. """,
  29. tenantId);
  30. var dwdExecution = await SafeCountAsync(
  31. """
  32. SELECT COUNT(*) FROM dwd_s4_purchase_execution
  33. WHERE tenant_id = @TenantId
  34. """,
  35. tenantId);
  36. var dwdPoTrans = await SafeCountAsync(
  37. """
  38. SELECT COUNT(*) FROM dwd_po_trans
  39. WHERE tenant_id = @TenantId
  40. """,
  41. tenantId);
  42. var dwdDelivery = await SafeCountAsync(
  43. """
  44. SELECT COUNT(*) FROM dwd_supplier_delivery
  45. WHERE tenant_id = @TenantId
  46. """,
  47. tenantId);
  48. var checks = new List<S4ReadPathCheckItem>
  49. {
  50. BuildCheck("runtime_pr", runtimePr, null, runtimePr >= 0),
  51. BuildCheck("runtime_po", runtimePo, dwdPoTrans, dwdPoTrans is null || runtimePo <= dwdPoTrans + 50),
  52. BuildCheck("runtime_delivery", runtimeDelivery, dwdDelivery, dwdDelivery is null || runtimeDelivery <= dwdDelivery + 50),
  53. BuildCheck("dwd_purchase_execution", runtimePo, dwdExecution, dwdExecution is null || dwdExecution > 0 || runtimePo == 0)
  54. };
  55. return new S4ReadPathConsistencyResult
  56. {
  57. TenantId = tenantId,
  58. Checks = checks,
  59. Ok = checks.All(x => x.Ok)
  60. };
  61. }
  62. private static S4ReadPathCheckItem BuildCheck(string name, int runtime, int? dwd, bool ok) =>
  63. new()
  64. {
  65. Name = name,
  66. RuntimeCount = runtime,
  67. DwdCount = dwd,
  68. Ok = ok
  69. };
  70. private async Task<int> CountAsync(string sql, long tenantId) =>
  71. await _db.Ado.GetIntAsync(sql, new SugarParameter("@TenantId", tenantId));
  72. private async Task<int?> SafeCountAsync(string sql, long tenantId)
  73. {
  74. try
  75. {
  76. return await CountAsync(sql, tenantId);
  77. }
  78. catch
  79. {
  80. return null;
  81. }
  82. }
  83. }
  84. public sealed class S4ReadPathConsistencyResult
  85. {
  86. public long TenantId { get; set; }
  87. public bool Ok { get; set; }
  88. public List<S4ReadPathCheckItem> Checks { get; set; } = new();
  89. }
  90. public sealed class S4ReadPathCheckItem
  91. {
  92. public string Name { get; set; } = string.Empty;
  93. public int RuntimeCount { get; set; }
  94. public int? DwdCount { get; set; }
  95. public bool Ok { get; set; }
  96. }