diff --git a/package.json b/package.json index 42bbef56f9d..4a87b83591e 100644 --- a/package.json +++ b/package.json @@ -46,7 +46,7 @@ "test:debug": "TZ=utc NODE_OPTIONS='--inspect-brk --experimental-vm-modules' jest --runInBand", "perf-test": "NODE_OPTIONS=--experimental-vm-modules npx reassure", "typecheck": "NODE_OPTIONS=--max_old_space_size=8192 tsc", - "lint": "NODE_OPTIONS=--max_old_space_size=8192 eslint . --max-warnings=326 --cache --cache-location=node_modules/.cache/eslint", + "lint": "NODE_OPTIONS=--max_old_space_size=8192 eslint . --max-warnings=325 --cache --cache-location=node_modules/.cache/eslint", "lint-changed": "NODE_OPTIONS=--max_old_space_size=8192 ./scripts/lintChanged.sh", "lint-watch": "npx eslint-watch --watch --changed", "shellcheck": "./scripts/shellCheck.sh", diff --git a/src/components/TestDrive/Modal/EmployeeTestDriveModal.tsx b/src/components/TestDrive/Modal/EmployeeTestDriveModal.tsx index c93caf877b9..8faf31f2b5a 100644 --- a/src/components/TestDrive/Modal/EmployeeTestDriveModal.tsx +++ b/src/components/TestDrive/Modal/EmployeeTestDriveModal.tsx @@ -7,6 +7,7 @@ import TestReceipt from '@assets/images/fake-test-drive-employee-receipt.jpg'; import TextInput from '@components/TextInput'; import useLocalize from '@hooks/useLocalize'; import useOnboardingMessages from '@hooks/useOnboardingMessages'; +import useOnyx from '@hooks/useOnyx'; import { initMoneyRequest, setMoneyRequestAmount, @@ -24,12 +25,16 @@ import type {TestDriveModalNavigatorParamList} from '@libs/Navigation/types'; import {generateReportID} from '@libs/ReportUtils'; import {generateAccountID} from '@libs/UserUtils'; import CONST from '@src/CONST'; +import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; import type SCREENS from '@src/SCREENS'; import BaseTestDriveModal from './BaseTestDriveModal'; function EmployeeTestDriveModal() { const {translate} = useLocalize(); + const reportID = generateReportID(); + const [report] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${reportID}`, {canBeMissing: true}); + const [parentReport] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${report?.parentReportID}`, {canBeMissing: true}); const route = useRoute>(); const [bossEmail, setBossEmail] = useState(route.params?.bossEmail ?? ''); const [formError, setFormError] = useState(); @@ -57,11 +62,13 @@ function EmployeeTestDriveModal() { 'jpg', (source, _, filename) => { const transactionID = CONST.IOU.OPTIMISTIC_TRANSACTION_ID; - const reportID = generateReportID(); + initMoneyRequest({ reportID, isFromGlobalCreate: false, newIouRequestType: CONST.IOU.REQUEST_TYPE.SCAN, + report, + parentReport, }); setMoneyRequestReceipt(transactionID, source, filename, true, CONST.TEST_RECEIPT.FILE_TYPE, false, true); diff --git a/src/libs/PerDiemRequestUtils.ts b/src/libs/PerDiemRequestUtils.ts index 8f47471b2b7..b25d8598cc0 100644 --- a/src/libs/PerDiemRequestUtils.ts +++ b/src/libs/PerDiemRequestUtils.ts @@ -1,9 +1,7 @@ import {addDays, differenceInDays, differenceInMinutes, format, isSameDay, startOfDay} from 'date-fns'; import lodashSortBy from 'lodash/sortBy'; -import type {OnyxCollection, OnyxEntry} from 'react-native-onyx'; -import Onyx from 'react-native-onyx'; +import type {OnyxEntry} from 'react-native-onyx'; import CONST from '@src/CONST'; -import ONYXKEYS from '@src/ONYXKEYS'; import type {Report, Transaction} from '@src/types/onyx'; import type {CustomUnit, Rate} from '@src/types/onyx/Policy'; import {translateLocal} from './Localize'; @@ -12,21 +10,10 @@ import {getPolicy} from './PolicyUtils'; import {isPolicyExpenseChat} from './ReportUtils'; import tokenizedSearch from './tokenizedSearch'; -let allReports: OnyxCollection; -Onyx.connect({ - key: ONYXKEYS.COLLECTION.REPORT, - waitForCollectionCallback: true, - callback: (value) => { - allReports = value; - }, -}); - /** * Returns custom unit ID for the per diem transaction */ -function getCustomUnitID(reportID: string) { - const report = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]; - const parentReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${report?.parentReportID}`]; +function getCustomUnitID(report: OnyxEntry, parentReport: OnyxEntry) { // This will be fixed as part of https://github.com/Expensify/Expensify/issues/507850 // eslint-disable-next-line deprecation/deprecation const policy = getPolicy(report?.policyID ?? parentReport?.policyID); diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index 4a39b875e99..f5497b6c6c0 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -259,6 +259,8 @@ type InitMoneyRequestParams = { isFromGlobalCreate?: boolean; currentIouRequestType?: IOURequestType | undefined; newIouRequestType: IOURequestType; + report: OnyxEntry; + parentReport: OnyxEntry; }; type MoneyRequestInformation = { @@ -895,8 +897,10 @@ function getReportPreviewAction(chatReportID: string | undefined, iouReportID: s * @param policy * @param isFromGlobalCreate * @param iouRequestType one of manual/scan/distance + * @param report the report to attach the transaction to + * @param parentReport the parent report to attach the transaction to */ -function initMoneyRequest({reportID, policy, isFromGlobalCreate, currentIouRequestType, newIouRequestType}: InitMoneyRequestParams) { +function initMoneyRequest({reportID, policy, isFromGlobalCreate, currentIouRequestType, newIouRequestType, report, parentReport}: InitMoneyRequestParams) { // Generate a brand new transactionID // This will be fixed as part of https://github.com/Expensify/Expensify/issues/507850 // eslint-disable-next-line deprecation/deprecation @@ -952,7 +956,7 @@ function initMoneyRequest({reportID, policy, isFromGlobalCreate, currentIouReque }, }; if (!isFromGlobalCreate) { - const {customUnitID, category} = getCustomUnitID(reportID); + const {customUnitID, category} = getCustomUnitID(report, parentReport); comment.customUnit = {...comment.customUnit, customUnitID}; requestCategory = category ?? null; } diff --git a/src/pages/Search/SearchPage.tsx b/src/pages/Search/SearchPage.tsx index 875e1eade77..c27751b89c0 100644 --- a/src/pages/Search/SearchPage.tsx +++ b/src/pages/Search/SearchPage.tsx @@ -72,7 +72,9 @@ function SearchPage({route}: SearchPageProps) { const currentUserPersonalDetails = useCurrentUserPersonalDetails(); const isMobileSelectionModeEnabled = useMobileSelectionMode(); const [lastPaymentMethods] = useOnyx(ONYXKEYS.NVP_LAST_PAYMENT_METHOD, {canBeMissing: true}); - + const newReportID = generateReportID(); + const [newReport] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${newReportID}`, {canBeMissing: true}); + const [newParentReport] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${newReport?.parentReportID}`, {canBeMissing: true}); const [activePolicyID] = useOnyx(ONYXKEYS.NVP_ACTIVE_POLICY_ID, {canBeMissing: false}); const [activePolicy] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY}${activePolicyID}`, {canBeMissing: true}); @@ -392,11 +394,12 @@ function SearchPage({route}: SearchPageProps) { }; const saveFileAndInitMoneyRequest = (files: FileObject[]) => { - const newReportID = generateReportID(); const initialTransaction = initMoneyRequest({ isFromGlobalCreate: true, reportID: newReportID, newIouRequestType: CONST.IOU.REQUEST_TYPE.SCAN, + report: newReport, + parentReport: newParentReport, }); const newReceiptFiles: ReceiptFile[] = []; diff --git a/src/pages/Share/SubmitDetailsPage.tsx b/src/pages/Share/SubmitDetailsPage.tsx index b3814d41635..341d8590165 100644 --- a/src/pages/Share/SubmitDetailsPage.tsx +++ b/src/pages/Share/SubmitDetailsPage.tsx @@ -43,6 +43,7 @@ function SubmitDetailsPage({ const [unknownUserDetails] = useOnyx(ONYXKEYS.SHARE_UNKNOWN_USER_DETAILS, {canBeMissing: true}); const [personalDetails] = useOnyx(`${ONYXKEYS.PERSONAL_DETAILS_LIST}`, {canBeMissing: true}); const report: OnyxEntry = getReportOrDraftReport(reportOrAccountID); + const [parentReport] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${report?.parentReportID}`, {canBeMissing: true}); const [policy] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY}${report?.policyID}`, {canBeMissing: false}); const [transaction] = useOnyx(`${ONYXKEYS.COLLECTION.TRANSACTION_DRAFT}${CONST.IOU.OPTIMISTIC_TRANSACTION_ID}`, {canBeMissing: true}); const [policyCategories] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY_CATEGORIES}${getIOURequestPolicyID(transaction, report)}`, {canBeMissing: false}); @@ -69,8 +70,10 @@ function SubmitDetailsPage({ policy, currentIouRequestType: CONST.IOU.REQUEST_TYPE.SCAN, newIouRequestType: CONST.IOU.REQUEST_TYPE.SCAN, + report, + parentReport, }); - }, [reportOrAccountID, policy]); + }, [reportOrAccountID, policy, report, parentReport]); const selectedParticipants = unknownUserDetails ? [unknownUserDetails] : getMoneyRequestParticipantsFromReport(report); const participants = selectedParticipants.map((participant) => diff --git a/src/pages/home/report/ReportActionCompose/ReportActionCompose.tsx b/src/pages/home/report/ReportActionCompose/ReportActionCompose.tsx index aae3713d743..5a6cc51e412 100644 --- a/src/pages/home/report/ReportActionCompose/ReportActionCompose.tsx +++ b/src/pages/home/report/ReportActionCompose/ReportActionCompose.tsx @@ -150,7 +150,7 @@ function ReportActionCompose({ const [blockedFromConcierge] = useOnyx(ONYXKEYS.NVP_BLOCKED_FROM_CONCIERGE, {canBeMissing: true}); const [shouldShowComposeInput = true] = useOnyx(ONYXKEYS.SHOULD_SHOW_COMPOSE_INPUT, {canBeMissing: true}); const [policy] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY}${report?.policyID}`, {canBeMissing: true}); - + const [newParentReport] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${report?.parentReportID}`, {canBeMissing: true}); /** * Updates the Highlight state of the composer */ @@ -496,6 +496,8 @@ function ReportActionCompose({ const initialTransaction = initMoneyRequest({ reportID, newIouRequestType: CONST.IOU.REQUEST_TYPE.SCAN, + report, + parentReport: newParentReport, }); files.forEach((file, index) => { diff --git a/src/pages/iou/request/IOURequestStartPage.tsx b/src/pages/iou/request/IOURequestStartPage.tsx index dbbd9cd5f86..446d8158325 100644 --- a/src/pages/iou/request/IOURequestStartPage.tsx +++ b/src/pages/iou/request/IOURequestStartPage.tsx @@ -56,6 +56,7 @@ function IOURequestStartPage({ const shouldUseTab = iouType !== CONST.IOU.TYPE.SEND && iouType !== CONST.IOU.TYPE.PAY && iouType !== CONST.IOU.TYPE.INVOICE; const [isDraggingOver, setIsDraggingOver] = useState(false); const [report] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${reportID}`, {canBeMissing: true}); + const [parentReport] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${report?.parentReportID}`, {canBeMissing: true}); const policy = usePolicy(report?.policyID); const [selectedTab, selectedTabResult] = useOnyx(`${ONYXKEYS.COLLECTION.SELECTED_TAB}${CONST.TAB.IOU_REQUEST_TYPE}`, {canBeMissing: true}); const [session] = useOnyx(ONYXKEYS.SESSION, {canBeMissing: false}); @@ -126,9 +127,11 @@ function IOURequestStartPage({ isFromGlobalCreate, currentIouRequestType: transaction?.iouRequestType, newIouRequestType: newIOUType, + report, + parentReport, }); }, - [policy, reportID, isFromGlobalCreate, transaction], + [policy, reportID, isFromGlobalCreate, transaction, report, parentReport], ); // Clear out the temporary expense if the reportID in the URL has changed from the transaction's reportID. diff --git a/tests/actions/IOUTest.ts b/tests/actions/IOUTest.ts index d1fdfdc7d28..8cf87fd8468 100644 --- a/tests/actions/IOUTest.ts +++ b/tests/actions/IOUTest.ts @@ -5668,6 +5668,14 @@ describe('actions/IOU', () => { type: CONST.POLICY.TYPE.TEAM, outputCurrency: 'USD', }; + + const fakeParentReport: Report = { + ...createRandomReport(1), + reportID: fakeReport.reportID, + type: CONST.REPORT.TYPE.EXPENSE, + policyID: '1', + managerID: CARLOS_ACCOUNT_ID, + }; const fakePersonalPolicy: Policy = { ...createRandomPolicy(2), type: CONST.POLICY.TYPE.PERSONAL, @@ -5715,6 +5723,8 @@ describe('actions/IOU', () => { policy: fakePolicy, isFromGlobalCreate: true, newIouRequestType: CONST.IOU.REQUEST_TYPE.MANUAL, + report: fakeReport, + parentReport: fakeParentReport, }); }) .then(async () => { @@ -5731,6 +5741,8 @@ describe('actions/IOU', () => { isFromGlobalCreate: true, currentIouRequestType: CONST.IOU.REQUEST_TYPE.MANUAL, newIouRequestType: CONST.IOU.REQUEST_TYPE.SCAN, + report: fakeReport, + parentReport: fakeParentReport, }); }) .then(async () => { @@ -5747,6 +5759,8 @@ describe('actions/IOU', () => { reportID: fakeReport.reportID, isFromGlobalCreate: true, newIouRequestType: CONST.IOU.REQUEST_TYPE.MANUAL, + report: fakeReport, + parentReport: fakeParentReport, }); }) .then(async () => { diff --git a/tests/unit/PerDiemRequestUtilsTest.ts b/tests/unit/PerDiemRequestUtilsTest.ts index a6d720f6512..e6d6b3f9413 100644 --- a/tests/unit/PerDiemRequestUtilsTest.ts +++ b/tests/unit/PerDiemRequestUtilsTest.ts @@ -1,8 +1,36 @@ +import Onyx from 'react-native-onyx'; import type {DestinationTreeSection} from '@libs/PerDiemRequestUtils'; import {getDestinationListSections} from '@libs/PerDiemRequestUtils'; +import CONST from '@src/CONST'; +import {getCustomUnitID} from '@src/libs/PerDiemRequestUtils'; +import ONYXKEYS from '@src/ONYXKEYS'; +import type {Policy, Report} from '@src/types/onyx'; import type {Rate} from '@src/types/onyx/Policy'; +import {getFakePolicy, getFakeReport} from '../utils/LHNTestUtils'; + +const policyID = '1'; +const report: Report = { + ...getFakeReport(), + policyID, + chatType: CONST.REPORT.CHAT_TYPE.POLICY_EXPENSE_CHAT, +}; + +const parentReport: Report = { + ...getFakeReport(), + policyID, +}; describe('PerDiemRequestUtils', () => { + beforeAll(() => + Onyx.init({ + keys: ONYXKEYS, + }), + ); + + beforeEach(() => { + Onyx.clear(); + }); + it('getDestinationListSections()', () => { const tokenizeSearch = 'Antigua Barbuda'; @@ -48,4 +76,37 @@ describe('PerDiemRequestUtils', () => { }); expect(tokenizeSearchResult).toStrictEqual(searchResultList); }); + + describe('getCustomUnitID', () => { + it('should return the correct custom unit ID', async () => { + const policy: Policy = { + ...getFakePolicy(), + id: policyID, + customUnits: { + [CONST.CUSTOM_UNITS.DISTANCE_UNIT_KILOMETERS]: { + name: CONST.CUSTOM_UNITS.NAME_PER_DIEM_INTERNATIONAL, + customUnitID: CONST.CUSTOM_UNITS.DISTANCE_UNIT_KILOMETERS, + rates: {}, + }, + }, + }; + + await Onyx.set(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`, policy); + + const customUnitID = getCustomUnitID(report, parentReport); + expect(customUnitID.customUnitID).toBe(CONST.CUSTOM_UNITS.DISTANCE_UNIT_KILOMETERS); + }); + + it('should return fake P2P ID if the policy does not have a custom unit', async () => { + const policy: Policy = { + ...getFakePolicy(), + customUnits: {}, + }; + + await Onyx.set(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`, policy); + + const customUnitID = getCustomUnitID(report, parentReport); + expect(customUnitID.customUnitID).toBe(CONST.CUSTOM_UNITS.FAKE_P2P_ID); + }); + }); });