Skip to content

Commit d1c0178

Browse files
authored
Merge pull request Expensify#85658 from huult/856520-fix-duplicate-disabled-tax-rate
Improve deleted tax behavior
2 parents 7552a50 + 084e3a7 commit d1c0178

4 files changed

Lines changed: 94 additions & 29 deletions

File tree

src/components/MoneyRequestConfirmationList.tsx

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ import {
2424
setMoneyRequestPendingFields,
2525
setMoneyRequestTag,
2626
setMoneyRequestTaxAmount,
27-
setMoneyRequestTaxRate,
27+
setMoneyRequestTaxRateValues,
2828
} from '@libs/actions/IOU';
2929
import {computePerDiemExpenseAmount, isValidPerDiemExpenseAmount} from '@libs/actions/IOU/PerDiem';
3030
import {adjustRemainingSplitShares, resetSplitShares, setIndividualShare, setSplitShares} from '@libs/actions/IOU/Split';
@@ -350,6 +350,7 @@ function MoneyRequestConfirmationList({
350350
const isFromGlobalCreateAndCanEditParticipant = !!transaction?.isFromGlobalCreate && !isPerDiemRequest && !isTimeRequest;
351351

352352
const transactionID = transaction?.transactionID;
353+
const previousTransactionCurrency = usePrevious(transaction?.currency);
353354
const customUnitRateID = getRateID(transaction);
354355

355356
const subRates = transaction?.comment?.customUnit?.subRates ?? [];
@@ -380,14 +381,27 @@ function MoneyRequestConfirmationList({
380381

381382
// Update the tax code when the default changes (for example, because the transaction currency changed)
382383
const defaultTaxCode = getDefaultTaxCode(policy, transaction) ?? (isMovingTransactionFromTrackExpense ? (getDefaultTaxCode(policyForMovingExpenses, transaction) ?? '') : '');
384+
const defaultTaxValue = getTaxValue(policy, transaction, defaultTaxCode) ?? null;
385+
const previousDefaultTaxCode = getDefaultTaxCode(policy, transaction, previousTransactionCurrency);
386+
const shouldKeepCurrentTaxSelection = hasTaxRateWithMatchingValue(policy, transaction) && transaction?.taxCode !== previousDefaultTaxCode;
383387

384388
useEffect(() => {
385389
if (!transactionID || isReadOnly || !shouldShowTax || isMovingTransactionFromTrackExpense) {
386390
return;
387391
}
388-
setMoneyRequestTaxRate(transactionID, defaultTaxCode);
392+
393+
// Keep the user's current selection when it's still valid for the active policy.
394+
if (shouldKeepCurrentTaxSelection) {
395+
return;
396+
}
397+
398+
setMoneyRequestTaxRateValues(transactionID, {
399+
taxCode: defaultTaxCode,
400+
taxValue: defaultTaxValue,
401+
taxAmount: transaction?.taxAmount ?? null,
402+
});
389403
// trigger this useEffect also when policyID changes - the defaultTaxCode may stay the same
390-
}, [defaultTaxCode, isMovingTransactionFromTrackExpense, isReadOnly, transactionID, policyID, shouldShowTax]);
404+
}, [defaultTaxCode, defaultTaxValue, isMovingTransactionFromTrackExpense, isReadOnly, transactionID, policyID, shouldShowTax, shouldKeepCurrentTaxSelection, transaction?.taxAmount]);
391405

392406
const distance = getDistanceInMeters(transaction, unit);
393407
const prevDistance = usePrevious(distance);

src/components/ReportActionItem/MoneyRequestView.tsx

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -305,7 +305,13 @@ function MoneyRequestView({
305305
: convertToDisplayString(Math.abs(transactionTaxAmount ?? 0), actualCurrency);
306306

307307
const taxRatesDescription = taxRates?.name;
308-
const taxRateTitle = updatedTransaction ? getTaxName(policy, updatedTransaction, isExpenseUnreported) : getTaxName(policy, transaction, isExpenseUnreported);
308+
309+
const baseTransaction = updatedTransaction ?? transaction;
310+
const {taxCode, taxValue} = baseTransaction ?? {};
311+
312+
const taxRateTitle = getTaxName(policy, baseTransaction, isExpenseUnreported);
313+
const selectedPolicyTaxValue = taxCode ? policy?.taxRates?.taxes?.[taxCode]?.value : undefined;
314+
const hasTaxValueChanged = taxCode && taxValue !== undefined ? selectedPolicyTaxValue !== taxValue : false;
309315

310316
const actualTransactionDate = isFromMergeTransaction && updatedTransaction ? getFormattedCreated(updatedTransaction) : transactionDate;
311317
const fallbackTaxRateTitle = transaction?.taxValue;
@@ -592,7 +598,7 @@ function MoneyRequestView({
592598
const decodedCategoryName = getDecodedCategoryName(categoryValue);
593599
const categoryCopyValue = !canEdit ? decodedCategoryName : undefined;
594600
const cardCopyValue = cardProgramName;
595-
const taxRateValue = transaction?.taxName ?? taxRateTitle ?? fallbackTaxRateTitle;
601+
const taxRateValue = hasTaxValueChanged ? taxValue : (transaction?.taxName ?? taxRateTitle ?? fallbackTaxRateTitle ?? '');
596602
const taxRateCopyValue = !canEditTaxFields ? taxRateValue : undefined;
597603
const taxAmountTitle = formattedTaxAmount ? formattedTaxAmount.toString() : '';
598604
const taxAmountCopyValue = !canEditTaxFields ? taxAmountTitle : undefined;

src/components/TaxPicker.tsx

Lines changed: 46 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import Navigation from '@libs/Navigation/Navigation';
77
import {getHeaderMessageForNonUserList} from '@libs/OptionsListUtils';
88
import {getTaxRatesSection} from '@libs/TaxOptionsListUtils';
99
import type {TaxRatesOption} from '@libs/TaxOptionsListUtils';
10-
import {getEnabledTaxRateCount} from '@libs/TransactionUtils';
10+
import {getDefaultTaxCode, getEnabledTaxRateCount, transformedTaxRates} from '@libs/TransactionUtils';
1111
import CONST from '@src/CONST';
1212
import type {IOUAction} from '@src/CONST';
1313
import ONYXKEYS from '@src/ONYXKEYS';
@@ -26,7 +26,7 @@ type TaxPickerProps = {
2626
transactionID?: string;
2727

2828
/** Callback to fire when a tax is pressed */
29-
onSubmit: (tax: TaxRatesOption) => void;
29+
onSubmit: (tax: TaxRatesOption, shouldClearTax?: boolean) => void;
3030

3131
/** The action to take */
3232
action?: IOUAction;
@@ -68,10 +68,29 @@ function TaxPicker({selectedTaxRate = '', policyID, transactionID, onSubmit, act
6868

6969
const shouldShowTextInput = !isTaxRatesCountBelowThreshold;
7070

71-
const selectedOptions = selectedTaxRate
71+
const {taxCode, taxValue} = currentTransaction ?? {};
72+
const defaultTaxCode = getDefaultTaxCode(policy, currentTransaction) ?? '';
73+
const effectiveTaxCode = taxCode && taxCode.length > 0 ? taxCode : defaultTaxCode;
74+
const effectiveSelectedTaxRate = selectedTaxRate || (effectiveTaxCode ? (transformedTaxRates(policy, currentTransaction)[effectiveTaxCode]?.modifiedName ?? '') : '');
75+
const hasTaxBeenDeleted = !!taxCode && taxValue !== undefined && !taxRates?.taxes?.[taxCode];
76+
const hasTaxValueChanged = !!taxCode && taxValue !== undefined && taxRates?.taxes?.[taxCode]?.value !== taxValue;
77+
78+
const deletedTaxOption = !hasTaxBeenDeleted
79+
? null
80+
: {
81+
code: undefined,
82+
text: taxValue ?? '',
83+
keyForList: taxCode ?? '',
84+
searchText: taxValue ?? '',
85+
tooltipText: taxValue ?? '',
86+
isDisabled: true,
87+
isSelected: true,
88+
};
89+
90+
const selectedOptions = effectiveSelectedTaxRate
7291
? [
7392
{
74-
modifiedName: selectedTaxRate,
93+
modifiedName: effectiveSelectedTaxRate,
7594
isDisabled: false,
7695
accountID: null,
7796
},
@@ -86,14 +105,26 @@ function TaxPicker({selectedTaxRate = '', policyID, transactionID, onSubmit, act
86105
transaction: currentTransaction,
87106
});
88107

89-
const selectedOptionKey = sections?.at(0)?.data?.find((taxRate) => taxRate.searchText === selectedTaxRate)?.keyForList;
108+
const flattenedOptions = sections.flatMap((section) => section.data);
109+
const selectedOptionKey =
110+
flattenedOptions.find((taxRate) => taxRate.code === effectiveTaxCode)?.keyForList ?? flattenedOptions.find((taxRate) => taxRate.searchText === effectiveSelectedTaxRate)?.keyForList;
90111

91112
const handleSelectRow = (newSelectedOption: TaxRatesOption) => {
92-
if (selectedOptionKey === newSelectedOption.keyForList) {
113+
if (hasTaxValueChanged) {
114+
onSubmit(newSelectedOption, !newSelectedOption.code);
115+
return;
116+
}
117+
118+
const isSameTaxCode = taxCode === newSelectedOption.code;
119+
const currentTaxRateValue = taxCode ? taxRates?.taxes?.[taxCode]?.value : undefined;
120+
const hasMatchingTaxValue = taxValue === undefined || currentTaxRateValue === taxValue;
121+
122+
if (isSameTaxCode && hasMatchingTaxValue) {
93123
onDismiss();
94124
return;
95125
}
96-
onSubmit(newSelectedOption);
126+
127+
onSubmit(newSelectedOption, hasTaxBeenDeleted);
97128
};
98129

99130
const textInputOptions = {
@@ -103,9 +134,16 @@ function TaxPicker({selectedTaxRate = '', policyID, transactionID, onSubmit, act
103134
headerMessage: getHeaderMessageForNonUserList((sections.at(0)?.data?.length ?? 0) > 0, searchValue),
104135
};
105136

137+
const updatedSections = deletedTaxOption
138+
? sections.map((section) => ({
139+
...section,
140+
data: [...section.data.filter((item) => item.code !== deletedTaxOption.code), deletedTaxOption],
141+
}))
142+
: sections;
143+
106144
return (
107145
<SelectionListWithSections
108-
sections={sections}
146+
sections={updatedSections}
109147
shouldShowTextInput={shouldShowTextInput}
110148
textInputOptions={textInputOptions}
111149
onSelectRow={handleSelectRow}

src/pages/iou/request/step/IOURequestStepTaxRatePage.tsx

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,28 @@ function IOURequestStepTaxRatePage({
7676
const currency = getCurrency(currentTransaction);
7777
const decimals = getCurrencyDecimals(currency);
7878

79-
const updateTaxRates = (taxes: TaxRatesOption) => {
79+
const updateTaxRates = (taxes: TaxRatesOption, shouldClearTax?: boolean) => {
80+
const updateTaxRateParams = {
81+
transactionID: currentTransaction?.transactionID,
82+
transactionThreadReport: report,
83+
parentReport,
84+
taxCode: '',
85+
taxValue: '',
86+
taxAmount: 0,
87+
policy,
88+
policyTagList: policyTags,
89+
policyCategories,
90+
currentUserAccountIDParam,
91+
currentUserEmailParam,
92+
isASAPSubmitBetaEnabled,
93+
parentReportNextStep,
94+
};
95+
96+
if (shouldClearTax && isEditing) {
97+
updateMoneyRequestTaxRate(updateTaxRateParams);
98+
navigateBack();
99+
return;
100+
}
80101
if (!currentTransaction || !taxes.code || !taxRates) {
81102
Navigation.goBack();
82103
return;
@@ -97,21 +118,7 @@ function IOURequestStepTaxRatePage({
97118

98119
if (isEditing) {
99120
const newTaxCode = taxes.code;
100-
updateMoneyRequestTaxRate({
101-
transactionID: currentTransaction?.transactionID,
102-
transactionThreadReport: report,
103-
parentReport,
104-
taxCode: newTaxCode,
105-
taxValue,
106-
taxAmount: convertToBackendAmount(taxAmount ?? 0),
107-
policy,
108-
policyTagList: policyTags,
109-
policyCategories,
110-
currentUserAccountIDParam,
111-
currentUserEmailParam,
112-
isASAPSubmitBetaEnabled,
113-
parentReportNextStep,
114-
});
121+
updateMoneyRequestTaxRate({...updateTaxRateParams, taxCode: newTaxCode, taxValue, taxAmount: convertToBackendAmount(taxAmount ?? 0)});
115122
navigateBack();
116123
return;
117124
}

0 commit comments

Comments
 (0)