using System; using System.Threading; using System.Threading.Tasks; using GB5Shared.DTO.Framework.Criteria; using GB5Shared.DTO.Framework.Login; using GB5Shared.ListQuery; using GB5Shared.QueryExecutor; using MMDAL.DTO.Allocation; using Newtonsoft.Json; using static GB5Shared.GB5Constant.Constant; namespace MMBLL.Allocation { // ───────────────────────────────────────────────────────────────────── // PendingAllocationBLL – Pattern B (routed) query router // // Routing logic: // Read 'objectheadertypeid' and 'allitemsview'/'multiprocess' from // the CriteriaDTO, then dispatch to the correct query variant via // IListDispatcher (which resolves the IListHandler from DI). // // Discriminator fields (read from CriteriaDTO via CriteriaRouterHelper): // objectheadertypeid = EntityConstant.OBJECTMMHEAD → MM document variants // objectheadertypeid = EntityConstant.OBJECTINDENT → Indent variants // allitemsview = "true" → detail-level MM view // multiprocess = "true" → multi-process indent view // // Default (no discriminator or unknown value): PendingMMDocumentsQuery // ───────────────────────────────────────────────────────────────────── public sealed class PendingAllocationBLL : IPendingAllocationBLL { private readonly IListDispatcher _dispatcher; private readonly IListHandler _selectListHandler; public PendingAllocationBLL( IListDispatcher dispatcher, IListHandler selectListHandler) { _dispatcher = dispatcher; _selectListHandler = selectListHandler; } public async Task GetPendingAllocations( CriteriaDTO criteria, string? searchText, int pageOffset, int pageSize, LoginDTO login, CancellationToken ct = default) { // Merge query-param search text and paging into the criteria body. // searchText=null means legacy client already embedded it in the body. var merged = CriteriaRouterHelper.WithSearchAndPaging( criteria, searchText, pageOffset, pageSize); // Read discriminator fields from the merged criteria var flat = CriteriaRouterHelper.Flatten(merged); int headTypeId = CriteriaRouterHelper.GetInt(flat, "objectheadertypeid"); bool allItems = string.Equals( CriteriaRouterHelper.GetStr(flat, "allitemsview"), "true", StringComparison.OrdinalIgnoreCase); bool multiProc = string.Equals( CriteriaRouterHelper.GetStr(flat, "multiprocess"), "true", StringComparison.OrdinalIgnoreCase); PagedResult result; if (headTypeId == EntityConstant.OBJECTINDENT) { if (multiProc) { var c = CriteriaBinder.Bind(merged); result = await _dispatcher.DispatchAsync( new PendingIndentMultiProcessQuery(c), login, ct).ConfigureAwait(false); } else { var c = CriteriaBinder.Bind(merged); result = await _dispatcher.DispatchAsync( new PendingIndentsQuery(c), login, ct).ConfigureAwait(false); } } else { // Default: OBJECTMMHEAD (or when objectheadertypeid is absent) if (allItems) { var c = CriteriaBinder.Bind(merged); result = await _dispatcher.DispatchAsync( new PendingMMAllItemsQuery(c), login, ct).ConfigureAwait(false); } else { var c = CriteriaBinder.Bind(merged); result = await _dispatcher.DispatchAsync( new PendingMMDocumentsQuery(c), login, ct).ConfigureAwait(false); } } return JsonConvert.SerializeObject(result.Items); } // ───────────────────────────────────────────────────────────────── // GetSelectListTPendingAllocation – Pattern A (direct) — single // query variant, no routing/discriminator needed, so the typed // IListHandler is injected and called directly instead of going // through IListDispatcher. // ───────────────────────────────────────────────────────────────── public async Task GetSelectListTPendingAllocation( CriteriaDTO criteria, string? searchText, int pageOffset, int pageSize, LoginDTO login, CancellationToken ct = default) { var merged = CriteriaRouterHelper.WithSearchAndPaging( criteria, searchText, pageOffset, pageSize); var c = CriteriaBinder.Bind(merged); var result = await _selectListHandler.HandleAsync( new PendingAllocationSelectListQuery(c), login, ct).ConfigureAwait(false); return JsonConvert.SerializeObject(result.Items); } } }