feat(Sales & Purchases ): add exchange rate input.

This commit is contained in:
elforjani13
2022-02-21 15:25:32 +02:00
parent 914e1de79f
commit 7c9ad8438c
22 changed files with 306 additions and 47 deletions

View File

@@ -6,7 +6,13 @@ import { FastField, ErrorMessage } from 'formik';
import classNames from 'classnames'; import classNames from 'classnames';
import { CLASSES } from 'common/classes'; import { CLASSES } from 'common/classes';
import { VendorSelectField, FieldRequiredHint, Icon } from 'components'; import {
VendorSelectField,
FieldRequiredHint,
Icon,
ExchangeRateInputGroup,
If,
} from 'components';
import { vendorsFieldShouldUpdate } from './utils'; import { vendorsFieldShouldUpdate } from './utils';
import { useBillFormContext } from './BillFormProvider'; import { useBillFormContext } from './BillFormProvider';
@@ -24,7 +30,7 @@ import {
*/ */
function BillFormHeader() { function BillFormHeader() {
// Bill form context. // Bill form context.
const { vendors } = useBillFormContext(); const { vendors, isForeignVendor, setSelectVendor } = useBillFormContext();
return ( return (
<div className={classNames(CLASSES.PAGE_FORM_HEADER_FIELDS)}> <div className={classNames(CLASSES.PAGE_FORM_HEADER_FIELDS)}>
@@ -49,6 +55,7 @@ function BillFormHeader() {
defaultSelectText={<T id={'select_vender_account'} />} defaultSelectText={<T id={'select_vender_account'} />}
onContactSelected={(contact) => { onContactSelected={(contact) => {
form.setFieldValue('vendor_id', contact.id); form.setFieldValue('vendor_id', contact.id);
setSelectVendor(contact);
}} }}
popoverFill={true} popoverFill={true}
allowCreate={true} allowCreate={true}
@@ -57,6 +64,16 @@ function BillFormHeader() {
)} )}
</FastField> </FastField>
{/* ----------- Exchange rate ----------- */}
<If condition={isForeignVendor}>
<ExchangeRateInputGroup
fromCurrency={'USD'}
toCurrency={'LYD'}
name={'exchange_rate'}
formGroupProps={{ label: ' ', inline: true }}
/>
</If>
{/* ------- Bill date ------- */} {/* ------- Bill date ------- */}
<FastField name={'bill_date'}> <FastField name={'bill_date'}>
{({ form, field: { value }, meta: { error, touched } }) => ( {({ form, field: { value }, meta: { error, touched } }) => (

View File

@@ -4,15 +4,22 @@ import { useParams } from 'react-router-dom';
import BillForm from './BillForm'; import BillForm from './BillForm';
import { BillFormProvider } from './BillFormProvider'; import { BillFormProvider } from './BillFormProvider';
import withCurrentOrganization from 'containers/Organization/withCurrentOrganization';
import { compose } from 'utils';
import 'style/pages/Bills/PageForm.scss'; import 'style/pages/Bills/PageForm.scss';
export default function BillFormPage() { function BillFormPage({
// #withCurrentOrganization
organization: { base_currency },
}) {
const { id } = useParams(); const { id } = useParams();
const billId = parseInt(id, 10); const billId = parseInt(id, 10);
return ( return (
<BillFormProvider billId={billId}> <BillFormProvider billId={billId} baseCurrency={base_currency}>
<BillForm /> <BillForm />
</BillFormProvider> </BillFormProvider>
); );
} }
export default compose(withCurrentOrganization())(BillFormPage);

View File

@@ -1,4 +1,6 @@
import React, { createContext, useState } from 'react'; import React, { createContext, useState } from 'react';
import {isEqual, isUndefined } from 'lodash';
import DashboardInsider from 'components/Dashboard/DashboardInsider'; import DashboardInsider from 'components/Dashboard/DashboardInsider';
import { import {
useAccounts, useAccounts,
@@ -35,7 +37,7 @@ const stringifiedFilterRoles = JSON.stringify([
/** /**
* Bill form provider. * Bill form provider.
*/ */
function BillFormProvider({ billId, ...props }) { function BillFormProvider({ billId, baseCurrency, ...props }) {
// Handle fetch accounts. // Handle fetch accounts.
const { data: accounts, isLoading: isAccountsLoading } = useAccounts(); const { data: accounts, isLoading: isAccountsLoading } = useAccounts();
@@ -78,6 +80,7 @@ function BillFormProvider({ billId, ...props }) {
// Form submit payload. // Form submit payload.
const [submitPayload, setSubmitPayload] = useState({}); const [submitPayload, setSubmitPayload] = useState({});
const [selectVendor, setSelectVendor] = React.useState(null);
// Create and edit bills mutations. // Create and edit bills mutations.
const { mutateAsync: createBillMutate } = useCreateBill(); const { mutateAsync: createBillMutate } = useCreateBill();
@@ -88,6 +91,11 @@ function BillFormProvider({ billId, ...props }) {
// Determines whether the warehouse and branches are loading. // Determines whether the warehouse and branches are loading.
const isFeatureLoading = isWarehouesLoading || isBranchesLoading; const isFeatureLoading = isWarehouesLoading || isBranchesLoading;
// Determines whether the foreign vendor.
const isForeignVendor =
!isEqual(selectVendor?.currency_code, baseCurrency) &&
!isUndefined(selectVendor?.currency_code);
const provider = { const provider = {
accounts, accounts,
vendors, vendors,
@@ -95,6 +103,9 @@ function BillFormProvider({ billId, ...props }) {
bill, bill,
warehouses, warehouses,
branches, branches,
baseCurrency,
selectVendor,
setSelectVendor,
submitPayload, submitPayload,
isNewMode, isNewMode,
@@ -106,6 +117,7 @@ function BillFormProvider({ billId, ...props }) {
isFeatureLoading, isFeatureLoading,
isBranchesSuccess, isBranchesSuccess,
isWarehousesSuccess, isWarehousesSuccess,
isForeignVendor,
createBillMutate, createBillMutate,
editBillMutate, editBillMutate,

View File

@@ -13,7 +13,9 @@ import {
VendorSelectField, VendorSelectField,
FieldRequiredHint, FieldRequiredHint,
InputPrependButton, InputPrependButton,
ExchangeRateInputGroup,
Icon, Icon,
If,
FormattedMessage as T, FormattedMessage as T,
} from 'components'; } from 'components';
import { import {
@@ -47,7 +49,8 @@ function VendorCreditNoteFormHeaderFields({
vendorcreditNextNumber, vendorcreditNextNumber,
}) { }) {
// Vendor Credit form context. // Vendor Credit form context.
const { vendors } = useVendorCreditNoteFormContext(); const { vendors, isForeignVendor, setSelectVendor } =
useVendorCreditNoteFormContext();
// Handle vendor credit number changing. // Handle vendor credit number changing.
const handleVendorCreditNumberChange = () => { const handleVendorCreditNumberChange = () => {
@@ -96,6 +99,7 @@ function VendorCreditNoteFormHeaderFields({
defaultSelectText={<T id={'select_vender_account'} />} defaultSelectText={<T id={'select_vender_account'} />}
onContactSelected={(contact) => { onContactSelected={(contact) => {
form.setFieldValue('vendor_id', contact.id); form.setFieldValue('vendor_id', contact.id);
setSelectVendor(contact);
}} }}
popoverFill={true} popoverFill={true}
allowCreate={true} allowCreate={true}
@@ -104,6 +108,16 @@ function VendorCreditNoteFormHeaderFields({
)} )}
</FastField> </FastField>
{/* ----------- Exchange rate ----------- */}
<If condition={isForeignVendor}>
<ExchangeRateInputGroup
fromCurrency={'USD'}
toCurrency={'LYD'}
name={'exchange_rate'}
formGroupProps={{ label: ' ', inline: true }}
/>
</If>
{/* ------- Vendor Credit date ------- */} {/* ------- Vendor Credit date ------- */}
<FastField name={'vendor_credit_date'}> <FastField name={'vendor_credit_date'}>
{({ form, field: { value }, meta: { error, touched } }) => ( {({ form, field: { value }, meta: { error, touched } }) => (

View File

@@ -6,16 +6,26 @@ import '../../../../style/pages/VendorsCreditNote/PageForm.scss';
import VendorCreditNoteForm from './VendorCreditNoteForm'; import VendorCreditNoteForm from './VendorCreditNoteForm';
import { VendorCreditNoteFormProvider } from './VendorCreditNoteFormProvider'; import { VendorCreditNoteFormProvider } from './VendorCreditNoteFormProvider';
import withCurrentOrganization from 'containers/Organization/withCurrentOrganization';
import { compose } from 'utils';
/** /**
* Vendor Credit note form pages. * Vendor Credit note form pages.
*/ */
export default function VendorCreditNoteFormPage() { function VendorCreditNoteFormPage({
// #withCurrentOrganization
organization: { base_currency },
}) {
const { id } = useParams(); const { id } = useParams();
const idAsInteger = parseInt(id, 10); const idAsInteger = parseInt(id, 10);
return ( return (
<VendorCreditNoteFormProvider vendorCreditId={idAsInteger}> <VendorCreditNoteFormProvider
vendorCreditId={idAsInteger}
baseCurrency={base_currency}
>
<VendorCreditNoteForm /> <VendorCreditNoteForm />
</VendorCreditNoteFormProvider> </VendorCreditNoteFormProvider>
); );
} }
export default compose(withCurrentOrganization())(VendorCreditNoteFormPage);

View File

@@ -1,6 +1,6 @@
import React from 'react'; import React from 'react';
import { useLocation } from 'react-router-dom'; import { useLocation } from 'react-router-dom';
import { isEmpty, pick } from 'lodash'; import { isEmpty, pick, isEqual, isUndefined } from 'lodash';
import DashboardInsider from 'components/Dashboard/DashboardInsider'; import DashboardInsider from 'components/Dashboard/DashboardInsider';
import { transformToEditForm } from './utils'; import { transformToEditForm } from './utils';
import { import {
@@ -20,7 +20,11 @@ const VendorCreditNoteFormContext = React.createContext();
/** /**
* Vendor Credit note data provider. * Vendor Credit note data provider.
*/ */
function VendorCreditNoteFormProvider({ vendorCreditId, ...props }) { function VendorCreditNoteFormProvider({
vendorCreditId,
baseCurrency,
...props
}) {
const { state } = useLocation(); const { state } = useLocation();
const billId = state?.billId; const billId = state?.billId;
@@ -69,6 +73,7 @@ function VendorCreditNoteFormProvider({ vendorCreditId, ...props }) {
// Form submit payload. // Form submit payload.
const [submitPayload, setSubmitPayload] = React.useState(); const [submitPayload, setSubmitPayload] = React.useState();
const [selectVendor, setSelectVendor] = React.useState(null);
// Create and edit vendor credit mutations. // Create and edit vendor credit mutations.
const { mutateAsync: createVendorCreditMutate } = useCreateVendorCredit(); const { mutateAsync: createVendorCreditMutate } = useCreateVendorCredit();
@@ -80,6 +85,11 @@ function VendorCreditNoteFormProvider({ vendorCreditId, ...props }) {
// Determines whether the warehouse and branches are loading. // Determines whether the warehouse and branches are loading.
const isFeatureLoading = isWarehouesLoading || isBranchesLoading; const isFeatureLoading = isWarehouesLoading || isBranchesLoading;
// Determines whether the foreign vendor.
const isForeignVendor =
!isEqual(selectVendor?.currency_code, baseCurrency) &&
!isUndefined(selectVendor?.currency_code);
const newVendorCredit = !isEmpty(bill) const newVendorCredit = !isEmpty(bill)
? transformToEditForm({ ? transformToEditForm({
...pick(bill, ['vendor_id', 'entries']), ...pick(bill, ['vendor_id', 'entries']),
@@ -93,6 +103,9 @@ function VendorCreditNoteFormProvider({ vendorCreditId, ...props }) {
vendorCredit, vendorCredit,
warehouses, warehouses,
branches, branches,
baseCurrency,
selectVendor,
setSelectVendor,
submitPayload, submitPayload,
isNewMode, isNewMode,
newVendorCredit, newVendorCredit,
@@ -101,7 +114,8 @@ function VendorCreditNoteFormProvider({ vendorCreditId, ...props }) {
isFeatureLoading, isFeatureLoading,
isBranchesSuccess, isBranchesSuccess,
isWarehousesSuccess, isWarehousesSuccess,
isForeignVendor,
createVendorCreditMutate, createVendorCreditMutate,
editVendorCreditMutate, editVendorCreditMutate,
setSubmitPayload, setSubmitPayload,

View File

@@ -20,8 +20,10 @@ import {
InputPrependText, InputPrependText,
Money, Money,
Hint, Hint,
If,
Icon, Icon,
MoneyInputGroup, MoneyInputGroup,
ExchangeRateInputGroup,
} from 'components'; } from 'components';
import withCurrentOrganization from 'containers/Organization/withCurrentOrganization'; import withCurrentOrganization from 'containers/Organization/withCurrentOrganization';
import { usePaymentMadeFormContext } from './PaymentMadeFormProvider'; import { usePaymentMadeFormContext } from './PaymentMadeFormProvider';
@@ -49,8 +51,14 @@ function PaymentMadeFormHeaderFields({ organization: { base_currency } }) {
} = useFormikContext(); } = useFormikContext();
// Payment made form context. // Payment made form context.
const { vendors, accounts, isNewMode, setPaymentVendorId } = const {
usePaymentMadeFormContext(); vendors,
accounts,
isNewMode,
setPaymentVendorId,
isForeignVendor,
setSelectVendor,
} = usePaymentMadeFormContext();
// Sumation of payable full-amount. // Sumation of payable full-amount.
const payableFullAmount = useMemo( const payableFullAmount = useMemo(
@@ -97,6 +105,7 @@ function PaymentMadeFormHeaderFields({ organization: { base_currency } }) {
onContactSelected={(contact) => { onContactSelected={(contact) => {
form.setFieldValue('vendor_id', contact.id); form.setFieldValue('vendor_id', contact.id);
setPaymentVendorId(contact.id); setPaymentVendorId(contact.id);
setSelectVendor(contact);
}} }}
disabled={!isNewMode} disabled={!isNewMode}
popoverFill={true} popoverFill={true}
@@ -106,6 +115,16 @@ function PaymentMadeFormHeaderFields({ organization: { base_currency } }) {
)} )}
</FastField> </FastField>
{/* ----------- Exchange rate ----------- */}
<If condition={isForeignVendor}>
<ExchangeRateInputGroup
fromCurrency={'USD'}
toCurrency={'LYD'}
name={'exchange_rate'}
formGroupProps={{ label: ' ', inline: true }}
/>
</If>
{/* ------------ Payment date ------------ */} {/* ------------ Payment date ------------ */}
<FastField name={'payment_date'}> <FastField name={'payment_date'}>
{({ form, field: { value }, meta: { error, touched } }) => ( {({ form, field: { value }, meta: { error, touched } }) => (

View File

@@ -4,17 +4,27 @@ import { useParams } from 'react-router-dom';
import PaymentMadeForm from './PaymentMadeForm'; import PaymentMadeForm from './PaymentMadeForm';
import { PaymentMadeFormProvider } from './PaymentMadeFormProvider'; import { PaymentMadeFormProvider } from './PaymentMadeFormProvider';
import 'style/pages/PaymentMade/PageForm.scss' import 'style/pages/PaymentMade/PageForm.scss';
import withCurrentOrganization from 'containers/Organization/withCurrentOrganization';
import { compose } from 'utils';
/** /**
* Payment made - Page form. * Payment made - Page form.
*/ */
export default function PaymentMadeFormPage() { function PaymentMadeFormPage({
// #withCurrentOrganization
organization: { base_currency },
}) {
const { id: paymentMadeId } = useParams(); const { id: paymentMadeId } = useParams();
return ( return (
<PaymentMadeFormProvider paymentMadeId={paymentMadeId}> <PaymentMadeFormProvider
<PaymentMadeForm /> paymentMadeId={paymentMadeId}
baseCurrency={base_currency}
>
<PaymentMadeForm />
</PaymentMadeFormProvider> </PaymentMadeFormProvider>
); );
} }
export default compose(withCurrentOrganization())(PaymentMadeFormPage);

View File

@@ -1,4 +1,5 @@
import React, { createContext, useContext } from 'react'; import React, { createContext, useContext } from 'react';
import { isEqual, isUndefined } from 'lodash';
import { import {
useAccounts, useAccounts,
useVendors, useVendors,
@@ -17,9 +18,10 @@ const PaymentMadeFormContext = createContext();
/** /**
* Payment made form provider. * Payment made form provider.
*/ */
function PaymentMadeFormProvider({ paymentMadeId, ...props }) { function PaymentMadeFormProvider({ paymentMadeId, baseCurrency, ...props }) {
const [submitPayload, setSubmitPayload] = React.useState({}); const [submitPayload, setSubmitPayload] = React.useState({});
const [paymentVendorId, setPaymentVendorId] = React.useState(null); const [paymentVendorId, setPaymentVendorId] = React.useState(null);
const [selectVendor, setSelectVendor] = React.useState(null);
// Handle fetch accounts data. // Handle fetch accounts data.
const { data: accounts, isLoading: isAccountsLoading } = useAccounts(); const { data: accounts, isLoading: isAccountsLoading } = useAccounts();
@@ -64,6 +66,11 @@ function PaymentMadeFormProvider({ paymentMadeId, ...props }) {
const isFeatureLoading = isBranchesLoading; const isFeatureLoading = isBranchesLoading;
// Determines whether the foreign vendor.
const isForeignVendor =
!isEqual(selectVendor?.currency_code, baseCurrency) &&
!isUndefined(selectVendor?.currency_code);
// Provider payload. // Provider payload.
const provider = { const provider = {
paymentMadeId, paymentMadeId,
@@ -74,6 +81,9 @@ function PaymentMadeFormProvider({ paymentMadeId, ...props }) {
items, items,
branches, branches,
submitPayload, submitPayload,
baseCurrency,
selectVendor,
setSelectVendor,
paymentVendorId, paymentVendorId,
isNewMode, isNewMode,
@@ -85,6 +95,7 @@ function PaymentMadeFormProvider({ paymentMadeId, ...props }) {
isPaymentLoading, isPaymentLoading,
isFeatureLoading, isFeatureLoading,
isBranchesSuccess, isBranchesSuccess,
isForeignVendor,
createPaymentMadeMutate, createPaymentMadeMutate,
editPaymentMadeMutate, editPaymentMadeMutate,

View File

@@ -14,7 +14,9 @@ import {
FieldRequiredHint, FieldRequiredHint,
InputPrependButton, InputPrependButton,
Icon, Icon,
If,
FormattedMessage as T, FormattedMessage as T,
ExchangeRateInputGroup,
} from 'components'; } from 'components';
import { import {
customerNameFieldShouldUpdate, customerNameFieldShouldUpdate,
@@ -46,7 +48,8 @@ function CreditNoteFormHeaderFields({
creditNextNumber, creditNextNumber,
}) { }) {
// Credit note form context. // Credit note form context.
const { customers } = useCreditNoteFormContext(); const { customers, isForeignCustomer, baseCurrency, setSelectCustomer } =
useCreditNoteFormContext();
// Handle credit number changing. // Handle credit number changing.
const handleCreditNumberChange = () => { const handleCreditNumberChange = () => {
@@ -97,6 +100,7 @@ function CreditNoteFormHeaderFields({
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}
@@ -104,6 +108,17 @@ function CreditNoteFormHeaderFields({
</FormGroup> </FormGroup>
)} )}
</FastField> </FastField>
{/* ----------- Exchange rate ----------- */}
<If condition={isForeignCustomer}>
<ExchangeRateInputGroup
fromCurrency={'USD'}
toCurrency={'LYD'}
name={'exchange_rate'}
formGroupProps={{ label: ' ', inline: true }}
/>
</If>
{/* ----------- Credit note date ----------- */} {/* ----------- Credit note date ----------- */}
<FastField name={'credit_note_date'}> <FastField name={'credit_note_date'}>
{({ form, field: { value }, meta: { error, touched } }) => ( {({ form, field: { value }, meta: { error, touched } }) => (

View File

@@ -5,17 +5,27 @@ import '../../../../style/pages/CreditNote/PageForm.scss';
import CreditNoteForm from './CreditNoteForm'; import CreditNoteForm from './CreditNoteForm';
import { CreditNoteFormProvider } from './CreditNoteFormProvider'; import { CreditNoteFormProvider } from './CreditNoteFormProvider';
import withCurrentOrganization from 'containers/Organization/withCurrentOrganization';
import { compose } from 'utils';
/** /**
* Credit note form page. * Credit note form page.
*/ */
export default function CreditNoteFormPage() { function CreditNoteFormPage({
// #withCurrentOrganization
organization: { base_currency },
}) {
const { id } = useParams(); const { id } = useParams();
const idAsInteger = parseInt(id, 10); const idAsInteger = parseInt(id, 10);
return ( return (
<CreditNoteFormProvider creditNoteId={idAsInteger}> <CreditNoteFormProvider
creditNoteId={idAsInteger}
baseCurrency={base_currency}
>
<CreditNoteForm /> <CreditNoteForm />
</CreditNoteFormProvider> </CreditNoteFormProvider>
); );
} }
export default compose(withCurrentOrganization())(CreditNoteFormPage);

View File

@@ -1,6 +1,6 @@
import React from 'react'; import React from 'react';
import { useLocation } from 'react-router-dom'; import { useLocation } from 'react-router-dom';
import { isEmpty, pick } from 'lodash'; import { isEmpty, pick, isEqual, isUndefined } from 'lodash';
import DashboardInsider from 'components/Dashboard/DashboardInsider'; import DashboardInsider from 'components/Dashboard/DashboardInsider';
import { transformToEditForm } from './utils'; import { transformToEditForm } from './utils';
@@ -21,7 +21,7 @@ const CreditNoteFormContext = React.createContext();
/** /**
* Credit note data provider. * Credit note data provider.
*/ */
function CreditNoteFormProvider({ creditNoteId, ...props }) { function CreditNoteFormProvider({ creditNoteId, baseCurrency, ...props }) {
const { state } = useLocation(); const { state } = useLocation();
const invoiceId = state?.invoiceId; const invoiceId = state?.invoiceId;
@@ -75,6 +75,8 @@ function CreditNoteFormProvider({ creditNoteId, ...props }) {
// Form submit payload. // Form submit payload.
const [submitPayload, setSubmitPayload] = React.useState(); const [submitPayload, setSubmitPayload] = React.useState();
const [selectCustomer, setSelectCustomer] = React.useState(null);
// Determines whether the form in new mode. // Determines whether the form in new mode.
const isNewMode = !creditNoteId; const isNewMode = !creditNoteId;
@@ -87,6 +89,11 @@ function CreditNoteFormProvider({ creditNoteId, ...props }) {
}) })
: []; : [];
// Determines whether the foreign customer.
const isForeignCustomer =
!isEqual(selectCustomer?.currency_code, baseCurrency) &&
!isUndefined(selectCustomer?.currency_code);
// Provider payload. // Provider payload.
const provider = { const provider = {
items, items,
@@ -95,15 +102,19 @@ function CreditNoteFormProvider({ creditNoteId, ...props }) {
branches, branches,
warehouses, warehouses,
submitPayload, submitPayload,
baseCurrency,
selectCustomer,
setSelectCustomer,
isNewMode, isNewMode,
newCreditNote, newCreditNote,
isForeignCustomer,
isItemsLoading, isItemsLoading,
isCustomersLoading, isCustomersLoading,
isFeatureLoading, isFeatureLoading,
isBranchesSuccess, isBranchesSuccess,
isWarehousesSuccess, isWarehousesSuccess,
createCreditNoteMutate, createCreditNoteMutate,
editCreditNoteMutate, editCreditNoteMutate,
setSubmitPayload, setSubmitPayload,

View File

@@ -21,8 +21,10 @@ import { CLASSES } from 'common/classes';
import { import {
CustomerSelectField, CustomerSelectField,
FieldRequiredHint, FieldRequiredHint,
If,
Icon, Icon,
InputPrependButton, InputPrependButton,
ExchangeRateInputGroup,
} from 'components'; } from 'components';
import withDialogActions from 'containers/Dialog/withDialogActions'; import withDialogActions from 'containers/Dialog/withDialogActions';
@@ -43,7 +45,8 @@ function EstimateFormHeader({
estimateNumberPrefix, estimateNumberPrefix,
estimateNextNumber, estimateNextNumber,
}) { }) {
const { customers } = useEstimateFormContext(); const { customers, isForeignCustomer, baseCurrency, setSelectCustomer } =
useEstimateFormContext();
const handleEstimateNumberBtnClick = () => { const handleEstimateNumberBtnClick = () => {
openDialog('estimate-number-form', {}); openDialog('estimate-number-form', {});
@@ -88,6 +91,7 @@ function EstimateFormHeader({
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}
intent={inputIntent({ error, touched })} intent={inputIntent({ error, touched })}
@@ -97,6 +101,16 @@ function EstimateFormHeader({
)} )}
</FastField> </FastField>
{/* ----------- Exchange rate ----------- */}
<If condition={isForeignCustomer}>
<ExchangeRateInputGroup
fromCurrency={'USD'}
toCurrency={'LYD'}
name={'exchange_rate'}
formGroupProps={{ label: ' ', inline: true }}
/>
</If>
{/* ----------- Estimate date ----------- */} {/* ----------- Estimate date ----------- */}
<FastField name={'estimate_date'}> <FastField name={'estimate_date'}>
{({ form, field: { value }, meta: { error, touched } }) => ( {({ form, field: { value }, meta: { error, touched } }) => (

View File

@@ -1,21 +1,27 @@
import React from 'react'; import React from 'react';
import { useParams } from 'react-router-dom'; import { useParams } from 'react-router-dom';
import 'style/pages/SaleEstimate/PageForm.scss'; import 'style/pages/SaleEstimate/PageForm.scss';
import EstimateForm from './EstimateForm'; import EstimateForm from './EstimateForm';
import { EstimateFormProvider } from './EstimateFormProvider'; import { EstimateFormProvider } from './EstimateFormProvider';
import withCurrentOrganization from 'containers/Organization/withCurrentOrganization';
import { compose } from 'utils';
/** /**
* Estimate form page. * Estimate form page.
*/ */
export default function EstimateFormPage() { function EstimateFormPage({
// #withCurrentOrganization
organization: { base_currency },
}) {
const { id } = useParams(); const { id } = useParams();
const idInteger = parseInt(id, 10); const idInteger = parseInt(id, 10);
return ( return (
<EstimateFormProvider estimateId={idInteger}> <EstimateFormProvider estimateId={idInteger} baseCurrency={base_currency}>
<EstimateForm /> <EstimateForm />
</EstimateFormProvider> </EstimateFormProvider>
); );
} }
export default compose(withCurrentOrganization())(EstimateFormPage);

View File

@@ -1,4 +1,6 @@
import React, { createContext, useContext } from 'react'; import React, { createContext, useContext } from 'react';
import { isEqual, isUndefined } from 'lodash';
import DashboardInsider from 'components/Dashboard/DashboardInsider'; import DashboardInsider from 'components/Dashboard/DashboardInsider';
import { import {
useEstimate, useEstimate,
@@ -17,7 +19,7 @@ const EstimateFormContext = createContext();
/** /**
* Estimate form provider. * Estimate form provider.
*/ */
function EstimateFormProvider({ estimateId, ...props }) { function EstimateFormProvider({ estimateId, baseCurrency, ...props }) {
const { const {
data: estimate, data: estimate,
isFetching: isEstimateFetching, isFetching: isEstimateFetching,
@@ -60,6 +62,7 @@ function EstimateFormProvider({ estimateId, ...props }) {
// Form submit payload. // Form submit payload.
const [submitPayload, setSubmitPayload] = React.useState({}); const [submitPayload, setSubmitPayload] = React.useState({});
const [selectCustomer, setSelectCustomer] = React.useState(null);
// Create and edit estimate form. // Create and edit estimate form.
const { mutateAsync: createEstimateMutate } = useCreateEstimate(); const { mutateAsync: createEstimateMutate } = useCreateEstimate();
@@ -70,6 +73,11 @@ function EstimateFormProvider({ estimateId, ...props }) {
// Determines whether the warehouse and branches are loading. // Determines whether the warehouse and branches are loading.
const isFeatureLoading = isWarehouesLoading || isBranchesLoading; const isFeatureLoading = isWarehouesLoading || isBranchesLoading;
// Determines whether the foreign customer.
const isForeignCustomer =
!isEqual(selectCustomer?.currency_code, baseCurrency) &&
!isUndefined(selectCustomer?.currency_code);
// Provider payload. // Provider payload.
const provider = { const provider = {
estimateId, estimateId,
@@ -89,9 +97,13 @@ function EstimateFormProvider({ estimateId, ...props }) {
isFeatureLoading, isFeatureLoading,
isBranchesSuccess, isBranchesSuccess,
isWarehousesSuccess, isWarehousesSuccess,
isForeignCustomer,
submitPayload, submitPayload,
setSubmitPayload, setSubmitPayload,
selectCustomer,
setSelectCustomer,
baseCurrency,
createEstimateMutate, createEstimateMutate,
editEstimateMutate, editEstimateMutate,
}; };

View File

@@ -3,17 +3,25 @@ import { useParams } from 'react-router-dom';
import { PaymentReceiveFormProvider } from './PaymentReceiveFormProvider'; import { PaymentReceiveFormProvider } from './PaymentReceiveFormProvider';
import PaymentReceiveForm from './PaymentReceiveForm'; import PaymentReceiveForm from './PaymentReceiveForm';
import withCurrentOrganization from 'containers/Organization/withCurrentOrganization';
import { compose } from 'utils';
/** /**
* Payment receive form page. * Payment receive form page.
*/ */
export default function PaymentReceiveFormPage() { function PaymentReceiveFormPage({
// #withCurrentOrganization
organization: { base_currency },
}) {
const { id: paymentReceiveId } = useParams(); const { id: paymentReceiveId } = useParams();
const paymentReceiveIdInt = parseInt(paymentReceiveId, 10); const paymentReceiveIdInt = parseInt(paymentReceiveId, 10);
return ( return (
<PaymentReceiveFormProvider paymentReceiveId={paymentReceiveIdInt}> <PaymentReceiveFormProvider
paymentReceiveId={paymentReceiveIdInt}
baseCurrency={base_currency}
>
<PaymentReceiveForm paymentReceiveId={paymentReceiveIdInt} /> <PaymentReceiveForm paymentReceiveId={paymentReceiveIdInt} />
</PaymentReceiveFormProvider> </PaymentReceiveFormProvider>
); );
} }
export default compose(withCurrentOrganization())(PaymentReceiveFormPage);

View File

@@ -1,4 +1,6 @@
import React, { createContext, useContext } from 'react'; import React, { createContext, useContext } from 'react';
import { isEmpty, pick, isEqual, isUndefined } from 'lodash';
import { DashboardInsider } from 'components'; import { DashboardInsider } from 'components';
import { import {
useSettingsPaymentReceives, useSettingsPaymentReceives,
@@ -16,10 +18,16 @@ const PaymentReceiveFormContext = createContext();
/** /**
* Payment receive form provider. * Payment receive form provider.
*/ */
function PaymentReceiveFormProvider({ paymentReceiveId, ...props }) { function PaymentReceiveFormProvider({
paymentReceiveId,
baseCurrency,
...props
}) {
// Form state. // Form state.
const [submitPayload, setSubmitPayload] = React.useState({}); const [submitPayload, setSubmitPayload] = React.useState({});
const [selectCustomer, setSelectCustomer] = React.useState(null);
// Fetches payment recevie details. // Fetches payment recevie details.
const { const {
data: { data: {
@@ -59,6 +67,11 @@ function PaymentReceiveFormProvider({ paymentReceiveId, ...props }) {
const { mutateAsync: editPaymentReceiveMutate } = useEditPaymentReceive(); const { mutateAsync: editPaymentReceiveMutate } = useEditPaymentReceive();
const { mutateAsync: createPaymentReceiveMutate } = useCreatePaymentReceive(); const { mutateAsync: createPaymentReceiveMutate } = useCreatePaymentReceive();
// Determines whether the foreign customer.
const isForeignCustomer =
!isEqual(selectCustomer?.currency_code, baseCurrency) &&
!isUndefined(selectCustomer?.currency_code);
// Provider payload. // Provider payload.
const provider = { const provider = {
paymentReceiveId, paymentReceiveId,
@@ -67,6 +80,7 @@ function PaymentReceiveFormProvider({ paymentReceiveId, ...props }) {
accounts, accounts,
customers, customers,
branches, branches,
baseCurrency,
isPaymentLoading, isPaymentLoading,
isAccountsLoading, isAccountsLoading,
@@ -74,10 +88,13 @@ function PaymentReceiveFormProvider({ paymentReceiveId, ...props }) {
isCustomersLoading, isCustomersLoading,
isFeatureLoading, isFeatureLoading,
isBranchesSuccess, isBranchesSuccess,
isForeignCustomer,
isNewMode, isNewMode,
submitPayload, submitPayload,
setSubmitPayload, setSubmitPayload,
selectCustomer,
setSelectCustomer,
editPaymentReceiveMutate, editPaymentReceiveMutate,
createPaymentReceiveMutate, createPaymentReceiveMutate,

View File

@@ -7,7 +7,7 @@ import {
Button, Button,
} from '@blueprintjs/core'; } from '@blueprintjs/core';
import { DateInput } from '@blueprintjs/datetime'; import { DateInput } from '@blueprintjs/datetime';
import { FormattedMessage as T } from 'components'; import { FormattedMessage as T, If } from 'components';
import { FastField, Field, useFormikContext, ErrorMessage } from 'formik'; import { FastField, Field, useFormikContext, ErrorMessage } from 'formik';
import { useAutofocus } from 'hooks'; import { useAutofocus } from 'hooks';
@@ -29,6 +29,7 @@ import {
InputPrependButton, InputPrependButton,
MoneyInputGroup, MoneyInputGroup,
InputPrependText, InputPrependText,
ExchangeRateInputGroup,
Hint, Hint,
Money, Money,
} from 'components'; } from 'components';
@@ -64,7 +65,14 @@ function PaymentReceiveHeaderFields({
paymentReceiveNextNumber, paymentReceiveNextNumber,
}) { }) {
// Payment receive form context. // Payment receive form context.
const { customers, accounts, isNewMode } = usePaymentReceiveFormContext(); const {
customers,
accounts,
isNewMode,
isForeignCustomer,
baseCurrency,
setSelectCustomer,
} = usePaymentReceiveFormContext();
// Formik form context. // Formik form context.
const { const {
@@ -141,6 +149,7 @@ function PaymentReceiveHeaderFields({
onContactSelected={(customer) => { onContactSelected={(customer) => {
form.setFieldValue('customer_id', customer.id); form.setFieldValue('customer_id', customer.id);
form.setFieldValue('full_amount', ''); form.setFieldValue('full_amount', '');
setSelectCustomer(customer);
}} }}
popoverFill={true} popoverFill={true}
disabled={!isNewMode} disabled={!isNewMode}
@@ -153,6 +162,16 @@ function PaymentReceiveHeaderFields({
)} )}
</FastField> </FastField>
{/* ----------- Exchange rate ----------- */}
<If condition={isForeignCustomer}>
<ExchangeRateInputGroup
fromCurrency={'USD'}
toCurrency={'LYD'}
name={'exchange_rate'}
formGroupProps={{ label: ' ', inline: true }}
/>
</If>
{/* ------------- Payment date ------------- */} {/* ------------- Payment date ------------- */}
<FastField name={'payment_date'}> <FastField name={'payment_date'}>
{({ form, field: { value }, meta: { error, touched } }) => ( {({ form, field: { value }, meta: { error, touched } }) => (

View File

@@ -15,7 +15,9 @@ import {
CustomerSelectField, CustomerSelectField,
FieldRequiredHint, FieldRequiredHint,
Icon, Icon,
If,
InputPrependButton, InputPrependButton,
ExchangeRateInputGroup,
} from 'components'; } from 'components';
import withSettings from 'containers/Settings/withSettings'; import withSettings from 'containers/Settings/withSettings';
import withDialogActions from 'containers/Dialog/withDialogActions'; import withDialogActions from 'containers/Dialog/withDialogActions';
@@ -49,7 +51,8 @@ function ReceiptFormHeader({
receiptNextNumber, receiptNextNumber,
receiptNumberPrefix, receiptNumberPrefix,
}) { }) {
const { accounts, customers } = useReceiptFormContext(); const { accounts, customers, isForeignCustomer, setSelectCustomer } =
useReceiptFormContext();
const handleReceiptNumberChange = useCallback(() => { const handleReceiptNumberChange = useCallback(() => {
openDialog('receipt-number-form', {}); openDialog('receipt-number-form', {});
@@ -92,8 +95,9 @@ function ReceiptFormHeader({
contacts={customers} contacts={customers}
selectedContactId={value} selectedContactId={value}
defaultSelectText={<T id={'select_customer_account'} />} defaultSelectText={<T id={'select_customer_account'} />}
onContactSelected={(contact) => { onContactSelected={(customer) => {
form.setFieldValue('customer_id', contact.id); form.setFieldValue('customer_id', customer.id);
setSelectCustomer(customer);
}} }}
popoverFill={true} popoverFill={true}
allowCreate={true} allowCreate={true}
@@ -102,6 +106,16 @@ function ReceiptFormHeader({
)} )}
</FastField> </FastField>
{/* ----------- Exchange rate ----------- */}
<If condition={isForeignCustomer}>
<ExchangeRateInputGroup
fromCurrency={'USD'}
toCurrency={'LYD'}
name={'exchange_rate'}
formGroupProps={{ label: ' ', inline: true }}
/>
</If>
{/* ----------- Deposit account ----------- */} {/* ----------- Deposit account ----------- */}
<FastField <FastField
name={'deposit_account_id'} name={'deposit_account_id'}

View File

@@ -4,18 +4,25 @@ import { useParams } from 'react-router-dom';
import 'style/pages/SaleReceipt/PageForm.scss'; import 'style/pages/SaleReceipt/PageForm.scss';
import ReceiptFrom from './ReceiptForm'; import ReceiptFrom from './ReceiptForm';
import withCurrentOrganization from 'containers/Organization/withCurrentOrganization';
import { ReceiptFormProvider } from './ReceiptFormProvider'; import { ReceiptFormProvider } from './ReceiptFormProvider';
import { compose } from 'utils';
/** /**
* Receipt form page. * Receipt form page.
*/ */
export default function ReceiptFormPage() { function ReceiptFormPage({
// #withCurrentOrganization
organization: { base_currency },
}) {
const { id } = useParams(); const { id } = useParams();
const idInt = parseInt(id, 10); const idInt = parseInt(id, 10);
return ( return (
<ReceiptFormProvider receiptId={idInt}> <ReceiptFormProvider receiptId={idInt} baseCurrency={base_currency}>
<ReceiptFrom /> <ReceiptFrom />
</ReceiptFormProvider> </ReceiptFormProvider>
); );
} }
export default compose(withCurrentOrganization())(ReceiptFormPage);

View File

@@ -1,4 +1,6 @@
import React, { createContext, useState } from 'react'; import React, { createContext, useState } from 'react';
import { isEmpty, pick, isEqual, isUndefined } from 'lodash';
import DashboardInsider from 'components/Dashboard/DashboardInsider'; import DashboardInsider from 'components/Dashboard/DashboardInsider';
import { import {
useReceipt, useReceipt,
@@ -17,7 +19,7 @@ const ReceiptFormContext = createContext();
/** /**
* Receipt form provider. * Receipt form provider.
*/ */
function ReceiptFormProvider({ receiptId, ...props }) { function ReceiptFormProvider({ receiptId, baseCurrency, ...props }) {
// Fetch sale receipt details. // Fetch sale receipt details.
const { data: receipt, isLoading: isReceiptLoading } = useReceipt(receiptId, { const { data: receipt, isLoading: isReceiptLoading } = useReceipt(receiptId, {
enabled: !!receiptId, enabled: !!receiptId,
@@ -84,10 +86,17 @@ function ReceiptFormProvider({ receiptId, ...props }) {
const [submitPayload, setSubmitPayload] = useState({}); const [submitPayload, setSubmitPayload] = useState({});
const [selectCustomer, setSelectCustomer] = React.useState(null);
const isNewMode = !receiptId; const isNewMode = !receiptId;
const isFeatureLoading = isWarehouesLoading || isBranchesLoading; const isFeatureLoading = isWarehouesLoading || isBranchesLoading;
// Determines whether the foreign customer.
const isForeignCustomer =
!isEqual(selectCustomer?.currency_code, baseCurrency) &&
!isUndefined(selectCustomer?.currency_code);
const provider = { const provider = {
receiptId, receiptId,
receipt, receipt,
@@ -97,6 +106,9 @@ function ReceiptFormProvider({ receiptId, ...props }) {
branches, branches,
warehouses, warehouses,
submitPayload, submitPayload,
baseCurrency,
selectCustomer,
setSelectCustomer,
isNewMode, isNewMode,
isReceiptLoading, isReceiptLoading,
@@ -109,6 +121,7 @@ function ReceiptFormProvider({ receiptId, ...props }) {
isSettingLoading, isSettingLoading,
isBranchesSuccess, isBranchesSuccess,
isWarehousesSuccess, isWarehousesSuccess,
isForeignCustomer,
createReceiptMutate, createReceiptMutate,
editReceiptMutate, editReceiptMutate,

View File

@@ -98,7 +98,6 @@ export default function VendorFinanicalPanelTab() {
onCurrencySelected={(currency) => { onCurrencySelected={(currency) => {
form.setFieldValue('currency_code', currency.currency_code); form.setFieldValue('currency_code', currency.currency_code);
}} }}
disabled={true}
/> />
</FormGroup> </FormGroup>
)} )}