feat: get bank account meta summary

This commit is contained in:
Ahmed Bouhuolia
2024-07-02 19:21:26 +02:00
parent 8a09de9771
commit 91730d204e
22 changed files with 476 additions and 69 deletions

View File

@@ -2,6 +2,7 @@
.root {
flex: 1 1 auto;
overflow: auto;
padding-bottom: 60px;
}
.transaction {
@@ -35,4 +36,5 @@
.footerTotal {
padding: 8px 16px;
border-top: 1px solid #d8d9d9;
line-height: 24px;
}

View File

@@ -1,11 +1,23 @@
// @ts-nocheck
import { Tab, Tabs } from '@blueprintjs/core';
import { MatchingBankTransaction } from './MatchingTransaction';
import styles from './CategorizeTransactionTabs.module.scss';
import { CategorizeTransactionContent } from '../CategorizeTransaction/drawers/CategorizeTransactionDrawer/CategorizeTransactionContent';
import { useCategorizeTransactionTabsBoot } from './CategorizeTransactionTabsBoot';
import styles from './CategorizeTransactionTabs.module.scss';
export function CategorizeTransactionTabs() {
const { uncategorizedTransaction } = useCategorizeTransactionTabsBoot();
const defaultSelectedTabId = uncategorizedTransaction?.is_recognized
? 'categorize'
: 'matching';
return (
<Tabs large renderActiveTabPanelOnly className={styles.tabs}>
<Tabs
large
renderActiveTabPanelOnly
defaultSelectedTabId={defaultSelectedTabId}
className={styles.tabs}
>
<Tab
id="categorize"
title="Categorize Transaction"

View File

@@ -2,22 +2,26 @@
import { isEmpty } from 'lodash';
import * as R from 'ramda';
import { AnchorButton, Button, Intent, Tag, Text } from '@blueprintjs/core';
import { FastField, FastFieldProps, Formik } from 'formik';
import { AppToaster, Box, FormatNumber, Group, Stack } from '@/components';
import {
MatchingTransactionBoot,
useMatchingTransactionBoot,
} from './MatchingTransactionBoot';
import { MatchTransaction, MatchTransactionProps } from './MatchTransaction';
import styles from './CategorizeTransactionAside.module.scss';
import { FastField, FastFieldProps, Form, Formik } from 'formik';
import { useMatchUncategorizedTransaction } from '@/hooks/query/bank-rules';
import { MatchingTransactionFormValues } from './types';
import { transformToReq, useGetPendingAmountMatched } from './utils';
import {
transformToReq,
useGetPendingAmountMatched,
useIsShowReconcileTransactionLink,
} from './utils';
import { useCategorizeTransactionTabsBoot } from './CategorizeTransactionTabsBoot';
import {
WithBankingActionsProps,
withBankingActions,
} from '../withBankingActions';
import styles from './CategorizeTransactionAside.module.scss';
const initialValues = {
matched: {},
@@ -189,20 +193,26 @@ interface MatchTransctionFooterProps extends WithBankingActionsProps {}
*/
const MatchTransactionFooter = R.compose(withBankingActions)(
({ closeMatchingTransactionAside }: MatchTransctionFooterProps) => {
const totalPending = useGetPendingAmountMatched();
const showReconcileLink = useIsShowReconcileTransactionLink();
const handleCancelBtnClick = () => {
closeMatchingTransactionAside();
};
const totalPending = useGetPendingAmountMatched();
return (
<Box className={styles.footer}>
<Box className={styles.footerTotal}>
<Group position={'apart'}>
<AnchorButton small minimal intent={Intent.PRIMARY}>
Add Reconcile Transaction +
</AnchorButton>
<Text style={{ fontSize: 13 }} tagName="span">
{showReconcileLink && (
<AnchorButton small minimal intent={Intent.PRIMARY}>
Add Reconcile Transaction +
</AnchorButton>
)}
<Text
style={{ fontSize: 14, marginLeft: 'auto', color: '#5F6B7C' }}
tagName="span"
>
Pending <FormatNumber value={totalPending} currency={'USD'} />
</Text>
</Group>

View File

@@ -1,6 +1,8 @@
import { useFormikContext } from 'formik';
import { MatchingTransactionFormValues } from './types';
import { useMatchingTransactionBoot } from './MatchingTransactionBoot';
import { useCategorizeTransactionTabsBoot } from './CategorizeTransactionTabsBoot';
import { useMemo } from 'react';
export const transformToReq = (values: MatchingTransactionFormValues) => {
const matchedTransactions = Object.entries(values.matched)
@@ -17,18 +19,38 @@ export const transformToReq = (values: MatchingTransactionFormValues) => {
export const useGetPendingAmountMatched = () => {
const { values } = useFormikContext<MatchingTransactionFormValues>();
const { perfectMatches, possibleMatches } = useMatchingTransactionBoot();
const { uncategorizedTransaction } = useCategorizeTransactionTabsBoot();
const matchedItems = [...perfectMatches, ...possibleMatches].filter(
(match) => {
const key = `${match.transactionType}-${match.transactionId}`;
return values.matched[key];
},
);
const totalMatchedAmount = matchedItems.reduce(
(total, item) => total + parseFloat(item.amount),
0,
);
const pendingAmount = 0 - totalMatchedAmount;
return useMemo(() => {
const matchedItems = [...perfectMatches, ...possibleMatches].filter(
(match) => {
const key = `${match.transactionType}-${match.transactionId}`;
return values.matched[key];
},
);
const totalMatchedAmount = matchedItems.reduce(
(total, item) => total + parseFloat(item.amount),
0,
);
const amount = uncategorizedTransaction.amount;
const pendingAmount = amount - totalMatchedAmount;
return pendingAmount;
return pendingAmount;
}, [uncategorizedTransaction, perfectMatches, possibleMatches, values]);
};
export const useAtleastOneMatchedSelected = () => {
const { values } = useFormikContext<MatchingTransactionFormValues>();
return useMemo(() => {
const matchedCount = Object.values(values.matched).filter(Boolean).length;
return matchedCount > 0;
}, [values]);
};
export const useIsShowReconcileTransactionLink = () => {
const pendingAmount = useGetPendingAmountMatched();
const atleastOneSelected = useAtleastOneMatchedSelected();
return atleastOneSelected && pendingAmount !== 0;
};