Merge branch 'feature/multi-dimensions' of https://github.com/bigcapitalhq/client into feature/multi-dimensions

This commit is contained in:
a.bouhuolia
2022-03-20 16:45:24 +02:00
23 changed files with 559 additions and 127 deletions

View File

@@ -8,29 +8,37 @@ import {
TotalLineBorderStyle,
TotalLineTextStyle,
} from 'components';
import { useBillTotals } from './utils';
export function BillFormFooterRight() {
const {
formattedSubtotal,
formattedTotal,
formattedDueTotal,
formattedPaymentTotal,
} = useBillTotals();
return (
<BillTotalLines labelColWidth={'180px'} amountColWidth={'180px'}>
<TotalLine
title={<T id={'bill.details.subtotal'} />}
value={'$5000.00'}
value={formattedSubtotal}
borderStyle={TotalLineBorderStyle.None}
/>
<TotalLine
title={<T id={'bill.details.total'} />}
value={'$5000.00'}
value={formattedTotal}
borderStyle={TotalLineBorderStyle.SingleDark}
textStyle={TotalLineTextStyle.Bold}
/>
<TotalLine
title={<T id={'bill.details.payment_amount'} />}
value={'$0.00'}
value={formattedPaymentTotal}
borderStyle={TotalLineBorderStyle.None}
/>
<TotalLine
title={<T id={'bill.details.due_amount'} />}
value={'$5000.00'}
value={formattedDueTotal}
textStyle={TotalLineTextStyle.Bold}
/>
</BillTotalLines>

View File

@@ -16,13 +16,13 @@ import {
VendorSelectField,
FieldRequiredHint,
Icon,
ExchangeRateInputGroup,
If,
CustomerDrawerLink,
VendorDrawerLink,
} from 'components';
import { vendorsFieldShouldUpdate } from './utils';
import { useBillFormContext } from './BillFormProvider';
import BillFormCurrencyTag from './BillFormCurrencyTag';
import { BillExchangeRateInputField } from './components';
import withDialogActions from 'containers/Dialog/withDialogActions';
import {
momentFormatter,
@@ -37,13 +37,7 @@ import {
*/
function BillFormHeader() {
// Bill form context.
const {
vendors,
isForeignVendor,
baseCurrency,
selectVendor,
setSelectVendor,
} = useBillFormContext();
const { vendors } = useBillFormContext();
return (
<div className={classNames(CLASSES.PAGE_FORM_HEADER_FIELDS)}>
@@ -57,7 +51,11 @@ function BillFormHeader() {
<FormGroup
label={<T id={'vendor_name'} />}
inline={true}
className={classNames(CLASSES.FILL, 'form-group--vendor')}
className={classNames(
'form-group--customer-name',
'form-group--select-list',
CLASSES.FILL,
)}
labelInfo={<FieldRequiredHint />}
intent={inputIntent({ error, touched })}
helperText={<ErrorMessage name={'vendor_id'} />}
@@ -70,26 +68,25 @@ function BillFormHeader() {
onContactSelected={(contact) => {
form.setFieldValue('vendor_id', contact.id);
form.setFieldValue('currency_code', contact?.currency_code);
setSelectVendor(contact);
}}
popoverFill={true}
allowCreate={true}
/>
<BillFormCurrencyTag />
</ControlVendorGroup>
{value && (
<VendorButtonLink vendorId={value}>
View Vendor Details
</VendorButtonLink>
)}
</FormGroup>
)}
</FastField>
{/* ----------- Exchange rate ----------- */}
<If condition={isForeignVendor}>
<ExchangeRateInputGroup
fromCurrency={baseCurrency}
toCurrency={selectVendor?.currency_code}
name={'exchange_rate'}
formGroupProps={{ label: ' ', inline: true }}
/>
</If>
<BillExchangeRateInputField
name={'exchange_rate'}
formGroupProps={{ label: ' ', inline: true }}
/>
{/* ------- Bill date ------- */}
<FastField name={'bill_date'}>
@@ -184,3 +181,8 @@ const ControlVendorGroup = styled(ControlGroup)`
align-items: center;
transform: none;
`;
const VendorButtonLink = styled(VendorDrawerLink)`
font-size: 11px;
margin-top: 6px;
`;

View File

@@ -0,0 +1,28 @@
import React from 'react';
import { useFormikContext } from 'formik';
import { ExchangeRateInputGroup } from 'components';
import { useCurrentOrganization } from 'hooks/state';
import { useBillIsForeignCustomer } from './utils';
/**
* bill exchange rate input field.
* @returns {JSX.Element}
*/
export function BillExchangeRateInputField({ ...props }) {
const currentOrganization = useCurrentOrganization();
const { values } = useFormikContext();
const isForeignCustomer = useBillIsForeignCustomer();
// Can't continue if the customer is not foreign.
if (!isForeignCustomer) {
return null;
}
return (
<ExchangeRateInputGroup
fromCurrency={values.currency_code}
toCurrency={currentOrganization.base_currency}
{...props}
/>
);
}

View File

@@ -11,12 +11,14 @@ import {
transformToForm,
repeatValue,
orderingLinesIndexes,
formattedAmount,
} from 'utils';
import {
updateItemsEntriesTotal,
ensureEntriesHaveEmptyLine,
} from 'containers/Entries/utils';
import { isLandedCostDisabled } from '../../../Entries/utils';
import { useCurrentOrganization } from 'hooks/state';
import { isLandedCostDisabled, getEntriesTotal } from '../../../Entries/utils';
import { useBillFormContext } from './BillFormProvider';
export const MIN_LINES_NUMBER = 1;
@@ -216,3 +218,69 @@ export const useSetPrimaryWarehouseToForm = () => {
}
}, [isWarehousesSuccess, setFieldValue, warehouses]);
};
/**
* Retreives the bill totals.
*/
export const useBillTotals = () => {
const {
values: { entries, currency_code: currencyCode },
} = useFormikContext();
// Retrieves the bili entries total.
const total = React.useMemo(() => getEntriesTotal(entries), [entries]);
// Retrieves the formatted total money.
const formattedTotal = React.useMemo(
() => formattedAmount(total, currencyCode),
[total, currencyCode],
);
// Retrieves the formatted subtotal.
const formattedSubtotal = React.useMemo(
() => formattedAmount(total, currencyCode, { money: false }),
[total, currencyCode],
);
// Retrieves the payment total.
const paymentTotal = React.useMemo(() => 0, []);
// Retireves the formatted payment total.
const formattedPaymentTotal = React.useMemo(
() => formattedAmount(paymentTotal, currencyCode),
[paymentTotal, currencyCode],
);
// Retrieves the formatted due total.
const dueTotal = React.useMemo(
() => total - paymentTotal,
[total, paymentTotal],
);
// Retrieves the formatted due total.
const formattedDueTotal = React.useMemo(
() => formattedAmount(dueTotal, currencyCode),
[dueTotal, currencyCode],
);
return {
total,
paymentTotal,
dueTotal,
formattedTotal,
formattedSubtotal,
formattedPaymentTotal,
formattedDueTotal,
};
};
/**
* Detarmines whether the bill has foreign customer.
* @returns {boolean}
*/
export const useBillIsForeignCustomer = () => {
const { values } = useFormikContext();
const currentOrganization = useCurrentOrganization();
const isForeignCustomer = React.useMemo(
() => values.currency_code !== currentOrganization.base_currency,
[values.currency_code, currentOrganization.base_currency],
);
return isForeignCustomer;
};