mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-22 07:40:32 +00:00
Merge branch 'feature/multi-dimensions' of https://github.com/bigcapitalhq/client into feature/multi-dimensions
This commit is contained in:
76
src/components/Currencies/CurrencySelect.js
Normal file
76
src/components/Currencies/CurrencySelect.js
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import intl from 'react-intl-universal';
|
||||||
|
|
||||||
|
import { MenuItem, Button } from '@blueprintjs/core';
|
||||||
|
import { FSelect } from '../Forms';
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {*} query
|
||||||
|
* @param {*} currency
|
||||||
|
* @param {*} _index
|
||||||
|
* @param {*} exactMatch
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
const currencyItemPredicate = (query, currency, _index, exactMatch) => {
|
||||||
|
const normalizedTitle = currency.currency_code.toLowerCase();
|
||||||
|
const normalizedQuery = query.toLowerCase();
|
||||||
|
|
||||||
|
if (exactMatch) {
|
||||||
|
return normalizedTitle === normalizedQuery;
|
||||||
|
} else {
|
||||||
|
return (
|
||||||
|
`${currency.currency_code}. ${normalizedTitle}`.indexOf(
|
||||||
|
normalizedQuery,
|
||||||
|
) >= 0
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {*} currency
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
const currencyItemRenderer = (currency, { handleClick, modifiers, query }) => {
|
||||||
|
return (
|
||||||
|
<MenuItem
|
||||||
|
active={modifiers.active}
|
||||||
|
disabled={modifiers.disabled}
|
||||||
|
text={currency.currency_name}
|
||||||
|
label={currency.currency_code.toString()}
|
||||||
|
key={currency.id}
|
||||||
|
onClick={handleClick}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const currencySelectProps = {
|
||||||
|
itemPredicate: currencyItemPredicate,
|
||||||
|
itemRenderer: currencyItemRenderer,
|
||||||
|
valueAccessor: 'currency_code',
|
||||||
|
labelAccessor: 'currency_code',
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {*} currencies
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export function CurrencySelect({ currencies, ...rest }) {
|
||||||
|
return (
|
||||||
|
<FSelect
|
||||||
|
{...currencySelectProps}
|
||||||
|
{...rest}
|
||||||
|
items={currencies}
|
||||||
|
input={CurrnecySelectButton}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {*} label
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
function CurrnecySelectButton({ label }) {
|
||||||
|
return <Button text={label ? label : intl.get('select_currency_code')} />;
|
||||||
|
}
|
||||||
1
src/components/Currencies/index.js
Normal file
1
src/components/Currencies/index.js
Normal file
@@ -0,0 +1 @@
|
|||||||
|
export * from './CurrencySelect'
|
||||||
74
src/components/Warehouses/WarehouseMultiSelect.js
Normal file
74
src/components/Warehouses/WarehouseMultiSelect.js
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import intl from 'react-intl-universal';
|
||||||
|
import { MenuItem } from '@blueprintjs/core';
|
||||||
|
import { FMultiSelect } from '../Forms';
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {*} query
|
||||||
|
* @param {*} warehouse
|
||||||
|
* @param {*} _index
|
||||||
|
* @param {*} exactMatch
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
const warehouseItemPredicate = (query, warehouse, _index, exactMatch) => {
|
||||||
|
const normalizedTitle = warehouse.name.toLowerCase();
|
||||||
|
const normalizedQuery = query.toLowerCase();
|
||||||
|
|
||||||
|
if (exactMatch) {
|
||||||
|
return normalizedTitle === normalizedQuery;
|
||||||
|
} else {
|
||||||
|
return (
|
||||||
|
`${warehouse.code}. ${normalizedTitle}`.indexOf(normalizedQuery) >= 0
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {*} branch
|
||||||
|
* @param {*} param1
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
const warehouseItemRenderer = (
|
||||||
|
warehouse,
|
||||||
|
{ handleClick, modifiers, query },
|
||||||
|
{ isSelected },
|
||||||
|
) => {
|
||||||
|
return (
|
||||||
|
<MenuItem
|
||||||
|
active={modifiers.active}
|
||||||
|
disabled={modifiers.disabled}
|
||||||
|
icon={isSelected ? 'tick' : 'blank'}
|
||||||
|
text={warehouse.name.toString()}
|
||||||
|
label={warehouse.code.toString()}
|
||||||
|
key={warehouse.id}
|
||||||
|
onClick={handleClick}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const warehouseSelectProps = {
|
||||||
|
itemPredicate: warehouseItemPredicate,
|
||||||
|
itemRenderer: warehouseItemRenderer,
|
||||||
|
valueAccessor: (item) => item.id,
|
||||||
|
labelAccessor: (item) => item.label,
|
||||||
|
tagRenderer: (item) => item.name,
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* warehouses mulit select.
|
||||||
|
* @param {*} param0
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export function WarehouseMultiSelect({ warehouses, ...rest }) {
|
||||||
|
return (
|
||||||
|
<FMultiSelect
|
||||||
|
items={warehouses}
|
||||||
|
placeholder={intl.get('warehouses_multi_select.placeholder')}
|
||||||
|
popoverProps={{ minimal: true, usePortal: false }}
|
||||||
|
{...warehouseSelectProps}
|
||||||
|
{...rest}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -1 +1,2 @@
|
|||||||
export * from './WarehouseSelect';
|
export * from './WarehouseSelect';
|
||||||
|
export * from './WarehouseMultiSelect';
|
||||||
|
|||||||
@@ -101,6 +101,7 @@ export * from './FeatureGuard';
|
|||||||
export * from './ExchangeRate';
|
export * from './ExchangeRate';
|
||||||
export * from './Branches';
|
export * from './Branches';
|
||||||
export * from './Warehouses';
|
export * from './Warehouses';
|
||||||
|
export * from './Currencies';
|
||||||
|
|
||||||
const Hint = FieldHint;
|
const Hint = FieldHint;
|
||||||
|
|
||||||
@@ -169,5 +170,4 @@ export {
|
|||||||
BaseCurrency,
|
BaseCurrency,
|
||||||
MoreMenuItems,
|
MoreMenuItems,
|
||||||
CustomSelectList,
|
CustomSelectList,
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import React from 'react';
|
|||||||
import { useBranches } from 'hooks/query';
|
import { useBranches } from 'hooks/query';
|
||||||
import { FinancialHeaderLoadingSkeleton } from '../FinancialHeaderLoadingSkeleton';
|
import { FinancialHeaderLoadingSkeleton } from '../FinancialHeaderLoadingSkeleton';
|
||||||
|
|
||||||
const BalanceSheetHeaderDimensionsPanelConext = React.createContext();
|
const BalanceSheetHeaderDimensionsPanelContext = React.createContext();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* BL sheet header provider.
|
* BL sheet header provider.
|
||||||
@@ -22,11 +22,17 @@ function BalanceSheetHeaderDimensionsProvider({ ...props }) {
|
|||||||
return isBranchesLoading ? (
|
return isBranchesLoading ? (
|
||||||
<FinancialHeaderLoadingSkeleton />
|
<FinancialHeaderLoadingSkeleton />
|
||||||
) : (
|
) : (
|
||||||
<BalanceSheetHeaderDimensionsPanelConext.Provider value={provider} {...props} />
|
<BalanceSheetHeaderDimensionsPanelContext.Provider
|
||||||
|
value={provider}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const useBalanceSheetHeaderDimensionsPanelContext = () =>
|
const useBalanceSheetHeaderDimensionsPanelContext = () =>
|
||||||
React.useContext(BalanceSheetHeaderDimensionsPanelConext);
|
React.useContext(BalanceSheetHeaderDimensionsPanelContext);
|
||||||
|
|
||||||
export { BalanceSheetHeaderDimensionsProvider, useBalanceSheetHeaderDimensionsPanelContext };
|
export {
|
||||||
|
BalanceSheetHeaderDimensionsProvider,
|
||||||
|
useBalanceSheetHeaderDimensionsPanelContext,
|
||||||
|
};
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import intl from 'react-intl-universal';
|
|||||||
|
|
||||||
import FinancialStatementHeader from 'containers/FinancialStatements/FinancialStatementHeader';
|
import FinancialStatementHeader from 'containers/FinancialStatements/FinancialStatementHeader';
|
||||||
import InventoryItemDetailsHeaderGeneralPanel from './InventoryItemDetailsHeaderGeneralPanel';
|
import InventoryItemDetailsHeaderGeneralPanel from './InventoryItemDetailsHeaderGeneralPanel';
|
||||||
|
import InventoryItemDetailsHeaderDimensionsPanel from './InventoryItemDetailsHeaderDimensionsPanel';
|
||||||
|
|
||||||
import withInventoryItemDetails from './withInventoryItemDetails';
|
import withInventoryItemDetails from './withInventoryItemDetails';
|
||||||
import withInventoryItemDetailsActions from './withInventoryItemDetailsActions';
|
import withInventoryItemDetailsActions from './withInventoryItemDetailsActions';
|
||||||
@@ -32,27 +33,28 @@ function InventoryItemDetailsHeader({
|
|||||||
fromDate: moment().toDate(),
|
fromDate: moment().toDate(),
|
||||||
toDate: moment().toDate(),
|
toDate: moment().toDate(),
|
||||||
itemsIds: [],
|
itemsIds: [],
|
||||||
|
warehousesIds: [],
|
||||||
};
|
};
|
||||||
|
|
||||||
// Filter form initial values.
|
// Filter form initial values.
|
||||||
const initialValues = transformToForm({
|
const initialValues = transformToForm(
|
||||||
...pageFilter,
|
{
|
||||||
fromDate: moment(pageFilter.fromDate).toDate(),
|
...pageFilter,
|
||||||
toDate: moment(pageFilter.toDate).toDate(),
|
fromDate: moment(pageFilter.fromDate).toDate(),
|
||||||
}, defaultValues);
|
toDate: moment(pageFilter.toDate).toDate(),
|
||||||
|
warehousesIds: [],
|
||||||
|
},
|
||||||
|
defaultValues,
|
||||||
|
);
|
||||||
|
|
||||||
// Validation schema.
|
// Validation schema.
|
||||||
const validationSchema = Yup.object().shape({
|
const validationSchema = Yup.object().shape({
|
||||||
fromDate: Yup.date()
|
fromDate: Yup.date().required().label(intl.get('fromDate')),
|
||||||
.required()
|
|
||||||
.label(intl.get('fromDate')),
|
|
||||||
toDate: Yup.date()
|
toDate: Yup.date()
|
||||||
.min(Yup.ref('fromDate'))
|
.min(Yup.ref('fromDate'))
|
||||||
.required()
|
.required()
|
||||||
.label(intl.get('toDate')),
|
.label(intl.get('toDate')),
|
||||||
});
|
});
|
||||||
;
|
|
||||||
|
|
||||||
// Handle form submit.
|
// Handle form submit.
|
||||||
const handleSubmit = (values, { setSubmitting }) => {
|
const handleSubmit = (values, { setSubmitting }) => {
|
||||||
onSubmitFilter(values);
|
onSubmitFilter(values);
|
||||||
@@ -61,7 +63,9 @@ function InventoryItemDetailsHeader({
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Handle drawer close action.
|
// Handle drawer close action.
|
||||||
const handleDrawerClose = () => { toggleFilterDrawer(false); };
|
const handleDrawerClose = () => {
|
||||||
|
toggleFilterDrawer(false);
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<FinancialStatementHeader
|
<FinancialStatementHeader
|
||||||
@@ -80,6 +84,11 @@ function InventoryItemDetailsHeader({
|
|||||||
title={<T id={'general'} />}
|
title={<T id={'general'} />}
|
||||||
panel={<InventoryItemDetailsHeaderGeneralPanel />}
|
panel={<InventoryItemDetailsHeaderGeneralPanel />}
|
||||||
/>
|
/>
|
||||||
|
<Tab
|
||||||
|
id="dimensions"
|
||||||
|
title={'Dimensions'}
|
||||||
|
panel={<InventoryItemDetailsHeaderDimensionsPanel />}
|
||||||
|
/>
|
||||||
</Tabs>
|
</Tabs>
|
||||||
<div class="financial-header-drawer__footer">
|
<div class="financial-header-drawer__footer">
|
||||||
<Button className={'mr1'} intent={Intent.PRIMARY} type={'submit'}>
|
<Button className={'mr1'} intent={Intent.PRIMARY} type={'submit'}>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -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,
|
||||||
|
};
|
||||||
@@ -7,6 +7,7 @@ import { Tabs, Tab, Button, Intent } from '@blueprintjs/core';
|
|||||||
|
|
||||||
import FinancialStatementHeader from 'containers/FinancialStatements/FinancialStatementHeader';
|
import FinancialStatementHeader from 'containers/FinancialStatements/FinancialStatementHeader';
|
||||||
import InventoryValuationHeaderGeneralPanel from './InventoryValuationHeaderGeneralPanel';
|
import InventoryValuationHeaderGeneralPanel from './InventoryValuationHeaderGeneralPanel';
|
||||||
|
import InventoryValuationHeaderDimensionsPanel from './InventoryValuationHeaderDimensionsPanel';
|
||||||
import withInventoryValuation from './withInventoryValuation';
|
import withInventoryValuation from './withInventoryValuation';
|
||||||
import withInventoryValuationActions from './withInventoryValuationActions';
|
import withInventoryValuationActions from './withInventoryValuationActions';
|
||||||
|
|
||||||
@@ -36,13 +37,18 @@ function InventoryValuationHeader({
|
|||||||
...pageFilter,
|
...pageFilter,
|
||||||
asDate: moment().toDate(),
|
asDate: moment().toDate(),
|
||||||
itemsIds: [],
|
itemsIds: [],
|
||||||
|
warehousesIds: [],
|
||||||
};
|
};
|
||||||
// Initial values.
|
// Initial values.
|
||||||
const initialValues = transformToForm({
|
const initialValues = transformToForm(
|
||||||
...pageFilter,
|
{
|
||||||
...defaultValues,
|
...pageFilter,
|
||||||
asDate: moment(pageFilter.asDate).toDate(),
|
...defaultValues,
|
||||||
}, defaultValues);
|
asDate: moment(pageFilter.asDate).toDate(),
|
||||||
|
warehousesIds: [],
|
||||||
|
},
|
||||||
|
defaultValues,
|
||||||
|
);
|
||||||
|
|
||||||
// Handle the form of header submit.
|
// Handle the form of header submit.
|
||||||
const handleSubmit = (values, { setSubmitting }) => {
|
const handleSubmit = (values, { setSubmitting }) => {
|
||||||
@@ -78,6 +84,11 @@ function InventoryValuationHeader({
|
|||||||
title={<T id={'general'} />}
|
title={<T id={'general'} />}
|
||||||
panel={<InventoryValuationHeaderGeneralPanel />}
|
panel={<InventoryValuationHeaderGeneralPanel />}
|
||||||
/>
|
/>
|
||||||
|
<Tab
|
||||||
|
id="dimensions"
|
||||||
|
title={'Dimensions'}
|
||||||
|
panel={<InventoryValuationHeaderDimensionsPanel />}
|
||||||
|
/>
|
||||||
</Tabs>
|
</Tabs>
|
||||||
<div class="financial-header-drawer__footer">
|
<div class="financial-header-drawer__footer">
|
||||||
<Button className={'mr1'} intent={Intent.PRIMARY} type={'submit'}>
|
<Button className={'mr1'} intent={Intent.PRIMARY} type={'submit'}>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -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,
|
||||||
|
};
|
||||||
@@ -3,7 +3,7 @@ import React from 'react';
|
|||||||
import { useBranches } from 'hooks/query';
|
import { useBranches } from 'hooks/query';
|
||||||
import { FinancialHeaderLoadingSkeleton } from '../FinancialHeaderLoadingSkeleton';
|
import { FinancialHeaderLoadingSkeleton } from '../FinancialHeaderLoadingSkeleton';
|
||||||
|
|
||||||
const ProfitLossSheetHeaderDimensionsPanelConext = React.createContext();
|
const ProfitLossSheetHeaderDimensionsPanelContext = React.createContext();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* profit loss sheet header provider.
|
* profit loss sheet header provider.
|
||||||
@@ -22,7 +22,7 @@ function ProfitLossSheetHeaderDimensionsProvider({ ...props }) {
|
|||||||
return isBranchesLoading ? (
|
return isBranchesLoading ? (
|
||||||
<FinancialHeaderLoadingSkeleton />
|
<FinancialHeaderLoadingSkeleton />
|
||||||
) : (
|
) : (
|
||||||
<ProfitLossSheetHeaderDimensionsPanelConext.Provider
|
<ProfitLossSheetHeaderDimensionsPanelContext.Provider
|
||||||
value={provider}
|
value={provider}
|
||||||
{...props}
|
{...props}
|
||||||
/>
|
/>
|
||||||
@@ -30,7 +30,7 @@ function ProfitLossSheetHeaderDimensionsProvider({ ...props }) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const useProfitLossSheetPanelContext = () =>
|
const useProfitLossSheetPanelContext = () =>
|
||||||
React.useContext(ProfitLossSheetHeaderDimensionsPanelConext);
|
React.useContext(ProfitLossSheetHeaderDimensionsPanelContext);
|
||||||
|
|
||||||
export {
|
export {
|
||||||
ProfitLossSheetHeaderDimensionsProvider,
|
ProfitLossSheetHeaderDimensionsProvider,
|
||||||
|
|||||||
@@ -57,7 +57,8 @@ function InvoiceFormHeaderFields({
|
|||||||
invoiceNextNumber,
|
invoiceNextNumber,
|
||||||
}) {
|
}) {
|
||||||
// Invoice form context.
|
// Invoice form context.
|
||||||
const { customers, isForeignCustomer } = useInvoiceFormContext();
|
const { customers, isForeignCustomer, setSelectCustomer } =
|
||||||
|
useInvoiceFormContext();
|
||||||
|
|
||||||
// Handle invoice number changing.
|
// Handle invoice number changing.
|
||||||
const handleInvoiceNumberChange = () => {
|
const handleInvoiceNumberChange = () => {
|
||||||
@@ -109,6 +110,7 @@ function InvoiceFormHeaderFields({
|
|||||||
defaultSelectText={<T id={'select_customer_account'} />}
|
defaultSelectText={<T id={'select_customer_account'} />}
|
||||||
onContactSelected={(customer) => {
|
onContactSelected={(customer) => {
|
||||||
form.setFieldValue('customer_id', customer.id);
|
form.setFieldValue('customer_id', customer.id);
|
||||||
|
setSelectCustomer(customer);
|
||||||
}}
|
}}
|
||||||
popoverFill={true}
|
popoverFill={true}
|
||||||
allowCreate={true}
|
allowCreate={true}
|
||||||
@@ -120,7 +122,7 @@ function InvoiceFormHeaderFields({
|
|||||||
</FastField>
|
</FastField>
|
||||||
|
|
||||||
{/* ----------- Exchange rate ----------- */}
|
{/* ----------- Exchange rate ----------- */}
|
||||||
<If condition={true}>
|
<If condition={isForeignCustomer}>
|
||||||
<ExchangeRateInputGroup
|
<ExchangeRateInputGroup
|
||||||
fromCurrency={'USD'}
|
fromCurrency={'USD'}
|
||||||
toCurrency={'LYD'}
|
toCurrency={'LYD'}
|
||||||
|
|||||||
@@ -5,17 +5,23 @@ import 'style/pages/SaleInvoice/PageForm.scss';
|
|||||||
|
|
||||||
import InvoiceForm from './InvoiceForm';
|
import InvoiceForm from './InvoiceForm';
|
||||||
import { InvoiceFormProvider } from './InvoiceFormProvider';
|
import { InvoiceFormProvider } from './InvoiceFormProvider';
|
||||||
|
import withCurrentOrganization from 'containers/Organization/withCurrentOrganization';
|
||||||
|
import { compose } from 'utils';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Invoice form page.
|
* Invoice form page.
|
||||||
*/
|
*/
|
||||||
export default function InvoiceFormPage() {
|
function InvoiceFormPage({
|
||||||
|
// #withCurrentOrganization
|
||||||
|
organization: { base_currency },
|
||||||
|
}) {
|
||||||
const { id } = useParams();
|
const { id } = useParams();
|
||||||
const idAsInteger = parseInt(id, 10);
|
const idAsInteger = parseInt(id, 10);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<InvoiceFormProvider invoiceId={idAsInteger}>
|
<InvoiceFormProvider invoiceId={idAsInteger} baseCurrency={base_currency}>
|
||||||
<InvoiceForm />
|
<InvoiceForm />
|
||||||
</InvoiceFormProvider>
|
</InvoiceFormProvider>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
export default compose(withCurrentOrganization())(InvoiceFormPage);
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import React, { createContext, useState } from 'react';
|
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 { useLocation } from 'react-router-dom';
|
||||||
import DashboardInsider from 'components/Dashboard/DashboardInsider';
|
import DashboardInsider from 'components/Dashboard/DashboardInsider';
|
||||||
import { transformToEditForm, ITEMS_FILTER_ROLES_QUERY } from './utils';
|
import { transformToEditForm, ITEMS_FILTER_ROLES_QUERY } from './utils';
|
||||||
@@ -20,7 +20,7 @@ const InvoiceFormContext = createContext();
|
|||||||
/**
|
/**
|
||||||
* Accounts chart data provider.
|
* Accounts chart data provider.
|
||||||
*/
|
*/
|
||||||
function InvoiceFormProvider({ invoiceId, ...props }) {
|
function InvoiceFormProvider({ invoiceId, baseCurrency, ...props }) {
|
||||||
const { state } = useLocation();
|
const { state } = useLocation();
|
||||||
const estimateId = state?.action;
|
const estimateId = state?.action;
|
||||||
|
|
||||||
@@ -78,6 +78,7 @@ function InvoiceFormProvider({ invoiceId, ...props }) {
|
|||||||
|
|
||||||
// Form submit payload.
|
// Form submit payload.
|
||||||
const [submitPayload, setSubmitPayload] = useState();
|
const [submitPayload, setSubmitPayload] = useState();
|
||||||
|
const [selectCustomer, setSelectCustomer] = useState(null);
|
||||||
|
|
||||||
// Detarmines whether the form in new mode.
|
// Detarmines whether the form in new mode.
|
||||||
const isNewMode = !invoiceId;
|
const isNewMode = !invoiceId;
|
||||||
@@ -86,9 +87,10 @@ function InvoiceFormProvider({ invoiceId, ...props }) {
|
|||||||
const isFeatureLoading = isWarehouesLoading || isBranchesLoading;
|
const isFeatureLoading = isWarehouesLoading || isBranchesLoading;
|
||||||
|
|
||||||
// Determines whether the foreign customer.
|
// Determines whether the foreign customer.
|
||||||
const isForeignCustomer = false;
|
const isForeignCustomer =
|
||||||
|
!isEqual(selectCustomer?.currency_code, baseCurrency) &&
|
||||||
|
!isUndefined(selectCustomer?.currency_code);
|
||||||
|
|
||||||
// Provider payload.
|
|
||||||
const provider = {
|
const provider = {
|
||||||
invoice,
|
invoice,
|
||||||
items,
|
items,
|
||||||
@@ -97,6 +99,7 @@ function InvoiceFormProvider({ invoiceId, ...props }) {
|
|||||||
estimateId,
|
estimateId,
|
||||||
invoiceId,
|
invoiceId,
|
||||||
submitPayload,
|
submitPayload,
|
||||||
|
selectCustomer,
|
||||||
branches,
|
branches,
|
||||||
warehouses,
|
warehouses,
|
||||||
|
|
||||||
@@ -114,6 +117,7 @@ function InvoiceFormProvider({ invoiceId, ...props }) {
|
|||||||
createInvoiceMutate,
|
createInvoiceMutate,
|
||||||
editInvoiceMutate,
|
editInvoiceMutate,
|
||||||
setSubmitPayload,
|
setSubmitPayload,
|
||||||
|
setSelectCustomer,
|
||||||
isNewMode,
|
isNewMode,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1854,7 +1854,9 @@
|
|||||||
"make_primary": "Make as Primary",
|
"make_primary": "Make as Primary",
|
||||||
"invoice.branch_button.label": "Branch: {label}",
|
"invoice.branch_button.label": "Branch: {label}",
|
||||||
"invoice.warehouse_button.label": "Warehouse: {label}",
|
"invoice.warehouse_button.label": "Warehouse: {label}",
|
||||||
"branches_multi_select.label":"Branches",
|
"branches_multi_select.label": "Branches",
|
||||||
"branches_multi_select.placeholder": "Filter by branches…",
|
"branches_multi_select.placeholder": "Filter by branches…",
|
||||||
|
"warehouses_multi_select.label": "Warehouses",
|
||||||
|
"warehouses_multi_select.placeholder": "Filter by warehouses…",
|
||||||
"dimensions": "Dimensions"
|
"dimensions": "Dimensions"
|
||||||
}
|
}
|
||||||
@@ -5,7 +5,7 @@
|
|||||||
// Blueprint framework.
|
// Blueprint framework.
|
||||||
@import '@blueprintjs/core/src/blueprint.scss';
|
@import '@blueprintjs/core/src/blueprint.scss';
|
||||||
@import '@blueprintjs/datetime/src/blueprint-datetime.scss';
|
@import '@blueprintjs/datetime/src/blueprint-datetime.scss';
|
||||||
@import "@blueprintjs/popover2/src/blueprint-popover2.scss";
|
@import '@blueprintjs/popover2/src/blueprint-popover2.scss';
|
||||||
|
|
||||||
@import 'basscss';
|
@import 'basscss';
|
||||||
|
|
||||||
@@ -52,7 +52,6 @@ body.hide-scrollbar .Pane2 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.bp3-fill {
|
.bp3-fill {
|
||||||
|
|
||||||
.bp3-popover-wrapper,
|
.bp3-popover-wrapper,
|
||||||
.bp3-popover-target {
|
.bp3-popover-target {
|
||||||
display: block;
|
display: block;
|
||||||
@@ -104,22 +103,27 @@ body.hide-scrollbar .Pane2 {
|
|||||||
background-color: #0066ff;
|
background-color: #0066ff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.ReactVirtualized__Collection {
|
||||||
|
}
|
||||||
|
|
||||||
.ReactVirtualized__Collection {}
|
.ReactVirtualized__Collection__innerScrollContainer {
|
||||||
|
}
|
||||||
.ReactVirtualized__Collection__innerScrollContainer {}
|
|
||||||
|
|
||||||
/* Grid default theme */
|
/* Grid default theme */
|
||||||
|
|
||||||
.ReactVirtualized__Grid {}
|
.ReactVirtualized__Grid {
|
||||||
|
}
|
||||||
|
|
||||||
.ReactVirtualized__Grid__innerScrollContainer {}
|
.ReactVirtualized__Grid__innerScrollContainer {
|
||||||
|
}
|
||||||
|
|
||||||
/* Table default theme */
|
/* Table default theme */
|
||||||
|
|
||||||
.ReactVirtualized__Table {}
|
.ReactVirtualized__Table {
|
||||||
|
}
|
||||||
|
|
||||||
.ReactVirtualized__Table__Grid {}
|
.ReactVirtualized__Table__Grid {
|
||||||
|
}
|
||||||
|
|
||||||
.ReactVirtualized__Table__headerRow {
|
.ReactVirtualized__Table__headerRow {
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
@@ -182,8 +186,8 @@ body.hide-scrollbar .Pane2 {
|
|||||||
|
|
||||||
/* List default theme */
|
/* List default theme */
|
||||||
|
|
||||||
.ReactVirtualized__List {}
|
.ReactVirtualized__List {
|
||||||
|
}
|
||||||
|
|
||||||
.bp3-drawer {
|
.bp3-drawer {
|
||||||
box-shadow: 0 0 0;
|
box-shadow: 0 0 0;
|
||||||
@@ -195,21 +199,20 @@ body.hide-scrollbar .Pane2 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// RTL Icons.
|
// RTL Icons.
|
||||||
html[dir="rtl"] {
|
html[dir='rtl'] {
|
||||||
.bp3-icon-caret-right {
|
.bp3-icon-caret-right {
|
||||||
transform: scaleX(-1);
|
transform: scaleX(-1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
html[lang^="ar"] {
|
html[lang^='ar'] {
|
||||||
body {
|
body {
|
||||||
letter-spacing: -0.01rem;
|
letter-spacing: -0.01rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.bp3-popover2 {
|
.bp3-popover2 {
|
||||||
box-shadow: 0 0 0 1px rgba(16, 22, 26, 0.02),
|
box-shadow: 0 0 0 1px rgba(16, 22, 26, 0.02), 0 2px 4px rgba(16, 22, 26, 0.1),
|
||||||
0 2px 4px rgba(16, 22, 26, 0.1),
|
|
||||||
0 8px 24px rgba(16, 22, 26, 0.1);
|
0 8px 24px rgba(16, 22, 26, 0.1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -240,21 +243,19 @@ html[lang^="ar"] {
|
|||||||
padding-left: 14px;
|
padding-left: 14px;
|
||||||
padding-right: 14px;
|
padding-right: 14px;
|
||||||
|
|
||||||
&+.bp3-button {
|
& + .bp3-button {
|
||||||
margin-left: 8px;
|
margin-left: 8px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.bp3-dialog {
|
.bp3-dialog {
|
||||||
|
|
||||||
&-body {
|
&-body {
|
||||||
|
|
||||||
&:not(.loading) {
|
&:not(.loading) {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
>.bp3-spinner {
|
> .bp3-spinner {
|
||||||
margin: 20px 0;
|
margin: 20px 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -266,13 +267,11 @@ html[lang^="ar"] {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.drawer-portal {
|
.drawer-portal {
|
||||||
|
|
||||||
.bp3-overlay-backdrop {
|
.bp3-overlay-backdrop {
|
||||||
background: rgba(0, 10, 30, 0.05);
|
background: rgba(0, 10, 30, 0.05);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.big-number {
|
.big-number {
|
||||||
font-size: 28px;
|
font-size: 28px;
|
||||||
color: #c06361;
|
color: #c06361;
|
||||||
@@ -281,18 +280,13 @@ html[lang^="ar"] {
|
|||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.align-right {
|
.align-right {
|
||||||
text-align: right;
|
text-align: right;
|
||||||
}
|
}
|
||||||
.align-center{
|
.align-center {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.font-bold {
|
.font-bold {
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
}
|
}
|
||||||
|
|
||||||
.bp3-tag-input {
|
|
||||||
height: auto;
|
|
||||||
}
|
|
||||||
@@ -124,4 +124,14 @@
|
|||||||
padding-right: 0.85rem;
|
padding-right: 0.85rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.bp3-popover-target {
|
||||||
|
.bp3-tag-input {
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// .bp3-multi-select-popover .bp3-menu {
|
||||||
|
// max-height: 200px;
|
||||||
|
// width: 300px;
|
||||||
|
// overflow: auto;
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user