Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
92 commits
Select commit Hold shift + click to select a range
8677040
display tax rate in merge details page
dominictb Sep 24, 2025
dc95254
Merge branch 'main' of github.com-dominictb:dominictb/epsf-app into f…
dominictb Sep 29, 2025
bd346d2
auto calculate tax amount when selecting tax rate or amount
dominictb Sep 29, 2025
cee6050
auto calculate tax amount when selecting tax value
dominictb Sep 29, 2025
20274b3
centralize merge tax logic
dominictb Sep 29, 2025
33185a3
fix typescript check
dominictb Sep 29, 2025
93172bf
fix unit test
dominictb Sep 29, 2025
8d646ca
Merge branch 'main' of github.com-dominictb:dominictb/epsf-app into f…
dominictb Oct 1, 2025
7b3c393
remove redundant conversion
dominictb Oct 1, 2025
62289d9
Merge branch 'main' of github.com-dominictb:dominictb/epsf-app into f…
dominictb Oct 8, 2025
2175bce
only show policy specific fields for supported reports
dominictb Oct 9, 2025
0294213
update merge transaction in Onyx after calculating tax
dominictb Oct 9, 2025
9fc1c60
Merge branch 'main' of github.com-dominictb:dominictb/epsf-app into f…
dominictb Oct 14, 2025
d0c7366
fix typecheck
dominictb Oct 14, 2025
03493a6
Merge branch 'main' of github.com-dominictb:dominictb/epsf-app into f…
dominictb Oct 16, 2025
84cbc1b
revert: only show policy specific fields for supported reports
dominictb Oct 16, 2025
b7d9c6b
sort eligible transactions list by creation data
dominictb Oct 16, 2025
3e06a58
save tax optimistically
dominictb Oct 16, 2025
60471e1
Merge branch 'main' of github.com-dominictb:dominictb/epsf-app into f…
dominictb Oct 16, 2025
552fafe
fix lint
dominictb Oct 16, 2025
b83e50e
Merge branch 'main' of github.com-dominictb:dominictb/epsf-app into f…
dominictb Oct 20, 2025
d4011de
refactor: define list of derived merge fields
dominictb Oct 20, 2025
ec9047a
Merge branch 'main' of github.com-dominictb:dominictb/epsf-app into f…
dominictb Oct 22, 2025
dea773e
Merge branch 'main' of github.com-dominictb:dominictb/epsf-app into f…
dominictb Oct 22, 2025
877dd0e
Merge branch 'main' of github.com-dominictb:dominictb/epsf-app into f…
dominictb Oct 23, 2025
899649a
use comment.udfs
dominictb Oct 23, 2025
e0a2343
Merge branch 'main' of github.com-dominictb:dominictb/epsf-app into f…
dominictb Oct 30, 2025
6411b17
Merge branch 'main' of github.com-dominictb:dominictb/epsf-app into f…
dominictb Oct 30, 2025
7ba8864
remove redundant changes
dominictb Oct 30, 2025
a29850e
incrementally update tax and amount based on selection
dominictb Oct 30, 2025
3ce7d2f
send taxCode to Transaction_Merge API
dominictb Oct 30, 2025
ea683dc
Merge branch 'main' of github.com-dominictb:dominictb/epsf-app into f…
dominictb Nov 3, 2025
130ff06
fix unit test
dominictb Nov 3, 2025
37ef137
Merge branch 'main' of github.com-dominictb:dominictb/epsf-app into f…
dominictb Nov 5, 2025
67f0e96
Merge branch 'main' of github.com-dominictb:dominictb/epsf-app into f…
dominictb Nov 6, 2025
d14c2b4
fallback tax rate
dominictb Nov 6, 2025
e44f919
Merge branch 'main' of github.com-dominictb:dominictb/epsf-app into f…
dominictb Nov 10, 2025
5638769
auto merge taxAmount
dominictb Nov 10, 2025
25ada60
Merge branch 'main' of github.com-dominictb:dominictb/epsf-app into f…
dominictb Nov 13, 2025
1ea0682
Merge branch 'main' of github.com-dominictb:dominictb/epsf-app into f…
dominictb Nov 24, 2025
331bb46
fix unit test
dominictb Nov 24, 2025
6af2fd0
fix source transaction tax name is missing
dominictb Nov 24, 2025
347d5a9
Merge branch 'main' of github.com-dominictb:dominictb/epsf-app into f…
dominictb Nov 27, 2025
823cc4c
fix typecheck
dominictb Nov 27, 2025
9bbc0ff
fix typecheck
dominictb Nov 27, 2025
70cd447
Merge branch 'main' of github.com-dominictb:dominictb/epsf-app into f…
dominictb Dec 1, 2025
cd3db94
fix: tax does not show in confirm step if target policy does not supp…
dominictb Dec 1, 2025
25d6e32
fix failed checks
dominictb Dec 1, 2025
a86b07e
Merge branch 'main' of github.com-dominictb:dominictb/epsf-app into f…
dominictb Dec 4, 2025
2b75594
do not use transactionThreadReport
dominictb Dec 4, 2025
bdf1c69
rely on selectedTransactionByField to know which policy does the sele…
dominictb Dec 4, 2025
90bec5b
handle selectedTransactionByField in auto merge case
dominictb Dec 4, 2025
4c3c29e
fix unit test
dominictb Dec 4, 2025
86db0f3
fix unit test
dominictb Dec 4, 2025
8d68975
Merge branch 'main' of github.com-dominictb:dominictb/epsf-app into f…
dominictb Dec 17, 2025
2ab992a
Merge branch 'main' of github.com-dominictb:dominictb/epsf-app into f…
dominictb Dec 18, 2025
a98bb1b
Merge branch 'main' of github.com-dominictb:dominictb/epsf-app into f…
dominictb Dec 22, 2025
a7cb2bb
fix tax push row missing description
dominictb Dec 22, 2025
27557e4
fix: tax is auto merged even when target transaction does not have ta…
dominictb Dec 22, 2025
2b15531
Merge branch 'main' of github.com-dominictb:dominictb/epsf-app into f…
dominictb Dec 29, 2025
ef15ad3
Merge branch 'main' of github.com-dominictb:dominictb/epsf-app into f…
dominictb Dec 29, 2025
027d737
lint
dominictb Dec 29, 2025
496e727
lint
dominictb Dec 29, 2025
0d8581f
get sourceTransactionReport from useMergeTransactions
dominictb Dec 29, 2025
08a5a9d
Merge branch 'main' of github.com-dominictb:dominictb/epsf-app into f…
dominictb Dec 31, 2025
86d0b4c
use snapshot policy data
dominictb Dec 31, 2025
0e59988
Revert "fix tax push row missing description"
dominictb Dec 31, 2025
bcce786
Merge branch 'main' of github.com-dominictb:dominictb/epsf-app into f…
dominictb Jan 3, 2026
7e86943
Merge branch 'main' of github.com-dominictb:dominictb/epsf-app into f…
dominictb Jan 5, 2026
7d56278
update transaction report ID based on selection
dominictb Jan 5, 2026
2a4cbb5
Merge branch 'main' of github.com-dominictb:dominictb/epsf-app into f…
dominictb Jan 8, 2026
6328a3b
Revert "fallback tax rate"
dominictb Jan 8, 2026
6518595
fix: do not reset selectedTransactionByField
dominictb Jan 8, 2026
ca76e87
Merge branch 'main' of github.com-dominictb:dominictb/epsf-app into f…
dominictb Jan 14, 2026
b909921
fix lint
dominictb Jan 14, 2026
f12a935
compute taxName on selection
dominictb Jan 15, 2026
97bec70
Merge branch 'main' of github.com-dominictb:dominictb/epsf-app into f…
dominictb Jan 15, 2026
8d88494
Merge branch 'main' of github.com-dominictb:dominictb/epsf-app into f…
dominictb Jan 15, 2026
02fbb14
fix lint
dominictb Jan 15, 2026
10ed005
fix lint
dominictb Jan 16, 2026
0e348f1
remove lint silent
dominictb Jan 16, 2026
847b063
Merge branch 'main' of github.com-dominictb:dominictb/epsf-app into f…
dominictb Jan 26, 2026
4f45a0b
fix: tax does not show in confirmation step
dominictb Jan 26, 2026
07a2c7c
fix unit test
dominictb Jan 26, 2026
6a7da5e
fix: get correct report and policy for unreported expenses
dominictb Jan 29, 2026
ff306de
Merge branch 'main' of github.com-dominictb:dominictb/epsf-app into f…
dominictb Feb 9, 2026
f319cd2
pass taxPolicyID param
dominictb Feb 9, 2026
48f006c
fix typescript check
dominictb Feb 9, 2026
da1544f
Merge branch 'main' of github.com-dominictb:dominictb/epsf-app into f…
dominictb Feb 17, 2026
064603d
fix typescript
dominictb Feb 17, 2026
b7476bd
Merge branch 'main' of github.com-dominictb:dominictb/epsf-app into f…
dominictb Feb 18, 2026
9b00da0
Merge branch 'main' of github.com-dominictb:dominictb/epsf-app into f…
dominictb Feb 19, 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
13 changes: 7 additions & 6 deletions src/components/ReportActionItem/MoneyRequestView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ type MoneyRequestViewProps = {

parentReportID?: string;

/** Policy that the report belongs to */
/** Policy that the report belongs to, or the target transaction policy in merge transaction flow */
expensePolicy: OnyxEntry<OnyxTypes.Policy>;

/** Whether we should display the animated banner above the component */
Expand Down Expand Up @@ -309,9 +309,10 @@ function MoneyRequestView({
const shouldShowCard = isManagedCardTransaction && cardProgramName;

const taxRates = policy?.taxRates;
const formattedTaxAmount = updatedTransaction?.taxAmount
? convertToDisplayString(Math.abs(updatedTransaction?.taxAmount), transactionCurrency)
: convertToDisplayString(Math.abs(transactionTaxAmount ?? 0), transactionCurrency);
const formattedTaxAmount =
updatedTransaction?.taxAmount !== undefined
? convertToDisplayString(Math.abs(updatedTransaction.taxAmount), actualCurrency)
: convertToDisplayString(Math.abs(transactionTaxAmount ?? 0), actualCurrency);

const taxRatesDescription = taxRates?.name;
const taxRateTitle = updatedTransaction ? getTaxName(policy, updatedTransaction, isExpenseUnreported) : getTaxName(policy, transaction, isExpenseUnreported);
Expand Down Expand Up @@ -408,7 +409,7 @@ function MoneyRequestView({
canEditFieldOfMoneyRequest(parentReportAction, CONST.EDIT_REQUEST_FIELD.REIMBURSABLE, undefined, isChatReportArchived, undefined, transaction, moneyRequestReport, policy);
const shouldShowAttendees = shouldShowAttendeesTransactionUtils(iouType, policy);

const shouldShowTax = isTaxTrackingEnabled(isPolicyExpenseChat || isExpenseUnreported, policy, isDistanceRequest, isPerDiemRequest, isTimeRequest);
const shouldShowTax = !!transaction?.taxName || isTaxTrackingEnabled(isPolicyExpenseChat || isExpenseUnreported, policy, isDistanceRequest, isPerDiemRequest, isTimeRequest);
const tripID = getTripIDFromTransactionParentReportID(parentReport?.parentReportID);
const shouldShowViewTripDetails = hasReservationList(transaction) && !!tripID;

Expand Down Expand Up @@ -589,7 +590,7 @@ function MoneyRequestView({
const decodedCategoryName = getDecodedCategoryName(categoryValue);
const categoryCopyValue = !canEdit ? decodedCategoryName : undefined;
const cardCopyValue = cardProgramName;
const taxRateValue = taxRateTitle ?? fallbackTaxRateTitle;
const taxRateValue = transaction?.taxName ?? taxRateTitle ?? fallbackTaxRateTitle;
const taxRateCopyValue = !canEditTaxFields ? taxRateValue : undefined;
const taxAmountTitle = formattedTaxAmount ? formattedTaxAmount.toString() : '';
const taxAmountCopyValue = !canEditTaxFields ? taxAmountTitle : undefined;
Expand Down
35 changes: 28 additions & 7 deletions src/hooks/useMergeTransactions.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import type {OnyxEntry} from 'react-native-onyx';
import {useSearchContext} from '@components/Search/SearchContext';
import getNonEmptyStringOnyxID from '@libs/getNonEmptyStringOnyxID';
import {getTransactionFromMergeTransaction} from '@libs/MergeTransactionUtils';
import {getReportIDForExpense, getTransactionFromMergeTransaction} from '@libs/MergeTransactionUtils';
import {isExpenseUnreported} from '@libs/TransactionUtils';
import ONYXKEYS from '@src/ONYXKEYS';
import type {MergeTransaction, Report, SearchResults, Transaction} from '@src/types/onyx';
import type {MergeTransaction, Policy, Report, SearchResults, Transaction} from '@src/types/onyx';
import useOnyx from './useOnyx';
import usePolicyForMovingExpenses from './usePolicyForMovingExpenses';

type UseMergeTransactionsProps = {
mergeTransaction?: MergeTransaction;
Expand All @@ -15,6 +17,8 @@ type UseMergeTransactionsReturn = {
sourceTransaction?: Transaction;
targetTransactionReport?: Report;
sourceTransactionReport?: Report;
targetTransactionPolicy?: Policy;
sourceTransactionPolicy?: Policy;
};

function getTransaction(
Expand All @@ -37,6 +41,7 @@ function getTransaction(

function useMergeTransactions({mergeTransaction}: UseMergeTransactionsProps): UseMergeTransactionsReturn {
const {currentSearchHash, currentSearchResults} = useSearchContext();
const {policyForMovingExpensesID} = usePolicyForMovingExpenses();

const [onyxTargetTransaction] = useOnyx(`${ONYXKEYS.COLLECTION.TRANSACTION}${getNonEmptyStringOnyxID(mergeTransaction?.targetTransactionID)}`, {
canBeMissing: true,
Expand All @@ -48,24 +53,40 @@ function useMergeTransactions({mergeTransaction}: UseMergeTransactionsProps): Us
const targetTransaction = getTransaction(mergeTransaction, mergeTransaction?.targetTransactionID, onyxTargetTransaction, currentSearchResults);
const sourceTransaction = getTransaction(mergeTransaction, mergeTransaction?.sourceTransactionID, onyxSourceTransaction, currentSearchResults);

let [targetTransactionReport] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${getNonEmptyStringOnyxID(targetTransaction?.reportID)}`, {
const targetTransactionReportID = getReportIDForExpense(targetTransaction);
const sourceTransactionReportID = getReportIDForExpense(sourceTransaction);
let [targetTransactionReport] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${getNonEmptyStringOnyxID(targetTransactionReportID)}`, {
canBeMissing: true,
});
let [sourceTransactionReport] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${getNonEmptyStringOnyxID(sourceTransaction?.reportID)}`, {
let [sourceTransactionReport] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${getNonEmptyStringOnyxID(sourceTransactionReportID)}`, {
canBeMissing: true,
});

const targetTransactionPolicyID = isExpenseUnreported(targetTransaction) ? policyForMovingExpensesID : targetTransactionReport?.policyID;
const sourceTransactionPolicyID = isExpenseUnreported(sourceTransaction) ? policyForMovingExpensesID : sourceTransactionReport?.policyID;
let [targetTransactionPolicy] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY}${getNonEmptyStringOnyxID(targetTransactionPolicyID)}`, {
canBeMissing: true,
});
let [sourceTransactionPolicy] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY}${getNonEmptyStringOnyxID(sourceTransactionPolicyID)}`, {
canBeMissing: true,
});

// If we're on search and main collection reports are not available, get them from the search snapshot
if (currentSearchHash && currentSearchResults?.data) {
targetTransactionReport = targetTransactionReport ?? currentSearchResults?.data[`${ONYXKEYS.COLLECTION.REPORT}${targetTransaction?.reportID}`];
sourceTransactionReport = sourceTransactionReport ?? currentSearchResults?.data[`${ONYXKEYS.COLLECTION.REPORT}${sourceTransaction?.reportID}`];
// If we're on search and main collection reports are not available, get them from the search snapshot
targetTransactionReport = targetTransactionReport ?? currentSearchResults?.data[`${ONYXKEYS.COLLECTION.REPORT}${targetTransactionReportID}`];
sourceTransactionReport = sourceTransactionReport ?? currentSearchResults?.data[`${ONYXKEYS.COLLECTION.REPORT}${sourceTransactionReportID}`];
// If we're on search, search snapshot policies are more up to date
targetTransactionPolicy = currentSearchResults?.data[`${ONYXKEYS.COLLECTION.POLICY}${targetTransactionPolicyID}`];
sourceTransactionPolicy = currentSearchResults?.data[`${ONYXKEYS.COLLECTION.POLICY}${sourceTransactionPolicyID}`];
}

return {
targetTransaction,
sourceTransaction,
targetTransactionReport,
sourceTransactionReport,
targetTransactionPolicy,
sourceTransactionPolicy,
};
}

Expand Down
11 changes: 10 additions & 1 deletion src/hooks/useSelectedTransactionsActions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -341,7 +341,16 @@ function useSelectedTransactionsActions({
text: translate('common.merge'),
icon: expensifyIcons.ArrowCollapse,
value: MERGE,
onSelected: () => setupMergeTransactionDataAndNavigate(transactionID, selectedTransactionsList, localeCompare, [], false, isOnSearch),
onSelected: () =>
setupMergeTransactionDataAndNavigate(
transactionID,
selectedTransactionsList,
localeCompare,
[],
false,
isOnSearch,
selectedTransactionsList.length > 1 ? [policy, policy] : undefined,
),
});
}
}
Expand Down
2 changes: 2 additions & 0 deletions src/libs/DebugUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -952,6 +952,7 @@ function validateTransactionDraftProperty(key: keyof Transaction, value: string)
case 'category':
case 'merchant':
case 'taxCode':
case 'taxName':
case 'modifiedCurrency':
case 'modifiedMerchant':
case 'transactionID':
Expand Down Expand Up @@ -1119,6 +1120,7 @@ function validateTransactionDraftProperty(key: keyof Transaction, value: string)
isDemoTransaction: CONST.RED_BRICK_ROAD_PENDING_ACTION,
splitExpensesTotal: CONST.RED_BRICK_ROAD_PENDING_ACTION,
taxValue: CONST.RED_BRICK_ROAD_PENDING_ACTION,
taxName: CONST.RED_BRICK_ROAD_PENDING_ACTION,
pendingAutoCategorizationTime: CONST.RED_BRICK_ROAD_PENDING_ACTION,
groupAmount: CONST.RED_BRICK_ROAD_PENDING_ACTION,
groupCurrency: CONST.RED_BRICK_ROAD_PENDING_ACTION,
Expand Down
Loading
Loading