diff --git a/Mobile-Expensify b/Mobile-Expensify index 3c9ebae559b5d..4309ffb96b37c 160000 --- a/Mobile-Expensify +++ b/Mobile-Expensify @@ -1 +1 @@ -Subproject commit 3c9ebae559b5d842cd507889cc9098300d83e69a +Subproject commit 4309ffb96b37c3e3d16c8d5c28831a861a14fcdf diff --git a/android/app/build.gradle b/android/app/build.gradle index 6957943b0680b..2ed395c68cf82 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -114,8 +114,8 @@ android { minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion multiDexEnabled rootProject.ext.multiDexEnabled - versionCode 1009031606 - versionName "9.3.16-6" + versionCode 1009031607 + versionName "9.3.16-7" // Supported language variants must be declared here to avoid from being removed during the compilation. // This also helps us to not include unnecessary language variants in the APK. resConfigs "en", "es" diff --git a/ios/NewExpensify/Info.plist b/ios/NewExpensify/Info.plist index 3c85459140286..79fd487875c1a 100644 --- a/ios/NewExpensify/Info.plist +++ b/ios/NewExpensify/Info.plist @@ -44,7 +44,7 @@ CFBundleVersion - 9.3.16.6 + 9.3.16.7 FullStory OrgId diff --git a/ios/NotificationServiceExtension/Info.plist b/ios/NotificationServiceExtension/Info.plist index c5c5fdb3f6cc6..13cc4668f9bc5 100644 --- a/ios/NotificationServiceExtension/Info.plist +++ b/ios/NotificationServiceExtension/Info.plist @@ -13,7 +13,7 @@ CFBundleShortVersionString 9.3.16 CFBundleVersion - 9.3.16.6 + 9.3.16.7 NSExtension NSExtensionPointIdentifier diff --git a/ios/ShareViewController/Info.plist b/ios/ShareViewController/Info.plist index 53518692ef9a9..d68eeb9edaa46 100644 --- a/ios/ShareViewController/Info.plist +++ b/ios/ShareViewController/Info.plist @@ -13,7 +13,7 @@ CFBundleShortVersionString 9.3.16 CFBundleVersion - 9.3.16.6 + 9.3.16.7 NSExtension NSExtensionAttributes diff --git a/package-lock.json b/package-lock.json index fc21abb5095ad..be86fe1c4dc74 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "new.expensify", - "version": "9.3.16-6", + "version": "9.3.16-7", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "new.expensify", - "version": "9.3.16-6", + "version": "9.3.16-7", "hasInstallScript": true, "license": "MIT", "dependencies": { diff --git a/package.json b/package.json index 5307a4f4dff31..ea1aca2768ec3 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "new.expensify", - "version": "9.3.16-6", + "version": "9.3.16-7", "author": "Expensify, Inc.", "homepage": "https://new.expensify.com", "description": "New Expensify is the next generation of Expensify: a reimagination of payments based atop a foundation of chat.", diff --git a/src/components/MoneyRequestConfirmationList.tsx b/src/components/MoneyRequestConfirmationList.tsx index 6bf4357c81820..bf78917609bd4 100755 --- a/src/components/MoneyRequestConfirmationList.tsx +++ b/src/components/MoneyRequestConfirmationList.tsx @@ -24,6 +24,7 @@ import { setIndividualShare, setMoneyRequestAmount, setMoneyRequestCategory, + setMoneyRequestDistance, setMoneyRequestMerchant, setMoneyRequestPendingFields, setMoneyRequestTag, @@ -35,6 +36,7 @@ import {getIsMissingAttendeesViolation} from '@libs/AttendeeUtils'; import {isCategoryDescriptionRequired} from '@libs/CategoryUtils'; import {convertToBackendAmount, convertToDisplayString, convertToDisplayStringWithoutCurrency} from '@libs/CurrencyUtils'; import DistanceRequestUtils from '@libs/DistanceRequestUtils'; +import {calculateGPSDistance} from '@libs/GPSDraftDetailsUtils'; import {calculateAmount, insertTagIntoTransactionTagsString, isMovingTransactionFromTrackExpense as isMovingTransactionFromTrackExpenseUtil} from '@libs/IOUUtils'; import Log from '@libs/Log'; import {validateAmount} from '@libs/MoneyRequestUtils'; @@ -345,8 +347,8 @@ function MoneyRequestConfirmationList({ return; } - setCustomUnitRateID(transactionID, lastSelectedRate, transaction, policy); - }, [customUnitRateID, transactionID, lastSelectedRate, isDistanceRequest, isPolicyExpenseChat, isMovingTransactionFromTrackExpense, transaction, policy]); + setCustomUnitRateID(transactionID, lastSelectedRate); + }, [customUnitRateID, transactionID, lastSelectedRate, isDistanceRequest, isPolicyExpenseChat, isMovingTransactionFromTrackExpense]); const mileageRate = DistanceRequestUtils.getRate({transaction, policy, policyDraft}); const rate = mileageRate.rate; @@ -393,6 +395,19 @@ function MoneyRequestConfirmationList({ const distanceRequestAmount = DistanceRequestUtils.getDistanceRequestAmount(distance, unit ?? CONST.CUSTOM_UNITS.DISTANCE_UNIT_MILES, rate ?? 0); + // Update GPS distance whenever the current distance unit differs from the one that was used + // to calculate the distance stored in transaction.comment.customUnit.quantity + const gpsDistance = transaction?.comment?.customUnit?.quantity; + const gpsDistanceWithCurrentDistanceUnit = calculateGPSDistance(distance, unit); + const shouldUpdateGpsDistance = isGPSDistanceRequest && gpsDistance !== gpsDistanceWithCurrentDistanceUnit; + useEffect(() => { + if (!shouldUpdateGpsDistance || !transactionID || isReadOnly) { + return; + } + + setMoneyRequestDistance(transactionID, gpsDistanceWithCurrentDistanceUnit, true); + }, [shouldUpdateGpsDistance, transactionID, isReadOnly, gpsDistanceWithCurrentDistanceUnit]); + let amountToBeUsed = iouAmount; if (shouldCalculateDistanceAmount) { @@ -499,7 +514,7 @@ function MoneyRequestConfirmationList({ // If there is a distance rate in the policy that matches the rate and unit of the currently selected mileage rate, select it automatically const matchingRate = Object.values(policyRates).find((policyRate) => policyRate.rate === mileageRate.rate && policyRate.unit === mileageRate.unit); if (matchingRate?.customUnitRateID) { - setCustomUnitRateID(transactionID, matchingRate.customUnitRateID, transaction, policy); + setCustomUnitRateID(transactionID, matchingRate.customUnitRateID); return; } @@ -516,7 +531,6 @@ function MoneyRequestConfirmationList({ isMovingTransactionFromTrackExpense, setFormError, clearFormErrors, - transaction, ]); const routeError = Object.values(transaction?.errorFields?.route ?? {}).at(0); diff --git a/src/libs/GPSDraftDetailsUtils.ts b/src/libs/GPSDraftDetailsUtils.ts index ff82b47624704..89c95eae53ca8 100644 --- a/src/libs/GPSDraftDetailsUtils.ts +++ b/src/libs/GPSDraftDetailsUtils.ts @@ -62,7 +62,7 @@ function getGPSCoordinates(gpsDraftDetails: GpsDraftDetails | undefined): string } function calculateGPSDistance(distanceInMeters: number, unit: Unit): number { - return DistanceRequestUtils.convertDistanceUnit(distanceInMeters, unit); + return roundToTwoDecimalPlaces(DistanceRequestUtils.convertDistanceUnit(distanceInMeters, unit)); } function getGPSConvertedDistance(gpsDraftDetails: GpsDraftDetails | undefined, unit: Unit): number { diff --git a/src/libs/actions/IOU/MoneyRequest.ts b/src/libs/actions/IOU/MoneyRequest.ts index 56f70d79e3199..aef318d924b95 100644 --- a/src/libs/actions/IOU/MoneyRequest.ts +++ b/src/libs/actions/IOU/MoneyRequest.ts @@ -661,10 +661,7 @@ function handleMoneyRequestStepDistanceNavigation({ lastSelectedDistanceRates, }); setTransactionReport(transactionID, {reportID: transactionReportID}, true); - // Do not pass transaction and policy so it only updates customUnitRateID without changing distance and distance unit - // as it is set for Manual requests before this function is called and transaction may have - // obsolete customUnit values - setCustomUnitRateID(transactionID, rateID, undefined, undefined); + setCustomUnitRateID(transactionID, rateID); setMoneyRequestParticipantsFromReport(transactionID, targetReport, currentUserAccountID).then(() => { Navigation.navigate(ROUTES.MONEY_REQUEST_STEP_CONFIRMATION.getRoute(CONST.IOU.ACTION.CREATE, iouTypeTrackOrSubmit, transactionID, targetReport?.reportID)); }); diff --git a/src/libs/actions/IOU/index.ts b/src/libs/actions/IOU/index.ts index 61a5db5bd71b9..75225b56990c4 100644 --- a/src/libs/actions/IOU/index.ts +++ b/src/libs/actions/IOU/index.ts @@ -67,7 +67,6 @@ import Navigation, {navigationRef} from '@libs/Navigation/Navigation'; import {isOffline} from '@libs/Network/NetworkStore'; // eslint-disable-next-line @typescript-eslint/no-deprecated import {buildNextStepNew, buildOptimisticNextStep} from '@libs/NextStepUtils'; -import {roundToTwoDecimalPlaces} from '@libs/NumberUtils'; import * as NumberUtils from '@libs/NumberUtils'; import {getManagerMcTestParticipant, getPersonalDetailsForAccountIDs} from '@libs/OptionsListUtils'; import Parser from '@libs/Parser'; @@ -1510,48 +1509,15 @@ function setMoneyRequestReceipt(transactionID: string, source: string, filename: } /** - * Set custom unit rateID for the transaction draft, also updates quantity and distanceUnit - * if passed transaction previously had it to make sure that transaction does not have inconsistent - * states (for example distanceUnit not matching distance unit of the new customUnitRateID) + * Set custom unit rateID for the transaction draft */ -function setCustomUnitRateID(transactionID: string, customUnitRateID: string | undefined, transaction: OnyxEntry, policy: OnyxEntry) { +function setCustomUnitRateID(transactionID: string, customUnitRateID: string | undefined) { const isFakeP2PRate = customUnitRateID === CONST.CUSTOM_UNITS.FAKE_P2P_ID; - - let newDistanceUnit: Unit | undefined; - let newQuantity: number | undefined; - - if (customUnitRateID && transaction) { - const distanceRate = isFakeP2PRate - ? DistanceRequestUtils.getRate({transaction, useTransactionDistanceUnit: false, policy}) - : DistanceRequestUtils.getRateByCustomUnitRateID({policy, customUnitRateID}); - - const transactionDistanceUnit = transaction.comment?.customUnit?.distanceUnit; - const transactionQuantity = transaction.comment?.customUnit?.quantity; - - const shouldUpdateDistanceUnit = !!transactionDistanceUnit && !!distanceRate?.unit; - const shouldUpdateQuantity = transactionQuantity !== null && transactionQuantity !== undefined; - - if (shouldUpdateDistanceUnit) { - newDistanceUnit = distanceRate.unit; - } - if (shouldUpdateQuantity && !!distanceRate?.unit) { - const newQuantityInMeters = getDistanceInMeters(transaction, transactionDistanceUnit); - - // getDistanceInMeters returns 0 only if there was not enough input to get the correct - // distance in meters or if the current transaction distance is 0 - if (newQuantityInMeters !== 0) { - newQuantity = DistanceRequestUtils.convertDistanceUnit(newQuantityInMeters, distanceRate.unit); - } - } - } - Onyx.merge(`${ONYXKEYS.COLLECTION.TRANSACTION_DRAFT}${transactionID}`, { comment: { customUnit: { customUnitRateID, ...(!isFakeP2PRate && {defaultP2PRate: null}), - distanceUnit: newDistanceUnit, - quantity: newQuantity, }, }, }); @@ -1699,8 +1665,8 @@ function addSubrate(transaction: OnyxEntry, currentIndex: Onyx.set(`${ONYXKEYS.COLLECTION.TRANSACTION_DRAFT}${transaction?.transactionID}`, newTransaction); } -function setMoneyRequestDistance(transactionID: string, distanceAsFloat: number, isDraft: boolean, distanceUnit: Unit) { - Onyx.merge(`${isDraft ? ONYXKEYS.COLLECTION.TRANSACTION_DRAFT : ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`, {comment: {customUnit: {quantity: distanceAsFloat, distanceUnit}}}); +function setMoneyRequestDistance(transactionID: string, distanceAsFloat: number, isDraft: boolean) { + Onyx.merge(`${isDraft ? ONYXKEYS.COLLECTION.TRANSACTION_DRAFT : ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`, {comment: {customUnit: {quantity: distanceAsFloat}}}); } /** @@ -1762,7 +1728,6 @@ function setMoneyRequestDistanceRate(transactionID: string, customUnitRateID: st if (distanceRate?.unit && distanceRate?.unit !== transaction?.comment?.customUnit?.distanceUnit) { newDistance = DistanceRequestUtils.convertDistanceUnit(getDistanceInMeters(transaction, transaction?.comment?.customUnit?.distanceUnit), distanceRate.unit); } - Onyx.merge(`${isDraft ? ONYXKEYS.COLLECTION.TRANSACTION_DRAFT : ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`, { comment: { customUnit: { @@ -7174,7 +7139,7 @@ function trackExpense(params: CreateTrackExpenseParams) { attendees: attendees ? JSON.stringify(attendees) : undefined, currency, comment, - distance: distance !== undefined ? roundToTwoDecimalPlaces(distance) : undefined, + distance, created, merchant, iouReportID: iouReport?.reportID, @@ -8047,7 +8012,7 @@ function createDistanceRequest(distanceRequestInformation: CreateDistanceRequest createdIOUReportActionID, reportPreviewReportActionID: reportPreviewAction.reportActionID, waypoints: JSON.stringify(sanitizedWaypoints), - distance: distance !== undefined ? roundToTwoDecimalPlaces(distance) : undefined, + distance, receipt, odometerStart, odometerEnd, diff --git a/src/pages/iou/request/step/IOURequestStepDestination.tsx b/src/pages/iou/request/step/IOURequestStepDestination.tsx index 0b1723e224fd5..c8945ffe40ac9 100644 --- a/src/pages/iou/request/step/IOURequestStepDestination.tsx +++ b/src/pages/iou/request/step/IOURequestStepDestination.tsx @@ -111,7 +111,7 @@ function IOURequestStepDestination({ setCustomUnitID(transactionID, customUnit.customUnitID); setMoneyRequestCategory(transactionID, customUnit?.defaultCategory ?? '', undefined); } - setCustomUnitRateID(transactionID, destination.keyForList ?? '', transaction, policy); + setCustomUnitRateID(transactionID, destination.keyForList ?? ''); setMoneyRequestCurrency(transactionID, destination.currency); clearSubrates(transactionID); } diff --git a/src/pages/iou/request/step/IOURequestStepDistanceManual.tsx b/src/pages/iou/request/step/IOURequestStepDistanceManual.tsx index 33886d82aaad8..54dfe622b1c56 100644 --- a/src/pages/iou/request/step/IOURequestStepDistanceManual.tsx +++ b/src/pages/iou/request/step/IOURequestStepDistanceManual.tsx @@ -29,7 +29,7 @@ import Navigation from '@libs/Navigation/Navigation'; import {roundToTwoDecimalPlaces} from '@libs/NumberUtils'; import {isArchivedReport, isPolicyExpenseChat as isPolicyExpenseChatUtils} from '@libs/ReportUtils'; import shouldUseDefaultExpensePolicyUtil from '@libs/shouldUseDefaultExpensePolicy'; -import {getDistanceInMeters, getRateID} from '@libs/TransactionUtils'; +import {getRateID} from '@libs/TransactionUtils'; import variables from '@styles/variables'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; @@ -101,12 +101,8 @@ function IOURequestStepDistanceManual({ const shouldUseDefaultExpensePolicy = useMemo(() => shouldUseDefaultExpensePolicyUtil(iouType, defaultExpensePolicy), [iouType, defaultExpensePolicy]); const customUnitRateID = getRateID(transaction); - // to make sure the correct distance amount and unit will be shown we use distance unit - // from defaultExpensePolicy or current report's policy instead of from transaction and - // then we use transaction data (distanceUnit and quantity) for conversions - const unit = DistanceRequestUtils.getRate({transaction, policy: shouldUseDefaultExpensePolicy ? defaultExpensePolicy : policy, useTransactionDistanceUnit: false}).unit; - const distanceInMeters = getDistanceInMeters(transaction, transaction?.comment?.customUnit?.distanceUnit ? transaction.comment.customUnit.distanceUnit : unit); - const distance = typeof transaction?.comment?.customUnit?.quantity === 'number' ? roundToTwoDecimalPlaces(DistanceRequestUtils.convertDistanceUnit(distanceInMeters, unit)) : undefined; + const unit = DistanceRequestUtils.getRate({transaction, policy: shouldUseDefaultExpensePolicy ? defaultExpensePolicy : policy}).unit; + const distance = typeof transaction?.comment?.customUnit?.quantity === 'number' ? roundToTwoDecimalPlaces(transaction.comment.customUnit.quantity) : undefined; const isASAPSubmitBetaEnabled = isBetaEnabled(CONST.BETAS.ASAP_SUBMIT); useEffect(() => { @@ -153,7 +149,7 @@ function IOURequestStepDistanceManual({ const navigateToNextPage = useCallback( (amount: string) => { const distanceAsFloat = roundToTwoDecimalPlaces(parseFloat(amount)); - setMoneyRequestDistance(transactionID, distanceAsFloat, isTransactionDraft, unit); + setMoneyRequestDistance(transactionID, distanceAsFloat, isTransactionDraft); if (action === CONST.IOU.ACTION.EDIT) { if (distance !== distanceAsFloat) { @@ -247,7 +243,6 @@ function IOURequestStepDistanceManual({ policyCategories, parentReportNextStep, recentWaypoints, - unit, selfDMReport, betas, ], diff --git a/src/pages/iou/request/step/IOURequestStepDistanceOdometer.tsx b/src/pages/iou/request/step/IOURequestStepDistanceOdometer.tsx index a350b7f7ff0b6..81d191ff6d5ac 100644 --- a/src/pages/iou/request/step/IOURequestStepDistanceOdometer.tsx +++ b/src/pages/iou/request/step/IOURequestStepDistanceOdometer.tsx @@ -357,7 +357,7 @@ function IOURequestStepDistanceOdometer({ const calculatedDistance = roundToTwoDecimalPlaces(distance); // Store total distance in transaction.comment.customUnit.quantity - setMoneyRequestDistance(transactionID, calculatedDistance, isTransactionDraft, unit); + setMoneyRequestDistance(transactionID, calculatedDistance, isTransactionDraft); if (isEditing) { // Update existing transaction @@ -509,7 +509,7 @@ function IOURequestStepDistanceOdometer({ lastSelectedDistanceRates, }); setTransactionReport(transactionID, {reportID: transactionReportID}, true); - setCustomUnitRateID(transactionID, rateID, transaction, policy); + setCustomUnitRateID(transactionID, rateID); setMoneyRequestParticipantsFromReport(transactionID, activePolicyExpenseChat, currentUserPersonalDetails.accountID).then(() => { Navigation.navigate( ROUTES.MONEY_REQUEST_STEP_CONFIRMATION.getRoute( diff --git a/src/pages/iou/request/step/IOURequestStepParticipants.tsx b/src/pages/iou/request/step/IOURequestStepParticipants.tsx index 85ea9da513881..1bc4ad207a973 100644 --- a/src/pages/iou/request/step/IOURequestStepParticipants.tsx +++ b/src/pages/iou/request/step/IOURequestStepParticipants.tsx @@ -191,7 +191,7 @@ function IOURequestStepParticipants({ const rateID = CONST.CUSTOM_UNITS.FAKE_P2P_ID; for (const transaction of transactions) { - setCustomUnitRateID(transaction.transactionID, rateID, transaction, activePolicy); + setCustomUnitRateID(transaction.transactionID, rateID); const shouldSetParticipantAutoAssignment = iouType === CONST.IOU.TYPE.CREATE; setMoneyRequestParticipantsFromReport( transaction.transactionID, @@ -215,19 +215,7 @@ function IOURequestStepParticipants({ } }); }); - }, [ - selfDMReportID, - transactions, - action, - initialTransactionID, - waitForKeyboardDismiss, - iouType, - selfDMReport, - currentUserPersonalDetails.accountID, - isActivePolicyRequest, - backTo, - activePolicy, - ]); + }, [selfDMReportID, transactions, action, initialTransactionID, waitForKeyboardDismiss, iouType, selfDMReport, currentUserPersonalDetails.accountID, isActivePolicyRequest, backTo]); const addParticipant = useCallback( (val: Participant[]) => { @@ -264,11 +252,11 @@ function IOURequestStepParticipants({ if (transactions.length > 0) { for (const transaction of transactions) { - setCustomUnitRateID(transaction.transactionID, rateID, transaction, policy); + setCustomUnitRateID(transaction.transactionID, rateID); } } else { // Fallback to using initialTransactionID directly - setCustomUnitRateID(initialTransactionID, rateID, undefined, policy); + setCustomUnitRateID(initialTransactionID, rateID); } } diff --git a/src/pages/iou/request/step/IOURequestStepReport.tsx b/src/pages/iou/request/step/IOURequestStepReport.tsx index 7ea899b114ac4..26fa92cca3e61 100644 --- a/src/pages/iou/request/step/IOURequestStepReport.tsx +++ b/src/pages/iou/request/step/IOURequestStepReport.tsx @@ -128,7 +128,7 @@ function IOURequestStepReport({route, transaction}: IOURequestStepReportProps) { // Clear subrates, and update customUnitID if policy changed for per diem transactions if (policyChanged && isPerDiemTransaction) { setCustomUnitID(transaction.transactionID, newCustomUnitID ?? CONST.CUSTOM_UNITS.FAKE_P2P_ID); - setCustomUnitRateID(transaction.transactionID, undefined, transaction, newPolicy); + setCustomUnitRateID(transaction.transactionID, undefined); clearSubrates(transaction.transactionID); } diff --git a/src/pages/iou/request/step/IOURequestStepUpgrade.tsx b/src/pages/iou/request/step/IOURequestStepUpgrade.tsx index e112d4cbd131d..a19e7033d8723 100644 --- a/src/pages/iou/request/step/IOURequestStepUpgrade.tsx +++ b/src/pages/iou/request/step/IOURequestStepUpgrade.tsx @@ -96,7 +96,7 @@ function IOURequestStepUpgrade({ } setTransactionReport(transactionID, {reportID: expenseReportID}, true); // Let the confirmation step decide the distance rate because policy data is not fully available at this step - setCustomUnitRateID(transactionID, '-1', undefined, undefined); + setCustomUnitRateID(transactionID, '-1'); Navigation.setParams({reportID: expenseReportID}); navigateWithMicrotask(ROUTES.WORKSPACE_CREATE_DISTANCE_RATE_UPGRADE.getRoute(policyID, transactionID, expenseReportID));