using AccountsBLL.AccountReports.BRSDashboard; using AccountsDAL.DTO.Instrument; using FastEndpoints; using GB5Shared.DTO.Framework.Login; using GB5Shared.DTO.Report; using GB5Shared.FastEndPoint; using static GB5Shared.GB5Constant.Constant; namespace AccountsSL.EndPoints.AccountReports { // Bank Reconciliation Dashboard (Finance Analytics Dashboards, Phase 2) -- wires the // previously dead BRSSummaryReportDTO/BRSDetailReportDTO into a real query. Single // consolidated-object response (Summary + Detail), same pattern as // AccountProfitLossDashboardReport/AccountReceivableDashboardReport -- ExecutePagedAsync is // overridden since this is a small, bounded result, not a real paged list. ExecuteReportAsync // streams just the Detail (pending-instrument) rows, for CSV/Excel export. public class AccountBRSDashboardReport : BaseReportEndpoint { private readonly IBRSDashboardBLL _bll; public AccountBRSDashboardReport(IBRSDashboardBLL bll) { _bll = bll; } public override void Configure() { Post("/AccountReports/AccountBRSDashboardReport"); AllowAnonymous(); } public record AccountBRSDashboardReportParameter( [property: FromHeader] string Login, [property: FromBody] ReportCallingDTO ReportCallingDTO ); // BankAccountIds is BRS-specific (no other AccountReports family report needs it), so it's // parsed locally here rather than added to the shared AccountReportCriteriaParser -- // same convention as AccountProfitLossDashboardReport's own ParseDashboardPeriodType. private static List? ParseBankAccountIds(GB5Shared.DTO.Framework.Criteria.CriteriaDTO? criteriaDTO) { if (criteriaDTO?.SectionCriteriaList == null) return null; foreach (var section in criteriaDTO.SectionCriteriaList) { if (section.AttributesCriteriaList == null) continue; foreach (var attr in section.AttributesCriteriaList) { if (attr.FieldName?.ToLowerInvariant() != "bankaccountids" || attr.FieldValue == null) continue; var raw = attr.FieldValue.ToString() ?? ""; return raw.Split(',', StringSplitOptions.RemoveEmptyEntries) .Select(s => int.TryParse(s.Trim(), out var v) ? v : 0) .Where(v => v != 0) .ToList(); } } return null; } protected override async IAsyncEnumerable ExecuteReportAsync( AccountBRSDashboardReportParameter req, LoginDTO login, [System.Runtime.CompilerServices.EnumeratorCancellation] CancellationToken ct) { var bankAccountIds = ParseBankAccountIds(req.ReportCallingDTO.CriteriaDTO); var result = await _bll.GetBRSDashboard(bankAccountIds, login, ct).ConfigureAwait(false); foreach (var row in result.Detail) { ct.ThrowIfCancellationRequested(); yield return row; } } protected override async Task> ExecutePagedAsync( AccountBRSDashboardReportParameter req, LoginDTO login, CancellationToken ct) { try { var bankAccountIds = ParseBankAccountIds(req.ReportCallingDTO.CriteriaDTO); var result = await _bll.GetBRSDashboard(bankAccountIds, login, ct).ConfigureAwait(false); return await GB5Shared.ResponseStandard.Response.CreateSuccessResponse( result, CacheKeyLevel.NOT_REQUIRED, login); } catch (Exception ex) { return await GB5Shared.ResponseStandard.Response.CreateExceptionError( ex, CacheKeyLevel.NOT_REQUIRED, login, ex.Message, 500); } } } }