diff --git a/packages/server/src/modules/FinancialStatements/modules/ContactBalanceSummary/ContactBalanceSummaryQuery.dto.ts b/packages/server/src/modules/FinancialStatements/modules/ContactBalanceSummary/ContactBalanceSummaryQuery.dto.ts index 6d9068beb..df4305c51 100644 --- a/packages/server/src/modules/FinancialStatements/modules/ContactBalanceSummary/ContactBalanceSummaryQuery.dto.ts +++ b/packages/server/src/modules/FinancialStatements/modules/ContactBalanceSummary/ContactBalanceSummaryQuery.dto.ts @@ -8,27 +8,55 @@ import { INumberFormatQuery } from '../../types/Report.types'; import { Transform, Type } from 'class-transformer'; import { NumberFormatQueryDto } from '@/modules/BankingTransactions/dtos/NumberFormatQuery.dto'; import { parseBoolean } from '@/utils/parse-boolean'; +import { ApiPropertyOptional } from '@nestjs/swagger'; export class ContactBalanceSummaryQueryDto { + @ApiPropertyOptional({ + description: 'The date as of which the balance summary is calculated', + example: '2024-01-01', + type: String, + }) @IsDateString() @IsOptional() asDate: Date; + @ApiPropertyOptional({ + description: 'Number formatting options for the summary', + type: NumberFormatQueryDto, + }) @ValidateNested() @Type(() => NumberFormatQueryDto) @IsOptional() numberFormat: INumberFormatQuery; + @ApiPropertyOptional({ + description: 'Whether to show the percentage column in the summary', + example: false, + type: Boolean, + default: false, + }) @IsBoolean() @Transform(({ value }) => parseBoolean(value, false)) @IsOptional() percentageColumn: boolean; + @ApiPropertyOptional({ + description: 'Whether to exclude contacts with no transactions', + example: false, + type: Boolean, + default: false, + }) @IsBoolean() @Transform(({ value }) => parseBoolean(value, false)) @IsOptional() noneTransactions: boolean; + @ApiPropertyOptional({ + description: 'Whether to exclude contacts with zero balance', + example: false, + type: Boolean, + default: false, + }) @IsBoolean() @Transform(({ value }) => parseBoolean(value, false)) @IsOptional() diff --git a/packages/server/src/modules/FinancialStatements/modules/CustomerBalanceSummary/CustomerBalanceSummaryQuery.dto.ts b/packages/server/src/modules/FinancialStatements/modules/CustomerBalanceSummary/CustomerBalanceSummaryQuery.dto.ts index 141f13774..e8358cedd 100644 --- a/packages/server/src/modules/FinancialStatements/modules/CustomerBalanceSummary/CustomerBalanceSummaryQuery.dto.ts +++ b/packages/server/src/modules/FinancialStatements/modules/CustomerBalanceSummary/CustomerBalanceSummaryQuery.dto.ts @@ -1,7 +1,13 @@ import { IsArray, IsOptional } from 'class-validator'; import { ContactBalanceSummaryQueryDto } from '../ContactBalanceSummary/ContactBalanceSummaryQuery.dto'; +import { ApiPropertyOptional } from '@nestjs/swagger'; export class CustomerBalanceSummaryQueryDto extends ContactBalanceSummaryQueryDto { + @ApiPropertyOptional({ + description: 'Array of customer IDs to filter the summary', + type: [Number], + example: [1, 2, 3], + }) @IsArray() @IsOptional() customersIds: number[]; 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 f6af8da89..3e823c649 100644 --- a/packages/server/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSheet.controller.ts +++ b/packages/server/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSheet.controller.ts @@ -9,6 +9,7 @@ import { ApiTags, } from '@nestjs/swagger'; import { ProfitLossSheetQueryDto } from './ProfitLossSheetQuery.dto'; +import { ProfitLossSheetResponseExample } from './ProfitLossSheet.swagger'; @Controller('/reports/profit-loss-sheet') @ApiTags('Reports') @@ -24,7 +25,11 @@ export class ProfitLossSheetController { * @param {string} acceptHeader */ @Get('/') - @ApiResponse({ status: 200, description: 'Profit & loss statement' }) + @ApiResponse({ + status: 200, + description: 'Profit & loss statement', + example: ProfitLossSheetResponseExample, + }) @ApiOperation({ summary: 'Get profit/loss statement report' }) @ApiProduces( AcceptType.ApplicationJson, diff --git a/packages/server/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSheet.swagger.ts b/packages/server/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSheet.swagger.ts new file mode 100644 index 000000000..4cedf6680 --- /dev/null +++ b/packages/server/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSheet.swagger.ts @@ -0,0 +1,240 @@ +export const ProfitLossSheetResponseExample = { + query: { + from_date: '2025-01-01', + to_date: '2025-06-22', + number_format: { + divide_on1000: false, + negative_format: 'mines', + show_zero: false, + format_money: 'total', + precision: 2, + }, + basis: 'accrual', + none_zero: false, + none_transactions: false, + display_columns_type: 'total', + display_columns_by: 'year', + accounts_ids: [], + percentage_column: false, + percentage_row: false, + percentage_income: false, + percentage_expense: 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, + }, + data: [ + { + id: 'INCOME', + name: 'Income', + node_type: 'ACCOUNTS', + total: { + amount: 3931, + formatted_amount: '$3,931.00', + }, + children: [ + { + id: 1025, + name: 'Sales of Product Income', + node_type: 'ACCOUNT', + total: { + amount: 3931, + formatted_amount: '3,931.00', + }, + }, + { + id: 1026, + name: 'Sales of Service Income', + node_type: 'ACCOUNT', + total: { + amount: 0, + formatted_amount: '', + }, + }, + { + id: 1027, + name: 'Uncategorized Income', + node_type: 'ACCOUNT', + total: { + amount: 0, + formatted_amount: '', + }, + }, + ], + }, + { + id: 'COST_OF_SALES', + name: 'Cost of sales', + node_type: 'ACCOUNTS', + total: { + amount: 800, + formatted_amount: '$800.00', + }, + children: [ + { + id: 1019, + name: 'Cost of Goods Sold', + node_type: 'ACCOUNT', + total: { + amount: 800, + formatted_amount: '800.00', + }, + }, + ], + }, + { + id: 'GROSS_PROFIT', + name: 'GROSS PROFIT', + node_type: 'EQUATION', + total: { + amount: 3131, + formatted_amount: '$3,131.00', + }, + }, + { + id: 'EXPENSES', + name: 'Expenses', + node_type: 'ACCOUNTS', + total: { + amount: -111563, + formatted_amount: '-$111,563.00', + }, + children: [ + { + id: 1020, + name: 'Office expenses', + node_type: 'ACCOUNT', + total: { + amount: 0, + formatted_amount: '', + }, + }, + { + id: 1021, + name: 'Rent', + node_type: 'ACCOUNT', + total: { + amount: -92831, + formatted_amount: '-92,831.00', + }, + }, + { + id: 1023, + name: 'Bank Fees and Charges', + node_type: 'ACCOUNT', + total: { + amount: -8732, + formatted_amount: '-8,732.00', + }, + }, + { + id: 1024, + name: 'Depreciation Expense', + node_type: 'ACCOUNT', + total: { + amount: -10000, + formatted_amount: '-10,000.00', + }, + }, + ], + }, + { + id: 'NET_OPERATING_INCOME', + name: 'NET OPERATING INCOME', + node_type: 'EQUATION', + total: { + amount: 114694, + formatted_amount: '$114,694.00', + }, + }, + { + id: 'OTHER_INCOME', + name: 'Other income', + node_type: 'ACCOUNTS', + total: { + amount: 0, + formatted_amount: '$0.00', + }, + children: [ + { + id: 1031, + name: 'Discount', + node_type: 'ACCOUNT', + total: { + amount: 0, + formatted_amount: '', + }, + }, + { + id: 1033, + name: 'Other Charges', + node_type: 'ACCOUNT', + total: { + amount: 0, + formatted_amount: '', + }, + }, + ], + }, + { + id: 'OTHER_EXPENSES', + name: 'Other expenses', + node_type: 'ACCOUNTS', + total: { + amount: 119149, + formatted_amount: '$119,149.00', + }, + children: [ + { + id: 1018, + name: 'Other Expenses', + node_type: 'ACCOUNT', + total: { + amount: -1243, + formatted_amount: '-1,243.00', + }, + }, + { + id: 1022, + name: 'Exchange Gain or Loss', + node_type: 'ACCOUNT', + total: { + amount: 123123, + formatted_amount: '123,123.00', + }, + }, + { + id: 1032, + name: 'Purchase Discount', + node_type: 'ACCOUNT', + total: { + amount: -2731, + formatted_amount: '-2,731.00', + }, + }, + ], + }, + { + id: 'NET_INCOME', + name: 'NET INCOME', + node_type: 'EQUATION', + total: { + amount: -4455, + formatted_amount: '-$4,455.00', + }, + }, + ], + meta: { + organization_name: 'BIGCAPITAL, INC', + base_currency: 'USD', + date_format: 'DD MMM yyyy', + is_cost_compute_running: false, + sheet_name: 'Cashflow Statement', + formatted_from_date: '2025/01/01', + formatted_to_date: '2025/06/22', + formatted_date_range: 'From 2025/01/01 | To 2025/06/22', + }, +}; diff --git a/packages/server/src/modules/FinancialStatements/modules/PurchasesByItems/PurchasesByItemsQuery.dto.ts b/packages/server/src/modules/FinancialStatements/modules/PurchasesByItems/PurchasesByItemsQuery.dto.ts index e722e41e6..5b6021fe4 100644 --- a/packages/server/src/modules/FinancialStatements/modules/PurchasesByItems/PurchasesByItemsQuery.dto.ts +++ b/packages/server/src/modules/FinancialStatements/modules/PurchasesByItems/PurchasesByItemsQuery.dto.ts @@ -9,29 +9,61 @@ import { INumberFormatQuery } from '../../types/Report.types'; import { NumberFormatQueryDto } from '@/modules/BankingTransactions/dtos/NumberFormatQuery.dto'; import { Transform, Type } from 'class-transformer'; import { parseBoolean } from '@/utils/parse-boolean'; +import { ApiPropertyOptional } from '@nestjs/swagger'; export class PurchasesByItemsQueryDto { + @ApiPropertyOptional({ + description: 'Start date for the purchases by items report', + example: '2024-01-01', + type: String, + }) @IsDateString() @IsOptional() fromDate: Date | string; + @ApiPropertyOptional({ + description: 'End date for the purchases by items report', + example: '2024-01-31', + type: String, + }) @IsDateString() @IsOptional() toDate: Date | string; + @ApiPropertyOptional({ + description: 'Array of item IDs to filter the purchases report', + type: [Number], + example: [1, 2, 3], + }) @IsArray() @IsOptional() itemsIds: number[]; + @ApiPropertyOptional({ + description: 'Number formatting options for the report', + type: NumberFormatQueryDto, + }) @ValidateNested() @Type(() => NumberFormatQueryDto) @IsOptional() numberFormat: INumberFormatQuery; + @ApiPropertyOptional({ + description: 'Whether to exclude items with no transactions', + example: false, + type: Boolean, + default: false, + }) @IsBoolean() @Transform(({ value }) => parseBoolean(value, false)) noneTransactions: boolean; + @ApiPropertyOptional({ + description: 'Whether to include only active items', + example: false, + type: Boolean, + default: false, + }) @IsBoolean() @Transform(({ value }) => parseBoolean(value, false)) onlyActive: boolean; diff --git a/packages/server/src/modules/FinancialStatements/modules/SalesByItems/SalesByItemsQuery.dto.ts b/packages/server/src/modules/FinancialStatements/modules/SalesByItems/SalesByItemsQuery.dto.ts index de6f86409..6dce21f1b 100644 --- a/packages/server/src/modules/FinancialStatements/modules/SalesByItems/SalesByItemsQuery.dto.ts +++ b/packages/server/src/modules/FinancialStatements/modules/SalesByItems/SalesByItemsQuery.dto.ts @@ -9,31 +9,63 @@ import { INumberFormatQuery } from '../../types/Report.types'; import { Transform, Type } from 'class-transformer'; import { NumberFormatQueryDto } from '@/modules/BankingTransactions/dtos/NumberFormatQuery.dto'; import { parseBoolean } from '@/utils/parse-boolean'; +import { ApiPropertyOptional } from '@nestjs/swagger'; export class SalesByItemsQueryDto { + @ApiPropertyOptional({ + description: 'Start date for the sales by items report', + example: '2024-01-01', + type: String, + }) @IsDateString() @IsOptional() fromDate: Date | string; + @ApiPropertyOptional({ + description: 'End date for the sales by items report', + example: '2024-01-31', + type: String, + }) @IsDateString() @IsOptional() toDate: Date | string; + @ApiPropertyOptional({ + description: 'Number formatting options for the report', + type: NumberFormatQueryDto, + }) @ValidateNested() @Type(() => NumberFormatQueryDto) @IsOptional() numberFormat: INumberFormatQuery; + @ApiPropertyOptional({ + description: 'Whether to exclude items with no transactions', + example: false, + type: Boolean, + default: false, + }) @IsBoolean() @Transform(({ value }) => parseBoolean(value, false)) @IsOptional() noneTransactions: boolean; + @ApiPropertyOptional({ + description: 'Whether to include only active items', + example: false, + type: Boolean, + default: false, + }) @IsBoolean() @Transform(({ value }) => parseBoolean(value, false)) @IsOptional() onlyActive: boolean; + @ApiPropertyOptional({ + description: 'Array of item IDs to filter the sales report', + type: [Number], + example: [1, 2, 3], + }) @IsArray() @IsOptional() itemsIds: number[]; diff --git a/packages/server/src/modules/FinancialStatements/modules/VendorBalanceSummary/VendorBalanceSummaryQuery.dto.ts b/packages/server/src/modules/FinancialStatements/modules/VendorBalanceSummary/VendorBalanceSummaryQuery.dto.ts index b6bc4fb22..177dc6e09 100644 --- a/packages/server/src/modules/FinancialStatements/modules/VendorBalanceSummary/VendorBalanceSummaryQuery.dto.ts +++ b/packages/server/src/modules/FinancialStatements/modules/VendorBalanceSummary/VendorBalanceSummaryQuery.dto.ts @@ -1,8 +1,14 @@ import { IsArray, IsOptional } from 'class-validator'; import { ContactBalanceSummaryQueryDto } from '../ContactBalanceSummary/ContactBalanceSummaryQuery.dto'; +import { ApiPropertyOptional } from '@nestjs/swagger'; export class VendorBalanceSummaryQueryDto extends ContactBalanceSummaryQueryDto { @IsArray() @IsOptional() + @ApiPropertyOptional({ + description: 'Array of vendor IDs to filter the summary', + type: [Number], + example: [1, 2, 3], + }) vendorsIds: number[]; } diff --git a/packages/server/src/modules/UsersModule/Users.controller.ts b/packages/server/src/modules/UsersModule/Users.controller.ts index fd8e5f865..9909fd9b7 100644 --- a/packages/server/src/modules/UsersModule/Users.controller.ts +++ b/packages/server/src/modules/UsersModule/Users.controller.ts @@ -8,7 +8,7 @@ import { Put, Query, } from '@nestjs/common'; -import { ApiOperation, ApiTags } from '@nestjs/swagger'; +import { ApiOperation, ApiTags, ApiResponse } from '@nestjs/swagger'; import { UsersApplication } from './Users.application'; import { EditUserDto } from './dtos/EditUser.dto'; @@ -22,6 +22,13 @@ export class UsersController { */ @Post(':id') @ApiOperation({ summary: 'Edit details of the given user.' }) + @ApiResponse({ + status: 200, + description: 'The user has been edited successfully.', + schema: { + example: { id: 1, message: 'The user has been edited successfully.' }, + }, + }) async editUser( @Param('id') userId: number, @Body() editUserDTO: EditUserDto, @@ -39,6 +46,13 @@ export class UsersController { */ @Delete(':id') @ApiOperation({ summary: 'Soft deleting the given user.' }) + @ApiResponse({ + status: 200, + description: 'The user has been deleted successfully.', + schema: { + example: { id: 1, message: 'The user has been deleted successfully.' }, + }, + }) async deleteUser(@Param('id') userId: number) { await this.usersApplication.deleteUser(userId); @@ -53,6 +67,10 @@ export class UsersController { */ @Get(':id') @ApiOperation({ summary: 'Retrieve user details of the given user id.' }) + @ApiResponse({ + status: 200, + description: 'User details retrieved successfully.', + }) async getUser(@Param('id') userId: number) { return this.usersApplication.getUser(userId); } @@ -62,6 +80,10 @@ export class UsersController { */ @Get() @ApiOperation({ summary: 'Retrieve the list of users.' }) + @ApiResponse({ + status: 200, + description: 'List of users retrieved successfully.', + }) async listUsers( @Query('page_size') pageSize?: number, @Query('page') page?: number, @@ -74,6 +96,13 @@ export class UsersController { */ @Put(':id/activate') @ApiOperation({ summary: 'Activate the given user.' }) + @ApiResponse({ + status: 200, + description: 'The user has been activated successfully.', + schema: { + example: { id: 1, message: 'The user has been activated successfully.' }, + }, + }) async activateUser(@Param('id') userId: number) { await this.usersApplication.activateUser(userId); @@ -88,6 +117,16 @@ export class UsersController { */ @Put(':id/inactivate') @ApiOperation({ summary: 'Inactivate the given user.' }) + @ApiResponse({ + status: 200, + description: 'The user has been inactivated successfully.', + schema: { + example: { + id: 1, + message: 'The user has been inactivated successfully.', + }, + }, + }) async inactivateUser(@Param('id') userId: number) { await this.usersApplication.inactivateUser(userId); @@ -96,5 +135,4 @@ export class UsersController { message: 'The user has been inactivated successfully.', }; } - }