WorkOrderMaterialDetailSyncService.cs 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. namespace Admin.NET.Plugin.AiDOP.WorkOrder;
  2. /// <summary>从资源检查结果同步工单物料明细(WorkOrdDetail)。</summary>
  3. public class WorkOrderMaterialDetailSyncService : ITransient
  4. {
  5. private readonly ISqlSugarClient _db;
  6. public WorkOrderMaterialDetailSyncService(ISqlSugarClient db)
  7. {
  8. _db = db;
  9. }
  10. public async Task<int> EnsureFromResourceCheckAsync(long tenantId, string workOrd, string account)
  11. {
  12. var existing = await _db.Ado.GetIntAsync(
  13. """
  14. SELECT COUNT(*) FROM WorkOrdDetail
  15. WHERE tenant_id = @TenantId AND WorkOrd = @WorkOrd AND IFNULL(IsActive, 0) = 1
  16. """,
  17. new SugarParameter("@TenantId", tenantId),
  18. new SugarParameter("@WorkOrd", workOrd));
  19. if (existing > 0)
  20. return 0;
  21. var wo = await LoadWorkOrderAsync(tenantId, workOrd);
  22. if (wo is null)
  23. return 0;
  24. var components = await LoadResourceCheckComponentsAsync(tenantId, workOrd);
  25. if (components.Count == 0)
  26. return 0;
  27. var now = DateTime.Now;
  28. var line = 1;
  29. foreach (var c in components)
  30. {
  31. await _db.Ado.ExecuteCommandAsync(
  32. """
  33. INSERT INTO WorkOrdDetail (
  34. WorkOrdMasterRecID, `Domain`, WorkOrd, LineNum, ItemNum, Op,
  35. Location, QtyRequired, QtyPosted, UM, IsActive, IsConfirm,
  36. CreateUser, CreateTime, UpdateUser, UpdateTime, tenant_id
  37. ) VALUES (
  38. @MasterRecId, @Domain, @WorkOrd, @LineNum, @ItemNum, @Op,
  39. @Location, @QtyRequired, 0, @UM, 1, 0,
  40. @User, @Now, @User, @Now, @TenantId
  41. )
  42. """,
  43. new SugarParameter("@MasterRecId", wo.RecId),
  44. new SugarParameter("@Domain", wo.Domain ?? tenantId.ToString()),
  45. new SugarParameter("@WorkOrd", workOrd),
  46. new SugarParameter("@LineNum", line),
  47. new SugarParameter("@ItemNum", c.ItemNumber),
  48. new SugarParameter("@Op", c.Op),
  49. new SugarParameter("@Location", c.Location ?? (object)DBNull.Value),
  50. new SugarParameter("@QtyRequired", c.QtyRequired),
  51. new SugarParameter("@UM", c.Unit ?? (object)DBNull.Value),
  52. new SugarParameter("@User", account),
  53. new SugarParameter("@Now", now),
  54. new SugarParameter("@TenantId", tenantId));
  55. line++;
  56. }
  57. return components.Count;
  58. }
  59. private async Task<WorkOrderRow?> LoadWorkOrderAsync(long tenantId, string workOrd)
  60. {
  61. var rows = await _db.Ado.SqlQueryAsync<WorkOrderRow>(
  62. """
  63. SELECT RecID AS RecId, `Domain`, ItemNum
  64. FROM WorkOrdMaster
  65. WHERE tenant_id = @TenantId AND WorkOrd = @WorkOrd
  66. LIMIT 1
  67. """,
  68. new SugarParameter("@TenantId", tenantId),
  69. new SugarParameter("@WorkOrd", workOrd));
  70. return rows.FirstOrDefault();
  71. }
  72. private async Task<List<ComponentRow>> LoadResourceCheckComponentsAsync(long tenantId, string workOrd)
  73. {
  74. return await _db.Ado.SqlQueryAsync<ComponentRow>(
  75. """
  76. SELECT
  77. bce.item_number AS ItemNumber,
  78. CASE
  79. WHEN IFNULL(bce.use_qty, 0) > 0 THEN bce.use_qty
  80. ELSE IFNULL(bce.needCount, 0)
  81. END AS QtyRequired,
  82. IFNULL(bce.unit, im.Um) AS Unit,
  83. IFNULL(im.Location, '') AS Location,
  84. IFNULL(bce.Op, 0) AS Op
  85. FROM b_examine_result ber
  86. INNER JOIN b_bom_child_examine bce ON ber.Id = bce.examine_id AND bce.is_use = 1
  87. LEFT JOIN ItemMaster im ON bce.item_number = im.ItemNum
  88. WHERE ber.tenant_id = @TenantId
  89. AND ber.IsDeleted = 0
  90. AND ber.morder_no = @WorkOrd
  91. AND ber.Id = (
  92. SELECT br.Id FROM b_examine_result br
  93. WHERE br.tenant_id = @TenantId AND br.morder_no = @WorkOrd AND br.IsDeleted = 0
  94. ORDER BY br.create_time DESC LIMIT 1
  95. )
  96. AND IFNULL(bce.num, '') <> '1'
  97. AND IFNULL(bce.backflush, 0) = 0
  98. AND IFNULL(bce.erp_cls, 3) <> 4
  99. AND (
  100. IFNULL(bce.use_qty, 0) > 0
  101. OR IFNULL(bce.needCount, 0) > 0
  102. )
  103. ORDER BY bce.id
  104. """,
  105. new SugarParameter("@TenantId", tenantId),
  106. new SugarParameter("@WorkOrd", workOrd));
  107. }
  108. private sealed class WorkOrderRow
  109. {
  110. public long RecId { get; set; }
  111. public string? Domain { get; set; }
  112. public string? ItemNum { get; set; }
  113. }
  114. private sealed class ComponentRow
  115. {
  116. public string ItemNumber { get; set; } = string.Empty;
  117. public decimal QtyRequired { get; set; }
  118. public string? Unit { get; set; }
  119. public string? Location { get; set; }
  120. public int Op { get; set; }
  121. }
  122. }