using GB5Shared.DTO.Framework.Criteria; using GB5Shared.DTO.Framework.Login; using GB5Shared.ResponseStandard; using QMSDAL.DTO; using System.Data.Common; namespace QMSDAL.CustomCode.Matrix { public interface IMatrixDAL { // ── READ — Queries ──────────────────────────────────────────────────── /// /// Returns all matrix headers for the tenant (no MatrixId filter). /// Inputs and Outputs are NOT populated — call GetAllMatrixInputsAsync / /// GetAllMatrixOutputsAsync and stitch in the caller. /// Task> GetAllMatrixHeadersAsync( LoginDTO login, CancellationToken ct = default); /// Returns all input lines for the tenant across all matrices. Task> GetAllMatrixInputsAsync( LoginDTO login, CancellationToken ct = default); /// Returns all output rows for the tenant across all matrices. Task> GetAllMatrixOutputsAsync( LoginDTO login, CancellationToken ct = default); /// /// Returns the matrix header. Inputs list is NOT populated here — /// call GetMatrixInputsAsync separately when lines are needed. /// Task GetMatrixAsync( int matrixId, LoginDTO login, CancellationToken ct = default); /// /// Returns all input lines for the given matrix. /// Task> GetMatrixInputsAsync( int matrixId, LoginDTO login, CancellationToken ct = default); /// /// Returns all output rows for the given matrix. /// Used to populate MatrixDTO.Outputs for Mode 2 display and editing. /// Task> GetMatrixOutputsAsync( int matrixId, LoginDTO login, CancellationToken ct = default); /// /// Returns true if TMATRIXOUTPUT already has rows for this matrix. /// Used by ActivateMatrix to skip lot generation when pre-generated. /// Task HasOutputsGeneratedAsync( int matrixId, LoginDTO login, CancellationToken ct = default); /// /// Returns Set lot count and FGSerial count generated for /// this matrix (populated from TMATRIXOUTPUT). /// Task<(int Sets, int Serials)> GetMatrixOutputCountsAsync( int matrixId, LoginDTO login, CancellationToken ct = default); /// /// Returns true if allocationId resolves to a real MALLOCATION row. /// TMATRIX.ALLOCATIONID's FK requires the SO's own header allocation id — /// NOT a pending-allocation line's AllotedAllocationId. /// Task AllocationExistsAsync( int allocationId, LoginDTO login, CancellationToken ct = default); /// /// Returns count of rows matching matrixCode for the tenant, /// excluding the given matrixId (pass 0 for new records). /// Task CheckDuplicateCodeAsync( string matrixCode, int excludeMatrixId, LoginDTO login, CancellationToken ct = default); /// /// Returns true if [setFrom..setTo] overlaps any Active matrix /// for the given allocation and mode, excluding excludeMatrixId. /// SetFrom / SetTo use short to match MatrixDTO. /// Task HasSetRangeOverlapAsync( int allocationId, byte matrixMode, short setFrom, short setTo, int excludeMatrixId, LoginDTO login, CancellationToken ct = default); /// /// Returns the next sequential AllocationSlNo for the given /// allocationId within the tenant. /// MAX(ALLOCATIONSLNO) + 1, or 1 if none exist yet. /// Task GetNextAllocationSlNoAsync( int allocationId, LoginDTO login, CancellationToken ct = default); /// /// Returns input lines that have FreeQty below PlannedQty /// for shortage reporting. FreeQty is populated from stock query. /// Task> GetStockShortageInputsAsync( int matrixId, LoginDTO login, CancellationToken ct = default); /// /// Returns available RM batches for a given item/SKU, /// optionally filtered by requiredQty for shortage check. /// Task> GetAvailableBatchesAsync( int itemId, int skuId, decimal? requiredQty, LoginDTO login, CancellationToken ct = default); /// /// Resolves the MatrixId from a given IndentId via TINDENT.MATRIXID. /// Returns -1 if not found or not linked. /// Task GetMatrixIdFromIndentAsync( int indentId, LoginDTO login, CancellationToken ct = default); /// /// Returns the single input line for a given matrix + item combination. /// Used at material issue time for batch and qty validation. /// Returns null if no restriction line exists. /// Task GetMatrixInputForItemAsync( int matrixId, int itemId, LoginDTO login, CancellationToken ct = default); // ── WRITE — Commands (all transactional) ────────────────────────────── /// Inserts a new TMATRIX header row. Task> SaveMatrixAsync( MatrixDTO dto, LoginDTO login, DbTransaction tx, CancellationToken ct = default); /// Updates an existing TMATRIX header row (Draft only). Task> UpdateMatrixAsync( MatrixDTO dto, LoginDTO login, DbTransaction tx, CancellationToken ct = default); /// /// Hard-deletes all TMATRIXOUTPUT rows for the given matrixId. /// Only called for Mode 2 on the update path — Mode 0/1 outputs are immutable. /// Task> DeleteMatrixOutputsAsync( int matrixId, LoginDTO login, DbTransaction tx, CancellationToken ct = default); /// /// Hard-deletes all TMATRIXINPUT rows for the given matrixId. /// Safe only on Draft matrices — enforced in BLL before calling. /// Task> DeleteMatrixInputsAsync( int matrixId, LoginDTO login, DbTransaction tx, CancellationToken ct = default); /// /// Bulk-inserts TMATRIXINPUT rows. IList used (not IEnumerable) /// because bulk operations require count and index access. /// Task> BulkSaveMatrixInputsAsync( IList inputs, int matrixId, LoginDTO login, DbTransaction tx, CancellationToken ct = default); /// /// Soft-deletes a matrix: sets STATUS = 3 (Deleted). /// Only permitted on Draft matrices — enforced in BLL. /// Task> SoftDeleteMatrixAsync( int matrixId, LoginDTO login, DbTransaction tx, CancellationToken ct = default); /// /// Marks oldMatrixId as Superseded (MATRIXSTATUS = 2) and /// sets SUPERSEDEDBYID = newMatrixId on the old row. /// Task> SupersedeMatrixAsync( int oldMatrixId, int newMatrixId, LoginDTO login, DbTransaction tx, CancellationToken ct = default); /// /// Updates TMATRIXINPUT.LINESTATUS for all lines of the given matrix /// after OpenMix (Mode 2) activation: /// AllocatedQty > 0 → 1 (Partial), otherwise → 0 (Open). /// Task> ActivateOpenMixInputsAsync( int matrixId, LoginDTO login, DbTransaction tx, CancellationToken ct = default); /// /// Sets MATRIXSTATUS = 1 (Active) and ACTIVATEDON = GETDATE() /// on the given matrix. Called after Set lots and FGSerials /// have been generated into TMATRIXOUTPUT. /// Task> ActivateMatrixAsync( int matrixId, LoginDTO login, DbTransaction tx, CancellationToken ct = default); /// /// Bulk-inserts TLOT rows generated during matrix activation. /// One row per Set lot or FGSerial depending on MatrixMode. /// Task> BulkSaveTlotRowsAsync( IEnumerable lots, LoginDTO login, DbTransaction tx, CancellationToken ct = default); /// /// Bulk-inserts TMATRIXOUTPUT rows linking generated lots /// back to the matrix. Called in the same activation transaction. /// Task> BulkSaveMatrixOutputsAsync( IEnumerable outputs, LoginDTO login, DbTransaction tx, CancellationToken ct = default); /// /// Updates TMATRIXINPUT.CONSUMEDQTY and LINESTATUS /// for a single input line after a material issue is posted. /// Task> UpdateConsumedQtyAsync( int matrixInputId, decimal additionalQty, LoginDTO login, DbTransaction tx, CancellationToken ct = default); Task GetSelectListMatrix(CriteriaDTO criteriaDTO, LoginDTO login, CancellationToken ct); /// /// Matrix-independent picklist joining TPENDINGALLOCATION with MITEM, /// MBIZTRANSACTIONTYPE, MALLOCATION and MPARTY (via TALLOCATION for quantities). /// Does not depend on TMATRIX. /// Task GetSelectListAllocationWithItem(CriteriaDTO criteriaDTO, LoginDTO login, CancellationToken ct); /// Matrix-independent single allocation-line summary — no TMATRIX. Task GetAllocationItemSummaryAsync(int allotedAllocationId, LoginDTO login, CancellationToken ct = default); /// Count of TLOT rows already generated for this item + header allocation — no TMATRIXOUTPUT. Task GetSetsGeneratedCountAsync(int itemId, int headerAllocationId, LoginDTO login, CancellationToken ct = default); /// Sets generated for ONE alloted-allocation line only — see GET_SETS_GENERATED_COUNT_FOR_ALLOTED_ALLOCATION. Task GetSetsGeneratedCountForAllotedAllocationAsync(int itemId, int allotedAllocationId, LoginDTO login, CancellationToken ct = default); /// The actual SET-level TLOT rows generated for one alloted-allocation line — backs the SetFrom/SetTo picklist. Task> GetGeneratedSetLotsAsync(int allotedAllocationId, LoginDTO login, CancellationToken ct = default); /// Reservation policy for a business transaction type — 0=Not Required, 1=Auto, 2=Manual. Task GetBizTransactionTypeReservationTypeAsync(int bizTransactionTypeId, LoginDTO login, CancellationToken ct = default); /// Resolves a BizTransactionTypeId by its system code (e.g. "LTPRD"), scoped by tenant + OU. Null if not found. Task GetBizTransactionTypeIdByCodeAsync(string code, LoginDTO login, CancellationToken ct = default); /// Resolves an MENTITY.ENTITYID by its ENTITYCODE (e.g. "MATRIX"). Null if not found. Task GetEntityIdByCodeAsync(string code, LoginDTO login, CancellationToken ct = default); /// Non-locking read of the current lot sequence — preview/display only. Task GetLastLotSequencePreviewAsync(string prefix, string suffix, LoginDTO login, CancellationToken ct = default); /// Current stock + last issued serial per item, from TLOT/TLOTDETAIL only. Task> GetStockAndLastSerialForItemsAsync(IEnumerable itemIds, LoginDTO login, CancellationToken ct = default); /// Locking (UPDLOCK, HOLDLOCK) read of the last issued serial for one item — must run inside the caller's transaction. Task GetLastSerialForItemLockingAsync(int itemId, LoginDTO login, DbTransaction transaction, CancellationToken ct = default); /// Reserved qty per item, from TRESERVATION only (active reservations). Task> GetReservedQtyForItemsAsync(IEnumerable itemIds, LoginDTO login, CancellationToken ct = default); /// Skipped/available serials (TLOT STATUS = 0) for one item — deselected during a prior save. Task> GetSkippedSerialsAsync(int itemId, LoginDTO login, CancellationToken ct = default); /// Existing issued serials (TLOT STATUS = 1) for one item — real active stock, pickable to fulfill a run via an existing lot instead of a new one. Task> GetIssuedSerialsAsync(int itemId, LoginDTO login, CancellationToken ct = default); /// Free RM stock-on-hand (TSTOCKPOSITION.QUANTITY − RESERVEDQUANTITY, summed across stores) for a set of items. Task> GetStockOnHandForItemsAsync(IEnumerable itemIds, LoginDTO login, CancellationToken ct = default); /// Reactivates a previously-skipped serial (TLOT STATUS 0 → 1) in place — user picked it to fulfill the current run instead of issuing a fresh number. Task> ReactivateSkippedSerialAsync(int lotId, string stockLedgerNumber, DateTime stockLedgerDate, LoginDTO login, DbTransaction tx, CancellationToken ct = default); /// Resolves a BOM output component's QtyPerSet directly from its own ItemId (no parent product context needed). Task GetBomOutputQtyPerSetForItemAsync(int itemId, LoginDTO login, CancellationToken ct = default); // ── BOM Explosion ───────────────────────────────────────────────────── /// /// Returns BOM component lines (BOMLEVEL != 0) for the given item and planned qty. /// These form the Input array of the ExplodeBOM response. /// Task> ExplodeBOMInputsAsync( int productItemId, int plannedQty, LoginDTO login, CancellationToken ct = default); /// /// Returns the production item / FG output line (BOMLEVEL = 0) for the given item and planned qty. /// These form the Output array of the ExplodeBOM response. /// Task> ExplodeBOMOutputsAsync( int productItemId, int plannedQty, LoginDTO login, CancellationToken ct = default); Task GetMatrixSummaryAsync( int allotedAllocationId, LoginDTO login, CancellationToken ct = default); Task> BulkSaveTlotDetailRowsAsync( IEnumerable details, LoginDTO login, DbTransaction tx, CancellationToken ct = default); /// /// Bulk-inserts TRESERVATION rows for input lines where IsReservation == false. /// Each row reserves AllocatedQty of an RM batch against the matrix. /// Called inside the SaveMatrix transaction so reservations roll back with the header. /// Task> BulkSaveReservationsAsync( IEnumerable reservations, LoginDTO login, DbTransaction tx, CancellationToken ct = default); } }