From f601fa303d1e01a11024e21c4adf609931b29d10 Mon Sep 17 00:00:00 2001 From: OSBotify Date: Tue, 23 Apr 2024 19:13:28 +0000 Subject: [PATCH 1/3] Update version to 1.4.64-4 (cherry picked from commit bebeed1020f39acbbe1de68e4d0cb1a19c1463d3) --- android/app/build.gradle | 4 ++-- ios/NewExpensify/Info.plist | 7 ++++++- ios/NewExpensifyTests/Info.plist | 2 +- ios/NotificationServiceExtension/Info.plist | 2 +- package-lock.json | 4 ++-- package.json | 2 +- 6 files changed, 13 insertions(+), 8 deletions(-) diff --git a/android/app/build.gradle b/android/app/build.gradle index 547fbc7a985e..2f53f89b8b1e 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -98,8 +98,8 @@ android { minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion multiDexEnabled rootProject.ext.multiDexEnabled - versionCode 1001046403 - versionName "1.4.64-3" + versionCode 1001046404 + versionName "1.4.64-4" // 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 54a8c0b2c31e..642b8f9b1ca9 100644 --- a/ios/NewExpensify/Info.plist +++ b/ios/NewExpensify/Info.plist @@ -40,7 +40,12 @@ CFBundleVersion - 1.4.64.3 + 1.4.64.4 + FullStory + + OrgId + o-1WN56P-na1 + ITSAppUsesNonExemptEncryption LSApplicationQueriesSchemes diff --git a/ios/NewExpensifyTests/Info.plist b/ios/NewExpensifyTests/Info.plist index 0b28ad3a629e..21e9b1b8641f 100644 --- a/ios/NewExpensifyTests/Info.plist +++ b/ios/NewExpensifyTests/Info.plist @@ -19,6 +19,6 @@ CFBundleSignature ???? CFBundleVersion - 1.4.64.3 + 1.4.64.4 diff --git a/ios/NotificationServiceExtension/Info.plist b/ios/NotificationServiceExtension/Info.plist index f1ec8bcebb0c..c4ae046a1e5d 100644 --- a/ios/NotificationServiceExtension/Info.plist +++ b/ios/NotificationServiceExtension/Info.plist @@ -13,7 +13,7 @@ CFBundleShortVersionString 1.4.64 CFBundleVersion - 1.4.64.3 + 1.4.64.4 NSExtension NSExtensionPointIdentifier diff --git a/package-lock.json b/package-lock.json index 0d2fc35b439e..ee98190ae8d6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "new.expensify", - "version": "1.4.64-3", + "version": "1.4.64-4", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "new.expensify", - "version": "1.4.64-3", + "version": "1.4.64-4", "hasInstallScript": true, "license": "MIT", "dependencies": { diff --git a/package.json b/package.json index d30f1d2174e8..549f1d11a13c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "new.expensify", - "version": "1.4.64-3", + "version": "1.4.64-4", "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.", From fa748ea42d2d799a03e42fcc7649521e3d3bbb1c Mon Sep 17 00:00:00 2001 From: Neil Marcellini Date: Tue, 23 Apr 2024 12:12:12 -0700 Subject: [PATCH 2/3] Merge pull request #40711 from koko57/feat/36985-create-new-rate-field-followups [CP Staging] Feat/36985 create new rate field followups (cherry picked from commit 7e5b43611275355d7aae58e50d148da5ef299842) --- .../MoneyRequestConfirmationList.tsx | 5 +- .../MoneyRequestPreviewContent.tsx | 2 +- .../ReportActionItem/MoneyRequestView.tsx | 29 ++++++--- .../ReportActionItem/ReportPreview.tsx | 2 +- src/languages/en.ts | 2 +- src/languages/es.ts | 2 +- src/libs/DistanceRequestUtils.ts | 61 +++++++------------ src/libs/ReportUtils.ts | 4 +- src/libs/actions/IOU.ts | 4 +- .../request/step/IOURequestStepDistance.tsx | 6 +- .../step/IOURequestStepDistanceRate.tsx | 2 +- 11 files changed, 55 insertions(+), 64 deletions(-) diff --git a/src/components/MoneyRequestConfirmationList.tsx b/src/components/MoneyRequestConfirmationList.tsx index 99901dd261de..552b849e74a3 100755 --- a/src/components/MoneyRequestConfirmationList.tsx +++ b/src/components/MoneyRequestConfirmationList.tsx @@ -749,7 +749,6 @@ function MoneyRequestConfirmationList({ style={[styles.moneyRequestMenuItem]} titleStyle={styles.flex1} onPress={() => Navigation.navigate(ROUTES.MONEY_REQUEST_STEP_DISTANCE.getRoute(action, iouType, transactionID, reportID, Navigation.getActiveRouteWithoutParams()))} - // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing disabled={didConfirm} // todo: handle edit for transaction while moving from track expense interactive={!isReadOnly && !isMovingTransactionFromTrackExpense} @@ -767,9 +766,7 @@ function MoneyRequestConfirmationList({ description={translate('common.distance')} style={[styles.moneyRequestMenuItem]} titleStyle={styles.flex1} - onPress={() => - Navigation.navigate(ROUTES.MONEY_REQUEST_STEP_DISTANCE.getRoute(CONST.IOU.ACTION.CREATE, iouType, transactionID, reportID, Navigation.getActiveRouteWithoutParams())) - } + onPress={() => Navigation.navigate(ROUTES.MONEY_REQUEST_STEP_DISTANCE.getRoute(action, iouType, transactionID, reportID, Navigation.getActiveRouteWithoutParams()))} disabled={didConfirm} interactive={!isReadOnly} /> diff --git a/src/components/ReportActionItem/MoneyRequestPreview/MoneyRequestPreviewContent.tsx b/src/components/ReportActionItem/MoneyRequestPreview/MoneyRequestPreviewContent.tsx index 8994d456904a..7f70a3e538a9 100644 --- a/src/components/ReportActionItem/MoneyRequestPreview/MoneyRequestPreviewContent.tsx +++ b/src/components/ReportActionItem/MoneyRequestPreview/MoneyRequestPreviewContent.tsx @@ -196,7 +196,7 @@ function MoneyRequestPreviewContent({ } if (isFetchingWaypointsFromServer && !requestAmount) { - return translate('iou.routePending'); + return translate('iou.fieldPending'); } return CurrencyUtils.convertToDisplayString(requestAmount, requestCurrency); diff --git a/src/components/ReportActionItem/MoneyRequestView.tsx b/src/components/ReportActionItem/MoneyRequestView.tsx index f337f2f40c71..1eaeafdc655f 100644 --- a/src/components/ReportActionItem/MoneyRequestView.tsx +++ b/src/components/ReportActionItem/MoneyRequestView.tsx @@ -67,8 +67,8 @@ type MoneyRequestViewOnyxPropsWithoutTransaction = { /** The actions from the parent report */ parentReportActions: OnyxEntry; - /** The rates for the policy */ - rates: Record; + /** The distance rates from the policy */ + distanceRates: Record; }; type MoneyRequestViewPropsWithoutTransaction = MoneyRequestViewOnyxPropsWithoutTransaction & { @@ -95,7 +95,7 @@ function MoneyRequestView({ policy, transactionViolations, shouldShowAnimatedBackground, - rates, + distanceRates, }: MoneyRequestViewProps) { const theme = useTheme(); const styles = useThemeStyles(); @@ -103,8 +103,9 @@ function MoneyRequestView({ const {isOffline} = useNetwork(); const {isSmallScreenWidth} = useWindowDimensions(); const {translate, toLocaleDigit} = useLocalize(); - const {canUseViolations, canUseP2PDistanceRequests} = usePermissions(); const parentReportAction = parentReportActions?.[report.parentReportActionID ?? ''] ?? null; + const isTrackExpense = ReportUtils.isTrackExpenseReport(report); + const {canUseViolations, canUseP2PDistanceRequests} = usePermissions(isTrackExpense ? CONST.IOU.TYPE.TRACK : undefined); const moneyRequestReport = parentReport; const { created: transactionDate, @@ -150,7 +151,8 @@ function MoneyRequestView({ const canEditMerchant = ReportUtils.canEditFieldOfMoneyRequest(parentReportAction, CONST.EDIT_REQUEST_FIELD.MERCHANT); const canEditDate = ReportUtils.canEditFieldOfMoneyRequest(parentReportAction, CONST.EDIT_REQUEST_FIELD.DATE); const canEditReceipt = ReportUtils.canEditFieldOfMoneyRequest(parentReportAction, CONST.EDIT_REQUEST_FIELD.RECEIPT); - const canEditDistance = ReportUtils.canEditFieldOfMoneyRequest(parentReportAction, CONST.EDIT_REQUEST_FIELD.DISTANCE); + // TODO: remove the !isTrackExpense from this condition after this fix: https://github.com/Expensify/Expensify/issues/382786 + const canEditDistance = ReportUtils.canEditFieldOfMoneyRequest(parentReportAction, CONST.EDIT_REQUEST_FIELD.DISTANCE) && !isTrackExpense; // A flag for verifying that the current report is a sub-report of a workspace chat // if the policy of the report is either Collect or Control, then this report must be tied to workspace chat @@ -158,6 +160,11 @@ function MoneyRequestView({ const policyTagLists = useMemo(() => PolicyUtils.getTagLists(policyTagList), [policyTagList]); +<<<<<<< HEAD +======= + const iouType = isTrackExpense ? CONST.IOU.TYPE.TRACK : CONST.IOU.TYPE.SUBMIT; + +>>>>>>> 7e5b436 (Merge pull request #40711 from koko57/feat/36985-create-new-rate-field-followups) // Flags for showing categories and tags // transactionCategory can be an empty string // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing @@ -183,10 +190,11 @@ function MoneyRequestView({ const currency = policy ? policy.outputCurrency : PolicyUtils.getPersonalPolicy()?.outputCurrency ?? CONST.CURRENCY.USD; - const mileageRate = TransactionUtils.isCustomUnitRateIDForP2P(transaction) ? DistanceRequestUtils.getRateForP2P(currency) : rates[rateID as string] ?? {}; - const {unit, rate} = mileageRate; + const mileageRate = TransactionUtils.isCustomUnitRateIDForP2P(transaction) ? DistanceRequestUtils.getRateForP2P(currency) : distanceRates[rateID as string] ?? {}; + const {unit} = mileageRate; + const rate = (transaction?.comment?.customUnit?.defaultP2PRate as number) ?? mileageRate.rate; - const distance = DistanceRequestUtils.getDistanceFromMerchant(transactionMerchant, unit); + const distance = DistanceRequestUtils.convertToDistanceInMeters((transaction?.comment?.customUnit?.quantity as number) ?? 0, unit); const rateToDisplay = DistanceRequestUtils.getRateForDisplay(unit, rate, currency, translate, toLocaleDigit, isOffline); const distanceToDisplay = DistanceRequestUtils.getDistanceForDisplay(hasRoute, distance, unit, rate, translate); @@ -280,7 +288,7 @@ function MoneyRequestView({ + {/* TODO: correct the pending field action https://github.com/Expensify/App/issues/36987 */} `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${report ? report.parentReportID : '0'}`, canEvict: false, }, - rates: { + distanceRates: { key: ({report}) => `${ONYXKEYS.COLLECTION.POLICY}${report.policyID}`, selector: DistanceRequestUtils.getMileageRates, }, diff --git a/src/components/ReportActionItem/ReportPreview.tsx b/src/components/ReportActionItem/ReportPreview.tsx index d14d2df1bb43..5c78e1e2604e 100644 --- a/src/components/ReportActionItem/ReportPreview.tsx +++ b/src/components/ReportActionItem/ReportPreview.tsx @@ -165,7 +165,7 @@ function ReportPreview({ return translate('iou.receiptScanning'); } if (hasOnlyTransactionsWithPendingRoutes) { - return translate('iou.routePending'); + return translate('iou.fieldPending'); } // If iouReport is not available, get amount from the action message (Ex: "Domain20821's Workspace owes $33.00" or "paid ₫60" or "paid -₫60 elsewhere") diff --git a/src/languages/en.ts b/src/languages/en.ts index 8fc4334a9125..bd729aa4a47e 100755 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -630,7 +630,7 @@ export default { canceled: 'Canceled', posted: 'Posted', deleteReceipt: 'Delete receipt', - routePending: 'Pending...', + fieldPending: 'Pending...', defaultRate: 'Default rate', receiptScanning: 'Scan in progress…', receiptMissingDetails: 'Receipt missing details', diff --git a/src/languages/es.ts b/src/languages/es.ts index e6a558c0f5a1..159c7066c4ac 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -623,7 +623,7 @@ export default { canceled: 'Canceló', posted: 'Contabilizado', deleteReceipt: 'Eliminar recibo', - routePending: 'Pendiente...', + fieldPending: 'Pendiente...', defaultRate: 'Tasa predeterminada', receiptScanning: 'Escaneo en curso…', receiptMissingDetails: 'Recibo con campos vacíos', diff --git a/src/libs/DistanceRequestUtils.ts b/src/libs/DistanceRequestUtils.ts index 676c4493fe75..9cb48534214e 100644 --- a/src/libs/DistanceRequestUtils.ts +++ b/src/libs/DistanceRequestUtils.ts @@ -20,18 +20,6 @@ type MileageRate = { name?: string; }; -const policies: OnyxCollection = {}; -Onyx.connect({ - key: ONYXKEYS.COLLECTION.POLICY, - callback: (policy, key) => { - if (!policy || !key || !policy.name) { - return; - } - - policies[key] = policy; - }, -}); - let lastSelectedDistanceRates: OnyxEntry = {}; Onyx.connect({ key: ONYXKEYS.NVP_LAST_SELECTED_DISTANCE_RATES, @@ -116,7 +104,7 @@ function getRoundedDistanceInUnits(distanceInMeters: number, unit: Unit): string * @param currency The currency associated with the rate * @param translate Translate function * @param toLocaleDigit Function to convert to localized digit - * @returns A string that describes the distance traveled and the rate used for expense calculation + * @returns A string that displays the rate used for expense calculation */ function getRateForDisplay( unit: Unit | undefined, @@ -130,15 +118,15 @@ function getRateForDisplay( return translate('iou.defaultRate'); } if (!rate || !currency || !unit) { - return translate('iou.routePending'); + return translate('iou.fieldPending'); } const singularDistanceUnit = unit === CONST.CUSTOM_UNITS.DISTANCE_UNIT_MILES ? translate('common.mile') : translate('common.kilometer'); - const ratePerUnit = PolicyUtils.getUnitRateValue(toLocaleDigit, {rate}); + const formattedRate = PolicyUtils.getUnitRateValue(toLocaleDigit, {rate}); // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing const currencySymbol = CurrencyUtils.getCurrencySymbol(currency) || `${currency} `; - return `${currencySymbol}${ratePerUnit} / ${singularDistanceUnit}`; + return `${currencySymbol}${formattedRate} / ${singularDistanceUnit}`; } /** @@ -150,8 +138,8 @@ function getRateForDisplay( * @returns A string that describes the distance traveled */ function getDistanceForDisplay(hasRoute: boolean, distanceInMeters: number, unit: Unit | undefined, rate: number | undefined, translate: LocaleContextProps['translate']): string { - if (!hasRoute || !rate || !unit) { - return translate('iou.routePending'); + if (!hasRoute || !rate || !unit || !distanceInMeters) { + return translate('iou.fieldPending'); } const distanceInUnits = getRoundedDistanceInUnits(distanceInMeters, unit); @@ -182,7 +170,7 @@ function getDistanceMerchant( toLocaleDigit: LocaleContextProps['toLocaleDigit'], ): string { if (!hasRoute || !rate) { - return translate('iou.routePending'); + return translate('iou.fieldPending'); } const distanceInUnits = getDistanceForDisplay(hasRoute, distanceInMeters, unit, rate, translate); @@ -201,11 +189,7 @@ function getDistanceMerchant( function getMileageRates(policy: OnyxEntry): Record { const mileageRates: Record = {}; - if (!policy) { - return mileageRates; - } - - if (!policy?.customUnits) { + if (!policy || !policy?.customUnits) { return mileageRates; } @@ -227,6 +211,12 @@ function getMileageRates(policy: OnyxEntry): Record return mileageRates; } +/** + * Retrieves the rate and unit for a P2P distance expense for a given currency. + * + * @param currency + * @returns The rate and unit in RateAndUnit object. + */ function getRateForP2P(currency: string): RateAndUnit { return CONST.CURRENCY_TO_DEFAULT_MILEAGE_RATE[currency] ?? CONST.CURRENCY_TO_DEFAULT_MILEAGE_RATE.USD; } @@ -246,22 +236,17 @@ function getDistanceRequestAmount(distance: number, unit: Unit, rate: number): n } /** - * Extracts the distance from a merchant string. + * Converts the distance from kilometers or miles to meters. * - * @param merchant - The merchant string containing the distance. - * @returns The distance extracted from the merchant string. + * @param distance - The distance to be converted. + * @param unit - The unit of measurement for the distance. + * @returns The distance in meters. */ -function getDistanceFromMerchant(merchant: string | undefined, unit: Unit): number { - if (!merchant) { - return 0; - } - - const distance = Number(merchant.split(' ')[0]); - if (!distance) { - return 0; +function convertToDistanceInMeters(distance: number, unit: Unit): number { + if (unit === CONST.CUSTOM_UNITS.DISTANCE_UNIT_KILOMETERS) { + return distance / METERS_TO_KM; } - // we need to convert the distance back to meters (it's saved in kilometers or miles in merchant) to pass it to getDistanceForDisplay - return unit === CONST.CUSTOM_UNITS.DISTANCE_UNIT_KILOMETERS ? distance / METERS_TO_KM : distance / METERS_TO_MILES; + return distance / METERS_TO_MILES; } /** @@ -289,8 +274,8 @@ export default { getMileageRates, getDistanceForDisplay, getRateForP2P, - getDistanceFromMerchant, getCustomUnitRateID, + convertToDistanceInMeters, }; export type {MileageRate}; diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index f2f7bab41fae..c0798a33a723 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -2629,7 +2629,7 @@ function getTransactionReportName(reportAction: OnyxEntry item.isSelected)?.keyForList; function selectDistanceRate(customUnitRateID: string) { IOU.updateDistanceRequestRate(transactionID, customUnitRateID, policy?.id ?? ''); From 4fcd8bfe2d26b208857ac337cd0713dc090e10b7 Mon Sep 17 00:00:00 2001 From: Amy Evans Date: Tue, 23 Apr 2024 16:47:30 -0400 Subject: [PATCH 3/3] Fix conflict --- src/components/ReportActionItem/MoneyRequestView.tsx | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/components/ReportActionItem/MoneyRequestView.tsx b/src/components/ReportActionItem/MoneyRequestView.tsx index 1eaeafdc655f..e45d5291d2c2 100644 --- a/src/components/ReportActionItem/MoneyRequestView.tsx +++ b/src/components/ReportActionItem/MoneyRequestView.tsx @@ -160,11 +160,6 @@ function MoneyRequestView({ const policyTagLists = useMemo(() => PolicyUtils.getTagLists(policyTagList), [policyTagList]); -<<<<<<< HEAD -======= - const iouType = isTrackExpense ? CONST.IOU.TYPE.TRACK : CONST.IOU.TYPE.SUBMIT; - ->>>>>>> 7e5b436 (Merge pull request #40711 from koko57/feat/36985-create-new-rate-field-followups) // Flags for showing categories and tags // transactionCategory can be an empty string // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing