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; }
}
}