From 5bbcb7913db8e86ff8999b2188d23802857903ec Mon Sep 17 00:00:00 2001 From: Ahmed Bouhuolia Date: Sun, 30 Jun 2024 16:54:25 +0200 Subject: [PATCH] fix: Delete bank rule if it has no associations --- packages/server/src/loaders/eventEmitter.ts | 2 + .../UnlinkBankRuleRecognizedTransactions.ts | 54 +++++++++++++++++++ .../events/UnlinkBankRuleOnDeleteBankRule.ts | 34 ++++++++++++ 3 files changed, 90 insertions(+) create mode 100644 packages/server/src/services/Banking/Rules/UnlinkBankRuleRecognizedTransactions.ts create mode 100644 packages/server/src/services/Banking/Rules/events/UnlinkBankRuleOnDeleteBankRule.ts diff --git a/packages/server/src/loaders/eventEmitter.ts b/packages/server/src/loaders/eventEmitter.ts index 2e5f46c3f..6a282a8f7 100644 --- a/packages/server/src/loaders/eventEmitter.ts +++ b/packages/server/src/loaders/eventEmitter.ts @@ -109,6 +109,7 @@ import { ValidateMatchingOnPaymentReceivedDelete } from '@/services/Banking/Matc import { ValidateMatchingOnPaymentMadeDelete } from '@/services/Banking/Matching/events/ValidateMatchingOnPaymentMadeDelete'; import { ValidateMatchingOnCashflowDelete } from '@/services/Banking/Matching/events/ValidateMatchingOnCashflowDelete'; import { RecognizeSyncedBankTranasctions } from '@/services/Banking/Plaid/subscribers/RecognizeSyncedBankTransactions'; +import { UnlinkBankRuleOnDeleteBankRule } from '@/services/Banking/Rules/events/UnlinkBankRuleOnDeleteBankRule'; export default () => { return new EventPublisher(); @@ -256,6 +257,7 @@ export const susbcribers = () => { // Bank Rules TriggerRecognizedTransactions, + UnlinkBankRuleOnDeleteBankRule, // Validate matching ValidateMatchingOnCashflowDelete, diff --git a/packages/server/src/services/Banking/Rules/UnlinkBankRuleRecognizedTransactions.ts b/packages/server/src/services/Banking/Rules/UnlinkBankRuleRecognizedTransactions.ts new file mode 100644 index 000000000..25bff99ef --- /dev/null +++ b/packages/server/src/services/Banking/Rules/UnlinkBankRuleRecognizedTransactions.ts @@ -0,0 +1,54 @@ +import { Inject, Service } from 'typedi'; +import { Knex } from 'knex'; +import HasTenancyService from '@/services/Tenancy/TenancyService'; +import UnitOfWork from '@/services/UnitOfWork'; + +@Service() +export class UnlinkBankRuleRecognizedTransactions { + @Inject() + private tenancy: HasTenancyService; + + @Inject() + private uow: UnitOfWork; + + /** + * Unlinks the given bank rule out of recognized transactions. + * @param {number} tenantId - Tenant id. + * @param {number} bankRuleId - Bank rule id. + * @param {Knex.Transaction} trx - Knex transaction. + * @returns {Promise} + */ + public async unlinkBankRuleOutRecognizedTransactions( + tenantId: number, + bankRuleId: number, + trx?: Knex.Transaction + ): Promise { + const { UncategorizedCashflowTransaction, RecognizedBankTransaction } = + this.tenancy.models(tenantId); + + return this.uow.withTransaction( + tenantId, + async (trx: Knex.Transaction) => { + // Retrieves all the recognized transactions of the banbk rule. + const recognizedTransactions = await RecognizedBankTransaction.query( + trx + ).where('bankRuleId', bankRuleId); + + const uncategorizedTransactionIds = recognizedTransactions.map( + (r) => r.uncategorizedTransactionId + ); + // Unlink the recongized transactions out of uncategorized transactions. + await UncategorizedCashflowTransaction.query(trx) + .whereIn('id', uncategorizedTransactionIds) + .patch({ + recognizedTransactionId: null, + }); + // Delete the recognized bank transactions that assocaited to bank rule. + await RecognizedBankTransaction.query(trx) + .where({ bankRuleId }) + .delete(); + }, + trx + ); + } +} diff --git a/packages/server/src/services/Banking/Rules/events/UnlinkBankRuleOnDeleteBankRule.ts b/packages/server/src/services/Banking/Rules/events/UnlinkBankRuleOnDeleteBankRule.ts new file mode 100644 index 000000000..91ad36fe9 --- /dev/null +++ b/packages/server/src/services/Banking/Rules/events/UnlinkBankRuleOnDeleteBankRule.ts @@ -0,0 +1,34 @@ +import { Inject, Service } from 'typedi'; +import events from '@/subscribers/events'; +import { UnlinkBankRuleRecognizedTransactions } from '../UnlinkBankRuleRecognizedTransactions'; +import { IBankRuleEventDeletingPayload } from '../types'; + +@Service() +export class UnlinkBankRuleOnDeleteBankRule { + @Inject() + private unlinkBankRule: UnlinkBankRuleRecognizedTransactions; + + /** + * Constructor method. + */ + public attach(bus) { + bus.subscribe( + events.bankRules.onDeleting, + this.unlinkBankRuleOutRecognizedTransactionsOnRuleDeleting.bind(this) + ); + } + + /** + * Unlinks the bank rule out of recognized transactions. + * @param {IBankRuleEventDeletingPayload} payload - + */ + private async unlinkBankRuleOutRecognizedTransactionsOnRuleDeleting({ + tenantId, + ruleId, + }: IBankRuleEventDeletingPayload) { + await this.unlinkBankRule.unlinkBankRuleOutRecognizedTransactions( + tenantId, + ruleId + ); + } +}