@@ -2199,6 +2199,7 @@ describe('updateSplitTransactionsFromSplitExpensesFlow', () => {
21992199 { transactionID : splitTransactionID1 , amount : amount / 2 , created : DateUtils . getDBTime ( ) } ,
22002200 { transactionID : splitTransactionID2 , amount : amount / 2 , created : DateUtils . getDBTime ( ) } ,
22012201 ] ,
2202+ splitExpensesTotal : undefined ,
22022203 } ,
22032204 policyCategories : undefined ,
22042205 policy : undefined ,
@@ -2259,6 +2260,7 @@ describe('updateSplitTransactionsFromSplitExpensesFlow', () => {
22592260 reportID,
22602261 originalTransactionID : originalTransactionID ?? String ( CONST . DEFAULT_NUMBER_ID ) ,
22612262 splitExpenses : [ { transactionID : splitTransactionID1 , amount, created : DateUtils . getDBTime ( ) , reportID : differentReportID } ] ,
2263+ splitExpensesTotal : undefined ,
22622264 } ,
22632265 policyCategories : undefined ,
22642266 policy : undefined ,
@@ -2423,6 +2425,7 @@ describe('updateSplitTransactionsFromSplitExpensesFlow', () => {
24232425 { transactionID : splitTransactionID1 , amount : amount / 2 , created : DateUtils . getDBTime ( ) } ,
24242426 { transactionID : splitTransactionID2 , amount : amount / 2 , created : DateUtils . getDBTime ( ) } ,
24252427 ] ,
2428+ splitExpensesTotal : undefined ,
24262429 } ,
24272430 policyCategories : undefined ,
24282431 policy : undefined ,
@@ -2530,6 +2533,7 @@ describe('updateSplitTransactionsFromSplitExpensesFlow', () => {
25302533 reportID,
25312534 originalTransactionID : originalTransactionID ?? String ( CONST . DEFAULT_NUMBER_ID ) ,
25322535 splitExpenses : [ { transactionID : splitTransactionID1 , amount, created : DateUtils . getDBTime ( ) } ] ,
2536+ splitExpensesTotal : undefined ,
25332537 } ,
25342538 policyCategories : undefined ,
25352539 policy : undefined ,
@@ -2703,6 +2707,7 @@ describe('updateSplitTransactionsFromSplitExpensesFlow', () => {
27032707 reportID : reportID1 ,
27042708 originalTransactionID : originalTransaction . transactionID ,
27052709 splitExpenses : [ { transactionID : childTransaction . transactionID , amount : 10000 , created : DateUtils . getDBTime ( ) } ] ,
2710+ splitExpensesTotal : undefined ,
27062711 } ,
27072712 searchContext : {
27082713 currentSearchHash : - 2 ,
@@ -2837,6 +2842,7 @@ describe('updateSplitTransactionsFromSplitExpensesFlow', () => {
28372842 reportID : reportID2 ,
28382843 originalTransactionID : originalTransaction . transactionID ,
28392844 splitExpenses : [ { transactionID : childTransaction . transactionID , amount : 10000 , created : DateUtils . getDBTime ( ) } ] ,
2845+ splitExpensesTotal : undefined ,
28402846 } ,
28412847 searchContext : {
28422848 currentSearchHash : - 2 ,
@@ -3792,6 +3798,7 @@ describe('updateSplitTransactions', () => {
37923798 { transactionID : 'split-1' , amount : amount / 2 , description : 'Split 1' , created : DateUtils . getDBTime ( ) } ,
37933799 { transactionID : 'split-2' , amount : amount / 2 , description : 'Split 2' , created : DateUtils . getDBTime ( ) } ,
37943800 ] ,
3801+ splitExpensesTotal : undefined ,
37953802 } ,
37963803 searchContext : { currentSearchHash : - 2 } ,
37973804 policyCategories : undefined ,
@@ -3923,6 +3930,7 @@ describe('updateSplitTransactions', () => {
39233930 { transactionID : 'offline-split-1' , amount : amount / 2 , description : 'Offline Split 1' , created : DateUtils . getDBTime ( ) } ,
39243931 { transactionID : 'offline-split-2' , amount : amount / 2 , description : 'Offline Split 2' , created : DateUtils . getDBTime ( ) } ,
39253932 ] ,
3933+ splitExpensesTotal : undefined ,
39263934 } ,
39273935 searchContext : { currentSearchHash : - 2 } ,
39283936 policyCategories : undefined ,
@@ -4053,6 +4061,7 @@ describe('updateSplitTransactions', () => {
40534061 { transactionID : 'cat-tag-1' , amount : amount / 2 , description : 'Split 1' , created : DateUtils . getDBTime ( ) , category : testCategory , tags : [ testTag ] } ,
40544062 { transactionID : 'cat-tag-2' , amount : amount / 2 , description : 'Split 2' , created : DateUtils . getDBTime ( ) , category : testCategory , tags : [ testTag ] } ,
40554063 ] ,
4064+ splitExpensesTotal : undefined ,
40564065 } ,
40574066 searchContext : { currentSearchHash : - 2 } ,
40584067 policyCategories : undefined ,
@@ -4230,6 +4239,7 @@ describe('updateSplitTransactions', () => {
42304239 description : `Split ${ index + 1 } ` ,
42314240 created : DateUtils . getDBTime ( ) ,
42324241 } ) ) ,
4242+ splitExpensesTotal : undefined ,
42334243 } ,
42344244 searchContext : { currentSearchHash : - 2 } ,
42354245 policyCategories : undefined ,
@@ -4465,6 +4475,7 @@ describe('updateSplitTransactions', () => {
44654475 reportID : expenseReport . reportID ,
44664476 originalTransactionID,
44674477 splitExpenses : [ { transactionID : splitTransactionID1 , reportID : remainingSplitTransaction ?. reportID , amount, created : DateUtils . getDBTime ( ) } ] ,
4478+ splitExpensesTotal : undefined ,
44684479 } ,
44694480 searchContext : { currentSearchHash : - 2 } ,
44704481 policyCategories : undefined ,
@@ -4544,6 +4555,7 @@ describe('updateSplitTransactions', () => {
45444555 { transactionID : splitTransactionID1 , amount : amount / 2 , created : DateUtils . getDBTime ( ) } ,
45454556 { transactionID : splitTransactionID2 , amount : amount / 2 , created : DateUtils . getDBTime ( ) } ,
45464557 ] ,
4558+ splitExpensesTotal : undefined ,
45474559 } ,
45484560 searchContext : { currentSearchHash : - 2 } ,
45494561 policyCategories : undefined ,
@@ -4569,6 +4581,74 @@ describe('updateSplitTransactions', () => {
45694581 const updatedReportPreviewAction = getReportPreviewAction ( chatReport ?. reportID , expenseReport ?. reportID ) ;
45704582 expect ( updatedReportPreviewAction ?. childVisibleActionCount ) . toEqual ( 2 ) ;
45714583 } ) ;
4584+
4585+ it ( 'should preserve report total when deleting a split with correct splitExpensesTotal' , async ( ) => {
4586+ // This tests the bug where useDeleteTransactions was not passing splitExpensesTotal,
4587+ // causing the report total to be incorrect after offline split deletion.
4588+ // Without splitExpensesTotal, changesInReportTotal = sum(remaining splits) - 0 = remaining total,
4589+ // which incorrectly subtracts that from the report total again.
4590+ const { expenseReport, originalTransactionID} = await createBaseExpense ( ) ;
4591+ const reportID = expenseReport ?. reportID ?? String ( CONST . DEFAULT_NUMBER_ID ) ;
4592+ const txID = originalTransactionID ?? String ( CONST . DEFAULT_NUMBER_ID ) ;
4593+
4594+ // Split into 4 parts for clean division (amount=10000, each split = 2500)
4595+ const splitIDs = await splitToN ( 4 , expenseReport , txID ) ;
4596+
4597+ // Capture the report total after the initial split
4598+ const reportAfterSplit = await getOnyxValue ( `${ ONYXKEYS . COLLECTION . REPORT } ${ reportID } ` ) ;
4599+ const totalAfterSplit = reportAfterSplit ?. total ?? 0 ;
4600+
4601+ const { allTransactions, allReports, allReportNameValuePairs} = await getCollections ( ) ;
4602+ const policyTags = await getPolicyTags ( reportID ) ;
4603+ const reports = getTransactionAndExpenseReports ( reportID ) ;
4604+
4605+ // "Delete" one split by calling updateSplitTransactions with only three remaining splits.
4606+ // Pass splitExpensesTotal = sum of remaining splits (this is what useDeleteTransactions now does).
4607+ const splitAmount = amount / 4 ;
4608+ const splitExpensesTotal = splitAmount * 3 ;
4609+
4610+ updateSplitTransactions ( {
4611+ allTransactionsList : allTransactions ,
4612+ allReportsList : allReports ,
4613+ allReportNameValuePairsList : allReportNameValuePairs ,
4614+ transactionData : {
4615+ reportID,
4616+ originalTransactionID : txID ,
4617+ splitExpenses : [
4618+ { transactionID : splitIDs . at ( 0 ) ?? '' , amount : splitAmount , created : DateUtils . getDBTime ( ) } ,
4619+ { transactionID : splitIDs . at ( 1 ) ?? '' , amount : splitAmount , created : DateUtils . getDBTime ( ) } ,
4620+ { transactionID : splitIDs . at ( 2 ) ?? '' , amount : splitAmount , created : DateUtils . getDBTime ( ) } ,
4621+ ] ,
4622+ splitExpensesTotal,
4623+ } ,
4624+ searchContext : { currentSearchHash : - 2 } ,
4625+ policyCategories : undefined ,
4626+ policy : undefined ,
4627+ policyRecentlyUsedCategories : [ ] ,
4628+ iouReport : expenseReport ,
4629+ firstIOU : undefined ,
4630+ isASAPSubmitBetaEnabled : false ,
4631+ currentUserPersonalDetails,
4632+ transactionViolations : { } ,
4633+ policyRecentlyUsedCurrencies : [ ] ,
4634+ quickAction : undefined ,
4635+ iouReportNextStep : undefined ,
4636+ betas : [ CONST . BETAS . ALL ] ,
4637+ policyTags,
4638+ personalDetails : { [ RORY_ACCOUNT_ID ] : { accountID : RORY_ACCOUNT_ID , login : RORY_EMAIL } } ,
4639+ transactionReport : reports . transactionReport ,
4640+ expenseReport : reports . expenseReport ,
4641+ isOffline : false ,
4642+ } ) ;
4643+ await waitForBatchedUpdates ( ) ;
4644+
4645+ // With correct splitExpensesTotal: changesInReportTotal = remainingAmount - splitExpensesTotal = 0,
4646+ // so the report total should not change from the post-split value.
4647+ // Without splitExpensesTotal (the bug): changesInReportTotal = remainingAmount - 0 = remainingAmount,
4648+ // which would incorrectly subtract that from the total, resulting in totalAfterSplit + remainingAmount.
4649+ const updatedReport = await getOnyxValue ( `${ ONYXKEYS . COLLECTION . REPORT } ${ reportID } ` ) ;
4650+ expect ( updatedReport ?. total ) . toBe ( totalAfterSplit ) ;
4651+ } ) ;
45724652} ) ;
45734653
45744654describe ( 'initSplitExpense' , ( ) => {
0 commit comments