diff --git a/src/CONST.ts b/src/CONST.ts index 57a61c1c1c64..e793ea70cfc8 100755 --- a/src/CONST.ts +++ b/src/CONST.ts @@ -152,8 +152,25 @@ type OnboardingInviteType = ValueOf; type OnboardingTaskType = { type: string; autoCompleted: boolean; - title: string; - description: string | ((params: Partial<{adminsRoomLink: string; workspaceCategoriesLink: string; workspaceMoreFeaturesLink: string; workspaceMembersLink: string}>) => string); + title: + | string + | (( + params: Partial<{ + integrationName: string; + }>, + ) => string); + description: + | string + | (( + params: Partial<{ + adminsRoomLink: string; + workspaceCategoriesLink: string; + workspaceMoreFeaturesLink: string; + workspaceMembersLink: string; + integrationName: string; + workspaceAccountingLink: string; + }>, + ) => string); }; type OnboardingMessageType = { @@ -4736,7 +4753,13 @@ const CONST = { '\n' + "We'll send a request to each person so they can pay you back. Let me know if you have any questions!", }, - + ONBOARDING_ACCOUNTING_MAPPING: { + quickbooksOnline: 'QuickBooks Online', + xero: 'Xero', + netsuite: 'NetSuite', + intacct: 'Sage Intacct', + quickbooksDesktop: 'QuickBooks Desktop', + }, ONBOARDING_MESSAGES: { [onboardingChoices.EMPLOYER]: onboardingEmployerOrSubmitMessage, [onboardingChoices.SUBMIT]: onboardingEmployerOrSubmitMessage, @@ -4848,6 +4871,24 @@ const CONST = { '\n' + `[Take me to workspace members](${workspaceMembersLink}). That’s it, happy expensing! :)`, }, + { + type: 'addAccountingIntegration', + autoCompleted: false, + title: ({integrationName}) => `Connect to ${integrationName}`, + description: ({integrationName, workspaceAccountingLink}) => + `Connect to ${integrationName} for automatic expense coding and syncing that makes month-end close a breeze.\n` + + '\n' + + `Here’s how to connect to ${integrationName}:\n` + + '\n' + + '1. Click your profile photo.\n' + + '2. Go to Workspaces.\n' + + '3. Select your workspace.\n' + + '4. Click Accounting.\n' + + `5. Find ${integrationName}.\n` + + '6. Click Connect.\n' + + '\n' + + `[Take me to Accounting!](${workspaceAccountingLink})`, + }, ], }, [onboardingChoices.PERSONAL_SPEND]: { diff --git a/src/libs/API/parameters/CompleteGuidedSetupParams.ts b/src/libs/API/parameters/CompleteGuidedSetupParams.ts index 1242b9285de9..6ff45ecc424a 100644 --- a/src/libs/API/parameters/CompleteGuidedSetupParams.ts +++ b/src/libs/API/parameters/CompleteGuidedSetupParams.ts @@ -9,6 +9,7 @@ type CompleteGuidedSetupParams = { paymentSelected?: string; companySize?: OnboardingCompanySizeType; userReportedIntegration?: OnboardingAccountingType; + policyID?: string; }; export default CompleteGuidedSetupParams; diff --git a/src/libs/actions/Report.ts b/src/libs/actions/Report.ts index b638b8cbd7f1..808c4b80dace 100644 --- a/src/libs/actions/Report.ts +++ b/src/libs/actions/Report.ts @@ -3380,6 +3380,7 @@ function completeOnboarding( companySize?: OnboardingCompanySizeType, userReportedIntegration?: OnboardingAccountingType, ) { + const integrationName = userReportedIntegration ? CONST.ONBOARDING_ACCOUNTING_MAPPING[userReportedIntegration] : ''; const actorAccountID = CONST.ACCOUNT_ID.CONCIERGE; const targetChatReport = ReportUtils.getChatByParticipants([actorAccountID, currentUserAccountID]); const {reportID: targetChatReportID = '', policyID: targetChatPolicyID = ''} = targetChatReport ?? {}; @@ -3414,50 +3415,65 @@ function completeOnboarding( }; } - const tasksData = data.tasks.map((task, index) => { - const taskDescription = - typeof task.description === 'function' - ? task.description({ - adminsRoomLink: `${environmentURL}/${ROUTES.REPORT_WITH_ID.getRoute(adminsChatReportID ?? '-1')}`, - workspaceCategoriesLink: `${environmentURL}/${ROUTES.WORKSPACE_CATEGORIES.getRoute(onboardingPolicyID ?? '-1')}`, - workspaceMembersLink: `${environmentURL}/${ROUTES.WORKSPACE_MEMBERS.getRoute(onboardingPolicyID ?? '-1')}`, - workspaceMoreFeaturesLink: `${environmentURL}/${ROUTES.WORKSPACE_MORE_FEATURES.getRoute(onboardingPolicyID ?? '-1')}`, - }) - : task.description; - const currentTask = ReportUtils.buildOptimisticTaskReport( - actorAccountID, - currentUserAccountID, - targetChatReportID, - task.title, - taskDescription, - targetChatPolicyID, - CONST.REPORT.NOTIFICATION_PREFERENCE.HIDDEN, - ); - const taskCreatedAction = ReportUtils.buildOptimisticCreatedReportAction(CONST.EMAIL.CONCIERGE); - const taskReportAction = ReportUtils.buildOptimisticTaskCommentReportAction( - currentTask.reportID, - task.title, - 0, - `task for ${task.title}`, - targetChatReportID, - actorAccountID, - index + 3, - ); - currentTask.parentReportActionID = taskReportAction.reportAction.reportActionID; - - const completedTaskReportAction = task.autoCompleted - ? ReportUtils.buildOptimisticTaskReportAction(currentTask.reportID, CONST.REPORT.ACTIONS.TYPE.TASK_COMPLETED, 'marked as complete', actorAccountID, 2) - : null; - - return { - task, - currentTask, - taskCreatedAction, - taskReportAction, - taskDescription: currentTask.description, - completedTaskReportAction, - }; - }); + const tasksData = data.tasks + .filter((task) => { + if (task.type === 'addAccountingIntegration' && !userReportedIntegration) { + return false; + } + return true; + }) + .map((task, index) => { + const taskDescription = + typeof task.description === 'function' + ? task.description({ + adminsRoomLink: `${environmentURL}/${ROUTES.REPORT_WITH_ID.getRoute(adminsChatReportID ?? '-1')}`, + workspaceCategoriesLink: `${environmentURL}/${ROUTES.WORKSPACE_CATEGORIES.getRoute(onboardingPolicyID ?? '-1')}`, + workspaceMembersLink: `${environmentURL}/${ROUTES.WORKSPACE_MEMBERS.getRoute(onboardingPolicyID ?? '-1')}`, + workspaceMoreFeaturesLink: `${environmentURL}/${ROUTES.WORKSPACE_MORE_FEATURES.getRoute(onboardingPolicyID ?? '-1')}`, + integrationName, + workspaceAccountingLink: `${environmentURL}/${ROUTES.POLICY_ACCOUNTING.getRoute(onboardingPolicyID ?? '-1')}`, + }) + : task.description; + const taskTitle = + typeof task.title === 'function' + ? task.title({ + integrationName, + }) + : task.title; + const currentTask = ReportUtils.buildOptimisticTaskReport( + actorAccountID, + currentUserAccountID, + targetChatReportID, + taskTitle, + taskDescription, + targetChatPolicyID, + CONST.REPORT.NOTIFICATION_PREFERENCE.HIDDEN, + ); + const taskCreatedAction = ReportUtils.buildOptimisticCreatedReportAction(CONST.EMAIL.CONCIERGE); + const taskReportAction = ReportUtils.buildOptimisticTaskCommentReportAction( + currentTask.reportID, + taskTitle, + 0, + `task for ${taskTitle}`, + targetChatReportID, + actorAccountID, + index + 3, + ); + currentTask.parentReportActionID = taskReportAction.reportAction.reportActionID; + + const completedTaskReportAction = task.autoCompleted + ? ReportUtils.buildOptimisticTaskReportAction(currentTask.reportID, CONST.REPORT.ACTIONS.TYPE.TASK_COMPLETED, 'marked as complete', actorAccountID, 2) + : null; + + return { + task, + currentTask, + taskCreatedAction, + taskReportAction, + taskDescription: currentTask.description, + completedTaskReportAction, + }; + }); const tasksForParameters = tasksData.map(({task, currentTask, taskCreatedAction, taskReportAction, taskDescription, completedTaskReportAction}) => ({ type: 'task', @@ -3769,6 +3785,7 @@ function completeOnboarding( paymentSelected, companySize, userReportedIntegration, + policyID: onboardingPolicyID, }; API.write(WRITE_COMMANDS.COMPLETE_GUIDED_SETUP, parameters, {optimisticData, successData, failureData});