Skip to content

Commit

Permalink
Merge branch 'main' into ts/no-unsafe-assignment
Browse files Browse the repository at this point in the history
  • Loading branch information
blazejkustra committed Jul 3, 2024
2 parents 825b310 + 00e7b1e commit 2f656bf
Show file tree
Hide file tree
Showing 108 changed files with 2,015 additions and 337 deletions.
4 changes: 2 additions & 2 deletions android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,8 @@ android {
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
multiDexEnabled rootProject.ext.multiDexEnabled
versionCode 1009000305
versionName "9.0.3-5"
versionCode 1009000306
versionName "9.0.3-6"
// 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"
Expand Down
2 changes: 1 addition & 1 deletion config/electronBuilder.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ module.exports = {
},
target: [
{
target: 'dmg',
target: 'default',
arch: ['universal'],
},
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,29 +7,9 @@ description: International Reimbursements
If your company’s business bank account is in the US, Canada, the UK, Europe, or Australia, you now have the option to send direct reimbursements to nearly any country across the globe!
The process to enable global reimbursements is dependent on the currency of your reimbursement bank account, so be sure to review the corresponding instructions below.

# How to request international reimbursements

## The reimbursement account is in USD

If your reimbursement bank account is in USD, the first step is connecting the bank account to Expensify.
The individual who plans on sending reimbursements internationally should head to **Settings > Account > Payments > Add Verified Bank Account**. From there, you will provide company details, input personal information, and upload a copy of your ID.

Once the USD bank account is verified (or if you already had a USD business bank account connected), click the support icon in your Expensify account to inform your Setup Specialist, Account Manager, or Concierge that you’d like to enable international reimbursements. From there, Expensify will ask you to confirm the currencies of the reimbursement and employee bank accounts.

Our team will assess your account, and if you meet the criteria, international reimbursements will be enabled.

## The reimbursement account is in AUD, CAD, GBP, EUR

To request international reimbursements, contact Expensify Support to make that request.

You can do this by clicking on the support icon and informing your Setup Specialist, Account Manager, or Concierge that you’d like to set up global reimbursements on your account.
From there, Expensify will ask you to confirm both the currencies of the reimbursement and employee bank accounts.

Our team will assess your account, and if you meet the criteria, international reimbursements will be enabled.

# How to verify the bank account for sending international payments

Once international payments are enabled on your Expensify account, the next step is verifying the bank account to send the reimbursements.
The steps for USD accounts and non-USD accounts differ slightly.

## The reimbursement account is in USD

Expand All @@ -38,9 +18,9 @@ First, confirm the workspace settings are set up correctly by doing the followin
2. Under **Settings > Workspaces > Group > _[Workspace Name]_ > Reimbursements**, set the reimbursement method to direct
3. Under **Settings > Workspaces > Group > _[Workspace Name]_ > Reimbursements**, set the USD bank account to the default account

Once that’s all set, head to **Settings > Account > Payments**, and click **Enable Global Reimbursement** on the bank account (this button may not show for up to 60 minutes after the Expensify team confirms international reimbursements are available on your account).
Once that’s all set, head to **Settings > Account > Payments**, and click **Enable Global Reimbursement** on the bank account.

From there, you’ll fill out a form via DocuSign. Once the form is complete, it is automatically sent to our Compliance Team for review. Our Support Team will contact you with more details if additional information is required.
From there, you’ll fill out a form via DocuSign. Once the form is complete, it is automatically sent to our Compliance Team for review. If additional information is required, our Support Team will contact you with more details.

## The reimbursement account is in AUD, CAD, GBP, EUR

Expand All @@ -53,7 +33,7 @@ Next, add the bank account to Expensify:
4. Enter the bank account details
5. Click **Save & Continue**

From there, you’ll fill out a form via DocuSign. Once the form is complete, it is automatically sent to our Compliance Team for review. Our Support Team will contact you with more details if additional information is required.
From there, you’ll fill out a form via DocuSign. Once the form is complete, it is automatically sent to our Compliance Team for review. If additional information is required, our Support Team will contact you with more details.

# How to start reimbursing internationally

Expand Down
2 changes: 1 addition & 1 deletion ios/NewExpensify/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
</dict>
</array>
<key>CFBundleVersion</key>
<string>9.0.3.5</string>
<string>9.0.3.6</string>
<key>FullStory</key>
<dict>
<key>OrgId</key>
Expand Down
2 changes: 1 addition & 1 deletion ios/NewExpensifyTests/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,6 @@
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>9.0.3.5</string>
<string>9.0.3.6</string>
</dict>
</plist>
2 changes: 1 addition & 1 deletion ios/NotificationServiceExtension/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
<key>CFBundleShortVersionString</key>
<string>9.0.3</string>
<key>CFBundleVersion</key>
<string>9.0.3.5</string>
<string>9.0.3.6</string>
<key>NSExtension</key>
<dict>
<key>NSExtensionPointIdentifier</key>
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "new.expensify",
"version": "9.0.3-5",
"version": "9.0.3-6",
"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.",
Expand Down
21 changes: 21 additions & 0 deletions src/CONST.ts
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,7 @@ const CONST = {
REPORT_FIELDS_FEATURE: 'reportFieldsFeature',
WORKSPACE_FEEDS: 'workspaceFeeds',
NETSUITE_USA_TAX: 'netsuiteUsaTax',
INTACCT_ON_NEW_EXPENSIFY: 'intacctOnNewExpensify',
},
BUTTON_STATES: {
DEFAULT: 'default',
Expand Down Expand Up @@ -1288,6 +1289,7 @@ const CONST = {
REPORT_FIELD: 'REPORT_FIELD',
NOT_IMPORTED: 'NOT_IMPORTED',
IMPORTED: 'IMPORTED',
NETSUITE_DEFAULT: 'NETSUITE_DEFAULT',
},
QUICKBOOKS_ONLINE: 'quickbooksOnline',

Expand Down Expand Up @@ -1367,6 +1369,11 @@ const CONST = {
PROVINCIAL_TAX_POSTING_ACCOUNT: 'provincialTaxPostingAccount',
ALLOW_FOREIGN_CURRENCY: 'allowForeignCurrency',
EXPORT_TO_NEXT_OPEN_PERIOD: 'exportToNextOpenPeriod',
IMPORT_FIELDS: ['departments', 'classes', 'locations', 'customers', 'jobs'],
IMPORT_CUSTOM_FIELDS: ['customSegments', 'customLists'],
SYNC_OPTIONS: {
SYNC_TAX: 'syncTax',
},
},

NETSUITE_EXPORT_DATE: {
Expand Down Expand Up @@ -5022,6 +5029,14 @@ const CONST = {
ACTION: 'action',
TAX_AMOUNT: 'taxAmount',
},
BULK_ACTION_TYPES: {
DELETE: 'delete',
HOLD: 'hold',
UNHOLD: 'unhold',
SUBMIT: 'submit',
APPROVE: 'approve',
PAY: 'pay',
},
},

REFERRER: {
Expand Down Expand Up @@ -5057,6 +5072,12 @@ const CONST = {
},
},

WORKSPACE_CARDS_LIST_LABEL_TYPE: {
CURRENT_BALANCE: 'currentBalance',
REMAINING_LIMIT: 'remainingLimit',
CASH_BACK: 'cashBack',
},

EXCLUDE_FROM_LAST_VISITED_PATH: [SCREENS.NOT_FOUND, SCREENS.SAML_SIGN_IN, SCREENS.VALIDATE_LOGIN] as string[],
} as const;

Expand Down
11 changes: 11 additions & 0 deletions src/ONYXKEYS.ts
Original file line number Diff line number Diff line change
Expand Up @@ -427,6 +427,15 @@ const ONYXKEYS = {
// Shared NVPs
/** Collection of objects where each object represents the owner of the workspace that is past due billing AND the user is a member of. */
SHARED_NVP_PRIVATE_USER_BILLING_GRACE_PERIOD_END: 'sharedNVP_private_billingGracePeriodEnd_',

/** Expensify cards settings */
SHARED_NVP_PRIVATE_EXPENSIFY_CARD_SETTINGS: 'sharedNVP_private_expensifyCardSettings_',

/**
* Stores the card list for a given fundID and feed in the format: card_<fundID>_<bankName>
* So for example: card_12345_Expensify Card
*/
WORKSPACE_CARDS_LIST: 'card_',
},

/** List of Form ids */
Expand Down Expand Up @@ -650,6 +659,8 @@ type OnyxCollectionValuesMapping = {
[ONYXKEYS.COLLECTION.POLICY_CONNECTION_SYNC_PROGRESS]: OnyxTypes.PolicyConnectionSyncProgress;
[ONYXKEYS.COLLECTION.SNAPSHOT]: OnyxTypes.SearchResults;
[ONYXKEYS.COLLECTION.SHARED_NVP_PRIVATE_USER_BILLING_GRACE_PERIOD_END]: OnyxTypes.BillingGraceEndPeriod;
[ONYXKEYS.COLLECTION.SHARED_NVP_PRIVATE_EXPENSIFY_CARD_SETTINGS]: OnyxTypes.ExpensifyCardSettings;
[ONYXKEYS.COLLECTION.WORKSPACE_CARDS_LIST]: OnyxTypes.WorkspaceCardsList;
};

type OnyxValuesMapping = {
Expand Down
16 changes: 10 additions & 6 deletions src/ROUTES.ts
Original file line number Diff line number Diff line change
Expand Up @@ -783,6 +783,10 @@ const ROUTES = {
route: 'settings/workspaces/:policyID/reportFields',
getRoute: (policyID: string) => `settings/workspaces/${policyID}/reportFields` as const,
},
WORKSPACE_EXPENSIFY_CARD: {
route: 'settings/workspaces/:policyID/expensify-card',
getRoute: (policyID: string) => `settings/workspaces/${policyID}/expensify-card` as const,
},
// TODO: uncomment after development is done
// WORKSPACE_EXPENSIFY_CARD_ISSUE_NEW: {
// route: 'settings/workspaces/:policyID/expensify-card/issues-new',
Expand All @@ -794,10 +798,6 @@ const ROUTES = {
route: 'settings/workspaces/:policyID/distance-rates',
getRoute: (policyID: string) => `settings/workspaces/${policyID}/distance-rates` as const,
},
WORKSPACE_EXPENSIFY_CARD: {
route: 'settings/workspaces/:policyID/expensify-card',
getRoute: (policyID: string) => `settings/workspaces/${policyID}/expensify-card` as const,
},
WORKSPACE_CREATE_DISTANCE_RATE: {
route: 'settings/workspaces/:policyID/distance-rates/new',
getRoute: (policyID: string) => `settings/workspaces/${policyID}/distance-rates/new` as const,
Expand Down Expand Up @@ -937,8 +937,12 @@ const ROUTES = {
getRoute: (policyID: string) => `restricted-action/workspace/${policyID}` as const,
},
POLICY_ACCOUNTING_NETSUITE_SUBSIDIARY_SELECTOR: {
route: 'settings/workspaces/:policyID/accounting/net-suite/subsidiary-selector',
getRoute: (policyID: string) => `settings/workspaces/${policyID}/accounting/net-suite/subsidiary-selector` as const,
route: 'settings/workspaces/:policyID/accounting/netsuite/subsidiary-selector',
getRoute: (policyID: string) => `settings/workspaces/${policyID}/accounting/netsuite/subsidiary-selector` as const,
},
POLICY_ACCOUNTING_NETSUITE_IMPORT: {
route: 'settings/workspaces/:policyID/accounting/netsuite/import',
getRoute: (policyID: string) => `settings/workspaces/${policyID}/accounting/netsuite/import` as const,
},
POLICY_ACCOUNTING_NETSUITE_EXPORT: {
route: 'settings/workspaces/:policyID/connections/netsuite/export/',
Expand Down
3 changes: 2 additions & 1 deletion src/SCREENS.ts
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,8 @@ const SCREENS = {
XERO_EXPORT_PREFERRED_EXPORTER_SELECT: 'Workspace_Accounting_Xero_Export_Preferred_Exporter_Select',
XERO_BILL_PAYMENT_ACCOUNT_SELECTOR: 'Policy_Accounting_Xero_Bill_Payment_Account_Selector',
XERO_EXPORT_BANK_ACCOUNT_SELECT: 'Policy_Accounting_Xero_Export_Bank_Account_Select',
NETSUITE_SUBSIDIARY_SELECTOR: 'Policy_Accounting_Net_Suite_Subsidiary_Selector',
NETSUITE_SUBSIDIARY_SELECTOR: 'Policy_Accounting_NetSuite_Subsidiary_Selector',
NETSUITE_IMPORT: 'Policy_Accounting_NetSuite_Import',
NETSUITE_EXPORT: 'Policy_Accounting_NetSuite_Export',
NETSUITE_PREFERRED_EXPORTER_SELECT: 'Policy_Accounting_NetSuite_Preferred_Exporter_Select',
NETSUITE_DATE_SELECT: 'Policy_Accounting_NetSuite_Date_Select',
Expand Down
4 changes: 4 additions & 0 deletions src/components/ButtonWithDropdownMenu/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ type DropdownOption<TValueType> = {
iconDescription?: string;
onSelected?: () => void;
disabled?: boolean;
iconFill?: string;
interactive?: boolean;
numberOfLinesTitle?: number;
titleStyle?: ViewStyle;
};

type ButtonWithDropdownMenuProps<TValueType> = {
Expand Down
9 changes: 9 additions & 0 deletions src/components/LHNOptionsList/OptionRowLHN.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import React, {useCallback, useRef, useState} from 'react';
import type {GestureResponderEvent, ViewStyle} from 'react-native';
import {StyleSheet, View} from 'react-native';
import {useOnyx} from 'react-native-onyx';
import Badge from '@components/Badge';
import DisplayNames from '@components/DisplayNames';
import Hoverable from '@components/Hoverable';
import Icon from '@components/Icon';
Expand All @@ -25,6 +26,7 @@ import * as OptionsListUtils from '@libs/OptionsListUtils';
import Performance from '@libs/Performance';
import ReportActionComposeFocusManager from '@libs/ReportActionComposeFocusManager';
import * as ReportUtils from '@libs/ReportUtils';
import * as SubscriptionUtils from '@libs/SubscriptionUtils';
import * as ReportActionContextMenu from '@pages/home/report/ContextMenu/ReportActionContextMenu';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
Expand Down Expand Up @@ -227,6 +229,13 @@ function OptionRowLHN({reportID, isFocused = false, onSelectRow = () => {}, opti
ReportUtils.isSystemChat(report)
}
/>
{ReportUtils.isChatUsedForOnboarding(report) && SubscriptionUtils.isUserOnFreeTrial() && (
<Badge
success
text={translate('subscription.badge.freeTrial', {numOfDays: SubscriptionUtils.calculateRemainingFreeTrialDays()})}
badgeStyles={[styles.mnh0, styles.pl2, styles.pr2, styles.ml1]}
/>
)}
{isStatusVisible && (
<Tooltip
text={statusContent}
Expand Down
7 changes: 4 additions & 3 deletions src/components/MoneyReportHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -90,10 +90,11 @@ function MoneyReportHeader({policy, report: moneyRequestReport, transactionThrea
const {reimbursableSpend} = ReportUtils.getMoneyRequestSpendBreakdown(moneyRequestReport);
const isSettled = ReportUtils.isSettled(moneyRequestReport.reportID);
const isApproved = ReportUtils.isReportApproved(moneyRequestReport);
const isClosed = ReportUtils.isClosedReport(moneyRequestReport);
const isOnHold = TransactionUtils.isOnHold(transaction);
const isScanning = TransactionUtils.hasReceipt(transaction) && TransactionUtils.isReceiptBeingScanned(transaction);
const isDeletedParentAction = !!requestParentReportAction && ReportActionsUtils.isDeletedAction(requestParentReportAction);
const canHoldOrUnholdRequest = !isEmptyObject(transaction) && !isSettled && !isApproved && !isDeletedParentAction;
const canHoldOrUnholdRequest = !isEmptyObject(transaction) && !isSettled && !isApproved && !isDeletedParentAction && !isClosed;

// Only the requestor can delete the request, admins can only edit it.
const isActionOwner =
Expand Down Expand Up @@ -146,7 +147,7 @@ function MoneyReportHeader({policy, report: moneyRequestReport, transactionThrea
const displayedAmount = ReportUtils.hasHeldExpenses(moneyRequestReport.reportID) && canAllowSettlement ? nonHeldAmount : formattedAmount;
const isMoreContentShown = shouldShowNextStep || shouldShowStatusBar || (shouldShowAnyButton && shouldUseNarrowLayout);

const confirmPayment = (type?: PaymentMethodType | undefined) => {
const confirmPayment = (type?: PaymentMethodType | undefined, payAsBusiness?: boolean) => {
if (!type || !chatReport) {
return;
}
Expand All @@ -155,7 +156,7 @@ function MoneyReportHeader({policy, report: moneyRequestReport, transactionThrea
if (ReportUtils.hasHeldExpenses(moneyRequestReport.reportID)) {
setIsHoldMenuVisible(true);
} else if (ReportUtils.isInvoiceReport(moneyRequestReport)) {
IOU.payInvoice(type, chatReport, moneyRequestReport);
IOU.payInvoice(type, chatReport, moneyRequestReport, payAsBusiness);
} else {
IOU.payMoneyRequest(type, chatReport, moneyRequestReport, true);
}
Expand Down
3 changes: 3 additions & 0 deletions src/components/PopoverMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,7 @@ function PopoverMenu({
iconFill={item.iconFill}
contentFit={item.contentFit}
title={item.text}
titleStyle={item.titleStyle}
shouldCheckActionAllowedOnPress={false}
description={item.description}
numberOfLinesDescription={item.numberOfLinesDescription}
Expand All @@ -247,6 +248,8 @@ function PopoverMenu({
shouldForceRenderingTooltipLeft={item.shouldForceRenderingTooltipLeft}
tooltipWrapperStyle={item.tooltipWrapperStyle}
renderTooltipContent={item.renderTooltipContent}
numberOfLinesTitle={item.numberOfLinesTitle}
interactive={item.interactive}
/>
))}
</View>
Expand Down
3 changes: 1 addition & 2 deletions src/components/Reactions/EmojiReactionBubble.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import useStyleUtils from '@hooks/useStyleUtils';
import useThemeStyles from '@hooks/useThemeStyles';
import type {ReactionListEvent} from '@pages/home/ReportScreenContext';
import CONST from '@src/CONST';
import getEmojiReactionBubbleTextOffsetStyle from './getEmojiReactionBubbleTextOffsetStyle';

type EmojiReactionBubbleProps = {
/**
Expand Down Expand Up @@ -83,7 +82,7 @@ function EmojiReactionBubble(
accessible
dataSet={{[CONST.SELECTION_SCRAPER_HIDDEN_ELEMENT]: true}}
>
<Text style={[styles.emojiReactionBubbleText, StyleUtils.getEmojiReactionBubbleTextStyle(isContextMenu), getEmojiReactionBubbleTextOffsetStyle()]}>{emojiCodes.join('')}</Text>
<Text style={[styles.emojiReactionBubbleText, StyleUtils.getEmojiReactionBubbleTextStyle(isContextMenu)]}>{emojiCodes.join('')}</Text>
{count > 0 && <Text style={[styles.reactionCounterText, StyleUtils.getEmojiReactionCounterTextStyle(hasUserReacted)]}>{count}</Text>}
</PressableWithSecondaryInteraction>
);
Expand Down

This file was deleted.

This file was deleted.

Loading

0 comments on commit 2f656bf

Please sign in to comment.