diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index 174bc0d37b6..0520a952751 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -4168,10 +4168,10 @@ function buildOptimisticChangeFieldAction(reportField: PolicyReportField, previo * Builds an optimistic REIMBURSEMENT_DEQUEUED report action with a randomly generated reportActionID. * */ -function buildOptimisticCancelPaymentReportAction(expenseReportID: string, amount: number, currency: string): OptimisticCancelPaymentReportAction { +function buildOptimisticCancelPaymentReportAction(expenseReportID: string, amount: number, currency: string, currentUserAccountID: number): OptimisticCancelPaymentReportAction { return { actionName: CONST.REPORT.ACTIONS.TYPE.REIMBURSEMENT_DEQUEUED, - actorAccountID: deprecatedCurrentUserAccountID, + actorAccountID: currentUserAccountID, message: [ { cancellationReason: CONST.REPORT.CANCEL_PAYMENT_REASONS.ADMIN, @@ -7266,7 +7266,7 @@ function buildOptimisticIOUReportAction(params: BuildOptimisticIOUReportActionPa /** * Builds an optimistic APPROVED report action with a randomly generated reportActionID. */ -function buildOptimisticApprovedReportAction(amount: number, currency: string, expenseReportID: string): OptimisticApprovedReportAction { +function buildOptimisticApprovedReportAction(amount: number, currency: string, expenseReportID: string, currentUserAccountID: number): OptimisticApprovedReportAction { const originalMessage = { amount, currency, @@ -7276,7 +7276,7 @@ function buildOptimisticApprovedReportAction(amount: number, currency: string, e return { actionName: CONST.REPORT.ACTIONS.TYPE.APPROVED, - actorAccountID: deprecatedCurrentUserAccountID, + actorAccountID: currentUserAccountID, automatic: false, avatar: getCurrentUserAvatar(), isAttachmentOnly: false, @@ -8300,10 +8300,10 @@ function buildOptimisticEditedTaskFieldReportAction({title, description}: Task): }; } -function buildOptimisticCardAssignedReportAction(assigneeAccountID: number): OptimisticCardAssignedReportAction { +function buildOptimisticCardAssignedReportAction(assigneeAccountID: number, currentUserAccountID: number): OptimisticCardAssignedReportAction { return { actionName: CONST.REPORT.ACTIONS.TYPE.CARD_ASSIGNED, - actorAccountID: deprecatedCurrentUserAccountID, + actorAccountID: currentUserAccountID, avatar: getCurrentUserAvatar(), created: DateUtils.getDBTime(), originalMessage: {assigneeAccountID, cardID: -1}, diff --git a/src/libs/actions/CompanyCards.ts b/src/libs/actions/CompanyCards.ts index 4439218ab5e..c10f3cd381c 100644 --- a/src/libs/actions/CompanyCards.ts +++ b/src/libs/actions/CompanyCards.ts @@ -317,13 +317,19 @@ function deleteWorkspaceCompanyCardFeed( API.write(WRITE_COMMANDS.DELETE_COMPANY_CARD_FEED, parameters, {optimisticData, successData, failureData}); } -function assignWorkspaceCompanyCard(policy: OnyxEntry, domainOrWorkspaceAccountID: number, translate: LocaleContextProps['translate'], data: Partial) { +function assignWorkspaceCompanyCard( + policy: OnyxEntry, + domainOrWorkspaceAccountID: number, + translate: LocaleContextProps['translate'], + data: Partial, + currentUserAccountID: number, +) { if (!policy?.id) { return; } const {bankName, email = '', encryptedCardNumber = '', startDate = '', customCardName = ''} = data; const assigneeDetails = PersonalDetailsUtils.getPersonalDetailByEmail(email); - const optimisticCardAssignedReportAction = ReportUtils.buildOptimisticCardAssignedReportAction(assigneeDetails?.accountID ?? CONST.DEFAULT_NUMBER_ID); + const optimisticCardAssignedReportAction = ReportUtils.buildOptimisticCardAssignedReportAction(assigneeDetails?.accountID ?? CONST.DEFAULT_NUMBER_ID, currentUserAccountID); const parameters: AssignCompanyCardParams = { domainAccountID: domainOrWorkspaceAccountID, diff --git a/src/libs/actions/IOU/index.ts b/src/libs/actions/IOU/index.ts index d6a63ac7636..314d5b5a0ac 100644 --- a/src/libs/actions/IOU/index.ts +++ b/src/libs/actions/IOU/index.ts @@ -9921,7 +9921,7 @@ function approveMoneyRequest(params: ApproveMoneyRequestFunctionParams) { if (hasHeldExpenses && !full && !!expenseReport.unheldTotal) { total = expenseReport.unheldTotal; } - const optimisticApprovedReportAction = buildOptimisticApprovedReportAction(total, expenseReport.currency ?? '', expenseReport.reportID); + const optimisticApprovedReportAction = buildOptimisticApprovedReportAction(total, expenseReport.currency ?? '', expenseReport.reportID, currentUserAccountIDParam); const isDEWPolicy = hasDynamicExternalWorkflow(policy); const shouldAddOptimisticApproveAction = !isDEWPolicy || isOffline(); @@ -11079,6 +11079,7 @@ function cancelPayment( expenseReport.reportID, -((expenseReport.total ?? 0) - (expenseReport?.nonReimbursableTotal ?? 0)), expenseReport.currency ?? '', + currentUserAccountIDParam, ); const approvalMode = policy?.approvalMode ?? CONST.POLICY.APPROVAL_MODE.BASIC; diff --git a/src/pages/workspace/companyCards/assignCard/ConfirmationStep.tsx b/src/pages/workspace/companyCards/assignCard/ConfirmationStep.tsx index e9c71c8d091..1fc637b484d 100644 --- a/src/pages/workspace/companyCards/assignCard/ConfirmationStep.tsx +++ b/src/pages/workspace/companyCards/assignCard/ConfirmationStep.tsx @@ -10,6 +10,7 @@ import ScrollView from '@components/ScrollView'; import Text from '@components/Text'; import useCardFeeds from '@hooks/useCardFeeds'; import {useCurrencyListState} from '@hooks/useCurrencyList'; +import useCurrentUserPersonalDetails from '@hooks/useCurrentUserPersonalDetails'; import useLocalize from '@hooks/useLocalize'; import useNetwork from '@hooks/useNetwork'; import useOnyx from '@hooks/useOnyx'; @@ -69,6 +70,9 @@ function ConfirmationStep({route}: ConfirmationStepProps) { const cardholderEmail = Str.removeSMSDomain(cardToAssign?.email ?? ''); const cardholderAccountID = cardholder?.accountID; + const currentUserPersonalDetails = useCurrentUserPersonalDetails(); + const currentUserAccountID = currentUserPersonalDetails.accountID; + useEffect(() => { if (!assignCard?.isAssignmentFinished) { return; @@ -112,7 +116,7 @@ function ConfirmationStep({route}: ConfirmationStepProps) { return; } - assignWorkspaceCompanyCard(policy, domainOrWorkspaceAccountID, translate, {...cardToAssign, cardholder, bankName}); + assignWorkspaceCompanyCard(policy, domainOrWorkspaceAccountID, translate, {...cardToAssign, cardholder, bankName}, currentUserAccountID); }; const editStep = (step: string) => { diff --git a/tests/unit/ReportUtilsTest.ts b/tests/unit/ReportUtilsTest.ts index bdd2593d62f..74a1026f016 100644 --- a/tests/unit/ReportUtilsTest.ts +++ b/tests/unit/ReportUtilsTest.ts @@ -32,6 +32,9 @@ import {getOriginalMessage, getReportAction, isWhisperAction} from '@libs/Report import {buildReportNameFromParticipantNames, computeReportName as computeReportNameOriginal, getGroupChatName, getPolicyExpenseChatName, getReportName} from '@libs/ReportNameUtils'; import type {OptionData} from '@libs/ReportUtils'; import { + buildOptimisticApprovedReportAction, + buildOptimisticCancelPaymentReportAction, + buildOptimisticCardAssignedReportAction, buildOptimisticChatReport, buildOptimisticCreatedReportAction, buildOptimisticCreatedReportForUnapprovedAction, @@ -14881,4 +14884,116 @@ describe('ReportUtils', () => { expect(details?.taxValue).toBe('10%'); }); }); + + describe('buildOptimisticApprovedReportAction', () => { + it('should set actorAccountID to the provided currentUserAccountID', () => { + const customAccountID = 99; + const action = buildOptimisticApprovedReportAction(500, 'USD', 'expenseReport1', customAccountID); + + expect(action.actorAccountID).toBe(customAccountID); + }); + + it('should set actionName to APPROVED', () => { + const action = buildOptimisticApprovedReportAction(500, 'USD', 'expenseReport1', currentUserAccountID); + + expect(action.actionName).toBe(CONST.REPORT.ACTIONS.TYPE.APPROVED); + }); + + it('should set originalMessage with the provided amount, currency, and expenseReportID', () => { + const amount = 1200; + const currency = 'EUR'; + const expenseReportID = 'report42'; + const action = buildOptimisticApprovedReportAction(amount, currency, expenseReportID, currentUserAccountID); + + expect(getOriginalMessage(action as ReportAction)).toMatchObject({amount, currency, expenseReportID}); + }); + + it('should set pendingAction to ADD', () => { + const action = buildOptimisticApprovedReportAction(500, 'USD', 'expenseReport1', currentUserAccountID); + + expect(action.pendingAction).toBe(CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD); + }); + + it('should generate a non-empty reportActionID', () => { + const action = buildOptimisticApprovedReportAction(500, 'USD', 'expenseReport1', currentUserAccountID); + + expect(action.reportActionID).toBeTruthy(); + }); + }); + + describe('buildOptimisticCancelPaymentReportAction', () => { + it('should set actorAccountID to the provided currentUserAccountID', () => { + const customAccountID = 77; + const action = buildOptimisticCancelPaymentReportAction('expenseReport2', 300, 'USD', customAccountID); + + expect(action.actorAccountID).toBe(customAccountID); + }); + + it('should set actionName to REIMBURSEMENT_DEQUEUED', () => { + const action = buildOptimisticCancelPaymentReportAction('expenseReport2', 300, 'USD', currentUserAccountID); + + expect(action.actionName).toBe(CONST.REPORT.ACTIONS.TYPE.REIMBURSEMENT_DEQUEUED); + }); + + it('should set originalMessage with the provided expenseReportID, amount, currency, and cancellationReason', () => { + const expenseReportID = 'report55'; + const amount = 750; + const currency = 'GBP'; + const action = buildOptimisticCancelPaymentReportAction(expenseReportID, amount, currency, currentUserAccountID); + + expect(getOriginalMessage(action as ReportAction)).toMatchObject({ + expenseReportID, + amount, + currency, + cancellationReason: CONST.REPORT.CANCEL_PAYMENT_REASONS.ADMIN, + }); + }); + + it('should set pendingAction to ADD', () => { + const action = buildOptimisticCancelPaymentReportAction('expenseReport2', 300, 'USD', currentUserAccountID); + + expect(action.pendingAction).toBe(CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD); + }); + + it('should generate a non-empty reportActionID', () => { + const action = buildOptimisticCancelPaymentReportAction('expenseReport2', 300, 'USD', currentUserAccountID); + + expect(action.reportActionID).toBeTruthy(); + }); + }); + + describe('buildOptimisticCardAssignedReportAction', () => { + it('should set actorAccountID to the provided currentUserAccountID', () => { + const assigneeAccountID = 10; + const customAccountID = 88; + const action = buildOptimisticCardAssignedReportAction(assigneeAccountID, customAccountID); + + expect(action.actorAccountID).toBe(customAccountID); + }); + + it('should set actionName to CARD_ASSIGNED', () => { + const action = buildOptimisticCardAssignedReportAction(10, currentUserAccountID); + + expect(action.actionName).toBe(CONST.REPORT.ACTIONS.TYPE.CARD_ASSIGNED); + }); + + it('should set originalMessage with the provided assigneeAccountID', () => { + const assigneeAccountID = 42; + const action = buildOptimisticCardAssignedReportAction(assigneeAccountID, currentUserAccountID); + + expect(getOriginalMessage(action as ReportAction)).toMatchObject({assigneeAccountID}); + }); + + it('should set pendingAction to ADD', () => { + const action = buildOptimisticCardAssignedReportAction(10, currentUserAccountID); + + expect(action.pendingAction).toBe(CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD); + }); + + it('should generate a non-empty reportActionID', () => { + const action = buildOptimisticCardAssignedReportAction(10, currentUserAccountID); + + expect(action.reportActionID).toBeTruthy(); + }); + }); });