| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118 |
- using Admin.NET.Plugin.AiDOP.MaterialWarehouse.InventoryPosting;
- using Xunit;
- namespace Admin.NET.Plugin.AiDOP.Tests.S5.MaterialWarehouse;
- /// <summary>
- /// C1 IqcResultMapping 契约测试(Phase 1 · 契约测试先行)。
- /// 把 dopdemorq 旧 LIVE 链(qms_WMS_SaveIQCResult → pr_WMS_SaveIQCResult 真定义)
- /// 的 5 个 (pd,clfs) 分支行为固化为测试:QCStatus / MRBStatus / QtyAcc / QtyReject /
- /// PartRctFlag / 是否进入收货编排 / 是否进入库存过账。
- /// 样本 dhsl=10(检验/收货数)、bhgsl=3(不合格数)。
- /// </summary>
- public class IqcResultMappingContractTests
- {
- // 分支 | pd | clfs | 语义 | QCStatus | MRB | QtyAcc | QtyReject | PartRctFlag | 进过账 | 路由
- // ① | 0 | '' | 合格无处理 | YES | 0 | 10 | 0 | 0 | 是 | FullReceiptPosting
- // ② | 0 | 3 | 合格挑选 | NO | 1 | 10 | 3 | 1 | 否 | MrbChooseMobileTask
- // ③ | 1 | 0 | 不良退货 | NO | 2 | 0 | 13 | 0 | 否 | ReturnOnly
- // ④ | 1 | 2 | 不良让步接收 | NO | 3 | 13 | 0 | 0 | 是 | FullReceiptPosting
- // ⑤ | 1 | 3 | 不良挑选 | NO | 1 | 10 | 3 | 1 | 否 | MrbChooseMobileTask
- [Theory]
- [InlineData(1, 0, "", 10, 3, "YES", 0, 10, 0, 0, true, IqcRoutingKind.FullReceiptPosting)]
- [InlineData(2, 0, "3", 10, 3, "NO", 1, 10, 3, 1, false, IqcRoutingKind.MrbChooseMobileTask)]
- [InlineData(3, 1, "0", 10, 3, "NO", 2, 0, 13, 0, false, IqcRoutingKind.ReturnOnly)]
- [InlineData(4, 1, "2", 10, 3, "NO", 3, 13, 0, 0, true, IqcRoutingKind.FullReceiptPosting)]
- [InlineData(5, 1, "3", 10, 3, "NO", 1, 10, 3, 1, false, IqcRoutingKind.MrbChooseMobileTask)]
- public void Map_FiveMrbBranches_MatchLiveContract(
- int expBranchNo, int pd, string clfs, int dhsl, int bhgsl,
- string expQcStatus, int expMrb, int expQtyAcc, int expQtyReject,
- int expPartRctFlag, bool expEntersPosting, IqcRoutingKind expRouting)
- {
- var result = IqcResultMapping.Map(new IqcResultMappingInput
- {
- Pd = pd,
- Clfs = clfs,
- Dhsl = dhsl,
- Bhgsl = bhgsl,
- });
- Assert.True(result.Matched);
- Assert.Equal(expBranchNo, result.BranchNo);
- Assert.Equal(expQcStatus, result.QcStatus);
- Assert.Equal(expMrb, result.MrbStatus);
- Assert.Equal(expQtyAcc, result.QtyAcc);
- Assert.Equal(expQtyReject, result.QtyReject);
- Assert.Equal(expPartRctFlag, result.PartRctFlag);
- Assert.Equal(expEntersPosting, result.EntersInventoryPosting);
- // 收货编排与库存过账同门(pr_WMS_SaveIQCResult L299 块内)
- Assert.Equal(expEntersPosting, result.EntersReceiptOrchestration);
- Assert.Equal(expRouting, result.RoutingKind);
- }
- [Fact]
- public void Map_Branch1_QtyRejectAlwaysZero_AndQtyAccEqualsDhsl()
- {
- var r = IqcResultMapping.Map(new IqcResultMappingInput { Pd = 0, Clfs = null, Dhsl = 7, Bhgsl = 2 });
- // clfs=null 与 '' 等价,命中分支 ①
- Assert.Equal(1, r.BranchNo);
- Assert.Equal("YES", r.QcStatus);
- Assert.Equal(7, r.QtyAcc);
- Assert.Equal(0, r.QtyReject);
- }
- [Fact]
- public void Map_Branch3_Return_QtyAccZero_QtyRejectSumsBoth()
- {
- // 退货:QtyAcc=0,QtyReject=dhsl+bhgsl(旧入口 set @QtyReject=@QtyAcc+@QtyReject)
- var r = IqcResultMapping.Map(new IqcResultMappingInput { Pd = 1, Clfs = "0", Dhsl = 8, Bhgsl = 5 });
- Assert.Equal(2, r.MrbStatus);
- Assert.Equal(0, r.QtyAcc);
- Assert.Equal(13, r.QtyReject);
- Assert.False(r.EntersInventoryPosting);
- Assert.Equal(IqcRoutingKind.ReturnOnly, r.RoutingKind);
- }
- [Fact]
- public void Map_Branch4_Concession_QtyAccSumsBoth_QtyRejectZero_EntersPosting()
- {
- // 让步接收:QtyAcc=dhsl+bhgsl,QtyReject=0,进过账
- var r = IqcResultMapping.Map(new IqcResultMappingInput { Pd = 1, Clfs = "2", Dhsl = 8, Bhgsl = 5 });
- Assert.Equal(3, r.MrbStatus);
- Assert.Equal(13, r.QtyAcc);
- Assert.Equal(0, r.QtyReject);
- Assert.True(r.EntersInventoryPosting);
- Assert.Equal(IqcRoutingKind.FullReceiptPosting, r.RoutingKind);
- }
- [Fact]
- public void Map_Branch1_WhenDhslZero_DoesNotEnterPosting()
- {
- // QtyAcc>0 是过账门的可纯判定部分:合格但收货数=0 → 不进过账
- var r = IqcResultMapping.Map(new IqcResultMappingInput { Pd = 0, Clfs = "", Dhsl = 0, Bhgsl = 0 });
- Assert.Equal(1, r.BranchNo);
- Assert.False(r.EntersInventoryPosting);
- }
- [Theory]
- [InlineData(0, "0")] // 合格但处理方式=退货:旧入口无此分支
- [InlineData(0, "2")] // 合格但处理方式=让步接收:无此分支
- [InlineData(1, "")] // 不合格但处理方式为空:isnull(clfs,100) 不匹配任何分支
- [InlineData(1, "9")] // 未知处理方式
- [InlineData(2, "")] // 未知 pd
- public void Map_UnmatchedCombos_ReturnUnmatched_NoRouting(int pd, string clfs)
- {
- var r = IqcResultMapping.Map(new IqcResultMappingInput { Pd = pd, Clfs = clfs, Dhsl = 10, Bhgsl = 3 });
- Assert.False(r.Matched);
- Assert.Equal(0, r.BranchNo);
- Assert.Equal(IqcRoutingKind.Unmatched, r.RoutingKind);
- Assert.False(r.EntersInventoryPosting);
- Assert.False(r.EntersReceiptOrchestration);
- }
- [Fact]
- public void Map_NullInput_Throws()
- {
- Assert.Throws<ArgumentNullException>(() => IqcResultMapping.Map(null));
- }
- }
|