mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-19 14:20:31 +00:00
feat: wip categorize the cashflow transactions
This commit is contained in:
@@ -80,10 +80,7 @@ export default class NewCashflowTransactionController extends BaseController {
|
|||||||
public get categorizeCashflowTransactionValidationSchema() {
|
public get categorizeCashflowTransactionValidationSchema() {
|
||||||
return [
|
return [
|
||||||
check('date').exists().isISO8601().toDate(),
|
check('date').exists().isISO8601().toDate(),
|
||||||
oneOf([
|
check('credit_account_id').exists().isInt().toInt(),
|
||||||
check('to_account_id').exists().isInt().toInt(),
|
|
||||||
check('from_account_id').exists().isInt().toInt(),
|
|
||||||
]),
|
|
||||||
check('transaction_number').optional(),
|
check('transaction_number').optional(),
|
||||||
check('transaction_type').exists(),
|
check('transaction_type').exists(),
|
||||||
check('reference_no').optional(),
|
check('reference_no').optional(),
|
||||||
|
|||||||
@@ -235,8 +235,7 @@ export interface ICashflowTransactionSchema {
|
|||||||
export interface ICashflowTransactionInput extends ICashflowTransactionSchema {}
|
export interface ICashflowTransactionInput extends ICashflowTransactionSchema {}
|
||||||
|
|
||||||
export interface ICategorizeCashflowTransactioDTO {
|
export interface ICategorizeCashflowTransactioDTO {
|
||||||
fromAccountId: number;
|
creditAccountId: number;
|
||||||
toAccountId: number;
|
|
||||||
referenceNo: string;
|
referenceNo: string;
|
||||||
transactionNumber: string;
|
transactionNumber: string;
|
||||||
transactionType: string;
|
transactionType: string;
|
||||||
|
|||||||
@@ -318,7 +318,7 @@ export default class Account extends mixin(TenantModel, [
|
|||||||
to: 'uncategorized_cashflow_transactions.accountId',
|
to: 'uncategorized_cashflow_transactions.accountId',
|
||||||
},
|
},
|
||||||
filter: (query) => {
|
filter: (query) => {
|
||||||
query.filter('categorized', false);
|
query.where('categorized', false);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/* eslint-disable global-require */
|
/* eslint-disable global-require */
|
||||||
import TenantModel from 'models/TenantModel';
|
import TenantModel from 'models/TenantModel';
|
||||||
import { Model } from 'objection';
|
import { Model, ModelOptions, QueryContext } from 'objection';
|
||||||
import Account from './Account';
|
import Account from './Account';
|
||||||
|
|
||||||
export default class UncategorizedCashflowTransaction extends TenantModel {
|
export default class UncategorizedCashflowTransaction extends TenantModel {
|
||||||
@@ -95,6 +95,19 @@ export default class UncategorizedCashflowTransaction extends TenantModel {
|
|||||||
.increment('uncategorized_transactions', 1);
|
.increment('uncategorized_transactions', 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async $afterUpdate(
|
||||||
|
opt: ModelOptions,
|
||||||
|
queryContext: QueryContext
|
||||||
|
): void | Promise<any> {
|
||||||
|
await super.$afterUpdate(opt, queryContext);
|
||||||
|
|
||||||
|
if (this.id && this.categorized) {
|
||||||
|
await Account.query(queryContext.transaction)
|
||||||
|
.findById(this.accountId)
|
||||||
|
.decrement('uncategorized_transactions', 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param queryContext
|
* @param queryContext
|
||||||
@@ -102,7 +115,7 @@ export default class UncategorizedCashflowTransaction extends TenantModel {
|
|||||||
public async $afterDelete(queryContext) {
|
public async $afterDelete(queryContext) {
|
||||||
await super.$afterDelete(queryContext);
|
await super.$afterDelete(queryContext);
|
||||||
|
|
||||||
await Account.query()
|
await Account.query(queryContext.transaction)
|
||||||
.findById(this.accountId)
|
.findById(this.accountId)
|
||||||
.decrement('uncategorized_transactions', 1);
|
.decrement('uncategorized_transactions', 1);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -79,13 +79,14 @@ export class CategorizeCashflowTransaction {
|
|||||||
cashflowTransactionDTO
|
cashflowTransactionDTO
|
||||||
);
|
);
|
||||||
// Updates the uncategorized transaction as categorized.
|
// Updates the uncategorized transaction as categorized.
|
||||||
await UncategorizedCashflowTransaction.query(trx)
|
await UncategorizedCashflowTransaction.query(trx).patchAndFetchById(
|
||||||
.findById(uncategorizedTransactionId)
|
uncategorizedTransactionId,
|
||||||
.patch({
|
{
|
||||||
categorized: true,
|
categorized: true,
|
||||||
categorizeRefType: 'CashflowTransaction',
|
categorizeRefType: 'CashflowTransaction',
|
||||||
categorizeRefId: cashflowTransaction.id,
|
categorizeRefId: cashflowTransaction.id,
|
||||||
});
|
}
|
||||||
|
);
|
||||||
// Triggers `onCashflowTransactionCategorized` event.
|
// Triggers `onCashflowTransactionCategorized` event.
|
||||||
await this.eventPublisher.emitAsync(
|
await this.eventPublisher.emitAsync(
|
||||||
events.cashflow.onTransactionCategorized,
|
events.cashflow.onTransactionCategorized,
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ export default class GetCashflowTransactionsService {
|
|||||||
.withGraphFetched('entries.cashflowAccount')
|
.withGraphFetched('entries.cashflowAccount')
|
||||||
.withGraphFetched('entries.creditAccount')
|
.withGraphFetched('entries.creditAccount')
|
||||||
.withGraphFetched('transactions.account')
|
.withGraphFetched('transactions.account')
|
||||||
|
.orderBy('date', 'DESC')
|
||||||
.throwIfNotFound();
|
.throwIfNotFound();
|
||||||
|
|
||||||
this.throwErrorCashflowTranscationNotFound(cashflowTransaction);
|
this.throwErrorCashflowTranscationNotFound(cashflowTransaction);
|
||||||
|
|||||||
@@ -24,7 +24,8 @@ export class GetUncategorizedTransactions {
|
|||||||
.where('accountId', accountId)
|
.where('accountId', accountId)
|
||||||
.where('categorized', false)
|
.where('categorized', false)
|
||||||
.withGraphFetched('account')
|
.withGraphFetched('account')
|
||||||
.pagination(0, 10);
|
.orderBy('date', 'DESC')
|
||||||
|
.pagination(0, 1000);
|
||||||
|
|
||||||
const data = await this.transformer.transform(
|
const data = await this.transformer.transform(
|
||||||
tenantId,
|
tenantId,
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ export class UncategorizedTransactionTransformer extends Transformer {
|
|||||||
*/
|
*/
|
||||||
public includeAttributes = (): string[] => {
|
public includeAttributes = (): string[] => {
|
||||||
return [
|
return [
|
||||||
|
'formattedAmount',
|
||||||
'formattedDate',
|
'formattedDate',
|
||||||
'formattetDepositAmount',
|
'formattetDepositAmount',
|
||||||
'formattedWithdrawalAmount',
|
'formattedWithdrawalAmount',
|
||||||
@@ -23,6 +24,17 @@ export class UncategorizedTransactionTransformer extends Transformer {
|
|||||||
return this.formatDate(transaction.date);
|
return this.formatDate(transaction.date);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Formatted amount.
|
||||||
|
* @param transaction
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
public formattedAmount(transaction) {
|
||||||
|
return formatNumber(transaction.amount, {
|
||||||
|
currencyCode: transaction.currencyCode,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Formatted deposit amount.
|
* Formatted deposit amount.
|
||||||
* @param transaction
|
* @param transaction
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ export const transformCategorizeTransToCashflow = (
|
|||||||
referenceNo: categorizeDTO.referenceNo || uncategorizeModel.referenceNo,
|
referenceNo: categorizeDTO.referenceNo || uncategorizeModel.referenceNo,
|
||||||
description: categorizeDTO.description || uncategorizeModel.description,
|
description: categorizeDTO.description || uncategorizeModel.description,
|
||||||
cashflowAccountId: uncategorizeModel.accountId,
|
cashflowAccountId: uncategorizeModel.accountId,
|
||||||
creditAccountId: categorizeDTO.fromAccountId || categorizeDTO.toAccountId,
|
creditAccountId: categorizeDTO.creditAccountId,
|
||||||
exchangeRate: categorizeDTO.exchangeRate || 1,
|
exchangeRate: categorizeDTO.exchangeRate || 1,
|
||||||
currencyCode: uncategorizeModel.currencyCode,
|
currencyCode: uncategorizeModel.currencyCode,
|
||||||
amount: uncategorizeModel.amount,
|
amount: uncategorizeModel.amount,
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
// @ts-nocheck
|
// @ts-nocheck
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import clsx from 'classnames';
|
||||||
import { Classes } from '@blueprintjs/core';
|
import { Classes } from '@blueprintjs/core';
|
||||||
import { LoadingIndicator } from '../Indicator';
|
import { LoadingIndicator } from '../Indicator';
|
||||||
|
|
||||||
@@ -11,8 +12,8 @@ export function DrawerLoading({ loading, mount = false, children }) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function DrawerBody({ children }) {
|
export function DrawerBody({ children, className }) {
|
||||||
return <div className={Classes.DRAWER_BODY}>{children}</div>;
|
return <div className={clsx(Classes.DRAWER_BODY, className)}>{children}</div>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export * from './DrawerActionsBar';
|
export * from './DrawerActionsBar';
|
||||||
|
|||||||
@@ -26,12 +26,12 @@ const SelectButton = styled(Button)`
|
|||||||
position: relative;
|
position: relative;
|
||||||
padding-right: 30px;
|
padding-right: 30px;
|
||||||
|
|
||||||
&.bp4-small{
|
&.bp4-small {
|
||||||
padding-right: 24px;
|
padding-right: 24px;
|
||||||
}
|
}
|
||||||
|
|
||||||
&:not(.is-selected):not([class*='bp4-intent-']):not(.bp4-minimal) {
|
&:not(.is-selected):not([class*='bp4-intent-']):not(.bp4-minimal) {
|
||||||
color: #5c7080;
|
color: #8f99a8;
|
||||||
}
|
}
|
||||||
&:after {
|
&:after {
|
||||||
content: '';
|
content: '';
|
||||||
|
|||||||
@@ -2,30 +2,55 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { DrawerHeaderContent, DrawerLoading } from '@/components';
|
import { DrawerHeaderContent, DrawerLoading } from '@/components';
|
||||||
import { DRAWERS } from '@/constants/drawers';
|
import { DRAWERS } from '@/constants/drawers';
|
||||||
import { useUncategorizedTransaction } from '@/hooks/query';
|
import {
|
||||||
|
useAccounts,
|
||||||
|
useBranches,
|
||||||
|
useUncategorizedTransaction,
|
||||||
|
} from '@/hooks/query';
|
||||||
|
import { useFeatureCan } from '@/hooks/state';
|
||||||
|
import { Features } from '@/constants';
|
||||||
|
|
||||||
const CategorizeTransactionBootContext = React.createContext();
|
const CategorizeTransactionBootContext = React.createContext();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Estimate detail provider.
|
* Categorize transcation boot.
|
||||||
*/
|
*/
|
||||||
function CategorizeTransactionBoot({ uncategorizedTransactionId, ...props }) {
|
function CategorizeTransactionBoot({ uncategorizedTransactionId, ...props }) {
|
||||||
|
// Detarmines whether the feature is enabled.
|
||||||
|
const { featureCan } = useFeatureCan();
|
||||||
|
const isBranchFeatureCan = featureCan(Features.Branches);
|
||||||
|
|
||||||
|
// Fetches accounts list.
|
||||||
|
const { isLoading: isAccountsLoading, data: accounts } = useAccounts();
|
||||||
|
|
||||||
|
// Fetches the branches list.
|
||||||
|
const { data: branches, isLoading: isBranchesLoading } = useBranches(
|
||||||
|
{},
|
||||||
|
{ enabled: isBranchFeatureCan },
|
||||||
|
);
|
||||||
|
// Retrieves the uncategorized transaction.
|
||||||
const {
|
const {
|
||||||
data: uncategorizedTransaction,
|
data: uncategorizedTransaction,
|
||||||
isLoading: isUncategorizedTransactionLoading,
|
isLoading: isUncategorizedTransactionLoading,
|
||||||
} = useUncategorizedTransaction(uncategorizedTransactionId);
|
} = useUncategorizedTransaction(uncategorizedTransactionId);
|
||||||
|
|
||||||
const provider = {
|
const provider = {
|
||||||
|
uncategorizedTransactionId,
|
||||||
uncategorizedTransaction,
|
uncategorizedTransaction,
|
||||||
isUncategorizedTransactionLoading,
|
isUncategorizedTransactionLoading,
|
||||||
|
branches,
|
||||||
|
accounts,
|
||||||
|
isBranchesLoading,
|
||||||
|
isAccountsLoading,
|
||||||
};
|
};
|
||||||
|
const isLoading =
|
||||||
|
isBranchesLoading || isUncategorizedTransactionLoading || isAccountsLoading;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DrawerLoading loading={isUncategorizedTransactionLoading}>
|
<DrawerLoading loading={isLoading}>
|
||||||
<DrawerHeaderContent
|
<DrawerHeaderContent
|
||||||
name={DRAWERS.CATEGORIZE_TRANSACTION}
|
name={DRAWERS.CATEGORIZE_TRANSACTION}
|
||||||
title={'Categorize Transaction'}
|
title={'Categorize Transaction'}
|
||||||
subTitle={''}
|
|
||||||
/>
|
/>
|
||||||
<CategorizeTransactionBootContext.Provider value={provider} {...props} />
|
<CategorizeTransactionBootContext.Provider value={provider} {...props} />
|
||||||
</DrawerLoading>
|
</DrawerLoading>
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
// @ts-nocheck
|
// @ts-nocheck
|
||||||
|
import styled from 'styled-components';
|
||||||
import { DrawerBody } from '@/components';
|
import { DrawerBody } from '@/components';
|
||||||
import { CategorizeTransactionBoot } from './CategorizeTransactionBoot';
|
import { CategorizeTransactionBoot } from './CategorizeTransactionBoot';
|
||||||
import { CategorizeTransactionForm } from './CategorizeTransactionForm';
|
import { CategorizeTransactionForm } from './CategorizeTransactionForm';
|
||||||
@@ -10,9 +11,14 @@ export default function CategorizeTransactionContent({
|
|||||||
<CategorizeTransactionBoot
|
<CategorizeTransactionBoot
|
||||||
uncategorizedTransactionId={uncategorizedTransactionId}
|
uncategorizedTransactionId={uncategorizedTransactionId}
|
||||||
>
|
>
|
||||||
<DrawerBody>
|
<CategorizeTransactionDrawerBody>
|
||||||
<CategorizeTransactionForm />
|
<CategorizeTransactionForm />
|
||||||
</DrawerBody>
|
</CategorizeTransactionDrawerBody>
|
||||||
</CategorizeTransactionBoot>
|
</CategorizeTransactionBoot>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const CategorizeTransactionDrawerBody = styled(DrawerBody)`
|
||||||
|
padding: 20px;
|
||||||
|
background-color: #fff;
|
||||||
|
`;
|
||||||
|
|||||||
@@ -1,7 +1,14 @@
|
|||||||
// @ts-nocheck
|
// @ts-nocheck
|
||||||
import * as Yup from 'yup';
|
import * as Yup from 'yup';
|
||||||
|
|
||||||
const Schema = Yup.object().shape({});
|
const Schema = Yup.object().shape({
|
||||||
|
amount: Yup.string().required().label('Amount'),
|
||||||
|
exchangeRate: Yup.string().required().label('Exchange rate'),
|
||||||
|
transactionType: Yup.string().required().label('Transaction type'),
|
||||||
|
date: Yup.string().required().label('Date'),
|
||||||
|
creditAccountId: Yup.string().required().label('Credit account'),
|
||||||
|
referenceNo: Yup.string().optional().label('Reference No.'),
|
||||||
|
description: Yup.string().optional().label('Description'),
|
||||||
|
});
|
||||||
|
|
||||||
export const CreateCategorizeTransactionSchema = Schema;
|
export const CreateCategorizeTransactionSchema = Schema;
|
||||||
export const EditCategorizeTransactionSchema = Schema;
|
|
||||||
|
|||||||
@@ -1,34 +1,57 @@
|
|||||||
// @ts-nocheck
|
// @ts-nocheck
|
||||||
import { Formik, Form } from 'formik';
|
import { Formik, Form } from 'formik';
|
||||||
|
import styled from 'styled-components';
|
||||||
import withDialogActions from '@/containers/Dialog/withDialogActions';
|
import withDialogActions from '@/containers/Dialog/withDialogActions';
|
||||||
import {
|
import { CreateCategorizeTransactionSchema } from './CategorizeTransactionForm.schema';
|
||||||
EditCategorizeTransactionSchema,
|
|
||||||
CreateCategorizeTransactionSchema,
|
|
||||||
} from './CategorizeTransactionForm.schema';
|
|
||||||
import { compose, transformToForm } from '@/utils';
|
|
||||||
import { CategorizeTransactionFormContent } from './CategorizeTransactionFormContent';
|
import { CategorizeTransactionFormContent } from './CategorizeTransactionFormContent';
|
||||||
import { CategorizeTransactionFormFooter } from './CategorizeTransactionFormFooter';
|
import { CategorizeTransactionFormFooter } from './CategorizeTransactionFormFooter';
|
||||||
|
import { useCategorizeTransaction } from '@/hooks/query';
|
||||||
// Default initial form values.
|
import { useCategorizeTransactionBoot } from './CategorizeTransactionBoot';
|
||||||
const defaultInitialValues = {};
|
import { DRAWERS } from '@/constants/drawers';
|
||||||
|
import {
|
||||||
|
transformToCategorizeForm,
|
||||||
|
defaultInitialValues,
|
||||||
|
tranformToRequest,
|
||||||
|
} from './_utils';
|
||||||
|
import { compose } from '@/utils';
|
||||||
|
import withDrawerActions from '@/containers/Drawer/withDrawerActions';
|
||||||
|
import { AppToaster } from '@/components';
|
||||||
|
import { Intent } from '@blueprintjs/core';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Categorize cashflow transaction form dialog content.
|
* Categorize cashflow transaction form dialog content.
|
||||||
*/
|
*/
|
||||||
function CategorizeTransactionFormRoot({
|
function CategorizeTransactionFormRoot({
|
||||||
// #withDialogActions
|
// #withDrawerActions
|
||||||
closeDialog,
|
closeDrawer,
|
||||||
}) {
|
}) {
|
||||||
const isNewMode = true;
|
const { uncategorizedTransactionId, uncategorizedTransaction } =
|
||||||
|
useCategorizeTransactionBoot();
|
||||||
// Form validation schema in create and edit mode.
|
const { mutateAsync: categorizeTransaction } = useCategorizeTransaction();
|
||||||
const validationSchema = isNewMode
|
|
||||||
? CreateCategorizeTransactionSchema
|
|
||||||
: EditCategorizeTransactionSchema;
|
|
||||||
|
|
||||||
// Callbacks handles form submit.
|
// Callbacks handles form submit.
|
||||||
const handleFormSubmit = (values, { setSubmitting, setErrors }) => {};
|
const handleFormSubmit = (values, { setSubmitting, setErrors }) => {
|
||||||
|
const transformedValues = tranformToRequest(values);
|
||||||
|
|
||||||
|
setSubmitting(true);
|
||||||
|
categorizeTransaction([uncategorizedTransactionId, transformedValues])
|
||||||
|
.then(() => {
|
||||||
|
setSubmitting(false);
|
||||||
|
closeDrawer(DRAWERS.CATEGORIZE_TRANSACTION);
|
||||||
|
|
||||||
|
AppToaster.show({
|
||||||
|
message: 'The uncategorized transaction has been categorized.',
|
||||||
|
intent: Intent.SUCCESS,
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
setSubmitting(false);
|
||||||
|
AppToaster.show({
|
||||||
|
message: 'Something went wrong!',
|
||||||
|
intent: Intent.DANGER,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
// Form initial values in create and edit mode.
|
// Form initial values in create and edit mode.
|
||||||
const initialValues = {
|
const initialValues = {
|
||||||
...defaultInitialValues,
|
...defaultInitialValues,
|
||||||
@@ -37,23 +60,37 @@ function CategorizeTransactionFormRoot({
|
|||||||
* values such as `notes` come back from the API as null, so remove those
|
* values such as `notes` come back from the API as null, so remove those
|
||||||
* as well.
|
* as well.
|
||||||
*/
|
*/
|
||||||
...transformToForm({}, defaultInitialValues),
|
...transformToCategorizeForm(uncategorizedTransaction),
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Formik
|
<DivRoot>
|
||||||
validationSchema={validationSchema}
|
<Formik
|
||||||
initialValues={initialValues}
|
validationSchema={CreateCategorizeTransactionSchema}
|
||||||
onSubmit={handleFormSubmit}
|
initialValues={initialValues}
|
||||||
>
|
onSubmit={handleFormSubmit}
|
||||||
<Form>
|
>
|
||||||
<CategorizeTransactionFormContent />
|
<Form>
|
||||||
<CategorizeTransactionFormFooter />
|
<CategorizeTransactionFormContent />
|
||||||
</Form>
|
<CategorizeTransactionFormFooter />
|
||||||
</Formik>
|
</Form>
|
||||||
|
</Formik>
|
||||||
|
</DivRoot>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export const CategorizeTransactionForm = compose(withDialogActions)(
|
export const CategorizeTransactionForm = compose(withDrawerActions)(
|
||||||
CategorizeTransactionFormRoot,
|
CategorizeTransactionFormRoot,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const DivRoot = styled.div`
|
||||||
|
.bp4-form-group .bp4-form-content {
|
||||||
|
flex: 1 0;
|
||||||
|
}
|
||||||
|
.bp4-form-group .bp4-label {
|
||||||
|
width: 140px;
|
||||||
|
}
|
||||||
|
.bp4-form-group {
|
||||||
|
margin-bottom: 18px;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|||||||
@@ -1,31 +1,39 @@
|
|||||||
// @ts-nocheck
|
// @ts-nocheck
|
||||||
import { Position } from '@blueprintjs/core';
|
import React from 'react';
|
||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
import {
|
import { FormGroup } from '@blueprintjs/core';
|
||||||
AccountsSelect,
|
import { FFormGroup, FSelect, FSuggest } from '@/components';
|
||||||
FDateInput,
|
import { getAddMoneyInOptions, getAddMoneyOutOptions } from '@/constants';
|
||||||
FFormGroup,
|
import { useFormikContext } from 'formik';
|
||||||
FInputGroup,
|
import { useCategorizeTransactionBoot } from './CategorizeTransactionBoot';
|
||||||
FSelect,
|
|
||||||
FSuggest,
|
|
||||||
FTextArea,
|
|
||||||
} from '@/components';
|
|
||||||
import { getAddMoneyInOptions } from '@/constants';
|
|
||||||
|
|
||||||
// Retrieves the add money in button options.
|
// Retrieves the add money in button options.
|
||||||
const AddMoneyInOptions = getAddMoneyInOptions();
|
const MoneyInOptions = getAddMoneyInOptions();
|
||||||
|
const MoneyOutOptions = getAddMoneyOutOptions();
|
||||||
|
|
||||||
const Title = styled('h3')``;
|
const Title = styled('h3')`
|
||||||
|
font-size: 20px;
|
||||||
|
font-weight: 400;
|
||||||
|
color: #cd4246;
|
||||||
|
`;
|
||||||
|
|
||||||
export function CategorizeTransactionFormContent() {
|
export function CategorizeTransactionFormContent() {
|
||||||
|
const { uncategorizedTransaction } = useCategorizeTransactionBoot();
|
||||||
|
|
||||||
|
const transactionTypes = uncategorizedTransaction?.is_deposit_transaction
|
||||||
|
? MoneyInOptions
|
||||||
|
: MoneyOutOptions;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Title>$22,583.00</Title>
|
<FormGroup label={'Amount'} inline>
|
||||||
|
<Title>{uncategorizedTransaction.formatted_amount}</Title>
|
||||||
|
</FormGroup>
|
||||||
|
|
||||||
<FFormGroup name={'category'} label={'Category'} fastField inline>
|
<FFormGroup name={'category'} label={'Category'} fastField inline>
|
||||||
<FSuggest
|
<FSelect
|
||||||
name={'transaction_type'}
|
name={'transactionType'}
|
||||||
items={AddMoneyInOptions}
|
items={transactionTypes}
|
||||||
popoverProps={{ minimal: true }}
|
popoverProps={{ minimal: true }}
|
||||||
valueAccessor={'value'}
|
valueAccessor={'value'}
|
||||||
textAccessor={'name'}
|
textAccessor={'name'}
|
||||||
@@ -33,58 +41,56 @@ export function CategorizeTransactionFormContent() {
|
|||||||
/>
|
/>
|
||||||
</FFormGroup>
|
</FFormGroup>
|
||||||
|
|
||||||
<FFormGroup name={'date'} label={'Date'} fastField inline>
|
<CategorizeTransactionFormSubContent />
|
||||||
<FDateInput
|
|
||||||
name={'date'}
|
|
||||||
popoverProps={{ position: Position.BOTTOM, minimal: true }}
|
|
||||||
formatDate={(date) => date.toLocaleDateString()}
|
|
||||||
parseDate={(str) => new Date(str)}
|
|
||||||
inputProps={{ fill: true }}
|
|
||||||
/>
|
|
||||||
</FFormGroup>
|
|
||||||
|
|
||||||
<FFormGroup
|
|
||||||
name={'from_account_id'}
|
|
||||||
label={'From Account'}
|
|
||||||
fastField={true}
|
|
||||||
inline
|
|
||||||
>
|
|
||||||
<AccountsSelect
|
|
||||||
name={'from_account_id'}
|
|
||||||
items={[]}
|
|
||||||
fastField={true}
|
|
||||||
fill={true}
|
|
||||||
allowCreate={true}
|
|
||||||
/>
|
|
||||||
</FFormGroup>
|
|
||||||
|
|
||||||
<FFormGroup
|
|
||||||
name={'toAccountId'}
|
|
||||||
label={'To Account'}
|
|
||||||
fastField={true}
|
|
||||||
inline
|
|
||||||
>
|
|
||||||
<AccountsSelect
|
|
||||||
name={'to_account_id'}
|
|
||||||
items={[]}
|
|
||||||
fastField={true}
|
|
||||||
fill={true}
|
|
||||||
allowCreate={true}
|
|
||||||
/>
|
|
||||||
</FFormGroup>
|
|
||||||
|
|
||||||
<FFormGroup name={'referenceNo'} label={'Reference No.'} fastField inline>
|
|
||||||
<FInputGroup name={'reference_no'} fill />
|
|
||||||
</FFormGroup>
|
|
||||||
|
|
||||||
<FFormGroup name={'description'} label={'Description'} fastField inline>
|
|
||||||
<FTextArea
|
|
||||||
name={'description'}
|
|
||||||
growVertically={true}
|
|
||||||
large={true}
|
|
||||||
fill={true}
|
|
||||||
/>
|
|
||||||
</FFormGroup>
|
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const CategorizeTransactionOtherIncome = React.lazy(
|
||||||
|
() => import('./MoneyIn/CategorizeTransactionOtherIncome'),
|
||||||
|
);
|
||||||
|
|
||||||
|
const CategorizeTransactionOwnerContribution = React.lazy(
|
||||||
|
() => import('./MoneyIn/CategorizeTransactionOwnerContribution'),
|
||||||
|
);
|
||||||
|
|
||||||
|
const CategorizeTransactionTransferFrom = React.lazy(
|
||||||
|
() => import('./MoneyIn/CategorizeTransactionTransferFrom'),
|
||||||
|
);
|
||||||
|
|
||||||
|
const CategorizeTransactionOtherExpense = React.lazy(
|
||||||
|
() => import('./MoneyOut/CategorizeTransactionOtherExpense'),
|
||||||
|
);
|
||||||
|
|
||||||
|
const CategorizeTransactionToAccount = React.lazy(
|
||||||
|
() => import('./MoneyOut/CategorizeTransactionToAccount'),
|
||||||
|
);
|
||||||
|
|
||||||
|
const CategorizeTransactionOwnerDrawings = React.lazy(
|
||||||
|
() => import('./MoneyOut/CategorizeTransactionOwnerDrawings'),
|
||||||
|
);
|
||||||
|
|
||||||
|
function CategorizeTransactionFormSubContent() {
|
||||||
|
const { values } = useFormikContext();
|
||||||
|
|
||||||
|
// Other expense.
|
||||||
|
if (values.transactionType === 'other_expense') {
|
||||||
|
return <CategorizeTransactionOtherExpense />;
|
||||||
|
// Owner contribution.
|
||||||
|
} else if (values.transactionType === 'owner_contribution') {
|
||||||
|
return <CategorizeTransactionOwnerContribution />;
|
||||||
|
// Other Income.
|
||||||
|
} else if (values.transactionType === 'other_income') {
|
||||||
|
return <CategorizeTransactionOtherIncome />;
|
||||||
|
// Transfer from account.
|
||||||
|
} else if (values.transactionType === 'transfer_from_account') {
|
||||||
|
return <CategorizeTransactionTransferFrom />;
|
||||||
|
// Transfer to account.
|
||||||
|
} else if (values.transactionType === 'transfer_to_account') {
|
||||||
|
return <CategorizeTransactionToAccount />;
|
||||||
|
// Owner drawings.
|
||||||
|
} else if (values.transactionType === 'OwnerDrawing') {
|
||||||
|
return <CategorizeTransactionOwnerDrawings />;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,26 +1,56 @@
|
|||||||
|
// @ts-nocheck
|
||||||
|
import * as R from 'ramda';
|
||||||
import { Button, Classes, Intent } from '@blueprintjs/core';
|
import { Button, Classes, Intent } from '@blueprintjs/core';
|
||||||
|
import { useFormikContext } from 'formik';
|
||||||
|
import styled from 'styled-components';
|
||||||
|
import withDrawerActions from '@/containers/Drawer/withDrawerActions';
|
||||||
|
import { DRAWERS } from '@/constants/drawers';
|
||||||
|
import { Group } from '@/components';
|
||||||
|
|
||||||
|
function CategorizeTransactionFormFooterRoot({
|
||||||
|
// #withDrawerActions
|
||||||
|
closeDrawer,
|
||||||
|
}) {
|
||||||
|
const { isSubmitting } = useFormikContext();
|
||||||
|
|
||||||
|
const handleClose = () => {
|
||||||
|
closeDrawer(DRAWERS.CATEGORIZE_TRANSACTION);
|
||||||
|
};
|
||||||
|
|
||||||
export function CategorizeTransactionFormFooter() {
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<Root>
|
||||||
<div className={Classes.DRAWER_FOOTER}>
|
<div className={Classes.DRAWER_FOOTER}>
|
||||||
<Button
|
<Group spacing={10}>
|
||||||
intent={Intent.PRIMARY}
|
<Button
|
||||||
// loading={isSubmitting}
|
intent={Intent.PRIMARY}
|
||||||
style={{ minWidth: '85px' }}
|
loading={isSubmitting}
|
||||||
type="submit"
|
style={{ minWidth: '75px' }}
|
||||||
>
|
type="submit"
|
||||||
Save
|
>
|
||||||
</Button>
|
Save
|
||||||
|
</Button>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
// disabled={isSubmitting}
|
disabled={isSubmitting}
|
||||||
// onClick={onClose}
|
onClick={handleClose}
|
||||||
style={{ minWidth: '75px' }}
|
style={{ minWidth: '75px' }}
|
||||||
>
|
>
|
||||||
Close
|
Close
|
||||||
</Button>
|
</Button>
|
||||||
|
</Group>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</Root>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const CategorizeTransactionFormFooter = R.compose(withDrawerActions)(
|
||||||
|
CategorizeTransactionFormFooterRoot,
|
||||||
|
);
|
||||||
|
|
||||||
|
const Root = styled.div`
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
background: #fff;
|
||||||
|
`;
|
||||||
|
|||||||
@@ -0,0 +1,73 @@
|
|||||||
|
// @ts-nocheck
|
||||||
|
import { Position } from '@blueprintjs/core';
|
||||||
|
import {
|
||||||
|
AccountsSelect,
|
||||||
|
FDateInput,
|
||||||
|
FFormGroup,
|
||||||
|
FInputGroup,
|
||||||
|
FTextArea,
|
||||||
|
} from '@/components';
|
||||||
|
import { useCategorizeTransactionBoot } from '../CategorizeTransactionBoot';
|
||||||
|
|
||||||
|
export default function CategorizeTransactionOtherIncome() {
|
||||||
|
const { accounts } = useCategorizeTransactionBoot();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<FFormGroup name={'date'} label={'Date'} fastField inline>
|
||||||
|
<FDateInput
|
||||||
|
name={'date'}
|
||||||
|
popoverProps={{ position: Position.BOTTOM, minimal: true }}
|
||||||
|
formatDate={(date) => date.toLocaleDateString()}
|
||||||
|
parseDate={(str) => new Date(str)}
|
||||||
|
inputProps={{ fill: true }}
|
||||||
|
/>
|
||||||
|
</FFormGroup>
|
||||||
|
|
||||||
|
<FFormGroup
|
||||||
|
name={'debitAccountId'}
|
||||||
|
label={'To Account'}
|
||||||
|
fastField={true}
|
||||||
|
inline
|
||||||
|
>
|
||||||
|
<AccountsSelect
|
||||||
|
name={'debitAccountId'}
|
||||||
|
items={accounts}
|
||||||
|
fastField
|
||||||
|
fill
|
||||||
|
allowCreate
|
||||||
|
disabled
|
||||||
|
/>
|
||||||
|
</FFormGroup>
|
||||||
|
|
||||||
|
<FFormGroup
|
||||||
|
name={'creditAccountId'}
|
||||||
|
label={'Income Account'}
|
||||||
|
fastField
|
||||||
|
inline
|
||||||
|
>
|
||||||
|
<AccountsSelect
|
||||||
|
name={'creditAccountId'}
|
||||||
|
items={accounts}
|
||||||
|
filterByRootTypes={['income']}
|
||||||
|
fastField
|
||||||
|
fill
|
||||||
|
allowCreate
|
||||||
|
/>
|
||||||
|
</FFormGroup>
|
||||||
|
|
||||||
|
<FFormGroup name={'referenceNo'} label={'Reference No.'} fastField inline>
|
||||||
|
<FInputGroup name={'reference_no'} fill />
|
||||||
|
</FFormGroup>
|
||||||
|
|
||||||
|
<FFormGroup name={'description'} label={'Description'} fastField inline>
|
||||||
|
<FTextArea
|
||||||
|
name={'description'}
|
||||||
|
growVertically={true}
|
||||||
|
large={true}
|
||||||
|
fill={true}
|
||||||
|
/>
|
||||||
|
</FFormGroup>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
// @ts-nocheck
|
||||||
|
import { Position } from '@blueprintjs/core';
|
||||||
|
import {
|
||||||
|
AccountsSelect,
|
||||||
|
FDateInput,
|
||||||
|
FFormGroup,
|
||||||
|
FInputGroup,
|
||||||
|
FTextArea,
|
||||||
|
} from '@/components';
|
||||||
|
import { useCategorizeTransactionBoot } from '../CategorizeTransactionBoot';
|
||||||
|
|
||||||
|
export default function CategorizeTransactionOwnerContribution() {
|
||||||
|
const { accounts } = useCategorizeTransactionBoot();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<FFormGroup name={'date'} label={'Date'} fastField inline>
|
||||||
|
<FDateInput
|
||||||
|
name={'date'}
|
||||||
|
popoverProps={{ position: Position.BOTTOM, minimal: true }}
|
||||||
|
formatDate={(date) => date.toLocaleDateString()}
|
||||||
|
parseDate={(str) => new Date(str)}
|
||||||
|
inputProps={{ fill: true }}
|
||||||
|
/>
|
||||||
|
</FFormGroup>
|
||||||
|
|
||||||
|
<FFormGroup
|
||||||
|
name={'debitAccountId'}
|
||||||
|
label={'From Account'}
|
||||||
|
fastField
|
||||||
|
inline
|
||||||
|
>
|
||||||
|
<AccountsSelect
|
||||||
|
name={'debitAccountId'}
|
||||||
|
items={accounts}
|
||||||
|
fastField
|
||||||
|
fill
|
||||||
|
allowCreate
|
||||||
|
disabled
|
||||||
|
/>
|
||||||
|
</FFormGroup>
|
||||||
|
|
||||||
|
<FFormGroup
|
||||||
|
name={'creditAccountId'}
|
||||||
|
label={'Equity Account'}
|
||||||
|
fastField
|
||||||
|
inline
|
||||||
|
>
|
||||||
|
<AccountsSelect
|
||||||
|
name={'creditAccountId'}
|
||||||
|
items={accounts}
|
||||||
|
filterByRootTypes={['equity']}
|
||||||
|
fastField
|
||||||
|
fill
|
||||||
|
allowCreate
|
||||||
|
/>
|
||||||
|
</FFormGroup>
|
||||||
|
|
||||||
|
<FFormGroup name={'referenceNo'} label={'Reference No.'} fastField inline>
|
||||||
|
<FInputGroup name={'reference_no'} fill />
|
||||||
|
</FFormGroup>
|
||||||
|
|
||||||
|
<FFormGroup name={'description'} label={'Description'} fastField inline>
|
||||||
|
<FTextArea name={'description'} growVertically large fill />
|
||||||
|
</FFormGroup>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,73 @@
|
|||||||
|
// @ts-nocheck
|
||||||
|
import { Position } from '@blueprintjs/core';
|
||||||
|
import {
|
||||||
|
AccountsSelect,
|
||||||
|
FDateInput,
|
||||||
|
FFormGroup,
|
||||||
|
FInputGroup,
|
||||||
|
FTextArea,
|
||||||
|
} from '@/components';
|
||||||
|
import { useCategorizeTransactionBoot } from '../CategorizeTransactionBoot';
|
||||||
|
|
||||||
|
export default function CategorizeTransactionTransferFrom() {
|
||||||
|
const { accounts } = useCategorizeTransactionBoot();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<FFormGroup name={'date'} label={'Date'} fastField inline>
|
||||||
|
<FDateInput
|
||||||
|
name={'date'}
|
||||||
|
popoverProps={{ position: Position.BOTTOM, minimal: true }}
|
||||||
|
formatDate={(date) => date.toLocaleDateString()}
|
||||||
|
parseDate={(str) => new Date(str)}
|
||||||
|
inputProps={{ fill: true }}
|
||||||
|
/>
|
||||||
|
</FFormGroup>
|
||||||
|
|
||||||
|
<FFormGroup
|
||||||
|
name={'debitAccountId'}
|
||||||
|
label={'From Account'}
|
||||||
|
fastField
|
||||||
|
inline
|
||||||
|
>
|
||||||
|
<AccountsSelect
|
||||||
|
name={'debitAccountId'}
|
||||||
|
items={accounts}
|
||||||
|
fastField
|
||||||
|
fill
|
||||||
|
allowCreate
|
||||||
|
disabled
|
||||||
|
/>
|
||||||
|
</FFormGroup>
|
||||||
|
|
||||||
|
<FFormGroup
|
||||||
|
name={'creditAccountId'}
|
||||||
|
label={'To Account'}
|
||||||
|
fastField
|
||||||
|
inline
|
||||||
|
>
|
||||||
|
<AccountsSelect
|
||||||
|
name={'to_account_id'}
|
||||||
|
items={accounts}
|
||||||
|
filterByRootTypes={['asset']}
|
||||||
|
fastField
|
||||||
|
fill
|
||||||
|
allowCreate
|
||||||
|
/>
|
||||||
|
</FFormGroup>
|
||||||
|
|
||||||
|
<FFormGroup name={'referenceNo'} label={'Reference No.'} fastField inline>
|
||||||
|
<FInputGroup name={'reference_no'} fill />
|
||||||
|
</FFormGroup>
|
||||||
|
|
||||||
|
<FFormGroup name={'description'} label={'Description'} fastField inline>
|
||||||
|
<FTextArea
|
||||||
|
name={'description'}
|
||||||
|
growVertically={true}
|
||||||
|
large={true}
|
||||||
|
fill={true}
|
||||||
|
/>
|
||||||
|
</FFormGroup>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,73 @@
|
|||||||
|
// @ts-nocheck
|
||||||
|
import { Position } from '@blueprintjs/core';
|
||||||
|
import {
|
||||||
|
AccountsSelect,
|
||||||
|
FDateInput,
|
||||||
|
FFormGroup,
|
||||||
|
FInputGroup,
|
||||||
|
FTextArea,
|
||||||
|
} from '@/components';
|
||||||
|
import { useCategorizeTransactionBoot } from '../CategorizeTransactionBoot';
|
||||||
|
|
||||||
|
export default function CategorizeTransactionOtherExpense() {
|
||||||
|
const { accounts } = useCategorizeTransactionBoot();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<FFormGroup name={'date'} label={'Date'} fastField inline>
|
||||||
|
<FDateInput
|
||||||
|
name={'date'}
|
||||||
|
popoverProps={{ position: Position.BOTTOM, minimal: true }}
|
||||||
|
formatDate={(date) => date.toLocaleDateString()}
|
||||||
|
parseDate={(str) => new Date(str)}
|
||||||
|
inputProps={{ fill: true }}
|
||||||
|
/>
|
||||||
|
</FFormGroup>
|
||||||
|
|
||||||
|
<FFormGroup
|
||||||
|
name={'debitAccountId'}
|
||||||
|
label={'Payment Account'}
|
||||||
|
fastField={true}
|
||||||
|
inline
|
||||||
|
>
|
||||||
|
<AccountsSelect
|
||||||
|
name={'debitAccountId'}
|
||||||
|
items={accounts}
|
||||||
|
fastField
|
||||||
|
fill
|
||||||
|
allowCreate
|
||||||
|
disabled
|
||||||
|
/>
|
||||||
|
</FFormGroup>
|
||||||
|
|
||||||
|
<FFormGroup
|
||||||
|
name={'creditAccountId'}
|
||||||
|
label={'Expense Account'}
|
||||||
|
fastField={true}
|
||||||
|
inline
|
||||||
|
>
|
||||||
|
<AccountsSelect
|
||||||
|
name={'creditAccountId'}
|
||||||
|
items={accounts}
|
||||||
|
filterByRootTypes={['expense']}
|
||||||
|
fastField
|
||||||
|
fill
|
||||||
|
allowCreate
|
||||||
|
/>
|
||||||
|
</FFormGroup>
|
||||||
|
|
||||||
|
<FFormGroup name={'referenceNo'} label={'Reference No.'} fastField inline>
|
||||||
|
<FInputGroup name={'reference_no'} fill />
|
||||||
|
</FFormGroup>
|
||||||
|
|
||||||
|
<FFormGroup name={'description'} label={'Description'} fastField inline>
|
||||||
|
<FTextArea
|
||||||
|
name={'description'}
|
||||||
|
growVertically={true}
|
||||||
|
large={true}
|
||||||
|
fill={true}
|
||||||
|
/>
|
||||||
|
</FFormGroup>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,73 @@
|
|||||||
|
// @ts-nocheck
|
||||||
|
import { Position } from '@blueprintjs/core';
|
||||||
|
import {
|
||||||
|
AccountsSelect,
|
||||||
|
FDateInput,
|
||||||
|
FFormGroup,
|
||||||
|
FInputGroup,
|
||||||
|
FTextArea,
|
||||||
|
} from '@/components';
|
||||||
|
import { useCategorizeTransactionBoot } from '../CategorizeTransactionBoot';
|
||||||
|
|
||||||
|
export default function CategorizeTransactionOwnerDrawings() {
|
||||||
|
const { accounts } = useCategorizeTransactionBoot();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<FFormGroup name={'date'} label={'Date'} fastField inline>
|
||||||
|
<FDateInput
|
||||||
|
name={'date'}
|
||||||
|
popoverProps={{ position: Position.BOTTOM, minimal: true }}
|
||||||
|
formatDate={(date) => date.toLocaleDateString()}
|
||||||
|
parseDate={(str) => new Date(str)}
|
||||||
|
inputProps={{ fill: true }}
|
||||||
|
/>
|
||||||
|
</FFormGroup>
|
||||||
|
|
||||||
|
<FFormGroup
|
||||||
|
name={'debitAccountId'}
|
||||||
|
label={'Debit Account'}
|
||||||
|
fastField
|
||||||
|
inline
|
||||||
|
>
|
||||||
|
<AccountsSelect
|
||||||
|
name={'debitAccountId'}
|
||||||
|
items={accounts}
|
||||||
|
fastField
|
||||||
|
fill
|
||||||
|
allowCreate
|
||||||
|
disabled
|
||||||
|
/>
|
||||||
|
</FFormGroup>
|
||||||
|
|
||||||
|
<FFormGroup
|
||||||
|
name={'creditAccountId'}
|
||||||
|
label={'Equity Account'}
|
||||||
|
fastField
|
||||||
|
inline
|
||||||
|
>
|
||||||
|
<AccountsSelect
|
||||||
|
name={'creditAccountId'}
|
||||||
|
items={accounts}
|
||||||
|
filterByRootTypes={['equity']}
|
||||||
|
fastField
|
||||||
|
fill
|
||||||
|
allowCreate
|
||||||
|
/>
|
||||||
|
</FFormGroup>
|
||||||
|
|
||||||
|
<FFormGroup name={'referenceNo'} label={'Reference No.'} fastField inline>
|
||||||
|
<FInputGroup name={'reference_no'} fill />
|
||||||
|
</FFormGroup>
|
||||||
|
|
||||||
|
<FFormGroup name={'description'} label={'Description'} fastField inline>
|
||||||
|
<FTextArea
|
||||||
|
name={'description'}
|
||||||
|
growVertically={true}
|
||||||
|
large={true}
|
||||||
|
fill={true}
|
||||||
|
/>
|
||||||
|
</FFormGroup>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,73 @@
|
|||||||
|
// @ts-nocheck
|
||||||
|
import { Position } from '@blueprintjs/core';
|
||||||
|
import {
|
||||||
|
AccountsSelect,
|
||||||
|
FDateInput,
|
||||||
|
FFormGroup,
|
||||||
|
FInputGroup,
|
||||||
|
FTextArea,
|
||||||
|
} from '@/components';
|
||||||
|
import { useCategorizeTransactionBoot } from '../CategorizeTransactionBoot';
|
||||||
|
|
||||||
|
export default function CategorizeTransactionToAccount() {
|
||||||
|
const { accounts } = useCategorizeTransactionBoot();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<FFormGroup name={'date'} label={'Date'} fastField inline>
|
||||||
|
<FDateInput
|
||||||
|
name={'date'}
|
||||||
|
popoverProps={{ position: Position.BOTTOM, minimal: true }}
|
||||||
|
formatDate={(date) => date.toLocaleDateString()}
|
||||||
|
parseDate={(str) => new Date(str)}
|
||||||
|
inputProps={{ fill: true }}
|
||||||
|
/>
|
||||||
|
</FFormGroup>
|
||||||
|
|
||||||
|
<FFormGroup
|
||||||
|
name={'debitAccountId'}
|
||||||
|
label={'From Account'}
|
||||||
|
fastField
|
||||||
|
inline
|
||||||
|
>
|
||||||
|
<AccountsSelect
|
||||||
|
name={'debitAccountId'}
|
||||||
|
items={accounts}
|
||||||
|
fastField
|
||||||
|
fill
|
||||||
|
allowCreate
|
||||||
|
disabled
|
||||||
|
/>
|
||||||
|
</FFormGroup>
|
||||||
|
|
||||||
|
<FFormGroup
|
||||||
|
name={'creditAccountId'}
|
||||||
|
label={'To Account'}
|
||||||
|
fastField
|
||||||
|
inline
|
||||||
|
>
|
||||||
|
<AccountsSelect
|
||||||
|
name={'creditAccountId'}
|
||||||
|
items={accounts}
|
||||||
|
filterByRootTypes={['assset']}
|
||||||
|
fastField
|
||||||
|
fill
|
||||||
|
allowCreate
|
||||||
|
/>
|
||||||
|
</FFormGroup>
|
||||||
|
|
||||||
|
<FFormGroup name={'referenceNo'} label={'Reference No.'} fastField inline>
|
||||||
|
<FInputGroup name={'reference_no'} fill />
|
||||||
|
</FFormGroup>
|
||||||
|
|
||||||
|
<FFormGroup name={'description'} label={'Description'} fastField inline>
|
||||||
|
<FTextArea
|
||||||
|
name={'description'}
|
||||||
|
growVertically={true}
|
||||||
|
large={true}
|
||||||
|
fill={true}
|
||||||
|
/>
|
||||||
|
</FFormGroup>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
// @ts-nocheck
|
||||||
|
import { transformToForm, transfromToSnakeCase } from '@/utils';
|
||||||
|
|
||||||
|
// Default initial form values.
|
||||||
|
export const defaultInitialValues = {
|
||||||
|
amount: '',
|
||||||
|
date: '',
|
||||||
|
creditAccountId: '',
|
||||||
|
debitAccountId: '',
|
||||||
|
exchangeRate: '1',
|
||||||
|
transactionType: '',
|
||||||
|
referenceNo: '',
|
||||||
|
description: '',
|
||||||
|
};
|
||||||
|
|
||||||
|
export const transformToCategorizeForm = (uncategorizedTransaction) => {
|
||||||
|
const defaultValues = {
|
||||||
|
debitAccountId: uncategorizedTransaction.account_id,
|
||||||
|
transactionType: uncategorizedTransaction.is_deposit_transaction
|
||||||
|
? 'other_income'
|
||||||
|
: 'other_expense',
|
||||||
|
amount: uncategorizedTransaction.amount,
|
||||||
|
date: uncategorizedTransaction.date,
|
||||||
|
};
|
||||||
|
return transformToForm(defaultValues, defaultInitialValues);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
export const tranformToRequest = (formValues) => {
|
||||||
|
return transfromToSnakeCase(formValues);
|
||||||
|
};
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
export * from './CategorizeTransactionDrawer';
|
||||||
@@ -231,3 +231,27 @@ export function useUncategorizedTransaction(
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Categorize the cashflow transaction.
|
||||||
|
*/
|
||||||
|
export function useCategorizeTransaction(props) {
|
||||||
|
const queryClient = useQueryClient();
|
||||||
|
const apiRequest = useApiRequest();
|
||||||
|
|
||||||
|
return useMutation(
|
||||||
|
([id, values]) =>
|
||||||
|
apiRequest.post(`cashflow/transactions/${id}/categorize`, values),
|
||||||
|
{
|
||||||
|
onSuccess: (res, id) => {
|
||||||
|
// Invalidate queries.
|
||||||
|
commonInvalidateQueries(queryClient);
|
||||||
|
queryClient.invalidateQueries(t.CASHFLOW_UNCAATEGORIZED_TRANSACTION);
|
||||||
|
queryClient.invalidateQueries(
|
||||||
|
t.CASHFLOW_ACCOUNT_UNCATEGORIZED_TRANSACTIONS_INFINITY,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
...props,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|||||||
@@ -202,7 +202,6 @@ const CASH_FLOW_ACCOUNTS = {
|
|||||||
'CASHFLOW_ACCOUNT_TRANSACTIONS_INFINITY',
|
'CASHFLOW_ACCOUNT_TRANSACTIONS_INFINITY',
|
||||||
CASHFLOW_ACCOUNT_UNCATEGORIZED_TRANSACTIONS_INFINITY:
|
CASHFLOW_ACCOUNT_UNCATEGORIZED_TRANSACTIONS_INFINITY:
|
||||||
'CASHFLOW_ACCOUNT_UNCATEGORIZED_TRANSACTIONS_INFINITY',
|
'CASHFLOW_ACCOUNT_UNCATEGORIZED_TRANSACTIONS_INFINITY',
|
||||||
|
|
||||||
CASHFLOW_UNCAATEGORIZED_TRANSACTION: 'CASHFLOW_UNCAATEGORIZED_TRANSACTION',
|
CASHFLOW_UNCAATEGORIZED_TRANSACTION: 'CASHFLOW_UNCAATEGORIZED_TRANSACTION',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user