namespace AccountsDAL.DTO.Reports { // Replaces this session's own earlier draft of this DTO (a copy of PAndLVerticalReportDTO's // single-side shape) after checking the REAL, already-configured MREPORTVIEWFIELDS metadata for // the 3 live P&L Horizontal grid views (-1499999422/423/424, MREPORT -1399975830) directly // against the target database. That metadata expects a genuine T-format row: one Income entry // and one Expense entry side by side on the SAME row, not two stacked single-side reports. // FIELDNAME values below are a verbatim match to what's already wired live — confirmed via a // live JOIN of MREPORTVIEWFIELDS to MREPORTVSFIELDS, not assumed. // // Income and Expense have no natural 1:1 relationship (an arbitrary income line has nothing // connecting it to an arbitrary expense line) — PAndLReportQB.cs's horizontal queries pair them // positionally (ROW_NUMBER-ordered FULL OUTER JOIN), same as how a paper T-account lists both // sides top-to-bottom independently. A row can have only an Income side populated, only an // Expense side, or both, depending on which side ran out of lines first. public class PAndLHorizontalReportDTO { public int IncomeAccountId { get; set; } public string? IncomeAccountCode { get; set; } public string? IncomeAccountName { get; set; } public string? IncomeAccountGroupName { get; set; } public string? IncomeAccountScheduleName { get; set; } public decimal IncomeAmount { get; set; } // Same value as IncomeAmount — MREPORTVSFIELDS already has both "Income" (FIELDTYPE=6, // decimal) and "IncomeAmount" as separate configured fields (mirrors a similar Id/Code/Name // vs AccountId/AccountCode/AccountName duplication already present on the Vertical report's // own views) — populated defensively rather than left at its zero default in case anything // reads it directly. public decimal Income { get; set; } public int ExpenseAccountId { get; set; } public string? ExpenseAccountCode { get; set; } public string? ExpenseAccountName { get; set; } public string? ExpenseAccountGroupName { get; set; } public string? ExpenseAccountScheduleName { get; set; } public decimal ExpenseAmount { get; set; } // Same value as ExpenseAmount — see Income. public decimal Expense { get; set; } // ACCOUNT / ACCOUNTGROUP / ACCOUNTSCHEDULE — which of the 3 live menus' grain this row is at. public string ReportType { get; set; } = string.Empty; public string AccountNature { get; set; } = string.Empty; public string IncomeType { get; set; } = "Income"; public string ExpenseType { get; set; } = "Expenditure"; } }