namespace Admin.NET.Plugin.AiDOP.MaterialWarehouse.InventoryPosting.Receipt; /// /// MRB 挑选(IQC ②⑤)任务服务。据 Phase 6A/6C:挑选分支 **不进 C5 库存过账**,只创建 /// `PurOrdRctByMRBChoose` 移动任务(LIVE pr_WMS_SaveIQCResult L270-281,PartRctFlag=1 后 goto IQCEnd)。 /// 与 分离,避免让挑选强行进入 Inventory Posting。 /// 幂等由 TaskID(=QCNbr) 的 DB UNIQUE 兜底。 /// public sealed class IqcMrbSelectionTaskService { private readonly IIqcReceiptUnitOfWorkFactory _factory; public IqcMrbSelectionTaskService(IIqcReceiptUnitOfWorkFactory factory) { _factory = factory ?? throw new ArgumentNullException(nameof(factory)); } public async Task PostAsync(IqcMrbSelectionCommand m) { if (m == null) throw new ArgumentNullException(nameof(m)); await using var uow = _factory.Create(); try { await uow.BeginAsync(m.TenantId, m.DomainCode); // 任务-only:仅开事务,无库存锁 await uow.WriteMobileTaskAsync(MobileTaskBuilder.MrbChoose(m)); // 无 C5/C6 // Phase 7C A3:完成锚(与任务同事务提交)——闭合 commit→MarkPosted 崩溃窗口 await uow.WriteCompletionAsync(new IqcCompletionMarker { TenantId = m.TenantId, DomainCode = m.DomainCode, FbillNo = m.Fbillno, PostingId = m.PostingId, RouteKind = "MrbChoose", }); await uow.CommitAsync(); return new IqcReceiptResult { Outcome = IqcReceiptOutcome.Success, WrittenRows = 1, LegacyReturnMsg = "保存成功" }; } catch (Exception ex) { try { await uow.RollbackAsync(); } catch { } return new IqcReceiptResult { Outcome = IqcReceiptOutcome.Error, WrittenRows = 0, Reason = ex.Message, LegacyReturnMsg = "保存失败," + (ex.Message ?? string.Empty) }; } } }