using Yitter.IdGenerator; namespace Admin.NET.Plugin.AiDOP.Order; /// 将资源检查结果写入 b_examine_result / b_bom_child_examine。 public class ResourceCheckResultWriter : ITransient { private readonly ISqlSugarClient _db; public ResourceCheckResultWriter(ISqlSugarClient db) { _db = db; } public async Task WriteAsync( OrderWorkOrderGenerationService.OrderHeader order, OrderWorkOrderGenerationService.OrderEntryLine entry, string workOrd, long? morderId, IReadOnlyList lines, string account, DateTime now) { await InvalidatePreviousAsync(entry.Id, entry.TenantId, now); var examineId = YitIdHelper.NextId(); var needQty = entry.Qty ?? 0; var needTime = entry.SysCapacityDate ?? entry.PlanDate ?? now; var kittingTime = lines .Where(x => x.IsUse == 1 && x.LackQty > 0) .Select(x => x.KittingTime) .DefaultIfEmpty(needTime) .Max(); var factoryId = entry.FactoryId ?? order.FactoryId ?? entry.TenantId; var companyId = entry.CompanyId ?? factoryId; await _db.Ado.ExecuteCommandAsync( """ INSERT INTO b_examine_result ( Id, sorderid, bill_no, sentry_id, entry_seq, morder_id, morder_no, bom_number, need_qty, need_time, earliest_times, latest_times, order_statr_time, kitting_times, sys_capacity_date, sys_material_date, create_by_name, create_time, update_by_name, update_time, tenant_id, factory_id, company_id, IsDeleted ) VALUES ( @Id, @SorderId, @BillNo, @SentryId, @EntrySeq, @MorderId, @MorderNo, @BomNumber, @NeedQty, @NeedTime, @NeedTime, @NeedTime, @NeedTime, @KittingTime, @NeedTime, @KittingTime, @User, @Now, @User, @Now, @TenantId, @FactoryId, @CompanyId, 0 ) """, new SugarParameter("@Id", examineId), new SugarParameter("@SorderId", order.Id), new SugarParameter("@BillNo", order.BillNo ?? entry.BillNo ?? string.Empty), new SugarParameter("@SentryId", entry.Id), new SugarParameter("@EntrySeq", entry.EntrySeq ?? 0), new SugarParameter("@MorderId", morderId ?? (object)DBNull.Value), new SugarParameter("@MorderNo", workOrd), new SugarParameter("@BomNumber", entry.BomNumber ?? (object)DBNull.Value), new SugarParameter("@NeedQty", needQty), new SugarParameter("@NeedTime", needTime), new SugarParameter("@KittingTime", kittingTime ?? needTime), new SugarParameter("@User", account), new SugarParameter("@Now", now), new SugarParameter("@TenantId", entry.TenantId), new SugarParameter("@FactoryId", factoryId), new SugarParameter("@CompanyId", companyId)); var activeLines = lines.Where(x => x.IsUse == 1).ToList(); foreach (var line in activeLines) { var childId = YitIdHelper.NextId(); await _db.Ado.ExecuteCommandAsync( """ INSERT INTO b_bom_child_examine ( Id, examine_id, fid, parent_id, bom_child_id, bom_number, item_number, level, sentry_id, num, type, item_name, model, unit, erp_cls, erp_cls_name, backflush, qty, sqty, use_qty, self_lack_qty, lack_qty, mo_qty, make_qty, purchase_qty, purchase_occupy_qty, kitting_time, satisfy_time, isbom, haveicsubs, substitute_code, needCount, needCountNoloss, wastage, scrap, is_use, Op, create_by_name, create_time, update_by_name, update_time, tenant_id, factory_id, company_id, IsDeleted ) VALUES ( @Id, @ExamineId, @Fid, @ParentId, @BomChildId, @BomNumber, @ItemNumber, @Level, @SentryId, @Num, @Type, @ItemName, @Model, @Unit, @ErpCls, @ErpClsName, @Backflush, @Qty, @Sqty, @UseQty, @SelfLackQty, @LackQty, @MoQty, @MakeQty, @PurchaseQty, @PurchaseOccupyQty, @KittingTime, @SatisfyTime, @IsBom, @HaveIcSubs, @SubstituteCode, @NeedCount, @NeedCountNoLoss, @Wastage, @Scrap, 1, 0, @User, @Now, @User, @Now, @TenantId, @FactoryId, @CompanyId, 0 ) """, new SugarParameter("@Id", childId), new SugarParameter("@ExamineId", examineId), new SugarParameter("@Fid", line.Fid), new SugarParameter("@ParentId", line.ParentFid ?? (object)DBNull.Value), new SugarParameter("@BomChildId", line.BomChildId ?? (object)DBNull.Value), new SugarParameter("@BomNumber", line.BomNumber ?? (object)DBNull.Value), new SugarParameter("@ItemNumber", line.ItemNumber), new SugarParameter("@Level", line.Level), new SugarParameter("@SentryId", entry.Id), new SugarParameter("@Num", line.Num), new SugarParameter("@Type", line.Type), new SugarParameter("@ItemName", line.ItemName ?? (object)DBNull.Value), new SugarParameter("@Model", line.Model ?? (object)DBNull.Value), new SugarParameter("@Unit", line.Unit ?? (object)DBNull.Value), new SugarParameter("@ErpCls", line.ErpCls), new SugarParameter("@ErpClsName", line.ErpClsName ?? (object)DBNull.Value), new SugarParameter("@Backflush", line.Backflush), new SugarParameter("@Qty", line.Qty), new SugarParameter("@Sqty", line.Sqty), new SugarParameter("@UseQty", line.UseQty), new SugarParameter("@SelfLackQty", line.SelfLackQty), new SugarParameter("@LackQty", line.LackQty), new SugarParameter("@MoQty", line.MoQty), new SugarParameter("@MakeQty", line.MakeQty), new SugarParameter("@PurchaseQty", line.PurchaseQty), new SugarParameter("@PurchaseOccupyQty", line.PurchaseOccupyQty), new SugarParameter("@KittingTime", line.KittingTime ?? needTime), new SugarParameter("@SatisfyTime", line.SatisfyTime ?? needTime), new SugarParameter("@IsBom", line.IsBom), new SugarParameter("@HaveIcSubs", line.HaveIcSubs), new SugarParameter("@SubstituteCode", line.SubstituteCode ?? (object)DBNull.Value), new SugarParameter("@NeedCount", line.NeedCount), new SugarParameter("@NeedCountNoLoss", line.NeedCountNoLoss), new SugarParameter("@Wastage", line.Wastage), new SugarParameter("@Scrap", line.Scrap), new SugarParameter("@User", account), new SugarParameter("@Now", now), new SugarParameter("@TenantId", entry.TenantId), new SugarParameter("@FactoryId", factoryId), new SugarParameter("@CompanyId", companyId)); } var hasShortage = activeLines.Any(x => x.LackQty > 0); await UpdateMesMorderMaterialSituationAsync(workOrd, entry.TenantId, hasShortage, account, now); return new OrderResourceCheckResult { ExamineId = examineId, LineCount = activeLines.Count, HasShortage = hasShortage, KittingTime = kittingTime }; } private async Task InvalidatePreviousAsync(long entryId, long tenantId, DateTime now) { var oldIds = await _db.Ado.SqlQueryAsync( """ SELECT Id FROM b_examine_result WHERE sentry_id = @EntryId AND tenant_id = @TenantId AND IsDeleted = 0 """, new SugarParameter("@EntryId", entryId), new SugarParameter("@TenantId", tenantId)); if (oldIds.Count == 0) return; foreach (var examineId in oldIds) { await _db.Ado.ExecuteCommandAsync( """ UPDATE b_bom_child_examine SET is_use = 0, update_time = @Now WHERE examine_id = @ExamineId """, new SugarParameter("@ExamineId", examineId), new SugarParameter("@Now", now)); } await _db.Ado.ExecuteCommandAsync( """ UPDATE b_examine_result SET IsDeleted = 1, update_time = @Now WHERE sentry_id = @EntryId AND tenant_id = @TenantId AND IsDeleted = 0 """, new SugarParameter("@EntryId", entryId), new SugarParameter("@TenantId", tenantId), new SugarParameter("@Now", now)); } private async Task UpdateMesMorderMaterialSituationAsync( string workOrd, long tenantId, bool hasShortage, string account, DateTime now) { var situation = hasShortage ? "缺料" : "齐套"; await _db.Ado.ExecuteCommandAsync( """ UPDATE mes_morder SET MaterialSituation = @Situation, update_by_name = @User, update_time = @Now WHERE morder_no = @WorkOrd AND tenant_id = @TenantId AND IsDeleted = 0 """, new SugarParameter("@Situation", situation), new SugarParameter("@User", account), new SugarParameter("@Now", now), new SugarParameter("@WorkOrd", workOrd), new SugarParameter("@TenantId", tenantId)); } }