mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-15 12:20:31 +00:00
feat: endpoints swagger document
This commit is contained in:
@@ -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()
|
||||
|
||||
@@ -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[];
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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',
|
||||
},
|
||||
};
|
||||
@@ -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;
|
||||
|
||||
@@ -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[];
|
||||
|
||||
@@ -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[];
|
||||
}
|
||||
|
||||
@@ -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.',
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user