From e51f203ca84df0702dc143957e8e4634d8df7449 Mon Sep 17 00:00:00 2001 From: elforjani13 <39470382+elforjani13@users.noreply.github.com> Date: Sun, 20 Mar 2022 17:56:37 +0200 Subject: [PATCH] feat(purchases): add purchases. --- src/components/Vendors/VendorDrawerLink.js | 3 +- .../Bills/BillForm/BillFormHeaderFields.js | 13 +++-- .../VendorCreditNoteFormFooterRight.js | 7 ++- .../VendorCreditNoteFormHeaderFields.js | 46 +++++++++--------- .../CreditNotes/CreditNoteForm/components.js | 28 +++++++++++ .../CreditNotes/CreditNoteForm/utils.js | 44 +++++++++++++++++ .../PaymentForm/PaymentMadeFormFooterRight.js | 6 ++- .../PaymentMadeFormHeaderFields.js | 37 +++++++------- .../PaymentMades/PaymentForm/components.js | 30 ++++++++++-- .../PaymentMades/PaymentForm/utils.js | 48 ++++++++++++++++++- .../CreditNoteFormHeaderFields.js | 2 +- .../EstimateForm/EstimateFormHeaderFields.js | 2 +- .../InvoiceForm/InvoiceFormHeaderFields.js | 2 +- .../PaymentReceiveHeaderFields.js | 2 +- .../ReceiptForm/ReceiptFormHeaderFields.js | 2 +- src/lang/en/index.json | 6 ++- 16 files changed, 214 insertions(+), 64 deletions(-) create mode 100644 src/containers/Purchases/CreditNotes/CreditNoteForm/components.js diff --git a/src/components/Vendors/VendorDrawerLink.js b/src/components/Vendors/VendorDrawerLink.js index 9fdabf6df..e65b996b3 100644 --- a/src/components/Vendors/VendorDrawerLink.js +++ b/src/components/Vendors/VendorDrawerLink.js @@ -8,6 +8,7 @@ function VendorDrawerLinkComponent({ // #ownProps children, vendorId, + className, // #withDrawerActions openDrawer, @@ -18,7 +19,7 @@ function VendorDrawerLinkComponent({ event.preventDefault(); }; - return {children}; + return {children}; } export const VendorDrawerLink = R.compose(withDrawerActions)(VendorDrawerLinkComponent); diff --git a/src/containers/Purchases/Bills/BillForm/BillFormHeaderFields.js b/src/containers/Purchases/Bills/BillForm/BillFormHeaderFields.js index 335189720..5d6db0a98 100644 --- a/src/containers/Purchases/Bills/BillForm/BillFormHeaderFields.js +++ b/src/containers/Purchases/Bills/BillForm/BillFormHeaderFields.js @@ -13,10 +13,10 @@ import styled from 'styled-components'; import { CLASSES } from 'common/classes'; import { + FFormGroup, VendorSelectField, FieldRequiredHint, Icon, - CustomerDrawerLink, VendorDrawerLink, } from 'components'; import { vendorsFieldShouldUpdate } from './utils'; @@ -48,17 +48,16 @@ function BillFormHeader() { shouldUpdate={vendorsFieldShouldUpdate} > {({ form, field: { value }, meta: { error, touched } }) => ( - } inline={true} className={classNames( - 'form-group--customer-name', + 'form-group--vendor-name', 'form-group--select-list', CLASSES.FILL, )} labelInfo={} - intent={inputIntent({ error, touched })} - helperText={} > {value && ( - View Vendor Details + )} - + )} diff --git a/src/containers/Purchases/CreditNotes/CreditNoteForm/VendorCreditNoteFormFooterRight.js b/src/containers/Purchases/CreditNotes/CreditNoteForm/VendorCreditNoteFormFooterRight.js index f85aa8acd..47dedf41b 100644 --- a/src/containers/Purchases/CreditNotes/CreditNoteForm/VendorCreditNoteFormFooterRight.js +++ b/src/containers/Purchases/CreditNotes/CreditNoteForm/VendorCreditNoteFormFooterRight.js @@ -7,8 +7,11 @@ import { TotalLineBorderStyle, TotalLineTextStyle, } from 'components'; +import { useVendorCrditNoteTotals } from './utils'; export function VendorCreditNoteFormFooterRight() { + const { formattedSubtotal, formattedTotal } = useVendorCrditNoteTotals(); + return ( } - value={'$5000.00'} + value={formattedSubtotal} borderStyle={TotalLineBorderStyle.None} /> } - value={'$5000.00'} + value={formattedTotal} // borderStyle={TotalLineBorderStyle.SingleDark} textStyle={TotalLineTextStyle.Bold} /> diff --git a/src/containers/Purchases/CreditNotes/CreditNoteForm/VendorCreditNoteFormHeaderFields.js b/src/containers/Purchases/CreditNotes/CreditNoteForm/VendorCreditNoteFormHeaderFields.js index 3b1b74a94..f48775749 100644 --- a/src/containers/Purchases/CreditNotes/CreditNoteForm/VendorCreditNoteFormHeaderFields.js +++ b/src/containers/Purchases/CreditNotes/CreditNoteForm/VendorCreditNoteFormHeaderFields.js @@ -6,19 +6,19 @@ import { ControlGroup, } from '@blueprintjs/core'; import { DateInput } from '@blueprintjs/datetime'; -import { FastField, Field, ErrorMessage } from 'formik'; +import { FastField, ErrorMessage } from 'formik'; import { CLASSES } from 'common/classes'; import classNames from 'classnames'; import styled from 'styled-components'; import { + FFormGroup, VendorSelectField, FieldRequiredHint, InputPrependButton, - ExchangeRateInputGroup, Icon, - If, FormattedMessage as T, + VendorDrawerLink, } from 'components'; import { vendorsFieldShouldUpdate, @@ -26,7 +26,7 @@ import { } from './utils'; import { useVendorCreditNoteFormContext } from './VendorCreditNoteFormProvider'; -import VendorCreditNoteFormCurrencyTag from './VendorCreditNoteFormCurrencyTag'; +import { VendorCreditNoteExchangeRateInputField } from './components'; import { momentFormatter, compose, @@ -51,13 +51,7 @@ function VendorCreditNoteFormHeaderFields({ vendorcreditNextNumber, }) { // Vendor Credit form context. - const { - vendors, - isForeignVendor, - baseCurrency, - selectVendor, - setSelectVendor, - } = useVendorCreditNoteFormContext(); + const { vendors } = useVendorCreditNoteFormContext(); // Handle vendor credit number changing. const handleVendorCreditNumberChange = () => { @@ -92,13 +86,12 @@ function VendorCreditNoteFormHeaderFields({ shouldUpdate={vendorsFieldShouldUpdate} > {({ form, field: { value }, meta: { error, touched } }) => ( - } inline={true} className={classNames(CLASSES.FILL, 'form-group--vendor')} labelInfo={} - intent={inputIntent({ error, touched })} - helperText={} > { form.setFieldValue('vendor_id', contact.id); form.setFieldValue('currency_code', contact?.currency_code); - setSelectVendor(contact); }} popoverFill={true} allowCreate={true} /> - + {value && ( + + + + )} + )} {/* ----------- Exchange rate ----------- */} - - - + {/* ------- Vendor Credit date ------- */} @@ -226,3 +219,8 @@ const ControlVendorGroup = styled(ControlGroup)` align-items: center; transform: none; `; + +const VendorButtonLink = styled(VendorDrawerLink)` + font-size: 11px; + margin-top: 6px; +`; diff --git a/src/containers/Purchases/CreditNotes/CreditNoteForm/components.js b/src/containers/Purchases/CreditNotes/CreditNoteForm/components.js new file mode 100644 index 000000000..82c2df879 --- /dev/null +++ b/src/containers/Purchases/CreditNotes/CreditNoteForm/components.js @@ -0,0 +1,28 @@ +import React from 'react'; +import { useFormikContext } from 'formik'; +import { ExchangeRateInputGroup } from 'components'; +import { useCurrentOrganization } from 'hooks/state'; +import { useVendorNoteIsForeignCustomer } from './utils'; + +/** + * vendor credit note exchange rate input field. + * @returns {JSX.Element} + */ +export function VendorCreditNoteExchangeRateInputField({ ...props }) { + const currentOrganization = useCurrentOrganization(); + const { values } = useFormikContext(); + + const isForeignCustomer = useVendorNoteIsForeignCustomer(); + + // Can't continue if the customer is not foreign. + if (!isForeignCustomer) { + return null; + } + return ( + + ); +} diff --git a/src/containers/Purchases/CreditNotes/CreditNoteForm/utils.js b/src/containers/Purchases/CreditNotes/CreditNoteForm/utils.js index 4f63fd50d..5ee6d9779 100644 --- a/src/containers/Purchases/CreditNotes/CreditNoteForm/utils.js +++ b/src/containers/Purchases/CreditNotes/CreditNoteForm/utils.js @@ -9,6 +9,7 @@ import { repeatValue, transactionNumber, orderingLinesIndexes, + formattedAmount, } from 'utils'; import { updateItemsEntriesTotal, @@ -16,6 +17,8 @@ import { } from 'containers/Entries/utils'; import { useFormikContext } from 'formik'; import { useVendorCreditNoteFormContext } from './VendorCreditNoteFormProvider'; +import { useCurrentOrganization } from 'hooks/state'; +import { getEntriesTotal } from 'containers/Entries/utils'; export const MIN_LINES_NUMBER = 1; @@ -166,3 +169,44 @@ export const useSetPrimaryWarehouseToForm = () => { } }, [isWarehousesSuccess, setFieldValue, warehouses]); }; + +export const useVendorCrditNoteTotals = () => { + const { + values: { entries, currency_code: currencyCode }, + } = useFormikContext(); + + // Retrieves the invoice entries total. + const total = React.useMemo(() => getEntriesTotal(entries), [entries]); + + // Retrieves the formatted total money. + const formattedTotal = React.useMemo( + () => formattedAmount(total, currencyCode), + [total, currencyCode], + ); + // Retrieves the formatted subtotal. + const formattedSubtotal = React.useMemo( + () => formattedAmount(total, currencyCode, { money: false }), + [total, currencyCode], + ); + + return { + total, + formattedTotal, + formattedSubtotal, + }; +}; + +/** + * Detarmines whether the vendor note has foreign customer. + * @returns {boolean} + */ +export const useVendorNoteIsForeignCustomer = () => { + const { values } = useFormikContext(); + const currentOrganization = useCurrentOrganization(); + + const isForeignCustomer = React.useMemo( + () => values.currency_code !== currentOrganization.base_currency, + [values.currency_code, currentOrganization.base_currency], + ); + return isForeignCustomer; +}; diff --git a/src/containers/Purchases/PaymentMades/PaymentForm/PaymentMadeFormFooterRight.js b/src/containers/Purchases/PaymentMades/PaymentForm/PaymentMadeFormFooterRight.js index 8a6e1b533..2622cf0f8 100644 --- a/src/containers/Purchases/PaymentMades/PaymentForm/PaymentMadeFormFooterRight.js +++ b/src/containers/Purchases/PaymentMades/PaymentForm/PaymentMadeFormFooterRight.js @@ -7,18 +7,20 @@ import { TotalLineBorderStyle, TotalLineTextStyle, } from 'components'; +import { usePaymentMadeTotals } from './utils'; export function PaymentMadeFormFooterRight() { + const { formattedSubtotal, formattedTotal } = usePaymentMadeTotals(); return ( } - value={'$5000.00'} + value={formattedSubtotal} borderStyle={TotalLineBorderStyle.None} /> } - value={'$5000.00'} + value={formattedTotal} // borderStyle={TotalLineBorderStyle.SingleDark} textStyle={TotalLineTextStyle.Bold} /> diff --git a/src/containers/Purchases/PaymentMades/PaymentForm/PaymentMadeFormHeaderFields.js b/src/containers/Purchases/PaymentMades/PaymentForm/PaymentMadeFormHeaderFields.js index 03074306f..820e6abf2 100644 --- a/src/containers/Purchases/PaymentMades/PaymentForm/PaymentMadeFormHeaderFields.js +++ b/src/containers/Purchases/PaymentMades/PaymentForm/PaymentMadeFormHeaderFields.js @@ -16,21 +16,21 @@ import { CLASSES } from 'common/classes'; import styled from 'styled-components'; import { + FFormGroup, AccountsSelectList, VendorSelectField, FieldRequiredHint, InputPrependText, Money, Hint, - If, Icon, + VendorDrawerLink, MoneyInputGroup, - ExchangeRateInputGroup, } from 'components'; import withCurrentOrganization from 'containers/Organization/withCurrentOrganization'; import { usePaymentMadeFormContext } from './PaymentMadeFormProvider'; import { ACCOUNT_TYPE } from 'common/accountTypes'; -import PaymentMadeFormCurrencyTag from './PaymentMadeFormCurrencyTag'; +import { PaymentMadeExchangeRateInputField } from './components'; import { momentFormatter, tansformDateValue, @@ -62,7 +62,6 @@ function PaymentMadeFormHeaderFields({ organization: { base_currency } }) { isForeignVendor, baseCurrency, selectVendor, - setSelectVendor, } = usePaymentMadeFormContext(); // Sumation of payable full-amount. @@ -95,13 +94,12 @@ function PaymentMadeFormHeaderFields({ organization: { base_currency } }) { shouldUpdate={vendorsFieldShouldUpdate} > {({ form, field: { value }, meta: { error, touched } }) => ( - } inline={true} className={classNames('form-group--select-list', Classes.FILL)} labelInfo={} - intent={inputIntent({ error, touched })} - helperText={} > - + {value && ( + + + + )} + )} {/* ----------- Exchange rate ----------- */} - - - + {/* ------------ Payment date ------------ */} @@ -285,3 +283,8 @@ const ControlVendorGroup = styled(ControlGroup)` align-items: center; transform: none; `; + +const VendorButtonLink = styled(VendorDrawerLink)` + font-size: 11px; + margin-top: 6px; +`; diff --git a/src/containers/Purchases/PaymentMades/PaymentForm/components.js b/src/containers/Purchases/PaymentMades/PaymentForm/components.js index 230c97a76..5780d11b0 100644 --- a/src/containers/Purchases/PaymentMades/PaymentForm/components.js +++ b/src/containers/Purchases/PaymentMades/PaymentForm/components.js @@ -1,9 +1,12 @@ import React from 'react'; import intl from 'react-intl-universal'; import moment from 'moment'; -import { Money } from 'components'; +import { Money, ExchangeRateInputGroup } from 'components'; import { safeSumBy, formattedAmount } from 'utils'; import { MoneyFieldCell } from 'components/DataTableCells'; +import { useFormikContext } from 'formik'; +import { useCurrentOrganization } from 'hooks/state'; +import { usePaymentMadeIsForeignCustomer } from './utils'; function BillNumberAccessor(row) { return row?.bill_no ? row?.bill_no : '-'; @@ -51,8 +54,6 @@ function MoneyTableCell({ row: { original }, value }) { * Payment made entries table columns */ export function usePaymentMadeEntriesTableColumns() { - - return React.useMemo( () => [ { @@ -107,3 +108,26 @@ export function usePaymentMadeEntriesTableColumns() { [], ); } + +/** + * payment made exchange rate input field. + * @returns {JSX.Element} + */ +export function PaymentMadeExchangeRateInputField({ ...props }) { + const currentOrganization = useCurrentOrganization(); + const { values } = useFormikContext(); + + const isForeignCustomer = usePaymentMadeIsForeignCustomer(); + + // Can't continue if the customer is not foreign. + if (!isForeignCustomer) { + return null; + } + return ( + + ); +} diff --git a/src/containers/Purchases/PaymentMades/PaymentForm/utils.js b/src/containers/Purchases/PaymentMades/PaymentForm/utils.js index 07be02f51..aed5a7f51 100644 --- a/src/containers/Purchases/PaymentMades/PaymentForm/utils.js +++ b/src/containers/Purchases/PaymentMades/PaymentForm/utils.js @@ -11,7 +11,10 @@ import { safeSumBy, transformToForm, orderingLinesIndexes, + formattedAmount, } from 'utils'; +import { getEntriesTotal } from '../../../Entries/utils'; +import { useCurrentOrganization } from 'hooks/state'; export const ERRORS = { PAYMENT_NUMBER_NOT_UNIQUE: 'PAYMENT.NUMBER.NOT.UNIQUE', @@ -126,8 +129,51 @@ export const transformErrors = (errors, { setFieldError }) => { } if (getError('WITHDRAWAL_ACCOUNT_CURRENCY_INVALID')) { AppToaster.show({ - message: intl.get('payment_made.error.withdrawal_account_currency_invalid'), + message: intl.get( + 'payment_made.error.withdrawal_account_currency_invalid', + ), intent: Intent.DANGER, }); } }; + +export const usePaymentMadeTotals = () => { + const { + values: { entries, currency_code: currencyCode }, + } = useFormikContext(); + + // Retrieves the invoice entries total. + const total = React.useMemo(() => getEntriesTotal(entries), [entries]); + + // Retrieves the formatted total money. + const formattedTotal = React.useMemo( + () => formattedAmount(total, currencyCode), + [total, currencyCode], + ); + // Retrieves the formatted subtotal. + const formattedSubtotal = React.useMemo( + () => formattedAmount(total, currencyCode, { money: false }), + [total, currencyCode], + ); + + return { + total, + formattedTotal, + formattedSubtotal, + }; +}; + +/** + * Detarmines whether the bill has foreign customer. + * @returns {boolean} + */ +export const usePaymentMadeIsForeignCustomer = () => { + const { values } = useFormikContext(); + const currentOrganization = useCurrentOrganization(); + + const isForeignCustomer = React.useMemo( + () => values.currency_code !== currentOrganization.base_currency, + [values.currency_code, currentOrganization.base_currency], + ); + return isForeignCustomer; +}; diff --git a/src/containers/Sales/CreditNotes/CreditNoteForm/CreditNoteFormHeaderFields.js b/src/containers/Sales/CreditNotes/CreditNoteForm/CreditNoteFormHeaderFields.js index f06fcce36..89dc8606d 100644 --- a/src/containers/Sales/CreditNotes/CreditNoteForm/CreditNoteFormHeaderFields.js +++ b/src/containers/Sales/CreditNotes/CreditNoteForm/CreditNoteFormHeaderFields.js @@ -108,7 +108,7 @@ function CreditNoteFormHeaderFields({ {value && ( - View Customer Details + )} diff --git a/src/containers/Sales/Estimates/EstimateForm/EstimateFormHeaderFields.js b/src/containers/Sales/Estimates/EstimateForm/EstimateFormHeaderFields.js index 34d4db271..1fb88dc1d 100644 --- a/src/containers/Sales/Estimates/EstimateForm/EstimateFormHeaderFields.js +++ b/src/containers/Sales/Estimates/EstimateForm/EstimateFormHeaderFields.js @@ -101,7 +101,7 @@ function EstimateFormHeader({ {value && ( - View Customer Details + )} diff --git a/src/containers/Sales/Invoices/InvoiceForm/InvoiceFormHeaderFields.js b/src/containers/Sales/Invoices/InvoiceForm/InvoiceFormHeaderFields.js index ca9c58d5e..ec04c218b 100644 --- a/src/containers/Sales/Invoices/InvoiceForm/InvoiceFormHeaderFields.js +++ b/src/containers/Sales/Invoices/InvoiceForm/InvoiceFormHeaderFields.js @@ -107,7 +107,7 @@ function InvoiceFormHeaderFields({ {value && ( - View Customer Details + )} diff --git a/src/containers/Sales/PaymentReceives/PaymentReceiveForm/PaymentReceiveHeaderFields.js b/src/containers/Sales/PaymentReceives/PaymentReceiveForm/PaymentReceiveHeaderFields.js index bb7616c8a..44b03ed9c 100644 --- a/src/containers/Sales/PaymentReceives/PaymentReceiveForm/PaymentReceiveHeaderFields.js +++ b/src/containers/Sales/PaymentReceives/PaymentReceiveForm/PaymentReceiveHeaderFields.js @@ -158,7 +158,7 @@ function PaymentReceiveHeaderFields({ {value && ( - View Customer Details + )} diff --git a/src/containers/Sales/Receipts/ReceiptForm/ReceiptFormHeaderFields.js b/src/containers/Sales/Receipts/ReceiptForm/ReceiptFormHeaderFields.js index 03f812dd1..f2e7c6457 100644 --- a/src/containers/Sales/Receipts/ReceiptForm/ReceiptFormHeaderFields.js +++ b/src/containers/Sales/Receipts/ReceiptForm/ReceiptFormHeaderFields.js @@ -105,7 +105,7 @@ function ReceiptFormHeader({ {value && ( - View Customer Details + )} diff --git a/src/lang/en/index.json b/src/lang/en/index.json index 7dea2b787..70571f1a1 100644 --- a/src/lang/en/index.json +++ b/src/lang/en/index.json @@ -1912,6 +1912,8 @@ "warehouse.error.warehouse_has_associated_transactions": "You could not delete the warehouse that has associated transactions.", "branche.error.warehouse_code_not_unique": "Branch code not unique", "branche.error.branch_has_associated_transactions": "You could not delete the branch that has associated transactions.", - "payment_Receive.error.payment_account_currency_invalid":"The deposit account currency should be same customer currency or organization base currency.", - "payment_made.error.withdrawal_account_currency_invalid":"The withdrawal account currency should be same vendor currency or organization base currency." + "payment_Receive.error.payment_account_currency_invalid": "The deposit account currency should be same customer currency or organization base currency.", + "payment_made.error.withdrawal_account_currency_invalid": "The withdrawal account currency should be same vendor currency or organization base currency.", + "view_customer_details": "View Customer Details", + "view_vendor_details":"View Vendor Details" } \ No newline at end of file