Skip to content

Commit a7fe1c9

Browse files
iwizniaOSBotify
authored andcommitted
Merge pull request #39610 from eVoloshchak/revert-35797-preserving-the-transactions-amounts-the-same-as-the-user-entered
Revert "35797-preserving-the-transactions-amounts-the-same-as-entered" (cherry picked from commit a1f9cec)
1 parent 2822486 commit a7fe1c9

File tree

8 files changed

+24
-68
lines changed

8 files changed

+24
-68
lines changed

src/components/transactionPropTypes.js

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,6 @@ export default PropTypes.shape({
1414
/** The original transaction amount */
1515
amount: PropTypes.number,
1616

17-
/** Whether the original input should be shown */
18-
shouldShowOriginalAmount: PropTypes.bool,
19-
2017
/** The edited transaction amount */
2118
modifiedAmount: PropTypes.number,
2219

src/libs/CurrencyUtils.ts

Lines changed: 3 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -87,22 +87,9 @@ function convertToBackendAmount(amountAsFloat: number): number {
8787
*
8888
* @note we do not support any currencies with more than two decimal places.
8989
*/
90-
function convertToFrontendAmountAsInteger(amountAsInt: number): number {
90+
function convertToFrontendAmount(amountAsInt: number): number {
9191
return Math.trunc(amountAsInt) / 100.0;
9292
}
93-
94-
/**
95-
* Takes an amount in "cents" as an integer and converts it to a string amount used in the frontend.
96-
*
97-
* @note we do not support any currencies with more than two decimal places.
98-
*/
99-
function convertToFrontendAmountAsString(amountAsInt: number | null | undefined): string {
100-
if (amountAsInt === null || amountAsInt === undefined) {
101-
return '';
102-
}
103-
return convertToFrontendAmountAsInteger(amountAsInt).toFixed(2);
104-
}
105-
10693
/**
10794
* Given an amount in the "cents", convert it to a string for display in the UI.
10895
* The backend always handle things in "cents" (subunit equal to 1/100)
@@ -111,7 +98,7 @@ function convertToFrontendAmountAsString(amountAsInt: number | null | undefined)
11198
* @param currency - IOU currency
11299
*/
113100
function convertToDisplayString(amountInCents = 0, currency: string = CONST.CURRENCY.USD): string {
114-
const convertedAmount = convertToFrontendAmountAsInteger(amountInCents);
101+
const convertedAmount = convertToFrontendAmount(amountInCents);
115102
return NumberFormatUtils.format(BaseLocaleListener.getPreferredLocale(), convertedAmount, {
116103
style: 'currency',
117104
currency,
@@ -152,8 +139,7 @@ export {
152139
getCurrencySymbol,
153140
isCurrencySymbolLTR,
154141
convertToBackendAmount,
155-
convertToFrontendAmountAsInteger,
156-
convertToFrontendAmountAsString,
142+
convertToFrontendAmount,
157143
convertToDisplayString,
158144
convertAmountToDisplayString,
159145
isValidCurrencyCode,

src/libs/actions/IOU.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -355,12 +355,12 @@ function startMoneyRequest(iouType: ValueOf<typeof CONST.IOU.TYPE>, reportID: st
355355
}
356356

357357
// eslint-disable-next-line @typescript-eslint/naming-convention
358-
function setMoneyRequestAmount_temporaryForRefactor(transactionID: string, amount: number, currency: string, removeOriginalCurrency = false, shouldShowOriginalAmount = false) {
358+
function setMoneyRequestAmount_temporaryForRefactor(transactionID: string, amount: number, currency: string, removeOriginalCurrency = false) {
359359
if (removeOriginalCurrency) {
360-
Onyx.merge(`${ONYXKEYS.COLLECTION.TRANSACTION_DRAFT}${transactionID}`, {amount, currency, originalCurrency: null, shouldShowOriginalAmount});
360+
Onyx.merge(`${ONYXKEYS.COLLECTION.TRANSACTION_DRAFT}${transactionID}`, {amount, currency, originalCurrency: null});
361361
return;
362362
}
363-
Onyx.merge(`${ONYXKEYS.COLLECTION.TRANSACTION_DRAFT}${transactionID}`, {amount, currency, shouldShowOriginalAmount});
363+
Onyx.merge(`${ONYXKEYS.COLLECTION.TRANSACTION_DRAFT}${transactionID}`, {amount, currency});
364364
}
365365

366366
// eslint-disable-next-line @typescript-eslint/naming-convention

src/pages/iou/request/IOURequestStartPage.js

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -165,14 +165,7 @@ function IOURequestStartPage({
165165
onTabSelected={resetIOUTypeIfChanged}
166166
tabBar={TabSelector}
167167
>
168-
<TopTab.Screen name={CONST.TAB_REQUEST.MANUAL}>
169-
{() => (
170-
<IOURequestStepAmount
171-
shouldKeepUserInput
172-
route={route}
173-
/>
174-
)}
175-
</TopTab.Screen>
168+
<TopTab.Screen name={CONST.TAB_REQUEST.MANUAL}>{() => <IOURequestStepAmount route={route} />}</TopTab.Screen>
176169
<TopTab.Screen name={CONST.TAB_REQUEST.SCAN}>{() => <IOURequestStepScan route={route} />}</TopTab.Screen>
177170
{shouldDisplayDistanceRequest && <TopTab.Screen name={CONST.TAB_REQUEST.DISTANCE}>{() => <IOURequestStepDistance route={route} />}</TopTab.Screen>}
178171
</OnyxTabNavigator>

src/pages/iou/request/step/IOURequestStepAmount.js

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import {useFocusEffect} from '@react-navigation/native';
22
import lodashGet from 'lodash/get';
33
import lodashIsEmpty from 'lodash/isEmpty';
4-
import PropTypes from 'prop-types';
54
import React, {useCallback, useEffect, useRef} from 'react';
65
import {withOnyx} from 'react-native-onyx';
76
import transactionPropTypes from '@components/transactionPropTypes';
@@ -38,9 +37,6 @@ const propTypes = {
3837
/** The draft transaction that holds data to be persisted on the current transaction */
3938
splitDraftTransaction: transactionPropTypes,
4039

41-
/** Whether the user input should be kept or not */
42-
shouldKeepUserInput: PropTypes.bool,
43-
4440
/** The draft transaction object being modified in Onyx */
4541
draftTransaction: transactionPropTypes,
4642
};
@@ -50,7 +46,6 @@ const defaultProps = {
5046
transaction: {},
5147
splitDraftTransaction: {},
5248
draftTransaction: {},
53-
shouldKeepUserInput: false,
5449
};
5550

5651
function IOURequestStepAmount({
@@ -61,7 +56,6 @@ function IOURequestStepAmount({
6156
transaction,
6257
splitDraftTransaction,
6358
draftTransaction,
64-
shouldKeepUserInput,
6559
}) {
6660
const {translate} = useLocalize();
6761
const textInput = useRef(null);
@@ -131,7 +125,7 @@ function IOURequestStepAmount({
131125
isSaveButtonPressed.current = true;
132126
const amountInSmallestCurrencyUnits = CurrencyUtils.convertToBackendAmount(Number.parseFloat(amount));
133127

134-
IOU.setMoneyRequestAmount_temporaryForRefactor(transactionID, amountInSmallestCurrencyUnits, currency || CONST.CURRENCY.USD, true, shouldKeepUserInput);
128+
IOU.setMoneyRequestAmount_temporaryForRefactor(transactionID, amountInSmallestCurrencyUnits, currency || CONST.CURRENCY.USD, true);
135129

136130
if (backTo) {
137131
Navigation.goBack(backTo);
@@ -189,7 +183,6 @@ function IOURequestStepAmount({
189183
currency={currency}
190184
amount={Math.abs(transactionAmount)}
191185
ref={(e) => (textInput.current = e)}
192-
shouldKeepUserInput={transaction.shouldShowOriginalAmount}
193186
onCurrencyButtonPress={navigateToCurrencySelectionPage}
194187
onSubmitButtonPress={saveAmountAndCurrency}
195188
selectedTab={iouRequestType}

src/pages/iou/steps/MoneyRequestAmountForm.tsx

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,6 @@ type MoneyRequestAmountFormProps = {
2828
/** Calculated tax amount based on selected tax rate */
2929
taxAmount?: number;
3030

31-
/** Whether the user input should be kept or not */
32-
shouldKeepUserInput?: boolean;
33-
3431
/** Currency chosen by user or saved in Onyx */
3532
currency?: string;
3633

@@ -65,7 +62,7 @@ const getNewSelection = (oldSelection: Selection, prevLength: number, newLength:
6562

6663
const isAmountInvalid = (amount: string) => !amount.length || parseFloat(amount) < 0.01;
6764
const isTaxAmountInvalid = (currentAmount: string, taxAmount: number, isTaxAmountForm: boolean) =>
68-
isTaxAmountForm && Number.parseFloat(currentAmount) > CurrencyUtils.convertToFrontendAmountAsInteger(Math.abs(taxAmount));
65+
isTaxAmountForm && Number.parseFloat(currentAmount) > CurrencyUtils.convertToFrontendAmount(Math.abs(taxAmount));
6966

7067
const AMOUNT_VIEW_ID = 'amountView';
7168
const NUM_PAD_CONTAINER_VIEW_ID = 'numPadContainerView';
@@ -81,7 +78,6 @@ function MoneyRequestAmountForm(
8178
onCurrencyButtonPress,
8279
onSubmitButtonPress,
8380
selectedTab = CONST.TAB_REQUEST.MANUAL,
84-
shouldKeepUserInput = false,
8581
}: MoneyRequestAmountFormProps,
8682
forwardedRef: ForwardedRef<BaseTextInputRef>,
8783
) {
@@ -91,8 +87,10 @@ function MoneyRequestAmountForm(
9187

9288
const textInput = useRef<BaseTextInputRef | null>(null);
9389
const isTaxAmountForm = Navigation.getActiveRoute().includes('taxAmount');
90+
9491
const decimals = CurrencyUtils.getCurrencyDecimals(currency);
95-
const selectedAmountAsString = CurrencyUtils.convertToFrontendAmountAsString(amount);
92+
const selectedAmountAsString = amount ? CurrencyUtils.convertToFrontendAmount(amount).toString() : '';
93+
9694
const [currentAmount, setCurrentAmount] = useState(selectedAmountAsString);
9795
const [formError, setFormError] = useState<MaybePhraseKey>('');
9896
const [shouldUpdateSelection, setShouldUpdateSelection] = useState(true);
@@ -125,7 +123,7 @@ function MoneyRequestAmountForm(
125123
};
126124

127125
const initializeAmount = useCallback((newAmount: number) => {
128-
const frontendAmount = CurrencyUtils.convertToFrontendAmountAsString(newAmount);
126+
const frontendAmount = newAmount ? CurrencyUtils.convertToFrontendAmount(newAmount).toString() : '';
129127
setCurrentAmount(frontendAmount);
130128
setSelection({
131129
start: frontendAmount.length,
@@ -134,13 +132,13 @@ function MoneyRequestAmountForm(
134132
}, []);
135133

136134
useEffect(() => {
137-
if (!currency || typeof amount !== 'number' || shouldKeepUserInput) {
135+
if (!currency || typeof amount !== 'number') {
138136
return;
139137
}
140138
initializeAmount(amount);
141139
// we want to re-initialize the state only when the selected tab or amount changes
142140
// eslint-disable-next-line react-hooks/exhaustive-deps
143-
}, [selectedTab, amount, shouldKeepUserInput]);
141+
}, [selectedTab, amount]);
144142

145143
/**
146144
* Sets the selection and the amount accordingly to the value passed to the input
@@ -241,8 +239,13 @@ function MoneyRequestAmountForm(
241239
return;
242240
}
243241

242+
// Update display amount string post-edit to ensure consistency with backend amount
243+
// Reference: https://github.com/Expensify/App/issues/30505
244+
const backendAmount = CurrencyUtils.convertToBackendAmount(Number.parseFloat(currentAmount));
245+
initializeAmount(backendAmount);
246+
244247
onSubmitButtonPress({amount: currentAmount, currency});
245-
}, [currentAmount, taxAmount, isTaxAmountForm, onSubmitButtonPress, currency, formattedTaxAmount]);
248+
}, [currentAmount, taxAmount, isTaxAmountForm, onSubmitButtonPress, currency, formattedTaxAmount, initializeAmount]);
246249

247250
/**
248251
* Input handler to check for a forward-delete key (or keyboard shortcut) press.

src/types/onyx/Transaction.ts

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -111,9 +111,6 @@ type Transaction = OnyxCommon.OnyxValueWithOfflineFeedback<
111111
/** Whether the request is billable */
112112
billable?: boolean;
113113

114-
/** Whether the user input should be kept */
115-
shouldShowOriginalAmount?: boolean;
116-
117114
/** The category name */
118115
category?: string;
119116

tests/unit/CurrencyUtilsTest.ts

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -105,31 +105,18 @@ describe('CurrencyUtils', () => {
105105
});
106106
});
107107

108-
describe('convertToFrontendAmountAsInteger', () => {
108+
describe('convertToFrontendAmount', () => {
109109
test.each([
110110
[2500, 25],
111111
[2550, 25.5],
112112
[25, 0.25],
113113
[2500, 25],
114114
[2500.5, 25], // The backend should never send a decimal .5 value
115-
])('Correctly converts %s to amount in units handled in frontend as an integer', (amount, expectedResult) => {
116-
expect(CurrencyUtils.convertToFrontendAmountAsInteger(amount)).toBe(expectedResult);
115+
])('Correctly converts %s to amount in units handled in frontend', (amount, expectedResult) => {
116+
expect(CurrencyUtils.convertToFrontendAmount(amount)).toBe(expectedResult);
117117
});
118118
});
119119

120-
describe('convertToFrontendAmountAsString', () => {
121-
test.each([
122-
[2500, '25.00'],
123-
[2550, '25.50'],
124-
[25, '0.25'],
125-
[2500.5, '25.00'],
126-
[null, ''],
127-
[undefined, ''],
128-
[0, '0.00'],
129-
])('Correctly converts %s to amount in units handled in frontend as a string', (input, expectedResult) => {
130-
expect(CurrencyUtils.convertToFrontendAmountAsString(input)).toBe(expectedResult);
131-
});
132-
});
133120
describe('convertToDisplayString', () => {
134121
test.each([
135122
[CONST.CURRENCY.USD, 25, '$0.25'],

0 commit comments

Comments
 (0)