refactor: dtos validation

This commit is contained in:
Ahmed Bouhuolia
2025-03-20 05:42:19 +02:00
parent fd65ee9428
commit 136cc907bb
105 changed files with 1641 additions and 366 deletions

View File

@@ -25,12 +25,12 @@ export class CreateAccountDTO {
@IsString()
@MinLength(3)
@MaxLength(255) // Assuming DATATYPES_LENGTH.STRING is 255
@MaxLength(255)
accountType: string;
@IsOptional()
@IsString()
@MaxLength(65535) // Assuming DATATYPES_LENGTH.TEXT is 65535
@MaxLength(65535)
description?: string;
@IsOptional()

View File

@@ -18,6 +18,13 @@ import { TenantModelProxy } from '../System/models/TenantBaseModel';
@Injectable()
export class CreateAccountService {
/**
* @param {TenantModelProxy<typeof Account>} accountModel - The account model proxy.
* @param {EventEmitter2} eventEmitter - The event emitter.
* @param {UnitOfWork} uow - The unit of work.
* @param {CommandAccountValidators} validator - The command account validators.
* @param {TenancyContext} tenancyContext - The tenancy context.
*/
constructor(
@Inject(Account.name)
private readonly accountModel: TenantModelProxy<typeof Account>,

View File

@@ -3,6 +3,7 @@ import { ConfigModule, ConfigService } from '@nestjs/config';
import { EventEmitterModule } from '@nestjs/event-emitter';
import { APP_GUARD, APP_INTERCEPTOR } from '@nestjs/core';
import { join } from 'path';
import { RedisModule } from '@liaoliaots/nestjs-redis';
import {
AcceptLanguageResolver,
CookieResolver,
@@ -71,7 +72,7 @@ import { StripePaymentModule } from '../StripePayment/StripePayment.module';
import { FeaturesModule } from '../Features/Features.module';
import { InventoryCostModule } from '../InventoryCost/InventoryCost.module';
import { WarehousesTransfersModule } from '../WarehousesTransfers/WarehouseTransfers.module';
import { RedisModule } from '@liaoliaots/nestjs-redis';
@Module({
imports: [

View File

@@ -0,0 +1,8 @@
import { IsNotEmpty, IsString } from "class-validator";
export class AttachmentLinkDto {
@IsString()
@IsNotEmpty()
key: string;
}

View File

@@ -12,6 +12,8 @@ import { BankRulesApplication } from './BankRulesApplication';
import { ICreateBankRuleDTO, IEditBankRuleDTO } from './types';
import { PublicRoute } from '../Auth/Jwt.guard';
import { BankRule } from './models/BankRule';
import { CreateBankRuleDto } from './dtos/BankRule.dto';
import { EditBankRuleDto } from './dtos/BankRule.dto';
@Controller('banking/rules')
@ApiTags('bank-rules')
@@ -22,7 +24,7 @@ export class BankRulesController {
@Post()
@ApiOperation({ summary: 'Create a new bank rule.' })
async createBankRule(
@Body() createRuleDTO: ICreateBankRuleDTO,
@Body() createRuleDTO: CreateBankRuleDto,
): Promise<BankRule> {
return this.bankRulesApplication.createBankRule(createRuleDTO);
}
@@ -31,7 +33,7 @@ export class BankRulesController {
@ApiOperation({ summary: 'Edit the given bank rule.' })
async editBankRule(
@Param('id') ruleId: number,
@Body() editRuleDTO: IEditBankRuleDTO,
@Body() editRuleDTO: EditBankRuleDto,
): Promise<void> {
return this.bankRulesApplication.editBankRule(ruleId, editRuleDTO);
}

View File

@@ -4,8 +4,8 @@ import { DeleteBankRuleService } from './commands/DeleteBankRule.service';
import { EditBankRuleService } from './commands/EditBankRule.service';
import { GetBankRuleService } from './queries/GetBankRule.service';
import { GetBankRulesService } from './queries/GetBankRules.service';
import { ICreateBankRuleDTO, IEditBankRuleDTO } from './types';
import { BankRule } from './models/BankRule';
import { CreateBankRuleDto, EditBankRuleDto } from './dtos/BankRule.dto';
@Injectable()
export class BankRulesApplication {
@@ -23,7 +23,7 @@ export class BankRulesApplication {
* @returns {Promise<void>}
*/
public createBankRule(
createRuleDTO: ICreateBankRuleDTO,
createRuleDTO: CreateBankRuleDto,
): Promise<BankRule> {
return this.createBankRuleService.createBankRule(createRuleDTO);
}
@@ -31,12 +31,12 @@ export class BankRulesApplication {
/**
* Edits the given bank rule.
* @param {number} ruleId - Bank rule identifier.
* @param {IEditBankRuleDTO} editRuleDTO - Bank rule data.
* @param {EditBankRuleDto} editRuleDTO - Bank rule data.
* @returns {Promise<void>}
*/
public editBankRule(
ruleId: number,
editRuleDTO: IEditBankRuleDTO,
editRuleDTO: EditBankRuleDto,
): Promise<void> {
return this.editBankRuleService.editBankRule(ruleId, editRuleDTO);
}

View File

@@ -1,3 +1,4 @@
import { ModelObject } from 'objection';
import { Knex } from 'knex';
import { Inject, Injectable } from '@nestjs/common';
import {
@@ -9,6 +10,7 @@ import { UnitOfWork } from '../../Tenancy/TenancyDB/UnitOfWork.service';
import { EventEmitter2 } from '@nestjs/event-emitter';
import { events } from '@/common/events/events';
import { BankRule } from '../models/BankRule';
import { CreateBankRuleDto } from '../dtos/BankRule.dto';
@Injectable()
export class CreateBankRuleService {
@@ -23,10 +25,10 @@ export class CreateBankRuleService {
* Transforms the DTO to model.
* @param {ICreateBankRuleDTO} createDTO
*/
private transformDTO(createDTO: ICreateBankRuleDTO) {
private transformDTO(createDTO: CreateBankRuleDto): ModelObject<BankRule> {
return {
...createDTO,
};
} as ModelObject<BankRule>;
}
/**
@@ -35,7 +37,7 @@ export class CreateBankRuleService {
* @returns {Promise<BankRule>}
*/
public async createBankRule(
createRuleDTO: ICreateBankRuleDTO,
createRuleDTO: CreateBankRuleDto,
): Promise<BankRule> {
const transformDTO = this.transformDTO(createRuleDTO);

View File

@@ -9,6 +9,8 @@ import { EventEmitter2 } from '@nestjs/event-emitter';
import { UnitOfWork } from '@/modules/Tenancy/TenancyDB/UnitOfWork.service';
import { events } from '@/common/events/events';
import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel';
import { EditBankRuleDto } from '../dtos/BankRule.dto';
import { ModelObject } from 'objection';
@Injectable()
export class EditBankRuleService {
@@ -25,10 +27,10 @@ export class EditBankRuleService {
* @param createDTO
* @returns
*/
private transformDTO(createDTO: IEditBankRuleDTO) {
private transformDTO(createDTO: EditBankRuleDto): ModelObject<BankRule> {
return {
...createDTO,
};
} as ModelObject<BankRule>;
}
/**
@@ -36,7 +38,7 @@ export class EditBankRuleService {
* @param {number} ruleId -
* @param {IEditBankRuleDTO} editBankDTO
*/
public async editBankRule(ruleId: number, editRuleDTO: IEditBankRuleDTO) {
public async editBankRule(ruleId: number, editRuleDTO: EditBankRuleDto) {
const oldBankRule = await this.bankRuleModel()
.query()
.findById(ruleId)

View File

@@ -0,0 +1,81 @@
import { Type } from 'class-transformer';
import {
IsString,
IsInt,
Min,
IsOptional,
IsIn,
IsArray,
ValidateNested,
ArrayMinSize,
IsNotEmpty,
} from 'class-validator';
import { BankRuleComparator } from '../types';
class BankRuleConditionDto {
@IsNotEmpty()
@IsIn(['description', 'amount'])
field: string;
@IsNotEmpty()
@IsIn([
'equals',
'equal',
'contains',
'not_contain',
'bigger',
'bigger_or_equal',
'smaller',
'smaller_or_equal',
])
comparator: BankRuleComparator = 'contains';
@IsNotEmpty()
value: string;
}
export class CommandBankRuleDto {
@IsString()
@IsNotEmpty()
name: string;
@IsInt()
@Min(0)
order: number;
@IsOptional()
@IsInt()
@Min(0)
applyIfAccountId?: number;
@IsIn(['deposit', 'withdrawal'])
applyIfTransactionType: 'deposit' | 'withdrawal';
@IsString()
@IsIn(['and', 'or'])
conditionsType: 'and' | 'or' = 'and';
@IsArray()
@ArrayMinSize(1)
@ValidateNested({ each: true })
@Type(() => BankRuleConditionDto)
conditions: BankRuleConditionDto[];
@IsString()
assignCategory: string;
@IsInt()
@Min(0)
assignAccountId: number;
@IsOptional()
@IsString()
assignPayee?: string;
@IsOptional()
@IsString()
assignMemo?: string;
}
export class CreateBankRuleDto extends CommandBankRuleDto {}
export class EditBankRuleDto extends CommandBankRuleDto {}

View File

@@ -4,18 +4,18 @@ import { BankRuleCondition } from './BankRuleCondition';
import { BankRuleAssignCategory, BankRuleConditionType } from '../types';
export class BankRule extends BaseModel {
public id!: number;
public name!: string;
public order!: number;
public applyIfAccountId!: number;
public applyIfTransactionType!: string;
public assignCategory!: BankRuleAssignCategory;
public assignAccountId!: number;
public assignPayee!: string;
public assignMemo!: string;
public conditionsType!: BankRuleConditionType;
public readonly id!: number;
public readonly name!: string;
public readonly order!: number;
public readonly applyIfAccountId!: number;
public readonly applyIfTransactionType!: string;
public readonly assignCategory!: BankRuleAssignCategory;
public readonly assignAccountId!: number;
public readonly assignPayee!: string;
public readonly assignMemo!: string;
public readonly conditionsType!: BankRuleConditionType;
conditions!: BankRuleCondition[];
public readonly conditions!: BankRuleCondition[];
/**
* Table name
@@ -27,7 +27,7 @@ export class BankRule extends BaseModel {
/**
* Timestamps columns.
*/
get timestamps() {
static get timestamps() {
return ['created_at', 'updated_at'];
}

View File

@@ -1,5 +1,6 @@
import { Knex } from 'knex';
import { BankRule } from './models/BankRule';
import { CreateBankRuleDto, EditBankRuleDto } from './dtos/BankRule.dto';
export enum BankRuleConditionField {
Amount = 'amount',
@@ -94,11 +95,11 @@ export interface ICreateBankRuleDTO extends IBankRuleCommonDTO {}
export interface IEditBankRuleDTO extends IBankRuleCommonDTO {}
export interface IBankRuleEventCreatingPayload {
createRuleDTO: ICreateBankRuleDTO;
createRuleDTO: CreateBankRuleDto;
trx?: Knex.Transaction;
}
export interface IBankRuleEventCreatedPayload {
createRuleDTO: ICreateBankRuleDTO;
createRuleDTO: CreateBankRuleDto;
bankRule: BankRule;
trx?: Knex.Transaction;
}
@@ -106,13 +107,13 @@ export interface IBankRuleEventCreatedPayload {
export interface IBankRuleEventEditingPayload {
ruleId: number;
oldBankRule: any;
editRuleDTO: IEditBankRuleDTO;
editRuleDTO: EditBankRuleDto;
trx?: Knex.Transaction;
}
export interface IBankRuleEventEditedPayload {
oldBankRule: BankRule;
bankRule: BankRule;
editRuleDTO: IEditBankRuleDTO;
editRuleDTO: EditBankRuleDto;
trx?: Knex.Transaction;
}

View File

@@ -1,7 +1,8 @@
import { ApiOperation, ApiTags } from '@nestjs/swagger';
import { Body, Controller, Get, Param, Post, Query } from '@nestjs/common';
import { BankingMatchingApplication } from './BankingMatchingApplication';
import { GetMatchedTransactionsFilter, IMatchTransactionDTO } from './types';
import { ApiOperation, ApiTags } from '@nestjs/swagger';
import { MatchBankTransactionDto } from './dtos/MatchBankTransaction.dto';
@Controller('banking/matching')
@ApiTags('banking-transactions-matching')
@@ -26,7 +27,7 @@ export class BankingMatchingController {
@ApiOperation({ summary: 'Match the given uncategorized transaction.' })
async matchTransaction(
@Param('uncategorizedTransactionId') uncategorizedTransactionId: number | number[],
@Body() matchedTransactions: IMatchTransactionDTO[]
@Body() matchedTransactions: MatchBankTransactionDto
) {
return this.bankingMatchingApplication.matchTransaction(
uncategorizedTransactionId,

View File

@@ -3,13 +3,14 @@ import { GetMatchedTransactions } from './queries/GetMatchedTransactions.service
import { MatchBankTransactions } from './commands/MatchTransactions';
import { UnmatchMatchedBankTransaction } from './commands/UnmatchMatchedTransaction.service';
import { GetMatchedTransactionsFilter, IMatchTransactionDTO } from './types';
import { MatchBankTransactionDto } from './dtos/MatchBankTransaction.dto';
@Injectable()
export class BankingMatchingApplication {
constructor(
private readonly getMatchedTransactionsService: GetMatchedTransactions,
private readonly matchTransactionService: MatchBankTransactions,
private readonly unmatchMatchedTransactionService: UnmatchMatchedBankTransaction
private readonly unmatchMatchedTransactionService: UnmatchMatchedBankTransaction,
) {}
/**
@@ -20,11 +21,11 @@ export class BankingMatchingApplication {
*/
public getMatchedTransactions(
uncategorizedTransactionsIds: Array<number>,
filter: GetMatchedTransactionsFilter
filter: GetMatchedTransactionsFilter,
) {
return this.getMatchedTransactionsService.getMatchedTransactions(
uncategorizedTransactionsIds,
filter
filter,
);
}
@@ -36,11 +37,11 @@ export class BankingMatchingApplication {
*/
public matchTransaction(
uncategorizedTransactionId: number | Array<number>,
matchedTransactions: Array<IMatchTransactionDTO>
matchedTransactions: MatchBankTransactionDto,
): Promise<void> {
return this.matchTransactionService.matchTransaction(
uncategorizedTransactionId,
matchedTransactions
matchedTransactions,
);
}
@@ -49,11 +50,9 @@ export class BankingMatchingApplication {
* @param {number} uncategorizedTransactionId - Uncategorized transaction id.
* @returns {Promise<void>}
*/
public unmatchMatchedTransaction(
uncategorizedTransactionId: number
) {
public unmatchMatchedTransaction(uncategorizedTransactionId: number) {
return this.unmatchMatchedTransactionService.unmatchMatchedTransaction(
uncategorizedTransactionId
uncategorizedTransactionId,
);
}
}

View File

@@ -21,6 +21,7 @@ import { ServiceError } from '@/modules/Items/ServiceError';
import { UncategorizedBankTransaction } from '@/modules/BankingTransactions/models/UncategorizedBankTransaction';
import { events } from '@/common/events/events';
import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel';
import { MatchBankTransactionDto } from '../dtos/MatchBankTransaction.dto';
@Injectable()
export class MatchBankTransactions {
@@ -112,9 +113,10 @@ export class MatchBankTransactions {
*/
public async matchTransaction(
uncategorizedTransactionId: number | Array<number>,
matchedTransactions: Array<IMatchTransactionDTO>,
matchedTransactionsDto: MatchBankTransactionDto,
): Promise<void> {
const uncategorizedTransactionIds = castArray(uncategorizedTransactionId);
const matchedTransactions = matchedTransactionsDto.entries;
// Validates the given matching transactions DTO.
await this.validate(uncategorizedTransactionIds, matchedTransactions);

View File

@@ -0,0 +1,25 @@
import {
IsArray,
IsNotEmpty,
IsNumber,
IsString,
ValidateNested,
} from 'class-validator';
import { Type } from 'class-transformer';
export class MatchTransactionEntryDto {
@IsString()
@IsNotEmpty()
referenceType: string;
@IsNumber()
@IsNotEmpty()
referenceId: number;
}
export class MatchBankTransactionDto {
@IsArray()
@ValidateNested({ each: true })
@Type(() => MatchTransactionEntryDto)
entries: MatchTransactionEntryDto[];
}

View File

@@ -10,10 +10,10 @@ import {
import { GetMatchedTransactionsByType } from './GetMatchedTransactionsByType';
import { CreateBillPaymentService } from '@/modules/BillPayments/commands/CreateBillPayment.service';
import { TransformerInjectable } from '@/modules/Transformer/TransformerInjectable.service';
import { IBillPaymentDTO } from '@/modules/BillPayments/types/BillPayments.types';
import { Bill } from '@/modules/Bills/models/Bill';
import { UncategorizedBankTransaction } from '@/modules/BankingTransactions/models/UncategorizedBankTransaction';
import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel';
import { CreateBillPaymentDto } from '@/modules/BillPayments/dtos/BillPayment.dto';
@Injectable()
export class GetMatchedTransactionsByBills extends GetMatchedTransactionsByType {
@@ -110,7 +110,7 @@ export class GetMatchedTransactionsByBills extends GetMatchedTransactionsByType
.findById(matchTransactionDTO.referenceId)
.throwIfNotFound();
const createPaymentMadeDTO: IBillPaymentDTO = {
const createPaymentMadeDTO: CreateBillPaymentDto = {
vendorId: bill.vendorId,
paymentAccountId: uncategorizedTransaction.accountId,
paymentDate: uncategorizedTransaction.date,

View File

@@ -14,6 +14,7 @@ import {
} from './types/BankingTransactions.types';
import { PublicRoute } from '../Auth/Jwt.guard';
import { ApiTags } from '@nestjs/swagger';
import { CreateBankTransactionDto } from './dtos/CreateBankTransaction.dto';
@Controller('banking/transactions')
@ApiTags('banking-transactions')
@@ -29,7 +30,7 @@ export class BankingTransactionsController {
}
@Post()
async createTransaction(@Body() transactionDTO: ICashflowNewCommandDTO) {
async createTransaction(@Body() transactionDTO: CreateBankTransactionDto) {
return this.bankingTransactionsApplication.createTransaction(
transactionDTO,
);

View File

@@ -1,10 +1,12 @@
import { Knex } from 'knex';
import { Injectable } from '@nestjs/common';
import { DeleteCashflowTransaction } from './commands/DeleteCashflowTransaction.service';
import { CreateBankTransactionService } from './commands/CreateBankTransaction.service';
import { GetBankTransactionService } from './queries/GetBankTransaction.service';
import { IBankAccountsFilter, ICashflowNewCommandDTO } from './types/BankingTransactions.types';
import { Injectable } from '@nestjs/common';
import {
IBankAccountsFilter,
} from './types/BankingTransactions.types';
import { GetBankAccountsService } from './queries/GetBankAccounts.service';
import { CreateBankTransactionDto } from './dtos/CreateBankTransaction.dto';
@Injectable()
export class BankingTransactionsApplication {
@@ -20,7 +22,7 @@ export class BankingTransactionsApplication {
* @param {ICashflowNewCommandDTO} transactionDTO
* @returns
*/
public createTransaction(transactionDTO: ICashflowNewCommandDTO) {
public createTransaction(transactionDTO: CreateBankTransactionDto) {
return this.createTransactionService.newCashflowTransaction(transactionDTO);
}

View File

@@ -18,6 +18,7 @@ import {
ICommandCashflowCreatingPayload,
} from '../types/BankingTransactions.types';
import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel';
import { CreateBankTransactionDto } from '../dtos/CreateBankTransaction.dto';
@Injectable()
export class CreateBankTransactionService {
@@ -62,7 +63,7 @@ export class CreateBankTransactionService {
* @returns {ICashflowTransactionInput} - Cashflow transaction object.
*/
private transformCashflowTransactionDTO = async (
newCashflowTransactionDTO: ICashflowNewCommandDTO,
newCashflowTransactionDTO: CreateBankTransactionDto,
cashflowAccount: Account,
userId: number,
): Promise<BankTransaction> => {

View File

@@ -0,0 +1,58 @@
import {
IsBoolean,
IsDate,
IsNumber,
IsOptional,
IsString,
} from 'class-validator';
export class CreateBankTransactionDto {
@IsDate()
date: Date;
@IsString()
transactionNumber: string;
@IsString()
referenceNo: string;
@IsString()
transactionType: string;
@IsString()
description: string;
@IsNumber()
amount: number;
@IsNumber()
exchangeRate: number;
@IsString()
currencyCode: string;
@IsNumber()
creditAccountId: number;
@IsNumber()
cashflowAccountId: number;
@IsBoolean()
publish: boolean;
@IsOptional()
@IsNumber()
branchId?: number;
@IsOptional()
@IsString()
plaidTransactionId?: string;
@IsOptional()
@IsString()
plaidAccountId?: string;
@IsOptional()
@IsNumber()
uncategorizedTransactionId?: number;
}

View File

@@ -1,6 +1,7 @@
import { Knex } from 'knex';
import { UncategorizedBankTransaction } from '../models/UncategorizedBankTransaction';
import { BankTransaction } from '../models/BankTransaction';
import { CreateBankTransactionDto } from '../dtos/CreateBankTransaction.dto';
export interface IPendingTransactionRemovingEventPayload {
uncategorizedTransactionId: number;
@@ -67,7 +68,7 @@ export interface ICommandCashflowCreatingPayload {
}
export interface ICommandCashflowCreatedPayload {
newTransactionDTO: ICashflowNewCommandDTO;
newTransactionDTO: CreateBankTransactionDto;
cashflowTransaction: BankTransaction;
trx: Knex.Transaction;
}

View File

@@ -8,8 +8,11 @@ import {
Put,
} from '@nestjs/common';
import { BillPaymentsApplication } from './BillPaymentsApplication.service';
import { IBillPaymentDTO } from './types/BillPayments.types';
import { ApiOperation, ApiParam, ApiTags } from '@nestjs/swagger';
import {
CreateBillPaymentDto,
EditBillPaymentDto,
} from './dtos/BillPayment.dto';
@Controller('bill-payments')
@ApiTags('bill-payments')
@@ -18,7 +21,7 @@ export class BillPaymentsController {
@Post()
@ApiOperation({ summary: 'Create a new bill payment.' })
public createBillPayment(@Body() billPaymentDTO: IBillPaymentDTO) {
public createBillPayment(@Body() billPaymentDTO: CreateBillPaymentDto) {
return this.billPaymentsApplication.createBillPayment(billPaymentDTO);
}
@@ -46,7 +49,7 @@ export class BillPaymentsController {
})
public editBillPayment(
@Param('billPaymentId') billPaymentId: string,
@Body() billPaymentDTO: IBillPaymentDTO,
@Body() billPaymentDTO: EditBillPaymentDto,
) {
return this.billPaymentsApplication.editBillPayment(
Number(billPaymentId),

View File

@@ -5,8 +5,8 @@ import { EditBillPayment } from './commands/EditBillPayment.service';
// import { GetBillPayments } from './GetBillPayments';
import { GetBillPayment } from './queries/GetBillPayment.service';
import { GetPaymentBills } from './queries/GetPaymentBills.service';
import { IBillPaymentDTO } from './types/BillPayments.types';
import { GetBillPayments } from '../Bills/queries/GetBillPayments';
import { CreateBillPaymentDto, EditBillPaymentDto } from './dtos/BillPayment.dto';
/**
* Bill payments application.
@@ -28,7 +28,7 @@ export class BillPaymentsApplication {
* @param {IBillPaymentDTO} billPaymentDTO
* @returns {Promise<IBillPayment>}
*/
public createBillPayment(billPaymentDTO: IBillPaymentDTO) {
public createBillPayment(billPaymentDTO: CreateBillPaymentDto) {
return this.createBillPaymentService.createBillPayment(billPaymentDTO);
}
@@ -48,7 +48,7 @@ export class BillPaymentsApplication {
*/
public editBillPayment(
billPaymentId: number,
billPaymentDTO: IBillPaymentDTO,
billPaymentDTO: EditBillPaymentDto,
) {
return this.editBillPaymentService.editBillPayment(
billPaymentId,

View File

@@ -1,10 +1,11 @@
import { Inject, Injectable } from '@nestjs/common';
import { Knex } from 'knex';
import { Bill } from '../../Bills/models/Bill';
import { IBillPaymentEntryDTO } from '../types/BillPayments.types';
import { entriesAmountDiff } from '@/utils/entries-amount-diff';
import Objection from 'objection';
import Objection, { ModelObject } from 'objection';
import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel';
import { BillPaymentEntryDto } from '../dtos/BillPayment.dto';
import { BillPaymentEntry } from '../models/BillPaymentEntry';
@Injectable()
export class BillPaymentBillSync {
@@ -20,8 +21,8 @@ export class BillPaymentBillSync {
* @param {IBillPaymentEntryDTO[]} oldPaymentMadeEntries -
*/
public async saveChangeBillsPaymentAmount(
paymentMadeEntries: IBillPaymentEntryDTO[],
oldPaymentMadeEntries?: IBillPaymentEntryDTO[],
paymentMadeEntries: BillPaymentEntryDto[],
oldPaymentMadeEntries?: ModelObject<BillPaymentEntry>[],
trx?: Knex.Transaction,
): Promise<void> {
const opers: Objection.QueryBuilder<Bill, Bill[]>[] = [];

View File

@@ -1,9 +1,5 @@
import { Inject, Injectable } from '@nestjs/common';
import { sumBy, difference } from 'lodash';
import {
IBillPaymentDTO,
IBillPaymentEntryDTO,
} from '../types/BillPayments.types';
import { ERRORS } from '../constants';
import { Bill } from '../../Bills/models/Bill';
import { BillPayment } from '../models/BillPayment';
@@ -12,6 +8,10 @@ import { ServiceError } from '../../Items/ServiceError';
import { ACCOUNT_TYPE } from '@/constants/accounts';
import { Account } from '../../Accounts/models/Account.model';
import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel';
import {
BillPaymentEntryDto,
EditBillPaymentDto,
} from '../dtos/BillPayment.dto';
@Injectable()
export class BillPaymentValidators {
@@ -141,11 +141,11 @@ export class BillPaymentValidators {
* @return {void}
*/
public async validateBillsDueAmount(
billPaymentEntries: IBillPaymentEntryDTO[],
billPaymentEntries: BillPaymentEntryDto[],
oldPaymentEntries: BillPaymentEntry[] = [],
) {
const billsIds = billPaymentEntries.map(
(entry: IBillPaymentEntryDTO) => entry.billId,
(entry: BillPaymentEntryDto) => entry.billId,
);
const storedBills = await this.billModel().query().whereIn('id', billsIds);
@@ -168,7 +168,7 @@ export class BillPaymentValidators {
}
const hasWrongPaymentAmount: invalidPaymentAmountError[] = [];
billPaymentEntries.forEach((entry: IBillPaymentEntryDTO, index: number) => {
billPaymentEntries.forEach((entry: BillPaymentEntryDto, index: number) => {
const entryBill = storedBillsMap.get(entry.billId);
const { dueAmount } = entryBill;
@@ -212,7 +212,7 @@ export class BillPaymentValidators {
* @param {string} billPaymentNo
*/
public validateVendorNotModified(
billPaymentDTO: IBillPaymentDTO,
billPaymentDTO: EditBillPaymentDto,
oldBillPayment: BillPayment,
) {
if (billPaymentDTO.vendorId !== oldBillPayment.vendorId) {

View File

@@ -2,11 +2,14 @@ import { Injectable } from '@nestjs/common';
import * as R from 'ramda';
import { omit, sumBy } from 'lodash';
import { formatDateFields } from '@/utils/format-date-fields';
import { IBillPaymentDTO } from '../types/BillPayments.types';
import { assocItemEntriesDefaultIndex } from '@/utils/associate-item-entries-index';
import { BranchTransactionDTOTransformer } from '@/modules/Branches/integrations/BranchTransactionDTOTransform';
import { Vendor } from '@/modules/Vendors/models/Vendor';
import { BillPayment } from '../models/BillPayment';
import {
CreateBillPaymentDto,
EditBillPaymentDto,
} from '../dtos/BillPayment.dto';
@Injectable()
export class CommandBillPaymentDTOTransformer {
@@ -22,7 +25,7 @@ export class CommandBillPaymentDTOTransformer {
* @return {Promise<IBillPayment>}
*/
public async transformDTOToModel(
billPaymentDTO: IBillPaymentDTO,
billPaymentDTO: CreateBillPaymentDto | EditBillPaymentDto,
vendor: Vendor,
oldBillPayment?: BillPayment,
): Promise<BillPayment> {

View File

@@ -1,6 +1,5 @@
import { Knex } from 'knex';
import {
IBillPaymentDTO,
IBillPaymentEventCreatedPayload,
IBillPaymentCreatingPayload,
} from '../types/BillPayments.types';
@@ -14,6 +13,7 @@ import { TenancyContext } from '../../Tenancy/TenancyContext.service';
import { BillPayment } from '../models/BillPayment';
import { Vendor } from '../../Vendors/models/Vendor';
import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel';
import { CreateBillPaymentDto } from '../dtos/BillPayment.dto';
@Injectable()
export class CreateBillPaymentService {
@@ -56,7 +56,7 @@ export class CreateBillPaymentService {
* @param {BillPaymentDTO} billPayment - Bill payment object.
*/
public async createBillPayment(
billPaymentDTO: IBillPaymentDTO,
billPaymentDTO: CreateBillPaymentDto,
trx?: Knex.Transaction,
): Promise<BillPayment> {
const tenantMeta = await this.tenancyContext.getTenant(true);

View File

@@ -13,6 +13,7 @@ import { Vendor } from '@/modules/Vendors/models/Vendor';
import { events } from '@/common/events/events';
import { TenancyContext } from '@/modules/Tenancy/TenancyContext.service';
import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel';
import { EditBillPaymentDto } from '../dtos/BillPayment.dto';
@Injectable()
export class EditBillPayment {
@@ -43,14 +44,13 @@ export class EditBillPayment {
* - Update the diff vendor balance.
* - Update the diff bill payment amount.
* ------
* @param {number} tenantId - Tenant id
* @param {Integer} billPaymentId
* @param {BillPaymentDTO} billPayment
* @param {IBillPayment} oldBillPayment
* @param {EditBillPaymentDto} billPayment
* @param {BillPayment} oldBillPayment
*/
public async editBillPayment(
billPaymentId: number,
billPaymentDTO,
billPaymentDTO: EditBillPaymentDto,
): Promise<BillPayment> {
const tenantMeta = await this.tenancyContext.getTenant(true);

View File

@@ -0,0 +1,68 @@
import { Type } from 'class-transformer';
import {
IsArray,
IsDate,
IsNumber,
IsOptional,
IsString,
ValidateNested,
} from 'class-validator';
import { AttachmentLinkDto } from '@/modules/Attachments/dtos/Attachment.dto';
export class BillPaymentEntryDto {
@IsNumber()
billId: number;
@IsNumber()
paymentAmount: number;
}
export class CommandBillPaymentDTO {
@IsNumber()
vendorId: number;
@IsNumber()
@IsOptional()
amount?: number;
@IsNumber()
paymentAccountId: number;
@IsString()
@IsOptional()
paymentNumber?: string;
@IsDate()
@Type(() => Date)
paymentDate: Date | string;
@IsNumber()
@IsOptional()
exchangeRate?: number;
@IsString()
@IsOptional()
statement?: string;
@IsString()
@IsOptional()
reference?: string;
@IsArray()
@ValidateNested({ each: true })
@Type(() => BillPaymentEntryDto)
entries: BillPaymentEntryDto[];
@IsNumber()
@IsOptional()
branchId?: number;
@IsArray()
@IsOptional()
@ValidateNested({ each: true })
@Type(() => AttachmentLinkDto)
attachments?: AttachmentLinkDto[];
}
export class CreateBillPaymentDto extends CommandBillPaymentDTO {}
export class EditBillPaymentDto extends CommandBillPaymentDTO {}

View File

@@ -1,25 +1,7 @@
import { Knex } from 'knex';
import { BillPayment } from '../models/BillPayment';
import { AttachmentLinkDTO } from '@/modules/Attachments/Attachments.types';
export interface IBillPaymentEntryDTO {
billId: number;
paymentAmount: number;
}
export interface IBillPaymentDTO {
vendorId: number;
amount?: number;
paymentAccountId: number;
paymentNumber?: string;
paymentDate: Date | string;
exchangeRate?: number;
statement?: string;
reference?: string;
entries: IBillPaymentEntryDTO[];
branchId?: number;
attachments?: AttachmentLinkDTO[];
}
import { CreateBillPaymentDto, EditBillPaymentDto } from '../dtos/BillPayment.dto';
export interface IBillReceivePageEntry {
billId: number;
@@ -35,18 +17,18 @@ export interface IBillReceivePageEntry {
export interface IBillPaymentEventCreatedPayload {
billPayment: BillPayment;
billPaymentDTO: IBillPaymentDTO;
billPaymentDTO: CreateBillPaymentDto;
billPaymentId: number;
trx: Knex.Transaction;
}
export interface IBillPaymentCreatingPayload {
billPaymentDTO: IBillPaymentDTO;
billPaymentDTO: CreateBillPaymentDto;
trx: Knex.Transaction;
}
export interface IBillPaymentEditingPayload {
billPaymentDTO: IBillPaymentDTO;
billPaymentDTO: EditBillPaymentDto;
oldBillPayment: BillPayment;
trx: Knex.Transaction;
}
@@ -54,7 +36,7 @@ export interface IBillPaymentEventEditedPayload {
billPaymentId: number;
billPayment: BillPayment;
oldBillPayment: BillPayment;
billPaymentDTO: IBillPaymentDTO;
billPaymentDTO: EditBillPaymentDto;
trx: Knex.Transaction;
}

View File

@@ -7,6 +7,7 @@ import { GetDueBills } from './queries/GetDueBills.service';
import { OpenBillService } from './commands/OpenBill.service';
import { Injectable } from '@nestjs/common';
import { GetBillsService } from './queries/GetBills.service';
import { CreateBillDto, EditBillDto } from './dtos/Bill.dto';
// import { GetBillPayments } from './queries/GetBillPayments';
// import { GetBills } from './queries/GetBills';
@@ -28,7 +29,7 @@ export class BillsApplication {
* @param {IBillDTO} billDTO
* @returns
*/
public createBill(billDTO: IBillDTO) {
public createBill(billDTO: CreateBillDto) {
return this.createBillService.createBill(billDTO);
}
@@ -38,7 +39,7 @@ export class BillsApplication {
* @param {IBillEditDTO} billDTO
* @returns
*/
public editBill(billId: number, billDTO: IBillEditDTO) {
public editBill(billId: number, billDTO: EditBillDto) {
return this.editBillService.editBill(billId, billDTO);
}

View File

@@ -10,8 +10,9 @@ import {
Query,
} from '@nestjs/common';
import { BillsApplication } from './Bills.application';
import { IBillDTO, IBillEditDTO, IBillsFilter } from './Bills.types';
import { IBillsFilter } from './Bills.types';
import { PublicRoute } from '../Auth/Jwt.guard';
import { CreateBillDto, EditBillDto } from './dtos/Bill.dto';
@Controller('bills')
@ApiTags('bills')
@@ -21,7 +22,7 @@ export class BillsController {
@Post()
@ApiOperation({ summary: 'Create a new bill.' })
createBill(@Body() billDTO: IBillDTO) {
createBill(@Body() billDTO: CreateBillDto) {
return this.billsApplication.createBill(billDTO);
}
@@ -33,7 +34,7 @@ export class BillsController {
type: Number,
description: 'The bill id',
})
editBill(@Param('id') billId: number, @Body() billDTO: IBillEditDTO) {
editBill(@Param('id') billId: number, @Body() billDTO: EditBillDto) {
return this.billsApplication.editBill(billId, billDTO);
}

View File

@@ -3,6 +3,7 @@ import { IItemEntryDTO } from '../TransactionItemEntry/ItemEntry.types';
import { AttachmentLinkDTO } from '../Attachments/Attachments.types';
import { Bill } from './models/Bill';
import { IDynamicListFilter } from '../DynamicListing/DynamicFilter/DynamicFilter.types';
import { CreateBillDto, EditBillDto } from './dtos/Bill.dto';
export interface IBillDTO {
vendorId: number;
@@ -51,29 +52,25 @@ export interface IBillsFilter extends IDynamicListFilter {
}
export interface IBillCreatedPayload {
// tenantId: number;
bill: Bill;
billDTO: IBillDTO;
// billId: number;
billDTO: CreateBillDto;
trx?: Knex.Transaction;
}
export interface IBillCreatingPayload {
// tenantId: number;
billDTO: IBillDTO;
billDTO: CreateBillDto;
trx: Knex.Transaction;
}
export interface IBillEditingPayload {
// tenantId: number;
oldBill: Bill;
billDTO: IBillEditDTO;
billDTO: EditBillDto;
trx: Knex.Transaction;
}
export interface IBillEditedPayload {
oldBill: Bill;
bill: Bill;
billDTO: IBillDTO;
billDTO: EditBillDto;
trx?: Knex.Transaction;
}

View File

@@ -15,6 +15,7 @@ import { Bill } from '../models/Bill';
import { assocItemEntriesDefaultIndex } from '@/utils/associate-item-entries-index';
import { TenancyContext } from '@/modules/Tenancy/TenancyContext.service';
import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel';
import { CreateBillDto } from '../dtos/Bill.dto';
@Injectable()
export class BillDTOTransformer {
@@ -40,10 +41,10 @@ export class BillDTOTransformer {
/**
* Retrieve the bill landed cost amount.
* @param {IBillDTO} billDTO
* @param {CreateBillDto} billDTO
* @returns {number}
*/
private getBillLandedCostAmount(billDTO: IBillDTO): number {
private getBillLandedCostAmount(billDTO: CreateBillDto): number {
const costEntries = billDTO.entries.filter((entry) => entry.landedCost);
// return this.getBillEntriesTotal(costEntries);
@@ -58,7 +59,7 @@ export class BillDTOTransformer {
* @returns {IBill}
*/
public async billDTOToModel(
billDTO: IBillDTO,
billDTO: CreateBillDto,
vendor: Vendor,
oldBill?: Bill,
): Promise<Bill> {

View File

@@ -9,6 +9,8 @@ import { BillLandedCost } from '@/modules/BillLandedCosts/models/BillLandedCost'
import { VendorCreditAppliedBill } from '@/modules/VendorCreditsApplyBills/models/VendorCreditAppliedBill';
import { transformToMap } from '@/utils/transform-to-key';
import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel';
import { ItemEntryDto } from '@/modules/TransactionItemEntry/dto/ItemEntry.dto';
import { BillEntryDto } from '../dtos/Bill.dto';
@Injectable()
export class BillsValidators {
@@ -123,7 +125,7 @@ export class BillsValidators {
* @param {IItemEntryDTO[]} newEntriesDTO -
*/
public async validateCostEntriesShouldBeInventoryItems(
newEntriesDTO: IItemEntryDTO[],
newEntriesDTO: BillEntryDto[],
) {
const entriesItemsIds = newEntriesDTO.map((e) => e.itemId);
const entriesItems = await this.itemModel()

View File

@@ -14,6 +14,7 @@ import { Bill } from '../models/Bill';
import { Vendor } from '@/modules/Vendors/models/Vendor';
import { events } from '@/common/events/events';
import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel';
import { CreateBillDto } from '../dtos/Bill.dto';
@Injectable()
export class CreateBill {
@@ -46,7 +47,7 @@ export class CreateBill {
* @return {Promise<IBill>}
*/
public async createBill(
billDTO: IBillDTO,
billDTO: CreateBillDto,
trx?: Knex.Transaction,
): Promise<Bill> {
// Retrieves the given bill vendor or throw not found error.

View File

@@ -15,6 +15,7 @@ import { Vendor } from '@/modules/Vendors/models/Vendor';
import { Knex } from 'knex';
import { TransactionLandedCostEntriesService } from '@/modules/BillLandedCosts/TransactionLandedCostEntries.service';
import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel';
import { EditBillDto } from '../dtos/Bill.dto';
@Injectable()
export class EditBillService {
@@ -46,7 +47,7 @@ export class EditBillService {
* @param {IBillEditDTO} billDTO - The given new bill details.
* @return {Promise<IBill>}
*/
public async editBill(billId: number, billDTO: IBillEditDTO): Promise<Bill> {
public async editBill(billId: number, billDTO: EditBillDto): Promise<Bill> {
// Retrieve the given bill or throw not found error.
const oldBill = await this.billModel()
.query()

View File

@@ -0,0 +1,106 @@
import { ItemEntryDto } from '@/modules/TransactionItemEntry/dto/ItemEntry.dto';
import { Type } from 'class-transformer';
import {
IsArray,
IsBoolean,
IsDate,
IsEnum,
IsInt,
IsNumber,
IsOptional,
IsPositive,
IsString,
Min,
MinLength,
ValidateNested,
} from 'class-validator';
enum DiscountType {
Percentage = 'percentage',
Amount = 'amount',
}
export class BillEntryDto extends ItemEntryDto {
@IsOptional()
@IsBoolean()
landedCost?: boolean;
}
class AttachmentDto {
@IsString()
key: string;
}
export class CommandBillDto {
@IsString()
billNumber: string;
@IsOptional()
@IsString()
referenceNo?: string;
@IsDate()
@Type(() => Date)
billDate: Date;
@IsOptional()
@IsDate()
@Type(() => Date)
dueDate?: Date;
@IsInt()
vendorId: number;
@IsOptional()
@IsNumber()
@IsPositive()
exchangeRate?: number;
@IsOptional()
@IsInt()
warehouseId?: number;
@IsOptional()
@IsInt()
branchId?: number;
@IsOptional()
@IsInt()
projectId?: number;
@IsOptional()
@IsString()
note?: string;
@IsBoolean()
open: boolean = false;
@IsBoolean()
isInclusiveTax: boolean = false;
@IsArray()
@ValidateNested({ each: true })
@Type(() => BillEntryDto)
@MinLength(1)
entries: BillEntryDto[];
@IsOptional()
@IsArray()
@ValidateNested({ each: true })
@Type(() => AttachmentDto)
attachments?: AttachmentDto[];
@IsEnum(DiscountType)
discountType: DiscountType = DiscountType.Amount;
@IsOptional()
@IsNumber()
discount?: number;
@IsOptional()
@IsNumber()
adjustment?: number;
}
export class CreateBillDto extends CommandBillDto {}
export class EditBillDto extends CommandBillDto {}

View File

@@ -1,5 +1,6 @@
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
import {
IsBoolean,
IsEmail,
IsNotEmpty,
IsOptional,
@@ -13,6 +14,11 @@ class CommandBranchDto {
@IsString()
name: string;
@ApiPropertyOptional({ description: 'Branch code' })
@IsOptional()
@IsBoolean()
primary?: boolean;
@ApiPropertyOptional({ description: 'Branch code' })
@IsOptional()
@IsString()

View File

@@ -3,6 +3,7 @@ import { Body, Controller, Delete, Param, Post } from '@nestjs/common';
import { ICreditNoteRefundDTO } from '../CreditNotes/types/CreditNotes.types';
import { CreditNotesRefundsApplication } from './CreditNotesRefundsApplication.service';
import { RefundCreditNote } from './models/RefundCreditNote';
import { CreditNoteRefundDto } from './dto/CreditNoteRefund.dto';
@Controller('credit-notes')
@ApiTags('credit-notes-refunds')
@@ -21,7 +22,7 @@ export class CreditNoteRefundsController {
@ApiOperation({ summary: 'Create a refund for the given credit note.' })
createRefundCreditNote(
@Param('creditNoteId') creditNoteId: number,
@Body() creditNoteDTO: ICreditNoteRefundDTO,
@Body() creditNoteDTO: CreditNoteRefundDto,
): Promise<RefundCreditNote> {
return this.creditNotesRefundsApplication.createRefundCreditNote(
creditNoteId,

View File

@@ -4,6 +4,7 @@ import { CreateRefundCreditNoteService } from './commands/CreateRefundCreditNote
import { DeleteRefundCreditNoteService } from './commands/DeleteRefundCreditNote.service';
import { RefundCreditNoteService } from './commands/RefundCreditNote.service';
import { RefundSyncCreditNoteBalanceService } from './commands/RefundSyncCreditNoteBalance';
import { CreditNoteRefundDto } from './dto/CreditNoteRefund.dto';
@Injectable()
export class CreditNotesRefundsApplication {
@@ -17,12 +18,12 @@ export class CreditNotesRefundsApplication {
/**
* Create a refund credit note.
* @param {number} creditNoteId - The credit note ID.
* @param {ICreditNoteRefundDTO} creditNoteDTO - The credit note DTO.
* @param {CreditNoteRefundDto} creditNoteDTO - The credit note DTO.
* @returns {Promise<RefundCreditNote>}
*/
public createRefundCreditNote(
creditNoteId: number,
creditNoteDTO: ICreditNoteRefundDTO,
creditNoteDTO: CreditNoteRefundDto,
) {
return this.createRefundCreditNoteService.createCreditNoteRefund(
creditNoteId,

View File

@@ -13,6 +13,7 @@ import { CommandCreditNoteDTOTransform } from '@/modules/CreditNotes/commands/Co
import { CreditNote } from '@/modules/CreditNotes/models/CreditNote';
import { events } from '@/common/events/events';
import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel';
import { CreditNoteRefundDto } from '../dto/CreditNoteRefund.dto';
@Injectable()
export class CreateRefundCreditNoteService {
@@ -47,7 +48,7 @@ export class CreateRefundCreditNoteService {
*/
public async createCreditNoteRefund(
creditNoteId: number,
newCreditNoteDTO: ICreditNoteRefundDTO,
newCreditNoteDTO: CreditNoteRefundDto,
): Promise<RefundCreditNote> {
// Retrieve the credit note or throw not found service error.
const creditNote = await this.creditNoteModel()
@@ -85,7 +86,6 @@ export class CreateRefundCreditNoteService {
.insertAndFetch({
...this.transformDTOToModel(creditNote, newCreditNoteDTO),
});
// Triggers `onCreditNoteRefundCreated` event.
await this.eventPublisher.emitAsync(events.creditNote.onRefundCreated, {
trx,
@@ -99,13 +99,13 @@ export class CreateRefundCreditNoteService {
/**
* Transformes the refund credit note DTO to model.
* @param {number} creditNoteId
* @param {ICreditNoteRefundDTO} creditNoteDTO
* @returns {ICreditNote}
* @param {CreditNote} creditNote - The credit note.
* @param {CreditNoteRefundDto} creditNoteDTO - The credit note refund DTO.
* @returns {Partial<RefundCreditNote>}
*/
private transformDTOToModel = (
creditNote: CreditNote,
creditNoteDTO: ICreditNoteRefundDTO,
creditNoteDTO: CreditNoteRefundDto,
): Partial<RefundCreditNote> => {
return {
creditNoteId: creditNote.id,

View File

@@ -0,0 +1,35 @@
import { IsNotEmpty, IsOptional, IsPositive, IsString } from 'class-validator';
import { IsDate } from 'class-validator';
import { IsNumber } from 'class-validator';
export class CreditNoteRefundDto {
@IsNumber()
@IsNotEmpty()
fromAccountId: number;
@IsNumber()
@IsPositive()
@IsNotEmpty()
amount: number;
@IsNumber()
@IsOptional()
@IsPositive()
exchangeRate?: number;
@IsString()
@IsNotEmpty()
referenceNo: string;
@IsString()
@IsNotEmpty()
description: string;
@IsDate()
@IsNotEmpty()
date: Date;
@IsNumber()
@IsOptional()
branchId?: number;
}

View File

@@ -1,6 +1,7 @@
import { Knex } from 'knex';
import { RefundCreditNote } from '../models/RefundCreditNote';
import { CreditNote } from '@/modules/CreditNotes/models/CreditNote';
import { CreditNoteRefundDto } from '../dto/CreditNoteRefund.dto';
export interface ICreditNoteRefundDTO {
fromAccountId: number;
@@ -31,7 +32,7 @@ export interface IRefundCreditNoteDeletingPayload {
export interface IRefundCreditNoteCreatingPayload {
trx: Knex.Transaction;
creditNote: CreditNote;
newCreditNoteDTO: ICreditNoteRefundDTO;
newCreditNoteDTO: CreditNoteRefundDto;
}
export interface IRefundCreditNoteCreatedPayload {

View File

@@ -4,12 +4,9 @@ import { DeleteCreditNoteService } from './commands/DeleteCreditNote.service';
import { EditCreditNoteService } from './commands/EditCreditNote.service';
import { OpenCreditNoteService } from './commands/OpenCreditNote.service';
import { GetCreditNotePdf } from './queries/GetCreditNotePdf.serivce';
import {
ICreditNoteEditDTO,
ICreditNoteNewDTO,
ICreditNotesQueryDTO,
} from './types/CreditNotes.types';
import { ICreditNotesQueryDTO } from './types/CreditNotes.types';
import { GetCreditNotesService } from './queries/GetCreditNotes.service';
import { CreateCreditNoteDto, EditCreditNoteDto } from './dtos/CreditNote.dto';
@Injectable()
export class CreditNoteApplication {
@@ -24,20 +21,20 @@ export class CreditNoteApplication {
/**
* Creates a new credit note.
* @param {ICreditNoteNewDTO} creditNoteDTO
* @param {CreateCreditNoteDto} creditNoteDTO
* @returns {Promise<CreditNote>}
*/
createCreditNote(creditNoteDTO: ICreditNoteNewDTO) {
createCreditNote(creditNoteDTO: CreateCreditNoteDto) {
return this.createCreditNoteService.creditCreditNote(creditNoteDTO);
}
/**
* Edits a credit note.
* @param {number} creditNoteId
* @param {ICreditNoteEditDTO} creditNoteDTO
* @param {EditCreditNoteDto} creditNoteDTO
* @returns {Promise<CreditNote>}
*/
editCreditNote(creditNoteId: number, creditNoteDTO: ICreditNoteEditDTO) {
editCreditNote(creditNoteId: number, creditNoteDTO: EditCreditNoteDto) {
return this.editCreditNoteService.editCreditNote(
creditNoteId,
creditNoteDTO,

View File

@@ -9,13 +9,10 @@ import {
Query,
} from '@nestjs/common';
import { CreditNoteApplication } from './CreditNoteApplication.service';
import {
ICreditNoteEditDTO,
ICreditNoteNewDTO,
ICreditNotesQueryDTO,
} from './types/CreditNotes.types';
import { ICreditNotesQueryDTO } from './types/CreditNotes.types';
import { PublicRoute } from '../Auth/Jwt.guard';
import { ApiTags } from '@nestjs/swagger';
import { CreateCreditNoteDto, EditCreditNoteDto } from './dtos/CreditNote.dto';
@Controller('credit-notes')
@ApiTags('credit-notes')
@@ -27,7 +24,7 @@ export class CreditNotesController {
constructor(private creditNoteApplication: CreditNoteApplication) {}
@Post()
createCreditNote(@Body() creditNoteDTO: ICreditNoteNewDTO) {
createCreditNote(@Body() creditNoteDTO: CreateCreditNoteDto) {
return this.creditNoteApplication.createCreditNote(creditNoteDTO);
}
@@ -39,7 +36,7 @@ export class CreditNotesController {
@Put(':id')
editCreditNote(
@Param('id') creditNoteId: number,
@Body() creditNoteDTO: ICreditNoteEditDTO,
@Body() creditNoteDTO: EditCreditNoteDto,
) {
return this.creditNoteApplication.editCreditNote(
creditNoteId,

View File

@@ -17,6 +17,7 @@ import { BrandingTemplateDTOTransformer } from '../../PdfTemplate/BrandingTempla
import { assocItemEntriesDefaultIndex } from '@/utils/associate-item-entries-index';
import { CreditNoteAutoIncrementService } from './CreditNoteAutoIncrement.service';
import { CreditNote } from '../models/CreditNote';
import { CreateCreditNoteDto, EditCreditNoteDto } from '../dtos/CreditNote.dto';
@Injectable()
export class CommandCreditNoteDTOTransform {
@@ -41,7 +42,7 @@ export class CommandCreditNoteDTOTransform {
* @param {string} customerCurrencyCode -
*/
public transformCreateEditDTOToModel = async (
creditNoteDTO: ICreditNoteNewDTO | ICreditNoteEditDTO,
creditNoteDTO: CreateCreditNoteDto | EditCreditNoteDto,
customerCurrencyCode: string,
oldCreditNote?: CreditNote,
): Promise<CreditNote> => {

View File

@@ -3,7 +3,6 @@ import { Inject, Injectable } from '@nestjs/common';
import {
ICreditNoteCreatedPayload,
ICreditNoteCreatingPayload,
ICreditNoteNewDTO,
} from '../types/CreditNotes.types';
import { CreditNote } from '../models/CreditNote';
import { Contact } from '../../Contacts/models/Contact';
@@ -13,6 +12,7 @@ import { ItemsEntriesService } from '@/modules/Items/ItemsEntries.service';
import { EventEmitter2 } from '@nestjs/event-emitter';
import { events } from '@/common/events/events';
import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel';
import { CreateCreditNoteDto } from '../dtos/CreditNote.dto';
@Injectable()
export class CreateCreditNoteService {
@@ -42,7 +42,7 @@ export class CreateCreditNoteService {
* @param creditNoteDTO
*/
public creditCreditNote = async (
creditNoteDTO: ICreditNoteNewDTO,
creditNoteDTO: CreateCreditNoteDto,
trx?: Knex.Transaction,
) => {
// Triggers `onCreditNoteCreate` event.

View File

@@ -1,6 +1,5 @@
import { Inject, Injectable } from '@nestjs/common';
import {
ICreditNoteEditDTO,
ICreditNoteEditedPayload,
ICreditNoteEditingPayload,
} from '../types/CreditNotes.types';
@@ -13,6 +12,7 @@ import { UnitOfWork } from '../../Tenancy/TenancyDB/UnitOfWork.service';
import { events } from '@/common/events/events';
import { CommandCreditNoteDTOTransform } from './CommandCreditNoteDTOTransform.service';
import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel';
import { EditCreditNoteDto } from '../dtos/CreditNote.dto';
@Injectable()
export class EditCreditNoteService {
@@ -27,6 +27,7 @@ export class EditCreditNoteService {
constructor(
@Inject(CreditNote.name)
private creditNoteModel: TenantModelProxy<typeof CreditNote>,
@Inject(Contact.name)
private contactModel: TenantModelProxy<typeof Contact>,
@@ -42,7 +43,7 @@ export class EditCreditNoteService {
*/
public async editCreditNote(
creditNoteId: number,
creditNoteEditDTO: ICreditNoteEditDTO,
creditNoteEditDTO: EditCreditNoteDto,
) {
// Retrieve the sale invoice or throw not found service error.
const oldCreditNote = await this.creditNoteModel()

View File

@@ -0,0 +1,98 @@
import { ItemEntryDto } from '@/modules/TransactionItemEntry/dto/ItemEntry.dto';
import { Type } from 'class-transformer';
import {
IsArray,
IsBoolean,
IsDate,
IsEnum,
IsInt,
IsNumber,
IsOptional,
IsPositive,
IsString,
Min,
ValidateNested,
} from 'class-validator';
enum DiscountType {
Percentage = 'percentage',
Amount = 'amount',
}
class CreditNoteEntryDto extends ItemEntryDto {}
class AttachmentDto {
@IsString()
key: string;
}
export class CommandCreditNoteDto {
@IsInt()
customerId: number;
@IsOptional()
@IsPositive()
exchangeRate?: number;
@IsDate()
@Type(() => Date)
creditNoteDate: Date;
@IsOptional()
@IsString()
referenceNo?: string;
@IsOptional()
@IsString()
creditNoteNumber?: string;
@IsOptional()
@IsString()
note?: string;
@IsOptional()
@IsString()
termsConditions?: string;
@IsBoolean()
open: boolean = false;
@IsOptional()
@IsInt()
warehouseId?: number;
@IsOptional()
@IsInt()
branchId?: number;
@IsArray()
@ValidateNested({ each: true })
@Type(() => CreditNoteEntryDto)
@Min(1)
entries: CreditNoteEntryDto[];
@IsOptional()
@IsArray()
@ValidateNested({ each: true })
@Type(() => AttachmentDto)
attachments?: AttachmentDto[];
@IsOptional()
@IsInt()
pdfTemplateId?: number;
@IsOptional()
@IsNumber()
discount?: number;
@IsOptional()
@IsEnum(DiscountType)
discountType?: DiscountType;
@IsOptional()
@IsNumber()
adjustment?: number;
}
export class CreateCreditNoteDto extends CommandCreditNoteDto {}
export class EditCreditNoteDto extends CommandCreditNoteDto {}

View File

@@ -0,0 +1,12 @@
import {
IsDate,
IsInt,
IsNumber,
IsOptional,
IsPositive,
IsString,
} from 'class-validator';
export class RefundCreditNoteDto {
}

View File

@@ -6,6 +6,7 @@ import { IItemEntryDTO } from '@/modules/TransactionItemEntry/ItemEntry.types';
import { IFilterMeta, IPaginationMeta } from '@/interfaces/Model';
import { IDynamicListFilter } from '@/modules/DynamicListing/DynamicFilter/DynamicFilter.types';
import { ILedgerEntry } from '@/modules/Ledger/types/Ledger.types';
import { EditCreditNoteDto } from '../dtos/CreditNote.dto';
export interface ICreditNoteEntryNewDTO extends IItemEntryDTO {}
@@ -60,17 +61,16 @@ export interface ICreditNoteDeletedPayload {
}
export interface ICreditNoteEditingPayload {
trx: Knex.Transaction;
oldCreditNote: CreditNote;
creditNoteEditDTO: ICreditNoteEditDTO;
tenantId: number;
creditNoteEditDTO: EditCreditNoteDto;
trx?: Knex.Transaction;
}
export interface ICreditNoteEditedPayload {
trx: Knex.Transaction;
trx?: Knex.Transaction;
oldCreditNote: CreditNote;
creditNote: CreditNote;
creditNoteEditDTO: ICreditNoteEditDTO;
creditNoteEditDTO: EditCreditNoteDto;
}
export interface ICreditNoteCreatedPayload {

View File

@@ -6,6 +6,11 @@ import { Injectable } from '@nestjs/common';
@Injectable()
export class TrialBalanceSheetApplication {
/**
* @param {TrialBalanceSheetService} sheetService - The trial balance sheet service.
* @param {TrialBalanceSheetTableInjectable} tablable - The trial balance sheet table injectable.
* @param {TrialBalanceExportInjectable} exportable - The trial balance export injectable.
*/
constructor(
private readonly sheetService: TrialBalanceSheetService,
private readonly tablable: TrialBalanceSheetTableInjectable,

View File

@@ -17,6 +17,7 @@ import { InventoryAdjustment } from './models/InventoryAdjustment';
import { PublicRoute } from '../Auth/Jwt.guard';
import { IPaginationMeta } from '@/interfaces/Model';
import { ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger';
import { CreateQuickInventoryAdjustmentDto } from './dtos/CreateQuickInventoryAdjustment.dto';
@Controller('inventory-adjustments')
@ApiTags('inventory-adjustments')
@@ -33,7 +34,7 @@ export class InventoryAdjustmentsController {
description: 'The inventory adjustment has been successfully created.',
})
public async createQuickInventoryAdjustment(
@Body() quickAdjustmentDTO: IQuickInventoryAdjustmentDTO,
@Body() quickAdjustmentDTO: CreateQuickInventoryAdjustmentDto,
): Promise<InventoryAdjustment> {
return this.inventoryAdjustmentsApplicationService.createQuickInventoryAdjustment(
quickAdjustmentDTO,

View File

@@ -10,6 +10,7 @@ import { InventoryAdjustment } from './models/InventoryAdjustment';
import { GetInventoryAdjustmentService } from './queries/GetInventoryAdjustment.service';
import { GetInventoryAdjustmentsService } from './queries/GetInventoryAdjustments.service';
import { IPaginationMeta } from '@/interfaces/Model';
import { CreateQuickInventoryAdjustmentDto } from './dtos/CreateQuickInventoryAdjustment.dto';
@Injectable()
export class InventoryAdjustmentsApplicationService {
@@ -39,7 +40,7 @@ export class InventoryAdjustmentsApplicationService {
* @param {IQuickInventoryAdjustmentDTO} quickAdjustmentDTO - Quick inventory adjustment DTO.
*/
public async createQuickInventoryAdjustment(
quickAdjustmentDTO: IQuickInventoryAdjustmentDTO,
quickAdjustmentDTO: CreateQuickInventoryAdjustmentDto,
): Promise<InventoryAdjustment> {
return this.createQuickInventoryAdjustmentService.createQuickAdjustment(
quickAdjustmentDTO,

View File

@@ -17,6 +17,7 @@ import { Item } from '@/modules/Items/models/Item';
import { Account } from '@/modules/Accounts/models/Account.model';
import { BranchTransactionDTOTransformer } from '@/modules/Branches/integrations/BranchTransactionDTOTransform';
import { WarehouseTransactionDTOTransform } from '@/modules/Warehouses/Integrations/WarehouseTransactionDTOTransform';
import { CreateQuickInventoryAdjustmentDto } from '../dtos/CreateQuickInventoryAdjustment.dto';
import { TenancyContext } from '@/modules/Tenancy/TenancyContext.service';
import { ERRORS } from '../constants/InventoryAdjustments.constants';
import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel';
@@ -89,7 +90,7 @@ export class CreateQuickInventoryAdjustmentService {
* @param {IQuickInventoryAdjustmentDTO} quickAdjustmentDTO - qucik adjustment DTO.
*/
public async createQuickAdjustment(
quickAdjustmentDTO: IQuickInventoryAdjustmentDTO,
quickAdjustmentDTO: CreateQuickInventoryAdjustmentDto,
): Promise<InventoryAdjustment> {
// Retrieve the adjustment account or throw not found error.
const adjustmentAccount = await this.accountModel()

View File

@@ -0,0 +1,86 @@
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
import {
IsBoolean,
IsDate,
IsEnum,
IsNotEmpty,
IsNumber,
IsOptional,
IsPositive,
IsString,
} from 'class-validator';
import { Type } from 'class-transformer';
enum IAdjustmentTypes {
INCREMENT = 'increment',
DECREMENT = 'decrement',
}
export class CreateQuickInventoryAdjustmentDto {
@ApiProperty({ description: 'Date of the inventory adjustment' })
@IsNotEmpty()
@IsDate()
@Type(() => Date)
date: Date;
@ApiProperty({ description: 'Type of adjustment', enum: IAdjustmentTypes })
@IsNotEmpty()
@IsEnum(IAdjustmentTypes)
type: 'increment' | 'decrement';
@ApiProperty({ description: 'ID of the adjustment account' })
@IsNotEmpty()
@IsNumber()
@IsPositive()
adjustmentAccountId: number;
@ApiProperty({ description: 'Reason for the adjustment' })
@IsNotEmpty()
@IsString()
reason: string;
@ApiProperty({ description: 'Description of the adjustment' })
@IsNotEmpty()
@IsString()
description: string;
@ApiProperty({ description: 'Reference number' })
@IsNotEmpty()
@IsString()
referenceNo: string;
@ApiProperty({ description: 'ID of the item being adjusted' })
@IsNotEmpty()
@IsNumber()
@IsPositive()
itemId: number;
@ApiProperty({ description: 'Quantity to adjust' })
@IsNotEmpty()
@IsNumber()
@IsPositive()
quantity: number;
@ApiProperty({ description: 'Cost of the item' })
@IsNotEmpty()
@IsNumber()
@IsPositive()
cost: number;
@ApiProperty({ description: 'Whether to publish the adjustment immediately' })
@IsNotEmpty()
@IsBoolean()
publish: boolean;
@ApiPropertyOptional({ description: 'ID of the warehouse (optional)' })
@IsOptional()
@IsNumber()
@IsPositive()
warehouseId?: number;
@ApiPropertyOptional({ description: 'ID of the branch (optional)' })
@IsOptional()
@IsNumber()
@IsPositive()
branchId?: number;
}

View File

@@ -1,5 +1,6 @@
import { Knex } from 'knex';
import { InventoryAdjustment } from '../models/InventoryAdjustment';
import { CreateQuickInventoryAdjustmentDto } from '../dtos/CreateQuickInventoryAdjustment.dto';
type IAdjustmentTypes = 'increment' | 'decrement';
@@ -29,7 +30,7 @@ export interface IInventoryAdjustmentEventCreatedPayload {
trx: Knex.Transaction;
}
export interface IInventoryAdjustmentCreatingPayload {
quickAdjustmentDTO: IQuickInventoryAdjustmentDTO;
quickAdjustmentDTO: CreateQuickInventoryAdjustmentDto;
trx: Knex.Transaction;
}

View File

@@ -118,7 +118,6 @@ export class ItemsController extends TenantController {
description: 'The item has been successfully updated.',
})
@ApiResponse({ status: 404, description: 'The item not found.' })
// @UsePipes(new ZodValidationPipe(createItemSchema))
async editItem(
@Param('id') id: string,
@Body() editItemDto: EditItemDto,

View File

@@ -7,6 +7,7 @@ import { ServiceError } from './ServiceError';
import { IItemEntryDTO } from '../TransactionItemEntry/ItemEntry.types';
import { TenantModelProxy } from '../System/models/TenantBaseModel';
import { entriesAmountDiff } from '@/utils/entries-amount-diff';
import { ItemEntryDto } from '../TransactionItemEntry/dto/ItemEntry.dto';
const ERRORS = {
ITEMS_NOT_FOUND: 'ITEMS_NOT_FOUND',
@@ -83,7 +84,7 @@ export class ItemsEntriesService {
* @param {IItemEntryDTO[]} itemEntries - Items entries.
* @returns {Promise<Item[]>}
*/
public async validateItemsIdsExistance(itemEntries: IItemEntryDTO[]) {
public async validateItemsIdsExistance(itemEntries: Array<{ itemId: number }>) {
const itemsIds = itemEntries.map((e) => e.itemId);
const foundItems = await this.itemModel().query().whereIn('id', itemsIds);
@@ -106,7 +107,7 @@ export class ItemsEntriesService {
public async validateEntriesIdsExistance(
referenceId: number,
referenceType: string,
billEntries: IItemEntryDTO[],
billEntries: ItemEntryDto[],
) {
const entriesIds = billEntries
.filter((e: ItemEntry) => e.id)
@@ -130,9 +131,9 @@ export class ItemsEntriesService {
* @param {IItemEntryDTO[]} itemEntries -
*/
public async validateNonPurchasableEntriesItems(
itemEntries: IItemEntryDTO[],
itemEntries: ItemEntryDto[],
) {
const itemsIds = itemEntries.map((e: IItemEntryDTO) => e.itemId);
const itemsIds = itemEntries.map((e: ItemEntryDto) => e.itemId);
const purchasbleItems = await this.itemModel()
.query()
.where('purchasable', true)
@@ -150,8 +151,8 @@ export class ItemsEntriesService {
* Validate the entries items that not sell-able.
* @param {IItemEntryDTO[]} itemEntries -
*/
public async validateNonSellableEntriesItems(itemEntries: IItemEntryDTO[]) {
const itemsIds = itemEntries.map((e: IItemEntryDTO) => e.itemId);
public async validateNonSellableEntriesItems(itemEntries: ItemEntryDto[]) {
const itemsIds = itemEntries.map((e: ItemEntryDto) => e.itemId);
const sellableItems = await this.itemModel()
.query()
@@ -218,7 +219,7 @@ export class ItemsEntriesService {
/**
* Sets the cost/sell accounts to the invoice entries.
*/
public setItemsEntriesDefaultAccounts = async (entries: IItemEntryDTO[]) => {
public setItemsEntriesDefaultAccounts = async (entries: ItemEntryDto[]) => {
const entriesItemsIds = entries.map((e) => e.itemId);
const items = await this.itemModel().query().whereIn('id', entriesItemsIds);
@@ -240,7 +241,7 @@ export class ItemsEntriesService {
* @param {ItemEntry[]} entries - Items entries.
* @returns {number}
*/
public getTotalItemsEntries(entries: IItemEntryDTO[]): number {
public getTotalItemsEntries(entries: ItemEntryDto[]): number {
return sumBy(entries, (e) => ItemEntry.calcAmount(e));
}

View File

@@ -14,6 +14,10 @@ import { GetPaymentReceivedPdfService } from './queries/GetPaymentReceivedPdf.se
import { GetPaymentReceivedStateService } from './queries/GetPaymentReceivedState.service';
import { GetPaymentsReceivedService } from './queries/GetPaymentsReceived.service';
import { SendPaymentReceiveMailNotification } from './commands/PaymentReceivedMailNotification';
import {
CreatePaymentReceivedDto,
EditPaymentReceivedDto,
} from './dtos/PaymentReceived.dto';
@Injectable()
export class PaymentReceivesApplication {
@@ -31,10 +35,10 @@ export class PaymentReceivesApplication {
/**
* Creates a new payment receive.
* @param {IPaymentReceivedCreateDTO} paymentReceiveDTO
* @param {CreatePaymentReceivedDto} paymentReceiveDTO
* @returns
*/
public createPaymentReceived(paymentReceiveDTO: IPaymentReceivedCreateDTO) {
public createPaymentReceived(paymentReceiveDTO: CreatePaymentReceivedDto) {
return this.createPaymentReceivedService.createPaymentReceived(
paymentReceiveDTO,
);
@@ -43,12 +47,12 @@ export class PaymentReceivesApplication {
/**
* Edit details the given payment receive with associated entries.
* @param {number} paymentReceiveId - Payment receive id.
* @param {IPaymentReceivedEditDTO} paymentReceiveDTO - Payment receive data.
* @param {EditPaymentReceivedDto} paymentReceiveDTO - Payment receive data.
* @returns
*/
public editPaymentReceive(
paymentReceiveId: number,
paymentReceiveDTO: IPaymentReceivedEditDTO,
paymentReceiveDTO: EditPaymentReceivedDto,
) {
return this.editPaymentReceivedService.editPaymentReceive(
paymentReceiveId,
@@ -130,17 +134,17 @@ export class PaymentReceivesApplication {
* @param {PaymentReceive} paymentReceive
* @returns
*/
public getPaymentReceivePdf = (paymentReceiveId: number) => {
public getPaymentReceivePdf(paymentReceiveId: number) {
return this.getPaymentReceivePdfService.getPaymentReceivePdf(
paymentReceiveId,
);
};
}
/**
* Retrieves the create/edit initial state of the payment received.
* @returns {Promise<IPaymentReceivedState>}
*/
public getPaymentReceivedState = () => {
public getPaymentReceivedState() {
return this.getPaymentReceivedStateService.getPaymentReceivedState();
};
}
}

View File

@@ -14,6 +14,7 @@ import { Customer } from '@/modules/Customers/models/Customer';
import { TenancyContext } from '@/modules/Tenancy/TenancyContext.service';
import { Inject, Injectable } from '@nestjs/common';
import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel';
import { CreatePaymentReceivedDto } from '../dtos/PaymentReceived.dto';
@Injectable()
export class CreatePaymentReceivedService {
@@ -38,7 +39,7 @@ export class CreatePaymentReceivedService {
* @param {Knex.Transaction} trx - Database transaction.
*/
public async createPaymentReceived(
paymentReceiveDTO: IPaymentReceivedCreateDTO,
paymentReceiveDTO: CreatePaymentReceivedDto,
trx?: Knex.Transaction,
) {
const tenant = await this.tenancyContext.getTenant(true);

View File

@@ -14,6 +14,7 @@ import { events } from '@/common/events/events';
import { Customer } from '@/modules/Customers/models/Customer';
import { TenancyContext } from '@/modules/Tenancy/TenancyContext.service';
import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel';
import { EditPaymentReceivedDto } from '../dtos/PaymentReceived.dto';
@Injectable()
export class EditPaymentReceivedService {
@@ -49,7 +50,7 @@ export class EditPaymentReceivedService {
*/
public async editPaymentReceive(
paymentReceiveId: number,
paymentReceiveDTO: IPaymentReceivedEditDTO,
paymentReceiveDTO: EditPaymentReceivedDto,
) {
const tenant = await this.tenancyContext.getTenant(true);
@@ -151,7 +152,7 @@ export class EditPaymentReceivedService {
*/
private transformEditDTOToModel = async (
customer: Customer,
paymentReceiveDTO: IPaymentReceivedEditDTO,
paymentReceiveDTO: EditPaymentReceivedDto,
oldPaymentReceive: PaymentReceived,
) => {
return this.transformer.transformPaymentReceiveDTOToModel(

View File

@@ -12,6 +12,7 @@ import { SaleInvoice } from '@/modules/SaleInvoices/models/SaleInvoice';
import { ServiceError } from '@/modules/Items/ServiceError';
import { ACCOUNT_TYPE } from '@/constants/accounts';
import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel';
import { EditPaymentReceivedDto } from '../dtos/PaymentReceived.dto';
@Injectable()
export class PaymentReceivedValidators {
@@ -191,11 +192,11 @@ export class PaymentReceivedValidators {
/**
* Validate the payment customer whether modified.
* @param {IPaymentReceivedEditDTO} paymentReceiveDTO
* @param {IPaymentReceived} oldPaymentReceive
* @param {EditPaymentReceivedDto} paymentReceiveDTO
* @param {PaymentReceived} oldPaymentReceive
*/
public validateCustomerNotModified(
paymentReceiveDTO: IPaymentReceivedEditDTO,
paymentReceiveDTO: EditPaymentReceivedDto,
oldPaymentReceive: PaymentReceived,
) {
if (paymentReceiveDTO.customerId !== oldPaymentReceive.customerId) {

View File

@@ -0,0 +1,75 @@
import { AttachmentLinkDto } from '@/modules/Attachments/dtos/Attachment.dto';
import { Type } from 'class-transformer';
import { IsArray, ValidateNested } from 'class-validator';
import { IsString } from 'class-validator';
import { IsDateString, IsNumber, IsOptional } from 'class-validator';
import { IsInt } from 'class-validator';
export class PaymentReceivedEntryDto {
@IsOptional()
@IsInt()
id?: number;
@IsOptional()
@IsInt()
index?: number;
@IsOptional()
@IsInt()
paymentReceiveId?: number;
@IsInt()
invoiceId: number;
@IsNumber()
paymentAmount: number;
}
export class CommandPaymentReceivedDto {
@IsInt()
customerId: number;
@IsDateString()
paymentDate: Date | string;
@IsOptional()
@IsNumber()
amount?: number;
@IsOptional()
@IsNumber()
exchangeRate?: number;
@IsOptional()
@IsString()
referenceNo?: string;
@IsInt()
depositAccountId: number;
@IsOptional()
@IsString()
paymentReceiveNo?: string;
@IsOptional()
@IsString()
statement?: string;
@IsArray()
@ValidateNested({ each: true })
@Type(() => PaymentReceivedEntryDto)
entries: PaymentReceivedEntryDto[];
@IsOptional()
@IsInt()
branchId?: number;
@IsOptional()
@IsArray()
@ValidateNested({ each: true })
@Type(() => AttachmentLinkDto)
attachments?: AttachmentLinkDto[];
}
export class CreatePaymentReceivedDto extends CommandPaymentReceivedDto {}
export class EditPaymentReceivedDto extends CommandPaymentReceivedDto {}

View File

@@ -7,6 +7,17 @@ import {
CommonMailOptionsDTO,
} from '@/modules/MailNotification/MailNotification.types';
import { TenantJobPayload } from '@/interfaces/Tenant';
import { EditPaymentReceivedDto } from '../dtos/PaymentReceived.dto';
export interface IPaymentReceivedEntryDTO {
id?: number;
index?: number;
paymentReceiveId?: number;
invoiceId: number;
paymentAmount: number;
}
export interface IPaymentReceivedCreateDTO {
customerId: number;
@@ -37,14 +48,6 @@ export interface IPaymentReceivedEditDTO {
attachments?: AttachmentLinkDTO[];
}
export interface IPaymentReceivedEntryDTO {
id?: number;
index?: number;
paymentReceiveId?: number;
invoiceId: number;
paymentAmount: number;
}
export interface IPaymentsReceivedFilter extends IDynamicListFilter {
stringifiedFilterRoles?: string;
filterQuery?: (trx: Knex.Transaction) => void;
@@ -96,32 +99,26 @@ export interface IPaymentReceivedCreatedPayload {
}
export interface IPaymentReceivedEditedPayload {
// tenantId: number;
paymentReceiveId: number;
paymentReceive: PaymentReceived;
oldPaymentReceive: PaymentReceived;
paymentReceiveDTO: IPaymentReceivedEditDTO;
// authorizedUser: ISystemUser;
paymentReceiveDTO: EditPaymentReceivedDto;
trx: Knex.Transaction;
}
export interface IPaymentReceivedEditingPayload {
// tenantId: number;
oldPaymentReceive: PaymentReceived;
paymentReceiveDTO: IPaymentReceivedEditDTO;
trx: Knex.Transaction;
}
export interface IPaymentReceivedDeletingPayload {
// tenantId: number;
oldPaymentReceive: PaymentReceived;
trx: Knex.Transaction;
}
export interface IPaymentReceivedDeletedPayload {
// tenantId: number;
paymentReceiveId: number;
oldPaymentReceive: PaymentReceived;
// authorizedUser: ISystemUser;
trx: Knex.Transaction;
}

View File

@@ -1,6 +1,6 @@
import { Injectable } from '@nestjs/common';
import { CreateSaleEstimate } from './commands/CreateSaleEstimate.service';
import {
ISaleEstimateDTO,
ISalesEstimatesFilter,
SaleEstimateMailOptionsDTO,
} from './types/SaleEstimates.types';
@@ -10,12 +10,14 @@ import { GetSaleEstimate } from './queries/GetSaleEstimate.service';
import { DeliverSaleEstimateService } from './commands/DeliverSaleEstimate.service';
import { ApproveSaleEstimateService } from './commands/ApproveSaleEstimate.service';
import { RejectSaleEstimateService } from './commands/RejectSaleEstimate.service';
// import { SaleEstimateNotifyBySms } from './commands/SaleEstimateSmsNotify';
import { SendSaleEstimateMail } from './commands/SendSaleEstimateMail';
import { GetSaleEstimateState } from './queries/GetSaleEstimateState.service';
import { GetSaleEstimatesService } from './queries/GetSaleEstimates.service';
import { Injectable } from '@nestjs/common';
import { GetSaleEstimatePdf } from './queries/GetSaleEstimatePdf';
import {
CreateSaleEstimateDto,
EditSaleEstimateDto,
} from './dtos/SaleEstimate.dto';
@Injectable()
export class SaleEstimatesApplication {
@@ -31,25 +33,27 @@ export class SaleEstimatesApplication {
private readonly sendEstimateMailService: SendSaleEstimateMail,
private readonly getSaleEstimateStateService: GetSaleEstimateState,
private readonly saleEstimatesPdfService: GetSaleEstimatePdf,
// private readonly saleEstimateNotifyBySmsService: SaleEstimateNotifyBySms,
) {}
/**
* Create a sale estimate.
* @param {EstimateDTO} estimate - Estimate DTO.
* @param {CreateSaleEstimateDto} estimate - Estimate DTO.
* @return {Promise<ISaleEstimate>}
*/
public createSaleEstimate(estimateDTO: ISaleEstimateDTO) {
public createSaleEstimate(estimateDTO: CreateSaleEstimateDto) {
return this.createSaleEstimateService.createEstimate(estimateDTO);
}
/**
* Edit the given sale estimate.
* @param {number} estimateId - Sale estimate ID.
* @param {EstimateDTO} estimate - Estimate DTO.
* @param {EditSaleEstimateDto} estimate - Estimate DTO.
* @return {Promise<ISaleEstimate>}
*/
public editSaleEstimate(estimateId: number, estimateDTO: ISaleEstimateDTO) {
public editSaleEstimate(
estimateId: number,
estimateDTO: EditSaleEstimateDto,
) {
return this.editSaleEstimateService.editEstimate(estimateId, estimateDTO);
}

View File

@@ -13,12 +13,15 @@ import {
} from '@nestjs/common';
import { SaleEstimatesApplication } from './SaleEstimates.application';
import {
ISaleEstimateDTO,
ISalesEstimatesFilter,
SaleEstimateMailOptionsDTO,
} from './types/SaleEstimates.types';
import { SaleEstimate } from './models/SaleEstimate';
import { PublicRoute } from '../Auth/Jwt.guard';
import {
CreateSaleEstimateDto,
EditSaleEstimateDto,
} from './dtos/SaleEstimate.dto';
@Controller('sale-estimates')
@ApiTags('sale-estimates')
@@ -38,7 +41,7 @@ export class SaleEstimatesController {
description: 'Sale estimate created successfully',
})
public createSaleEstimate(
@Body() estimateDTO: ISaleEstimateDTO,
@Body() estimateDTO: CreateSaleEstimateDto,
): Promise<SaleEstimate> {
return this.saleEstimatesApplication.createSaleEstimate(estimateDTO);
}
@@ -61,7 +64,7 @@ export class SaleEstimatesController {
})
public editSaleEstimate(
@Param('id', ParseIntPipe) estimateId: number,
@Body() estimateDTO: ISaleEstimateDTO,
@Body() estimateDTO: EditSaleEstimateDto,
): Promise<SaleEstimate> {
return this.saleEstimatesApplication.editSaleEstimate(
estimateId,

View File

@@ -14,6 +14,7 @@ import { events } from '@/common/events/events';
import { ItemsEntriesService } from '@/modules/Items/ItemsEntries.service';
import { Customer } from '@/modules/Customers/models/Customer';
import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel';
import { CreateSaleEstimateDto } from '../dtos/SaleEstimate.dto';
@Injectable()
export class CreateSaleEstimate {
@@ -37,7 +38,7 @@ export class CreateSaleEstimate {
* @return {Promise<ISaleEstimate>}
*/
public async createEstimate(
estimateDTO: ISaleEstimateDTO,
estimateDTO: CreateSaleEstimateDto,
trx?: Knex.Transaction,
): Promise<SaleEstimate> {
// Retrieve the given customer or throw not found service error.

View File

@@ -14,6 +14,7 @@ import { SaleEstimate } from '../models/SaleEstimate';
import { ItemsEntriesService } from '@/modules/Items/ItemsEntries.service';
import { Customer } from '@/modules/Customers/models/Customer';
import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel';
import { EditSaleEstimateDto } from '../dtos/SaleEstimate.dto';
@Injectable()
export class EditSaleEstimate {
@@ -40,7 +41,7 @@ export class EditSaleEstimate {
*/
public async editEstimate(
estimateId: number,
estimateDTO: ISaleEstimateDTO,
estimateDTO: EditSaleEstimateDto,
): Promise<SaleEstimate> {
// Retrieve details of the given sale estimate id.
const oldSaleEstimate = await this.saleEstimateModel()

View File

@@ -2,10 +2,7 @@ import * as R from 'ramda';
import { Inject, Injectable } from '@nestjs/common';
import { omit, sumBy } from 'lodash';
import * as composeAsync from 'async/compose';
// import { ICustomer, ISaleEstimate, ISaleEstimateDTO } from '../types/SaleEstimates.types';
import { SaleEstimateValidators } from './SaleEstimateValidators.service';
// import { BranchTransactionDTOTransform } from '@/services/Branches/Integrations/BranchTransactionDTOTransform';
// import { WarehouseTransactionDTOTransform } from '@/services/Warehouses/Integrations/WarehouseTransactionDTOTransform';
import { formatDateFields } from '@/utils/format-date-fields';
import * as moment from 'moment';
import { SaleEstimateIncrement } from './SaleEstimateIncrement.service';
@@ -18,8 +15,7 @@ import { SaleEstimate } from '../models/SaleEstimate';
import { Customer } from '@/modules/Customers/models/Customer';
import { ISaleEstimateDTO } from '../types/SaleEstimates.types';
import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel';
// import { assocItemEntriesDefaultIndex } from '@/services/Items/utils';
// import { BrandingTemplateDTOTransformer } from '@/services/PdfTemplate/BrandingTemplateDTOTransformer';
import { CommandSaleEstimateDto } from '../dtos/SaleEstimate.dto';
@Injectable()
export class SaleEstimateDTOTransformer {
@@ -42,7 +38,7 @@ export class SaleEstimateDTOTransformer {
* @return {ISaleEstimate}
*/
async transformDTOToModel(
estimateDTO: ISaleEstimateDTO,
estimateDTO: CommandSaleEstimateDto,
paymentCustomer: Customer,
oldSaleEstimate?: SaleEstimate,
): Promise<SaleEstimate> {

View File

@@ -0,0 +1,104 @@
import { ItemEntryDto } from '@/modules/TransactionItemEntry/dto/ItemEntry.dto';
import { Type } from 'class-transformer';
import {
IsArray,
IsBoolean,
IsDate,
IsEnum,
IsNumber,
IsOptional,
IsString,
Min,
MinLength,
ValidateNested,
} from 'class-validator';
enum DiscountType {
Percentage = 'percentage',
Amount = 'amount',
}
class SaleEstimateEntryDto extends ItemEntryDto {}
class AttachmentDto {
@IsString()
key: string;
}
export class CommandSaleEstimateDto {
@IsNumber()
customerId: number;
@IsDate()
@Type(() => Date)
estimateDate: Date;
@IsDate()
@Type(() => Date)
expirationDate: Date;
@IsString()
@IsOptional()
reference?: string;
@IsString()
@IsOptional()
estimateNumber?: string;
@IsBoolean()
delivered: boolean = false;
@IsNumber()
@Min(0.01)
@IsOptional()
exchangeRate?: number;
@IsNumber()
@IsOptional()
warehouseId?: number;
@IsNumber()
@IsOptional()
branchId?: number;
@IsArray()
@MinLength(1)
@ValidateNested({ each: true })
@Type(() => SaleEstimateEntryDto)
entries: SaleEstimateEntryDto[];
@IsString()
@IsOptional()
note?: string;
@IsString()
@IsOptional()
termsConditions?: string;
@IsString()
@IsOptional()
sendToEmail?: string;
@IsArray()
@IsOptional()
@ValidateNested({ each: true })
@Type(() => AttachmentDto)
attachments?: AttachmentDto[];
@IsNumber()
@IsOptional()
pdfTemplateId?: number;
@IsNumber()
@IsOptional()
discount?: number;
@IsEnum(DiscountType)
discountType: DiscountType = DiscountType.Amount;
@IsNumber()
@IsOptional()
adjustment?: number;
}
export class CreateSaleEstimateDto extends CommandSaleEstimateDto {}
export class EditSaleEstimateDto extends CommandSaleEstimateDto {}

View File

@@ -7,6 +7,7 @@ import { AttachmentLinkDTO } from '@/modules/Attachments/Attachments.types';
import { IDynamicListFilter } from '@/modules/DynamicListing/DynamicFilter/DynamicFilter.types';
import { CommonMailOptionsDTO } from '@/modules/MailNotification/MailNotification.types';
import { CommonMailOptions } from '@/modules/MailNotification/MailNotification.types';
import { EditSaleEstimateDto } from '../dtos/SaleEstimate.dto';
export const SendSaleEstimateMailQueue = 'SendSaleEstimateMailProcessor';
export const SendSaleEstimateMailJob = 'SendSaleEstimateMailProcess';
@@ -34,7 +35,6 @@ export interface ISalesEstimatesFilter extends IDynamicListFilter {
}
export interface ISaleEstimateCreatedPayload {
// tenantId: number;
saleEstimate: SaleEstimate;
saleEstimateId: number;
saleEstimateDTO: ISaleEstimateDTO;
@@ -43,12 +43,10 @@ export interface ISaleEstimateCreatedPayload {
export interface ISaleEstimateCreatingPayload {
estimateDTO: ISaleEstimateDTO;
tenantId: number;
trx: Knex.Transaction;
}
export interface ISaleEstimateEditedPayload {
// tenantId: number;
estimateId: number;
saleEstimate: SaleEstimate;
oldSaleEstimate: SaleEstimate;
@@ -57,33 +55,28 @@ export interface ISaleEstimateEditedPayload {
}
export interface ISaleEstimateEditingPayload {
// tenantId: number;
oldSaleEstimate: SaleEstimate;
estimateDTO: ISaleEstimateDTO;
estimateDTO: EditSaleEstimateDto;
trx: Knex.Transaction;
}
export interface ISaleEstimateDeletedPayload {
// tenantId: number;
saleEstimateId: number;
oldSaleEstimate: SaleEstimate;
trx: Knex.Transaction;
}
export interface ISaleEstimateDeletingPayload {
// tenantId: number;
oldSaleEstimate: SaleEstimate;
trx: Knex.Transaction;
}
export interface ISaleEstimateEventDeliveredPayload {
// tenantId: number;
saleEstimate: SaleEstimate;
trx: Knex.Transaction;
}
export interface ISaleEstimateEventDeliveringPayload {
// tenantId: number;
oldSaleEstimate: SaleEstimate;
trx: Knex.Transaction;
}
@@ -97,13 +90,11 @@ export enum SaleEstimateAction {
}
export interface ISaleEstimateApprovingEvent {
// tenantId: number;
oldSaleEstimate: SaleEstimate;
trx: Knex.Transaction;
}
export interface ISaleEstimateApprovedEvent {
// tenantId: number;
oldSaleEstimate: SaleEstimate;
saleEstimate: SaleEstimate;
trx: Knex.Transaction;

View File

@@ -8,13 +8,7 @@ import {
CommonMailOptionsDTO,
} from '../MailNotification/MailNotification.types';
import { TenantJobPayload } from '@/interfaces/Tenant';
// import SaleInvoice from './models/SaleInvoice';
// import { SystemUser } from '../System/models/SystemUser';
// import { ISystemUser, IAccount, ITaxTransaction } from '@/interfaces';
// import { CommonMailOptions, CommonMailOptionsDTO } from './Mailable';
// import { IDynamicListFilter } from '@/interfaces/DynamicFilter';
// import { IItemEntry, IItemEntryDTO } from './ItemEntry';
// import { AttachmentLinkDTO } from './Attachments';
import { CreateSaleInvoiceDto, EditSaleInvoiceDto } from './dtos/SaleInvoice.dto';
export interface PaymentIntegrationTransactionLink {
id: number;
@@ -89,27 +83,27 @@ export type InvoiceNotificationType = 'details' | 'reminder';
export interface ISaleInvoiceCreatedPayload {
saleInvoice: SaleInvoice;
saleInvoiceDTO: ISaleInvoiceCreateDTO;
saleInvoiceDTO: CreateSaleInvoiceDto;
saleInvoiceId: number;
trx: Knex.Transaction;
}
export interface ISaleInvoiceCreatingPaylaod {
tenantId: number;
saleInvoiceDTO: ISaleInvoiceCreateDTO;
saleInvoiceDTO: CreateSaleInvoiceDto;
trx: Knex.Transaction;
}
export interface ISaleInvoiceEditedPayload {
saleInvoice: SaleInvoice;
oldSaleInvoice: SaleInvoice;
saleInvoiceDTO: ISaleInvoiceEditDTO;
saleInvoiceDTO: EditSaleInvoiceDto;
saleInvoiceId: number;
trx: Knex.Transaction;
}
export interface ISaleInvoiceEditingPayload {
saleInvoiceDTO: ISaleInvoiceEditDTO;
saleInvoiceDTO: EditSaleInvoiceDto;
oldSaleInvoice: SaleInvoice;
trx: Knex.Transaction;
}

View File

@@ -11,8 +11,6 @@ import { GetInvoicePaymentsService } from './queries/GetInvoicePayments.service'
import { GetSaleInvoiceState } from './queries/GetSaleInvoiceState.service';
import { GetSaleInvoiceMailState } from './queries/GetSaleInvoiceMailState.service';
import {
ISaleInvoiceCreateDTO,
ISaleInvoiceEditDTO,
ISaleInvoiceWriteoffDTO,
ISalesInvoicesFilter,
SaleInvoiceMailState,
@@ -20,6 +18,10 @@ import {
} from './SaleInvoice.types';
import { GetSaleInvoicesService } from './queries/GetSaleInvoices';
import { SendSaleInvoiceMail } from './commands/SendSaleInvoiceMail';
import {
CreateSaleInvoiceDto,
EditSaleInvoiceDto,
} from './dtos/SaleInvoice.dto';
@Injectable()
export class SaleInvoiceApplication {
@@ -44,7 +46,7 @@ export class SaleInvoiceApplication {
* @param {ISaleInvoiceCreateDTO} saleInvoiceDTO
* @returns {Promise<ISaleInvoice>}
*/
public createSaleInvoice(saleInvoiceDTO: ISaleInvoiceCreateDTO) {
public createSaleInvoice(saleInvoiceDTO: CreateSaleInvoiceDto) {
return this.createSaleInvoiceService.createSaleInvoice(saleInvoiceDTO);
}
@@ -55,7 +57,7 @@ export class SaleInvoiceApplication {
*/
public editSaleInvoice(
saleInvoiceId: number,
saleInvoiceDTO: ISaleInvoiceEditDTO,
saleInvoiceDTO: EditSaleInvoiceDto,
) {
return this.editSaleInvoiceService.editSaleInvoice(
saleInvoiceId,

View File

@@ -11,8 +11,6 @@ import {
Query,
} from '@nestjs/common';
import {
ISaleInvoiceCreateDTO,
ISaleInvoiceEditDTO,
ISaleInvoiceWriteoffDTO,
ISalesInvoicesFilter,
SaleInvoiceMailState,
@@ -27,6 +25,10 @@ import {
ApiResponse,
ApiTags,
} from '@nestjs/swagger';
import {
CreateSaleInvoiceDto,
EditSaleInvoiceDto,
} from './dtos/SaleInvoice.dto';
@Controller('sale-invoices')
@ApiTags('sale-invoices')
@@ -50,7 +52,7 @@ export class SaleInvoicesController {
status: 201,
description: 'Sale invoice created successfully',
})
createSaleInvoice(@Body() saleInvoiceDTO: ISaleInvoiceCreateDTO) {
createSaleInvoice(@Body() saleInvoiceDTO: CreateSaleInvoiceDto) {
return this.saleInvoiceApplication.createSaleInvoice(saleInvoiceDTO);
}
@@ -89,7 +91,7 @@ export class SaleInvoicesController {
})
editSaleInvoice(
@Param('id', ParseIntPipe) id: number,
@Body() saleInvoiceDTO: ISaleInvoiceEditDTO,
@Body() saleInvoiceDTO: EditSaleInvoiceDto,
) {
return this.saleInvoiceApplication.editSaleInvoice(id, saleInvoiceDTO);
}

View File

@@ -4,10 +4,6 @@ import * as R from 'ramda';
import * as moment from 'moment';
import '../../../utils/moment-mysql';
import * as composeAsync from 'async/compose';
import {
ISaleInvoiceCreateDTO,
ISaleInvoiceEditDTO,
} from '../SaleInvoice.types';
import { Customer } from '@/modules/Customers/models/Customer';
import { BranchTransactionDTOTransformer } from '@/modules/Branches/integrations/BranchTransactionDTOTransform';
import { WarehouseTransactionDTOTransform } from '@/modules/Warehouses/Integrations/WarehouseTransactionDTOTransform';
@@ -21,6 +17,10 @@ import { assocItemEntriesDefaultIndex } from '@/utils/associate-item-entries-ind
import { formatDateFields } from '@/utils/format-date-fields';
import { ItemEntriesTaxTransactions } from '@/modules/TaxRates/ItemEntriesTaxTransactions.service';
import { TenancyContext } from '@/modules/Tenancy/TenancyContext.service';
import {
CreateSaleInvoiceDto,
EditSaleInvoiceDto,
} from '../dtos/SaleInvoice.dto';
@Injectable()
export class CommandSaleInvoiceDTOTransformer {
@@ -54,7 +54,7 @@ export class CommandSaleInvoiceDTOTransformer {
*/
public async transformDTOToModel(
customer: Customer,
saleInvoiceDTO: ISaleInvoiceCreateDTO | ISaleInvoiceEditDTO,
saleInvoiceDTO: CreateSaleInvoiceDto | EditSaleInvoiceDto,
oldSaleInvoice?: SaleInvoice,
): Promise<SaleInvoice> {
const entriesModels = this.transformDTOEntriesToModels(saleInvoiceDTO);
@@ -140,7 +140,7 @@ export class CommandSaleInvoiceDTOTransformer {
* @returns {IItemEntry[]}
*/
private transformDTOEntriesToModels = (
saleInvoiceDTO: ISaleInvoiceCreateDTO | ISaleInvoiceEditDTO,
saleInvoiceDTO: CreateSaleInvoiceDto | EditSaleInvoiceDto,
): ItemEntry[] => {
return saleInvoiceDTO.entries.map((entry) => {
return ItemEntry.fromJson({

View File

@@ -16,6 +16,7 @@ import { SaleEstimate } from '@/modules/SaleEstimates/models/SaleEstimate';
import { Customer } from '@/modules/Customers/models/Customer';
import { events } from '@/common/events/events';
import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel';
import { CreateSaleInvoiceDto } from '../dtos/SaleInvoice.dto';
@Injectable()
export class CreateSaleInvoice {
@@ -57,8 +58,7 @@ export class CreateSaleInvoice {
* @return {Promise<ISaleInvoice>}
*/
public createSaleInvoice = async (
saleInvoiceDTO: ISaleInvoiceCreateDTO,
// authorizedUser: ITenantUser,
saleInvoiceDTO: CreateSaleInvoiceDto,
trx?: Knex.Transaction,
): Promise<SaleInvoice> => {
// Validate customer existance.
@@ -132,7 +132,7 @@ export class CreateSaleInvoice {
*/
private transformCreateDTOToModel = async (
customer: Customer,
saleInvoiceDTO: ISaleInvoiceCreateDTO,
saleInvoiceDTO: CreateSaleInvoiceDto,
) => {
return this.transformerDTO.transformDTOToModel(customer, saleInvoiceDTO);
};

View File

@@ -14,6 +14,7 @@ import { events } from '@/common/events/events';
import { SaleInvoice } from '../models/SaleInvoice';
import { Customer } from '@/modules/Customers/models/Customer';
import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel';
import { EditSaleInvoiceDto } from '../dtos/SaleInvoice.dto';
@Injectable()
export class EditSaleInvoice {
@@ -49,7 +50,7 @@ export class EditSaleInvoice {
*/
public async editSaleInvoice(
saleInvoiceId: number,
saleInvoiceDTO: ISaleInvoiceEditDTO,
saleInvoiceDTO: EditSaleInvoiceDto,
): Promise<SaleInvoice> {
// Retrieve the sale invoice or throw not found service error.
const oldSaleInvoice = await this.saleInvoiceModel()
@@ -139,15 +140,13 @@ export class EditSaleInvoice {
*/
private tranformEditDTOToModel = async (
customer: Customer,
saleInvoiceDTO: ISaleInvoiceEditDTO,
saleInvoiceDTO: EditSaleInvoiceDto,
oldSaleInvoice: SaleInvoice,
// authorizedUser: ITenantUser,
) => {
return this.transformerDTO.transformDTOToModel(
customer,
saleInvoiceDTO,
oldSaleInvoice,
// authorizedUser,
);
};
}

View File

@@ -0,0 +1,121 @@
import { ItemEntryDto } from '@/modules/TransactionItemEntry/dto/ItemEntry.dto';
import { Type } from 'class-transformer';
import {
IsArray,
IsBoolean,
IsDate,
IsEnum,
IsInt,
IsNotEmpty,
IsNumber,
IsOptional,
IsString,
Min,
MinLength,
ValidateNested,
} from 'class-validator';
enum DiscountType {
Percentage = 'percentage',
Amount = 'amount',
}
class PaymentMethodDto {
@IsInt()
paymentIntegrationId: number;
@IsBoolean()
enable: boolean;
}
class CommandSaleInvoiceDto {
@IsInt()
@IsNotEmpty()
customerId: number;
@IsDate()
@Type(() => Date)
@IsNotEmpty()
invoiceDate: Date;
@IsDate()
@Type(() => Date)
@IsNotEmpty()
dueDate: Date;
@IsOptional()
@IsString()
invoiceNo?: string;
@IsOptional()
@IsString()
referenceNo?: string;
@IsOptional()
@IsBoolean()
delivered: boolean = false;
@IsOptional()
@IsString()
invoiceMessage?: string;
@IsOptional()
@IsString()
termsConditions?: string;
@IsOptional()
@IsNumber()
@Min(0)
exchangeRate?: number;
@IsOptional()
@IsInt()
warehouseId?: number;
@IsOptional()
@IsInt()
branchId?: number;
@IsOptional()
@IsInt()
projectId?: number;
@IsOptional()
@IsBoolean()
isInclusiveTax?: boolean;
@IsArray()
@ValidateNested({ each: true })
@Type(() => ItemEntryDto)
@MinLength(1)
entries: ItemEntryDto[];
@IsOptional()
@IsInt()
pdfTemplateId?: number;
@IsOptional()
@IsArray()
@ValidateNested({ each: true })
@Type(() => PaymentMethodDto)
paymentMethods?: PaymentMethodDto[];
@IsOptional()
@IsNumber()
discount?: number;
@IsOptional()
@IsEnum(DiscountType)
discountType?: DiscountType;
@IsOptional()
@IsNumber()
adjustment?: number;
@IsOptional()
@IsInt()
fromEstimateId?: number;
}
export class CreateSaleInvoiceDto extends CommandSaleInvoiceDto {}
export class EditSaleInvoiceDto extends CommandSaleInvoiceDto {}

View File

@@ -4,12 +4,10 @@ import { CreateSaleReceipt } from './commands/CreateSaleReceipt.service';
import { GetSaleReceiptState } from './queries/GetSaleReceiptState.service';
import { SaleReceiptsPdfService } from './queries/SaleReceiptsPdf.service';
import { CloseSaleReceipt } from './commands/CloseSaleReceipt.service';
// import { GetSaleReceipts } from './queries/GetSaleReceipts';
import { DeleteSaleReceipt } from './commands/DeleteSaleReceipt.service';
import { GetSaleReceipt } from './queries/GetSaleReceipt.service';
import { EditSaleReceipt } from './commands/EditSaleReceipt.service';
import {
ISaleReceiptDTO,
ISaleReceiptState,
ISalesReceiptsFilter,
SaleReceiptMailOpts,
@@ -19,6 +17,7 @@ import { GetSaleReceiptsService } from './queries/GetSaleReceipts.service';
import { SaleReceipt } from './models/SaleReceipt';
import { IFilterMeta, IPaginationMeta } from '@/interfaces/Model';
import { SaleReceiptMailNotification } from './commands/SaleReceiptMailNotification';
import { CreateSaleReceiptDto, EditSaleReceiptDto } from './dtos/SaleReceipt.dto';
@Injectable()
export class SaleReceiptApplication {
@@ -40,7 +39,7 @@ export class SaleReceiptApplication {
* @returns {Promise<ISaleReceipt>}
*/
public async createSaleReceipt(
saleReceiptDTO: ISaleReceiptDTO,
saleReceiptDTO: CreateSaleReceiptDto,
trx?: Knex.Transaction,
) {
return this.createSaleReceiptService.createSaleReceipt(saleReceiptDTO, trx);
@@ -55,7 +54,7 @@ export class SaleReceiptApplication {
*/
public async editSaleReceipt(
saleReceiptId: number,
saleReceiptDTO: ISaleReceiptDTO,
saleReceiptDTO: EditSaleReceiptDto,
) {
return this.editSaleReceiptService.editSaleReceipt(
saleReceiptId,

View File

@@ -9,10 +9,13 @@ import {
Post,
Put,
} from '@nestjs/common';
import { ISaleReceiptDTO } from './types/SaleReceipts.types';
import { SaleReceiptApplication } from './SaleReceiptApplication.service';
import { PublicRoute } from '../Auth/Jwt.guard';
import { ApiOperation, ApiParam, ApiTags } from '@nestjs/swagger';
import {
CreateSaleReceiptDto,
EditSaleReceiptDto,
} from './dtos/SaleReceipt.dto';
@Controller('sale-receipts')
@ApiTags('sale-receipts')
@@ -22,7 +25,7 @@ export class SaleReceiptsController {
@Post()
@ApiOperation({ summary: 'Create a new sale receipt.' })
createSaleReceipt(@Body() saleReceiptDTO: ISaleReceiptDTO) {
createSaleReceipt(@Body() saleReceiptDTO: CreateSaleReceiptDto) {
return this.saleReceiptApplication.createSaleReceipt(saleReceiptDTO);
}
@@ -62,7 +65,7 @@ export class SaleReceiptsController {
})
editSaleReceipt(
@Param('id', ParseIntPipe) id: number,
@Body() saleReceiptDTO: ISaleReceiptDTO,
@Body() saleReceiptDTO: EditSaleReceiptDto,
) {
return this.saleReceiptApplication.editSaleReceipt(id, saleReceiptDTO);
}

View File

@@ -14,6 +14,7 @@ import { SaleReceipt } from '../models/SaleReceipt';
import { Customer } from '@/modules/Customers/models/Customer';
import { events } from '@/common/events/events';
import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel';
import { CreateSaleReceiptDto } from '../dtos/SaleReceipt.dto';
@Injectable()
export class CreateSaleReceipt {
@@ -47,7 +48,7 @@ export class CreateSaleReceipt {
* @return {Promise<ISaleReceipt>}
*/
public async createSaleReceipt(
saleReceiptDTO: ISaleReceiptDTO,
saleReceiptDTO: CreateSaleReceiptDto,
trx?: Knex.Transaction,
): Promise<SaleReceipt> {
// Retrieves the payment customer model.

View File

@@ -14,6 +14,7 @@ import { Contact } from '@/modules/Contacts/models/Contact';
import { events } from '@/common/events/events';
import { Customer } from '@/modules/Customers/models/Customer';
import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel';
import { EditSaleReceiptDto } from '../dtos/SaleReceipt.dto';
@Injectable()
export class EditSaleReceipt {
@@ -37,7 +38,10 @@ export class EditSaleReceipt {
* @param {ISaleReceipt} saleReceipt
* @return {void}
*/
public async editSaleReceipt(saleReceiptId: number, saleReceiptDTO: any) {
public async editSaleReceipt(
saleReceiptId: number,
saleReceiptDTO: EditSaleReceiptDto,
) {
// Retrieve sale receipt or throw not found service error.
const oldSaleReceipt = await this.saleReceiptModel()
.query()

View File

@@ -13,9 +13,9 @@ import { ItemEntry } from '@/modules/TransactionItemEntry/models/ItemEntry';
import { formatDateFields } from '@/utils/format-date-fields';
import { assocItemEntriesDefaultIndex } from '@/utils/associate-item-entries-index';
import { SaleReceipt } from '../models/SaleReceipt';
import { ISaleReceiptDTO } from '../types/SaleReceipts.types';
import { Customer } from '@/modules/Customers/models/Customer';
import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel';
import { CreateSaleReceiptDto, EditSaleReceiptDto } from '../dtos/SaleReceipt.dto';
@Injectable()
export class SaleReceiptDTOTransformer {
@@ -47,7 +47,7 @@ export class SaleReceiptDTOTransformer {
* @returns {ISaleReceipt}
*/
async transformDTOToModel(
saleReceiptDTO: ISaleReceiptDTO,
saleReceiptDTO: CreateSaleReceiptDto | EditSaleReceiptDto,
paymentCustomer: Customer,
oldSaleReceipt?: SaleReceipt,
): Promise<SaleReceipt> {

View File

@@ -0,0 +1,100 @@
import { ItemEntryDto } from '@/modules/TransactionItemEntry/dto/ItemEntry.dto';
import { Type } from 'class-transformer';
import {
IsArray,
IsBoolean,
IsDate,
IsEnum,
IsNumber,
IsOptional,
IsPositive,
IsString,
Min,
ValidateNested,
} from 'class-validator';
enum DiscountType {
Percentage = 'percentage',
Amount = 'amount',
}
class SaleReceiptEntryDto extends ItemEntryDto {}
class AttachmentDto {
@IsString()
key: string;
}
export class CommandSaleReceiptDto {
@IsNumber()
customerId: number;
@IsOptional()
@IsNumber()
@IsPositive()
exchangeRate?: number;
@IsNumber()
depositAccountId: number;
@IsDate()
receiptDate: Date;
@IsOptional()
@IsString()
receiptNumber?: string;
@IsOptional()
@IsString()
referenceNo?: string;
@IsBoolean()
closed: boolean = false;
@IsOptional()
@IsNumber()
warehouseId?: number;
@IsOptional()
@IsNumber()
branchId?: number;
@IsArray()
@ValidateNested({ each: true })
@Type(() => SaleReceiptEntryDto)
@Min(1)
entries: SaleReceiptEntryDto[];
@IsOptional()
@IsString()
receiptMessage?: string;
@IsOptional()
@IsString()
statement?: string;
@IsOptional()
@IsArray()
@ValidateNested({ each: true })
@Type(() => AttachmentDto)
attachments?: AttachmentDto[];
@IsOptional()
@IsNumber()
pdfTemplateId?: number;
@IsOptional()
@IsNumber()
discount?: number;
@IsOptional()
@IsEnum(DiscountType)
discountType?: DiscountType;
@IsOptional()
@IsNumber()
adjustment?: number;
}
export class CreateSaleReceiptDto extends CommandSaleReceiptDto {}
export class EditSaleReceiptDto extends CommandSaleReceiptDto {}

View File

@@ -8,6 +8,7 @@ import { Injectable } from '@nestjs/common';
import { ServiceError } from '@/modules/Items/ServiceError';
import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel';
import { IItemEntryDTO } from '@/modules/TransactionItemEntry/ItemEntry.types';
import { ItemEntryDto } from '@/modules/TransactionItemEntry/dto/ItemEntry.dto';
@Injectable()
export class CommandTaxRatesValidators {
@@ -67,11 +68,10 @@ export class CommandTaxRatesValidators {
/**
* Validates the tax codes of the given item entries DTO.
* @param {number} tenantId
* @param {IItemEntryDTO[]} itemEntriesDTO
* @throws {ServiceError}
*/
public async validateItemEntriesTaxCode(itemEntriesDTO: IItemEntryDTO[]) {
public async validateItemEntriesTaxCode(itemEntriesDTO: ItemEntryDto[]) {
const filteredTaxEntries = itemEntriesDTO.filter((e) => e.taxCode);
const taxCodes = filteredTaxEntries.map((e) => e.taxCode);
@@ -92,10 +92,10 @@ export class CommandTaxRatesValidators {
/**
* Validates the tax rate id of the given item entries DTO.
* @param {IItemEntryDTO[]} itemEntriesDTO
* @param {ItemEntryDto[]} itemEntriesDTO
* @throws {ServiceError}
*/
public async validateItemEntriesTaxCodeId(itemEntriesDTO: IItemEntryDTO[]) {
public async validateItemEntriesTaxCodeId(itemEntriesDTO: ItemEntryDto[]) {
const filteredTaxEntries = itemEntriesDTO.filter((e) => e.taxRateId);
const taxRatesIds = filteredTaxEntries.map((e) => e.taxRateId);

View File

@@ -0,0 +1,76 @@
import { DiscountType } from '@/common/types/Discount';
import {
IsEnum,
IsIn,
IsInt,
IsNotEmpty,
IsNumber,
IsOptional,
IsString,
} from 'class-validator';
export class ItemEntryDto {
@IsInt()
index: number;
@IsInt()
@IsNotEmpty()
itemId: number;
@IsNumber()
@IsNotEmpty()
rate: number;
@IsNumber()
@IsNotEmpty()
quantity: number;
@IsOptional()
@IsNumber()
discount?: number;
@IsOptional()
@IsEnum(DiscountType)
discountType?: DiscountType = DiscountType.Percentage;
@IsOptional()
@IsString()
description?: string;
@IsOptional()
@IsString()
taxCode?: string;
@IsOptional()
@IsInt()
taxRateId?: number;
@IsOptional()
@IsInt()
warehouseId?: number;
@IsOptional()
@IsInt()
projectId?: number;
@IsOptional()
@IsInt()
projectRefId?: number;
@IsOptional()
@IsString()
@IsIn(['TASK', 'BILL', 'EXPENSE'])
projectRefType?: string;
@IsOptional()
@IsNumber()
projectRefInvoicedAmount?: number;
@IsOptional()
@IsInt()
sellAccountId?: number;
@IsOptional()
@IsInt()
costAccountId?: number;
}

View File

@@ -8,6 +8,7 @@ import { QueryTransactionsLocking } from './queries/QueryTransactionsLocking';
import { PublicRoute } from '../Auth/Jwt.guard';
import { ApiOperation } from '@nestjs/swagger';
import { ApiTags } from '@nestjs/swagger';
import { CancelTransactionsLockingDto, TransactionsLockingDto, UnlockTransactionsLockingDto } from './dtos/TransactionsLocking.dto';
@Controller('transactions-locking')
@ApiTags('Transactions Locking')
@@ -22,7 +23,7 @@ export class TransactionsLockingController {
@ApiOperation({ summary: 'Lock all transactions for a module or all modules' })
async commandTransactionsLocking(
@Body('module') module: TransactionsLockingGroup,
@Body() transactionLockingDTO: ITransactionsLockingAllDTO,
@Body() transactionLockingDTO: TransactionsLockingDto,
) {
const transactionMeta =
await this.transactionsLockingService.commandTransactionsLocking(
@@ -39,7 +40,7 @@ export class TransactionsLockingController {
@ApiOperation({ summary: 'Cancel all transactions locking for a module or all modules' })
async cancelTransactionLocking(
@Body('module') module: TransactionsLockingGroup,
@Body() cancelLockingDTO: ICancelTransactionsLockingDTO,
@Body() cancelLockingDTO: CancelTransactionsLockingDto,
) {
const data = await this.transactionsLockingService.cancelTransactionLocking(
module,
@@ -55,7 +56,7 @@ export class TransactionsLockingController {
@ApiOperation({ summary: 'Partial unlock all transactions locking for a module or all modules' })
async unlockTransactionsLockingBetweenPeriod(
@Body('module') module: TransactionsLockingGroup,
@Body() unlockDTO: ITransactionLockingPartiallyDTO,
@Body() unlockDTO: UnlockTransactionsLockingDto,
) {
const transactionMeta =
await this.transactionsLockingService.unlockTransactionsLockingPartially(

View File

@@ -15,6 +15,7 @@ import { Injectable } from '@nestjs/common';
import { EventEmitter2 } from '@nestjs/event-emitter';
import { events } from '@/common/events/events';
import { ServiceError } from '@/modules/Items/ServiceError';
import { CancelTransactionsLockingDto, TransactionsLockingDto } from '../dtos/TransactionsLocking.dto';
const Modules = ['all', 'sales', 'purchases', 'financial'];
@@ -33,7 +34,7 @@ export class TransactionsLockingService {
*/
public commandTransactionsLocking = async (
module: TransactionsLockingGroup = TransactionsLockingGroup.All,
transactionLockingDTO: Partial<ITransactionsLockingAllDTO>,
transactionLockingDTO: TransactionsLockingDto,
): Promise<ITransactionMeta> => {
// Validate the transaction locking module.
this.validateTransactionsLockingModule(module);
@@ -70,7 +71,7 @@ export class TransactionsLockingService {
*/
public cancelTransactionLocking = async (
module: TransactionsLockingGroup = TransactionsLockingGroup.All,
cancelLockingDTO: ICancelTransactionsLockingDTO,
cancelLockingDTO: CancelTransactionsLockingDto,
): Promise<ITransactionMeta> => {
// Validate the transaction locking module.
this.validateTransactionsLockingModule(module);
@@ -137,10 +138,11 @@ export class TransactionsLockingService {
this.validateTransactionsLockingModule(module);
// Saves transactions locking settings.
await this.transactionsLockingRepo.saveTransactionsLocking(
module,
{ unlockFromDate: '', unlockToDate: '', partialUnlockReason: '' },
);
await this.transactionsLockingRepo.saveTransactionsLocking(module, {
unlockFromDate: '',
unlockToDate: '',
partialUnlockReason: '',
});
};
/**

View File

@@ -0,0 +1,25 @@
import { IsString } from 'class-validator';
import { IsNotEmpty } from 'class-validator';
import { IsDate } from 'class-validator';
export class TransactionsLockingDto {
@IsDate()
@IsNotEmpty()
lockToDate: Date;
@IsString()
@IsNotEmpty()
reason: string;
}
export class CancelTransactionsLockingDto {
@IsString()
@IsNotEmpty()
reason: string;
}
export class UnlockTransactionsLockingDto {
@IsDate()
@IsNotEmpty()
unlockFromDate: Date;
}

View File

@@ -9,13 +9,13 @@ import {
Query,
} from '@nestjs/common';
import { VendorCreditsApplicationService } from './VendorCreditsApplication.service';
import {
IVendorCreditCreateDTO,
IVendorCreditEditDTO,
IVendorCreditsQueryDTO,
} from './types/VendorCredit.types';
import { IVendorCreditsQueryDTO } from './types/VendorCredit.types';
import { PublicRoute } from '../Auth/Jwt.guard';
import { ApiOperation, ApiTags } from '@nestjs/swagger';
import {
CreateVendorCreditDto,
EditVendorCreditDto,
} from './dtos/VendorCredit.dto';
@Controller('vendor-credits')
@ApiTags('vendor-credits')
@@ -27,7 +27,7 @@ export class VendorCreditsController {
@Post()
@ApiOperation({ summary: 'Create a new vendor credit.' })
async createVendorCredit(@Body() dto: IVendorCreditCreateDTO) {
async createVendorCredit(@Body() dto: CreateVendorCreditDto) {
return this.vendorCreditsApplication.createVendorCredit(dto);
}
@@ -47,7 +47,7 @@ export class VendorCreditsController {
@ApiOperation({ summary: 'Edit the given vendor credit.' })
async editVendorCredit(
@Param('id') vendorCreditId: number,
@Body() dto: IVendorCreditEditDTO,
@Body() dto: EditVendorCreditDto,
) {
return this.vendorCreditsApplication.editVendorCredit(vendorCreditId, dto);
}

View File

@@ -8,6 +8,7 @@ import { IVendorCreditCreateDTO } from './types/VendorCredit.types';
import { Injectable } from '@nestjs/common';
import { OpenVendorCreditService } from './commands/OpenVendorCredit.service';
import { GetVendorCreditsService } from './queries/GetVendorCredits.service';
import { CreateVendorCreditDto, EditVendorCreditDto } from './dtos/VendorCredit.dto';
@Injectable()
export class VendorCreditsApplicationService {
@@ -28,11 +29,11 @@ export class VendorCreditsApplicationService {
/**
* Creates a new vendor credit.
* @param {IVendorCreditCreateDTO} dto - The vendor credit create DTO.
* @param {CreateVendorCreditDto} dto - The vendor credit create DTO.
* @param {Knex.Transaction} trx - The transaction.
* @returns {Promise<VendorCredit>} The created vendor credit.
*/
createVendorCredit(dto: IVendorCreditCreateDTO, trx?: Knex.Transaction) {
createVendorCredit(dto: CreateVendorCreditDto, trx?: Knex.Transaction) {
return this.createVendorCreditService.newVendorCredit(dto, trx);
}
@@ -48,13 +49,13 @@ export class VendorCreditsApplicationService {
/**
* Edits the given vendor credit.
* @param {number} vendorCreditId - The vendor credit id.
* @param {IVendorCreditEditDTO} dto - The vendor credit edit DTO.
* @param {EditVendorCreditDto} dto - The vendor credit edit DTO.
* @param {Knex.Transaction} trx - The transaction.
* @returns {Promise<VendorCredit>} The edited vendor credit.
*/
editVendorCredit(
vendorCreditId: number,
dto: IVendorCreditEditDTO,
dto: EditVendorCreditDto,
trx?: Knex.Transaction,
) {
return this.editVendorCreditService.editVendorCredit(

View File

@@ -2,7 +2,6 @@ import { Inject, Injectable } from '@nestjs/common';
import { Knex } from 'knex';
import {
IVendorCreditCreatedPayload,
IVendorCreditCreateDTO,
IVendorCreditCreatingPayload,
} from '@/modules/VendorCredit/types/VendorCredit.types';
import { VendorCredit } from '../models/VendorCredit';
@@ -13,6 +12,7 @@ import { ItemsEntriesService } from '@/modules/Items/ItemsEntries.service';
import { UnitOfWork } from '@/modules/Tenancy/TenancyDB/UnitOfWork.service';
import { VendorCreditDTOTransformService } from './VendorCreditDTOTransform.service';
import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel';
import { CreateVendorCreditDto } from '../dtos/VendorCredit.dto';
@Injectable()
export class CreateVendorCreditService {
@@ -42,7 +42,7 @@ export class CreateVendorCreditService {
* @param {Knex.Transaction} trx -
*/
public newVendorCredit = async (
vendorCreditCreateDTO: IVendorCreditCreateDTO,
vendorCreditCreateDTO: CreateVendorCreditDto,
trx?: Knex.Transaction,
) => {
// Triggers `onVendorCreditCreate` event.

View File

@@ -13,6 +13,7 @@ import { events } from '@/common/events/events';
import { Knex } from 'knex';
import { VendorCreditDTOTransformService } from './VendorCreditDTOTransform.service';
import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel';
import { EditVendorCreditDto } from '../dtos/VendorCredit.dto';
@Injectable()
export class EditVendorCreditService {
@@ -39,10 +40,11 @@ export class EditVendorCreditService {
/**
* Deletes the given vendor credit.
* @param {number} vendorCreditId - Vendor credit id.
* @param {EditVendorCreditDto} vendorCreditDto -
*/
public editVendorCredit = async (
vendorCreditId: number,
vendorCreditDTO: IVendorCreditEditDTO,
vendorCreditDTO: EditVendorCreditDto,
trx?: Knex.Transaction,
) => {
// Retrieve the vendor credit or throw not found service error.

View File

@@ -2,11 +2,7 @@ import * as moment from 'moment';
import { omit } from 'lodash';
import * as R from 'ramda';
import { ERRORS } from '../constants';
import {
IVendorCreditCreateDTO,
IVendorCreditEditDTO,
IVendorCreditEntryDTO,
} from '../types/VendorCredit.types';
import { IVendorCreditEntryDTO } from '../types/VendorCredit.types';
import { ItemsEntriesService } from '@/modules/Items/ItemsEntries.service';
import { BranchTransactionDTOTransformer } from '@/modules/Branches/integrations/BranchTransactionDTOTransform';
import { WarehouseTransactionDTOTransform } from '@/modules/Warehouses/Integrations/WarehouseTransactionDTOTransform';
@@ -15,6 +11,10 @@ import { assocItemEntriesDefaultIndex } from '@/utils/associate-item-entries-ind
import { VendorCreditAutoIncrementService } from './VendorCreditAutoIncrement.service';
import { ServiceError } from '@/modules/Items/ServiceError';
import { Injectable } from '@nestjs/common';
import {
CreateVendorCreditDto,
EditVendorCreditDto,
} from '../dtos/VendorCredit.dto';
@Injectable()
export class VendorCreditDTOTransformService {
@@ -39,7 +39,7 @@ export class VendorCreditDTOTransformService {
* @returns {VendorCredit}
*/
public transformCreateEditDTOToModel = async (
vendorCreditDTO: IVendorCreditCreateDTO | IVendorCreditEditDTO,
vendorCreditDTO: CreateVendorCreditDto | EditVendorCreditDto,
vendorCurrencyCode: string,
oldVendorCredit?: VendorCredit,
): Promise<VendorCredit> => {

View File

@@ -0,0 +1,83 @@
import { ItemEntryDto } from '@/modules/TransactionItemEntry/dto/ItemEntry.dto';
import { Type } from 'class-transformer';
import {
IsArray,
IsEnum,
IsNumber,
IsOptional,
IsString,
ValidateNested,
} from 'class-validator';
enum DiscountType {
Percentage = 'percentage',
Amount = 'amount',
}
class VendorCreditEntryDto extends ItemEntryDto {}
class AttachmentDto {
@IsString()
key: string;
}
export class CommandVendorCreditDto {
@IsNumber()
vendorId: number;
@IsNumber()
@IsOptional()
exchangeRate?: number;
@IsString()
@IsOptional()
vendorCreditNumber?: string;
@IsString()
@IsOptional()
referenceNo?: string;
@IsString() // ISO8601 date string
vendorCreditDate: string;
@IsString()
@IsOptional()
note?: string;
@IsOptional()
open: boolean = false;
@IsNumber()
@IsOptional()
warehouseId?: number;
@IsNumber()
@IsOptional()
branchId?: number;
@IsArray()
@ValidateNested({ each: true })
@Type(() => VendorCreditEntryDto)
entries: VendorCreditEntryDto[];
@IsArray()
@ValidateNested({ each: true })
@Type(() => AttachmentDto)
@IsOptional()
attachments?: AttachmentDto[];
@IsNumber()
@IsOptional()
discount?: number;
@IsEnum(DiscountType)
@IsOptional()
discountType?: DiscountType;
@IsNumber()
@IsOptional()
adjustment?: number;
}
export class CreateVendorCreditDto extends CommandVendorCreditDto {}
export class EditVendorCreditDto extends CommandVendorCreditDto {}

View File

@@ -5,6 +5,10 @@ import { IRefundVendorCreditDTO } from '@/modules/VendorCreditsRefund/types/Vend
import { IItemEntryDTO } from '@/modules/TransactionItemEntry/ItemEntry.types';
import { DiscountType } from '@/common/types/Discount';
import { IDynamicListFilter } from '@/modules/DynamicListing/DynamicFilter/DynamicFilter.types';
import {
CreateVendorCreditDto,
EditVendorCreditDto,
} from '../dtos/VendorCredit.dto';
export enum VendorCreditAction {
Create = 'Create',
@@ -39,7 +43,7 @@ export interface IVendorCreditDTO {
discount?: number;
discountType?: DiscountType;
adjustment?: number;
}
@@ -54,14 +58,13 @@ export interface IVendorCreditCreatePayload {
export interface IVendorCreditCreatingPayload {
vendorCredit: VendorCredit;
vendorCreditId: number;
vendorCreditCreateDTO: IVendorCreditCreateDTO;
vendorCreditCreateDTO: CreateVendorCreditDto;
trx: Knex.Transaction;
}
export interface IVendorCreditCreatedPayload {
// tenantId: number;
vendorCredit: VendorCredit;
vendorCreditCreateDTO: IVendorCreditCreateDTO;
vendorCreditCreateDTO: CreateVendorCreditDto;
trx: Knex.Transaction;
}
@@ -83,18 +86,15 @@ export interface IVendorCreditDeletingPayload {
// Edit Vendor Credit Events
// ------------------------
export interface IVendorCreditEditingPayload {
// tenantId: number;
oldVendorCredit: VendorCredit;
vendorCreditDTO: IVendorCreditEditDTO;
vendorCreditDTO: EditVendorCreditDto;
trx: Knex.Transaction;
}
export interface IVendorCreditEditedPayload {
// tenantId: number;
oldVendorCredit: VendorCredit;
vendorCredit: VendorCredit;
// vendorCreditId: number;
vendorCreditDTO: IVendorCreditEditDTO;
vendorCreditDTO: EditVendorCreditDto;
trx: Knex.Transaction;
}

View File

@@ -41,8 +41,7 @@ export class WarehousesDTOValidators {
/**
* Validate the warehouse existance of
* @param {number} tenantId
* @param {IWarehouseTransactionDTO} saleInvoiceDTO
* @param {IWarehouseTransactionDTO} saleInvoiceDTO
* @returns
*/
public validateDTOWarehouseWhenActive = async (

View File

@@ -1,8 +1,6 @@
import {
ICreateWarehouseTransferDTO,
IEditWarehouseTransferDTO,
IGetWarehousesTransfersFilterDTO,
} from '@/modules/Warehouses/Warehouse.types';
import { Injectable } from '@nestjs/common';
import { ModelObject } from 'objection';
import { IGetWarehousesTransfersFilterDTO } from '@/modules/Warehouses/Warehouse.types';
import { CreateWarehouseTransfer } from './commands/CreateWarehouseTransfer';
import { DeleteWarehouseTransfer } from './commands/DeleteWarehouseTransfer';
import { EditWarehouseTransfer } from './commands/EditWarehouseTransfer';
@@ -10,9 +8,11 @@ import { GetWarehouseTransfer } from './queries/GetWarehouseTransfer';
import { GetWarehouseTransfers } from './queries/GetWarehouseTransfers';
import { InitiateWarehouseTransfer } from './commands/InitiateWarehouseTransfer';
import { TransferredWarehouseTransfer } from './commands/TransferredWarehouseTransfer';
import { Injectable } from '@nestjs/common';
import { WarehouseTransfer } from './models/WarehouseTransfer';
import { ModelObject } from 'objection';
import {
CreateWarehouseTransferDto,
EditWarehouseTransferDto,
} from './dtos/WarehouseTransfer.dto';
@Injectable()
export class WarehouseTransferApplication {
@@ -32,7 +32,7 @@ export class WarehouseTransferApplication {
* @returns {Promise<ModelObject<WarehouseTransfer>>}
*/
public createWarehouseTransfer = (
createWarehouseTransferDTO: ICreateWarehouseTransferDTO,
createWarehouseTransferDTO: CreateWarehouseTransferDto,
): Promise<ModelObject<WarehouseTransfer>> => {
return this.createWarehouseTransferService.createWarehouseTransfer(
createWarehouseTransferDTO,
@@ -46,7 +46,7 @@ export class WarehouseTransferApplication {
*/
public editWarehouseTransfer = (
warehouseTransferId: number,
editWarehouseTransferDTO: IEditWarehouseTransferDTO,
editWarehouseTransferDTO: EditWarehouseTransferDto,
): Promise<ModelObject<WarehouseTransfer>> => {
return this.editWarehouseTransferService.editWarehouseTransfer(
warehouseTransferId,
@@ -69,8 +69,8 @@ export class WarehouseTransferApplication {
/**
* Retrieves warehouse transfer transaction.
* @param {number} warehouseTransferId
* @returns {Promise<IWarehouseTransfer>}
* @param {number} warehouseTransferId - Warehouse transfer id.
* @returns {Promise<ModelObject<WarehouseTransfer>>}
*/
public getWarehouseTransfer = (
warehouseTransferId: number,

Some files were not shown because too many files have changed in this diff Show More