Skip to content

Commit 15e561b

Browse files
authored
Merge pull request Expensify#80611 from cretadn22/new-branch-add-modifyAmount-check
Fix wrong avatar shown after submitting report in Self DM
2 parents c2449ed + 2e9c66a commit 15e561b

2 files changed

Lines changed: 222 additions & 2 deletions

File tree

src/libs/SearchUIUtils.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1304,8 +1304,13 @@ function getToFieldValueForTransaction(
13041304
const isIOUReport = report?.type === CONST.REPORT.TYPE.IOU;
13051305
if (isIOUReport) {
13061306
return (
1307-
getIOUPayerAndReceiver(report?.managerID ?? CONST.DEFAULT_NUMBER_ID, report?.ownerAccountID ?? CONST.DEFAULT_NUMBER_ID, personalDetailsList, transactionItem.amount)?.to ??
1308-
emptyPersonalDetails
1307+
getIOUPayerAndReceiver(
1308+
report?.managerID ?? CONST.DEFAULT_NUMBER_ID,
1309+
report?.ownerAccountID ?? CONST.DEFAULT_NUMBER_ID,
1310+
personalDetailsList,
1311+
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
1312+
Number(transactionItem.modifiedAmount) || transactionItem.amount,
1313+
)?.to ?? emptyPersonalDetails
13091314
);
13101315
}
13111316
return personalDetailsList?.[report?.managerID] ?? emptyPersonalDetails;
@@ -3808,6 +3813,7 @@ export {
38083813
getTableMinWidth,
38093814
getCustomColumns,
38103815
getCustomColumnDefault,
3816+
getToFieldValueForTransaction,
38113817
isTodoSearch,
38123818
};
38133819
export type {SavedSearchMenuItem, SearchTypeMenuSection, SearchTypeMenuItem, SearchDateModifier, SearchDateModifierLower, SearchKey, ArchivedReportsIDSet};

tests/unit/Search/SearchUIUtilsTest.ts

Lines changed: 214 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ jest.mock('@userActions/Search', () => ({
5353

5454
const adminAccountID = 18439984;
5555
const adminEmail = 'admin@policy.com';
56+
const receiverAccountID = 18439985;
57+
const receiverEmail = 'receiver@policy.com';
5658

5759
const emptyPersonalDetails = {
5860
accountID: 0,
@@ -3938,4 +3940,216 @@ describe('SearchUIUtils', () => {
39383940
expect(transactionThread).toBeTruthy();
39393941
});
39403942
});
3943+
3944+
describe('getToFieldValueForTransaction', () => {
3945+
const mockTransaction: OnyxTypes.Transaction = {
3946+
transactionID: '1',
3947+
amount: 1000,
3948+
currency: 'USD',
3949+
reportID,
3950+
accountID: adminAccountID,
3951+
created: '2024-12-21 13:05:20',
3952+
merchant: 'Test Merchant',
3953+
} as OnyxTypes.Transaction;
3954+
3955+
const mockPersonalDetails: OnyxTypes.PersonalDetailsList = {
3956+
[adminAccountID]: {
3957+
accountID: adminAccountID,
3958+
displayName: 'Admin User',
3959+
login: adminEmail,
3960+
avatar: 'https://example.com/avatar.png',
3961+
},
3962+
[receiverAccountID]: {
3963+
accountID: receiverAccountID,
3964+
displayName: 'Receiver User',
3965+
login: receiverEmail,
3966+
avatar: 'https://example.com/avatar2.png',
3967+
},
3968+
};
3969+
3970+
test('Should return emptyPersonalDetails when report is undefined', () => {
3971+
const result = SearchUIUtils.getToFieldValueForTransaction(mockTransaction, undefined, mockPersonalDetails, undefined);
3972+
expect(result).toEqual(emptyPersonalDetails);
3973+
});
3974+
3975+
test('Should return emptyPersonalDetails when report is an open expense report', () => {
3976+
const openExpenseReport: OnyxTypes.Report = {
3977+
...report1,
3978+
stateNum: CONST.REPORT.STATE_NUM.OPEN,
3979+
statusNum: CONST.REPORT.STATUS_NUM.OPEN,
3980+
} as OnyxTypes.Report;
3981+
3982+
const result = SearchUIUtils.getToFieldValueForTransaction(mockTransaction, openExpenseReport, mockPersonalDetails, undefined);
3983+
expect(result).toEqual(emptyPersonalDetails);
3984+
});
3985+
3986+
test('Should return ownerAccountID personal details when reportAction is PAY type and report has ownerAccountID', () => {
3987+
const payReportAction: OnyxTypes.ReportAction = {
3988+
...reportAction1,
3989+
originalMessage: {
3990+
type: CONST.IOU.REPORT_ACTION_TYPE.PAY,
3991+
IOUTransactionID: mockTransaction.transactionID,
3992+
IOUReportID: report1.reportID,
3993+
},
3994+
} as OnyxTypes.ReportAction;
3995+
3996+
const nonOpenReport: OnyxTypes.Report = {
3997+
...report1,
3998+
stateNum: CONST.REPORT.STATE_NUM.SUBMITTED,
3999+
statusNum: CONST.REPORT.STATUS_NUM.SUBMITTED,
4000+
ownerAccountID: adminAccountID,
4001+
} as OnyxTypes.Report;
4002+
4003+
const result = SearchUIUtils.getToFieldValueForTransaction(mockTransaction, nonOpenReport, mockPersonalDetails, payReportAction);
4004+
expect(result).toEqual(mockPersonalDetails[adminAccountID]);
4005+
});
4006+
4007+
test('Should return managerID personal details when reportAction is not a money request action', () => {
4008+
const nonMoneyRequestAction: OnyxTypes.ReportAction = {
4009+
...reportAction1,
4010+
actionName: CONST.REPORT.ACTIONS.TYPE.CREATED,
4011+
originalMessage: undefined,
4012+
} as OnyxTypes.ReportAction;
4013+
4014+
const nonOpenReport: OnyxTypes.Report = {
4015+
...report1,
4016+
stateNum: CONST.REPORT.STATE_NUM.SUBMITTED,
4017+
statusNum: CONST.REPORT.STATUS_NUM.SUBMITTED,
4018+
managerID: receiverAccountID,
4019+
} as OnyxTypes.Report;
4020+
4021+
const result = SearchUIUtils.getToFieldValueForTransaction(mockTransaction, nonOpenReport, mockPersonalDetails, nonMoneyRequestAction);
4022+
expect(result).toEqual(mockPersonalDetails[receiverAccountID]);
4023+
});
4024+
4025+
test('Should return getIOUPayerAndReceiver result for IOU report with managerID', () => {
4026+
const iouReport: OnyxTypes.Report = {
4027+
...report3,
4028+
managerID: receiverAccountID,
4029+
ownerAccountID: adminAccountID,
4030+
type: CONST.REPORT.TYPE.IOU,
4031+
} as OnyxTypes.Report;
4032+
4033+
const transactionWithNegativeAmount: OnyxTypes.Transaction = {
4034+
...mockTransaction,
4035+
amount: -1000,
4036+
modifiedAmount: 1000,
4037+
} as OnyxTypes.Transaction;
4038+
4039+
const result = SearchUIUtils.getToFieldValueForTransaction(transactionWithNegativeAmount, iouReport, mockPersonalDetails, undefined);
4040+
expect(result).toEqual(mockPersonalDetails[receiverAccountID]);
4041+
});
4042+
4043+
test('Should return getIOUPayerAndReceiver result for IOU report with positive amount', () => {
4044+
const iouReport: OnyxTypes.Report = {
4045+
...report3,
4046+
managerID: receiverAccountID,
4047+
ownerAccountID: adminAccountID,
4048+
type: CONST.REPORT.TYPE.IOU,
4049+
} as OnyxTypes.Report;
4050+
4051+
const transactionWithPositiveAmount: OnyxTypes.Transaction = {
4052+
...mockTransaction,
4053+
amount: 1000,
4054+
} as OnyxTypes.Transaction;
4055+
4056+
const result = SearchUIUtils.getToFieldValueForTransaction(transactionWithPositiveAmount, iouReport, mockPersonalDetails, undefined);
4057+
expect(result).toEqual(mockPersonalDetails[receiverAccountID]);
4058+
});
4059+
4060+
test('Should use modifiedAmount when available for IOU report', () => {
4061+
const iouReport: OnyxTypes.Report = {
4062+
...report3,
4063+
managerID: receiverAccountID,
4064+
ownerAccountID: adminAccountID,
4065+
type: CONST.REPORT.TYPE.IOU,
4066+
} as OnyxTypes.Report;
4067+
4068+
const transactionWithModifiedAmount: OnyxTypes.Transaction = {
4069+
...mockTransaction,
4070+
amount: 1000,
4071+
modifiedAmount: -2000,
4072+
} as OnyxTypes.Transaction;
4073+
4074+
const result = SearchUIUtils.getToFieldValueForTransaction(transactionWithModifiedAmount, iouReport, mockPersonalDetails, undefined);
4075+
expect(result).toEqual(mockPersonalDetails[adminAccountID]);
4076+
});
4077+
4078+
test('Should return managerID personal details for non-IOU report with managerID', () => {
4079+
const nonIOUReport: OnyxTypes.Report = {
4080+
...report1,
4081+
stateNum: CONST.REPORT.STATE_NUM.SUBMITTED,
4082+
statusNum: CONST.REPORT.STATUS_NUM.SUBMITTED,
4083+
managerID: receiverAccountID,
4084+
type: CONST.REPORT.TYPE.EXPENSE,
4085+
} as OnyxTypes.Report;
4086+
4087+
const result = SearchUIUtils.getToFieldValueForTransaction(mockTransaction, nonIOUReport, mockPersonalDetails, undefined);
4088+
expect(result).toEqual(mockPersonalDetails[receiverAccountID]);
4089+
});
4090+
4091+
test('Should return emptyPersonalDetails when managerID personal details are not found', () => {
4092+
const nonIOUReport: OnyxTypes.Report = {
4093+
...report1,
4094+
stateNum: CONST.REPORT.STATE_NUM.SUBMITTED,
4095+
statusNum: CONST.REPORT.STATUS_NUM.SUBMITTED,
4096+
managerID: 999999,
4097+
type: CONST.REPORT.TYPE.EXPENSE,
4098+
} as OnyxTypes.Report;
4099+
4100+
const result = SearchUIUtils.getToFieldValueForTransaction(mockTransaction, nonIOUReport, mockPersonalDetails, undefined);
4101+
expect(result).toEqual(emptyPersonalDetails);
4102+
});
4103+
4104+
test('Should return emptyPersonalDetails when report has no managerID', () => {
4105+
const reportWithoutManager: OnyxTypes.Report = {
4106+
...report1,
4107+
stateNum: CONST.REPORT.STATE_NUM.SUBMITTED,
4108+
statusNum: CONST.REPORT.STATUS_NUM.SUBMITTED,
4109+
managerID: undefined,
4110+
type: CONST.REPORT.TYPE.EXPENSE,
4111+
} as OnyxTypes.Report;
4112+
4113+
const result = SearchUIUtils.getToFieldValueForTransaction(mockTransaction, reportWithoutManager, mockPersonalDetails, undefined);
4114+
expect(result).toEqual(emptyPersonalDetails);
4115+
});
4116+
4117+
test('Should return emptyPersonalDetails when getIOUPayerAndReceiver returns undefined for IOU report', () => {
4118+
const iouReport: OnyxTypes.Report = {
4119+
...report3,
4120+
managerID: receiverAccountID,
4121+
ownerAccountID: adminAccountID,
4122+
type: CONST.REPORT.TYPE.IOU,
4123+
} as OnyxTypes.Report;
4124+
4125+
const emptyPersonalDetailsList: OnyxTypes.PersonalDetailsList = {};
4126+
4127+
const result = SearchUIUtils.getToFieldValueForTransaction(mockTransaction, iouReport, emptyPersonalDetailsList, undefined);
4128+
expect(result).toEqual(emptyPersonalDetails);
4129+
});
4130+
4131+
test('Should handle IOU report with DEFAULT_NUMBER_ID for managerID', () => {
4132+
const iouReport: OnyxTypes.Report = {
4133+
...report3,
4134+
managerID: CONST.DEFAULT_NUMBER_ID,
4135+
ownerAccountID: adminAccountID,
4136+
type: CONST.REPORT.TYPE.IOU,
4137+
} as OnyxTypes.Report;
4138+
4139+
const result = SearchUIUtils.getToFieldValueForTransaction(mockTransaction, iouReport, mockPersonalDetails, undefined);
4140+
expect(result).toBeDefined();
4141+
});
4142+
4143+
test('Should handle IOU report with DEFAULT_NUMBER_ID for ownerAccountID', () => {
4144+
const iouReport: OnyxTypes.Report = {
4145+
...report3,
4146+
managerID: receiverAccountID,
4147+
ownerAccountID: CONST.DEFAULT_NUMBER_ID,
4148+
type: CONST.REPORT.TYPE.IOU,
4149+
} as OnyxTypes.Report;
4150+
4151+
const result = SearchUIUtils.getToFieldValueForTransaction(mockTransaction, iouReport, mockPersonalDetails, undefined);
4152+
expect(result).toBeDefined();
4153+
});
4154+
});
39414155
});

0 commit comments

Comments
 (0)