| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778 |
- namespace Admin.NET.Plugin.AiDOP.MaterialWarehouse.InventoryPosting.Inventory;
- /// <summary>C5 前置守卫代码(LIVE pr_SFM_InventoryTransactionProcessing2 实核 9 道)。</summary>
- public enum InventoryGuardCode
- {
- /// <summary>G1 进销存数据重复(基础数据 fan-out)。</summary>
- DuplicateBaseData = 1,
- /// <summary>G2 物料无基础资料(ItemMaster)。</summary>
- ItemMasterMissing = 2,
- /// <summary>G3 库位未维护(LocationMaster)。</summary>
- LocationMasterMissing = 3,
- /// <summary>G4 物料_库位无库存(InvMaster)——净出库前置。</summary>
- InvMasterMissing = 4,
- /// <summary>G5 物料_库位[_批次]无库存(LocationDetail)——净出库前置。</summary>
- LocationDetailMissing = 5,
- /// <summary>G6 解冻数 > 冻结库存(inv-unfrz)。</summary>
- UnfreezeExceedsFreeze = 6,
- /// <summary>G7 冻结数 > 非限制库存(inv-frz)。</summary>
- FreezeExceedsAvail = 7,
- /// <summary>G8 质检过账数 > 质检库存(iss-tr-ins)——旧总结遗漏。</summary>
- AssayIssueExceedsAssay = 8,
- /// <summary>G9 出库数 > 非限制库存(其它 TransType)。</summary>
- IssueExceedsAvail = 9,
- }
- /// <summary>单条守卫错误(结构化,非仅中文串;保留 LIVE ReturnMsg 语义供对账)。</summary>
- public sealed class InventoryGuardError
- {
- public InventoryGuardCode Code { get; set; }
- public string Message { get; set; }
- public string ItemNum { get; set; }
- public string Location { get; set; }
- public string LotSerial { get; set; }
- }
- /// <summary>
- /// C5 库存上下文快照(守卫与写入的输入;由 store 加载,测试可 fake)。
- /// 余额取自 DOP-L3(ado_inventory_master / ado_inventory_location_detail)变动前值;
- /// 存在性取自主数据(ItemMaster/LocationMaster,态①/②只读)。
- /// </summary>
- public sealed class InventoryContext
- {
- public bool IsLotControl { get; set; }
- /// <summary>G1:加载时任一键 fan-out(一条命令匹配到多行基础数据)。</summary>
- public bool HasDuplicateBaseData { get; set; }
- public HashSet<string> Items { get; } = new(StringComparer.Ordinal);
- public HashSet<string> Locations { get; } = new(StringComparer.Ordinal);
- /// <summary>InvMaster 变动前余额,键 = item|loc(存在性 = ContainsKey)。</summary>
- public Dictionary<string, InventoryBalance> InvMasters { get; } = new(StringComparer.Ordinal);
- /// <summary>LocationDetail 变动前余额,键 = item|loc|lot|refs。</summary>
- public Dictionary<string, InventoryBalance> LocationDetails { get; } = new(StringComparer.Ordinal);
- /// <summary>item → 当前默认库位(ItemMaster.Location 等价;空串/缺失=未落位)。</summary>
- public Dictionary<string, string> ItemDefaultLocation { get; } = new(StringComparer.Ordinal);
- public static string InvKey(string item, string loc) => (item ?? "") + "|" + (loc ?? "");
- public static string DetailKey(string item, string loc, string lot, string refs)
- => (item ?? "") + "|" + (loc ?? "") + "|" + (lot ?? "") + "|" + (refs ?? "");
- public bool ItemExists(string item) => Items.Contains(item ?? "");
- public bool LocationExists(string loc) => Locations.Contains(loc ?? "");
- public bool HasInvMaster(string item, string loc) => InvMasters.ContainsKey(InvKey(item, loc));
- /// <summary>取 InvMaster 变动前余额;缺失返回 null。</summary>
- public InventoryBalance GetInvMaster(string item, string loc)
- => InvMasters.TryGetValue(InvKey(item, loc), out var b) ? b : null;
- /// <summary>取 LocationDetail 变动前余额;缺失返回 null。</summary>
- public InventoryBalance GetLocationDetail(string item, string loc, string lot, string refs)
- => LocationDetails.TryGetValue(DetailKey(item, loc, lot, refs), out var b) ? b : null;
- public string GetItemDefaultLocation(string item)
- => ItemDefaultLocation.TryGetValue(item ?? "", out var l) ? (l ?? "") : "";
- }
|