diff --git a/packages/server/src/modules/BillPayments/queries/BillPaymentsExportable.ts b/packages/server/src/modules/BillPayments/queries/BillPaymentsExportable.ts index 306d1c6d7..662e69bc6 100644 --- a/packages/server/src/modules/BillPayments/queries/BillPaymentsExportable.ts +++ b/packages/server/src/modules/BillPayments/queries/BillPaymentsExportable.ts @@ -16,8 +16,6 @@ export class BillPaymentsExportable extends Exportable { /** * Retrieves the accounts data to exportable sheet. - * @param {number} tenantId - * @returns */ public async exportable(query: any) { const filterQuery = (builder) => { diff --git a/packages/server/src/modules/CreditNoteRefunds/CreditNoteRefunds.module.ts b/packages/server/src/modules/CreditNoteRefunds/CreditNoteRefunds.module.ts index 9fe7c7bdb..66cd4730b 100644 --- a/packages/server/src/modules/CreditNoteRefunds/CreditNoteRefunds.module.ts +++ b/packages/server/src/modules/CreditNoteRefunds/CreditNoteRefunds.module.ts @@ -7,9 +7,13 @@ import { CreditNotesRefundsApplication } from './CreditNotesRefundsApplication.s import { CreditNoteRefundsController } from './CreditNoteRefunds.controller'; import { CreditNotesModule } from '../CreditNotes/CreditNotes.module'; import { GetCreditNoteRefundsService } from './queries/GetCreditNoteRefunds.service'; +import { RefundCreditNoteGLEntries } from './commands/RefundCreditNoteGLEntries'; +import { RefundCreditNoteGLEntriesSubscriber } from '../CreditNotes/subscribers/RefundCreditNoteGLEntriesSubscriber'; +import { LedgerModule } from '../Ledger/Ledger.module'; +import { AccountsModule } from '../Accounts/Accounts.module'; @Module({ - imports: [forwardRef(() => CreditNotesModule)], + imports: [forwardRef(() => CreditNotesModule), LedgerModule, AccountsModule], providers: [ CreateRefundCreditNoteService, DeleteRefundCreditNoteService, @@ -17,8 +21,10 @@ import { GetCreditNoteRefundsService } from './queries/GetCreditNoteRefunds.serv RefundSyncCreditNoteBalanceService, CreditNotesRefundsApplication, GetCreditNoteRefundsService, + RefundCreditNoteGLEntries, + RefundCreditNoteGLEntriesSubscriber, ], exports: [RefundSyncCreditNoteBalanceService], controllers: [CreditNoteRefundsController], }) -export class CreditNoteRefundsModule {} +export class CreditNoteRefundsModule { } diff --git a/packages/server/src/modules/VendorCreditsRefund/VendorCreditsRefund.module.ts b/packages/server/src/modules/VendorCreditsRefund/VendorCreditsRefund.module.ts index b9f614a59..894f48485 100644 --- a/packages/server/src/modules/VendorCreditsRefund/VendorCreditsRefund.module.ts +++ b/packages/server/src/modules/VendorCreditsRefund/VendorCreditsRefund.module.ts @@ -6,15 +6,21 @@ import { VendorCreditsRefundApplication } from './VendorCreditsRefund.applicatio import { CreateRefundVendorCredit } from './commands/CreateRefundVendorCredit.service'; import { WarehousesModule } from '../Warehouses/Warehouses.module'; import { BranchesModule } from '../Branches/Branches.module'; +import { RefundVendorCreditGLEntries } from './commands/RefundVendorCreditGLEntries'; +import { RefundVendorCreditGLEntriesSubscriber } from './subscribers/RefundVendorCreditGLEntriesSubscriber'; +import { LedgerModule } from '../Ledger/Ledger.module'; +import { AccountsModule } from '../Accounts/Accounts.module'; @Module({ - imports: [WarehousesModule, BranchesModule], + imports: [WarehousesModule, BranchesModule, LedgerModule, AccountsModule], providers: [ GetRefundVendorCreditsService, DeleteRefundVendorCreditService, CreateRefundVendorCredit, - VendorCreditsRefundApplication + VendorCreditsRefundApplication, + RefundVendorCreditGLEntries, + RefundVendorCreditGLEntriesSubscriber, ], controllers: [VendorCreditsRefundController], }) -export class VendorCreditsRefundModule {} +export class VendorCreditsRefundModule { } diff --git a/packages/server/src/modules/VendorCreditsRefund/commands/RefundVendorCreditGLEntries.ts b/packages/server/src/modules/VendorCreditsRefund/commands/RefundVendorCreditGLEntries.ts index c9786c790..8c961233b 100644 --- a/packages/server/src/modules/VendorCreditsRefund/commands/RefundVendorCreditGLEntries.ts +++ b/packages/server/src/modules/VendorCreditsRefund/commands/RefundVendorCreditGLEntries.ts @@ -1,159 +1,172 @@ -// import { Inject, Service } from 'typedi'; -// import { Knex } from 'knex'; -// import { AccountNormal, ILedgerEntry } from '@/interfaces'; -// import { IRefundVendorCredit } from '@/interfaces'; -// import JournalPosterService from '@/services/Sales/JournalPosterService'; -// import LedgerRepository from '@/services/Ledger/LedgerRepository'; -// import HasTenancyService from '@/services/Tenancy/TenancyService'; +import { LedgerStorageService } from '@/modules/Ledger/LedgerStorage.service'; +import { Inject, Injectable } from '@nestjs/common'; +import { RefundVendorCredit } from '../models/RefundVendorCredit'; +import { Ledger } from '@/modules/Ledger/Ledger'; +import { Knex } from 'knex'; +import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel'; +import { Account } from '@/modules/Accounts/models/Account.model'; +import { ILedgerEntry } from '@/modules/Ledger/types/Ledger.types'; +import { AccountNormal } from '@/interfaces/Account'; +import { AccountRepository } from '@/modules/Accounts/repositories/Account.repository'; -// @Service() -// export default class RefundVendorCreditGLEntries { -// @Inject() -// private journalService: JournalPosterService; +@Injectable() +export class RefundVendorCreditGLEntries { + constructor( + private readonly ledgerStorage: LedgerStorageService, + private readonly accountRepository: AccountRepository, -// @Inject() -// private ledgerRepository: LedgerRepository; + @Inject(Account.name) + private readonly accountModel: TenantModelProxy, -// @Inject() -// private tenancy: HasTenancyService; + @Inject(RefundVendorCredit.name) + private readonly refundVendorCreditModel: TenantModelProxy< + typeof RefundVendorCredit + >, + ) { } -// /** -// * Retrieves the refund credit common GL entry. -// * @param {IRefundVendorCredit} refundCredit -// */ -// private getRefundCreditGLCommonEntry = ( -// refundCredit: IRefundVendorCredit -// ) => { -// return { -// exchangeRate: refundCredit.exchangeRate, -// currencyCode: refundCredit.currencyCode, + /** + * Retrieves the refund vendor credit common GL entry. + * @param {RefundVendorCredit} refundVendorCredit + * @returns + */ + private getRefundVendorCreditCommonGLEntry = ( + refundVendorCredit: RefundVendorCredit, + ) => { + const model = refundVendorCredit as any; + return { + currencyCode: refundVendorCredit.currencyCode, + exchangeRate: refundVendorCredit.exchangeRate, -// transactionType: 'RefundVendorCredit', -// transactionId: refundCredit.id, + transactionType: 'RefundVendorCredit', + transactionId: refundVendorCredit.id, + date: refundVendorCredit.date, + userId: refundVendorCredit.vendorCredit?.userId, -// date: refundCredit.date, -// userId: refundCredit.userId, -// referenceNumber: refundCredit.referenceNo, -// createdAt: refundCredit.createdAt, -// indexGroup: 10, + referenceNumber: refundVendorCredit.referenceNo, -// credit: 0, -// debit: 0, + createdAt: model.createdAt, + indexGroup: 10, -// note: refundCredit.description, -// branchId: refundCredit.branchId, -// }; -// }; + credit: 0, + debit: 0, -// /** -// * Retrieves the refund credit payable GL entry. -// * @param {IRefundVendorCredit} refundCredit -// * @param {number} APAccountId -// * @returns {ILedgerEntry} -// */ -// private getRefundCreditGLPayableEntry = ( -// refundCredit: IRefundVendorCredit, -// APAccountId: number -// ): ILedgerEntry => { -// const commonEntry = this.getRefundCreditGLCommonEntry(refundCredit); + note: refundVendorCredit.description, + branchId: refundVendorCredit.branchId, + }; + }; -// return { -// ...commonEntry, -// credit: refundCredit.amount, -// accountId: APAccountId, -// contactId: refundCredit.vendorCredit.vendorId, -// index: 1, -// accountNormal: AccountNormal.CREDIT, -// }; -// }; + /** + * Retrieves the refund vendor credit payable GL entry. + * @param {RefundVendorCredit} refundVendorCredit + * @param {number} APAccountId + * @returns {ILedgerEntry} + */ + private getRefundVendorCreditGLPayableEntry = ( + refundVendorCredit: RefundVendorCredit, + APAccountId: number, + ): ILedgerEntry => { + const commonEntry = this.getRefundVendorCreditCommonGLEntry( + refundVendorCredit, + ); -// /** -// * Retrieves the refund credit deposit GL entry. -// * @param {IRefundVendorCredit} refundCredit -// * @returns {ILedgerEntry} -// */ -// private getRefundCreditGLDepositEntry = ( -// refundCredit: IRefundVendorCredit -// ): ILedgerEntry => { -// const commonEntry = this.getRefundCreditGLCommonEntry(refundCredit); + return { + ...commonEntry, + credit: refundVendorCredit.amount, + accountId: APAccountId, + contactId: refundVendorCredit.vendorCredit.vendorId, + index: 1, + accountNormal: AccountNormal.CREDIT, + }; + }; -// return { -// ...commonEntry, -// debit: refundCredit.amount, -// accountId: refundCredit.depositAccountId, -// index: 2, -// accountNormal: AccountNormal.DEBIT, -// }; -// }; + /** + * Retrieves the refund vendor credit deposit GL entry. + * @param {RefundVendorCredit} refundVendorCredit + * @returns {ILedgerEntry} + */ + private getRefundVendorCreditGLDepositEntry = ( + refundVendorCredit: RefundVendorCredit, + ): ILedgerEntry => { + const commonEntry = this.getRefundVendorCreditCommonGLEntry( + refundVendorCredit, + ); -// /** -// * Retrieve refund vendor credit GL entries. -// * @param {IRefundVendorCredit} refundCredit -// * @param {number} APAccountId -// * @returns {ILedgerEntry[]} -// */ -// public getRefundCreditGLEntries = ( -// refundCredit: IRefundVendorCredit, -// APAccountId: number -// ): ILedgerEntry[] => { -// const payableEntry = this.getRefundCreditGLPayableEntry( -// refundCredit, -// APAccountId -// ); -// const depositEntry = this.getRefundCreditGLDepositEntry(refundCredit); + return { + ...commonEntry, + debit: refundVendorCredit.amount, + accountId: refundVendorCredit.depositAccountId, + index: 2, + accountNormal: AccountNormal.DEBIT, + }; + }; -// return [payableEntry, depositEntry]; -// }; + /** + * Retrieve refund vendor credit GL entries. + * @param {RefundVendorCredit} refundVendorCredit + * @param {number} APAccountId + * @returns {ILedgerEntry[]} + */ + public getRefundVendorCreditGLEntries( + refundVendorCredit: RefundVendorCredit, + APAccountId: number, + ): ILedgerEntry[] { + const payableEntry = this.getRefundVendorCreditGLPayableEntry( + refundVendorCredit, + APAccountId, + ); + const depositEntry = this.getRefundVendorCreditGLDepositEntry( + refundVendorCredit, + ); -// /** -// * Saves refund credit note GL entries. -// * @param {number} tenantId -// * @param {IRefundVendorCredit} refundCredit - -// * @param {Knex.Transaction} trx - -// * @return {Promise} -// */ -// public saveRefundCreditGLEntries = async ( -// tenantId: number, -// refundCreditId: number, -// trx?: Knex.Transaction -// ): Promise => { -// const { Account, RefundVendorCredit } = this.tenancy.models(tenantId); + return [payableEntry, depositEntry]; + } -// // Retireve refund with associated vendor credit entity. -// const refundCredit = await RefundVendorCredit.query() -// .findById(refundCreditId) -// .withGraphFetched('vendorCredit'); + /** + * Creates refund vendor credit GL entries. + * @param {number} refundVendorCreditId + * @param {Knex.Transaction} trx + */ + public createRefundVendorCreditGLEntries = async ( + refundVendorCreditId: number, + trx?: Knex.Transaction, + ) => { + // Retrieve the refund with associated vendor credit. + const refundVendorCredit = await this.refundVendorCreditModel() + .query(trx) + .findById(refundVendorCreditId) + .withGraphFetched('vendorCredit'); -// const payableAccount = await Account.query().findOne( -// 'slug', -// 'accounts-payable' -// ); -// // Generates the GL entries of the given refund credit. -// const entries = this.getRefundCreditGLEntries( -// refundCredit, -// payableAccount.id -// ); -// // Saves the ledegr to the storage. -// await this.ledgerRepository.saveLedgerEntries(tenantId, entries, trx); -// }; + // Retrieve the payable account (A/P) account based on the given currency. + const APAccount = await this.accountRepository.findOrCreateAccountsPayable( + refundVendorCredit.currencyCode, + {}, + trx, + ); -// /** -// * Reverts refund credit note GL entries. -// * @param {number} tenantId -// * @param {number} refundCreditId -// * @param {Knex.Transaction} trx -// * @return {Promise} -// */ -// public revertRefundCreditGLEntries = async ( -// tenantId: number, -// refundCreditId: number, -// trx?: Knex.Transaction -// ) => { -// await this.journalService.revertJournalTransactions( -// tenantId, -// refundCreditId, -// 'RefundVendorCredit', -// trx -// ); -// }; -// } + // Retrieve refund vendor credit GL entries. + const refundGLEntries = this.getRefundVendorCreditGLEntries( + refundVendorCredit, + APAccount.id, + ); + const ledger = new Ledger(refundGLEntries); + + // Saves refund ledger entries. + await this.ledgerStorage.commit(ledger, trx); + }; + + /** + * Reverts refund vendor credit GL entries. + * @param {number} refundVendorCreditId + * @param {Knex.Transaction} trx + */ + public revertRefundVendorCreditGLEntries = async ( + refundVendorCreditId: number, + trx?: Knex.Transaction, + ) => { + await this.ledgerStorage.deleteByReference( + refundVendorCreditId, + 'RefundVendorCredit', + trx, + ); + }; +} diff --git a/packages/server/src/modules/VendorCreditsRefund/subscribers/RefundVendorCreditGLEntriesSubscriber.ts b/packages/server/src/modules/VendorCreditsRefund/subscribers/RefundVendorCreditGLEntriesSubscriber.ts new file mode 100644 index 000000000..620ac092b --- /dev/null +++ b/packages/server/src/modules/VendorCreditsRefund/subscribers/RefundVendorCreditGLEntriesSubscriber.ts @@ -0,0 +1,48 @@ +import { events } from '@/common/events/events'; +import { RefundVendorCreditGLEntries } from '../commands/RefundVendorCreditGLEntries'; +import { + IRefundVendorCreditCreatedPayload, + IRefundVendorCreditDeletedPayload, +} from '../types/VendorCreditRefund.types'; +import { Injectable } from '@nestjs/common'; +import { OnEvent } from '@nestjs/event-emitter'; + +@Injectable() +export class RefundVendorCreditGLEntriesSubscriber { + constructor( + private readonly refundVendorCreditGLEntries: RefundVendorCreditGLEntries, + ) { } + + /** + * Writes refund vendor credit GL entries once the transaction created. + * @param {IRefundVendorCreditCreatedPayload} payload - + */ + @OnEvent(events.vendorCredit.onRefundCreated) + async writeRefundVendorCreditGLEntriesOnceCreated({ + trx, + refundVendorCredit, + vendorCredit, + }: IRefundVendorCreditCreatedPayload) { + await this.refundVendorCreditGLEntries.createRefundVendorCreditGLEntries( + refundVendorCredit.id, + trx, + ); + } + + /** + * Reverts refund vendor credit GL entries once the transaction deleted. + * @param {IRefundVendorCreditDeletedPayload} payload - + */ + @OnEvent(events.vendorCredit.onRefundDeleted) + async revertRefundVendorCreditGLEntriesOnceDeleted({ + trx, + refundCreditId, + oldRefundCredit, + }: IRefundVendorCreditDeletedPayload) { + await this.refundVendorCreditGLEntries.revertRefundVendorCreditGLEntries( + refundCreditId, + trx, + ); + } +} + diff --git a/packages/webapp/src/containers/Alerts/Accounts/AccountBulkInactivateAlert.tsx b/packages/webapp/src/containers/Alerts/Accounts/AccountBulkInactivateAlert.tsx index 6f540b042..cb40d0a45 100644 --- a/packages/webapp/src/containers/Alerts/Accounts/AccountBulkInactivateAlert.tsx +++ b/packages/webapp/src/containers/Alerts/Accounts/AccountBulkInactivateAlert.tsx @@ -6,7 +6,7 @@ import { Intent, Alert } from '@blueprintjs/core'; import { queryCache } from 'react-query'; import { AppToaster } from '@/components'; -import { withAccountsActions } from '@/containers/Accounts/withAccountsTableActions'; +// import { withAccountsActions } from '@/containers/Accounts/withAccountsTableActions'; import { withAlertStoreConnect } from '@/containers/Alert/withAlertStoreConnect'; import { withAlertActions } from '@/containers/Alert/withAlertActions'; @@ -22,7 +22,7 @@ function AccountBulkInactivateAlert({ closeAlert, }) { - + const [isLoading, setLoading] = useState(false); const selectedRowsCount = 0; @@ -41,7 +41,7 @@ function AccountBulkInactivateAlert({ }); queryCache.invalidateQueries('accounts-table'); }) - .catch((errors) => {}) + .catch((errors) => { }) .finally(() => { setLoading(false); closeAlert(name); @@ -68,5 +68,5 @@ function AccountBulkInactivateAlert({ export default compose( withAlertStoreConnect(), withAlertActions, - withAccountsActions, + // withAccountsActions, )(AccountBulkInactivateAlert); diff --git a/packages/webapp/src/containers/Purchases/CreditNotes/CreditNoteForm/VendorCreditNoteForm.tsx b/packages/webapp/src/containers/Purchases/CreditNotes/CreditNoteForm/VendorCreditNoteForm.tsx index 4114e463c..86c9caed3 100644 --- a/packages/webapp/src/containers/Purchases/CreditNotes/CreditNoteForm/VendorCreditNoteForm.tsx +++ b/packages/webapp/src/containers/Purchases/CreditNotes/CreditNoteForm/VendorCreditNoteForm.tsx @@ -70,16 +70,16 @@ function VendorCreditNoteForm({ () => ({ ...(!isEmpty(vendorCredit) ? { - ...transformToEditForm(vendorCredit), - } + ...transformToEditForm(vendorCredit), + } : { - ...defaultVendorsCreditNote, - ...(vendorcreditAutoIncrement && { - vendor_credit_number: vendorCreditNumber, - }), - currency_code: base_currency, - ...newVendorCredit, + ...defaultVendorsCreditNote, + ...(vendorcreditAutoIncrement && { + vendor_credit_number: vendorCreditNumber, }), + currency_code: base_currency, + ...newVendorCredit, + }), }), [vendorCredit, base_currency], ); diff --git a/packages/webapp/src/containers/Purchases/CreditNotes/CreditNoteForm/VendorCreditNoteFormHeaderFields.tsx b/packages/webapp/src/containers/Purchases/CreditNotes/CreditNoteForm/VendorCreditNoteFormHeaderFields.tsx index 1054fcf75..06c8d9940 100644 --- a/packages/webapp/src/containers/Purchases/CreditNotes/CreditNoteForm/VendorCreditNoteFormHeaderFields.tsx +++ b/packages/webapp/src/containers/Purchases/CreditNotes/CreditNoteForm/VendorCreditNoteFormHeaderFields.tsx @@ -24,6 +24,7 @@ import { VendorsSelect, Stack, FDateInput, + FInputGroup, } from '@/components'; import { vendorsFieldShouldUpdate, @@ -74,6 +75,7 @@ function VendorCreditNoteFormHeaderFields({ }) { const theme = useTheme(); const fieldsClassName = getFieldsStyle(theme); + const { values } = useFormikContext(); // Handle vendor credit number changing. const handleVendorCreditNumberChange = () => { @@ -81,10 +83,11 @@ function VendorCreditNoteFormHeaderFields({ }; // Handle vendor credit no. field blur. - const handleVendorCreditNoBlur = (form, field) => (event) => { + const handleVendorCreditNoBlur = (event) => { const newValue = event.target.value; + const oldValue = values.vendor_credit_number; - if (field.value !== newValue && vendorcreditAutoIncrement) { + if (oldValue !== newValue && vendorcreditAutoIncrement) { openDialog('vendor-credit-form', { initialFormValues: { manualTransactionNo: newValue, @@ -109,7 +112,6 @@ function VendorCreditNoteFormHeaderFields({ name={'exchange_rate'} formGroupProps={{ label: ' ', inline: true }} /> - {/* ------- Vendor Credit date ------- */} {/* ----------- Vendor Credit No # ----------- */} - } @@ -163,7 +164,7 @@ function VendorCreditNoteFormHeaderFields({ {/* ----------- Reference ----------- */} - } inline={true} fastField> + } inline={true} fastField>