diff --git a/assets/images/integrationicons/zoho-books-icon-square.svg b/assets/images/integrationicons/zoho-books-icon-square.svg
new file mode 100644
index 000000000000..03699e1bbaf4
--- /dev/null
+++ b/assets/images/integrationicons/zoho-books-icon-square.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/cspell.json b/cspell.json
index cd4050470f8c..0919a131be9b 100644
--- a/cspell.json
+++ b/cspell.json
@@ -469,6 +469,7 @@
"Yema",
"Zenefit",
"Zenefits",
+ "Zoho",
"Zipaligning",
"Zürcher",
"aaroon",
diff --git a/knip.json b/knip.json
index 72c09c1b8500..32c6af6ddd9d 100644
--- a/knip.json
+++ b/knip.json
@@ -43,6 +43,7 @@
"tests/perf-test/**",
"web/snippets/gib.js",
"src/libs/actions/connections/FinancialForce.ts",
+ "src/libs/actions/connections/ZohoBooks.ts",
"src/setup/telemetry/noopExpoUpdates.ts"
],
"eslint": {
diff --git a/src/CONST/index.ts b/src/CONST/index.ts
index 41376e1a296a..3752deec46e3 100644
--- a/src/CONST/index.ts
+++ b/src/CONST/index.ts
@@ -4023,6 +4023,63 @@ const CONST = {
EMPLOYEE: 'employee',
},
+ ZOHO_BOOKS_CONFIG: {
+ ORGANIZATION_ID: 'organizationID',
+ ENABLE_NEW_CATEGORIES: 'enableNewCategories',
+ SYNC_TAX_RATES: 'syncTaxRates',
+ EXPORTER: 'exporter',
+ EXPORT_DATE: 'exportDate',
+ REIMBURSABLE: 'reimbursable',
+ NON_REIMBURSABLE: 'nonReimbursable',
+ CREDIT_CARD_ACCOUNT_ID: 'creditCardAccountID',
+ EXPORT_TO_MULTIPLE_ACCOUNTS: 'exportToMultipleAccounts',
+ DEFAULT_VENDORID: 'defaultVendorID',
+ TRAVEL_BILLING_PAYABLE_ACCOUNT_ID: 'travelInvoicingPayableAccountID',
+ ACCOUNTING_METHOD: 'accountingMethod',
+ AUTO_SYNC: 'autoSync',
+ SYNC_REIMBURSED_REPORTS: 'syncReimbursedReports',
+ BILL_PAYMENT_ACCOUNT_ID: 'billPaymentAccountID',
+ SYNC_EXPENSIFY_CARD_SETTLEMENTS: 'syncExpensifyCardSettlements',
+ SETTLEMENTS_BANK_ACCOUNT_ID: 'settlementsBankAccountID',
+ SYNC_TRAVEL_BILLING_SETTLEMENTS: 'syncTravelInvoicingSettlements',
+ TRAVEL_BILLING_SETTLEMENTS_BANK_ACCOUNT_ID: 'travelInvoicingSettlementsBankAccountID',
+ FIELD_MAPPING_PREFIX: 'fieldMapping_',
+ CARD_PROGRAM_ACCOUNT_PREFIX: 'cardProgramAccount_',
+ },
+
+ ZOHO_BOOKS_MAPPING_VALUE: {
+ NONE: 'NONE',
+ TAG: 'TAG',
+ },
+
+ ZOHO_BOOKS_EXPORT_REIMBURSABLE: {
+ VENDOR_BILL: 'VENDOR_BILL',
+ },
+
+ ZOHO_BOOKS_EXPORT_NON_REIMBURSABLE: {
+ EXPENSE: 'EXPENSE',
+ },
+
+ ZOHO_BOOKS_EXPORT_DATE: {
+ LAST_EXPENSE: 'LAST_EXPENSE',
+ REPORT_EXPORTED: 'REPORT_EXPORTED',
+ REPORT_SUBMITTED: 'REPORT_SUBMITTED',
+ },
+
+ // Zoho Books accounts have one account_type. These are the lowercase values the API returns.
+ ZOHO_BOOKS_ACCOUNT_TYPE: {
+ BANK: 'bank',
+ CREDIT_CARD: 'credit_card',
+ EXPENSE: 'expense',
+ COST_OF_GOODS_SOLD: 'cost_of_goods_sold',
+ OTHER_EXPENSE: 'other_expense',
+ },
+
+ ZOHO_BOOKS_VENDOR_TYPE: {
+ VENDOR: 'vendor',
+ CUSTOMER: 'customer',
+ },
+
BUSINESS_CENTRAL_CONFIG: {
COMPANY_ID: 'companyID',
ENABLE_NEW_CATEGORIES: 'enableNewCategories',
@@ -4856,6 +4913,7 @@ const CONST = {
RILLET: 'rillet',
DUALENTRY: 'dualEntry',
CAMPFIRE: 'campfire',
+ ZOHO_BOOKS: 'zohoBooks',
BUSINESS_CENTRAL: 'businessCentral',
GUSTO: 'gusto',
ZENEFITS: 'zenefits',
@@ -4876,6 +4934,7 @@ const CONST = {
RILLET: 'rillet',
DUALENTRY: 'dualentry',
CAMPFIRE: 'campfire',
+ ZOHO_BOOKS: 'zoho-books',
BUSINESS_CENTRAL: 'business-central',
GUSTO: 'gusto',
ZENEFITS: 'zenefits',
@@ -4892,6 +4951,7 @@ const CONST = {
rillet: 'Rillet',
dualEntry: 'DualEntry',
campfire: 'Campfire',
+ zohoBooks: 'Zoho Books',
businessCentral: 'Dynamics 365 Business Central',
gusto: 'Gusto',
billCom: 'Bill.com',
@@ -5055,6 +5115,7 @@ const CONST = {
CAMPFIRE_SYNC_PAYMENTS: 'campfireSyncPayments',
CAMPFIRE_SYNC_CARD_SETTLEMENTS: 'campfireSyncCardSettlements',
CAMPFIRE_SYNC_TRAVEL_SETTLEMENTS: 'campfireSyncTravelSettlements',
+ ZOHO_BOOKS_SYNC_CONNECTION: 'zohoBooksSyncConnection',
BUSINESS_CENTRAL_SYNC_TITLE: 'businessCentralSyncTitle',
BUSINESS_CENTRAL_SYNC_CONNECTION: 'businessCentralSyncConnection',
BUSINESS_CENTRAL_SYNC_IMPORT_DATA: 'businessCentralSyncImportData',
diff --git a/src/components/Icon/chunks/expensify-icons.chunk.ts b/src/components/Icon/chunks/expensify-icons.chunk.ts
index dbb862ca5000..7b2c4282e4cd 100644
--- a/src/components/Icon/chunks/expensify-icons.chunk.ts
+++ b/src/components/Icon/chunks/expensify-icons.chunk.ts
@@ -165,6 +165,7 @@ import Uber from '@assets/images/integrationicons/uber.svg';
import XeroCircle from '@assets/images/integrationicons/xero-icon-circle.svg';
import XeroSquare from '@assets/images/integrationicons/xero-icon-square.svg';
import ZenefitsSquare from '@assets/images/integrationicons/zenefits-icon-square.svg';
+import ZohoBooksSquare from '@assets/images/integrationicons/zoho-books-icon-square.svg';
import InvoiceBookmark from '@assets/images/invoice-bookmark.svg';
import InvoiceGeneric from '@assets/images/invoice-generic.svg';
import Invoice from '@assets/images/invoice.svg';
@@ -609,6 +610,7 @@ const Expensicons = {
ApplePayMark,
Contactless,
CampfireSquare,
+ ZohoBooksSquare,
};
// Create the ExpensifyIcons object from the imported Expensicons
diff --git a/src/languages/de.ts b/src/languages/de.ts
index 505a983f8e72..c02da9c1c183 100644
--- a/src/languages/de.ts
+++ b/src/languages/de.ts
@@ -7318,6 +7318,8 @@ Der Control-Tarif beginnt bei 9 $ pro aktivem Mitglied und Monat.`,
return 'DualEntry';
case CONST.POLICY.CONNECTIONS.NAME.CAMPFIRE:
return 'Campfire';
+ case CONST.POLICY.CONNECTIONS.NAME.ZOHO_BOOKS:
+ return 'Zoho Books';
case CONST.POLICY.CONNECTIONS.NAME.BUSINESS_CENTRAL:
return 'Dynamics 365 Business Central';
default: {
@@ -7545,6 +7547,8 @@ Der Control-Tarif beginnt bei 9 $ pro aktivem Mitglied und Monat.`,
return 'Campfire-Daten werden synchronisiert';
case 'campfireSyncConnection':
return 'Verbindung zu Campfire wird initialisiert';
+ case 'zohoBooksSyncConnection':
+ return 'Verbindung zu Zoho Books wird initialisiert';
case 'campfireSyncImportData':
return 'Daten werden geladen';
case 'campfireSyncPayments':
@@ -7602,6 +7606,7 @@ Der Control-Tarif beginnt bei 9 $ pro aktivem Mitglied und Monat.`,
syncTravelInvoicingSettlementsNoAccountTooltip: 'Zum Aktivieren legen Sie ein Konto für Ihre Exporte fest.',
syncTravelInvoicingSettlementsNoAutoSyncTooltip: 'Zum Entsperren automatische Synchronisierung aktivieren.',
campfire: 'Campfire',
+ zohoBooks: 'Zoho Books',
continuousReconciliationFeedSelection:
'Die fortlaufende Abstimmung wird pro Kartenfeed konfiguriert. Wählen Sie einen Feed aus, um zu ändern, welchen Sie konfigurieren.',
businessCentral: 'Dynamics 365 Business Central',
diff --git a/src/languages/el.ts b/src/languages/el.ts
index 064233a100a1..87d967a9c603 100644
--- a/src/languages/el.ts
+++ b/src/languages/el.ts
@@ -7448,6 +7448,8 @@ _Για πιο αναλυτικές οδηγίες, [επισκεφθείτε τ
return 'DualEntry';
case CONST.POLICY.CONNECTIONS.NAME.CAMPFIRE:
return 'Campfire';
+ case CONST.POLICY.CONNECTIONS.NAME.ZOHO_BOOKS:
+ return 'Zoho Books';
case CONST.POLICY.CONNECTIONS.NAME.BUSINESS_CENTRAL:
return 'Dynamics 365 Business Central';
default: {
@@ -7676,6 +7678,8 @@ _Για πιο αναλυτικές οδηγίες, [επισκεφθείτε τ
return 'Γίνεται συγχρονισμός δεδομένων Campfire';
case 'campfireSyncConnection':
return 'Γίνεται αρχικοποίηση σύνδεσης με το Campfire';
+ case 'zohoBooksSyncConnection':
+ return 'Γίνεται αρχικοποίηση σύνδεσης με το Zoho Books';
case 'campfireSyncImportData':
return 'Φόρτωση δεδομένων';
case 'campfireSyncPayments':
@@ -7733,6 +7737,7 @@ _Για πιο αναλυτικές οδηγίες, [επισκεφθείτε τ
syncTravelInvoicingSettlementsNoAccountTooltip: 'Για να το ενεργοποιήσετε, ορίστε έναν λογαριασμό για τις εξαγωγές σας.',
syncTravelInvoicingSettlementsNoAutoSyncTooltip: 'Για να το ξεκλειδώσετε, ενεργοποιήστε τον αυτόματο συγχρονισμό.',
campfire: 'Campfire',
+ zohoBooks: 'Zoho Books',
continuousReconciliationFeedSelection:
'Η συνεχής συμφωνία είναι ρυθμισμένη ανά ροή καρτών. Επιλέξτε μια ροή για να αλλάξετε ποια ρυθμίζετε.',
businessCentral: 'Dynamics 365 Business Central',
diff --git a/src/languages/en.ts b/src/languages/en.ts
index da4c1455f16c..9c2c63980d80 100644
--- a/src/languages/en.ts
+++ b/src/languages/en.ts
@@ -7641,6 +7641,7 @@ const translations = {
rillet: 'Rillet',
dualEntry: 'DualEntry',
campfire: 'Campfire',
+ zohoBooks: 'Zoho Books',
businessCentral: 'Dynamics 365 Business Central',
sap: 'SAP',
oracle: 'Oracle',
@@ -7665,6 +7666,8 @@ const translations = {
return 'DualEntry';
case CONST.POLICY.CONNECTIONS.NAME.CAMPFIRE:
return 'Campfire';
+ case CONST.POLICY.CONNECTIONS.NAME.ZOHO_BOOKS:
+ return 'Zoho Books';
case CONST.POLICY.CONNECTIONS.NAME.BUSINESS_CENTRAL:
return 'Dynamics 365 Business Central';
default: {
@@ -7895,6 +7898,8 @@ const translations = {
return 'Syncing Campfire data';
case 'campfireSyncConnection':
return 'Initializing connection to Campfire';
+ case 'zohoBooksSyncConnection':
+ return 'Initializing connection to Zoho Books';
case 'campfireSyncImportData':
return 'Loading data';
case 'campfireSyncPayments':
diff --git a/src/languages/es.ts b/src/languages/es.ts
index b75baf48477d..533a2b31fa28 100644
--- a/src/languages/es.ts
+++ b/src/languages/es.ts
@@ -7123,6 +7123,8 @@ El plan Controlar empieza en 9 $ por miembro activo al mes.`,
return 'DualEntry';
case CONST.POLICY.CONNECTIONS.NAME.CAMPFIRE:
return 'Campfire';
+ case CONST.POLICY.CONNECTIONS.NAME.ZOHO_BOOKS:
+ return 'Zoho Books';
case CONST.POLICY.CONNECTIONS.NAME.BUSINESS_CENTRAL:
return 'Dynamics 365 Business Central';
default: {
@@ -7351,6 +7353,8 @@ El plan Controlar empieza en 9 $ por miembro activo al mes.`,
return 'Sincronizando datos de Campfire';
case 'campfireSyncConnection':
return 'Iniciando conexión con Campfire';
+ case 'zohoBooksSyncConnection':
+ return 'Iniciando conexión con Zoho Books';
case 'campfireSyncImportData':
return 'Cargando datos';
case 'campfireSyncPayments':
@@ -7408,6 +7412,7 @@ El plan Controlar empieza en 9 $ por miembro activo al mes.`,
syncTravelInvoicingSettlementsNoAccountTooltip: 'Para desbloquearlo, configura una cuenta para tus exportaciones.',
syncTravelInvoicingSettlementsNoAutoSyncTooltip: 'Para desbloquear, habilita la sincronización automática.',
campfire: 'Campfire',
+ zohoBooks: 'Zoho Books',
continuousReconciliationFeedSelection:
'La conciliación continua se configura por cada fuente de tarjetas. Selecciona una fuente para cambiar cuál estás configurando.',
businessCentral: 'Dynamics 365 Business Central',
diff --git a/src/languages/fr.ts b/src/languages/fr.ts
index 2953e37f929f..cdf0e4777d54 100644
--- a/src/languages/fr.ts
+++ b/src/languages/fr.ts
@@ -7336,6 +7336,8 @@ Le forfait Control commence à 9 $ par Membre actif et par mois.`,
return 'DualEntry';
case CONST.POLICY.CONNECTIONS.NAME.CAMPFIRE:
return 'Campfire';
+ case CONST.POLICY.CONNECTIONS.NAME.ZOHO_BOOKS:
+ return 'Zoho Books';
case CONST.POLICY.CONNECTIONS.NAME.BUSINESS_CENTRAL:
return 'Dynamics 365 Business Central';
default: {
@@ -7564,6 +7566,8 @@ Le forfait Control commence à 9 $ par Membre actif et par mois.`,
return 'Synchronisation des données Campfire';
case 'campfireSyncConnection':
return 'Initialisation de la connexion à Campfire';
+ case 'zohoBooksSyncConnection':
+ return 'Initialisation de la connexion à Zoho Books';
case 'campfireSyncImportData':
return 'Chargement des données';
case 'campfireSyncPayments':
@@ -7621,6 +7625,7 @@ Le forfait Control commence à 9 $ par Membre actif et par mois.`,
syncTravelInvoicingSettlementsNoAccountTooltip: 'Pour le déverrouiller, définissez un compte pour vos exports.',
syncTravelInvoicingSettlementsNoAutoSyncTooltip: 'Pour le déverrouiller, activez la synchronisation automatique.',
campfire: 'Campfire',
+ zohoBooks: 'Zoho Books',
continuousReconciliationFeedSelection:
'Le rapprochement continu est configuré par flux de carte. Sélectionnez un flux pour changer celui que vous configurez.',
businessCentral: 'Dynamics 365 Business Central',
diff --git a/src/languages/it.ts b/src/languages/it.ts
index 4493c684f9c6..6703b0b8abed 100644
--- a/src/languages/it.ts
+++ b/src/languages/it.ts
@@ -7276,6 +7276,8 @@ Il piano Control parte da 9 $ al mese per ogni membro attivo.`,
return 'DualEntry';
case CONST.POLICY.CONNECTIONS.NAME.CAMPFIRE:
return 'Campfire';
+ case CONST.POLICY.CONNECTIONS.NAME.ZOHO_BOOKS:
+ return 'Zoho Books';
case CONST.POLICY.CONNECTIONS.NAME.BUSINESS_CENTRAL:
return 'Dynamics 365 Business Central';
default: {
@@ -7503,6 +7505,8 @@ Il piano Control parte da 9 $ al mese per ogni membro attivo.`,
return 'Sincronizzazione dei dati Campfire';
case 'campfireSyncConnection':
return 'Inizializzazione della connessione a Campfire';
+ case 'zohoBooksSyncConnection':
+ return 'Inizializzazione della connessione a Zoho Books';
case 'campfireSyncImportData':
return 'Caricamento dei dati';
case 'campfireSyncPayments':
@@ -7560,6 +7564,7 @@ Il piano Control parte da 9 $ al mese per ogni membro attivo.`,
syncTravelInvoicingSettlementsNoAccountTooltip: 'Per sbloccare, imposta un conto per le tue esportazioni.',
syncTravelInvoicingSettlementsNoAutoSyncTooltip: 'Per sbloccare, abilita la sincronizzazione automatica.',
campfire: 'Campfire',
+ zohoBooks: 'Zoho Books',
continuousReconciliationFeedSelection:
'La Riconciliazione continua è configurata per ogni flusso di carte. Seleziona un flusso per cambiare quello che stai configurando.',
businessCentral: 'Dynamics 365 Business Central',
diff --git a/src/languages/ja.ts b/src/languages/ja.ts
index 8c0ae357052b..6efad1e448d2 100644
--- a/src/languages/ja.ts
+++ b/src/languages/ja.ts
@@ -7186,6 +7186,8 @@ Control プランは、アクティブメンバー1人あたり月額 $9 から
return 'DualEntry';
case CONST.POLICY.CONNECTIONS.NAME.CAMPFIRE:
return 'Campfire';
+ case CONST.POLICY.CONNECTIONS.NAME.ZOHO_BOOKS:
+ return 'Zoho Books';
case CONST.POLICY.CONNECTIONS.NAME.BUSINESS_CENTRAL:
return 'Dynamics 365 Business Central';
default: {
@@ -7414,6 +7416,8 @@ Control プランは、アクティブメンバー1人あたり月額 $9 から
return 'Campfire データを同期しています';
case 'campfireSyncConnection':
return 'Campfire への接続を初期化しています';
+ case 'zohoBooksSyncConnection':
+ return 'Zoho Books への接続を初期化しています';
case 'campfireSyncImportData':
return 'データを読み込んでいます';
case 'campfireSyncPayments':
@@ -7470,6 +7474,7 @@ Control プランは、アクティブメンバー1人あたり月額 $9 から
syncTravelInvoicingSettlementsNoAccountTooltip: 'ロックを解除するには、エクスポート用の口座を設定してください。',
syncTravelInvoicingSettlementsNoAutoSyncTooltip: 'ロックを解除するには、自動同期を有効にしてください。',
campfire: 'Campfire',
+ zohoBooks: 'Zoho Books',
continuousReconciliationFeedSelection:
'継続的な照合はカードフィードごとに設定されます。設定するフィードを変更するには、フィードを選択してください。',
businessCentral: 'Dynamics 365 Business Central',
diff --git a/src/languages/nl.ts b/src/languages/nl.ts
index fadbc004788e..93789f0c3537 100644
--- a/src/languages/nl.ts
+++ b/src/languages/nl.ts
@@ -7260,6 +7260,8 @@ Het Control-abonnement begint bij $9 per actieve deelnemer per maand.`,
return 'DualEntry';
case CONST.POLICY.CONNECTIONS.NAME.CAMPFIRE:
return 'Campfire';
+ case CONST.POLICY.CONNECTIONS.NAME.ZOHO_BOOKS:
+ return 'Zoho Books';
case CONST.POLICY.CONNECTIONS.NAME.BUSINESS_CENTRAL:
return 'Dynamics 365 Business Central';
default: {
@@ -7487,6 +7489,8 @@ Het Control-abonnement begint bij $9 per actieve deelnemer per maand.`,
return 'Campfire-gegevens synchroniseren';
case 'campfireSyncConnection':
return 'Verbinding met Campfire initialiseren';
+ case 'zohoBooksSyncConnection':
+ return 'Verbinding met Zoho Books initialiseren';
case 'campfireSyncImportData':
return 'Gegevens laden';
case 'campfireSyncPayments':
@@ -7544,6 +7548,7 @@ Het Control-abonnement begint bij $9 per actieve deelnemer per maand.`,
syncTravelInvoicingSettlementsNoAccountTooltip: 'Om dit te ontgrendelen, stel je een rekening in voor je exporten.',
syncTravelInvoicingSettlementsNoAutoSyncTooltip: 'Schakel automatisch synchroniseren in om dit te ontgrendelen.',
campfire: 'Campfire',
+ zohoBooks: 'Zoho Books',
continuousReconciliationFeedSelection:
'Doorlopende afstemming wordt per kaartfeed geconfigureerd. Selecteer een feed om te wijzigen welke je configureert.',
businessCentral: 'Dynamics 365 Business Central',
diff --git a/src/languages/pl.ts b/src/languages/pl.ts
index 889539ccabe5..c09dd3434716 100644
--- a/src/languages/pl.ts
+++ b/src/languages/pl.ts
@@ -7284,6 +7284,8 @@ Plan Control zaczyna się od 9 USD za aktywnego członka miesięcznie.`,
return 'DualEntry';
case CONST.POLICY.CONNECTIONS.NAME.CAMPFIRE:
return 'Campfire';
+ case CONST.POLICY.CONNECTIONS.NAME.ZOHO_BOOKS:
+ return 'Zoho Books';
case CONST.POLICY.CONNECTIONS.NAME.BUSINESS_CENTRAL:
return 'Dynamics 365 Business Central';
default: {
@@ -7511,6 +7513,8 @@ Plan Control zaczyna się od 9 USD za aktywnego członka miesięcznie.`,
return 'Synchronizowanie danych Campfire';
case 'campfireSyncConnection':
return 'Inicjowanie połączenia z Campfire';
+ case 'zohoBooksSyncConnection':
+ return 'Inicjowanie połączenia z Zoho Books';
case 'campfireSyncImportData':
return 'Wczytywanie danych';
case 'campfireSyncPayments':
@@ -7567,6 +7571,7 @@ Plan Control zaczyna się od 9 USD za aktywnego członka miesięcznie.`,
syncTravelInvoicingSettlementsNoAccountTooltip: 'Aby odblokować, ustaw konto dla swoich eksportów.',
syncTravelInvoicingSettlementsNoAutoSyncTooltip: 'Aby odblokować, włącz automatyczną synchronizację.',
campfire: 'Campfire',
+ zohoBooks: 'Zoho Books',
continuousReconciliationFeedSelection:
'Ciągłe uzgadnianie jest konfigurowane dla każdego źródła kart osobno. Wybierz źródło, aby zmienić, które konfigurujesz.',
businessCentral: 'Dynamics 365 Business Central',
diff --git a/src/languages/pt-BR.ts b/src/languages/pt-BR.ts
index 1de49e27f39a..5a76f42a9875 100644
--- a/src/languages/pt-BR.ts
+++ b/src/languages/pt-BR.ts
@@ -7262,6 +7262,8 @@ O plano Control começa em US$ 9 por membro ativo por mês.`,
return 'DualEntry';
case CONST.POLICY.CONNECTIONS.NAME.CAMPFIRE:
return 'Campfire';
+ case CONST.POLICY.CONNECTIONS.NAME.ZOHO_BOOKS:
+ return 'Zoho Books';
case CONST.POLICY.CONNECTIONS.NAME.BUSINESS_CENTRAL:
return 'Dynamics 365 Business Central';
default: {
@@ -7489,6 +7491,8 @@ O plano Control começa em US$ 9 por membro ativo por mês.`,
return 'Sincronizando dados do Campfire';
case 'campfireSyncConnection':
return 'Inicializando conexão com o Campfire';
+ case 'zohoBooksSyncConnection':
+ return 'Inicializando conexão com o Zoho Books';
case 'campfireSyncImportData':
return 'Carregando dados';
case 'campfireSyncPayments':
@@ -7546,6 +7550,7 @@ O plano Control começa em US$ 9 por membro ativo por mês.`,
syncTravelInvoicingSettlementsNoAccountTooltip: 'Para desbloquear, defina uma conta para suas exportações.',
syncTravelInvoicingSettlementsNoAutoSyncTooltip: 'Para desbloquear, ative a sincronização automática.',
campfire: 'Campfire',
+ zohoBooks: 'Zoho Books',
continuousReconciliationFeedSelection:
'A Conciliação Contínua é configurada por feed de cartão. Selecione um feed para alterar qual você está configurando.',
businessCentral: 'Dynamics 365 Business Central',
diff --git a/src/languages/zh-hans.ts b/src/languages/zh-hans.ts
index 35b7beee7a11..55283d0431ea 100644
--- a/src/languages/zh-hans.ts
+++ b/src/languages/zh-hans.ts
@@ -7008,6 +7008,8 @@ _如需更详细的说明,请[访问我们的帮助网站](${CONST.NETSUITE_IM
return 'DualEntry';
case CONST.POLICY.CONNECTIONS.NAME.CAMPFIRE:
return 'Campfire';
+ case CONST.POLICY.CONNECTIONS.NAME.ZOHO_BOOKS:
+ return 'Zoho Books';
case CONST.POLICY.CONNECTIONS.NAME.BUSINESS_CENTRAL:
return 'Dynamics 365 Business Central';
default: {
@@ -7234,6 +7236,8 @@ _如需更详细的说明,请[访问我们的帮助网站](${CONST.NETSUITE_IM
return '正在同步 Campfire 数据';
case 'campfireSyncConnection':
return '正在初始化与 Campfire 的连接';
+ case 'zohoBooksSyncConnection':
+ return '正在初始化与 Zoho Books 的连接';
case 'campfireSyncImportData':
return '正在加载数据';
case 'campfireSyncPayments':
@@ -7286,6 +7290,7 @@ _如需更详细的说明,请[访问我们的帮助网站](${CONST.NETSUITE_IM
syncTravelInvoicingSettlementsNoAccountTooltip: '要解锁,请为导出设置一个账户。',
syncTravelInvoicingSettlementsNoAutoSyncTooltip: '若要解锁,请启用自动同步。',
campfire: 'Campfire',
+ zohoBooks: 'Zoho Books',
continuousReconciliationFeedSelection: '按卡片流水单独配置持续对账。选择一个流水以更改您正在配置的流水。',
businessCentral: 'Dynamics 365 Business Central',
qboConnectionExpiring: ({date}: {date: string}) => `您的 QuickBooks Online 连接将于 ${date} 过期。`,
diff --git a/src/libs/API/parameters/ConnectPolicyToZohoBooksParams.ts b/src/libs/API/parameters/ConnectPolicyToZohoBooksParams.ts
new file mode 100644
index 000000000000..a1b38c276641
--- /dev/null
+++ b/src/libs/API/parameters/ConnectPolicyToZohoBooksParams.ts
@@ -0,0 +1,5 @@
+type ConnectPolicyToZohoBooksParams = {
+ policyID: string;
+};
+
+export default ConnectPolicyToZohoBooksParams;
diff --git a/src/libs/API/parameters/SyncPolicyToZohoBooksParams.ts b/src/libs/API/parameters/SyncPolicyToZohoBooksParams.ts
new file mode 100644
index 000000000000..8fb2c5992296
--- /dev/null
+++ b/src/libs/API/parameters/SyncPolicyToZohoBooksParams.ts
@@ -0,0 +1,6 @@
+type SyncPolicyToZohoBooksParams = {
+ policyID: string;
+ idempotencyKey: string;
+};
+
+export default SyncPolicyToZohoBooksParams;
diff --git a/src/libs/API/parameters/UpdateZohoBooksAccountingMethodParams.ts b/src/libs/API/parameters/UpdateZohoBooksAccountingMethodParams.ts
new file mode 100644
index 000000000000..004fcc2b6074
--- /dev/null
+++ b/src/libs/API/parameters/UpdateZohoBooksAccountingMethodParams.ts
@@ -0,0 +1,9 @@
+import type {CONST as COMMON_CONST} from 'expensify-common';
+import type {ValueOf} from 'type-fest';
+
+type UpdateZohoBooksAccountingMethodParams = {
+ policyID: string;
+ accountingMethod: ValueOf;
+};
+
+export default UpdateZohoBooksAccountingMethodParams;
diff --git a/src/libs/API/parameters/UpdateZohoBooksAutoSyncParams.ts b/src/libs/API/parameters/UpdateZohoBooksAutoSyncParams.ts
new file mode 100644
index 000000000000..df0764f4d78e
--- /dev/null
+++ b/src/libs/API/parameters/UpdateZohoBooksAutoSyncParams.ts
@@ -0,0 +1,6 @@
+type UpdateZohoBooksAutoSyncParams = {
+ policyID: string;
+ enabled: boolean;
+};
+
+export default UpdateZohoBooksAutoSyncParams;
diff --git a/src/libs/API/parameters/UpdateZohoBooksBillPaymentAccountParams.ts b/src/libs/API/parameters/UpdateZohoBooksBillPaymentAccountParams.ts
new file mode 100644
index 000000000000..3ac5d96cd718
--- /dev/null
+++ b/src/libs/API/parameters/UpdateZohoBooksBillPaymentAccountParams.ts
@@ -0,0 +1,8 @@
+import type {ZohoBooksAccount} from '@src/types/onyx/Policy';
+
+type UpdateZohoBooksBillPaymentAccountParams = {
+ policyID: string;
+ billPaymentAccountID: ZohoBooksAccount['id'];
+};
+
+export default UpdateZohoBooksBillPaymentAccountParams;
diff --git a/src/libs/API/parameters/UpdateZohoBooksCardProgramAccountParams.ts b/src/libs/API/parameters/UpdateZohoBooksCardProgramAccountParams.ts
new file mode 100644
index 000000000000..aa0fad7563f5
--- /dev/null
+++ b/src/libs/API/parameters/UpdateZohoBooksCardProgramAccountParams.ts
@@ -0,0 +1,10 @@
+import type {CardFeedWithNumber} from '@src/types/onyx/CardFeeds';
+import type {ZohoBooksAccount} from '@src/types/onyx/Policy';
+
+type UpdateZohoBooksCardProgramAccountParams = {
+ policyID: string;
+ feedKey: CardFeedWithNumber;
+ cardProgramAccountID: ZohoBooksAccount['id'];
+};
+
+export default UpdateZohoBooksCardProgramAccountParams;
diff --git a/src/libs/API/parameters/UpdateZohoBooksCreditCardAccountParams.ts b/src/libs/API/parameters/UpdateZohoBooksCreditCardAccountParams.ts
new file mode 100644
index 000000000000..1c98a59deab0
--- /dev/null
+++ b/src/libs/API/parameters/UpdateZohoBooksCreditCardAccountParams.ts
@@ -0,0 +1,8 @@
+import type {ZohoBooksAccount} from '@src/types/onyx/Policy';
+
+type UpdateZohoBooksCreditCardAccountParams = {
+ policyID: string;
+ creditCardAccountID: ZohoBooksAccount['id'];
+};
+
+export default UpdateZohoBooksCreditCardAccountParams;
diff --git a/src/libs/API/parameters/UpdateZohoBooksDefaultVendorParams.ts b/src/libs/API/parameters/UpdateZohoBooksDefaultVendorParams.ts
new file mode 100644
index 000000000000..a3eb5f7d58c4
--- /dev/null
+++ b/src/libs/API/parameters/UpdateZohoBooksDefaultVendorParams.ts
@@ -0,0 +1,8 @@
+import type {ZohoBooksVendor} from '@src/types/onyx/Policy';
+
+type UpdateZohoBooksDefaultVendorParams = {
+ policyID: string;
+ vendorID: ZohoBooksVendor['id'];
+};
+
+export default UpdateZohoBooksDefaultVendorParams;
diff --git a/src/libs/API/parameters/UpdateZohoBooksEnableNewCategoriesParams.ts b/src/libs/API/parameters/UpdateZohoBooksEnableNewCategoriesParams.ts
new file mode 100644
index 000000000000..c4b458815727
--- /dev/null
+++ b/src/libs/API/parameters/UpdateZohoBooksEnableNewCategoriesParams.ts
@@ -0,0 +1,9 @@
+type UpdateZohoBooksEnableNewCategoriesParams = {
+ /** The workspace where the setting is updated. */
+ policyID: string;
+
+ /** Whether categories newly created in Zoho Books are imported. */
+ enabled: boolean;
+};
+
+export default UpdateZohoBooksEnableNewCategoriesParams;
diff --git a/src/libs/API/parameters/UpdateZohoBooksExportDateParams.ts b/src/libs/API/parameters/UpdateZohoBooksExportDateParams.ts
new file mode 100644
index 000000000000..777f3089e304
--- /dev/null
+++ b/src/libs/API/parameters/UpdateZohoBooksExportDateParams.ts
@@ -0,0 +1,8 @@
+import type {ZohoBooksExportDate} from '@src/types/onyx/Policy';
+
+type UpdateZohoBooksExportDateParams = {
+ policyID: string;
+ value: ZohoBooksExportDate;
+};
+
+export default UpdateZohoBooksExportDateParams;
diff --git a/src/libs/API/parameters/UpdateZohoBooksExportToMultipleAccountsParams.ts b/src/libs/API/parameters/UpdateZohoBooksExportToMultipleAccountsParams.ts
new file mode 100644
index 000000000000..77def440e222
--- /dev/null
+++ b/src/libs/API/parameters/UpdateZohoBooksExportToMultipleAccountsParams.ts
@@ -0,0 +1,6 @@
+type UpdateZohoBooksExportToMultipleAccountsParams = {
+ policyID: string;
+ enabled: boolean;
+};
+
+export default UpdateZohoBooksExportToMultipleAccountsParams;
diff --git a/src/libs/API/parameters/UpdateZohoBooksExporterParams.ts b/src/libs/API/parameters/UpdateZohoBooksExporterParams.ts
new file mode 100644
index 000000000000..a1bbbad5f896
--- /dev/null
+++ b/src/libs/API/parameters/UpdateZohoBooksExporterParams.ts
@@ -0,0 +1,6 @@
+type UpdateZohoBooksExporterParams = {
+ policyID: string;
+ email: string;
+};
+
+export default UpdateZohoBooksExporterParams;
diff --git a/src/libs/API/parameters/UpdateZohoBooksFieldMappingParams.ts b/src/libs/API/parameters/UpdateZohoBooksFieldMappingParams.ts
new file mode 100644
index 000000000000..34c301973558
--- /dev/null
+++ b/src/libs/API/parameters/UpdateZohoBooksFieldMappingParams.ts
@@ -0,0 +1,16 @@
+import type CONST from '@src/CONST';
+
+import type {ValueOf} from 'type-fest';
+
+type UpdateZohoBooksFieldMappingParams = {
+ /** The workspace where the field mapping is updated. */
+ policyID: string;
+
+ /** The Zoho Books reporting tag to map. */
+ fieldID: string;
+
+ /** The Expensify dimension mapped to the Zoho Books reporting tag. */
+ mapping: ValueOf;
+};
+
+export default UpdateZohoBooksFieldMappingParams;
diff --git a/src/libs/API/parameters/UpdateZohoBooksOrganizationParams.ts b/src/libs/API/parameters/UpdateZohoBooksOrganizationParams.ts
new file mode 100644
index 000000000000..51adb4193bb3
--- /dev/null
+++ b/src/libs/API/parameters/UpdateZohoBooksOrganizationParams.ts
@@ -0,0 +1,6 @@
+type UpdateZohoBooksOrganizationParams = {
+ policyID: string;
+ organizationID: string;
+};
+
+export default UpdateZohoBooksOrganizationParams;
diff --git a/src/libs/API/parameters/UpdateZohoBooksSettlementsAccountParams.ts b/src/libs/API/parameters/UpdateZohoBooksSettlementsAccountParams.ts
new file mode 100644
index 000000000000..c46c0cb9dd70
--- /dev/null
+++ b/src/libs/API/parameters/UpdateZohoBooksSettlementsAccountParams.ts
@@ -0,0 +1,8 @@
+import type {ZohoBooksAccount} from '@src/types/onyx/Policy';
+
+type UpdateZohoBooksSettlementsAccountParams = {
+ policyID: string;
+ settlementsBankAccountID: ZohoBooksAccount['id'];
+};
+
+export default UpdateZohoBooksSettlementsAccountParams;
diff --git a/src/libs/API/parameters/UpdateZohoBooksSyncExpensifyCardSettlementsParams.ts b/src/libs/API/parameters/UpdateZohoBooksSyncExpensifyCardSettlementsParams.ts
new file mode 100644
index 000000000000..4c4ba509e804
--- /dev/null
+++ b/src/libs/API/parameters/UpdateZohoBooksSyncExpensifyCardSettlementsParams.ts
@@ -0,0 +1,6 @@
+type UpdateZohoBooksSyncExpensifyCardSettlementsParams = {
+ policyID: string;
+ enabled: boolean;
+};
+
+export default UpdateZohoBooksSyncExpensifyCardSettlementsParams;
diff --git a/src/libs/API/parameters/UpdateZohoBooksSyncReimbursedReportsParams.ts b/src/libs/API/parameters/UpdateZohoBooksSyncReimbursedReportsParams.ts
new file mode 100644
index 000000000000..b07370de5763
--- /dev/null
+++ b/src/libs/API/parameters/UpdateZohoBooksSyncReimbursedReportsParams.ts
@@ -0,0 +1,6 @@
+type UpdateZohoBooksSyncReimbursedReportsParams = {
+ policyID: string;
+ enabled: boolean;
+};
+
+export default UpdateZohoBooksSyncReimbursedReportsParams;
diff --git a/src/libs/API/parameters/UpdateZohoBooksSyncTaxRatesParams.ts b/src/libs/API/parameters/UpdateZohoBooksSyncTaxRatesParams.ts
new file mode 100644
index 000000000000..614ef888dd8d
--- /dev/null
+++ b/src/libs/API/parameters/UpdateZohoBooksSyncTaxRatesParams.ts
@@ -0,0 +1,9 @@
+type UpdateZohoBooksSyncTaxRatesParams = {
+ /** The workspace where the setting is updated. */
+ policyID: string;
+
+ /** Whether tax rates are imported from Zoho Books. */
+ enabled: boolean;
+};
+
+export default UpdateZohoBooksSyncTaxRatesParams;
diff --git a/src/libs/API/parameters/UpdateZohoBooksSyncTravelInvoicingSettlementsParams.ts b/src/libs/API/parameters/UpdateZohoBooksSyncTravelInvoicingSettlementsParams.ts
new file mode 100644
index 000000000000..9f563629b877
--- /dev/null
+++ b/src/libs/API/parameters/UpdateZohoBooksSyncTravelInvoicingSettlementsParams.ts
@@ -0,0 +1,6 @@
+type UpdateZohoBooksSyncTravelInvoicingSettlementsParams = {
+ policyID: string;
+ enabled: boolean;
+};
+
+export default UpdateZohoBooksSyncTravelInvoicingSettlementsParams;
diff --git a/src/libs/API/parameters/UpdateZohoBooksTravelInvoicingPayableAccountParams.ts b/src/libs/API/parameters/UpdateZohoBooksTravelInvoicingPayableAccountParams.ts
new file mode 100644
index 000000000000..f8c5f8c2f769
--- /dev/null
+++ b/src/libs/API/parameters/UpdateZohoBooksTravelInvoicingPayableAccountParams.ts
@@ -0,0 +1,8 @@
+import type {ZohoBooksAccount} from '@src/types/onyx/Policy';
+
+type UpdateZohoBooksTravelInvoicingPayableAccountParams = {
+ policyID: string;
+ travelInvoicingPayableAccountID: ZohoBooksAccount['id'];
+};
+
+export default UpdateZohoBooksTravelInvoicingPayableAccountParams;
diff --git a/src/libs/API/parameters/UpdateZohoBooksTravelInvoicingSettlementsAccountParams.ts b/src/libs/API/parameters/UpdateZohoBooksTravelInvoicingSettlementsAccountParams.ts
new file mode 100644
index 000000000000..3fcb3a50ffc3
--- /dev/null
+++ b/src/libs/API/parameters/UpdateZohoBooksTravelInvoicingSettlementsAccountParams.ts
@@ -0,0 +1,8 @@
+import type {ZohoBooksAccount} from '@src/types/onyx/Policy';
+
+type UpdateZohoBooksTravelInvoicingSettlementsAccountParams = {
+ policyID: string;
+ travelInvoicingSettlementsBankAccountID: ZohoBooksAccount['id'];
+};
+
+export default UpdateZohoBooksTravelInvoicingSettlementsAccountParams;
diff --git a/src/libs/API/parameters/index.ts b/src/libs/API/parameters/index.ts
index 5f66c7ca5c99..c38e680189c0 100644
--- a/src/libs/API/parameters/index.ts
+++ b/src/libs/API/parameters/index.ts
@@ -30,6 +30,7 @@ export type {default as ConnectPolicyToZenefitsParams} from './ConnectPolicyToZe
export type {default as ConnectPolicyToRilletParams} from './ConnectPolicyToRilletParams';
export type {default as ConnectPolicyToDualEntryParams} from './ConnectPolicyToDualEntryParams';
export type {default as ConnectPolicyToCampfireParams} from './ConnectPolicyToCampfireParams';
+export type {default as ConnectPolicyToZohoBooksParams} from './ConnectPolicyToZohoBooksParams';
export type {default as ConnectPolicyToBusinessCentralParams} from './ConnectPolicyToBusinessCentralParams';
export type {default as OpenPolicyProfilePageParams} from './OpenPolicyProfilePageParams';
export type {default as OpenPolicyInitialPageParams} from './OpenPolicyInitialPageParams';
@@ -101,6 +102,26 @@ export type {default as UpdateCampfireSettlementsAccountParams} from './UpdateCa
export type {default as UpdateCampfireSyncTravelInvoicingSettlementsParams} from './UpdateCampfireSyncTravelInvoicingSettlementsParams';
export type {default as UpdateCampfireTravelInvoicingSettlementsAccountParams} from './UpdateCampfireTravelInvoicingSettlementsAccountParams';
export type {default as UpdateCampfireTravelInvoicingPayableAccountParams} from './UpdateCampfireTravelInvoicingPayableAccountParams';
+export type {default as SyncPolicyToZohoBooksParams} from './SyncPolicyToZohoBooksParams';
+export type {default as UpdateZohoBooksOrganizationParams} from './UpdateZohoBooksOrganizationParams';
+export type {default as UpdateZohoBooksFieldMappingParams} from './UpdateZohoBooksFieldMappingParams';
+export type {default as UpdateZohoBooksEnableNewCategoriesParams} from './UpdateZohoBooksEnableNewCategoriesParams';
+export type {default as UpdateZohoBooksSyncTaxRatesParams} from './UpdateZohoBooksSyncTaxRatesParams';
+export type {default as UpdateZohoBooksExporterParams} from './UpdateZohoBooksExporterParams';
+export type {default as UpdateZohoBooksExportDateParams} from './UpdateZohoBooksExportDateParams';
+export type {default as UpdateZohoBooksDefaultVendorParams} from './UpdateZohoBooksDefaultVendorParams';
+export type {default as UpdateZohoBooksCreditCardAccountParams} from './UpdateZohoBooksCreditCardAccountParams';
+export type {default as UpdateZohoBooksExportToMultipleAccountsParams} from './UpdateZohoBooksExportToMultipleAccountsParams';
+export type {default as UpdateZohoBooksCardProgramAccountParams} from './UpdateZohoBooksCardProgramAccountParams';
+export type {default as UpdateZohoBooksAutoSyncParams} from './UpdateZohoBooksAutoSyncParams';
+export type {default as UpdateZohoBooksAccountingMethodParams} from './UpdateZohoBooksAccountingMethodParams';
+export type {default as UpdateZohoBooksSyncReimbursedReportsParams} from './UpdateZohoBooksSyncReimbursedReportsParams';
+export type {default as UpdateZohoBooksBillPaymentAccountParams} from './UpdateZohoBooksBillPaymentAccountParams';
+export type {default as UpdateZohoBooksSyncExpensifyCardSettlementsParams} from './UpdateZohoBooksSyncExpensifyCardSettlementsParams';
+export type {default as UpdateZohoBooksSettlementsAccountParams} from './UpdateZohoBooksSettlementsAccountParams';
+export type {default as UpdateZohoBooksSyncTravelInvoicingSettlementsParams} from './UpdateZohoBooksSyncTravelInvoicingSettlementsParams';
+export type {default as UpdateZohoBooksTravelInvoicingSettlementsAccountParams} from './UpdateZohoBooksTravelInvoicingSettlementsAccountParams';
+export type {default as UpdateZohoBooksTravelInvoicingPayableAccountParams} from './UpdateZohoBooksTravelInvoicingPayableAccountParams';
export type {default as SyncPolicyToBusinessCentralParams} from './SyncPolicyToBusinessCentralParams';
export type {default as UpdateBusinessCentralCompanyParams} from './UpdateBusinessCentralCompanyParams';
export type {default as UpdateBusinessCentralCustomerMappingParams} from './UpdateBusinessCentralCustomerMappingParams';
diff --git a/src/libs/API/types.ts b/src/libs/API/types.ts
index 87983049317c..53b395c71dea 100644
--- a/src/libs/API/types.ts
+++ b/src/libs/API/types.ts
@@ -615,6 +615,25 @@ const WRITE_COMMANDS = {
UPDATE_CAMPFIRE_SYNC_TRAVEL_INVOICING_SETTLEMENTS: 'UpdateCampfireSyncTravelInvoicingSettlements',
UPDATE_CAMPFIRE_TRAVEL_INVOICING_SETTLEMENTS_ACCOUNT: 'UpdateCampfireTravelInvoicingSettlementsAccount',
UPDATE_CAMPFIRE_TRAVEL_INVOICING_PAYABLE_ACCOUNT: 'UpdateCampfireTravelInvoicingPayableAccount',
+ UPDATE_ZOHO_BOOKS_ORGANIZATION: 'UpdateZohoBooksOrganization',
+ UPDATE_ZOHO_BOOKS_FIELD_MAPPING: 'UpdateZohoBooksFieldMapping',
+ UPDATE_ZOHO_BOOKS_ENABLE_NEW_CATEGORIES: 'UpdateZohoBooksEnableNewCategories',
+ UPDATE_ZOHO_BOOKS_SYNC_TAX_RATES: 'UpdateZohoBooksSyncTaxRates',
+ UPDATE_ZOHO_BOOKS_EXPORTER: 'UpdateZohoBooksExporter',
+ UPDATE_ZOHO_BOOKS_EXPORT_DATE: 'UpdateZohoBooksExportDate',
+ UPDATE_ZOHO_BOOKS_DEFAULT_VENDOR: 'UpdateZohoBooksDefaultVendor',
+ UPDATE_ZOHO_BOOKS_CREDIT_CARD_ACCOUNT: 'UpdateZohoBooksCreditCardAccount',
+ UPDATE_ZOHO_BOOKS_EXPORT_TO_MULTIPLE_ACCOUNTS: 'UpdateZohoBooksExportToMultipleAccounts',
+ UPDATE_ZOHO_BOOKS_CARD_PROGRAM_ACCOUNT: 'UpdateZohoBooksCardProgramAccount',
+ UPDATE_ZOHO_BOOKS_AUTO_SYNC: 'UpdateZohoBooksAutoSync',
+ UPDATE_ZOHO_BOOKS_ACCOUNTING_METHOD: 'UpdateZohoBooksAccountingMethod',
+ UPDATE_ZOHO_BOOKS_SYNC_REIMBURSED_REPORTS: 'UpdateZohoBooksSyncReimbursedReports',
+ UPDATE_ZOHO_BOOKS_BILL_PAYMENT_ACCOUNT: 'UpdateZohoBooksBillPaymentAccount',
+ UPDATE_ZOHO_BOOKS_SYNC_EXPENSIFY_CARD_SETTLEMENTS: 'UpdateZohoBooksSyncExpensifyCardSettlements',
+ UPDATE_ZOHO_BOOKS_SETTLEMENTS_ACCOUNT: 'UpdateZohoBooksSettlementsAccount',
+ UPDATE_ZOHO_BOOKS_SYNC_TRAVEL_INVOICING_SETTLEMENTS: 'UpdateZohoBooksSyncTravelInvoicingSettlements',
+ UPDATE_ZOHO_BOOKS_TRAVEL_INVOICING_SETTLEMENTS_ACCOUNT: 'UpdateZohoBooksTravelInvoicingSettlementsAccount',
+ UPDATE_ZOHO_BOOKS_TRAVEL_INVOICING_PAYABLE_ACCOUNT: 'UpdateZohoBooksTravelInvoicingPayableAccount',
SET_PROMO_CODE: 'User_SetPromoCode',
REQUEST_TAX_EXEMPTION: 'RequestTaxExemption',
@@ -1343,6 +1362,25 @@ type WriteCommandParameters = {
[WRITE_COMMANDS.UPDATE_CAMPFIRE_SYNC_TRAVEL_INVOICING_SETTLEMENTS]: Parameters.UpdateCampfireSyncTravelInvoicingSettlementsParams;
[WRITE_COMMANDS.UPDATE_CAMPFIRE_TRAVEL_INVOICING_SETTLEMENTS_ACCOUNT]: Parameters.UpdateCampfireTravelInvoicingSettlementsAccountParams;
[WRITE_COMMANDS.UPDATE_CAMPFIRE_TRAVEL_INVOICING_PAYABLE_ACCOUNT]: Parameters.UpdateCampfireTravelInvoicingPayableAccountParams;
+ [WRITE_COMMANDS.UPDATE_ZOHO_BOOKS_ORGANIZATION]: Parameters.UpdateZohoBooksOrganizationParams;
+ [WRITE_COMMANDS.UPDATE_ZOHO_BOOKS_FIELD_MAPPING]: Parameters.UpdateZohoBooksFieldMappingParams;
+ [WRITE_COMMANDS.UPDATE_ZOHO_BOOKS_ENABLE_NEW_CATEGORIES]: Parameters.UpdateZohoBooksEnableNewCategoriesParams;
+ [WRITE_COMMANDS.UPDATE_ZOHO_BOOKS_SYNC_TAX_RATES]: Parameters.UpdateZohoBooksSyncTaxRatesParams;
+ [WRITE_COMMANDS.UPDATE_ZOHO_BOOKS_EXPORTER]: Parameters.UpdateZohoBooksExporterParams;
+ [WRITE_COMMANDS.UPDATE_ZOHO_BOOKS_EXPORT_DATE]: Parameters.UpdateZohoBooksExportDateParams;
+ [WRITE_COMMANDS.UPDATE_ZOHO_BOOKS_DEFAULT_VENDOR]: Parameters.UpdateZohoBooksDefaultVendorParams;
+ [WRITE_COMMANDS.UPDATE_ZOHO_BOOKS_CREDIT_CARD_ACCOUNT]: Parameters.UpdateZohoBooksCreditCardAccountParams;
+ [WRITE_COMMANDS.UPDATE_ZOHO_BOOKS_EXPORT_TO_MULTIPLE_ACCOUNTS]: Parameters.UpdateZohoBooksExportToMultipleAccountsParams;
+ [WRITE_COMMANDS.UPDATE_ZOHO_BOOKS_CARD_PROGRAM_ACCOUNT]: Parameters.UpdateZohoBooksCardProgramAccountParams;
+ [WRITE_COMMANDS.UPDATE_ZOHO_BOOKS_AUTO_SYNC]: Parameters.UpdateZohoBooksAutoSyncParams;
+ [WRITE_COMMANDS.UPDATE_ZOHO_BOOKS_ACCOUNTING_METHOD]: Parameters.UpdateZohoBooksAccountingMethodParams;
+ [WRITE_COMMANDS.UPDATE_ZOHO_BOOKS_SYNC_REIMBURSED_REPORTS]: Parameters.UpdateZohoBooksSyncReimbursedReportsParams;
+ [WRITE_COMMANDS.UPDATE_ZOHO_BOOKS_BILL_PAYMENT_ACCOUNT]: Parameters.UpdateZohoBooksBillPaymentAccountParams;
+ [WRITE_COMMANDS.UPDATE_ZOHO_BOOKS_SYNC_EXPENSIFY_CARD_SETTLEMENTS]: Parameters.UpdateZohoBooksSyncExpensifyCardSettlementsParams;
+ [WRITE_COMMANDS.UPDATE_ZOHO_BOOKS_SETTLEMENTS_ACCOUNT]: Parameters.UpdateZohoBooksSettlementsAccountParams;
+ [WRITE_COMMANDS.UPDATE_ZOHO_BOOKS_SYNC_TRAVEL_INVOICING_SETTLEMENTS]: Parameters.UpdateZohoBooksSyncTravelInvoicingSettlementsParams;
+ [WRITE_COMMANDS.UPDATE_ZOHO_BOOKS_TRAVEL_INVOICING_SETTLEMENTS_ACCOUNT]: Parameters.UpdateZohoBooksTravelInvoicingSettlementsAccountParams;
+ [WRITE_COMMANDS.UPDATE_ZOHO_BOOKS_TRAVEL_INVOICING_PAYABLE_ACCOUNT]: Parameters.UpdateZohoBooksTravelInvoicingPayableAccountParams;
[WRITE_COMMANDS.UPGRADE_TO_CORPORATE]: Parameters.UpgradeToCorporateParams;
[WRITE_COMMANDS.DOWNGRADE_TO_TEAM]: Parameters.DowngradeToTeamParams;
@@ -1562,6 +1600,8 @@ const READ_COMMANDS = {
SYNC_POLICY_TO_RILLET: 'SyncPolicyToRillet',
SYNC_POLICY_TO_DUALENTRY: 'SyncPolicyToDualEntry',
SYNC_POLICY_TO_CAMPFIRE: 'SyncPolicyToCampfire',
+ SYNC_POLICY_TO_ZOHO_BOOKS: 'SyncPolicyToZohoBooks',
+ CONNECT_POLICY_TO_ZOHO_BOOKS: 'ConnectPolicyToZohoBooks',
SYNC_POLICY_TO_BUSINESS_CENTRAL: 'SyncPolicyToBusinessCentral',
CONNECT_POLICY_TO_FINANCIAL_FORCE: 'ConnectPolicyToFinancialForce',
OPEN_REIMBURSEMENT_ACCOUNT_PAGE: 'OpenReimbursementAccountPage',
@@ -1684,6 +1724,8 @@ type ReadCommandParameters = {
[READ_COMMANDS.SYNC_POLICY_TO_RILLET]: Parameters.SyncPolicyToRilletParams;
[READ_COMMANDS.SYNC_POLICY_TO_DUALENTRY]: Parameters.SyncPolicyToDualEntryParams;
[READ_COMMANDS.SYNC_POLICY_TO_CAMPFIRE]: Parameters.SyncPolicyToCampfireParams;
+ [READ_COMMANDS.SYNC_POLICY_TO_ZOHO_BOOKS]: Parameters.SyncPolicyToZohoBooksParams;
+ [READ_COMMANDS.CONNECT_POLICY_TO_ZOHO_BOOKS]: Parameters.ConnectPolicyToZohoBooksParams;
[READ_COMMANDS.SYNC_POLICY_TO_BUSINESS_CENTRAL]: Parameters.SyncPolicyToBusinessCentralParams;
[READ_COMMANDS.OPEN_REIMBURSEMENT_ACCOUNT_PAGE]: Parameters.OpenReimbursementAccountPageParams;
[READ_COMMANDS.OPEN_WORKSPACE_VIEW]: Parameters.OpenWorkspaceViewParams;
diff --git a/src/libs/AccountingUtils.ts b/src/libs/AccountingUtils.ts
index af5c8662556e..bbf03d1bd4e5 100644
--- a/src/libs/AccountingUtils.ts
+++ b/src/libs/AccountingUtils.ts
@@ -23,6 +23,7 @@ const ROUTE_NAME_MAPPING = {
[CONST.POLICY.CONNECTIONS.ROUTE.MERGE_ATS]: CONST.POLICY.CONNECTIONS.NAME.MERGE_ATS,
[CONST.POLICY.CONNECTIONS.ROUTE.DUALENTRY]: CONST.POLICY.CONNECTIONS.NAME.DUALENTRY,
[CONST.POLICY.CONNECTIONS.ROUTE.CAMPFIRE]: CONST.POLICY.CONNECTIONS.NAME.CAMPFIRE,
+ [CONST.POLICY.CONNECTIONS.ROUTE.ZOHO_BOOKS]: CONST.POLICY.CONNECTIONS.NAME.ZOHO_BOOKS,
[CONST.POLICY.CONNECTIONS.ROUTE.BUSINESS_CENTRAL]: CONST.POLICY.CONNECTIONS.NAME.BUSINESS_CENTRAL,
};
@@ -40,6 +41,7 @@ const NAME_ROUTE_MAPPING = {
[CONST.POLICY.CONNECTIONS.NAME.MERGE_ATS]: CONST.POLICY.CONNECTIONS.ROUTE.MERGE_ATS,
[CONST.POLICY.CONNECTIONS.NAME.DUALENTRY]: CONST.POLICY.CONNECTIONS.ROUTE.DUALENTRY,
[CONST.POLICY.CONNECTIONS.NAME.CAMPFIRE]: CONST.POLICY.CONNECTIONS.ROUTE.CAMPFIRE,
+ [CONST.POLICY.CONNECTIONS.NAME.ZOHO_BOOKS]: CONST.POLICY.CONNECTIONS.ROUTE.ZOHO_BOOKS,
[CONST.POLICY.CONNECTIONS.NAME.BUSINESS_CENTRAL]: CONST.POLICY.CONNECTIONS.ROUTE.BUSINESS_CENTRAL,
};
diff --git a/src/libs/actions/connections/ZohoBooks.ts b/src/libs/actions/connections/ZohoBooks.ts
new file mode 100644
index 000000000000..aa99ab7dfa83
--- /dev/null
+++ b/src/libs/actions/connections/ZohoBooks.ts
@@ -0,0 +1,813 @@
+import {write} from '@libs/API';
+import type {
+ UpdateZohoBooksAccountingMethodParams,
+ UpdateZohoBooksAutoSyncParams,
+ UpdateZohoBooksBillPaymentAccountParams,
+ UpdateZohoBooksCardProgramAccountParams,
+ UpdateZohoBooksCreditCardAccountParams,
+ UpdateZohoBooksDefaultVendorParams,
+ UpdateZohoBooksEnableNewCategoriesParams,
+ UpdateZohoBooksExportDateParams,
+ UpdateZohoBooksExporterParams,
+ UpdateZohoBooksExportToMultipleAccountsParams,
+ UpdateZohoBooksFieldMappingParams,
+ UpdateZohoBooksOrganizationParams,
+ UpdateZohoBooksSettlementsAccountParams,
+ UpdateZohoBooksSyncExpensifyCardSettlementsParams,
+ UpdateZohoBooksSyncReimbursedReportsParams,
+ UpdateZohoBooksSyncTaxRatesParams,
+ UpdateZohoBooksSyncTravelInvoicingSettlementsParams,
+ UpdateZohoBooksTravelInvoicingPayableAccountParams,
+ UpdateZohoBooksTravelInvoicingSettlementsAccountParams,
+} from '@libs/API/parameters';
+import {READ_COMMANDS, WRITE_COMMANDS} from '@libs/API/types';
+import {getCommandURL} from '@libs/ApiUtils';
+import {getMicroSecondOnyxErrorWithTranslationKey} from '@libs/ErrorUtils';
+
+import CONST from '@src/CONST';
+import ONYXKEYS from '@src/ONYXKEYS';
+import type {ZohoBooksAutoSync, ZohoBooksCoding, ZohoBooksConnectionsConfig, ZohoBooksExport, ZohoBooksSync} from '@src/types/onyx/Policy';
+
+import type {OnyxUpdate} from 'react-native-onyx';
+import type {ValueOf} from 'type-fest';
+
+import Onyx from 'react-native-onyx';
+
+function getZohoBooksSetupLink(policyID: string) {
+ // Zoho Books authenticates with OAuth, so the connector opens this URL in the browser.
+ const params = new URLSearchParams({policyID});
+ const commandURL = getCommandURL({command: READ_COMMANDS.CONNECT_POLICY_TO_ZOHO_BOOKS, shouldSkipWebProxy: true});
+ return commandURL + params.toString();
+}
+
+function clearZohoBooksErrorField(policyID: string, fieldName: string) {
+ Onyx.merge(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`, {
+ connections: {
+ [CONST.POLICY.CONNECTIONS.NAME.ZOHO_BOOKS]: {
+ config: {errorFields: {[fieldName]: null}},
+ },
+ },
+ });
+}
+
+function prepareZohoBooksOnyxData(
+ policyID: string,
+ settingName: TSettingName,
+ settingValue: Partial,
+ oldSettingValue: Partial | null,
+) {
+ const optimisticData: Array> = [
+ {
+ onyxMethod: Onyx.METHOD.MERGE,
+ key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`,
+ value: {
+ connections: {
+ [CONST.POLICY.CONNECTIONS.NAME.ZOHO_BOOKS]: {
+ config: {
+ [settingName]: settingValue ?? null,
+ pendingFields: {
+ [settingName]: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE,
+ },
+ errorFields: {
+ [settingName]: null,
+ },
+ },
+ },
+ },
+ },
+ },
+ ];
+
+ const successData: Array> = [
+ {
+ onyxMethod: Onyx.METHOD.MERGE,
+ key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`,
+ value: {
+ connections: {
+ [CONST.POLICY.CONNECTIONS.NAME.ZOHO_BOOKS]: {
+ config: {
+ pendingFields: {
+ [settingName]: null,
+ },
+ },
+ },
+ },
+ },
+ },
+ ];
+
+ const failureData: Array> = [
+ {
+ onyxMethod: Onyx.METHOD.MERGE,
+ key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`,
+ value: {
+ connections: {
+ [CONST.POLICY.CONNECTIONS.NAME.ZOHO_BOOKS]: {
+ config: {
+ [settingName]: oldSettingValue ?? null,
+ pendingFields: {
+ [settingName]: null,
+ },
+ errorFields: {
+ [settingName]: getMicroSecondOnyxErrorWithTranslationKey('common.genericErrorMessage'),
+ },
+ },
+ },
+ },
+ },
+ },
+ ];
+
+ return {optimisticData, successData, failureData};
+}
+
+function prepareZohoBooksCodingOnyxData(
+ policyID: string,
+ settingName: TSettingName,
+ settingValue: Partial,
+ oldSettingValue: Partial | null,
+) {
+ const optimisticData: Array> = [
+ {
+ onyxMethod: Onyx.METHOD.MERGE,
+ key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`,
+ value: {
+ connections: {
+ [CONST.POLICY.CONNECTIONS.NAME.ZOHO_BOOKS]: {
+ config: {
+ coding: {
+ [settingName]: settingValue ?? null,
+ },
+ pendingFields: {
+ [settingName]: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE,
+ },
+ errorFields: {
+ [settingName]: null,
+ },
+ },
+ },
+ },
+ },
+ },
+ ];
+
+ const successData: Array> = [
+ {
+ onyxMethod: Onyx.METHOD.MERGE,
+ key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`,
+ value: {
+ connections: {
+ [CONST.POLICY.CONNECTIONS.NAME.ZOHO_BOOKS]: {
+ config: {
+ pendingFields: {
+ [settingName]: null,
+ },
+ },
+ },
+ },
+ },
+ },
+ ];
+
+ const failureData: Array> = [
+ {
+ onyxMethod: Onyx.METHOD.MERGE,
+ key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`,
+ value: {
+ connections: {
+ [CONST.POLICY.CONNECTIONS.NAME.ZOHO_BOOKS]: {
+ config: {
+ coding: {
+ [settingName]: oldSettingValue ?? null,
+ },
+ pendingFields: {
+ [settingName]: null,
+ },
+ errorFields: {
+ [settingName]: getMicroSecondOnyxErrorWithTranslationKey('common.genericErrorMessage'),
+ },
+ },
+ },
+ },
+ },
+ },
+ ];
+
+ return {optimisticData, successData, failureData};
+}
+
+function prepareZohoBooksFieldMappingOnyxData(
+ policyID: string,
+ fieldID: keyof NonNullable,
+ mapping: ValueOf>,
+ oldMapping: ValueOf> | null,
+) {
+ const fieldOfflineFeedbackKey = `${CONST.ZOHO_BOOKS_CONFIG.FIELD_MAPPING_PREFIX}${fieldID}`;
+
+ const optimisticData: Array> = [
+ {
+ onyxMethod: Onyx.METHOD.MERGE,
+ key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`,
+ value: {
+ connections: {
+ [CONST.POLICY.CONNECTIONS.NAME.ZOHO_BOOKS]: {
+ config: {
+ coding: {
+ fieldMappings: {
+ [fieldID]: mapping,
+ },
+ },
+ pendingFields: {
+ [fieldOfflineFeedbackKey]: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE,
+ },
+ errorFields: {
+ [fieldOfflineFeedbackKey]: null,
+ },
+ },
+ },
+ },
+ },
+ },
+ ];
+
+ const successData: Array> = [
+ {
+ onyxMethod: Onyx.METHOD.MERGE,
+ key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`,
+ value: {
+ connections: {
+ [CONST.POLICY.CONNECTIONS.NAME.ZOHO_BOOKS]: {
+ config: {
+ pendingFields: {
+ [fieldOfflineFeedbackKey]: null,
+ },
+ },
+ },
+ },
+ },
+ },
+ ];
+
+ const failureData: Array> = [
+ {
+ onyxMethod: Onyx.METHOD.MERGE,
+ key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`,
+ value: {
+ connections: {
+ [CONST.POLICY.CONNECTIONS.NAME.ZOHO_BOOKS]: {
+ config: {
+ coding: {
+ fieldMappings: {
+ [fieldID]: oldMapping ?? null,
+ },
+ },
+ pendingFields: {
+ [fieldOfflineFeedbackKey]: null,
+ },
+ errorFields: {
+ [fieldOfflineFeedbackKey]: getMicroSecondOnyxErrorWithTranslationKey('common.genericErrorMessage'),
+ },
+ },
+ },
+ },
+ },
+ },
+ ];
+
+ return {optimisticData, successData, failureData};
+}
+
+function prepareZohoBooksExportOnyxData(
+ policyID: string,
+ settingName: TSettingName,
+ settingValue: Partial,
+ oldSettingValue: Partial | null,
+) {
+ const optimisticData: Array> = [
+ {
+ onyxMethod: Onyx.METHOD.MERGE,
+ key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`,
+ value: {
+ connections: {
+ [CONST.POLICY.CONNECTIONS.NAME.ZOHO_BOOKS]: {
+ config: {
+ export: {
+ [settingName]: settingValue ?? null,
+ },
+ pendingFields: {
+ [settingName]: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE,
+ },
+ errorFields: {
+ [settingName]: null,
+ },
+ },
+ },
+ },
+ },
+ },
+ ];
+
+ const successData: Array> = [
+ {
+ onyxMethod: Onyx.METHOD.MERGE,
+ key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`,
+ value: {
+ connections: {
+ [CONST.POLICY.CONNECTIONS.NAME.ZOHO_BOOKS]: {
+ config: {
+ pendingFields: {
+ [settingName]: null,
+ },
+ },
+ },
+ },
+ },
+ },
+ ];
+
+ const failureData: Array> = [
+ {
+ onyxMethod: Onyx.METHOD.MERGE,
+ key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`,
+ value: {
+ connections: {
+ [CONST.POLICY.CONNECTIONS.NAME.ZOHO_BOOKS]: {
+ config: {
+ export: {
+ [settingName]: oldSettingValue ?? null,
+ },
+ pendingFields: {
+ [settingName]: null,
+ },
+ errorFields: {
+ [settingName]: getMicroSecondOnyxErrorWithTranslationKey('common.genericErrorMessage'),
+ },
+ },
+ },
+ },
+ },
+ },
+ ];
+
+ return {optimisticData, successData, failureData};
+}
+
+function prepareZohoBooksAutoSyncOnyxData(policyID: string, enabled: ZohoBooksAutoSync['enabled'], oldEnabled?: ZohoBooksAutoSync['enabled'] | null) {
+ const optimisticData: Array> = [
+ {
+ onyxMethod: Onyx.METHOD.MERGE,
+ key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`,
+ value: {
+ connections: {
+ [CONST.POLICY.CONNECTIONS.NAME.ZOHO_BOOKS]: {
+ config: {
+ autoSync: {
+ enabled,
+ },
+ pendingFields: {
+ [CONST.ZOHO_BOOKS_CONFIG.AUTO_SYNC]: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE,
+ },
+ errorFields: {
+ [CONST.ZOHO_BOOKS_CONFIG.AUTO_SYNC]: null,
+ },
+ },
+ },
+ },
+ },
+ },
+ ];
+
+ const successData: Array> = [
+ {
+ onyxMethod: Onyx.METHOD.MERGE,
+ key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`,
+ value: {
+ connections: {
+ [CONST.POLICY.CONNECTIONS.NAME.ZOHO_BOOKS]: {
+ config: {
+ pendingFields: {
+ [CONST.ZOHO_BOOKS_CONFIG.AUTO_SYNC]: null,
+ },
+ },
+ },
+ },
+ },
+ },
+ ];
+
+ const failureData: Array> = [
+ {
+ onyxMethod: Onyx.METHOD.MERGE,
+ key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`,
+ value: {
+ connections: {
+ [CONST.POLICY.CONNECTIONS.NAME.ZOHO_BOOKS]: {
+ config: {
+ autoSync: {
+ enabled: oldEnabled ?? null,
+ },
+ pendingFields: {
+ [CONST.ZOHO_BOOKS_CONFIG.AUTO_SYNC]: null,
+ },
+ errorFields: {
+ [CONST.ZOHO_BOOKS_CONFIG.AUTO_SYNC]: getMicroSecondOnyxErrorWithTranslationKey('common.genericErrorMessage'),
+ },
+ },
+ },
+ },
+ },
+ },
+ ];
+
+ return {optimisticData, successData, failureData};
+}
+
+function prepareZohoBooksSyncOnyxData(
+ policyID: string,
+ settingName: TSettingName,
+ settingValue: Partial,
+ oldSettingValue: Partial | null,
+) {
+ const optimisticData: Array> = [
+ {
+ onyxMethod: Onyx.METHOD.MERGE,
+ key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`,
+ value: {
+ connections: {
+ [CONST.POLICY.CONNECTIONS.NAME.ZOHO_BOOKS]: {
+ config: {
+ sync: {
+ [settingName]: settingValue ?? null,
+ },
+ pendingFields: {
+ [settingName]: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE,
+ },
+ errorFields: {
+ [settingName]: null,
+ },
+ },
+ },
+ },
+ },
+ },
+ ];
+
+ const successData: Array> = [
+ {
+ onyxMethod: Onyx.METHOD.MERGE,
+ key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`,
+ value: {
+ connections: {
+ [CONST.POLICY.CONNECTIONS.NAME.ZOHO_BOOKS]: {
+ config: {
+ pendingFields: {
+ [settingName]: null,
+ },
+ },
+ },
+ },
+ },
+ },
+ ];
+
+ const failureData: Array> = [
+ {
+ onyxMethod: Onyx.METHOD.MERGE,
+ key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`,
+ value: {
+ connections: {
+ [CONST.POLICY.CONNECTIONS.NAME.ZOHO_BOOKS]: {
+ config: {
+ sync: {
+ [settingName]: oldSettingValue ?? null,
+ },
+ pendingFields: {
+ [settingName]: null,
+ },
+ errorFields: {
+ [settingName]: getMicroSecondOnyxErrorWithTranslationKey('common.genericErrorMessage'),
+ },
+ },
+ },
+ },
+ },
+ },
+ ];
+
+ return {optimisticData, successData, failureData};
+}
+
+function prepareZohoBooksCardProgramAccountOnyxData(
+ policyID: string,
+ feedKey: keyof ZohoBooksExport['cardProgramAccounts'],
+ accountID: ValueOf,
+ oldAccountID?: ValueOf | null,
+) {
+ const cardProgramAccountOfflineFeedbackKey = `${CONST.ZOHO_BOOKS_CONFIG.CARD_PROGRAM_ACCOUNT_PREFIX}${feedKey}`;
+
+ const optimisticData: Array> = [
+ {
+ onyxMethod: Onyx.METHOD.MERGE,
+ key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`,
+ value: {
+ connections: {
+ [CONST.POLICY.CONNECTIONS.NAME.ZOHO_BOOKS]: {
+ config: {
+ export: {
+ cardProgramAccounts: {
+ // An empty accountID string implies clearing the custom account
+ [feedKey]: accountID || null,
+ },
+ },
+ pendingFields: {
+ [cardProgramAccountOfflineFeedbackKey]: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE,
+ },
+ errorFields: {
+ [cardProgramAccountOfflineFeedbackKey]: null,
+ },
+ },
+ },
+ },
+ },
+ },
+ ];
+
+ const successData: Array> = [
+ {
+ onyxMethod: Onyx.METHOD.MERGE,
+ key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`,
+ value: {
+ connections: {
+ [CONST.POLICY.CONNECTIONS.NAME.ZOHO_BOOKS]: {
+ config: {
+ pendingFields: {
+ [cardProgramAccountOfflineFeedbackKey]: null,
+ },
+ },
+ },
+ },
+ },
+ },
+ ];
+
+ const failureData: Array> = [
+ {
+ onyxMethod: Onyx.METHOD.MERGE,
+ key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`,
+ value: {
+ connections: {
+ [CONST.POLICY.CONNECTIONS.NAME.ZOHO_BOOKS]: {
+ config: {
+ export: {
+ cardProgramAccounts: {
+ [feedKey]: oldAccountID ?? null,
+ },
+ },
+ pendingFields: {
+ [cardProgramAccountOfflineFeedbackKey]: null,
+ },
+ errorFields: {
+ [cardProgramAccountOfflineFeedbackKey]: getMicroSecondOnyxErrorWithTranslationKey('common.genericErrorMessage'),
+ },
+ },
+ },
+ },
+ },
+ },
+ ];
+
+ return {optimisticData, successData, failureData};
+}
+
+function updateZohoBooksOrganization(policyID: string, organizationID: ZohoBooksConnectionsConfig['organizationID'], oldSubsidiaryID?: ZohoBooksConnectionsConfig['organizationID']) {
+ const onyxData = prepareZohoBooksOnyxData(policyID, CONST.ZOHO_BOOKS_CONFIG.ORGANIZATION_ID, organizationID, oldSubsidiaryID ?? null);
+ const params: UpdateZohoBooksOrganizationParams = {
+ policyID,
+ organizationID,
+ };
+ write(WRITE_COMMANDS.UPDATE_ZOHO_BOOKS_ORGANIZATION, params, onyxData);
+}
+
+function updateZohoBooksEnableNewCategories(policyID: string, enabled: ZohoBooksConnectionsConfig['enableNewCategories'], oldEnabled?: ZohoBooksConnectionsConfig['enableNewCategories']) {
+ const onyxData = prepareZohoBooksOnyxData(policyID, CONST.ZOHO_BOOKS_CONFIG.ENABLE_NEW_CATEGORIES, enabled, oldEnabled ?? null);
+ const parameters: UpdateZohoBooksEnableNewCategoriesParams = {
+ policyID,
+ enabled,
+ };
+ write(WRITE_COMMANDS.UPDATE_ZOHO_BOOKS_ENABLE_NEW_CATEGORIES, parameters, onyxData);
+}
+
+function updateZohoBooksSyncTaxRates(policyID: string, enabled: ZohoBooksCoding['syncTaxRates'], oldEnabled?: ZohoBooksCoding['syncTaxRates']) {
+ const onyxData = prepareZohoBooksCodingOnyxData(policyID, CONST.ZOHO_BOOKS_CONFIG.SYNC_TAX_RATES, enabled, oldEnabled ?? null);
+ const parameters: UpdateZohoBooksSyncTaxRatesParams = {
+ policyID,
+ enabled,
+ };
+ write(WRITE_COMMANDS.UPDATE_ZOHO_BOOKS_SYNC_TAX_RATES, parameters, onyxData);
+}
+
+function updateZohoBooksFieldMapping(
+ policyID: string,
+ fieldID: keyof NonNullable,
+ mapping: ValueOf>,
+ oldMapping?: ValueOf>,
+) {
+ const onyxData = prepareZohoBooksFieldMappingOnyxData(policyID, fieldID, mapping, oldMapping ?? null);
+ const parameters: UpdateZohoBooksFieldMappingParams = {
+ policyID,
+ fieldID,
+ mapping,
+ };
+ write(WRITE_COMMANDS.UPDATE_ZOHO_BOOKS_FIELD_MAPPING, parameters, onyxData);
+}
+
+function updateZohoBooksExporter(policyID: string, email: ZohoBooksExport['exporter'], oldEmail?: ZohoBooksExport['exporter']) {
+ const onyxData = prepareZohoBooksExportOnyxData(policyID, CONST.ZOHO_BOOKS_CONFIG.EXPORTER, email, oldEmail ?? null);
+ const parameters: UpdateZohoBooksExporterParams = {
+ policyID,
+ email,
+ };
+ write(WRITE_COMMANDS.UPDATE_ZOHO_BOOKS_EXPORTER, parameters, onyxData);
+}
+
+function updateZohoBooksExportDate(policyID: string, value: ZohoBooksExport['exportDate'], oldValue?: ZohoBooksExport['exportDate']) {
+ const onyxData = prepareZohoBooksExportOnyxData(policyID, CONST.ZOHO_BOOKS_CONFIG.EXPORT_DATE, value, oldValue ?? null);
+ const parameters: UpdateZohoBooksExportDateParams = {
+ policyID,
+ value,
+ };
+ write(WRITE_COMMANDS.UPDATE_ZOHO_BOOKS_EXPORT_DATE, parameters, onyxData);
+}
+
+function updateZohoBooksDefaultVendor(policyID: string, vendorID: ZohoBooksExport['defaultVendorID'], oldVendorID?: ZohoBooksExport['defaultVendorID']) {
+ const onyxData = prepareZohoBooksExportOnyxData(policyID, CONST.ZOHO_BOOKS_CONFIG.DEFAULT_VENDORID, vendorID, oldVendorID ?? null);
+ const parameters: UpdateZohoBooksDefaultVendorParams = {
+ policyID,
+ vendorID,
+ };
+ write(WRITE_COMMANDS.UPDATE_ZOHO_BOOKS_DEFAULT_VENDOR, parameters, onyxData);
+}
+
+function updateZohoBooksCreditCardAccount(policyID: string, creditCardAccountID: ZohoBooksExport['creditCardAccountID'], oldCreditCardAccountID?: ZohoBooksExport['creditCardAccountID']) {
+ const onyxData = prepareZohoBooksExportOnyxData(policyID, CONST.ZOHO_BOOKS_CONFIG.CREDIT_CARD_ACCOUNT_ID, creditCardAccountID, oldCreditCardAccountID ?? null);
+ const parameters: UpdateZohoBooksCreditCardAccountParams = {
+ policyID,
+ creditCardAccountID,
+ };
+ write(WRITE_COMMANDS.UPDATE_ZOHO_BOOKS_CREDIT_CARD_ACCOUNT, parameters, onyxData);
+}
+
+function updateZohoBooksAutoSync(policyID: string, enabled: ZohoBooksAutoSync['enabled'], oldEnabled?: ZohoBooksAutoSync['enabled']) {
+ const onyxData = prepareZohoBooksAutoSyncOnyxData(policyID, enabled, oldEnabled ?? null);
+ const parameters: UpdateZohoBooksAutoSyncParams = {
+ policyID,
+ enabled,
+ };
+ write(WRITE_COMMANDS.UPDATE_ZOHO_BOOKS_AUTO_SYNC, parameters, onyxData);
+}
+
+function updateZohoBooksAccountingMethod(policyID: string, accountingMethod: ZohoBooksExport['accountingMethod'], oldAccountingMethod?: ZohoBooksExport['accountingMethod']) {
+ const onyxData = prepareZohoBooksExportOnyxData(policyID, CONST.ZOHO_BOOKS_CONFIG.ACCOUNTING_METHOD, accountingMethod, oldAccountingMethod ?? null);
+ const parameters: UpdateZohoBooksAccountingMethodParams = {
+ policyID,
+ accountingMethod,
+ };
+ write(WRITE_COMMANDS.UPDATE_ZOHO_BOOKS_ACCOUNTING_METHOD, parameters, onyxData);
+}
+
+function updateZohoBooksSyncReimbursedReports(policyID: string, enabled: ZohoBooksSync['syncReimbursedReports'], oldEnabled?: ZohoBooksSync['syncReimbursedReports']) {
+ const onyxData = prepareZohoBooksSyncOnyxData(policyID, CONST.ZOHO_BOOKS_CONFIG.SYNC_REIMBURSED_REPORTS, enabled, oldEnabled ?? null);
+ const parameters: UpdateZohoBooksSyncReimbursedReportsParams = {
+ policyID,
+ enabled,
+ };
+ write(WRITE_COMMANDS.UPDATE_ZOHO_BOOKS_SYNC_REIMBURSED_REPORTS, parameters, onyxData);
+}
+
+function updateZohoBooksBillPaymentAccount(policyID: string, billPaymentAccountID: ZohoBooksSync['billPaymentAccountID'], oldBillPaymentAccountID?: ZohoBooksSync['billPaymentAccountID']) {
+ const onyxData = prepareZohoBooksSyncOnyxData(policyID, CONST.ZOHO_BOOKS_CONFIG.BILL_PAYMENT_ACCOUNT_ID, billPaymentAccountID, oldBillPaymentAccountID ?? null);
+ const parameters: UpdateZohoBooksBillPaymentAccountParams = {
+ policyID,
+ billPaymentAccountID,
+ };
+ write(WRITE_COMMANDS.UPDATE_ZOHO_BOOKS_BILL_PAYMENT_ACCOUNT, parameters, onyxData);
+}
+
+function updateZohoBooksSyncExpensifyCardSettlements(policyID: string, enabled: ZohoBooksSync['syncExpensifyCardSettlements'], oldEnabled?: ZohoBooksSync['syncExpensifyCardSettlements']) {
+ const onyxData = prepareZohoBooksSyncOnyxData(policyID, CONST.ZOHO_BOOKS_CONFIG.SYNC_EXPENSIFY_CARD_SETTLEMENTS, enabled, oldEnabled ?? null);
+ const parameters: UpdateZohoBooksSyncExpensifyCardSettlementsParams = {
+ policyID,
+ enabled,
+ };
+ write(WRITE_COMMANDS.UPDATE_ZOHO_BOOKS_SYNC_EXPENSIFY_CARD_SETTLEMENTS, parameters, onyxData);
+}
+
+function updateZohoBooksSettlementsAccount(
+ policyID: string,
+ settlementsBankAccountID: ZohoBooksSync['settlementsBankAccountID'],
+ oldSettlementsBankAccountID?: ZohoBooksSync['settlementsBankAccountID'],
+) {
+ const onyxData = prepareZohoBooksSyncOnyxData(policyID, CONST.ZOHO_BOOKS_CONFIG.SETTLEMENTS_BANK_ACCOUNT_ID, settlementsBankAccountID, oldSettlementsBankAccountID ?? null);
+ const parameters: UpdateZohoBooksSettlementsAccountParams = {
+ policyID,
+ settlementsBankAccountID,
+ };
+ write(WRITE_COMMANDS.UPDATE_ZOHO_BOOKS_SETTLEMENTS_ACCOUNT, parameters, onyxData);
+}
+
+function updateZohoBooksSyncTravelInvoicingSettlements(
+ policyID: string,
+ enabled: ZohoBooksSync['syncTravelInvoicingSettlements'],
+ oldEnabled?: ZohoBooksSync['syncTravelInvoicingSettlements'],
+) {
+ const onyxData = prepareZohoBooksSyncOnyxData(policyID, CONST.ZOHO_BOOKS_CONFIG.SYNC_TRAVEL_BILLING_SETTLEMENTS, enabled, oldEnabled ?? null);
+ const parameters: UpdateZohoBooksSyncTravelInvoicingSettlementsParams = {
+ policyID,
+ enabled,
+ };
+ write(WRITE_COMMANDS.UPDATE_ZOHO_BOOKS_SYNC_TRAVEL_INVOICING_SETTLEMENTS, parameters, onyxData);
+}
+
+function updateZohoBooksTravelInvoicingSettlementsAccount(
+ policyID: string,
+ travelInvoicingSettlementsBankAccountID: ZohoBooksSync['travelInvoicingSettlementsBankAccountID'],
+ oldTravelInvoicingSettlementsBankAccountID?: ZohoBooksSync['travelInvoicingSettlementsBankAccountID'],
+) {
+ const onyxData = prepareZohoBooksSyncOnyxData(
+ policyID,
+ CONST.ZOHO_BOOKS_CONFIG.TRAVEL_BILLING_SETTLEMENTS_BANK_ACCOUNT_ID,
+ travelInvoicingSettlementsBankAccountID,
+ oldTravelInvoicingSettlementsBankAccountID ?? null,
+ );
+ const parameters: UpdateZohoBooksTravelInvoicingSettlementsAccountParams = {
+ policyID,
+ travelInvoicingSettlementsBankAccountID,
+ };
+ write(WRITE_COMMANDS.UPDATE_ZOHO_BOOKS_TRAVEL_INVOICING_SETTLEMENTS_ACCOUNT, parameters, onyxData);
+}
+
+function updateZohoBooksTravelInvoicingPayableAccount(
+ policyID: string,
+ travelInvoicingPayableAccountID: ZohoBooksExport['travelInvoicingPayableAccountID'],
+ oldTravelInvoicingPayableAccountID?: ZohoBooksExport['travelInvoicingPayableAccountID'],
+) {
+ const onyxData = prepareZohoBooksExportOnyxData(
+ policyID,
+ CONST.ZOHO_BOOKS_CONFIG.TRAVEL_BILLING_PAYABLE_ACCOUNT_ID,
+ travelInvoicingPayableAccountID,
+ oldTravelInvoicingPayableAccountID ?? null,
+ );
+ const parameters: UpdateZohoBooksTravelInvoicingPayableAccountParams = {
+ policyID,
+ travelInvoicingPayableAccountID,
+ };
+ write(WRITE_COMMANDS.UPDATE_ZOHO_BOOKS_TRAVEL_INVOICING_PAYABLE_ACCOUNT, parameters, onyxData);
+}
+
+function updateZohoBooksExportToMultipleAccounts(policyID: string, enabled: ZohoBooksExport['exportToMultipleAccounts'], oldEnabled?: ZohoBooksExport['exportToMultipleAccounts']) {
+ const onyxData = prepareZohoBooksExportOnyxData(policyID, CONST.ZOHO_BOOKS_CONFIG.EXPORT_TO_MULTIPLE_ACCOUNTS, enabled, oldEnabled ?? null);
+ const parameters: UpdateZohoBooksExportToMultipleAccountsParams = {
+ policyID,
+ enabled,
+ };
+ write(WRITE_COMMANDS.UPDATE_ZOHO_BOOKS_EXPORT_TO_MULTIPLE_ACCOUNTS, parameters, onyxData);
+}
+
+function updateZohoBooksCardProgramAccount(
+ policyID: string,
+ feedKey: keyof ZohoBooksExport['cardProgramAccounts'],
+ cardProgramAccountID: ValueOf,
+ oldCardProgramAccountID?: ValueOf,
+) {
+ const onyxData = prepareZohoBooksCardProgramAccountOnyxData(policyID, feedKey, cardProgramAccountID, oldCardProgramAccountID ?? null);
+ const parameters: UpdateZohoBooksCardProgramAccountParams = {
+ policyID,
+ feedKey,
+ cardProgramAccountID,
+ };
+ write(WRITE_COMMANDS.UPDATE_ZOHO_BOOKS_CARD_PROGRAM_ACCOUNT, parameters, onyxData);
+}
+
+export {
+ getZohoBooksSetupLink,
+ clearZohoBooksErrorField,
+ updateZohoBooksOrganization,
+ updateZohoBooksEnableNewCategories,
+ updateZohoBooksSyncTaxRates,
+ updateZohoBooksFieldMapping,
+ updateZohoBooksExporter,
+ updateZohoBooksExportDate,
+ updateZohoBooksDefaultVendor,
+ updateZohoBooksCreditCardAccount,
+ updateZohoBooksAutoSync,
+ updateZohoBooksAccountingMethod,
+ updateZohoBooksSyncReimbursedReports,
+ updateZohoBooksBillPaymentAccount,
+ updateZohoBooksSyncExpensifyCardSettlements,
+ updateZohoBooksSettlementsAccount,
+ updateZohoBooksSyncTravelInvoicingSettlements,
+ updateZohoBooksTravelInvoicingSettlementsAccount,
+ updateZohoBooksTravelInvoicingPayableAccount,
+ updateZohoBooksExportToMultipleAccounts,
+ updateZohoBooksCardProgramAccount,
+};
diff --git a/src/libs/actions/connections/index.ts b/src/libs/actions/connections/index.ts
index 97901dda98e5..244550066811 100644
--- a/src/libs/actions/connections/index.ts
+++ b/src/libs/actions/connections/index.ts
@@ -163,6 +163,9 @@ function getSyncConnectionParameters(connectionName: PolicyConnectionName) {
case CONST.POLICY.CONNECTIONS.NAME.CAMPFIRE: {
return {readCommand: READ_COMMANDS.SYNC_POLICY_TO_CAMPFIRE, stageInProgress: CONST.POLICY.CONNECTIONS.SYNC_STAGE_NAME.CAMPFIRE_SYNC_CONNECTION};
}
+ case CONST.POLICY.CONNECTIONS.NAME.ZOHO_BOOKS: {
+ return {readCommand: READ_COMMANDS.SYNC_POLICY_TO_ZOHO_BOOKS, stageInProgress: CONST.POLICY.CONNECTIONS.SYNC_STAGE_NAME.ZOHO_BOOKS_SYNC_CONNECTION};
+ }
case CONST.POLICY.CONNECTIONS.NAME.BUSINESS_CENTRAL: {
return {
readCommand: READ_COMMANDS.SYNC_POLICY_TO_BUSINESS_CENTRAL,
diff --git a/src/types/onyx/Policy.ts b/src/types/onyx/Policy.ts
index 9ae952b123ec..325652c9a510 100644
--- a/src/types/onyx/Policy.ts
+++ b/src/types/onyx/Policy.ts
@@ -1,3 +1,4 @@
+/* eslint-disable max-lines -- Accounting connection types stay together in the policy type. */
import type MergeSyncResult from '@libs/API/MergeSyncResult';
import type CONST from '@src/CONST';
@@ -2511,6 +2512,309 @@ type CampfireConnectionsConfig = OnyxCommon.OnyxValueWithOfflineFeedback<
CampfireCodingOfflineFeedbackKeys | CampfireExportOfflineFeedbackKeys | keyof CampfireAutoSync | keyof CampfireSync
>;
+/**
+ * An organization configured in Zoho Books.
+ */
+type ZohoBooksOrganization = {
+ /** Unique identifier of the organization. */
+ id: string;
+
+ /** Name of the organization. */
+ name: string;
+
+ /** Currency associated with the organization. */
+ currency: string;
+
+ /** Multi-location organizations are not supported. The organization selector uses this to show an error. */
+ isMultiLocation?: boolean;
+};
+
+/**
+ * Available account types.
+ */
+type ZohoBooksAccountType = ValueOf;
+
+/**
+ * Account retrieved from Zoho Books.
+ */
+type ZohoBooksAccount = {
+ /** Unique identifier of the account. */
+ id: string;
+
+ /** Account number. */
+ number?: string;
+
+ /** Name of the account. */
+ name: string;
+
+ /** Zoho Books account_type. */
+ accountType: ZohoBooksAccountType;
+
+ /** Currency associated with the account. */
+ currency?: string;
+
+ /** Whether the account is active. */
+ isActive: boolean;
+};
+
+/**
+ * Reporting tag retrieved from Zoho Books.
+ */
+type ZohoBooksReportingTag = {
+ /** Unique identifier of the reporting tag. */
+ id: string;
+
+ /** Name of the reporting tag. */
+ name: string;
+};
+
+/**
+ * Available vendor types.
+ */
+type ZohoBooksVendorType = ValueOf;
+
+/**
+ * Vendor retrieved from Zoho Books.
+ */
+type ZohoBooksVendor = {
+ /** Unique identifier of the vendor. */
+ id: string;
+
+ /** Name of the vendor. */
+ name: string;
+
+ /** Email address associated with the vendor. */
+ email?: string;
+
+ /** Type of the vendor. */
+ vendorType: ZohoBooksVendorType;
+
+ /** Whether the vendor is active. */
+ isActive: boolean;
+};
+
+/**
+ * Tax rate line retrieved from Zoho Books.
+ */
+type ZohoBooksTaxRateLine = {
+ /** Value of the tax rate. */
+ rate: string;
+
+ /** Tax account ID. */
+ taxAccountID?: string;
+
+ /** Whether to use expense account itself instead of taxAccountID */
+ useExpenseAccount: boolean;
+};
+
+/**
+ * Tax rate retrieved from Zoho Books.
+ */
+type ZohoBooksTaxRate = {
+ /** Unique identifier of the tax rate. */
+ id: string;
+
+ /** Name of the tax rate. */
+ name: string;
+
+ /** Value of the tax rate. */
+ rate: string;
+
+ /** Code used to identify the tax rate. */
+ code?: string;
+
+ /**
+ * A rate is made of lines, and each line says where its share of the tax goes:
+ * a named tax account, or the expense account itself when useExpenseAccount is set.
+ */
+ lines: ZohoBooksTaxRateLine[];
+};
+
+/**
+ * Connection data retrieved from Zoho Books.
+ */
+type ZohoBooksConnectionData = {
+ /** Collection of eligible organizations in Zoho Books. */
+ organizations?: ZohoBooksOrganization[];
+
+ /** Accounts available in Zoho Books. */
+ accounts?: ZohoBooksAccount[];
+
+ /** Reporting tags available in Zoho Books. */
+ reportingTags?: ZohoBooksReportingTag[];
+
+ /** Vendors available in Zoho Books. */
+ vendors?: ZohoBooksVendor[];
+
+ /** Mapping of settlement identifiers to their corresponding journal entry identifiers. */
+ settlementJournalEntryIDs?: Record;
+
+ /** Mapping of travel settlement identifiers to their corresponding journal entry identifiers. */
+ travelSettlementJournalEntryIDs?: Record;
+
+ /** Entry identifier from which settlement synchronization should start. */
+ settlementSyncStartEntryID?: number;
+
+ /** Entry identifier from which travel settlement synchronization should start. */
+ travelSettlementSyncStartEntryID?: number;
+
+ /** Tax rates available in Zoho Books. */
+ taxRates?: ZohoBooksTaxRate[];
+};
+
+/**
+ * Coding configuration used when exporting data to Zoho Books.
+ */
+type ZohoBooksCoding = {
+ /**
+ * Mapping of Zoho Books reporting tag IDs to their configured mapping behavior.
+ */
+ fieldMappings?: Record>;
+
+ /** Whether tax rates should be synchronized from Zoho Books. */
+ syncTaxRates: boolean;
+};
+
+/** Offline feedback key for field mapping */
+type ZohoBooksCodingFieldMappingsOfflineFeedbackKey = `${typeof CONST.ZOHO_BOOKS_CONFIG.FIELD_MAPPING_PREFIX}${string}`;
+
+/**
+ * Offline feedback keys for `ZohoBooksCoding`
+ */
+type ZohoBooksCodingOfflineFeedbackKeys = keyof Omit | ZohoBooksCodingFieldMappingsOfflineFeedbackKey;
+
+/**
+ * Available dates that can be used as the export date.
+ */
+type ZohoBooksExportDate = ValueOf;
+
+/**
+ * Export strategy for reimbursable expenses.
+ */
+type ZohoBooksExportReimbursable = ValueOf;
+
+/**
+ * Export strategy for company card expenses.
+ */
+type ZohoBooksExportNonReimbursable = ValueOf;
+
+/**
+ * Export configuration for sending accounting data to Zoho Books.
+ */
+type ZohoBooksExport = {
+ /** Identifier of the export implementation to use. */
+ exporter: string;
+
+ /** Date source used when generating exported transactions. */
+ exportDate: ZohoBooksExportDate;
+
+ /** Export behavior for reimbursable expenses. */
+ reimbursable: ZohoBooksExportReimbursable;
+
+ /** Export behavior for company card expenses. */
+ nonReimbursable: ZohoBooksExportNonReimbursable;
+
+ /** Account used when exporting company card expenses. */
+ creditCardAccountID: string;
+
+ /**
+ * Whether card transactions should be exported to multiple
+ * accounts based on card program mappings.
+ */
+ exportToMultipleAccounts: boolean;
+
+ /**
+ * Mapping of card program identifiers to account codes.
+ */
+ cardProgramAccounts: Record;
+
+ /** Default vendor used when exporting transactions. */
+ defaultVendorID: string;
+
+ /** Payable account used when exporting travel billings. */
+ travelInvoicingPayableAccountID: string;
+
+ /** Accounting method used during export. */
+ accountingMethod: ValueOf;
+};
+
+/** Offline feedback key for card program account */
+type ZohoBooksExportCardProgramAccountsOfflineFeedbackKey = `${typeof CONST.ZOHO_BOOKS_CONFIG.CARD_PROGRAM_ACCOUNT_PREFIX}${string}`;
+
+/**
+ * Offline feedback keys for `ZohoBooksExport`
+ */
+type ZohoBooksExportOfflineFeedbackKeys = keyof Omit | ZohoBooksExportCardProgramAccountsOfflineFeedbackKey;
+
+/**
+ * Automatic synchronization settings for Zoho Books.
+ */
+type ZohoBooksAutoSync = {
+ /** Whether automatic synchronization is enabled. */
+ enabled: boolean;
+
+ /** Unique identifier of the automatic synchronization job. */
+ jobID?: string | null;
+};
+
+/**
+ * Synchronization settings for importing and updating data in Zoho Books.
+ */
+type ZohoBooksSync = {
+ /** Whether reimbursed expense reports should be synchronized. */
+ syncReimbursedReports: boolean;
+
+ /** Account code used for bill payment transactions. */
+ billPaymentAccountID: string;
+
+ /** Whether Expensify Card settlement transactions should be synchronized. */
+ syncExpensifyCardSettlements: boolean;
+
+ /** Bank account used for Expensify Card settlements. */
+ settlementsBankAccountID: string;
+
+ /** Whether travel billing settlement transactions should be synchronized. */
+ syncTravelInvoicingSettlements: boolean;
+
+ /** Bank account used for travel billing settlements. */
+ travelInvoicingSettlementsBankAccountID: string;
+};
+
+/**
+ * Connection config for Zoho Books.
+ */
+type ZohoBooksConnectionsConfig = OnyxCommon.OnyxValueWithOfflineFeedback<
+ {
+ /** The internalID of the selected organization in Zoho Books */
+ organizationID: string;
+
+ /** Whether the connection has been configured */
+ isConfigured: boolean;
+
+ /** Whether to enable a new Expense Category into Expensify */
+ enableNewCategories: boolean;
+
+ /** Coding settings */
+ coding?: ZohoBooksCoding;
+
+ /** Export settings */
+ export?: ZohoBooksExport;
+
+ /** Auto-sync settings */
+ autoSync?: ZohoBooksAutoSync;
+
+ /** Sync settings */
+ sync?: ZohoBooksSync;
+
+ /** Collection of errors coming from BE */
+ errors?: OnyxCommon.Errors;
+
+ /** Collection of form field errors */
+ errorFields?: OnyxCommon.ErrorFields;
+ },
+ ZohoBooksCodingOfflineFeedbackKeys | ZohoBooksExportOfflineFeedbackKeys | keyof ZohoBooksAutoSync | keyof ZohoBooksSync
+>;
+
/**
* A company (legal entity) reachable with the Business Central connection's credentials.
*/
@@ -3041,6 +3345,9 @@ type Connections = {
/** Campfire integration connection */
[CONST.POLICY.CONNECTIONS.NAME.CAMPFIRE]: Connection;
+ /** Zoho Books integration connection */
+ [CONST.POLICY.CONNECTIONS.NAME.ZOHO_BOOKS]: Connection;
+
/** Business Central integration connection */
[CONST.POLICY.CONNECTIONS.NAME.BUSINESS_CENTRAL]: Connection;
@@ -3912,9 +4219,19 @@ export type {
CampfireExport,
CampfireAutoSync,
CampfireSync,
+ ZohoBooksExportDate,
+ ZohoBooksVendor,
+ ZohoBooksAccount,
BusinessCentralCompany,
BusinessCentralCoding,
BusinessCentralCustomerMappings,
BusinessCentralExport,
BusinessCentralCodingOfflineFeedbackKeys,
};
+
+/**
+ * The Zoho Books action module is the only importer of these config types, and Knip ignores that module until workspace screens import it.
+ *
+ * @public
+ */
+export type {ZohoBooksAutoSync, ZohoBooksCoding, ZohoBooksConnectionsConfig, ZohoBooksExport, ZohoBooksSync};