From 48f47b48ff194d3d0d9f27c9bff6e4c1405b1ce0 Mon Sep 17 00:00:00 2001 From: GCyganek Date: Wed, 11 Mar 2026 17:24:55 +0100 Subject: [PATCH 1/3] Simplify isXRequest utils to only use iouRequestType --- src/libs/GPSDraftDetailsUtils.ts | 2 - src/libs/TransactionUtils/index.ts | 168 +++++------------------------ 2 files changed, 28 insertions(+), 142 deletions(-) diff --git a/src/libs/GPSDraftDetailsUtils.ts b/src/libs/GPSDraftDetailsUtils.ts index 612b7c2d558f..7a19cf2a7e17 100644 --- a/src/libs/GPSDraftDetailsUtils.ts +++ b/src/libs/GPSDraftDetailsUtils.ts @@ -21,7 +21,6 @@ function getGPSWaypoints(gpsDraftDetails: GpsDraftDetails | undefined): Waypoint ...(firstPoint ? { waypoint0: { - keyForList: 'gps_start', // temporary for hasGPSWaypoints() lat: firstPoint.lat, lng: firstPoint.long, address: startAddress, @@ -32,7 +31,6 @@ function getGPSWaypoints(gpsDraftDetails: GpsDraftDetails | undefined): Waypoint ...(lastPoint ? { waypoint1: { - keyForList: 'gps_stop', // temporary for hasGPSWaypoints() lat: lastPoint.lat, lng: lastPoint.long, address: endAddress, diff --git a/src/libs/TransactionUtils/index.ts b/src/libs/TransactionUtils/index.ts index 06426bf23b32..d7762c869046 100644 --- a/src/libs/TransactionUtils/index.ts +++ b/src/libs/TransactionUtils/index.ts @@ -135,140 +135,62 @@ type BuildOptimisticTransactionParams = { isDemoTransactionParam?: boolean; }; -function hasDistanceCustomUnit(transaction: OnyxEntry | Partial): boolean { - return transaction?.comment?.type === CONST.TRANSACTION.TYPE.CUSTOM_UNIT && transaction?.comment?.customUnit?.name === CONST.CUSTOM_UNITS.NAME_DISTANCE; -} - -function isDistanceRequest(transaction: OnyxEntry): boolean { - // This is used during the expense creation flow before the transaction has been saved to the server - if (transaction && Object.hasOwn(transaction, 'iouRequestType')) { - return ( - transaction?.iouRequestType === CONST.IOU.REQUEST_TYPE.DISTANCE || - transaction?.iouRequestType === CONST.IOU.REQUEST_TYPE.DISTANCE_MAP || - transaction?.iouRequestType === CONST.IOU.REQUEST_TYPE.DISTANCE_ODOMETER || - transaction?.iouRequestType === CONST.IOU.REQUEST_TYPE.DISTANCE_GPS || - transaction?.iouRequestType === CONST.IOU.REQUEST_TYPE.DISTANCE_MANUAL - ); - } - - // This is the case for transaction objects once they have been saved to the server - return hasDistanceCustomUnit(transaction); -} - -function isDistanceTypeRequest(transaction: OnyxEntry): boolean { - // This is used during the expense creation flow before the transaction has been saved to the server - if (transaction && Object.hasOwn(transaction, 'iouRequestType')) { - return transaction?.iouRequestType === CONST.IOU.REQUEST_TYPE.DISTANCE; +function isRequestOfType(transaction: OnyxEntry | Partial, type: IOURequestType): boolean { + if (!transaction || !Object.hasOwn(transaction, 'iouRequestType')) { + return false; } - // This is the case for transaction objects once they have been saved to the server - return hasDistanceCustomUnit(transaction); + return transaction.iouRequestType === type; } -/** - * todo: Currently there is no way to tell server map transaction object from - * server GPS transaction object, this will be discussed and updated later. - * To fix this temporarily we set keyForList of GPS waypoints to 'gps_start' and 'gps_end' - * and use that to determine if it's a GPS or Map transaction. This should be changed before - * the first GPS release. - */ -function hasGPSWaypoints(transaction: OnyxEntry) { - const waypoints = transaction?.comment?.waypoints; - - if (!waypoints) { +function isDistanceRequest(transaction: OnyxEntry): boolean { + if (!transaction || !Object.hasOwn(transaction, 'iouRequestType')) { return false; } - const waypoint = Object.values(waypoints).at(0); + return ( + transaction?.iouRequestType === CONST.IOU.REQUEST_TYPE.DISTANCE || + transaction?.iouRequestType === CONST.IOU.REQUEST_TYPE.DISTANCE_MAP || + transaction?.iouRequestType === CONST.IOU.REQUEST_TYPE.DISTANCE_ODOMETER || + transaction?.iouRequestType === CONST.IOU.REQUEST_TYPE.DISTANCE_GPS || + transaction?.iouRequestType === CONST.IOU.REQUEST_TYPE.DISTANCE_MANUAL + ); +} - return !!waypoint?.keyForList?.startsWith('gps'); +function isDistanceTypeRequest(transaction: OnyxEntry): boolean { + isRequestOfType(transaction, CONST.IOU.REQUEST_TYPE.DISTANCE); } function isMapDistanceRequest(transaction: OnyxEntry): boolean { - // This is used during the expense creation flow before the transaction has been saved to the server - if (transaction && Object.hasOwn(transaction, 'iouRequestType')) { - return transaction?.iouRequestType === CONST.IOU.REQUEST_TYPE.DISTANCE_MAP; - } - - // This is the case for transaction objects once they have been saved to the server - return hasDistanceCustomUnit(transaction) && !hasGPSWaypoints(transaction); + isRequestOfType(transaction, CONST.IOU.REQUEST_TYPE.DISTANCE_MAP); } function isGPSDistanceRequest(transaction: OnyxEntry): boolean { - // This is used during the expense creation flow before the transaction has been saved to the server - if (transaction && Object.hasOwn(transaction, 'iouRequestType')) { - return transaction?.iouRequestType === CONST.IOU.REQUEST_TYPE.DISTANCE_GPS; - } - - // This is the case for transaction objects once they have been saved to the server - return hasGPSWaypoints(transaction); + isRequestOfType(transaction, CONST.IOU.REQUEST_TYPE.DISTANCE_GPS); } -function isManualDistanceRequest(transaction: OnyxEntry, isUpdatedMergeTransaction = false): boolean { - // This is used during the expense creation flow before the transaction has been saved to the server - if (transaction && Object.hasOwn(transaction, 'iouRequestType') && !isUpdatedMergeTransaction) { - return transaction?.iouRequestType === CONST.IOU.REQUEST_TYPE.DISTANCE_MANUAL; - } - - // This is the case for transaction objects once they have been saved to the server - // Exclude odometer requests which also have no waypoints but have odometer readings - return ( - hasDistanceCustomUnit(transaction) && - isEmptyObject(transaction?.comment?.waypoints) && - transaction?.comment?.odometerStart === undefined && - transaction?.comment?.odometerEnd === undefined - ); +function isManualDistanceRequest(transaction: OnyxEntry): boolean { + isRequestOfType(transaction, CONST.IOU.REQUEST_TYPE.DISTANCE_MANUAL); } function isOdometerDistanceRequest(transaction: OnyxEntry): boolean { - // This is used during the expense creation flow before the transaction has been saved to the server - if (transaction && Object.hasOwn(transaction, 'iouRequestType')) { - return transaction?.iouRequestType === CONST.IOU.REQUEST_TYPE.DISTANCE_ODOMETER; - } - - // This is the case for transaction objects once they have been saved to the server - // Odometer requests have odometerStart and odometerEnd in comment, and no waypoints - return ( - hasDistanceCustomUnit(transaction) && - isEmptyObject(transaction?.comment?.waypoints) && - (transaction?.comment?.odometerStart !== undefined || transaction?.comment?.odometerEnd !== undefined) - ); + isRequestOfType(transaction, CONST.IOU.REQUEST_TYPE.DISTANCE_ODOMETER); } function isScanRequest(transaction: OnyxEntry | Partial): boolean { - // This is used during the expense creation flow before the transaction has been saved to the server - if (transaction && Object.hasOwn(transaction, 'iouRequestType')) { - return transaction?.iouRequestType === CONST.IOU.REQUEST_TYPE.SCAN; - } - - // Distance requests can have a receipt source (for the map), so we need to exclude them - if (hasDistanceCustomUnit(transaction)) { - return false; - } - - return !!transaction?.receipt?.source && transaction?.amount === 0; + isRequestOfType(transaction, CONST.IOU.REQUEST_TYPE.SCAN); } function isPerDiemRequest(transaction: OnyxEntry): boolean { - // This is used during the expense creation flow before the transaction has been saved to the server - if (transaction && Object.hasOwn(transaction, 'iouRequestType')) { - return transaction?.iouRequestType === CONST.IOU.REQUEST_TYPE.PER_DIEM; - } - - // This is the case for transaction objects once they have been saved to the server - const type = transaction?.comment?.type; - const customUnitName = transaction?.comment?.customUnit?.name; - return type === CONST.TRANSACTION.TYPE.CUSTOM_UNIT && customUnitName === CONST.CUSTOM_UNITS.NAME_PER_DIEM_INTERNATIONAL; + isRequestOfType(transaction, CONST.IOU.REQUEST_TYPE.PER_DIEM); } function isTimeRequest(transaction: OnyxEntry): boolean { - // This is used during the expense creation flow before the transaction has been saved to the server - if (transaction && Object.hasOwn(transaction, 'iouRequestType')) { - return transaction?.iouRequestType === CONST.IOU.REQUEST_TYPE.TIME; - } + isRequestOfType(transaction, CONST.IOU.REQUEST_TYPE.TIME); +} - // This is the case for transaction objects once they have been saved to the server - return transaction?.comment?.type === CONST.TRANSACTION.TYPE.TIME; +function isManualRequest(transaction: Transaction): boolean { + isRequestOfType(transaction, CONST.IOU.REQUEST_TYPE.MANUAL); } function isCorporateCardTransaction(transaction: OnyxEntry): boolean { @@ -276,32 +198,7 @@ function isCorporateCardTransaction(transaction: OnyxEntry): boolea } function getRequestType(transaction: OnyxEntry): IOURequestType { - if (isOdometerDistanceRequest(transaction)) { - return CONST.IOU.REQUEST_TYPE.DISTANCE_ODOMETER; - } - if (isManualDistanceRequest(transaction)) { - return CONST.IOU.REQUEST_TYPE.DISTANCE_MANUAL; - } - if (isMapDistanceRequest(transaction)) { - return CONST.IOU.REQUEST_TYPE.DISTANCE_MAP; - } - if (isDistanceTypeRequest(transaction)) { - return CONST.IOU.REQUEST_TYPE.DISTANCE; - } - if (isScanRequest(transaction)) { - return CONST.IOU.REQUEST_TYPE.SCAN; - } - if (isPerDiemRequest(transaction)) { - return CONST.IOU.REQUEST_TYPE.PER_DIEM; - } - if (isTimeRequest(transaction)) { - return CONST.IOU.REQUEST_TYPE.TIME; - } - if (isGPSDistanceRequest(transaction)) { - return CONST.IOU.REQUEST_TYPE.DISTANCE_GPS; - } - - return CONST.IOU.REQUEST_TYPE.MANUAL; + return transaction?.iouRequestType ?? CONST.IOU.REQUEST_TYPE.MANUAL; } /** @@ -381,15 +278,6 @@ function getExpenseTypeTranslationKey(expenseType: ValueOf): boolean { const merchant = getMerchant(transaction); From 3d04cf0a9fa702d85be5ea7e7ca1055c207ebdd7 Mon Sep 17 00:00:00 2001 From: GCyganek Date: Fri, 13 Mar 2026 16:41:15 +0100 Subject: [PATCH 2/3] Fix typescript --- src/libs/TransactionUtils/index.ts | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/libs/TransactionUtils/index.ts b/src/libs/TransactionUtils/index.ts index 92cc529b9a73..a4b18f66b08c 100644 --- a/src/libs/TransactionUtils/index.ts +++ b/src/libs/TransactionUtils/index.ts @@ -159,39 +159,39 @@ function isDistanceRequest(transaction: OnyxEntry): boolean { } function isDistanceTypeRequest(transaction: OnyxEntry): boolean { - isRequestOfType(transaction, CONST.IOU.REQUEST_TYPE.DISTANCE); + return isRequestOfType(transaction, CONST.IOU.REQUEST_TYPE.DISTANCE); } function isMapDistanceRequest(transaction: OnyxEntry): boolean { - isRequestOfType(transaction, CONST.IOU.REQUEST_TYPE.DISTANCE_MAP); + return isRequestOfType(transaction, CONST.IOU.REQUEST_TYPE.DISTANCE_MAP); } function isGPSDistanceRequest(transaction: OnyxEntry): boolean { - isRequestOfType(transaction, CONST.IOU.REQUEST_TYPE.DISTANCE_GPS); + return isRequestOfType(transaction, CONST.IOU.REQUEST_TYPE.DISTANCE_GPS); } function isManualDistanceRequest(transaction: OnyxEntry): boolean { - isRequestOfType(transaction, CONST.IOU.REQUEST_TYPE.DISTANCE_MANUAL); + return isRequestOfType(transaction, CONST.IOU.REQUEST_TYPE.DISTANCE_MANUAL); } function isOdometerDistanceRequest(transaction: OnyxEntry): boolean { - isRequestOfType(transaction, CONST.IOU.REQUEST_TYPE.DISTANCE_ODOMETER); + return isRequestOfType(transaction, CONST.IOU.REQUEST_TYPE.DISTANCE_ODOMETER); } function isScanRequest(transaction: OnyxEntry | Partial): boolean { - isRequestOfType(transaction, CONST.IOU.REQUEST_TYPE.SCAN); + return isRequestOfType(transaction, CONST.IOU.REQUEST_TYPE.SCAN); } function isPerDiemRequest(transaction: OnyxEntry): boolean { - isRequestOfType(transaction, CONST.IOU.REQUEST_TYPE.PER_DIEM); + return isRequestOfType(transaction, CONST.IOU.REQUEST_TYPE.PER_DIEM); } function isTimeRequest(transaction: OnyxEntry): boolean { - isRequestOfType(transaction, CONST.IOU.REQUEST_TYPE.TIME); + return isRequestOfType(transaction, CONST.IOU.REQUEST_TYPE.TIME); } function isManualRequest(transaction: Transaction): boolean { - isRequestOfType(transaction, CONST.IOU.REQUEST_TYPE.MANUAL); + return isRequestOfType(transaction, CONST.IOU.REQUEST_TYPE.MANUAL); } function isCorporateCardTransaction(transaction: OnyxEntry): boolean { From 3f3e62716c86dd8cbf5c34a03dc74c891724c04d Mon Sep 17 00:00:00 2001 From: GCyganek Date: Fri, 13 Mar 2026 16:48:34 +0100 Subject: [PATCH 3/3] fix isManualDistanceRequestTransactionUtils() call --- src/components/ReportActionItem/MoneyRequestView.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/ReportActionItem/MoneyRequestView.tsx b/src/components/ReportActionItem/MoneyRequestView.tsx index e4f492357f52..89215f2f52ed 100644 --- a/src/components/ReportActionItem/MoneyRequestView.tsx +++ b/src/components/ReportActionItem/MoneyRequestView.tsx @@ -274,7 +274,7 @@ function MoneyRequestView({ } = getTransactionDetails(transaction, undefined, undefined, allowNegativeAmount, false, currentUserPersonalDetails) ?? {}; const isEmptyMerchant = isInvalidMerchantValue(transactionMerchant); const isDistanceRequest = isDistanceRequestTransactionUtils(transaction); - const isManualDistanceRequest = isManualDistanceRequestTransactionUtils(transaction, !!mergeTransactionID); + const isManualDistanceRequest = isManualDistanceRequestTransactionUtils(transaction); const isGPSDistanceRequest = isGPSDistanceRequestTransactionUtils(transaction); const isOdometerDistanceRequest = isOdometerDistanceRequestTransactionUtils(transaction); const isMapDistanceRequest = isMapDistanceRequestTransactionUtils(transaction) || isDistanceTypeRequest(transaction);