diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index fa4eb376dbc6..bec6894e5477 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -11326,9 +11326,16 @@ function canLeaveChat(report: OnyxEntry, policy: OnyxEntry, isRe ); } -function createDraftWorkspaceAndNavigateToConfirmationScreen(introSelected: OnyxEntry, transactionID: string, actionName: IOUAction, workspaceName: string): void { +function createDraftWorkspaceAndNavigateToConfirmationScreen( + introSelected: OnyxEntry, + transactionID: string, + actionName: IOUAction, + workspaceName: string, + currentUserAccountID: number, + currentUserEmail: string, +): void { const isCategorizing = actionName === CONST.IOU.ACTION.CATEGORIZE; - const {expenseChatReportID, policyID, policyName} = createDraftWorkspace(introSelected, workspaceName, deprecatedCurrentUserEmail); + const {expenseChatReportID, policyID, policyName} = createDraftWorkspace(introSelected, workspaceName, currentUserAccountID, currentUserEmail); setMoneyRequestParticipants(transactionID, [ { selected: true, @@ -11360,6 +11367,8 @@ type CreateDraftTransactionParams = { isRestrictedToPreferredPolicy?: boolean; preferredPolicyID?: string; transaction: OnyxEntry; + currentUserAccountID: number; + currentUserEmail: string; }; function createDraftTransactionAndNavigateToParticipantSelector({ @@ -11375,6 +11384,8 @@ function createDraftTransactionAndNavigateToParticipantSelector({ isRestrictedToPreferredPolicy = false, preferredPolicyID, transaction, + currentUserAccountID, + currentUserEmail, }: CreateDraftTransactionParams): void { const transactionID = transaction?.transactionID; if (!transactionID || !reportID) { @@ -11519,7 +11530,7 @@ function createDraftTransactionAndNavigateToParticipantSelector({ return; } - return createDraftWorkspaceAndNavigateToConfirmationScreen(introSelected, transactionID, actionName, ''); + return createDraftWorkspaceAndNavigateToConfirmationScreen(introSelected, transactionID, actionName, '', currentUserAccountID, currentUserEmail); } /** diff --git a/src/libs/actions/Policy/Policy.ts b/src/libs/actions/Policy/Policy.ts index 43231723a183..ea06d9469530 100644 --- a/src/libs/actions/Policy/Policy.ts +++ b/src/libs/actions/Policy/Policy.ts @@ -2977,6 +2977,8 @@ function createWorkspace(options: CreateWorkspaceDataOptions): CreateWorkspacePa function createDraftWorkspace( introSelected: OnyxEntry, workspaceName: string, + currentUserAccountID: number, + currentUserEmail: string, policyOwnerEmail = '', makeMeAdmin = false, policyID = generatePolicyID(), @@ -3002,13 +3004,13 @@ function createDraftWorkspace( type: CONST.POLICY.TYPE.TEAM, name: workspaceName, role: CONST.POLICY.ROLE.ADMIN, - owner: deprecatedSessionEmail, - ownerAccountID: deprecatedSessionAccountID, + owner: currentUserEmail, + ownerAccountID: currentUserAccountID, isPolicyExpenseChatEnabled: true, outputCurrency, pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD, autoReporting: true, - approver: deprecatedSessionEmail, + approver: currentUserEmail, autoReportingFrequency: shouldEnableWorkflowsByDefault ? CONST.POLICY.AUTO_REPORTING_FREQUENCIES.IMMEDIATE : CONST.POLICY.AUTO_REPORTING_FREQUENCIES.INSTANT, harvesting: { enabled: !shouldEnableWorkflowsByDefault, @@ -3024,9 +3026,9 @@ function createDraftWorkspace( areConnectionsEnabled: false, areExpensifyCardsEnabled: false, employeeList: { - [deprecatedSessionEmail]: { - submitsTo: deprecatedSessionEmail, - email: deprecatedSessionEmail, + [currentUserEmail]: { + submitsTo: currentUserEmail, + email: currentUserEmail, role: CONST.POLICY.ROLE.ADMIN, errors: {}, }, diff --git a/src/pages/ReportDetailsPage.tsx b/src/pages/ReportDetailsPage.tsx index e64a853fef2c..4bcfac50274f 100644 --- a/src/pages/ReportDetailsPage.tsx +++ b/src/pages/ReportDetailsPage.tsx @@ -469,6 +469,8 @@ function ReportDetailsPage({policy, report, route, reportMetadata}: ReportDetail isRestrictedToPreferredPolicy, preferredPolicyID, transaction: iouTransaction, + currentUserAccountID: currentUserPersonalDetails.accountID, + currentUserEmail: currentUserPersonalDetails.email ?? '', }); }, }); @@ -491,6 +493,8 @@ function ReportDetailsPage({policy, report, route, reportMetadata}: ReportDetail amountOwed, ownerBillingGracePeriodEnd, transaction: iouTransaction, + currentUserAccountID: currentUserPersonalDetails.accountID, + currentUserEmail: currentUserPersonalDetails.email ?? '', }); }, }); @@ -512,6 +516,8 @@ function ReportDetailsPage({policy, report, route, reportMetadata}: ReportDetail amountOwed, ownerBillingGracePeriodEnd, transaction: iouTransaction, + currentUserAccountID: currentUserPersonalDetails.accountID, + currentUserEmail: currentUserPersonalDetails.email ?? '', }); }, }); diff --git a/src/pages/Travel/WorkspaceConfirmationForTravelPage.tsx b/src/pages/Travel/WorkspaceConfirmationForTravelPage.tsx index 186a2ddd5a0b..d463b75d1a40 100644 --- a/src/pages/Travel/WorkspaceConfirmationForTravelPage.tsx +++ b/src/pages/Travel/WorkspaceConfirmationForTravelPage.tsx @@ -30,7 +30,17 @@ function WorkspaceConfirmationForTravelPage({route}: WorkspaceConfirmationForTra }; const onSubmit = (params: WorkspaceConfirmationSubmitFunctionParams) => { - createDraftWorkspace(introSelected, params.name, '', false, params.policyID, params.currency, params.avatarFile as File); + createDraftWorkspace( + introSelected, + params.name, + currentUserPersonalDetails.accountID, + currentUserPersonalDetails.email ?? '', + '', + false, + params.policyID, + params.currency, + params.avatarFile as File, + ); createWorkspace({ policyName: params.name, policyID: params.policyID, diff --git a/src/pages/inbox/report/PureReportActionItem.tsx b/src/pages/inbox/report/PureReportActionItem.tsx index ca19344d56b7..c91888f402bd 100644 --- a/src/pages/inbox/report/PureReportActionItem.tsx +++ b/src/pages/inbox/report/PureReportActionItem.tsx @@ -976,6 +976,8 @@ function PureReportActionItem({ isRestrictedToPreferredPolicy, preferredPolicyID, transaction: trackExpenseTransaction, + currentUserAccountID: personalDetail.accountID, + currentUserEmail: personalDetail.email ?? '', }); }, }, @@ -998,6 +1000,8 @@ function PureReportActionItem({ amountOwed, ownerBillingGracePeriodEnd, transaction: trackExpenseTransaction, + currentUserAccountID: personalDetail.accountID, + currentUserEmail: personalDetail.email ?? '', }); }, }, @@ -1016,6 +1020,8 @@ function PureReportActionItem({ amountOwed, ownerBillingGracePeriodEnd, transaction: trackExpenseTransaction, + currentUserAccountID: personalDetail.accountID, + currentUserEmail: personalDetail.email ?? '', }); }, }, diff --git a/src/pages/iou/request/step/IOURequestStepAccountant.tsx b/src/pages/iou/request/step/IOURequestStepAccountant.tsx index 063ff756942d..221b52ec8f54 100644 --- a/src/pages/iou/request/step/IOURequestStepAccountant.tsx +++ b/src/pages/iou/request/step/IOURequestStepAccountant.tsx @@ -26,7 +26,7 @@ function IOURequestStepAccountant({ }, }: IOURequestStepAccountantProps) { const {translate} = useLocalize(); - const {login, email = ''} = useCurrentUserPersonalDetails(); + const {accountID, login, email = ''} = useCurrentUserPersonalDetails(); const selector = useCallback( (policies: OnyxCollection) => { return activeAdminPoliciesSelector(policies, login ?? ''); @@ -49,7 +49,14 @@ function IOURequestStepAccountant({ // Sharing with an accountant involves inviting them to the workspace and that requires admin access. const hasActiveAdminWorkspaces = (adminPolicies?.length ?? 0) > 0; if (!hasActiveAdminWorkspaces) { - createDraftWorkspaceAndNavigateToConfirmationScreen(introSelected, transactionID, action, newGenerateDefaultWorkspaceName(email, lastWorkspaceNumber, translate)); + createDraftWorkspaceAndNavigateToConfirmationScreen( + introSelected, + transactionID, + action, + newGenerateDefaultWorkspaceName(email, lastWorkspaceNumber, translate), + accountID, + email, + ); return; } diff --git a/src/pages/iou/request/step/IOURequestStepParticipants.tsx b/src/pages/iou/request/step/IOURequestStepParticipants.tsx index 9ab933c6b78b..66833eac23b3 100644 --- a/src/pages/iou/request/step/IOURequestStepParticipants.tsx +++ b/src/pages/iou/request/step/IOURequestStepParticipants.tsx @@ -336,7 +336,12 @@ function IOURequestStepParticipants({ if ((isCategorizing || isShareAction) && numberOfParticipants.current === 0) { const email = currentUserPersonalDetails.email ?? ''; const lastWorkspaceNumber = lastWorkspaceNumberSelector(allPolicies, email); - const {expenseChatReportID, policyID, policyName} = createDraftWorkspace(introSelected, newGenerateDefaultWorkspaceName(email, lastWorkspaceNumber, translate)); + const {expenseChatReportID, policyID, policyName} = createDraftWorkspace( + introSelected, + newGenerateDefaultWorkspaceName(email, lastWorkspaceNumber, translate), + currentUserPersonalDetails.accountID, + email, + ); for (const transaction of draftTransactions) { setMoneyRequestParticipants(transaction.transactionID, [ { @@ -392,6 +397,7 @@ function IOURequestStepParticipants({ participants, iouType, initialTransaction, + selfDMReportID, initialTransactionID, reportID, waitForKeyboardDismiss, @@ -399,10 +405,11 @@ function IOURequestStepParticipants({ isMovingTransactionFromTrackExpense, allPolicies, policyForMovingExpenses, + currentUserPersonalDetails.email, + currentUserPersonalDetails.accountID, introSelected, - backTo, - selfDMReportID, translate, + backTo, ], ); diff --git a/tests/actions/IOUTest.ts b/tests/actions/IOUTest.ts index 72f6fabdd640..1374b81b91a1 100644 --- a/tests/actions/IOUTest.ts +++ b/tests/actions/IOUTest.ts @@ -540,6 +540,8 @@ describe('actions/IOU', () => { userBillingGracePeriodEnds: undefined, amountOwed: 0, transaction: transactionToCategorize, + currentUserAccountID: RORY_ACCOUNT_ID, + currentUserEmail: RORY_EMAIL, }); await waitForBatchedUpdates(); @@ -588,6 +590,8 @@ describe('actions/IOU', () => { userBillingGracePeriodEnds: undefined, amountOwed: 0, transaction: originalTransaction, + currentUserAccountID: RORY_ACCOUNT_ID, + currentUserEmail: RORY_EMAIL, }); await waitForBatchedUpdates(); @@ -625,6 +629,8 @@ describe('actions/IOU', () => { userBillingGracePeriodEnds: undefined, amountOwed: 0, transaction: undefined, + currentUserAccountID: RORY_ACCOUNT_ID, + currentUserEmail: RORY_EMAIL, }); await waitForBatchedUpdates(); @@ -657,6 +663,8 @@ describe('actions/IOU', () => { transaction, userBillingGracePeriodEnds: undefined, amountOwed: 0, + currentUserAccountID: RORY_ACCOUNT_ID, + currentUserEmail: RORY_EMAIL, }); await waitForBatchedUpdates(); diff --git a/tests/actions/IOUTest/TrackExpenseTest.ts b/tests/actions/IOUTest/TrackExpenseTest.ts index b0e38be59db2..b0ab5679492d 100644 --- a/tests/actions/IOUTest/TrackExpenseTest.ts +++ b/tests/actions/IOUTest/TrackExpenseTest.ts @@ -268,6 +268,8 @@ describe('actions/IOU/TrackExpense', () => { userBillingGracePeriodEnds: undefined, amountOwed: 0, transaction, + currentUserAccountID: RORY_ACCOUNT_ID, + currentUserEmail: RORY_EMAIL, }); await waitForBatchedUpdates(); @@ -841,6 +843,8 @@ describe('actions/IOU/TrackExpense', () => { userBillingGracePeriodEnds: undefined, amountOwed: 0, transaction: createdTransaction, + currentUserAccountID: RORY_ACCOUNT_ID, + currentUserEmail: RORY_EMAIL, }); await waitForBatchedUpdates(); diff --git a/tests/actions/PolicyTest.ts b/tests/actions/PolicyTest.ts index eacc043faf22..f0f68b80dd2d 100644 --- a/tests/actions/PolicyTest.ts +++ b/tests/actions/PolicyTest.ts @@ -1924,7 +1924,16 @@ describe('actions/Policy', () => { await waitForBatchedUpdates(); const policyID = Policy.generatePolicyID(); - const params = Policy.createDraftWorkspace({choice: CONST.ONBOARDING_CHOICES.MANAGE_TEAM}, WORKSPACE_NAME, ESH_EMAIL, true, policyID, CONST.CURRENCY.USD); + const params = Policy.createDraftWorkspace( + {choice: CONST.ONBOARDING_CHOICES.MANAGE_TEAM}, + WORKSPACE_NAME, + ESH_ACCOUNT_ID, + ESH_EMAIL, + ESH_EMAIL, + true, + policyID, + CONST.CURRENCY.USD, + ); await waitForBatchedUpdates(); const draft = await getOnyxValue(`${ONYXKEYS.COLLECTION.POLICY_DRAFTS}${policyID}`); @@ -1952,7 +1961,7 @@ describe('actions/Policy', () => { await waitForBatchedUpdates(); const policyID = Policy.generatePolicyID(); - Policy.createDraftWorkspace({choice: CONST.ONBOARDING_CHOICES.TRACK_WORKSPACE}, WORKSPACE_NAME, ESH_EMAIL, false, policyID, CONST.CURRENCY.EUR); + Policy.createDraftWorkspace({choice: CONST.ONBOARDING_CHOICES.TRACK_WORKSPACE}, WORKSPACE_NAME, ESH_ACCOUNT_ID, ESH_EMAIL, ESH_EMAIL, false, policyID, CONST.CURRENCY.EUR); await waitForBatchedUpdates(); const draft = await getOnyxValue(`${ONYXKEYS.COLLECTION.POLICY_DRAFTS}${policyID}`); @@ -1963,6 +1972,37 @@ describe('actions/Policy', () => { expect(draft?.harvesting?.enabled).toBe(true); expect(draft?.outputCurrency).toBe(CONST.CURRENCY.EUR); }); + + it('should set owner, ownerAccountID, approver, and employeeList from explicit parameters instead of Onyx session', async () => { + // Set Onyx session to a DIFFERENT accountID/email to verify the explicit parameters are used + await Onyx.set(ONYXKEYS.SESSION, {email: ESH_EMAIL, accountID: ESH_ACCOUNT_ID}); + await waitForBatchedUpdates(); + + const customAccountID = 999; + const customEmail = 'custom@example.com'; + const policyID = Policy.generatePolicyID(); + + Policy.createDraftWorkspace({choice: CONST.ONBOARDING_CHOICES.MANAGE_TEAM}, WORKSPACE_NAME, customAccountID, customEmail, customEmail, false, policyID); + await waitForBatchedUpdates(); + + const draft = await getOnyxValue(`${ONYXKEYS.COLLECTION.POLICY_DRAFTS}${policyID}`); + + // Verify explicit params are used, not the Onyx session values + expect(draft?.owner).toBe(customEmail); + expect(draft?.ownerAccountID).toBe(customAccountID); + expect(draft?.approver).toBe(customEmail); + expect(draft?.employeeList?.[customEmail]).toEqual({ + submitsTo: customEmail, + email: customEmail, + role: CONST.POLICY.ROLE.ADMIN, + errors: {}, + }); + + // Verify the Onyx session values are NOT used + expect(draft?.owner).not.toBe(ESH_EMAIL); + expect(draft?.ownerAccountID).not.toBe(ESH_ACCOUNT_ID); + expect(draft?.employeeList?.[ESH_EMAIL]).toBeUndefined(); + }); }); describe('upgradeToCorporate', () => { diff --git a/tests/unit/ReportUtilsTest.ts b/tests/unit/ReportUtilsTest.ts index 061ada5226b5..566c75e288ea 100644 --- a/tests/unit/ReportUtilsTest.ts +++ b/tests/unit/ReportUtilsTest.ts @@ -13966,6 +13966,8 @@ describe('ReportUtils', () => { userBillingGracePeriodEnds: undefined, amountOwed: 0, transaction: undefined, + currentUserAccountID, + currentUserEmail, }); expect(Navigation.navigate).not.toHaveBeenCalled(); @@ -14005,6 +14007,8 @@ describe('ReportUtils', () => { amountOwed: 1, ownerBillingGracePeriodEnd: pastGracePeriod, transaction, + currentUserAccountID, + currentUserEmail, }); // Then it should navigate to the restricted action page @@ -14040,6 +14044,8 @@ describe('ReportUtils', () => { userBillingGracePeriodEnds, amountOwed: 0, transaction, + currentUserAccountID, + currentUserEmail, }); // Then it should navigate to the restricted action page @@ -14078,6 +14084,8 @@ describe('ReportUtils', () => { userBillingGracePeriodEnds: undefined, amountOwed: 0, transaction, + currentUserAccountID, + currentUserEmail, }); // Then it should navigate to the category step @@ -14118,6 +14126,8 @@ describe('ReportUtils', () => { userBillingGracePeriodEnds: undefined, amountOwed: 0, transaction, + currentUserAccountID, + currentUserEmail, }); // Then it should automatically pick the available policy and navigate to the category step @@ -14145,6 +14155,8 @@ describe('ReportUtils', () => { userBillingGracePeriodEnds: undefined, amountOwed: 0, transaction, + currentUserAccountID, + currentUserEmail, }); // Then it should navigate to the upgrade page because no policies were found to categorize with @@ -14193,6 +14205,8 @@ describe('ReportUtils', () => { userBillingGracePeriodEnds: undefined, amountOwed: 0, transaction, + currentUserAccountID, + currentUserEmail, }); // Then it should navigate to the upgrade page because it's ambiguous which policy to use @@ -14237,6 +14251,8 @@ describe('ReportUtils', () => { userBillingGracePeriodEnds: undefined, amountOwed: 0, transaction, + currentUserAccountID, + currentUserEmail, }); // Then it should log a warning and not navigate @@ -14281,6 +14297,8 @@ describe('ReportUtils', () => { amountOwed: 0, ownerBillingGracePeriodEnd: pastGracePeriod, transaction, + currentUserAccountID, + currentUserEmail, }); // Then it should NOT navigate to restricted action page, but to category step @@ -14317,6 +14335,8 @@ describe('ReportUtils', () => { amountOwed: 50, ownerBillingGracePeriodEnd: pastGracePeriod, transaction, + currentUserAccountID, + currentUserEmail, }); // Then it should navigate to restricted action page