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));
}
}