Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
3 changes: 2 additions & 1 deletion src/components/AvatarWithDisplayName.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,7 @@ function AvatarWithDisplayName({
const theme = useTheme();
const styles = useThemeStyles();
const StyleUtils = useStyleUtils();
const {translate} = useLocalize();
const [parentReport] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${report?.parentReportID}`, {canBeMissing: true});
const [invoiceReceiverPolicy] = useOnyx(
`${ONYXKEYS.COLLECTION.POLICY}${parentReport?.invoiceReceiver && 'policyID' in parentReport.invoiceReceiver ? parentReport.invoiceReceiver.policyID : undefined}`,
Expand All @@ -196,7 +197,7 @@ function AvatarWithDisplayName({
const ownerPersonalDetails = getPersonalDetailsForAccountIDs(report?.ownerAccountID ? [report.ownerAccountID] : [], personalDetails);
const displayNamesWithTooltips = getDisplayNamesWithTooltips(Object.values(ownerPersonalDetails), false, localeCompare);
const avatarBorderColor = avatarBorderColorProp ?? (isAnonymous ? theme.highlightBG : theme.componentBG);
const statusText = shouldDisplayStatus ? getReportStatusTranslation(report?.stateNum, report?.statusNum) : undefined;
const statusText = shouldDisplayStatus ? getReportStatusTranslation({stateNum: report?.stateNum, statusNum: report?.statusNum, translate}) : undefined;
const reportStatusColorStyle = shouldDisplayStatus ? getReportStatusColorStyle(theme, report?.stateNum, report?.statusNum) : {};

const actorAccountID = useRef<number | null>(null);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -338,8 +338,13 @@ function MoneyRequestReportPreviewContent({
);

const reportStatus = useMemo(
() => getReportStatusTranslation(iouReport?.stateNum ?? action?.childStateNum, iouReport?.statusNum ?? action?.childStatusNum),
[action?.childStateNum, action?.childStatusNum, iouReport?.stateNum, iouReport?.statusNum],
() =>
getReportStatusTranslation({
stateNum: iouReport?.stateNum ?? action?.childStateNum,
statusNum: iouReport?.statusNum ?? action?.childStatusNum,
translate,
}),
[action?.childStateNum, action?.childStatusNum, iouReport?.stateNum, iouReport?.statusNum, translate],
);

const reportStatusColorStyle = useMemo(
Expand Down
23 changes: 12 additions & 11 deletions src/libs/ReportUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -925,6 +925,12 @@
isReportArchived?: boolean;
};

type GetReportStatusParams = {
stateNum?: number;
statusNum?: number;
translate: LocaleContextProps['translate'];
};

type ReportByPolicyMap = Record<string, OnyxCollection<Report>>;

let currentUserEmail: string | undefined;
Expand All @@ -945,7 +951,7 @@
const parsedReportActionMessageCache: Record<string, string> = {};

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

Check warning on line 954 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) => {
conciergeReportID = value;
Expand All @@ -953,7 +959,7 @@
});

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

Check warning on line 962 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 @@ -971,7 +977,7 @@
let allPersonalDetails: OnyxEntry<PersonalDetailsList>;
let allPersonalDetailLogins: string[];
let currentUserPersonalDetails: OnyxEntry<PersonalDetails>;
Onyx.connect({

Check warning on line 980 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 (currentUserAccountID) {
Expand All @@ -983,14 +989,14 @@
});

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

Check warning on line 992 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),
});

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

Check warning on line 999 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) => (allPolicies = value),
Expand All @@ -998,7 +1004,7 @@

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

Check warning on line 1007 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 @@ -1039,14 +1045,14 @@
});

let allBetas: OnyxEntry<Beta[]>;
Onyx.connect({

Check warning on line 1048 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.BETAS,
callback: (value) => (allBetas = value),
});

let allTransactions: OnyxCollection<Transaction> = {};
let reportsTransactions: Record<string, Transaction[]> = {};
Onyx.connect({

Check warning on line 1055 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.TRANSACTION,
waitForCollectionCallback: true,
callback: (value) => {
Expand All @@ -1072,7 +1078,7 @@
});

let allReportActions: OnyxCollection<ReportActions>;
Onyx.connect({

Check warning on line 1081 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_ACTIONS,
waitForCollectionCallback: true,
callback: (actions) => {
Expand All @@ -1085,7 +1091,7 @@

let allReportMetadata: OnyxCollection<ReportMetadata>;
const allReportMetadataKeyValue: Record<string, ReportMetadata> = {};
Onyx.connect({

Check warning on line 1094 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_METADATA,
waitForCollectionCallback: true,
callback: (value) => {
Expand Down Expand Up @@ -12340,34 +12346,29 @@
* ========================================
*/

function getReportStatusTranslation(stateNum?: number, statusNum?: number): string {
function getReportStatusTranslation({stateNum, statusNum, translate}: GetReportStatusParams): string {
if (stateNum === undefined || statusNum === undefined) {
return '';
}

if (stateNum === CONST.REPORT.STATE_NUM.OPEN && statusNum === CONST.REPORT.STATUS_NUM.OPEN) {
// eslint-disable-next-line @typescript-eslint/no-deprecated
return translateLocal('common.draft');
return translate('common.draft');
}
if (stateNum === CONST.REPORT.STATE_NUM.SUBMITTED && statusNum === CONST.REPORT.STATUS_NUM.SUBMITTED) {
// eslint-disable-next-line @typescript-eslint/no-deprecated
return translateLocal('common.outstanding');
return translate('common.outstanding');
}
if (stateNum === CONST.REPORT.STATE_NUM.APPROVED && statusNum === CONST.REPORT.STATUS_NUM.CLOSED) {
// eslint-disable-next-line @typescript-eslint/no-deprecated
return translateLocal('common.done');
return translate('common.done');
}
if (stateNum === CONST.REPORT.STATE_NUM.APPROVED && statusNum === CONST.REPORT.STATUS_NUM.APPROVED) {
// eslint-disable-next-line @typescript-eslint/no-deprecated
return translateLocal('iou.approved');
return translate('iou.approved');
}
if (
(stateNum === CONST.REPORT.STATE_NUM.APPROVED && statusNum === CONST.REPORT.STATUS_NUM.REIMBURSED) ||
(stateNum === CONST.REPORT.STATE_NUM.BILLING && statusNum === CONST.REPORT.STATUS_NUM.REIMBURSED) ||
(stateNum === CONST.REPORT.STATE_NUM.AUTOREIMBURSED && statusNum === CONST.REPORT.STATUS_NUM.REIMBURSED)
) {
// eslint-disable-next-line @typescript-eslint/no-deprecated
return translateLocal('iou.settledExpensify');
return translate('iou.settledExpensify');
}

return '';
Expand Down
37 changes: 27 additions & 10 deletions tests/unit/ReportUtilsTest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {renderHook} from '@testing-library/react-native';
import {addDays, format as formatDate} from 'date-fns';
import type {OnyxCollection, OnyxEntry} from 'react-native-onyx';
import Onyx from 'react-native-onyx';
import type {LocaleContextProps} from '@components/LocaleContextProvider';
import useReportIsArchived from '@hooks/useReportIsArchived';
import {putOnHold} from '@libs/actions/IOU';
import type {OnboardingTaskLinks} from '@libs/actions/Welcome/OnboardingFlow';
Expand Down Expand Up @@ -7016,38 +7017,47 @@ describe('ReportUtils', () => {
});

describe('getReportStatusTranslation', () => {
const mockTranslate: LocaleContextProps['translate'] = (path, ...params) => translate(CONST.LOCALES.EN, path, ...params);

it('should return "Draft" for state 0, status 0', () => {
expect(getReportStatusTranslation(CONST.REPORT.STATE_NUM.OPEN, CONST.REPORT.STATUS_NUM.OPEN)).toBe(translate(CONST.LOCALES.EN, 'common.draft'));
const result = getReportStatusTranslation({stateNum: CONST.REPORT.STATE_NUM.OPEN, statusNum: CONST.REPORT.STATUS_NUM.OPEN, translate: mockTranslate});
expect(result).toBe(mockTranslate('common.draft'));
});

it('should return "Outstanding" for state 1, status 1', () => {
expect(getReportStatusTranslation(CONST.REPORT.STATE_NUM.SUBMITTED, CONST.REPORT.STATUS_NUM.SUBMITTED)).toBe(translate(CONST.LOCALES.EN, 'common.outstanding'));
const result = getReportStatusTranslation({stateNum: CONST.REPORT.STATE_NUM.SUBMITTED, statusNum: CONST.REPORT.STATUS_NUM.SUBMITTED, translate: mockTranslate});
expect(result).toBe(mockTranslate('common.outstanding'));
});

it('should return "Done" for state 2, status 2', () => {
expect(getReportStatusTranslation(CONST.REPORT.STATE_NUM.APPROVED, CONST.REPORT.STATUS_NUM.CLOSED)).toBe(translate(CONST.LOCALES.EN, 'common.done'));
const result = getReportStatusTranslation({stateNum: CONST.REPORT.STATE_NUM.APPROVED, statusNum: CONST.REPORT.STATUS_NUM.CLOSED, translate: mockTranslate});
expect(result).toBe(mockTranslate('common.done'));
});

it('should return "Approved" for state 2, status 3', () => {
expect(getReportStatusTranslation(CONST.REPORT.STATE_NUM.APPROVED, CONST.REPORT.STATUS_NUM.APPROVED)).toBe(translate(CONST.LOCALES.EN, 'iou.approved'));
const result = getReportStatusTranslation({stateNum: CONST.REPORT.STATE_NUM.APPROVED, statusNum: CONST.REPORT.STATUS_NUM.APPROVED, translate: mockTranslate});
expect(result).toBe(mockTranslate('iou.approved'));
});

it('should return "Paid" for state 2, status 4', () => {
expect(getReportStatusTranslation(CONST.REPORT.STATE_NUM.APPROVED, CONST.REPORT.STATUS_NUM.REIMBURSED)).toBe(translate(CONST.LOCALES.EN, 'iou.settledExpensify'));
const result = getReportStatusTranslation({stateNum: CONST.REPORT.STATE_NUM.APPROVED, statusNum: CONST.REPORT.STATUS_NUM.REIMBURSED, translate: mockTranslate});
expect(result).toBe(mockTranslate('iou.settledExpensify'));
});

it('should return "Paid" for state 3, status 4', () => {
expect(getReportStatusTranslation(CONST.REPORT.STATE_NUM.BILLING, CONST.REPORT.STATUS_NUM.REIMBURSED)).toBe(translate(CONST.LOCALES.EN, 'iou.settledExpensify'));
const result = getReportStatusTranslation({stateNum: CONST.REPORT.STATE_NUM.BILLING, statusNum: CONST.REPORT.STATUS_NUM.REIMBURSED, translate: mockTranslate});
expect(result).toBe(mockTranslate('iou.settledExpensify'));
});

it('should return "Paid" for state 6, status 4', () => {
expect(getReportStatusTranslation(CONST.REPORT.STATE_NUM.AUTOREIMBURSED, CONST.REPORT.STATUS_NUM.REIMBURSED)).toBe(translate(CONST.LOCALES.EN, 'iou.settledExpensify'));
const result = getReportStatusTranslation({stateNum: CONST.REPORT.STATE_NUM.AUTOREIMBURSED, statusNum: CONST.REPORT.STATUS_NUM.REIMBURSED, translate: mockTranslate});
expect(result).toBe(mockTranslate('iou.settledExpensify'));
});

it('should return an empty string when stateNum or statusNum is undefined', () => {
expect(getReportStatusTranslation(undefined, undefined)).toBe('');
expect(getReportStatusTranslation(CONST.REPORT.STATE_NUM.OPEN, undefined)).toBe('');
expect(getReportStatusTranslation(undefined, CONST.REPORT.STATUS_NUM.OPEN)).toBe('');
expect(getReportStatusTranslation({stateNum: undefined, statusNum: undefined, translate: mockTranslate})).toBe('');
expect(getReportStatusTranslation({stateNum: CONST.REPORT.STATE_NUM.OPEN, statusNum: undefined, translate: mockTranslate})).toBe('');
expect(getReportStatusTranslation({stateNum: undefined, statusNum: CONST.REPORT.STATUS_NUM.OPEN, translate: mockTranslate})).toBe('');
});
});

Expand Down Expand Up @@ -8388,6 +8398,7 @@ describe('ReportUtils', () => {
describe('getReportOrDraftReport', () => {
const mockReportIDIndex = 1;
const mockReportID = mockReportIDIndex.toString();
// eslint-disable-next-line @typescript-eslint/no-deprecated
const mockSearchReport: SearchReport = {
...createRandomReport(mockReportIDIndex, undefined),
reportName: 'Search Report',
Expand Down Expand Up @@ -8417,26 +8428,30 @@ describe('ReportUtils', () => {
});

test('returns onyx report when search report is not found but onyx report exists', async () => {
// eslint-disable-next-line @typescript-eslint/no-deprecated
const searchReports: SearchReport[] = [];
await Onyx.set(`${ONYXKEYS.COLLECTION.REPORT}${mockReportID}`, mockOnyxReport);
const result = getReportOrDraftReport(mockReportID, searchReports);
expect(result).toEqual(mockOnyxReport);
});

test('returns draft report when neither search nor onyx report exists but draft exists', async () => {
// eslint-disable-next-line @typescript-eslint/no-deprecated
const searchReports: SearchReport[] = [];
await Onyx.set(`${ONYXKEYS.COLLECTION.REPORT_DRAFT}${mockReportID}`, mockDraftReport);
const result = getReportOrDraftReport(mockReportID, searchReports);
expect(result).toEqual(mockDraftReport);
});

test('returns fallback report when no other reports exist', () => {
// eslint-disable-next-line @typescript-eslint/no-deprecated
const searchReports: SearchReport[] = [];
const result = getReportOrDraftReport('unknownReportID', searchReports, mockFallbackReport);
expect(result).toEqual(mockFallbackReport);
});

test('returns undefined when no reports exist and no fallback provided', () => {
// eslint-disable-next-line @typescript-eslint/no-deprecated
const searchReports: SearchReport[] = [];
const result = getReportOrDraftReport(mockReportID, searchReports);
expect(result).toBeUndefined();
Expand Down Expand Up @@ -8468,6 +8483,7 @@ describe('ReportUtils', () => {
});

test('prioritizes onyx report over draft report when both exist', async () => {
// eslint-disable-next-line @typescript-eslint/no-deprecated
const searchReports: SearchReport[] = [];
await Onyx.set(`${ONYXKEYS.COLLECTION.REPORT}${mockReportID}`, mockOnyxReport);
await Onyx.set(`${ONYXKEYS.COLLECTION.REPORT_DRAFT}${mockReportID}`, mockDraftReport);
Expand All @@ -8477,6 +8493,7 @@ describe('ReportUtils', () => {
});

test('prioritizes draft report over fallback when both exist', async () => {
// eslint-disable-next-line @typescript-eslint/no-deprecated
const searchReports: SearchReport[] = [];
await Onyx.set(`${ONYXKEYS.COLLECTION.REPORT_DRAFT}${mockReportID}`, mockDraftReport);
const result = getReportOrDraftReport(mockReportID, searchReports, mockFallbackReport);
Expand Down
Loading