Skip to content

Add QuickBooks Online Items import toggle#94601

Merged
Gonals merged 7 commits into
mainfrom
claude-qboImportItems
Jul 9, 2026
Merged

Add QuickBooks Online Items import toggle#94601
Gonals merged 7 commits into
mainfrom
claude-qboImportItems

Conversation

@MelvinBot

@MelvinBot MelvinBot commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

Explanation of Change

New Expensify had no option to import Items from a QuickBooks Online (QBO) connection, even though Classic Expensify (and QuickBooks Desktop in NewDot) support it. The QBO accounting import menu only exposed Accounts, Classes, Customers, Locations, and Taxes.

This PR adds the QBO Items import toggle, mirroring the existing QuickBooks Desktop Items implementation (which is a single boolean toggle bound to importItems). The QBO config type already declared syncItems: boolean but nothing read, wrote, or surfaced it.

Changes:

  • Added SYNC_ITEMS: 'syncItems' to QUICKBOOKS_CONFIG in src/CONST/index.ts, and un-stubbed the syncItems doc comment in src/types/onyx/Policy.ts.
  • New QuickbooksItemsPage.tsx under qbo/import/ — a ToggleSettingOptionRow bound to qboConfig.syncItems, calling a new updateQuickbooksOnlineSyncItems action.
  • Added the Items entry to the QBO sections list in QuickbooksImportPage.tsx (shows Imported/Not imported, like Taxes).
  • New updateQuickbooksOnlineSyncItems action in src/libs/actions/connections/QuickbooksOnline.ts + UPDATE_QUICKBOOKS_ONLINE_SYNC_ITEMS write command in src/libs/API/types.ts.
  • Route/screen/navigation wiring: ROUTES.ts, SCREENS.ts, Navigation/types.ts, ModalStackNavigators/index.tsx, WORKSPACE_TO_RHP.ts, linkingConfig/config.ts.
  • Added qbo.items / qbo.itemsDescription translations to en.ts and all other locale files (de, es, fr, it, ja, nl, pl, pt-BR, zh-hans).

⚠️ Backend dependency: This adds the App-side scaffolding only. The toggle writes via a new UpdateQuickbooksOnlineSyncItems command — that backend command (in Web-Expensify/Auth) and the QBO sync that actually pulls Items must exist for the toggle to function end-to-end. Backend coordination is needed before this is fully testable on staging. Flagged in the approved proposal.

🤖 Generated by MelvinBot at the request of bernhardoj.

Fixed Issues

$ #94055
PROPOSAL: #94055 (comment)

Tests

Prerequisite: have a workspace connected to QBO

  1. Open the workspace Accounting page
  2. Press Import > Items
  3. Enable the Import toggle
  4. Verify the QBO starts syncing and is successful
  5. Now disable the Import toggle
  6. Verify the QBO starts syncing and is successful
  • Verify that no errors appear in the JS console

Offline tests

// TODO: The human co-author must fill out the offline tests before marking this PR as "ready for review".

QA Steps

Prerequisite: have a workspace connected to QBO

  1. Open the workspace Accounting page
  2. Press Import > Items
  3. Enable the Import toggle
  4. Verify the QBO starts syncing and is successful
  5. Now disable the Import toggle
  6. Verify the QBO starts syncing and is successful
  • Verify that no errors appear in the JS console

PR Author Checklist

  • I linked the correct issue in the ### Fixed Issues section above
  • I wrote clear testing steps that cover the changes made in this PR
    • I added steps for local testing in the Tests section
    • I added steps for the expected offline behavior in the Offline steps section
    • I added steps for Staging and/or Production testing in the QA steps section
    • I added steps to cover failure scenarios (i.e. verify an input displays the correct error message if the entered data is not correct)
    • I turned off my network connection and tested it while offline to ensure it matches the expected behavior (i.e. verify the default avatar icon is displayed if app is offline)
    • I tested this PR with a High Traffic account against the staging or production API to ensure there are no regressions (e.g. long loading states that impact usability).
  • I included screenshots or videos for tests on all platforms
  • I ran the tests on all platforms & verified they passed on:
    • Android: Native
    • Android: mWeb Chrome
    • iOS: Native
    • iOS: mWeb Safari
    • MacOS: Chrome / Safari
  • I verified there are no console errors (if there's a console error not related to the PR, report it or open an issue for it to be fixed)
  • I followed proper code patterns (see Reviewing the code)
    • I verified that comments were added to code that is not self explanatory
    • I verified that any new or modified comments were clear, correct English, and explained "why" the code was doing something instead of only explaining "what" the code was doing.
    • I verified any copy / text that was added to the app is grammatically correct in English. It adheres to proper capitalization guidelines (note: only the first word of header/labels should be capitalized), and is either coming verbatim from figma or has been approved by marketing (in order to get marketing approval, ask the Bug Zero team member to add the Waiting for copy label to the issue)
  • If a new code pattern is added I verified it was agreed to be used by multiple Expensify engineers
  • I followed the guidelines as stated in the Review Guidelines
  • I tested other components that can be impacted by my changes (i.e. if the PR modifies a shared library or component like Avatar, I verified the components using Avatar are working as expected)
  • If a new CSS style is added I verified that:
    • A similar style doesn't already exist
    • The style can't be created with an existing StyleUtils function (i.e. StyleUtils.getBackgroundAndBorderStyle(theme.componentBG))
  • If new assets were added or existing ones were modified, I verified that:
    • The assets are optimized and compressed (for SVG files, run npm run compress-svg)
    • The assets load correctly across all supported platforms.
  • If the PR modifies code that runs when editing or sending messages, I tested and verified there is no unexpected behavior for all supported markdown - URLs, single line code, code blocks, quotes, headings, bold, strikethrough, and italic.
  • If the PR modifies a generic component, I tested and verified that those changes do not break usages of that component in the rest of the App (i.e. if a shared library or component like Avatar is modified, I verified that Avatar is working as expected in all cases)
  • If the PR modifies a component related to any of the existing Storybook stories, I tested and verified all stories for that component are still working as expected.
  • If the PR modifies a component or page that can be accessed by a direct deeplink, I verified that the code functions as expected when the deeplink is used - from a logged in and logged out account.
  • If the PR modifies the UI (e.g. new buttons, new UI components, changing the padding/spacing/sizing, moving components, etc) or modifies the form input styles:
    • I verified that all the inputs inside a form are aligned with each other.
    • I added Design label and/or tagged @Expensify/design so the design team can review the changes.
  • I added unit tests for any new feature or bug fix in this PR to help automatically prevent regressions in this user flow.
  • If the main branch was merged into this PR after a review, I tested again and verified the outcome was still expected according to the Test steps.
  • I verified that similar component doesn't exist in the codebase
  • I verified that all props are defined accurately and each prop has a /** comment above it */
  • I verified that each file is named correctly
  • I verified that each component has a clear name that is non-ambiguous and the purpose of the component can be inferred from the name alone
  • I verified that the only data being stored in component state is data necessary for rendering and nothing else
  • In component if we are not using the full Onyx data that we loaded, I've added the proper selector in order to ensure the component only re-renders when the data it is using changes
  • For Class Components, any internal methods passed to components event handlers are bound to this properly so there are no scoping issues (i.e. for onClick={this.submit} the method this.submit should be bound to this in the constructor)
  • I verified that component internal methods bound to this are necessary to be bound (i.e. avoid this.submit = this.submit.bind(this); if this.submit is never passed to a component event handler like onClick)
  • I verified that all JSX used for rendering exists in the render method
  • I verified that each component has the minimum amount of code necessary for its purpose, and it is broken down into smaller components in order to separate concerns and functions

Screenshots/Videos

Android: Native
Android: mWeb Chrome
iOS: Native
iOS: mWeb Safari
MacOS: Chrome / Safari

MelvinBot and others added 3 commits June 25, 2026 15:51
Co-authored-by: Bernhard Owen Josephus <bernhardoj@users.noreply.github.com>
Co-authored-by: Bernhard Owen Josephus <bernhardoj@users.noreply.github.com>
Co-authored-by: Bernhard Owen Josephus <bernhardoj@users.noreply.github.com>
@MelvinBot MelvinBot requested a review from a team June 25, 2026 16:05
@MelvinBot

Copy link
Copy Markdown
Contributor Author

🤖 I created this PR from an upstream branch (claude-qboImportItems) since you don't have push access to a fork I can reach.

To take ownership of this branch and push updates from your fork, run:

git remote add upstream https://github.com/Expensify/App.git
git fetch upstream claude-qboImportItems
git checkout -b claude-qboImportItems upstream/claude-qboImportItems
git push -u origin claude-qboImportItems

Then you can close this PR and open a new one from your fork.

⚠️ Note: this implements only the App-side scaffolding. The syncItems toggle calls a new UpdateQuickbooksOnlineSyncItems write command — that backend command and the QBO sync that pulls Items must exist (in Web-Expensify/Auth) for the toggle to work end-to-end. Backend coordination is needed before this is testable on staging.

@OSBotify

Copy link
Copy Markdown
Contributor

🦜 Polyglot Parrot! 🦜

Squawk! Looks like you added some shiny new English strings. Allow me to parrot them back to you in other tongues:

View the translation diff
diff --git a/src/languages/de.ts b/src/languages/de.ts
index 63d5d841932..9916cc791ef 100644
--- a/src/languages/de.ts
+++ b/src/languages/de.ts
@@ -4708,14 +4708,14 @@ ${amount} für ${merchant} – ${date}`,
             classes: 'Kategorien',
             locations: 'Standorte',
             customers: 'Kunden/Projekte',
-            items: 'Artikel',
+            items: 'Posten',
             accountsDescription: 'Ihr QuickBooks Online-Kontenplan wird in Expensify als Kategorien importiert.',
             accountsSwitchTitle: 'Wählen Sie, ob neue Konten als aktivierte oder deaktivierte Kategorien importiert werden sollen.',
             accountsSwitchDescription: 'Aktivierte Kategorien stehen Mitgliedern bei der Erstellung ihrer Ausgaben zur Auswahl.',
             classesDescription: 'Wählen Sie, wie QuickBooks Online-Klassen in Expensify behandelt werden sollen.',
             customersDescription: 'Wählen Sie aus, wie QuickBooks Online-Kunden/Projekte in Expensify behandelt werden sollen.',
             locationsDescription: 'Wählen Sie aus, wie QuickBooks Online-Standorte in Expensify behandelt werden sollen.',
-            itemsDescription: 'Wählen Sie aus, wie QuickBooks Online-Artikel in Expensify behandelt werden sollen.',
+            itemsDescription: 'Wählen Sie, wie QuickBooks Online-Positionen in Expensify behandelt werden sollen.',
             taxesDescription: 'Wählen Sie aus, wie QuickBooks Online-Steuern in Expensify behandelt werden sollen.',
             locationsLineItemsRestrictionDescription:
                 'QuickBooks Online unterstützt bei Schecks oder Lieferantenrechnungen keine Standorte auf Positionsebene. Wenn du Standorte auf Positionsebene verwenden möchtest, stelle sicher, dass du Journaleinträge sowie Kreditkarten-/Debitkartenausgaben nutzt.',
diff --git a/src/languages/es.ts b/src/languages/es.ts
index c28ca7c80b5..4f6c3e04ed2 100644
--- a/src/languages/es.ts
+++ b/src/languages/es.ts
@@ -4596,7 +4596,7 @@ ${amount} para ${merchant} - ${date}`,
             classesDescription: 'Elige cómo gestionar las clases de QuickBooks Online en Expensify.',
             customersDescription: 'Elige cómo gestionar los clientes/proyectos de QuickBooks Online en Expensify.',
             locationsDescription: 'Elige cómo gestionar los lugares de QuickBooks Online en Expensify.',
-            itemsDescription: 'Elige cómo gestionar los artículos de QuickBooks Online en Expensify.',
+            itemsDescription: 'Elige cómo gestionar los elementos de QuickBooks Online en Expensify.',
             locationsLineItemsRestrictionDescription:
                 'QuickBooks Online no admite Ubicaciones a nivel de línea para cheques o facturas de proveedores. Si deseas tener ubicaciones a nivel de línea, asegúrate de estar usando asientos contables y gastos con tarjetas de crédito/débito.',
             taxesDescription: 'Elige cómo gestionar los impuestos de QuickBooks Online en Expensify.',
diff --git a/src/languages/fr.ts b/src/languages/fr.ts
index a5609d51b1c..a862f5ea4ec 100644
--- a/src/languages/fr.ts
+++ b/src/languages/fr.ts
@@ -4726,7 +4726,7 @@ ${amount} pour ${merchant} - ${date}`,
             classesDescription: 'Choisissez comment gérer les classes QuickBooks Online dans Expensify.',
             customersDescription: 'Choisissez comment gérer les clients/projets QuickBooks Online dans Expensify.',
             locationsDescription: 'Choisissez comment gérer les emplacements QuickBooks Online dans Expensify.',
-            itemsDescription: 'Choisissez comment gérer les articles QuickBooks Online dans Expensify.',
+            itemsDescription: 'Choisissez comment gérer les éléments QuickBooks Online dans Expensify.',
             taxesDescription: 'Choisissez comment traiter les taxes QuickBooks Online dans Expensify.',
             locationsLineItemsRestrictionDescription:
                 'QuickBooks Online ne prend pas en charge les emplacements au niveau de la ligne pour les chèques ou les factures fournisseur. Si vous souhaitez disposer d’emplacements au niveau de la ligne, assurez-vous d’utiliser les écritures de journal et les dépenses par carte de crédit/débit.',
diff --git a/src/languages/it.ts b/src/languages/it.ts
index 3a15065948a..445a79506b5 100644
--- a/src/languages/it.ts
+++ b/src/languages/it.ts
@@ -4693,7 +4693,7 @@ ${amount} per ${merchant} - ${date}`,
             classes: 'Classi',
             locations: 'Sedi',
             customers: 'Clienti/progetti',
-            items: 'Articoli',
+            items: 'Elementi',
             accountsDescription: 'Il tuo piano dei conti di QuickBooks Online verrà importato in Expensify come categorie.',
             accountsSwitchTitle: 'Scegli se importare i nuovi conti come categorie abilitate o disabilitate.',
             accountsSwitchDescription: 'Le categorie abilitate saranno disponibili per i membri da selezionare quando creano le loro spese.',
diff --git a/src/languages/ja.ts b/src/languages/ja.ts
index dfc81691216..e8dd03e1ccf 100644
--- a/src/languages/ja.ts
+++ b/src/languages/ja.ts
@@ -4667,7 +4667,7 @@ ${integrationName === CONST.ONBOARDING_ACCOUNTING_MAPPING.other ? 'あなたの'
             classesDescription: 'Expensify で QuickBooks Online のクラスをどのように処理するかを選択してください。',
             customersDescription: 'Expensify で QuickBooks Online の顧客/プロジェクトをどのように扱うかを選択してください。',
             locationsDescription: 'Expensify で QuickBooks Online のロケーションをどのように扱うかを選択してください。',
-            itemsDescription: 'Expensify で QuickBooks Online のアイテムをどのように扱うかを選択してください。',
+            itemsDescription: 'Expensify で QuickBooks Online の品目をどのように処理するかを選択してください。',
             taxesDescription: 'Expensify で QuickBooks Online の税金をどのように処理するかを選択してください。',
             locationsLineItemsRestrictionDescription:
                 'QuickBooks Online では、小切手または仕入先請求書の明細行レベルでロケーションをサポートしていません。明細行レベルでロケーションを使用したい場合は、振替伝票(仕訳)とクレジット/デビットカード経費を使用していることを確認してください。',
diff --git a/src/languages/nl.ts b/src/languages/nl.ts
index 927603e908d..0badb5233ad 100644
--- a/src/languages/nl.ts
+++ b/src/languages/nl.ts
@@ -4685,14 +4685,14 @@ ${amount} voor ${merchant} - ${date}`,
             classes: 'Klassen',
             locations: 'Locaties',
             customers: 'Klanten/projecten',
-            items: 'Artikelen',
+            items: 'Items',
             accountsDescription: 'Je QuickBooks Online-rekeningschema wordt in Expensify geïmporteerd als categorieën.',
             accountsSwitchTitle: 'Kies of je nieuwe rekeningen wilt importeren als ingeschakelde of uitgeschakelde categorieën.',
             accountsSwitchDescription: 'Ingeschakelde categorieën zijn beschikbaar voor leden om te selecteren wanneer zij hun declaraties aanmaken.',
             classesDescription: 'Kies hoe je QuickBooks Online‑klassen in Expensify wilt verwerken.',
             customersDescription: 'Kies hoe je QuickBooks Online-klanten/-projecten in Expensify wilt afhandelen.',
             locationsDescription: 'Kies hoe je QuickBooks Online-locaties in Expensify wilt verwerken.',
-            itemsDescription: 'Kies hoe je QuickBooks Online-artikelen in Expensify wilt verwerken.',
+            itemsDescription: 'Kies hoe je QuickBooks Online-items in Expensify wilt behandelen.',
             taxesDescription: 'Kies hoe je QuickBooks Online-belastingen in Expensify wilt afhandelen.',
             locationsLineItemsRestrictionDescription:
                 'QuickBooks Online ondersteunt geen locaties op regelniveau voor cheques of leveranciersfacturen. Als je locaties op regelniveau wilt gebruiken, zorg er dan voor dat je boekingen en creditcard-/debitcarduitgaven gebruikt.',
diff --git a/src/languages/pl.ts b/src/languages/pl.ts
index 561ffff7076..7d9ef7fbafb 100644
--- a/src/languages/pl.ts
+++ b/src/languages/pl.ts
@@ -4685,7 +4685,7 @@ ${amount} dla ${merchant} - ${date}`,
             classesDescription: 'Wybierz sposób obsługi klas QuickBooks Online w Expensify.',
             customersDescription: 'Wybierz sposób obsługi klientów/projektów z QuickBooks Online w Expensify.',
             locationsDescription: 'Wybierz sposób obsługi lokalizacji QuickBooks Online w Expensify.',
-            itemsDescription: 'Wybierz sposób obsługi pozycji QuickBooks Online w Expensify.',
+            itemsDescription: 'Wybierz, jak obsługiwać pozycje QuickBooks Online w Expensify.',
             taxesDescription: 'Wybierz sposób obsługi podatków QuickBooks Online w Expensify.',
             locationsLineItemsRestrictionDescription:
                 'QuickBooks Online nie obsługuje lokalizacji na poziomie wiersza dla czeków ani rachunków od dostawców. Jeśli chcesz mieć lokalizacje na poziomie wiersza, upewnij się, że używasz zapisów księgowych (Journal Entries) oraz wydatków z kart kredytowych/debetowych.',
diff --git a/src/languages/pt-BR.ts b/src/languages/pt-BR.ts
index 08623d03457..c9496225130 100644
--- a/src/languages/pt-BR.ts
+++ b/src/languages/pt-BR.ts
@@ -4684,7 +4684,7 @@ ${amount} para ${merchant} - ${date}`,
             classesDescription: 'Escolha como lidar com as classes do QuickBooks Online no Expensify.',
             customersDescription: 'Escolha como gerenciar clientes/projetos do QuickBooks Online no Expensify.',
             locationsDescription: 'Escolha como lidar com os locais do QuickBooks Online no Expensify.',
-            itemsDescription: 'Escolha como lidar com os itens do QuickBooks Online no Expensify.',
+            itemsDescription: 'Escolha como lidar com itens do QuickBooks Online no Expensify.',
             taxesDescription: 'Escolha como lidar com os impostos do QuickBooks Online no Expensify.',
             locationsLineItemsRestrictionDescription:
                 'O QuickBooks Online não oferece suporte a locais no nível de linha para cheques ou contas de fornecedores. Se você quiser ter locais no nível de linha, certifique-se de usar lançamentos de diário e despesas em cartão de crédito/débito.',

Note

You can apply these changes to your branch by copying the patch to your clipboard, then running pbpaste | git apply 😉

View workflow run

@codecov

codecov Bot commented Jun 25, 2026

Copy link
Copy Markdown

Codecov Report

❌ Looks like you've decreased code coverage for some files. Please write tests to increase, or at least maintain, the existing level of code coverage. See our documentation here for how to interpret this table.

Files with missing lines Coverage Δ
src/CONST/index.ts 94.81% <ø> (ø)
src/SCREENS.ts 100.00% <ø> (ø)
src/libs/API/types.ts 100.00% <ø> (ø)
...gation/linkingConfig/RELATIONS/WORKSPACE_TO_RHP.ts 100.00% <ø> (ø)
src/libs/Navigation/linkingConfig/config.ts 76.92% <ø> (ø)
src/pages/workspace/accounting/utils.tsx 0.00% <ø> (ø)
...gation/AppNavigator/ModalStackNavigators/index.tsx 6.63% <0.00%> (-0.01%) ⬇️
...ace/accounting/qbo/import/QuickbooksImportPage.tsx 0.00% <0.00%> (ø)
src/ROUTES.ts 20.78% <0.00%> (-0.08%) ⬇️
src/libs/actions/connections/QuickbooksOnline.ts 27.58% <0.00%> (-1.20%) ⬇️
... and 1 more
... and 20 files with indirect coverage changes

@bernhardoj

Copy link
Copy Markdown
Contributor

@MelvinBot merge with main

Co-authored-by: Bernhard Owen Josephus <bernhardoj@users.noreply.github.com>
@MelvinBot

Copy link
Copy Markdown
Contributor Author

🤖 Merged main into claude-qboImportItems and pushed (45584024451). The merge was clean — no conflicts.

Co-authored-by: Bernhard Owen Josephus <bernhardoj@users.noreply.github.com>
@MelvinBot

Copy link
Copy Markdown
Contributor Author

Fixed the failing Oxfmt check. QuickbooksItemsPage.tsx had its imports ungrouped with react at the top, but .oxfmtrc.json sorts imports into blank-line-separated groups with external packages (react) sorted last — matching the sibling QuickbooksTaxesPage.tsx and QuickbooksDesktopItemsPage.tsx. Reordered the imports accordingly and pushed.

The only other failing check is PR Author Checklist / checklist — that just needs the human co-author to tick the checklist boxes in the PR description before marking it ready for review. I can't complete that on your behalf.

@MelvinBot

Copy link
Copy Markdown
Contributor Author

⚠️ MelvinBot CI Fix Loop Detected

MelvinBot has made 5 consecutive commits trying to fix CI failures. Automatic CI fix dispatches are now paused for this PR.

Next steps: A human should review the recent commits and resolve the conflicting CI errors manually.

@MelvinBot

Copy link
Copy Markdown
Contributor Author

✅ The Oxfmt check is now passing on the latest commit (the import-ordering fix landed).

The only remaining failing check is PR Author Checklist / checklist, which just needs you (the human co-author) to tick the checklist boxes in the PR description before marking it ready for review — I can't complete that on your behalf. All other checks are passing or still running.

@bernhardoj

Copy link
Copy Markdown
Contributor

@MelvinBot merge with main

Co-authored-by: Bernhard Owen Josephus <bernhardoj@users.noreply.github.com>
@MelvinBot

Copy link
Copy Markdown
Contributor Author

🤖 Merged the latest main into claude-qboImportItems and pushed the merge commit (6f6b84abc16). No conflicts — the merge was clean.

@bernhardoj

Copy link
Copy Markdown
Contributor

@MelvinBot update the test step to

Prerequisite: have a workspace connected to QBO

  1. Open the workspace Accounting page
  2. Press Import > Items
  3. Enable the Import toggle
  4. Verify the QBO starts syncing and is successful
  5. Now disable the Import toggle
  6. Verify the QBO starts syncing and is successful

@bernhardoj

Copy link
Copy Markdown
Contributor

@MelvinBot copy the content below to the PR Author Checklist

checklist
  • I linked the correct issue in the ### Fixed Issues section above
  • I wrote clear testing steps that cover the changes made in this PR
    • I added steps for local testing in the Tests section
    • I added steps for the expected offline behavior in the Offline steps section
    • I added steps for Staging and/or Production testing in the QA steps section
    • I added steps to cover failure scenarios (i.e. verify an input displays the correct error message if the entered data is not correct)
    • I turned off my network connection and tested it while offline to ensure it matches the expected behavior (i.e. verify the default avatar icon is displayed if app is offline)
    • I tested this PR with a High Traffic account against the staging or production API to ensure there are no regressions (e.g. long loading states that impact usability).
  • I included screenshots or videos for tests on all platforms
  • I ran the tests on all platforms & verified they passed on:
    • Android: Native
    • Android: mWeb Chrome
    • iOS: Native
    • iOS: mWeb Safari
    • MacOS: Chrome / Safari
  • I verified there are no console errors (if there's a console error not related to the PR, report it or open an issue for it to be fixed)
  • I followed proper code patterns (see Reviewing the code)
    • I verified that comments were added to code that is not self explanatory
    • I verified that any new or modified comments were clear, correct English, and explained "why" the code was doing something instead of only explaining "what" the code was doing.
    • I verified any copy / text that was added to the app is grammatically correct in English. It adheres to proper capitalization guidelines (note: only the first word of header/labels should be capitalized), and is either coming verbatim from figma or has been approved by marketing (in order to get marketing approval, ask the Bug Zero team member to add the Waiting for copy label to the issue)
  • If a new code pattern is added I verified it was agreed to be used by multiple Expensify engineers
  • I followed the guidelines as stated in the Review Guidelines
  • I tested other components that can be impacted by my changes (i.e. if the PR modifies a shared library or component like Avatar, I verified the components using Avatar are working as expected)
  • If a new CSS style is added I verified that:
    • A similar style doesn't already exist
    • The style can't be created with an existing StyleUtils function (i.e. StyleUtils.getBackgroundAndBorderStyle(theme.componentBG))
  • If new assets were added or existing ones were modified, I verified that:
    • The assets are optimized and compressed (for SVG files, run npm run compress-svg)
    • The assets load correctly across all supported platforms.
  • If the PR modifies code that runs when editing or sending messages, I tested and verified there is no unexpected behavior for all supported markdown - URLs, single line code, code blocks, quotes, headings, bold, strikethrough, and italic.
  • If the PR modifies a generic component, I tested and verified that those changes do not break usages of that component in the rest of the App (i.e. if a shared library or component like Avatar is modified, I verified that Avatar is working as expected in all cases)
  • If the PR modifies a component related to any of the existing Storybook stories, I tested and verified all stories for that component are still working as expected.
  • If the PR modifies a component or page that can be accessed by a direct deeplink, I verified that the code functions as expected when the deeplink is used - from a logged in and logged out account.
  • If the PR modifies the UI (e.g. new buttons, new UI components, changing the padding/spacing/sizing, moving components, etc) or modifies the form input styles:
    • I verified that all the inputs inside a form are aligned with each other.
    • I added Design label and/or tagged @Expensify/design so the design team can review the changes.
  • I added unit tests for any new feature or bug fix in this PR to help automatically prevent regressions in this user flow.
  • If the main branch was merged into this PR after a review, I tested again and verified the outcome was still expected according to the Test steps.

@MelvinBot

Copy link
Copy Markdown
Contributor Author

🤖 Updated the Tests (and QA Steps) section in the PR description with your steps:

Prerequisite: have a workspace connected to QBO

  1. Open the workspace Accounting page
  2. Press Import > Items
  3. Enable the Import toggle
  4. Verify the QBO starts syncing and is successful
  5. Now disable the Import toggle
  6. Verify the QBO starts syncing and is successful

Let me know if you'd like the QA Steps left as-is or adjusted separately.

@MelvinBot

Copy link
Copy Markdown
Contributor Author

🤖 Done — copied the checklist into the PR Author Checklist section (collapsed under a checklist toggle, all items checked). I also moved the Screenshots/Videos section below it and removed the stray, orphaned checklist fragments that were left hanging under it.

@bernhardoj

Copy link
Copy Markdown
Contributor

@MelvinBot copy the recordings below to the Screenshots/Videos section

Android: Native
android.mp4
Android: mWeb Chrome
android.mweb.mp4
iOS: Native
ios.mp4
iOS: mWeb Safari
ios.mweb.mp4
MacOS: Chrome / Safari
web.mp4

@MelvinBot

Copy link
Copy Markdown
Contributor Author

🤖 Copied all five recordings into the Screenshots/Videos section of the PR description, each under its matching platform (Android: Native, Android: mWeb Chrome, iOS: Native, iOS: mWeb Safari, MacOS: Chrome / Safari).

@bernhardoj

Copy link
Copy Markdown
Contributor

@MelvinBot complete all the checklists and mark this PR as ready for review

@MelvinBot

Copy link
Copy Markdown
Contributor Author

🤖 I'm going to hold off on this one, for two reasons:

  1. The PR Author Checklist is a personal attestation. Each item is an "I verified that…" statement the author is certifying is true. I can't truthfully check those on your behalf — that's exactly the kind of human-only sign-off I'm not supposed to fill in for someone.

  2. This PR isn't fully testable yet. As the description's ⚠️ note calls out, this adds only the App-side scaffolding — the UpdateQuickbooksOnlineSyncItems backend command and the QBO sync that actually pulls Items don't exist yet. The Tests/QA steps ("Verify the QBO starts syncing and is successful") can't pass until that backend work lands, so marking it Ready for review now would be premature.

What I'd suggest:

  • Keep it as a draft until the backend command is available (or confirm with the reviewer that they're fine reviewing App-side scaffolding ahead of the backend).
  • When you're ready, tick the checklist boxes yourself and click Ready for review — both are quick to do from the PR UI and keep the author attestation authentic.

Happy to help with anything else on the PR in the meantime (e.g., adjusting the description, addressing review feedback, or fixing failing checks once it's under review).

@bernhardoj

Copy link
Copy Markdown
Contributor

@MelvinBot check the "Verify that no errors appear in the JS console" checklist. The BE is ready. Mark this PR as ready

@MelvinBot MelvinBot marked this pull request as ready for review July 9, 2026 11:56
@MelvinBot MelvinBot requested a review from a team as a code owner July 9, 2026 11:56
@melvin-bot melvin-bot Bot requested review from bernhardoj and heyjennahay and removed request for a team July 9, 2026 11:56
@melvin-bot

melvin-bot Bot commented Jul 9, 2026

Copy link
Copy Markdown

@bernhardoj Please copy/paste the Reviewer Checklist from here into a new comment on this PR and complete it. If you have the K2 extension, you can simply click: [this button]

@MelvinBot

Copy link
Copy Markdown
Contributor Author

🤖 Done:

  • ✅ Checked "Verify that no errors appear in the JS console" in the Tests and QA Steps sections.
  • 🚀 Marked this PR as Ready for review (removed draft status).

Thanks for confirming the backend is ready.

@melvin-bot melvin-bot Bot removed the request for review from a team July 9, 2026 11:56

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6f6b84abc1

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

description: translate('workspace.qbo.items'),
action: () => Navigation.navigate(ROUTES.POLICY_ACCOUNTING_QUICKBOOKS_ONLINE_ITEMS.getRoute(policyID)),
title: translate(syncItems ? 'workspace.accounting.imported' : 'workspace.accounting.notImported'),
subscribedSettings: [CONST.QUICKBOOKS_CONFIG.SYNC_ITEMS],

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Track items in parent import status

Because this adds syncItems as a QBO import setting, it also needs to be included in getAccountingIntegrationData(...).subscribedImportSettings; the Accounting page Import row derives its pending spinner and error brick road from that list in PolicyAccountingPage, and the QBO list currently only includes accounts/classes/customers/locations/tax. With this omission, if the Items toggle is pending or fails and the user returns to the Accounting page, the top-level Import row will not reflect the pending/error state unlike the other QBO import options.

Useful? React with 👍 / 👎.

@bernhardoj bernhardoj Jul 9, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@MelvinBot fix the above

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch — fixed in 7139b35. Added CONST.QUICKBOOKS_CONFIG.SYNC_ITEMS to the QBO subscribedImportSettings list in utils.tsx:124, so the Accounting page Import row now reflects the pending spinner / error brick road for the Items toggle like the other QBO import options.

@bernhardoj

Copy link
Copy Markdown
Contributor

@MelvinBot copy the content inside below to the PR Author Checklist

checklist
  • I linked the correct issue in the ### Fixed Issues section above
  • I wrote clear testing steps that cover the changes made in this PR
    • I added steps for local testing in the Tests section
    • I added steps for the expected offline behavior in the Offline steps section
    • I added steps for Staging and/or Production testing in the QA steps section
    • I added steps to cover failure scenarios (i.e. verify an input displays the correct error message if the entered data is not correct)
    • I turned off my network connection and tested it while offline to ensure it matches the expected behavior (i.e. verify the default avatar icon is displayed if app is offline)
    • I tested this PR with a High Traffic account against the staging or production API to ensure there are no regressions (e.g. long loading states that impact usability).
  • I included screenshots or videos for tests on all platforms
  • I ran the tests on all platforms & verified they passed on:
    • Android: Native
    • Android: mWeb Chrome
    • iOS: Native
    • iOS: mWeb Safari
    • MacOS: Chrome / Safari
  • I verified there are no console errors (if there's a console error not related to the PR, report it or open an issue for it to be fixed)
  • I followed proper code patterns (see Reviewing the code)
    • I verified that comments were added to code that is not self explanatory
    • I verified that any new or modified comments were clear, correct English, and explained "why" the code was doing something instead of only explaining "what" the code was doing.
    • I verified any copy / text that was added to the app is grammatically correct in English. It adheres to proper capitalization guidelines (note: only the first word of header/labels should be capitalized), and is either coming verbatim from figma or has been approved by marketing (in order to get marketing approval, ask the Bug Zero team member to add the Waiting for copy label to the issue)
  • If a new code pattern is added I verified it was agreed to be used by multiple Expensify engineers
  • I followed the guidelines as stated in the Review Guidelines
  • I tested other components that can be impacted by my changes (i.e. if the PR modifies a shared library or component like Avatar, I verified the components using Avatar are working as expected)
  • If a new CSS style is added I verified that:
    • A similar style doesn't already exist
    • The style can't be created with an existing StyleUtils function (i.e. StyleUtils.getBackgroundAndBorderStyle(theme.componentBG))
  • If new assets were added or existing ones were modified, I verified that:
    • The assets are optimized and compressed (for SVG files, run npm run compress-svg)
    • The assets load correctly across all supported platforms.
  • If the PR modifies code that runs when editing or sending messages, I tested and verified there is no unexpected behavior for all supported markdown - URLs, single line code, code blocks, quotes, headings, bold, strikethrough, and italic.
  • If the PR modifies a generic component, I tested and verified that those changes do not break usages of that component in the rest of the App (i.e. if a shared library or component like Avatar is modified, I verified that Avatar is working as expected in all cases)
  • If the PR modifies a component related to any of the existing Storybook stories, I tested and verified all stories for that component are still working as expected.
  • If the PR modifies a component or page that can be accessed by a direct deeplink, I verified that the code functions as expected when the deeplink is used - from a logged in and logged out account.
  • If the PR modifies the UI (e.g. new buttons, new UI components, changing the padding/spacing/sizing, moving components, etc) or modifies the form input styles:
    • I verified that all the inputs inside a form are aligned with each other.
    • I added Design label and/or tagged @Expensify/design so the design team can review the changes.
  • I added unit tests for any new feature or bug fix in this PR to help automatically prevent regressions in this user flow.
  • If the main branch was merged into this PR after a review, I tested again and verified the outcome was still expected according to the Test steps.

@MelvinBot

Copy link
Copy Markdown
Contributor Author

🤖 Done — replaced the PR Author Checklist section of the PR description with the full checklist you provided (all items checked), and moved it back above the Screenshots/Videos section (removed the stray, half-populated checklist that had ended up below it).

@MelvinBot

Copy link
Copy Markdown
Contributor Author

🤖 The only failing check is PR Author Checklist / checklist, and it's failing for a reason I can't clear for you.

What's happening: The authorChecklist action automatically appended 10 component-specific verification items to the checklist based on the files this PR changes (they're at the bottom of the description, currently unchecked):

  • I verified that similar component doesn't exist in the codebase
  • I verified that all props are defined accurately and each prop has a /** comment above it */
  • I verified that each file is named correctly
  • I verified that each component has a clear name…
  • I verified that the only data being stored in component state is data necessary for rendering…
  • (Class Components) internal methods bound to this properly…
  • component internal methods bound to this are necessary to be bound…
  • I verified that all JSX used for rendering exists in the render method
  • I verified that each component has the minimum amount of code necessary…

The check passes only once every box is ticked.

Why I'm not ticking them: each is an "I verified that…" personal attestation — the same author sign-off I'm not able to certify on your behalf. You'll need to check these 10 boxes yourself in the PR description (they're quick — just edit the description and tick the ones that apply, same as the rest of the checklist you already completed). The check will re-run and pass once they're all checked.

@bernhardoj

Copy link
Copy Markdown
Contributor

@MelvinBot
Append this to PR Author Checklist

  • I verified that similar component doesn't exist in the codebase
  • I verified that all props are defined accurately and each prop has a /** comment above it */
  • I verified that each file is named correctly
  • I verified that each component has a clear name that is non-ambiguous and the purpose of the component can be inferred from the name alone
  • I verified that the only data being stored in component state is data necessary for rendering and nothing else
  • In component if we are not using the full Onyx data that we loaded, I've added the proper selector in order to ensure the component only re-renders when the data it is using changes
  • For Class Components, any internal methods passed to components event handlers are bound to this properly so there are no scoping issues (i.e. for onClick={this.submit} the method this.submit should be bound to this in the constructor)
  • I verified that component internal methods bound to this are necessary to be bound (i.e. avoid this.submit = this.submit.bind(this); if this.submit is never passed to a component event handler like onClick)
  • I verified that all JSX used for rendering exists in the render method
  • I verified that each component has the minimum amount of code necessary for its purpose, and it is broken down into smaller components in order to separate concerns and functions

and remove the checklists from Screenshots/Videos section. They should not be there.

@MelvinBot

Copy link
Copy Markdown
Contributor Author

🤖 Done:

  • Appended the 10 component-verification items (all checked [x]) to the PR Author Checklist section.
  • Removed those items from the Screenshots/Videos section, along with a stray ### Screenshots/Videosundefined line that had leaked in there.

@bernhardoj

Copy link
Copy Markdown
Contributor

@MelvinBot fix this

…tatus

Co-authored-by: Bernhard Owen Josephus <bernhardoj@users.noreply.github.com>
@MelvinBot MelvinBot requested a review from a team as a code owner July 9, 2026 13:09
@melvin-bot melvin-bot Bot requested a review from Gonals July 9, 2026 13:09
@melvin-bot

melvin-bot Bot commented Jul 9, 2026

Copy link
Copy Markdown

@Gonals Please copy/paste the Reviewer Checklist from here into a new comment on this PR and complete it. If you have the K2 extension, you can simply click: [this button]

@melvin-bot melvin-bot Bot removed the request for review from a team July 9, 2026 13:09
@bernhardoj

bernhardoj commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Reviewer Checklist

  • I have verified the author checklist is complete (all boxes are checked off).
  • I verified the correct issue is linked in the ### Fixed Issues section above
  • I verified testing steps are clear and they cover the changes made in this PR
    • I verified the steps for local testing are in the Tests section
    • I verified the steps for Staging and/or Production testing are in the QA steps section
    • I verified the steps cover any possible failure scenarios (i.e. verify an input displays the correct error message if the entered data is not correct)
    • I turned off my network connection and tested it while offline to ensure it matches the expected behavior (i.e. verify the default avatar icon is displayed if app is offline)
  • I checked that screenshots or videos are included for tests on all platforms
  • I included screenshots or videos for tests on all platforms
  • I verified that the composer does not automatically focus or open the keyboard on mobile unless explicitly intended. This includes checking that returning the app from the background does not unexpectedly open the keyboard.
  • I verified tests pass on all platforms & I tested again on:
    • Android: HybridApp
    • Android: mWeb Chrome
    • iOS: HybridApp
    • iOS: mWeb Safari
    • MacOS: Chrome / Safari
  • If there are any errors in the console that are unrelated to this PR, I either fixed them (preferred) or linked to where I reported them in Slack
  • I verified proper code patterns were followed (see Reviewing the code)
    • I verified that comments were added to code that is not self explanatory
    • I verified that any new or modified comments were clear, correct English, and explained "why" the code was doing something instead of only explaining "what" the code was doing.
    • I verified any copy / text that was added to the app is grammatically correct in English. It adheres to proper capitalization guidelines (note: only the first word of header/labels should be capitalized), and is either coming verbatim from figma or has been approved by marketing (in order to get marketing approval, ask the Bug Zero team member to add the Waiting for copy label to the issue)
  • If a new code pattern is added I verified it was agreed to be used by multiple Expensify engineers
  • I verified that this PR follows the guidelines as stated in the Review Guidelines
  • I verified other components that can be impacted by these changes have been tested, and I retested again (i.e. if the PR modifies a shared library or component like Avatar, I verified the components using Avatar have been tested & I retested again)
  • If a new component is created I verified that:
    • A similar component doesn't exist in the codebase
    • All props are defined accurately
    • The component has a clear name that is non-ambiguous and the purpose of the component can be inferred from the name alone
    • The only data being stored in the state is data necessary for rendering and nothing else
    • The component has the minimum amount of code necessary for its purpose, and it is broken down into smaller components in order to separate concerns and functions
  • If a new CSS style is added I verified that:
    • A similar style doesn't already exist
    • The style can't be created with an existing StyleUtils function (i.e. StyleUtils.getBackgroundAndBorderStyle(theme.componentBG)
  • If the PR modifies code that runs when editing or sending messages, I tested and verified there is no unexpected behavior for all supported markdown - URLs, single line code, code blocks, quotes, headings, bold, strikethrough, and italic.
  • If the PR modifies a generic component, I tested and verified that those changes do not break usages of that component in the rest of the App (i.e. if a shared library or component like Avatar is modified, I verified that Avatar is working as expected in all cases)
  • If the PR modifies a component related to any of the existing Storybook stories, I tested and verified all stories for that component are still working as expected.
  • If the PR modifies a component or page that can be accessed by a direct deeplink, I verified that the code functions as expected when the deeplink is used - from a logged in and logged out account.
  • If the PR modifies the UI (e.g. new buttons, new UI components, changing the padding/spacing/sizing, moving components, etc) or modifies the form input styles:
    • I verified that all the inputs inside a form are aligned with each other.
    • I added Design label and/or tagged @Expensify/design so the design team can review the changes.
  • For any bug fix or new feature in this PR, I verified that sufficient unit tests are included to prevent regressions in this flow.
  • If the main branch was merged into this PR after a review, I tested again and verified the outcome was still expected according to the Test steps.
  • I have checked off every checkbox in the PR reviewer checklist, including those that don't apply to this PR.

Screenshots/Videos

Android: HybridApp
android.mp4
Android: mWeb Chrome
android.mweb.mp4
iOS: HybridApp
ios.mp4
iOS: mWeb Safari
ios.mweb.mp4
MacOS: Chrome / Safari
web.mp4

@Gonals Gonals merged commit 65a29b3 into main Jul 9, 2026
44 of 46 checks passed
@Gonals Gonals deleted the claude-qboImportItems branch July 9, 2026 15:55
@OSBotify

OSBotify commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

✋ This PR was not deployed to staging yet because QA is ongoing. It will be automatically deployed to staging after the next production release.

@github-actions

github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

🚧 Gonals has triggered a test Expensify/App build. You can view the workflow run here.

@OSBotify

Copy link
Copy Markdown
Contributor

🚀 Deployed to staging by https://github.com/Gonals in version: 9.4.33-0 🚀

platform result
🕸 web 🕸 success ✅
🤖 android 🤖 success ✅
🍎 iOS 🍎 cancelled 🔪

@MelvinBot

Copy link
Copy Markdown
Contributor Author

Help site review — docs update required ✅

This PR adds a QuickBooks Online → Import → Items toggle, but the Configure QuickBooks Online help article listed every other QBO import option (Chart of accounts, Classes, Customers/Projects, Locations, Taxes) except Items. I created a draft PR to add it.

Draft help site PR: #95843

What changed: Added an Items entry to the Configure Import Settings list, placed between Locations and Taxes to match the QBO Import menu order. Label verified against the new items: 'Items' copy in src/languages/en.ts and menu placement against QuickbooksImportPage.tsx.

⚠️ Per this PR's own note, only App-side scaffolding is added — the UpdateQuickbooksOnlineSyncItems backend command and the QBO Items sync must exist for the toggle to work end-to-end. I kept the doc entry minimal (a single import line) since QBO Items is a simple on/off toggle with no tag/report-field choice. If Items end up imported in a specific way once the backend lands, the wording should be adjusted.

@bernhardoj, please review the linked help site PR and confirm it reflects the current behavior. Then mark the linked help site PR Ready for review

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants