feat: pause bank account feeds

This commit is contained in:
Ahmed Bouhuolia
2024-08-04 21:14:05 +02:00
parent fc0240c692
commit f9cf6d325a
8 changed files with 64 additions and 13 deletions

View File

@@ -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

View File

@@ -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[]}

View File

@@ -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();

View File

@@ -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(),
});
});
}

View File

@@ -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,
});
});
}

View File

@@ -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<void> {
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(

View File

@@ -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({
<Tooltip
content={
isFeedsActive
? 'The bank syncing is active'
? isFeedsPaused
? 'The bank syncing is paused'
: 'The bank syncing is active'
: 'The bank syncing is disconnected'
}
minimal={true}
@@ -253,7 +256,13 @@ function AccountTransactionsActionsBar({
<Button
className={Classes.MINIMAL}
icon={<Icon icon="feed" iconSize={16} />}
intent={isFeedsActive ? Intent.SUCCESS : Intent.DANGER}
intent={
isFeedsActive
? isFeedsPaused
? Intent.WARNING
: Intent.SUCCESS
: Intent.DANGER
}
/>
</Tooltip>
</If>
@@ -291,6 +300,11 @@ function AccountTransactionsActionsBar({
content={
<Menu>
<If condition={isSyncingOwner && isFeedsActive}>
<MenuItem onClick={handleBankUpdateClick} text={'Update'} />
<MenuDivider />
</If>
<If condition={isSyncingOwner && isFeedsActive && !isFeedsPaused}>
<MenuItem
onClick={handlePauseFeedsSyncing}
text={'Pause bank feeds'}
@@ -298,7 +312,7 @@ function AccountTransactionsActionsBar({
<MenuDivider />
</If>
<If condition={isSyncingOwner && isFeedsActive}>
<If condition={isSyncingOwner && isFeedsActive && isFeedsPaused}>
<MenuItem
onClick={handleResumeFeedsSyncing}
text={'Resume bank feeds'}
@@ -306,10 +320,6 @@ function AccountTransactionsActionsBar({
<MenuDivider />
</If>
<If condition={isSyncingOwner && isFeedsActive}>
<MenuItem onClick={handleBankUpdateClick} text={'Update'} />
<MenuDivider />
</If>
<MenuItem onClick={handleBankRulesClick} text={'Bank rules'} />
<If condition={isSyncingOwner && isFeedsActive}>

View File

@@ -229,6 +229,9 @@ $dashboard-views-bar-height: 44px;
}
}
&.#{$ns}-minimal.#{$ns}-intent-warning{
color: #cc7e25;
}
&.button--blue-highlight {
background-color: #ebfaff;