diff --git a/.github/workflows/cla.yml b/.github/workflows/cla.yml index 4031d6c0c119..34a5c356356e 100644 --- a/.github/workflows/cla.yml +++ b/.github/workflows/cla.yml @@ -4,39 +4,9 @@ on: issue_comment: types: [created] pull_request_target: - types: [opened, synchronize] + types: [opened, closed, synchronize] jobs: CLA: - runs-on: ubuntu-latest - # This job only runs for pull request comments or pull request target events (not issue comments) - # It does not run for pull requests created by OSBotify - if: ${{ github.event.issue.pull_request || (github.event_name == 'pull_request_target' && github.event.pull_request.user.login != 'OSBotify' && github.event.pull_request.user.login != 'imgbot[bot]') }} - steps: - - name: CLA comment check - uses: actions-ecosystem/action-regex-match@9c35fe9ac1840239939c59e5db8839422eed8a73 - id: sign - with: - text: ${{ github.event.comment.body }} - regex: '\s*I have read the CLA Document and I hereby sign the CLA\s*' - - name: CLA comment re-check - uses: actions-ecosystem/action-regex-match@9c35fe9ac1840239939c59e5db8839422eed8a73 - id: recheck - with: - text: ${{ github.event.comment.body }} - regex: '\s*recheck\s*' - - name: CLA Assistant - if: ${{ steps.recheck.outputs.match != '' || steps.sign.outputs.match != '' || github.event_name == 'pull_request_target' }} - # Version: 2.1.2-beta - uses: cla-assistant/github-action@948230deb0d44dd38957592f08c6bd934d96d0cf - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - PERSONAL_ACCESS_TOKEN : ${{ secrets.CLA_BOTIFY_TOKEN }} - with: - path-to-signatures: '${{ github.repository }}/cla.json' - path-to-document: 'https://github.com/${{ github.repository }}/blob/main/contributingGuides/CLA.md' - branch: 'main' - remote-organization-name: 'Expensify' - remote-repository-name: 'CLA' - lock-pullrequest-aftermerge: false - allowlist: OSBotify,snyk-bot + uses: Expensify/GitHub-Actions/.github/workflows/cla.yml@main + secrets: inherit diff --git a/android/app/build.gradle b/android/app/build.gradle index b07de7a4da33..40de69b4b7be 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -110,8 +110,8 @@ android { minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion multiDexEnabled rootProject.ext.multiDexEnabled - versionCode 1009005001 - versionName "9.0.50-1" + versionCode 1009005101 + versionName "9.0.51-1" // 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/docs/articles/expensify-classic/connections/netsuite/Connect-To-NetSuite.md b/docs/articles/expensify-classic/connections/netsuite/Connect-To-NetSuite.md index 1f96d9b8a633..6cc69fccccc1 100644 --- a/docs/articles/expensify-classic/connections/netsuite/Connect-To-NetSuite.md +++ b/docs/articles/expensify-classic/connections/netsuite/Connect-To-NetSuite.md @@ -1,12 +1,11 @@ --- title: NetSuite -description: Set up the direct connection from Expensify to NetSuite. +description: Connect NetSuite to Expensify for streamlined expense reporting and accounting integration. order: 1 --- -# Overview -Expensify's integration with NetSuite allows you to automate report exports, tailor your coding preferences, and tap into NetSuite's array of advanced features. By correctly configuring your NetSuite settings in Expensify, you can leverage the connection's settings to automate most of the tasks, making your workflow more efficient. +Expensify's direct integration with NetSuite allows you to automate report exports, tailor your coding preferences, and tap into NetSuite's array of advanced features. -**Before connecting NetSuite to Expensify, a few things to note:** +## Before connecting NetSuite to Expensify, review the following details: - Token-based authentication works by ensuring that each request to NetSuite is accompanied by a signed token which is verified for authenticity - You must be able to login to NetSuite as an administrator to initiate the connection - You must have a Control Plan in Expensify to integrate with NetSuite @@ -15,9 +14,7 @@ Expensify's integration with NetSuite allows you to automate report exports, tai - Ensure that your workspace's report output currency setting matches the NetSuite Subsidiary default currency - Make sure your page size is set to 1000 for importing your customers and vendors. You can check this in NetSuite under **Setup > Integration > Web Services Preferences > 'Search Page Size'** -# Connect to NetSuite - -## Step 1: Install the Expensify Bundle in NetSuite +# Step 1: Install the Expensify Bundle in NetSuite 1. While logged into NetSuite as an administrator, go to Customization > SuiteBundler > Search & Install Bundles, then search for "Expensify" 2. Click on the Expensify Connect bundle (Bundle ID 283395) @@ -25,13 +22,13 @@ Expensify's integration with NetSuite allows you to automate report exports, tai 4. If you already have the Expensify Connect bundle installed, head to _Customization > SuiteBundler > Search & Install Bundles > List_ and update it to the latest version 5. Select **Show on Existing Custom Forms** for all available fields -## Step 2: Enable Token-Based Authentication +# Step 2: Enable Token-Based Authentication 1. Head to _Setup > Company > Enable Features > SuiteCloud > Manage Authentication_ 2. Make sure “Token Based Authentication” is enabled 3. Click **Save** -## Step 3: Add Expensify Integration Role to a User +# Step 3: Add Expensify Integration Role to a User The user you select must have access to at least the permissions included in the Expensify Integration Role, but they're not required to be an Admin. 1. In NetSuite, head to Lists > Employees, and find the user you want to add the Expensify Integration role to @@ -40,7 +37,7 @@ The user you select must have access to at least the permissions included in the Remember that Tokens are linked to a User and a Role, not solely to a User. It's important to note that you cannot establish a connection with tokens using one role and then switch to another role afterward. Once you've initiated a connection with tokens, you must continue using the same token/user/role combination for all subsequent sync or export actions. -## Step 4: Create Access Tokens +# Step 4: Create Access Tokens 1. Using Global Search in NetSuite, enter “page: tokens” 2. Click **New Access Token** @@ -49,21 +46,20 @@ Remember that Tokens are linked to a User and a Role, not solely to a User. It's 5. Press **Save** 6. Copy and Paste the token and token ID to a saved location on your computer (this is the only time you will see these details) -## Step 5: Confirm Expense Reports are Enabled in NetSuite. +# Step 5: Confirm Expense Reports are Enabled in NetSuite. Enabling Expense Reports is required as part of Expensify's integration with NetSuite: 1. Logged into NetSuite as an administrator, go to Setup > Company > Enable Features > Employees 2. Confirm the checkbox next to Expense Reports is checked 3. If not, click the checkbox and then Save to enable Expense Reports -## Step 6: Confirm Expense Categories are set up in NetSuite. +# Step 6: Confirm Expense Categories are set up in NetSuite. Once Expense Reports are enabled, Expense Categories can be set up in NetSuite. Expense Categories are an alias for General Ledger accounts used to code expenses. - 1. Logged into NetSuite as an administrator, go to Setup > Accounting > Expense Categories (a list of Expense Categories should show) 2. If no Expense Categories are visible, click **New** to create new ones -## Step 7: Confirm Journal Entry Transaction Forms are Configured Properly +# Step 7: Confirm Journal Entry Transaction Forms are Configured Properly 1. Logged into NetSuite as an administrator, go to _Customization > Forms > Transaction Forms_ 2. Click **Customize** or **Edit** next to the Standard Journal Entry form @@ -71,7 +67,7 @@ Once Expense Reports are enabled, Expense Categories can be set up in NetSuite. 4. Click the sub-header Lines and verify that the "Show" column for "Receipt URL" is checked 5. Go to _Customization > Forms > Transaction Forms_ and ensure all other transaction forms with the journal type have this same configuration -## Step 8: Confirm Expense Report Transaction Forms are Configured Properly +# Step 8: Confirm Expense Report Transaction Forms are Configured Properly 1. Logged into NetSuite as an administrator, go to _Customization > Forms > Transaction Forms_ 2. Click **Customize** or **Edit** next to the Standard Expense Report form, then click **Screen Fields > Main** @@ -79,7 +75,7 @@ Once Expense Reports are enabled, Expense Categories can be set up in NetSuite. 4. Click the second sub-header, Expenses, and verify that the 'Show' column for 'Receipt URL' is checked 5. Go to _Customization > Forms > Transaction Forms_ and ensure all other transaction forms with the expense report type have this same configuration -## Step 9: Confirm Vendor Bill Transactions Forms are Configured Properly +# Step 9: Confirm Vendor Bill Transactions Forms are Configured Properly 1. Logged into NetSuite as an administrator, go to _Customization > Forms > Transaction Forms_ 2. Click **Customize** or **Edit** next to your preferred Vendor Bill form @@ -87,20 +83,20 @@ Once Expense Reports are enabled, Expense Categories can be set up in NetSuite. 4. Under the Expenses sub-header (make sure to click the "Expenses" sub-header at the very bottom and not "Expenses & Items"), ensure "Show" is checked for Receipt URL, Department, Location, and Class 5. Go to _Customization > Forms > Transaction Forms_ and provide all other transaction forms with the vendor bill type have this same configuration -## Step 10: Confirm Vendor Credit Transactions Forms are Configured Properly +# Step 10: Confirm Vendor Credit Transactions Forms are Configured Properly 1. While logged in as an administrator, go to _Customization > Forms > Transaction Forms_ 2. Click **Customize** or **Edit** next to your preferred Vendor Credit form, then click _Screen Fields > Main_ and verify that the "Created From" label has "Show" checked and that Departments, Classes, and Locations have the "Show" label unchecked 3. Under the Expenses sub-header (make sure to click the "Expenses" sub-header at the very bottom and not "Expenses & Items"), ensure "Show" is checked for Receipt URL, Department, Location, and Class 4. Go to _Customization > Forms > Transaction Forms_ and ensure all other transaction forms with the vendor credit type have this same configuration -## Step 11: Set up Tax Groups (only applicable if tracking taxes) +# Step 11: Set up Tax Groups (only applicable if tracking taxes) Expensify imports NetSuite Tax Groups (not Tax Codes), which you can find in NetSuite under _Setup > Accounting > Tax Groups_. Tax Groups are an alias for Tax Codes in NetSuite and can contain one or more Tax Codes (Please note: for UK and Ireland subsidiaries, please ensure your Tax Groups do not have more than one Tax Code). We recommend naming Tax Groups so your employees can easily understand them, as the name and rate will be displayed in Expensify. -Before importing NetSuite Tax Groups into Expensify: +## Before importing NetSuite Tax Groups into Expensify: 1. Create your Tax Groups in NetSuite by going to _Setup > Accounting > Tax Groups_ 2. Click **New** 3. Select the country for your Tax Group @@ -115,9 +111,9 @@ Ensure Tax Groups can be applied to expenses by going to _Setup > Accounting > S If this field does not display, it’s not needed for that specific country. -## Step 12: Connect Expensify and NetSuite +# Step 12: Connect Expensify and NetSuite -1. Log into Expensify as a Policy Admin and go to **Settings > Workspaces > _[Workspace Name]_ > Connections > NetSuite** +1. Log into Expensify as a Workspace Admin and go to **Settings > Workspaces > _[Workspace Name]_ > Connections > NetSuite** 2. Click **Connect to NetSuite** 3. Enter your Account ID (Account ID can be found in NetSuite by going to _Setup > Integration > Web Services Preferences_) 4. Then, enter the token and token secret diff --git a/docs/assets/images/NetSuite_Configure_06.png b/docs/assets/images/NetSuite_Configure_06.png new file mode 100644 index 000000000000..cddfe2fabcd6 Binary files /dev/null and b/docs/assets/images/NetSuite_Configure_06.png differ diff --git a/docs/assets/images/NetSuite_Configure_08.png b/docs/assets/images/NetSuite_Configure_08.png new file mode 100644 index 000000000000..77690a2c3aa1 Binary files /dev/null and b/docs/assets/images/NetSuite_Configure_08.png differ diff --git a/docs/assets/images/NetSuite_Configure_09.png b/docs/assets/images/NetSuite_Configure_09.png new file mode 100644 index 000000000000..8da56f22838d Binary files /dev/null and b/docs/assets/images/NetSuite_Configure_09.png differ diff --git a/docs/assets/images/NetSuite_Configure_Advanced_10.png b/docs/assets/images/NetSuite_Configure_Advanced_10.png new file mode 100644 index 000000000000..23fe99498052 Binary files /dev/null and b/docs/assets/images/NetSuite_Configure_Advanced_10.png differ diff --git a/docs/assets/images/NetSuite_Connect_Bundle_02.png b/docs/assets/images/NetSuite_Connect_Bundle_02.png new file mode 100644 index 000000000000..c015178873ad Binary files /dev/null and b/docs/assets/images/NetSuite_Connect_Bundle_02.png differ diff --git a/docs/assets/images/NetSuite_Connect_Categories_05.png b/docs/assets/images/NetSuite_Connect_Categories_05.png new file mode 100644 index 000000000000..e71341170129 Binary files /dev/null and b/docs/assets/images/NetSuite_Connect_Categories_05.png differ diff --git a/docs/assets/images/NetSuite_Connect_Customization_01.png b/docs/assets/images/NetSuite_Connect_Customization_01.png new file mode 100644 index 000000000000..8a0c53b45d7f Binary files /dev/null and b/docs/assets/images/NetSuite_Connect_Customization_01.png differ diff --git a/docs/assets/images/NetSuite_Connect_Expense_Reports_03.png b/docs/assets/images/NetSuite_Connect_Expense_Reports_03.png new file mode 100644 index 000000000000..44c8fe6c993d Binary files /dev/null and b/docs/assets/images/NetSuite_Connect_Expense_Reports_03.png differ diff --git a/docs/assets/images/NetSuite_Expense_Categories_04.png b/docs/assets/images/NetSuite_Expense_Categories_04.png new file mode 100644 index 000000000000..d13e9f95cfea Binary files /dev/null and b/docs/assets/images/NetSuite_Expense_Categories_04.png differ diff --git a/docs/assets/images/NetSuite_HelpScreenshot_07.png b/docs/assets/images/NetSuite_HelpScreenshot_07.png new file mode 100644 index 000000000000..55cfe532f890 Binary files /dev/null and b/docs/assets/images/NetSuite_HelpScreenshot_07.png differ diff --git a/ios/NewExpensify/Info.plist b/ios/NewExpensify/Info.plist index 1cd1cdf3ee77..36a986b37b89 100644 --- a/ios/NewExpensify/Info.plist +++ b/ios/NewExpensify/Info.plist @@ -19,7 +19,7 @@ CFBundlePackageType APPL CFBundleShortVersionString - 9.0.50 + 9.0.51 CFBundleSignature ???? CFBundleURLTypes @@ -40,7 +40,7 @@ CFBundleVersion - 9.0.50.1 + 9.0.51.1 FullStory OrgId diff --git a/ios/NewExpensifyTests/Info.plist b/ios/NewExpensifyTests/Info.plist index 7fd36223c03d..f5bd7a20c34a 100644 --- a/ios/NewExpensifyTests/Info.plist +++ b/ios/NewExpensifyTests/Info.plist @@ -15,10 +15,10 @@ CFBundlePackageType BNDL CFBundleShortVersionString - 9.0.50 + 9.0.51 CFBundleSignature ???? CFBundleVersion - 9.0.50.1 + 9.0.51.1 diff --git a/ios/NotificationServiceExtension/Info.plist b/ios/NotificationServiceExtension/Info.plist index 078041a521b9..7c5da25860f0 100644 --- a/ios/NotificationServiceExtension/Info.plist +++ b/ios/NotificationServiceExtension/Info.plist @@ -11,9 +11,9 @@ CFBundleName $(PRODUCT_NAME) CFBundleShortVersionString - 9.0.50 + 9.0.51 CFBundleVersion - 9.0.50.1 + 9.0.51.1 NSExtension NSExtensionPointIdentifier diff --git a/package-lock.json b/package-lock.json index b7e42c99e7d0..2ef609e9ef94 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "new.expensify", - "version": "9.0.50-1", + "version": "9.0.51-1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "new.expensify", - "version": "9.0.50-1", + "version": "9.0.51-1", "hasInstallScript": true, "license": "MIT", "dependencies": { diff --git a/package.json b/package.json index 1705abd4cce5..bad9d3b31469 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "new.expensify", - "version": "9.0.50-1", + "version": "9.0.51-1", "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/CONST.ts b/src/CONST.ts index 171dc7ff2c8a..84003710938a 100755 --- a/src/CONST.ts +++ b/src/CONST.ts @@ -5,18 +5,11 @@ import Config from 'react-native-config'; import * as KeyCommand from 'react-native-key-command'; import type {ValueOf} from 'type-fest'; import type {Video} from './libs/actions/Report'; +import type {MileageRate} from './libs/DistanceRequestUtils'; import BankAccount from './libs/models/BankAccount'; import * as Url from './libs/Url'; import SCREENS from './SCREENS'; import type PlaidBankAccount from './types/onyx/PlaidBankAccount'; -import type {Unit} from './types/onyx/Policy'; - -type RateAndUnit = { - unit: Unit; - rate: number; - currency: string; -}; -type CurrencyDefaultMileageRate = Record; // Creating a default array and object this way because objects ({}) and arrays ([]) are not stable types. // Freezing the array ensures that it cannot be unintentionally modified. @@ -754,6 +747,11 @@ const CONST = { DELAYED_SUBMISSION_HELP_URL: 'https://help.expensify.com/articles/expensify-classic/reports/Automatically-submit-employee-reports', // Use Environment.getEnvironmentURL to get the complete URL with port number DEV_NEW_EXPENSIFY_URL: 'https://dev.new.expensify.com:', + NAVATTIC: { + ADMIN_TOUR: 'https://expensify.navattic.com/kh204a7', + EMPLOYEE_TOUR: 'https://expensify.navattic.com/35609gb', + }, + OLDDOT_URLS: { ADMIN_POLICIES_URL: 'admin_policies', ADMIN_DOMAINS_URL: 'admin_domains', @@ -825,6 +823,7 @@ const CONST = { CARD_MISSING_ADDRESS: 'CARDMISSINGADDRESS', CARD_ISSUED: 'CARDISSUED', CARD_ISSUED_VIRTUAL: 'CARDISSUEDVIRTUAL', + CARD_ASSIGNED: 'CARDASSIGNED', CHANGE_FIELD: 'CHANGEFIELD', // OldDot Action CHANGE_POLICY: 'CHANGEPOLICY', // OldDot Action CHANGE_TYPE: 'CHANGETYPE', // OldDot Action @@ -1131,6 +1130,9 @@ const CONST = { SEARCH_OPTION_LIST_DEBOUNCE_TIME: 300, RESIZE_DEBOUNCE_TIME: 100, UNREAD_UPDATE_DEBOUNCE_TIME: 300, + SEARCH_CONVERT_SEARCH_VALUES: 'search_convert_search_values', + SEARCH_MAKE_TREE: 'search_make_tree', + SEARCH_BUILD_TREE: 'search_build_tree', SEARCH_FILTER_OPTIONS: 'search_filter_options', USE_DEBOUNCED_STATE_DELAY: 300, }, @@ -1492,14 +1494,18 @@ const CONST = { EXPORTER: 'exporter', MARK_CHECKS_TO_BE_PRINTED: 'markChecksToBePrinted', REIMBURSABLE_ACCOUNT: 'reimbursableAccount', + NON_REIMBURSABLE_ACCOUNT: 'nonReimbursableAccount', REIMBURSABLE: 'reimbursable', + NON_REIMBURSABLE: 'nonReimbursable', + SHOULD_AUTO_CREATE_VENDOR: 'shouldAutoCreateVendor', + NON_REIMBURSABLE_BILL_DEFAULT_VENDOR: 'nonReimbursableBillDefaultVendor', AUTO_SYNC: 'autoSync', ENABLE_NEW_CATEGORIES: 'enableNewCategories', - SHOULD_AUTO_CREATE_VENDOR: 'shouldAutoCreateVendor', MAPPINGS: { CLASSES: 'classes', CUSTOMERS: 'customers', }, + IMPORT_ITEMS: 'importItems', }, QUICKBOOKS_CONFIG: { @@ -1614,7 +1620,6 @@ const CONST = { VENDOR_BILL: 'VENDOR_BILL', CHECK: 'CHECK', JOURNAL_ENTRY: 'JOURNAL_ENTRY', - NOTHING: 'NOTHING', }, SAGE_INTACCT_REIMBURSABLE_EXPENSE_TYPE: { @@ -1889,7 +1894,7 @@ const CONST = { QUICKBOOKS_DESKTOP_NON_REIMBURSABLE_EXPORT_ACCOUNT_TYPE: { CREDIT_CARD: 'CREDIT_CARD_CHARGE', - JOURNAL_ENTRY: 'JOURNAL_ENTRY', + CHECK: 'CHECK', VENDOR_BILL: 'VENDOR_BILL', }, @@ -2382,6 +2387,7 @@ const CONST = { SYNC_STAGE_NAME: { STARTING_IMPORT_QBO: 'startingImportQBO', STARTING_IMPORT_XERO: 'startingImportXero', + STARTING_IMPORT_QBD: 'startingImportQBD', QBO_IMPORT_MAIN: 'quickbooksOnlineImportMain', QBO_IMPORT_CUSTOMERS: 'quickbooksOnlineImportCustomers', QBO_IMPORT_EMPLOYEES: 'quickbooksOnlineImportEmployees', @@ -2398,6 +2404,17 @@ const CONST = { QBO_SYNC_APPLY_CUSTOMERS: 'quickbooksOnlineSyncApplyCustomers', QBO_SYNC_APPLY_PEOPLE: 'quickbooksOnlineSyncApplyEmployees', QBO_SYNC_APPLY_CLASSES_LOCATIONS: 'quickbooksOnlineSyncApplyClassesLocations', + QBD_IMPORT_TITLE: 'quickbooksDesktopImportTitle', + QBD_IMPORT_ACCOUNTS: 'quickbooksDesktopImportAccounts', + QBD_IMPORT_APPROVE_CERTIFICATE: 'quickbooksDesktopImportApproveCertificate', + QBD_IMPORT_DIMENSIONS: 'quickbooksDesktopImportDimensions', + QBD_IMPORT_CLASSES: 'quickbooksDesktopImportClasses', + QBD_IMPORT_CUSTOMERS: 'quickbooksDesktopImportCustomers', + QBD_IMPORT_VENDORS: 'quickbooksDesktopImportVendors', + QBD_IMPORT_EMPLOYEES: 'quickbooksDesktopImportEmployees', + QBD_IMPORT_MORE: 'quickbooksDesktopImportMore', + QBD_IMPORT_GENERIC: 'quickbooksDesktopImportSavePolicy', + QBD_WEB_CONNECTOR_REMINDER: 'quickbooksDesktopWebConnectorReminder', JOB_DONE: 'jobDone', XERO_SYNC_STEP: 'xeroSyncStep', XERO_SYNC_XERO_REIMBURSED_REPORTS: 'xeroSyncXeroReimbursedReports', @@ -2466,6 +2483,8 @@ const CONST = { DEFAULT_RATE: 'Default Rate', RATE_DECIMALS: 3, FAKE_P2P_ID: '_FAKE_P2P_ID_', + MILES_TO_KILOMETERS: 1.609344, + KILOMETERS_TO_MILES: 0.621371, }, TERMS: { @@ -2509,6 +2528,7 @@ const CONST = { MASTER_CARD: 'cdf', VISA: 'vcf', AMEX: 'gl1025', + STRIPE: 'stripe', }, STEP_NAMES: ['1', '2', '3', '4'], STEP: { @@ -2907,6 +2927,7 @@ const CONST = { SETTINGS: 'settings', LEAVE_ROOM: 'leaveRoom', PRIVATE_NOTES: 'privateNotes', + DOWNLOAD: 'download', EXPORT: 'export', DELETE: 'delete', MARK_AS_INCOMPLETE: 'markAsIncomplete', @@ -5525,7 +5546,7 @@ const CONST = { "rate": 2377, "unit": "km" } - }`) as CurrencyDefaultMileageRate, + }`) as Record, EXIT_SURVEY: { REASONS: { @@ -5683,7 +5704,6 @@ const CONST = { KEYWORD: 'keyword', IN: 'in', }, - EMPTY_VALUE: 'none', }, REFERRER: { @@ -5768,6 +5788,14 @@ const CONST = { description: `workspace.upgrade.${this.POLICY.CONNECTIONS.NAME.SAGE_INTACCT}.description` as const, icon: 'IntacctSquare', }, + [this.POLICY.CONNECTIONS.NAME.QBD]: { + id: this.POLICY.CONNECTIONS.NAME.QBD, + alias: 'qbd', + name: this.POLICY.CONNECTIONS.NAME_USER_FRIENDLY.quickbooksDesktop, + title: `workspace.upgrade.${this.POLICY.CONNECTIONS.NAME.QBD}.title` as const, + description: `workspace.upgrade.${this.POLICY.CONNECTIONS.NAME.QBD}.description` as const, + icon: 'QBDSquare', + }, approvals: { id: 'approvals' as const, alias: 'approvals' as const, @@ -5920,7 +5948,6 @@ export type { Country, IOUAction, IOUType, - RateAndUnit, OnboardingPurposeType, OnboardingCompanySizeType, IOURequestType, diff --git a/src/ONYXKEYS.ts b/src/ONYXKEYS.ts index 0b69fe9be80b..14c0dc4abc50 100755 --- a/src/ONYXKEYS.ts +++ b/src/ONYXKEYS.ts @@ -441,6 +441,12 @@ const ONYXKEYS = { /** Stores recently used currencies */ RECENTLY_USED_CURRENCIES: 'nvp_recentlyUsedCurrencies', + /** States whether we transitioned from OldDot to show only certain group of screens. It should be undefined on pure NewDot. */ + IS_SINGLE_NEW_DOT_ENTRY: 'isSingleNewDotEntry', + + /** Company cards custom names */ + NVP_EXPENSIFY_COMPANY_CARDS_CUSTOM_NAMES: 'nvp_expensify_ccCustomNames', + /** Collection Keys */ COLLECTION: { DOWNLOAD: 'download_', @@ -849,7 +855,7 @@ type OnyxCollectionValuesMapping = { [ONYXKEYS.COLLECTION.WORKSPACE_CARDS_LIST]: OnyxTypes.WorkspaceCardsList; [ONYXKEYS.COLLECTION.EXPENSIFY_CARD_CONTINUOUS_RECONCILIATION_CONNECTION]: OnyxTypes.PolicyConnectionName; [ONYXKEYS.COLLECTION.EXPENSIFY_CARD_USE_CONTINUOUS_RECONCILIATION]: boolean; - [ONYXKEYS.COLLECTION.LAST_SELECTED_FEED]: string; + [ONYXKEYS.COLLECTION.LAST_SELECTED_FEED]: OnyxTypes.CompanyCardFeed; }; type OnyxValuesMapping = { @@ -1001,8 +1007,10 @@ type OnyxValuesMapping = { [ONYXKEYS.APPROVAL_WORKFLOW]: OnyxTypes.ApprovalWorkflowOnyx; [ONYXKEYS.IMPORTED_SPREADSHEET]: OnyxTypes.ImportedSpreadsheet; [ONYXKEYS.LAST_ROUTE]: string; + [ONYXKEYS.IS_SINGLE_NEW_DOT_ENTRY]: boolean | undefined; [ONYXKEYS.IS_USING_IMPORTED_STATE]: boolean; [ONYXKEYS.SHOULD_SHOW_SAVED_SEARCH_RENAME_TOOLTIP]: boolean; + [ONYXKEYS.NVP_EXPENSIFY_COMPANY_CARDS_CUSTOM_NAMES]: Record; }; type OnyxValues = OnyxValuesMapping & OnyxCollectionValuesMapping & OnyxFormValuesMapping & OnyxFormDraftValuesMapping; diff --git a/src/ROUTES.ts b/src/ROUTES.ts index 98ea64bc65b4..a8d562c8f244 100644 --- a/src/ROUTES.ts +++ b/src/ROUTES.ts @@ -669,6 +669,22 @@ const ROUTES = { route: 'settings/workspaces/:policyID/accounting/quickbooks-online/export/date-select', getRoute: (policyID: string) => `settings/workspaces/${policyID}/accounting/quickbooks-online/export/date-select` as const, }, + POLICY_ACCOUNTING_QUICKBOOKS_DESKTOP_COMPANY_CARD_EXPENSE_ACCOUNT_SELECT: { + route: 'settings/workspaces/:policyID/accounting/quickbooks-desktop/export/company-card-expense-account/account-select', + getRoute: (policyID: string) => `settings/workspaces/${policyID}/accounting/quickbooks-desktop/export/company-card-expense-account/account-select` as const, + }, + POLICY_ACCOUNTING_QUICKBOOKS_DESKTOP_COMPANY_CARD_EXPENSE_SELECT: { + route: 'settings/workspaces/:policyID/accounting/quickbooks-desktop/export/company-card-expense-account/card-select', + getRoute: (policyID: string) => `settings/workspaces/${policyID}/accounting/quickbooks-desktop/export/company-card-expense-account/card-select` as const, + }, + POLICY_ACCOUNTING_QUICKBOOKS_DESKTOP_NON_REIMBURSABLE_DEFAULT_VENDOR_SELECT: { + route: 'settings/workspaces/:policyID/accounting/quickbooks-desktop/export/company-card-expense-account/default-vendor-select', + getRoute: (policyID: string) => `settings/workspaces/${policyID}/accounting/quickbooks-desktop/export/company-card-expense-account/default-vendor-select` as const, + }, + POLICY_ACCOUNTING_QUICKBOOKS_DESKTOP_COMPANY_CARD_EXPENSE_ACCOUNT: { + route: 'settings/workspaces/:policyID/accounting/quickbooks-desktop/export/company-card-expense-account', + getRoute: (policyID: string) => `settings/workspaces/${policyID}/accounting/quickbooks-desktop/export/company-card-expense-account` as const, + }, WORKSPACE_ACCOUNTING_QUICKBOOKS_DESKTOP_ADVANCED: { route: 'settings/workspaces/:policyID/accounting/quickbooks-desktop/advanced', getRoute: (policyID: string) => `settings/workspaces/${policyID}/accounting/quickbooks-desktop/advanced` as const, @@ -733,6 +749,10 @@ const ROUTES = { route: 'settings/workspaces/:policyID/accounting/quickbooks-desktop/import/customers/displayed_as', getRoute: (policyID: string) => `settings/workspaces/${policyID}/accounting/quickbooks-desktop/import/customers/displayed_as` as const, }, + POLICY_ACCOUNTING_QUICKBOOKS_DESKTOP_ITEMS: { + route: 'settings/workspaces/:policyID/accounting/quickbooks-desktop/import/items', + getRoute: (policyID: string) => `settings/workspaces/${policyID}/accounting/quickbooks-desktop/import/items` as const, + }, WORKSPACE_PROFILE_NAME: { route: 'settings/workspaces/:policyID/profile/name', getRoute: (policyID: string) => `settings/workspaces/${policyID}/profile/name` as const, @@ -1072,7 +1092,7 @@ const ROUTES = { }, WORKSPACE_COMPANY_CARDS_ASSIGN_CARD: { route: 'settings/workspaces/:policyID/company-cards/:feed/assign-card', - getRoute: (policyID: string, feed: string) => `settings/workspaces/${policyID}/company-cards/${feed}/assign-card` as const, + getRoute: (policyID: string, feed: string, backTo?: string) => getUrlWithBackToParam(`settings/workspaces/${policyID}/company-cards/${feed}/assign-card`, backTo), }, WORKSPACE_COMPANY_CARD_DETAILS: { route: 'settings/workspaces/:policyID/company-cards/:bank/:cardID', diff --git a/src/SCREENS.ts b/src/SCREENS.ts index 719c67f0365b..39df4594c277 100644 --- a/src/SCREENS.ts +++ b/src/SCREENS.ts @@ -316,6 +316,10 @@ const SCREENS = { QUICKBOOKS_ONLINE_ADVANCED: 'Policy_Accounting_Quickbooks_Online_Advanced', QUICKBOOKS_ONLINE_ACCOUNT_SELECTOR: 'Policy_Accounting_Quickbooks_Online_Account_Selector', QUICKBOOKS_ONLINE_INVOICE_ACCOUNT_SELECTOR: 'Policy_Accounting_Quickbooks_Online_Invoice_Account_Selector', + QUICKBOOKS_DESKTOP_COMPANY_CARD_EXPENSE_ACCOUNT_SELECT: 'Workspace_Accounting_Quickbooks_Desktop_Export_Company_Card_Expense_Account_Select', + QUICKBOOKS_DESKTOP_COMPANY_CARD_EXPENSE_ACCOUNT_COMPANY_CARD_SELECT: 'Workspace_Accounting_Quickbooks_Desktop_Export_Company_Card_Expense_Select', + QUICKBOOKS_DESKTOP_COMPANY_CARD_EXPENSE_ACCOUNT: 'Workspace_Accounting_Quickbooks_Desktop_Export_Company_Card_Expense', + QUICKBOOKS_DESKTOP_NON_REIMBURSABLE_DEFAULT_VENDOR_SELECT: 'Workspace_Accounting_Quickbooks_Desktop_Export_Non_Reimbursable_Default_Vendor_Select', QUICKBOOKS_DESKTOP_ADVANCED: 'Policy_Accounting_Quickbooks_Desktop_Advanced', QUICKBOOKS_DESKTOP_EXPORT_DATE_SELECT: 'Workspace_Accounting_Quickbooks_Desktop_Export_Date_Select', QUICKBOOKS_DESKTOP_EXPORT_PREFERRED_EXPORTER: 'Workspace_Accounting_Quickbooks_Desktop_Export_Preferred_Exporter', @@ -332,6 +336,7 @@ const SCREENS = { QUICKBOOKS_DESKTOP_CLASSES_DISPLAYED_AS: 'Policy_Accounting_Quickbooks_Desktop_Import_Classes_Dipslayed_As', QUICKBOOKS_DESKTOP_CUSTOMERS: 'Policy_Accounting_Quickbooks_Desktop_Import_Customers', QUICKBOOKS_DESKTOP_CUSTOMERS_DISPLAYED_AS: 'Policy_Accounting_Quickbooks_Desktop_Import_Customers_Dipslayed_As', + QUICKBOOKS_DESKTOP_ITEMS: 'Policy_Accounting_Quickbooks_Desktop_Import_Items', XERO_IMPORT: 'Policy_Accounting_Xero_Import', XERO_ORGANIZATION: 'Policy_Accounting_Xero_Customers', XERO_CHART_OF_ACCOUNTS: 'Policy_Accounting_Xero_Import_Chart_Of_Accounts', diff --git a/src/components/CategoryPicker.tsx b/src/components/CategoryPicker.tsx index a8117fc1f4a0..33d97c6909f5 100644 --- a/src/components/CategoryPicker.tsx +++ b/src/components/CategoryPicker.tsx @@ -44,20 +44,14 @@ function CategoryPicker({selectedCategory, policyID, onSubmit}: CategoryPickerPr const [sections, headerMessage, shouldShowTextInput] = useMemo(() => { const categories = policyCategories ?? policyCategoriesDraft ?? {}; const validPolicyRecentlyUsedCategories = policyRecentlyUsedCategories?.filter?.((p) => !isEmptyObject(p)); - const {categoryOptions} = OptionsListUtils.getFilteredOptions( - [], - [], - [], - debouncedSearchValue, + const {categoryOptions} = OptionsListUtils.getFilteredOptions({ + searchValue: debouncedSearchValue, selectedOptions, - [], - false, - false, - true, + includeP2P: false, + includeCategories: true, categories, - validPolicyRecentlyUsedCategories, - false, - ); + recentlyUsedCategories: validPolicyRecentlyUsedCategories, + }); const categoryData = categoryOptions?.at(0)?.data ?? []; const header = OptionsListUtils.getHeaderMessageForNonUserList(categoryData.length > 0, debouncedSearchValue); diff --git a/src/components/ConnectToQuickbooksDesktopFlow/index.tsx b/src/components/ConnectToQuickbooksDesktopFlow/index.tsx index bf1315b452c6..07ca376a7449 100644 --- a/src/components/ConnectToQuickbooksDesktopFlow/index.tsx +++ b/src/components/ConnectToQuickbooksDesktopFlow/index.tsx @@ -1,7 +1,6 @@ import {useEffect} from 'react'; import useResponsiveLayout from '@hooks/useResponsiveLayout'; import Navigation from '@libs/Navigation/Navigation'; -import * as PolicyAction from '@userActions/Policy/Policy'; import ROUTES from '@src/ROUTES'; import type {ConnectToQuickbooksDesktopFlowProps} from './types'; @@ -12,8 +11,6 @@ function ConnectToQuickbooksDesktopFlow({policyID}: ConnectToQuickbooksDesktopFl if (isSmallScreenWidth) { Navigation.navigate(ROUTES.POLICY_ACCOUNTING_QUICKBOOKS_DESKTOP_SETUP_REQUIRED_DEVICE_MODAL.getRoute(policyID)); } else { - // Since QBD doesn't support Taxes, we should disable them from the LHN when connecting to QBD - PolicyAction.enablePolicyTaxes(policyID, false); Navigation.navigate(ROUTES.POLICY_ACCOUNTING_QUICKBOOKS_DESKTOP_SETUP_MODAL.getRoute(policyID)); } }, [isSmallScreenWidth, policyID]); diff --git a/src/components/EmojiPicker/EmojiPicker.tsx b/src/components/EmojiPicker/EmojiPicker.tsx index aa6c3e8dfdfb..706265f2e11a 100644 --- a/src/components/EmojiPicker/EmojiPicker.tsx +++ b/src/components/EmojiPicker/EmojiPicker.tsx @@ -56,7 +56,7 @@ function EmojiPicker({viewportOffsetTop}: EmojiPickerProps, ref: ForwardedRef emojiPopoverAnchorRef.current ?? emojiPopoverAnchorRef?.current, []); + const getEmojiPopoverAnchor = useCallback(() => emojiPopoverAnchorRef.current ?? (emojiPopoverAnchorRef as EmojiPopoverAnchor), []); /** * Show the emoji picker menu. diff --git a/src/components/EmptyStateComponent/index.tsx b/src/components/EmptyStateComponent/index.tsx index 8eb991b17b63..81a31174a2ce 100644 --- a/src/components/EmptyStateComponent/index.tsx +++ b/src/components/EmptyStateComponent/index.tsx @@ -18,8 +18,7 @@ function EmptyStateComponent({ SkeletonComponent, headerMediaType, headerMedia, - buttonText, - buttonAction, + buttons, containerStyles, title, titleStyles, @@ -99,15 +98,22 @@ function EmptyStateComponent({ {title} {typeof subtitle === 'string' ? {subtitle} : subtitle} - {!!buttonText && !!buttonAction && ( -