From 7dd08d6141f63bb257d8ddb74583cef1a69fc585 Mon Sep 17 00:00:00 2001 From: Ahmed Bouhuolia Date: Fri, 6 Mar 2026 05:25:44 +0200 Subject: [PATCH] feat(financial-statements): add new financial report DTOs and update controllers - Introduced new DTOs for various financial reports including Balance Sheet, Cash Flow Statement, and Aging Summaries. - Updated existing controllers to utilize the new DTOs and enhance OpenAPI documentation with proper schema references. - Removed unnecessary query parameters from the Bank Accounts controller. - Enhanced response structures for better data representation in reports. --- .../BankAccounts.controller.ts | 6 - .../dtos/FinancialReportResponse.dto.ts | 103 +++++++++++ .../APAgingSummary.controller.ts | 17 +- .../APAgingSummaryResponse.dto.ts | 109 +++++++++++ .../ARAgingSummary.controller.ts | 17 +- .../ARAgingSummaryResponse.dto.ts | 115 ++++++++++++ .../BalanceSheet/BalanceSheet.controller.ts | 23 ++- .../BalanceSheet/BalanceSheetResponse.dto.ts | 158 ++++++++++++++++ .../CashFlowStatement/Cashflow.controller.ts | 17 +- .../CashflowStatementResponse.dto.ts | 109 +++++++++++ .../CustomerBalanceSummary.controller.ts | 20 ++- .../CustomerBalanceSummaryResponse.dto.ts | 82 +++++++++ .../GeneralLedger/GeneralLedger.controller.ts | 17 +- .../GeneralLedgerResponse.dto.ts | 156 ++++++++++++++++ .../InventoryItemDetails.controller.ts | 26 ++- .../InventoryItemDetailsResponse.dto.ts | 114 ++++++++++++ .../InventoryValuation.controller.ts | 15 ++ .../InventoryValuationResponse.dto.ts | 88 +++++++++ .../JournalSheet/JournalSheet.controller.ts | 17 +- .../JournalSheet/JournalSheetResponse.dto.ts | 137 ++++++++++++++ .../ProfitLossSheet.controller.ts | 17 +- .../ProfitLossSheetResponse.dto.ts | 170 ++++++++++++++++++ .../PurchasesByItems.controller.ts | 20 ++- .../PurchasesByItemsResponse.dto.ts | 88 +++++++++ .../SalesByItems/SalesByItems.controller.ts | 20 ++- .../SalesByItems/SalesByItemsResponse.dto.ts | 97 ++++++++++ .../SalesTaxLiabilitySummary.controller.ts | 15 ++ .../SalesTaxLiabilitySummaryResponse.dto.ts | 79 ++++++++ .../TransactionsByCustomer.controller.ts | 20 ++- .../TransactionsByCustomerResponse.dto.ts | 117 ++++++++++++ .../TransactionsByVendor.controller.ts | 20 ++- .../TransactionsByVendorResponse.dto.ts | 117 ++++++++++++ .../TrialBalanceSheet.controller.ts | 17 +- .../TrialBalanceSheetResponse.dto.ts | 123 +++++++++++++ .../VendorBalanceSummary.controller.ts | 20 ++- .../VendorBalanceSummaryResponse.dto.ts | 82 +++++++++ 36 files changed, 2342 insertions(+), 26 deletions(-) create mode 100644 packages/server/src/modules/FinancialStatements/dtos/FinancialReportResponse.dto.ts create mode 100644 packages/server/src/modules/FinancialStatements/modules/APAgingSummary/APAgingSummaryResponse.dto.ts create mode 100644 packages/server/src/modules/FinancialStatements/modules/ARAgingSummary/ARAgingSummaryResponse.dto.ts create mode 100644 packages/server/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetResponse.dto.ts create mode 100644 packages/server/src/modules/FinancialStatements/modules/CashFlowStatement/CashflowStatementResponse.dto.ts create mode 100644 packages/server/src/modules/FinancialStatements/modules/CustomerBalanceSummary/CustomerBalanceSummaryResponse.dto.ts create mode 100644 packages/server/src/modules/FinancialStatements/modules/GeneralLedger/GeneralLedgerResponse.dto.ts create mode 100644 packages/server/src/modules/FinancialStatements/modules/InventoryItemDetails/InventoryItemDetailsResponse.dto.ts create mode 100644 packages/server/src/modules/FinancialStatements/modules/InventoryValuationSheet/InventoryValuationResponse.dto.ts create mode 100644 packages/server/src/modules/FinancialStatements/modules/JournalSheet/JournalSheetResponse.dto.ts create mode 100644 packages/server/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSheetResponse.dto.ts create mode 100644 packages/server/src/modules/FinancialStatements/modules/PurchasesByItems/PurchasesByItemsResponse.dto.ts create mode 100644 packages/server/src/modules/FinancialStatements/modules/SalesByItems/SalesByItemsResponse.dto.ts create mode 100644 packages/server/src/modules/FinancialStatements/modules/SalesTaxLiabilitySummary/SalesTaxLiabilitySummaryResponse.dto.ts create mode 100644 packages/server/src/modules/FinancialStatements/modules/TransactionsByCustomer/TransactionsByCustomerResponse.dto.ts create mode 100644 packages/server/src/modules/FinancialStatements/modules/TransactionsByVendor/TransactionsByVendorResponse.dto.ts create mode 100644 packages/server/src/modules/FinancialStatements/modules/TrialBalanceSheet/TrialBalanceSheetResponse.dto.ts create mode 100644 packages/server/src/modules/FinancialStatements/modules/VendorBalanceSummary/VendorBalanceSummaryResponse.dto.ts diff --git a/packages/server/src/modules/BankingAccounts/BankAccounts.controller.ts b/packages/server/src/modules/BankingAccounts/BankAccounts.controller.ts index 2bfeb35ab..f77fe0285 100644 --- a/packages/server/src/modules/BankingAccounts/BankAccounts.controller.ts +++ b/packages/server/src/modules/BankingAccounts/BankAccounts.controller.ts @@ -11,12 +11,6 @@ export class BankAccountsController { @Get() @ApiOperation({ summary: 'Retrieve the bank accounts.' }) - @ApiQuery({ - name: 'query', - description: 'Query parameters for the bank accounts list.', - type: BankAccountsQueryDto, - required: false, - }) @ApiResponse({ status: 200, description: 'List of bank accounts retrieved successfully.', diff --git a/packages/server/src/modules/FinancialStatements/dtos/FinancialReportResponse.dto.ts b/packages/server/src/modules/FinancialStatements/dtos/FinancialReportResponse.dto.ts new file mode 100644 index 000000000..7ae89100d --- /dev/null +++ b/packages/server/src/modules/FinancialStatements/dtos/FinancialReportResponse.dto.ts @@ -0,0 +1,103 @@ +import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; + +// ============== Common DTOs ============== + +export class FinancialReportTotalDto { + @ApiProperty({ description: 'Numeric amount', type: Number }) + amount: number; + + @ApiProperty({ description: 'Formatted amount string' }) + formattedAmount: string; + + @ApiProperty({ description: 'Currency code' }) + currencyCode: string; + + @ApiPropertyOptional({ description: 'Date associated with the total' }) + date?: string | Date; +} + +export class FinancialReportPercentageDto { + @ApiProperty({ description: 'Percentage amount', type: Number }) + amount: number; + + @ApiProperty({ description: 'Formatted percentage string' }) + formattedAmount: string; +} + +export class FinancialReportMetaDto { + @ApiProperty({ description: 'Organization name' }) + organizationName: string; + + @ApiProperty({ description: 'Base currency code' }) + baseCurrency: string; + + @ApiProperty({ description: 'Date format string' }) + dateFormat: string; + + @ApiProperty({ description: 'Whether cost computation is running' }) + isCostComputeRunning: boolean; + + @ApiProperty({ description: 'Sheet name' }) + sheetName: string; +} + +// ============== Table DTOs ============== + +export class FinancialTableCellDto { + @ApiProperty({ description: 'Cell key' }) + key: string; + + @ApiProperty({ description: 'Cell value' }) + value: string; +} + +export class FinancialTableRowDto { + @ApiProperty({ description: 'Cell data for this row', type: [FinancialTableCellDto] }) + cells: FinancialTableCellDto[]; + + @ApiProperty({ description: 'Row type classifications', type: [String] }) + rowTypes: string[]; + + @ApiProperty({ description: 'Row identifier' }) + id: string | number; + + @ApiPropertyOptional({ description: 'Child rows', type: () => [FinancialTableRowDto] }) + children?: FinancialTableRowDto[]; +} + +export class FinancialTableColumnDto { + @ApiProperty({ description: 'Column key' }) + key: string; + + @ApiProperty({ description: 'Column header label' }) + label: string; + + @ApiPropertyOptional({ description: 'Cell position index', type: Number }) + cellIndex?: number; + + @ApiPropertyOptional({ description: 'Nested column definitions', type: () => [FinancialTableColumnDto] }) + children?: FinancialTableColumnDto[]; +} + +export class FinancialTableDataDto { + @ApiProperty({ description: 'Table column definitions', type: [FinancialTableColumnDto] }) + columns: FinancialTableColumnDto[]; + + @ApiProperty({ description: 'Table row data', type: [FinancialTableRowDto] }) + rows: FinancialTableRowDto[]; +} + +// ============== Base Report Response DTOs ============== + +export class BaseFinancialReportResponseDto { + @ApiProperty({ description: 'Report metadata', type: FinancialReportMetaDto }) + meta: FinancialReportMetaDto; +} + +export class BaseFinancialTableResponseDto { + @ApiProperty({ description: 'Table data structure', type: FinancialTableDataDto }) + table: FinancialTableDataDto; + + @ApiProperty({ description: 'Report metadata', type: FinancialReportMetaDto }) + meta: FinancialReportMetaDto; +} diff --git a/packages/server/src/modules/FinancialStatements/modules/APAgingSummary/APAgingSummary.controller.ts b/packages/server/src/modules/FinancialStatements/modules/APAgingSummary/APAgingSummary.controller.ts index e552f1a90..9c87bbdfb 100644 --- a/packages/server/src/modules/FinancialStatements/modules/APAgingSummary/APAgingSummary.controller.ts +++ b/packages/server/src/modules/FinancialStatements/modules/APAgingSummary/APAgingSummary.controller.ts @@ -3,13 +3,19 @@ import { Controller, Get, Headers, Query, Res, UseGuards } from '@nestjs/common' import { APAgingSummaryApplication } from './APAgingSummaryApplication'; import { AcceptType } from '@/constants/accept-type'; import { + ApiExtraModels, ApiOperation, ApiProduces, ApiResponse, ApiTags, + getSchemaPath, } from '@nestjs/swagger'; import { APAgingSummaryQueryDto } from './APAgingSummaryQuery.dto'; import { APAgingSummaryResponseExample } from './APAgingSummary.swagger'; +import { + APAgingSummaryResponseDto, + APAgingSummaryTableResponseDto, +} from './APAgingSummaryResponse.dto'; import { ApiCommonHeaders } from '@/common/decorators/ApiCommonHeaders'; import { RequirePermission } from '@/modules/Roles/RequirePermission.decorator'; import { PermissionGuard } from '@/modules/Roles/Permission.guard'; @@ -21,6 +27,7 @@ import { ReportsAction } from '../../types/Report.types'; @ApiTags('Reports') @ApiCommonHeaders() @UseGuards(AuthorizationGuard, PermissionGuard) +@ApiExtraModels(APAgingSummaryResponseDto, APAgingSummaryTableResponseDto) export class APAgingSummaryController { constructor(private readonly APAgingSummaryApp: APAgingSummaryApplication) { } @@ -30,7 +37,15 @@ export class APAgingSummaryController { @ApiResponse({ status: 200, description: 'A/P aging summary response', - example: APAgingSummaryResponseExample, + content: { + [AcceptType.ApplicationJson]: { + schema: { $ref: getSchemaPath(APAgingSummaryResponseDto) }, + example: APAgingSummaryResponseExample, + }, + [AcceptType.ApplicationJsonTable]: { + schema: { $ref: getSchemaPath(APAgingSummaryTableResponseDto) }, + }, + }, }) @ApiProduces( AcceptType.ApplicationJson, diff --git a/packages/server/src/modules/FinancialStatements/modules/APAgingSummary/APAgingSummaryResponse.dto.ts b/packages/server/src/modules/FinancialStatements/modules/APAgingSummary/APAgingSummaryResponse.dto.ts new file mode 100644 index 000000000..4c2f0e518 --- /dev/null +++ b/packages/server/src/modules/FinancialStatements/modules/APAgingSummary/APAgingSummaryResponse.dto.ts @@ -0,0 +1,109 @@ +import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; +import { NumberFormatQueryDto } from '@/modules/BankingTransactions/dtos/NumberFormatQuery.dto'; +import { + FinancialReportTotalDto, + FinancialReportMetaDto, + FinancialTableDataDto, +} from '../../dtos/FinancialReportResponse.dto'; + +export class APAgingPeriodDto { + @ApiProperty({ description: 'From period date' }) + fromPeriod: string; + + @ApiPropertyOptional({ description: 'To period date' }) + toPeriod: string | null; + + @ApiProperty({ description: 'Before days', type: Number }) + beforeDays: number; + + @ApiPropertyOptional({ description: 'To days', type: Number }) + toDays: number | null; +} + +export class APAgingPeriodTotalDto extends APAgingPeriodDto { + @ApiProperty({ description: 'Period total', type: FinancialReportTotalDto }) + total: FinancialReportTotalDto; +} + +export class APAgingVendorDto { + @ApiProperty({ description: 'Vendor name' }) + vendorName: string; + + @ApiProperty({ description: 'Current balance', type: FinancialReportTotalDto }) + current: FinancialReportTotalDto; + + @ApiProperty({ description: 'Aging periods', type: [APAgingPeriodTotalDto] }) + aging: APAgingPeriodTotalDto[]; + + @ApiProperty({ description: 'Vendor total', type: FinancialReportTotalDto }) + total: FinancialReportTotalDto; +} + +export class APAgingSummaryDataDto { + @ApiProperty({ description: 'Vendors aging data', type: [APAgingVendorDto] }) + vendors: APAgingVendorDto[]; + + @ApiProperty({ description: 'Current total', type: FinancialReportTotalDto }) + current: FinancialReportTotalDto; + + @ApiProperty({ description: 'Aging totals', type: [APAgingPeriodTotalDto] }) + aging: APAgingPeriodTotalDto[]; + + @ApiProperty({ description: 'Grand total', type: FinancialReportTotalDto }) + total: FinancialReportTotalDto; +} + +export class APAgingSummaryMetaDto extends FinancialReportMetaDto { + @ApiProperty({ description: 'Formatted as-of date' }) + formattedAsDate: string; +} + +export class APAgingSummaryQueryResponseDto { + @ApiProperty({ description: 'As-of date' }) + asDate: string; + + @ApiProperty({ description: 'Aging days before', type: Number }) + agingDaysBefore: number; + + @ApiProperty({ description: 'Number of aging periods', type: Number }) + agingPeriods: number; + + @ApiProperty({ description: 'Number format settings', type: NumberFormatQueryDto }) + numberFormat: NumberFormatQueryDto; + + @ApiProperty({ description: 'Vendor IDs to include', type: [Number] }) + vendorsIds: number[]; + + @ApiProperty({ description: 'Branch IDs to include', type: [Number] }) + branchesIds: number[]; + + @ApiProperty({ description: 'Exclude zero balance accounts' }) + noneZero: boolean; +} + +export class APAgingSummaryResponseDto { + @ApiProperty({ description: 'Aging summary data', type: APAgingSummaryDataDto }) + data: APAgingSummaryDataDto; + + @ApiProperty({ description: 'Report metadata', type: APAgingSummaryMetaDto }) + meta: APAgingSummaryMetaDto; +} + +// Re-export table DTOs for convenience +export { + FinancialTableCellDto as APAgingSummaryTableCellDto, + FinancialTableRowDto as APAgingSummaryTableRowDto, + FinancialTableColumnDto as APAgingSummaryTableColumnDto, + FinancialTableDataDto as APAgingSummaryTableDataDto, +} from '../../dtos/FinancialReportResponse.dto'; + +export class APAgingSummaryTableResponseDto { + @ApiProperty({ description: 'Table data structure', type: () => FinancialTableDataDto }) + table: FinancialTableDataDto; + + @ApiProperty({ description: 'Query parameters used to generate the report', type: APAgingSummaryQueryResponseDto }) + query: APAgingSummaryQueryResponseDto; + + @ApiProperty({ description: 'Report metadata', type: APAgingSummaryMetaDto }) + meta: APAgingSummaryMetaDto; +} diff --git a/packages/server/src/modules/FinancialStatements/modules/ARAgingSummary/ARAgingSummary.controller.ts b/packages/server/src/modules/FinancialStatements/modules/ARAgingSummary/ARAgingSummary.controller.ts index 46bfaf439..19d7d2ed0 100644 --- a/packages/server/src/modules/FinancialStatements/modules/ARAgingSummary/ARAgingSummary.controller.ts +++ b/packages/server/src/modules/FinancialStatements/modules/ARAgingSummary/ARAgingSummary.controller.ts @@ -3,13 +3,19 @@ import { ARAgingSummaryApplication } from './ARAgingSummaryApplication'; import { AcceptType } from '@/constants/accept-type'; import { Response } from 'express'; import { + ApiExtraModels, ApiOperation, ApiProduces, ApiResponse, ApiTags, + getSchemaPath, } from '@nestjs/swagger'; import { ARAgingSummaryQueryDto } from './ARAgingSummaryQuery.dto'; import { ARAgingSummaryResponseExample } from './ARAgingSummary.swagger'; +import { + ARAgingSummaryResponseDto, + ARAgingSummaryTableResponseDto, +} from './ARAgingSummaryResponse.dto'; import { ApiCommonHeaders } from '@/common/decorators/ApiCommonHeaders'; import { RequirePermission } from '@/modules/Roles/RequirePermission.decorator'; import { PermissionGuard } from '@/modules/Roles/Permission.guard'; @@ -21,6 +27,7 @@ import { ReportsAction } from '../../types/Report.types'; @ApiTags('Reports') @ApiCommonHeaders() @UseGuards(AuthorizationGuard, PermissionGuard) +@ApiExtraModels(ARAgingSummaryResponseDto, ARAgingSummaryTableResponseDto) export class ARAgingSummaryController { constructor(private readonly ARAgingSummaryApp: ARAgingSummaryApplication) {} @@ -30,7 +37,15 @@ export class ARAgingSummaryController { @ApiResponse({ status: 200, description: 'Receivable aging summary response', - example: ARAgingSummaryResponseExample, + content: { + [AcceptType.ApplicationJson]: { + schema: { $ref: getSchemaPath(ARAgingSummaryResponseDto) }, + example: ARAgingSummaryResponseExample, + }, + [AcceptType.ApplicationJsonTable]: { + schema: { $ref: getSchemaPath(ARAgingSummaryTableResponseDto) }, + }, + }, }) @ApiProduces( AcceptType.ApplicationJson, diff --git a/packages/server/src/modules/FinancialStatements/modules/ARAgingSummary/ARAgingSummaryResponse.dto.ts b/packages/server/src/modules/FinancialStatements/modules/ARAgingSummary/ARAgingSummaryResponse.dto.ts new file mode 100644 index 000000000..3c1a32fe1 --- /dev/null +++ b/packages/server/src/modules/FinancialStatements/modules/ARAgingSummary/ARAgingSummaryResponse.dto.ts @@ -0,0 +1,115 @@ +import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; +import { NumberFormatQueryDto } from '@/modules/BankingTransactions/dtos/NumberFormatQuery.dto'; +import { + FinancialReportTotalDto, + FinancialReportMetaDto, + FinancialTableDataDto, +} from '../../dtos/FinancialReportResponse.dto'; + +export class ARAgingPeriodDto { + @ApiProperty({ description: 'From period date' }) + fromPeriod: string; + + @ApiPropertyOptional({ description: 'To period date' }) + toPeriod: string | null; + + @ApiProperty({ description: 'Before days', type: Number }) + beforeDays: number; + + @ApiPropertyOptional({ description: 'To days', type: Number }) + toDays: number | null; +} + +export class ARAgingPeriodTotalDto extends ARAgingPeriodDto { + @ApiProperty({ description: 'Period total', type: FinancialReportTotalDto }) + total: FinancialReportTotalDto; +} + +export class ARAgingCustomerDto { + @ApiProperty({ description: 'Customer name' }) + customerName: string; + + @ApiProperty({ description: 'Current balance', type: FinancialReportTotalDto }) + current: FinancialReportTotalDto; + + @ApiProperty({ description: 'Aging periods', type: [ARAgingPeriodTotalDto] }) + aging: ARAgingPeriodTotalDto[]; + + @ApiProperty({ description: 'Customer total', type: FinancialReportTotalDto }) + total: FinancialReportTotalDto; +} + +export class ARAgingSummaryDataDto { + @ApiProperty({ description: 'Customers aging data', type: [ARAgingCustomerDto] }) + customers: ARAgingCustomerDto[]; + + @ApiProperty({ description: 'Current total', type: FinancialReportTotalDto }) + current: FinancialReportTotalDto; + + @ApiProperty({ description: 'Aging totals', type: [ARAgingPeriodTotalDto] }) + aging: ARAgingPeriodTotalDto[]; + + @ApiProperty({ description: 'Grand total', type: FinancialReportTotalDto }) + total: FinancialReportTotalDto; +} + +export class ARAgingSummaryMetaDto extends FinancialReportMetaDto { + @ApiProperty({ description: 'Formatted as-of date' }) + formattedAsDate: string; +} + +export class ARAgingSummaryQueryResponseDto { + @ApiProperty({ description: 'As-of date' }) + asDate: string; + + @ApiProperty({ description: 'Aging days before', type: Number }) + agingDaysBefore: number; + + @ApiProperty({ description: 'Number of aging periods', type: Number }) + agingPeriods: number; + + @ApiProperty({ description: 'Number format settings', type: NumberFormatQueryDto }) + numberFormat: NumberFormatQueryDto; + + @ApiProperty({ description: 'Customer IDs to include', type: [Number] }) + customersIds: number[]; + + @ApiProperty({ description: 'Branch IDs to include', type: [Number] }) + branchesIds: number[]; + + @ApiProperty({ description: 'Exclude zero balance accounts' }) + noneZero: boolean; +} + +export class ARAgingSummaryResponseDto { + @ApiProperty({ description: 'Query parameters used to generate the report', type: ARAgingSummaryQueryResponseDto }) + query: ARAgingSummaryQueryResponseDto; + + @ApiProperty({ description: 'Aging columns definitions', type: [ARAgingPeriodDto] }) + columns: ARAgingPeriodDto[]; + + @ApiProperty({ description: 'Aging summary data', type: ARAgingSummaryDataDto }) + data: ARAgingSummaryDataDto; + + @ApiProperty({ description: 'Report metadata', type: ARAgingSummaryMetaDto }) + meta: ARAgingSummaryMetaDto; +} + +// Re-export table DTOs for convenience +export { + FinancialTableCellDto as ARAgingSummaryTableCellDto, + FinancialTableRowDto as ARAgingSummaryTableRowDto, + FinancialTableColumnDto as ARAgingSummaryTableColumnDto, + FinancialTableDataDto as ARAgingSummaryTableDataDto, +} from '../../dtos/FinancialReportResponse.dto'; + +export class ARAgingSummaryTableResponseDto { + @ApiProperty({ description: 'Table data structure', type: () => FinancialTableDataDto }) + table: FinancialTableDataDto; + + @ApiProperty({ description: 'Query parameters used to generate the report', type: ARAgingSummaryQueryResponseDto }) + query: ARAgingSummaryQueryResponseDto; + + @ApiProperty({ description: 'Report metadata', type: ARAgingSummaryMetaDto }) + meta: ARAgingSummaryMetaDto; +} diff --git a/packages/server/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheet.controller.ts b/packages/server/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheet.controller.ts index 7d80f00c3..c85acfbd5 100644 --- a/packages/server/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheet.controller.ts +++ b/packages/server/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheet.controller.ts @@ -3,13 +3,22 @@ import { Controller, Get, Headers, Query, Res, UseGuards } from '@nestjs/common' import { AcceptType } from '@/constants/accept-type'; import { BalanceSheetApplication } from './BalanceSheetApplication'; import { + ApiExtraModels, ApiOperation, ApiProduces, ApiResponse, ApiTags, + getSchemaPath, } from '@nestjs/swagger'; import { BalanceSheetQueryDto } from './BalanceSheet.dto'; -import { BalanceSheetResponseExample } from './BalanceSheet.swagger'; +import { + BalanceSheetResponseExample, + BalanceSheetTableResponseExample, +} from './BalanceSheet.swagger'; +import { + BalanceSheetResponseDto, + BalanceSheetTableResponseDto, +} from './BalanceSheetResponse.dto'; import { ApiCommonHeaders } from '@/common/decorators/ApiCommonHeaders'; import { RequirePermission } from '@/modules/Roles/RequirePermission.decorator'; import { PermissionGuard } from '@/modules/Roles/Permission.guard'; @@ -21,6 +30,7 @@ import { ReportsAction } from '../../types/Report.types'; @ApiTags('Reports') @ApiCommonHeaders() @UseGuards(AuthorizationGuard, PermissionGuard) +@ApiExtraModels(BalanceSheetResponseDto, BalanceSheetTableResponseDto) export class BalanceSheetStatementController { constructor(private readonly balanceSheetApp: BalanceSheetApplication) {} @@ -36,7 +46,16 @@ export class BalanceSheetStatementController { @ApiResponse({ status: 200, description: 'Balance sheet statement', - example: BalanceSheetResponseExample, + content: { + [AcceptType.ApplicationJson]: { + schema: { $ref: getSchemaPath(BalanceSheetResponseDto) }, + example: BalanceSheetResponseExample, + }, + [AcceptType.ApplicationJsonTable]: { + schema: { $ref: getSchemaPath(BalanceSheetTableResponseDto) }, + example: BalanceSheetTableResponseExample, + }, + }, }) @ApiProduces( AcceptType.ApplicationJson, diff --git a/packages/server/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetResponse.dto.ts b/packages/server/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetResponse.dto.ts new file mode 100644 index 000000000..04f905969 --- /dev/null +++ b/packages/server/src/modules/FinancialStatements/modules/BalanceSheet/BalanceSheetResponse.dto.ts @@ -0,0 +1,158 @@ +import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; +import { NumberFormatQueryDto } from '@/modules/BankingTransactions/dtos/NumberFormatQuery.dto'; +import { + FinancialReportTotalDto, + FinancialReportPercentageDto, + FinancialReportMetaDto, + FinancialTableDataDto, +} from '../../dtos/FinancialReportResponse.dto'; + +export class BalanceSheetDataNodeDto { + @ApiProperty({ description: 'Node identifier (string for aggregates, number for accounts)' }) + id: string | number; + + @ApiProperty({ description: 'Account or category name' }) + name: string; + + @ApiProperty({ + description: 'Type of node', + enum: ['AGGREGATE', 'ACCOUNTS', 'ACCOUNT', 'NET_INCOME'], + }) + nodeType: string; + + @ApiPropertyOptional({ description: 'Node type alias' }) + type?: string; + + @ApiProperty({ description: 'Total amount information', type: FinancialReportTotalDto }) + total: FinancialReportTotalDto; + + @ApiPropertyOptional({ description: 'Horizontal totals for date periods', type: [FinancialReportTotalDto] }) + horizontalTotals?: FinancialReportTotalDto[]; + + @ApiPropertyOptional({ description: 'Percentage of row', type: FinancialReportPercentageDto }) + percentageRow?: FinancialReportPercentageDto; + + @ApiPropertyOptional({ description: 'Percentage of column', type: FinancialReportPercentageDto }) + percentageColumn?: FinancialReportPercentageDto; + + @ApiPropertyOptional({ description: 'Previous period total', type: FinancialReportTotalDto }) + previousPeriod?: FinancialReportTotalDto; + + @ApiPropertyOptional({ description: 'Previous period change', type: FinancialReportTotalDto }) + previousPeriodChange?: FinancialReportTotalDto; + + @ApiPropertyOptional({ description: 'Previous period percentage', type: FinancialReportPercentageDto }) + previousPeriodPercentage?: FinancialReportPercentageDto; + + @ApiPropertyOptional({ description: 'Previous year total', type: FinancialReportTotalDto }) + previousYear?: FinancialReportTotalDto; + + @ApiPropertyOptional({ description: 'Previous year change', type: FinancialReportTotalDto }) + previousYearChange?: FinancialReportTotalDto; + + @ApiPropertyOptional({ description: 'Previous year percentage', type: FinancialReportPercentageDto }) + previousYearPercentage?: FinancialReportPercentageDto; + + @ApiPropertyOptional({ description: 'Account code' }) + code?: string; + + @ApiPropertyOptional({ description: 'Display index', type: Number }) + index?: number; + + @ApiPropertyOptional({ description: 'Parent account ID', type: Number }) + parentAccountId?: number; + + @ApiPropertyOptional({ description: 'Child nodes', type: () => [BalanceSheetDataNodeDto] }) + children?: BalanceSheetDataNodeDto[]; +} + +export class BalanceSheetMetaDto extends FinancialReportMetaDto { + @ApiProperty({ description: 'Formatted as-of date' }) + formattedAsDate: string; + + @ApiProperty({ description: 'Formatted date range' }) + formattedDateRange: string; +} + +export class BalanceSheetQueryResponseDto { + @ApiProperty({ description: 'Column display type', enum: ['total', 'date_periods'] }) + displayColumnsType: string; + + @ApiProperty({ description: 'Column grouping', enum: ['day', 'month', 'year', 'quarter'] }) + displayColumnsBy: string; + + @ApiProperty({ description: 'Start date' }) + fromDate: string; + + @ApiProperty({ description: 'End date' }) + toDate: string; + + @ApiProperty({ description: 'Number format settings', type: NumberFormatQueryDto }) + numberFormat: NumberFormatQueryDto; + + @ApiProperty({ description: 'Exclude zero balance accounts' }) + noneZero: boolean; + + @ApiProperty({ description: 'Exclude accounts with no transactions' }) + noneTransactions: boolean; + + @ApiProperty({ description: 'Accounting basis', enum: ['cash', 'accrual'] }) + basis: string; + + @ApiProperty({ description: 'Account IDs to include', type: [Number] }) + accountIds: number[]; + + @ApiProperty({ description: 'Show percentage of column' }) + percentageOfColumn: boolean; + + @ApiProperty({ description: 'Show percentage of row' }) + percentageOfRow: boolean; + + @ApiProperty({ description: 'Include previous period' }) + previousPeriod: boolean; + + @ApiProperty({ description: 'Show previous period amount change' }) + previousPeriodAmountChange: boolean; + + @ApiProperty({ description: 'Show previous period percentage change' }) + previousPeriodPercentageChange: boolean; + + @ApiProperty({ description: 'Include previous year' }) + previousYear: boolean; + + @ApiProperty({ description: 'Show previous year amount change' }) + previousYearAmountChange: boolean; + + @ApiProperty({ description: 'Show previous year percentage change' }) + previousYearPercentageChange: boolean; +} + +export class BalanceSheetResponseDto { + @ApiProperty({ description: 'Query parameters used to generate the report', type: BalanceSheetQueryResponseDto }) + query: BalanceSheetQueryResponseDto; + + @ApiProperty({ description: 'Hierarchical balance sheet data', type: [BalanceSheetDataNodeDto] }) + data: BalanceSheetDataNodeDto[]; + + @ApiProperty({ description: 'Report metadata', type: BalanceSheetMetaDto }) + meta: BalanceSheetMetaDto; +} + +// Re-export table DTOs for convenience +export { + FinancialTableCellDto as BalanceSheetTableCellDto, + FinancialTableRowDto as BalanceSheetTableRowDto, + FinancialTableColumnDto as BalanceSheetTableColumnDto, + FinancialTableDataDto as BalanceSheetTableDataDto, +} from '../../dtos/FinancialReportResponse.dto'; + +export class BalanceSheetTableResponseDto { + @ApiProperty({ description: 'Table data structure', type: () => FinancialTableDataDto }) + table: FinancialTableDataDto; + + @ApiProperty({ description: 'Query parameters used to generate the report', type: BalanceSheetQueryResponseDto }) + query: BalanceSheetQueryResponseDto; + + @ApiProperty({ description: 'Report metadata', type: BalanceSheetMetaDto }) + meta: BalanceSheetMetaDto; +} diff --git a/packages/server/src/modules/FinancialStatements/modules/CashFlowStatement/Cashflow.controller.ts b/packages/server/src/modules/FinancialStatements/modules/CashFlowStatement/Cashflow.controller.ts index f963e17bb..967f3e5f2 100644 --- a/packages/server/src/modules/FinancialStatements/modules/CashFlowStatement/Cashflow.controller.ts +++ b/packages/server/src/modules/FinancialStatements/modules/CashFlowStatement/Cashflow.controller.ts @@ -3,13 +3,19 @@ import { Controller, Get, Headers, Query, Res, UseGuards } from '@nestjs/common' import { AcceptType } from '@/constants/accept-type'; import { CashflowSheetApplication } from './CashflowSheetApplication'; import { + ApiExtraModels, ApiOperation, ApiProduces, ApiResponse, ApiTags, + getSchemaPath, } from '@nestjs/swagger'; import { CashFlowStatementQueryDto } from './CashFlowStatementQuery.dto'; import { CashflowStatementResponseExample } from './CashflowStatement.swagger'; +import { + CashflowStatementResponseDto, + CashflowStatementTableResponseDto, +} from './CashflowStatementResponse.dto'; import { ApiCommonHeaders } from '@/common/decorators/ApiCommonHeaders'; import { RequirePermission } from '@/modules/Roles/RequirePermission.decorator'; import { PermissionGuard } from '@/modules/Roles/Permission.guard'; @@ -21,6 +27,7 @@ import { ReportsAction } from '../../types/Report.types'; @ApiTags('Reports') @ApiCommonHeaders() @UseGuards(AuthorizationGuard, PermissionGuard) +@ApiExtraModels(CashflowStatementResponseDto, CashflowStatementTableResponseDto) export class CashflowController { constructor(private readonly cashflowSheetApp: CashflowSheetApplication) { } @@ -29,7 +36,15 @@ export class CashflowController { @ApiResponse({ status: 200, description: 'Cashflow statement report', - example: CashflowStatementResponseExample, + content: { + [AcceptType.ApplicationJson]: { + schema: { $ref: getSchemaPath(CashflowStatementResponseDto) }, + example: CashflowStatementResponseExample, + }, + [AcceptType.ApplicationJsonTable]: { + schema: { $ref: getSchemaPath(CashflowStatementTableResponseDto) }, + }, + }, }) @ApiOperation({ summary: 'Get cashflow statement report' }) @ApiProduces( diff --git a/packages/server/src/modules/FinancialStatements/modules/CashFlowStatement/CashflowStatementResponse.dto.ts b/packages/server/src/modules/FinancialStatements/modules/CashFlowStatement/CashflowStatementResponse.dto.ts new file mode 100644 index 000000000..d110874c9 --- /dev/null +++ b/packages/server/src/modules/FinancialStatements/modules/CashFlowStatement/CashflowStatementResponse.dto.ts @@ -0,0 +1,109 @@ +import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; +import { NumberFormatQueryDto } from '@/modules/BankingTransactions/dtos/NumberFormatQuery.dto'; +import { + FinancialReportTotalDto, + FinancialReportMetaDto, + FinancialTableDataDto, +} from '../../dtos/FinancialReportResponse.dto'; + +export class CashflowStatementDataNodeDto { + @ApiProperty({ description: 'Node identifier (string for aggregates, number for accounts)' }) + id: string | number; + + @ApiProperty({ description: 'Account or category name' }) + name: string; + + @ApiProperty({ + description: 'Type of node', + enum: ['AGGREGATE', 'ACCOUNT', 'NET_INCOME', 'TOTAL'], + }) + nodeType: string; + + @ApiPropertyOptional({ description: 'Node type alias' }) + type?: string; + + @ApiProperty({ description: 'Total amount information', type: FinancialReportTotalDto }) + total: FinancialReportTotalDto; + + @ApiPropertyOptional({ description: 'Horizontal totals for date periods', type: [FinancialReportTotalDto] }) + horizontalTotals?: FinancialReportTotalDto[]; + + @ApiPropertyOptional({ description: 'Account code' }) + code?: string; + + @ApiPropertyOptional({ description: 'Display index', type: Number }) + index?: number; + + @ApiPropertyOptional({ description: 'Child nodes', type: () => [CashflowStatementDataNodeDto] }) + children?: CashflowStatementDataNodeDto[]; +} + +export class CashflowStatementMetaDto extends FinancialReportMetaDto { + @ApiProperty({ description: 'Formatted from date' }) + formattedFromDate: string; + + @ApiProperty({ description: 'Formatted to date' }) + formattedToDate: string; + + @ApiProperty({ description: 'Formatted date range' }) + formattedDateRange: string; +} + +export class CashflowStatementQueryResponseDto { + @ApiProperty({ description: 'Column display type', enum: ['total', 'date_periods'] }) + displayColumnsType: string; + + @ApiProperty({ description: 'Column grouping', enum: ['day', 'month', 'year', 'quarter'] }) + displayColumnsBy: string; + + @ApiProperty({ description: 'Start date' }) + fromDate: string; + + @ApiProperty({ description: 'End date' }) + toDate: string; + + @ApiProperty({ description: 'Number format settings', type: NumberFormatQueryDto }) + numberFormat: NumberFormatQueryDto; + + @ApiProperty({ description: 'Exclude zero balance accounts' }) + noneZero: boolean; + + @ApiProperty({ description: 'Exclude accounts with no transactions' }) + noneTransactions: boolean; + + @ApiProperty({ description: 'Accounting basis', enum: ['cash', 'accrual'] }) + basis: string; + + @ApiProperty({ description: 'Account IDs to include', type: [Number] }) + accountIds: number[]; +} + +export class CashflowStatementResponseDto { + @ApiProperty({ description: 'Query parameters used to generate the report', type: CashflowStatementQueryResponseDto }) + query: CashflowStatementQueryResponseDto; + + @ApiProperty({ description: 'Hierarchical cashflow data', type: [CashflowStatementDataNodeDto] }) + data: CashflowStatementDataNodeDto[]; + + @ApiProperty({ description: 'Report metadata', type: CashflowStatementMetaDto }) + meta: CashflowStatementMetaDto; +} + +// Re-export table DTOs for convenience +export { + FinancialTableCellDto as CashflowStatementTableCellDto, + FinancialTableRowDto as CashflowStatementTableRowDto, + FinancialTableColumnDto as CashflowStatementTableColumnDto, + FinancialTableDataDto as CashflowStatementTableDataDto, +} from '../../dtos/FinancialReportResponse.dto'; + +export class CashflowStatementTableResponseDto { + @ApiProperty({ description: 'Table data structure', type: () => FinancialTableDataDto }) + table: FinancialTableDataDto; + + @ApiProperty({ description: 'Query parameters used to generate the report', type: CashflowStatementQueryResponseDto }) + query: CashflowStatementQueryResponseDto; + + @ApiProperty({ description: 'Report metadata', type: CashflowStatementMetaDto }) + meta: CashflowStatementMetaDto; +} diff --git a/packages/server/src/modules/FinancialStatements/modules/CustomerBalanceSummary/CustomerBalanceSummary.controller.ts b/packages/server/src/modules/FinancialStatements/modules/CustomerBalanceSummary/CustomerBalanceSummary.controller.ts index 3601a2818..20ff6aa01 100644 --- a/packages/server/src/modules/FinancialStatements/modules/CustomerBalanceSummary/CustomerBalanceSummary.controller.ts +++ b/packages/server/src/modules/FinancialStatements/modules/CustomerBalanceSummary/CustomerBalanceSummary.controller.ts @@ -1,26 +1,44 @@ import { Response } from 'express'; import { + ApiExtraModels, ApiOperation, ApiProduces, ApiResponse, ApiTags, + getSchemaPath, } from '@nestjs/swagger'; import { Controller, Get, Headers, Query, Res } from '@nestjs/common'; import { CustomerBalanceSummaryApplication } from './CustomerBalanceSummaryApplication'; import { CustomerBalanceSummaryQueryDto } from './CustomerBalanceSummaryQuery.dto'; import { AcceptType } from '@/constants/accept-type'; +import { + CustomerBalanceSummaryResponseDto, + CustomerBalanceSummaryTableResponseDto, +} from './CustomerBalanceSummaryResponse.dto'; import { ApiCommonHeaders } from '@/common/decorators/ApiCommonHeaders'; @Controller('/reports/customer-balance-summary') @ApiTags('Reports') @ApiCommonHeaders() +@ApiExtraModels(CustomerBalanceSummaryResponseDto, CustomerBalanceSummaryTableResponseDto) export class CustomerBalanceSummaryController { constructor( private readonly customerBalanceSummaryApp: CustomerBalanceSummaryApplication, ) {} @Get() - @ApiResponse({ status: 200, description: 'Customer balance summary report' }) + @ApiResponse({ + status: 200, + description: 'Customer balance summary report', + content: { + [AcceptType.ApplicationJson]: { + schema: { $ref: getSchemaPath(CustomerBalanceSummaryResponseDto) }, + }, + [AcceptType.ApplicationJsonTable]: { + schema: { $ref: getSchemaPath(CustomerBalanceSummaryTableResponseDto) }, + }, + }, + }) @ApiOperation({ summary: 'Get customer balance summary report' }) @ApiProduces( AcceptType.ApplicationJson, diff --git a/packages/server/src/modules/FinancialStatements/modules/CustomerBalanceSummary/CustomerBalanceSummaryResponse.dto.ts b/packages/server/src/modules/FinancialStatements/modules/CustomerBalanceSummary/CustomerBalanceSummaryResponse.dto.ts new file mode 100644 index 000000000..a1dbb929f --- /dev/null +++ b/packages/server/src/modules/FinancialStatements/modules/CustomerBalanceSummary/CustomerBalanceSummaryResponse.dto.ts @@ -0,0 +1,82 @@ +import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; +import { NumberFormatQueryDto } from '@/modules/BankingTransactions/dtos/NumberFormatQuery.dto'; +import { + FinancialReportTotalDto, + FinancialReportMetaDto, + FinancialTableDataDto, +} from '../../dtos/FinancialReportResponse.dto'; + +export class CustomerBalanceDto { + @ApiProperty({ description: 'Customer ID', type: Number }) + customerId: number; + + @ApiProperty({ description: 'Customer name' }) + customerName: string; + + @ApiPropertyOptional({ description: 'Opening balance', type: FinancialReportTotalDto }) + openingBalance?: FinancialReportTotalDto; + + @ApiProperty({ description: 'Closing balance', type: FinancialReportTotalDto }) + closingBalance: FinancialReportTotalDto; + + @ApiPropertyOptional({ description: 'Total debit', type: FinancialReportTotalDto }) + totalDebit?: FinancialReportTotalDto; + + @ApiPropertyOptional({ description: 'Total credit', type: FinancialReportTotalDto }) + totalCredit?: FinancialReportTotalDto; +} + +export class CustomerBalanceSummaryMetaDto extends FinancialReportMetaDto { + @ApiProperty({ description: 'Formatted as-of date' }) + formattedAsDate: string; + + @ApiProperty({ description: 'Formatted date range' }) + formattedDateRange: string; +} + +export class CustomerBalanceSummaryQueryResponseDto { + @ApiProperty({ description: 'As-of date' }) + asDate: string; + + @ApiProperty({ description: 'Number format settings', type: NumberFormatQueryDto }) + numberFormat: NumberFormatQueryDto; + + @ApiProperty({ description: 'Customer IDs to include', type: [Number] }) + customersIds: number[]; + + @ApiProperty({ description: 'Exclude zero balance customers' }) + noneZero: boolean; + + @ApiProperty({ description: 'Exclude inactive customers' }) + noneInactive: boolean; +} + +export class CustomerBalanceSummaryResponseDto { + @ApiProperty({ description: 'Query parameters used to generate the report', type: CustomerBalanceSummaryQueryResponseDto }) + query: CustomerBalanceSummaryQueryResponseDto; + + @ApiProperty({ description: 'Customer balances', type: [CustomerBalanceDto] }) + data: CustomerBalanceDto[]; + + @ApiProperty({ description: 'Report metadata', type: CustomerBalanceSummaryMetaDto }) + meta: CustomerBalanceSummaryMetaDto; +} + +// Re-export table DTOs for convenience +export { + FinancialTableCellDto as CustomerBalanceSummaryTableCellDto, + FinancialTableRowDto as CustomerBalanceSummaryTableRowDto, + FinancialTableColumnDto as CustomerBalanceSummaryTableColumnDto, + FinancialTableDataDto as CustomerBalanceSummaryTableDataDto, +} from '../../dtos/FinancialReportResponse.dto'; + +export class CustomerBalanceSummaryTableResponseDto { + @ApiProperty({ description: 'Table data structure', type: () => FinancialTableDataDto }) + table: FinancialTableDataDto; + + @ApiProperty({ description: 'Query parameters used to generate the report', type: CustomerBalanceSummaryQueryResponseDto }) + query: CustomerBalanceSummaryQueryResponseDto; + + @ApiProperty({ description: 'Report metadata', type: CustomerBalanceSummaryMetaDto }) + meta: CustomerBalanceSummaryMetaDto; +} diff --git a/packages/server/src/modules/FinancialStatements/modules/GeneralLedger/GeneralLedger.controller.ts b/packages/server/src/modules/FinancialStatements/modules/GeneralLedger/GeneralLedger.controller.ts index 7cdf63f21..dc169da1c 100644 --- a/packages/server/src/modules/FinancialStatements/modules/GeneralLedger/GeneralLedger.controller.ts +++ b/packages/server/src/modules/FinancialStatements/modules/GeneralLedger/GeneralLedger.controller.ts @@ -1,8 +1,10 @@ import { + ApiExtraModels, ApiOperation, ApiProduces, ApiResponse, ApiTags, + getSchemaPath, } from '@nestjs/swagger'; import { Response } from 'express'; import { Controller, Get, Headers, Query, Res, UseGuards } from '@nestjs/common'; @@ -10,6 +12,10 @@ import { GeneralLedgerApplication } from './GeneralLedgerApplication'; import { AcceptType } from '@/constants/accept-type'; import { GeneralLedgerQueryDto } from './GeneralLedgerQuery.dto'; import { GeneralLedgerResponseExample } from './GeneralLedger.swagger'; +import { + GeneralLedgerResponseDto, + GeneralLedgerTableResponseDto, +} from './GeneralLedgerResponse.dto'; import { ApiCommonHeaders } from '@/common/decorators/ApiCommonHeaders'; import { RequirePermission } from '@/modules/Roles/RequirePermission.decorator'; import { PermissionGuard } from '@/modules/Roles/Permission.guard'; @@ -21,6 +27,7 @@ import { ReportsAction } from '../../types/Report.types'; @ApiTags('Reports') @ApiCommonHeaders() @UseGuards(AuthorizationGuard, PermissionGuard) +@ApiExtraModels(GeneralLedgerResponseDto, GeneralLedgerTableResponseDto) export class GeneralLedgerController { constructor( private readonly generalLedgerApplication: GeneralLedgerApplication, @@ -31,7 +38,15 @@ export class GeneralLedgerController { @ApiResponse({ status: 200, description: 'General ledger report', - example: GeneralLedgerResponseExample, + content: { + [AcceptType.ApplicationJson]: { + schema: { $ref: getSchemaPath(GeneralLedgerResponseDto) }, + example: GeneralLedgerResponseExample, + }, + [AcceptType.ApplicationJsonTable]: { + schema: { $ref: getSchemaPath(GeneralLedgerTableResponseDto) }, + }, + }, }) @ApiOperation({ summary: 'Get general ledger report' }) @ApiProduces( diff --git a/packages/server/src/modules/FinancialStatements/modules/GeneralLedger/GeneralLedgerResponse.dto.ts b/packages/server/src/modules/FinancialStatements/modules/GeneralLedger/GeneralLedgerResponse.dto.ts new file mode 100644 index 000000000..5c2372386 --- /dev/null +++ b/packages/server/src/modules/FinancialStatements/modules/GeneralLedger/GeneralLedgerResponse.dto.ts @@ -0,0 +1,156 @@ +import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; +import { NumberFormatQueryDto } from '@/modules/BankingTransactions/dtos/NumberFormatQuery.dto'; +import { + FinancialReportTotalDto, + FinancialReportMetaDto, + FinancialTableDataDto, +} from '../../dtos/FinancialReportResponse.dto'; + +export class GeneralLedgerTransactionDto { + @ApiProperty({ description: 'Transaction date' }) + date: string; + + @ApiProperty({ description: 'Formatted date' }) + dateFormatted: string; + + @ApiProperty({ description: 'Reference type' }) + referenceType: string; + + @ApiProperty({ description: 'Reference ID', type: Number }) + referenceId: number; + + @ApiPropertyOptional({ description: 'Transaction number' }) + transactionNumber: string | null; + + @ApiProperty({ description: 'Formatted transaction type' }) + transactionTypeFormatted: string; + + @ApiProperty({ description: 'Contact name' }) + contactName: string; + + @ApiProperty({ description: 'Contact type' }) + contactType: string; + + @ApiProperty({ description: 'Transaction type' }) + transactionType: string; + + @ApiProperty({ description: 'Transaction index', type: Number }) + index: number; + + @ApiPropertyOptional({ description: 'Transaction note' }) + note: string | null; + + @ApiProperty({ description: 'Credit amount', type: Number }) + credit: number; + + @ApiProperty({ description: 'Debit amount', type: Number }) + debit: number; + + @ApiProperty({ description: 'Transaction amount', type: Number }) + amount: number; + + @ApiProperty({ description: 'Running balance', type: Number }) + runningBalance: number; + + @ApiProperty({ description: 'Formatted amount' }) + formattedAmount: string; + + @ApiProperty({ description: 'Formatted credit' }) + formattedCredit: string; + + @ApiProperty({ description: 'Formatted debit' }) + formattedDebit: string; + + @ApiProperty({ description: 'Formatted running balance' }) + formattedRunningBalance: string; + + @ApiProperty({ description: 'Currency code' }) + currencyCode: string; +} + +export class GeneralLedgerAccountDto { + @ApiProperty({ description: 'Account ID', type: Number }) + id: number; + + @ApiProperty({ description: 'Account name' }) + name: string; + + @ApiProperty({ description: 'Account code' }) + code: string; + + @ApiProperty({ description: 'Account index', type: Number }) + index: number; + + @ApiPropertyOptional({ description: 'Parent account ID', type: Number }) + parentAccountId: number | null; + + @ApiProperty({ description: 'Opening balance', type: FinancialReportTotalDto }) + openingBalance: FinancialReportTotalDto; + + @ApiProperty({ description: 'Account transactions', type: [GeneralLedgerTransactionDto] }) + transactions: GeneralLedgerTransactionDto[]; + + @ApiProperty({ description: 'Closing balance', type: FinancialReportTotalDto }) + closingBalance: FinancialReportTotalDto; +} + +export class GeneralLedgerMetaDto extends FinancialReportMetaDto { + @ApiProperty({ description: 'Formatted from date' }) + formattedFromDate: string; + + @ApiProperty({ description: 'Formatted to date' }) + formattedToDate: string; + + @ApiProperty({ description: 'Formatted date range' }) + formattedDateRange: string; +} + +export class GeneralLedgerQueryResponseDto { + @ApiProperty({ description: 'Start date' }) + fromDate: string; + + @ApiProperty({ description: 'End date' }) + toDate: string; + + @ApiProperty({ description: 'Accounting basis', enum: ['cash', 'accrual'] }) + basis: string; + + @ApiProperty({ description: 'Number format settings', type: NumberFormatQueryDto }) + numberFormat: NumberFormatQueryDto; + + @ApiProperty({ description: 'Exclude zero balance accounts' }) + noneZero: boolean; + + @ApiProperty({ description: 'Account IDs to include', type: [Number] }) + accountsIds: number[]; +} + +export class GeneralLedgerResponseDto { + @ApiProperty({ description: 'Query parameters used to generate the report', type: GeneralLedgerQueryResponseDto }) + query: GeneralLedgerQueryResponseDto; + + @ApiProperty({ description: 'General ledger data', type: [GeneralLedgerAccountDto] }) + data: GeneralLedgerAccountDto[]; + + @ApiProperty({ description: 'Report metadata', type: GeneralLedgerMetaDto }) + meta: GeneralLedgerMetaDto; +} + +// Re-export table DTOs for convenience +export { + FinancialTableCellDto as GeneralLedgerTableCellDto, + FinancialTableRowDto as GeneralLedgerTableRowDto, + FinancialTableColumnDto as GeneralLedgerTableColumnDto, + FinancialTableDataDto as GeneralLedgerTableDataDto, +} from '../../dtos/FinancialReportResponse.dto'; + +export class GeneralLedgerTableResponseDto { + @ApiProperty({ description: 'Table data structure', type: () => FinancialTableDataDto }) + table: FinancialTableDataDto; + + @ApiProperty({ description: 'Query parameters used to generate the report', type: GeneralLedgerQueryResponseDto }) + query: GeneralLedgerQueryResponseDto; + + @ApiProperty({ description: 'Report metadata', type: GeneralLedgerMetaDto }) + meta: GeneralLedgerMetaDto; +} diff --git a/packages/server/src/modules/FinancialStatements/modules/InventoryItemDetails/InventoryItemDetails.controller.ts b/packages/server/src/modules/FinancialStatements/modules/InventoryItemDetails/InventoryItemDetails.controller.ts index a3074e66e..a099900db 100644 --- a/packages/server/src/modules/FinancialStatements/modules/InventoryItemDetails/InventoryItemDetails.controller.ts +++ b/packages/server/src/modules/FinancialStatements/modules/InventoryItemDetails/InventoryItemDetails.controller.ts @@ -1,14 +1,19 @@ import { Response } from 'express'; -import { ApiOperation, ApiTags } from '@nestjs/swagger'; +import { ApiExtraModels, ApiOperation, ApiTags, ApiResponse, ApiProduces, getSchemaPath } from '@nestjs/swagger'; import { Controller, Get, Headers, Query, Res } from '@nestjs/common'; import { InventoryItemDetailsApplication } from './InventoryItemDetailsApplication'; import { AcceptType } from '@/constants/accept-type'; import { InventoryItemDetailsQueryDto } from './InventoryItemDetailsQuery.dto'; +import { + InventoryItemDetailsResponseDto, + InventoryItemDetailsTableResponseDto, +} from './InventoryItemDetailsResponse.dto'; import { ApiCommonHeaders } from '@/common/decorators/ApiCommonHeaders'; @Controller('reports/inventory-item-details') @ApiTags('Reports') @ApiCommonHeaders() +@ApiExtraModels(InventoryItemDetailsResponseDto, InventoryItemDetailsTableResponseDto) export class InventoryItemDetailsController { constructor( private readonly inventoryItemDetailsApp: InventoryItemDetailsApplication, @@ -16,6 +21,25 @@ export class InventoryItemDetailsController { @Get('/') @ApiOperation({ summary: 'Get inventory item details' }) + @ApiResponse({ + status: 200, + description: 'Inventory item details report', + content: { + [AcceptType.ApplicationJson]: { + schema: { $ref: getSchemaPath(InventoryItemDetailsResponseDto) }, + }, + [AcceptType.ApplicationJsonTable]: { + schema: { $ref: getSchemaPath(InventoryItemDetailsTableResponseDto) }, + }, + }, + }) + @ApiProduces( + AcceptType.ApplicationJson, + AcceptType.ApplicationJsonTable, + AcceptType.ApplicationPdf, + AcceptType.ApplicationXlsx, + AcceptType.ApplicationCsv, + ) async inventoryItemDetails( @Query() query: InventoryItemDetailsQueryDto, @Res({ passthrough: true }) res: Response, diff --git a/packages/server/src/modules/FinancialStatements/modules/InventoryItemDetails/InventoryItemDetailsResponse.dto.ts b/packages/server/src/modules/FinancialStatements/modules/InventoryItemDetails/InventoryItemDetailsResponse.dto.ts new file mode 100644 index 000000000..eeb5450b3 --- /dev/null +++ b/packages/server/src/modules/FinancialStatements/modules/InventoryItemDetails/InventoryItemDetailsResponse.dto.ts @@ -0,0 +1,114 @@ +import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; +import { NumberFormatQueryDto } from '@/modules/BankingTransactions/dtos/NumberFormatQuery.dto'; +import { + FinancialReportTotalDto, + FinancialReportMetaDto, + FinancialTableDataDto, +} from '../../dtos/FinancialReportResponse.dto'; + +export class InventoryItemTransactionDto { + @ApiProperty({ description: 'Transaction date' }) + date: string; + + @ApiProperty({ description: 'Formatted date' }) + dateFormatted: string; + + @ApiProperty({ description: 'Transaction type' }) + transactionType: string; + + @ApiProperty({ description: 'Reference ID', type: Number }) + referenceId: number; + + @ApiProperty({ description: 'Transaction number' }) + transactionNumber: string; + + @ApiPropertyOptional({ description: 'Transaction description' }) + description?: string; + + @ApiProperty({ description: 'Quantity', type: Number }) + quantity: number; + + @ApiProperty({ description: 'Rate', type: Number }) + rate: number; + + @ApiProperty({ description: 'Total amount', type: FinancialReportTotalDto }) + total: FinancialReportTotalDto; + + @ApiProperty({ description: 'Running quantity', type: Number }) + runningQuantity: number; +} + +export class InventoryItemDetailDto { + @ApiProperty({ description: 'Item ID', type: Number }) + id: number; + + @ApiProperty({ description: 'Item name' }) + name: string; + + @ApiProperty({ description: 'Item code' }) + code: string; + + @ApiProperty({ description: 'Opening quantity', type: Number }) + openingQuantity: number; + + @ApiProperty({ description: 'Closing quantity', type: Number }) + closingQuantity: number; + + @ApiProperty({ description: 'Item transactions', type: [InventoryItemTransactionDto] }) + transactions: InventoryItemTransactionDto[]; +} + +export class InventoryItemDetailsMetaDto extends FinancialReportMetaDto { + @ApiProperty({ description: 'Formatted from date' }) + formattedFromDate: string; + + @ApiProperty({ description: 'Formatted to date' }) + formattedToDate: string; + + @ApiProperty({ description: 'Formatted date range' }) + formattedDateRange: string; +} + +export class InventoryItemDetailsQueryResponseDto { + @ApiProperty({ description: 'Start date' }) + fromDate: string; + + @ApiProperty({ description: 'End date' }) + toDate: string; + + @ApiProperty({ description: 'Number format settings', type: NumberFormatQueryDto }) + numberFormat: NumberFormatQueryDto; + + @ApiProperty({ description: 'Item IDs to include', type: [Number] }) + itemsIds: number[]; +} + +export class InventoryItemDetailsResponseDto { + @ApiProperty({ description: 'Query parameters used to generate the report', type: InventoryItemDetailsQueryResponseDto }) + query: InventoryItemDetailsQueryResponseDto; + + @ApiProperty({ description: 'Inventory items with details', type: [InventoryItemDetailDto] }) + data: InventoryItemDetailDto[]; + + @ApiProperty({ description: 'Report metadata', type: InventoryItemDetailsMetaDto }) + meta: InventoryItemDetailsMetaDto; +} + +// Re-export table DTOs for convenience +export { + FinancialTableCellDto as InventoryItemDetailsTableCellDto, + FinancialTableRowDto as InventoryItemDetailsTableRowDto, + FinancialTableColumnDto as InventoryItemDetailsTableColumnDto, + FinancialTableDataDto as InventoryItemDetailsTableDataDto, +} from '../../dtos/FinancialReportResponse.dto'; + +export class InventoryItemDetailsTableResponseDto { + @ApiProperty({ description: 'Table data structure', type: () => FinancialTableDataDto }) + table: FinancialTableDataDto; + + @ApiProperty({ description: 'Query parameters used to generate the report', type: InventoryItemDetailsQueryResponseDto }) + query: InventoryItemDetailsQueryResponseDto; + + @ApiProperty({ description: 'Report metadata', type: InventoryItemDetailsMetaDto }) + meta: InventoryItemDetailsMetaDto; +} diff --git a/packages/server/src/modules/FinancialStatements/modules/InventoryValuationSheet/InventoryValuation.controller.ts b/packages/server/src/modules/FinancialStatements/modules/InventoryValuationSheet/InventoryValuation.controller.ts index 4edc380e2..1dfbf0c80 100644 --- a/packages/server/src/modules/FinancialStatements/modules/InventoryValuationSheet/InventoryValuation.controller.ts +++ b/packages/server/src/modules/FinancialStatements/modules/InventoryValuationSheet/InventoryValuation.controller.ts @@ -1,19 +1,26 @@ import { Response } from 'express'; import { + ApiExtraModels, ApiOperation, ApiProduces, ApiResponse, ApiTags, + getSchemaPath, } from '@nestjs/swagger'; import { Controller, Get, Headers, Query, Res } from '@nestjs/common'; import { InventoryValuationSheetApplication } from './InventoryValuationSheetApplication'; import { InventoryValuationQueryDto } from './InventoryValuationQuery.dto'; import { AcceptType } from '@/constants/accept-type'; +import { + InventoryValuationResponseDto, + InventoryValuationTableResponseDto, +} from './InventoryValuationResponse.dto'; import { ApiCommonHeaders } from '@/common/decorators/ApiCommonHeaders'; @Controller('reports/inventory-valuation') @ApiTags('Reports') @ApiCommonHeaders() +@ApiExtraModels(InventoryValuationResponseDto, InventoryValuationTableResponseDto) export class InventoryValuationController { constructor( private readonly inventoryValuationApp: InventoryValuationSheetApplication, @@ -24,6 +31,14 @@ export class InventoryValuationController { @ApiResponse({ status: 200, description: 'The inventory valuation sheet', + content: { + [AcceptType.ApplicationJson]: { + schema: { $ref: getSchemaPath(InventoryValuationResponseDto) }, + }, + [AcceptType.ApplicationJsonTable]: { + schema: { $ref: getSchemaPath(InventoryValuationTableResponseDto) }, + }, + }, }) @ApiProduces( AcceptType.ApplicationJson, diff --git a/packages/server/src/modules/FinancialStatements/modules/InventoryValuationSheet/InventoryValuationResponse.dto.ts b/packages/server/src/modules/FinancialStatements/modules/InventoryValuationSheet/InventoryValuationResponse.dto.ts new file mode 100644 index 000000000..d59f5a029 --- /dev/null +++ b/packages/server/src/modules/FinancialStatements/modules/InventoryValuationSheet/InventoryValuationResponse.dto.ts @@ -0,0 +1,88 @@ +import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; +import { NumberFormatQueryDto } from '@/modules/BankingTransactions/dtos/NumberFormatQuery.dto'; +import { + FinancialReportTotalDto, + FinancialReportMetaDto, + FinancialTableDataDto, +} from '../../dtos/FinancialReportResponse.dto'; + +export class InventoryValuationItemDto { + @ApiProperty({ description: 'Item ID', type: Number }) + id: number; + + @ApiProperty({ description: 'Item name' }) + name: string; + + @ApiProperty({ description: 'Item code' }) + code: string; + + @ApiProperty({ description: 'Item type' }) + type: string; + + @ApiPropertyOptional({ description: 'Quantity on hand', type: Number }) + quantityOnHand?: number; + + @ApiPropertyOptional({ description: 'Average cost', type: Number }) + averageCost?: number; + + @ApiPropertyOptional({ description: 'Total value', type: FinancialReportTotalDto }) + totalValue?: FinancialReportTotalDto; + + @ApiPropertyOptional({ description: 'Asset account name' }) + assetAccountName?: string; + + @ApiPropertyOptional({ description: 'Asset account code' }) + assetAccountCode?: string; +} + +export class InventoryValuationMetaDto extends FinancialReportMetaDto { + @ApiProperty({ description: 'Formatted as-of date' }) + formattedAsDate: string; + + @ApiProperty({ description: 'Formatted date range' }) + formattedDateRange: string; +} + +export class InventoryValuationQueryResponseDto { + @ApiProperty({ description: 'As-of date' }) + asDate: string; + + @ApiProperty({ description: 'Number format settings', type: NumberFormatQueryDto }) + numberFormat: NumberFormatQueryDto; + + @ApiProperty({ description: 'Item IDs to include', type: [Number] }) + itemsIds: number[]; + + @ApiProperty({ description: 'Exclude zero quantity items' }) + noneZero: boolean; +} + +export class InventoryValuationResponseDto { + @ApiProperty({ description: 'Query parameters used to generate the report', type: InventoryValuationQueryResponseDto }) + query: InventoryValuationQueryResponseDto; + + @ApiProperty({ description: 'Inventory items valuation', type: [InventoryValuationItemDto] }) + data: InventoryValuationItemDto[]; + + @ApiProperty({ description: 'Report metadata', type: InventoryValuationMetaDto }) + meta: InventoryValuationMetaDto; +} + +// Re-export table DTOs for convenience +export { + FinancialTableCellDto as InventoryValuationTableCellDto, + FinancialTableRowDto as InventoryValuationTableRowDto, + FinancialTableColumnDto as InventoryValuationTableColumnDto, + FinancialTableDataDto as InventoryValuationTableDataDto, +} from '../../dtos/FinancialReportResponse.dto'; + +export class InventoryValuationTableResponseDto { + @ApiProperty({ description: 'Table data structure', type: () => FinancialTableDataDto }) + table: FinancialTableDataDto; + + @ApiProperty({ description: 'Query parameters used to generate the report', type: InventoryValuationQueryResponseDto }) + query: InventoryValuationQueryResponseDto; + + @ApiProperty({ description: 'Report metadata', type: InventoryValuationMetaDto }) + meta: InventoryValuationMetaDto; +} diff --git a/packages/server/src/modules/FinancialStatements/modules/JournalSheet/JournalSheet.controller.ts b/packages/server/src/modules/FinancialStatements/modules/JournalSheet/JournalSheet.controller.ts index 415d13133..1989b30da 100644 --- a/packages/server/src/modules/FinancialStatements/modules/JournalSheet/JournalSheet.controller.ts +++ b/packages/server/src/modules/FinancialStatements/modules/JournalSheet/JournalSheet.controller.ts @@ -3,13 +3,19 @@ import { Response } from 'express'; import { AcceptType } from '@/constants/accept-type'; import { JournalSheetApplication } from './JournalSheetApplication'; import { + ApiExtraModels, ApiOperation, ApiProduces, ApiResponse, ApiTags, + getSchemaPath, } from '@nestjs/swagger'; import { JournalSheetQueryDto } from './JournalSheetQuery.dto'; import { JournalSheetResponseExample } from './JournalSheet.swagger'; +import { + JournalSheetResponseDto, + JournalSheetTableResponseDto, +} from './JournalSheetResponse.dto'; import { ApiCommonHeaders } from '@/common/decorators/ApiCommonHeaders'; import { RequirePermission } from '@/modules/Roles/RequirePermission.decorator'; import { PermissionGuard } from '@/modules/Roles/Permission.guard'; @@ -21,6 +27,7 @@ import { ReportsAction } from '../../types/Report.types'; @ApiTags('Reports') @ApiCommonHeaders() @UseGuards(AuthorizationGuard, PermissionGuard) +@ApiExtraModels(JournalSheetResponseDto, JournalSheetTableResponseDto) export class JournalSheetController { constructor(private readonly journalSheetApp: JournalSheetApplication) {} @@ -29,7 +36,15 @@ export class JournalSheetController { @ApiResponse({ status: 200, description: 'Journal report', - example: JournalSheetResponseExample, + content: { + [AcceptType.ApplicationJson]: { + schema: { $ref: getSchemaPath(JournalSheetResponseDto) }, + example: JournalSheetResponseExample, + }, + [AcceptType.ApplicationJsonTable]: { + schema: { $ref: getSchemaPath(JournalSheetTableResponseDto) }, + }, + }, }) @ApiOperation({ summary: 'Journal report' }) @ApiProduces( diff --git a/packages/server/src/modules/FinancialStatements/modules/JournalSheet/JournalSheetResponse.dto.ts b/packages/server/src/modules/FinancialStatements/modules/JournalSheet/JournalSheetResponse.dto.ts new file mode 100644 index 000000000..af529a2c8 --- /dev/null +++ b/packages/server/src/modules/FinancialStatements/modules/JournalSheet/JournalSheetResponse.dto.ts @@ -0,0 +1,137 @@ +import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; +import { + FinancialReportTotalDto, + FinancialReportMetaDto, + FinancialTableDataDto, +} from '../../dtos/FinancialReportResponse.dto'; + +export class JournalEntryDto { + @ApiProperty({ description: 'Entry index', type: Number }) + index: number; + + @ApiPropertyOptional({ description: 'Entry note' }) + note: string | null; + + @ApiPropertyOptional({ description: 'Contact name' }) + contactName?: string; + + @ApiPropertyOptional({ description: 'Contact type' }) + contactType?: string; + + @ApiProperty({ description: 'Account name' }) + accountName: string; + + @ApiProperty({ description: 'Account code' }) + accountCode: string; + + @ApiPropertyOptional({ description: 'Transaction number' }) + transactionNumber: string | null; + + @ApiProperty({ description: 'Formatted credit' }) + formattedCredit: string; + + @ApiProperty({ description: 'Formatted debit' }) + formattedDebit: string; + + @ApiProperty({ description: 'Credit amount', type: Number }) + credit: number; + + @ApiProperty({ description: 'Debit amount', type: Number }) + debit: number; +} + +export class JournalTransactionDto { + @ApiProperty({ description: 'Transaction date' }) + date: string; + + @ApiProperty({ description: 'Formatted date' }) + dateFormatted: string; + + @ApiProperty({ description: 'Transaction type' }) + transactionType: string; + + @ApiProperty({ description: 'Reference ID', type: Number }) + referenceId: number; + + @ApiProperty({ description: 'Formatted reference type' }) + referenceTypeFormatted: string; + + @ApiProperty({ description: 'Journal entries', type: [JournalEntryDto] }) + entries: JournalEntryDto[]; + + @ApiProperty({ description: 'Total credit', type: Number }) + credit: number; + + @ApiProperty({ description: 'Total debit', type: Number }) + debit: number; + + @ApiProperty({ description: 'Formatted total credit' }) + formattedCredit: string; + + @ApiProperty({ description: 'Formatted total debit' }) + formattedDebit: string; +} + +export class JournalSheetMetaDto extends FinancialReportMetaDto { + @ApiProperty({ description: 'Formatted from date' }) + formattedFromDate: string; + + @ApiProperty({ description: 'Formatted to date' }) + formattedToDate: string; + + @ApiProperty({ description: 'Formatted date range' }) + formattedDateRange: string; +} + +export class JournalSheetQueryResponseDto { + @ApiProperty({ description: 'Start date' }) + fromDate: string; + + @ApiProperty({ description: 'End date' }) + toDate: string; + + @ApiPropertyOptional({ description: 'From range' }) + fromRange: number | null; + + @ApiPropertyOptional({ description: 'To range' }) + toRange: number | null; + + @ApiProperty({ description: 'Account IDs to include', type: [Number] }) + accountsIds: number[]; + + @ApiProperty({ description: 'Number format settings', type: Object }) + numberFormat: { + noCents: boolean; + divideOn1000: boolean; + }; +} + +export class JournalSheetResponseDto { + @ApiProperty({ description: 'Query parameters used to generate the report', type: JournalSheetQueryResponseDto }) + query: JournalSheetQueryResponseDto; + + @ApiProperty({ description: 'Journal transactions', type: [JournalTransactionDto] }) + data: JournalTransactionDto[]; + + @ApiProperty({ description: 'Report metadata', type: JournalSheetMetaDto }) + meta: JournalSheetMetaDto; +} + +// Re-export table DTOs for convenience +export { + FinancialTableCellDto as JournalSheetTableCellDto, + FinancialTableRowDto as JournalSheetTableRowDto, + FinancialTableColumnDto as JournalSheetTableColumnDto, + FinancialTableDataDto as JournalSheetTableDataDto, +} from '../../dtos/FinancialReportResponse.dto'; + +export class JournalSheetTableResponseDto { + @ApiProperty({ description: 'Table data structure', type: () => FinancialTableDataDto }) + table: FinancialTableDataDto; + + @ApiProperty({ description: 'Query parameters used to generate the report', type: JournalSheetQueryResponseDto }) + query: JournalSheetQueryResponseDto; + + @ApiProperty({ description: 'Report metadata', type: JournalSheetMetaDto }) + meta: JournalSheetMetaDto; +} diff --git a/packages/server/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSheet.controller.ts b/packages/server/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSheet.controller.ts index 70cc31561..c28bbe370 100644 --- a/packages/server/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSheet.controller.ts +++ b/packages/server/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSheet.controller.ts @@ -3,13 +3,19 @@ import { Controller, Get, Headers, Query, Res, UseGuards } from '@nestjs/common' import { ProfitLossSheetApplication } from './ProfitLossSheetApplication'; import { AcceptType } from '@/constants/accept-type'; import { + ApiExtraModels, ApiOperation, ApiProduces, ApiResponse, ApiTags, + getSchemaPath, } from '@nestjs/swagger'; import { ProfitLossSheetQueryDto } from './ProfitLossSheetQuery.dto'; import { ProfitLossSheetResponseExample } from './ProfitLossSheet.swagger'; +import { + ProfitLossSheetResponseDto, + ProfitLossSheetTableResponseDto, +} from './ProfitLossSheetResponse.dto'; import { ApiCommonHeaders } from '@/common/decorators/ApiCommonHeaders'; import { RequirePermission } from '@/modules/Roles/RequirePermission.decorator'; import { PermissionGuard } from '@/modules/Roles/Permission.guard'; @@ -21,6 +27,7 @@ import { ReportsAction } from '../../types/Report.types'; @ApiTags('Reports') @ApiCommonHeaders() @UseGuards(AuthorizationGuard, PermissionGuard) +@ApiExtraModels(ProfitLossSheetResponseDto, ProfitLossSheetTableResponseDto) export class ProfitLossSheetController { constructor( private readonly profitLossSheetApp: ProfitLossSheetApplication, @@ -37,7 +44,15 @@ export class ProfitLossSheetController { @ApiResponse({ status: 200, description: 'Profit & loss statement', - example: ProfitLossSheetResponseExample, + content: { + [AcceptType.ApplicationJson]: { + schema: { $ref: getSchemaPath(ProfitLossSheetResponseDto) }, + example: ProfitLossSheetResponseExample, + }, + [AcceptType.ApplicationJsonTable]: { + schema: { $ref: getSchemaPath(ProfitLossSheetTableResponseDto) }, + }, + }, }) @ApiOperation({ summary: 'Get profit/loss statement report' }) @ApiProduces( diff --git a/packages/server/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSheetResponse.dto.ts b/packages/server/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSheetResponse.dto.ts new file mode 100644 index 000000000..80053fb51 --- /dev/null +++ b/packages/server/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSheetResponse.dto.ts @@ -0,0 +1,170 @@ +import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; +import { NumberFormatQueryDto } from '@/modules/BankingTransactions/dtos/NumberFormatQuery.dto'; +import { + FinancialReportTotalDto, + FinancialReportPercentageDto, + FinancialReportMetaDto, + FinancialTableDataDto, +} from '../../dtos/FinancialReportResponse.dto'; + +export class ProfitLossSheetDataNodeDto { + @ApiProperty({ description: 'Node identifier (string for aggregates, number for accounts)' }) + id: string | number; + + @ApiProperty({ description: 'Account or category name' }) + name: string; + + @ApiProperty({ + description: 'Type of node', + enum: ['ACCOUNTS', 'ACCOUNT', 'EQUATION', 'TOTAL'], + }) + node_type: string; + + @ApiPropertyOptional({ description: 'Node type alias' }) + type?: string; + + @ApiProperty({ description: 'Total amount information', type: FinancialReportTotalDto }) + total: FinancialReportTotalDto; + + @ApiPropertyOptional({ description: 'Horizontal totals for date periods', type: [FinancialReportTotalDto] }) + horizontal_totals?: FinancialReportTotalDto[]; + + @ApiPropertyOptional({ description: 'Percentage of income', type: FinancialReportPercentageDto }) + percentage_income?: FinancialReportPercentageDto; + + @ApiPropertyOptional({ description: 'Percentage of expense', type: FinancialReportPercentageDto }) + percentage_expense?: FinancialReportPercentageDto; + + @ApiPropertyOptional({ description: 'Percentage of row', type: FinancialReportPercentageDto }) + percentage_row?: FinancialReportPercentageDto; + + @ApiPropertyOptional({ description: 'Percentage of column', type: FinancialReportPercentageDto }) + percentage_column?: FinancialReportPercentageDto; + + @ApiPropertyOptional({ description: 'Previous period total', type: FinancialReportTotalDto }) + previous_period?: FinancialReportTotalDto; + + @ApiPropertyOptional({ description: 'Previous period change', type: FinancialReportTotalDto }) + previous_period_change?: FinancialReportTotalDto; + + @ApiPropertyOptional({ description: 'Previous period percentage', type: FinancialReportPercentageDto }) + previous_period_percentage?: FinancialReportPercentageDto; + + @ApiPropertyOptional({ description: 'Previous year total', type: FinancialReportTotalDto }) + previous_year?: FinancialReportTotalDto; + + @ApiPropertyOptional({ description: 'Previous year change', type: FinancialReportTotalDto }) + previous_year_change?: FinancialReportTotalDto; + + @ApiPropertyOptional({ description: 'Previous year percentage', type: FinancialReportPercentageDto }) + previous_year_percentage?: FinancialReportPercentageDto; + + @ApiPropertyOptional({ description: 'Account code' }) + code?: string; + + @ApiPropertyOptional({ description: 'Display index', type: Number }) + index?: number; + + @ApiPropertyOptional({ description: 'Child nodes', type: () => [ProfitLossSheetDataNodeDto] }) + children?: ProfitLossSheetDataNodeDto[]; +} + +export class ProfitLossSheetMetaDto extends FinancialReportMetaDto { + @ApiProperty({ description: 'Formatted from date' }) + formatted_from_date: string; + + @ApiProperty({ description: 'Formatted to date' }) + formatted_to_date: string; + + @ApiProperty({ description: 'Formatted date range' }) + formatted_date_range: string; +} + +export class ProfitLossSheetQueryResponseDto { + @ApiProperty({ description: 'Column display type', enum: ['total', 'date_periods'] }) + display_columns_type: string; + + @ApiProperty({ description: 'Column grouping', enum: ['day', 'month', 'year', 'quarter'] }) + display_columns_by: string; + + @ApiProperty({ description: 'Start date' }) + from_date: string; + + @ApiProperty({ description: 'End date' }) + to_date: string; + + @ApiProperty({ description: 'Number format settings', type: NumberFormatQueryDto }) + number_format: NumberFormatQueryDto; + + @ApiProperty({ description: 'Exclude zero balance accounts' }) + none_zero: boolean; + + @ApiProperty({ description: 'Exclude accounts with no transactions' }) + none_transactions: boolean; + + @ApiProperty({ description: 'Accounting basis', enum: ['cash', 'accrual'] }) + basis: string; + + @ApiProperty({ description: 'Account IDs to include', type: [Number] }) + accounts_ids: number[]; + + @ApiProperty({ description: 'Show percentage of column' }) + percentage_column: boolean; + + @ApiProperty({ description: 'Show percentage of row' }) + percentage_row: boolean; + + @ApiProperty({ description: 'Show percentage of income' }) + percentage_income: boolean; + + @ApiProperty({ description: 'Show percentage of expense' }) + percentage_expense: boolean; + + @ApiProperty({ description: 'Include previous period' }) + previous_period: boolean; + + @ApiProperty({ description: 'Show previous period amount change' }) + previous_period_amount_change: boolean; + + @ApiProperty({ description: 'Show previous period percentage change' }) + previous_period_percentage_change: boolean; + + @ApiProperty({ description: 'Include previous year' }) + previous_year: boolean; + + @ApiProperty({ description: 'Show previous year amount change' }) + previous_year_amount_change: boolean; + + @ApiProperty({ description: 'Show previous year percentage change' }) + previous_year_percentage_change: boolean; +} + +export class ProfitLossSheetResponseDto { + @ApiProperty({ description: 'Query parameters used to generate the report', type: ProfitLossSheetQueryResponseDto }) + query: ProfitLossSheetQueryResponseDto; + + @ApiProperty({ description: 'Hierarchical profit/loss data', type: [ProfitLossSheetDataNodeDto] }) + data: ProfitLossSheetDataNodeDto[]; + + @ApiProperty({ description: 'Report metadata', type: ProfitLossSheetMetaDto }) + meta: ProfitLossSheetMetaDto; +} + +// Re-export table DTOs for convenience +export { + FinancialTableCellDto as ProfitLossSheetTableCellDto, + FinancialTableRowDto as ProfitLossSheetTableRowDto, + FinancialTableColumnDto as ProfitLossSheetTableColumnDto, + FinancialTableDataDto as ProfitLossSheetTableDataDto, +} from '../../dtos/FinancialReportResponse.dto'; + +export class ProfitLossSheetTableResponseDto { + @ApiProperty({ description: 'Table data structure', type: () => FinancialTableDataDto }) + table: FinancialTableDataDto; + + @ApiProperty({ description: 'Query parameters used to generate the report', type: ProfitLossSheetQueryResponseDto }) + query: ProfitLossSheetQueryResponseDto; + + @ApiProperty({ description: 'Report metadata', type: ProfitLossSheetMetaDto }) + meta: ProfitLossSheetMetaDto; +} diff --git a/packages/server/src/modules/FinancialStatements/modules/PurchasesByItems/PurchasesByItems.controller.ts b/packages/server/src/modules/FinancialStatements/modules/PurchasesByItems/PurchasesByItems.controller.ts index ae78f3b89..66c223a1e 100644 --- a/packages/server/src/modules/FinancialStatements/modules/PurchasesByItems/PurchasesByItems.controller.ts +++ b/packages/server/src/modules/FinancialStatements/modules/PurchasesByItems/PurchasesByItems.controller.ts @@ -2,20 +2,36 @@ import { Response } from 'express'; import { Controller, Get, Headers, Query, Res } from '@nestjs/common'; import { PurchasesByItemsApplication } from './PurchasesByItemsApplication'; import { AcceptType } from '@/constants/accept-type'; -import { ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger'; +import { ApiExtraModels, ApiOperation, ApiResponse, ApiTags, getSchemaPath } from '@nestjs/swagger'; import { PurchasesByItemsQueryDto } from './PurchasesByItemsQuery.dto'; +import { + PurchasesByItemsResponseDto, + PurchasesByItemsTableResponseDto, +} from './PurchasesByItemsResponse.dto'; import { ApiCommonHeaders } from '@/common/decorators/ApiCommonHeaders'; @Controller('/reports/purchases-by-items') @ApiTags('Reports') @ApiCommonHeaders() +@ApiExtraModels(PurchasesByItemsResponseDto, PurchasesByItemsTableResponseDto) export class PurchasesByItemReportController { constructor( private readonly purchasesByItemsApp: PurchasesByItemsApplication, ) {} @Get() - @ApiResponse({ status: 200, description: 'Purchases by items report' }) + @ApiResponse({ + status: 200, + description: 'Purchases by items report', + content: { + [AcceptType.ApplicationJson]: { + schema: { $ref: getSchemaPath(PurchasesByItemsResponseDto) }, + }, + [AcceptType.ApplicationJsonTable]: { + schema: { $ref: getSchemaPath(PurchasesByItemsTableResponseDto) }, + }, + }, + }) @ApiOperation({ summary: 'Get purchases by items report' }) async purchasesByItems( @Query() filter: PurchasesByItemsQueryDto, diff --git a/packages/server/src/modules/FinancialStatements/modules/PurchasesByItems/PurchasesByItemsResponse.dto.ts b/packages/server/src/modules/FinancialStatements/modules/PurchasesByItems/PurchasesByItemsResponse.dto.ts new file mode 100644 index 000000000..7bc34b93a --- /dev/null +++ b/packages/server/src/modules/FinancialStatements/modules/PurchasesByItems/PurchasesByItemsResponse.dto.ts @@ -0,0 +1,88 @@ +import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; +import { NumberFormatQueryDto } from '@/modules/BankingTransactions/dtos/NumberFormatQuery.dto'; +import { + FinancialReportTotalDto, + FinancialReportMetaDto, + FinancialTableDataDto, +} from '../../dtos/FinancialReportResponse.dto'; + +export class PurchasesByItemDto { + @ApiProperty({ description: 'Item ID', type: Number }) + id: number; + + @ApiProperty({ description: 'Item name' }) + name: string; + + @ApiProperty({ description: 'Item code' }) + code: string; + + @ApiProperty({ description: 'Item type' }) + type: string; + + @ApiProperty({ description: 'Quantity purchased', type: Number }) + quantity: number; + + @ApiProperty({ description: 'Total purchases amount', type: FinancialReportTotalDto }) + total: FinancialReportTotalDto; + + @ApiPropertyOptional({ description: 'Average cost', type: Number }) + averageCost?: number; +} + +export class PurchasesByItemsMetaDto extends FinancialReportMetaDto { + @ApiProperty({ description: 'Formatted from date' }) + formattedFromDate: string; + + @ApiProperty({ description: 'Formatted to date' }) + formattedToDate: string; + + @ApiProperty({ description: 'Formatted date range' }) + formattedDateRange: string; +} + +export class PurchasesByItemsQueryResponseDto { + @ApiProperty({ description: 'Start date' }) + fromDate: string; + + @ApiProperty({ description: 'End date' }) + toDate: string; + + @ApiProperty({ description: 'Number format settings', type: NumberFormatQueryDto }) + numberFormat: NumberFormatQueryDto; + + @ApiProperty({ description: 'Item IDs to include', type: [Number] }) + itemsIds: number[]; + + @ApiProperty({ description: 'Vendor IDs to include', type: [Number] }) + vendorsIds: number[]; +} + +export class PurchasesByItemsResponseDto { + @ApiProperty({ description: 'Query parameters used to generate the report', type: PurchasesByItemsQueryResponseDto }) + query: PurchasesByItemsQueryResponseDto; + + @ApiProperty({ description: 'Purchases by items', type: [PurchasesByItemDto] }) + data: PurchasesByItemDto[]; + + @ApiProperty({ description: 'Report metadata', type: PurchasesByItemsMetaDto }) + meta: PurchasesByItemsMetaDto; +} + +// Re-export table DTOs for convenience +export { + FinancialTableCellDto as PurchasesByItemsTableCellDto, + FinancialTableRowDto as PurchasesByItemsTableRowDto, + FinancialTableColumnDto as PurchasesByItemsTableColumnDto, + FinancialTableDataDto as PurchasesByItemsTableDataDto, +} from '../../dtos/FinancialReportResponse.dto'; + +export class PurchasesByItemsTableResponseDto { + @ApiProperty({ description: 'Table data structure', type: () => FinancialTableDataDto }) + table: FinancialTableDataDto; + + @ApiProperty({ description: 'Query parameters used to generate the report', type: PurchasesByItemsQueryResponseDto }) + query: PurchasesByItemsQueryResponseDto; + + @ApiProperty({ description: 'Report metadata', type: PurchasesByItemsMetaDto }) + meta: PurchasesByItemsMetaDto; +} diff --git a/packages/server/src/modules/FinancialStatements/modules/SalesByItems/SalesByItems.controller.ts b/packages/server/src/modules/FinancialStatements/modules/SalesByItems/SalesByItems.controller.ts index 5361beca6..16904db27 100644 --- a/packages/server/src/modules/FinancialStatements/modules/SalesByItems/SalesByItems.controller.ts +++ b/packages/server/src/modules/FinancialStatements/modules/SalesByItems/SalesByItems.controller.ts @@ -10,18 +10,34 @@ import { import { AcceptType } from '@/constants/accept-type'; import { SalesByItemsApplication } from './SalesByItemsApplication'; import { Response } from 'express'; -import { ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger'; +import { ApiExtraModels, ApiOperation, ApiResponse, ApiTags, getSchemaPath } from '@nestjs/swagger'; import { SalesByItemsQueryDto } from './SalesByItemsQuery.dto'; +import { + SalesByItemsResponseDto, + SalesByItemsTableResponseDto, +} from './SalesByItemsResponse.dto'; import { ApiCommonHeaders } from '@/common/decorators/ApiCommonHeaders'; @Controller('/reports/sales-by-items') @ApiTags('Reports') @ApiCommonHeaders() +@ApiExtraModels(SalesByItemsResponseDto, SalesByItemsTableResponseDto) export class SalesByItemsController { constructor(private readonly salesByItemsApp: SalesByItemsApplication) {} @Get() - @ApiResponse({ status: 200, description: 'Sales by items report' }) + @ApiResponse({ + status: 200, + description: 'Sales by items report', + content: { + [AcceptType.ApplicationJson]: { + schema: { $ref: getSchemaPath(SalesByItemsResponseDto) }, + }, + [AcceptType.ApplicationJsonTable]: { + schema: { $ref: getSchemaPath(SalesByItemsTableResponseDto) }, + }, + }, + }) @ApiOperation({ summary: 'Sales by items report', description: 'Retrieves the sales by items report.', diff --git a/packages/server/src/modules/FinancialStatements/modules/SalesByItems/SalesByItemsResponse.dto.ts b/packages/server/src/modules/FinancialStatements/modules/SalesByItems/SalesByItemsResponse.dto.ts new file mode 100644 index 000000000..2634542de --- /dev/null +++ b/packages/server/src/modules/FinancialStatements/modules/SalesByItems/SalesByItemsResponse.dto.ts @@ -0,0 +1,97 @@ +import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; +import { NumberFormatQueryDto } from '@/modules/BankingTransactions/dtos/NumberFormatQuery.dto'; +import { + FinancialReportTotalDto, + FinancialReportMetaDto, + FinancialTableDataDto, +} from '../../dtos/FinancialReportResponse.dto'; + +export class SalesByItemDto { + @ApiProperty({ description: 'Item ID', type: Number }) + id: number; + + @ApiProperty({ description: 'Item name' }) + name: string; + + @ApiProperty({ description: 'Item code' }) + code: string; + + @ApiProperty({ description: 'Item type' }) + type: string; + + @ApiProperty({ description: 'Quantity sold', type: Number }) + quantity: number; + + @ApiProperty({ description: 'Total sales amount', type: FinancialReportTotalDto }) + total: FinancialReportTotalDto; + + @ApiPropertyOptional({ description: 'Average price', type: Number }) + averagePrice?: number; + + @ApiPropertyOptional({ description: 'COGS', type: FinancialReportTotalDto }) + cogs?: FinancialReportTotalDto; + + @ApiPropertyOptional({ description: 'Profit', type: FinancialReportTotalDto }) + profit?: FinancialReportTotalDto; + + @ApiPropertyOptional({ description: 'Profit percentage', type: Number }) + profitPercentage?: number; +} + +export class SalesByItemsMetaDto extends FinancialReportMetaDto { + @ApiProperty({ description: 'Formatted from date' }) + formattedFromDate: string; + + @ApiProperty({ description: 'Formatted to date' }) + formattedToDate: string; + + @ApiProperty({ description: 'Formatted date range' }) + formattedDateRange: string; +} + +export class SalesByItemsQueryResponseDto { + @ApiProperty({ description: 'Start date' }) + fromDate: string; + + @ApiProperty({ description: 'End date' }) + toDate: string; + + @ApiProperty({ description: 'Number format settings', type: NumberFormatQueryDto }) + numberFormat: NumberFormatQueryDto; + + @ApiProperty({ description: 'Item IDs to include', type: [Number] }) + itemsIds: number[]; + + @ApiProperty({ description: 'Customer IDs to include', type: [Number] }) + customersIds: number[]; +} + +export class SalesByItemsResponseDto { + @ApiProperty({ description: 'Query parameters used to generate the report', type: SalesByItemsQueryResponseDto }) + query: SalesByItemsQueryResponseDto; + + @ApiProperty({ description: 'Sales by items', type: [SalesByItemDto] }) + data: SalesByItemDto[]; + + @ApiProperty({ description: 'Report metadata', type: SalesByItemsMetaDto }) + meta: SalesByItemsMetaDto; +} + +// Re-export table DTOs for convenience +export { + FinancialTableCellDto as SalesByItemsTableCellDto, + FinancialTableRowDto as SalesByItemsTableRowDto, + FinancialTableColumnDto as SalesByItemsTableColumnDto, + FinancialTableDataDto as SalesByItemsTableDataDto, +} from '../../dtos/FinancialReportResponse.dto'; + +export class SalesByItemsTableResponseDto { + @ApiProperty({ description: 'Table data structure', type: () => FinancialTableDataDto }) + table: FinancialTableDataDto; + + @ApiProperty({ description: 'Query parameters used to generate the report', type: SalesByItemsQueryResponseDto }) + query: SalesByItemsQueryResponseDto; + + @ApiProperty({ description: 'Report metadata', type: SalesByItemsMetaDto }) + meta: SalesByItemsMetaDto; +} diff --git a/packages/server/src/modules/FinancialStatements/modules/SalesTaxLiabilitySummary/SalesTaxLiabilitySummary.controller.ts b/packages/server/src/modules/FinancialStatements/modules/SalesTaxLiabilitySummary/SalesTaxLiabilitySummary.controller.ts index c6ea1b7ff..51c9ec2ea 100644 --- a/packages/server/src/modules/FinancialStatements/modules/SalesTaxLiabilitySummary/SalesTaxLiabilitySummary.controller.ts +++ b/packages/server/src/modules/FinancialStatements/modules/SalesTaxLiabilitySummary/SalesTaxLiabilitySummary.controller.ts @@ -1,19 +1,26 @@ import { Response } from 'express'; import { + ApiExtraModels, ApiOperation, ApiProduces, ApiResponse, ApiTags, + getSchemaPath, } from '@nestjs/swagger'; import { Controller, Get, Headers, Query, Res } from '@nestjs/common'; import { AcceptType } from '@/constants/accept-type'; import { SalesTaxLiabilitySummaryApplication } from './SalesTaxLiabilitySummaryApplication'; import { SalesTaxLiabilitySummaryQueryDto } from './dtos/SalesTaxLiabilityQuery.dto'; +import { + SalesTaxLiabilitySummaryResponseDto, + SalesTaxLiabilitySummaryTableResponseDto, +} from './SalesTaxLiabilitySummaryResponse.dto'; import { ApiCommonHeaders } from '@/common/decorators/ApiCommonHeaders'; @Controller('/reports/sales-tax-liability-summary') @ApiTags('Reports') @ApiCommonHeaders() +@ApiExtraModels(SalesTaxLiabilitySummaryResponseDto, SalesTaxLiabilitySummaryTableResponseDto) export class SalesTaxLiabilitySummaryController { constructor( private readonly salesTaxLiabilitySummaryApp: SalesTaxLiabilitySummaryApplication, @@ -23,6 +30,14 @@ export class SalesTaxLiabilitySummaryController { @ApiResponse({ status: 200, description: 'Sales tax liability summary report', + content: { + [AcceptType.ApplicationJson]: { + schema: { $ref: getSchemaPath(SalesTaxLiabilitySummaryResponseDto) }, + }, + [AcceptType.ApplicationJsonTable]: { + schema: { $ref: getSchemaPath(SalesTaxLiabilitySummaryTableResponseDto) }, + }, + }, }) @ApiOperation({ summary: 'Get sales tax liability summary report' }) @ApiProduces( diff --git a/packages/server/src/modules/FinancialStatements/modules/SalesTaxLiabilitySummary/SalesTaxLiabilitySummaryResponse.dto.ts b/packages/server/src/modules/FinancialStatements/modules/SalesTaxLiabilitySummary/SalesTaxLiabilitySummaryResponse.dto.ts new file mode 100644 index 000000000..5de510434 --- /dev/null +++ b/packages/server/src/modules/FinancialStatements/modules/SalesTaxLiabilitySummary/SalesTaxLiabilitySummaryResponse.dto.ts @@ -0,0 +1,79 @@ +import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; +import { NumberFormatQueryDto } from '@/modules/BankingTransactions/dtos/NumberFormatQuery.dto'; +import { + FinancialReportTotalDto, + FinancialReportMetaDto, + FinancialTableDataDto, +} from '../../dtos/FinancialReportResponse.dto'; + +export class TaxRateSummaryDto { + @ApiProperty({ description: 'Tax rate ID', type: Number }) + id: number; + + @ApiProperty({ description: 'Tax rate name' }) + name: string; + + @ApiProperty({ description: 'Tax rate percentage', type: Number }) + rate: number; + + @ApiProperty({ description: 'Taxable amount', type: FinancialReportTotalDto }) + taxableAmount: FinancialReportTotalDto; + + @ApiProperty({ description: 'Tax amount collected', type: FinancialReportTotalDto }) + taxAmount: FinancialReportTotalDto; + + @ApiProperty({ description: 'Total sales (including tax)', type: FinancialReportTotalDto }) + totalSales: FinancialReportTotalDto; +} + +export class SalesTaxLiabilitySummaryMetaDto extends FinancialReportMetaDto { + @ApiProperty({ description: 'Formatted from date' }) + formattedFromDate: string; + + @ApiProperty({ description: 'Formatted to date' }) + formattedToDate: string; + + @ApiProperty({ description: 'Formatted date range' }) + formattedDateRange: string; +} + +export class SalesTaxLiabilitySummaryQueryResponseDto { + @ApiProperty({ description: 'Start date' }) + fromDate: string; + + @ApiProperty({ description: 'End date' }) + toDate: string; + + @ApiProperty({ description: 'Number format settings', type: NumberFormatQueryDto }) + numberFormat: NumberFormatQueryDto; +} + +export class SalesTaxLiabilitySummaryResponseDto { + @ApiProperty({ description: 'Query parameters used to generate the report', type: SalesTaxLiabilitySummaryQueryResponseDto }) + query: SalesTaxLiabilitySummaryQueryResponseDto; + + @ApiProperty({ description: 'Tax rate summaries', type: [TaxRateSummaryDto] }) + data: TaxRateSummaryDto[]; + + @ApiProperty({ description: 'Report metadata', type: SalesTaxLiabilitySummaryMetaDto }) + meta: SalesTaxLiabilitySummaryMetaDto; +} + +// Re-export table DTOs for convenience +export { + FinancialTableCellDto as SalesTaxLiabilitySummaryTableCellDto, + FinancialTableRowDto as SalesTaxLiabilitySummaryTableRowDto, + FinancialTableColumnDto as SalesTaxLiabilitySummaryTableColumnDto, + FinancialTableDataDto as SalesTaxLiabilitySummaryTableDataDto, +} from '../../dtos/FinancialReportResponse.dto'; + +export class SalesTaxLiabilitySummaryTableResponseDto { + @ApiProperty({ description: 'Table data structure', type: () => FinancialTableDataDto }) + table: FinancialTableDataDto; + + @ApiProperty({ description: 'Query parameters used to generate the report', type: SalesTaxLiabilitySummaryQueryResponseDto }) + query: SalesTaxLiabilitySummaryQueryResponseDto; + + @ApiProperty({ description: 'Report metadata', type: SalesTaxLiabilitySummaryMetaDto }) + meta: SalesTaxLiabilitySummaryMetaDto; +} diff --git a/packages/server/src/modules/FinancialStatements/modules/TransactionsByCustomer/TransactionsByCustomer.controller.ts b/packages/server/src/modules/FinancialStatements/modules/TransactionsByCustomer/TransactionsByCustomer.controller.ts index 34fbef486..4ddf615ed 100644 --- a/packages/server/src/modules/FinancialStatements/modules/TransactionsByCustomer/TransactionsByCustomer.controller.ts +++ b/packages/server/src/modules/FinancialStatements/modules/TransactionsByCustomer/TransactionsByCustomer.controller.ts @@ -1,5 +1,9 @@ import { Controller, Get, Headers, Query, Res } from '@nestjs/common'; -import { ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger'; +import { ApiExtraModels, ApiOperation, ApiResponse, ApiTags, getSchemaPath } from '@nestjs/swagger'; +import { + TransactionsByCustomerResponseDto, + TransactionsByCustomerTableResponseDto, +} from './TransactionsByCustomerResponse.dto'; import { ITransactionsByCustomersFilter } from './TransactionsByCustomer.types'; import { TransactionsByCustomerApplication } from './TransactionsByCustomersApplication'; import { AcceptType } from '@/constants/accept-type'; @@ -10,6 +14,7 @@ import { ApiCommonHeaders } from '@/common/decorators/ApiCommonHeaders'; @Controller('/reports/transactions-by-customers') @ApiTags('Reports') @ApiCommonHeaders() +@ApiExtraModels(TransactionsByCustomerResponseDto, TransactionsByCustomerTableResponseDto) export class TransactionsByCustomerController { constructor( private readonly transactionsByCustomersApp: TransactionsByCustomerApplication, @@ -17,7 +22,18 @@ export class TransactionsByCustomerController { @Get() @ApiOperation({ summary: 'Get transactions by customer' }) - @ApiResponse({ status: 200, description: 'Transactions by customer' }) + @ApiResponse({ + status: 200, + description: 'Transactions by customer', + content: { + [AcceptType.ApplicationJson]: { + schema: { $ref: getSchemaPath(TransactionsByCustomerResponseDto) }, + }, + [AcceptType.ApplicationJsonTable]: { + schema: { $ref: getSchemaPath(TransactionsByCustomerTableResponseDto) }, + }, + }, + }) async transactionsByCustomer( @Query() filter: TransactionsByCustomerQueryDto, @Res({ passthrough: true }) res: Response, diff --git a/packages/server/src/modules/FinancialStatements/modules/TransactionsByCustomer/TransactionsByCustomerResponse.dto.ts b/packages/server/src/modules/FinancialStatements/modules/TransactionsByCustomer/TransactionsByCustomerResponse.dto.ts new file mode 100644 index 000000000..c3afbf30a --- /dev/null +++ b/packages/server/src/modules/FinancialStatements/modules/TransactionsByCustomer/TransactionsByCustomerResponse.dto.ts @@ -0,0 +1,117 @@ +import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; +import { NumberFormatQueryDto } from '@/modules/BankingTransactions/dtos/NumberFormatQuery.dto'; +import { + FinancialReportTotalDto, + FinancialReportMetaDto, + FinancialTableDataDto, +} from '../../dtos/FinancialReportResponse.dto'; + +export class CustomerTransactionDto { + @ApiProperty({ description: 'Transaction date' }) + date: string; + + @ApiProperty({ description: 'Formatted date' }) + dateFormatted: string; + + @ApiProperty({ description: 'Transaction type' }) + transactionType: string; + + @ApiProperty({ description: 'Transaction number' }) + transactionNumber: string; + + @ApiPropertyOptional({ description: 'Reference type' }) + referenceType?: string; + + @ApiPropertyOptional({ description: 'Reference ID', type: Number }) + referenceId?: number; + + @ApiPropertyOptional({ description: 'Transaction description' }) + description?: string; + + @ApiProperty({ description: 'Transaction amount', type: FinancialReportTotalDto }) + amount: FinancialReportTotalDto; + + @ApiProperty({ description: 'Running balance', type: FinancialReportTotalDto }) + runningBalance: FinancialReportTotalDto; +} + +export class CustomerWithTransactionsDto { + @ApiProperty({ description: 'Customer ID', type: Number }) + customerId: number; + + @ApiProperty({ description: 'Customer name' }) + customerName: string; + + @ApiPropertyOptional({ description: 'Opening balance', type: FinancialReportTotalDto }) + openingBalance?: FinancialReportTotalDto; + + @ApiProperty({ description: 'Customer transactions', type: [CustomerTransactionDto] }) + transactions: CustomerTransactionDto[]; + + @ApiProperty({ description: 'Closing balance', type: FinancialReportTotalDto }) + closingBalance: FinancialReportTotalDto; + + @ApiPropertyOptional({ description: 'Total debit', type: FinancialReportTotalDto }) + totalDebit?: FinancialReportTotalDto; + + @ApiPropertyOptional({ description: 'Total credit', type: FinancialReportTotalDto }) + totalCredit?: FinancialReportTotalDto; +} + +export class TransactionsByCustomerMetaDto extends FinancialReportMetaDto { + @ApiProperty({ description: 'Formatted from date' }) + formattedFromDate: string; + + @ApiProperty({ description: 'Formatted to date' }) + formattedToDate: string; + + @ApiProperty({ description: 'Formatted date range' }) + formattedDateRange: string; +} + +export class TransactionsByCustomerQueryResponseDto { + @ApiProperty({ description: 'Start date' }) + fromDate: string; + + @ApiProperty({ description: 'End date' }) + toDate: string; + + @ApiProperty({ description: 'Number format settings', type: NumberFormatQueryDto }) + numberFormat: NumberFormatQueryDto; + + @ApiProperty({ description: 'Customer IDs to include', type: [Number] }) + customersIds: number[]; + + @ApiProperty({ description: 'Exclude zero balance customers' }) + noneZero: boolean; +} + +export class TransactionsByCustomerResponseDto { + @ApiProperty({ description: 'Query parameters used to generate the report', type: TransactionsByCustomerQueryResponseDto }) + query: TransactionsByCustomerQueryResponseDto; + + @ApiProperty({ description: 'Customers with transactions', type: [CustomerWithTransactionsDto] }) + data: CustomerWithTransactionsDto[]; + + @ApiProperty({ description: 'Report metadata', type: TransactionsByCustomerMetaDto }) + meta: TransactionsByCustomerMetaDto; +} + +// Re-export table DTOs for convenience +export { + FinancialTableCellDto as TransactionsByCustomerTableCellDto, + FinancialTableRowDto as TransactionsByCustomerTableRowDto, + FinancialTableColumnDto as TransactionsByCustomerTableColumnDto, + FinancialTableDataDto as TransactionsByCustomerTableDataDto, +} from '../../dtos/FinancialReportResponse.dto'; + +export class TransactionsByCustomerTableResponseDto { + @ApiProperty({ description: 'Table data structure', type: () => FinancialTableDataDto }) + table: FinancialTableDataDto; + + @ApiProperty({ description: 'Query parameters used to generate the report', type: TransactionsByCustomerQueryResponseDto }) + query: TransactionsByCustomerQueryResponseDto; + + @ApiProperty({ description: 'Report metadata', type: TransactionsByCustomerMetaDto }) + meta: TransactionsByCustomerMetaDto; +} diff --git a/packages/server/src/modules/FinancialStatements/modules/TransactionsByVendor/TransactionsByVendor.controller.ts b/packages/server/src/modules/FinancialStatements/modules/TransactionsByVendor/TransactionsByVendor.controller.ts index 291855844..7705d82cd 100644 --- a/packages/server/src/modules/FinancialStatements/modules/TransactionsByVendor/TransactionsByVendor.controller.ts +++ b/packages/server/src/modules/FinancialStatements/modules/TransactionsByVendor/TransactionsByVendor.controller.ts @@ -3,13 +3,18 @@ import { ITransactionsByVendorsFilter } from './TransactionsByVendor.types'; import { AcceptType } from '@/constants/accept-type'; import { Response } from 'express'; import { TransactionsByVendorApplication } from './TransactionsByVendorApplication'; -import { ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger'; +import { ApiExtraModels, ApiOperation, ApiResponse, ApiTags, getSchemaPath } from '@nestjs/swagger'; +import { + TransactionsByVendorResponseDto, + TransactionsByVendorTableResponseDto, +} from './TransactionsByVendorResponse.dto'; import { TransactionsByVendorQueryDto } from './TransactionsByVendorQuery.dto'; import { ApiCommonHeaders } from '@/common/decorators/ApiCommonHeaders'; @Controller('/reports/transactions-by-vendors') @ApiTags('Reports') @ApiCommonHeaders() +@ApiExtraModels(TransactionsByVendorResponseDto, TransactionsByVendorTableResponseDto) export class TransactionsByVendorController { constructor( private readonly transactionsByVendorsApp: TransactionsByVendorApplication, @@ -17,7 +22,18 @@ export class TransactionsByVendorController { @Get() @ApiOperation({ summary: 'Get transactions by vendor' }) - @ApiResponse({ status: 200, description: 'Transactions by vendor' }) + @ApiResponse({ + status: 200, + description: 'Transactions by vendor', + content: { + [AcceptType.ApplicationJson]: { + schema: { $ref: getSchemaPath(TransactionsByVendorResponseDto) }, + }, + [AcceptType.ApplicationJsonTable]: { + schema: { $ref: getSchemaPath(TransactionsByVendorTableResponseDto) }, + }, + }, + }) async transactionsByVendor( @Query() filter: TransactionsByVendorQueryDto, @Res({ passthrough: true }) res: Response, diff --git a/packages/server/src/modules/FinancialStatements/modules/TransactionsByVendor/TransactionsByVendorResponse.dto.ts b/packages/server/src/modules/FinancialStatements/modules/TransactionsByVendor/TransactionsByVendorResponse.dto.ts new file mode 100644 index 000000000..a3b2502b1 --- /dev/null +++ b/packages/server/src/modules/FinancialStatements/modules/TransactionsByVendor/TransactionsByVendorResponse.dto.ts @@ -0,0 +1,117 @@ +import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; +import { NumberFormatQueryDto } from '@/modules/BankingTransactions/dtos/NumberFormatQuery.dto'; +import { + FinancialReportTotalDto, + FinancialReportMetaDto, + FinancialTableDataDto, +} from '../../dtos/FinancialReportResponse.dto'; + +export class VendorTransactionDto { + @ApiProperty({ description: 'Transaction date' }) + date: string; + + @ApiProperty({ description: 'Formatted date' }) + dateFormatted: string; + + @ApiProperty({ description: 'Transaction type' }) + transactionType: string; + + @ApiProperty({ description: 'Transaction number' }) + transactionNumber: string; + + @ApiPropertyOptional({ description: 'Reference type' }) + referenceType?: string; + + @ApiPropertyOptional({ description: 'Reference ID', type: Number }) + referenceId?: number; + + @ApiPropertyOptional({ description: 'Transaction description' }) + description?: string; + + @ApiProperty({ description: 'Transaction amount', type: FinancialReportTotalDto }) + amount: FinancialReportTotalDto; + + @ApiProperty({ description: 'Running balance', type: FinancialReportTotalDto }) + runningBalance: FinancialReportTotalDto; +} + +export class VendorWithTransactionsDto { + @ApiProperty({ description: 'Vendor ID', type: Number }) + vendorId: number; + + @ApiProperty({ description: 'Vendor name' }) + vendorName: string; + + @ApiPropertyOptional({ description: 'Opening balance', type: FinancialReportTotalDto }) + openingBalance?: FinancialReportTotalDto; + + @ApiProperty({ description: 'Vendor transactions', type: [VendorTransactionDto] }) + transactions: VendorTransactionDto[]; + + @ApiProperty({ description: 'Closing balance', type: FinancialReportTotalDto }) + closingBalance: FinancialReportTotalDto; + + @ApiPropertyOptional({ description: 'Total debit', type: FinancialReportTotalDto }) + totalDebit?: FinancialReportTotalDto; + + @ApiPropertyOptional({ description: 'Total credit', type: FinancialReportTotalDto }) + totalCredit?: FinancialReportTotalDto; +} + +export class TransactionsByVendorMetaDto extends FinancialReportMetaDto { + @ApiProperty({ description: 'Formatted from date' }) + formattedFromDate: string; + + @ApiProperty({ description: 'Formatted to date' }) + formattedToDate: string; + + @ApiProperty({ description: 'Formatted date range' }) + formattedDateRange: string; +} + +export class TransactionsByVendorQueryResponseDto { + @ApiProperty({ description: 'Start date' }) + fromDate: string; + + @ApiProperty({ description: 'End date' }) + toDate: string; + + @ApiProperty({ description: 'Number format settings', type: NumberFormatQueryDto }) + numberFormat: NumberFormatQueryDto; + + @ApiProperty({ description: 'Vendor IDs to include', type: [Number] }) + vendorsIds: number[]; + + @ApiProperty({ description: 'Exclude zero balance vendors' }) + noneZero: boolean; +} + +export class TransactionsByVendorResponseDto { + @ApiProperty({ description: 'Query parameters used to generate the report', type: TransactionsByVendorQueryResponseDto }) + query: TransactionsByVendorQueryResponseDto; + + @ApiProperty({ description: 'Vendors with transactions', type: [VendorWithTransactionsDto] }) + data: VendorWithTransactionsDto[]; + + @ApiProperty({ description: 'Report metadata', type: TransactionsByVendorMetaDto }) + meta: TransactionsByVendorMetaDto; +} + +// Re-export table DTOs for convenience +export { + FinancialTableCellDto as TransactionsByVendorTableCellDto, + FinancialTableRowDto as TransactionsByVendorTableRowDto, + FinancialTableColumnDto as TransactionsByVendorTableColumnDto, + FinancialTableDataDto as TransactionsByVendorTableDataDto, +} from '../../dtos/FinancialReportResponse.dto'; + +export class TransactionsByVendorTableResponseDto { + @ApiProperty({ description: 'Table data structure', type: () => FinancialTableDataDto }) + table: FinancialTableDataDto; + + @ApiProperty({ description: 'Query parameters used to generate the report', type: TransactionsByVendorQueryResponseDto }) + query: TransactionsByVendorQueryResponseDto; + + @ApiProperty({ description: 'Report metadata', type: TransactionsByVendorMetaDto }) + meta: TransactionsByVendorMetaDto; +} diff --git a/packages/server/src/modules/FinancialStatements/modules/TrialBalanceSheet/TrialBalanceSheet.controller.ts b/packages/server/src/modules/FinancialStatements/modules/TrialBalanceSheet/TrialBalanceSheet.controller.ts index 6090dba68..578e0e69f 100644 --- a/packages/server/src/modules/FinancialStatements/modules/TrialBalanceSheet/TrialBalanceSheet.controller.ts +++ b/packages/server/src/modules/FinancialStatements/modules/TrialBalanceSheet/TrialBalanceSheet.controller.ts @@ -1,9 +1,11 @@ import { Controller, Get, Headers, Query, Res } from '@nestjs/common'; import { + ApiExtraModels, ApiOperation, ApiProduces, ApiResponse, ApiTags, + getSchemaPath, } from '@nestjs/swagger'; import { castArray } from 'lodash'; import { Response } from 'express'; @@ -11,11 +13,16 @@ import { AcceptType } from '@/constants/accept-type'; import { TrialBalanceSheetApplication } from './TrialBalanceSheetApplication'; import { TrialBalanceSheetQueryDto } from './TrialBalanceSheetQuery.dto'; import { TrialBalanceSheetResponseExample } from './TrialBalanceSheet.swagger'; +import { + TrialBalanceSheetResponseDto, + TrialBalanceSheetTableResponseDto, +} from './TrialBalanceSheetResponse.dto'; import { ApiCommonHeaders } from '@/common/decorators/ApiCommonHeaders'; @Controller('reports/trial-balance-sheet') @ApiTags('Reports') @ApiCommonHeaders() +@ApiExtraModels(TrialBalanceSheetResponseDto, TrialBalanceSheetTableResponseDto) export class TrialBalanceSheetController { constructor( private readonly trialBalanceSheetApp: TrialBalanceSheetApplication, @@ -26,7 +33,15 @@ export class TrialBalanceSheetController { @ApiResponse({ status: 200, description: 'Trial balance sheet', - example: TrialBalanceSheetResponseExample, + content: { + [AcceptType.ApplicationJson]: { + schema: { $ref: getSchemaPath(TrialBalanceSheetResponseDto) }, + example: TrialBalanceSheetResponseExample, + }, + [AcceptType.ApplicationJsonTable]: { + schema: { $ref: getSchemaPath(TrialBalanceSheetTableResponseDto) }, + }, + }, }) @ApiProduces( AcceptType.ApplicationJson, diff --git a/packages/server/src/modules/FinancialStatements/modules/TrialBalanceSheet/TrialBalanceSheetResponse.dto.ts b/packages/server/src/modules/FinancialStatements/modules/TrialBalanceSheet/TrialBalanceSheetResponse.dto.ts new file mode 100644 index 000000000..faa33cd15 --- /dev/null +++ b/packages/server/src/modules/FinancialStatements/modules/TrialBalanceSheet/TrialBalanceSheetResponse.dto.ts @@ -0,0 +1,123 @@ +import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; +import { + FinancialReportTotalDto, + FinancialReportMetaDto, + FinancialTableDataDto, +} from '../../dtos/FinancialReportResponse.dto'; + +export class TrialBalanceSheetAccountDto { + @ApiProperty({ description: 'Account ID', type: Number }) + id: number; + + @ApiProperty({ description: 'Account name' }) + name: string; + + @ApiProperty({ description: 'Account code' }) + code: string; + + @ApiPropertyOptional({ description: 'Opening balance', type: FinancialReportTotalDto }) + openingBalance?: FinancialReportTotalDto; + + @ApiPropertyOptional({ description: 'Closing balance', type: FinancialReportTotalDto }) + closingBalance?: FinancialReportTotalDto; + + @ApiPropertyOptional({ description: 'Debit total', type: FinancialReportTotalDto }) + debitTotal?: FinancialReportTotalDto; + + @ApiPropertyOptional({ description: 'Credit total', type: FinancialReportTotalDto }) + creditTotal?: FinancialReportTotalDto; + + @ApiPropertyOptional({ description: 'Debit/change', type: FinancialReportTotalDto }) + debit?: FinancialReportTotalDto; + + @ApiPropertyOptional({ description: 'Credit/change', type: FinancialReportTotalDto }) + credit?: FinancialReportTotalDto; + + @ApiPropertyOptional({ description: 'Period balance', type: FinancialReportTotalDto }) + periodBalance?: FinancialReportTotalDto; + + @ApiPropertyOptional({ description: 'Account normal', enum: ['debit', 'credit'] }) + accountNormal?: string; + + @ApiPropertyOptional({ description: 'Account index', type: Number }) + index?: number; +} + +export class TrialBalanceSheetMetaDto extends FinancialReportMetaDto { + @ApiProperty({ description: 'Formatted from date' }) + formattedFromDate: string; + + @ApiProperty({ description: 'Formatted to date' }) + formattedToDate: string; + + @ApiProperty({ description: 'Formatted date range' }) + formattedDateRange: string; + + @ApiPropertyOptional({ description: 'Opening balance at', type: Date }) + openingBalanceAt?: Date; + + @ApiPropertyOptional({ description: 'Closing balance at', type: Date }) + closingBalanceAt?: Date; + + @ApiPropertyOptional({ description: 'Formatted opening balance date' }) + formattedOpeningBalanceDate?: string; + + @ApiPropertyOptional({ description: 'Formatted closing balance date' }) + formattedClosingBalanceDate?: string; +} + +export class TrialBalanceSheetQueryResponseDto { + @ApiProperty({ description: 'Start date' }) + fromDate: string; + + @ApiProperty({ description: 'End date' }) + toDate: string; + + @ApiProperty({ description: 'Account IDs to include', type: [Number] }) + accountIds: number[]; + + @ApiProperty({ description: 'Exclude zero balance accounts' }) + noneZero: boolean; + + @ApiProperty({ description: 'Exclude accounts with no transactions' }) + noneTransactions: boolean; + + @ApiProperty({ description: 'Accounting basis', enum: ['cash', 'accrual'] }) + basis: string; + + @ApiProperty({ description: 'Column display type', enum: ['total', 'date_periods'] }) + displayColumnsType: string; + + @ApiProperty({ description: 'Column grouping', enum: ['day', 'month', 'year', 'quarter'] }) + displayColumnsBy: string; +} + +export class TrialBalanceSheetResponseDto { + @ApiProperty({ description: 'Query parameters used to generate the report', type: TrialBalanceSheetQueryResponseDto }) + query: TrialBalanceSheetQueryResponseDto; + + @ApiProperty({ description: 'Trial balance sheet data', type: [TrialBalanceSheetAccountDto] }) + data: TrialBalanceSheetAccountDto[]; + + @ApiProperty({ description: 'Report metadata', type: TrialBalanceSheetMetaDto }) + meta: TrialBalanceSheetMetaDto; +} + +// Re-export table DTOs for convenience +export { + FinancialTableCellDto as TrialBalanceSheetTableCellDto, + FinancialTableRowDto as TrialBalanceSheetTableRowDto, + FinancialTableColumnDto as TrialBalanceSheetTableColumnDto, + FinancialTableDataDto as TrialBalanceSheetTableDataDto, +} from '../../dtos/FinancialReportResponse.dto'; + +export class TrialBalanceSheetTableResponseDto { + @ApiProperty({ description: 'Table data structure', type: () => FinancialTableDataDto }) + table: FinancialTableDataDto; + + @ApiProperty({ description: 'Query parameters used to generate the report', type: TrialBalanceSheetQueryResponseDto }) + query: TrialBalanceSheetQueryResponseDto; + + @ApiProperty({ description: 'Report metadata', type: TrialBalanceSheetMetaDto }) + meta: TrialBalanceSheetMetaDto; +} diff --git a/packages/server/src/modules/FinancialStatements/modules/VendorBalanceSummary/VendorBalanceSummary.controller.ts b/packages/server/src/modules/FinancialStatements/modules/VendorBalanceSummary/VendorBalanceSummary.controller.ts index bfb2fa748..cb21f4f19 100644 --- a/packages/server/src/modules/FinancialStatements/modules/VendorBalanceSummary/VendorBalanceSummary.controller.ts +++ b/packages/server/src/modules/FinancialStatements/modules/VendorBalanceSummary/VendorBalanceSummary.controller.ts @@ -4,17 +4,24 @@ import { VendorBalanceSummaryApplication } from './VendorBalanceSummaryApplicati import { Response } from 'express'; import { AcceptType } from '@/constants/accept-type'; import { + ApiExtraModels, ApiOperation, ApiProduces, ApiResponse, ApiTags, + getSchemaPath, } from '@nestjs/swagger'; import { VendorBalanceSummaryQueryDto } from './VendorBalanceSummaryQuery.dto'; +import { + VendorBalanceSummaryResponseDto, + VendorBalanceSummaryTableResponseDto, +} from './VendorBalanceSummaryResponse.dto'; import { ApiCommonHeaders } from '@/common/decorators/ApiCommonHeaders'; @Controller('/reports/vendor-balance-summary') @ApiTags('Reports') @ApiCommonHeaders() +@ApiExtraModels(VendorBalanceSummaryResponseDto, VendorBalanceSummaryTableResponseDto) export class VendorBalanceSummaryController { constructor( private readonly vendorBalanceSummaryApp: VendorBalanceSummaryApplication, @@ -22,7 +29,18 @@ export class VendorBalanceSummaryController { @Get() @ApiOperation({ summary: 'Get vendor balance summary' }) - @ApiResponse({ status: 200, description: 'Vendor balance summary' }) + @ApiResponse({ + status: 200, + description: 'Vendor balance summary', + content: { + [AcceptType.ApplicationJson]: { + schema: { $ref: getSchemaPath(VendorBalanceSummaryResponseDto) }, + }, + [AcceptType.ApplicationJsonTable]: { + schema: { $ref: getSchemaPath(VendorBalanceSummaryTableResponseDto) }, + }, + }, + }) @ApiProduces( AcceptType.ApplicationJson, AcceptType.ApplicationJsonTable, diff --git a/packages/server/src/modules/FinancialStatements/modules/VendorBalanceSummary/VendorBalanceSummaryResponse.dto.ts b/packages/server/src/modules/FinancialStatements/modules/VendorBalanceSummary/VendorBalanceSummaryResponse.dto.ts new file mode 100644 index 000000000..4a3957e19 --- /dev/null +++ b/packages/server/src/modules/FinancialStatements/modules/VendorBalanceSummary/VendorBalanceSummaryResponse.dto.ts @@ -0,0 +1,82 @@ +import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; +import { NumberFormatQueryDto } from '@/modules/BankingTransactions/dtos/NumberFormatQuery.dto'; +import { + FinancialReportTotalDto, + FinancialReportMetaDto, + FinancialTableDataDto, +} from '../../dtos/FinancialReportResponse.dto'; + +export class VendorBalanceDto { + @ApiProperty({ description: 'Vendor ID', type: Number }) + vendorId: number; + + @ApiProperty({ description: 'Vendor name' }) + vendorName: string; + + @ApiPropertyOptional({ description: 'Opening balance', type: FinancialReportTotalDto }) + openingBalance?: FinancialReportTotalDto; + + @ApiProperty({ description: 'Closing balance', type: FinancialReportTotalDto }) + closingBalance: FinancialReportTotalDto; + + @ApiPropertyOptional({ description: 'Total debit', type: FinancialReportTotalDto }) + totalDebit?: FinancialReportTotalDto; + + @ApiPropertyOptional({ description: 'Total credit', type: FinancialReportTotalDto }) + totalCredit?: FinancialReportTotalDto; +} + +export class VendorBalanceSummaryMetaDto extends FinancialReportMetaDto { + @ApiProperty({ description: 'Formatted as-of date' }) + formattedAsDate: string; + + @ApiProperty({ description: 'Formatted date range' }) + formattedDateRange: string; +} + +export class VendorBalanceSummaryQueryResponseDto { + @ApiProperty({ description: 'As-of date' }) + asDate: string; + + @ApiProperty({ description: 'Number format settings', type: NumberFormatQueryDto }) + numberFormat: NumberFormatQueryDto; + + @ApiProperty({ description: 'Vendor IDs to include', type: [Number] }) + vendorsIds: number[]; + + @ApiProperty({ description: 'Exclude zero balance vendors' }) + noneZero: boolean; + + @ApiProperty({ description: 'Exclude inactive vendors' }) + noneInactive: boolean; +} + +export class VendorBalanceSummaryResponseDto { + @ApiProperty({ description: 'Query parameters used to generate the report', type: VendorBalanceSummaryQueryResponseDto }) + query: VendorBalanceSummaryQueryResponseDto; + + @ApiProperty({ description: 'Vendor balances', type: [VendorBalanceDto] }) + data: VendorBalanceDto[]; + + @ApiProperty({ description: 'Report metadata', type: VendorBalanceSummaryMetaDto }) + meta: VendorBalanceSummaryMetaDto; +} + +// Re-export table DTOs for convenience +export { + FinancialTableCellDto as VendorBalanceSummaryTableCellDto, + FinancialTableRowDto as VendorBalanceSummaryTableRowDto, + FinancialTableColumnDto as VendorBalanceSummaryTableColumnDto, + FinancialTableDataDto as VendorBalanceSummaryTableDataDto, +} from '../../dtos/FinancialReportResponse.dto'; + +export class VendorBalanceSummaryTableResponseDto { + @ApiProperty({ description: 'Table data structure', type: () => FinancialTableDataDto }) + table: FinancialTableDataDto; + + @ApiProperty({ description: 'Query parameters used to generate the report', type: VendorBalanceSummaryQueryResponseDto }) + query: VendorBalanceSummaryQueryResponseDto; + + @ApiProperty({ description: 'Report metadata', type: VendorBalanceSummaryMetaDto }) + meta: VendorBalanceSummaryMetaDto; +}