Skip to content

Commit 737f30f

Browse files
authored
Merge pull request Expensify#65920 from thelullabyy/fix/64799/negative-sign-expense
Expense - Negative sign disappears after moving expense with negative sign to self DM
2 parents 799b550 + f3679a5 commit 737f30f

4 files changed

Lines changed: 33 additions & 19 deletions

File tree

src/libs/ReportUtils.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3975,7 +3975,7 @@ function getTransactionDetails(
39753975
const report = getReportOrDraftReport(transaction?.reportID);
39763976
return {
39773977
created: getFormattedCreated(transaction, createdDateFormat),
3978-
amount: getTransactionAmount(transaction, !isEmptyObject(report) && isExpenseReport(report)),
3978+
amount: getTransactionAmount(transaction, !isEmptyObject(report) && isExpenseReport(report), transaction?.reportID === CONST.REPORT.UNREPORTED_REPORT_ID),
39793979
attendees: getAttendees(transaction),
39803980
taxAmount: getTaxAmount(transaction, !isEmptyObject(report) && isExpenseReport(report)),
39813981
taxCode: getTaxCode(transaction),
@@ -4235,8 +4235,8 @@ function canEditFieldOfMoneyRequest(reportAction: OnyxInputOrEntry<ReportAction>
42354235

42364236
if (fieldToEdit === CONST.EDIT_REQUEST_FIELD.REPORT) {
42374237
// Unreported transaction from OldDot can have the reportID as an empty string
4238-
const isUnreported = !transaction?.reportID || transaction?.reportID === CONST.REPORT.UNREPORTED_REPORT_ID;
4239-
return isUnreported
4238+
const isUnreportedExpense = !transaction?.reportID || transaction?.reportID === CONST.REPORT.UNREPORTED_REPORT_ID;
4239+
return isUnreportedExpense
42404240
? Object.values(allPolicies ?? {}).flatMap((currentPolicy) =>
42414241
getOutstandingReportsForUser(currentPolicy?.id, currentUserAccountID, reportsByPolicyID?.[currentPolicy?.id ?? CONST.DEFAULT_NUMBER_ID] ?? {}),
42424242
).length > 0
@@ -4487,7 +4487,7 @@ function getTransactionReportName({
44874487
}
44884488

44894489
const report = getReportOrDraftReport(transaction?.reportID, reports);
4490-
const amount = getTransactionAmount(transaction, !isEmptyObject(report) && isExpenseReport(report)) ?? 0;
4490+
const amount = getTransactionAmount(transaction, !isEmptyObject(report) && isExpenseReport(report), transaction?.reportID === CONST.REPORT.UNREPORTED_REPORT_ID) ?? 0;
44914491
const formattedAmount = convertToDisplayString(amount, getCurrency(transaction)) ?? '';
44924492
const comment = getMerchantOrDescription(transaction);
44934493

@@ -4542,7 +4542,7 @@ function getReportPreviewMessage(
45424542
return translateLocal('iou.receiptMissingDetails');
45434543
}
45444544

4545-
const amount = getTransactionAmount(linkedTransaction, !isEmptyObject(report) && isExpenseReport(report)) ?? 0;
4545+
const amount = getTransactionAmount(linkedTransaction, !isEmptyObject(report) && isExpenseReport(report), linkedTransaction?.reportID === CONST.REPORT.UNREPORTED_REPORT_ID) ?? 0;
45464546
const formattedAmount = convertToDisplayString(amount, getCurrency(linkedTransaction)) ?? '';
45474547
return translateLocal('iou.didSplitAmount', {formattedAmount, comment: getMerchantOrDescription(linkedTransaction)});
45484548
}
@@ -4564,7 +4564,7 @@ function getReportPreviewMessage(
45644564
return translateLocal('iou.receiptMissingDetails');
45654565
}
45664566

4567-
const amount = getTransactionAmount(linkedTransaction, !isEmptyObject(report) && isExpenseReport(report)) ?? 0;
4567+
const amount = getTransactionAmount(linkedTransaction, !isEmptyObject(report) && isExpenseReport(report), linkedTransaction?.reportID === CONST.REPORT.UNREPORTED_REPORT_ID) ?? 0;
45684568
const formattedAmount = convertToDisplayString(amount, getCurrency(linkedTransaction)) ?? '';
45694569
return translateLocal('iou.trackedAmount', {formattedAmount, comment: getMerchantOrDescription(linkedTransaction)});
45704570
}
@@ -9179,7 +9179,7 @@ function getIOUReportActionDisplayMessage(reportAction: OnyxEntry<ReportAction>,
91799179
return translateLocal(translationKey, {amount: formattedAmount, payer: ''});
91809180
}
91819181

9182-
const amount = getTransactionAmount(transaction, !isEmptyObject(iouReport) && isExpenseReport(iouReport)) ?? 0;
9182+
const amount = getTransactionAmount(transaction, !isEmptyObject(iouReport) && isExpenseReport(iouReport), transaction?.reportID === CONST.REPORT.UNREPORTED_REPORT_ID) ?? 0;
91839183
const formattedAmount = convertToDisplayString(amount, getCurrency(transaction)) ?? '';
91849184
const isRequestSettled = isSettled(IOUReportID);
91859185
const isApproved = isReportApproved({report: iouReport});

src/libs/TransactionUtils/index.ts

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -413,6 +413,8 @@ function getUpdatedTransaction({
413413
shouldUpdateReceiptState?: boolean;
414414
policy?: OnyxEntry<Policy>;
415415
}): Transaction {
416+
const isUnReportedExpense = transaction?.reportID === CONST.REPORT.UNREPORTED_REPORT_ID;
417+
416418
// Only changing the first level fields so no need for deep clone now
417419
const updatedTransaction = lodashDeepClone(transaction);
418420
let shouldStopSmartscan = false;
@@ -429,7 +431,7 @@ function getUpdatedTransaction({
429431
shouldStopSmartscan = true;
430432
}
431433
if (Object.hasOwn(transactionChanges, 'amount') && typeof transactionChanges.amount === 'number') {
432-
updatedTransaction.modifiedAmount = isFromExpenseReport ? -transactionChanges.amount : transactionChanges.amount;
434+
updatedTransaction.modifiedAmount = isFromExpenseReport || isUnReportedExpense ? -transactionChanges.amount : transactionChanges.amount;
433435
shouldStopSmartscan = true;
434436
}
435437
if (Object.hasOwn(transactionChanges, 'currency')) {
@@ -458,7 +460,7 @@ function getUpdatedTransaction({
458460

459461
const distanceInMeters = getDistanceInMeters(transaction, unit);
460462
const amount = DistanceRequestUtils.getDistanceRequestAmount(distanceInMeters, unit, rate ?? 0);
461-
const updatedAmount = isFromExpenseReport ? -amount : amount;
463+
const updatedAmount = isFromExpenseReport || isUnReportedExpense ? -amount : amount;
462464
const updatedMerchant = DistanceRequestUtils.getDistanceMerchant(true, distanceInMeters, unit, rate, transaction.currency, translateLocal, (digit) =>
463465
toLocaleDigit(IntlStore.getCurrentLocale(), digit),
464466
);
@@ -497,7 +499,7 @@ function getUpdatedTransaction({
497499

498500
const distanceInMeters = getDistanceInMeters(transaction, oldMileageRate?.unit);
499501
const amount = DistanceRequestUtils.getDistanceRequestAmount(distanceInMeters, unit, rate ?? 0);
500-
const updatedAmount = isFromExpenseReport ? -amount : amount;
502+
const updatedAmount = isFromExpenseReport || isUnReportedExpense ? -amount : amount;
501503
const updatedCurrency = updatedMileageRate.currency ?? CONST.CURRENCY.USD;
502504
const updatedMerchant = DistanceRequestUtils.getDistanceMerchant(true, distanceInMeters, unit, rate, updatedCurrency, translateLocal, (digit) =>
503505
toLocaleDigit(IntlStore.getCurrentLocale(), digit),
@@ -583,7 +585,7 @@ function getDescription(transaction: OnyxInputOrEntry<Transaction>): string {
583585
*/
584586
function getAmount(transaction: OnyxInputOrEntry<Transaction>, isFromExpenseReport = false, isFromTrackedExpense = false): number {
585587
// IOU requests cannot have negative values, but they can be stored as negative values, let's return absolute value
586-
if (!isFromExpenseReport || isFromTrackedExpense) {
588+
if (!isFromExpenseReport && !isFromTrackedExpense) {
587589
const amount = transaction?.modifiedAmount ?? 0;
588590
if (amount) {
589591
return Math.abs(amount);
@@ -687,9 +689,9 @@ function isUnreportedAndHasInvalidDistanceRateTransaction(transaction: OnyxInput
687689
// eslint-disable-next-line deprecation/deprecation
688690
const policy = policyParam ?? getPolicy(report?.policyID);
689691
const {rate} = DistanceRequestUtils.getRate({transaction, policy});
690-
const isUnreported = !transaction.reportID || transaction.reportID === CONST.REPORT.UNREPORTED_REPORT_ID;
692+
const isUnreportedExpense = !transaction.reportID || transaction.reportID === CONST.REPORT.UNREPORTED_REPORT_ID;
691693

692-
if (isUnreported && !rate) {
694+
if (isUnreportedExpense && !rate) {
693695
return true;
694696
}
695697
}

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
@@ -447,4 +447,16 @@ describe('Check valid amount for IOU/Expense request', () => {
447447
const expenseAmount = TransactionUtils.getAmount(expenseTransaction, true, false);
448448
expect(expenseAmount).toBeLessThan(0);
449449
});
450+
451+
test('Unreported expense amount should retain negative sign', () => {
452+
const unreportedTransaction = TransactionUtils.buildOptimisticTransaction({
453+
transactionParams: {
454+
amount: 100,
455+
currency: 'USD',
456+
reportID: CONST.REPORT.UNREPORTED_REPORT_ID,
457+
},
458+
});
459+
const unreportedAmount = TransactionUtils.getAmount(unreportedTransaction, true, false);
460+
expect(unreportedAmount).toBeLessThan(0);
461+
});
450462
});

0 commit comments

Comments
 (0)