diff --git a/assets/images/simple-illustrations/simple-illustration__receipt.svg b/assets/images/simple-illustrations/simple-illustration__receipt.svg new file mode 100644 index 000000000000..b241dd2ea501 --- /dev/null +++ b/assets/images/simple-illustrations/simple-illustration__receipt.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/src/CONST/index.ts b/src/CONST/index.ts index 332cc0d5ccf1..8838e8ceb6c0 100755 --- a/src/CONST/index.ts +++ b/src/CONST/index.ts @@ -677,6 +677,7 @@ const CONST = { EUR_BILLING: 'eurBilling', MANUAL_DISTANCE: 'manualDistance', VACATION_DELEGATE: 'vacationDelegate', + UBER_FOR_BUSINESS: 'uberForBusiness', }, BUTTON_STATES: { DEFAULT: 'default', @@ -2911,6 +2912,7 @@ const CONST = { ARE_WORKFLOWS_ENABLED: 'areWorkflowsEnabled', ARE_REPORT_FIELDS_ENABLED: 'areReportFieldsEnabled', ARE_CONNECTIONS_ENABLED: 'areConnectionsEnabled', + ARE_RECEIPT_PARTNERS_ENABLED: 'areReceiptPartnersEnabled', ARE_COMPANY_CARDS_ENABLED: 'areCompanyCardsEnabled', ARE_EXPENSIFY_CARDS_ENABLED: 'areExpensifyCardsEnabled', ARE_INVOICES_ENABLED: 'areInvoicesEnabled', diff --git a/src/SCREENS.ts b/src/SCREENS.ts index 6e05d7a0fcfa..7ad1e49b4fda 100644 --- a/src/SCREENS.ts +++ b/src/SCREENS.ts @@ -623,6 +623,7 @@ const SCREENS = { UPGRADE: 'Workspace_Upgrade', DOWNGRADE: 'Workspace_Downgrade', PAY_AND_DOWNGRADE: 'Workspace_Pay_And_Downgrade', + RECEIPT_PARTNERS: 'Workspace_Receipt_Partners', RULES: 'Policy_Rules', RULES_CUSTOM_NAME: 'Rules_Custom_Name', RULES_AUTO_APPROVE_REPORTS_UNDER: 'Rules_Auto_Approve_Reports_Under', diff --git a/src/components/Icon/Illustrations.ts b/src/components/Icon/Illustrations.ts index 81b511cce86f..11c406987d97 100644 --- a/src/components/Icon/Illustrations.ts +++ b/src/components/Icon/Illustrations.ts @@ -135,6 +135,7 @@ import RealtimeReport from '@assets/images/simple-illustrations/simple-illustrat import ReceiptEnvelope from '@assets/images/simple-illustrations/simple-illustration__receipt-envelope.svg'; import ReceiptLocationMarker from '@assets/images/simple-illustrations/simple-illustration__receipt-location-marker.svg'; import ReceiptWrangler from '@assets/images/simple-illustrations/simple-illustration__receipt-wrangler.svg'; +import ReceiptPartners from '@assets/images/simple-illustrations/simple-illustration__receipt.svg'; import ReceiptUpload from '@assets/images/simple-illustrations/simple-illustration__receiptupload.svg'; import ReportReceipt from '@assets/images/simple-illustrations/simple-illustration__report-receipt.svg'; import Rules from '@assets/images/simple-illustrations/simple-illustration__rules.svg'; @@ -313,6 +314,7 @@ export { ChaseCompanyCardDetailLarge, CitibankCompanyCardDetailLarge, MasterCardCompanyCardDetailLarge, + ReceiptPartners, StripeCompanyCardDetailLarge, VisaCompanyCardDetailLarge, WellsFargoCompanyCardDetailLarge, diff --git a/src/languages/de.ts b/src/languages/de.ts index ed6c1f598675..c5a315a7cd55 100644 --- a/src/languages/de.ts +++ b/src/languages/de.ts @@ -3391,6 +3391,7 @@ const translations = { travel: 'Reisen', members: 'Mitglieder', accounting: 'Buchhaltung', + receiptPartners: 'Beleg-Partner', rules: 'Regeln', displayedAs: 'Angezeigt als', plan: 'Plan', @@ -4603,12 +4604,21 @@ const translations = { title: 'Buchhaltung', subtitle: 'Synchronisieren Sie Ihren Kontenplan und mehr.', }, + receiptPartners: { + title: 'Beleg-Partner', + subtitle: 'Automatischer Import von Belegen.', + }, connectionsWarningModal: { featureEnabledTitle: 'Nicht so schnell...', featureEnabledText: 'Um diese Funktion zu aktivieren oder zu deaktivieren, müssen Sie Ihre Buchhaltungsimporteinstellungen ändern.', disconnectText: 'Um die Buchhaltung zu deaktivieren, müssen Sie Ihre Buchhaltungsverbindung von Ihrem Arbeitsbereich trennen.', manageSettings: 'Einstellungen verwalten', }, + receiptPartnersWarningModal: { + featureEnabledTitle: 'Uber trennen', + disconnectText: 'Um diese Funktion zu deaktivieren, trennen Sie bitte zuerst die Uber for Business Integration.', + confirmText: 'Verstanden', + }, workflowWarningModal: { featureEnabledTitle: 'Nicht so schnell...', featureEnabledText: diff --git a/src/languages/en.ts b/src/languages/en.ts index ef7b9e4908b5..5f71b343b02f 100755 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -3384,6 +3384,7 @@ const translations = { travel: 'Travel', members: 'Members', accounting: 'Accounting', + receiptPartners: 'Receipt partners', rules: 'Rules', displayedAs: 'Displayed as', plan: 'Plan', @@ -4582,12 +4583,21 @@ const translations = { title: 'Accounting', subtitle: 'Sync your chart of accounts and more.', }, + receiptPartners: { + title: 'Receipt partners', + subtitle: 'Automatically import receipts.', + }, connectionsWarningModal: { featureEnabledTitle: 'Not so fast...', featureEnabledText: "To enable or disable this feature, you'll need to change your accounting import settings.", disconnectText: "To disable accounting, you'll need to disconnect your accounting connection from your workspace.", manageSettings: 'Manage settings', }, + receiptPartnersWarningModal: { + featureEnabledTitle: 'Disconnect Uber', + disconnectText: 'To disable this feature, please disconnect the Uber for Business integration first.', + confirmText: 'Got it', + }, workflowWarningModal: { featureEnabledTitle: 'Not so fast...', featureEnabledText: diff --git a/src/languages/es.ts b/src/languages/es.ts index e8f9f1bf89eb..80ace7626c20 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -3375,6 +3375,7 @@ const translations = { travel: 'Viajes', members: 'Miembros', accounting: 'Contabilidad', + receiptPartners: 'Socios de recibos', rules: 'Reglas', plan: 'Plan', profile: 'Resumen', @@ -4596,12 +4597,21 @@ const translations = { title: 'Contabilidad', subtitle: 'Sincroniza tu plan de cuentas y otras opciones.', }, + receiptPartners: { + title: 'Socios de recibos', + subtitle: 'Importación automática de recibos.', + }, connectionsWarningModal: { featureEnabledTitle: 'No tan rápido...', featureEnabledText: 'Para activar o desactivar esta función, cambia la configuración de importación contable.', disconnectText: 'Para desactivar la contabilidad, desconecta tu conexión contable del espacio de trabajo.', manageSettings: 'Gestionar la configuración', }, + receiptPartnersWarningModal: { + featureEnabledTitle: 'Desconectar Uber', + disconnectText: 'Para desactivar esta función, desconecta primero la integración de Uber for Business.', + confirmText: 'Entendido', + }, workflowWarningModal: { featureEnabledTitle: 'No tan rápido...', featureEnabledText: diff --git a/src/languages/fr.ts b/src/languages/fr.ts index a5fc1643ff78..b01d66e4bc2b 100644 --- a/src/languages/fr.ts +++ b/src/languages/fr.ts @@ -3399,6 +3399,7 @@ const translations = { travel: 'Voyage', members: 'Membres', accounting: 'Comptabilité', + receiptPartners: 'Partenaires de reçus', rules: 'Règles', displayedAs: 'Affiché comme', plan: 'Planification', @@ -4619,12 +4620,21 @@ const translations = { title: 'Comptabilité', subtitle: 'Synchronisez votre plan comptable et plus encore.', }, + receiptPartners: { + title: 'Partenaires de reçus', + subtitle: 'Importer automatiquement les reçus.', + }, connectionsWarningModal: { featureEnabledTitle: 'Pas si vite...', featureEnabledText: "Pour activer ou désactiver cette fonctionnalité, vous devrez modifier vos paramètres d'importation comptable.", disconnectText: 'Pour désactiver la comptabilité, vous devrez déconnecter votre connexion comptable de votre espace de travail.', manageSettings: 'Gérer les paramètres', }, + receiptPartnersWarningModal: { + featureEnabledTitle: 'Déconnecter Uber', + disconnectText: "Pour désactiver cette fonctionnalité, veuillez d'abord déconnecter l'intégration Uber for Business.", + confirmText: 'Compris', + }, workflowWarningModal: { featureEnabledTitle: 'Pas si vite...', featureEnabledText: diff --git a/src/languages/it.ts b/src/languages/it.ts index 1371ec2a2989..cfdffbfbe8c4 100644 --- a/src/languages/it.ts +++ b/src/languages/it.ts @@ -3404,6 +3404,7 @@ const translations = { travel: 'Viaggio', members: 'Membri', accounting: 'Contabilità', + receiptPartners: 'Partner ricevute', rules: 'Regole', displayedAs: 'Visualizzato come', plan: 'Piano', @@ -4618,12 +4619,21 @@ const translations = { title: 'Contabilità', subtitle: 'Sincronizza il tuo piano dei conti e altro ancora.', }, + receiptPartners: { + title: 'Partner ricevute', + subtitle: 'Importa automaticamente le ricevute.', + }, connectionsWarningModal: { featureEnabledTitle: 'Non così in fretta...', featureEnabledText: 'Per abilitare o disabilitare questa funzione, dovrai modificare le impostazioni di importazione contabile.', disconnectText: 'Per disabilitare la contabilità, dovrai disconnettere la tua connessione contabile dal tuo spazio di lavoro.', manageSettings: 'Gestisci impostazioni', }, + receiptPartnersWarningModal: { + featureEnabledTitle: 'Disconnetti Uber', + disconnectText: "Per disabilitare questa funzionalità, disconnetti prima l'integrazione Uber for Business.", + confirmText: 'Capito', + }, workflowWarningModal: { featureEnabledTitle: 'Non così in fretta...', featureEnabledText: diff --git a/src/languages/ja.ts b/src/languages/ja.ts index aebcef05c0a9..1f494fce08e0 100644 --- a/src/languages/ja.ts +++ b/src/languages/ja.ts @@ -3404,6 +3404,7 @@ const translations = { travel: '旅行', members: 'メンバー', accounting: '会計', + receiptPartners: 'レシートパートナー', rules: 'ルール', displayedAs: '表示される内容', plan: '計画', @@ -4597,12 +4598,21 @@ const translations = { title: '会計', subtitle: '勘定科目表などを同期します。', }, + receiptPartners: { + title: 'レシートパートナー', + subtitle: 'レシートを自動的にインポート', + }, connectionsWarningModal: { featureEnabledTitle: 'ちょっと待ってください…', featureEnabledText: 'この機能を有効または無効にするには、会計インポート設定を変更する必要があります。', disconnectText: '会計を無効にするには、ワークスペースから会計接続を切断する必要があります。', manageSettings: '設定を管理', }, + receiptPartnersWarningModal: { + featureEnabledTitle: 'Uberを切断', + disconnectText: 'この機能を無効にするには、まずUber for Business統合を切断してください。', + confirmText: '了解', + }, workflowWarningModal: { featureEnabledTitle: 'ちょっと待ってください…', featureEnabledText: diff --git a/src/languages/nl.ts b/src/languages/nl.ts index d43856e80f63..48772e979787 100644 --- a/src/languages/nl.ts +++ b/src/languages/nl.ts @@ -3411,6 +3411,7 @@ const translations = { travel: 'Reis', members: 'Leden', accounting: 'Boekhouding', + receiptPartners: 'Bonnetjespartners', rules: 'Regels', displayedAs: 'Weergegeven als', plan: 'Plan', @@ -4620,12 +4621,21 @@ const translations = { title: 'Boekhouding', subtitle: 'Synchroniseer uw rekeningschema en meer.', }, + receiptPartners: { + title: 'Bonnetjespartners', + subtitle: 'Automatisch bonnetjes importeren.', + }, connectionsWarningModal: { featureEnabledTitle: 'Niet zo snel...', featureEnabledText: 'Om deze functie in of uit te schakelen, moet je je boekhoudimportinstellingen wijzigen.', disconnectText: 'Om boekhouding uit te schakelen, moet je de boekhoudkoppeling van je werkruimte loskoppelen.', manageSettings: 'Instellingen beheren', }, + receiptPartnersWarningModal: { + featureEnabledTitle: 'Uber verbreken', + disconnectText: 'Om deze functie uit te schakelen, verbreek eerst de Uber for Business integratie.', + confirmText: 'Begrepen', + }, workflowWarningModal: { featureEnabledTitle: 'Niet zo snel...', featureEnabledText: diff --git a/src/languages/pl.ts b/src/languages/pl.ts index d8977ee43551..a7f939b85f9f 100644 --- a/src/languages/pl.ts +++ b/src/languages/pl.ts @@ -3404,6 +3404,7 @@ const translations = { travel: 'Podróżować', members: 'Członkowie', accounting: 'Księgowość', + receiptPartners: 'Partnerzy paragonów', rules: 'Zasady', displayedAs: 'Wyświetlane jako', plan: 'Plan', @@ -4609,12 +4610,21 @@ const translations = { title: 'Księgowość', subtitle: 'Synchronizuj swój plan kont i więcej.', }, + receiptPartners: { + title: 'Partnerzy paragonów', + subtitle: 'Automatycznie importuj paragony.', + }, connectionsWarningModal: { featureEnabledTitle: 'Nie tak szybko...', featureEnabledText: 'Aby włączyć lub wyłączyć tę funkcję, musisz zmienić ustawienia importu księgowego.', disconnectText: 'Aby wyłączyć księgowość, musisz odłączyć swoje połączenie księgowe od przestrzeni roboczej.', manageSettings: 'Zarządzaj ustawieniami', }, + receiptPartnersWarningModal: { + featureEnabledTitle: 'Rozłącz Uber', + disconnectText: 'Aby wyłączyć tę funkcję, najpierw rozłącz integrację Uber for Business.', + confirmText: 'Rozumiem', + }, workflowWarningModal: { featureEnabledTitle: 'Nie tak szybko...', featureEnabledText: diff --git a/src/languages/pt-BR.ts b/src/languages/pt-BR.ts index c81252be63bb..7a75574544a6 100644 --- a/src/languages/pt-BR.ts +++ b/src/languages/pt-BR.ts @@ -3409,6 +3409,7 @@ const translations = { travel: 'Viagem', members: 'Membros', accounting: 'Contabilidade', + receiptPartners: 'Parceiros de recibos', rules: 'Regras', displayedAs: 'Exibido como', plan: 'Plano', @@ -4615,12 +4616,21 @@ const translations = { title: 'Contabilidade', subtitle: 'Sincronize seu plano de contas e mais.', }, + receiptPartners: { + title: 'Parceiros de recibos', + subtitle: 'Importar recibos automaticamente.', + }, connectionsWarningModal: { featureEnabledTitle: 'Não tão rápido...', featureEnabledText: 'Para ativar ou desativar este recurso, você precisará alterar suas configurações de importação de contabilidade.', disconnectText: 'Para desativar a contabilidade, você precisará desconectar sua conexão contábil do seu espaço de trabalho.', manageSettings: 'Gerenciar configurações', }, + receiptPartnersWarningModal: { + featureEnabledTitle: 'Desconectar Uber', + disconnectText: 'Para desativar este recurso, desconecte primeiro a integração do Uber for Business.', + confirmText: 'Entendi', + }, workflowWarningModal: { featureEnabledTitle: 'Não tão rápido...', featureEnabledText: diff --git a/src/languages/zh-hans.ts b/src/languages/zh-hans.ts index 799557f2ca9f..4c0dd814b673 100644 --- a/src/languages/zh-hans.ts +++ b/src/languages/zh-hans.ts @@ -3364,6 +3364,7 @@ const translations = { travel: '旅行', members: '成员', accounting: '会计', + receiptPartners: '收据合作伙伴', rules: '规则', displayedAs: '显示为', plan: '计划', @@ -4535,12 +4536,21 @@ const translations = { title: '会计', subtitle: '同步您的会计科目表及更多内容。', }, + receiptPartners: { + title: '收据合作伙伴', + subtitle: '自动导入收据。', + }, connectionsWarningModal: { featureEnabledTitle: '慢着...', featureEnabledText: '要启用或禁用此功能,您需要更改会计导入设置。', disconnectText: '要禁用会计功能,您需要从工作区断开会计连接。', manageSettings: '管理设置', }, + receiptPartnersWarningModal: { + featureEnabledTitle: '断开Uber连接', + disconnectText: '要禁用此功能,请先断开Uber for Business集成。', + confirmText: '明白了', + }, workflowWarningModal: { featureEnabledTitle: '慢着...', featureEnabledText: '此工作区的Expensify卡片依赖审批工作流程来定义其智能限额。\n\n请在禁用工作流程之前更改任何具有智能限额的卡片的限额类型。', diff --git a/src/libs/API/parameters/ToggleReceiptPartnersParams.ts b/src/libs/API/parameters/ToggleReceiptPartnersParams.ts new file mode 100644 index 000000000000..aeff6e203252 --- /dev/null +++ b/src/libs/API/parameters/ToggleReceiptPartnersParams.ts @@ -0,0 +1,6 @@ +type ToggleReceiptPartnersParams = { + policyID: string; + enabled: boolean; +}; + +export default ToggleReceiptPartnersParams; diff --git a/src/libs/API/parameters/index.ts b/src/libs/API/parameters/index.ts index 4626c848eec0..43959a4a38da 100644 --- a/src/libs/API/parameters/index.ts +++ b/src/libs/API/parameters/index.ts @@ -201,6 +201,7 @@ export type {default as SwitchToOldDotParams} from './SwitchToOldDotParams'; export type {default as TrackExpenseParams} from './TrackExpenseParams'; export type {default as EnablePolicyCategoriesParams} from './EnablePolicyCategoriesParams'; export type {default as EnablePolicyConnectionsParams} from './EnablePolicyConnectionsParams'; +export type {default as ToggleReceiptPartnersParams} from './ToggleReceiptPartnersParams'; export type {default as EnablePolicyDistanceRatesParams} from './EnablePolicyDistanceRatesParams'; export type {default as EnablePolicyTagsParams} from './EnablePolicyTagsParams'; export type {default as SetPolicyTagsEnabled} from './SetPolicyTagsEnabled'; diff --git a/src/libs/API/types.ts b/src/libs/API/types.ts index 20739d73c738..e4ba60e7ed74 100644 --- a/src/libs/API/types.ts +++ b/src/libs/API/types.ts @@ -228,6 +228,7 @@ const WRITE_COMMANDS = { TRACK_EXPENSE: 'TrackExpense', ENABLE_POLICY_CATEGORIES: 'EnablePolicyCategories', ENABLE_POLICY_CONNECTIONS: 'EnablePolicyConnections', + TOGGLE_RECEIPT_PARTNERS: 'ToggleReceiptPartners', ENABLE_POLICY_DISTANCE_RATES: 'EnablePolicyDistanceRates', ENABLE_POLICY_TAGS: 'EnablePolicyTags', ENABLE_POLICY_TAXES: 'EnablePolicyTaxes', @@ -725,6 +726,7 @@ type WriteCommandParameters = { [WRITE_COMMANDS.TRACK_EXPENSE]: Parameters.TrackExpenseParams; [WRITE_COMMANDS.ENABLE_POLICY_CATEGORIES]: Parameters.EnablePolicyCategoriesParams; [WRITE_COMMANDS.ENABLE_POLICY_CONNECTIONS]: Parameters.EnablePolicyConnectionsParams; + [WRITE_COMMANDS.TOGGLE_RECEIPT_PARTNERS]: Parameters.ToggleReceiptPartnersParams; [WRITE_COMMANDS.ENABLE_POLICY_DISTANCE_RATES]: Parameters.EnablePolicyDistanceRatesParams; [WRITE_COMMANDS.ENABLE_POLICY_TAGS]: Parameters.EnablePolicyTagsParams; [WRITE_COMMANDS.ENABLE_POLICY_TAXES]: Parameters.EnablePolicyTaxesParams; diff --git a/src/libs/actions/Policy/Policy.ts b/src/libs/actions/Policy/Policy.ts index 668de5db8ea3..bd59d52cccb1 100644 --- a/src/libs/actions/Policy/Policy.ts +++ b/src/libs/actions/Policy/Policy.ts @@ -51,6 +51,7 @@ import type { SetWorkspaceAutoReportingMonthlyOffsetParams, SetWorkspacePayerParams, SetWorkspaceReimbursementParams, + ToggleReceiptPartnersParams, UpdateInvoiceCompanyNameParams, UpdateInvoiceCompanyWebsiteParams, UpdatePolicyAddressParams, @@ -3216,6 +3217,54 @@ function enablePolicyConnections(policyID: string, enabled: boolean) { } } +function enablePolicyReceiptPartners(policyID: string, enabled: boolean) { + const onyxData: OnyxData = { + optimisticData: [ + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, + value: { + areReceiptPartnersEnabled: enabled, + pendingFields: { + areReceiptPartnersEnabled: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE, + }, + }, + }, + ], + successData: [ + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, + value: { + pendingFields: { + areReceiptPartnersEnabled: null, + }, + }, + }, + ], + failureData: [ + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, + value: { + areReceiptPartnersEnabled: !enabled, + pendingFields: { + areReceiptPartnersEnabled: null, + }, + }, + }, + ], + }; + + const parameters: ToggleReceiptPartnersParams = {policyID, enabled}; + + API.write(WRITE_COMMANDS.TOGGLE_RECEIPT_PARTNERS, parameters, onyxData); + + if (enabled && getIsNarrowLayout()) { + goBackWhenEnableFeature(policyID); + } +} + /** Save the preferred export method for a policy */ function savePreferredExportMethod(policyID: string, exportMethod: ReportExportType) { Onyx.merge(`${ONYXKEYS.LAST_EXPORT_METHOD}`, {[policyID]: exportMethod}); @@ -5716,6 +5765,7 @@ export { openPolicyWorkflowsPage, enableCompanyCards, enablePolicyConnections, + enablePolicyReceiptPartners, enablePolicyReportFields, enablePolicyTaxes, enablePolicyWorkflows, diff --git a/src/libs/actions/RequestConflictUtils.ts b/src/libs/actions/RequestConflictUtils.ts index 359db4ada266..d93a4120525e 100644 --- a/src/libs/actions/RequestConflictUtils.ts +++ b/src/libs/actions/RequestConflictUtils.ts @@ -26,6 +26,7 @@ const enablePolicyFeatureCommand = [ WRITE_COMMANDS.ENABLE_POLICY_EXPENSIFY_CARDS, WRITE_COMMANDS.ENABLE_POLICY_COMPANY_CARDS, WRITE_COMMANDS.ENABLE_POLICY_CONNECTIONS, + WRITE_COMMANDS.TOGGLE_RECEIPT_PARTNERS, WRITE_COMMANDS.ENABLE_POLICY_CATEGORIES, WRITE_COMMANDS.ENABLE_POLICY_TAGS, WRITE_COMMANDS.ENABLE_POLICY_TAXES, diff --git a/src/pages/workspace/WorkspaceInitialPage.tsx b/src/pages/workspace/WorkspaceInitialPage.tsx index a73787d36455..4794e31053af 100644 --- a/src/pages/workspace/WorkspaceInitialPage.tsx +++ b/src/pages/workspace/WorkspaceInitialPage.tsx @@ -18,6 +18,7 @@ import { Folder, Gear, InvoiceGeneric, + Receipt, Sync, Tag, Users, @@ -35,6 +36,7 @@ import useCurrentUserPersonalDetails from '@hooks/useCurrentUserPersonalDetails' import useLocalize from '@hooks/useLocalize'; import useNetwork from '@hooks/useNetwork'; import useOnyx from '@hooks/useOnyx'; +import usePermissions from '@hooks/usePermissions'; import usePrevious from '@hooks/usePrevious'; import useResponsiveLayout from '@hooks/useResponsiveLayout'; import useSingleExecution from '@hooks/useSingleExecution'; @@ -122,6 +124,8 @@ function WorkspaceInitialPage({policyDraft, policy: policyProp, route}: Workspac const activeRoute = useNavigationState((state) => findFocusedRoute(state)?.name); const {shouldUseNarrowLayout} = useResponsiveLayout(); const {translate} = useLocalize(); + const {isBetaEnabled} = usePermissions(); + const isUberForBusinessEnabled = isBetaEnabled(CONST.BETAS.UBER_FOR_BUSINESS); const {isOffline} = useNetwork(); const wasRendered = useRef(false); const [allReports] = useOnyx(ONYXKEYS.COLLECTION.REPORT, {canBeMissing: true}); @@ -145,8 +149,9 @@ function WorkspaceInitialPage({policyDraft, policy: policyProp, route}: Workspac [CONST.POLICY.MORE_FEATURES.ARE_RULES_ENABLED]: policy?.areRulesEnabled, [CONST.POLICY.MORE_FEATURES.ARE_INVOICES_ENABLED]: policy?.areInvoicesEnabled, [CONST.POLICY.MORE_FEATURES.ARE_PER_DIEM_RATES_ENABLED]: policy?.arePerDiemRatesEnabled, + [CONST.POLICY.MORE_FEATURES.ARE_RECEIPT_PARTNERS_ENABLED]: isUberForBusinessEnabled && (policy?.areReceiptPartnersEnabled ?? false), }), - [policy], + [policy, isUberForBusinessEnabled], ) as PolicyFeatureStates; const fetchPolicyData = useCallback(() => { @@ -200,6 +205,21 @@ function WorkspaceInitialPage({policyDraft, policy: policyProp, route}: Workspac }); } + if (featureStates?.[CONST.POLICY.MORE_FEATURES.ARE_RECEIPT_PARTNERS_ENABLED]) { + protectedMenuItems.push({ + translationKey: 'workspace.common.receiptPartners', + icon: Receipt, + action: singleExecution( + waitForNavigate(() => { + // TODO: Navigate to Receipt Partners page when it's created + // Navigation.navigate(ROUTES.POLICY_RECEIPT_PARTNERS.getRoute(policyID)) + }), + ), + screenName: SCREENS.WORKSPACE.CATEGORIES, // Update to SCREENS.WORKSPACE.RECEIPT_PARTNERS when created + highlighted: highlightedFeature === CONST.POLICY.MORE_FEATURES.ARE_RECEIPT_PARTNERS_ENABLED, + }); + } + if (featureStates?.[CONST.POLICY.MORE_FEATURES.ARE_CATEGORIES_ENABLED]) { protectedMenuItems.push({ translationKey: 'workspace.common.categories', diff --git a/src/pages/workspace/WorkspaceMoreFeaturesPage.tsx b/src/pages/workspace/WorkspaceMoreFeaturesPage.tsx index e25143581d05..3bbdc1e776f4 100644 --- a/src/pages/workspace/WorkspaceMoreFeaturesPage.tsx +++ b/src/pages/workspace/WorkspaceMoreFeaturesPage.tsx @@ -11,6 +11,7 @@ import useCardFeeds from '@hooks/useCardFeeds'; import useLocalize from '@hooks/useLocalize'; import useNetwork from '@hooks/useNetwork'; import useOnyx from '@hooks/useOnyx'; +import usePermissions from '@hooks/usePermissions'; import useResponsiveLayout from '@hooks/useResponsiveLayout'; import useStyleUtils from '@hooks/useStyleUtils'; import useThemeStyles from '@hooks/useThemeStyles'; @@ -29,6 +30,7 @@ import { enableExpensifyCard, enablePolicyConnections, enablePolicyInvoicing, + enablePolicyReceiptPartners, enablePolicyRules, enablePolicyTaxes, enablePolicyWorkflows, @@ -75,6 +77,7 @@ function WorkspaceMoreFeaturesPage({policy, route}: WorkspaceMoreFeaturesPagePro const StyleUtils = useStyleUtils(); const {shouldUseNarrowLayout} = useResponsiveLayout(); const {translate} = useLocalize(); + const {isBetaEnabled} = usePermissions(); const hasAccountingConnection = !isEmptyObject(policy?.connections); const isAccountingEnabled = !!policy?.areConnectionsEnabled || !isEmptyObject(policy?.connections); const isSyncTaxEnabled = @@ -90,6 +93,7 @@ function WorkspaceMoreFeaturesPage({policy, route}: WorkspaceMoreFeaturesPagePro const [cardFeeds] = useCardFeeds(policyID); const [isOrganizeWarningModalOpen, setIsOrganizeWarningModalOpen] = useState(false); const [isIntegrateWarningModalOpen, setIsIntegrateWarningModalOpen] = useState(false); + const [isReceiptPartnersWarningModalOpen, setIsReceiptPartnersWarningModalOpen] = useState(false); const [isDisableExpensifyCardWarningModalOpen, setIsDisableExpensifyCardWarningModalOpen] = useState(false); const [isDisableCompanyCardsWarningModalOpen, setIsDisableCompanyCardsWarningModalOpen] = useState(false); const [isDisableWorkflowWarningModalOpen, setIsDisableWorkflowWarningModalOpen] = useState(false); @@ -316,6 +320,34 @@ function WorkspaceMoreFeaturesPage({policy, route}: WorkspaceMoreFeaturesPagePro }, ]; + if (isBetaEnabled(CONST.BETAS.UBER_FOR_BUSINESS)) { + integrateItems.push({ + icon: Illustrations.ReceiptPartners, + titleTranslationKey: 'workspace.moreFeatures.receiptPartners.title', + subtitleTranslationKey: 'workspace.moreFeatures.receiptPartners.subtitle', + isActive: policy?.areReceiptPartnersEnabled ?? false, + pendingAction: policy?.pendingFields?.areReceiptPartnersEnabled, + disabledAction: () => { + // TODO: When Uber integration is added, check if any integration exists if(!hasReceiptPartnersIntegration) return; + setIsReceiptPartnersWarningModalOpen(true); + }, + action: (isEnabled: boolean) => { + if (!policyID) { + return; + } + enablePolicyReceiptPartners(policyID, isEnabled); + }, + disabled: false, // TODO: When Uber integration is added, set to hasReceiptPartnersIntegration + errors: getLatestErrorField(policy ?? {}, CONST.POLICY.MORE_FEATURES.ARE_RECEIPT_PARTNERS_ENABLED), + onCloseError: () => { + if (!policyID) { + return; + } + clearPolicyErrorField(policyID, CONST.POLICY.MORE_FEATURES.ARE_RECEIPT_PARTNERS_ENABLED); + }, + }); + } + const sections: SectionObject[] = [ { titleTranslationKey: 'workspace.moreFeatures.integrateSection.title', @@ -482,6 +514,23 @@ function WorkspaceMoreFeaturesPage({policy, route}: WorkspaceMoreFeaturesPagePro confirmText={translate('workspace.moreFeatures.connectionsWarningModal.manageSettings')} cancelText={translate('common.cancel')} /> + {isBetaEnabled(CONST.BETAS.UBER_FOR_BUSINESS) && ( + { + if (!policyID) { + return; + } + setIsReceiptPartnersWarningModalOpen(false); + // TODO: Navigate to Receipt Partners settings page when it exists + // Navigation.navigate(ROUTES.POLICY_RECEIPT_PARTNERS.getRoute(policyID)); + }} + isVisible={isReceiptPartnersWarningModalOpen} + prompt={translate('workspace.moreFeatures.receiptPartnersWarningModal.disconnectText')} + confirmText={translate('workspace.moreFeatures.receiptPartnersWarningModal.confirmText')} + shouldShowCancelButton={false} + /> + )}