diff --git a/src/components/MoneyRequestConfirmationList.tsx b/src/components/MoneyRequestConfirmationList.tsx index 0fc2c478e75a6..8928b0efb7390 100755 --- a/src/components/MoneyRequestConfirmationList.tsx +++ b/src/components/MoneyRequestConfirmationList.tsx @@ -35,7 +35,7 @@ import Log from '@libs/Log'; import {validateAmount} from '@libs/MoneyRequestUtils'; import Navigation from '@libs/Navigation/Navigation'; import {getIOUConfirmationOptionsFromPayeePersonalDetail, hasEnabledOptions} from '@libs/OptionsListUtils'; -import {getTagLists, isTaxTrackingEnabled} from '@libs/PolicyUtils'; +import {getDistanceRateCustomUnitRate, getTagLists, isTaxTrackingEnabled} from '@libs/PolicyUtils'; import {isSelectedManagerMcTest} from '@libs/ReportUtils'; import type {OptionData} from '@libs/ReportUtils'; import { @@ -332,14 +332,27 @@ function MoneyRequestConfirmationList({ const shouldShowTax = isTaxTrackingEnabled(isPolicyExpenseChat, policy, isDistanceRequest, isPerDiemRequest); - // Update the tax code when the default changes (for example, because the transaction currency changed) - const defaultTaxCode = getDefaultTaxCode(policy, transaction) ?? ''; + const previousTransactionAmount = usePrevious(transaction?.amount); + const previousTransactionCurrency = usePrevious(transaction?.currency); + const previousTransactionModifiedCurrency = usePrevious(transaction?.modifiedCurrency); + const previousCustomUnitRateID = usePrevious(customUnitRateID); useEffect(() => { - if (!transactionID) { + // previousTransaction is in the condition because if it is falsy, it means this is the first time the useEffect is triggered after we load it, so we should calculate the default + // tax even if the other parameters are the same against their previous values. + if ( + !shouldShowTax || + !transaction || + !transactionID || + (transaction.taxCode && + previousTransactionModifiedCurrency === transaction.modifiedCurrency && + previousTransactionCurrency === transaction.currency && + previousCustomUnitRateID === customUnitRateID) + ) { return; } - setMoneyRequestTaxRate(transactionID, defaultTaxCode); - }, [defaultTaxCode, transactionID]); + const defaultTaxCode = getDefaultTaxCode(policy, transaction); + setMoneyRequestTaxRate(transactionID, defaultTaxCode ?? ''); + }, [customUnitRateID, policy, previousCustomUnitRateID, previousTransactionCurrency, previousTransactionModifiedCurrency, shouldShowTax, transaction, transactionID]); const isMovingTransactionFromTrackExpense = isMovingTransactionFromTrackExpenseUtil(action); @@ -474,17 +487,53 @@ function MoneyRequestConfirmationList({ } }, [shouldCalculateDistanceAmount, isReadOnly, distanceRequestAmount, transactionID, currency, isTypeSplit, isPolicyExpenseChat, selectedParticipantsProp, transaction]); + const previousTaxCode = usePrevious(transaction?.taxCode); + // Calculate and set tax amount in transaction draft - const taxableAmount = isDistanceRequest ? DistanceRequestUtils.getTaxableAmount(policy, customUnitRateID, distance) : (transaction?.amount ?? 0); - const taxPercentage = getTaxValue(policy, transaction, transaction?.taxCode ?? defaultTaxCode) ?? ''; - const taxAmount = calculateTaxAmount(taxPercentage, taxableAmount, transaction?.currency ?? CONST.CURRENCY.USD); - const taxAmountInSmallestCurrencyUnits = convertToBackendAmount(Number.parseFloat(taxAmount.toString())); useEffect(() => { - if (!transactionID) { + if ( + !shouldShowTax || + !transaction || + (transaction.taxAmount !== undefined && + previousTransactionAmount === transaction.amount && + previousTransactionCurrency === transaction.currency && + previousCustomUnitRateID === customUnitRateID && + previousTaxCode === transaction.taxCode) + ) { return; } - setMoneyRequestTaxAmount(transactionID, taxAmountInSmallestCurrencyUnits); - }, [transactionID, taxAmountInSmallestCurrencyUnits]); + + let taxableAmount: number | undefined; + let taxCode: string | undefined; + if (isDistanceRequest) { + if (customUnitRateID) { + const customUnitRate = getDistanceRateCustomUnitRate(policy, customUnitRateID); + taxCode = customUnitRate?.attributes?.taxRateExternalID; + taxableAmount = DistanceRequestUtils.getTaxableAmount(policy, customUnitRateID, distance); + } + } else { + taxableAmount = transaction.amount ?? 0; + taxCode = transaction.taxCode ?? getDefaultTaxCode(policy, transaction) ?? ''; + } + + if (taxCode && taxableAmount) { + const taxPercentage = getTaxValue(policy, transaction, taxCode) ?? ''; + const taxAmount = calculateTaxAmount(taxPercentage, taxableAmount, transaction.currency); + const taxAmountInSmallestCurrencyUnits = convertToBackendAmount(Number.parseFloat(taxAmount.toString())); + setMoneyRequestTaxAmount(transaction.transactionID, taxAmountInSmallestCurrencyUnits); + } + }, [ + policy, + shouldShowTax, + previousTransactionAmount, + previousTransactionCurrency, + transaction, + isDistanceRequest, + customUnitRateID, + previousCustomUnitRateID, + previousTaxCode, + distance, + ]); // If completing a split expense fails, set didConfirm to false to allow the user to edit the fields again if (isEditingSplitBill && didConfirm) { @@ -945,7 +994,6 @@ function MoneyRequestConfirmationList({ routeError, isDelegateAccessRestricted, showDelegateNoAccessModal, - setDidConfirmSplit, ], );