// @ts-nocheck import React from 'react'; import moment from 'moment'; import intl from 'react-intl-universal'; import { pick, first, sumBy } from 'lodash'; import { useFormikContext } from 'formik'; import { Intent } from '@blueprintjs/core'; import { AppToaster } from '@/components'; import { usePaymentMadeFormContext } from './PaymentMadeFormProvider'; import { defaultFastFieldShouldUpdate, safeSumBy, transformToForm, orderingLinesIndexes, formattedAmount, } from '@/utils'; import { useCurrentOrganization } from '@/hooks/state'; import { PAYMENT_MADE_ERRORS } from '../constants'; import { transformAttachmentsToForm, transformAttachmentsToRequest, } from '@/containers/Attachments/utils'; export const ERRORS = { PAYMENT_NUMBER_NOT_UNIQUE: 'PAYMENT.NUMBER.NOT.UNIQUE', }; // Default payment made entry values. export const defaultPaymentMadeEntry = { bill_id: '', payment_amount: '', currency_code: '', id: null, due_amount: null, amount: '', }; // Default initial values of payment made. export const defaultPaymentMade = { amount: '', vendor_id: '', payment_account_id: '', payment_date: moment(new Date()).format('YYYY-MM-DD'), reference: '', payment_number: '', statement: '', currency_code: '', branch_id: '', exchange_rate: 1, entries: [], attachments: [], }; export const transformToEditForm = (paymentMade, paymentMadeEntries) => { const attachments = transformAttachmentsToForm(paymentMade); const appliedAmount = safeSumBy(paymentMadeEntries, 'payment_amount'); return { ...transformToForm(paymentMade, defaultPaymentMade), entries: [ ...paymentMadeEntries.map((paymentMadeEntry) => ({ ...transformToForm(paymentMadeEntry, defaultPaymentMadeEntry), payment_amount: paymentMadeEntry.payment_amount || '', })), ], attachments, }; }; /** * Transform the new page entries. */ export const transformToNewPageEntries = (entries) => { return entries.map((entry) => ({ ...transformToForm(entry, defaultPaymentMadeEntry), payment_amount: '', currency_code: entry.currency_code, })); }; /** * Detarmines vendors fast field when update. */ export const vendorsFieldShouldUpdate = (newProps, oldProps) => { return ( newProps.shouldUpdateDeps.items !== oldProps.shouldUpdateDeps.items || defaultFastFieldShouldUpdate(newProps, oldProps) ); }; /** * Detarmines accounts fast field when update. */ export const accountsFieldShouldUpdate = (newProps, oldProps) => { return ( newProps.items !== oldProps.items || defaultFastFieldShouldUpdate(newProps, oldProps) ); }; /** * Transformes the form values to request body. */ export const transformFormToRequest = (form) => { // Filters entries that have no `bill_id` or `payment_amount`. const entries = form.entries .filter((item) => item.bill_id && item.payment_amount) .map((entry) => ({ ...pick(entry, ['payment_amount', 'bill_id']), })); const attachments = transformAttachmentsToRequest(form); return { ...form, entries: orderingLinesIndexes(entries), attachments }; }; export const useSetPrimaryBranchToForm = () => { const { setFieldValue } = useFormikContext(); const { branches, isBranchesSuccess } = usePaymentMadeFormContext(); React.useEffect(() => { if (isBranchesSuccess) { const primaryBranch = branches.find((b) => b.primary) || first(branches); if (primaryBranch) { setFieldValue('branch_id', primaryBranch.id); } } }, [isBranchesSuccess, setFieldValue, branches]); }; /** * Transformes the response errors types. */ export const transformErrors = (errors, { setFieldError }) => { const getError = (errorType) => errors.find((e) => e.type === errorType); if (getError(PAYMENT_MADE_ERRORS.PAYMENT_NUMBER_NOT_UNIQUE)) { setFieldError('payment_number', intl.get('payment_number_is_not_unique')); } if (getError(PAYMENT_MADE_ERRORS.WITHDRAWAL_ACCOUNT_CURRENCY_INVALID)) { AppToaster.show({ 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( () => sumBy(entries, 'payment_amount'), [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, }; }; export const usePaymentmadeTotalAmount = () => { const { values: { amount }, } = useFormikContext(); return amount; }; export const usePaymentMadeAppliedAmount = () => { const { values: { entries }, } = useFormikContext(); // Retrieves the invoice entries total. return React.useMemo(() => sumBy(entries, 'payment_amount'), [entries]); }; export const usePaymentMadeExcessAmount = () => { const appliedAmount = usePaymentMadeAppliedAmount(); const totalAmount = usePaymentmadeTotalAmount(); return Math.abs(totalAmount - appliedAmount); }; /** * 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; }; export const getPaymentExcessAmountFromValues = (values) => { const appliedAmount = sumBy(values.entries, 'payment_amount'); const totalAmount = values.amount; return Math.abs(totalAmount - appliedAmount); };