Skip to content

Commit 13f08ed

Browse files
committed
fix: negative sign unreported expense
1 parent 7be2292 commit 13f08ed

4 files changed

Lines changed: 29 additions & 16 deletions

File tree

src/libs/ReportUtils.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3961,7 +3961,7 @@ function getTransactionDetails(
39613961
const report = getReportOrDraftReport(transaction?.reportID);
39623962
return {
39633963
created: getFormattedCreated(transaction, createdDateFormat),
3964-
amount: getTransactionAmount(transaction, !isEmptyObject(report) && isExpenseReport(report)),
3964+
amount: getTransactionAmount(transaction, !isEmptyObject(report) && isExpenseReport(report), transaction?.reportID === CONST.REPORT.UNREPORTED_REPORT_ID),
39653965
attendees: getAttendees(transaction),
39663966
taxAmount: getTaxAmount(transaction, !isEmptyObject(report) && isExpenseReport(report)),
39673967
taxCode: getTaxCode(transaction),
@@ -4221,8 +4221,8 @@ function canEditFieldOfMoneyRequest(reportAction: OnyxInputOrEntry<ReportAction>
42214221

42224222
if (fieldToEdit === CONST.EDIT_REQUEST_FIELD.REPORT) {
42234223
// Unreported transaction from OldDot can have the reportID as an empty string
4224-
const isUnreported = !transaction?.reportID || transaction?.reportID === CONST.REPORT.UNREPORTED_REPORT_ID;
4225-
return isUnreported
4224+
const isUnreportedExpense = !transaction?.reportID || transaction?.reportID === CONST.REPORT.UNREPORTED_REPORT_ID;
4225+
return isUnreportedExpense
42264226
? Object.values(allPolicies ?? {}).flatMap((currentPolicy) => getOutstandingReportsForUser(currentPolicy?.id, currentUserAccountID, allReports ?? {})).length > 0
42274227
: Object.values(allPolicies ?? {}).flatMap((currentPolicy) => getOutstandingReportsForUser(currentPolicy?.id, moneyRequestReport?.ownerAccountID, allReports ?? {})).length > 1;
42284228
}

src/libs/TransactionUtils/index.ts

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -392,6 +392,8 @@ function getUpdatedTransaction({
392392
shouldUpdateReceiptState?: boolean;
393393
policy?: OnyxEntry<Policy>;
394394
}): Transaction {
395+
const isUnReportedExpense = transaction?.reportID === CONST.REPORT.UNREPORTED_REPORT_ID;
396+
395397
// Only changing the first level fields so no need for deep clone now
396398
const updatedTransaction = lodashDeepClone(transaction);
397399
let shouldStopSmartscan = false;
@@ -408,8 +410,7 @@ function getUpdatedTransaction({
408410
shouldStopSmartscan = true;
409411
}
410412
if (Object.hasOwn(transactionChanges, 'amount') && typeof transactionChanges.amount === 'number') {
411-
updatedTransaction.modifiedAmount = isFromExpenseReport ? -transactionChanges.amount : transactionChanges.amount;
412-
shouldStopSmartscan = true;
413+
updatedTransaction.modifiedAmount = isFromExpenseReport || isUnReportedExpense ? -transactionChanges.amount : transactionChanges.amount;
413414
}
414415
if (Object.hasOwn(transactionChanges, 'currency')) {
415416
updatedTransaction.modifiedCurrency = transactionChanges.currency;
@@ -437,7 +438,7 @@ function getUpdatedTransaction({
437438

438439
const distanceInMeters = getDistanceInMeters(transaction, unit);
439440
const amount = DistanceRequestUtils.getDistanceRequestAmount(distanceInMeters, unit, rate ?? 0);
440-
const updatedAmount = isFromExpenseReport ? -amount : amount;
441+
const updatedAmount = isFromExpenseReport || isUnReportedExpense ? -amount : amount;
441442
const updatedMerchant = DistanceRequestUtils.getDistanceMerchant(true, distanceInMeters, unit, rate, transaction.currency, translateLocal, (digit) =>
442443
toLocaleDigit(IntlStore.getCurrentLocale(), digit),
443444
);
@@ -476,7 +477,7 @@ function getUpdatedTransaction({
476477

477478
const distanceInMeters = getDistanceInMeters(transaction, oldMileageRate?.unit);
478479
const amount = DistanceRequestUtils.getDistanceRequestAmount(distanceInMeters, unit, rate ?? 0);
479-
const updatedAmount = isFromExpenseReport ? -amount : amount;
480+
const updatedAmount = isFromExpenseReport || isUnReportedExpense ? -amount : amount;
480481
const updatedCurrency = updatedMileageRate.currency ?? CONST.CURRENCY.USD;
481482
const updatedMerchant = DistanceRequestUtils.getDistanceMerchant(true, distanceInMeters, unit, rate, updatedCurrency, translateLocal, (digit) =>
482483
toLocaleDigit(IntlStore.getCurrentLocale(), digit),
@@ -562,7 +563,7 @@ function getDescription(transaction: OnyxInputOrEntry<Transaction>): string {
562563
*/
563564
function getAmount(transaction: OnyxInputOrEntry<Transaction>, isFromExpenseReport = false, isFromTrackedExpense = false): number {
564565
// IOU requests cannot have negative values, but they can be stored as negative values, let's return absolute value
565-
if (!isFromExpenseReport || isFromTrackedExpense) {
566+
if (!isFromExpenseReport && !isFromTrackedExpense) {
566567
const amount = transaction?.modifiedAmount ?? 0;
567568
if (amount) {
568569
return Math.abs(amount);
@@ -666,9 +667,9 @@ function isUnreportedAndHasInvalidDistanceRateTransaction(transaction: OnyxInput
666667
// eslint-disable-next-line deprecation/deprecation
667668
const policy = policyParam ?? getPolicy(report?.policyID);
668669
const {rate} = DistanceRequestUtils.getRate({transaction, policy});
669-
const isUnreported = !transaction.reportID || transaction.reportID === CONST.REPORT.UNREPORTED_REPORT_ID;
670+
const isUnreportedExpense = !transaction.reportID || transaction.reportID === CONST.REPORT.UNREPORTED_REPORT_ID;
670671

671-
if (isUnreported && !rate) {
672+
if (isUnreportedExpense && !rate) {
672673
return true;
673674
}
674675
}

src/libs/actions/Transaction.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -619,12 +619,12 @@ function changeTransactionsReport(transactionIDs: string[], reportID: string, po
619619
let transactionsMoved = false;
620620

621621
transactions.forEach((transaction) => {
622-
const isUnreported = !transaction.reportID || transaction.reportID === CONST.REPORT.UNREPORTED_REPORT_ID;
622+
const isUnreportedExpense = !transaction.reportID || transaction.reportID === CONST.REPORT.UNREPORTED_REPORT_ID;
623623

624624
// We'll handle optimistically creating the selfDM as part of https://github.com/Expensify/App/issues/60288
625625
const selfDMReportID = findSelfDMReportID() ?? CONST.REPORT.UNREPORTED_REPORT_ID;
626626

627-
const oldIOUAction = getIOUActionForReportID(isUnreported ? selfDMReportID : transaction.reportID, transaction.transactionID);
627+
const oldIOUAction = getIOUActionForReportID(isUnreportedExpense ? selfDMReportID : transaction.reportID, transaction.transactionID);
628628
if (!transaction.reportID || transaction.reportID === reportID) {
629629
return;
630630
}
@@ -699,7 +699,7 @@ function changeTransactionsReport(transactionIDs: string[], reportID: string, po
699699
created: oldIOUAction?.created ?? DateUtils.getDBTime(),
700700
};
701701

702-
const trackExpenseActionableWhisper = isUnreported ? getTrackExpenseActionableWhisper(transaction.transactionID, selfDMReportID) : undefined;
702+
const trackExpenseActionableWhisper = isUnreportedExpense ? getTrackExpenseActionableWhisper(transaction.transactionID, selfDMReportID) : undefined;
703703

704704
if (oldIOUAction) {
705705
optimisticData.push({
@@ -712,7 +712,7 @@ function changeTransactionsReport(transactionIDs: string[], reportID: string, po
712712

713713
optimisticData.push({
714714
onyxMethod: Onyx.METHOD.MERGE,
715-
key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${isUnreported ? selfDMReportID : oldReportID}`,
715+
key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${isUnreportedExpense ? selfDMReportID : oldReportID}`,
716716
value: {
717717
[oldIOUAction.reportActionID]: {
718718
previousMessage: oldIOUAction.message,
@@ -753,7 +753,7 @@ function changeTransactionsReport(transactionIDs: string[], reportID: string, po
753753
},
754754
{
755755
onyxMethod: Onyx.METHOD.MERGE,
756-
key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${isUnreported ? selfDMReportID : oldReportID}`,
756+
key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${isUnreportedExpense ? selfDMReportID : oldReportID}`,
757757
value: {
758758
[oldIOUAction.reportActionID]: oldIOUAction,
759759
...(trackExpenseActionableWhisper ? {[trackExpenseActionableWhisper.reportActionID]: trackExpenseActionableWhisper} : {}),
@@ -778,7 +778,7 @@ function changeTransactionsReport(transactionIDs: string[], reportID: string, po
778778
onyxMethod: Onyx.METHOD.MERGE,
779779
key: `${ONYXKEYS.COLLECTION.REPORT}${oldIOUAction.childReportID}`,
780780
value: {
781-
parentReportID: isUnreported ? selfDMReportID : oldReportID,
781+
parentReportID: isUnreportedExpense ? selfDMReportID : oldReportID,
782782
optimisticMoneyRequestReportActionID: oldIOUAction.reportActionID,
783783
policyID: allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${oldIOUAction.reportActionID}`]?.policyID,
784784
},

tests/unit/IOUUtilsTest.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -383,4 +383,16 @@ describe('Check valid amount for IOU/Expense request', () => {
383383
const expenseAmount = TransactionUtils.getAmount(expenseTransaction, true, false);
384384
expect(expenseAmount).toBeLessThan(0);
385385
});
386+
387+
test('Unreported transaction amount should be negative', () => {
388+
const unreportedTransaction = TransactionUtils.buildOptimisticTransaction({
389+
transactionParams: {
390+
amount: 100,
391+
currency: 'USD',
392+
reportID: CONST.REPORT.UNREPORTED_REPORT_ID,
393+
},
394+
});
395+
const unreportedAmount = TransactionUtils.getAmount(unreportedTransaction, true, false);
396+
expect(unreportedAmount).toBeLessThan(0);
397+
});
386398
});

0 commit comments

Comments
 (0)