using System.Data; using GB5Shared.DTO.Framework.Login; using GB5Shared.QueryExecutor; using MMDAL.DTO.Allocation; using MMDAL.Query.Allocation; namespace MMDAL.CustomCode.Allocation; public class AllocationPostingDAL : IAllocationPostingDAL { private readonly IQueryExecutor _qe; public AllocationPostingDAL(IQueryExecutor qe) => _qe = qe; public async Task SaveAllocationsAsync( DataTable allocationsTvp, DataTable sourceLinksTvp, LoginDTO login, CancellationToken ct) { // TenantId, DocumentId, DocumentTypeId are derived by the SP from the TVP rows. var tvpParameters = new Dictionary { { "@Allocations", (allocationsTvp, "GB5_TVP_TALLOCATION") }, { "@SourceLinks", (sourceLinksTvp, "TVP_SOURCELINK") } }; // SP_SaveAllocations inserts TALLOCATION and, internally, calls SP_SyncPendingAllocation // to insert/update TPENDINGALLOCATION in the same transaction — no separate step needed here. // The reverse (delete/cancel) path is CancelAllocationsAsync below, via SP_CancelDocumentAllocations. await _qe.BulkInsertMultipleAsync( login, AllocationPostingQB.SP_SAVE_ALLOCATIONS, tvpParameters).ConfigureAwait(false); } public async Task> GetAllocationsForDocumentAsync( int documentId, int documentTypeId, LoginDTO login, CancellationToken ct) { var param = new { DocumentId = documentId, DocumentTypeId = documentTypeId, TenantId = login.ClientId }; var rows = await _qe.QueryAsync( login, AllocationPostingQB.GET_ALLOCATIONS_FOR_CANCEL, param, cancellationToken: ct).ConfigureAwait(false); return rows.ToList(); } public async Task CancelAllocationsAsync(DataTable cancelledRowsTvp, LoginDTO login, CancellationToken ct) { // DocumentId, DocumentTypeId, TenantId, CancelledById are derived by SP from TVP rows. var tvpParameters = new Dictionary { { "@CancelledRows", (cancelledRowsTvp, "GB5_TVP_TALLOCATION") } }; await _qe.BulkInsertMultipleAsync( login, AllocationPostingQB.SP_CANCEL_ALLOCATIONS, tvpParameters).ConfigureAwait(false); } public async Task> GetAllocationNaturesAsync( IEnumerable allocationIds, LoginDTO login, CancellationToken ct) { var ids = allocationIds.Distinct().ToArray(); if (ids.Length == 0) return new Dictionary(); var param = new { AllocationIds = ids, TenantId = login.ClientId }; var rows = await _qe.QueryAsync( login, AllocationPostingQB.GET_ALLOCATION_NATURES, param, cancellationToken: ct).ConfigureAwait(false); return rows.ToDictionary(r => r.AllocationId, r => r.AllocationNature); } }