namespace QMSDAL.DTO { // "Product Composition" dashboard. // Quantities are sourced purely from MBOM/MBOMDETAIL (recipe), TLOT/TLOTDETAIL // (stock + last-run history) and TRESERVATION (reserved qty) — never from // TMATRIX / TMATRIXINPUT / TMATRIXOUTPUT. public class MatrixCompositionDTO { public string SONumber { get; set; } = string.Empty; public string ProductCode { get; set; } = string.Empty; public string ProductName { get; set; } = string.Empty; public string SetRange { get; set; } = string.Empty; public int SetsToGenerate { get; set; } /// Total physical serials this run will create — sum of each item's ThisRun. public int SerialNumbers { get; set; } /// Total TLOT records this run will create (matches SaveSetSerialGenerationAsync's TLotRecords convention). public int TotalRecords { get; set; } public List Items { get; set; } = []; } public class MatrixCompositionItemDTO { public int RowNumber { get; set; } public int ItemId { get; set; } public string ItemCode { get; set; } = string.Empty; public string ItemName { get; set; } = string.Empty; public string UomCode { get; set; } = string.Empty; /// Total stock on hand for this item — from TLOT/TLOTDETAIL. public decimal TotalQuantity { get; set; } /// Sum of active TRESERVATION.BALANCEQUANTITY for this item. 0 if none reserved. public decimal ReservedQuantity { get; set; } /// TotalQuantity − ReservedQuantity. public decimal AvailableQuantity { get; set; } /// Quantity of this component required per 1 set (BOM-normalized). public decimal QtyPerSet { get; set; } /// QtyPerSet × SetsToGenerate — quantity needed for this run (also used as the serial run count). public decimal ThisRun { get; set; } /// /// This item's own last-used run number — the numeric sequence extracted from its /// most recent TLOT lot number (e.g. "RM00065/2526" → 65). 0 if none exist yet or /// the stored lot number has no readable numeric sequence. /// public int LastRun { get; set; } /// LastRun + 1. 0 when ThisRun is 0. public int NextSerialFrom { get; set; } /// LastRun + round(ThisRun). 0 when ThisRun is 0. public int NextSerialTo { get; set; } } // Result row of GET_STOCK_AND_LAST_SERIAL_FOR_ITEMS — TLOT/TLOTDETAIL only. public class ItemStockDTO { public int ItemId { get; set; } public decimal TotalQuantity { get; set; } public string? LastSerialNo { get; set; } } // Result row of GET_RESERVED_QTY_FOR_ITEMS — TRESERVATION only. public class ItemReservationDTO { public int ItemId { get; set; } public decimal ReservedQuantity { get; set; } } }