feat: swagger doc

This commit is contained in:
Ahmed Bouhuolia
2025-06-21 20:55:32 +02:00
parent 91976842a7
commit e5701140e1
19 changed files with 1028 additions and 19 deletions

View File

@@ -2,7 +2,7 @@ import { Response } from 'express';
import { Controller, Get, Headers, Query, Res } from '@nestjs/common'; import { Controller, Get, Headers, Query, Res } from '@nestjs/common';
import { APAgingSummaryApplication } from './APAgingSummaryApplication'; import { APAgingSummaryApplication } from './APAgingSummaryApplication';
import { AcceptType } from '@/constants/accept-type'; import { AcceptType } from '@/constants/accept-type';
import { ApiOperation, ApiTags } from '@nestjs/swagger'; import { ApiOperation, ApiProduces, ApiTags } from '@nestjs/swagger';
import { APAgingSummaryQueryDto } from './APAgingSummaryQuery.dto'; import { APAgingSummaryQueryDto } from './APAgingSummaryQuery.dto';
@Controller('reports/payable-aging-summary') @Controller('reports/payable-aging-summary')
@@ -12,6 +12,13 @@ export class APAgingSummaryController {
@Get() @Get()
@ApiOperation({ summary: 'Get payable aging summary' }) @ApiOperation({ summary: 'Get payable aging summary' })
@ApiProduces(
AcceptType.ApplicationJson,
AcceptType.ApplicationJsonTable,
AcceptType.ApplicationPdf,
AcceptType.ApplicationXlsx,
AcceptType.ApplicationCsv,
)
public async get( public async get(
@Query() filter: APAgingSummaryQueryDto, @Query() filter: APAgingSummaryQueryDto,
@Res({ passthrough: true }) res: Response, @Res({ passthrough: true }) res: Response,

View File

@@ -3,7 +3,7 @@ import { Query, Res } from '@nestjs/common';
import { ARAgingSummaryApplication } from './ARAgingSummaryApplication'; import { ARAgingSummaryApplication } from './ARAgingSummaryApplication';
import { AcceptType } from '@/constants/accept-type'; import { AcceptType } from '@/constants/accept-type';
import { Response } from 'express'; import { Response } from 'express';
import { ApiOperation, ApiTags } from '@nestjs/swagger'; import { ApiOperation, ApiProduces, ApiTags } from '@nestjs/swagger';
import { ARAgingSummaryQueryDto } from './ARAgingSummaryQuery.dto'; import { ARAgingSummaryQueryDto } from './ARAgingSummaryQuery.dto';
@Controller('reports/receivable-aging-summary') @Controller('reports/receivable-aging-summary')
@@ -13,6 +13,13 @@ export class ARAgingSummaryController {
@Get() @Get()
@ApiOperation({ summary: 'Get receivable aging summary' }) @ApiOperation({ summary: 'Get receivable aging summary' })
@ApiProduces(
AcceptType.ApplicationJson,
AcceptType.ApplicationJsonTable,
AcceptType.ApplicationPdf,
AcceptType.ApplicationXlsx,
AcceptType.ApplicationCsv,
)
public async get( public async get(
@Query() filter: ARAgingSummaryQueryDto, @Query() filter: ARAgingSummaryQueryDto,
@Res({ passthrough: true }) res: Response, @Res({ passthrough: true }) res: Response,

View File

@@ -2,7 +2,12 @@ import { Response } from 'express';
import { Controller, Get, Headers, Query, Res } from '@nestjs/common'; import { Controller, Get, Headers, Query, Res } from '@nestjs/common';
import { AcceptType } from '@/constants/accept-type'; import { AcceptType } from '@/constants/accept-type';
import { BalanceSheetApplication } from './BalanceSheetApplication'; import { BalanceSheetApplication } from './BalanceSheetApplication';
import { ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger'; import {
ApiOperation,
ApiProduces,
ApiResponse,
ApiTags,
} from '@nestjs/swagger';
import { BalanceSheetQueryDto } from './BalanceSheet.dto'; import { BalanceSheetQueryDto } from './BalanceSheet.dto';
import { BalanceSheetResponseExample } from './BalanceSheet.swagger'; import { BalanceSheetResponseExample } from './BalanceSheet.swagger';
@@ -24,6 +29,13 @@ export class BalanceSheetStatementController {
description: 'Balance sheet statement', description: 'Balance sheet statement',
example: BalanceSheetResponseExample, example: BalanceSheetResponseExample,
}) })
@ApiProduces(
AcceptType.ApplicationJson,
AcceptType.ApplicationJsonTable,
AcceptType.ApplicationPdf,
AcceptType.ApplicationXlsx,
AcceptType.ApplicationCsv,
)
public async balanceSheet( public async balanceSheet(
@Query() query: BalanceSheetQueryDto, @Query() query: BalanceSheetQueryDto,
@Res({ passthrough: true }) res: Response, @Res({ passthrough: true }) res: Response,

View File

@@ -499,3 +499,737 @@ export const BalanceSheetResponseExample = {
formatted_date_range: 'As 2025/06/16', formatted_date_range: 'As 2025/06/16',
}, },
}; };
export const BalanceSheetTableResponseExample = {
table: {
columns: [
{
key: 'name',
label: 'Account name',
cell_index: 0,
},
{
key: 'total',
label: 'Total',
children: [],
cell_index: 1,
},
],
rows: [
{
cells: [
{
key: 'name',
value: 'Assets',
},
{
key: 'total',
value: '-$122,623.00',
},
],
row_types: ['AGGREGATE'],
id: 'ASSETS',
children: [
{
cells: [
{
key: 'name',
value: 'Current Asset',
},
{
key: 'total',
value: '-$122,623.00',
},
],
row_types: ['AGGREGATE'],
id: 'CURRENT_ASSETS',
children: [
{
cells: [
{
key: 'name',
value: 'Cash and cash equivalents',
},
{
key: 'total',
value: '-$500.00',
},
],
row_types: ['AGGREGATE'],
id: 'CASH_EQUIVALENTS',
children: [
{
cells: [
{
key: 'name',
value: 'Undeposited Funds',
},
{
key: 'total',
value: '',
},
],
row_types: ['ACCOUNT'],
id: 1002,
},
{
cells: [
{
key: 'name',
value: 'Petty Cash',
},
{
key: 'total',
value: '',
},
],
row_types: ['ACCOUNT'],
id: 1003,
},
{
cells: [
{
key: 'name',
value: 'Bank Account',
},
{
key: 'total',
value: '-500.00',
},
],
row_types: ['ACCOUNT'],
id: 1000,
},
{
cells: [
{
key: 'name',
value: 'Saving Bank Account',
},
{
key: 'total',
value: '',
},
],
row_types: ['ACCOUNT'],
id: 1001,
},
{
cells: [
{
key: 'name',
value: 'Chase - Plaid Checking',
},
{
key: 'total',
value: '',
},
],
row_types: ['ACCOUNT'],
id: 1034,
},
{
cells: [
{
key: 'name',
value: 'Total Cash and cash equivalents',
},
{
key: 'total',
value: '-$500.00',
},
],
row_types: ['TOTAL'],
id: 'CASH_EQUIVALENTS',
},
],
},
{
cells: [
{
key: 'name',
value: 'Accounts Receivable',
},
{
key: 'total',
value: '$0.00',
},
],
row_types: ['AGGREGATE'],
id: 'ACCOUNTS_RECEIVABLE',
children: [
{
cells: [
{
key: 'name',
value: 'Accounts Receivable (A/R)',
},
{
key: 'total',
value: '',
},
],
row_types: ['ACCOUNT'],
id: 1006,
},
{
cells: [
{
key: 'name',
value: 'Total Accounts Receivable',
},
{
key: 'total',
value: '$0.00',
},
],
row_types: ['TOTAL'],
id: 'ACCOUNTS_RECEIVABLE',
},
],
},
{
cells: [
{
key: 'name',
value: 'Inventory',
},
{
key: 'total',
value: '$1,000.00',
},
],
row_types: ['AGGREGATE'],
id: 'INVENTORY',
children: [
{
cells: [
{
key: 'name',
value: 'Inventory Asset',
},
{
key: 'total',
value: '1,000.00',
},
],
row_types: ['ACCOUNT'],
id: 1007,
},
{
cells: [
{
key: 'name',
value: 'Total Inventory',
},
{
key: 'total',
value: '$1,000.00',
},
],
row_types: ['TOTAL'],
id: 'INVENTORY',
},
],
},
{
cells: [
{
key: 'name',
value: 'Other current assets',
},
{
key: 'total',
value: '-$123,123.00',
},
],
row_types: ['AGGREGATE'],
id: 'OTHER_CURRENT_ASSET',
children: [
{
cells: [
{
key: 'name',
value: 'Prepaid Expenses',
},
{
key: 'total',
value: '-123,123.00',
},
],
row_types: ['ACCOUNT'],
id: 1030,
},
{
cells: [
{
key: 'name',
value: 'Total Other current assets',
},
{
key: 'total',
value: '-$123,123.00',
},
],
row_types: ['TOTAL'],
id: 'OTHER_CURRENT_ASSET',
},
],
},
{
cells: [
{
key: 'name',
value: 'Total Current Asset',
},
{
key: 'total',
value: '-$122,623.00',
},
],
row_types: ['TOTAL'],
id: 'CURRENT_ASSETS',
},
],
},
{
cells: [
{
key: 'name',
value: 'Fixed Asset',
},
{
key: 'total',
value: '$0.00',
},
],
row_types: ['AGGREGATE'],
id: 'FIXED_ASSET',
children: [
{
cells: [
{
key: 'name',
value: 'Computer Equipment',
},
{
key: 'total',
value: '',
},
],
row_types: ['ACCOUNT'],
id: 1004,
},
{
cells: [
{
key: 'name',
value: 'Office Equipment',
},
{
key: 'total',
value: '',
},
],
row_types: ['ACCOUNT'],
id: 1005,
},
{
cells: [
{
key: 'name',
value: 'Total Fixed Asset',
},
{
key: 'total',
value: '$0.00',
},
],
row_types: ['TOTAL'],
id: 'FIXED_ASSET',
},
],
},
{
cells: [
{
key: 'name',
value: 'Non-Current Assets',
},
{
key: 'total',
value: '$0.00',
},
],
row_types: ['AGGREGATE'],
id: 'NON_CURRENT_ASSET',
},
{
cells: [
{
key: 'name',
value: 'Total Assets',
},
{
key: 'total',
value: '-$122,623.00',
},
],
row_types: ['TOTAL'],
id: 'ASSETS',
},
],
},
{
cells: [
{
key: 'name',
value: 'Liabilities and Equity',
},
{
key: 'total',
value: '-$122,623.00',
},
],
row_types: ['AGGREGATE'],
id: 'LIABILITY_EQUITY',
children: [
{
cells: [
{
key: 'name',
value: 'Liabilities',
},
{
key: 'total',
value: '-$8,700.00',
},
],
row_types: ['AGGREGATE'],
id: 'LIABILITY',
children: [
{
cells: [
{
key: 'name',
value: 'Current Liabilties',
},
{
key: 'total',
value: '-$8,700.00',
},
],
row_types: ['AGGREGATE'],
id: 'CURRENT_LIABILITY',
children: [
{
cells: [
{
key: 'name',
value: 'Accounts Payable (A/P)',
},
{
key: 'total',
value: '1,300.00',
},
],
row_types: ['ACCOUNT'],
id: 1008,
},
{
cells: [
{
key: 'name',
value: 'Tax Payable',
},
{
key: 'total',
value: '',
},
],
row_types: ['ACCOUNT'],
id: 1013,
},
{
cells: [
{
key: 'name',
value: 'Owner A Drawings',
},
{
key: 'total',
value: '',
},
],
row_types: ['ACCOUNT'],
id: 1009,
},
{
cells: [
{
key: 'name',
value: 'Loan',
},
{
key: 'total',
value: '-10,000.00',
},
],
row_types: ['ACCOUNT'],
id: 1010,
},
{
cells: [
{
key: 'name',
value: 'Opening Balance Liabilities',
},
{
key: 'total',
value: '',
},
],
row_types: ['ACCOUNT'],
id: 1011,
},
{
cells: [
{
key: 'name',
value: 'Revenue Received in Advance',
},
{
key: 'total',
value: '',
},
],
row_types: ['ACCOUNT'],
id: 1012,
},
{
cells: [
{
key: 'name',
value: 'Unearned Revenue',
},
{
key: 'total',
value: '',
},
],
row_types: ['ACCOUNT'],
id: 1029,
},
{
cells: [
{
key: 'name',
value: 'Total Current Liabilties',
},
{
key: 'total',
value: '-$8,700.00',
},
],
row_types: ['TOTAL'],
id: 'CURRENT_LIABILITY',
},
],
},
{
cells: [
{
key: 'name',
value: 'Long-Term Liabilities',
},
{
key: 'total',
value: '$0.00',
},
],
row_types: ['AGGREGATE'],
id: 'LOGN_TERM_LIABILITY',
},
{
cells: [
{
key: 'name',
value: 'Non-Current Liabilities',
},
{
key: 'total',
value: '$0.00',
},
],
row_types: ['AGGREGATE'],
id: 'NON_CURRENT_LIABILITY',
},
{
cells: [
{
key: 'name',
value: 'Total Liabilities',
},
{
key: 'total',
value: '-$8,700.00',
},
],
row_types: ['TOTAL'],
id: 'LIABILITY',
},
],
},
{
cells: [
{
key: 'name',
value: 'Equity',
},
{
key: 'total',
value: '-$113,923.00',
},
],
row_types: ['AGGREGATE'],
id: 'EQUITY',
children: [
{
cells: [
{
key: 'name',
value: 'Retained Earnings',
},
{
key: 'total',
value: '',
},
],
row_types: ['ACCOUNT'],
id: 1014,
},
{
cells: [
{
key: 'name',
value: 'Opening Balance Equity',
},
{
key: 'total',
value: '',
},
],
row_types: ['ACCOUNT'],
id: 1015,
},
{
cells: [
{
key: 'name',
value: "Owner's Equity",
},
{
key: 'total',
value: '',
},
],
row_types: ['ACCOUNT'],
id: 1016,
},
{
cells: [
{
key: 'name',
value: 'Drawings',
},
{
key: 'total',
value: '',
},
],
row_types: ['ACCOUNT'],
id: 1017,
},
{
cells: [
{
key: 'name',
value: 'Net Income',
},
{
key: 'total',
value: '-$113,923.00',
},
],
row_types: ['NET_INCOME'],
id: 'NET_INCOME',
},
{
cells: [
{
key: 'name',
value: 'Total Equity',
},
{
key: 'total',
value: '-$113,923.00',
},
],
row_types: ['TOTAL'],
id: 'EQUITY',
},
],
},
{
cells: [
{
key: 'name',
value: 'Total Liabilities and Equity',
},
{
key: 'total',
value: '-$122,623.00',
},
],
row_types: ['TOTAL'],
id: 'LIABILITY_EQUITY',
},
],
},
],
},
query: {
display_columns_type: 'total',
display_columns_by: 'year',
from_date: '2025-01-01',
to_date: '2025-06-21',
number_format: {
precision: 2,
divide_on1000: false,
show_zero: false,
format_money: 'total',
negative_format: 'mines',
},
none_zero: false,
none_transactions: false,
basis: 'cash',
account_ids: [],
percentage_of_column: false,
percentage_of_row: false,
previous_period: false,
previous_period_amount_change: false,
previous_period_percentage_change: false,
previous_year: false,
previous_year_amount_change: false,
previous_year_percentage_change: false,
},
meta: {
organization_name: 'BIGCAPITAL, INC',
base_currency: 'USD',
date_format: 'DD MMM yyyy',
is_cost_compute_running: false,
sheet_name: 'Balance Sheet Statement',
formatted_as_date: '2025/06/21',
formatted_date_range: 'As 2025/06/21',
},
};

View File

@@ -2,7 +2,12 @@ import { Response } from 'express';
import { Controller, Get, Headers, Query, Res } from '@nestjs/common'; import { Controller, Get, Headers, Query, Res } from '@nestjs/common';
import { AcceptType } from '@/constants/accept-type'; import { AcceptType } from '@/constants/accept-type';
import { CashflowSheetApplication } from './CashflowSheetApplication'; import { CashflowSheetApplication } from './CashflowSheetApplication';
import { ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger'; import {
ApiOperation,
ApiProduces,
ApiResponse,
ApiTags,
} from '@nestjs/swagger';
import { CashFlowStatementQueryDto } from './CashFlowStatementQuery.dto'; import { CashFlowStatementQueryDto } from './CashFlowStatementQuery.dto';
import { CashflowStatementResponseExample } from './CashflowStatement.swagger'; import { CashflowStatementResponseExample } from './CashflowStatement.swagger';
@@ -18,6 +23,13 @@ export class CashflowController {
example: CashflowStatementResponseExample, example: CashflowStatementResponseExample,
}) })
@ApiOperation({ summary: 'Get cashflow statement report' }) @ApiOperation({ summary: 'Get cashflow statement report' })
@ApiProduces(
AcceptType.ApplicationJson,
AcceptType.ApplicationJsonTable,
AcceptType.ApplicationPdf,
AcceptType.ApplicationXlsx,
AcceptType.ApplicationCsv,
)
async getCashflow( async getCashflow(
@Query() query: CashFlowStatementQueryDto, @Query() query: CashFlowStatementQueryDto,
@Res({ passthrough: true }) res: Response, @Res({ passthrough: true }) res: Response,

View File

@@ -1,5 +1,10 @@
import { Response } from 'express'; import { Response } from 'express';
import { ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger'; import {
ApiOperation,
ApiProduces,
ApiResponse,
ApiTags,
} from '@nestjs/swagger';
import { Controller, Get, Headers, Query, Res } from '@nestjs/common'; import { Controller, Get, Headers, Query, Res } from '@nestjs/common';
import { CustomerBalanceSummaryApplication } from './CustomerBalanceSummaryApplication'; import { CustomerBalanceSummaryApplication } from './CustomerBalanceSummaryApplication';
import { CustomerBalanceSummaryQueryDto } from './CustomerBalanceSummaryQuery.dto'; import { CustomerBalanceSummaryQueryDto } from './CustomerBalanceSummaryQuery.dto';
@@ -15,6 +20,13 @@ export class CustomerBalanceSummaryController {
@Get() @Get()
@ApiResponse({ status: 200, description: 'Customer balance summary report' }) @ApiResponse({ status: 200, description: 'Customer balance summary report' })
@ApiOperation({ summary: 'Get customer balance summary report' }) @ApiOperation({ summary: 'Get customer balance summary report' })
@ApiProduces(
AcceptType.ApplicationJson,
AcceptType.ApplicationJsonTable,
AcceptType.ApplicationPdf,
AcceptType.ApplicationXlsx,
AcceptType.ApplicationCsv,
)
async customerBalanceSummary( async customerBalanceSummary(
@Query() filter: CustomerBalanceSummaryQueryDto, @Query() filter: CustomerBalanceSummaryQueryDto,
@Res({ passthrough: true }) res: Response, @Res({ passthrough: true }) res: Response,

View File

@@ -1,4 +1,9 @@
import { ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger'; import {
ApiOperation,
ApiProduces,
ApiResponse,
ApiTags,
} from '@nestjs/swagger';
import { Response } from 'express'; import { Response } from 'express';
import { Controller, Get, Headers, Query, Res } from '@nestjs/common'; import { Controller, Get, Headers, Query, Res } from '@nestjs/common';
import { GeneralLedgerApplication } from './GeneralLedgerApplication'; import { GeneralLedgerApplication } from './GeneralLedgerApplication';
@@ -20,6 +25,13 @@ export class GeneralLedgerController {
example: GeneralLedgerResponseExample, example: GeneralLedgerResponseExample,
}) })
@ApiOperation({ summary: 'Get general ledger report' }) @ApiOperation({ summary: 'Get general ledger report' })
@ApiProduces(
AcceptType.ApplicationJson,
AcceptType.ApplicationJsonTable,
AcceptType.ApplicationPdf,
AcceptType.ApplicationXlsx,
AcceptType.ApplicationCsv,
)
public async getGeneralLedger( public async getGeneralLedger(
@Query() query: GeneralLedgerQueryDto, @Query() query: GeneralLedgerQueryDto,
@Res({ passthrough: true }) res: Response, @Res({ passthrough: true }) res: Response,

View File

@@ -19,7 +19,6 @@ export class InventoryItemDetailsApplication {
/** /**
* Retrieves the inventory details report in sheet format. * Retrieves the inventory details report in sheet format.
* @param {number} tenantId
* @param {IInventoryDetailsQuery} query * @param {IInventoryDetailsQuery} query
* @returns {Promise<IInvetoryItemDetailDOO>} * @returns {Promise<IInvetoryItemDetailDOO>}
*/ */

View File

@@ -1,5 +1,10 @@
import { Response } from 'express'; import { Response } from 'express';
import { ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger'; import {
ApiOperation,
ApiProduces,
ApiResponse,
ApiTags,
} from '@nestjs/swagger';
import { Controller, Get, Headers, Query, Res } from '@nestjs/common'; import { Controller, Get, Headers, Query, Res } from '@nestjs/common';
import { InventoryValuationSheetApplication } from './InventoryValuationSheetApplication'; import { InventoryValuationSheetApplication } from './InventoryValuationSheetApplication';
import { InventoryValuationQueryDto } from './InventoryValuationQuery.dto'; import { InventoryValuationQueryDto } from './InventoryValuationQuery.dto';
@@ -18,6 +23,13 @@ export class InventoryValuationController {
status: 200, status: 200,
description: 'The inventory valuation sheet', description: 'The inventory valuation sheet',
}) })
@ApiProduces(
AcceptType.ApplicationJson,
AcceptType.ApplicationJsonTable,
AcceptType.ApplicationPdf,
AcceptType.ApplicationXlsx,
AcceptType.ApplicationCsv,
)
public async getInventoryValuationSheet( public async getInventoryValuationSheet(
@Query() query: InventoryValuationQueryDto, @Query() query: InventoryValuationQueryDto,
@Res({ passthrough: true }) res: Response, @Res({ passthrough: true }) res: Response,

View File

@@ -9,40 +9,81 @@ import { INumberFormatQuery } from '../../types/Report.types';
import { Transform, Type } from 'class-transformer'; import { Transform, Type } from 'class-transformer';
import { parseBoolean } from '@/utils/parse-boolean'; import { parseBoolean } from '@/utils/parse-boolean';
import { NumberFormatQueryDto } from '@/modules/BankingTransactions/dtos/NumberFormatQuery.dto'; import { NumberFormatQueryDto } from '@/modules/BankingTransactions/dtos/NumberFormatQuery.dto';
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
export class InventoryValuationQueryDto { export class InventoryValuationQueryDto {
@ApiPropertyOptional({
description: 'The date for which the inventory valuation is requested',
example: '2024-01-01T00:00:00.000Z',
type: String,
})
@IsDateString() @IsDateString()
@IsOptional() @IsOptional()
asDate: Date | string; asDate: Date | string;
@ApiPropertyOptional({
description: 'Number format options',
type: NumberFormatQueryDto,
example: { currency: 'USD', decimals: 2 },
})
@ValidateNested() @ValidateNested()
@Type(() => NumberFormatQueryDto) @Type(() => NumberFormatQueryDto)
@IsOptional() @IsOptional()
numberFormat: INumberFormatQuery; numberFormat: INumberFormatQuery;
@ApiPropertyOptional({
description: 'Whether to exclude transactions',
example: false,
type: Boolean,
})
@IsBoolean() @IsBoolean()
@Transform(({ value }) => parseBoolean(value, false)) @Transform(({ value }) => parseBoolean(value, false))
@IsOptional() @IsOptional()
noneTransactions: boolean; noneTransactions: boolean;
@ApiPropertyOptional({
description: 'Whether to exclude zero values',
example: false,
type: Boolean,
})
@IsBoolean() @IsBoolean()
@Transform(({ value }) => parseBoolean(value, false)) @Transform(({ value }) => parseBoolean(value, false))
@IsOptional() @IsOptional()
noneZero: boolean; noneZero: boolean;
@ApiPropertyOptional({
description: 'Whether to include only active items',
example: true,
type: Boolean,
})
@IsBoolean() @IsBoolean()
@Transform(({ value }) => parseBoolean(value, false)) @Transform(({ value }) => parseBoolean(value, false))
@IsOptional() @IsOptional()
onlyActive: boolean; onlyActive: boolean;
@ApiPropertyOptional({
description: 'Array of item IDs to filter',
example: [1, 2, 3],
type: [Number],
})
@IsArray() @IsArray()
@IsOptional() @IsOptional()
itemsIds: number[]; itemsIds: number[];
@ApiPropertyOptional({
description: 'Array of warehouse IDs to filter',
example: [10, 20],
type: [Number],
})
@IsArray() @IsArray()
@IsOptional() @IsOptional()
warehousesIds?: number[]; warehousesIds?: number[];
@ApiPropertyOptional({
description: 'Array of branch IDs to filter',
example: [100, 200],
type: [Number],
})
@IsArray() @IsArray()
@IsOptional() @IsOptional()
branchesIds?: number[]; branchesIds?: number[];

View File

@@ -1,9 +1,13 @@
import { Controller, Get, Headers, Query, Res } from '@nestjs/common'; import { Controller, Get, Headers, Query, Res } from '@nestjs/common';
import { IJournalReportQuery } from './JournalSheet.types';
import { Response } from 'express'; import { Response } from 'express';
import { AcceptType } from '@/constants/accept-type'; import { AcceptType } from '@/constants/accept-type';
import { JournalSheetApplication } from './JournalSheetApplication'; import { JournalSheetApplication } from './JournalSheetApplication';
import { ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger'; import {
ApiOperation,
ApiProduces,
ApiResponse,
ApiTags,
} from '@nestjs/swagger';
import { JournalSheetQueryDto } from './JournalSheetQuery.dto'; import { JournalSheetQueryDto } from './JournalSheetQuery.dto';
@Controller('/reports/journal') @Controller('/reports/journal')
@@ -14,6 +18,13 @@ export class JournalSheetController {
@Get('/') @Get('/')
@ApiResponse({ status: 200, description: 'Journal report' }) @ApiResponse({ status: 200, description: 'Journal report' })
@ApiOperation({ summary: 'Journal report' }) @ApiOperation({ summary: 'Journal report' })
@ApiProduces(
AcceptType.ApplicationJson,
AcceptType.ApplicationJsonTable,
AcceptType.ApplicationPdf,
AcceptType.ApplicationXlsx,
AcceptType.ApplicationCsv,
)
async journalSheet( async journalSheet(
@Query() query: JournalSheetQueryDto, @Query() query: JournalSheetQueryDto,
@Res({ passthrough: true }) res: Response, @Res({ passthrough: true }) res: Response,

View File

@@ -9,46 +9,87 @@ import {
} from 'class-validator'; } from 'class-validator';
import { Type } from 'class-transformer'; import { Type } from 'class-transformer';
import { FinancialSheetBranchesQueryDto } from '../../dtos/FinancialSheetBranchesQuery.dto'; import { FinancialSheetBranchesQueryDto } from '../../dtos/FinancialSheetBranchesQuery.dto';
import { ApiPropertyOptional } from '@nestjs/swagger';
class JournalSheetNumberFormatQueryDto { class JournalSheetNumberFormatQueryDto {
@ApiPropertyOptional({
description: 'Whether to hide cents in the number format',
example: false,
})
@IsBoolean() @IsBoolean()
@IsOptional() @IsOptional()
noCents: boolean; noCents: boolean;
@ApiPropertyOptional({
description: 'Whether to divide numbers by 1000',
example: false,
})
@IsBoolean() @IsBoolean()
@IsOptional() @IsOptional()
divideOn1000: boolean; divideOn1000: boolean;
} }
export class JournalSheetQueryDto extends FinancialSheetBranchesQueryDto { export class JournalSheetQueryDto extends FinancialSheetBranchesQueryDto {
@ApiPropertyOptional({
description: 'Start date for the journal sheet',
example: '2024-01-01T00:00:00.000Z',
})
@IsDateString() @IsDateString()
@IsOptional() @IsOptional()
fromDate: Date | string; fromDate: Date | string;
@ApiPropertyOptional({
description: 'End date for the journal sheet',
example: '2024-01-31T23:59:59.000Z',
})
@IsDateString() @IsDateString()
@IsOptional() @IsOptional()
toDate: Date | string; toDate: Date | string;
@ApiPropertyOptional({
description: 'Number format options for the journal sheet',
example: { noCents: false, divideOn1000: false },
})
@ValidateNested() @ValidateNested()
@Type(() => JournalSheetNumberFormatQueryDto) @Type(() => JournalSheetNumberFormatQueryDto)
numberFormat: JournalSheetNumberFormatQueryDto; numberFormat: JournalSheetNumberFormatQueryDto;
@ApiPropertyOptional({
description: 'Type of transaction to filter',
example: 'payment',
})
@IsString() @IsString()
@IsOptional() @IsOptional()
transactionType: string; transactionType: string;
@ApiPropertyOptional({
description: 'ID of the transaction to filter',
example: 'TXN-12345',
})
@IsString() @IsString()
@IsOptional() @IsOptional()
transactionId: string; transactionId: string;
@ApiPropertyOptional({
description: 'Array of account IDs to filter',
example: [1, 2, 3],
})
@IsArray() @IsArray()
@IsOptional() @IsOptional()
accountsIds: number | number[]; accountsIds: number | number[];
@ApiPropertyOptional({
description: 'Start range for filtering',
example: 100,
})
@IsNumber() @IsNumber()
@IsOptional() @IsOptional()
fromRange: number; fromRange: number;
@ApiPropertyOptional({
description: 'End range for filtering',
example: 200,
})
@IsNumber() @IsNumber()
@IsOptional() @IsOptional()
toRange: number; toRange: number;

View File

@@ -2,7 +2,12 @@ import { Response } from 'express';
import { Controller, Get, Headers, Query, Res } from '@nestjs/common'; import { Controller, Get, Headers, Query, Res } from '@nestjs/common';
import { ProfitLossSheetApplication } from './ProfitLossSheetApplication'; import { ProfitLossSheetApplication } from './ProfitLossSheetApplication';
import { AcceptType } from '@/constants/accept-type'; import { AcceptType } from '@/constants/accept-type';
import { ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger'; import {
ApiOperation,
ApiProduces,
ApiResponse,
ApiTags,
} from '@nestjs/swagger';
import { ProfitLossSheetQueryDto } from './ProfitLossSheetQuery.dto'; import { ProfitLossSheetQueryDto } from './ProfitLossSheetQuery.dto';
@Controller('/reports/profit-loss-sheet') @Controller('/reports/profit-loss-sheet')
@@ -21,6 +26,13 @@ export class ProfitLossSheetController {
@Get('/') @Get('/')
@ApiResponse({ status: 200, description: 'Profit & loss statement' }) @ApiResponse({ status: 200, description: 'Profit & loss statement' })
@ApiOperation({ summary: 'Get profit/loss statement report' }) @ApiOperation({ summary: 'Get profit/loss statement report' })
@ApiProduces(
AcceptType.ApplicationJson,
AcceptType.ApplicationJsonTable,
AcceptType.ApplicationPdf,
AcceptType.ApplicationXlsx,
AcceptType.ApplicationCsv,
)
async profitLossSheet( async profitLossSheet(
@Query() query: ProfitLossSheetQueryDto, @Query() query: ProfitLossSheetQueryDto,
@Res({ passthrough: true }) res: Response, @Res({ passthrough: true }) res: Response,

View File

@@ -1,9 +1,14 @@
import { Response } from 'express'; import { Response } from 'express';
import { ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger'; import {
ApiOperation,
ApiProduces,
ApiResponse,
ApiTags,
} from '@nestjs/swagger';
import { Controller, Get, Headers, Query, Res } from '@nestjs/common'; import { Controller, Get, Headers, Query, Res } from '@nestjs/common';
import { SalesTaxLiabilitySummaryQuery } from './SalesTaxLiability.types';
import { AcceptType } from '@/constants/accept-type'; import { AcceptType } from '@/constants/accept-type';
import { SalesTaxLiabilitySummaryApplication } from './SalesTaxLiabilitySummaryApplication'; import { SalesTaxLiabilitySummaryApplication } from './SalesTaxLiabilitySummaryApplication';
import { SalesTaxLiabilitySummaryQueryDto } from './dtos/SalesTaxLiabilityQuery.dto';
@Controller('/reports/sales-tax-liability-summary') @Controller('/reports/sales-tax-liability-summary')
@ApiTags('Reports') @ApiTags('Reports')
@@ -18,8 +23,15 @@ export class SalesTaxLiabilitySummaryController {
description: 'Sales tax liability summary report', description: 'Sales tax liability summary report',
}) })
@ApiOperation({ summary: 'Get sales tax liability summary report' }) @ApiOperation({ summary: 'Get sales tax liability summary report' })
@ApiProduces(
AcceptType.ApplicationJson,
AcceptType.ApplicationJsonTable,
AcceptType.ApplicationPdf,
AcceptType.ApplicationXlsx,
AcceptType.ApplicationCsv,
)
public async getSalesTaxLiabilitySummary( public async getSalesTaxLiabilitySummary(
@Query() query: SalesTaxLiabilitySummaryQuery, @Query() query: SalesTaxLiabilitySummaryQueryDto,
@Res({ passthrough: true }) res: Response, @Res({ passthrough: true }) res: Response,
@Headers('accept') acceptHeader: string, @Headers('accept') acceptHeader: string,
) { ) {

View File

@@ -0,0 +1,29 @@
import { ApiProperty } from '@nestjs/swagger';
import { IsDateString, IsEnum, IsNotEmpty, IsOptional } from 'class-validator';
export class SalesTaxLiabilitySummaryQueryDto {
@ApiProperty({
description: 'Start date for the sales tax liability summary',
example: '2024-01-01',
})
@IsDateString()
@IsOptional()
fromDate: Date;
@ApiProperty({
description: 'End date for the sales tax liability summary',
example: '2024-01-31',
})
@IsDateString()
@IsOptional()
toDate: Date;
@ApiProperty({
description: 'Accounting basis for the summary',
enum: ['cash', 'accrual'],
example: 'accrual',
})
@IsEnum(['cash', 'accrual'])
@IsNotEmpty()
basis: 'cash' | 'accrual';
}

View File

@@ -13,26 +13,53 @@ import { ApiPropertyOptional } from '@nestjs/swagger';
export class TransactionsByContactQueryDto { export class TransactionsByContactQueryDto {
@IsDateString() @IsDateString()
@IsOptional() @IsOptional()
@ApiPropertyOptional({
description: 'Start date for the transactions by contact query',
example: '2024-01-01',
})
fromDate: Date | string; fromDate: Date | string;
@IsDateString() @IsDateString()
@IsOptional() @IsOptional()
@ApiPropertyOptional({
description: 'End date for the transactions by contact query',
example: '2024-12-31',
})
toDate: Date | string; toDate: Date | string;
@ValidateNested() @ValidateNested()
@Type(() => NumberFormatQueryDto) @Type(() => NumberFormatQueryDto)
@IsOptional() @IsOptional()
@ApiPropertyOptional({
description: 'Number format configuration for the report',
type: NumberFormatQueryDto,
example: {
precision: 2,
divideOn1000: false,
showZero: true,
formatMoney: 'total',
negativeFormat: 'parentheses',
},
})
numberFormat: INumberFormatQuery; numberFormat: INumberFormatQuery;
@Transform(({ value }) => parseBoolean(value, false)) @Transform(({ value }) => parseBoolean(value, false))
@IsBoolean() @IsBoolean()
@IsOptional() @IsOptional()
@ApiPropertyOptional({ description: 'Whether to exclude transactions' }) @ApiPropertyOptional({
description: 'Whether to exclude transactions',
example: false,
default: false,
})
noneTransactions: boolean; noneTransactions: boolean;
@Transform(({ value }) => parseBoolean(value, false)) @Transform(({ value }) => parseBoolean(value, false))
@IsBoolean() @IsBoolean()
@IsOptional() @IsOptional()
@ApiPropertyOptional({ description: 'Whether to exclude zero values' }) @ApiPropertyOptional({
description: 'Whether to exclude zero values',
example: false,
default: false,
})
noneZero: boolean; noneZero: boolean;
} }

View File

@@ -1,8 +1,13 @@
import { IsArray, IsOptional } from 'class-validator'; import { IsArray, IsOptional } from 'class-validator';
import { TransactionsByContactQueryDto } from '../TransactionsByContact/TransactionsByContactQuery.dto'; import { TransactionsByContactQueryDto } from '../TransactionsByContact/TransactionsByContactQuery.dto';
import { ApiPropertyOptional } from '@nestjs/swagger';
export class TransactionsByVendorQueryDto extends TransactionsByContactQueryDto { export class TransactionsByVendorQueryDto extends TransactionsByContactQueryDto {
@IsArray() @IsArray()
@IsOptional() @IsOptional()
@ApiPropertyOptional({
description: 'Array of vendor IDs to include',
example: [1, 2, 3],
})
vendorsIds: number[]; vendorsIds: number[];
} }

View File

@@ -1,5 +1,10 @@
import { Controller, Get, Headers, Query, Res } from '@nestjs/common'; import { Controller, Get, Headers, Query, Res } from '@nestjs/common';
import { ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger'; import {
ApiOperation,
ApiProduces,
ApiResponse,
ApiTags,
} from '@nestjs/swagger';
import { castArray } from 'lodash'; import { castArray } from 'lodash';
import { Response } from 'express'; import { Response } from 'express';
import { AcceptType } from '@/constants/accept-type'; import { AcceptType } from '@/constants/accept-type';
@@ -21,6 +26,13 @@ export class TrialBalanceSheetController {
description: 'Trial balance sheet', description: 'Trial balance sheet',
example: TrialBalanceSheetResponseExample, example: TrialBalanceSheetResponseExample,
}) })
@ApiProduces(
AcceptType.ApplicationJson,
AcceptType.ApplicationJsonTable,
AcceptType.ApplicationPdf,
AcceptType.ApplicationXlsx,
AcceptType.ApplicationCsv,
)
async getTrialBalanceSheet( async getTrialBalanceSheet(
@Query() query: TrialBalanceSheetQueryDto, @Query() query: TrialBalanceSheetQueryDto,
@Res({ passthrough: true }) res: Response, @Res({ passthrough: true }) res: Response,

View File

@@ -3,7 +3,12 @@ import { IVendorBalanceSummaryQuery } from './VendorBalanceSummary.types';
import { VendorBalanceSummaryApplication } from './VendorBalanceSummaryApplication'; import { VendorBalanceSummaryApplication } from './VendorBalanceSummaryApplication';
import { Response } from 'express'; import { Response } from 'express';
import { AcceptType } from '@/constants/accept-type'; import { AcceptType } from '@/constants/accept-type';
import { ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger'; import {
ApiOperation,
ApiProduces,
ApiResponse,
ApiTags,
} from '@nestjs/swagger';
import { VendorBalanceSummaryQueryDto } from './VendorBalanceSummaryQuery.dto'; import { VendorBalanceSummaryQueryDto } from './VendorBalanceSummaryQuery.dto';
@Controller('/reports/vendor-balance-summary') @Controller('/reports/vendor-balance-summary')
@@ -16,6 +21,13 @@ export class VendorBalanceSummaryController {
@Get() @Get()
@ApiOperation({ summary: 'Get vendor balance summary' }) @ApiOperation({ summary: 'Get vendor balance summary' })
@ApiResponse({ status: 200, description: 'Vendor balance summary' }) @ApiResponse({ status: 200, description: 'Vendor balance summary' })
@ApiProduces(
AcceptType.ApplicationJson,
AcceptType.ApplicationJsonTable,
AcceptType.ApplicationPdf,
AcceptType.ApplicationXlsx,
AcceptType.ApplicationCsv,
)
async vendorBalanceSummary( async vendorBalanceSummary(
@Query() filter: VendorBalanceSummaryQueryDto, @Query() filter: VendorBalanceSummaryQueryDto,
@Res({ passthrough: true }) res: Response, @Res({ passthrough: true }) res: Response,