This commit is contained in:
Ahmed Bouhuolia
2026-01-24 13:59:43 +02:00
parent ca910ee489
commit 04d065b969
29 changed files with 174 additions and 95 deletions

View File

@@ -17,7 +17,7 @@ export class BillBranchValidateSubscriber {
* Validate branch existance on bill creating.
* @param {IBillCreatingPayload} payload
*/
@OnEvent(events.bill.onCreating)
@OnEvent(events.bill.onCreating, { suppressErrors: false })
async validateBranchExistanceOnBillCreating({
billDTO,
}: IBillCreatingPayload) {
@@ -30,7 +30,7 @@ export class BillBranchValidateSubscriber {
* Validate branch existance once bill editing.
* @param {IBillEditingPayload} payload
*/
@OnEvent(events.bill.onEditing)
@OnEvent(events.bill.onEditing, { suppressErrors: false })
async validateBranchExistanceOnBillEditing({ billDTO }: IBillEditingPayload) {
await this.validateBranchExistance.validateTransactionBranchWhenActive(
billDTO.branchId,

View File

@@ -14,7 +14,7 @@ export class CashflowBranchDTOValidatorSubscriber {
* Validate branch existance once cashflow transaction creating.
* @param {ICommandCashflowCreatingPayload} payload
*/
@OnEvent(events.cashflow.onTransactionCreating)
@OnEvent(events.cashflow.onTransactionCreating, { suppressErrors: false })
async validateBranchExistanceOnCashflowTransactionCreating({
newTransactionDTO,
}: ICommandCashflowCreatingPayload) {

View File

@@ -15,13 +15,13 @@ import {
export class ContactBranchValidateSubscriber {
constructor(
private readonly validateBranchExistance: ValidateBranchExistance,
) { }
) {}
/**
* Validate branch existance on customer creating.
* @param {ICustomerEventCreatingPayload} payload
*/
@OnEvent(events.customers.onCreating)
@OnEvent(events.customers.onCreating, { suppressErrors: false })
async validateBranchExistanceOnCustomerCreating({
customerDTO,
}: ICustomerEventCreatingPayload) {
@@ -37,7 +37,7 @@ export class ContactBranchValidateSubscriber {
* Validate branch existance once customer opening balance editing.
* @param {ICustomerOpeningBalanceEditingPayload} payload
*/
@OnEvent(events.customers.onOpeningBalanceChanging)
@OnEvent(events.customers.onOpeningBalanceChanging, { suppressErrors: false })
async validateBranchExistanceOnCustomerOpeningBalanceEditing({
openingBalanceEditDTO,
}: ICustomerOpeningBalanceEditingPayload) {
@@ -52,7 +52,7 @@ export class ContactBranchValidateSubscriber {
* Validates the branch existance on vendor creating.
* @param {IVendorEventCreatingPayload} payload
*/
@OnEvent(events.vendors.onCreating)
@OnEvent(events.vendors.onCreating, { suppressErrors: false })
async validateBranchExistanceonVendorCreating({
vendorDTO,
}: IVendorEventCreatingPayload) {
@@ -68,7 +68,7 @@ export class ContactBranchValidateSubscriber {
* Validate branch existance once the vendor opening balance editing.
* @param {IVendorOpeningBalanceEditingPayload} payload
*/
@OnEvent(events.vendors.onOpeningBalanceChanging)
@OnEvent(events.vendors.onOpeningBalanceChanging, { suppressErrors: false })
async validateBranchExistanceOnVendorOpeningBalanceEditing({
openingBalanceEditDTO,
}: IVendorOpeningBalanceEditingPayload) {

View File

@@ -15,7 +15,7 @@ export class CreditNoteBranchValidateSubscriber {
* Validate branch existance on credit note creating.
* @param {ICreditNoteCreatingPayload} payload
*/
@OnEvent(events.creditNote.onCreating)
@OnEvent(events.creditNote.onCreating, { suppressErrors: false })
async validateBranchExistanceOnCreditCreating({
creditNoteDTO,
}: ICreditNoteCreatingPayload) {
@@ -28,7 +28,7 @@ export class CreditNoteBranchValidateSubscriber {
* Validate branch existance once credit note editing.
* @param {ICreditNoteEditingPayload} payload
*/
@OnEvent(events.creditNote.onEditing)
@OnEvent(events.creditNote.onEditing, { suppressErrors: false })
async validateBranchExistanceOnCreditEditing({
creditNoteEditDTO,
}: ICreditNoteEditingPayload) {

View File

@@ -14,7 +14,7 @@ export class CreditNoteRefundBranchValidateSubscriber {
* Validate branch existance on refund credit note creating.
* @param {IRefundCreditNoteCreatingPayload} payload
*/
@OnEvent(events.creditNote.onRefundCreating)
@OnEvent(events.creditNote.onRefundCreating, { suppressErrors: false })
async validateBranchExistanceOnCreditRefundCreating({
newCreditNoteDTO,
}: IRefundCreditNoteCreatingPayload) {

View File

@@ -16,7 +16,7 @@ export class ExpenseBranchValidateSubscriber {
* Validate branch existance once expense transaction creating.
* @param {IExpenseCreatingPayload} payload
*/
@OnEvent(events.expenses.onCreating)
@OnEvent(events.expenses.onCreating, { suppressErrors: false })
async validateBranchExistanceOnExpenseCreating({
expenseDTO,
}: IExpenseCreatingPayload) {
@@ -29,7 +29,7 @@ export class ExpenseBranchValidateSubscriber {
* Validate branch existance once expense transaction editing.
* @param {IExpenseEventEditingPayload} payload
*/
@OnEvent(events.expenses.onEditing)
@OnEvent(events.expenses.onEditing, { suppressErrors: false })
async validateBranchExistanceOnExpenseEditing({
expenseDTO,
}: IExpenseEventEditingPayload) {

View File

@@ -14,7 +14,7 @@ export class InventoryAdjustmentBranchValidateSubscriber {
* Validate branch existance on inventory adjustment creating.
* @param {IInventoryAdjustmentCreatingPayload} payload
*/
@OnEvent(events.inventoryAdjustment.onQuickCreating)
@OnEvent(events.inventoryAdjustment.onQuickCreating, { suppressErrors: false })
async validateBranchExistanceOnInventoryCreating({
quickAdjustmentDTO,
}: IInventoryAdjustmentCreatingPayload) {

View File

@@ -17,7 +17,7 @@ export class InvoiceBranchValidateSubscriber {
* Validate branch existance on invoice creating.
* @param {ISaleInvoiceCreatingPayload} payload
*/
@OnEvent(events.saleInvoice.onCreating)
@OnEvent(events.saleInvoice.onCreating, { suppressErrors: false })
async validateBranchExistanceOnInvoiceCreating({
saleInvoiceDTO,
}: ISaleInvoiceCreatingPaylaod) {
@@ -30,7 +30,7 @@ export class InvoiceBranchValidateSubscriber {
* Validate branch existance once invoice editing.
* @param {ISaleInvoiceEditingPayload} payload
*/
@OnEvent(events.saleInvoice.onEditing)
@OnEvent(events.saleInvoice.onEditing, { suppressErrors: false })
async validateBranchExistanceOnInvoiceEditing({
saleInvoiceDTO,
}: ISaleInvoiceEditingPayload) {

View File

@@ -17,7 +17,7 @@ export class PaymentMadeBranchValidateSubscriber {
* Validate branch existance on estimate creating.
* @param {ISaleEstimateCreatedPayload} payload
*/
@OnEvent(events.billPayment.onCreating)
@OnEvent(events.billPayment.onCreating, { suppressErrors: false })
async validateBranchExistanceOnPaymentCreating({
billPaymentDTO,
}: IBillPaymentCreatingPayload) {
@@ -30,7 +30,7 @@ export class PaymentMadeBranchValidateSubscriber {
* Validate branch existance once estimate editing.
* @param {ISaleEstimateEditingPayload} payload
*/
@OnEvent(events.billPayment.onEditing)
@OnEvent(events.billPayment.onEditing, { suppressErrors: false })
async validateBranchExistanceOnPaymentEditing({
billPaymentDTO,
}: IBillPaymentEditingPayload) {

View File

@@ -17,7 +17,7 @@ export class PaymentReceiveBranchValidateSubscriber {
* Validate branch existance on estimate creating.
* @param {IPaymentReceivedCreatingPayload} payload
*/
@OnEvent(events.paymentReceive.onCreating)
@OnEvent(events.paymentReceive.onCreating, { suppressErrors: false })
async validateBranchExistanceOnPaymentCreating({
paymentReceiveDTO,
}: IPaymentReceivedCreatingPayload) {
@@ -30,7 +30,7 @@ export class PaymentReceiveBranchValidateSubscriber {
* Validate branch existance once estimate editing.
* @param {IPaymentReceivedEditingPayload} payload
*/
@OnEvent(events.paymentReceive.onEditing)
@OnEvent(events.paymentReceive.onEditing, { suppressErrors: false })
async validateBranchExistanceOnPaymentEditing({
paymentReceiveDTO,
}: IPaymentReceivedEditingPayload) {

View File

@@ -17,7 +17,7 @@ export class SaleEstimateBranchValidateSubscriber {
* Validate branch existance on estimate creating.
* @param {ISaleEstimateCreatedPayload} payload
*/
@OnEvent(events.saleEstimate.onCreating)
@OnEvent(events.saleEstimate.onCreating, { suppressErrors: false })
async validateBranchExistanceOnEstimateCreating({
estimateDTO,
}: ISaleEstimateCreatingPayload) {
@@ -30,7 +30,7 @@ export class SaleEstimateBranchValidateSubscriber {
* Validate branch existance once estimate editing.
* @param {ISaleEstimateEditingPayload} payload
*/
@OnEvent(events.saleEstimate.onEditing)
@OnEvent(events.saleEstimate.onEditing, { suppressErrors: false })
async validateBranchExistanceOnEstimateEditing({
estimateDTO,
}: ISaleEstimateEditingPayload) {

View File

@@ -17,7 +17,7 @@ export class SaleReceiptBranchValidateSubscriber {
* Validate branch existance on estimate creating.
* @param {ISaleReceiptCreatingPayload} payload
*/
@OnEvent(events.saleReceipt.onCreating)
@OnEvent(events.saleReceipt.onCreating, { suppressErrors: false })
async validateBranchExistanceOnInvoiceCreating({
saleReceiptDTO,
}: ISaleReceiptCreatingPayload) {
@@ -30,7 +30,7 @@ export class SaleReceiptBranchValidateSubscriber {
* Validate branch existance once estimate editing.
* @param {ISaleReceiptEditingPayload} payload
*/
@OnEvent(events.saleReceipt.onEditing)
@OnEvent(events.saleReceipt.onEditing, { suppressErrors: false })
async validateBranchExistanceOnInvoiceEditing({
saleReceiptDTO,
}: ISaleReceiptEditingPayload) {

View File

@@ -17,7 +17,7 @@ export class VendorCreditBranchValidateSubscriber {
* Validate branch existance on estimate creating.
* @param {ISaleEstimateCreatedPayload} payload
*/
@OnEvent(events.vendorCredit.onCreating)
@OnEvent(events.vendorCredit.onCreating, { suppressErrors: false })
async validateBranchExistanceOnCreditCreating({
vendorCreditCreateDTO,
}: IVendorCreditCreatingPayload) {
@@ -30,7 +30,7 @@ export class VendorCreditBranchValidateSubscriber {
* Validate branch existance once estimate editing.
* @param {ISaleEstimateEditingPayload} payload
*/
@OnEvent(events.vendorCredit.onEditing)
@OnEvent(events.vendorCredit.onEditing, { suppressErrors: false })
async validateBranchExistanceOnCreditEditing({
vendorCreditDTO,
}: IVendorCreditEditingPayload) {

View File

@@ -14,7 +14,7 @@ export class VendorCreditRefundBranchValidateSubscriber {
* Validate branch existance on refund credit note creating.
* @param {IRefundVendorCreditCreatingPayload} payload
*/
@OnEvent(events.vendorCredit.onRefundCreating)
@OnEvent(events.vendorCredit.onRefundCreating, { suppressErrors: false })
async validateBranchExistanceOnCreditRefundCreating({
refundVendorCreditDTO,
}: IRefundVendorCreditCreatingPayload) {

View File

@@ -5,6 +5,7 @@ import { AccountRepository } from '@/modules/Accounts/repositories/Account.repos
import { CustomerGLEntries } from './CustomerGLEntries';
import { Customer } from './models/Customer';
import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel';
import { Account } from '../Accounts/models/Account.model';
@Injectable()
export class CustomerGLEntriesStorage {
@@ -13,6 +14,9 @@ export class CustomerGLEntriesStorage {
private readonly accountRepository: AccountRepository,
private readonly customerGLEntries: CustomerGLEntries,
@Inject(Account.name)
private readonly accountModel: TenantModelProxy<typeof Account>,
@Inject(Customer.name)
private readonly customerModel: TenantModelProxy<typeof Customer>,
) { }
@@ -29,9 +33,10 @@ export class CustomerGLEntriesStorage {
.findById(customerId);
// Finds the income account.
const incomeAccount = await this.accountRepository.findOne({
slug: 'other-income',
});
const incomeAccount = await this.accountModel()
.query(trx)
.findOne({ slug: 'other-income' });
// Find or create the A/R account.
const ARAccount =
await this.accountRepository.findOrCreateAccountReceivable(

View File

@@ -9,10 +9,7 @@ import {
Query,
} from '@nestjs/common';
import { CustomersApplication } from './CustomersApplication.service';
import {
ICustomerOpeningBalanceEditDTO,
ICustomersFilter,
} from './types/Customers.types';
import { CustomerOpeningBalanceEditDto } from './dtos/CustomerOpeningBalanceEdit.dto';
import {
ApiOperation,
ApiResponse,
@@ -106,7 +103,7 @@ export class CustomersController {
})
editOpeningBalance(
@Param('id') customerId: number,
@Body() openingBalanceDTO: ICustomerOpeningBalanceEditDTO,
@Body() openingBalanceDTO: CustomerOpeningBalanceEditDto,
) {
return this.customersApplication.editOpeningBalance(
customerId,

View File

@@ -25,7 +25,12 @@ import { CustomerGLEntriesStorage } from './CustomerGLEntriesStorage';
import { CustomerWriteGLOpeningBalanceSubscriber } from './subscribers/CustomerGLEntriesSubscriber';
@Module({
imports: [TenancyDatabaseModule, DynamicListModule, LedgerModule, AccountsModule],
imports: [
TenancyDatabaseModule,
DynamicListModule,
LedgerModule,
AccountsModule,
],
controllers: [CustomersController],
providers: [
ActivateCustomer,
@@ -51,4 +56,4 @@ import { CustomerWriteGLOpeningBalanceSubscriber } from './subscribers/CustomerG
CustomerWriteGLOpeningBalanceSubscriber,
],
})
export class CustomersModule { }
export class CustomersModule {}

View File

@@ -4,10 +4,7 @@ import { CreateCustomer } from './commands/CreateCustomer.service';
import { EditCustomer } from './commands/EditCustomer.service';
import { DeleteCustomer } from './commands/DeleteCustomer.service';
import { EditOpeningBalanceCustomer } from './commands/EditOpeningBalanceCustomer.service';
import {
ICustomerOpeningBalanceEditDTO,
ICustomersFilter,
} from './types/Customers.types';
import { CustomerOpeningBalanceEditDto } from './dtos/CustomerOpeningBalanceEdit.dto';
import { CreateCustomerDto } from './dtos/CreateCustomer.dto';
import { EditCustomerDto } from './dtos/EditCustomer.dto';
import { GetCustomers } from './queries/GetCustomers.service';
@@ -18,12 +15,12 @@ import { ValidateBulkDeleteCustomersService } from './ValidateBulkDeleteCustomer
@Injectable()
export class CustomersApplication {
constructor(
private getCustomerService: GetCustomerService,
private createCustomerService: CreateCustomer,
private editCustomerService: EditCustomer,
private deleteCustomerService: DeleteCustomer,
private editOpeningBalanceService: EditOpeningBalanceCustomer,
private getCustomersService: GetCustomers,
private readonly getCustomerService: GetCustomerService,
private readonly createCustomerService: CreateCustomer,
private readonly editCustomerService: EditCustomer,
private readonly deleteCustomerService: DeleteCustomer,
private readonly editOpeningBalanceService: EditOpeningBalanceCustomer,
private readonly getCustomersService: GetCustomers,
private readonly bulkDeleteCustomersService: BulkDeleteCustomersService,
private readonly validateBulkDeleteCustomersService: ValidateBulkDeleteCustomersService,
) {}
@@ -72,7 +69,7 @@ export class CustomersApplication {
*/
public editOpeningBalance = (
customerId: number,
openingBalanceEditDTO: ICustomerOpeningBalanceEditDTO,
openingBalanceEditDTO: CustomerOpeningBalanceEditDto,
) => {
return this.editOpeningBalanceService.changeOpeningBalance(
customerId,
@@ -82,7 +79,7 @@ export class CustomersApplication {
/**
* Retrieve customers paginated list.
* @param {ICustomersFilter} filter - Cusotmers filter.
* @param {GetCustomersQueryDto} filter - Cusotmers filter.
*/
public getCustomers = (filterDTO: GetCustomersQueryDto) => {
return this.getCustomersService.getCustomersList(filterDTO);

View File

@@ -31,7 +31,7 @@ export class CreateCustomer {
/**
* Creates a new customer.
* @param {ICustomerNewDTO} customerDTO
* @param {CreateCustomerDto} customerDTO
* @return {Promise<ICustomer>}
*/
public async createCustomer(

View File

@@ -1,10 +1,10 @@
import { Inject, Injectable } from '@nestjs/common';
import { Knex } from 'knex';
import {
ICustomerOpeningBalanceEditDTO,
ICustomerOpeningBalanceEditedPayload,
ICustomerOpeningBalanceEditingPayload,
} from '../types/Customers.types';
import { CustomerOpeningBalanceEditDto } from '../dtos/CustomerOpeningBalanceEdit.dto';
import { EventEmitter2 } from '@nestjs/event-emitter';
import { UnitOfWork } from '@/modules/Tenancy/TenancyDB/UnitOfWork.service';
import { Customer } from '../models/Customer';
@@ -29,11 +29,11 @@ export class EditOpeningBalanceCustomer {
/**
* Changes the opening balance of the given customer.
* @param {number} customerId - Customer ID.
* @param {ICustomerOpeningBalanceEditDTO} openingBalanceEditDTO
* @param {CustomerOpeningBalanceEditDto} openingBalanceEditDTO
*/
public async changeOpeningBalance(
customerId: number,
openingBalanceEditDTO: ICustomerOpeningBalanceEditDTO,
openingBalanceEditDTO: CustomerOpeningBalanceEditDto,
): Promise<Customer> {
// Retrieves the old customer or throw not found error.
const oldCustomer = await this.customerModel()

View File

@@ -4,6 +4,7 @@ import {
IsNotEmpty,
IsNumber,
IsString,
ValidateIf,
} from 'class-validator';
import { ApiProperty } from '@nestjs/swagger';
import { IsOptional, ToNumber } from '@/common/decorators/Validators';
@@ -40,10 +41,11 @@ export class CreateCustomerDto extends ContactAddressDto {
@ApiProperty({
required: false,
description: 'Opening balance date',
description: 'Opening balance date (required when openingBalance is provided)',
example: '2024-01-01',
})
@IsOptional()
@ValidateIf((o) => o.openingBalance != null)
@IsNotEmpty({ message: 'openingBalanceAt is required when openingBalance is provided' })
@IsString()
openingBalanceAt?: string;

View File

@@ -0,0 +1,44 @@
import { IsNotEmpty, IsNumber, IsString } from 'class-validator';
import { ApiProperty } from '@nestjs/swagger';
import { IsOptional, ToNumber } from '@/common/decorators/Validators';
export class CustomerOpeningBalanceEditDto {
@ApiProperty({
required: true,
description: 'Opening balance',
example: 5000.0,
})
@IsNumber()
@IsNotEmpty()
@ToNumber()
openingBalance: number;
@ApiProperty({
required: false,
description: 'Opening balance date',
example: '2024-01-01',
})
@IsOptional()
@IsString()
openingBalanceAt?: string;
@ApiProperty({
required: false,
description: 'Opening balance exchange rate',
example: 1.0,
})
@IsOptional()
@IsNumber()
@ToNumber()
openingBalanceExchangeRate?: number;
@ApiProperty({
required: false,
description: 'Opening balance branch ID',
example: 101,
})
@IsOptional()
@IsNumber()
@ToNumber()
openingBalanceBranchId?: number;
}

View File

@@ -4,6 +4,7 @@ import { IContactAddressDTO } from '@/modules/Contacts/types/Contacts.types';
import { IDynamicListFilter } from '@/modules/DynamicListing/DynamicFilter/DynamicFilter.types';
import { IFilterMeta, IPaginationMeta } from '@/interfaces/Model';
import { CreateCustomerDto } from '../dtos/CreateCustomer.dto';
import { CustomerOpeningBalanceEditDto } from '../dtos/CustomerOpeningBalanceEdit.dto';
import { EditCustomerDto } from '../dtos/EditCustomer.dto';
// Customer Interfaces.
@@ -113,23 +114,16 @@ export enum VendorAction {
View = 'View',
}
export interface ICustomerOpeningBalanceEditDTO {
openingBalance: number;
openingBalanceAt: Date | string;
openingBalanceExchangeRate: number;
openingBalanceBranchId?: number;
}
export interface ICustomerOpeningBalanceEditingPayload {
oldCustomer: Customer;
openingBalanceEditDTO: ICustomerOpeningBalanceEditDTO;
openingBalanceEditDTO: CustomerOpeningBalanceEditDto;
trx?: Knex.Transaction;
}
export interface ICustomerOpeningBalanceEditedPayload {
customer: Customer;
oldCustomer: Customer;
openingBalanceEditDTO: ICustomerOpeningBalanceEditDTO;
openingBalanceEditDTO: CustomerOpeningBalanceEditDto;
trx: Knex.Transaction;
}

View File

@@ -9,10 +9,7 @@ import {
Query,
} from '@nestjs/common';
import { VendorsApplication } from './VendorsApplication.service';
import {
IVendorOpeningBalanceEditDTO,
IVendorsFilter,
} from './types/Vendors.types';
import { VendorOpeningBalanceEditDto } from './dtos/VendorOpeningBalanceEdit.dto';
import {
ApiOperation,
ApiResponse,
@@ -68,7 +65,7 @@ export class VendorsController {
@ApiOperation({ summary: 'Edit the given vendor opening balance.' })
editOpeningBalance(
@Param('id') vendorId: number,
@Body() openingBalanceDTO: IVendorOpeningBalanceEditDTO,
@Body() openingBalanceDTO: VendorOpeningBalanceEditDto,
) {
return this.vendorsApplication.editOpeningBalance(
vendorId,

View File

@@ -5,10 +5,7 @@ import { EditVendorService } from './commands/EditVendor.service';
import { DeleteVendorService } from './commands/DeleteVendor.service';
import { EditOpeningBalanceVendorService } from './commands/EditOpeningBalanceVendor.service';
import { GetVendorService } from './queries/GetVendor';
import {
IVendorOpeningBalanceEditDTO,
IVendorsFilter,
} from './types/Vendors.types';
import { VendorOpeningBalanceEditDto } from './dtos/VendorOpeningBalanceEdit.dto';
import { GetVendorsService } from './queries/GetVendors.service';
import { CreateVendorDto } from './dtos/CreateVendor.dto';
import { EditVendorDto } from './dtos/EditVendor.dto';
@@ -58,14 +55,14 @@ export class VendorsApplication {
}
/**
* Changes the opening balance of the given customer.
* @param {number} vendorId
* @param {IVendorOpeningBalanceEditDTO} openingBalanceEditDTO
* Changes the opening balance of the given vendor.
* @param {number} vendorId
* @param {VendorOpeningBalanceEditDto} openingBalanceEditDTO
* @returns {Promise<IVendor>}
*/
public editOpeningBalance(
vendorId: number,
openingBalanceEditDTO: IVendorOpeningBalanceEditDTO,
openingBalanceEditDTO: VendorOpeningBalanceEditDto,
) {
return this.editOpeningBalanceService.editOpeningBalance(
vendorId,
@@ -95,10 +92,7 @@ export class VendorsApplication {
vendorIds: number[],
options?: { skipUndeletable?: boolean },
) {
return this.bulkDeleteVendorsService.bulkDeleteVendors(
vendorIds,
options,
);
return this.bulkDeleteVendorsService.bulkDeleteVendors(vendorIds, options);
}
public validateBulkDeleteVendors(vendorIds: number[]) {

View File

@@ -2,10 +2,10 @@ import { Knex } from 'knex';
import { Inject, Injectable } from '@nestjs/common';
import { EventEmitter2 } from '@nestjs/event-emitter';
import {
IVendorOpeningBalanceEditDTO,
IVendorOpeningBalanceEditedPayload,
IVendorOpeningBalanceEditingPayload,
} from '../types/Vendors.types';
import { VendorOpeningBalanceEditDto } from '../dtos/VendorOpeningBalanceEdit.dto';
import { UnitOfWork } from '@/modules/Tenancy/TenancyDB/UnitOfWork.service';
import { Vendor } from '../models/Vendor';
import { events } from '@/common/events/events';
@@ -29,12 +29,12 @@ export class EditOpeningBalanceVendorService {
/**
* Changes the opening balance of the given customer.
* @param {number} vendorId
* @param {IVendorOpeningBalanceEditDTO} openingBalanceEditDTO
* @param {VendorOpeningBalanceEditDto} openingBalanceEditDTO
* @returns {Promise<IVendor>}
*/
public async editOpeningBalance(
vendorId: number,
openingBalanceEditDTO: IVendorOpeningBalanceEditDTO,
openingBalanceEditDTO: VendorOpeningBalanceEditDto,
) {
// Retrieves the old vendor or throw not found error.
const oldVendor = await this.vendorModel()

View File

@@ -2,11 +2,13 @@ import { ApiProperty } from '@nestjs/swagger';
import {
IsISO8601,
IsInt,
IsNotEmpty,
IsNumber,
Min,
IsBoolean,
IsEmail,
IsString,
ValidateIf,
} from 'class-validator';
import { ContactAddressDto } from '@/modules/Customers/dtos/ContactAddress.dto';
import { IsOptional, ToNumber } from '@/common/decorators/Validators';
@@ -30,8 +32,12 @@ export class CreateVendorDto extends ContactAddressDto {
@ToNumber()
openingBalanceExchangeRate?: number;
@ApiProperty({ required: false, description: 'Date of the opening balance' })
@IsOptional()
@ApiProperty({
required: false,
description: 'Date of the opening balance (required when openingBalance is provided)',
})
@ValidateIf((o) => o.openingBalance != null)
@IsNotEmpty({ message: 'openingBalanceAt is required when openingBalance is provided' })
@IsISO8601()
openingBalanceAt?: Date;

View File

@@ -0,0 +1,44 @@
import { IsNotEmpty, IsNumber, IsString } from 'class-validator';
import { ApiProperty } from '@nestjs/swagger';
import { IsOptional, ToNumber } from '@/common/decorators/Validators';
export class VendorOpeningBalanceEditDto {
@ApiProperty({
required: true,
description: 'Opening balance',
example: 5000.0,
})
@IsNumber()
@IsNotEmpty()
@ToNumber()
openingBalance: number;
@ApiProperty({
required: false,
description: 'Opening balance date',
example: '2024-01-01',
})
@IsOptional()
@IsString()
openingBalanceAt?: string;
@ApiProperty({
required: false,
description: 'Opening balance exchange rate',
example: 1.0,
})
@IsOptional()
@IsNumber()
@ToNumber()
openingBalanceExchangeRate?: number;
@ApiProperty({
required: false,
description: 'Opening balance branch ID',
example: 101,
})
@IsOptional()
@IsNumber()
@ToNumber()
openingBalanceBranchId?: number;
}

View File

@@ -7,6 +7,7 @@ import { IDynamicListFilter } from '@/modules/DynamicListing/DynamicFilter/Dynam
import { IFilterMeta, IPaginationMeta } from '@/interfaces/Model';
import { CreateVendorDto } from '../dtos/CreateVendor.dto';
import { EditVendorDto } from '../dtos/EditVendor.dto';
import { VendorOpeningBalanceEditDto } from '../dtos/VendorOpeningBalanceEdit.dto';
// ----------------------------------
export interface IVendorNewDTO extends IContactAddressDTO {
@@ -92,23 +93,16 @@ export interface IVendorEventEditedPayload {
trx?: Knex.Transaction;
}
export interface IVendorOpeningBalanceEditDTO {
openingBalance: number;
openingBalanceAt: Date | string;
openingBalanceExchangeRate: number;
openingBalanceBranchId?: number;
}
export interface IVendorOpeningBalanceEditingPayload {
oldVendor: Vendor;
openingBalanceEditDTO: IVendorOpeningBalanceEditDTO;
openingBalanceEditDTO: VendorOpeningBalanceEditDto;
trx?: Knex.Transaction;
}
export interface IVendorOpeningBalanceEditedPayload {
vendor: Vendor;
oldVendor: Vendor;
openingBalanceEditDTO: IVendorOpeningBalanceEditDTO;
openingBalanceEditDTO: VendorOpeningBalanceEditDto;
trx: Knex.Transaction;
}