From db61dbe10ca41162b8e10c13e60701ccc80d8d2b Mon Sep 17 00:00:00 2001 From: dominictb Date: Thu, 22 Aug 2024 17:25:18 +0700 Subject: [PATCH 01/18] fix: show disabled distance rate if it is selected in IOU request --- src/libs/DistanceRequestUtils.ts | 6 ++++-- src/pages/iou/request/step/IOURequestStepDistanceRate.tsx | 4 +++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/libs/DistanceRequestUtils.ts b/src/libs/DistanceRequestUtils.ts index fa98cf32ee39..987c46c7932d 100644 --- a/src/libs/DistanceRequestUtils.ts +++ b/src/libs/DistanceRequestUtils.ts @@ -19,6 +19,7 @@ type MileageRate = { currency?: string; unit: Unit; name?: string; + enabled?: boolean; }; let lastSelectedDistanceRates: OnyxEntry = {}; @@ -32,7 +33,7 @@ Onyx.connect({ const METERS_TO_KM = 0.001; // 1 kilometer is 1000 meters const METERS_TO_MILES = 0.000621371; // There are approximately 0.000621371 miles in a meter -function getMileageRates(policy: OnyxInputOrEntry, includeDisabledRates = false): Record { +function getMileageRates(policy: OnyxInputOrEntry, includeDisabledRates = false, selectedRateID?: string): Record { const mileageRates: Record = {}; if (!policy?.customUnits) { @@ -45,7 +46,7 @@ function getMileageRates(policy: OnyxInputOrEntry, includeDisabledRates } Object.entries(distanceUnit.rates).forEach(([rateID, rate]) => { - if (!includeDisabledRates && rate.enabled === false) { + if (!includeDisabledRates && rate.enabled === false && (!selectedRateID || rateID !== selectedRateID)) { return; } @@ -55,6 +56,7 @@ function getMileageRates(policy: OnyxInputOrEntry, includeDisabledRates unit: distanceUnit.attributes.unit, name: rate.name, customUnitRateID: rate.customUnitRateID, + enabled: rate.enabled, }; }); diff --git a/src/pages/iou/request/step/IOURequestStepDistanceRate.tsx b/src/pages/iou/request/step/IOURequestStepDistanceRate.tsx index 3b42b1d9a1be..8dde04202a22 100644 --- a/src/pages/iou/request/step/IOURequestStepDistanceRate.tsx +++ b/src/pages/iou/request/step/IOURequestStepDistanceRate.tsx @@ -54,7 +54,6 @@ function IOURequestStepDistanceRate({ const [policyDraft] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY_DRAFTS}${IOU.getIOURequestPolicyID(transaction, reportDraft) ?? '-1'}`); const policy = policyReal ?? policyDraft; - const rates = DistanceRequestUtils.getMileageRates(policy); const styles = useThemeStyles(); const {translate, toLocaleDigit} = useLocalize(); @@ -65,6 +64,8 @@ function IOURequestStepDistanceRate({ const currentRateID = TransactionUtils.getRateID(transaction) ?? '-1'; + const rates = DistanceRequestUtils.getMileageRates(policy, false, currentRateID); + const navigateBack = () => { Navigation.goBack(backTo); }; @@ -77,6 +78,7 @@ function IOURequestStepDistanceRate({ alternateText: rate.name ? rateForDisplay : '', keyForList: rate.customUnitRateID, value: rate.customUnitRateID, + isDisabled: !rate.enabled, isSelected: currentRateID ? currentRateID === rate.customUnitRateID : rate.name === CONST.CUSTOM_UNITS.DEFAULT_RATE, }; }); From 23c4376099d79188892e21c3f5a3880cbf574b20 Mon Sep 17 00:00:00 2001 From: daledah Date: Mon, 26 Aug 2024 11:45:18 +0700 Subject: [PATCH 02/18] fix: prevent email address selection for categorize --- src/libs/OptionsListUtils.ts | 2 +- src/pages/iou/request/MoneyRequestParticipantsSelector.tsx | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/libs/OptionsListUtils.ts b/src/libs/OptionsListUtils.ts index 3f519f4de7c4..aa09c6799e5c 100644 --- a/src/libs/OptionsListUtils.ts +++ b/src/libs/OptionsListUtils.ts @@ -2471,7 +2471,7 @@ function filterOptions(options: Options, searchInputValue: string, config?: Filt return { personalDetails, recentReports: orderOptions(recentReports, searchValue, {preferChatroomsOverThreads, preferPolicyExpenseChat}), - userToInvite, + userToInvite: canInviteUser ? userToInvite : null, currentUserOption: matchResults.currentUserOption, categoryOptions: [], tagOptions: [], diff --git a/src/pages/iou/request/MoneyRequestParticipantsSelector.tsx b/src/pages/iou/request/MoneyRequestParticipantsSelector.tsx index 3d2f85ef6c62..c6b4e5fb82b5 100644 --- a/src/pages/iou/request/MoneyRequestParticipantsSelector.tsx +++ b/src/pages/iou/request/MoneyRequestParticipantsSelector.tsx @@ -162,13 +162,15 @@ function MoneyRequestParticipantsSelector({participants = CONST.EMPTY_ARRAY, onF } const newOptions = OptionsListUtils.filterOptions(defaultOptions, debouncedSearchTerm, { + // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing + canInviteUser: (canUseP2PDistanceRequests || iouRequestType !== CONST.IOU.REQUEST_TYPE.DISTANCE) && !isCategorizeOrShareAction, selectedOptions: participants as Participant[], excludeLogins: CONST.EXPENSIFY_EMAILS, maxRecentReportsToShow: CONST.IOU.MAX_RECENT_REPORTS_TO_SHOW, preferPolicyExpenseChat: isPaidGroupPolicy, }); return newOptions; - }, [areOptionsInitialized, defaultOptions, debouncedSearchTerm, participants, isPaidGroupPolicy]); + }, [areOptionsInitialized, defaultOptions, debouncedSearchTerm, participants, isPaidGroupPolicy, canUseP2PDistanceRequests, iouRequestType, isCategorizeOrShareAction]); /** * Returns the sections needed for the OptionsSelector From 15504a20ceee33ec18157a80a48f344057feea30 Mon Sep 17 00:00:00 2001 From: daledah Date: Mon, 26 Aug 2024 14:12:13 +0700 Subject: [PATCH 03/18] fix: remove unneeded change --- src/libs/OptionsListUtils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/OptionsListUtils.ts b/src/libs/OptionsListUtils.ts index aa09c6799e5c..3f519f4de7c4 100644 --- a/src/libs/OptionsListUtils.ts +++ b/src/libs/OptionsListUtils.ts @@ -2471,7 +2471,7 @@ function filterOptions(options: Options, searchInputValue: string, config?: Filt return { personalDetails, recentReports: orderOptions(recentReports, searchValue, {preferChatroomsOverThreads, preferPolicyExpenseChat}), - userToInvite: canInviteUser ? userToInvite : null, + userToInvite, currentUserOption: matchResults.currentUserOption, categoryOptions: [], tagOptions: [], From 4fcc84f8fecec6fca749e7e603c1ec37146e1e5a Mon Sep 17 00:00:00 2001 From: Bernhard Owen Josephus Date: Thu, 29 Aug 2024 14:13:42 +0800 Subject: [PATCH 04/18] don't show rbr if not a policy report --- src/libs/ReportUtils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index f8f85beff4ad..97c55b2a2fa0 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -5819,7 +5819,7 @@ function doesTransactionThreadHaveViolations( return ( TransactionUtils.hasViolation(IOUTransactionID, transactionViolations) || TransactionUtils.hasWarningTypeViolation(IOUTransactionID, transactionViolations) || - TransactionUtils.hasModifiedAmountOrDateViolation(IOUTransactionID, transactionViolations) + (isPaidGroupPolicy(report) && TransactionUtils.hasModifiedAmountOrDateViolation(IOUTransactionID, transactionViolations)) ); } From 24f3239096a27fef91d1324352b2e03fbfeae8eb Mon Sep 17 00:00:00 2001 From: Ren Jones <153645623+ren-jones@users.noreply.github.com> Date: Fri, 30 Aug 2024 12:01:28 -0500 Subject: [PATCH 05/18] Create Get-reimbursed-faster-as-a-non-US-employee.md New article --- ...-reimbursed-faster-as-a-non-US-employee.md | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 docs/articles/expensify-classic/bank-accounts-and-payments/payments/Get-reimbursed-faster-as-a-non-US-employee.md diff --git a/docs/articles/expensify-classic/bank-accounts-and-payments/payments/Get-reimbursed-faster-as-a-non-US-employee.md b/docs/articles/expensify-classic/bank-accounts-and-payments/payments/Get-reimbursed-faster-as-a-non-US-employee.md new file mode 100644 index 000000000000..30dea99bbfde --- /dev/null +++ b/docs/articles/expensify-classic/bank-accounts-and-payments/payments/Get-reimbursed-faster-as-a-non-US-employee.md @@ -0,0 +1,24 @@ +--- +title: Get Reimbursed Faster as a Non-US Employee +description: How to use Wise to get paid faster +--- + +If you are an overseas employee who works for a US-based company, you can use Wise to be reimbursed for expenses just as quickly as your US-based colleagues. Wise (formerly TransferWise) is an FCA-regulated global money transfer service. + +Here’s how it works: + +1. When you sign up for a Wise account, you are provided with a USD checking account number and a routing number to use as your Expensify bank account. +2. Once you receive a reimbursement, it will be deposited directly into your Wise account. +3. You can then convert your funds into 40+ different currencies and withdraw them to your local bank account. If you live in the UK or EU, you can also get a debit card to spend money directly from your Wise account. + +## Set up reimbursements through Wise + +1. Check with your company to see if you can submit your expenses in USD. +2. Sign up for a Wise Borderless Account and get verified (verification can take up to 3 days). +3. In Expensify, [add a deposit-only bank account](https://help.expensify.com/articles/expensify-classic/bank-accounts-and-payments/bank-accounts/Connect-Personal-US-Bank-Account) with your Wise USD account and ACH routing numbers (NOT the wire transfer routing number). + +{% include info.html %} +Do not include spaces in the Wise account number, which should be 16 digits. +{% include end-info.html %} + +If your expenses are not in USD, Expensify will automatically convert them to USD when they are added to your expense report. Once you submit your expenses to your company’s USD workspace and they are approved, you will receive the reimbursement for the approved report total in USD in your Wise account. From 36a0df2c92ebe8bfb28758a2552c88101f0356d7 Mon Sep 17 00:00:00 2001 From: BhuvaneshPatil Date: Tue, 3 Sep 2024 08:38:13 +0530 Subject: [PATCH 06/18] feat: update add bank account step page with latest design --- src/languages/en.ts | 1 + src/languages/es.ts | 1 + .../ReimbursementAccount/BankAccountStep.tsx | 69 ++++++++++++------- 3 files changed, 48 insertions(+), 23 deletions(-) diff --git a/src/languages/en.ts b/src/languages/en.ts index 30e2dad391d9..a8dc4cffecb4 100755 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -3500,6 +3500,7 @@ export default { continueWithSetup: 'Continue with setup', youreAlmostDone: "You're almost done setting up your bank account, which will let you issue corporate cards, reimburse expenses, collect invoices, and pay bills.", streamlinePayments: 'Streamline payments', + connectBankAccountNote: "Note: Personal bank accounts can't be used for payments on workspaces.", oneMoreThing: 'One more thing!', allSet: "You're all set!", accountDescriptionNoCards: diff --git a/src/languages/es.ts b/src/languages/es.ts index 16b8f6f42ed2..923c60360a70 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -3548,6 +3548,7 @@ export default { continueWithSetup: 'Continuar con la configuración', youreAlmostDone: 'Casi has acabado de configurar tu cuenta bancaria, que te permitirá emitir tarjetas corporativas, reembolsar gastos y cobrar pagar facturas.', streamlinePayments: 'Optimiza pagos', + connectBankAccountNote: 'Nota: No se pueden usar cuentas bancarias personales para realizar pagos en los espacios de trabajo.', oneMoreThing: '¡Una cosa más!', allSet: '¡Todo listo!', accountDescriptionNoCards: diff --git a/src/pages/ReimbursementAccount/BankAccountStep.tsx b/src/pages/ReimbursementAccount/BankAccountStep.tsx index 69e605878725..fc059bb26e57 100644 --- a/src/pages/ReimbursementAccount/BankAccountStep.tsx +++ b/src/pages/ReimbursementAccount/BankAccountStep.tsx @@ -2,11 +2,10 @@ import React from 'react'; import {View} from 'react-native'; import type {OnyxEntry} from 'react-native-onyx'; import {withOnyx} from 'react-native-onyx'; -import Button from '@components/Button'; import HeaderWithBackButton from '@components/HeaderWithBackButton'; import Icon from '@components/Icon'; import * as Expensicons from '@components/Icon/Expensicons'; -import * as Illustrations from '@components/Icon/Illustrations'; +import LottieAnimations from '@components/LottieAnimations'; import MenuItem from '@components/MenuItem'; import PressableWithoutFeedback from '@components/Pressable/PressableWithoutFeedback'; import ScreenWrapper from '@components/ScreenWrapper'; @@ -36,6 +35,9 @@ type BankAccountStepOnyxProps = { /** If the plaid button has been disabled */ isPlaidDisabled: OnyxEntry; + + /** The details about the Personal bank account we are adding saved in Onyx */ + personalBankAccount: OnyxEntry; }; type BankAccountStepProps = BankAccountStepOnyxProps & { @@ -69,6 +71,7 @@ function BankAccountStep({ reimbursementAccount, onBackButtonPress, isPlaidDisabled = false, + personalBankAccount = {}, }: BankAccountStepProps) { const theme = useTheme(); const styles = useThemeStyles(); @@ -119,34 +122,50 @@ function BankAccountStep({ />
- - {translate('bankAccount.toGetStarted')} - {!!plaidDesktopMessage && ( Link.openExternalLinkWithToken(bankAccountRoute)}>{translate(plaidDesktopMessage)} )} -