From 4148cd2745f196a907f36c1e83edca2b6f822b61 Mon Sep 17 00:00:00 2001 From: Wiktor Gut Date: Wed, 25 Feb 2026 11:20:37 +0100 Subject: [PATCH 1/6] add tests --- tests/actions/IOUTest/SplitTest.ts | 78 ++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) diff --git a/tests/actions/IOUTest/SplitTest.ts b/tests/actions/IOUTest/SplitTest.ts index 0e95917164ee1..9a994b4688a0f 100644 --- a/tests/actions/IOUTest/SplitTest.ts +++ b/tests/actions/IOUTest/SplitTest.ts @@ -1263,6 +1263,84 @@ describe('startSplitBill', () => { expect(newPolicyRecentlyUsedTags[tagName].length).toBe(2); expect(newPolicyRecentlyUsedTags[tagName].at(0)).toBe(transactionTag); }); + + it('should return splitTransactionID and create the transaction in Onyx with correct values', async () => { + // Given a participant + const policyID = 'A'; + const testComment = 'Test split comment'; + const testCategory = 'Food'; + const testCurrency = CONST.CURRENCY.USD; + + // When starting a split bill + const {splitTransactionID} = startSplitBill({ + participants: [{isPolicyExpenseChat: true, policyID, accountID: RORY_ACCOUNT_ID}], + currentUserLogin: currentUserPersonalDetails.login ?? '', + currentUserAccountID: currentUserPersonalDetails.accountID, + comment: testComment, + receipt: {}, + category: testCategory, + tag: '', + currency: testCurrency, + taxCode: '', + taxAmount: 0, + quickAction: undefined, + policyRecentlyUsedCurrencies: [], + policyRecentlyUsedTags: undefined, + }); + + await waitForBatchedUpdates(); + + // Then the returned splitTransactionID should be defined + expect(splitTransactionID).toBeDefined(); + + // And the transaction should be created in Onyx with correct values + const createdTransaction = await getOnyxValue(`${ONYXKEYS.COLLECTION.TRANSACTION}${splitTransactionID}`); + expect(createdTransaction).toBeDefined(); + expect(createdTransaction?.transactionID).toBe(splitTransactionID); + expect(createdTransaction?.comment?.comment).toBe(testComment); + expect(createdTransaction?.category).toBe(testCategory); + expect(createdTransaction?.currency).toBe(testCurrency); + expect(createdTransaction?.merchant).toBe(CONST.TRANSACTION.PARTIAL_TRANSACTION_MERCHANT); + expect(createdTransaction?.reportID).toBe(CONST.REPORT.SPLIT_REPORT_ID); + }); + + it('should update NVP_QUICK_ACTION_GLOBAL_CREATE with SPLIT_SCAN action', async () => { + // Given an existing quick action + const policyID = 'B'; + const existingQuickAction = { + action: CONST.QUICK_ACTIONS.REQUEST_MANUAL, + chatReportID: '12345', + }; + + await Onyx.merge(ONYXKEYS.NVP_QUICK_ACTION_GLOBAL_CREATE, existingQuickAction); + + // When starting a split bill + const {splitTransactionID} = startSplitBill({ + participants: [{isPolicyExpenseChat: true, policyID, accountID: RORY_ACCOUNT_ID}], + currentUserLogin: currentUserPersonalDetails.login ?? '', + currentUserAccountID: currentUserPersonalDetails.accountID, + comment: '', + receipt: {}, + category: '', + tag: '', + currency: CONST.CURRENCY.USD, + taxCode: '', + taxAmount: 0, + quickAction: existingQuickAction, + policyRecentlyUsedCurrencies: [], + policyRecentlyUsedTags: undefined, + }); + + await waitForBatchedUpdates(); + + expect(splitTransactionID).toBeDefined(); + + // Then NVP_QUICK_ACTION_GLOBAL_CREATE should be updated with SPLIT_SCAN action + const quickAction = await getOnyxValue(ONYXKEYS.NVP_QUICK_ACTION_GLOBAL_CREATE); + expect(quickAction?.action).toBe(CONST.QUICK_ACTIONS.SPLIT_SCAN); + expect(quickAction?.chatReportID).toBeDefined(); + expect(quickAction?.isFirstQuickAction).toBe(false); + }); }); describe('updateSplitTransactionsFromSplitExpensesFlow', () => { From 7d441b59fc811744bb10ab51c9346d139a097533 Mon Sep 17 00:00:00 2001 From: Wiktor Gut Date: Wed, 25 Feb 2026 13:36:45 +0100 Subject: [PATCH 2/6] move getPolicyTags one level higher --- src/libs/actions/IOU/MoneyRequest.ts | 2 ++ src/libs/actions/IOU/Split.ts | 6 +++--- src/libs/actions/IOU/index.ts | 1 + .../step/IOURequestStepConfirmation.tsx | 3 +++ tests/actions/IOUTest.ts | 20 +++++++++++++++++++ 5 files changed, 29 insertions(+), 3 deletions(-) diff --git a/src/libs/actions/IOU/MoneyRequest.ts b/src/libs/actions/IOU/MoneyRequest.ts index b66bd1a50dbf2..6a779d19419ff 100644 --- a/src/libs/actions/IOU/MoneyRequest.ts +++ b/src/libs/actions/IOU/MoneyRequest.ts @@ -26,6 +26,7 @@ import type {GpsPoint} from './index'; import { createDistanceRequest, getMoneyRequestParticipantsFromReport, + getPolicyTags, getRecentWaypoints, requestMoney, setCustomUnitRateID, @@ -355,6 +356,7 @@ function handleMoneyRequestStepScanParticipants({ policyRecentlyUsedCurrencies: policyRecentlyUsedCurrencies ?? [], // No need to update recently used tags because no tags are used when the confirmation step is skipped policyRecentlyUsedTags: undefined, + allPolicyTags: getPolicyTags(), }); return; } diff --git a/src/libs/actions/IOU/Split.ts b/src/libs/actions/IOU/Split.ts index b0536bbd5a815..9a5b3f9b97a6e 100644 --- a/src/libs/actions/IOU/Split.ts +++ b/src/libs/actions/IOU/Split.ts @@ -363,6 +363,7 @@ function startSplitBill({ policyRecentlyUsedTags, quickAction, policyRecentlyUsedCurrencies, + allPolicyTags, }: StartSplitBilActionParams) { const currentUserEmailForIOUSplit = addSMSDomainIfPhoneNumber(currentUserLogin); const participantAccountIDs = participants.map((participant) => Number(participant.accountID)); @@ -546,6 +547,7 @@ function startSplitBill({ quickAction, policyRecentlyUsedCurrencies, policyRecentlyUsedTags, + allPolicyTags, }; if (existingSplitChatReport) { @@ -639,9 +641,7 @@ function startSplitBill({ } const optimisticPolicyRecentlyUsedCategories = mergePolicyRecentlyUsedCategories(category, policyRecentlyUsedCategories); const optimisticPolicyRecentlyUsedTags = buildOptimisticPolicyRecentlyUsedTags({ - // TODO: remove `allPolicyTags` from this file [https://github.com/Expensify/App/issues/80401] - // eslint-disable-next-line @typescript-eslint/no-deprecated - policyTags: getPolicyTagsData(participant.policyID), + policyTags: allPolicyTags?.[`${ONYXKEYS.COLLECTION.POLICY_TAGS}${participant.policyID}`] ?? {}, policyRecentlyUsedTags, transactionTags: tag, }); diff --git a/src/libs/actions/IOU/index.ts b/src/libs/actions/IOU/index.ts index af4cc2fad5a4a..5064a00d85fe7 100644 --- a/src/libs/actions/IOU/index.ts +++ b/src/libs/actions/IOU/index.ts @@ -830,6 +830,7 @@ type StartSplitBilActionParams = { policyRecentlyUsedTags: OnyxEntry; quickAction: OnyxEntry; policyRecentlyUsedCurrencies: string[]; + allPolicyTags: OnyxCollection; }; type ReplaceReceipt = { diff --git a/src/pages/iou/request/step/IOURequestStepConfirmation.tsx b/src/pages/iou/request/step/IOURequestStepConfirmation.tsx index ce97f7cb18966..ba52e7e42cb80 100644 --- a/src/pages/iou/request/step/IOURequestStepConfirmation.tsx +++ b/src/pages/iou/request/step/IOURequestStepConfirmation.tsx @@ -202,6 +202,7 @@ function IOURequestStepConfirmation({ const [policyCategoriesDraft] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY_CATEGORIES_DRAFT}${draftPolicyID}`); const [policyRecentlyUsedCategories] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY_RECENTLY_USED_CATEGORIES}${policyID}`); + const [allPolicyTags] = useOnyx(ONYXKEYS.COLLECTION.POLICY_TAGS); const [policyTags] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY_TAGS}${policyID}`); const [policyRecentlyUsedTags] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY_RECENTLY_USED_TAGS}${policyID}`); const [policyRecentlyUsedCurrencies] = useOnyx(ONYXKEYS.RECENTLY_USED_CURRENCIES); @@ -1047,6 +1048,7 @@ function IOURequestStepConfirmation({ policyRecentlyUsedTags, quickAction, policyRecentlyUsedCurrencies: policyRecentlyUsedCurrencies ?? [], + allPolicyTags, }); } } @@ -1270,6 +1272,7 @@ function IOURequestStepConfirmation({ reportID, requestType, betas, + allPolicyTags, ], ); diff --git a/tests/actions/IOUTest.ts b/tests/actions/IOUTest.ts index 92a3c04f51cc5..27a06af400ba9 100644 --- a/tests/actions/IOUTest.ts +++ b/tests/actions/IOUTest.ts @@ -5474,6 +5474,15 @@ describe('actions/IOU', () => { }, }); + let allPolicyTags: OnyxCollection; + await getOnyxData({ + waitForCollectionCallback: true, + key: `${ONYXKEYS.COLLECTION.POLICY_TAGS}`, + callback: (tags) => { + allPolicyTags = tags; + }, + }); + // Start a scan split bill const {splitTransactionID} = startSplitBill({ participants: [{accountID: CARLOS_ACCOUNT_ID, login: CARLOS_EMAIL}], @@ -5490,6 +5499,7 @@ describe('actions/IOU', () => { quickAction: undefined, policyRecentlyUsedCurrencies: [], policyRecentlyUsedTags: undefined, + allPolicyTags, }); await waitForBatchedUpdates(); @@ -5690,6 +5700,15 @@ describe('actions/IOU', () => { }); await Onyx.merge(`${ONYXKEYS.COLLECTION.POLICY_RECENTLY_USED_TAGS}${policyID}`, policyRecentlyUsedTags); + let allPolicyTags: OnyxCollection; + await getOnyxData({ + waitForCollectionCallback: true, + key: `${ONYXKEYS.COLLECTION.POLICY_TAGS}`, + callback: (tags) => { + allPolicyTags = tags; + }, + }); + // When doing a split bill with a receipt startSplitBill({ participants: [{isPolicyExpenseChat: true, policyID}], @@ -5705,6 +5724,7 @@ describe('actions/IOU', () => { policyRecentlyUsedTags, quickAction: {}, policyRecentlyUsedCurrencies: [], + allPolicyTags, }); waitForBatchedUpdates(); From 370790c544b2af3aa2b7fb701c61a9996ab0959f Mon Sep 17 00:00:00 2001 From: Wiktor Gut Date: Wed, 25 Feb 2026 15:35:15 +0100 Subject: [PATCH 3/6] fix tests --- tests/actions/IOUTest/SplitTest.ts | 33 +++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/tests/actions/IOUTest/SplitTest.ts b/tests/actions/IOUTest/SplitTest.ts index 9a994b4688a0f..99d1dd2b3e264 100644 --- a/tests/actions/IOUTest/SplitTest.ts +++ b/tests/actions/IOUTest/SplitTest.ts @@ -30,7 +30,7 @@ import CONST from '@src/CONST'; import IntlStore from '@src/languages/IntlStore'; import DateUtils from '@src/libs/DateUtils'; import ONYXKEYS from '@src/ONYXKEYS'; -import type {Policy, RecentlyUsedTags, Report, ReportNameValuePairs, SearchResults} from '@src/types/onyx'; +import type {Policy, PolicyTagLists, RecentlyUsedTags, Report, ReportNameValuePairs, SearchResults} from '@src/types/onyx'; import type {Participant as IOUParticipant, SplitExpense} from '@src/types/onyx/IOU'; import type {CurrentUserPersonalDetails} from '@src/types/onyx/PersonalDetails'; import type {Participant} from '@src/types/onyx/Report'; @@ -1017,6 +1017,15 @@ describe('split expense', () => { }, }); + let allPolicyTags: OnyxCollection; + await getOnyxData({ + key: `${ONYXKEYS.COLLECTION.POLICY_TAGS}`, + waitForCollectionCallback: true, + callback: (value) => { + allPolicyTags = value; + }, + }); + // Start a scan split bill const {splitTransactionID} = startSplitBill({ participants: [{accountID: CARLOS_ACCOUNT_ID, login: CARLOS_EMAIL}], @@ -1033,6 +1042,7 @@ describe('split expense', () => { quickAction: undefined, policyRecentlyUsedCurrencies: [], policyRecentlyUsedTags: undefined, + allPolicyTags, }); await waitForBatchedUpdates(); @@ -1217,6 +1227,16 @@ describe('split expense', () => { }); describe('startSplitBill', () => { + let allPolicyTags: OnyxCollection; + beforeEach(async () => { + await getOnyxData({ + key: `${ONYXKEYS.COLLECTION.POLICY_TAGS}`, + waitForCollectionCallback: true, + callback: (value) => { + allPolicyTags = value; + }, + }); + }); it('should update the policyRecentlyUsedTags when tag is provided', async () => { // Given a policy recently used tags const policyID = 'A'; @@ -1231,6 +1251,14 @@ describe('startSplitBill', () => { }); await Onyx.merge(`${ONYXKEYS.COLLECTION.POLICY_RECENTLY_USED_TAGS}${policyID}`, policyRecentlyUsedTags); + await getOnyxData({ + key: `${ONYXKEYS.COLLECTION.POLICY_TAGS}`, + waitForCollectionCallback: true, + callback: (value) => { + allPolicyTags = value; + }, + }); + // When doing a split bill with a receipt startSplitBill({ participants: [{isPolicyExpenseChat: true, policyID}], @@ -1246,6 +1274,7 @@ describe('startSplitBill', () => { policyRecentlyUsedTags, quickAction: {}, policyRecentlyUsedCurrencies: [], + allPolicyTags, }); waitForBatchedUpdates(); @@ -1286,6 +1315,7 @@ describe('startSplitBill', () => { quickAction: undefined, policyRecentlyUsedCurrencies: [], policyRecentlyUsedTags: undefined, + allPolicyTags, }); await waitForBatchedUpdates(); @@ -1329,6 +1359,7 @@ describe('startSplitBill', () => { quickAction: existingQuickAction, policyRecentlyUsedCurrencies: [], policyRecentlyUsedTags: undefined, + allPolicyTags, }); await waitForBatchedUpdates(); From bdabc84a84cd80238191cd113150f33562eaac41 Mon Sep 17 00:00:00 2001 From: Wiktor Gut Date: Wed, 4 Mar 2026 13:23:46 +0100 Subject: [PATCH 4/6] pass only participantsPolicyTags --- src/libs/actions/IOU/MoneyRequest.ts | 24 ++++++++- src/libs/actions/IOU/Split.ts | 6 +-- src/libs/actions/IOU/index.ts | 2 +- tests/actions/IOUTest.ts | 30 +++++++---- tests/actions/IOUTest/SplitTest.ts | 81 +++++++++++++++++++--------- 5 files changed, 104 insertions(+), 39 deletions(-) diff --git a/src/libs/actions/IOU/MoneyRequest.ts b/src/libs/actions/IOU/MoneyRequest.ts index dafef50d9c7a3..d95e3cc3028de 100644 --- a/src/libs/actions/IOU/MoneyRequest.ts +++ b/src/libs/actions/IOU/MoneyRequest.ts @@ -16,9 +16,22 @@ import {setTransactionReport} from '@userActions/Transaction'; import type {IOUType} from '@src/CONST'; import CONST from '@src/CONST'; import type {TranslationParameters, TranslationPaths} from '@src/languages/types'; +import ONYXKEYS from '@src/ONYXKEYS'; import type {Route} from '@src/ROUTES'; import ROUTES from '@src/ROUTES'; -import type {Beta, IntroSelected, LastSelectedDistanceRates, PersonalDetailsList, Policy, QuickAction, RecentWaypoint, Report, Transaction, TransactionViolation} from '@src/types/onyx'; +import type { + Beta, + IntroSelected, + LastSelectedDistanceRates, + PersonalDetailsList, + Policy, + PolicyTagLists, + QuickAction, + RecentWaypoint, + Report, + Transaction, + TransactionViolation, +} from '@src/types/onyx'; import type {ReportAttributes, ReportAttributesDerivedValue} from '@src/types/onyx/DerivedValues'; import type {Participant} from '@src/types/onyx/IOU'; import type {Unit} from '@src/types/onyx/Policy'; @@ -356,6 +369,13 @@ function handleMoneyRequestStepScanParticipants({ const splitReceipt: Receipt = firstReceiptFile.file ?? {}; splitReceipt.source = firstReceiptFile.source; splitReceipt.state = CONST.IOU.RECEIPT_STATE.SCAN_READY; + const allPolicyTags: OnyxCollection = getPolicyTags(); + const participantsPolicyTags = participants.reduce>((acc, participant) => { + if (participant.policyID) { + acc[participant.policyID] = allPolicyTags?.[`${ONYXKEYS.COLLECTION.POLICY_TAGS}${participant.policyID}`] ?? {}; + } + return acc; + }, {}); startSplitBill({ participants, currentUserLogin: currentUserLogin ?? '', @@ -373,7 +393,7 @@ function handleMoneyRequestStepScanParticipants({ policyRecentlyUsedCurrencies: policyRecentlyUsedCurrencies ?? [], // No need to update recently used tags because no tags are used when the confirmation step is skipped policyRecentlyUsedTags: undefined, - allPolicyTags: getPolicyTags(), + participantsPolicyTags, }); return; } diff --git a/src/libs/actions/IOU/Split.ts b/src/libs/actions/IOU/Split.ts index 361982cfde3be..db4d4ec71b799 100644 --- a/src/libs/actions/IOU/Split.ts +++ b/src/libs/actions/IOU/Split.ts @@ -363,7 +363,7 @@ function startSplitBill({ policyRecentlyUsedTags, quickAction, policyRecentlyUsedCurrencies, - allPolicyTags, + participantsPolicyTags, }: StartSplitBilActionParams) { const currentUserEmailForIOUSplit = addSMSDomainIfPhoneNumber(currentUserLogin); const participantAccountIDs = participants.map((participant) => Number(participant.accountID)); @@ -547,7 +547,7 @@ function startSplitBill({ quickAction, policyRecentlyUsedCurrencies, policyRecentlyUsedTags, - allPolicyTags, + participantsPolicyTags, }; if (existingSplitChatReport) { @@ -641,7 +641,7 @@ function startSplitBill({ } const optimisticPolicyRecentlyUsedCategories = mergePolicyRecentlyUsedCategories(category, policyRecentlyUsedCategories); const optimisticPolicyRecentlyUsedTags = buildOptimisticPolicyRecentlyUsedTags({ - policyTags: allPolicyTags?.[`${ONYXKEYS.COLLECTION.POLICY_TAGS}${participant.policyID}`] ?? {}, + policyTags: participant.policyID ? participantsPolicyTags[participant.policyID] : {}, policyRecentlyUsedTags, transactionTags: tag, }); diff --git a/src/libs/actions/IOU/index.ts b/src/libs/actions/IOU/index.ts index 57ea5f877f8c1..479d5794befb8 100644 --- a/src/libs/actions/IOU/index.ts +++ b/src/libs/actions/IOU/index.ts @@ -835,7 +835,7 @@ type StartSplitBilActionParams = { policyRecentlyUsedTags: OnyxEntry; quickAction: OnyxEntry; policyRecentlyUsedCurrencies: string[]; - allPolicyTags: OnyxCollection; + participantsPolicyTags: Record; }; type ReplaceReceipt = { diff --git a/tests/actions/IOUTest.ts b/tests/actions/IOUTest.ts index 1c4bb69db43d6..8612a9af1482c 100644 --- a/tests/actions/IOUTest.ts +++ b/tests/actions/IOUTest.ts @@ -84,7 +84,7 @@ import * as SearchQueryUtils from '@src/libs/SearchQueryUtils'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; import type {IntroSelected, PersonalDetailsList, Policy, PolicyTagLists, RecentlyUsedTags, RecentWaypoint, Report, ReportNameValuePairs, SearchResults} from '@src/types/onyx'; -import type {Accountant, Attendee, SplitExpense} from '@src/types/onyx/IOU'; +import type {Accountant, Attendee, Participant as IOUParticipant, SplitExpense} from '@src/types/onyx/IOU'; import type {CurrentUserPersonalDetails} from '@src/types/onyx/PersonalDetails'; import type {Participant} from '@src/types/onyx/Report'; import type ReportAction from '@src/types/onyx/ReportAction'; @@ -5514,18 +5514,24 @@ describe('actions/IOU', () => { }, }); - let allPolicyTags: OnyxCollection; + const participants: IOUParticipant[] = [{accountID: CARLOS_ACCOUNT_ID, login: CARLOS_EMAIL}]; + let participantsPolicyTags: Record = {}; await getOnyxData({ waitForCollectionCallback: true, key: `${ONYXKEYS.COLLECTION.POLICY_TAGS}`, callback: (tags) => { - allPolicyTags = tags; + participantsPolicyTags = participants.reduce>((acc, participant) => { + if (participant.policyID) { + acc[participant.policyID] = tags?.[`${ONYXKEYS.COLLECTION.POLICY_TAGS}${participant.policyID}`] ?? {}; + } + return acc; + }, {}); }, }); // Start a scan split bill const {splitTransactionID} = startSplitBill({ - participants: [{accountID: CARLOS_ACCOUNT_ID, login: CARLOS_EMAIL}], + participants, currentUserLogin: RORY_EMAIL, currentUserAccountID: RORY_ACCOUNT_ID, comment: '# test', @@ -5539,7 +5545,7 @@ describe('actions/IOU', () => { quickAction: undefined, policyRecentlyUsedCurrencies: [], policyRecentlyUsedTags: undefined, - allPolicyTags, + participantsPolicyTags, }); await waitForBatchedUpdates(); @@ -5740,18 +5746,24 @@ describe('actions/IOU', () => { }); await Onyx.merge(`${ONYXKEYS.COLLECTION.POLICY_RECENTLY_USED_TAGS}${policyID}`, policyRecentlyUsedTags); - let allPolicyTags: OnyxCollection; + const participants: IOUParticipant[] = [{isPolicyExpenseChat: true, policyID}]; + let participantsPolicyTags: Record = {}; await getOnyxData({ waitForCollectionCallback: true, key: `${ONYXKEYS.COLLECTION.POLICY_TAGS}`, callback: (tags) => { - allPolicyTags = tags; + participantsPolicyTags = participants.reduce>((acc, participant) => { + if (participant.policyID) { + acc[participant.policyID] = tags?.[`${ONYXKEYS.COLLECTION.POLICY_TAGS}${participant.policyID}`] ?? {}; + } + return acc; + }, {}); }, }); // When doing a split bill with a receipt startSplitBill({ - participants: [{isPolicyExpenseChat: true, policyID}], + participants, currentUserLogin: currentUserPersonalDetails.login ?? '', currentUserAccountID: currentUserPersonalDetails.accountID, comment: '', @@ -5764,7 +5776,7 @@ describe('actions/IOU', () => { policyRecentlyUsedTags, quickAction: {}, policyRecentlyUsedCurrencies: [], - allPolicyTags, + participantsPolicyTags, }); waitForBatchedUpdates(); diff --git a/tests/actions/IOUTest/SplitTest.ts b/tests/actions/IOUTest/SplitTest.ts index 01053c055a621..df845c7f425a6 100644 --- a/tests/actions/IOUTest/SplitTest.ts +++ b/tests/actions/IOUTest/SplitTest.ts @@ -1017,12 +1017,18 @@ describe('split expense', () => { }, }); - let allPolicyTags: OnyxCollection; + const participants: IOUParticipant[] = [{accountID: CARLOS_ACCOUNT_ID, login: CARLOS_EMAIL}]; + let participantsPolicyTags: Record = {}; await getOnyxData({ - key: `${ONYXKEYS.COLLECTION.POLICY_TAGS}`, waitForCollectionCallback: true, - callback: (value) => { - allPolicyTags = value; + key: `${ONYXKEYS.COLLECTION.POLICY_TAGS}`, + callback: (tags) => { + participantsPolicyTags = participants.reduce>((acc, participant) => { + if (participant.policyID) { + acc[participant.policyID] = tags?.[`${ONYXKEYS.COLLECTION.POLICY_TAGS}${participant.policyID}`] ?? {}; + } + return acc; + }, {}); }, }); @@ -1042,7 +1048,7 @@ describe('split expense', () => { quickAction: undefined, policyRecentlyUsedCurrencies: [], policyRecentlyUsedTags: undefined, - allPolicyTags, + participantsPolicyTags, }); await waitForBatchedUpdates(); @@ -1227,16 +1233,6 @@ describe('split expense', () => { }); describe('startSplitBill', () => { - let allPolicyTags: OnyxCollection; - beforeEach(async () => { - await getOnyxData({ - key: `${ONYXKEYS.COLLECTION.POLICY_TAGS}`, - waitForCollectionCallback: true, - callback: (value) => { - allPolicyTags = value; - }, - }); - }); it('should update the policyRecentlyUsedTags when tag is provided', async () => { // Given a policy recently used tags const policyID = 'A'; @@ -1251,17 +1247,24 @@ describe('startSplitBill', () => { }); await Onyx.merge(`${ONYXKEYS.COLLECTION.POLICY_RECENTLY_USED_TAGS}${policyID}`, policyRecentlyUsedTags); + const participants: IOUParticipant[] = [{isPolicyExpenseChat: true, policyID}]; + let participantsPolicyTags: Record = {}; await getOnyxData({ - key: `${ONYXKEYS.COLLECTION.POLICY_TAGS}`, waitForCollectionCallback: true, - callback: (value) => { - allPolicyTags = value; + key: `${ONYXKEYS.COLLECTION.POLICY_TAGS}`, + callback: (tags) => { + participantsPolicyTags = participants.reduce>((acc, participant) => { + if (participant.policyID) { + acc[participant.policyID] = tags?.[`${ONYXKEYS.COLLECTION.POLICY_TAGS}${participant.policyID}`] ?? {}; + } + return acc; + }, {}); }, }); // When doing a split bill with a receipt startSplitBill({ - participants: [{isPolicyExpenseChat: true, policyID}], + participants, currentUserLogin: currentUserPersonalDetails.login ?? '', currentUserAccountID: currentUserPersonalDetails.accountID, comment: '', @@ -1274,7 +1277,7 @@ describe('startSplitBill', () => { policyRecentlyUsedTags, quickAction: {}, policyRecentlyUsedCurrencies: [], - allPolicyTags, + participantsPolicyTags, }); waitForBatchedUpdates(); @@ -1300,9 +1303,24 @@ describe('startSplitBill', () => { const testCategory = 'Food'; const testCurrency = CONST.CURRENCY.USD; + const participants: IOUParticipant[] = [{isPolicyExpenseChat: true, policyID, accountID: RORY_ACCOUNT_ID}]; + let participantsPolicyTags: Record = {}; + await getOnyxData({ + waitForCollectionCallback: true, + key: `${ONYXKEYS.COLLECTION.POLICY_TAGS}`, + callback: (tags) => { + participantsPolicyTags = participants.reduce>((acc, participant) => { + if (participant.policyID) { + acc[participant.policyID] = tags?.[`${ONYXKEYS.COLLECTION.POLICY_TAGS}${participant.policyID}`] ?? {}; + } + return acc; + }, {}); + }, + }); + // When starting a split bill const {splitTransactionID} = startSplitBill({ - participants: [{isPolicyExpenseChat: true, policyID, accountID: RORY_ACCOUNT_ID}], + participants, currentUserLogin: currentUserPersonalDetails.login ?? '', currentUserAccountID: currentUserPersonalDetails.accountID, comment: testComment, @@ -1315,7 +1333,7 @@ describe('startSplitBill', () => { quickAction: undefined, policyRecentlyUsedCurrencies: [], policyRecentlyUsedTags: undefined, - allPolicyTags, + participantsPolicyTags, }); await waitForBatchedUpdates(); @@ -1344,9 +1362,24 @@ describe('startSplitBill', () => { await Onyx.merge(ONYXKEYS.NVP_QUICK_ACTION_GLOBAL_CREATE, existingQuickAction); + const participants: IOUParticipant[] = [{isPolicyExpenseChat: true, policyID, accountID: RORY_ACCOUNT_ID}]; + let participantsPolicyTags: Record = {}; + await getOnyxData({ + waitForCollectionCallback: true, + key: `${ONYXKEYS.COLLECTION.POLICY_TAGS}`, + callback: (tags) => { + participantsPolicyTags = participants.reduce>((acc, participant) => { + if (participant.policyID) { + acc[participant.policyID] = tags?.[`${ONYXKEYS.COLLECTION.POLICY_TAGS}${participant.policyID}`] ?? {}; + } + return acc; + }, {}); + }, + }); + // When starting a split bill const {splitTransactionID} = startSplitBill({ - participants: [{isPolicyExpenseChat: true, policyID, accountID: RORY_ACCOUNT_ID}], + participants, currentUserLogin: currentUserPersonalDetails.login ?? '', currentUserAccountID: currentUserPersonalDetails.accountID, comment: '', @@ -1359,7 +1392,7 @@ describe('startSplitBill', () => { quickAction: existingQuickAction, policyRecentlyUsedCurrencies: [], policyRecentlyUsedTags: undefined, - allPolicyTags, + participantsPolicyTags, }); await waitForBatchedUpdates(); From e0a5a5eaf623c4b5c2a42ce55fec7b62bbd80646 Mon Sep 17 00:00:00 2001 From: Wiktor Gut Date: Wed, 4 Mar 2026 16:08:52 +0100 Subject: [PATCH 5/6] change allPolicyTags to participantsPolicyTags --- .../iou/request/step/IOURequestStepConfirmation.tsx | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/pages/iou/request/step/IOURequestStepConfirmation.tsx b/src/pages/iou/request/step/IOURequestStepConfirmation.tsx index 2db6ea11f517c..98613e659d9cb 100644 --- a/src/pages/iou/request/step/IOURequestStepConfirmation.tsx +++ b/src/pages/iou/request/step/IOURequestStepConfirmation.tsx @@ -103,7 +103,7 @@ import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; import type SCREENS from '@src/SCREENS'; -import type {RecentlyUsedCategories, Report} from '@src/types/onyx'; +import type {PolicyTagLists, RecentlyUsedCategories, Report} from '@src/types/onyx'; import type {Participant} from '@src/types/onyx/IOU'; import type {PaymentMethodType} from '@src/types/onyx/OriginalMessage'; import type {InvoiceReceiver} from '@src/types/onyx/Report'; @@ -1083,6 +1083,13 @@ function IOURequestStepConfirmation({ } const itemTrimmedComment = item?.comment?.comment?.trim() ?? ''; + const participantsPolicyTags = selectedParticipants.reduce>((acc, participant) => { + if (participant.policyID) { + acc[participant.policyID] = allPolicyTags?.[`${ONYXKEYS.COLLECTION.POLICY_TAGS}${participant.policyID}`] ?? {}; + } + return acc; + }, {}); + // If we have a receipt let's start the split expense by creating only the action, the transaction, and the group DM if needed startSplitBill({ participants: selectedParticipants, @@ -1103,7 +1110,7 @@ function IOURequestStepConfirmation({ policyRecentlyUsedTags, quickAction, policyRecentlyUsedCurrencies: policyRecentlyUsedCurrencies ?? [], - allPolicyTags, + participantsPolicyTags, }); } } From 420e1e8d6e03e0719b58f7ea3e56d08dc94a3d99 Mon Sep 17 00:00:00 2001 From: Wiktor Gut Date: Fri, 6 Mar 2026 11:53:30 +0100 Subject: [PATCH 6/6] extract logic to getParticipantsPolicyTags --- tests/actions/IOUTest.ts | 45 ++++++++---------- tests/actions/IOUTest/SplitTest.ts | 73 +++++++++--------------------- 2 files changed, 40 insertions(+), 78 deletions(-) diff --git a/tests/actions/IOUTest.ts b/tests/actions/IOUTest.ts index 4bd5a72a1798e..92eaae23afa3b 100644 --- a/tests/actions/IOUTest.ts +++ b/tests/actions/IOUTest.ts @@ -207,6 +207,23 @@ describe('actions/IOU', () => { avatar: 'https://example.com/avatar.jpg', }; + const getParticipantsPolicyTags = async (participants: IOUParticipant[]) => { + let participantsPolicyTags: Record = {}; + await getOnyxData({ + waitForCollectionCallback: true, + key: `${ONYXKEYS.COLLECTION.POLICY_TAGS}`, + callback: (tags) => { + participantsPolicyTags = participants.reduce>((acc, participant) => { + if (participant.policyID) { + acc[participant.policyID] = tags?.[`${ONYXKEYS.COLLECTION.POLICY_TAGS}${participant.policyID}`] ?? {}; + } + return acc; + }, {}); + }, + }); + return participantsPolicyTags; + }; + beforeAll(() => { Onyx.init({ keys: ONYXKEYS, @@ -5515,19 +5532,7 @@ describe('actions/IOU', () => { }); const participants: IOUParticipant[] = [{accountID: CARLOS_ACCOUNT_ID, login: CARLOS_EMAIL}]; - let participantsPolicyTags: Record = {}; - await getOnyxData({ - waitForCollectionCallback: true, - key: `${ONYXKEYS.COLLECTION.POLICY_TAGS}`, - callback: (tags) => { - participantsPolicyTags = participants.reduce>((acc, participant) => { - if (participant.policyID) { - acc[participant.policyID] = tags?.[`${ONYXKEYS.COLLECTION.POLICY_TAGS}${participant.policyID}`] ?? {}; - } - return acc; - }, {}); - }, - }); + const participantsPolicyTags = await getParticipantsPolicyTags(participants); // Start a scan split bill const {splitTransactionID} = startSplitBill({ @@ -5747,19 +5752,7 @@ describe('actions/IOU', () => { await Onyx.merge(`${ONYXKEYS.COLLECTION.POLICY_RECENTLY_USED_TAGS}${policyID}`, policyRecentlyUsedTags); const participants: IOUParticipant[] = [{isPolicyExpenseChat: true, policyID}]; - let participantsPolicyTags: Record = {}; - await getOnyxData({ - waitForCollectionCallback: true, - key: `${ONYXKEYS.COLLECTION.POLICY_TAGS}`, - callback: (tags) => { - participantsPolicyTags = participants.reduce>((acc, participant) => { - if (participant.policyID) { - acc[participant.policyID] = tags?.[`${ONYXKEYS.COLLECTION.POLICY_TAGS}${participant.policyID}`] ?? {}; - } - return acc; - }, {}); - }, - }); + const participantsPolicyTags = await getParticipantsPolicyTags(participants); // When doing a split bill with a receipt startSplitBill({ diff --git a/tests/actions/IOUTest/SplitTest.ts b/tests/actions/IOUTest/SplitTest.ts index df845c7f425a6..ded1cf5eac35e 100644 --- a/tests/actions/IOUTest/SplitTest.ts +++ b/tests/actions/IOUTest/SplitTest.ts @@ -129,6 +129,23 @@ const currentUserPersonalDetails: CurrentUserPersonalDetails = { avatar: 'https://example.com/avatar.jpg', }; +const getParticipantsPolicyTags = async (participants: IOUParticipant[]) => { + let participantsPolicyTags: Record = {}; + await getOnyxData({ + waitForCollectionCallback: true, + key: `${ONYXKEYS.COLLECTION.POLICY_TAGS}`, + callback: (tags) => { + participantsPolicyTags = participants.reduce>((acc, participant) => { + if (participant.policyID) { + acc[participant.policyID] = tags?.[`${ONYXKEYS.COLLECTION.POLICY_TAGS}${participant.policyID}`] ?? {}; + } + return acc; + }, {}); + }, + }); + return participantsPolicyTags; +}; + let mockFetch: MockFetch; beforeAll(() => { @@ -1018,19 +1035,7 @@ describe('split expense', () => { }); const participants: IOUParticipant[] = [{accountID: CARLOS_ACCOUNT_ID, login: CARLOS_EMAIL}]; - let participantsPolicyTags: Record = {}; - await getOnyxData({ - waitForCollectionCallback: true, - key: `${ONYXKEYS.COLLECTION.POLICY_TAGS}`, - callback: (tags) => { - participantsPolicyTags = participants.reduce>((acc, participant) => { - if (participant.policyID) { - acc[participant.policyID] = tags?.[`${ONYXKEYS.COLLECTION.POLICY_TAGS}${participant.policyID}`] ?? {}; - } - return acc; - }, {}); - }, - }); + const participantsPolicyTags = await getParticipantsPolicyTags(participants); // Start a scan split bill const {splitTransactionID} = startSplitBill({ @@ -1248,19 +1253,7 @@ describe('startSplitBill', () => { await Onyx.merge(`${ONYXKEYS.COLLECTION.POLICY_RECENTLY_USED_TAGS}${policyID}`, policyRecentlyUsedTags); const participants: IOUParticipant[] = [{isPolicyExpenseChat: true, policyID}]; - let participantsPolicyTags: Record = {}; - await getOnyxData({ - waitForCollectionCallback: true, - key: `${ONYXKEYS.COLLECTION.POLICY_TAGS}`, - callback: (tags) => { - participantsPolicyTags = participants.reduce>((acc, participant) => { - if (participant.policyID) { - acc[participant.policyID] = tags?.[`${ONYXKEYS.COLLECTION.POLICY_TAGS}${participant.policyID}`] ?? {}; - } - return acc; - }, {}); - }, - }); + const participantsPolicyTags = await getParticipantsPolicyTags(participants); // When doing a split bill with a receipt startSplitBill({ @@ -1304,19 +1297,7 @@ describe('startSplitBill', () => { const testCurrency = CONST.CURRENCY.USD; const participants: IOUParticipant[] = [{isPolicyExpenseChat: true, policyID, accountID: RORY_ACCOUNT_ID}]; - let participantsPolicyTags: Record = {}; - await getOnyxData({ - waitForCollectionCallback: true, - key: `${ONYXKEYS.COLLECTION.POLICY_TAGS}`, - callback: (tags) => { - participantsPolicyTags = participants.reduce>((acc, participant) => { - if (participant.policyID) { - acc[participant.policyID] = tags?.[`${ONYXKEYS.COLLECTION.POLICY_TAGS}${participant.policyID}`] ?? {}; - } - return acc; - }, {}); - }, - }); + const participantsPolicyTags = await getParticipantsPolicyTags(participants); // When starting a split bill const {splitTransactionID} = startSplitBill({ @@ -1363,19 +1344,7 @@ describe('startSplitBill', () => { await Onyx.merge(ONYXKEYS.NVP_QUICK_ACTION_GLOBAL_CREATE, existingQuickAction); const participants: IOUParticipant[] = [{isPolicyExpenseChat: true, policyID, accountID: RORY_ACCOUNT_ID}]; - let participantsPolicyTags: Record = {}; - await getOnyxData({ - waitForCollectionCallback: true, - key: `${ONYXKEYS.COLLECTION.POLICY_TAGS}`, - callback: (tags) => { - participantsPolicyTags = participants.reduce>((acc, participant) => { - if (participant.policyID) { - acc[participant.policyID] = tags?.[`${ONYXKEYS.COLLECTION.POLICY_TAGS}${participant.policyID}`] ?? {}; - } - return acc; - }, {}); - }, - }); + const participantsPolicyTags = await getParticipantsPolicyTags(participants); // When starting a split bill const {splitTransactionID} = startSplitBill({