fix(server): customer/vendor opening balance:

This commit is contained in:
Ahmed Bouhuolia
2026-01-23 17:43:22 +02:00
parent 17651e0768
commit ca910ee489
9 changed files with 495 additions and 552 deletions

View File

@@ -1,117 +1,103 @@
// import { Service, Inject } from 'typedi';
// import { AccountNormal, ICustomer, ILedgerEntry } from '@/interfaces';
// import Ledger from '@/services/Accounting/Ledger';
import { Injectable } from '@nestjs/common';
import { AccountNormal } from '@/interfaces/Account';
import { ILedgerEntry } from '@/modules/Ledger/types/Ledger.types';
import { Ledger } from '@/modules/Ledger/Ledger';
import { Customer } from './models/Customer';
// @Service()
// export class CustomerGLEntries {
// /**
// * Retrieves the customer opening balance common entry attributes.
// * @param {ICustomer} customer
// */
// private getCustomerOpeningGLCommonEntry = (customer: ICustomer) => {
// return {
// exchangeRate: customer.openingBalanceExchangeRate,
// currencyCode: customer.currencyCode,
@Injectable()
export class CustomerGLEntries {
/**
* Retrieves the customer opening balance common entry attributes.
*/
private getCustomerOpeningGLCommonEntry = (customer: Customer) => {
return {
exchangeRate: customer.openingBalanceExchangeRate,
currencyCode: customer.currencyCode,
// transactionType: 'CustomerOpeningBalance',
// transactionId: customer.id,
transactionType: 'CustomerOpeningBalance',
transactionId: customer.id,
// date: customer.openingBalanceAt,
// userId: customer.userId,
// contactId: customer.id,
date: customer.openingBalanceAt,
contactId: customer.id,
// credit: 0,
// debit: 0,
credit: 0,
debit: 0,
// branchId: customer.openingBalanceBranchId,
// };
// };
branchId: customer.openingBalanceBranchId,
};
};
// /**
// * Retrieves the customer opening GL credit entry.
// * @param {number} ARAccountId
// * @param {ICustomer} customer
// * @returns {ILedgerEntry}
// */
// private getCustomerOpeningGLCreditEntry = (
// ARAccountId: number,
// customer: ICustomer
// ): ILedgerEntry => {
// const commonEntry = this.getCustomerOpeningGLCommonEntry(customer);
/**
* Retrieves the customer opening GL credit entry.
*/
private getCustomerOpeningGLCreditEntry = (
ARAccountId: number,
customer: Customer
): ILedgerEntry => {
const commonEntry = this.getCustomerOpeningGLCommonEntry(customer);
// return {
// ...commonEntry,
// credit: 0,
// debit: customer.localOpeningBalance,
// accountId: ARAccountId,
// accountNormal: AccountNormal.DEBIT,
// index: 1,
// };
// };
return {
...commonEntry,
credit: 0,
debit: customer.localOpeningBalance,
accountId: ARAccountId,
accountNormal: AccountNormal.DEBIT,
index: 1,
};
};
// /**
// * Retrieves the customer opening GL debit entry.
// * @param {number} incomeAccountId
// * @param {ICustomer} customer
// * @returns {ILedgerEntry}
// */
// private getCustomerOpeningGLDebitEntry = (
// incomeAccountId: number,
// customer: ICustomer
// ): ILedgerEntry => {
// const commonEntry = this.getCustomerOpeningGLCommonEntry(customer);
/**
* Retrieves the customer opening GL debit entry.
*/
private getCustomerOpeningGLDebitEntry = (
incomeAccountId: number,
customer: Customer
): ILedgerEntry => {
const commonEntry = this.getCustomerOpeningGLCommonEntry(customer);
// return {
// ...commonEntry,
// credit: customer.localOpeningBalance,
// debit: 0,
// accountId: incomeAccountId,
// accountNormal: AccountNormal.CREDIT,
return {
...commonEntry,
credit: customer.localOpeningBalance,
debit: 0,
accountId: incomeAccountId,
accountNormal: AccountNormal.CREDIT,
// index: 2,
// };
// };
index: 2,
};
};
// /**
// * Retrieves the customer opening GL entries.
// * @param {number} ARAccountId
// * @param {number} incomeAccountId
// * @param {ICustomer} customer
// * @returns {ILedgerEntry[]}
// */
// public getCustomerOpeningGLEntries = (
// ARAccountId: number,
// incomeAccountId: number,
// customer: ICustomer
// ) => {
// const debitEntry = this.getCustomerOpeningGLDebitEntry(
// incomeAccountId,
// customer
// );
// const creditEntry = this.getCustomerOpeningGLCreditEntry(
// ARAccountId,
// customer
// );
// return [debitEntry, creditEntry];
// };
/**
* Retrieves the customer opening GL entries.
*/
public getCustomerOpeningGLEntries = (
ARAccountId: number,
incomeAccountId: number,
customer: Customer
) => {
const debitEntry = this.getCustomerOpeningGLDebitEntry(
incomeAccountId,
customer
);
const creditEntry = this.getCustomerOpeningGLCreditEntry(
ARAccountId,
customer
);
return [debitEntry, creditEntry];
};
// /**
// * Retrieves the customer opening balance ledger.
// * @param {number} ARAccountId
// * @param {number} incomeAccountId
// * @param {ICustomer} customer
// * @returns {ILedger}
// */
// public getCustomerOpeningLedger = (
// ARAccountId: number,
// incomeAccountId: number,
// customer: ICustomer
// ) => {
// const entries = this.getCustomerOpeningGLEntries(
// ARAccountId,
// incomeAccountId,
// customer
// );
// return new Ledger(entries);
// };
// }
/**
* Retrieves the customer opening balance ledger.
*/
public getCustomerOpeningLedger = (
ARAccountId: number,
incomeAccountId: number,
customer: Customer
) => {
const entries = this.getCustomerOpeningGLEntries(
ARAccountId,
incomeAccountId,
customer
);
return new Ledger(entries);
};
}

View File

@@ -1,90 +1,79 @@
// import { Knex } from 'knex';
// import LedgerStorageService from '@/services/Accounting/LedgerStorageService';
// import HasTenancyService from '@/services/Tenancy/TenancyService';
// import { Service, Inject } from 'typedi';
// import { CustomerGLEntries } from './CustomerGLEntries';
import { Knex } from 'knex';
import { Inject, Injectable } from '@nestjs/common';
import { LedgerStorageService } from '@/modules/Ledger/LedgerStorage.service';
import { AccountRepository } from '@/modules/Accounts/repositories/Account.repository';
import { CustomerGLEntries } from './CustomerGLEntries';
import { Customer } from './models/Customer';
import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel';
// @Service()
// export class CustomerGLEntriesStorage {
// @Inject()
// private tenancy: HasTenancyService;
@Injectable()
export class CustomerGLEntriesStorage {
constructor(
private readonly ledgerStorage: LedgerStorageService,
private readonly accountRepository: AccountRepository,
private readonly customerGLEntries: CustomerGLEntries,
// @Inject()
// private ledegrRepository: LedgerStorageService;
@Inject(Customer.name)
private readonly customerModel: TenantModelProxy<typeof Customer>,
) { }
// @Inject()
// private customerGLEntries: CustomerGLEntries;
/**
* Customer opening balance journals.
*/
public writeCustomerOpeningBalance = async (
customerId: number,
trx?: Knex.Transaction,
) => {
const customer = await this.customerModel()
.query(trx)
.findById(customerId);
// /**
// * Customer opening balance journals.
// * @param {number} tenantId
// * @param {number} customerId
// * @param {Knex.Transaction} trx
// */
// public writeCustomerOpeningBalance = async (
// tenantId: number,
// customerId: number,
// trx?: Knex.Transaction
// ) => {
// const { Customer } = this.tenancy.models(tenantId);
// const { accountRepository } = this.tenancy.repositories(tenantId);
// Finds the income account.
const incomeAccount = await this.accountRepository.findOne({
slug: 'other-income',
});
// Find or create the A/R account.
const ARAccount =
await this.accountRepository.findOrCreateAccountReceivable(
customer.currencyCode,
{},
trx,
);
// Retrieves the customer opening balance ledger.
const ledger = this.customerGLEntries.getCustomerOpeningLedger(
ARAccount.id,
incomeAccount.id,
customer,
);
// Commits the ledger entries to the storage.
await this.ledgerStorage.commit(ledger, trx);
};
// const customer = await Customer.query(trx).findById(customerId);
/**
* Reverts the customer opening balance GL entries.
*/
public revertCustomerOpeningBalance = async (
customerId: number,
trx?: Knex.Transaction,
) => {
await this.ledgerStorage.deleteByReference(
customerId,
'CustomerOpeningBalance',
trx,
);
};
// // Finds the income account.
// const incomeAccount = await accountRepository.findOne({
// slug: 'other-income',
// });
// // Find or create the A/R account.
// const ARAccount = await accountRepository.findOrCreateAccountReceivable(
// customer.currencyCode,
// {},
// trx
// );
// // Retrieves the customer opening balance ledger.
// const ledger = this.customerGLEntries.getCustomerOpeningLedger(
// ARAccount.id,
// incomeAccount.id,
// customer
// );
// // Commits the ledger entries to the storage.
// await this.ledegrRepository.commit(tenantId, ledger, trx);
// };
/**
* Writes the customer opening balance GL entries.
*/
public rewriteCustomerOpeningBalance = async (
customerId: number,
trx?: Knex.Transaction,
) => {
// Reverts the customer opening balance entries.
await this.revertCustomerOpeningBalance(customerId, trx);
// /**
// * Reverts the customer opening balance GL entries.
// * @param {number} tenantId
// * @param {number} customerId
// * @param {Knex.Transaction} trx
// */
// public revertCustomerOpeningBalance = async (
// tenantId: number,
// customerId: number,
// trx?: Knex.Transaction
// ) => {
// await this.ledegrRepository.deleteByReference(
// tenantId,
// customerId,
// 'CustomerOpeningBalance',
// trx
// );
// };
// /**
// * Writes the customer opening balance GL entries.
// * @param {number} tenantId
// * @param {number} customerId
// * @param {Knex.Transaction} trx
// */
// public rewriteCustomerOpeningBalance = async (
// tenantId: number,
// customerId: number,
// trx?: Knex.Transaction
// ) => {
// // Reverts the customer opening balance entries.
// await this.revertCustomerOpeningBalance(tenantId, customerId, trx);
// // Write the customer opening balance entries.
// await this.writeCustomerOpeningBalance(tenantId, customerId, trx);
// };
// }
// Write the customer opening balance entries.
await this.writeCustomerOpeningBalance(customerId, trx);
};
}

View File

@@ -18,9 +18,14 @@ import { GetCustomers } from './queries/GetCustomers.service';
import { DynamicListModule } from '../DynamicListing/DynamicList.module';
import { BulkDeleteCustomersService } from './BulkDeleteCustomers.service';
import { ValidateBulkDeleteCustomersService } from './ValidateBulkDeleteCustomers.service';
import { LedgerModule } from '../Ledger/Ledger.module';
import { AccountsModule } from '../Accounts/Accounts.module';
import { CustomerGLEntries } from './CustomerGLEntries';
import { CustomerGLEntriesStorage } from './CustomerGLEntriesStorage';
import { CustomerWriteGLOpeningBalanceSubscriber } from './subscribers/CustomerGLEntriesSubscriber';
@Module({
imports: [TenancyDatabaseModule, DynamicListModule],
imports: [TenancyDatabaseModule, DynamicListModule, LedgerModule, AccountsModule],
controllers: [CustomersController],
providers: [
ActivateCustomer,
@@ -41,6 +46,9 @@ import { ValidateBulkDeleteCustomersService } from './ValidateBulkDeleteCustomer
GetCustomers,
BulkDeleteCustomersService,
ValidateBulkDeleteCustomersService,
CustomerGLEntries,
CustomerGLEntriesStorage,
CustomerWriteGLOpeningBalanceSubscriber,
],
})
export class CustomersModule {}
export class CustomersModule { }

View File

@@ -1,91 +1,63 @@
// import { Service, Inject } from 'typedi';
// import {
// ICustomerEventCreatedPayload,
// ICustomerEventDeletedPayload,
// ICustomerOpeningBalanceEditedPayload,
// } from '@/interfaces';
// import events from '@/subscribers/events';
// import { CustomerGLEntriesStorage } from '../CustomerGLEntriesStorage';
import { Injectable } from '@nestjs/common';
import { OnEvent } from '@nestjs/event-emitter';
import {
ICustomerEventCreatedPayload,
ICustomerEventDeletedPayload,
ICustomerOpeningBalanceEditedPayload,
} from '../types/Customers.types';
import { events } from '@/common/events/events';
import { CustomerGLEntriesStorage } from '../CustomerGLEntriesStorage';
// @Service()
// export class CustomerWriteGLOpeningBalanceSubscriber {
// @Inject()
// private customerGLEntries: CustomerGLEntriesStorage;
@Injectable()
export class CustomerWriteGLOpeningBalanceSubscriber {
constructor(private readonly customerGLEntries: CustomerGLEntriesStorage) { }
// /**
// * Attaches events with handlers.
// */
// public attach(bus) {
// bus.subscribe(
// events.customers.onCreated,
// this.handleWriteOpenBalanceEntries
// );
// bus.subscribe(
// events.customers.onDeleted,
// this.handleRevertOpeningBalanceEntries
// );
// bus.subscribe(
// events.customers.onOpeningBalanceChanged,
// this.handleRewriteOpeningEntriesOnChanged
// );
// }
/**
* Handles the writing opening balance journal entries once the customer created.
*/
@OnEvent(events.customers.onCreated)
public async handleWriteOpenBalanceEntries({
customer,
trx,
}: ICustomerEventCreatedPayload) {
// Writes the customer opening balance journal entries.
if (customer.openingBalance) {
await this.customerGLEntries.writeCustomerOpeningBalance(
customer.id,
trx,
);
}
}
// /**
// * Handles the writing opening balance journal entries once the customer created.
// * @param {ICustomerEventCreatedPayload} payload -
// */
// private handleWriteOpenBalanceEntries = async ({
// tenantId,
// customer,
// trx,
// }: ICustomerEventCreatedPayload) => {
// // Writes the customer opening balance journal entries.
// if (customer.openingBalance) {
// await this.customerGLEntries.writeCustomerOpeningBalance(
// tenantId,
// customer.id,
// trx
// );
// }
// };
/**
* Handles the deleting opening balance journal entries once the customer deleted.
*/
@OnEvent(events.customers.onDeleted)
public async handleRevertOpeningBalanceEntries({
customerId,
trx,
}: ICustomerEventDeletedPayload) {
await this.customerGLEntries.revertCustomerOpeningBalance(customerId, trx);
}
// /**
// * Handles the deleting opeing balance journal entrise once the customer deleted.
// * @param {ICustomerEventDeletedPayload} payload -
// */
// private handleRevertOpeningBalanceEntries = async ({
// tenantId,
// customerId,
// trx,
// }: ICustomerEventDeletedPayload) => {
// await this.customerGLEntries.revertCustomerOpeningBalance(
// tenantId,
// customerId,
// trx
// );
// };
// /**
// * Handles the rewrite opening balance entries once opening balnace changed.
// * @param {ICustomerOpeningBalanceEditedPayload} payload -
// */
// private handleRewriteOpeningEntriesOnChanged = async ({
// tenantId,
// customer,
// trx,
// }: ICustomerOpeningBalanceEditedPayload) => {
// if (customer.openingBalance) {
// await this.customerGLEntries.rewriteCustomerOpeningBalance(
// tenantId,
// customer.id,
// trx
// );
// } else {
// await this.customerGLEntries.revertCustomerOpeningBalance(
// tenantId,
// customer.id,
// trx
// );
// }
// };
// }
/**
* Handles the rewrite opening balance entries once opening balance changed.
*/
@OnEvent(events.customers.onOpeningBalanceChanged)
public async handleRewriteOpeningEntriesOnChanged({
customer,
trx,
}: ICustomerOpeningBalanceEditedPayload) {
if (customer.openingBalance) {
await this.customerGLEntries.rewriteCustomerOpeningBalance(
customer.id,
trx,
);
} else {
await this.customerGLEntries.revertCustomerOpeningBalance(
customer.id,
trx,
);
}
}
}

View File

@@ -1,115 +1,116 @@
// import { Service } from 'typedi';
// import { IVendor, AccountNormal, ILedgerEntry } from '@/interfaces';
// import Ledger from '@/services/Accounting/Ledger';
import { Injectable } from '@nestjs/common';
import { AccountNormal } from '@/interfaces/Account';
import { ILedgerEntry } from '@/modules/Ledger/types/Ledger.types';
import { Ledger } from '@/modules/Ledger/Ledger';
import { Vendor } from './models/Vendor';
// @Service()
// export class VendorGLEntries {
// /**
// * Retrieves the opening balance GL common entry.
// * @param {IVendor} vendor -
// */
// private getOpeningBalanceGLCommonEntry = (vendor: IVendor) => {
// return {
// exchangeRate: vendor.openingBalanceExchangeRate,
// currencyCode: vendor.currencyCode,
@Injectable()
export class VendorGLEntries {
/**
* Retrieves the opening balance GL common entry.
* @param {Vendor} vendor -
*/
private getOpeningBalanceGLCommonEntry = (vendor: Vendor) => {
return {
exchangeRate: vendor.openingBalanceExchangeRate,
currencyCode: vendor.currencyCode,
// transactionType: 'VendorOpeningBalance',
// transactionId: vendor.id,
transactionType: 'VendorOpeningBalance',
transactionId: vendor.id,
// date: vendor.openingBalanceAt,
// userId: vendor.userId,
// contactId: vendor.id,
date: vendor.openingBalanceAt,
contactId: vendor.id,
// credit: 0,
// debit: 0,
credit: 0,
debit: 0,
// branchId: vendor.openingBalanceBranchId,
// };
// };
branchId: vendor.openingBalanceBranchId,
};
};
// /**
// * Retrieves the opening balance GL debit entry.
// * @param {number} costAccountId -
// * @param {IVendor} vendor
// * @returns {ILedgerEntry}
// */
// private getOpeningBalanceGLDebitEntry = (
// costAccountId: number,
// vendor: IVendor
// ): ILedgerEntry => {
// const commonEntry = this.getOpeningBalanceGLCommonEntry(vendor);
/**
* Retrieves the opening balance GL debit entry.
* @param {number} costAccountId -
* @param {Vendor} vendor
* @returns {ILedgerEntry}
*/
private getOpeningBalanceGLDebitEntry = (
costAccountId: number,
vendor: Vendor
): ILedgerEntry => {
const commonEntry = this.getOpeningBalanceGLCommonEntry(vendor);
// return {
// ...commonEntry,
// accountId: costAccountId,
// accountNormal: AccountNormal.DEBIT,
// debit: vendor.localOpeningBalance,
// credit: 0,
// index: 2,
// };
// };
return {
...commonEntry,
accountId: costAccountId,
accountNormal: AccountNormal.DEBIT,
debit: vendor.localOpeningBalance,
credit: 0,
index: 2,
};
};
// /**
// * Retrieves the opening balance GL credit entry.
// * @param {number} APAccountId
// * @param {IVendor} vendor
// * @returns {ILedgerEntry}
// */
// private getOpeningBalanceGLCreditEntry = (
// APAccountId: number,
// vendor: IVendor
// ): ILedgerEntry => {
// const commonEntry = this.getOpeningBalanceGLCommonEntry(vendor);
/**
* Retrieves the opening balance GL credit entry.
* @param {number} APAccountId
* @param {Vendor} vendor
* @returns {ILedgerEntry}
*/
private getOpeningBalanceGLCreditEntry = (
APAccountId: number,
vendor: Vendor
): ILedgerEntry => {
const commonEntry = this.getOpeningBalanceGLCommonEntry(vendor);
// return {
// ...commonEntry,
// accountId: APAccountId,
// accountNormal: AccountNormal.CREDIT,
// credit: vendor.localOpeningBalance,
// index: 1,
// };
// };
return {
...commonEntry,
accountId: APAccountId,
accountNormal: AccountNormal.CREDIT,
credit: vendor.localOpeningBalance,
index: 1,
};
};
// /**
// * Retrieves the opening balance GL entries.
// * @param {number} APAccountId
// * @param {number} costAccountId -
// * @param {IVendor} vendor
// * @returns {ILedgerEntry[]}
// */
// public getOpeningBalanceGLEntries = (
// APAccountId: number,
// costAccountId: number,
// vendor: IVendor
// ): ILedgerEntry[] => {
// const debitEntry = this.getOpeningBalanceGLDebitEntry(
// costAccountId,
// vendor
// );
// const creditEntry = this.getOpeningBalanceGLCreditEntry(
// APAccountId,
// vendor
// );
// return [debitEntry, creditEntry];
// };
/**
* Retrieves the opening balance GL entries.
* @param {number} APAccountId
* @param {number} costAccountId -
* @param {Vendor} vendor
* @returns {ILedgerEntry[]}
*/
public getOpeningBalanceGLEntries = (
APAccountId: number,
costAccountId: number,
vendor: Vendor
): ILedgerEntry[] => {
const debitEntry = this.getOpeningBalanceGLDebitEntry(
costAccountId,
vendor
);
const creditEntry = this.getOpeningBalanceGLCreditEntry(
APAccountId,
vendor
);
return [debitEntry, creditEntry];
};
// /**
// * Retrieves the opening balance ledger.
// * @param {number} APAccountId
// * @param {number} costAccountId -
// * @param {IVendor} vendor
// * @returns {Ledger}
// */
// public getOpeningBalanceLedger = (
// APAccountId: number,
// costAccountId: number,
// vendor: IVendor
// ) => {
// const entries = this.getOpeningBalanceGLEntries(
// APAccountId,
// costAccountId,
// vendor
// );
// return new Ledger(entries);
// };
// }
/**
* Retrieves the opening balance ledger.
* @param {number} APAccountId
* @param {number} costAccountId -
* @param {Vendor} vendor
* @returns {Ledger}
*/
public getOpeningBalanceLedger = (
APAccountId: number,
costAccountId: number,
vendor: Vendor
) => {
const entries = this.getOpeningBalanceGLEntries(
APAccountId,
costAccountId,
vendor
);
return new Ledger(entries);
};
}

View File

@@ -1,88 +1,86 @@
// import { Knex } from 'knex';
// import { Service, Inject } from 'typedi';
// import LedgerStorageService from '@/services/Accounting/LedgerStorageService';
// import HasTenancyService from '@/services/Tenancy/TenancyService';
// import { VendorGLEntries } from './VendorGLEntries';
import { Knex } from 'knex';
import { Inject, Injectable } from '@nestjs/common';
import { LedgerStorageService } from '@/modules/Ledger/LedgerStorage.service';
import { AccountRepository } from '@/modules/Accounts/repositories/Account.repository';
import { VendorGLEntries } from './VendorGLEntries';
import { Vendor } from './models/Vendor';
import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel';
// @Service()
// export class VendorGLEntriesStorage {
// @Inject()
// private tenancy: HasTenancyService;
@Injectable()
export class VendorGLEntriesStorage {
constructor(
private readonly ledgerStorage: LedgerStorageService,
private readonly accountRepository: AccountRepository,
private readonly vendorGLEntries: VendorGLEntries,
// @Inject()
// private ledegrRepository: LedgerStorageService;
@Inject(Vendor.name)
private readonly vendorModel: TenantModelProxy<typeof Vendor>,
) { }
// @Inject()
// private vendorGLEntries: VendorGLEntries;
/**
* Vendor opening balance journals.
* @param {number} vendorId
* @param {Knex.Transaction} trx
*/
public writeVendorOpeningBalance = async (
vendorId: number,
trx?: Knex.Transaction,
) => {
const vendor = await this.vendorModel()
.query(trx)
.findById(vendorId);
// /**
// * Vendor opening balance journals.
// * @param {number} tenantId
// * @param {number} vendorId
// * @param {Knex.Transaction} trx
// */
// public writeVendorOpeningBalance = async (
// tenantId: number,
// vendorId: number,
// trx?: Knex.Transaction
// ) => {
// const { Vendor } = this.tenancy.models(tenantId);
// const { accountRepository } = this.tenancy.repositories(tenantId);
// Finds the expense account.
const expenseAccount = await this.accountRepository.findOrCreateOtherExpensesAccount(
{},
trx,
);
// Find or create the A/P account.
const APAccount =
await this.accountRepository.findOrCreateAccountsPayable(
vendor.currencyCode,
{},
trx,
);
// Retrieves the vendor opening balance ledger.
const ledger = this.vendorGLEntries.getOpeningBalanceLedger(
APAccount.id,
expenseAccount.id,
vendor,
);
// Commits the ledger entries to the storage.
await this.ledgerStorage.commit(ledger, trx);
};
// const vendor = await Vendor.query(trx).findById(vendorId);
/**
* Reverts the vendor opening balance GL entries.
* @param {number} vendorId
* @param {Knex.Transaction} trx
*/
public revertVendorOpeningBalance = async (
vendorId: number,
trx?: Knex.Transaction,
) => {
await this.ledgerStorage.deleteByReference(
vendorId,
'VendorOpeningBalance',
trx,
);
};
// // Finds the expense account.
// const expenseAccount = await accountRepository.findOne({
// slug: 'other-expenses',
// });
// // Find or create the A/P account.
// const APAccount = await accountRepository.findOrCreateAccountsPayable(
// vendor.currencyCode,
// {},
// trx
// );
// // Retrieves the vendor opening balance ledger.
// const ledger = this.vendorGLEntries.getOpeningBalanceLedger(
// APAccount.id,
// expenseAccount.id,
// vendor
// );
// // Commits the ledger entries to the storage.
// await this.ledegrRepository.commit(tenantId, ledger, trx);
// };
/**
* Writes the vendor opening balance GL entries.
* @param {number} vendorId
* @param {Knex.Transaction} trx
*/
public rewriteVendorOpeningBalance = async (
vendorId: number,
trx?: Knex.Transaction,
) => {
// Reverts the vendor opening balance entries first.
await this.revertVendorOpeningBalance(vendorId, trx);
// /**
// * Reverts the vendor opening balance GL entries.
// * @param {number} tenantId
// * @param {number} vendorId
// * @param {Knex.Transaction} trx
// */
// public revertVendorOpeningBalance = async (
// tenantId: number,
// vendorId: number,
// trx?: Knex.Transaction
// ) => {
// await this.ledegrRepository.deleteByReference(
// tenantId,
// vendorId,
// 'VendorOpeningBalance',
// trx
// );
// };
// /**
// * Writes the vendor opening balance GL entries.
// * @param {number} tenantId
// * @param {number} vendorId
// * @param {Knex.Transaction} trx
// */
// public rewriteVendorOpeningBalance = async (
// tenantId: number,
// vendorId: number,
// trx?: Knex.Transaction
// ) => {
// await this.writeVendorOpeningBalance(tenantId, vendorId, trx);
// await this.revertVendorOpeningBalance(tenantId, vendorId, trx);
// };
// }
// Write the vendor opening balance entries.
await this.writeVendorOpeningBalance(vendorId, trx);
};
}

View File

@@ -18,9 +18,14 @@ import { VendorsExportable } from './VendorsExportable';
import { VendorsImportable } from './VendorsImportable';
import { BulkDeleteVendorsService } from './BulkDeleteVendors.service';
import { ValidateBulkDeleteVendorsService } from './ValidateBulkDeleteVendors.service';
import { LedgerModule } from '../Ledger/Ledger.module';
import { AccountsModule } from '../Accounts/Accounts.module';
import { VendorGLEntries } from './VendorGLEntries';
import { VendorGLEntriesStorage } from './VendorGLEntriesStorage';
import { VendorsWriteGLOpeningSubscriber } from './subscribers/VendorGLEntriesSubscriber';
@Module({
imports: [TenancyDatabaseModule, DynamicListModule],
imports: [TenancyDatabaseModule, DynamicListModule, LedgerModule, AccountsModule],
controllers: [VendorsController],
providers: [
ActivateVendorService,
@@ -38,7 +43,10 @@ import { ValidateBulkDeleteVendorsService } from './ValidateBulkDeleteVendors.se
TransformerInjectable,
TenancyContext,
VendorsExportable,
VendorsImportable
VendorsImportable,
VendorGLEntries,
VendorGLEntriesStorage,
VendorsWriteGLOpeningSubscriber,
],
})
export class VendorsModule {}
export class VendorsModule { }

View File

@@ -36,6 +36,7 @@ export class Vendor extends TenantBaseModel {
openingBalance: number;
openingBalanceExchangeRate: number;
openingBalanceAt: Date | string;
openingBalanceBranchId?: number;
salutation: string;
firstName: string;

View File

@@ -1,91 +1,71 @@
// import { Inject, Service } from 'typedi';
// import events from '@/subscribers/events';
// import { VendorGLEntriesStorage } from '../VendorGLEntriesStorage';
// import {
// IVendorEventCreatedPayload,
// IVendorEventDeletedPayload,
// IVendorOpeningBalanceEditedPayload,
// } from '@/interfaces';
import { Injectable } from '@nestjs/common';
import { OnEvent } from '@nestjs/event-emitter';
import { events } from '@/common/events/events';
import { VendorGLEntriesStorage } from '../VendorGLEntriesStorage';
import {
IVendorEventCreatedPayload,
IVendorEventDeletedPayload,
IVendorOpeningBalanceEditedPayload,
} from '../types/Vendors.types';
// @Service()
// export class VendorsWriteGLOpeningSubscriber {
// @Inject()
// private vendorGLEntriesStorage: VendorGLEntriesStorage;
@Injectable()
export class VendorsWriteGLOpeningSubscriber {
constructor(
private readonly vendorGLEntriesStorage: VendorGLEntriesStorage,
) {}
// /**
// * Constructor method.
// */
// public attach(bus) {
// bus.subscribe(
// events.vendors.onCreated,
// this.handleWriteOpeningBalanceEntries
// );
// bus.subscribe(
// events.vendors.onDeleted,
// this.handleRevertOpeningBalanceEntries
// );
// bus.subscribe(
// events.vendors.onOpeningBalanceChanged,
// this.handleRewriteOpeningEntriesOnChanged
// );
// }
/**
* Writes the open balance journal entries once the vendor created.
* @param {IVendorEventCreatedPayload} payload -
*/
@OnEvent(events.vendors.onCreated)
public async handleWriteOpeningBalanceEntries({
vendor,
trx,
}: IVendorEventCreatedPayload) {
// Writes the vendor opening balance journal entries.
if (vendor.openingBalance) {
await this.vendorGLEntriesStorage.writeVendorOpeningBalance(
vendor.id,
trx,
);
}
}
// /**
// * Writes the open balance journal entries once the vendor created.
// * @param {IVendorEventCreatedPayload} payload -
// */
// private handleWriteOpeningBalanceEntries = async ({
// tenantId,
// vendor,
// trx,
// }: IVendorEventCreatedPayload) => {
// // Writes the vendor opening balance journal entries.
// if (vendor.openingBalance) {
// await this.vendorGLEntriesStorage.writeVendorOpeningBalance(
// tenantId,
// vendor.id,
// trx
// );
// }
// };
/**
* Revert the opening balance journal entries once the vendor deleted.
* @param {IVendorEventDeletedPayload} payload -
*/
@OnEvent(events.vendors.onDeleted)
public async handleRevertOpeningBalanceEntries({
vendorId,
trx,
}: IVendorEventDeletedPayload) {
await this.vendorGLEntriesStorage.revertVendorOpeningBalance(
vendorId,
trx,
);
}
// /**
// * Revert the opening balance journal entries once the vendor deleted.
// * @param {IVendorEventDeletedPayload} payload -
// */
// private handleRevertOpeningBalanceEntries = async ({
// tenantId,
// vendorId,
// trx,
// }: IVendorEventDeletedPayload) => {
// await this.vendorGLEntriesStorage.revertVendorOpeningBalance(
// tenantId,
// vendorId,
// trx
// );
// };
// /**
// * Handles the rewrite opening balance entries once opening balnace changed.
// * @param {ICustomerOpeningBalanceEditedPayload} payload -
// */
// private handleRewriteOpeningEntriesOnChanged = async ({
// tenantId,
// vendor,
// trx,
// }: IVendorOpeningBalanceEditedPayload) => {
// if (vendor.openingBalance) {
// await this.vendorGLEntriesStorage.rewriteVendorOpeningBalance(
// tenantId,
// vendor.id,
// trx
// );
// } else {
// await this.vendorGLEntriesStorage.revertVendorOpeningBalance(
// tenantId,
// vendor.id,
// trx
// );
// }
// };
// }
/**
* Handles the rewrite opening balance entries once opening balance changed.
* @param {IVendorOpeningBalanceEditedPayload} payload -
*/
@OnEvent(events.vendors.onOpeningBalanceChanged)
public async handleRewriteOpeningEntriesOnChanged({
vendor,
trx,
}: IVendorOpeningBalanceEditedPayload) {
if (vendor.openingBalance) {
await this.vendorGLEntriesStorage.rewriteVendorOpeningBalance(
vendor.id,
trx,
);
} else {
await this.vendorGLEntriesStorage.revertVendorOpeningBalance(
vendor.id,
trx,
);
}
}
}