refactor: financial reports query dtos

This commit is contained in:
Ahmed Bouhuolia
2025-06-06 00:11:51 +02:00
parent 51988dba3b
commit 9a685ffe5d
39 changed files with 822 additions and 50 deletions

View File

@@ -0,0 +1,7 @@
import { IsArray, IsOptional } from "class-validator";
export class FinancialSheetBranchesQueryDto {
@IsArray()
@IsOptional()
branchesIds: Array<number>;
}

View File

@@ -4,6 +4,7 @@ import { IAPAgingSummaryQuery } from './APAgingSummary.types';
import { AcceptType } from '@/constants/accept-type';
import { Response } from 'express';
import { ApiOperation, ApiTags } from '@nestjs/swagger';
import { APAgingSummaryQueryDto } from './APAgingSummaryQuery.dto';
@Controller('reports/payable-aging-summary')
@ApiTags('reports')
@@ -13,7 +14,7 @@ export class APAgingSummaryController {
@Get()
@ApiOperation({ summary: 'Get payable aging summary' })
public async get(
@Query() filter: IAPAgingSummaryQuery,
@Query() filter: APAgingSummaryQueryDto,
@Res({ passthrough: true }) res: Response,
@Headers('accept') acceptHeader: string,
) {

View File

@@ -0,0 +1,36 @@
import { Transform, Type } from 'class-transformer';
import { IsNumber, IsOptional, IsDateString, IsBoolean, ValidateNested, IsArray } from 'class-validator';
import { FinancialSheetBranchesQueryDto } from '../../dtos/FinancialSheetBranchesQuery.dto';
import { parseBoolean } from '@/utils/parse-boolean';
import { ToNumber } from '@/common/decorators/Validators';
import { NumberFormatQueryDto } from '@/modules/BankingTransactions/dtos/NumberFormatQuery.dto';
export class APAgingSummaryQueryDto extends FinancialSheetBranchesQueryDto {
@IsDateString()
@IsOptional()
asDate: Date | string;
@ToNumber()
@IsNumber()
@IsOptional()
agingDaysBefore: number;
@ToNumber()
@IsNumber()
@IsOptional()
agingPeriods: number;
@IsOptional()
@ValidateNested()
@Type(() => NumberFormatQueryDto)
numberFormat: NumberFormatQueryDto;
@Transform(({ value }) => parseBoolean(value, false))
@IsBoolean()
@IsOptional()
noneZero: boolean;
@IsArray()
@IsOptional()
vendorsIds: number[];
}

View File

@@ -1,9 +1,9 @@
import { Response } from 'express';
import { Controller, Get, Headers, Query, Res } from '@nestjs/common';
import { IBalanceSheetQuery } from './BalanceSheet.types';
import { AcceptType } from '@/constants/accept-type';
import { BalanceSheetApplication } from './BalanceSheetApplication';
import { ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger';
import { BalanceSheetQueryDto } from './BalanceSheet.dto';
@Controller('/reports/balance-sheet')
@ApiTags('reports')
@@ -12,7 +12,7 @@ export class BalanceSheetStatementController {
/**
* Retrieve the balance sheet.
* @param {IBalanceSheetQuery} query - Balance sheet query.
* @param {BalanceSheetQueryDto} query - Balance sheet query.
* @param {Response} res - Response.
* @param {string} acceptHeader - Accept header.
*/
@@ -20,7 +20,7 @@ export class BalanceSheetStatementController {
@ApiOperation({ summary: 'Get balance sheet statement' })
@ApiResponse({ status: 200, description: 'Balance sheet statement' })
public async balanceSheet(
@Query() query: IBalanceSheetQuery,
@Query() query: BalanceSheetQueryDto,
@Res({ passthrough: true }) res: Response,
@Headers('accept') acceptHeader: string,
) {

View File

@@ -0,0 +1,92 @@
import { NumberFormatQueryDto } from '@/modules/BankingTransactions/dtos/NumberFormatQuery.dto';
import { parseBoolean } from '@/utils/parse-boolean';
import { Transform, Type } from 'class-transformer';
import {
IsBoolean,
IsDateString,
IsEnum,
IsOptional,
IsString,
ValidateNested,
} from 'class-validator';
import { FinancialSheetBranchesQueryDto } from '../../dtos/FinancialSheetBranchesQuery.dto';
export class BalanceSheetQueryDto extends FinancialSheetBranchesQueryDto {
@IsString()
@IsOptional()
@IsEnum(['total', 'date_periods'])
displayColumnsType: 'total' | 'date_periods' = 'total';
@IsString()
@IsOptional()
@IsEnum(['day', 'month', 'year'])
displayColumnsBy: 'day' | 'month' | 'year' = 'year';
@IsDateString()
@IsOptional()
fromDate: string;
@IsDateString()
@IsOptional()
toDate: string;
@ValidateNested()
@Type(() => NumberFormatQueryDto)
@IsOptional()
numberFormat: NumberFormatQueryDto;
@IsBoolean()
@Transform(({ value }) => parseBoolean(value, false))
@IsOptional()
noneTransactions: boolean;
@IsBoolean()
@Transform(({ value }) => parseBoolean(value, false))
@IsOptional()
noneZero: boolean;
@IsString()
@IsOptional()
basis: 'cash' | 'accrual';
accountIds: number[];
@IsBoolean()
@Transform(({ value }) => parseBoolean(value, false))
@IsOptional()
percentageOfColumn: boolean;
@IsBoolean()
@Transform(({ value }) => parseBoolean(value, false))
@IsOptional()
percentageOfRow: boolean;
@IsBoolean()
@IsOptional()
@Transform(({ value }) => parseBoolean(value, false))
previousPeriod: boolean;
@IsBoolean()
@Transform(({ value }) => parseBoolean(value, false))
@IsOptional()
previousPeriodAmountChange: boolean;
@IsBoolean()
@Transform(({ value }) => parseBoolean(value, false))
@IsOptional()
previousPeriodPercentageChange: boolean;
@IsBoolean()
@Transform(({ value }) => parseBoolean(value, false))
@IsOptional()
previousYear: boolean;
@IsBoolean()
@Transform(({ value }) => parseBoolean(value, false))
@IsOptional()
previousYearAmountChange: boolean;
@IsBoolean()
@Transform(({ value }) => parseBoolean(value, false))
@IsOptional()
previousYearPercentageChange: boolean;
}

View File

@@ -0,0 +1,49 @@
import {
IsBoolean,
IsDateString,
IsEnum,
IsOptional,
IsString,
ValidateNested,
} from 'class-validator';
import { FinancialSheetBranchesQueryDto } from '../../dtos/FinancialSheetBranchesQuery.dto';
import { NumberFormatQueryDto } from '@/modules/BankingTransactions/dtos/NumberFormatQuery.dto';
import { Transform, Type } from 'class-transformer';
import { parseBoolean } from '@/utils/parse-boolean';
export class CashFlowStatementQueryDto extends FinancialSheetBranchesQueryDto {
@IsDateString()
@IsOptional()
fromDate: Date | string;
@IsDateString()
@IsOptional()
toDate: Date | string;
@IsString()
@IsOptional()
@IsEnum(['day', 'month', 'year'])
displayColumnsBy: 'day' | 'month' | 'year' = 'year';
@IsEnum(['total', 'date_periods'])
@IsOptional()
displayColumnsType: 'total' | 'date_periods' = 'total';
@Transform(({ value }) => parseBoolean(value, false))
@IsBoolean()
@IsOptional()
noneZero: boolean;
@Transform(({ value }) => parseBoolean(value, false))
@IsBoolean()
@IsOptional()
noneTransactions: boolean;
@ValidateNested()
@Type(() => NumberFormatQueryDto)
numberFormat: NumberFormatQueryDto;
@IsString()
@IsOptional()
basis: string;
}

View File

@@ -1,9 +1,9 @@
import { Response } from 'express';
import { Controller, Get, Headers, Query, Res } from '@nestjs/common';
import { ICashFlowStatementQuery } from './Cashflow.types';
import { AcceptType } from '@/constants/accept-type';
import { CashflowSheetApplication } from './CashflowSheetApplication';
import { ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger';
import { CashFlowStatementQueryDto } from './CashFlowStatementQuery.dto';
@Controller('reports/cashflow-statement')
@ApiTags('reports')
@@ -14,7 +14,7 @@ export class CashflowController {
@ApiResponse({ status: 200, description: 'Cashflow statement report' })
@ApiOperation({ summary: 'Get cashflow statement report' })
async getCashflow(
@Query() query: ICashFlowStatementQuery,
@Query() query: CashFlowStatementQueryDto,
@Res({ passthrough: true }) res: Response,
@Headers('accept') acceptHeader: string,
) {

View File

@@ -0,0 +1,36 @@
import {
IsBoolean,
IsDateString,
IsOptional,
ValidateNested,
} from 'class-validator';
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';
export class ContactBalanceSummaryQueryDto {
@IsDateString()
@IsOptional()
asDate: Date;
@ValidateNested()
@Type(() => NumberFormatQueryDto)
@IsOptional()
numberFormat: INumberFormatQuery;
@IsBoolean()
@Transform(({ value }) => parseBoolean(value, false))
@IsOptional()
percentageColumn: boolean;
@IsBoolean()
@Transform(({ value }) => parseBoolean(value, false))
@IsOptional()
noneTransactions: boolean;
@IsBoolean()
@Transform(({ value }) => parseBoolean(value, false))
@IsOptional()
noneZero: boolean;
}

View File

@@ -1,8 +1,8 @@
import { Response } from 'express';
import { ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger';
import { Controller, Get, Headers, Query, Res } from '@nestjs/common';
import { ICustomerBalanceSummaryQuery } from './CustomerBalanceSummary.types';
import { CustomerBalanceSummaryApplication } from './CustomerBalanceSummaryApplication';
import { CustomerBalanceSummaryQueryDto } from './CustomerBalanceSummaryQuery.dto';
import { AcceptType } from '@/constants/accept-type';
@Controller('/reports/customer-balance-summary')
@@ -16,7 +16,7 @@ export class CustomerBalanceSummaryController {
@ApiResponse({ status: 200, description: 'Customer balance summary report' })
@ApiOperation({ summary: 'Get customer balance summary report' })
async customerBalanceSummary(
@Query() filter: ICustomerBalanceSummaryQuery,
@Query() filter: CustomerBalanceSummaryQueryDto,
@Res({ passthrough: true }) res: Response,
@Headers('accept') acceptHeader: string,
) {

View File

@@ -9,7 +9,7 @@ import {
export interface ICustomerBalanceSummaryQuery
extends IContactBalanceSummaryQuery {
customersIds?: number[];
customersIds: number[];
}
export interface ICustomerBalanceSummaryAmount

View File

@@ -0,0 +1,8 @@
import { IsArray, IsOptional } from 'class-validator';
import { ContactBalanceSummaryQueryDto } from '../ContactBalanceSummary/ContactBalanceSummaryQuery.dto';
export class CustomerBalanceSummaryQueryDto extends ContactBalanceSummaryQueryDto {
@IsArray()
@IsOptional()
customersIds: number[];
}

View File

@@ -1,9 +1,9 @@
import { ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger';
import { Response } from 'express';
import { Controller, Get, Headers, Query, Res } from '@nestjs/common';
import { IGeneralLedgerSheetQuery } from './GeneralLedger.types';
import { GeneralLedgerApplication } from './GeneralLedgerApplication';
import { AcceptType } from '@/constants/accept-type';
import { GeneralLedgerQueryDto } from './GeneralLedgerQuery.dto';
@Controller('/reports/general-ledger')
@ApiTags('reports')
@@ -16,7 +16,7 @@ export class GeneralLedgerController {
@ApiResponse({ status: 200, description: 'General ledger report' })
@ApiOperation({ summary: 'Get general ledger report' })
public async getGeneralLedger(
@Query() query: IGeneralLedgerSheetQuery,
@Query() query: GeneralLedgerQueryDto,
@Res({ passthrough: true }) res: Response,
@Headers('accept') acceptHeader: string,
) {

View File

@@ -0,0 +1,39 @@
import { NumberFormatQueryDto } from '@/modules/BankingTransactions/dtos/NumberFormatQuery.dto';
import { FinancialSheetBranchesQueryDto } from '../../dtos/FinancialSheetBranchesQuery.dto';
import {
IsArray,
IsBoolean,
IsDateString,
IsOptional,
IsString,
ValidateNested,
} from 'class-validator';
import { Transform, Type } from 'class-transformer';
import { parseBoolean } from '@/utils/parse-boolean';
export class GeneralLedgerQueryDto extends FinancialSheetBranchesQueryDto {
@IsDateString()
@IsOptional()
fromDate: Date | string;
@IsDateString()
@IsOptional()
toDate: Date | string;
@IsString()
@IsOptional()
basis: string;
@ValidateNested()
@Type(() => NumberFormatQueryDto)
numberFormat: NumberFormatQueryDto;
@Transform(({ value }) => parseBoolean(value, false))
@IsBoolean()
@IsOptional()
noneTransactions: boolean;
@IsArray()
@IsOptional()
accountsIds: number[];
}

View File

@@ -1,9 +1,9 @@
import { Controller, Get, Headers, Query, Res } from '@nestjs/common';
import { InventoryItemDetailsApplication } from './InventoryItemDetailsApplication';
import { IInventoryDetailsQuery } from './InventoryItemDetails.types';
import { AcceptType } from '@/constants/accept-type';
import { Response } from 'express';
import { ApiOperation, ApiTags } 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';
@Controller('reports/inventory-item-details')
@ApiTags('reports')
@@ -15,7 +15,7 @@ export class InventoryItemDetailsController {
@Get('/')
@ApiOperation({ summary: 'Get inventory item details' })
async inventoryItemDetails(
@Query() query: IInventoryDetailsQuery,
@Query() query: InventoryItemDetailsQueryDto,
@Res({ passthrough: true }) res: Response,
@Headers('accept') acceptHeader: string,
) {

View File

@@ -0,0 +1,63 @@
import { ApiPropertyOptional } from '@nestjs/swagger';
import {
IsArray,
IsBoolean,
IsDateString,
IsOptional,
ValidateNested,
} from 'class-validator';
import { Transform, Type } from 'class-transformer';
import { INumberFormatQuery } from '../../types/Report.types';
import { NumberFormatQueryDto } from '@/modules/BankingTransactions/dtos/NumberFormatQuery.dto';
import { parseBoolean } from '@/utils/parse-boolean';
export class InventoryItemDetailsQueryDto {
@IsDateString()
@IsOptional()
@ApiPropertyOptional({
description: 'Start date for the inventory item details',
})
fromDate: Date | string;
@IsDateString()
@IsOptional()
@ApiPropertyOptional({
description: 'End date for the inventory item details',
})
toDate: Date | string;
@ValidateNested()
@Type(() => NumberFormatQueryDto)
@IsOptional()
@ApiPropertyOptional({
description: 'Number format for the inventory item details',
})
numberFormat: INumberFormatQuery;
@Transform(({ value }) => parseBoolean(value, false))
@IsBoolean()
@IsOptional()
@ApiPropertyOptional({ description: 'Whether to exclude transactions' })
noneTransactions: boolean;
@IsArray()
@IsOptional()
@ApiPropertyOptional({
description: 'Items IDs for the inventory item details',
})
itemsIds: number[];
@IsArray()
@IsOptional()
@ApiPropertyOptional({
description: 'Warehouses IDs for the inventory item details',
})
warehousesIds?: number[];
@IsArray()
@IsOptional()
@ApiPropertyOptional({
description: 'Branches IDs for the inventory item details',
})
branchesIds?: number[];
}

View File

@@ -2,7 +2,7 @@ import { Response } from 'express';
import { ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger';
import { Controller, Get, Headers, Query, Res } from '@nestjs/common';
import { InventoryValuationSheetApplication } from './InventoryValuationSheetApplication';
import { IInventoryValuationReportQuery } from './InventoryValuationSheet.types';
import { InventoryValuationQueryDto } from './InventoryValuationQuery.dto';
import { AcceptType } from '@/constants/accept-type';
@Controller('reports/inventory-valuation')
@@ -19,7 +19,7 @@ export class InventoryValuationController {
description: 'The inventory valuation sheet',
})
public async getInventoryValuationSheet(
@Query() query: IInventoryValuationReportQuery,
@Query() query: InventoryValuationQueryDto,
@Res({ passthrough: true }) res: Response,
@Headers('accept') acceptHeader: string,
) {

View File

@@ -0,0 +1,49 @@
import {
IsArray,
IsBoolean,
IsDateString,
IsOptional,
ValidateNested,
} from 'class-validator';
import { INumberFormatQuery } from '../../types/Report.types';
import { Transform, Type } from 'class-transformer';
import { parseBoolean } from '@/utils/parse-boolean';
import { NumberFormatQueryDto } from '@/modules/BankingTransactions/dtos/NumberFormatQuery.dto';
export class InventoryValuationQueryDto {
@IsDateString()
@IsOptional()
asDate: Date | string;
@ValidateNested()
@Type(() => NumberFormatQueryDto)
@IsOptional()
numberFormat: INumberFormatQuery;
@IsBoolean()
@Transform(({ value }) => parseBoolean(value, false))
@IsOptional()
noneTransactions: boolean;
@IsBoolean()
@Transform(({ value }) => parseBoolean(value, false))
@IsOptional()
noneZero: boolean;
@IsBoolean()
@Transform(({ value }) => parseBoolean(value, false))
@IsOptional()
onlyActive: boolean;
@IsArray()
@IsOptional()
itemsIds: number[];
@IsArray()
@IsOptional()
warehousesIds?: number[];
@IsArray()
@IsOptional()
branchesIds?: number[];
}

View File

@@ -4,6 +4,7 @@ import { Response } from 'express';
import { AcceptType } from '@/constants/accept-type';
import { JournalSheetApplication } from './JournalSheetApplication';
import { ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger';
import { JournalSheetQueryDto } from './JournalSheetQuery.dto';
@Controller('/reports/journal')
@ApiTags('reports')
@@ -14,7 +15,7 @@ export class JournalSheetController {
@ApiResponse({ status: 200, description: 'Journal report' })
@ApiOperation({ summary: 'Journal report' })
async journalSheet(
@Query() query: IJournalReportQuery,
@Query() query: JournalSheetQueryDto,
@Res({ passthrough: true }) res: Response,
@Headers('accept') acceptHeader: string,
) {

View File

@@ -0,0 +1,55 @@
import {
IsArray,
IsBoolean,
IsDateString,
IsNumber,
IsOptional,
IsString,
ValidateNested,
} from 'class-validator';
import { Type } from 'class-transformer';
import { FinancialSheetBranchesQueryDto } from '../../dtos/FinancialSheetBranchesQuery.dto';
class JournalSheetNumberFormatQueryDto {
@IsBoolean()
@IsOptional()
noCents: boolean;
@IsBoolean()
@IsOptional()
divideOn1000: boolean;
}
export class JournalSheetQueryDto extends FinancialSheetBranchesQueryDto {
@IsDateString()
@IsOptional()
fromDate: Date | string;
@IsDateString()
@IsOptional()
toDate: Date | string;
@ValidateNested()
@Type(() => JournalSheetNumberFormatQueryDto)
numberFormat: JournalSheetNumberFormatQueryDto;
@IsString()
@IsOptional()
transactionType: string;
@IsString()
@IsOptional()
transactionId: string;
@IsArray()
@IsOptional()
accountsIds: number | number[];
@IsNumber()
@IsOptional()
fromRange: number;
@IsNumber()
@IsOptional()
toRange: number;
}

View File

@@ -112,6 +112,7 @@ export class JournalSheetRepository {
if (this.filter.transactionType && this.filter.transactionId) {
query.where('reference_id', this.filter.transactionId);
}
query.withGraphFetched('account');
});
this.accountTransactions = transactions;
}

View File

@@ -1,9 +1,9 @@
import { Response } from 'express';
import { Controller, Get, Headers, Query, Res } from '@nestjs/common';
import { IProfitLossSheetQuery } from './ProfitLossSheet.types';
import { ProfitLossSheetApplication } from './ProfitLossSheetApplication';
import { AcceptType } from '@/constants/accept-type';
import { ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger';
import { ProfitLossSheetQueryDto } from './ProfitLossSheetQuery.dto';
@Controller('/reports/profit-loss-sheet')
@ApiTags('reports')
@@ -14,7 +14,7 @@ export class ProfitLossSheetController {
/**
* Retrieves the profit/loss sheet.
* @param {IProfitLossSheetQuery} query
* @param {ProfitLossSheetQueryDto} query
* @param {Response} res
* @param {string} acceptHeader
*/
@@ -22,7 +22,7 @@ export class ProfitLossSheetController {
@ApiResponse({ status: 200, description: 'Profit & loss statement' })
@ApiOperation({ summary: 'Get profit/loss statement report' })
async profitLossSheet(
@Query() query: IProfitLossSheetQuery,
@Query() query: ProfitLossSheetQueryDto,
@Res({ passthrough: true }) res: Response,
@Headers('accept') acceptHeader: string,
) {

View File

@@ -0,0 +1,135 @@
import { FinancialSheetBranchesQueryDto } from '../../dtos/FinancialSheetBranchesQuery.dto';
import { INumberFormatQuery } from '../../types/Report.types';
import {
IsArray,
IsBoolean,
IsDateString,
IsEnum,
IsOptional,
IsString,
} from 'class-validator';
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
import { Transform, Type } from 'class-transformer';
import { ToNumber } from '@/common/decorators/Validators';
import { parseBoolean } from '@/utils/parse-boolean';
export class ProfitLossSheetQueryDto extends FinancialSheetBranchesQueryDto {
@IsString()
@IsOptional()
@ApiProperty({ description: 'The basis for the profit and loss sheet' })
basis: string;
@IsDateString()
@IsOptional()
@ApiProperty({ description: 'Start date for the profit and loss sheet' })
fromDate: moment.MomentInput;
@IsDateString()
@IsOptional()
@ApiProperty({ description: 'End date for the profit and loss sheet' })
toDate: moment.MomentInput;
@ApiProperty({ description: 'Number format configuration' })
@Type(() => Object)
numberFormat: INumberFormatQuery;
@IsBoolean()
@Transform(({ value }) => parseBoolean(value, false))
@IsOptional()
@ApiPropertyOptional({ description: 'Whether to exclude zero values' })
noneZero: boolean;
@IsBoolean()
@Transform(({ value }) => parseBoolean(value, false))
@IsOptional()
@ApiPropertyOptional({ description: 'Whether to exclude transactions' })
noneTransactions: boolean;
@IsArray()
@IsOptional()
@ToNumber()
@ApiPropertyOptional({ description: 'Array of account IDs to include' })
accountsIds: number[];
@IsEnum(['total', 'date_periods'])
@IsOptional()
@ApiProperty({
description: 'Type of columns to display',
enum: ['total', 'date_periods'],
})
displayColumnsType: 'total' | 'date_periods';
@IsString()
@IsEnum(['day', 'month', 'year'])
@IsOptional()
@ApiProperty({ description: 'How to display columns' })
displayColumnsBy: 'day' | 'month' | 'year' = 'year';
@Transform(({ value }) => parseBoolean(value, false))
@IsBoolean()
@IsOptional()
@ApiPropertyOptional({ description: 'Whether to show percentage column' })
percentageColumn: boolean;
@Transform(({ value }) => parseBoolean(value, false))
@IsBoolean()
@IsOptional()
@ApiPropertyOptional({ description: 'Whether to show percentage row' })
percentageRow: boolean;
@Transform(({ value }) => parseBoolean(value, false))
@IsBoolean()
@IsOptional()
@ApiPropertyOptional({ description: 'Whether to show income percentage' })
percentageIncome: boolean;
@Transform(({ value }) => parseBoolean(value, false))
@IsBoolean()
@IsOptional()
@ApiPropertyOptional({ description: 'Whether to show expense percentage' })
percentageExpense: boolean;
@Transform(({ value }) => parseBoolean(value, false))
@IsBoolean()
@IsOptional()
@ApiPropertyOptional({ description: 'Whether to include previous period' })
previousPeriod: boolean;
@Transform(({ value }) => parseBoolean(value, false))
@IsBoolean()
@IsOptional()
@ApiPropertyOptional({
description: 'Whether to show previous period amount change',
})
previousPeriodAmountChange: boolean;
@IsBoolean()
@IsOptional()
@ApiPropertyOptional({
description: 'Whether to show previous period percentage change',
})
@Transform(({ value }) => parseBoolean(value, false))
previousPeriodPercentageChange: boolean;
@Transform(({ value }) => parseBoolean(value, false))
@IsBoolean()
@IsOptional()
@ApiPropertyOptional({ description: 'Whether to include previous year' })
previousYear: boolean;
@Transform(({ value }) => parseBoolean(value, false))
@IsBoolean()
@IsOptional()
@ApiPropertyOptional({
description: 'Whether to show previous year amount change',
})
previousYearAmountChange: boolean;
@Transform(({ value }) => parseBoolean(value, false))
@IsBoolean()
@IsOptional()
@ApiPropertyOptional({
description: 'Whether to show previous year percentage change',
})
previousYearPercentageChange: boolean;
}

View File

@@ -1,9 +1,9 @@
import { Response } from 'express';
import { Controller, Get, Headers, Query, Res } from '@nestjs/common';
import { PurchasesByItemsApplication } from './PurchasesByItemsApplication';
import { IPurchasesByItemsReportQuery } from './types/PurchasesByItems.types';
import { AcceptType } from '@/constants/accept-type';
import { ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger';
import { PurchasesByItemsQueryDto } from './PurchasesByItemsQuery.dto';
@Controller('/reports/purchases-by-items')
@ApiTags('reports')
@@ -16,7 +16,7 @@ export class PurchasesByItemReportController {
@ApiResponse({ status: 200, description: 'Purchases by items report' })
@ApiOperation({ summary: 'Get purchases by items report' })
async purchasesByItems(
@Query() filter: IPurchasesByItemsReportQuery,
@Query() filter: PurchasesByItemsQueryDto,
@Res({ passthrough: true }) res: Response,
@Headers('accept') acceptHeader: string,
) {

View File

@@ -0,0 +1,38 @@
import {
IsBoolean,
IsOptional,
IsDateString,
IsArray,
ValidateNested,
} from 'class-validator';
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';
export class PurchasesByItemsQueryDto {
@IsDateString()
@IsOptional()
fromDate: Date | string;
@IsDateString()
@IsOptional()
toDate: Date | string;
@IsArray()
@IsOptional()
itemsIds: number[];
@ValidateNested()
@Type(() => NumberFormatQueryDto)
@IsOptional()
numberFormat: INumberFormatQuery;
@IsBoolean()
@Transform(({ value }) => parseBoolean(value, false))
noneTransactions: boolean;
@IsBoolean()
@Transform(({ value }) => parseBoolean(value, false))
onlyActive: boolean;
}

View File

@@ -12,6 +12,7 @@ import { AcceptType } from '@/constants/accept-type';
import { SalesByItemsApplication } from './SalesByItemsApplication';
import { Response } from 'express';
import { ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger';
import { SalesByItemsQueryDto } from './SalesByItemsQuery.dto';
@Controller('/reports/sales-by-items')
@ApiTags('reports')
@@ -22,7 +23,7 @@ export class SalesByItemsController {
@ApiResponse({ status: 200, description: 'Sales by items report' })
@ApiOperation({ summary: 'Get sales by items report' })
public async salesByitems(
@Query() filter: ISalesByItemsReportQuery,
@Query() filter: SalesByItemsQueryDto,
@Res({ passthrough: true }) res: Response,
@Headers('accept') acceptHeader: string,
) {

View File

@@ -0,0 +1,40 @@
import {
IsArray,
IsBoolean,
IsDateString,
IsOptional,
ValidateNested,
} from 'class-validator';
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';
export class SalesByItemsQueryDto {
@IsDateString()
@IsOptional()
fromDate: Date | string;
@IsDateString()
@IsOptional()
toDate: Date | string;
@ValidateNested()
@Type(() => NumberFormatQueryDto)
@IsOptional()
numberFormat: INumberFormatQuery;
@IsBoolean()
@Transform(({ value }) => parseBoolean(value, false))
@IsOptional()
noneTransactions: boolean;
@IsBoolean()
@Transform(({ value }) => parseBoolean(value, false))
@IsOptional()
onlyActive: boolean;
@IsArray()
@IsOptional()
itemsIds: number[];
}

View File

@@ -0,0 +1,38 @@
import {
IsBoolean,
IsDateString,
IsOptional,
ValidateNested,
} from 'class-validator';
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 TransactionsByContactQueryDto {
@IsDateString()
@IsOptional()
fromDate: Date | string;
@IsDateString()
@IsOptional()
toDate: Date | string;
@ValidateNested()
@Type(() => NumberFormatQueryDto)
@IsOptional()
numberFormat: INumberFormatQuery;
@Transform(({ value }) => parseBoolean(value, false))
@IsBoolean()
@IsOptional()
@ApiPropertyOptional({ description: 'Whether to exclude transactions' })
noneTransactions: boolean;
@Transform(({ value }) => parseBoolean(value, false))
@IsBoolean()
@IsOptional()
@ApiPropertyOptional({ description: 'Whether to exclude zero values' })
noneZero: boolean;
}

View File

@@ -4,6 +4,7 @@ import { ITransactionsByCustomersFilter } from './TransactionsByCustomer.types';
import { TransactionsByCustomerApplication } from './TransactionsByCustomersApplication';
import { AcceptType } from '@/constants/accept-type';
import { Response } from 'express';
import { TransactionsByCustomerQueryDto } from './TransactionsByCustomerQuery.dto';
@Controller('/reports/transactions-by-customers')
@ApiTags('reports')
@@ -16,7 +17,7 @@ export class TransactionsByCustomerController {
@ApiOperation({ summary: 'Get transactions by customer' })
@ApiResponse({ status: 200, description: 'Transactions by customer' })
async transactionsByCustomer(
@Query() filter: ITransactionsByCustomersFilter,
@Query() filter: TransactionsByCustomerQueryDto,
@Res({ passthrough: true }) res: Response,
@Headers('accept') acceptHeader: string,
) {

View File

@@ -0,0 +1,8 @@
import { IsArray, IsOptional } from 'class-validator';
import { TransactionsByContactQueryDto } from '../TransactionsByContact/TransactionsByContactQuery.dto';
export class TransactionsByCustomerQueryDto extends TransactionsByContactQueryDto {
@IsArray()
@IsOptional()
customersIds: number[];
}

View File

@@ -4,6 +4,7 @@ import { AcceptType } from '@/constants/accept-type';
import { Response } from 'express';
import { TransactionsByVendorApplication } from './TransactionsByVendorApplication';
import { ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger';
import { TransactionsByVendorQueryDto } from './TransactionsByVendorQuery.dto';
@Controller('/reports/transactions-by-vendors')
@ApiTags('reports')
@@ -16,7 +17,7 @@ export class TransactionsByVendorController {
@ApiOperation({ summary: 'Get transactions by vendor' })
@ApiResponse({ status: 200, description: 'Transactions by vendor' })
async transactionsByVendor(
@Query() filter: ITransactionsByVendorsFilter,
@Query() filter: TransactionsByVendorQueryDto,
@Res({ passthrough: true }) res: Response,
@Headers('accept') acceptHeader: string,
) {

View File

@@ -1,6 +1,7 @@
import * as R from 'ramda';
import { isEmpty } from 'lodash';
import { ModelObject } from 'objection';
import { I18nService } from 'nestjs-i18n';
import {
ITransactionsByVendorsFilter,
ITransactionsByVendorsTransaction,
@@ -10,7 +11,6 @@ import {
import { TransactionsByContact } from '../TransactionsByContact/TransactionsByContact';
import { Vendor } from '@/modules/Vendors/models/Vendor';
import { INumberFormatQuery } from '../../types/Report.types';
import { I18nService } from 'nestjs-i18n';
import { TransactionsByVendorRepository } from './TransactionsByVendorRepository';
const VENDOR_NORMAL = 'credit';

View File

@@ -0,0 +1,8 @@
import { IsArray, IsOptional } from 'class-validator';
import { TransactionsByContactQueryDto } from '../TransactionsByContact/TransactionsByContactQuery.dto';
export class TransactionsByVendorQueryDto extends TransactionsByContactQueryDto {
@IsArray()
@IsOptional()
vendorsIds: number[];
}

View File

@@ -2,9 +2,9 @@ import { Controller, Get, Headers, Query, Res } from '@nestjs/common';
import { ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger';
import { castArray } from 'lodash';
import { Response } from 'express';
import { ITrialBalanceSheetQuery } from './TrialBalanceSheet.types';
import { AcceptType } from '@/constants/accept-type';
import { TrialBalanceSheetApplication } from './TrialBalanceSheetApplication';
import { TrialBalanceSheetQueryDto } from './TrialBalanceSheetQuery.dto';
@Controller('reports/trial-balance-sheet')
@ApiTags('reports')
@@ -17,7 +17,7 @@ export class TrialBalanceSheetController {
@ApiOperation({ summary: 'Get trial balance sheet' })
@ApiResponse({ status: 200, description: 'Trial balance sheet' })
async getTrialBalanceSheet(
@Query() query: ITrialBalanceSheetQuery,
@Query() query: TrialBalanceSheetQueryDto,
@Res({ passthrough: true }) res: Response,
@Headers('accept') acceptHeader: string,
) {

View File

@@ -1,8 +1,9 @@
import { Injectable } from '@nestjs/common';
import { TrialBalanceSheetTableInjectable } from './TrialBalanceSheetTableInjectable';
import { TrialBalanceExportInjectable } from './TrialBalanceExportInjectable';
import { ITrialBalanceSheetQuery, ITrialBalanceStatement } from './TrialBalanceSheet.types';
import { ITrialBalanceStatement } from './TrialBalanceSheet.types';
import { TrialBalanceSheetService } from './TrialBalanceSheetInjectable';
import { Injectable } from '@nestjs/common';
import { TrialBalanceSheetQueryDto } from './TrialBalanceSheetQuery.dto';
@Injectable()
export class TrialBalanceSheetApplication {
@@ -19,48 +20,48 @@ export class TrialBalanceSheetApplication {
/**
* Retrieves the trial balance sheet.
* @param {ITrialBalanceSheetQuery} query
* @param {TrialBalanceSheetQueryDto} query
* @returns {Promise<ITrialBalanceStatement>}
*/
public sheet(
query: ITrialBalanceSheetQuery,
query: TrialBalanceSheetQueryDto,
): Promise<ITrialBalanceStatement> {
return this.sheetService.trialBalanceSheet(query);
}
/**
* Retrieves the trial balance sheet in table format.
* @param {ITrialBalanceSheetQuery} query
* @param {TrialBalanceSheetQueryDto} query
* @returns {Promise<ITrialBalanceSheetTable>}
*/
public table(query: ITrialBalanceSheetQuery) {
public table(query: TrialBalanceSheetQueryDto) {
return this.tablable.table(query);
}
/**
* Retrieve the trial balance sheet in CSV format.
* @param {ITrialBalanceSheetQuery} query
* @param {TrialBalanceSheetQueryDto} query
* @returns {Promise<Buffer>}
*/
public csv(query: ITrialBalanceSheetQuery) {
public csv(query: TrialBalanceSheetQueryDto) {
return this.exportable.csv(query);
}
/**
* Retrieve the trial balance sheet in XLSX format.
* @param {ITrialBalanceSheetQuery} query
* @param {TrialBalanceSheetQueryDto} query
* @returns {Promise<Buffer>}
*/
public async xlsx(query: ITrialBalanceSheetQuery) {
public async xlsx(query: TrialBalanceSheetQueryDto) {
return this.exportable.xlsx(query);
}
/**
* Retrieve the trial balance sheet in pdf format.
* @param {ITrialBalanceSheetQuery} query
* @param {TrialBalanceSheetQueryDto} query
* @returns {Promise<Buffer>}
*/
public async pdf(query: ITrialBalanceSheetQuery) {
public async pdf(query: TrialBalanceSheetQueryDto) {
return this.exportable.pdf(query);
}
}

View File

@@ -0,0 +1,51 @@
import { NumberFormatQueryDto } from '@/modules/BankingTransactions/dtos/NumberFormatQuery.dto';
import { FinancialSheetBranchesQueryDto } from '../../dtos/FinancialSheetBranchesQuery.dto';
import { INumberFormatQuery } from '../../types/Report.types';
import {
IsArray,
IsBoolean,
IsDateString,
IsOptional,
IsString,
ValidateNested,
} from 'class-validator';
import { Transform, Type } from 'class-transformer';
import { parseBoolean } from '@/utils/parse-boolean';
export class TrialBalanceSheetQueryDto extends FinancialSheetBranchesQueryDto {
@IsDateString()
@IsOptional()
fromDate: Date;
@IsDateString()
@IsOptional()
toDate: Date;
@ValidateNested()
@Type(() => NumberFormatQueryDto)
@IsOptional()
numberFormat: INumberFormatQuery;
@IsString()
@IsOptional()
basis: 'cash' | 'accrual';
@IsBoolean()
@Transform(({ value }) => parseBoolean(value, false))
@IsOptional()
noneZero: boolean;
@IsBoolean()
@Transform(({ value }) => parseBoolean(value, false))
@IsOptional()
noneTransactions: boolean;
@IsBoolean()
@Transform(({ value }) => parseBoolean(value, false))
@IsOptional()
onlyActive: boolean;
@IsArray()
@IsOptional()
accountIds: number[];
}

View File

@@ -4,6 +4,7 @@ import { VendorBalanceSummaryApplication } from './VendorBalanceSummaryApplicati
import { Response } from 'express';
import { AcceptType } from '@/constants/accept-type';
import { ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger';
import { VendorBalanceSummaryQueryDto } from './VendorBalanceSummaryQuery.dto';
@Controller('/reports/vendor-balance-summary')
@ApiTags('reports')
@@ -16,7 +17,7 @@ export class VendorBalanceSummaryController {
@ApiOperation({ summary: 'Get vendor balance summary' })
@ApiResponse({ status: 200, description: 'Vendor balance summary' })
async vendorBalanceSummary(
@Query() filter: IVendorBalanceSummaryQuery,
@Query() filter: VendorBalanceSummaryQueryDto,
@Res({ passthrough: true }) res: Response,
@Headers('accept') acceptHeader: string,
) {

View File

@@ -0,0 +1,8 @@
import { IsArray, IsOptional } from 'class-validator';
import { ContactBalanceSummaryQueryDto } from '../ContactBalanceSummary/ContactBalanceSummaryQuery.dto';
export class VendorBalanceSummaryQueryDto extends ContactBalanceSummaryQueryDto {
@IsArray()
@IsOptional()
vendorsIds: number[];
}