Skip to content

Commit

Permalink
Merge pull request #134 from bigcapitalhq/contacts-opening-balance-ex…
Browse files Browse the repository at this point in the history
…change-rate

fix(webapp): customer/vendor opening balance with exchange rate
  • Loading branch information
abouolia authored Jun 11, 2023
2 parents eb9b6ce + 3ebeb29 commit 35ebb9c
Show file tree
Hide file tree
Showing 8 changed files with 294 additions and 166 deletions.
Original file line number Diff line number Diff line change
@@ -1,26 +1,30 @@
// @ts-nocheck
import React from 'react';
import moment from 'moment';
import classNames from 'classnames';
import { FormGroup, Position, Classes, ControlGroup } from '@blueprintjs/core';
import { DateInput } from '@blueprintjs/datetime';
import { FastField, ErrorMessage } from 'formik';
import { FastField, ErrorMessage, useFormikContext } from 'formik';
import { Features } from '@/constants';
import {
FFormGroup,
FormattedMessage as T,
MoneyInputGroup,
InputPrependText,
CurrencySelectList,
BranchSelect,
BranchSelectButton,
FeatureCan,
Row,
Col,
FMoneyInputGroup,
ExchangeRateInputGroup,
FDateInput,
} from '@/components';
import { useCustomerFormContext } from './CustomerFormProvider';
import { useSetPrimaryBranchToForm } from './utils';
import { momentFormatter, tansformDateValue, inputIntent } from '@/utils';
import {
openingBalanceFieldShouldUpdate,
useIsCustomerForeignCurrency,
useSetPrimaryBranchToForm,
} from './utils';
import { useCurrentOrganization } from '@/hooks/state';

/**
* Customer financial panel.
Expand All @@ -35,58 +39,38 @@ export default function CustomerFinancialPanel() {
<div className={'tab-panel--financial'}>
<Row>
<Col xs={6}>
{/*------------ Opening balance at -----------*/}
<FastField name={'opening_balance_at'}>
{/*------------ Currency -----------*/}
<FastField name={'currency_code'}>
{({ form, field: { value }, meta: { error, touched } }) => (
<FormGroup
label={<T id={'opening_balance_at'} />}
className={classNames('form-group--select-list', Classes.FILL)}
intent={inputIntent({ error, touched })}
label={<T id={'currency'} />}
className={classNames(
'form-group--select-list',
'form-group--balance-currency',
Classes.FILL,
)}
inline={true}
helperText={<ErrorMessage name="opening_balance_at" />}
>
<DateInput
{...momentFormatter('YYYY/MM/DD')}
onChange={(date) => {
form.setFieldValue(
'opening_balance_at',
moment(date).format('YYYY-MM-DD'),
);
<CurrencySelectList
currenciesList={currencies}
selectedCurrencyCode={value}
onCurrencySelected={(currency) => {
form.setFieldValue('currency_code', currency.currency_code);
}}
value={tansformDateValue(value)}
popoverProps={{ position: Position.BOTTOM, minimal: true }}
disabled={customerId}
/>
</FormGroup>
)}
</FastField>

{/*------------ Opening balance -----------*/}
<FastField name={'opening_balance'}>
{({ form, field, field: { value }, meta: { error, touched } }) => (
<FormGroup
label={<T id={'opening_balance'} />}
className={classNames(
'form-group--opening-balance',
Classes.FILL,
)}
intent={inputIntent({ error, touched })}
inline={true}
>
<ControlGroup>
<InputPrependText text={form.values.currency_code} />
<MoneyInputGroup
value={value}
inputGroupProps={{ fill: true }}
disabled={customerId}
onChange={(balance) => {
form.setFieldValue('opening_balance', balance);
}}
/>
</ControlGroup>
</FormGroup>
)}
</FastField>
<CustomerOpeningBalanceField />

{/*------ Opening Balance Exchange Rate -----*/}
<CustomerOpeningBalanceExchangeRateField />

{/*------------ Opening balance at -----------*/}
<CustomerOpeningBalanceAtField />

{/*------------ Opening branch -----------*/}
<FeatureCan feature={Features.Branches}>
Expand All @@ -104,31 +88,99 @@ export default function CustomerFinancialPanel() {
/>
</FFormGroup>
</FeatureCan>

{/*------------ Currency -----------*/}
<FastField name={'currency_code'}>
{({ form, field: { value }, meta: { error, touched } }) => (
<FormGroup
label={<T id={'currency'} />}
className={classNames(
'form-group--select-list',
'form-group--balance-currency',
Classes.FILL,
)}
inline={true}
>
<CurrencySelectList
currenciesList={currencies}
selectedCurrencyCode={value}
onCurrencySelected={(currency) => {
form.setFieldValue('currency_code', currency.currency_code);
}}
/>
</FormGroup>
)}
</FastField>
</Col>
</Row>
</div>
);
}

/**
* Customer opening balance at date field.
* @returns {JSX.Element}
*/
function CustomerOpeningBalanceAtField() {
const { customerId } = useCustomerFormContext();

// Cannot continue if the customer id is defined.
if (customerId) return null;

return (
<FormGroup
name={'opening_balance_at'}
label={<T id={'opening_balance_at'} />}
inline={true}
helperText={<ErrorMessage name="opening_balance_at" />}
>
<FDateInput
name={'opening_balance_at'}
popoverProps={{ position: Position.BOTTOM, minimal: true }}
disabled={customerId}
formatDate={(date) => date.toLocaleDateString()}
parseDate={(str) => new Date(str)}
fill={true}
/>
</FormGroup>
);
}

/**
* Customer opening balance field.
* @returns {JSX.Element}
*/
function CustomerOpeningBalanceField() {
const { customerId } = useCustomerFormContext();
const { values } = useFormikContext();

// Cannot continue if the customer id is defined.
if (customerId) return null;

return (
<FFormGroup
label={<T id={'opening_balance'} />}
name={'opening_balance'}
inline={true}
shouldUpdate={openingBalanceFieldShouldUpdate}
shouldUpdateDeps={{ currencyCode: values.currency_code }}
fastField={true}
>
<ControlGroup>
<InputPrependText text={values.currency_code} />
<FMoneyInputGroup
name={'opening_balance'}
inputGroupProps={{ fill: true }}
/>
</ControlGroup>
</FFormGroup>
);
}

/**
* Customer opening balance exchange rate field if the customer has foreign
* currency.
* @returns {JSX.Element}
*/
function CustomerOpeningBalanceExchangeRateField() {
const { values } = useFormikContext();
const { customerId } = useCustomerFormContext();
const currentOrganization = useCurrentOrganization();

const isForeignJouranl = useIsCustomerForeignCurrency();

// Can't continue if the customer is not foreign.
if (!isForeignJouranl || customerId) {
return null;
}
return (
<FFormGroup
label={' '}
name={'opening_balance_exchange_rate'}
inline={true}
>
<ExchangeRateInputGroup
fromCurrency={values.currency_code}
toCurrency={currentOrganization.base_currency}
name={'opening_balance_exchange_rate'}
/>
</FFormGroup>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,6 @@ export default function CustomersTabs() {
title={intl.get('notes')}
panel={<CustomerNotePanel />}
/>
<Tab
id={'attachement'}
title={intl.get('attachement')}
panel={<CustomerAttachmentTabs />}
/>
</Tabs>
</div>
);
Expand Down
27 changes: 26 additions & 1 deletion packages/webapp/src/containers/Customers/CustomerForm/utils.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { useFormikContext } from 'formik';
import { first } from 'lodash';

import { useCustomerFormContext } from './CustomerFormProvider';
import { useCurrentOrganization } from '@/hooks/state';

export const defaultInitialValues = {
customer_type: 'business',
Expand Down Expand Up @@ -37,9 +38,11 @@ export const defaultInitialValues = {
shipping_address_postcode: '',
shipping_address_phone: '',

opening_balance: '',
currency_code: '',

opening_balance: '',
opening_balance_at: moment(new Date()).format('YYYY-MM-DD'),
opening_balance_exchange_rate: '',
opening_balance_branch_id: '',
};

Expand All @@ -57,3 +60,25 @@ export const useSetPrimaryBranchToForm = () => {
}
}, [isBranchesSuccess, setFieldValue, branches]);
};

/**
* Detarmines whether the current customer has foreign currency.
* @returns {boolean}
*/
export const useIsCustomerForeignCurrency = () => {
const currentOrganization = useCurrentOrganization();
const { values } = useFormikContext();

return currentOrganization.base_currency !== values.currency_code;
};

/**
* Detarmines the exchange opening balance field when should update.
*/
export const openingBalanceFieldShouldUpdate = (newProps, oldProps) => {
return (
newProps.shouldUpdateDeps.currencyCode !==
oldProps.shouldUpdateDeps.currencyCode ||
defaultFastFieldShouldUpdate(newProps, oldProps)
);
};
Loading

1 comment on commit 35ebb9c

@vercel
Copy link

@vercel vercel bot commented on 35ebb9c Jun 11, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.