namespace Admin.NET.Plugin.AiDOP.MaterialWarehouse; public static class InventoryDataSources { public const string Live165 = "LIVE_165"; public const string Std = "STD"; } public sealed class InventoryBalanceQuery { public long TenantId { get; init; } public string Domain { get; init; } = ""; public string? Type { get; init; } public string? Location { get; init; } public string? MaterialCode { get; init; } public string? BatchNo { get; init; } public decimal? StockGt { get; init; } public decimal? UnrestrictedGt { get; init; } public decimal? QcStockGt { get; init; } public decimal? FrozenGt { get; init; } public int Page { get; init; } = 1; public int PageSize { get; init; } = 10; } public sealed class InventoryBalanceRow { public string? Type { get; set; } public string? Location { get; set; } public string? LocationName { get; set; } public string? MaterialCode { get; set; } public string? MaterialName { get; set; } public string? BatchNo { get; set; } public string? Shelf { get; set; } public string? Version { get; set; } public decimal UnrestrictedStock { get; set; } public decimal QcStock { get; set; } public decimal FrozenStock { get; set; } public decimal QtyOnHand { get; set; } public string? Unit { get; set; } public string? Supplier { get; set; } } public sealed class InventoryBalancePage { public int Total { get; init; } public int Page { get; init; } public int PageSize { get; init; } public IReadOnlyList List { get; init; } = Array.Empty(); public decimal GrandTotalQtyOnHand { get; init; } public decimal GrandUnrestricted { get; init; } public decimal GrandQc { get; init; } public decimal GrandFrozen { get; init; } public string DataSource { get; init; } = InventoryDataSources.Std; public DateTime AsOf { get; init; } public bool IsRealtime { get; init; } /// /// 本次结果是否由「尝试实时源失败后回落标准层」产生。 /// /// 用于区分两种同为 的语义: /// ① 正常快照(无选择性筛选,按策略本就不查实时源)→ false; /// ② 实时源超时/异常后的降级结果 → true。 /// 只有 ② 才应向用户提示「实时库不可用」。 /// /// 由门面 InventoryBalanceReader 在回落分支设置,故为可写属性。 /// public bool FallbackFromLive { get; set; } } public sealed class InventoryTransactionQuery { public long TenantId { get; init; } public string Domain { get; init; } = ""; public string? MaterialCode { get; init; } public string? Location { get; init; } public string? BatchNo { get; init; } public string? WorkOrderNo { get; init; } public string? TransType { get; init; } public string? CreateTime { get; init; } public string? CreateUser { get; init; } public int Page { get; init; } = 1; public int PageSize { get; init; } = 10; } public sealed class InventoryTransactionRow { public DateTime? TransTime { get; set; } public string? MaterialCode { get; set; } public string? MaterialName { get; set; } public string? Location { get; set; } public string? LocationName { get; set; } public string? BatchNo { get; set; } public decimal BeginQty { get; set; } public decimal InQty { get; set; } public decimal OutQty { get; set; } public decimal EndQty { get; set; } public string? Unit { get; set; } public string? TransType { get; set; } public string? WorkOrderNo { get; set; } public string? DeliveryNo { get; set; } public string? DeliveryType { get; set; } public string? Remark { get; set; } public string? CreateUser { get; set; } } public sealed class InventoryTransactionPage { public int Total { get; init; } public int Page { get; init; } public int PageSize { get; init; } public IReadOnlyList List { get; init; } = Array.Empty(); public DateTime AsOf { get; init; } public DateTime HistoryFrom { get; init; } }