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

This commit is contained in:
a.bouhuolia
2022-02-19 17:15:58 +02:00
19 changed files with 422 additions and 62 deletions

View File

@@ -3,7 +3,7 @@ import React from 'react';
import { useBranches } from 'hooks/query';
import { FinancialHeaderLoadingSkeleton } from '../FinancialHeaderLoadingSkeleton';
const BalanceSheetHeaderDimensionsPanelConext = React.createContext();
const BalanceSheetHeaderDimensionsPanelContext = React.createContext();
/**
* BL sheet header provider.
@@ -22,11 +22,17 @@ function BalanceSheetHeaderDimensionsProvider({ ...props }) {
return isBranchesLoading ? (
<FinancialHeaderLoadingSkeleton />
) : (
<BalanceSheetHeaderDimensionsPanelConext.Provider value={provider} {...props} />
<BalanceSheetHeaderDimensionsPanelContext.Provider
value={provider}
{...props}
/>
);
}
const useBalanceSheetHeaderDimensionsPanelContext = () =>
React.useContext(BalanceSheetHeaderDimensionsPanelConext);
React.useContext(BalanceSheetHeaderDimensionsPanelContext);
export { BalanceSheetHeaderDimensionsProvider, useBalanceSheetHeaderDimensionsPanelContext };
export {
BalanceSheetHeaderDimensionsProvider,
useBalanceSheetHeaderDimensionsPanelContext,
};

View File

@@ -8,6 +8,7 @@ import intl from 'react-intl-universal';
import FinancialStatementHeader from 'containers/FinancialStatements/FinancialStatementHeader';
import InventoryItemDetailsHeaderGeneralPanel from './InventoryItemDetailsHeaderGeneralPanel';
import InventoryItemDetailsHeaderDimensionsPanel from './InventoryItemDetailsHeaderDimensionsPanel';
import withInventoryItemDetails from './withInventoryItemDetails';
import withInventoryItemDetailsActions from './withInventoryItemDetailsActions';
@@ -32,27 +33,28 @@ function InventoryItemDetailsHeader({
fromDate: moment().toDate(),
toDate: moment().toDate(),
itemsIds: [],
warehousesIds: [],
};
// Filter form initial values.
const initialValues = transformToForm({
...pageFilter,
fromDate: moment(pageFilter.fromDate).toDate(),
toDate: moment(pageFilter.toDate).toDate(),
}, defaultValues);
const initialValues = transformToForm(
{
...pageFilter,
fromDate: moment(pageFilter.fromDate).toDate(),
toDate: moment(pageFilter.toDate).toDate(),
warehousesIds: [],
},
defaultValues,
);
// Validation schema.
const validationSchema = Yup.object().shape({
fromDate: Yup.date()
.required()
.label(intl.get('fromDate')),
fromDate: Yup.date().required().label(intl.get('fromDate')),
toDate: Yup.date()
.min(Yup.ref('fromDate'))
.required()
.label(intl.get('toDate')),
});
;
// Handle form submit.
const handleSubmit = (values, { setSubmitting }) => {
onSubmitFilter(values);
@@ -61,8 +63,10 @@ function InventoryItemDetailsHeader({
};
// Handle drawer close action.
const handleDrawerClose = () => { toggleFilterDrawer(false); };
const handleDrawerClose = () => {
toggleFilterDrawer(false);
};
return (
<FinancialStatementHeader
isOpen={isFilterDrawerOpen}
@@ -80,6 +84,11 @@ function InventoryItemDetailsHeader({
title={<T id={'general'} />}
panel={<InventoryItemDetailsHeaderGeneralPanel />}
/>
<Tab
id="dimensions"
title={'Dimensions'}
panel={<InventoryItemDetailsHeaderDimensionsPanel />}
/>
</Tabs>
<div class="financial-header-drawer__footer">
<Button className={'mr1'} intent={Intent.PRIMARY} type={'submit'}>

View File

@@ -0,0 +1,44 @@
import React from 'react';
import intl from 'react-intl-universal';
import { FormGroup, Classes } from '@blueprintjs/core';
import { WarehouseMultiSelect, Row, Col } from 'components';
import {
InventoryItemDetailsHeaderDimensionsProvider,
useInventoryItemDetailsHeaderDimensionsPanelContext,
} from './InventoryItemDetailsHeaderDimensionsPanelProvider';
/**
* Inventory Item deatil header dismension panel.
* @returns
*/
export default function InventoryItemDetailsHeaderDimensionsPanel() {
return (
<InventoryItemDetailsHeaderDimensionsProvider>
<InventoryItemDetailsHeaderDimensionsPanelContent />
</InventoryItemDetailsHeaderDimensionsProvider>
);
}
/**
* Inventory Valuation header dismension panel content.
* @returns
*/
function InventoryItemDetailsHeaderDimensionsPanelContent() {
const { warehouses } = useInventoryItemDetailsHeaderDimensionsPanelContext();
return (
<Row>
<Col xs={4}>
<FormGroup
label={intl.get('warehouses_multi_select.label')}
className={Classes.FILL}
>
<WarehouseMultiSelect
name={'warehousesIds'}
warehouses={warehouses}
/>
</FormGroup>
</Col>
</Row>
);
}

View File

@@ -0,0 +1,38 @@
import React from 'react';
import { useWarehouses } from 'hooks/query';
import { FinancialHeaderLoadingSkeleton } from '../FinancialHeaderLoadingSkeleton';
const InventoryItemDetailsHeaderDimensionsPanelContext = React.createContext();
/**
* Inventory Item details header provider.
* @returns
*/
function InventoryItemDetailsHeaderDimensionsProvider({ ...props }) {
// Fetch warehouses list.
const { data: warehouses, isLoading: isWarehouesLoading } = useWarehouses();
// Provider
const provider = {
warehouses,
isWarehouesLoading,
};
return isWarehouesLoading ? (
<FinancialHeaderLoadingSkeleton />
) : (
<InventoryItemDetailsHeaderDimensionsPanelContext.Provider
value={provider}
{...props}
/>
);
}
const useInventoryItemDetailsHeaderDimensionsPanelContext = () =>
React.useContext(InventoryItemDetailsHeaderDimensionsPanelContext);
export {
InventoryItemDetailsHeaderDimensionsProvider,
useInventoryItemDetailsHeaderDimensionsPanelContext,
};

View File

@@ -7,6 +7,7 @@ import { Tabs, Tab, Button, Intent } from '@blueprintjs/core';
import FinancialStatementHeader from 'containers/FinancialStatements/FinancialStatementHeader';
import InventoryValuationHeaderGeneralPanel from './InventoryValuationHeaderGeneralPanel';
import InventoryValuationHeaderDimensionsPanel from './InventoryValuationHeaderDimensionsPanel';
import withInventoryValuation from './withInventoryValuation';
import withInventoryValuationActions from './withInventoryValuationActions';
@@ -36,13 +37,18 @@ function InventoryValuationHeader({
...pageFilter,
asDate: moment().toDate(),
itemsIds: [],
warehousesIds: [],
};
// Initial values.
const initialValues = transformToForm({
...pageFilter,
...defaultValues,
asDate: moment(pageFilter.asDate).toDate(),
}, defaultValues);
const initialValues = transformToForm(
{
...pageFilter,
...defaultValues,
asDate: moment(pageFilter.asDate).toDate(),
warehousesIds: [],
},
defaultValues,
);
// Handle the form of header submit.
const handleSubmit = (values, { setSubmitting }) => {
@@ -78,6 +84,11 @@ function InventoryValuationHeader({
title={<T id={'general'} />}
panel={<InventoryValuationHeaderGeneralPanel />}
/>
<Tab
id="dimensions"
title={'Dimensions'}
panel={<InventoryValuationHeaderDimensionsPanel />}
/>
</Tabs>
<div class="financial-header-drawer__footer">
<Button className={'mr1'} intent={Intent.PRIMARY} type={'submit'}>

View File

@@ -0,0 +1,44 @@
import React from 'react';
import intl from 'react-intl-universal';
import { FormGroup, Classes } from '@blueprintjs/core';
import { WarehouseMultiSelect, Row, Col } from 'components';
import {
InventoryValuationHeaderDimensionsProvider,
useInventoryValuationHeaderDimensionsPanelContext,
} from './InventoryValuationHeaderDimensionsPanelProvider';
/**
* Inventory Valuation header dismension panel.
* @returns
*/
export default function InventoryValuationHeaderDimensionsPanel() {
return (
<InventoryValuationHeaderDimensionsProvider>
<InventoryValuationHeaderDimensionsPanelContent />
</InventoryValuationHeaderDimensionsProvider>
);
}
/**
* Inventory Valuation header dismension panel content.
* @returns
*/
function InventoryValuationHeaderDimensionsPanelContent() {
const { warehouses } = useInventoryValuationHeaderDimensionsPanelContext();
return (
<Row>
<Col xs={4}>
<FormGroup
label={intl.get('warehouses_multi_select.label')}
className={Classes.FILL}
>
<WarehouseMultiSelect
name={'warehousesIds'}
warehouses={warehouses}
/>
</FormGroup>
</Col>
</Row>
);
}

View File

@@ -0,0 +1,38 @@
import React from 'react';
import { useWarehouses } from 'hooks/query';
import { FinancialHeaderLoadingSkeleton } from '../FinancialHeaderLoadingSkeleton';
const InventoryValuationHeaderDimensionsPanelContext = React.createContext();
/**
* Inventory valuation header provider.
* @returns
*/
function InventoryValuationHeaderDimensionsProvider({ ...props }) {
// Fetch warehouses list.
const { data: warehouses, isLoading: isWarehouesLoading } = useWarehouses();
// Provider
const provider = {
warehouses,
isWarehouesLoading,
};
return isWarehouesLoading ? (
<FinancialHeaderLoadingSkeleton />
) : (
<InventoryValuationHeaderDimensionsPanelContext.Provider
value={provider}
{...props}
/>
);
}
const useInventoryValuationHeaderDimensionsPanelContext = () =>
React.useContext(InventoryValuationHeaderDimensionsPanelContext);
export {
InventoryValuationHeaderDimensionsProvider,
useInventoryValuationHeaderDimensionsPanelContext,
};

View File

@@ -3,7 +3,7 @@ import React from 'react';
import { useBranches } from 'hooks/query';
import { FinancialHeaderLoadingSkeleton } from '../FinancialHeaderLoadingSkeleton';
const ProfitLossSheetHeaderDimensionsPanelConext = React.createContext();
const ProfitLossSheetHeaderDimensionsPanelContext = React.createContext();
/**
* profit loss sheet header provider.
@@ -22,7 +22,7 @@ function ProfitLossSheetHeaderDimensionsProvider({ ...props }) {
return isBranchesLoading ? (
<FinancialHeaderLoadingSkeleton />
) : (
<ProfitLossSheetHeaderDimensionsPanelConext.Provider
<ProfitLossSheetHeaderDimensionsPanelContext.Provider
value={provider}
{...props}
/>
@@ -30,7 +30,7 @@ function ProfitLossSheetHeaderDimensionsProvider({ ...props }) {
}
const useProfitLossSheetPanelContext = () =>
React.useContext(ProfitLossSheetHeaderDimensionsPanelConext);
React.useContext(ProfitLossSheetHeaderDimensionsPanelContext);
export {
ProfitLossSheetHeaderDimensionsProvider,

View File

@@ -57,7 +57,8 @@ function InvoiceFormHeaderFields({
invoiceNextNumber,
}) {
// Invoice form context.
const { customers, isForeignCustomer } = useInvoiceFormContext();
const { customers, isForeignCustomer, setSelectCustomer } =
useInvoiceFormContext();
// Handle invoice number changing.
const handleInvoiceNumberChange = () => {
@@ -109,6 +110,7 @@ function InvoiceFormHeaderFields({
defaultSelectText={<T id={'select_customer_account'} />}
onContactSelected={(customer) => {
form.setFieldValue('customer_id', customer.id);
setSelectCustomer(customer);
}}
popoverFill={true}
allowCreate={true}
@@ -120,7 +122,7 @@ function InvoiceFormHeaderFields({
</FastField>
{/* ----------- Exchange rate ----------- */}
<If condition={true}>
<If condition={isForeignCustomer}>
<ExchangeRateInputGroup
fromCurrency={'USD'}
toCurrency={'LYD'}

View File

@@ -5,17 +5,23 @@ import 'style/pages/SaleInvoice/PageForm.scss';
import InvoiceForm from './InvoiceForm';
import { InvoiceFormProvider } from './InvoiceFormProvider';
import withCurrentOrganization from 'containers/Organization/withCurrentOrganization';
import { compose } from 'utils';
/**
* Invoice form page.
*/
export default function InvoiceFormPage() {
function InvoiceFormPage({
// #withCurrentOrganization
organization: { base_currency },
}) {
const { id } = useParams();
const idAsInteger = parseInt(id, 10);
return (
<InvoiceFormProvider invoiceId={idAsInteger}>
<InvoiceFormProvider invoiceId={idAsInteger} baseCurrency={base_currency}>
<InvoiceForm />
</InvoiceFormProvider>
);
}
export default compose(withCurrentOrganization())(InvoiceFormPage);

View File

@@ -1,5 +1,5 @@
import React, { createContext, useState } from 'react';
import { isEmpty, pick } from 'lodash';
import { isEmpty, pick, isEqual, isUndefined } from 'lodash';
import { useLocation } from 'react-router-dom';
import DashboardInsider from 'components/Dashboard/DashboardInsider';
import { transformToEditForm, ITEMS_FILTER_ROLES_QUERY } from './utils';
@@ -20,7 +20,7 @@ const InvoiceFormContext = createContext();
/**
* Accounts chart data provider.
*/
function InvoiceFormProvider({ invoiceId, ...props }) {
function InvoiceFormProvider({ invoiceId, baseCurrency, ...props }) {
const { state } = useLocation();
const estimateId = state?.action;
@@ -78,6 +78,7 @@ function InvoiceFormProvider({ invoiceId, ...props }) {
// Form submit payload.
const [submitPayload, setSubmitPayload] = useState();
const [selectCustomer, setSelectCustomer] = useState(null);
// Detarmines whether the form in new mode.
const isNewMode = !invoiceId;
@@ -86,9 +87,10 @@ function InvoiceFormProvider({ invoiceId, ...props }) {
const isFeatureLoading = isWarehouesLoading || isBranchesLoading;
// Determines whether the foreign customer.
const isForeignCustomer = false;
const isForeignCustomer =
!isEqual(selectCustomer?.currency_code, baseCurrency) &&
!isUndefined(selectCustomer?.currency_code);
// Provider payload.
const provider = {
invoice,
items,
@@ -97,6 +99,7 @@ function InvoiceFormProvider({ invoiceId, ...props }) {
estimateId,
invoiceId,
submitPayload,
selectCustomer,
branches,
warehouses,
@@ -114,6 +117,7 @@ function InvoiceFormProvider({ invoiceId, ...props }) {
createInvoiceMutate,
editInvoiceMutate,
setSubmitPayload,
setSelectCustomer,
isNewMode,
};