From 8ccedd770cd46b5d09263feff1d466091fd2d5a7 Mon Sep 17 00:00:00 2001 From: nkdengineer Date: Fri, 18 Oct 2024 13:57:43 +0700 Subject: [PATCH 1/5] Add policyID param to CompleteOnboarding API --- src/libs/API/parameters/CompleteGuidedSetupParams.ts | 1 + src/libs/actions/Report.ts | 1 + 2 files changed, 2 insertions(+) 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 7071c96f8612..acd22cacaa2b 100644 --- a/src/libs/actions/Report.ts +++ b/src/libs/actions/Report.ts @@ -3715,6 +3715,7 @@ function completeOnboarding( paymentSelected, companySize, userReportedIntegration, + policyID: onboardingPolicyID, }; API.write(WRITE_COMMANDS.COMPLETE_GUIDED_SETUP, parameters, {optimisticData, successData, failureData}); From 87afbb89fc09ce6fb519271f1c1e96b1755ab058 Mon Sep 17 00:00:00 2001 From: nkdengineer Date: Mon, 21 Oct 2024 18:00:03 +0700 Subject: [PATCH 2/5] add accounting task --- src/CONST.ts | 55 +++++++++++++++++++++++++++++++++++--- src/libs/actions/Report.ts | 21 ++++++++++++--- 2 files changed, 68 insertions(+), 8 deletions(-) diff --git a/src/CONST.ts b/src/CONST.ts index 84003710938a..aa012f88f3f6 100755 --- a/src/CONST.ts +++ b/src/CONST.ts @@ -131,7 +131,7 @@ type OnboardingPurposeType = ValueOf; type OnboardingCompanySizeType = ValueOf; -type OnboardingAccountingType = ValueOf | null; +type OnboardingAccountingType = ValueOf | null; const onboardingInviteTypes = { IOU: 'iou', @@ -147,13 +147,37 @@ const onboardingCompanySize = { LARGE: '1001+', } as const; +const connectNames = { + QBO: 'quickbooksOnline', + XERO: 'xero', + NETSUITE: 'netsuite', + SAGE_INTACCT: 'intacct', +} as const; + 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<{ + accountingName: string; + }>, + ) => string); + description: + | string + | (( + params: Partial<{ + adminsRoomLink: string; + workspaceCategoriesLink: string; + workspaceMoreFeaturesLink: string; + workspaceMembersLink: string; + accountingName: string; + accountingLink: string; + }>, + ) => string); }; type OnboardingMessageType = { @@ -4622,7 +4646,12 @@ 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: { + [connectNames.QBO]: 'QuickBooks Online', + [connectNames.XERO]: 'Xero', + [connectNames.NETSUITE]: 'NetSuite', + [connectNames.SAGE_INTACCT]: 'Sage Intacct', + }, ONBOARDING_MESSAGES: { [onboardingChoices.EMPLOYER]: onboardingEmployerOrSubmitMessage, [onboardingChoices.SUBMIT]: onboardingEmployerOrSubmitMessage, @@ -4734,6 +4763,24 @@ const CONST = { '\n' + `[Take me to workspace members](${workspaceMembersLink}). That’s it, happy expensing! :)`, }, + { + type: 'integration', + autoCompleted: false, + title: ({accountingName}) => `Connect to ${accountingName}`, + description: ({accountingName, accountingLink}) => + `Connect to ${accountingName} for automatic expense coding and syncing that makes month-end close a breeze.\n` + + '\n' + + `Here’s how to connect to ${accountingName}:\n` + + '\n' + + '1. Click your profile photo.\n' + + '2. Go to Workspaces.\n' + + '3. Select your workspace.\n' + + '4. Click Accounting.\n' + + `5. Find ${accountingName}.\n` + + '6. Click Connect.\n' + + '\n' + + `[Take me to Accounting!](${accountingLink})`, + }, ], }, [onboardingChoices.PERSONAL_SPEND]: { diff --git a/src/libs/actions/Report.ts b/src/libs/actions/Report.ts index acd22cacaa2b..6593f43c5532 100644 --- a/src/libs/actions/Report.ts +++ b/src/libs/actions/Report.ts @@ -3326,6 +3326,7 @@ function completeOnboarding( companySize?: OnboardingCompanySizeType, userReportedIntegration?: OnboardingAccountingType, ) { + const accountingName = userReportedIntegration ? CONST.ONBOARDING_ACCOUNTING_MAPPING[userReportedIntegration] : ''; const actorAccountID = CONST.ACCOUNT_ID.CONCIERGE; const targetChatReport = ReportUtils.getChatByParticipants([actorAccountID, currentUserAccountID]); const {reportID: targetChatReportID = '', policyID: targetChatPolicyID = ''} = targetChatReport ?? {}; @@ -3360,7 +3361,7 @@ function completeOnboarding( }; } - const tasksData = data.tasks.map((task, index) => { + let tasksData = data.tasks.map((task, index) => { const taskDescription = typeof task.description === 'function' ? task.description({ @@ -3368,13 +3369,21 @@ function completeOnboarding( 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')}`, + accountingName, + accountingLink: `${environmentURL}/${ROUTES.POLICY_ACCOUNTING.getRoute(onboardingPolicyID ?? '-1')}`, }) : task.description; + const taskTitle = + typeof task.title === 'function' + ? task.title({ + accountingName, + }) + : task.title; const currentTask = ReportUtils.buildOptimisticTaskReport( actorAccountID, currentUserAccountID, targetChatReportID, - task.title, + taskTitle, taskDescription, targetChatPolicyID, CONST.REPORT.NOTIFICATION_PREFERENCE.HIDDEN, @@ -3382,9 +3391,9 @@ function completeOnboarding( const taskCreatedAction = ReportUtils.buildOptimisticCreatedReportAction(CONST.EMAIL.CONCIERGE); const taskReportAction = ReportUtils.buildOptimisticTaskCommentReportAction( currentTask.reportID, - task.title, + taskTitle, 0, - `task for ${task.title}`, + `task for ${taskTitle}`, targetChatReportID, actorAccountID, index + 3, @@ -3405,6 +3414,10 @@ function completeOnboarding( }; }); + if (!userReportedIntegration) { + tasksData = tasksData.filter((tasksDataItem) => tasksDataItem.task.type === 'accounting'); + } + const tasksForParameters = tasksData.map(({task, currentTask, taskCreatedAction, taskReportAction, taskDescription, completedTaskReportAction}) => ({ type: 'task', task: task.type, From 494ad4dde8a96538d1cde76f414dd3a434b2d80b Mon Sep 17 00:00:00 2001 From: nkdengineer Date: Tue, 22 Oct 2024 10:46:39 +0700 Subject: [PATCH 3/5] update type of accounting task --- src/CONST.ts | 2 +- src/libs/actions/Report.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/CONST.ts b/src/CONST.ts index 6e923b18ef78..f381ea8c9a1c 100755 --- a/src/CONST.ts +++ b/src/CONST.ts @@ -4789,7 +4789,7 @@ const CONST = { `[Take me to workspace members](${workspaceMembersLink}). That’s it, happy expensing! :)`, }, { - type: 'integration', + type: 'addAccountingIntegration', autoCompleted: false, title: ({accountingName}) => `Connect to ${accountingName}`, description: ({accountingName, accountingLink}) => diff --git a/src/libs/actions/Report.ts b/src/libs/actions/Report.ts index 1ba2fe85e82f..5bc79db0abb8 100644 --- a/src/libs/actions/Report.ts +++ b/src/libs/actions/Report.ts @@ -3420,7 +3420,7 @@ function completeOnboarding( }); if (!userReportedIntegration) { - tasksData = tasksData.filter((tasksDataItem) => tasksDataItem.task.type === 'accounting'); + tasksData = tasksData.filter((tasksDataItem) => tasksDataItem.task.type !== 'addAccountingIntegration'); } const tasksForParameters = tasksData.map(({task, currentTask, taskCreatedAction, taskReportAction, taskDescription, completedTaskReportAction}) => ({ From 5ee95ff6c41d064832c8f3dedaf33e036636f11c Mon Sep 17 00:00:00 2001 From: nkdengineer Date: Wed, 23 Oct 2024 14:26:58 +0700 Subject: [PATCH 4/5] refactor connection CONST --- src/CONST.ts | 36 +++++------- src/libs/actions/Report.ts | 112 ++++++++++++++++++------------------- 2 files changed, 70 insertions(+), 78 deletions(-) diff --git a/src/CONST.ts b/src/CONST.ts index 046577c5dd31..f657925a77c1 100755 --- a/src/CONST.ts +++ b/src/CONST.ts @@ -131,7 +131,7 @@ type OnboardingPurposeType = ValueOf; type OnboardingCompanySizeType = ValueOf; -type OnboardingAccountingType = ValueOf | null; +type OnboardingAccountingType = ValueOf | null; const onboardingInviteTypes = { IOU: 'iou', @@ -147,13 +147,6 @@ const onboardingCompanySize = { LARGE: '1001+', } as const; -const connectNames = { - QBO: 'quickbooksOnline', - XERO: 'xero', - NETSUITE: 'netsuite', - SAGE_INTACCT: 'intacct', -} as const; - type OnboardingInviteType = ValueOf; type OnboardingTaskType = { @@ -163,7 +156,7 @@ type OnboardingTaskType = { | string | (( params: Partial<{ - accountingName: string; + integrationName: string; }>, ) => string); description: @@ -174,8 +167,8 @@ type OnboardingTaskType = { workspaceCategoriesLink: string; workspaceMoreFeaturesLink: string; workspaceMembersLink: string; - accountingName: string; - accountingLink: string; + integrationName: string; + workspaceAccountingLink: string; }>, ) => string); }; @@ -4672,10 +4665,11 @@ const CONST = { "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: { - [connectNames.QBO]: 'QuickBooks Online', - [connectNames.XERO]: 'Xero', - [connectNames.NETSUITE]: 'NetSuite', - [connectNames.SAGE_INTACCT]: 'Sage Intacct', + quickbooksOnline: 'QuickBooks Online', + xero: 'Xero', + netsuite: 'NetSuite', + intacct: 'Sage Intacct', + quickbooksDesktop: 'QuickBooks Desktop', }, ONBOARDING_MESSAGES: { [onboardingChoices.EMPLOYER]: onboardingEmployerOrSubmitMessage, @@ -4791,20 +4785,20 @@ const CONST = { { type: 'addAccountingIntegration', autoCompleted: false, - title: ({accountingName}) => `Connect to ${accountingName}`, - description: ({accountingName, accountingLink}) => - `Connect to ${accountingName} for automatic expense coding and syncing that makes month-end close a breeze.\n` + + 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 ${accountingName}:\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 ${accountingName}.\n` + + `5. Find ${integrationName}.\n` + '6. Click Connect.\n' + '\n' + - `[Take me to Accounting!](${accountingLink})`, + `[Take me to Accounting!](${workspaceAccountingLink})`, }, ], }, diff --git a/src/libs/actions/Report.ts b/src/libs/actions/Report.ts index 330c9b7c254a..67809d947430 100644 --- a/src/libs/actions/Report.ts +++ b/src/libs/actions/Report.ts @@ -3330,7 +3330,7 @@ function completeOnboarding( companySize?: OnboardingCompanySizeType, userReportedIntegration?: OnboardingAccountingType, ) { - const accountingName = userReportedIntegration ? CONST.ONBOARDING_ACCOUNTING_MAPPING[userReportedIntegration] : ''; + 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 ?? {}; @@ -3365,62 +3365,60 @@ function completeOnboarding( }; } - let 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')}`, - accountingName, - accountingLink: `${environmentURL}/${ROUTES.POLICY_ACCOUNTING.getRoute(onboardingPolicyID ?? '-1')}`, - }) - : task.description; - const taskTitle = - typeof task.title === 'function' - ? task.title({ - accountingName, - }) - : 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, - }; - }); - - if (!userReportedIntegration) { - tasksData = tasksData.filter((tasksDataItem) => tasksDataItem.task.type !== 'addAccountingIntegration'); - } + const tasksData = data.tasks + .filter((task) => !!userReportedIntegration || task.type !== 'addAccountingIntegration') + .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', From bb2002f2f1ad2b3594799222821fdb34e3371ec8 Mon Sep 17 00:00:00 2001 From: nkdengineer Date: Thu, 24 Oct 2024 00:25:40 +0700 Subject: [PATCH 5/5] refactor function --- src/libs/actions/Report.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/libs/actions/Report.ts b/src/libs/actions/Report.ts index d3a94b35f5db..5abb0c79fff3 100644 --- a/src/libs/actions/Report.ts +++ b/src/libs/actions/Report.ts @@ -3373,7 +3373,12 @@ function completeOnboarding( } const tasksData = data.tasks - .filter((task) => !!userReportedIntegration || task.type !== 'addAccountingIntegration') + .filter((task) => { + if (task.type === 'addAccountingIntegration' && !userReportedIntegration) { + return false; + } + return true; + }) .map((task, index) => { const taskDescription = typeof task.description === 'function'