From cd663d99b7326dd9b8b95c66796c0ef24995eaa9 Mon Sep 17 00:00:00 2001 From: elforjani13 <39470382+elforjani13@users.noreply.github.com> Date: Thu, 17 Feb 2022 19:07:58 +0200 Subject: [PATCH 1/3] fix(invoice): foreign customer. --- .../Invoices/InvoiceForm/InvoiceFormHeaderFields.js | 6 ++++-- .../Sales/Invoices/InvoiceForm/InvoiceFormPage.js | 10 ++++++++-- .../Invoices/InvoiceForm/InvoiceFormProvider.js | 12 ++++++++---- 3 files changed, 20 insertions(+), 8 deletions(-) diff --git a/src/containers/Sales/Invoices/InvoiceForm/InvoiceFormHeaderFields.js b/src/containers/Sales/Invoices/InvoiceForm/InvoiceFormHeaderFields.js index 760ffcab2..31d48a57f 100644 --- a/src/containers/Sales/Invoices/InvoiceForm/InvoiceFormHeaderFields.js +++ b/src/containers/Sales/Invoices/InvoiceForm/InvoiceFormHeaderFields.js @@ -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={} onContactSelected={(customer) => { form.setFieldValue('customer_id', customer.id); + setSelectCustomer(customer); }} popoverFill={true} allowCreate={true} @@ -120,7 +122,7 @@ function InvoiceFormHeaderFields({ {/* ----------- Exchange rate ----------- */} - + + ); } +export default compose(withCurrentOrganization())(InvoiceFormPage); diff --git a/src/containers/Sales/Invoices/InvoiceForm/InvoiceFormProvider.js b/src/containers/Sales/Invoices/InvoiceForm/InvoiceFormProvider.js index 488d3d21f..3e3155c63 100644 --- a/src/containers/Sales/Invoices/InvoiceForm/InvoiceFormProvider.js +++ b/src/containers/Sales/Invoices/InvoiceForm/InvoiceFormProvider.js @@ -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; @@ -70,6 +70,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; @@ -78,9 +79,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, @@ -89,6 +91,7 @@ function InvoiceFormProvider({ invoiceId, ...props }) { estimateId, invoiceId, submitPayload, + selectCustomer, branches, warehouses, @@ -104,6 +107,7 @@ function InvoiceFormProvider({ invoiceId, ...props }) { createInvoiceMutate, editInvoiceMutate, setSubmitPayload, + setSelectCustomer, isNewMode, }; From 7a27ea9a650688b99b06231fec16267bff44ca56 Mon Sep 17 00:00:00 2001 From: elforjani13 <39470382+elforjani13@users.noreply.github.com> Date: Thu, 17 Feb 2022 20:30:16 +0200 Subject: [PATCH 2/3] feat(inventory item & valuation): warehouse multi select. --- .../Warehouses/WarehouseMultiSelect.js | 74 +++++++++++++++++++ src/components/Warehouses/index.js | 3 +- .../BalanceSheetHeaderDimensionsProvider.js | 14 +++- .../InventoryItemDetailsHeader.js | 33 ++++++--- ...ventoryItemDetailsHeaderDimensionsPanel.js | 44 +++++++++++ ...temDetailsHeaderDimensionsPanelProvider.js | 38 ++++++++++ .../InventoryValuationHeader.js | 21 ++++-- ...InventoryValuationHeaderDimensionsPanel.js | 44 +++++++++++ ...yValuationHeaderDimensionsPanelProvider.js | 38 ++++++++++ ...ProfitLossSheetHeaderDimensionsProvider.js | 6 +- src/lang/en/index.json | 4 +- src/style/App.scss | 48 ++++++------ .../FinancialStatements/DrawerHeader.scss | 10 +++ 13 files changed, 324 insertions(+), 53 deletions(-) create mode 100644 src/components/Warehouses/WarehouseMultiSelect.js create mode 100644 src/containers/FinancialStatements/InventoryItemDetails/InventoryItemDetailsHeaderDimensionsPanel.js create mode 100644 src/containers/FinancialStatements/InventoryItemDetails/InventoryItemDetailsHeaderDimensionsPanelProvider.js create mode 100644 src/containers/FinancialStatements/InventoryValuation/InventoryValuationHeaderDimensionsPanel.js create mode 100644 src/containers/FinancialStatements/InventoryValuation/InventoryValuationHeaderDimensionsPanelProvider.js diff --git a/src/components/Warehouses/WarehouseMultiSelect.js b/src/components/Warehouses/WarehouseMultiSelect.js new file mode 100644 index 000000000..e39651e94 --- /dev/null +++ b/src/components/Warehouses/WarehouseMultiSelect.js @@ -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 ( + + ); +}; + +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 ( + + ); +} diff --git a/src/components/Warehouses/index.js b/src/components/Warehouses/index.js index 3b38eb9e6..6975b2230 100644 --- a/src/components/Warehouses/index.js +++ b/src/components/Warehouses/index.js @@ -1 +1,2 @@ -export * from './WarehouseSelect'; \ No newline at end of file +export * from './WarehouseSelect'; +export * from './WarehouseMultiSelect'; diff --git a/src/containers/FinancialStatements/BalanceSheet/BalanceSheetHeaderDimensionsProvider.js b/src/containers/FinancialStatements/BalanceSheet/BalanceSheetHeaderDimensionsProvider.js index a3ea4de19..183f22fdf 100644 --- a/src/containers/FinancialStatements/BalanceSheet/BalanceSheetHeaderDimensionsProvider.js +++ b/src/containers/FinancialStatements/BalanceSheet/BalanceSheetHeaderDimensionsProvider.js @@ -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 ? ( ) : ( - + ); } const useBalanceSheetHeaderDimensionsPanelContext = () => - React.useContext(BalanceSheetHeaderDimensionsPanelConext); + React.useContext(BalanceSheetHeaderDimensionsPanelContext); -export { BalanceSheetHeaderDimensionsProvider, useBalanceSheetHeaderDimensionsPanelContext }; +export { + BalanceSheetHeaderDimensionsProvider, + useBalanceSheetHeaderDimensionsPanelContext, +}; diff --git a/src/containers/FinancialStatements/InventoryItemDetails/InventoryItemDetailsHeader.js b/src/containers/FinancialStatements/InventoryItemDetails/InventoryItemDetailsHeader.js index 5f7a2d2a2..0e3db74d5 100644 --- a/src/containers/FinancialStatements/InventoryItemDetails/InventoryItemDetailsHeader.js +++ b/src/containers/FinancialStatements/InventoryItemDetails/InventoryItemDetailsHeader.js @@ -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 ( } panel={} /> + } + />