Skip to content
Open
Show file tree
Hide file tree
Changes from 18 commits
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
c618237
Add main change for the feature
ZhenjaHorbach Mar 6, 2026
24fcc89
Fix 0 reportID for new selfDM splits
ZhenjaHorbach Mar 6, 2026
b8a221b
Fix lint issues and revert reportID changes for selfDM splits
ZhenjaHorbach Mar 9, 2026
6cb08e4
Fix conflicts
ZhenjaHorbach Mar 13, 2026
1bc30c6
Fix prettier
ZhenjaHorbach Mar 13, 2026
f6aa247
Fix lint issues
ZhenjaHorbach Mar 13, 2026
6f491d6
Fix optimistic issues during reverting
ZhenjaHorbach Mar 13, 2026
3d4369c
Fix conflicts
ZhenjaHorbach Mar 19, 2026
6cc1cd7
Fix getChildTransactions using
ZhenjaHorbach Mar 20, 2026
4e00ea6
Fix conflicts
ZhenjaHorbach Mar 20, 2026
45820dc
Fix issues with selfDMReportIDs
ZhenjaHorbach Mar 20, 2026
58f960e
Fix conflicts
ZhenjaHorbach Mar 23, 2026
0886cb7
Fix issues with dublication transactions
ZhenjaHorbach Mar 23, 2026
83f7ab9
Fix conflicts
ZhenjaHorbach Mar 25, 2026
89b53d1
Fix a few issues with selfDm splits
ZhenjaHorbach Mar 25, 2026
33e4079
Fix a few issues with selfDm splits x2
ZhenjaHorbach Mar 25, 2026
d449ec3
Fix conflicts
ZhenjaHorbach Mar 25, 2026
2b926a6
Fix lint issues
ZhenjaHorbach Mar 25, 2026
2264cd4
Fix comments
ZhenjaHorbach Mar 26, 2026
b00ae30
Fix conflicts
ZhenjaHorbach Mar 31, 2026
5ebfe73
Fix issues with removing splits on selfdm screen
ZhenjaHorbach Apr 1, 2026
dc77015
Fix issue with negative original amount
ZhenjaHorbach Apr 1, 2026
18a4ae7
Fix issue with expenses on report screen
ZhenjaHorbach Apr 1, 2026
569001e
Fix issue with successData for original transaction
ZhenjaHorbach Apr 2, 2026
24ef703
Fix conflicts
ZhenjaHorbach Apr 2, 2026
3e25c21
Fix conflicts x2
ZhenjaHorbach Apr 2, 2026
65e4c64
Fix issues with search hash
ZhenjaHorbach Apr 2, 2026
76c7e3f
Fix conflicts
ZhenjaHorbach Apr 2, 2026
590cbd6
Fix issues with selfDM splits
ZhenjaHorbach Apr 2, 2026
0823ee8
Merge branch 'main' into add-support-unreported-expenses-for-splits
ZhenjaHorbach Apr 4, 2026
358ff06
Fix conflicts
ZhenjaHorbach Apr 6, 2026
51c4210
Fix comments
ZhenjaHorbach Apr 8, 2026
72642b0
Fix bugs
ZhenjaHorbach Apr 8, 2026
7f53154
Fix conflicts
ZhenjaHorbach Apr 8, 2026
ca80c27
Fix rate issues
ZhenjaHorbach Apr 8, 2026
cbf3239
Merge branch 'main' into add-support-unreported-expenses-for-splits
ZhenjaHorbach Apr 10, 2026
d5d1995
Fix issues with map distances for selfDM splits
ZhenjaHorbach Apr 10, 2026
c9c2fec
Fix conflicts
ZhenjaHorbach Apr 13, 2026
34712f6
Fix comments
ZhenjaHorbach Apr 13, 2026
a9b4002
Fix rates
ZhenjaHorbach Apr 13, 2026
a2e211b
Fix issue with revert negative ammounts
ZhenjaHorbach Apr 13, 2026
c1619b0
Fix spellcheck
ZhenjaHorbach Apr 13, 2026
4a5ef95
Fix issue with revert selfDM split amount
ZhenjaHorbach Apr 13, 2026
87888f3
Fix conflicts
ZhenjaHorbach Apr 16, 2026
bf82460
Fix few issues
ZhenjaHorbach Apr 17, 2026
b82cc4a
Update tests
ZhenjaHorbach Apr 17, 2026
06d2017
Fix shanpshot ids for splits
ZhenjaHorbach Apr 17, 2026
0eaeaa1
Update tags and categories logic for selfDM splits
ZhenjaHorbach Apr 17, 2026
9ec5989
Fix conflicts
ZhenjaHorbach Apr 21, 2026
43d732d
Fix conflicts x2
ZhenjaHorbach Apr 21, 2026
620f97f
Merge branch 'main' into add-support-unreported-expenses-for-splits
ZhenjaHorbach Apr 22, 2026
4ca2e67
Fix few bugs
ZhenjaHorbach Apr 22, 2026
0891539
Fix tests and update comment counts
ZhenjaHorbach Apr 22, 2026
2c1cbe4
Fix counter for selfDM splits
ZhenjaHorbach Apr 23, 2026
20c3fed
Fix conflicts
ZhenjaHorbach Apr 23, 2026
0c9c7d6
Fix tests
ZhenjaHorbach Apr 23, 2026
43c85b9
Merge branch 'main' into add-support-unreported-expenses-for-splits
ZhenjaHorbach Apr 24, 2026
43ddd15
Fix bug with empty report after removing last split in this report
ZhenjaHorbach Apr 24, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 10 additions & 4 deletions src/components/MoneyReportHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -398,6 +398,9 @@
const hasCustomUnitOutOfPolicyViolation = hasCustomUnitOutOfPolicyViolationTransactionUtils(transactionViolations);
const isPerDiemRequestOnNonDefaultWorkspace = isPerDiemRequest(transaction) && defaultExpensePolicy?.id !== policy?.id;

const [allReports] = useOnyx(ONYXKEYS.COLLECTION.REPORT);
const parentReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${moneyRequestReport?.parentReportID}`];

const [exportModalStatus, setExportModalStatus] = useState<ExportType | null>(null);
const {showConfirmModal} = useConfirmModal();
const {isPaidAnimationRunning, isApprovedAnimationRunning, isSubmittingAnimationRunning, startAnimation, stopAnimation, startApprovedAnimation, startSubmittingAnimation} =
Expand All @@ -406,14 +409,14 @@
const theme = useTheme();
const {isExpenseSplit} = getOriginalTransactionWithSplitInfo(transaction, originalTransaction);
const [allTransactions] = useOnyx(ONYXKEYS.COLLECTION.TRANSACTION);
const [allReports] = useOnyx(ONYXKEYS.COLLECTION.REPORT);
const hasMultipleSplits = useMemo(() => {
if (!transaction?.comment?.originalTransactionID) {
return false;
}
const children = getChildTransactions(allTransactions, allReports, transaction.comment.originalTransactionID);
const children = getChildTransactions(allTransactions, transaction?.comment?.originalTransactionID);
return children.length > 1;
}, [allTransactions, allReports, transaction?.comment?.originalTransactionID]);
}, [allTransactions, transaction?.comment?.originalTransactionID]);

const isReportOpen = isOpenReport(moneyRequestReport);
const shouldShowSplitIndicator = isExpenseSplit && (hasMultipleSplits || isReportOpen);

Expand Down Expand Up @@ -1546,8 +1549,9 @@
policies,
outstandingReportsByPolicyID,
isChatReportArchived,
parentReport,
});
}, [

Check warning on line 1554 in src/components/MoneyReportHeader.tsx

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

React Hook useMemo has a duplicate dependency: 'bankAccountList'. Either omit it or remove the dependency array

Check warning on line 1554 in src/components/MoneyReportHeader.tsx

View workflow job for this annotation

GitHub Actions / ESLint check

React Hook useMemo has a duplicate dependency: 'bankAccountList'. Either omit it or remove the dependency array
moneyRequestReport,
currentUserLogin,
accountID,
Expand All @@ -1555,12 +1559,14 @@
nonPendingDeleteTransactions,
originalIOUTransaction,
violations,
bankAccountList,
Comment thread
ZhenjaHorbach marked this conversation as resolved.
Outdated
policy,
reportNameValuePairs,
reportActions,
reportMetadata,
policies,
isChatReportArchived,
parentReport,
bankAccountList,
outstandingReportsByPolicyID,
]);
Expand Down Expand Up @@ -1866,7 +1872,7 @@
return;
}

initSplitExpense(currentTransaction, policy);
initSplitExpense(currentTransaction, policy, moneyRequestReport);
},
},
[CONST.REPORT.SECONDARY_ACTIONS.MERGE]: {
Expand Down
2 changes: 1 addition & 1 deletion src/components/MoneyRequestHeaderSecondaryActions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,7 @@ function MoneyRequestHeaderSecondaryActions({reportID, onBackButtonPress}: Money
icon: expensifyIcons.ArrowSplit,
value: CONST.REPORT.TRANSACTION_SECONDARY_ACTIONS.SPLIT,
onSelected: () => {
initSplitExpense(transaction, policy);
initSplitExpense(transaction, policy, report);
},
},
[CONST.REPORT.TRANSACTION_SECONDARY_ACTIONS.MERGE]: {
Expand Down
2 changes: 1 addition & 1 deletion src/components/ReportActionItem/MoneyRequestView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -870,7 +870,7 @@ function MoneyRequestView({
}

if (shouldShowSplitIndicator && isSplitAvailable) {
initSplitExpense(transaction, policy);
initSplitExpense(transaction, policy, moneyRequestReport);
return;
}

Expand Down
2 changes: 1 addition & 1 deletion src/hooks/useDeleteTransactions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ function useDeleteTransactions({report, reportActions, policy}: UseDeleteTransac

for (const transactionID of Object.keys(splitTransactionsByOriginalTransactionID)) {
const splitIDs = new Set((splitTransactionsByOriginalTransactionID[transactionID] ?? []).map((transaction) => transaction.transactionID));
const childTransactions = getChildTransactions(allTransactions, allReports, transactionID).filter(
const childTransactions = getChildTransactions(allTransactions, transactionID).filter(
(transaction) => !splitIDs.has(transaction?.transactionID ?? String(CONST.DEFAULT_NUMBER_ID)),
);

Expand Down
2 changes: 1 addition & 1 deletion src/hooks/useSearchBulkActions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1089,7 +1089,7 @@ function useSearchBulkActions({queryJSON}: UseSearchBulkActionsParams) {
icon: expensifyIcons.ArrowSplit,
value: CONST.SEARCH.BULK_ACTION_TYPES.SPLIT,
onSelected: () => {
initSplitExpense(firstTransaction, firstTransactionPolicy);
initSplitExpense(firstTransaction, firstTransactionPolicy, firstTransactionReport);
},
});
}
Expand Down
2 changes: 1 addition & 1 deletion src/hooks/useSelectedTransactionsActions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -382,7 +382,7 @@ function useSelectedTransactionsActions({
icon: expensifyIcons.ArrowSplit,
value: SPLIT,
onSelected: () => {
initSplitExpense(firstTransaction, policy);
initSplitExpense(firstTransaction, policy, report);
},
});
}
Expand Down
13 changes: 10 additions & 3 deletions src/libs/ReportSecondaryActionUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ function isSplitAction(
currentUserLogin: string,
currentUserAccountID: number,
policy?: OnyxEntry<Policy>,
parentReport?: OnyxEntry<Report>,
): boolean {
if (Number(reportTransactions?.length) !== 1 || !report) {
return false;
Expand Down Expand Up @@ -143,7 +144,7 @@ function isSplitAction(
return false;
}

if (!isExpenseReportUtils(report)) {
if (!isExpenseReportUtils(report) && !(isSelfDMReportUtils(report) || isSelfDMReportUtils(parentReport))) {
return false;
}

Expand All @@ -155,6 +156,10 @@ function isSplitAction(
return false;
}

if (isSelfDMReportUtils(report) || isSelfDMReportUtils(parentReport)) {
Comment thread
ZhenjaHorbach marked this conversation as resolved.
Outdated
return true;
Comment thread
ZhenjaHorbach marked this conversation as resolved.
Outdated
}

const arePaymentsDisabled = policy?.reimbursementChoice === CONST.POLICY.REIMBURSEMENT_CHOICES.REIMBURSEMENT_NO;
if (isProcessingReportUtils(report) && isInstantSubmitEnabled(policy) && isSubmitAndClose(policy) && arePaymentsDisabled) {
return false;
Expand Down Expand Up @@ -855,6 +860,7 @@ function getSecondaryReportActions({
policies,
outstandingReportsByPolicyID,
isChatReportArchived = false,
parentReport,
}: {
currentUserLogin: string;
currentUserAccountID: number;
Expand All @@ -872,6 +878,7 @@ function getSecondaryReportActions({
outstandingReportsByPolicyID?: OutstandingReportsByPolicyIDDerivedValue;
canUseNewDotSplits?: boolean;
isChatReportArchived?: boolean;
parentReport?: OnyxEntry<Report>;
}): Array<ValueOf<typeof CONST.REPORT.SECONDARY_ACTIONS>> {
const options: Array<ValueOf<typeof CONST.REPORT.SECONDARY_ACTIONS>> = [];

Expand Down Expand Up @@ -955,7 +962,7 @@ function getSecondaryReportActions({
options.push(CONST.REPORT.SECONDARY_ACTIONS.REJECT);
}

if (isSplitAction(report, reportTransactions, originalTransaction, currentUserLogin, currentUserAccountID, policy)) {
if (isSplitAction(report, reportTransactions, originalTransaction, currentUserLogin, currentUserAccountID, policy, parentReport)) {
options.push(CONST.REPORT.SECONDARY_ACTIONS.SPLIT);
}

Expand Down Expand Up @@ -1067,7 +1074,7 @@ function getSecondaryTransactionThreadActions(
options.push(CONST.REPORT.TRANSACTION_SECONDARY_ACTIONS.REJECT);
}

if (isSplitAction(parentReport, [reportTransaction], originalTransaction, currentUserLogin, currentUserAccountID, policy)) {
if (isSplitAction(parentReport, [reportTransaction], originalTransaction, currentUserLogin, currentUserAccountID, policy, parentReport)) {
Comment thread
ZhenjaHorbach marked this conversation as resolved.
Outdated
options.push(CONST.REPORT.TRANSACTION_SECONDARY_ACTIONS.SPLIT);
}

Expand Down
2 changes: 1 addition & 1 deletion src/libs/ReportUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1055,7 +1055,7 @@
};

let conciergeReportIDOnyxConnect: OnyxEntry<string>;
Onyx.connect({

Check warning on line 1058 in src/libs/ReportUtils.ts

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

Onyx.connect() is deprecated. Use useOnyx() hook instead and pass the data as parameters to a pure function
key: ONYXKEYS.CONCIERGE_REPORT_ID,
callback: (value) => {
conciergeReportIDOnyxConnect = value;
Expand All @@ -1063,7 +1063,7 @@
});

const defaultAvatarBuildingIconTestID = 'SvgDefaultAvatarBuilding Icon';
Onyx.connect({

Check warning on line 1066 in src/libs/ReportUtils.ts

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

Onyx.connect() is deprecated. Use useOnyx() hook instead and pass the data as parameters to a pure function
key: ONYXKEYS.SESSION,
callback: (value) => {
// When signed out, val is undefined
Expand All @@ -1081,7 +1081,7 @@
let allPersonalDetails: OnyxEntry<PersonalDetailsList>;
let allPersonalDetailLogins: string[];
let currentUserPersonalDetails: OnyxEntry<PersonalDetails>;
Onyx.connect({

Check warning on line 1084 in src/libs/ReportUtils.ts

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

Onyx.connect() is deprecated. Use useOnyx() hook instead and pass the data as parameters to a pure function
key: ONYXKEYS.PERSONAL_DETAILS_LIST,
callback: (value) => {
if (deprecatedCurrentUserAccountID) {
Expand All @@ -1093,7 +1093,7 @@
});

let allReportsDraft: OnyxCollection<Report>;
Onyx.connect({

Check warning on line 1096 in src/libs/ReportUtils.ts

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

Onyx.connect() is deprecated. Use useOnyx() hook instead and pass the data as parameters to a pure function
key: ONYXKEYS.COLLECTION.REPORT_DRAFT,
waitForCollectionCallback: true,
callback: (value) => (allReportsDraft = value),
Expand All @@ -1101,7 +1101,7 @@

let allPolicies: OnyxCollection<Policy>;
let policiesArray: Policy[] = [];
Onyx.connect({

Check warning on line 1104 in src/libs/ReportUtils.ts

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

Onyx.connect() is deprecated. Use useOnyx() hook instead and pass the data as parameters to a pure function
key: ONYXKEYS.COLLECTION.POLICY,
waitForCollectionCallback: true,
callback: (value) => {
Expand All @@ -1111,7 +1111,7 @@
});

let allPolicyDrafts: OnyxCollection<Policy>;
Onyx.connect({

Check warning on line 1114 in src/libs/ReportUtils.ts

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

Onyx.connect() is deprecated. Use useOnyx() hook instead and pass the data as parameters to a pure function
key: ONYXKEYS.COLLECTION.POLICY_DRAFTS,
waitForCollectionCallback: true,
callback: (value) => (allPolicyDrafts = value),
Expand All @@ -1119,7 +1119,7 @@

let allReports: OnyxCollection<Report>;
let reportsByPolicyID: ReportByPolicyMap;
Onyx.connect({

Check warning on line 1122 in src/libs/ReportUtils.ts

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

Onyx.connect() is deprecated. Use useOnyx() hook instead and pass the data as parameters to a pure function
key: ONYXKEYS.COLLECTION.REPORT,
waitForCollectionCallback: true,
callback: (value) => {
Expand Down Expand Up @@ -1155,7 +1155,7 @@
});

let betaConfiguration: OnyxEntry<BetaConfiguration> = {};
Onyx.connect({

Check warning on line 1158 in src/libs/ReportUtils.ts

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

Onyx.connect() is deprecated. Use useOnyx() hook instead and pass the data as parameters to a pure function
key: ONYXKEYS.BETA_CONFIGURATION,
callback: (value) => (betaConfiguration = value ?? {}),
});
Expand Down Expand Up @@ -7217,7 +7217,7 @@

if (type !== CONST.IOU.REPORT_ACTION_TYPE.PAY) {
// Split expense made from a policy expense chat only have the payee's accountID as the participant because the payer could be any policy admin
if (isOwnPolicyExpenseChat && type === CONST.IOU.REPORT_ACTION_TYPE.SPLIT) {
if ((isOwnPolicyExpenseChat && type === CONST.IOU.REPORT_ACTION_TYPE.SPLIT) || isPersonalTrackingExpense) {
originalMessage.participantAccountIDs = deprecatedCurrentUserAccountID ? [deprecatedCurrentUserAccountID] : [];
} else {
originalMessage.participantAccountIDs = deprecatedCurrentUserAccountID
Expand Down
12 changes: 3 additions & 9 deletions src/libs/TransactionUtils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2702,20 +2702,14 @@ function isTransactionPendingDelete(transaction: OnyxEntry<Transaction>): boolea

/**
* Retrieves all "child" transactions associated with a given original transaction.
* By default excludes orphaned transactions (reportID '0'). Use includeOrphaned=true for counting.
*/
function getChildTransactions(transactions: OnyxCollection<Transaction>, reports: OnyxCollection<Report>, originalTransactionID: string | undefined, includeOrphaned = false) {
function getChildTransactions(transactions: OnyxCollection<Transaction>, originalTransactionID: string | undefined) {
return Object.values(transactions ?? {}).filter((currentTransaction) => {
const isSplitChild = currentTransaction?.comment?.originalTransactionID === originalTransactionID;
if (!isSplitChild || currentTransaction?.pendingAction === CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE) {
return false;
}
const isOrphaned = currentTransaction?.reportID === CONST.REPORT.UNREPORTED_REPORT_ID;
if (isOrphaned) {
return includeOrphaned;
}
const currentReport = reports?.[`${ONYXKEYS.COLLECTION.REPORT}${currentTransaction?.reportID}`];
return !!currentReport || currentTransaction?.comment?.source === CONST.IOU.TYPE.SPLIT;
return currentTransaction?.comment?.source === CONST.IOU.TYPE.SPLIT;
});
}

Expand All @@ -2726,7 +2720,7 @@ function hasMultipleSplitChildren(transactions: OnyxCollection<Transaction>, rep
if (!originalTransactionID) {
return false;
}
return getChildTransactions(transactions, reports, originalTransactionID).length > 1;
return getChildTransactions(transactions, originalTransactionID).length > 1;
}

/**
Expand Down
Loading
Loading