diff --git a/packages/webapp/src/containers/Customers/CustomerForm/CustomerFinancialPanel.tsx b/packages/webapp/src/containers/Customers/CustomerForm/CustomerFinancialPanel.tsx index b41312c818..8de4eb45cc 100644 --- a/packages/webapp/src/containers/Customers/CustomerForm/CustomerFinancialPanel.tsx +++ b/packages/webapp/src/containers/Customers/CustomerForm/CustomerFinancialPanel.tsx @@ -1,15 +1,12 @@ // @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, @@ -17,10 +14,17 @@ import { 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. @@ -35,26 +39,24 @@ export default function CustomerFinancialPanel() {
- {/*------------ Opening balance at -----------*/} - + {/*------------ Currency -----------*/} + {({ form, field: { value }, meta: { error, touched } }) => ( } - className={classNames('form-group--select-list', Classes.FILL)} - intent={inputIntent({ error, touched })} + label={} + className={classNames( + 'form-group--select-list', + 'form-group--balance-currency', + Classes.FILL, + )} inline={true} - helperText={} > - { - form.setFieldValue( - 'opening_balance_at', - moment(date).format('YYYY-MM-DD'), - ); + { + form.setFieldValue('currency_code', currency.currency_code); }} - value={tansformDateValue(value)} - popoverProps={{ position: Position.BOTTOM, minimal: true }} disabled={customerId} /> @@ -62,31 +64,13 @@ export default function CustomerFinancialPanel() { {/*------------ Opening balance -----------*/} - - {({ form, field, field: { value }, meta: { error, touched } }) => ( - } - className={classNames( - 'form-group--opening-balance', - Classes.FILL, - )} - intent={inputIntent({ error, touched })} - inline={true} - > - - - { - form.setFieldValue('opening_balance', balance); - }} - /> - - - )} - + + + {/*------ Opening Balance Exchange Rate -----*/} + + + {/*------------ Opening balance at -----------*/} + {/*------------ Opening branch -----------*/} @@ -104,31 +88,99 @@ export default function CustomerFinancialPanel() { /> - - {/*------------ Currency -----------*/} - - {({ form, field: { value }, meta: { error, touched } }) => ( - } - className={classNames( - 'form-group--select-list', - 'form-group--balance-currency', - Classes.FILL, - )} - inline={true} - > - { - form.setFieldValue('currency_code', currency.currency_code); - }} - /> - - )} -
); } + +/** + * 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 ( + } + inline={true} + helperText={} + > + date.toLocaleDateString()} + parseDate={(str) => new Date(str)} + fill={true} + /> + + ); +} + +/** + * 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 ( + } + name={'opening_balance'} + inline={true} + shouldUpdate={openingBalanceFieldShouldUpdate} + shouldUpdateDeps={{ currencyCode: values.currency_code }} + fastField={true} + > + + + + + + ); +} + +/** + * 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 ( + + + + ); +} diff --git a/packages/webapp/src/containers/Customers/CustomerForm/CustomersTabs.tsx b/packages/webapp/src/containers/Customers/CustomerForm/CustomersTabs.tsx index 72881e9837..02ecd39ace 100644 --- a/packages/webapp/src/containers/Customers/CustomerForm/CustomersTabs.tsx +++ b/packages/webapp/src/containers/Customers/CustomerForm/CustomersTabs.tsx @@ -32,11 +32,6 @@ export default function CustomersTabs() { title={intl.get('notes')} panel={} /> - } - /> ); diff --git a/packages/webapp/src/containers/Customers/CustomerForm/utils.tsx b/packages/webapp/src/containers/Customers/CustomerForm/utils.tsx index f230c1fd64..a6d17c45c3 100644 --- a/packages/webapp/src/containers/Customers/CustomerForm/utils.tsx +++ b/packages/webapp/src/containers/Customers/CustomerForm/utils.tsx @@ -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', @@ -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: '', }; @@ -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) + ); +}; diff --git a/packages/webapp/src/containers/Vendors/VendorForm/VendorFinanicalPanelTab.tsx b/packages/webapp/src/containers/Vendors/VendorForm/VendorFinanicalPanelTab.tsx index ada9e19300..511ba5cc26 100644 --- a/packages/webapp/src/containers/Vendors/VendorForm/VendorFinanicalPanelTab.tsx +++ b/packages/webapp/src/containers/Vendors/VendorForm/VendorFinanicalPanelTab.tsx @@ -1,14 +1,11 @@ // @ts-nocheck import React from 'react'; -import moment from 'moment'; import classNames from 'classnames'; import { FormGroup, ControlGroup, Position, Classes } 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, - MoneyInputGroup, InputPrependText, CurrencySelectList, BranchSelect, @@ -17,16 +14,23 @@ import { Row, Col, FormattedMessage as T, + FMoneyInputGroup, + ExchangeRateInputGroup, + FDateInput, } from '@/components'; -import { useSetPrimaryBranchToForm } from './utils'; -import { momentFormatter, tansformDateValue, inputIntent } from '@/utils'; +import { + openingBalanceFieldShouldUpdate, + useIsVendorForeignCurrency, + useSetPrimaryBranchToForm, +} from './utils'; import { useVendorFormContext } from './VendorFormProvider'; +import { useCurrentOrganization } from '@/hooks/state'; /** * Vendor Finaniceal Panel Tab. */ export default function VendorFinanicalPanelTab() { - const { vendorId, currencies, branches } = useVendorFormContext(); + const { currencies, branches } = useVendorFormContext(); // Sets the primary branch to form. useSetPrimaryBranchToForm(); @@ -35,61 +39,36 @@ export default function VendorFinanicalPanelTab() {
- {/*------------ Opening balance at -----------*/} - + {/*------------ Currency -----------*/} + {({ form, field: { value }, meta: { error, touched } }) => ( } - className={classNames('form-group--select-list', Classes.FILL)} - intent={inputIntent({ error, touched })} - inline={true} - helperText={} - > - { - form.setFieldValue( - 'opening_balance_at', - moment(date).format('YYYY-MM-DD'), - ); - }} - value={tansformDateValue(value)} - popoverProps={{ position: Position.BOTTOM, minimal: true }} - disabled={vendorId} - /> - - )} - - {/*------------ Opening balance -----------*/} - - {({ form, field, field: { value }, meta: { error, touched } }) => ( - } + label={} className={classNames( - 'form-group--opening-balance', + 'form-group--select-list', + 'form-group--balance-currency', Classes.FILL, )} - intent={inputIntent({ error, touched })} inline={true} > - - - { - form.setFieldValue('opening_balance', balance); - }} - disabled={vendorId} - /> - + { + form.setFieldValue('currency_code', currency.currency_code); + }} + /> )} + {/*------------ Opening balance -----------*/} + + + + {/*------------ Opening balance at -----------*/} + + {/*------------ Opening branch -----------*/} - - {/*------------ Currency -----------*/} - - {({ form, field: { value }, meta: { error, touched } }) => ( - } - className={classNames( - 'form-group--select-list', - 'form-group--balance-currency', - Classes.FILL, - )} - inline={true} - > - { - form.setFieldValue('currency_code', currency.currency_code); - }} - /> - - )} -
); } + +/** + * Vendor opening balance field. + * @returns {JSX.Element} + */ +function VendorOpeningBalanceField() { + const { vendorId } = useVendorFormContext(); + const { values } = useFormikContext(); + + // Cannot continue if the vendor id is defined. + if (vendorId) return null; + + return ( + } + inline={true} + shouldUpdate={openingBalanceFieldShouldUpdate} + shouldUpdateDeps={{ currencyCode: values.currency_code }} + fastField={true} + > + + + + + + ); +} + +/** + * Vendor opening balance at date field. + * @returns {JSX.Element} + */ +function VendorOpeningBalanceAtField() { + const { vendorId } = useVendorFormContext(); + + // Cannot continue if the vendor id is defined. + if (vendorId) return null; + + return ( + } + inline={true} + helperText={} + > + date.toLocaleDateString()} + parseDate={(str) => new Date(str)} + fill={true} + /> + + ); +} + +/** + * Vendor opening balance exchange rate field if the vendor has foreign currency. + * @returns {JSX.Element} + */ +function VendorOpeningBalanceExchangeRateField() { + const { values } = useFormikContext(); + const { vendorId } = useVendorFormContext(); + const isForeignVendor = useIsVendorForeignCurrency(); + const currentOrganization = useCurrentOrganization(); + + // Cannot continue if the current vendor does not have foreign currency. + if (!isForeignVendor || vendorId) { + return null; + } + return ( + + + + ); +} diff --git a/packages/webapp/src/containers/Vendors/VendorForm/VendorsTabs.tsx b/packages/webapp/src/containers/Vendors/VendorForm/VendorsTabs.tsx index 750d7b6b6d..7870c4000d 100644 --- a/packages/webapp/src/containers/Vendors/VendorForm/VendorsTabs.tsx +++ b/packages/webapp/src/containers/Vendors/VendorForm/VendorsTabs.tsx @@ -6,7 +6,6 @@ import { Tabs, Tab } from '@blueprintjs/core'; import { CLASSES } from '@/constants/classes'; import VendorFinanicalPanelTab from './VendorFinanicalPanelTab'; -import VendorAttahmentTab from './VendorAttahmentTab'; import CustomerAddressTabs from '@/containers/Customers/CustomerForm/CustomerAddressTabs'; import CustomerNotePanel from '@/containers/Customers/CustomerForm/CustomerNotePanel'; @@ -15,7 +14,6 @@ import CustomerNotePanel from '@/containers/Customers/CustomerForm/CustomerNoteP * Vendor form tabs. */ export default function VendorTabs() { - return (
} + panel={} /> } /> - } - />
); diff --git a/packages/webapp/src/containers/Vendors/VendorForm/utils.tsx b/packages/webapp/src/containers/Vendors/VendorForm/utils.tsx index 72ffdb9bcd..5be5627636 100644 --- a/packages/webapp/src/containers/Vendors/VendorForm/utils.tsx +++ b/packages/webapp/src/containers/Vendors/VendorForm/utils.tsx @@ -5,6 +5,7 @@ import { useFormikContext } from 'formik'; import { first } from 'lodash'; import { useVendorFormContext } from './VendorFormProvider'; +import { useCurrentOrganization } from '@/hooks/state'; export const defaultInitialValues = { salutation: '', @@ -36,10 +37,12 @@ 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_branch_id: '', + opening_balance_exchange_rate: '' }; export const useSetPrimaryBranchToForm = () => { @@ -56,3 +59,25 @@ export const useSetPrimaryBranchToForm = () => { } }, [isBranchesSuccess, setFieldValue, branches]); }; + +/** + * Detarmines whether the current vendor has foreign currency. + * @returns {boolean} + */ +export const useIsVendorForeignCurrency = () => { + 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) + ); +}; diff --git a/packages/webapp/src/lang/en/index.json b/packages/webapp/src/lang/en/index.json index 88d354d065..d8d490541b 100644 --- a/packages/webapp/src/lang/en/index.json +++ b/packages/webapp/src/lang/en/index.json @@ -658,7 +658,7 @@ "opening_balance_at": "Opening balance at", "opening_balance": "Opening balance", "balance_currency": "Balance currency", - "financial_details": "Financial details", + "financial_details": "Financial", "are_you_sure_you_want_to_clear_this_transaction": "Are you sure you want to clear this transaction?", "clearing_the_table_lines_will_delete_all_credits": "Clearing the table lines will delete all credits and payment were applied, Is this okay?", "changing_full_amount_will_change_all_credits_and_payment": " Changing full amount will change all credits and payment were applied, Is this okay?", diff --git a/packages/webapp/src/style/pages/Customers/Form.scss b/packages/webapp/src/style/pages/Customers/Form.scss index 6a90e84edf..3d9e1389ff 100644 --- a/packages/webapp/src/style/pages/Customers/Form.scss +++ b/packages/webapp/src/style/pages/Customers/Form.scss @@ -142,15 +142,8 @@ > *:not(:last-child) { margin-right: 25px; } - &.bp3-large > .bp3-tab { font-size: 15px; - color: #555; - - &[aria-selected='true'], - &:not([aria-disabled='true']):hover { - color: $pt-link-color; - } } } }