| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107 |
- using Admin.NET.Plugin.AiDOP.MaterialWarehouse.InventoryPosting.Inventory;
- using Admin.NET.Plugin.AiDOP.MaterialWarehouse.InventoryPosting.Receipt;
- using Xunit;
- namespace Admin.NET.Plugin.AiDOP.Tests.S5.MaterialWarehouse;
- /// <summary>
- /// Phase 6B 纯逻辑件测试:Runtime Gate + CheckInventoryStatus 轻校验 + IqcInventoryBatchBuilder。
- /// 据 Phase 6A LIVE 契约:IQC 收货 `rct-po`(→Avail,Assay=0),留样 `iss-unp`(-Sample);最终 +Accepted-Sample。
- /// </summary>
- public class IqcReceiptPureTests
- {
- // ── Runtime Gate ──
- [Fact]
- public void Gate_AllSatisfied_CanCreate()
- => Assert.True(PurchaseReceiptRuntimeGate.Evaluate(
- new PurchaseReceiptGateInput { HasPendingReceipt = true, AcceptedQty = 100m, HasReceivableDetails = true }).CanCreate);
- [Fact]
- public void Gate_AcceptedQtyZero_CannotCreate()
- => Assert.False(PurchaseReceiptRuntimeGate.Evaluate(
- new PurchaseReceiptGateInput { HasPendingReceipt = true, AcceptedQty = 0m, HasReceivableDetails = true }).CanCreate);
- [Fact]
- public void Gate_NoReceivableDetails_CannotCreate()
- => Assert.False(PurchaseReceiptRuntimeGate.Evaluate(
- new PurchaseReceiptGateInput { HasPendingReceipt = true, AcceptedQty = 100m, HasReceivableDetails = false }).CanCreate);
- [Fact]
- public void Gate_NoPendingReceipt_CannotCreate()
- => Assert.False(PurchaseReceiptRuntimeGate.Evaluate(
- new PurchaseReceiptGateInput { HasPendingReceipt = false, AcceptedQty = 100m, HasReceivableDetails = true }).CanCreate);
- // ── CheckInventoryStatus 轻校验 ──
- [Fact]
- public void LocationCheck_AllNonEmpty_Ok()
- {
- var cmds = new[] { new InventoryTransactionCommand { ItemNum = "IT-1", Location = "L1" } };
- Assert.True(InventoryLocationCheck.Validate(cmds).Ok);
- }
- [Fact]
- public void LocationCheck_EmptyLocation_Fails()
- {
- var cmds = new[] { new InventoryTransactionCommand { ItemNum = "IT-1", Location = "" } };
- var r = InventoryLocationCheck.Validate(cmds);
- Assert.False(r.Ok);
- Assert.Contains("IT-1", r.OffendingItems);
- }
- // ── Batch Builder ──
- private static IqcAcceptedReceipt Receipt(decimal accepted, decimal sample)
- => new IqcAcceptedReceipt
- {
- TenantId = 797403760988229L, DomainCode = "8010", PostingId = 1, TransactionGroupId = 100,
- RctNbr = "RCT-001", ItemNum = "IT-1", Location = "L1", LotSerial = "",
- AcceptedQty = accepted, SampleQty = sample, UmConversion = 1m, User = "t",
- };
- [Fact]
- public void Build_NoSample_OnlyRctPo()
- {
- var b = IqcInventoryBatchBuilder.Build(Receipt(100m, 0m));
- var c = Assert.Single(b.Commands);
- Assert.Equal(InventoryTransType.RctPo, c.TransType);
- Assert.Equal(100m, c.ChangeQty);
- Assert.Equal("RCT-001", c.OrdNbr);
- Assert.Equal(1, c.Seq);
- }
- [Fact]
- public void Build_WithSample_RctPoThenIssUnp_OrderAndSigns()
- {
- var b = IqcInventoryBatchBuilder.Build(Receipt(100m, 10m));
- Assert.Equal(2, b.Commands.Count);
- Assert.Equal(InventoryTransType.RctPo, b.Commands[0].TransType);
- Assert.Equal(100m, b.Commands[0].ChangeQty);
- Assert.Equal(InventoryTransType.IssUnp, b.Commands[1].TransType);
- Assert.Equal(-10m, b.Commands[1].ChangeQty); // 留样恒负
- Assert.Equal("iqc", b.Commands[1].Reason);
- Assert.Equal(1, b.Commands[0].Seq);
- Assert.Equal(2, b.Commands[1].Seq);
- }
- // 经 Calculator 验证最终库存语义
- [Fact]
- public void Build_RctPoAlone_IntoAvail_NotAssay()
- {
- var b = IqcInventoryBatchBuilder.Build(Receipt(100m, 0m));
- var after = InventoryBalanceCalculator.Project(new InventoryBalance(), b.Commands[0]).After;
- Assert.Equal(100m, after.QtyOnHand);
- Assert.Equal(100m, after.AvailStatusQty); // 进可用库存
- Assert.Equal(0m, after.Assay); // 非质检(修正 rct-po-ins 旧误判)
- }
- [Fact]
- public void Build_WithSample_FinalBalance_AcceptedMinusSample()
- {
- var b = IqcInventoryBatchBuilder.Build(Receipt(100m, 10m));
- var bal = new InventoryBalance();
- foreach (var c in b.Commands)
- bal = InventoryBalanceCalculator.Project(bal, c).After;
- Assert.Equal(90m, bal.QtyOnHand); // +100 -10
- Assert.Equal(90m, bal.AvailStatusQty);
- Assert.Equal(0m, bal.Assay);
- }
- }
|