Skip to content

Commit db308d2

Browse files
DylanDylannclaude
andcommitted
refactor: extract tax/category/distance/time setters from IOU/index.ts to MoneyRequest.ts
Moves 13 setter functions + 1 type from src/libs/actions/IOU/index.ts to src/libs/actions/IOU/MoneyRequest.ts: Tax/Category: - setMoneyRequestTaxRate - setMoneyRequestTaxValue - setMoneyRequestTaxAmount - setMoneyRequestTaxRateValues (+ TaxRateValues type) - setMoneyRequestCategory Time: - setMoneyRequestTimeRate - setMoneyRequestTimeCount Distance / custom unit: - setCustomUnitRateID - setGPSTransactionDraftData - resetDraftTransactionsCustomUnit - setCustomUnitID - setMoneyRequestDistance - setMoneyRequestDistanceRate Continues the IOU/index.ts cleanup after PR Expensify#90157 (init/start) and PR Expensify#90299 (participants). No re-exports — external callers updated directly. DAG stays clean (MoneyRequest.ts -> index.ts getter edge only). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent cb5db71 commit db308d2

29 files changed

Lines changed: 239 additions & 246 deletions

src/components/MoneyRequestConfirmationList/DistanceRequestController.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ import {useCurrencyListActions} from '@hooks/useCurrencyList';
44
import useLocalize from '@hooks/useLocalize';
55
import useOnyx from '@hooks/useOnyx';
66
import usePrevious from '@hooks/usePrevious';
7-
import {setCustomUnitRateID, setMoneyRequestAmount, setMoneyRequestMerchant, setMoneyRequestPendingFields} from '@libs/actions/IOU';
7+
import {setMoneyRequestAmount, setMoneyRequestMerchant, setMoneyRequestPendingFields} from '@libs/actions/IOU';
8+
import {setCustomUnitRateID} from '@libs/actions/IOU/MoneyRequest';
89
import {setSplitShares} from '@libs/actions/IOU/Split';
910
import DistanceRequestUtils from '@libs/DistanceRequestUtils';
1011
import type {MileageRate} from '@libs/DistanceRequestUtils';

src/components/MoneyRequestConfirmationList/FieldAutoSelector.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import {useEffect} from 'react';
22
import type {OnyxEntry} from 'react-native-onyx';
33
import type {ValueOf} from 'type-fest';
4-
import {setMoneyRequestCategory, setMoneyRequestTag} from '@libs/actions/IOU';
4+
import {setMoneyRequestTag} from '@libs/actions/IOU';
5+
import {setMoneyRequestCategory} from '@libs/actions/IOU/MoneyRequest';
56
import {insertTagIntoTransactionTagsString} from '@libs/IOUUtils';
67
import {getTag} from '@libs/TransactionUtils';
78
import type {Policy, PolicyCategories, PolicyTagLists, Transaction} from '@src/types/onyx';

src/components/MoneyRequestConfirmationList/TaxController.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import {useEffect} from 'react';
2-
import {setMoneyRequestTaxAmount, setMoneyRequestTaxRateValues} from '@libs/actions/IOU';
2+
import {setMoneyRequestTaxAmount, setMoneyRequestTaxRateValues} from '@libs/actions/IOU/MoneyRequest';
33

44
type TaxControllerProps = {
55
transactionID: string | undefined;

src/hooks/useParticipantSubmission.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,14 @@ import {isPaidGroupPolicy} from '@libs/PolicyUtils';
99
import {findSelfDMReportID, generateReportID, isInvoiceRoomWithID} from '@libs/ReportUtils';
1010
import {shouldRestrictUserBillableActions} from '@libs/SubscriptionUtils';
1111
import {isDistanceRequest} from '@libs/TransactionUtils';
12-
import {resetDraftTransactionsCustomUnit, setCustomUnitRateID, setMoneyRequestCategory, setMoneyRequestTag} from '@userActions/IOU';
13-
import {setMoneyRequestParticipants, setMoneyRequestParticipantsFromReport} from '@userActions/IOU/MoneyRequest';
12+
import {setMoneyRequestTag} from '@userActions/IOU';
13+
import {
14+
resetDraftTransactionsCustomUnit,
15+
setCustomUnitRateID,
16+
setMoneyRequestCategory,
17+
setMoneyRequestParticipants,
18+
setMoneyRequestParticipantsFromReport,
19+
} from '@userActions/IOU/MoneyRequest';
1420
import {setSplitShares} from '@userActions/IOU/Split';
1521
import {createDraftWorkspace, generateDefaultWorkspaceName} from '@userActions/Policy/Policy';
1622
import CONST from '@src/CONST';

src/libs/actions/IOU/MoneyRequest.ts

Lines changed: 196 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,15 @@ import {getCurrencySymbol} from '@libs/CurrencyUtils';
66
import DateUtils from '@libs/DateUtils';
77
import DistanceRequestUtils from '@libs/DistanceRequestUtils';
88
import getCurrentPosition from '@libs/getCurrentPosition';
9+
import {getGPSRoutes, getGPSWaypoints} from '@libs/GPSDraftDetailsUtils';
910
import {calculateDefaultReimbursable, formatCurrentUserToAttendee, getExistingTransactionID, navigateToConfirmationPage, navigateToParticipantPage} from '@libs/IOUUtils';
1011
import {toLocaleDigit} from '@libs/LocaleDigitUtils';
1112
import Log from '@libs/Log';
1213
import Navigation from '@libs/Navigation/Navigation';
1314
import {roundToTwoDecimalPlaces} from '@libs/NumberUtils';
1415
import {getManagerMcTestParticipant, getParticipantsOption, getReportOption} from '@libs/OptionsListUtils';
1516
import {getCustomUnitID} from '@libs/PerDiemRequestUtils';
17+
import {getDistanceRateCustomUnit} from '@libs/PolicyUtils';
1618
import {
1719
generateReportID,
1820
getPolicyExpenseChat,
@@ -25,7 +27,13 @@ import {
2527
import type {OptionData} from '@libs/ReportUtils';
2628
import shouldUseDefaultExpensePolicy from '@libs/shouldUseDefaultExpensePolicy';
2729
import {cancelSpan, startSpan} from '@libs/telemetry/activeSpans';
28-
import {getDefaultTaxCode, getValidWaypoints} from '@libs/TransactionUtils';
30+
import {
31+
getCategoryTaxDetails,
32+
getDefaultTaxCode,
33+
getDistanceInMeters,
34+
getValidWaypoints,
35+
isOdometerDistanceRequest as isOdometerDistanceRequestTransactionUtils,
36+
} from '@libs/TransactionUtils';
2937
import type {ReceiptFile} from '@pages/iou/request/step/IOURequestStepScan/types';
3038
import {setTransactionReport} from '@userActions/Transaction';
3139
import {getRemoveDraftTransactionsByIDsData, removeDraftTransactionsByIDs} from '@userActions/TransactionEdit';
@@ -39,6 +47,7 @@ import ROUTES from '@src/ROUTES';
3947
import type {
4048
Beta,
4149
BillingGraceEndPeriod,
50+
GpsDraftDetails,
4251
IntroSelected,
4352
LastSelectedDistanceRates,
4453
OdometerDraft,
@@ -58,7 +67,7 @@ import type {Unit} from '@src/types/onyx/Policy';
5867
import type {Comment, Receipt, WaypointCollection} from '@src/types/onyx/Transaction';
5968
import {isEmptyObject} from '@src/types/utils/EmptyObject';
6069
import type {GpsPoint, IOURequestType} from './index';
61-
import {setCustomUnitRateID, setMoneyRequestDistance, setMoneyRequestMerchant, setMoneyRequestPendingFields} from './index';
70+
import {getAllTransactionDrafts, setMoneyRequestMerchant, setMoneyRequestPendingFields} from './index';
6271
import {createDistanceRequest, resetSplitShares, startSplitBill} from './Split';
6372
import {requestMoney, trackExpense} from './TrackExpense';
6473

@@ -1133,6 +1142,178 @@ function setMultipleMoneyRequestParticipantsFromReport(transactionIDs: string[],
11331142
return Onyx.mergeCollection(ONYXKEYS.COLLECTION.TRANSACTION_DRAFT, updatedTransactions);
11341143
}
11351144

1145+
function setMoneyRequestTaxRate(transactionID: string, taxCode: string | null, isDraft = true) {
1146+
Onyx.merge(`${isDraft ? ONYXKEYS.COLLECTION.TRANSACTION_DRAFT : ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`, {taxCode});
1147+
}
1148+
1149+
function setMoneyRequestTaxValue(transactionID: string, taxValue: string | null, isDraft = true) {
1150+
Onyx.merge(`${isDraft ? ONYXKEYS.COLLECTION.TRANSACTION_DRAFT : ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`, {taxValue});
1151+
}
1152+
1153+
function setMoneyRequestTaxAmount(transactionID: string, taxAmount: number | null, isDraft = true) {
1154+
Onyx.merge(`${isDraft ? ONYXKEYS.COLLECTION.TRANSACTION_DRAFT : ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`, {taxAmount});
1155+
}
1156+
1157+
type TaxRateValues = {
1158+
taxCode: string | null;
1159+
taxAmount: number | null;
1160+
taxValue: string | null;
1161+
};
1162+
1163+
function setMoneyRequestTaxRateValues(transactionID: string, taxRateValues: TaxRateValues, isDraft = true) {
1164+
Onyx.merge(`${isDraft ? ONYXKEYS.COLLECTION.TRANSACTION_DRAFT : ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`, {...taxRateValues});
1165+
}
1166+
1167+
/**
1168+
* Sets the category for a money request transaction draft.
1169+
* @param transactionID - The transaction ID
1170+
* @param category - The category name
1171+
* @param policy - The policy object, or undefined for P2P transactions where tax info should be cleared
1172+
* @param isMovingFromTrackExpense - If the expense is moved from Track Expense
1173+
*/
1174+
function setMoneyRequestCategory(transactionID: string, category: string, policy: OnyxEntry<Policy>, isMovingFromTrackExpense?: boolean) {
1175+
Onyx.merge(`${ONYXKEYS.COLLECTION.TRANSACTION_DRAFT}${transactionID}`, {category});
1176+
if (isMovingFromTrackExpense) {
1177+
return;
1178+
}
1179+
if (!policy) {
1180+
setMoneyRequestTaxRateValues(transactionID, {taxCode: '', taxAmount: null, taxValue: null});
1181+
return;
1182+
}
1183+
const transaction = getAllTransactionDrafts()[`${ONYXKEYS.COLLECTION.TRANSACTION_DRAFT}${transactionID}`];
1184+
const {categoryTaxCode, categoryTaxAmount, categoryTaxValue} = getCategoryTaxDetails(category, transaction, policy);
1185+
if (categoryTaxCode && categoryTaxAmount !== undefined && categoryTaxValue) {
1186+
setMoneyRequestTaxRateValues(transactionID, {taxCode: categoryTaxCode, taxAmount: categoryTaxAmount, taxValue: categoryTaxValue});
1187+
}
1188+
}
1189+
1190+
function setMoneyRequestTimeRate(transactionID: string, rate: number, isDraft: boolean) {
1191+
Onyx.merge(`${isDraft ? ONYXKEYS.COLLECTION.TRANSACTION_DRAFT : ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`, {comment: {units: {rate}}});
1192+
}
1193+
1194+
function setMoneyRequestTimeCount(transactionID: string, count: number, isDraft: boolean) {
1195+
Onyx.merge(`${isDraft ? ONYXKEYS.COLLECTION.TRANSACTION_DRAFT : ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`, {comment: {units: {count}}});
1196+
}
1197+
1198+
/**
1199+
* Set custom unit rateID for the transaction draft, also updates quantity and distanceUnit
1200+
* if passed transaction previously had it to make sure that transaction does not have inconsistent
1201+
* states (for example distanceUnit not matching distance unit of the new customUnitRateID)
1202+
*/
1203+
function setCustomUnitRateID(transactionID: string, customUnitRateID: string | undefined, transaction: OnyxEntry<Transaction>, policy: OnyxEntry<Policy>) {
1204+
const isFakeP2PRate = customUnitRateID === CONST.CUSTOM_UNITS.FAKE_P2P_ID;
1205+
1206+
let newDistanceUnit: Unit | undefined;
1207+
let newQuantity: number | undefined;
1208+
1209+
if (customUnitRateID && transaction) {
1210+
const distanceRate = isFakeP2PRate
1211+
? DistanceRequestUtils.getRate({transaction: undefined, policy: undefined, useTransactionDistanceUnit: false, isFakeP2PRate})
1212+
: DistanceRequestUtils.getRateByCustomUnitRateID({policy, customUnitRateID});
1213+
1214+
const transactionDistanceUnit = transaction.comment?.customUnit?.distanceUnit;
1215+
const transactionQuantity = transaction.comment?.customUnit?.quantity;
1216+
1217+
const shouldUpdateDistanceUnit = !!transactionDistanceUnit && !!distanceRate?.unit;
1218+
const shouldUpdateQuantity = transactionQuantity !== null && transactionQuantity !== undefined;
1219+
1220+
if (shouldUpdateDistanceUnit) {
1221+
newDistanceUnit = distanceRate.unit;
1222+
}
1223+
if (shouldUpdateQuantity && !!distanceRate?.unit) {
1224+
const newQuantityInMeters = getDistanceInMeters(transaction, transactionDistanceUnit);
1225+
1226+
// getDistanceInMeters returns 0 only if there was not enough input to get the correct
1227+
// distance in meters or if the current transaction distance is 0
1228+
if (newQuantityInMeters !== 0) {
1229+
newQuantity = DistanceRequestUtils.convertDistanceUnit(newQuantityInMeters, distanceRate.unit);
1230+
}
1231+
}
1232+
}
1233+
Onyx.merge(`${ONYXKEYS.COLLECTION.TRANSACTION_DRAFT}${transactionID}`, {
1234+
comment: {
1235+
customUnit: {
1236+
customUnitRateID,
1237+
...(!isFakeP2PRate && {defaultP2PRate: null}),
1238+
distanceUnit: newDistanceUnit,
1239+
quantity: newQuantity,
1240+
},
1241+
},
1242+
});
1243+
}
1244+
1245+
function setGPSTransactionDraftData(transactionID: string, gpsDraftDetails: GpsDraftDetails | undefined, distance: number) {
1246+
const waypoints = getGPSWaypoints(gpsDraftDetails);
1247+
const routes = getGPSRoutes(gpsDraftDetails);
1248+
1249+
Onyx.merge(`${ONYXKEYS.COLLECTION.TRANSACTION_DRAFT}${transactionID}`, {
1250+
comment: {
1251+
customUnit: {quantity: distance},
1252+
waypoints,
1253+
},
1254+
routes,
1255+
});
1256+
}
1257+
1258+
/**
1259+
* Revert custom unit of the draft transaction to the original transaction's value
1260+
*/
1261+
function resetDraftTransactionsCustomUnit(transaction: OnyxEntry<Transaction>) {
1262+
if (!transaction?.transactionID) {
1263+
return;
1264+
}
1265+
Onyx.merge(`${ONYXKEYS.COLLECTION.TRANSACTION_DRAFT}${transaction?.transactionID}`, {
1266+
comment: {
1267+
customUnit: transaction.comment?.customUnit ?? {},
1268+
},
1269+
});
1270+
}
1271+
1272+
/**
1273+
* Set custom unit ID for the transaction draft
1274+
*/
1275+
function setCustomUnitID(transactionID: string, customUnitID: string) {
1276+
Onyx.merge(`${ONYXKEYS.COLLECTION.TRANSACTION_DRAFT}${transactionID}`, {comment: {customUnit: {customUnitID}}});
1277+
}
1278+
1279+
function setMoneyRequestDistance(transactionID: string, distanceAsFloat: number, isDraft: boolean, distanceUnit: Unit) {
1280+
Onyx.merge(`${isDraft ? ONYXKEYS.COLLECTION.TRANSACTION_DRAFT : ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`, {comment: {customUnit: {quantity: distanceAsFloat, distanceUnit}}});
1281+
}
1282+
1283+
/**
1284+
* Set the distance rate of a transaction.
1285+
* Used when creating a new transaction or moving an existing one from Self DM
1286+
*/
1287+
function setMoneyRequestDistanceRate(currentTransaction: OnyxEntry<Transaction>, customUnitRateID: string, policy: OnyxEntry<Policy>, isDraft: boolean) {
1288+
if (!currentTransaction) {
1289+
Log.warn('setMoneyRequestDistanceRate is called without a valid transaction, skipping setting distance rate.');
1290+
return;
1291+
}
1292+
if (policy) {
1293+
Onyx.merge(ONYXKEYS.NVP_LAST_SELECTED_DISTANCE_RATES, {[policy.id]: customUnitRateID});
1294+
}
1295+
1296+
const newDistanceUnit = getDistanceRateCustomUnit(policy)?.attributes?.unit;
1297+
const transactionID = currentTransaction?.transactionID;
1298+
const transaction = isDraft ? getAllTransactionDrafts()[`${ONYXKEYS.COLLECTION.TRANSACTION_DRAFT}${transactionID}`] : currentTransaction;
1299+
1300+
let newDistance;
1301+
if (newDistanceUnit && newDistanceUnit !== transaction?.comment?.customUnit?.distanceUnit && !isOdometerDistanceRequestTransactionUtils(transaction)) {
1302+
newDistance = DistanceRequestUtils.convertDistanceUnit(getDistanceInMeters(transaction, transaction?.comment?.customUnit?.distanceUnit), newDistanceUnit);
1303+
}
1304+
1305+
Onyx.merge(`${isDraft ? ONYXKEYS.COLLECTION.TRANSACTION_DRAFT : ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`, {
1306+
comment: {
1307+
customUnit: {
1308+
customUnitRateID,
1309+
...(!!policy && {defaultP2PRate: null}),
1310+
...(newDistanceUnit && {distanceUnit: newDistanceUnit}),
1311+
...(newDistance && {quantity: newDistance}),
1312+
},
1313+
},
1314+
});
1315+
}
1316+
11361317
export {
11371318
createTransaction,
11381319
handleMoneyRequestStepScanParticipants,
@@ -1149,5 +1330,18 @@ export {
11491330
getIOURequestPolicyID,
11501331
updateLastLocationPermissionPrompt,
11511332
setMultipleMoneyRequestParticipantsFromReport,
1333+
setMoneyRequestTaxRate,
1334+
setMoneyRequestTaxValue,
1335+
setMoneyRequestTaxAmount,
1336+
setMoneyRequestTaxRateValues,
1337+
setMoneyRequestCategory,
1338+
setMoneyRequestTimeRate,
1339+
setMoneyRequestTimeCount,
1340+
setCustomUnitRateID,
1341+
setGPSTransactionDraftData,
1342+
resetDraftTransactionsCustomUnit,
1343+
setCustomUnitID,
1344+
setMoneyRequestDistance,
1345+
setMoneyRequestDistanceRate,
11521346
};
11531347
export type {MoneyRequestStepScanParticipantsFlowParams};

0 commit comments

Comments
 (0)