Skip to content

Commit

Permalink
Merge branch 'main' of https://github.com/rezkiy37/Expensify into fea…
Browse files Browse the repository at this point in the history
…ture/45176-invoicing-details-section
  • Loading branch information
rezkiy37 committed Oct 22, 2024
2 parents dd161f5 + d3db2a1 commit 80a3066
Show file tree
Hide file tree
Showing 208 changed files with 5,358 additions and 2,690 deletions.
1 change: 1 addition & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,5 @@ docs/assets/**
web/gtm.js
**/.expo/**
src/libs/SearchParser/searchParser.js
src/libs/SearchParser/autocompleteParser.js
help/_scripts/**
2 changes: 1 addition & 1 deletion .github/workflows/deployNewHelp.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ jobs:
- name: Set up Node.js
uses: actions/setup-node@v3
with:
node-version: '20.15.1'
node-version: '20.18.0'

# Wil install the _help/package.js
- name: Install Node.js Dependencies
Expand Down
40 changes: 12 additions & 28 deletions .github/workflows/e2ePerformanceTests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,33 +24,21 @@ jobs:
runs-on: ubuntu-latest
name: Find the baseline and delta refs, and check for an existing build artifact for that commit
outputs:
BASELINE_ARTIFACT_FOUND: ${{ steps.checkForExistingArtifact.outputs.ARTIFACT_FOUND }}
BASELINE_ARTIFACT_WORKFLOW_ID: ${{ steps.checkForExistingArtifact.outputs.ARTIFACT_WORKFLOW_ID }}
BASELINE_VERSION: ${{ steps.getMostRecentRelease.outputs.VERSION }}
BASELINE_REF: ${{ steps.getBaselineRef.outputs.BASELINE_REF }}
DELTA_REF: ${{ steps.getDeltaRef.outputs.DELTA_REF }}
IS_PR_MERGED: ${{ steps.getPullRequestDetails.outputs.IS_MERGED }}
steps:
- uses: actions/checkout@v4
with:
# The OS_BOTIFY_COMMIT_TOKEN is a personal access token tied to osbotify (we need a PAT to access the artifact API)
token: ${{ secrets.OS_BOTIFY_COMMIT_TOKEN }}

- name: Get most recent release version
id: getMostRecentRelease
run: echo "VERSION=$(gh release list --limit 1 | awk '{ print $1 }')" >> "$GITHUB_OUTPUT"
env:
GITHUB_TOKEN: ${{ github.token }}

- name: Check if there's an existing artifact for this baseline
id: checkForExistingArtifact
uses: ./.github/actions/javascript/getArtifactInfo
with:
GITHUB_TOKEN: ${{ secrets.OS_BOTIFY_COMMIT_TOKEN }}
ARTIFACT_NAME: baseline-${{ steps.getMostRecentRelease.outputs.VERSION }}android-artifact-apk
fetch-depth: 0 # Fetches the entire history

- name: Skip build if there's already an existing artifact for the baseline
if: ${{ fromJSON(steps.checkForExistingArtifact.outputs.ARTIFACT_FOUND) }}
run: echo 'APK for baseline ${{ steps.getMostRecentRelease.outputs.VERSION }} already exists, reusing existing build'
- name: Determine "baseline ref" (prev merge commit)
id: getBaselineRef
run: |
previous_merge=$(git rev-list --merges HEAD~1 | head -n 1)
git checkout "$previous_merge"
echo "$previous_merge"
echo "BASELINE_REF=$previous_merge" >> "$GITHUB_OUTPUT"
- name: Get pull request details
id: getPullRequestDetails
Expand Down Expand Up @@ -84,15 +72,14 @@ jobs:
fi
buildBaseline:
name: Build apk from latest release as a baseline
name: Build apk from baseline
uses: ./.github/workflows/buildAndroid.yml
needs: prep
if: ${{ !fromJSON(needs.prep.outputs.BASELINE_ARTIFACT_FOUND) }}
secrets: inherit
with:
type: e2e
ref: ${{ needs.prep.outputs.BASELINE_VERSION }}
artifact-prefix: baseline-${{ needs.prep.outputs.BASELINE_VERSION }}
ref: ${{ needs.prep.outputs.BASELINE_REF }}
artifact-prefix: baseline-${{ needs.prep.outputs.BASELINE_REF }}

buildDelta:
name: Build apk from delta ref
Expand Down Expand Up @@ -127,9 +114,6 @@ jobs:
with:
name: ${{ needs.buildBaseline.outputs.APK_ARTIFACT_NAME }}
path: zip
# Set github-token only if the baseline was built in this workflow run:
github-token: ${{ needs.prep.outputs.BASELINE_ARTIFACT_WORKFLOW_ID && github.token }}
run-id: ${{ needs.prep.outputs.BASELINE_ARTIFACT_WORKFLOW_ID }}

# The downloaded artifact will be a file named "app-e2e-release.apk" so we have to rename it
- name: Rename baseline APK
Expand Down
2 changes: 1 addition & 1 deletion .nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
20.15.1
20.18.0
1 change: 1 addition & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,4 @@ lib/**

# Automatically generated files
src/libs/SearchParser/searchParser.js
src/libs/SearchParser/autocompleteParser.js
4 changes: 2 additions & 2 deletions android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -110,8 +110,8 @@ android {
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
multiDexEnabled rootProject.ext.multiDexEnabled
versionCode 1009005102
versionName "9.0.51-2"
versionCode 1009005201
versionName "9.0.52-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"
Expand Down
263 changes: 263 additions & 0 deletions assets/images/companyCards/pending-bank.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
18 changes: 18 additions & 0 deletions assets/images/gallery-not-found.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 0 additions & 2 deletions config/webpack/webpack.common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -227,8 +227,6 @@ const getCommonConfiguration = ({file = '.env', platform = 'web'}: Environment):
'react-native-config': 'react-web-config',
// eslint-disable-next-line @typescript-eslint/naming-convention
'react-native$': 'react-native-web',
// eslint-disable-next-line @typescript-eslint/naming-convention
'react-native-sound': 'react-native-web-sound',
// Module alias for web & desktop
// https://webpack.js.org/configuration/resolve/#resolvealias
// eslint-disable-next-line @typescript-eslint/naming-convention
Expand Down
25 changes: 25 additions & 0 deletions contributingGuides/STYLE.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
- [Refs](#refs)
- [Other Expensify Resources on TypeScript](#other-expensify-resources-on-typescript)
- [Default value for inexistent IDs](#default-value-for-inexistent-IDs)
- [Extract complex types](#extract-complex-types)
- [Naming Conventions](#naming-conventions)
- [Type names](#type-names)
- [Prop callbacks](#prop-callbacks)
Expand Down Expand Up @@ -492,6 +493,30 @@ const foo = report?.reportID ?? '-1';
report ? report.reportID : '-1';
```

### Extract complex types

Advanced data types, such as objects within function parameters, should be separated into their own type definitions. Callbacks in function parameters should be extracted if there's a possibility they could be reused somewhere else.

```ts
// BAD
function foo(param1: string, param2: {id: string}) {...};

// BAD
function foo(param1: string, param2: (value: string) => void) {...};

// GOOD
type Data = {
id: string;
};

function foo(param1: string, param2: Data) {...};

// GOOD
type Callback = (value: string) => void

function foo(param1: string, param2: Callback) {...};
```

## Naming Conventions

### Type names
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
---
title: Travel Receipt Integrations
description: How to use pre-built or custom integrations to track travel expenses
---

Expensify’s receipt integrations allow a merchant to upload receipts directly to a user’s Expensify account. A merchant just has to email a receipt to an Expensify user and Cc [email protected]. This automatically creates a transaction in the Expensify account for the user whose email address is in the To field.

You can set up a receipt integration by using one of our existing pre-built integrations, or by building your own receipt integration.

## Use a pre-built travel integration

You can use our pre-built integrations to automatically import travel receipts from Bolt Work, Spot Hero, Grab, and Kayak for Business.

### Bolt Work

1. In the Bolt app, tap the menu icon in the top left and tap **Work trips**.
2. Tap **Create profile**.
3. Enter the email address that you use for Expensify, then tap **Next**.
4. Enter your company details, then tap **Next**.
5. Choose a payment method. If you don’t want to use the existing payment methods, you can create a new one by tapping **Add Payment Method**. Then tap **Next**.
6. Tap **Done**.
7. Tap Add expense provider, then tap **Expensify**.
8. Tap **Verify**.
9. Tap the menu icon on the top left and tap **Work trips** once more.
10. Tap **Add expense provider** and select **Expensify** again.

When booking a trip with Bolt Work, select your work trip profile as the payment method before booking. Then the receipt details will be automatically sent to Expensify.

### SpotHero

1. In the SpotHero app, tap the menu icon in the top left and tap **Account Settings**.
2. Tap **Set up Business Profile**.
3. Tap **Create Business Profile**.
4. Enter the email address you use for Expensify and tap **Next**.
5. Tap **Add a Payment Method** and enter your payment account details. Then tap **Next**.
6. Tap **Expensify**.

When reserving parking with SpotHero, select your business profile in the Payment Details section. Then the receipt will be automatically sent to Expensify. In your SpotHero Business Profile settings, you can also set a weekly or monthly cadence for SpotHero to send a batch of expenses to Expensify.

### Grab

1. In the Grab app, tap your profile picture in the top left.
2. Tap your user icon again at the top of the settings menu.
3. Tap **Add a business profile**.
4. Tap Next twice, then tap **Let’s Get Started**.
5. Enter the email address you use for Expensify and tap the next arrow in the bottom right.
6. Check your email and copy the verification code you receive from Grab.
7. Tap **Manage My Business Profile**.
8. Under Preferences, tap **Expense Solution**.
9. Tap **Expensify**, then tap **Save**.

When booking a trip with Grab, tap **personal** and select **business** to ensure your business profile is selected. Then the receipt will be automatically sent to Expensify.

### KAYAK for Business

**Admin Setup**

This process must be completed by a KAYAK for Business admin.

1. On your KAYAK for Business homepage, click **Company Settings**.
2. Click **Connect to Expensify**.

KAYAK for Business will now forward bookings made by each employee into Expensify.

**Traveler Setup**

1. On your KAYAK for Business homepage, click **Profile Account Settings**.
2. Enable the Expensify toggle to have your expenses automatically sent to Expensify. You also have the option to send them manually.

## Build your own receipt integration

1. Email [email protected] and include:
- **Subject**: Use “Receipt Integration Request" as the subject line
- **Body**: List all email addresses the merchant sends email receipts from
2. Once you receive your email confirmation (within approximately 2 weeks) that the email addresses have been whitelisted, you’ll then be able to Cc [email protected] on receipt emails to users, and transactions will be created in the users’ Expensify account.
3. Test the integration by sending a receipt email to the email address you used to create your Expensify account and Cc [email protected]. Wait for the receipt to be SmartScanned. Then you will see the merchant, date, and amount added to the transaction.

### Using the integration

When sending an emailed receipt:

- Attachments on an email (that are not an .ics file) will be SmartScanned. We recommend including the receipt as the only attachment.
- You can only include one email address in the To field. In the Cc field, include only [email protected].
- Reservations for hotels and car rentals cannot be sent to Expensify as an expense because they are paid at the end of usage. You can only send transaction data for purchases that have already been made.
- Use standardized three-letter currency codes (ISO 4217) where applicable.

{% include faq-begin.md %}

**In Trainline, what if I don’t have the option for Send to Expensify?**

This can happen if the native iOS Mail app is not installed on an Apple device. However, you can still use the native iOS Share to Expensify function for Trainline receipts.

**Why does it take 2 weeks to set up a custom integration?**

Receipt integrations require our engineers to manually set them up on the backend. For that reason, it can take up to 2 weeks to set it up.

**Is there a way to connect via API?**

No, at this time there are no API receipt integrations. All receipt integrations are managed via receipt emails.

**What is your Open API?**

Our Open API is a self-serve tool meant to pull information out of Expensify. Typically, this tool is used to build integrations with accounting solutions that we don’t directly integrate with. If you wish to push data into Expensify, the only way to integrate is via the receipt integration options listed above in this article.

**Are you able to split one email into separate receipts?**

The receipt integration is unable to automatically split one email into separate receipts. However, once the receipt is SmartScanned, users can [split the expense](https://help.expensify.com/articles/expensify-classic/expenses/Split-an-expense) in their Expensify account.

**Can we set up a (co-marketing) partnership?**

We currently do not offer any co-marketing partnerships.

**Can we announce or advertise our custom integration with Expensify?**

Absolutely! You can promote the integration across your social media channels (tag @expensify and use the #expensify hashtag) and you can even create your own dedicated landing page on your website for your integration. At a minimum, we recommend including a brief overview of how the integration works, the benefits of using it, an integration setup guide, and guidance for how someone can contact you for support or integration setup if necessary.

**How can I get help?**

You can contact Concierge for ongoing support any time by clicking the green chat icon in the mobile or web app, or by emailing [email protected]. Concierge is a global team of highly trained product specialists focused on making our product as easy to use as possible and answering all your questions.

{% include faq-end.md %}
Loading

0 comments on commit 80a3066

Please sign in to comment.