feat: Filter uncategorized transactions by date

This commit is contained in:
Ahmed Bouhuolia
2024-08-23 17:40:05 +02:00
parent f6bad8fe30
commit b4d426d2e8
8 changed files with 74 additions and 13 deletions

View File

@@ -46,6 +46,10 @@ export class ExcludeBankTransactionsController extends BaseController {
query('account_id').optional().isNumeric().toInt(), query('account_id').optional().isNumeric().toInt(),
query('page').optional().isNumeric().toInt(), query('page').optional().isNumeric().toInt(),
query('page_size').optional().isNumeric().toInt(), query('page_size').optional().isNumeric().toInt(),
query('min_date').optional({ nullable: true }).isISO8601().toDate(),
query('max_date').optional({ nullable: true }).isISO8601().toDate(),
query('min_amount').optional({ nullable: true }).isFloat().toFloat(),
query('max_amount').optional({ nullable: true }).isFloat().toFloat(),
], ],
this.validationResult, this.validationResult,
this.getExcludedBankTransactions.bind(this) this.getExcludedBankTransactions.bind(this)

View File

@@ -21,6 +21,10 @@ export class RecognizedTransactionsController extends BaseController {
query('page').optional().isNumeric().toInt(), query('page').optional().isNumeric().toInt(),
query('page_size').optional().isNumeric().toInt(), query('page_size').optional().isNumeric().toInt(),
query('account_id').optional().isNumeric().toInt(), query('account_id').optional().isNumeric().toInt(),
query('min_date').optional({ nullable: true }).isISO8601().toDate(),
query('max_date').optional({ nullable: true }).isISO8601().toDate(),
query('min_amount').optional({ nullable: true }).isFloat().toFloat(),
query('max_amount').optional({ nullable: true }).isFloat().isFloat(),
], ],
this.validationResult, this.validationResult,
this.getRecognizedTransactions.bind(this) this.getRecognizedTransactions.bind(this)

View File

@@ -84,8 +84,10 @@ export default class NewCashflowTransactionController extends BaseController {
param('id').exists().isNumeric().toInt(), param('id').exists().isNumeric().toInt(),
query('page').optional().isNumeric().toInt(), query('page').optional().isNumeric().toInt(),
query('page_size').optional().isNumeric().toInt(), query('page_size').optional().isNumeric().toInt(),
query('min_date').optional().isISO8601().toDate(), query('min_date').optional({ nullable: true }).isISO8601().toDate(),
query('max_date').optional().isISO8601().toDate(), query('max_date').optional({ nullable: true }).isISO8601().toDate(),
query('min_amount').optional({ nullable: true }).isFloat().toFloat(),
query('max_amount').optional({ nullable: true }).isFloat().toFloat(),
]; ];
} }

View File

@@ -67,7 +67,7 @@ export function AccountTransactionsDateFilterForm({
<FFormGroup <FFormGroup
name={'fromDate'} name={'fromDate'}
label={'From Date'} label={'From Date'}
style={{ marginBottom: 0 }} style={{ marginBottom: 0, flex: '1' }}
> >
<FDateInput <FDateInput
name={'fromDate'} name={'fromDate'}
@@ -85,7 +85,7 @@ export function AccountTransactionsDateFilterForm({
<FormGroup <FormGroup
label={'To Date'} label={'To Date'}
name={'toDate'} name={'toDate'}
style={{ marginBottom: 0 }} style={{ marginBottom: 0, flex: '1' }}
> >
<FDateInput <FDateInput
name={'toDate'} name={'toDate'}
@@ -156,11 +156,16 @@ function AccountTransactionDatePeriodField() {
}; };
return ( return (
<FFormGroup name={'period'} label={'Date'} style={{ marginBottom: 0 }}> <FFormGroup
name={'period'}
label={'Date'}
style={{ marginBottom: 0, flex: '0 28%' }}
>
<FSelect <FSelect
name={'period'} name={'period'}
items={periodOptions} items={periodOptions}
onItemSelect={handleItemChange} onItemSelect={handleItemChange}
popoverProps={{ captureDismiss: true }}
/> />
</FFormGroup> </FFormGroup>
); );

View File

@@ -37,8 +37,8 @@ function AccountUncategorizedTransactionsBootRoot({
hasNextPage: hasUncategorizedTransactionsNextPage, hasNextPage: hasUncategorizedTransactionsNextPage,
} = useAccountUncategorizedTransactionsInfinity(accountId, { } = useAccountUncategorizedTransactionsInfinity(accountId, {
page_size: 50, page_size: 50,
min_date: uncategorizedTransactionsFilter?.fromDate, min_date: uncategorizedTransactionsFilter?.fromDate || null,
max_date: uncategorizedTransactionsFilter?.toDate, max_date: uncategorizedTransactionsFilter?.toDate || null,
}); });
// Memorized the cashflow account transactions. // Memorized the cashflow account transactions.
const uncategorizedTransactions = React.useMemo( const uncategorizedTransactions = React.useMemo(

View File

@@ -1,9 +1,11 @@
// @ts-nocheck // @ts-nocheck
import React from 'react'; import React from 'react';
import { flatten, map } from 'lodash'; import { flatten, map } from 'lodash';
import * as R from 'ramda';
import { IntersectionObserver } from '@/components'; import { IntersectionObserver } from '@/components';
import { useAccountTransactionsContext } from '../AccountTransactionsProvider'; import { useAccountTransactionsContext } from '../AccountTransactionsProvider';
import { useExcludedBankTransactionsInfinity } from '@/hooks/query/bank-rules'; import { useExcludedBankTransactionsInfinity } from '@/hooks/query/bank-rules';
import { withBanking } from '../../withBanking';
interface ExcludedBankTransactionsContextValue { interface ExcludedBankTransactionsContextValue {
isExcludedTransactionsLoading: boolean; isExcludedTransactionsLoading: boolean;
@@ -27,7 +29,11 @@ interface ExcludedBankTransactionsTableBootProps {
/** /**
* Account uncategorized transctions provider. * Account uncategorized transctions provider.
*/ */
function ExcludedBankTransactionsTableBoot({ function ExcludedBankTransactionsTableBootRoot({
// #withBanking
uncategorizedTransactionsFilter,
// #ownProps
children, children,
}: ExcludedBankTransactionsTableBootProps) { }: ExcludedBankTransactionsTableBootProps) {
const { accountId } = useAccountTransactionsContext(); const { accountId } = useAccountTransactionsContext();
@@ -44,6 +50,8 @@ function ExcludedBankTransactionsTableBoot({
} = useExcludedBankTransactionsInfinity({ } = useExcludedBankTransactionsInfinity({
page_size: 50, page_size: 50,
account_id: accountId, account_id: accountId,
min_date: uncategorizedTransactionsFilter?.fromDate || null,
max_date: uncategorizedTransactionsFilter.toDate || null,
}); });
// Memorized the cashflow account transactions. // Memorized the cashflow account transactions.
const excludedBankTransactions = React.useMemo( const excludedBankTransactions = React.useMemo(
@@ -84,6 +92,12 @@ function ExcludedBankTransactionsTableBoot({
); );
} }
const ExcludedBankTransactionsTableBoot = R.compose(
withBanking(({ uncategorizedTransactionsFilter }) => ({
uncategorizedTransactionsFilter,
})),
)(ExcludedBankTransactionsTableBootRoot);
const useExcludedTransactionsBoot = () => const useExcludedTransactionsBoot = () =>
React.useContext(ExcludedTransactionsContext); React.useContext(ExcludedTransactionsContext);

View File

@@ -1,9 +1,11 @@
// @ts-nocheck // @ts-nocheck
import React from 'react'; import React from 'react';
import { flatten, map } from 'lodash'; import { flatten, map } from 'lodash';
import { IntersectionObserver } from '@/components'; import * as R from 'ramda';
import { IntersectionObserver, NumericInputCell } from '@/components';
import { useAccountTransactionsContext } from '../AccountTransactionsProvider'; import { useAccountTransactionsContext } from '../AccountTransactionsProvider';
import { useRecognizedBankTransactionsInfinity } from '@/hooks/query/bank-rules'; import { useRecognizedBankTransactionsInfinity } from '@/hooks/query/bank-rules';
import { withBanking } from '../../withBanking';
interface RecognizedTransactionsContextValue { interface RecognizedTransactionsContextValue {
isRecongizedTransactionsLoading: boolean; isRecongizedTransactionsLoading: boolean;
@@ -27,7 +29,10 @@ interface RecognizedTransactionsTableBootProps {
/** /**
* Account uncategorized transctions provider. * Account uncategorized transctions provider.
*/ */
function RecognizedTransactionsTableBoot({ function RecognizedTransactionsTableBootRoot({
// #withBanking
uncategorizedTransactionsFilter,
children, children,
}: RecognizedTransactionsTableBootProps) { }: RecognizedTransactionsTableBootProps) {
const { accountId } = useAccountTransactionsContext(); const { accountId } = useAccountTransactionsContext();
@@ -44,6 +49,8 @@ function RecognizedTransactionsTableBoot({
} = useRecognizedBankTransactionsInfinity({ } = useRecognizedBankTransactionsInfinity({
page_size: 50, page_size: 50,
account_id: accountId, account_id: accountId,
min_date: uncategorizedTransactionsFilter.fromDate || null,
max_date: uncategorizedTransactionsFilter?.toDate || null,
}); });
// Memorized the cashflow account transactions. // Memorized the cashflow account transactions.
const recognizedTransactions = React.useMemo( const recognizedTransactions = React.useMemo(
@@ -84,6 +91,12 @@ function RecognizedTransactionsTableBoot({
); );
} }
const RecognizedTransactionsTableBoot = R.compose(
withBanking(({ uncategorizedTransactionsFilter }) => ({
uncategorizedTransactionsFilter,
})),
)(RecognizedTransactionsTableBootRoot);
const useRecognizedTransactionsBoot = () => const useRecognizedTransactionsBoot = () =>
React.useContext(RecognizedTransactionsContext); React.useContext(RecognizedTransactionsContext);

View File

@@ -1,8 +1,9 @@
// @ts-nocheck // @ts-nocheck
import { useState } from 'react';
import * as R from 'ramda'; import * as R from 'ramda';
import moment from 'moment'; import moment from 'moment';
import { Box, Icon } from '@/components'; import { Box, Icon } from '@/components';
import { Button, Classes, Popover, Position } from '@blueprintjs/core'; import { Classes, Popover, Position } from '@blueprintjs/core';
import { withBankingActions } from '../../withBankingActions'; import { withBankingActions } from '../../withBankingActions';
import { withBanking } from '../../withBanking'; import { withBanking } from '../../withBanking';
import { AccountTransactionsDateFilterForm } from '../AccountTransactionsDateFilter'; import { AccountTransactionsDateFilterForm } from '../AccountTransactionsDateFilter';
@@ -29,17 +30,31 @@ function AccountUncategorizedDateFilterRoot({
? `Date: ${fromDateFormatted}${toDateFormatted}` ? `Date: ${fromDateFormatted}${toDateFormatted}`
: 'Date Filter'; : 'Date Filter';
// Popover open state.
const [isOpen, setIsOpen] = useState<boolean>(false);
// Handle the filter form submitting.
const handleSubmit = () => {
setIsOpen(false);
};
return ( return (
<Popover <Popover
content={ content={
<Box style={{ padding: 18 }}> <Box style={{ padding: 18 }}>
<UncategorizedTransactionsDateFilter /> <UncategorizedTransactionsDateFilter onSubmit={handleSubmit} />
</Box> </Box>
} }
position={Position.RIGHT} position={Position.RIGHT}
popoverClassName={Classes.POPOVER_CONTENT} popoverClassName={Classes.POPOVER_CONTENT}
isOpen={isOpen}
onClose={() => setIsOpen(false)}
> >
<TagButton outline icon={<Icon icon={'date-range'} />}> <TagButton
outline
icon={<Icon icon={'date-range'} />}
onClick={() => setIsOpen(!isOpen)}
>
{buttonText} {buttonText}
</TagButton> </TagButton>
</Popover> </Popover>
@@ -64,6 +79,9 @@ export const UncategorizedTransactionsDateFilter = R.compose(
// #withBanking // #withBanking
uncategorizedTransactionsFilter, uncategorizedTransactionsFilter,
// #ownProps
onSubmit,
}) => { }) => {
const initialValues = { const initialValues = {
...uncategorizedTransactionsFilter, ...uncategorizedTransactionsFilter,
@@ -74,6 +92,7 @@ export const UncategorizedTransactionsDateFilter = R.compose(
fromDate: values.fromDate, fromDate: values.fromDate,
toDate: values.toDate, toDate: values.toDate,
}); });
onSubmit && onSubmit(values);
}; };
return ( return (