refactor(nestjs): validation schema dtos

This commit is contained in:
Ahmed Bouhuolia
2025-05-25 23:39:54 +02:00
parent 2b3f98d8fe
commit 24bf3dd06d
24 changed files with 247 additions and 135 deletions

View File

@@ -14,7 +14,10 @@ export class ValidationPipe implements PipeTransform<any> {
return value; return value;
} }
const object = plainToInstance(metatype, value); const object = plainToInstance(metatype, value);
const errors = await validate(object); const errors = await validate(object, {
// Strip validated object of any properties that do not have any decorators.
whitelist: true,
});
if (errors.length > 0) { if (errors.length > 0) {
throw new BadRequestException(errors); throw new BadRequestException(errors);

View File

@@ -12,6 +12,7 @@ import {
} from 'class-validator'; } from 'class-validator';
import { BankRuleComparator } from '../types'; import { BankRuleComparator } from '../types';
import { ApiProperty } from '@nestjs/swagger'; import { ApiProperty } from '@nestjs/swagger';
import { ToNumber } from '@/common/decorators/Validators';
class BankRuleConditionDto { class BankRuleConditionDto {
@IsNotEmpty() @IsNotEmpty()
@@ -44,6 +45,8 @@ export class CommandBankRuleDto {
}) })
name: string; name: string;
@IsNotEmpty()
@ToNumber()
@IsInt() @IsInt()
@Min(0) @Min(0)
@ApiProperty({ @ApiProperty({
@@ -53,6 +56,7 @@ export class CommandBankRuleDto {
order: number; order: number;
@IsOptional() @IsOptional()
@ToNumber()
@IsInt() @IsInt()
@Min(0) @Min(0)
@ApiProperty({ @ApiProperty({
@@ -61,6 +65,7 @@ export class CommandBankRuleDto {
}) })
applyIfAccountId?: number; applyIfAccountId?: number;
@IsNotEmpty()
@IsIn(['deposit', 'withdrawal']) @IsIn(['deposit', 'withdrawal'])
@ApiProperty({ @ApiProperty({
description: 'The transaction type to apply the rule if', description: 'The transaction type to apply the rule if',
@@ -82,11 +87,14 @@ export class CommandBankRuleDto {
@Type(() => BankRuleConditionDto) @Type(() => BankRuleConditionDto)
@ApiProperty({ @ApiProperty({
description: 'The conditions to apply the rule if', description: 'The conditions to apply the rule if',
example: [{ field: 'description', comparator: 'contains', value: 'Salary' }], example: [
{ field: 'description', comparator: 'contains', value: 'Salary' },
],
}) })
conditions: BankRuleConditionDto[]; conditions: BankRuleConditionDto[];
@IsString() @IsString()
@IsNotEmpty()
@ApiProperty({ @ApiProperty({
description: 'The category to assign the rule if', description: 'The category to assign the rule if',
example: 'Income:Salary', example: 'Income:Salary',
@@ -95,6 +103,8 @@ export class CommandBankRuleDto {
@IsInt() @IsInt()
@Min(0) @Min(0)
@ToNumber()
@IsNotEmpty()
@ApiProperty({ @ApiProperty({
description: 'The account ID to assign the rule if', description: 'The account ID to assign the rule if',
example: 1, example: 1,

View File

@@ -24,7 +24,7 @@ export class TriggerRecognizedTransactionsSubscriber {
* @param {IBankRuleEventEditedPayload} payload - * @param {IBankRuleEventEditedPayload} payload -
*/ */
@OnEvent(events.bankRules.onEdited) @OnEvent(events.bankRules.onEdited)
private async recognizedTransactionsOnRuleEdited({ async recognizedTransactionsOnRuleEdited({
editRuleDTO, editRuleDTO,
oldBankRule, oldBankRule,
bankRule, bankRule,

View File

@@ -7,6 +7,8 @@ import { GetCreditNotePdf } from './queries/GetCreditNotePdf.serivce';
import { ICreditNotesQueryDTO } from './types/CreditNotes.types'; import { ICreditNotesQueryDTO } from './types/CreditNotes.types';
import { GetCreditNotesService } from './queries/GetCreditNotes.service'; import { GetCreditNotesService } from './queries/GetCreditNotes.service';
import { CreateCreditNoteDto, EditCreditNoteDto } from './dtos/CreditNote.dto'; import { CreateCreditNoteDto, EditCreditNoteDto } from './dtos/CreditNote.dto';
import { GetCreditNoteState } from './queries/GetCreditNoteState.service';
import { GetCreditNoteService } from './queries/GetCreditNote.service';
@Injectable() @Injectable()
export class CreditNoteApplication { export class CreditNoteApplication {
@@ -17,6 +19,8 @@ export class CreditNoteApplication {
private readonly deleteCreditNoteService: DeleteCreditNoteService, private readonly deleteCreditNoteService: DeleteCreditNoteService,
private readonly getCreditNotePdfService: GetCreditNotePdf, private readonly getCreditNotePdfService: GetCreditNotePdf,
private readonly getCreditNotesService: GetCreditNotesService, private readonly getCreditNotesService: GetCreditNotesService,
private readonly getCreditNoteStateService: GetCreditNoteState,
private readonly getCreditNoteService: GetCreditNoteService
) {} ) {}
/** /**
@@ -76,4 +80,21 @@ export class CreditNoteApplication {
getCreditNotes(creditNotesQuery: ICreditNotesQueryDTO) { getCreditNotes(creditNotesQuery: ICreditNotesQueryDTO) {
return this.getCreditNotesService.getCreditNotesList(creditNotesQuery); return this.getCreditNotesService.getCreditNotesList(creditNotesQuery);
} }
/**
* Retrieves the create/edit initial state of the credit note.
* @returns {Promise<ICreditNoteState>}
*/
getCreditNoteState() {
return this.getCreditNoteStateService.getCreditNoteState();
}
/**
* Retrieves the credit note.
* @param {number} creditNoteId
* @returns {Promise<CreditNote>}
*/
getCreditNote(creditNoteId: number) {
return this.getCreditNoteService.getCreditNote(creditNoteId);
}
} }

View File

@@ -1,4 +1,4 @@
import { ApiTags } from '@nestjs/swagger'; import { ApiTags, ApiOperation, ApiResponse, ApiParam } from '@nestjs/swagger';
import { import {
Body, Body,
Controller, Controller,
@@ -22,16 +22,42 @@ export class CreditNotesController {
constructor(private creditNoteApplication: CreditNoteApplication) {} constructor(private creditNoteApplication: CreditNoteApplication) {}
@Post() @Post()
@ApiOperation({ summary: 'Create a new credit note' })
@ApiResponse({ status: 201, description: 'Credit note successfully created' })
@ApiResponse({ status: 400, description: 'Invalid input data' })
createCreditNote(@Body() creditNoteDTO: CreateCreditNoteDto) { createCreditNote(@Body() creditNoteDTO: CreateCreditNoteDto) {
return this.creditNoteApplication.createCreditNote(creditNoteDTO); return this.creditNoteApplication.createCreditNote(creditNoteDTO);
} }
@Get('state')
@ApiOperation({ summary: 'Get credit note state' })
@ApiResponse({ status: 200, description: 'Returns the credit note state' })
getCreditNoteState() {
return this.creditNoteApplication.getCreditNoteState();
}
@Get(':id')
@ApiOperation({ summary: 'Get a specific credit note by ID' })
@ApiParam({ name: 'id', description: 'Credit note ID', type: 'number' })
@ApiResponse({ status: 200, description: 'Returns the credit note' })
@ApiResponse({ status: 404, description: 'Credit note not found' })
getCreditNote(@Param('id') creditNoteId: number) {
return this.creditNoteApplication.getCreditNote(creditNoteId);
}
@Get() @Get()
@ApiOperation({ summary: 'Get all credit notes' })
@ApiResponse({ status: 200, description: 'Returns a list of credit notes' })
getCreditNotes(@Query() creditNotesQuery: ICreditNotesQueryDTO) { getCreditNotes(@Query() creditNotesQuery: ICreditNotesQueryDTO) {
return this.creditNoteApplication.getCreditNotes(creditNotesQuery); return this.creditNoteApplication.getCreditNotes(creditNotesQuery);
} }
@Put(':id') @Put(':id')
@ApiOperation({ summary: 'Update a credit note' })
@ApiParam({ name: 'id', description: 'Credit note ID', type: 'number' })
@ApiResponse({ status: 200, description: 'Credit note successfully updated' })
@ApiResponse({ status: 404, description: 'Credit note not found' })
@ApiResponse({ status: 400, description: 'Invalid input data' })
editCreditNote( editCreditNote(
@Param('id') creditNoteId: number, @Param('id') creditNoteId: number,
@Body() creditNoteDTO: EditCreditNoteDto, @Body() creditNoteDTO: EditCreditNoteDto,
@@ -43,11 +69,19 @@ export class CreditNotesController {
} }
@Put(':id/open') @Put(':id/open')
@ApiOperation({ summary: 'Open a credit note' })
@ApiParam({ name: 'id', description: 'Credit note ID', type: 'number' })
@ApiResponse({ status: 200, description: 'Credit note successfully opened' })
@ApiResponse({ status: 404, description: 'Credit note not found' })
openCreditNote(@Param('id') creditNoteId: number) { openCreditNote(@Param('id') creditNoteId: number) {
return this.creditNoteApplication.openCreditNote(creditNoteId); return this.creditNoteApplication.openCreditNote(creditNoteId);
} }
@Delete(':id') @Delete(':id')
@ApiOperation({ summary: 'Delete a credit note' })
@ApiParam({ name: 'id', description: 'Credit note ID', type: 'number' })
@ApiResponse({ status: 200, description: 'Credit note successfully deleted' })
@ApiResponse({ status: 404, description: 'Credit note not found' })
deleteCreditNote(@Param('id') creditNoteId: number) { deleteCreditNote(@Param('id') creditNoteId: number) {
return this.creditNoteApplication.deleteCreditNote(creditNoteId); return this.creditNoteApplication.deleteCreditNote(creditNoteId);
} }

View File

@@ -15,7 +15,7 @@ import { WarehousesModule } from '../Warehouses/Warehouses.module';
import { PdfTemplatesModule } from '../PdfTemplate/PdfTemplates.module'; import { PdfTemplatesModule } from '../PdfTemplate/PdfTemplates.module';
import { ChromiumlyTenancyModule } from '../ChromiumlyTenancy/ChromiumlyTenancy.module'; import { ChromiumlyTenancyModule } from '../ChromiumlyTenancy/ChromiumlyTenancy.module';
import { TemplateInjectableModule } from '../TemplateInjectable/TemplateInjectable.module'; import { TemplateInjectableModule } from '../TemplateInjectable/TemplateInjectable.module';
import { GetCreditNote } from './queries/GetCreditNote.service'; import { GetCreditNoteService } from './queries/GetCreditNote.service';
import { CreditNoteBrandingTemplate } from './queries/CreditNoteBrandingTemplate.service'; import { CreditNoteBrandingTemplate } from './queries/CreditNoteBrandingTemplate.service';
import { AutoIncrementOrdersModule } from '../AutoIncrementOrders/AutoIncrementOrders.module'; import { AutoIncrementOrdersModule } from '../AutoIncrementOrders/AutoIncrementOrders.module';
import { CreditNoteGLEntries } from './commands/CreditNoteGLEntries'; import { CreditNoteGLEntries } from './commands/CreditNoteGLEntries';
@@ -52,7 +52,7 @@ import { CreditNotesApplyInvoiceModule } from '../CreditNotesApplyInvoice/Credit
], ],
providers: [ providers: [
CreateCreditNoteService, CreateCreditNoteService,
GetCreditNote, GetCreditNoteService,
CommandCreditNoteDTOTransform, CommandCreditNoteDTOTransform,
EditCreditNoteService, EditCreditNoteService,
OpenCreditNoteService, OpenCreditNoteService,
@@ -74,7 +74,7 @@ import { CreditNotesApplyInvoiceModule } from '../CreditNotesApplyInvoice/Credit
], ],
exports: [ exports: [
CreateCreditNoteService, CreateCreditNoteService,
GetCreditNote, GetCreditNoteService,
CommandCreditNoteDTOTransform, CommandCreditNoteDTOTransform,
EditCreditNoteService, EditCreditNoteService,
OpenCreditNoteService, OpenCreditNoteService,

View File

@@ -1,3 +1,4 @@
import { ToNumber } from '@/common/decorators/Validators';
import { ItemEntryDto } from '@/modules/TransactionItemEntry/dto/ItemEntry.dto'; import { ItemEntryDto } from '@/modules/TransactionItemEntry/dto/ItemEntry.dto';
import { ApiProperty } from '@nestjs/swagger'; import { ApiProperty } from '@nestjs/swagger';
import { Type } from 'class-transformer'; import { Type } from 'class-transformer';
@@ -5,9 +6,10 @@ import {
ArrayMinSize, ArrayMinSize,
IsArray, IsArray,
IsBoolean, IsBoolean,
IsDate, IsDateString,
IsEnum, IsEnum,
IsInt, IsInt,
IsNotEmpty,
IsNumber, IsNumber,
IsOptional, IsOptional,
IsPositive, IsPositive,
@@ -25,21 +27,25 @@ export class CreditNoteEntryDto extends ItemEntryDto {}
class AttachmentDto { class AttachmentDto {
@IsString() @IsString()
@IsNotEmpty()
key: string; key: string;
} }
export class CommandCreditNoteDto { export class CommandCreditNoteDto {
@ToNumber()
@IsInt() @IsInt()
@IsNotEmpty()
@ApiProperty({ example: 1, description: 'The customer ID' }) @ApiProperty({ example: 1, description: 'The customer ID' })
customerId: number; customerId: number;
@IsOptional() @IsOptional()
@ToNumber()
@IsPositive() @IsPositive()
@ApiProperty({ example: 3.43, description: 'The exchange rate' }) @ApiProperty({ example: 3.43, description: 'The exchange rate' })
exchangeRate?: number; exchangeRate?: number;
@IsDate() @IsNotEmpty()
@Type(() => Date) @IsDateString()
@ApiProperty({ example: '2021-09-01', description: 'The credit note date' }) @ApiProperty({ example: '2021-09-01', description: 'The credit note date' })
creditNoteDate: Date; creditNoteDate: Date;
@@ -64,26 +70,19 @@ export class CommandCreditNoteDto {
termsConditions?: string; termsConditions?: string;
@IsBoolean() @IsBoolean()
@ApiProperty({ @ApiProperty({ example: false, description: 'The credit note is open' })
example: false,
description: 'The credit note is open',
})
open: boolean = false; open: boolean = false;
@IsOptional() @IsOptional()
@ToNumber()
@IsInt() @IsInt()
@ApiProperty({ @ApiProperty({ example: 1, description: 'The warehouse ID' })
example: 1,
description: 'The warehouse ID',
})
warehouseId?: number; warehouseId?: number;
@IsOptional() @IsOptional()
@ToNumber()
@IsInt() @IsInt()
@ApiProperty({ @ApiProperty({ example: 1, description: 'The branch ID' })
example: 1,
description: 'The branch ID',
})
branchId?: number; branchId?: number;
@IsArray() @IsArray()
@@ -91,14 +90,7 @@ export class CommandCreditNoteDto {
@Type(() => CreditNoteEntryDto) @Type(() => CreditNoteEntryDto)
@ArrayMinSize(1) @ArrayMinSize(1)
@ApiProperty({ @ApiProperty({
example: [ example: [{ itemId: 1, quantity: 1, rate: 10, taxRateId: 1 }],
{
itemId: 1,
quantity: 1,
rate: 10,
taxRateId: 1,
},
],
description: 'The credit note entries', description: 'The credit note entries',
}) })
entries: CreditNoteEntryDto[]; entries: CreditNoteEntryDto[];
@@ -110,19 +102,15 @@ export class CommandCreditNoteDto {
attachments?: AttachmentDto[]; attachments?: AttachmentDto[];
@IsOptional() @IsOptional()
@ToNumber()
@IsInt() @IsInt()
@ApiProperty({ @ApiProperty({ example: 1, description: 'The pdf template ID' })
example: 1,
description: 'The pdf template ID',
})
pdfTemplateId?: number; pdfTemplateId?: number;
@IsOptional() @IsOptional()
@ToNumber()
@IsNumber() @IsNumber()
@ApiProperty({ @ApiProperty({ example: 10, description: 'The discount amount' })
example: 10,
description: 'The discount amount',
})
discount?: number; discount?: number;
@IsOptional() @IsOptional()
@@ -135,6 +123,7 @@ export class CommandCreditNoteDto {
discountType?: DiscountType; discountType?: DiscountType;
@IsOptional() @IsOptional()
@ToNumber()
@IsNumber() @IsNumber()
adjustment?: number; adjustment?: number;
} }

View File

@@ -7,7 +7,7 @@ import { ServiceError } from '@/modules/Items/ServiceError';
import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel'; import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel';
@Injectable() @Injectable()
export class GetCreditNote { export class GetCreditNoteService {
constructor( constructor(
private readonly transformer: TransformerInjectable, private readonly transformer: TransformerInjectable,

View File

@@ -1,5 +1,5 @@
import { Inject, Injectable } from '@nestjs/common'; import { Inject, Injectable } from '@nestjs/common';
import { GetCreditNote } from './GetCreditNote.service'; import { GetCreditNoteService } from './GetCreditNote.service';
import { CreditNoteBrandingTemplate } from './CreditNoteBrandingTemplate.service'; import { CreditNoteBrandingTemplate } from './CreditNoteBrandingTemplate.service';
import { transformCreditNoteToPdfTemplate } from '../utils'; import { transformCreditNoteToPdfTemplate } from '../utils';
import { CreditNote } from '../models/CreditNote'; import { CreditNote } from '../models/CreditNote';
@@ -25,7 +25,7 @@ export class GetCreditNotePdf {
constructor( constructor(
private readonly chromiumlyTenancy: ChromiumlyTenancy, private readonly chromiumlyTenancy: ChromiumlyTenancy,
private readonly templateInjectable: TemplateInjectable, private readonly templateInjectable: TemplateInjectable,
private readonly getCreditNoteService: GetCreditNote, private readonly getCreditNoteService: GetCreditNoteService,
private readonly creditNoteBrandingTemplate: CreditNoteBrandingTemplate, private readonly creditNoteBrandingTemplate: CreditNoteBrandingTemplate,
private readonly eventPublisher: EventEmitter2, private readonly eventPublisher: EventEmitter2,

View File

@@ -1,7 +1,7 @@
import { Inject, Injectable } from '@nestjs/common'; import { Inject, Injectable } from '@nestjs/common';
import { TransformerInjectable } from '@/modules/Transformer/TransformerInjectable.service'; import { TransformerInjectable } from '@/modules/Transformer/TransformerInjectable.service';
import { SaleInvoice } from '@/modules/SaleInvoices/models/SaleInvoice'; import { SaleInvoice } from '@/modules/SaleInvoices/models/SaleInvoice';
import { GetCreditNote } from '../../CreditNotes/queries/GetCreditNote.service'; import { GetCreditNoteService } from '../../CreditNotes/queries/GetCreditNote.service';
import { CreditNoteWithInvoicesToApplyTransformer } from './CreditNoteWithInvoicesToApplyTransformer'; import { CreditNoteWithInvoicesToApplyTransformer } from './CreditNoteWithInvoicesToApplyTransformer';
import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel'; import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel';
@@ -14,7 +14,7 @@ export class GetCreditNoteAssociatedInvoicesToApply {
*/ */
constructor( constructor(
private transformer: TransformerInjectable, private transformer: TransformerInjectable,
private getCreditNote: GetCreditNote, private getCreditNote: GetCreditNoteService,
@Inject(SaleInvoice.name) @Inject(SaleInvoice.name)
private saleInvoiceModel: TenantModelProxy<typeof SaleInvoice>, private saleInvoiceModel: TenantModelProxy<typeof SaleInvoice>,

View File

@@ -1,6 +1,6 @@
import { TenantModel } from "@/modules/System/models/TenantModel"; import { TenantBaseModel } from '@/modules/System/models/TenantBaseModel';
export class Currency extends TenantModel { export class Currency extends TenantBaseModel {
public readonly currencySign: string; public readonly currencySign: string;
public readonly currencyName: string; public readonly currencyName: string;
public readonly currencyCode: string; public readonly currencyCode: string;

View File

@@ -394,7 +394,5 @@ export abstract class DynamicFilterRoleAbstractor implements IDynamicFilter {
/** /**
* Retrieves the response meta. * Retrieves the response meta.
*/ */
getResponseMeta() { getResponseMeta() {}
throw new Error('Method not implemented.');
}
} }

View File

@@ -1,10 +1,12 @@
import { ToNumber } from '@/common/decorators/Validators';
import { ApiProperty } from '@nestjs/swagger'; import { ApiProperty } from '@nestjs/swagger';
import { Type } from 'class-transformer'; import { Type } from 'class-transformer';
import { import {
IsArray, IsArray,
IsBoolean, IsBoolean,
IsDate, IsDateString,
IsInt, IsInt,
IsISO4217CurrencyCode,
IsNotEmpty, IsNotEmpty,
IsNumber, IsNumber,
IsOptional, IsOptional,
@@ -23,10 +25,12 @@ export class ExpenseCategoryDto {
@IsNotEmpty() @IsNotEmpty()
index: number; index: number;
@IsInt()
@IsNotEmpty() @IsNotEmpty()
@ToNumber()
@IsInt()
expenseAccountId: number; expenseAccountId: number;
@ToNumber()
@IsNumber() @IsNumber()
@IsOptional() @IsOptional()
amount?: number; amount?: number;
@@ -40,6 +44,7 @@ export class ExpenseCategoryDto {
@IsOptional() @IsOptional()
landedCost?: boolean; landedCost?: boolean;
@ToNumber()
@IsInt() @IsInt()
@IsOptional() @IsOptional()
projectId?: number; projectId?: number;
@@ -55,7 +60,7 @@ export class CommandExpenseDto {
}) })
referenceNo?: string; referenceNo?: string;
@IsDate() @IsDateString()
@IsNotEmpty() @IsNotEmpty()
@ApiProperty({ @ApiProperty({
description: 'The payment date of the expense', description: 'The payment date of the expense',
@@ -63,8 +68,9 @@ export class CommandExpenseDto {
}) })
paymentDate: Date; paymentDate: Date;
@IsInt()
@IsNotEmpty() @IsNotEmpty()
@ToNumber()
@IsInt()
@ApiProperty({ @ApiProperty({
description: 'The payment account id of the expense', description: 'The payment account id of the expense',
example: 1, example: 1,
@@ -80,31 +86,22 @@ export class CommandExpenseDto {
}) })
description?: string; description?: string;
@ToNumber()
@IsNumber() @IsNumber()
@IsOptional() @IsOptional()
@ApiProperty({ @ApiProperty({ description: 'The exchange rate of the expense', example: 1 })
description: 'The exchange rate of the expense',
example: 1,
})
exchangeRate?: number; exchangeRate?: number;
@IsString() @IsString()
@MaxLength(3) @MaxLength(3)
@IsOptional() @IsOptional()
@IsISO4217CurrencyCode()
@ApiProperty({ @ApiProperty({
description: 'The currency code of the expense', description: 'The currency code of the expense',
example: 'USD', example: 'USD',
}) })
currencyCode?: string; currencyCode?: string;
@IsNumber()
@IsOptional()
@ApiProperty({
description: 'The exchange rate of the expense',
example: 1,
})
exchange_rate?: number;
@IsBoolean() @IsBoolean()
@IsOptional() @IsOptional()
@ApiProperty({ @ApiProperty({
@@ -113,14 +110,16 @@ export class CommandExpenseDto {
}) })
publish?: boolean; publish?: boolean;
@IsInt()
@IsOptional() @IsOptional()
@ToNumber()
@IsInt()
@ApiProperty({ @ApiProperty({
description: 'The payee id of the expense', description: 'The payee id of the expense',
example: 1, example: 1,
}) })
payeeId?: number; payeeId?: number;
@ToNumber()
@IsInt() @IsInt()
@IsOptional() @IsOptional()
@ApiProperty({ @ApiProperty({

View File

@@ -108,11 +108,7 @@ export class ManualJournalsController {
description: 'The manual journal details have been successfully retrieved.', description: 'The manual journal details have been successfully retrieved.',
}) })
@ApiResponse({ status: 404, description: 'The manual journal not found.' }) @ApiResponse({ status: 404, description: 'The manual journal not found.' })
public getManualJournals( public getManualJournals(@Query() filterDto: Partial<IManualJournalsFilter>) {
@Query() filterDto: Partial<IManualJournalsFilter>
) {
return this.manualJournalsApplication.getManualJournals(filterDto); return this.manualJournalsApplication.getManualJournals(filterDto);
} }
} }

View File

@@ -1,10 +1,13 @@
import { ToNumber } from '@/common/decorators/Validators';
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
import { Type } from 'class-transformer'; import { Type } from 'class-transformer';
import { import {
IsArray, IsArray,
IsBoolean, IsBoolean,
IsDate, IsDate,
IsDateString,
IsInt, IsInt,
IsNotEmpty,
IsNumber, IsNumber,
IsOptional, IsOptional,
IsPositive, IsPositive,
@@ -20,18 +23,21 @@ export class ManualJournalEntryDto {
index: number; index: number;
@ApiPropertyOptional({ description: 'Credit amount' }) @ApiPropertyOptional({ description: 'Credit amount' })
@ToNumber()
@IsOptional() @IsOptional()
@IsNumber() @IsNumber()
@Min(0) @Min(0)
credit?: number; credit?: number;
@ApiPropertyOptional({ description: 'Debit amount' }) @ApiPropertyOptional({ description: 'Debit amount' })
@ToNumber()
@IsOptional() @IsOptional()
@IsNumber() @IsNumber()
@Min(0) @Min(0)
debit?: number; debit?: number;
@ApiProperty({ description: 'Account ID' }) @ApiProperty({ description: 'Account ID' })
@IsNotEmpty()
@IsInt() @IsInt()
accountId: number; accountId: number;
@@ -41,16 +47,19 @@ export class ManualJournalEntryDto {
note?: string; note?: string;
@ApiPropertyOptional({ description: 'Contact ID' }) @ApiPropertyOptional({ description: 'Contact ID' })
@IsOptional() @ToNumber()
@IsInt() @IsInt()
@IsOptional()
contactId?: number; contactId?: number;
@ApiPropertyOptional({ description: 'Branch ID' }) @ApiPropertyOptional({ description: 'Branch ID' })
@ToNumber()
@IsOptional() @IsOptional()
@IsInt() @IsInt()
branchId?: number; branchId?: number;
@ApiPropertyOptional({ description: 'Project ID' }) @ApiPropertyOptional({ description: 'Project ID' })
@ToNumber()
@IsOptional() @IsOptional()
@IsInt() @IsInt()
projectId?: number; projectId?: number;
@@ -64,8 +73,7 @@ class AttachmentDto {
export class CommandManualJournalDto { export class CommandManualJournalDto {
@ApiProperty({ description: 'Journal date' }) @ApiProperty({ description: 'Journal date' })
@IsDate() @IsDateString()
@Type(() => Date)
date: Date; date: Date;
@ApiPropertyOptional({ description: 'Currency code' }) @ApiPropertyOptional({ description: 'Currency code' })
@@ -74,6 +82,7 @@ export class CommandManualJournalDto {
currencyCode?: string; currencyCode?: string;
@ApiPropertyOptional({ description: 'Exchange rate' }) @ApiPropertyOptional({ description: 'Exchange rate' })
@ToNumber()
@IsOptional() @IsOptional()
@IsNumber() @IsNumber()
@IsPositive() @IsPositive()
@@ -103,6 +112,7 @@ export class CommandManualJournalDto {
description?: string; description?: string;
@ApiPropertyOptional({ description: 'Branch ID' }) @ApiPropertyOptional({ description: 'Branch ID' })
@ToNumber()
@IsOptional() @IsOptional()
@IsInt() @IsInt()
branchId?: number; branchId?: number;

View File

@@ -18,6 +18,7 @@ import {
IPaymentsReceivedFilter, IPaymentsReceivedFilter,
PaymentReceiveMailOptsDTO, PaymentReceiveMailOptsDTO,
} from './types/PaymentReceived.types'; } from './types/PaymentReceived.types';
import { CreatePaymentReceivedDto, EditPaymentReceivedDto } from './dtos/PaymentReceived.dto';
@Controller('payments-received') @Controller('payments-received')
@ApiTags('payments-received') @ApiTags('payments-received')
@@ -57,7 +58,7 @@ export class PaymentReceivesController {
@Post() @Post()
@ApiOperation({ summary: 'Create a new payment received.' }) @ApiOperation({ summary: 'Create a new payment received.' })
public createPaymentReceived( public createPaymentReceived(
@Body() paymentReceiveDTO: IPaymentReceivedCreateDTO, @Body() paymentReceiveDTO: CreatePaymentReceivedDto,
) { ) {
return this.paymentReceivesApplication.createPaymentReceived( return this.paymentReceivesApplication.createPaymentReceived(
paymentReceiveDTO, paymentReceiveDTO,
@@ -68,7 +69,7 @@ export class PaymentReceivesController {
@ApiOperation({ summary: 'Edit the given payment received.' }) @ApiOperation({ summary: 'Edit the given payment received.' })
public editPaymentReceive( public editPaymentReceive(
@Param('id', ParseIntPipe) paymentReceiveId: number, @Param('id', ParseIntPipe) paymentReceiveId: number,
@Body() paymentReceiveDTO: IPaymentReceivedEditDTO, @Body() paymentReceiveDTO: EditPaymentReceivedDto,
) { ) {
return this.paymentReceivesApplication.editPaymentReceive( return this.paymentReceivesApplication.editPaymentReceive(
paymentReceiveId, paymentReceiveId,

View File

@@ -1,16 +1,25 @@
import { AttachmentLinkDto } from '@/modules/Attachments/dtos/Attachment.dto';
import { ApiProperty } from '@nestjs/swagger'; import { ApiProperty } from '@nestjs/swagger';
import { Type } from 'class-transformer'; import { Type } from 'class-transformer';
import { IsArray, IsNotEmpty, ValidateNested } from 'class-validator'; import {
import { IsString } from 'class-validator'; IsString,
import { IsDateString, IsNumber, IsOptional } from 'class-validator'; IsDateString,
import { IsInt } from 'class-validator'; IsNumber,
IsOptional,
IsArray,
IsNotEmpty,
IsInt,
ValidateNested,
} from 'class-validator';
import { ToNumber } from '@/common/decorators/Validators';
import { AttachmentLinkDto } from '@/modules/Attachments/dtos/Attachment.dto';
export class PaymentReceivedEntryDto { export class PaymentReceivedEntryDto {
@ToNumber()
@IsOptional() @IsOptional()
@IsInt() @IsInt()
id?: number; id?: number;
@ToNumber()
@IsOptional() @IsOptional()
@IsInt() @IsInt()
index?: number; index?: number;
@@ -20,13 +29,16 @@ export class PaymentReceivedEntryDto {
paymentReceiveId?: number; paymentReceiveId?: number;
@IsInt() @IsInt()
@IsNotEmpty()
invoiceId: number; invoiceId: number;
@IsNumber() @IsNumber()
@IsNotEmpty()
paymentAmount: number; paymentAmount: number;
} }
export class CommandPaymentReceivedDto { export class CommandPaymentReceivedDto {
@ToNumber()
@IsInt() @IsInt()
@IsNotEmpty() @IsNotEmpty()
@ApiProperty({ description: 'The id of the customer', example: 1 }) @ApiProperty({ description: 'The id of the customer', example: 1 })
@@ -40,6 +52,7 @@ export class CommandPaymentReceivedDto {
paymentDate: Date | string; paymentDate: Date | string;
@IsOptional() @IsOptional()
@ToNumber()
@IsNumber() @IsNumber()
@ApiProperty({ @ApiProperty({
description: 'The amount of the payment received', description: 'The amount of the payment received',
@@ -48,6 +61,7 @@ export class CommandPaymentReceivedDto {
amount?: number; amount?: number;
@IsOptional() @IsOptional()
@ToNumber()
@IsNumber() @IsNumber()
@ApiProperty({ @ApiProperty({
description: 'The exchange rate of the payment received', description: 'The exchange rate of the payment received',
@@ -63,6 +77,7 @@ export class CommandPaymentReceivedDto {
}) })
referenceNo?: string; referenceNo?: string;
@ToNumber()
@IsInt() @IsInt()
@IsNotEmpty() @IsNotEmpty()
@ApiProperty({ @ApiProperty({
@@ -72,6 +87,7 @@ export class CommandPaymentReceivedDto {
depositAccountId: number; depositAccountId: number;
@IsOptional() @IsOptional()
@ToNumber()
@IsString() @IsString()
@ApiProperty({ @ApiProperty({
description: 'The payment receive number of the payment received', description: 'The payment receive number of the payment received',
@@ -97,6 +113,7 @@ export class CommandPaymentReceivedDto {
entries: PaymentReceivedEntryDto[]; entries: PaymentReceivedEntryDto[];
@IsOptional() @IsOptional()
@ToNumber()
@IsInt() @IsInt()
@ApiProperty({ @ApiProperty({
description: 'The id of the branch', description: 'The id of the branch',

View File

@@ -5,16 +5,16 @@ import {
ArrayMinSize, ArrayMinSize,
IsArray, IsArray,
IsBoolean, IsBoolean,
IsDate, IsDateString,
IsEmail,
IsEnum, IsEnum,
IsNotEmpty, IsNotEmpty,
IsNumber, IsNumber,
IsOptional,
IsString, IsString,
Min, Min,
MinLength,
ValidateNested, ValidateNested,
} from 'class-validator'; } from 'class-validator';
import { IsOptional, ToNumber } from '@/common/decorators/Validators';
enum DiscountType { enum DiscountType {
Percentage = 'percentage', Percentage = 'percentage',
@@ -28,24 +28,22 @@ class AttachmentDto {
key: string; key: string;
} }
export class CommandSaleEstimateDto { export class CommandSaleEstimateDto {
@IsNumber()
@IsNotEmpty() @IsNotEmpty()
@ApiProperty({ @ToNumber()
description: 'The id of the customer', @IsNumber()
example: 1, @ApiProperty({ description: 'The id of the customer', example: 1 })
})
customerId: number; customerId: number;
@IsDate() @IsNotEmpty()
@Type(() => Date) @IsDateString()
@ApiProperty({ @ApiProperty({
description: 'The date of the estimate', description: 'The date of the estimate',
example: '2021-01-01', example: '2021-01-01',
}) })
estimateDate: Date; estimateDate: Date;
@IsDate() @IsNotEmpty()
@Type(() => Date) @IsDateString()
@ApiProperty({ @ApiProperty({
description: 'The expiration date of the estimate', description: 'The expiration date of the estimate',
example: '2021-01-01', example: '2021-01-01',
@@ -65,31 +63,26 @@ export class CommandSaleEstimateDto {
estimateNumber?: string; estimateNumber?: string;
@IsBoolean() @IsBoolean()
delivered: boolean = false; @IsOptional()
delivered?: boolean = false;
@IsOptional()
@ToNumber()
@IsNumber() @IsNumber()
@Min(0.01) @Min(0.01)
@IsOptional() @ApiProperty({ description: 'The exchange rate of the estimate', example: 1 })
@ApiProperty({
description: 'The exchange rate of the estimate',
example: 1,
})
exchangeRate?: number; exchangeRate?: number;
@IsNumber()
@IsOptional() @IsOptional()
@ApiProperty({ @ToNumber()
description: 'The id of the warehouse', @IsNumber()
example: 1, @ApiProperty({ description: 'The id of the warehouse', example: 1 })
})
warehouseId?: number; warehouseId?: number;
@IsNumber()
@IsOptional() @IsOptional()
@ApiProperty({ @ToNumber()
description: 'The id of the branch', @IsNumber()
example: 1, @ApiProperty({ description: 'The id of the branch', example: 1 })
})
branchId?: number; branchId?: number;
@IsArray() @IsArray()
@@ -110,32 +103,33 @@ export class CommandSaleEstimateDto {
}) })
entries: SaleEstimateEntryDto[]; entries: SaleEstimateEntryDto[];
@IsString()
@IsOptional() @IsOptional()
@IsString()
@ApiProperty({ @ApiProperty({
description: 'The note of the estimate', description: 'The note of the estimate',
example: 'This is a note', example: 'This is a note',
}) })
note?: string; note?: string;
@IsString()
@IsOptional() @IsOptional()
@IsString()
@ApiProperty({ @ApiProperty({
description: 'The terms and conditions of the estimate', description: 'The terms and conditions of the estimate',
example: 'This is a terms and conditions', example: 'This is a terms and conditions',
}) })
termsConditions?: string; termsConditions?: string;
@IsString()
@IsOptional() @IsOptional()
@IsString()
@IsEmail()
@ApiProperty({ @ApiProperty({
description: 'The email to send the estimate to', description: 'The email to send the estimate to',
example: 'test@test.com', example: 'test@test.com',
}) })
sendToEmail?: string; sendToEmail?: string;
@IsArray()
@IsOptional() @IsOptional()
@IsArray()
@ValidateNested({ each: true }) @ValidateNested({ each: true })
@Type(() => AttachmentDto) @Type(() => AttachmentDto)
@ApiProperty({ @ApiProperty({
@@ -146,22 +140,26 @@ export class CommandSaleEstimateDto {
}, },
], ],
}) })
@IsNumber()
@IsOptional() @IsOptional()
@ToNumber()
@IsNumber()
@ApiProperty({ @ApiProperty({
description: 'The id of the pdf template', description: 'The id of the pdf template',
example: 1, example: 1,
}) })
pdfTemplateId?: number; pdfTemplateId?: number;
@IsNumber()
@IsOptional() @IsOptional()
@ToNumber()
@IsNumber()
@ApiProperty({ @ApiProperty({
description: 'The discount of the estimate', description: 'The discount of the estimate',
example: 1, example: 1,
}) })
discount?: number; discount?: number;
@IsOptional()
@IsEnum(DiscountType) @IsEnum(DiscountType)
@ApiProperty({ @ApiProperty({
description: 'The type of the discount', description: 'The type of the discount',
@@ -169,8 +167,9 @@ export class CommandSaleEstimateDto {
}) })
discountType: DiscountType = DiscountType.Amount; discountType: DiscountType = DiscountType.Amount;
@IsNumber() @ToNumber()
@IsOptional() @IsOptional()
@IsNumber()
@ApiProperty({ @ApiProperty({
description: 'The adjustment of the estimate', description: 'The adjustment of the estimate',
example: 1, example: 1,

View File

@@ -21,6 +21,7 @@ import {
ApiHeader, ApiHeader,
ApiOperation, ApiOperation,
ApiParam, ApiParam,
ApiQuery,
ApiResponse, ApiResponse,
ApiTags, ApiTags,
} from '@nestjs/swagger'; } from '@nestjs/swagger';
@@ -111,7 +112,7 @@ export class SaleInvoicesController {
return this.saleInvoiceApplication.deleteSaleInvoice(id); return this.saleInvoiceApplication.deleteSaleInvoice(id);
} }
@Get('receivable/:customerId?') @Get('receivable')
@ApiOperation({ summary: 'Retrieves the receivable sale invoices.' }) @ApiOperation({ summary: 'Retrieves the receivable sale invoices.' })
@ApiResponse({ @ApiResponse({
status: 200, status: 200,
@@ -119,13 +120,13 @@ export class SaleInvoicesController {
'The receivable sale invoices have been successfully retrieved.', 'The receivable sale invoices have been successfully retrieved.',
}) })
@ApiResponse({ status: 404, description: 'The customer not found.' }) @ApiResponse({ status: 404, description: 'The customer not found.' })
@ApiParam({ @ApiQuery({
name: 'customerId', name: 'customerId',
required: false, required: false,
type: Number, type: Number,
description: 'The customer id', description: 'The customer id',
}) })
getReceivableSaleInvoices(@Param('customerId') customerId?: number) { getReceivableSaleInvoices(@Query('customerId') customerId?: number) {
return this.saleInvoiceApplication.getReceivableSaleInvoices(customerId); return this.saleInvoiceApplication.getReceivableSaleInvoices(customerId);
} }

View File

@@ -1,3 +1,4 @@
import { IsOptional, ToNumber } from '@/common/decorators/Validators';
import { ItemEntryDto } from '@/modules/TransactionItemEntry/dto/ItemEntry.dto'; import { ItemEntryDto } from '@/modules/TransactionItemEntry/dto/ItemEntry.dto';
import { ApiProperty } from '@nestjs/swagger'; import { ApiProperty } from '@nestjs/swagger';
import { Type } from 'class-transformer'; import { Type } from 'class-transformer';
@@ -5,12 +6,11 @@ import {
ArrayMinSize, ArrayMinSize,
IsArray, IsArray,
IsBoolean, IsBoolean,
IsDate, IsDateString,
IsEnum, IsEnum,
IsInt, IsInt,
IsNotEmpty, IsNotEmpty,
IsNumber, IsNumber,
IsOptional,
IsString, IsString,
Min, Min,
ValidateNested, ValidateNested,
@@ -29,26 +29,24 @@ class PaymentMethodDto {
enable: boolean; enable: boolean;
} }
class AttachmentDto { class AttachmentDto {
@IsString() @IsString()
key: string; key: string;
} }
class CommandSaleInvoiceDto { class CommandSaleInvoiceDto {
@ToNumber()
@IsInt() @IsInt()
@IsNotEmpty() @IsNotEmpty()
@ApiProperty({ description: 'Customer ID', example: 1 }) @ApiProperty({ description: 'Customer ID', example: 1 })
customerId: number; customerId: number;
@IsDate() @IsDateString()
@Type(() => Date)
@IsNotEmpty() @IsNotEmpty()
@ApiProperty({ description: 'Invoice date', example: '2023-01-01T00:00:00Z' }) @ApiProperty({ description: 'Invoice date', example: '2023-01-01T00:00:00Z' })
invoiceDate: Date; invoiceDate: Date;
@IsDate() @IsDateString()
@Type(() => Date)
@IsNotEmpty() @IsNotEmpty()
@ApiProperty({ description: 'Due date', example: '2023-01-15T00:00:00Z' }) @ApiProperty({ description: 'Due date', example: '2023-01-15T00:00:00Z' })
dueDate: Date; dueDate: Date;
@@ -99,6 +97,7 @@ class CommandSaleInvoiceDto {
termsConditions?: string; termsConditions?: string;
@IsOptional() @IsOptional()
@ToNumber()
@IsNumber() @IsNumber()
@Min(0) @Min(0)
@ApiProperty({ @ApiProperty({
@@ -110,16 +109,19 @@ class CommandSaleInvoiceDto {
exchangeRate?: number; exchangeRate?: number;
@IsOptional() @IsOptional()
@ToNumber()
@IsInt() @IsInt()
@ApiProperty({ description: 'Warehouse ID', required: false, example: 1 }) @ApiProperty({ description: 'Warehouse ID', required: false, example: 1 })
warehouseId?: number; warehouseId?: number;
@IsOptional() @IsOptional()
@ToNumber()
@IsInt() @IsInt()
@ApiProperty({ description: 'Branch ID', required: false, example: 1 }) @ApiProperty({ description: 'Branch ID', required: false, example: 1 })
branchId?: number; branchId?: number;
@IsOptional() @IsOptional()
@ToNumber()
@IsInt() @IsInt()
@ApiProperty({ description: 'Project ID', required: false, example: 1 }) @ApiProperty({ description: 'Project ID', required: false, example: 1 })
projectId?: number; projectId?: number;
@@ -145,6 +147,7 @@ class CommandSaleInvoiceDto {
entries: ItemEntryDto[]; entries: ItemEntryDto[];
@IsOptional() @IsOptional()
@ToNumber()
@IsInt() @IsInt()
@ApiProperty({ description: 'PDF template ID', required: false, example: 1 }) @ApiProperty({ description: 'PDF template ID', required: false, example: 1 })
pdfTemplateId?: number; pdfTemplateId?: number;
@@ -161,6 +164,7 @@ class CommandSaleInvoiceDto {
paymentMethods?: PaymentMethodDto[]; paymentMethods?: PaymentMethodDto[];
@IsOptional() @IsOptional()
@ToNumber()
@IsNumber() @IsNumber()
@ApiProperty({ description: 'Discount value', required: false, example: 10 }) @ApiProperty({ description: 'Discount value', required: false, example: 10 })
discount?: number; discount?: number;
@@ -176,6 +180,7 @@ class CommandSaleInvoiceDto {
discountType?: DiscountType; discountType?: DiscountType;
@IsOptional() @IsOptional()
@ToNumber()
@IsNumber() @IsNumber()
@ApiProperty({ @ApiProperty({
description: 'Adjustment amount', description: 'Adjustment amount',
@@ -185,6 +190,7 @@ class CommandSaleInvoiceDto {
adjustment?: number; adjustment?: number;
@IsOptional() @IsOptional()
@ToNumber()
@IsInt() @IsInt()
@ApiProperty({ @ApiProperty({
description: 'ID of the estimate this invoice is created from', description: 'ID of the estimate this invoice is created from',

View File

@@ -1,10 +1,13 @@
import { ToNumber } from '@/common/decorators/Validators';
import { ItemEntryDto } from '@/modules/TransactionItemEntry/dto/ItemEntry.dto'; import { ItemEntryDto } from '@/modules/TransactionItemEntry/dto/ItemEntry.dto';
import { ApiProperty } from '@nestjs/swagger'; import { ApiProperty } from '@nestjs/swagger';
import { Type } from 'class-transformer'; import { Type } from 'class-transformer';
import { import {
ArrayMinSize,
IsArray, IsArray,
IsBoolean, IsBoolean,
IsDate, IsDate,
IsDateString,
IsEnum, IsEnum,
IsNotEmpty, IsNotEmpty,
IsNumber, IsNumber,
@@ -28,8 +31,9 @@ class AttachmentDto {
} }
export class CommandSaleReceiptDto { export class CommandSaleReceiptDto {
@IsNumber()
@IsNotEmpty() @IsNotEmpty()
@ToNumber()
@IsNumber()
@ApiProperty({ @ApiProperty({
description: 'The id of the customer', description: 'The id of the customer',
example: 1, example: 1,
@@ -37,6 +41,7 @@ export class CommandSaleReceiptDto {
customerId: number; customerId: number;
@IsOptional() @IsOptional()
@ToNumber()
@IsNumber() @IsNumber()
@IsPositive() @IsPositive()
@ApiProperty({ @ApiProperty({
@@ -46,11 +51,12 @@ export class CommandSaleReceiptDto {
exchangeRate?: number; exchangeRate?: number;
@IsNumber() @IsNumber()
@ToNumber()
@IsNotEmpty() @IsNotEmpty()
@ApiProperty({ description: 'The id of the deposit account', example: 1 }) @ApiProperty({ description: 'The id of the deposit account', example: 1 })
depositAccountId: number; depositAccountId: number;
@IsDate() @IsDateString()
@IsNotEmpty() @IsNotEmpty()
@ApiProperty({ @ApiProperty({
description: 'The date of the sale receipt', description: 'The date of the sale receipt',
@@ -83,6 +89,7 @@ export class CommandSaleReceiptDto {
@IsOptional() @IsOptional()
@IsNumber() @IsNumber()
@ToNumber()
@ApiProperty({ @ApiProperty({
description: 'The id of the warehouse', description: 'The id of the warehouse',
example: 1, example: 1,
@@ -90,6 +97,7 @@ export class CommandSaleReceiptDto {
warehouseId?: number; warehouseId?: number;
@IsOptional() @IsOptional()
@ToNumber()
@IsNumber() @IsNumber()
@ApiProperty({ @ApiProperty({
description: 'The id of the branch', description: 'The id of the branch',
@@ -100,7 +108,7 @@ export class CommandSaleReceiptDto {
@IsArray() @IsArray()
@ValidateNested({ each: true }) @ValidateNested({ each: true })
@Type(() => SaleReceiptEntryDto) @Type(() => SaleReceiptEntryDto)
@Min(1) @ArrayMinSize(1)
@ApiProperty({ @ApiProperty({
description: 'The entries of the sale receipt', description: 'The entries of the sale receipt',
example: [{ key: '123456' }], example: [{ key: '123456' }],
@@ -134,6 +142,7 @@ export class CommandSaleReceiptDto {
attachments?: AttachmentDto[]; attachments?: AttachmentDto[];
@IsOptional() @IsOptional()
@ToNumber()
@IsNumber() @IsNumber()
@ApiProperty({ @ApiProperty({
description: 'The id of the pdf template', description: 'The id of the pdf template',
@@ -142,6 +151,7 @@ export class CommandSaleReceiptDto {
pdfTemplateId?: number; pdfTemplateId?: number;
@IsOptional() @IsOptional()
@ToNumber()
@IsNumber() @IsNumber()
@ApiProperty({ @ApiProperty({
description: 'The discount of the sale receipt', description: 'The discount of the sale receipt',
@@ -158,6 +168,7 @@ export class CommandSaleReceiptDto {
discountType?: DiscountType; discountType?: DiscountType;
@IsOptional() @IsOptional()
@ToNumber()
@IsNumber() @IsNumber()
@ApiProperty({ @ApiProperty({
description: 'The adjustment of the sale receipt', description: 'The adjustment of the sale receipt',

View File

@@ -1,3 +1,4 @@
import { ToNumber } from '@/common/decorators/Validators';
import { DiscountType } from '@/common/types/Discount'; import { DiscountType } from '@/common/types/Discount';
import { ApiProperty } from '@nestjs/swagger'; import { ApiProperty } from '@nestjs/swagger';
import { import {
@@ -12,30 +13,35 @@ import {
export class ItemEntryDto { export class ItemEntryDto {
@IsInt() @IsInt()
@IsOptional()
@ApiProperty({ @ApiProperty({
description: 'The index of the item entry', description: 'The index of the item entry',
example: 1, example: 1,
}) })
index: number; index: number;
@IsInt()
@IsNotEmpty() @IsNotEmpty()
@IsInt()
@ApiProperty({ @ApiProperty({
description: 'The id of the item', description: 'The id of the item',
example: 1, example: 1,
}) })
itemId: number; itemId: number;
@IsNumber() @IsOptional()
@IsNotEmpty() @IsNotEmpty()
@ToNumber()
@IsNumber()
@ApiProperty({ @ApiProperty({
description: 'The rate of the item entry', description: 'The rate of the item entry',
example: 1, example: 1,
}) })
rate: number; rate: number;
@IsNumber() @IsOptional()
@IsNotEmpty() @IsNotEmpty()
@ToNumber()
@IsNumber()
@ApiProperty({ @ApiProperty({
description: 'The quantity of the item entry', description: 'The quantity of the item entry',
example: 1, example: 1,
@@ -43,7 +49,9 @@ export class ItemEntryDto {
quantity: number; quantity: number;
@IsOptional() @IsOptional()
@IsNotEmpty()
@IsNumber() @IsNumber()
@ToNumber()
@ApiProperty({ @ApiProperty({
description: 'The discount of the item entry', description: 'The discount of the item entry',
example: 1, example: 1,
@@ -67,6 +75,7 @@ export class ItemEntryDto {
description?: string; description?: string;
@IsOptional() @IsOptional()
@IsNotEmpty()
@IsString() @IsString()
@ApiProperty({ @ApiProperty({
description: 'The tax code of the item entry', description: 'The tax code of the item entry',
@@ -75,6 +84,7 @@ export class ItemEntryDto {
taxCode?: string; taxCode?: string;
@IsOptional() @IsOptional()
@IsNotEmpty()
@IsInt() @IsInt()
@ApiProperty({ @ApiProperty({
description: 'The tax rate id of the item entry', description: 'The tax rate id of the item entry',
@@ -83,6 +93,7 @@ export class ItemEntryDto {
taxRateId?: number; taxRateId?: number;
@IsOptional() @IsOptional()
@IsNotEmpty()
@IsInt() @IsInt()
@ApiProperty({ @ApiProperty({
description: 'The warehouse id of the item entry', description: 'The warehouse id of the item entry',
@@ -91,6 +102,7 @@ export class ItemEntryDto {
warehouseId?: number; warehouseId?: number;
@IsOptional() @IsOptional()
@IsNotEmpty()
@IsInt() @IsInt()
@ApiProperty({ @ApiProperty({
description: 'The project id of the item entry', description: 'The project id of the item entry',
@@ -99,6 +111,7 @@ export class ItemEntryDto {
projectId?: number; projectId?: number;
@IsOptional() @IsOptional()
@IsNotEmpty()
@IsInt() @IsInt()
@ApiProperty({ @ApiProperty({
description: 'The project ref id of the item entry', description: 'The project ref id of the item entry',
@@ -107,6 +120,7 @@ export class ItemEntryDto {
projectRefId?: number; projectRefId?: number;
@IsOptional() @IsOptional()
@IsNotEmpty()
@IsString() @IsString()
@IsIn(['TASK', 'BILL', 'EXPENSE']) @IsIn(['TASK', 'BILL', 'EXPENSE'])
@ApiProperty({ @ApiProperty({
@@ -116,6 +130,7 @@ export class ItemEntryDto {
projectRefType?: string; projectRefType?: string;
@IsOptional() @IsOptional()
@IsNotEmpty()
@IsNumber() @IsNumber()
@ApiProperty({ @ApiProperty({
description: 'The project ref invoiced amount of the item entry', description: 'The project ref invoiced amount of the item entry',
@@ -124,6 +139,7 @@ export class ItemEntryDto {
projectRefInvoicedAmount?: number; projectRefInvoicedAmount?: number;
@IsOptional() @IsOptional()
@IsNotEmpty()
@IsInt() @IsInt()
@ApiProperty({ @ApiProperty({
description: 'The sell account id of the item entry', description: 'The sell account id of the item entry',
@@ -132,6 +148,7 @@ export class ItemEntryDto {
sellAccountId?: number; sellAccountId?: number;
@IsOptional() @IsOptional()
@IsNotEmpty()
@IsInt() @IsInt()
@ApiProperty({ @ApiProperty({
description: 'The cost account id of the item entry', description: 'The cost account id of the item entry',

View File

@@ -225,7 +225,7 @@ export function useBankRule(
() => () =>
apiRequest apiRequest
.get(`/banking/rules/${bankRuleId}`) .get(`/banking/rules/${bankRuleId}`)
.then((res) => res.data.bank_rule), .then((res) => res.data),
{ ...options }, { ...options },
); );
} }

View File

@@ -238,11 +238,11 @@ export function useDueInvoices(customerId, props) {
[t.SALE_INVOICES, t.SALE_INVOICES_DUE, customerId], [t.SALE_INVOICES, t.SALE_INVOICES_DUE, customerId],
{ {
method: 'get', method: 'get',
url: `sale-invoices/payable`, url: `sale-invoices/receivable`,
params: { customer_id: customerId }, params: { customer_id: customerId },
}, },
{ {
select: (res) => res.data.sales_invoices, select: (res) => res.data,
defaultData: [], defaultData: [],
...props, ...props,
}, },