fix: bank transactions report

This commit is contained in:
Ahmed Bouhuolia
2024-07-07 22:11:57 +02:00
parent b7487f19d3
commit 9a5befbee7
28 changed files with 560 additions and 158 deletions

View File

@@ -1,6 +1,7 @@
// @ts-nocheck
import React from 'react';
import styled from 'styled-components';
import { Intent } from '@blueprintjs/core';
import {
DataTable,
@@ -9,6 +10,7 @@ import {
TableSkeletonHeader,
TableVirtualizedListRows,
FormattedMessage as T,
AppToaster,
} from '@/components';
import { TABLES } from '@/constants/tables';
@@ -19,9 +21,11 @@ import withDrawerActions from '@/containers/Drawer/withDrawerActions';
import { useMemorizedColumnsWidths } from '@/hooks';
import { useAccountTransactionsColumns, ActionsMenu } from './components';
import { useAccountTransactionsAllContext } from './AccountTransactionsAllBoot';
import { useUnmatchMatchedUncategorizedTransaction } from '@/hooks/query/bank-rules';
import { handleCashFlowTransactionType } from './utils';
import { compose } from '@/utils';
import { useUncategorizeTransaction } from '@/hooks/query';
/**
* Account transactions data table.
@@ -43,14 +47,14 @@ function AccountTransactionsDataTable({
const { cashflowTransactions, isCashFlowTransactionsLoading } =
useAccountTransactionsAllContext();
const { mutateAsync: uncategorizeTransaction } = useUncategorizeTransaction();
const { mutateAsync: unmatchTransaction } =
useUnmatchMatchedUncategorizedTransaction();
// Local storage memorizing columns widths.
const [initialColumnsWidths, , handleColumnResizing] =
useMemorizedColumnsWidths(TABLES.CASHFLOW_Transactions);
// handle delete transaction
const handleDeleteTransaction = ({ reference_id }) => {
openAlert('account-transaction-delete', { referenceId: reference_id });
};
// Handle view details action.
const handleViewDetailCashflowTransaction = (referenceType) => {
handleCashFlowTransactionType(referenceType, openDrawer);
@@ -60,6 +64,38 @@ function AccountTransactionsDataTable({
const referenceType = cell.row.original;
handleCashFlowTransactionType(referenceType, openDrawer);
};
// Handles the unmatching the matched transaction.
const handleUnmatchTransaction = (transaction) => {
unmatchTransaction({ id: transaction.uncategorized_transaction_id })
.then(() => {
AppToaster.show({
message: 'The bank transaction has been unmatched.',
intent: Intent.SUCCESS,
});
})
.catch(() => {
AppToaster.show({
message: 'Something went wrong.',
intent: Intent.DANGER,
});
});
};
// Handle uncategorize transaction.
const handleUncategorizeTransaction = (transaction) => {
uncategorizeTransaction(transaction.uncategorized_transaction_id)
.then(() => {
AppToaster.show({
message: 'The bank transaction has been uncategorized.',
intent: Intent.SUCCESS,
});
})
.catch(() => {
AppToaster.show({
message: 'Something went wrong.',
intent: Intent.DANGER,
});
});
};
return (
<CashflowTransactionsTable
@@ -87,7 +123,8 @@ function AccountTransactionsDataTable({
className="table-constrant"
payload={{
onViewDetails: handleViewDetailCashflowTransaction,
onDelete: handleDeleteTransaction,
onUncategorize: handleUncategorizeTransaction,
onUnmatch: handleUnmatchTransaction,
}}
/>
);

View File

@@ -12,19 +12,17 @@ import {
AppToaster,
} from '@/components';
import { TABLES } from '@/constants/tables';
import { ActionsMenu } from './UncategorizedTransactions/components';
import withSettings from '@/containers/Settings/withSettings';
import { withBankingActions } from '../withBankingActions';
import { useMemorizedColumnsWidths } from '@/hooks';
import {
ActionsMenu,
useAccountUncategorizedTransactionsColumns,
} from './components';
import { useAccountUncategorizedTransactionsColumns } from './components';
import { useAccountUncategorizedTransactionsContext } from './AllTransactionsUncategorizedBoot';
import { useExcludeUncategorizedTransaction } from '@/hooks/query/bank-rules';
import { compose } from '@/utils';
import { useExcludeUncategorizedTransaction } from '@/hooks/query/bank-rules';
/**
* Account transactions data table.

View File

@@ -0,0 +1,25 @@
// @ts-nocheck
import { Menu, MenuItem, MenuDivider } from '@blueprintjs/core';
import { Icon } from '@/components';
import { safeCallback } from '@/utils';
export function ActionsMenu({
payload: { onCategorize, onExclude },
row: { original },
}) {
return (
<Menu>
<MenuItem
icon={<Icon icon="reader-18" />}
text={'Categorize'}
onClick={safeCallback(onCategorize, original)}
/>
<MenuDivider />
<MenuItem
text={'Exclude'}
onClick={safeCallback(onExclude, original)}
icon={<Icon icon="disable" iconSize={16} />}
/>
</Menu>
);
}

View File

@@ -5,44 +5,57 @@ import {
Intent,
Menu,
MenuItem,
MenuDivider,
Tag,
Popover,
PopoverInteractionKind,
Position,
Tooltip,
MenuDivider,
} from '@blueprintjs/core';
import {
Box,
Can,
FormatDateCell,
Icon,
MaterialProgressBar,
} from '@/components';
import { Box, FormatDateCell, Icon, MaterialProgressBar } from '@/components';
import { useAccountTransactionsContext } from './AccountTransactionsProvider';
import { safeCallback } from '@/utils';
export function ActionsMenu({
payload: { onCategorize, onExclude },
payload: { onUncategorize, onUnmatch },
row: { original },
}) {
return (
<Menu>
<MenuItem
icon={<Icon icon="reader-18" />}
text={'Categorize'}
onClick={safeCallback(onCategorize, original)}
/>
<MenuDivider />
<MenuItem
text={'Exclude'}
onClick={safeCallback(onExclude, original)}
icon={<Icon icon="disable" iconSize={16} />}
/>
{original.status === 'categorized' && (
<MenuItem
icon={<Icon icon="reader-18" />}
text={'Uncategorize'}
onClick={safeCallback(onUncategorize, original)}
/>
)}
{original.status === 'matched' && (
<MenuItem
text={'Unmatch'}
icon={<Icon icon="unlink" iconSize={16} />}
onClick={safeCallback(onUnmatch, original)}
/>
)}
</Menu>
);
}
const allTransactionsStatusAccessor = (transaction) => {
return (
<Tag
intent={
transaction.status === 'categorized'
? Intent.SUCCESS
: transaction.status === 'matched'
? Intent.SUCCESS
: Intent.NONE
}
minimal={transaction.status === 'manual'}
>
{transaction.formatted_status}
</Tag>
);
};
/**
* Retrieve account transctions table columns.
*/
@@ -70,7 +83,7 @@ export function useAccountTransactionsColumns() {
},
{
id: 'transaction_number',
Header: intl.get('transaction_number'),
Header: 'Transaction #',
accessor: 'transaction_number',
width: 160,
className: 'transaction_number',
@@ -79,13 +92,18 @@ export function useAccountTransactionsColumns() {
},
{
id: 'reference_number',
Header: intl.get('reference_no'),
Header: 'Ref.#',
accessor: 'reference_number',
width: 160,
className: 'reference_number',
clickable: true,
textOverview: true,
},
{
id: 'status',
Header: 'Status',
accessor: allTransactionsStatusAccessor,
},
{
id: 'deposit',
Header: intl.get('cash_flow.label.deposit'),
@@ -116,16 +134,6 @@ export function useAccountTransactionsColumns() {
align: 'right',
clickable: true,
},
{
id: 'balance',
Header: intl.get('balance'),
accessor: 'formatted_balance',
className: 'balance',
width: 150,
textOverview: true,
clickable: true,
align: 'right',
},
],
[],
);
@@ -204,7 +212,7 @@ export function useAccountUncategorizedTransactionsColumns() {
},
{
id: 'reference_number',
Header: intl.get('reference_no'),
Header: 'Ref.#',
accessor: 'reference_number',
width: 50,
className: 'reference_number',

View File

@@ -212,8 +212,8 @@ function PerfectMatchingTransactions() {
key={index}
label={`${match.transsactionTypeFormatted} for ${match.amountFormatted}`}
date={match.dateFormatted}
transactionId={match.transactionId}
transactionType={match.transactionType}
transactionId={match.referenceId}
transactionType={match.referenceType}
/>
))}
</Stack>

View File

@@ -37,7 +37,7 @@ interface CreateBankRuleResponse {}
/**
* Creates a new bank rule.
* @param {UseMutationOptions<CreateBankRuleValues, Error, CreateBankRuleValues>} options -
* @returns {UseMutationResult<CreateBankRuleValues, Error, CreateBankRuleValues>}
* @returns {UseMutationResult<CreateBankRuleValues, Error, CreateBankRuleValues>}TCHES
*/
export function useCreateBankRule(
options?: UseMutationOptions<
@@ -322,6 +322,46 @@ export function useMatchUncategorizedTransaction(
queryClient.invalidateQueries(
t.CASHFLOW_ACCOUNT_UNCATEGORIZED_TRANSACTIONS_INFINITY,
);
queryClient.invalidateQueries(t.CASHFLOW_ACCOUNT_TRANSACTIONS_INFINITY);
},
...props,
});
}
interface UnmatchUncategorizedTransactionValues {
id: number;
}
interface UnmatchUncategorizedTransactionRes {}
/**
* Unmatch the given matched uncategorized transaction.
* @param {UseMutationOptions<UnmatchUncategorizedTransactionRes, Error, UnmatchUncategorizedTransactionValues>} props
* @returns {UseMutationResult<UnmatchUncategorizedTransactionRes, Error, UnmatchUncategorizedTransactionValues>}
*/
export function useUnmatchMatchedUncategorizedTransaction(
props?: UseMutationOptions<
UnmatchUncategorizedTransactionRes,
Error,
UnmatchUncategorizedTransactionValues
>,
): UseMutationResult<
UnmatchUncategorizedTransactionRes,
Error,
UnmatchUncategorizedTransactionValues
> {
const queryClient = useQueryClient();
const apiRequest = useApiRequest();
return useMutation<
UnmatchUncategorizedTransactionRes,
Error,
UnmatchUncategorizedTransactionValues
>(({ id }) => apiRequest.post(`/banking/matches/unmatch/${id}`), {
onSuccess: (res, id) => {
queryClient.invalidateQueries(
t.CASHFLOW_ACCOUNT_UNCATEGORIZED_TRANSACTIONS_INFINITY,
);
queryClient.invalidateQueries(t.CASHFLOW_ACCOUNT_TRANSACTIONS_INFINITY);
},
...props,
});

View File

@@ -629,4 +629,10 @@ export default {
],
viewBox: '0 0 16 16',
},
unlink: {
path: [
'M11.9975 0.00500107C14.2061 0.00500107 15.995 1.79388 15.995 4.0025C15.995 5.11181 15.5353 6.0912 14.8058 6.81075L14.8257 6.83074L13.8264 7.83011L13.8064 7.81012C13.2562 8.36798 12.5482 8.76807 11.7539 8.92548L10.8249 7.99643L12.4073 6.401L13.4066 5.40163L13.3966 5.39163C13.7564 5.03186 13.9963 4.54217 13.9963 3.99251C13.9963 2.8932 13.0968 1.99376 11.9975 1.99376C11.4479 1.99376 10.9582 2.23361 10.5984 2.59338L10.5884 2.58339L8.0001 5.17168L7.07559 4.24717C7.23518 3.45247 7.63943 2.74409 8.18989 2.19363L8.1699 2.17365L9.16928 1.17427L9.18926 1.19426C9.90882 0.464714 10.8982 0.00500107 11.9975 0.00500107ZM2.29289 2.29289C2.68341 1.90237 3.31657 1.90237 3.7071 2.29289L13.7071 12.2929C14.0976 12.6834 14.0976 13.3166 13.7071 13.7071C13.3166 14.0976 12.6834 14.0976 12.2929 13.7071L8.93565 10.3499C8.97565 10.562 8.99938 10.7781 8.99938 10.9981C8.99938 12.0974 8.53966 13.0868 7.81012 13.8064L7.83011 13.8263L6.83073 14.8257L6.81074 14.8057C6.09119 15.5353 5.10181 15.995 4.0025 15.995C1.79388 15.995 0.00499688 14.2061 0.00499688 11.9975C0.00499688 10.8982 0.464709 9.90879 1.19425 9.18924L1.17427 9.16925L2.17364 8.16988L2.19363 8.18986C2.91318 7.46032 3.90256 7.00061 5.00187 7.00061C5.2251 7.00061 5.44064 7.02369 5.65087 7.06509L2.29289 3.7071C1.90236 3.31658 1.90236 2.68341 2.29289 2.29289ZM8.00244 9.41666L8.707 10.1212L5.41162 13.4166L5.40162 13.4066C5.04185 13.7664 4.55216 14.0062 4.0025 14.0062C2.90319 14.0062 2.00375 13.1068 2.00375 12.0075C2.00375 11.4578 2.2436 10.9681 2.60337 10.6084L2.59338 10.5984L5.88876 7.30298L6.58333 7.99755L4.29231 10.2886C4.11243 10.4685 4.00249 10.7183 4.00249 10.9981C4.00249 11.5478 4.45221 11.9975 5.00187 11.9975C5.28169 11.9975 5.53154 11.8876 5.71143 11.7077L8.00244 9.41666ZM8.70466 5.87623L10.1238 7.29534L11.7077 5.71143C11.8876 5.53154 11.9975 5.2817 11.9975 5.00187C11.9975 4.45222 11.5478 4.0025 10.9981 4.0025C10.7183 4.0025 10.4685 4.11243 10.2886 4.29232L8.70466 5.87623Z',
],
viewBox: '0 0 16 16',
},
};