Compare commits

...

6 Commits

Author SHA1 Message Date
Ahmed Bouhuolia
031ccc4a0b fix: Edit the payment received transactions with attachments 2024-06-10 13:41:10 +02:00
Ahmed Bouhuolia
858f347fd4 Merge pull request #493 from bigcapitalhq/BIG-198
fix: Something wrong in uploading uncategorized bank transactions
2024-06-09 21:30:32 +02:00
Ahmed Bouhuolia
4d73b59cf3 fix: Something wrong in uploading uncategorized bank transactions 2024-06-09 21:30:07 +02:00
Ahmed Bouhuolia
bc67f0cca8 fix: increment/decrement the uncategorized transactios on accounts 2024-06-09 21:05:43 +02:00
Ahmed Bouhuolia
ef2d1ff141 feat: Add COGS type to cash transactions categorization 2024-06-09 21:05:19 +02:00
Ahmed Bouhuolia
dc4cdb2a8f fix: Assign branch in categorize bank transaction 2024-06-09 20:05:15 +02:00
17 changed files with 120 additions and 22 deletions

View File

@@ -104,10 +104,10 @@ export default class UncategorizedCashflowTransaction extends mixin(
*/ */
private async updateUncategorizedTransactionCount( private async updateUncategorizedTransactionCount(
queryContext: QueryContext, queryContext: QueryContext,
increment: boolean increment: boolean,
amount: number = 1
) { ) {
const operation = increment ? 'increment' : 'decrement'; const operation = increment ? 'increment' : 'decrement';
const amount = increment ? 1 : -1;
await Account.query(queryContext.transaction) await Account.query(queryContext.transaction)
.findById(this.accountId) .findById(this.accountId)

View File

@@ -12,7 +12,6 @@ import { Knex } from 'knex';
import { transformCategorizeTransToCashflow } from './utils'; import { transformCategorizeTransToCashflow } from './utils';
import { CommandCashflowValidator } from './CommandCasflowValidator'; import { CommandCashflowValidator } from './CommandCasflowValidator';
import NewCashflowTransactionService from './NewCashflowTransactionService'; import NewCashflowTransactionService from './NewCashflowTransactionService';
import { TransferAuthorizationGuaranteeDecision } from 'plaid';
@Service() @Service()
export class CategorizeCashflowTransaction { export class CategorizeCashflowTransaction {

View File

@@ -68,7 +68,11 @@ export const CASHFLOW_TRANSACTION_TYPE_META = {
[`${CASHFLOW_TRANSACTION_TYPE.OTHER_EXPENSE}`]: { [`${CASHFLOW_TRANSACTION_TYPE.OTHER_EXPENSE}`]: {
type: 'OtherExpense', type: 'OtherExpense',
direction: CASHFLOW_DIRECTION.OUT, direction: CASHFLOW_DIRECTION.OUT,
creditType: [ACCOUNT_TYPE.EXPENSE, ACCOUNT_TYPE.OTHER_EXPENSE], creditType: [
ACCOUNT_TYPE.EXPENSE,
ACCOUNT_TYPE.OTHER_EXPENSE,
ACCOUNT_TYPE.COST_OF_GOODS_SOLD,
],
}, },
}; };

View File

@@ -1,4 +1,4 @@
import { upperFirst, camelCase, omit } from 'lodash'; import { upperFirst, camelCase } from 'lodash';
import { import {
CASHFLOW_TRANSACTION_TYPE, CASHFLOW_TRANSACTION_TYPE,
CASHFLOW_TRANSACTION_TYPE_META, CASHFLOW_TRANSACTION_TYPE_META,
@@ -6,7 +6,6 @@ import {
} from './constants'; } from './constants';
import { import {
ICashflowNewCommandDTO, ICashflowNewCommandDTO,
ICashflowTransaction,
ICategorizeCashflowTransactioDTO, ICategorizeCashflowTransactioDTO,
IUncategorizedCashflowTransaction, IUncategorizedCashflowTransaction,
} from '@/interfaces'; } from '@/interfaces';
@@ -62,6 +61,7 @@ export const transformCategorizeTransToCashflow = (
transactionNumber: categorizeDTO.transactionNumber, transactionNumber: categorizeDTO.transactionNumber,
transactionType: categorizeDTO.transactionType, transactionType: categorizeDTO.transactionType,
uncategorizedTransactionId: uncategorizeModel.id, uncategorizedTransactionId: uncategorizeModel.id,
branchId: categorizeDTO?.branchId,
publish: true, publish: true,
}; };
}; };

View File

@@ -108,17 +108,28 @@ export default class ResourceService {
const $hasFields = (field) => const $hasFields = (field) =>
'undefined' !== typeof field.fields ? field : undefined; 'undefined' !== typeof field.fields ? field : undefined;
const $hasColumns = (column) => const $ColumnHasColumns = (column) =>
'undefined' !== typeof column.columns ? column : undefined; 'undefined' !== typeof column.columns ? column : undefined;
const $hasColumns = (columns) =>
'undefined' !== typeof columns ? columns : undefined;
const naviagations = [ const naviagations = [
['fields', qim.$each, 'name'], ['fields', qim.$each, 'name'],
['fields', qim.$each, $enumerationType, 'options', qim.$each, 'label'], ['fields', qim.$each, $enumerationType, 'options', qim.$each, 'label'],
['fields2', qim.$each, 'name'], ['fields2', qim.$each, 'name'],
['fields2', qim.$each, $enumerationType, 'options', qim.$each, 'label'], ['fields2', qim.$each, $enumerationType, 'options', qim.$each, 'label'],
['fields2', qim.$each, $hasFields, 'fields', qim.$each, 'name'], ['fields2', qim.$each, $hasFields, 'fields', qim.$each, 'name'],
['columns', qim.$each, 'name'], ['columns', $hasColumns, qim.$each, 'name'],
['columns', qim.$each, $hasColumns, 'columns', qim.$each, 'name'], [
'columns',
$hasColumns,
qim.$each,
$ColumnHasColumns,
'columns',
qim.$each,
'name',
],
]; ];
return this.i18nService.i18nApply(naviagations, meta, tenantId); return this.i18nService.i18nApply(naviagations, meta, tenantId);
} }

View File

@@ -146,6 +146,7 @@ export class EditPaymentReceive {
paymentReceiveId, paymentReceiveId,
paymentReceive, paymentReceive,
oldPaymentReceive, oldPaymentReceive,
paymentReceiveDTO,
authorizedUser, authorizedUser,
trx, trx,
} as IPaymentReceiveEditedPayload); } as IPaymentReceiveEditedPayload);

View File

@@ -0,0 +1,18 @@
// @ts-nocheck
import { FSuggest } from '../Forms';
interface BranchSuggestFieldProps {
items: any[];
}
export function BranchSuggestField({ ...props }: BranchSuggestFieldProps) {
return (
<FSuggest
valueAccessor={'id'}
labelAccessor={'code'}
textAccessor={'name'}
inputProps={{ placeholder: 'Select a branch' }}
{...props}
/>
);
}

View File

@@ -1,5 +1,6 @@
// @ts-nocheck // @ts-nocheck
import React from 'react'; import React, { useMemo } from 'react';
import { first } from 'lodash';
import { DrawerHeaderContent, DrawerLoading } from '@/components'; import { DrawerHeaderContent, DrawerLoading } from '@/components';
import { DRAWERS } from '@/constants/drawers'; import { DRAWERS } from '@/constants/drawers';
import { import {
@@ -34,6 +35,12 @@ function CategorizeTransactionBoot({ uncategorizedTransactionId, ...props }) {
isLoading: isUncategorizedTransactionLoading, isLoading: isUncategorizedTransactionLoading,
} = useUncategorizedTransaction(uncategorizedTransactionId); } = useUncategorizedTransaction(uncategorizedTransactionId);
// Retrieves the primary branch.
const primaryBranch = useMemo(
() => branches?.find((b) => b.primary) || first(branches),
[branches],
);
const provider = { const provider = {
uncategorizedTransactionId, uncategorizedTransactionId,
uncategorizedTransaction, uncategorizedTransaction,
@@ -42,6 +49,7 @@ function CategorizeTransactionBoot({ uncategorizedTransactionId, ...props }) {
accounts, accounts,
isBranchesLoading, isBranchesLoading,
isAccountsLoading, isAccountsLoading,
primaryBranch,
}; };
const isLoading = const isLoading =
isBranchesLoading || isUncategorizedTransactionLoading || isAccountsLoading; isBranchesLoading || isUncategorizedTransactionLoading || isAccountsLoading;

View File

@@ -0,0 +1,22 @@
// @ts-nocheck
import { FFormGroup, FeatureCan } from '@/components';
import { useCategorizeTransactionBoot } from './CategorizeTransactionBoot';
import { Features } from '@/constants';
import { BranchSuggestField } from '@/components/Branches/BranchSuggestField_';
export function CategorizeTransactionBranchField() {
const { branches } = useCategorizeTransactionBoot();
return (
<FFormGroup name={'branchId'} label={'Branch'} fastField inline>
<FeatureCan feature={Features.Branches}>
<BranchSuggestField
name={'branchId'}
items={branches}
popoverProps={{ minimal: true }}
fill
/>
</FeatureCan>
</FFormGroup>
);
}

View File

@@ -24,8 +24,11 @@ function CategorizeTransactionFormRoot({
// #withDrawerActions // #withDrawerActions
closeDrawer, closeDrawer,
}) { }) {
const { uncategorizedTransactionId, uncategorizedTransaction } = const {
useCategorizeTransactionBoot(); uncategorizedTransactionId,
uncategorizedTransaction,
primaryBranch,
} = useCategorizeTransactionBoot();
const { mutateAsync: categorizeTransaction } = useCategorizeTransaction(); const { mutateAsync: categorizeTransaction } = useCategorizeTransaction();
// Callbacks handles form submit. // Callbacks handles form submit.
@@ -43,12 +46,22 @@ function CategorizeTransactionFormRoot({
intent: Intent.SUCCESS, intent: Intent.SUCCESS,
}); });
}) })
.catch(() => { .catch((err) => {
setSubmitting(false); setSubmitting(false);
if (
err.response.data?.errors?.some(
(e) => e.type === 'BRANCH_ID_REQUIRED',
)
) {
setErrors({
branchId: 'The branch is required.',
});
} else {
AppToaster.show({ AppToaster.show({
message: 'Something went wrong!', message: 'Something went wrong!',
intent: Intent.DANGER, intent: Intent.DANGER,
}); });
}
}); });
}; };
// Form initial values in create and edit mode. // Form initial values in create and edit mode.
@@ -60,6 +73,9 @@ function CategorizeTransactionFormRoot({
* as well. * as well.
*/ */
...transformToCategorizeForm(uncategorizedTransaction), ...transformToCategorizeForm(uncategorizedTransaction),
/** Assign the primary branch id as default value. */
branchId: primaryBranch?.id || null,
}; };
return ( return (

View File

@@ -8,6 +8,7 @@ import {
FTextArea, FTextArea,
} from '@/components'; } from '@/components';
import { useCategorizeTransactionBoot } from '../CategorizeTransactionBoot'; import { useCategorizeTransactionBoot } from '../CategorizeTransactionBoot';
import { CategorizeTransactionBranchField } from '../CategorizeTransactionBranchField';
export default function CategorizeTransactionOtherIncome() { export default function CategorizeTransactionOtherIncome() {
const { accounts } = useCategorizeTransactionBoot(); const { accounts } = useCategorizeTransactionBoot();
@@ -68,6 +69,8 @@ export default function CategorizeTransactionOtherIncome() {
fill={true} fill={true}
/> />
</FFormGroup> </FFormGroup>
<CategorizeTransactionBranchField />
</> </>
); );
} }

View File

@@ -8,6 +8,7 @@ import {
FTextArea, FTextArea,
} from '@/components'; } from '@/components';
import { useCategorizeTransactionBoot } from '../CategorizeTransactionBoot'; import { useCategorizeTransactionBoot } from '../CategorizeTransactionBoot';
import { CategorizeTransactionBranchField } from '../CategorizeTransactionBranchField';
export default function CategorizeTransactionOwnerContribution() { export default function CategorizeTransactionOwnerContribution() {
const { accounts } = useCategorizeTransactionBoot(); const { accounts } = useCategorizeTransactionBoot();
@@ -63,6 +64,8 @@ export default function CategorizeTransactionOwnerContribution() {
<FFormGroup name={'description'} label={'Description'} fastField inline> <FFormGroup name={'description'} label={'Description'} fastField inline>
<FTextArea name={'description'} growVertically large fill /> <FTextArea name={'description'} growVertically large fill />
</FFormGroup> </FFormGroup>
<CategorizeTransactionBranchField />
</> </>
); );
} }

View File

@@ -8,6 +8,7 @@ import {
FTextArea, FTextArea,
} from '@/components'; } from '@/components';
import { useCategorizeTransactionBoot } from '../CategorizeTransactionBoot'; import { useCategorizeTransactionBoot } from '../CategorizeTransactionBoot';
import { CategorizeTransactionBranchField } from '../CategorizeTransactionBranchField';
export default function CategorizeTransactionTransferFrom() { export default function CategorizeTransactionTransferFrom() {
const { accounts } = useCategorizeTransactionBoot(); const { accounts } = useCategorizeTransactionBoot();
@@ -47,7 +48,7 @@ export default function CategorizeTransactionTransferFrom() {
inline inline
> >
<AccountsSelect <AccountsSelect
name={'to_account_id'} name={'creditAccountId'}
items={accounts} items={accounts}
filterByRootTypes={['asset']} filterByRootTypes={['asset']}
fastField fastField
@@ -68,6 +69,8 @@ export default function CategorizeTransactionTransferFrom() {
fill={true} fill={true}
/> />
</FFormGroup> </FFormGroup>
<CategorizeTransactionBranchField />
</> </>
); );
} }

View File

@@ -8,6 +8,7 @@ import {
FTextArea, FTextArea,
} from '@/components'; } from '@/components';
import { useCategorizeTransactionBoot } from '../CategorizeTransactionBoot'; import { useCategorizeTransactionBoot } from '../CategorizeTransactionBoot';
import { CategorizeTransactionBranchField } from '../CategorizeTransactionBranchField';
export default function CategorizeTransactionOtherExpense() { export default function CategorizeTransactionOtherExpense() {
const { accounts } = useCategorizeTransactionBoot(); const { accounts } = useCategorizeTransactionBoot();
@@ -68,6 +69,8 @@ export default function CategorizeTransactionOtherExpense() {
fill={true} fill={true}
/> />
</FFormGroup> </FFormGroup>
<CategorizeTransactionBranchField />
</> </>
); );
} }

View File

@@ -8,6 +8,7 @@ import {
FTextArea, FTextArea,
} from '@/components'; } from '@/components';
import { useCategorizeTransactionBoot } from '../CategorizeTransactionBoot'; import { useCategorizeTransactionBoot } from '../CategorizeTransactionBoot';
import { CategorizeTransactionBranchField } from '../CategorizeTransactionBranchField';
export default function CategorizeTransactionOwnerDrawings() { export default function CategorizeTransactionOwnerDrawings() {
const { accounts } = useCategorizeTransactionBoot(); const { accounts } = useCategorizeTransactionBoot();
@@ -68,6 +69,8 @@ export default function CategorizeTransactionOwnerDrawings() {
fill={true} fill={true}
/> />
</FFormGroup> </FFormGroup>
<CategorizeTransactionBranchField />
</> </>
); );
} }

View File

@@ -8,6 +8,7 @@ import {
FTextArea, FTextArea,
} from '@/components'; } from '@/components';
import { useCategorizeTransactionBoot } from '../CategorizeTransactionBoot'; import { useCategorizeTransactionBoot } from '../CategorizeTransactionBoot';
import { CategorizeTransactionBranchField } from '../CategorizeTransactionBranchField';
export default function CategorizeTransactionToAccount() { export default function CategorizeTransactionToAccount() {
const { accounts } = useCategorizeTransactionBoot(); const { accounts } = useCategorizeTransactionBoot();
@@ -49,7 +50,7 @@ export default function CategorizeTransactionToAccount() {
<AccountsSelect <AccountsSelect
name={'creditAccountId'} name={'creditAccountId'}
items={accounts} items={accounts}
filterByRootTypes={['assset']} filterByRootTypes={['asset']}
fastField fastField
fill fill
allowCreate allowCreate
@@ -68,6 +69,8 @@ export default function CategorizeTransactionToAccount() {
fill={true} fill={true}
/> />
</FFormGroup> </FFormGroup>
<CategorizeTransactionBranchField />
</> </>
); );
} }

View File

@@ -11,6 +11,7 @@ export const defaultInitialValues = {
transactionType: '', transactionType: '',
referenceNo: '', referenceNo: '',
description: '', description: '',
branchId: '',
}; };
export const transformToCategorizeForm = (uncategorizedTransaction) => { export const transformToCategorizeForm = (uncategorizedTransaction) => {