| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112 |
- namespace Admin.NET.Plugin.AiDOP.MaterialWarehouse.InventoryPosting;
- /// <summary>
- /// IQC 来料检验结果 → WMS 入库路由的纯逻辑映射(C1 · 路线 B 服务化重写)。
- ///
- /// 契约来源:dopdemorq 旧 LIVE 链真定义(**非死码 check 版**):
- /// 入口 dbo.qms_WMS_SaveIQCResult(5 个 (pd,clfs) 分支,逐分支转换 QCStatus/MRBStatus/QtyAcc/QtyReject)
- /// → dbo.pr_WMS_SaveIQCResult(据 @Barcodes=''/@Shelf='' 固定入参推导 PartRctFlag 与收货/过账门 L299)。
- ///
- /// 本组件**只做纯逻辑**:输入 (pd, clfs, dhsl, bhgsl) → 输出判定/数量/路由。
- /// 不触库、无副作用、可单测。运行期数据门(@IsRctTemp>0、#missedPrints 待过账明细是否存在)
- /// 不在此判定,交由 Service 层按真实数据校验;此处只给 (pd,clfs) 可纯判定的过账前置资格。
- /// </summary>
- public static class IqcResultMapping
- {
- /// <summary>合格判定值(qms_qcp_inspbill.pd = 0)。</summary>
- public const int PdPass = 0;
- /// <summary>不合格判定值(qms_qcp_inspbill.pd = 1)。</summary>
- public const int PdFail = 1;
- /// <summary>
- /// 把 IQC 检验结果映射为 WMS 入库路由决策。旧入口 qms_WMS_SaveIQCResult 的 5 个平行分支:
- /// ① pd=0,clfs='' 合格·无处理 → YES/0
- /// ② pd=0,clfs='3' 合格·挑选 → NO/1
- /// ③ pd=1,clfs='0' 不良·退货 → NO/2
- /// ④ pd=1,clfs='2' 不良·让步接收 → NO/3
- /// ⑤ pd=1,clfs='3' 不良·挑选 → NO/1
- /// 其余 (pd,clfs) 组合旧入口不动作 → Unmatched。
- /// </summary>
- public static IqcResultMappingResult Map(IqcResultMappingInput input)
- {
- if (input == null) throw new ArgumentNullException(nameof(input));
- var clfs = input.Clfs;
- var clfsEmpty = string.IsNullOrEmpty(clfs);
- var dhsl = input.Dhsl;
- var bhgsl = input.Bhgsl;
- // ① pd=0, clfs 为空 —— 来料合格·处理方式为空
- if (input.Pd == PdPass && clfsEmpty)
- return Build(1, "合格·无处理", "YES", 0, dhsl, 0m);
- // ② pd=0, clfs='3' —— 合格·挑选使用
- if (input.Pd == PdPass && clfs == "3")
- return Build(2, "合格·挑选使用", "NO", 1, dhsl, bhgsl);
- // ③ pd=1, clfs='0' —— 不良·退货
- if (input.Pd == PdFail && clfs == "0")
- return Build(3, "不良·退货", "NO", 2, 0m, dhsl + bhgsl);
- // ④ pd=1, clfs='2' —— 不良·让步接收
- if (input.Pd == PdFail && clfs == "2")
- return Build(4, "不良·让步接收", "NO", 3, dhsl + bhgsl, 0m);
- // ⑤ pd=1, clfs='3' —— 不良·挑选
- if (input.Pd == PdFail && clfs == "3")
- return Build(5, "不良·挑选", "NO", 1, dhsl, bhgsl);
- // 其余组合:旧入口无匹配分支,不动作
- return new IqcResultMappingResult
- {
- Matched = false,
- BranchNo = 0,
- BranchSemantics = "无匹配分支(旧入口不动作)",
- QcStatus = null,
- MrbStatus = 0,
- QtyAcc = 0m,
- QtyReject = 0m,
- PartRctFlag = 0,
- RoutingKind = IqcRoutingKind.Unmatched,
- EntersReceiptOrchestration = false,
- EntersInventoryPosting = false,
- };
- }
- private static IqcResultMappingResult Build(
- int branchNo, string semantics, string qcStatus, int mrbStatus, decimal qtyAcc, decimal qtyReject)
- {
- // PartRctFlag 推导(pr_WMS_SaveIQCResult L49-71,固定 @Barcodes=''):
- // QCStatus='NO' 且 MRBStatus=1 → PartRctFlag=1(Barcodes 非空才会是 2,本入口路径恒非 2)
- // 其余 → PartRctFlag=0
- var partRctFlag = (qcStatus == "NO" && mrbStatus == 1) ? 1 : 0;
- // 收货编排/库存过账门(pr_WMS_SaveIQCResult L299:@IsRctTemp>0 && @QtyAcc>0 && @RctDetails<>'')
- // 可纯逻辑判定部分 = PartRctFlag==0 && QtyAcc>0;运行期数据门(IsRctTemp/RctDetails)由 Service 层校验。
- var entersPosting = partRctFlag == 0 && qtyAcc > 0m;
- IqcRoutingKind routing;
- if (partRctFlag == 1)
- routing = IqcRoutingKind.MrbChooseMobileTask; // 分支 ②⑤:挑选 → PurOrdRctByMRBChoose 移动任务,不过账
- else if (entersPosting)
- routing = IqcRoutingKind.FullReceiptPosting; // 分支 ①④:收货编排 + 库存过账
- else
- routing = IqcRoutingKind.ReturnOnly; // 分支 ③:退货标记,不过账
- return new IqcResultMappingResult
- {
- Matched = true,
- BranchNo = branchNo,
- BranchSemantics = semantics,
- QcStatus = qcStatus,
- MrbStatus = mrbStatus,
- QtyAcc = qtyAcc,
- QtyReject = qtyReject,
- PartRctFlag = partRctFlag,
- RoutingKind = routing,
- EntersReceiptOrchestration = entersPosting,
- EntersInventoryPosting = entersPosting,
- };
- }
- }
|