Skip to content

Commit 0b2f55f

Browse files
authored
Merge pull request #39059 from software-mansion-labs/@szymczak/TaxRequestPage+TaxAmmountPage
[TS migration] Migrate IOURequestStepTaxRatePage and IOURequestStepTaxAmountPage to TypeScript
2 parents 38f2d7c + 38e9558 commit 0b2f55f

9 files changed

+182
-180
lines changed

src/components/TaxPicker.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import ONYXKEYS from '@src/ONYXKEYS';
1111
import type {Policy} from '@src/types/onyx';
1212
import SelectionList from './SelectionList';
1313
import RadioListItem from './SelectionList/RadioListItem';
14-
import type {ListItem} from './SelectionList/types';
1514

1615
type TaxPickerOnyxProps = {
1716
/** The policy which the user has access to and which the report is tied to */
@@ -33,7 +32,7 @@ type TaxPickerProps = TaxPickerOnyxProps & {
3332
insets?: EdgeInsets;
3433

3534
/** Callback to fire when a tax is pressed */
36-
onSubmit: (tax: ListItem) => void;
35+
onSubmit: (tax: OptionsListUtils.TaxRatesOption) => void;
3736
};
3837

3938
function TaxPicker({selectedTaxRate = '', policy, insets, onSubmit}: TaxPickerProps) {

src/libs/Navigation/types.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -382,7 +382,7 @@ type MoneyRequestNavigatorParamList = {
382382
backTo: Routes;
383383
};
384384
[SCREENS.MONEY_REQUEST.STEP_TAX_AMOUNT]: {
385-
iouType: string;
385+
iouType: ValueOf<typeof CONST.IOU.TYPE>;
386386
transactionID: string;
387387
reportID: string;
388388
backTo: Routes;
@@ -395,7 +395,7 @@ type MoneyRequestNavigatorParamList = {
395395
backTo: Routes;
396396
};
397397
[SCREENS.MONEY_REQUEST.STEP_TAX_RATE]: {
398-
iouType: string;
398+
iouType: ValueOf<typeof CONST.IOU.TYPE>;
399399
transactionID: string;
400400
reportID: string;
401401
backTo: Routes;

src/libs/OptionsListUtils.ts

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,22 @@ type CategorySection = CategorySectionBase & {
9898
data: Option[];
9999
};
100100

101+
type TaxRatesOption = {
102+
text?: string;
103+
code?: string;
104+
searchText?: string;
105+
tooltipText?: string;
106+
isDisabled?: boolean;
107+
keyForList?: string;
108+
data: Partial<TaxRate>;
109+
};
110+
111+
type TaxSection = {
112+
title: string | undefined;
113+
shouldShow: boolean;
114+
data: TaxRatesOption[];
115+
};
116+
101117
type CategoryTreeSection = CategorySectionBase & {
102118
data: OptionTree[];
103119
};
@@ -1240,7 +1256,7 @@ function sortTaxRates(taxRates: TaxRates): TaxRate[] {
12401256
/**
12411257
* Builds the options for taxRates
12421258
*/
1243-
function getTaxRatesOptions(taxRates: Array<Partial<TaxRate>>): Option[] {
1259+
function getTaxRatesOptions(taxRates: Array<Partial<TaxRate>>): TaxRatesOption[] {
12441260
return taxRates.map((taxRate) => ({
12451261
text: taxRate.modifiedName,
12461262
keyForList: taxRate.modifiedName,
@@ -1254,7 +1270,7 @@ function getTaxRatesOptions(taxRates: Array<Partial<TaxRate>>): Option[] {
12541270
/**
12551271
* Builds the section list for tax rates
12561272
*/
1257-
function getTaxRatesSection(taxRates: TaxRatesWithDefault | undefined, selectedOptions: Category[], searchInputValue: string): CategorySection[] {
1273+
function getTaxRatesSection(taxRates: TaxRatesWithDefault | undefined, selectedOptions: Category[], searchInputValue: string): TaxSection[] {
12581274
const policyRatesSections = [];
12591275

12601276
const taxes = transformedTaxRates(taxRates);
@@ -2125,4 +2141,4 @@ export {
21252141
getTaxRatesSection,
21262142
};
21272143

2128-
export type {MemberForList, CategorySection, GetOptions, OptionList, SearchOption, PayeePersonalDetails, Category};
2144+
export type {MemberForList, CategorySection, GetOptions, OptionList, SearchOption, PayeePersonalDetails, Category, TaxRatesOption};

src/libs/actions/IOU.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ import * as LocalePhoneNumber from '@libs/LocalePhoneNumber';
3535
import * as Localize from '@libs/Localize';
3636
import Navigation from '@libs/Navigation/Navigation';
3737
import * as NextStepUtils from '@libs/NextStepUtils';
38+
import type {TaxRatesOption} from '@libs/OptionsListUtils';
3839
import Permissions from '@libs/Permissions';
3940
import * as PhoneNumber from '@libs/PhoneNumber';
4041
import * as PolicyUtils from '@libs/PolicyUtils';
@@ -54,7 +55,7 @@ import type {ErrorFields, Errors} from '@src/types/onyx/OnyxCommon';
5455
import type {PaymentMethodType} from '@src/types/onyx/OriginalMessage';
5556
import type ReportAction from '@src/types/onyx/ReportAction';
5657
import type {OnyxData} from '@src/types/onyx/Request';
57-
import type {Comment, Receipt, ReceiptSource, TaxRate, TransactionChanges, WaypointCollection} from '@src/types/onyx/Transaction';
58+
import type {Comment, Receipt, ReceiptSource, TransactionChanges, WaypointCollection} from '@src/types/onyx/Transaction';
5859
import type {EmptyObject} from '@src/types/utils/EmptyObject';
5960
import {isEmptyObject} from '@src/types/utils/EmptyObject';
6061
import * as CachedPDFPaths from './CachedPDFPaths';
@@ -5112,7 +5113,7 @@ function setMoneyRequestCurrency(currency: string) {
51125113
Onyx.merge(ONYXKEYS.IOU, {currency});
51135114
}
51145115

5115-
function setMoneyRequestTaxRate(transactionID: string, taxRate: TaxRate) {
5116+
function setMoneyRequestTaxRate(transactionID: string, taxRate: TaxRatesOption) {
51165117
Onyx.merge(`${ONYXKEYS.COLLECTION.TRANSACTION_DRAFT}${transactionID}`, {taxRate});
51175118
}
51185119

Original file line numberDiff line numberDiff line change
@@ -1,84 +1,69 @@
11
import {useFocusEffect} from '@react-navigation/native';
2-
import lodashGet from 'lodash/get';
3-
import PropTypes from 'prop-types';
42
import React, {useCallback, useEffect, useRef} from 'react';
3+
import type {OnyxEntry} from 'react-native-onyx';
54
import {withOnyx} from 'react-native-onyx';
6-
import taxPropTypes from '@components/taxPropTypes';
7-
import transactionPropTypes from '@components/transactionPropTypes';
5+
import type {BaseTextInputRef} from '@components/TextInput/BaseTextInput/types';
86
import useLocalize from '@hooks/useLocalize';
9-
import compose from '@libs/compose';
107
import * as CurrencyUtils from '@libs/CurrencyUtils';
118
import Navigation from '@libs/Navigation/Navigation';
129
import * as TransactionUtils from '@libs/TransactionUtils';
10+
import type {CurrentMoney} from '@pages/iou/steps/MoneyRequestAmountForm';
1311
import MoneyRequestAmountForm from '@pages/iou/steps/MoneyRequestAmountForm';
14-
import reportPropTypes from '@pages/reportPropTypes';
1512
import * as IOU from '@userActions/IOU';
1613
import CONST from '@src/CONST';
1714
import ONYXKEYS from '@src/ONYXKEYS';
1815
import ROUTES from '@src/ROUTES';
19-
import IOURequestStepRoutePropTypes from './IOURequestStepRoutePropTypes';
16+
import type SCREENS from '@src/SCREENS';
17+
import type {Policy, Transaction} from '@src/types/onyx';
2018
import StepScreenWrapper from './StepScreenWrapper';
2119
import withFullTransactionOrNotFound from './withFullTransactionOrNotFound';
20+
import type {WithWritableReportOrNotFoundProps} from './withWritableReportOrNotFound';
2221
import withWritableReportOrNotFound from './withWritableReportOrNotFound';
2322

24-
const propTypes = {
25-
/** Navigation route context info provided by react navigation */
26-
route: IOURequestStepRoutePropTypes.isRequired,
27-
28-
/* Onyx Props */
29-
/** The report that the transaction belongs to */
30-
report: reportPropTypes,
31-
32-
/** The transaction object being modified in Onyx */
33-
transaction: transactionPropTypes,
34-
35-
/* Onyx Props */
36-
/** The policy of the report */
37-
policy: PropTypes.shape({
38-
/** Collection of tax rates attached to a policy */
39-
taxRates: taxPropTypes,
40-
}),
23+
type IOURequestStepTaxAmountPageOnyxProps = {
24+
policy: OnyxEntry<Policy>;
4125
};
4226

43-
const defaultProps = {
44-
report: {},
45-
policy: {},
46-
transaction: {},
47-
};
27+
type IOURequestStepTaxAmountPageProps = IOURequestStepTaxAmountPageOnyxProps &
28+
WithWritableReportOrNotFoundProps<typeof SCREENS.MONEY_REQUEST.STEP_TAX_AMOUNT> & {
29+
transaction: OnyxEntry<Transaction>;
30+
};
4831

49-
const getTaxAmount = (transaction, defaultTaxValue) => {
50-
const percentage = (transaction.taxRate ? transaction.taxRate.data.value : defaultTaxValue) || '';
51-
return CurrencyUtils.convertToBackendAmount(Number.parseFloat(TransactionUtils.calculateTaxAmount(percentage, transaction.amount)));
52-
};
32+
function getTaxAmount(transaction: OnyxEntry<Transaction>, defaultTaxValue: string | undefined): number | undefined {
33+
if (!transaction?.amount) {
34+
return;
35+
}
36+
const percentage = (transaction?.taxRate ? transaction?.taxRate?.data?.value : defaultTaxValue) ?? '';
37+
return CurrencyUtils.convertToBackendAmount(TransactionUtils.calculateTaxAmount(percentage, transaction?.amount));
38+
}
5339

5440
function IOURequestStepTaxAmountPage({
5541
route: {
5642
params: {iouType, reportID, transactionID, backTo},
5743
},
5844
transaction,
59-
transaction: {currency},
6045
report,
6146
policy,
62-
}) {
47+
}: IOURequestStepTaxAmountPageProps) {
6348
const {translate} = useLocalize();
64-
const textInput = useRef(null);
49+
const textInput = useRef<BaseTextInputRef | null>();
6550
const isEditing = Navigation.getActiveRoute().includes('taxAmount');
6651

67-
const focusTimeoutRef = useRef(null);
52+
const focusTimeoutRef = useRef<NodeJS.Timeout>();
6853

6954
const isSaveButtonPressed = useRef(false);
70-
const originalCurrency = useRef(null);
71-
const taxRates = lodashGet(policy, 'taxRates', {});
55+
const originalCurrency = useRef<string>();
56+
const taxRates = policy?.taxRates;
7257

7358
useEffect(() => {
74-
if (transaction.originalCurrency) {
59+
if (transaction?.originalCurrency) {
7560
originalCurrency.current = transaction.originalCurrency;
76-
} else {
77-
originalCurrency.current = currency;
78-
IOU.setMoneyRequestOriginalCurrency_temporaryForRefactor(transactionID, currency);
61+
} else if (transaction?.currency) {
62+
originalCurrency.current = transaction.currency;
63+
IOU.setMoneyRequestOriginalCurrency_temporaryForRefactor(transactionID, transaction?.currency);
7964
}
8065
return () => {
81-
if (isSaveButtonPressed.current) {
66+
if (isSaveButtonPressed.current || !originalCurrency.current) {
8267
return;
8368
}
8469
IOU.setMoneyRequestCurrency_temporaryForRefactor(transactionID, originalCurrency.current, true);
@@ -88,7 +73,7 @@ function IOURequestStepTaxAmountPage({
8873

8974
useFocusEffect(
9075
useCallback(() => {
91-
focusTimeoutRef.current = setTimeout(() => textInput.current && textInput.current.focus(), CONST.ANIMATED_TRANSITION);
76+
focusTimeoutRef.current = setTimeout(() => textInput.current?.focus(), CONST.ANIMATED_TRANSITION);
9277
return () => {
9378
if (!focusTimeoutRef.current) {
9479
return;
@@ -111,12 +96,13 @@ function IOURequestStepTaxAmountPage({
11196
);
11297
};
11398

114-
const updateTaxAmount = (currentAmount) => {
99+
const updateTaxAmount = (currentAmount: CurrentMoney) => {
115100
isSaveButtonPressed.current = true;
116101
const amountInSmallestCurrencyUnits = CurrencyUtils.convertToBackendAmount(Number.parseFloat(currentAmount.amount));
117102
IOU.setMoneyRequestTaxAmount(transactionID, amountInSmallestCurrencyUnits, true);
118103

119-
IOU.setMoneyRequestCurrency_temporaryForRefactor(transactionID, currency || CONST.CURRENCY.USD, true);
104+
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
105+
IOU.setMoneyRequestCurrency_temporaryForRefactor(transactionID, transaction?.currency || CONST.CURRENCY.USD, true);
120106

121107
if (backTo) {
122108
Navigation.goBack(backTo);
@@ -126,7 +112,7 @@ function IOURequestStepTaxAmountPage({
126112
// If a reportID exists in the report object, it's because the user started this flow from using the + button in the composer
127113
// inside a report. In this case, the participants can be automatically assigned from the report and the user can skip the participants step and go straight
128114
// to the confirm step.
129-
if (report.reportID) {
115+
if (report?.reportID) {
130116
// TODO: Is this really needed at all?
131117
IOU.setMoneyRequestParticipantsFromReport(transactionID, report);
132118
Navigation.navigate(ROUTES.MONEY_REQUEST_STEP_CONFIRMATION.getRoute(CONST.IOU.ACTION.CREATE, iouType, transactionID, reportID));
@@ -148,9 +134,9 @@ function IOURequestStepTaxAmountPage({
148134
>
149135
<MoneyRequestAmountForm
150136
isEditing={isEditing}
151-
currency={currency}
152-
amount={transaction.taxAmount}
153-
taxAmount={getTaxAmount(transaction, taxRates.defaultValue)}
137+
currency={transaction?.currency}
138+
amount={transaction?.taxAmount}
139+
taxAmount={getTaxAmount(transaction, taxRates?.defaultValue)}
154140
ref={(e) => (textInput.current = e)}
155141
onCurrencyButtonPress={navigateToCurrencySelectionPage}
156142
onSubmitButtonPress={updateTaxAmount}
@@ -159,16 +145,17 @@ function IOURequestStepTaxAmountPage({
159145
);
160146
}
161147

162-
IOURequestStepTaxAmountPage.propTypes = propTypes;
163-
IOURequestStepTaxAmountPage.defaultProps = defaultProps;
164148
IOURequestStepTaxAmountPage.displayName = 'IOURequestStepTaxAmountPage';
165149

166-
export default compose(
167-
withWritableReportOrNotFound,
168-
withFullTransactionOrNotFound,
169-
withOnyx({
170-
policy: {
171-
key: ({report}) => `${ONYXKEYS.COLLECTION.POLICY}${report ? report.policyID : '0'}`,
172-
},
173-
}),
174-
)(IOURequestStepTaxAmountPage);
150+
const IOURequestStepTaxAmountPageWithOnyx = withOnyx<IOURequestStepTaxAmountPageProps, IOURequestStepTaxAmountPageOnyxProps>({
151+
policy: {
152+
key: ({report}) => `${ONYXKEYS.COLLECTION.POLICY}${report ? report.policyID : '0'}`,
153+
},
154+
})(IOURequestStepTaxAmountPage);
155+
156+
// eslint-disable-next-line rulesdir/no-negated-variables
157+
const IOURequestStepTaxAmountPageWithWritableReportOrNotFound = withWritableReportOrNotFound(IOURequestStepTaxAmountPageWithOnyx);
158+
// eslint-disable-next-line rulesdir/no-negated-variables
159+
const IOURequestStepTaxAmountPageWithFullTransactionOrNotFound = withFullTransactionOrNotFound(IOURequestStepTaxAmountPageWithWritableReportOrNotFound);
160+
161+
export default IOURequestStepTaxAmountPageWithFullTransactionOrNotFound;

0 commit comments

Comments
 (0)