@@ -6,13 +6,15 @@ import {getCurrencySymbol} from '@libs/CurrencyUtils';
66import DateUtils from '@libs/DateUtils' ;
77import DistanceRequestUtils from '@libs/DistanceRequestUtils' ;
88import getCurrentPosition from '@libs/getCurrentPosition' ;
9+ import { getGPSRoutes , getGPSWaypoints } from '@libs/GPSDraftDetailsUtils' ;
910import { calculateDefaultReimbursable , formatCurrentUserToAttendee , getExistingTransactionID , navigateToConfirmationPage , navigateToParticipantPage } from '@libs/IOUUtils' ;
1011import { toLocaleDigit } from '@libs/LocaleDigitUtils' ;
1112import Log from '@libs/Log' ;
1213import Navigation from '@libs/Navigation/Navigation' ;
1314import { roundToTwoDecimalPlaces } from '@libs/NumberUtils' ;
1415import { getManagerMcTestParticipant , getParticipantsOption , getReportOption } from '@libs/OptionsListUtils' ;
1516import { getCustomUnitID } from '@libs/PerDiemRequestUtils' ;
17+ import { getDistanceRateCustomUnit } from '@libs/PolicyUtils' ;
1618import {
1719 generateReportID ,
1820 getPolicyExpenseChat ,
@@ -25,7 +27,13 @@ import {
2527import type { OptionData } from '@libs/ReportUtils' ;
2628import shouldUseDefaultExpensePolicy from '@libs/shouldUseDefaultExpensePolicy' ;
2729import { 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' ;
2937import type { ReceiptFile } from '@pages/iou/request/step/IOURequestStepScan/types' ;
3038import { setTransactionReport } from '@userActions/Transaction' ;
3139import { getRemoveDraftTransactionsByIDsData , removeDraftTransactionsByIDs } from '@userActions/TransactionEdit' ;
@@ -39,6 +47,7 @@ import ROUTES from '@src/ROUTES';
3947import 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';
5867import type { Comment , Receipt , WaypointCollection } from '@src/types/onyx/Transaction' ;
5968import { isEmptyObject } from '@src/types/utils/EmptyObject' ;
6069import type { GpsPoint , IOURequestType } from './index' ;
61- import { setCustomUnitRateID , setMoneyRequestDistance , setMoneyRequestMerchant , setMoneyRequestPendingFields } from './index' ;
70+ import { getAllTransactionDrafts , setMoneyRequestMerchant , setMoneyRequestPendingFields } from './index' ;
6271import { createDistanceRequest , resetSplitShares , startSplitBill } from './Split' ;
6372import { 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+
11361317export {
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} ;
11531347export type { MoneyRequestStepScanParticipantsFlowParams } ;
0 commit comments