From f9cf6d325acd6455734ca0a656143ccd2c048513 Mon Sep 17 00:00:00 2001 From: Ahmed Bouhuolia Date: Sun, 4 Aug 2024 21:14:05 +0200 Subject: [PATCH] feat: pause bank account feeds --- .../Banking/BankAccountsController.ts | 4 ++-- .../src/services/Accounts/AccountTransform.ts | 18 ++++++++++++++ .../src/services/Accounts/GetAccount.ts | 5 +++- .../BankAccounts/PauseBankAccountFeeds.tsx | 2 +- .../BankAccounts/ResumeBankAccountFeeds.tsx | 2 +- .../services/Banking/Plaid/PlaidWebhooks.ts | 19 ++++++++++++++- .../AccountTransactionsActionsBar.tsx | 24 +++++++++++++------ .../src/style/pages/Dashboard/Dashboard.scss | 3 +++ 8 files changed, 64 insertions(+), 13 deletions(-) diff --git a/packages/server/src/api/controllers/Banking/BankAccountsController.ts b/packages/server/src/api/controllers/Banking/BankAccountsController.ts index 942c6b890..424c28857 100644 --- a/packages/server/src/api/controllers/Banking/BankAccountsController.ts +++ b/packages/server/src/api/controllers/Banking/BankAccountsController.ts @@ -127,7 +127,7 @@ export class BankAccountsController extends BaseController { } /** - * + * Resumes the bank account feeds sync. * @param {Request} req * @param {Response} res * @param {NextFunction} next @@ -154,7 +154,7 @@ export class BankAccountsController extends BaseController { } /** - * + * Pauses the bank account feeds sync. * @param {Request} req * @param {Response} res * @param {NextFunction} next diff --git a/packages/server/src/services/Accounts/AccountTransform.ts b/packages/server/src/services/Accounts/AccountTransform.ts index 28f3b74a5..1fde95fe4 100644 --- a/packages/server/src/services/Accounts/AccountTransform.ts +++ b/packages/server/src/services/Accounts/AccountTransform.ts @@ -18,9 +18,18 @@ export class AccountTransformer extends Transformer { 'flattenName', 'bankBalanceFormatted', 'lastFeedsUpdatedAtFormatted', + 'isFeedsPaused', ]; }; + /** + * Exclude attributes. + * @returns {string[]} + */ + public excludeAttributes = (): string[] => { + return ['plaidItem']; + }; + /** * Retrieves the flatten name with all dependants accounts names. * @param {IAccount} account - @@ -66,6 +75,15 @@ export class AccountTransformer extends Transformer { return this.formatDate(account.lastFeedsUpdatedAt); }; + /** + * Detarmines whether the bank account connection is paused. + * @param account + * @returns {boolean} + */ + protected isFeedsPaused = (account: any): boolean => { + return account.plaidItem?.isPaused || false; + }; + /** * Transformes the accounts collection to flat or nested array. * @param {IAccount[]} diff --git a/packages/server/src/services/Accounts/GetAccount.ts b/packages/server/src/services/Accounts/GetAccount.ts index 7da213328..c16c69459 100644 --- a/packages/server/src/services/Accounts/GetAccount.ts +++ b/packages/server/src/services/Accounts/GetAccount.ts @@ -25,7 +25,10 @@ export class GetAccount { const { accountRepository } = this.tenancy.repositories(tenantId); // Find the given account or throw not found error. - const account = await Account.query().findById(accountId).throwIfNotFound(); + const account = await Account.query() + .findById(accountId) + .withGraphFetched('plaidItem') + .throwIfNotFound(); const accountsGraph = await accountRepository.getDependencyGraph(); diff --git a/packages/server/src/services/Banking/BankAccounts/PauseBankAccountFeeds.tsx b/packages/server/src/services/Banking/BankAccounts/PauseBankAccountFeeds.tsx index 4a4f24a6c..3b16ecd76 100644 --- a/packages/server/src/services/Banking/BankAccounts/PauseBankAccountFeeds.tsx +++ b/packages/server/src/services/Banking/BankAccounts/PauseBankAccountFeeds.tsx @@ -37,7 +37,7 @@ export class PauseBankAccountFeeds { } return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => { await PlaidItem.query(trx).findById(oldAccount.plaidItem.id).patch({ - pausedAt: null, + pausedAt: new Date(), }); }); } diff --git a/packages/server/src/services/Banking/BankAccounts/ResumeBankAccountFeeds.tsx b/packages/server/src/services/Banking/BankAccounts/ResumeBankAccountFeeds.tsx index 0808782c6..ab630a145 100644 --- a/packages/server/src/services/Banking/BankAccounts/ResumeBankAccountFeeds.tsx +++ b/packages/server/src/services/Banking/BankAccounts/ResumeBankAccountFeeds.tsx @@ -36,7 +36,7 @@ export class ResumeBankAccountFeeds { } return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => { await PlaidItem.query(trx).findById(oldAccount.plaidItem.id).patch({ - pausedAt: new Date(), + pausedAt: null, }); }); } diff --git a/packages/server/src/services/Banking/Plaid/PlaidWebhooks.ts b/packages/server/src/services/Banking/Plaid/PlaidWebhooks.ts index 5c3afb1ec..24a8c5d8d 100644 --- a/packages/server/src/services/Banking/Plaid/PlaidWebhooks.ts +++ b/packages/server/src/services/Banking/Plaid/PlaidWebhooks.ts @@ -1,11 +1,15 @@ import { Inject, Service } from 'typedi'; import { PlaidUpdateTransactions } from './PlaidUpdateTransactions'; +import HasTenancyService from '@/services/Tenancy/TenancyService'; @Service() export class PlaidWebooks { @Inject() private updateTransactionsService: PlaidUpdateTransactions; + @Inject() + private tenancy: HasTenancyService; + /** * Listens to Plaid webhooks * @param {number} tenantId - Tenant Id. @@ -61,7 +65,7 @@ export class PlaidWebooks { plaidItemId: string ): void { console.log( - `WEBHOOK: TRANSACTIONS: ${webhookCode}: Plaid_item_id ${plaidItemId}: ${additionalInfo}` + `PLAID WEBHOOK: TRANSACTIONS: ${webhookCode}: Plaid_item_id ${plaidItemId}: ${additionalInfo}` ); } @@ -78,8 +82,21 @@ export class PlaidWebooks { plaidItemId: string, webhookCode: string ): Promise { + const { PlaidItem } = this.tenancy.models(tenantId); + const plaidItem = await PlaidItem.query() + .findById(plaidItemId) + .throwIfNotFound(); + switch (webhookCode) { case 'SYNC_UPDATES_AVAILABLE': { + if (plaidItem.isPaused) { + this.serverLogAndEmitSocket( + 'Plaid item syncing is paused.', + webhookCode, + plaidItemId + ); + return; + } // Fired when new transactions data becomes available. const { addedCount, modifiedCount, removedCount } = await this.updateTransactionsService.updateTransactions( diff --git a/packages/webapp/src/containers/CashFlow/AccountTransactions/AccountTransactionsActionsBar.tsx b/packages/webapp/src/containers/CashFlow/AccountTransactions/AccountTransactionsActionsBar.tsx index 7a5ddd8fc..994b2c6e0 100644 --- a/packages/webapp/src/containers/CashFlow/AccountTransactions/AccountTransactionsActionsBar.tsx +++ b/packages/webapp/src/containers/CashFlow/AccountTransactions/AccountTransactionsActionsBar.tsx @@ -78,6 +78,7 @@ function AccountTransactionsActionsBar({ const addMoneyOutOptions = useMemo(() => getAddMoneyOutOptions(), []); const isFeedsActive = !!currentAccount.is_feeds_active; + const isFeedsPaused = currentAccount.is_feeds_paused; const isSyncingOwner = currentAccount.is_syncing_owner; // Handle table row size change. @@ -244,7 +245,9 @@ function AccountTransactionsActionsBar({ } - intent={isFeedsActive ? Intent.SUCCESS : Intent.DANGER} + intent={ + isFeedsActive + ? isFeedsPaused + ? Intent.WARNING + : Intent.SUCCESS + : Intent.DANGER + } /> @@ -291,6 +300,11 @@ function AccountTransactionsActionsBar({ content={ + + + + + - + - - - - diff --git a/packages/webapp/src/style/pages/Dashboard/Dashboard.scss b/packages/webapp/src/style/pages/Dashboard/Dashboard.scss index da1a3249f..a6ea3968f 100644 --- a/packages/webapp/src/style/pages/Dashboard/Dashboard.scss +++ b/packages/webapp/src/style/pages/Dashboard/Dashboard.scss @@ -229,6 +229,9 @@ $dashboard-views-bar-height: 44px; } } + &.#{$ns}-minimal.#{$ns}-intent-warning{ + color: #cc7e25; + } &.button--blue-highlight { background-color: #ebfaff;