diff --git a/.github/actions/javascript/getReleaseBody/action.yml b/.github/actions/javascript/getReleaseBody/action.yml index e4a451ccda8d..d9e381f8c99d 100644 --- a/.github/actions/javascript/getReleaseBody/action.yml +++ b/.github/actions/javascript/getReleaseBody/action.yml @@ -1,6 +1,9 @@ name: 'Get Release Body' description: 'Generate the body of a production release' inputs: + GITHUB_TOKEN: + description: Auth token for New Expensify Github + required: true PR_LIST: description: JSON array of pull request numbers (string) required: true diff --git a/.github/workflows/createNewVersion.yml b/.github/workflows/createNewVersion.yml index 653495b5a01a..ca9a128e848d 100644 --- a/.github/workflows/createNewVersion.yml +++ b/.github/workflows/createNewVersion.yml @@ -55,7 +55,7 @@ jobs: steps: - name: Run turnstyle - uses: softprops/turnstyle@ca99add00ff0c9cbc697d22631d2992f377e5bd5 + uses: softprops/turnstyle@49108bdfa571e62371bd2c3094893c547ab3fc03 with: poll-interval-seconds: 10 env: diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 5aacf0ceea1d..5960eb77dddb 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -80,6 +80,7 @@ jobs: id: getReleaseBody uses: ./.github/actions/javascript/getReleaseBody with: + GITHUB_TOKEN: ${{ github.token }} PR_LIST: ${{ steps.getReleasePRList.outputs.PR_LIST }} - name: 🚀 Create release to trigger production deploy 🚀 diff --git a/.github/workflows/preDeploy.yml b/.github/workflows/preDeploy.yml index bb1cd71c9518..5cfe5e213d2f 100644 --- a/.github/workflows/preDeploy.yml +++ b/.github/workflows/preDeploy.yml @@ -86,7 +86,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Run turnstyle - uses: softprops/turnstyle@ca99add00ff0c9cbc697d22631d2992f377e5bd5 + uses: softprops/turnstyle@49108bdfa571e62371bd2c3094893c547ab3fc03 with: poll-interval-seconds: 10 env: diff --git a/Gemfile.lock b/Gemfile.lock index 64f4d81c9e76..12cae5d0eb21 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -89,7 +89,7 @@ GEM escape (0.0.4) ethon (0.16.0) ffi (>= 1.15.0) - excon (0.110.0) + excon (0.111.0) faraday (1.10.3) faraday-em_http (~> 1.0) faraday-em_synchrony (~> 1.0) @@ -111,7 +111,7 @@ GEM faraday-httpclient (1.0.1) faraday-multipart (1.0.4) multipart-post (~> 2) - faraday-net_http (1.0.1) + faraday-net_http (1.0.2) faraday-net_http_persistent (1.2.0) faraday-patron (1.0.0) faraday-rack (1.0.0) @@ -119,7 +119,7 @@ GEM faraday_middleware (1.2.0) faraday (~> 1.0) fastimage (2.3.1) - fastlane (2.221.1) + fastlane (2.222.0) CFPropertyList (>= 2.3, < 4.0.0) addressable (>= 2.8, < 3.0.0) artifactory (~> 3.0) @@ -167,7 +167,7 @@ GEM ffi (1.17.0) ffi (1.17.0-arm64-darwin) ffi (1.17.0-x86_64-darwin) - ffi (1.17.0-x86_64-linux-gnu) + ffi (1.17.0-x86_64-linux) fourflusher (2.3.1) fuzzy_match (2.0.4) gh_inspector (1.1.3) @@ -220,7 +220,7 @@ GEM mime-types (3.5.1) mime-types-data (~> 3.2015) mime-types-data (3.2023.1003) - mini_magick (4.13.1) + mini_magick (4.13.2) mini_mime (1.1.5) minitest (5.24.0) molinillo (0.8.0) @@ -294,7 +294,7 @@ PLATFORMS DEPENDENCIES activesupport (>= 6.1.7.3, < 7.1.0) cocoapods (= 1.15.2) - fastlane (~> 2) + fastlane (~> 2, >= 2.222.0) fastlane-plugin-aws_s3 xcpretty (~> 0) diff --git a/__mocks__/@react-native-firebase/crashlytics.ts b/__mocks__/@react-native-firebase/crashlytics.ts index 2df845ba0c69..9a7179041320 100644 --- a/__mocks__/@react-native-firebase/crashlytics.ts +++ b/__mocks__/@react-native-firebase/crashlytics.ts @@ -1,6 +1,6 @@ import type {FirebaseCrashlyticsTypes} from '@react-native-firebase/crashlytics'; -type CrashlyticsModule = Pick; +type CrashlyticsModule = Pick; type CrashlyticsMock = () => CrashlyticsModule; @@ -10,6 +10,7 @@ const crashlyticsMock: CrashlyticsMock = () => ({ log: jest.fn(), recordError: jest.fn(), setCrashlyticsCollectionEnabled: jest.fn(), + setUserId: jest.fn(), }); export default crashlyticsMock; diff --git a/android/app/build.gradle b/android/app/build.gradle index 2491fb4cd7df..04d012c03e76 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -108,8 +108,8 @@ android { minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion multiDexEnabled rootProject.ext.multiDexEnabled - versionCode 1009001405 - versionName "9.0.14-5" + versionCode 1009001504 + versionName "9.0.15-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/assets/images/integrationicons/qbo-icon-circle.svg b/assets/images/integrationicons/qbo-icon-circle.svg new file mode 100644 index 000000000000..973f07ed8b8f --- /dev/null +++ b/assets/images/integrationicons/qbo-icon-circle.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/images/integrationicons/xero-icon-circle.svg b/assets/images/integrationicons/xero-icon-circle.svg new file mode 100644 index 000000000000..6c19f0f9e10a --- /dev/null +++ b/assets/images/integrationicons/xero-icon-circle.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/articles/expensify-classic/connections/sage-intacct/Connect-To-Sage-Intacct.md b/docs/articles/expensify-classic/connections/sage-intacct/Connect-To-Sage-Intacct.md index e32db29ee3ab..76851a35ce4c 100644 --- a/docs/articles/expensify-classic/connections/sage-intacct/Connect-To-Sage-Intacct.md +++ b/docs/articles/expensify-classic/connections/sage-intacct/Connect-To-Sage-Intacct.md @@ -4,10 +4,15 @@ description: Connect your Expensify workspace with Sage Intacct order: 1 --- # Overview + Expensify’s seamless integration with Sage Intacct allows you to connect using either Role-based permissions or User-based permissions. Once connected to Intacct you’re able to automate report exports, customize your coding preferences, and utilize Sage Intacct’s advanced features. When you’ve configured these settings in Expensify correctly, you can use the integration's settings to automate many tasks, streamlining your workflow for increased efficiency. +{% include info.html %} +The Sage Intacct integration is only available on the Control plan. +{% include end-info.html %} + # How to connect to Sage Intacct We support setting up Sage Intacct with both User-based permissions and Role-based permissions for Expense Reports and Vendor Bills. - User-based Permissions - Expense Reports diff --git a/docs/articles/expensify-classic/connections/xero/Xero-Troubleshooting.md b/docs/articles/expensify-classic/connections/xero/Xero-Troubleshooting.md index f1bb398dbecf..f23ec515cde4 100644 --- a/docs/articles/expensify-classic/connections/xero/Xero-Troubleshooting.md +++ b/docs/articles/expensify-classic/connections/xero/Xero-Troubleshooting.md @@ -5,7 +5,7 @@ description: Xero Troubleshooting # Overview of Xero Troubleshooting -Synchronizing and exporting data between Expensify and NetSuite can streamline your financial processes, but occasionally, users may encounter errors that prevent a smooth integration. These errors often arise from discrepancies in settings, missing data, or configuration issues within NetSuite or Expensify. +Synchronizing and exporting data between Expensify and Xero can streamline your financial processes, but occasionally, users may encounter errors that prevent a smooth integration. These errors often arise from discrepancies in settings, missing data, or configuration issues within Xero or Expensify. This troubleshooting guide aims to help you identify and resolve common sync and export errors, ensuring a seamless connection between your financial management systems. By following the step-by-step solutions provided for each specific error, you can quickly address issues and maintain accurate and efficient expense reporting and data management. diff --git a/docs/articles/expensify-classic/reports/Add-custom-fields-to-reports-and-invoices.md b/docs/articles/expensify-classic/reports/Add-custom-fields-to-reports-and-invoices.md index ce0f60d3be56..8203638ce7f9 100644 --- a/docs/articles/expensify-classic/reports/Add-custom-fields-to-reports-and-invoices.md +++ b/docs/articles/expensify-classic/reports/Add-custom-fields-to-reports-and-invoices.md @@ -4,10 +4,10 @@ description: Customize the fields that appear on a report or an invoice ---
-Workspace Admins can add additional required fields to a report to include selections for project names, locations, trip information, and more. +Workspace Admins can add additional required report fields which allow you to specify header-level details like specific project names, business trip information, locations, and more. {% include info.html %} -You cannot create these report fields directly in Expensify if you are connected to an accounting integration (QuickBooks Online, QuickBooks Desktop, Intacct, Xero, or NetSuite). Please refer to the relevant article for instructions on creating fields within that system. +Report fields are only available on the Control plan. You cannot create these report fields directly in Expensify if you are connected to an accounting integration (QuickBooks Online, QuickBooks Desktop, Intacct, Xero, or NetSuite). Please refer to the relevant article for instructions on creating fields within that system. {% include end-info.html %} To create a custom field for a report, diff --git a/docs/articles/expensify-classic/reports/Create-a-report-approval-workflow.md b/docs/articles/expensify-classic/reports/Create-a-report-approval-workflow.md index 015bbe2e8532..f39ffe1a05ad 100644 --- a/docs/articles/expensify-classic/reports/Create-a-report-approval-workflow.md +++ b/docs/articles/expensify-classic/reports/Create-a-report-approval-workflow.md @@ -18,7 +18,9 @@ Expensify allows Workspace Admins to create workflows and automations that deter 5. Select an approval mode. - **Submit and Close**: No approval is required. Once a report is submitted, it will be automatically approved and closed. This option may be useful if your expense approvals occur in another system or if the submitter and approver are the same person. - **Submit and Approve**: All reports go to one person that you assign as the approver. Once a report is submitted, it is sent to the approver. This is the default option. - - **Advanced Approval**: Allows for more complex workflows, like assigning different approvers for different employees or requiring secondary approvals for expenses that exceed a set limit. + - **Advanced Approval**: This workflow feature is for companies that require more than one person to approve a report before it can be reimbursed. + Advanced Approval is only available on the Control plan. + To add to your approval workflow, you can also set up approval rules for specific categories and tags. diff --git a/docs/articles/expensify-classic/travel/Approve-travel-expenses.md b/docs/articles/expensify-classic/travel/Approve-travel-expenses.md index ae0feb4efaa6..585e930a3dde 100644 --- a/docs/articles/expensify-classic/travel/Approve-travel-expenses.md +++ b/docs/articles/expensify-classic/travel/Approve-travel-expenses.md @@ -17,6 +17,40 @@ Travel expenses follow the same approval workflow as other expenses. Admins can 3. Click the **Program** tab at the top and select **Policies**. 4. Under General, select approval methods for Flights, Hotels, Cars and Rail. +![Screenshot of Expensify Travel policy approval settings](https://help.expensify.com/assets/images/Travel_Policy.png){:width="100%"} + +# Approve travel + +![Screenshot of Expensify Travel approval email](https://help.expensify.com/assets/images/Travel_Email.png){:width="100%"} + +## Soft approval + +Once an employee has booked a trip, their approver will receive an email notifying them of the booking with a prompt to decline it if needed. + +- To approve the booking, no action is required. +- To decline the booking, click **Decline booking** within 24 hours. Then click **Deny Booking**. + +## Hard approval + +Once an employee has booked a trip, their approver will receive an email notifying them of the booking with a prompt to accept or decline the booking. + +To approve the booking, click **Approve booking**. Then click **Approve**. +To decline the booking, click **Decline booking**. Then click **Deny**. + +# FAQs + +## Are extended approval windows given for trips booked over the weekend or during company holidays? + +No, the approval window will always be 24 hours from when the trip is booked. + +## How does Expensify Travel handle approvals when the assigned approver is out of office? + +It is recommended to have multiple approvers for travel, as there is no delegated approval for out-of-office approvers. + +## Can travelers upload a document when submitting a trip for approval? + +Travelers are unable to add a document when submitting a trip for approval, but the company can add a ‘reason code’ in the Out of Policy rules that the traveler can complete at checkout. The traveler can then add the document to the expense report in Expensify when submitting the report. +
@@ -34,4 +68,38 @@ Travel expenses follow the same approval workflow as other expenses. Admins can 3. Click the **Program** tab at the top and select **Policies**. 4. Under General, select approval methods for Flights, Hotels, Cars and Rail. +![Screenshot of Expensify Travel policy approval settings](https://help.expensify.com/assets/images/Travel_Policy.png){:width="100%"} + +# Approve travel + +![Screenshot of Expensify Travel approval email](https://help.expensify.com/assets/images/Travel_Email.png){:width="100%"} + +## Soft approval + +Once an employee has booked a trip, their approver will receive an email notifying them of the booking with a prompt to decline it if needed. + +- To approve the booking, no action is required. +- To decline the booking, click **Decline booking** within 24 hours. Then click **Deny Booking**. + +## Hard approval + +Once an employee has booked a trip, their approver will receive an email notifying them of the booking with a prompt to accept or decline the booking. + +To approve the booking, click **Approve booking**. Then click **Approve**. +To decline the booking, click **Decline booking**. Then click **Deny**. + +# FAQs + +## Are extended approval windows given for trips booked over the weekend or during company holidays? + +No, the approval window will always be 24 hours from when the trip is booked. + +## How does Expensify Travel handle approvals when the assigned approver is out of office? + +It is recommended to have multiple approvers for travel, as there is no delegated approval for out-of-office approvers. + +## Can travelers upload a document when submitting a trip for approval? + +Travelers are unable to add a document when submitting a trip for approval, but the company can add a ‘reason code’ in the Out of Policy rules that the traveler can complete at checkout. The traveler can then add the document to the expense report in Expensify when submitting the report. +
diff --git a/docs/articles/expensify-classic/travel/Configure-travel-policy-and-preferences.md b/docs/articles/expensify-classic/travel/Configure-travel-policy-and-preferences.md index 2e17af06773c..7e9a217b34ec 100644 --- a/docs/articles/expensify-classic/travel/Configure-travel-policy-and-preferences.md +++ b/docs/articles/expensify-classic/travel/Configure-travel-policy-and-preferences.md @@ -4,32 +4,78 @@ description: Set and update travel policies and preferences for your Expensify W ---
-As a Workspace Admin, you can set travel policies for all travel booked under your workspace, including approval methods, flight booking class, and hotel star preferences. You can also create multiple policies with specific conditions for particular groups of employees and/or non-employees. +As a Workspace Admin, you can set travel policies for all travel booked under a workspace, including approval methods, flight booking class, and hotel star preferences. You can also create multiple policies with specific conditions for particular groups of employees and/or non-employees. -# Create a travel policy +# Create or update a travel policy -When using Expensify Travel for the first time, you will need to create a new Travel Policy. +Workspace admins can create different travel policies that provide travel rules for different groups of travelers. When using Expensify Travel for the first time, you will need to create a new Travel Policy. -To create a travel policy from the Expensify web app, +To create or update a travel policy, 1. Click the **Travel** tab. 2. Click **Book or manage travel**. 3. Click the **Program** tab at the top and select **Policies**. 4. Under Employee or Non-employee in the left menu, click **Add new** to create a new policy. -5. Use the **Edit members** section to select the group of employees that belong to this policy. A Legal Entity in Expensify Travel is the equivalent of an Expensify Workspace. -6. Select which travel preferences you want to modify: General, flight, hotel, car, or rail. -7. Click the paperclip icon next to each setting to de-couple it from your default policy. -8. Update the desired settings. +5. Use the **Edit members** section to select the group of employees that belong to this policy. + 1. **To select an existing policy:** Select the policy in the left menu. + 2. **To add a new policy:** Click **Add new** under Employee or Non-employee in the left menu. Then under the Edit members section, select the group of employees that belong to this policy. -# Update travel policy preferences +{% include info.html %} +A Legal Entity in Expensify Travel is the equivalent of an Expensify Workspace. +{% include end-info.html %} -1. Click the **Travel** tab. -2. Click **Book or manage travel**. -3. Click the **Program** tab at the top and select **Policies**. -4. Select the appropriate policy in the left menu. -5. Select which travel preferences you want to modify: General, flight, hotel, car, or rail. -6. Click the paperclip icon next to each setting to de-couple it from your default policy. -7. Update the desired policies. +10. Select which travel preferences you want to modify: General, flight, hotel, car, or rail. +11. Click the paperclip icon next to each setting to de-couple it from your default policy. +12. Update the desired settings. + +# General + +Determine the currency and [approval type](https://help.expensify.com/articles/expensify-classic/travel/Approve-travel-expenses#set-approval-method) for different types of travel bookings. You can also upload a PDF of your company travel policy for employees to access when booking travel. + +![Screenshot of Expensify Travel policy approval settings](https://help.expensify.com/assets/images/Travel_Policy.png){:width="100%"} + +# Flight + +Flight preferences include multiple sections with different settings: + +- **Flights not allowed to be booked:** Restrict specific flight classes from being booked by employees. +- **Cabin class settings:** Set the highest cabin class allowed for booking and whether employees can accept cabin upgrades. +- **Budget:** Set a percentage or fare cap for the median or cheapest fares on flights, and a maximum capped price. Flight fares above this cap will be considered out of policy. You can also add customization to allow for different caps for different flight durations. +- **Lowest logical fare settings:** Set a preference for layovers, number of stops, flight time window, and airport connection changes. Expensify automatically takes these preferences into account when showing the lowest logical travel fare. +- **Add Ons and Preferences:** Select what types of add-ons your employees can book, including: + - Additional baggage + - Early check-in + - Seat preference + - No add-ons allowed +- **Booking windows:** Add a time limit to prevent employees from booking less than a certain number of days in advance to prohibit bookings too close to the flight time. +- **Refundable/changeable tickets:** Allow employees to book fully or partially refundable fares. To allow all options, you can leave this as the default option. +- **Maximum CO2 per kilometer:** If the CO2 per passenger km exceeds this threshold, the flight will be marked as out of policy. You can leave the entry blank if you do not wish to use this policy. +- **Out of policy reason codes:** If enabled, travelers will be asked to enter a reason code for an out-of-policy flight booking. This gives them a way to provide context for why the booking is still being placed. You can also modify the reason codes by clicking Manage reason codes below the toggle. + +# Hotel + +- **Restrict booking by keyword:** Keywords entered here will be compared to the hotel rate description. If any of the keywords are found, the hotel rate will be restricted. You also have the option to provide a reason why each keyword is restricted. +- **Hotel rates not allowed to be booked:** Restrict specific hotel rates (such as non-refundable, prepaid, and requires deposit) from being booked by employees. This overrides all other hotel policy rules. You also have the option to add a reason why these options aren’t available. +- **Maximum price:** Set a maximum price per night for bookings. You can also select the Customizations by location option to set a maximum price for each location. +- **Booking window:** Add a time limit to prevent employees from booking less than a certain number of days in advance to prohibit bookings too close to the flight time. +- **Cancellation policy:** Allow your employees to book fully or partially refundable rooms. To allow all options, you can leave this as the default option. +- **Experience:** Set hotel ratings that are in and out of policy. +- **Nightly median rate:** Determine which hotels to consider when calculating the median price. You can set a radius around the search location and include/disclude hotels above or below a certain rating. +- **Out of policy reason codes:** If enabled, travelers will be asked to enter a reason code for an out-of-policy hotel booking. This gives them a way to provide context for why the booking is still being placed. You can also modify the reason codes by clicking Manage reason codes below the toggle. + +# Car + +- **Car categories not allowed:** Restrict specific car types from being booked by employees. This overrides any other car policy. +- **Car categories in policy:** Define the types of cars that are in policy. If you do not list a specific car category, it will still be booked as long as it isn’t included in the Car categories not allowed setting. However, the booking will be classed as out of policy. +- **Car engine types not allowed:** Restrict specific engine types from being booked by employees regardless of other policy settings. +- **Maximum price:** Set a daily price cap per car (not including taxes and fees). +- **Out of policy reason codes:** If enabled, travelers will be asked to enter a reason code for an out-of-policy car booking. This gives them a way to provide context for why the booking is still being placed. You can also modify the reason codes by clicking Manage reason codes below the toggle. + +# FAQ + +How do travel policy rules interact with Expensify’s [approval flows](https://help.expensify.com/articles/expensify-classic/travel/Approve-travel-expenses)? + +Travel policy rules define what can and can’t be booked by your employees while they’re making the booking. Once a booking is placed and the travel itself is [approved](https://help.expensify.com/articles/expensify-classic/travel/Approve-travel-expenses), the expense will appear in Expensify. It will then be coded, submitted, pushed through the existing expense approval process as defined by your workspace, and exported to your preferred accounting platform (if applicable).
@@ -39,27 +85,73 @@ As a Workspace Admin, you can set travel policies for all travel booked under yo # Create a travel policy -When using Expensify Travel for the first time, you will need to create a new Travel Policy. +Workspace admins can create different travel policies that provide travel rules for different groups of travelers. When using Expensify Travel for the first time, you will need to create a new Travel Policy. -To create a travel policy from the Expensify web app, +To create or update a travel policy, 1. Click the + icon in the bottom left menu and select **Book travel**. 2. Click **Book or manage travel**. 3. Click the **Program** tab at the top and select **Policies**. 4. Under Employee or Non-employee in the left menu, click **Add new** to create a new policy. -5. Use the **Edit members** section to select the group of employees that belong to this policy. A Legal Entity in Expensify Travel is the equivalent of an Expensify Workspace. -6. Select which travel preferences you want to modify: General, flight, hotel, car, or rail. -7. Click the paperclip icon next to each setting to de-couple it from your default policy. -8. Update the desired settings. +5. Use the **Edit members** section to select the group of employees that belong to this policy. + 1. **To select an existing policy:** Select the policy in the left menu. + 2. **To add a new policy:** Click **Add new** under Employee or Non-employee in the left menu. Then under the Edit members section, select the group of employees that belong to this policy. -# Update travel policy preferences +{% include info.html %} +A Legal Entity in Expensify Travel is the equivalent of an Expensify Workspace. +{% include end-info.html %} -1. Click the + icon in the bottom left menu and select **Book travel**. -2. Click **Book or manage travel**. -3. Click the **Program** tab at the top and select **Policies**. -4. Select the appropriate policy in the left menu. -5. Select which travel preferences you want to modify: General, flight, hotel, car, or rail. -6. Click the paperclip icon next to each setting to de-couple it from your default policy. -7. Update the desired policies. +10. Select which travel preferences you want to modify: General, flight, hotel, car, or rail. +11. Click the paperclip icon next to each setting to de-couple it from your default policy. +12. Update the desired settings. + +# General + +Determine the currency and [approval type](https://help.expensify.com/articles/expensify-classic/travel/Approve-travel-expenses#set-approval-method) for different types of travel bookings. You can also upload a PDF of your company travel policy for employees to access when booking travel. + +![Screenshot of Expensify Travel policy approval settings](https://help.expensify.com/assets/images/Travel_Policy.png){:width="100%"} + +# Flight + +Flight preferences include multiple sections with different settings: + +- **Flights not allowed to be booked:** Restrict specific flight classes from being booked by employees. +- **Cabin class settings:** Set the highest cabin class allowed for booking and whether employees can accept cabin upgrades. +- **Budget:** Set a percentage or fare cap for the median or cheapest fares on flights, and a maximum capped price. Flight fares above this cap will be considered out of policy. You can also add customization to allow for different caps for different flight durations. +- **Lowest logical fare settings:** Set a preference for layovers, number of stops, flight time window, and airport connection changes. Expensify automatically takes these preferences into account when showing the lowest logical travel fare. +- **Add Ons and Preferences:** Select what types of add-ons your employees can book, including: + - Additional baggage + - Early check-in + - Seat preference + - No add-ons allowed +- **Booking windows:** Add a time limit to prevent employees from booking less than a certain number of days in advance to prohibit bookings too close to the flight time. +- **Refundable/changeable tickets:** Allow employees to book fully or partially refundable fares. To allow all options, you can leave this as the default option. +- **Maximum CO2 per kilometer:** If the CO2 per passenger km exceeds this threshold, the flight will be marked as out of policy. You can leave the entry blank if you do not wish to use this policy. +- **Out of policy reason codes:** If enabled, travelers will be asked to enter a reason code for an out-of-policy flight booking. This gives them a way to provide context for why the booking is still being placed. You can also modify the reason codes by clicking Manage reason codes below the toggle. + +# Hotel + +- **Restrict booking by keyword:** Keywords entered here will be compared to the hotel rate description. If any of the keywords are found, the hotel rate will be restricted. You also have the option to provide a reason why each keyword is restricted. +- **Hotel rates not allowed to be booked:** Restrict specific hotel rates (such as non-refundable, prepaid, and requires deposit) from being booked by employees. This overrides all other hotel policy rules. You also have the option to add a reason why these options aren’t available. +- **Maximum price:** Set a maximum price per night for bookings. You can also select the Customizations by location option to set a maximum price for each location. +- **Booking window:** Add a time limit to prevent employees from booking less than a certain number of days in advance to prohibit bookings too close to the flight time. +- **Cancellation policy:** Allow your employees to book fully or partially refundable rooms. To allow all options, you can leave this as the default option. +- **Experience:** Set hotel ratings that are in and out of policy. +- **Nightly median rate:** Determine which hotels to consider when calculating the median price. You can set a radius around the search location and include/disclude hotels above or below a certain rating. +- **Out of policy reason codes:** If enabled, travelers will be asked to enter a reason code for an out-of-policy hotel booking. This gives them a way to provide context for why the booking is still being placed. You can also modify the reason codes by clicking Manage reason codes below the toggle. + +# Car + +- **Car categories not allowed:** Restrict specific car types from being booked by employees. This overrides any other car policy. +- **Car categories in policy:** Define the types of cars that are in policy. If you do not list a specific car category, it will still be booked as long as it isn’t included in the Car categories not allowed setting. However, the booking will be classed as out of policy. +- **Car engine types not allowed:** Restrict specific engine types from being booked by employees regardless of other policy settings. +- **Maximum price:** Set a daily price cap per car (not including taxes and fees). +- **Out of policy reason codes:** If enabled, travelers will be asked to enter a reason code for an out-of-policy car booking. This gives them a way to provide context for why the booking is still being placed. You can also modify the reason codes by clicking Manage reason codes below the toggle. + +# FAQ + +How do travel policy rules interact with Expensify’s [approval flows](https://help.expensify.com/articles/expensify-classic/travel/Approve-travel-expenses)? + +Travel policy rules define what can and can’t be booked by your employees while they’re making the booking. Once a booking is placed and the travel itself is [approved](https://help.expensify.com/articles/expensify-classic/travel/Approve-travel-expenses), the expense will appear in Expensify. It will then be coded, submitted, pushed through the existing expense approval process as defined by your workspace, and exported to your preferred accounting platform (if applicable). diff --git a/docs/articles/expensify-classic/workspaces/Assign-Technical-Contact.md b/docs/articles/expensify-classic/workspaces/Assign-Technical-Contact.md new file mode 100644 index 000000000000..d7f71bdbb343 --- /dev/null +++ b/docs/articles/expensify-classic/workspaces/Assign-Technical-Contact.md @@ -0,0 +1,12 @@ +--- +title: Assign a Technical Contact +description: Adding a technical contact to receive integrations emails +--- +If your workspace is connected to an [integration](https://help.expensify.com/expensify-classic/hubs/connections/), the person assigned as your Technical Contact will receive notification emails for any integration errors that occur. + +To assign a Technical Contact, + +1. Hover over Settings and click Workspaces. +2. Click the desired workspace name. +3. Click the Connections tab on the left. +4. In the Technical Contact field, enter the email address for the person you want to assign. diff --git a/docs/articles/expensify-classic/workspaces/Create-categories.md b/docs/articles/expensify-classic/workspaces/Create-categories.md index 446cd55585c7..4d3f33a29ebc 100644 --- a/docs/articles/expensify-classic/workspaces/Create-categories.md +++ b/docs/articles/expensify-classic/workspaces/Create-categories.md @@ -11,6 +11,12 @@ You can choose to enable, disable, or edit the default Expensify categories, or # Enable, disable, or edit default categories +Once you have manually added your categories or automatically imported them from a connected accounting system, you can enable or disable the categories to determine whether they can be added to expenses. + +{% include info.html %} +Importing GL & payroll codes from your accounting system is only available on the Control plan. +{% include end-info.html %} + 1. Hover over Settings, then click **Workspaces**. 2. Click the **Group** tab on the left. 3. Click the desired workspace name. diff --git a/docs/articles/new-expensify/connections/sage-intacct/Connect-to-Sage-Intacct.md b/docs/articles/new-expensify/connections/sage-intacct/Connect-to-Sage-Intacct.md index 35a009ae8d4a..cf04a3655b30 100644 --- a/docs/articles/new-expensify/connections/sage-intacct/Connect-to-Sage-Intacct.md +++ b/docs/articles/new-expensify/connections/sage-intacct/Connect-to-Sage-Intacct.md @@ -6,7 +6,14 @@ order: 1 # Connect to Sage Intacct +Enjoy automated syncing and reduce manual entries with the Expensify and Sage Intacct integration. Gain in-depth, real-time financial insights with user-defined dimensions, as well as expense coding by department, class, location, customer, and project (job). + +{% include info.html %} +The Sage Intacct integration is only available on the Control plan. +{% include end-info.html %} + ## Overview + Expensify’s integration with Sage Intacct allows you to connect using either role-based permissions or user-based permissions and exporting either expense reports or vendor bills. Checklist of items to complete: diff --git a/docs/articles/new-expensify/getting-started/Create-a-company-workspace.md b/docs/articles/new-expensify/getting-started/Create-a-company-workspace.md index e25ae580e87a..f761e8dacd5e 100644 --- a/docs/articles/new-expensify/getting-started/Create-a-company-workspace.md +++ b/docs/articles/new-expensify/getting-started/Create-a-company-workspace.md @@ -4,7 +4,7 @@ description: Get started with Expensify by creating a workspace for your company ---
-To create an Expensify account for your company, follow the 6 steps below. +To create an Expensify account for your company, follow the 6 steps below and enjoy a free 7-day trial, which won’t begin until workspace activity has begun. {% include info.html %} After you create your new company workspace, you can schedule a free private onboarding session with one of our Setup Specialists. After you complete the steps below, check your email and notifications in Expensify for your unique signup link. @@ -12,7 +12,7 @@ After you create your new company workspace, you can schedule a free private onb # 1. Meet Concierge -Concierge is your personal assistant that walks you through setting up your account and also provides: +Concierge is your personal assistant who walks you through setting up your account and also provides: - Reminders to do things like submit your expenses - Alerts when more information is needed on an expense report - Updates on new and improved account features @@ -22,7 +22,7 @@ You can get support any time by locating your chat with Concierge in your chat i # 2. Create a new workspace
    -
  1. Click your profile image or icon in the bottom left menu.
  2. +
  3. Click your profile photo or icon in the bottom left menu.
  4. Scroll down and click Workspaces in the left menu.
  5. Click New workspace.
  6. Click the Edit pencil icon next to your workspace image or icon and select Upload Image to choose an image from your saved files.
  7. @@ -30,7 +30,7 @@ You can get support any time by locating your chat with Concierge in your chat i
  8. Click Default Currency to set the currency for all expenses submitted under the workspace. Expensify automatically converts all other currencies to your default currency.
-![Click your profile image or icon]({{site.url}}/assets/images/ExpensifyHelp_R1_CreateWorkspace_1.png){:width="100%"} +![Click your profile photo or icon]({{site.url}}/assets/images/ExpensifyHelp_R1_CreateWorkspace_1.png){:width="100%"} ![Click Workspaces in the left menu and New Worksapce]({{site.url}}/assets/images/ExpensifyHelp_R1_CreateWorkspace_2.png){:width="100%"} @@ -60,7 +60,7 @@ You can also invite members on the workspace’s Profile page by clicking **Shar # 4. Set admins -Admins are members of your workspace that have permissions to manage the workspace. The table below shows the difference between member and admin permissions: +Admins are members of your workspace who have permission to manage the workspace. The table below shows the difference between member and admin permissions: | Employee | Workspace Admin | | ----------------------------------------- | ------------------------------------------ | @@ -112,5 +112,7 @@ To add more features,
  • Enable any desired feature.
  • Click the related menu item that appears in the left menu to update its settings.
  • + +Easily monitor when your Free Trial starts and how many days are left on your Subscription page. We’ll also notify you when your trial starts and ends, at which point you’ll add a billing card to continue using all your favorite features!
    diff --git a/docs/articles/new-expensify/travel/Approve-travel-expenses.md b/docs/articles/new-expensify/travel/Approve-travel-expenses.md index ae0feb4efaa6..585e930a3dde 100644 --- a/docs/articles/new-expensify/travel/Approve-travel-expenses.md +++ b/docs/articles/new-expensify/travel/Approve-travel-expenses.md @@ -17,6 +17,40 @@ Travel expenses follow the same approval workflow as other expenses. Admins can 3. Click the **Program** tab at the top and select **Policies**. 4. Under General, select approval methods for Flights, Hotels, Cars and Rail. +![Screenshot of Expensify Travel policy approval settings](https://help.expensify.com/assets/images/Travel_Policy.png){:width="100%"} + +# Approve travel + +![Screenshot of Expensify Travel approval email](https://help.expensify.com/assets/images/Travel_Email.png){:width="100%"} + +## Soft approval + +Once an employee has booked a trip, their approver will receive an email notifying them of the booking with a prompt to decline it if needed. + +- To approve the booking, no action is required. +- To decline the booking, click **Decline booking** within 24 hours. Then click **Deny Booking**. + +## Hard approval + +Once an employee has booked a trip, their approver will receive an email notifying them of the booking with a prompt to accept or decline the booking. + +To approve the booking, click **Approve booking**. Then click **Approve**. +To decline the booking, click **Decline booking**. Then click **Deny**. + +# FAQs + +## Are extended approval windows given for trips booked over the weekend or during company holidays? + +No, the approval window will always be 24 hours from when the trip is booked. + +## How does Expensify Travel handle approvals when the assigned approver is out of office? + +It is recommended to have multiple approvers for travel, as there is no delegated approval for out-of-office approvers. + +## Can travelers upload a document when submitting a trip for approval? + +Travelers are unable to add a document when submitting a trip for approval, but the company can add a ‘reason code’ in the Out of Policy rules that the traveler can complete at checkout. The traveler can then add the document to the expense report in Expensify when submitting the report. +
    @@ -34,4 +68,38 @@ Travel expenses follow the same approval workflow as other expenses. Admins can 3. Click the **Program** tab at the top and select **Policies**. 4. Under General, select approval methods for Flights, Hotels, Cars and Rail. +![Screenshot of Expensify Travel policy approval settings](https://help.expensify.com/assets/images/Travel_Policy.png){:width="100%"} + +# Approve travel + +![Screenshot of Expensify Travel approval email](https://help.expensify.com/assets/images/Travel_Email.png){:width="100%"} + +## Soft approval + +Once an employee has booked a trip, their approver will receive an email notifying them of the booking with a prompt to decline it if needed. + +- To approve the booking, no action is required. +- To decline the booking, click **Decline booking** within 24 hours. Then click **Deny Booking**. + +## Hard approval + +Once an employee has booked a trip, their approver will receive an email notifying them of the booking with a prompt to accept or decline the booking. + +To approve the booking, click **Approve booking**. Then click **Approve**. +To decline the booking, click **Decline booking**. Then click **Deny**. + +# FAQs + +## Are extended approval windows given for trips booked over the weekend or during company holidays? + +No, the approval window will always be 24 hours from when the trip is booked. + +## How does Expensify Travel handle approvals when the assigned approver is out of office? + +It is recommended to have multiple approvers for travel, as there is no delegated approval for out-of-office approvers. + +## Can travelers upload a document when submitting a trip for approval? + +Travelers are unable to add a document when submitting a trip for approval, but the company can add a ‘reason code’ in the Out of Policy rules that the traveler can complete at checkout. The traveler can then add the document to the expense report in Expensify when submitting the report. +
    diff --git a/docs/articles/new-expensify/travel/Configure-travel-policy-and-preferences.md b/docs/articles/new-expensify/travel/Configure-travel-policy-and-preferences.md index 2e17af06773c..7e9a217b34ec 100644 --- a/docs/articles/new-expensify/travel/Configure-travel-policy-and-preferences.md +++ b/docs/articles/new-expensify/travel/Configure-travel-policy-and-preferences.md @@ -4,32 +4,78 @@ description: Set and update travel policies and preferences for your Expensify W ---
    -As a Workspace Admin, you can set travel policies for all travel booked under your workspace, including approval methods, flight booking class, and hotel star preferences. You can also create multiple policies with specific conditions for particular groups of employees and/or non-employees. +As a Workspace Admin, you can set travel policies for all travel booked under a workspace, including approval methods, flight booking class, and hotel star preferences. You can also create multiple policies with specific conditions for particular groups of employees and/or non-employees. -# Create a travel policy +# Create or update a travel policy -When using Expensify Travel for the first time, you will need to create a new Travel Policy. +Workspace admins can create different travel policies that provide travel rules for different groups of travelers. When using Expensify Travel for the first time, you will need to create a new Travel Policy. -To create a travel policy from the Expensify web app, +To create or update a travel policy, 1. Click the **Travel** tab. 2. Click **Book or manage travel**. 3. Click the **Program** tab at the top and select **Policies**. 4. Under Employee or Non-employee in the left menu, click **Add new** to create a new policy. -5. Use the **Edit members** section to select the group of employees that belong to this policy. A Legal Entity in Expensify Travel is the equivalent of an Expensify Workspace. -6. Select which travel preferences you want to modify: General, flight, hotel, car, or rail. -7. Click the paperclip icon next to each setting to de-couple it from your default policy. -8. Update the desired settings. +5. Use the **Edit members** section to select the group of employees that belong to this policy. + 1. **To select an existing policy:** Select the policy in the left menu. + 2. **To add a new policy:** Click **Add new** under Employee or Non-employee in the left menu. Then under the Edit members section, select the group of employees that belong to this policy. -# Update travel policy preferences +{% include info.html %} +A Legal Entity in Expensify Travel is the equivalent of an Expensify Workspace. +{% include end-info.html %} -1. Click the **Travel** tab. -2. Click **Book or manage travel**. -3. Click the **Program** tab at the top and select **Policies**. -4. Select the appropriate policy in the left menu. -5. Select which travel preferences you want to modify: General, flight, hotel, car, or rail. -6. Click the paperclip icon next to each setting to de-couple it from your default policy. -7. Update the desired policies. +10. Select which travel preferences you want to modify: General, flight, hotel, car, or rail. +11. Click the paperclip icon next to each setting to de-couple it from your default policy. +12. Update the desired settings. + +# General + +Determine the currency and [approval type](https://help.expensify.com/articles/expensify-classic/travel/Approve-travel-expenses#set-approval-method) for different types of travel bookings. You can also upload a PDF of your company travel policy for employees to access when booking travel. + +![Screenshot of Expensify Travel policy approval settings](https://help.expensify.com/assets/images/Travel_Policy.png){:width="100%"} + +# Flight + +Flight preferences include multiple sections with different settings: + +- **Flights not allowed to be booked:** Restrict specific flight classes from being booked by employees. +- **Cabin class settings:** Set the highest cabin class allowed for booking and whether employees can accept cabin upgrades. +- **Budget:** Set a percentage or fare cap for the median or cheapest fares on flights, and a maximum capped price. Flight fares above this cap will be considered out of policy. You can also add customization to allow for different caps for different flight durations. +- **Lowest logical fare settings:** Set a preference for layovers, number of stops, flight time window, and airport connection changes. Expensify automatically takes these preferences into account when showing the lowest logical travel fare. +- **Add Ons and Preferences:** Select what types of add-ons your employees can book, including: + - Additional baggage + - Early check-in + - Seat preference + - No add-ons allowed +- **Booking windows:** Add a time limit to prevent employees from booking less than a certain number of days in advance to prohibit bookings too close to the flight time. +- **Refundable/changeable tickets:** Allow employees to book fully or partially refundable fares. To allow all options, you can leave this as the default option. +- **Maximum CO2 per kilometer:** If the CO2 per passenger km exceeds this threshold, the flight will be marked as out of policy. You can leave the entry blank if you do not wish to use this policy. +- **Out of policy reason codes:** If enabled, travelers will be asked to enter a reason code for an out-of-policy flight booking. This gives them a way to provide context for why the booking is still being placed. You can also modify the reason codes by clicking Manage reason codes below the toggle. + +# Hotel + +- **Restrict booking by keyword:** Keywords entered here will be compared to the hotel rate description. If any of the keywords are found, the hotel rate will be restricted. You also have the option to provide a reason why each keyword is restricted. +- **Hotel rates not allowed to be booked:** Restrict specific hotel rates (such as non-refundable, prepaid, and requires deposit) from being booked by employees. This overrides all other hotel policy rules. You also have the option to add a reason why these options aren’t available. +- **Maximum price:** Set a maximum price per night for bookings. You can also select the Customizations by location option to set a maximum price for each location. +- **Booking window:** Add a time limit to prevent employees from booking less than a certain number of days in advance to prohibit bookings too close to the flight time. +- **Cancellation policy:** Allow your employees to book fully or partially refundable rooms. To allow all options, you can leave this as the default option. +- **Experience:** Set hotel ratings that are in and out of policy. +- **Nightly median rate:** Determine which hotels to consider when calculating the median price. You can set a radius around the search location and include/disclude hotels above or below a certain rating. +- **Out of policy reason codes:** If enabled, travelers will be asked to enter a reason code for an out-of-policy hotel booking. This gives them a way to provide context for why the booking is still being placed. You can also modify the reason codes by clicking Manage reason codes below the toggle. + +# Car + +- **Car categories not allowed:** Restrict specific car types from being booked by employees. This overrides any other car policy. +- **Car categories in policy:** Define the types of cars that are in policy. If you do not list a specific car category, it will still be booked as long as it isn’t included in the Car categories not allowed setting. However, the booking will be classed as out of policy. +- **Car engine types not allowed:** Restrict specific engine types from being booked by employees regardless of other policy settings. +- **Maximum price:** Set a daily price cap per car (not including taxes and fees). +- **Out of policy reason codes:** If enabled, travelers will be asked to enter a reason code for an out-of-policy car booking. This gives them a way to provide context for why the booking is still being placed. You can also modify the reason codes by clicking Manage reason codes below the toggle. + +# FAQ + +How do travel policy rules interact with Expensify’s [approval flows](https://help.expensify.com/articles/expensify-classic/travel/Approve-travel-expenses)? + +Travel policy rules define what can and can’t be booked by your employees while they’re making the booking. Once a booking is placed and the travel itself is [approved](https://help.expensify.com/articles/expensify-classic/travel/Approve-travel-expenses), the expense will appear in Expensify. It will then be coded, submitted, pushed through the existing expense approval process as defined by your workspace, and exported to your preferred accounting platform (if applicable).
    @@ -39,27 +85,73 @@ As a Workspace Admin, you can set travel policies for all travel booked under yo # Create a travel policy -When using Expensify Travel for the first time, you will need to create a new Travel Policy. +Workspace admins can create different travel policies that provide travel rules for different groups of travelers. When using Expensify Travel for the first time, you will need to create a new Travel Policy. -To create a travel policy from the Expensify web app, +To create or update a travel policy, 1. Click the + icon in the bottom left menu and select **Book travel**. 2. Click **Book or manage travel**. 3. Click the **Program** tab at the top and select **Policies**. 4. Under Employee or Non-employee in the left menu, click **Add new** to create a new policy. -5. Use the **Edit members** section to select the group of employees that belong to this policy. A Legal Entity in Expensify Travel is the equivalent of an Expensify Workspace. -6. Select which travel preferences you want to modify: General, flight, hotel, car, or rail. -7. Click the paperclip icon next to each setting to de-couple it from your default policy. -8. Update the desired settings. +5. Use the **Edit members** section to select the group of employees that belong to this policy. + 1. **To select an existing policy:** Select the policy in the left menu. + 2. **To add a new policy:** Click **Add new** under Employee or Non-employee in the left menu. Then under the Edit members section, select the group of employees that belong to this policy. -# Update travel policy preferences +{% include info.html %} +A Legal Entity in Expensify Travel is the equivalent of an Expensify Workspace. +{% include end-info.html %} -1. Click the + icon in the bottom left menu and select **Book travel**. -2. Click **Book or manage travel**. -3. Click the **Program** tab at the top and select **Policies**. -4. Select the appropriate policy in the left menu. -5. Select which travel preferences you want to modify: General, flight, hotel, car, or rail. -6. Click the paperclip icon next to each setting to de-couple it from your default policy. -7. Update the desired policies. +10. Select which travel preferences you want to modify: General, flight, hotel, car, or rail. +11. Click the paperclip icon next to each setting to de-couple it from your default policy. +12. Update the desired settings. + +# General + +Determine the currency and [approval type](https://help.expensify.com/articles/expensify-classic/travel/Approve-travel-expenses#set-approval-method) for different types of travel bookings. You can also upload a PDF of your company travel policy for employees to access when booking travel. + +![Screenshot of Expensify Travel policy approval settings](https://help.expensify.com/assets/images/Travel_Policy.png){:width="100%"} + +# Flight + +Flight preferences include multiple sections with different settings: + +- **Flights not allowed to be booked:** Restrict specific flight classes from being booked by employees. +- **Cabin class settings:** Set the highest cabin class allowed for booking and whether employees can accept cabin upgrades. +- **Budget:** Set a percentage or fare cap for the median or cheapest fares on flights, and a maximum capped price. Flight fares above this cap will be considered out of policy. You can also add customization to allow for different caps for different flight durations. +- **Lowest logical fare settings:** Set a preference for layovers, number of stops, flight time window, and airport connection changes. Expensify automatically takes these preferences into account when showing the lowest logical travel fare. +- **Add Ons and Preferences:** Select what types of add-ons your employees can book, including: + - Additional baggage + - Early check-in + - Seat preference + - No add-ons allowed +- **Booking windows:** Add a time limit to prevent employees from booking less than a certain number of days in advance to prohibit bookings too close to the flight time. +- **Refundable/changeable tickets:** Allow employees to book fully or partially refundable fares. To allow all options, you can leave this as the default option. +- **Maximum CO2 per kilometer:** If the CO2 per passenger km exceeds this threshold, the flight will be marked as out of policy. You can leave the entry blank if you do not wish to use this policy. +- **Out of policy reason codes:** If enabled, travelers will be asked to enter a reason code for an out-of-policy flight booking. This gives them a way to provide context for why the booking is still being placed. You can also modify the reason codes by clicking Manage reason codes below the toggle. + +# Hotel + +- **Restrict booking by keyword:** Keywords entered here will be compared to the hotel rate description. If any of the keywords are found, the hotel rate will be restricted. You also have the option to provide a reason why each keyword is restricted. +- **Hotel rates not allowed to be booked:** Restrict specific hotel rates (such as non-refundable, prepaid, and requires deposit) from being booked by employees. This overrides all other hotel policy rules. You also have the option to add a reason why these options aren’t available. +- **Maximum price:** Set a maximum price per night for bookings. You can also select the Customizations by location option to set a maximum price for each location. +- **Booking window:** Add a time limit to prevent employees from booking less than a certain number of days in advance to prohibit bookings too close to the flight time. +- **Cancellation policy:** Allow your employees to book fully or partially refundable rooms. To allow all options, you can leave this as the default option. +- **Experience:** Set hotel ratings that are in and out of policy. +- **Nightly median rate:** Determine which hotels to consider when calculating the median price. You can set a radius around the search location and include/disclude hotels above or below a certain rating. +- **Out of policy reason codes:** If enabled, travelers will be asked to enter a reason code for an out-of-policy hotel booking. This gives them a way to provide context for why the booking is still being placed. You can also modify the reason codes by clicking Manage reason codes below the toggle. + +# Car + +- **Car categories not allowed:** Restrict specific car types from being booked by employees. This overrides any other car policy. +- **Car categories in policy:** Define the types of cars that are in policy. If you do not list a specific car category, it will still be booked as long as it isn’t included in the Car categories not allowed setting. However, the booking will be classed as out of policy. +- **Car engine types not allowed:** Restrict specific engine types from being booked by employees regardless of other policy settings. +- **Maximum price:** Set a daily price cap per car (not including taxes and fees). +- **Out of policy reason codes:** If enabled, travelers will be asked to enter a reason code for an out-of-policy car booking. This gives them a way to provide context for why the booking is still being placed. You can also modify the reason codes by clicking Manage reason codes below the toggle. + +# FAQ + +How do travel policy rules interact with Expensify’s [approval flows](https://help.expensify.com/articles/expensify-classic/travel/Approve-travel-expenses)? + +Travel policy rules define what can and can’t be booked by your employees while they’re making the booking. Once a booking is placed and the travel itself is [approved](https://help.expensify.com/articles/expensify-classic/travel/Approve-travel-expenses), the expense will appear in Expensify. It will then be coded, submitted, pushed through the existing expense approval process as defined by your workspace, and exported to your preferred accounting platform (if applicable). diff --git a/docs/articles/new-expensify/workspaces/Create-expense-categories.md b/docs/articles/new-expensify/workspaces/Create-expense-categories.md index 3eb148e92fe1..80588aa95d63 100644 --- a/docs/articles/new-expensify/workspaces/Create-expense-categories.md +++ b/docs/articles/new-expensify/workspaces/Create-expense-categories.md @@ -54,7 +54,7 @@ To delete a category, Once you have manually added your categories or automatically imported them from a connected accounting system, you can enable or disable the categories to determine whether they can be added to expenses. {% include info.html %} -After connecting an accounting system, Expensify automatically imports charts of accounts, GL accounts, expense accounts, and additional details into your workspace as **disabled** categories. Workspace admins can enable these categories to make them available for workspace members to add to their expenses. +Importing GL & payroll codes from your accounting system is only available on the Control plan. After connecting an accounting system, Expensify automatically imports charts of accounts, GL accounts, expense accounts, and additional details into your workspace as **disabled** categories. Workspace admins can enable these categories to make them available for workspace members to add to their expenses. {% include end-info.html %} To enable or disable a category, diff --git a/docs/articles/new-expensify/workspaces/Track-taxes.md b/docs/articles/new-expensify/workspaces/Track-taxes.md index c98af9746607..fb4077679350 100644 --- a/docs/articles/new-expensify/workspaces/Track-taxes.md +++ b/docs/articles/new-expensify/workspaces/Track-taxes.md @@ -12,7 +12,7 @@ Tax rates are only available on the Control plan. Collect plan users will need t ## Enable taxes on a workspace -Taxes can be enabled on any workspace where the default currency is not USD. Please note that if you have a direct accounting integration, tax rates will be managed through the integration and cannot be manually enabled or disabled using the instructions below. +Tax codes are only available on the Control plan. Taxes can be enabled on any workspace where the default currency is not USD. Please note that if you have a direct accounting integration, tax rates will be managed through the integration and cannot be manually enabled or disabled using the instructions below. **To enable taxes on your workspace:** diff --git a/docs/assets/images/Travel_Email.png b/docs/assets/images/Travel_Email.png new file mode 100644 index 000000000000..95de51c18912 Binary files /dev/null and b/docs/assets/images/Travel_Email.png differ diff --git a/docs/assets/images/Travel_Policy.png b/docs/assets/images/Travel_Policy.png new file mode 100644 index 000000000000..6b80f938721c Binary files /dev/null and b/docs/assets/images/Travel_Policy.png differ diff --git a/ios/NewExpensify/Info.plist b/ios/NewExpensify/Info.plist index 14a783eb1866..226bce2146c6 100644 --- a/ios/NewExpensify/Info.plist +++ b/ios/NewExpensify/Info.plist @@ -19,7 +19,7 @@ CFBundlePackageType APPL CFBundleShortVersionString - 9.0.14 + 9.0.15 CFBundleSignature ???? CFBundleURLTypes @@ -40,7 +40,7 @@ CFBundleVersion - 9.0.14.5 + 9.0.15.4 FullStory OrgId diff --git a/ios/NewExpensifyTests/Info.plist b/ios/NewExpensifyTests/Info.plist index 68be54c984ff..36f9289911b4 100644 --- a/ios/NewExpensifyTests/Info.plist +++ b/ios/NewExpensifyTests/Info.plist @@ -15,10 +15,10 @@ CFBundlePackageType BNDL CFBundleShortVersionString - 9.0.14 + 9.0.15 CFBundleSignature ???? CFBundleVersion - 9.0.14.5 + 9.0.15.4 diff --git a/ios/NotificationServiceExtension/Info.plist b/ios/NotificationServiceExtension/Info.plist index d6b3f8763c11..3c2dcb06cdb7 100644 --- a/ios/NotificationServiceExtension/Info.plist +++ b/ios/NotificationServiceExtension/Info.plist @@ -11,9 +11,9 @@ CFBundleName $(PRODUCT_NAME) CFBundleShortVersionString - 9.0.14 + 9.0.15 CFBundleVersion - 9.0.14.5 + 9.0.15.4 NSExtension NSExtensionPointIdentifier diff --git a/package-lock.json b/package-lock.json index d96d25151a5f..e0b5af3667fd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "new.expensify", - "version": "9.0.14-5", + "version": "9.0.15-4", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "new.expensify", - "version": "9.0.14-5", + "version": "9.0.15-4", "hasInstallScript": true, "license": "MIT", "dependencies": { @@ -55,7 +55,7 @@ "date-fns-tz": "^2.0.0", "dom-serializer": "^0.2.2", "domhandler": "^4.3.0", - "expensify-common": "2.0.57", + "expensify-common": "2.0.61", "expo": "^50.0.3", "expo-av": "~13.10.4", "expo-image": "1.11.0", @@ -25791,9 +25791,9 @@ } }, "node_modules/expensify-common": { - "version": "2.0.57", - "resolved": "https://registry.npmjs.org/expensify-common/-/expensify-common-2.0.57.tgz", - "integrity": "sha512-ORAnuvMC4NZRgCTjOrxwW9SjigIP6/TlGGUV4DkCqTaiBriq8Mb2ypzv9LR1jcxDlbt19MuRsW66xMI3sAYLwA==", + "version": "2.0.61", + "resolved": "https://registry.npmjs.org/expensify-common/-/expensify-common-2.0.61.tgz", + "integrity": "sha512-X900glu2M/m2ggF9xlYlrrihNiwYN6cscYi7WmWp1yGzhGe5VFT+w033doJD1I8JLygtkZoV/xVMY4Porexrxw==", "dependencies": { "awesome-phonenumber": "^5.4.0", "classnames": "2.5.0", diff --git a/package.json b/package.json index ca88c73a4328..c7d21786a77e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "new.expensify", - "version": "9.0.14-5", + "version": "9.0.15-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.", @@ -110,7 +110,7 @@ "date-fns-tz": "^2.0.0", "dom-serializer": "^0.2.2", "domhandler": "^4.3.0", - "expensify-common": "2.0.57", + "expensify-common": "2.0.61", "expo": "^50.0.3", "expo-av": "~13.10.4", "expo-image": "1.11.0", diff --git a/patches/react-native-keyboard-controller+1.12.2.patch b/patches/react-native-keyboard-controller+1.12.2+001+initial.patch similarity index 100% rename from patches/react-native-keyboard-controller+1.12.2.patch rename to patches/react-native-keyboard-controller+1.12.2+001+initial.patch diff --git a/patches/react-native-keyboard-controller+1.12.2+002+keyboard-avoiding-view.patch b/patches/react-native-keyboard-controller+1.12.2+002+keyboard-avoiding-view.patch new file mode 100644 index 000000000000..3002a50c7986 --- /dev/null +++ b/patches/react-native-keyboard-controller+1.12.2+002+keyboard-avoiding-view.patch @@ -0,0 +1,15 @@ +diff --git a/node_modules/react-native-keyboard-controller/src/components/KeyboardAvoidingView/hooks.ts b/node_modules/react-native-keyboard-controller/src/components/KeyboardAvoidingView/hooks.ts +index 676eafc..6d84beb 100644 +--- a/node_modules/react-native-keyboard-controller/src/components/KeyboardAvoidingView/hooks.ts ++++ b/node_modules/react-native-keyboard-controller/src/components/KeyboardAvoidingView/hooks.ts +@@ -33,6 +33,10 @@ export const useKeyboardAnimation = () => { + + isClosed.value = e.height === 0; + ++ if (e.height > 0) { ++ heightWhenOpened.value = e.height; ++ } ++ + // `height` update happens in `onMove` handler + // in `onEnd` we need to update only if `onMove` + // wasn't called (i. e. duration === 0) diff --git a/src/CONST.ts b/src/CONST.ts index 79eaea4e14a2..0099ddbb5297 100755 --- a/src/CONST.ts +++ b/src/CONST.ts @@ -372,7 +372,6 @@ const CONST = { REPORT_FIELDS_FEATURE: 'reportFieldsFeature', WORKSPACE_FEEDS: 'workspaceFeeds', NETSUITE_USA_TAX: 'netsuiteUsaTax', - INTACCT_ON_NEW_EXPENSIFY: 'intacctOnNewExpensify', }, BUTTON_STATES: { DEFAULT: 'default', @@ -1409,6 +1408,7 @@ const CONST = { SYNC_REIMBURSED_REPORTS: 'syncReimbursedReports', REIMBURSEMENT_ACCOUNT_ID: 'reimbursementAccountID', ENTITY: 'entity', + DIMENSION_PREFIX: 'dimension_', }, SAGE_INTACCT: { @@ -4254,16 +4254,16 @@ const CONST = { 'Then, send your request and wait for that sweet “Cha-ching!” when it’s complete.', }, { - type: 'enableWallet', + type: 'addBankAccount', autoCompleted: false, - title: 'Enable your wallet', + title: 'Add personal bank account', description: - 'You’ll need to *enable your Expensify Wallet* to get paid back. Don’t worry, it’s easy!\n' + + 'You’ll need to add your personal bank account to get paid back. Don’t worry, it’s easy!\n' + '\n' + - 'Here’s how to set up your wallet:\n' + + 'Here’s how to set up your bank account:\n' + '\n' + '1. Click your profile picture.\n' + - '2. Click *Wallet* > *Enable wallet*.\n' + + '2. Click *Wallet* > *Bank accounts* > *+ Add bank account*.\n' + '3. Connect your bank account.\n' + '\n' + 'Once that’s done, you can request money from anyone and get paid back right into your personal bank account.', @@ -4428,19 +4428,19 @@ const CONST = { 'Feel free to add more details if you want, or just send it off. Let’s get you paid back!', }, { - type: 'enableWallet', + type: 'addBankAccount', autoCompleted: false, - title: 'Enable your wallet', + title: 'Add personal bank account', description: - 'You’ll need to *enable your Expensify Wallet* to get paid back. Don’t worry, it’s easy!\n' + + 'You’ll need to add your personal bank account to get paid back. Don’t worry, it’s easy!\n' + '\n' + - 'Here’s how to enable your wallet:\n' + + 'Here’s how to set up your bank account:\n' + '\n' + '1. Click your profile picture.\n' + - '2. *Click Wallet* > *Enable wallet*.\n' + - '3. Add your bank account.\n' + + '2. Click *Wallet* > *Bank accounts* > *+ Add bank account*.\n' + + '3. Connect your bank account.\n' + '\n' + - 'Once that’s done, you can request money from anyone and get paid right into your personal bank account.', + 'Once that’s done, you can request money from anyone and get paid back right into your personal bank account.', }, ], }, diff --git a/src/Expensify.tsx b/src/Expensify.tsx index 76f2b6ec19a8..ca9dec6d2279 100644 --- a/src/Expensify.tsx +++ b/src/Expensify.tsx @@ -31,6 +31,7 @@ import NetworkConnection from './libs/NetworkConnection'; import PushNotification from './libs/Notification/PushNotification'; import './libs/Notification/PushNotification/subscribePushNotification'; import Performance from './libs/Performance'; +import setCrashlyticsUserId from './libs/setCrashlyticsUserId'; import StartupTimer from './libs/StartupTimer'; // This lib needs to be imported, but it has nothing to export since all it contains is an Onyx connection import './libs/UnreadIndicatorUpdater'; @@ -238,6 +239,13 @@ function Expensify({ Audio.setAudioModeAsync({playsInSilentModeIOS: true}); }, []); + useEffect(() => { + if (!isAuthenticated) { + return; + } + setCrashlyticsUserId(session?.accountID ?? -1); + }, [isAuthenticated, session?.accountID]); + // Display a blank page until the onyx migration completes if (!isOnyxMigrated) { return null; diff --git a/src/ONYXKEYS.ts b/src/ONYXKEYS.ts index cecb02c2ca87..62ba2f83a69c 100755 --- a/src/ONYXKEYS.ts +++ b/src/ONYXKEYS.ts @@ -159,9 +159,13 @@ const ONYXKEYS = { /** Whether the user has seen HybridApp explanation modal */ NVP_SEEN_NEW_USER_MODAL: 'nvp_seen_new_user_modal', + /** Store the state of the subscription */ NVP_PRIVATE_SUBSCRIPTION: 'nvp_private_subscription', + /** Store the state of the private tax-exempt */ + NVP_PRIVATE_TAX_EXEMPT: 'nvp_private_taxExempt', + /** Store the stripe id status */ NVP_PRIVATE_STRIPE_CUSTOMER_ID: 'nvp_private_stripeCustomerID', @@ -844,6 +848,7 @@ type OnyxValuesMapping = { [ONYXKEYS.UPDATE_REQUIRED]: boolean; [ONYXKEYS.RESET_REQUIRED]: boolean; [ONYXKEYS.PLAID_CURRENT_EVENT]: string; + [ONYXKEYS.NVP_PRIVATE_TAX_EXEMPT]: boolean; [ONYXKEYS.LOGS]: OnyxTypes.CapturedLogs; [ONYXKEYS.SHOULD_STORE_LOGS]: boolean; [ONYXKEYS.SHOULD_MASK_ONYX_STATE]: boolean; diff --git a/src/components/AddPaymentMethodMenu.tsx b/src/components/AddPaymentMethodMenu.tsx index 451979b92efa..bd437cbb062d 100644 --- a/src/components/AddPaymentMethodMenu.tsx +++ b/src/components/AddPaymentMethodMenu.tsx @@ -74,7 +74,7 @@ function AddPaymentMethodMenu({ // We temporarily disabled P2P debit cards so we will automatically select the personal bank account option if there is no other option to select. useEffect(() => { - if (!isVisible) { + if (!isVisible || !isPersonalOnlyOption) { return; } diff --git a/src/components/AvatarWithImagePicker.tsx b/src/components/AvatarWithImagePicker.tsx index 919a4a67ebc6..cd2cea5208cb 100644 --- a/src/components/AvatarWithImagePicker.tsx +++ b/src/components/AvatarWithImagePicker.tsx @@ -307,16 +307,16 @@ function AvatarWithImagePicker({ const onPressAvatar = useCallback( (openPicker: OpenPicker) => { + if (disabled && enablePreview && onViewPhotoPress) { + onViewPhotoPress(); + return; + } if (isUsingDefaultAvatar) { openPicker({ onPicked: showAvatarCropModal, }); return; } - if (disabled && enablePreview && onViewPhotoPress) { - onViewPhotoPress(); - return; - } setIsMenuVisible((prev) => !prev); }, [disabled, enablePreview, isUsingDefaultAvatar, onViewPhotoPress, showAvatarCropModal], diff --git a/src/components/ButtonWithDropdownMenu/index.tsx b/src/components/ButtonWithDropdownMenu/index.tsx index 12802476ed0d..32fa50aad428 100644 --- a/src/components/ButtonWithDropdownMenu/index.tsx +++ b/src/components/ButtonWithDropdownMenu/index.tsx @@ -43,20 +43,20 @@ function ButtonWithDropdownMenu({ const [isMenuVisible, setIsMenuVisible] = useState(false); const [popoverAnchorPosition, setPopoverAnchorPosition] = useState(null); const {windowWidth, windowHeight} = useWindowDimensions(); - const caretButton = useRef(null); + const dropdownAnchor = useRef(null); const selectedItem = options[selectedItemIndex] || options[0]; const innerStyleDropButton = StyleUtils.getDropDownButtonHeight(buttonSize); const isButtonSizeLarge = buttonSize === CONST.DROPDOWN_BUTTON_SIZE.LARGE; useEffect(() => { - if (!caretButton.current) { + if (!dropdownAnchor.current) { return; } if (!isMenuVisible) { return; } - if ('measureInWindow' in caretButton.current) { - caretButton.current.measureInWindow((x, y, w, h) => { + if ('measureInWindow' in dropdownAnchor.current) { + dropdownAnchor.current.measureInWindow((x, y, w, h) => { setPopoverAnchorPosition({ horizontal: x + w, vertical: @@ -75,7 +75,10 @@ function ButtonWithDropdownMenu({ success={success} pressOnEnter={pressOnEnter} ref={(ref) => { - caretButton.current = ref; + if (isSplitButton) { + return; + } + dropdownAnchor.current = ref; }} onPress={(event) => (!isSplitButton ? setIsMenuVisible(!isMenuVisible) : onPress(event, selectedItem.value))} text={customText ?? selectedItem.text} @@ -94,7 +97,7 @@ function ButtonWithDropdownMenu({ {isSplitButton && (