From 3cc27f48201b0902cb3a74d57f436007df492587 Mon Sep 17 00:00:00 2001 From: nkdengineer Date: Sat, 19 Apr 2025 23:28:59 +0700 Subject: [PATCH 1/5] ensure Test Receipt is always sent to Manager McTest from FE --- src/libs/OptionsListUtils.ts | 5 +++- src/libs/actions/IOU.ts | 4 +-- .../step/IOURequestStepScan/index.native.tsx | 26 +++++++++++------ .../request/step/IOURequestStepScan/index.tsx | 28 +++++++++++++------ 4 files changed, 43 insertions(+), 20 deletions(-) diff --git a/src/libs/OptionsListUtils.ts b/src/libs/OptionsListUtils.ts index c1c03fe0e222..f0cbaef9d7a6 100644 --- a/src/libs/OptionsListUtils.ts +++ b/src/libs/OptionsListUtils.ts @@ -77,6 +77,7 @@ import { canUserPerformWriteAction, formatReportLastMessageText, getAllReportErrors, + getChatByParticipants, getChatRoomSubtitle, getDeletedParentActionMessageForChatReport, getDisplayNameForParticipant, @@ -2294,7 +2295,9 @@ function shouldUseBoldText(report: OptionData): boolean { function getManagerMcTestParticipant(): Participant | undefined { const managerMcTestPersonalDetails = Object.values(allPersonalDetails ?? {}).find((personalDetails) => personalDetails?.login === CONST.EMAIL.MANAGER_MCTEST); - return managerMcTestPersonalDetails ? getParticipantsOption(managerMcTestPersonalDetails, allPersonalDetails) : undefined; + const managerMcTestReport = + managerMcTestPersonalDetails?.accountID && currentUserAccountID ? getChatByParticipants([managerMcTestPersonalDetails?.accountID, currentUserAccountID]) : undefined; + return managerMcTestPersonalDetails ? {...getParticipantsOption(managerMcTestPersonalDetails, allPersonalDetails), reportID: managerMcTestReport?.reportID} : undefined; } export { diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index be0aa0282160..230ba18d0222 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -937,8 +937,8 @@ function setMoneyRequestBillable(transactionID: string, billable: boolean) { Onyx.merge(`${ONYXKEYS.COLLECTION.TRANSACTION_DRAFT}${transactionID}`, {billable}); } -function setMoneyRequestParticipants(transactionID: string, participants: Participant[] = []) { - Onyx.merge(`${ONYXKEYS.COLLECTION.TRANSACTION_DRAFT}${transactionID}`, {participants}); +function setMoneyRequestParticipants(transactionID: string, participants: Participant[] = [], shouldUpdateReportID = false) { + Onyx.merge(`${ONYXKEYS.COLLECTION.TRANSACTION_DRAFT}${transactionID}`, {participants, reportID: shouldUpdateReportID ? participants.at(0)?.reportID : undefined}); } function setSplitPayer(transactionID: string, payerAccountID: number) { diff --git a/src/pages/iou/request/step/IOURequestStepScan/index.native.tsx b/src/pages/iou/request/step/IOURequestStepScan/index.native.tsx index 15253a6c5fb7..4602c864ebff 100644 --- a/src/pages/iou/request/step/IOURequestStepScan/index.native.tsx +++ b/src/pages/iou/request/step/IOURequestStepScan/index.native.tsx @@ -255,7 +255,7 @@ function IOURequestStepScan({ }, [iouType, reportID, transactionID]); const navigateToConfirmationPage = useCallback( - (isTestTransaction = false) => { + (isTestTransaction = false, reportIDParam: string | undefined = undefined) => { switch (iouType) { case CONST.IOU.TYPE.REQUEST: Navigation.navigate(ROUTES.MONEY_REQUEST_STEP_CONFIRMATION.getRoute(CONST.IOU.ACTION.CREATE, CONST.IOU.TYPE.SUBMIT, transactionID, reportID)); @@ -265,7 +265,12 @@ function IOURequestStepScan({ break; default: Navigation.navigate( - ROUTES.MONEY_REQUEST_STEP_CONFIRMATION.getRoute(CONST.IOU.ACTION.CREATE, isTestTransaction ? CONST.IOU.TYPE.SUBMIT : iouType, transactionID, reportID), + ROUTES.MONEY_REQUEST_STEP_CONFIRMATION.getRoute( + CONST.IOU.ACTION.CREATE, + isTestTransaction ? CONST.IOU.TYPE.SUBMIT : iouType, + transactionID, + reportIDParam ?? reportID, + ), ); } }, @@ -319,6 +324,17 @@ function IOURequestStepScan({ return; } + if (isTestTransaction) { + const managerMcTestParticipant = getManagerMcTestParticipant() ?? {}; + let reportIDParam = managerMcTestParticipant.reportID; + if (!managerMcTestParticipant.reportID && report?.reportID) { + reportIDParam = generateReportID(); + } + setMoneyRequestParticipants(transactionID, [{...managerMcTestParticipant, reportID: reportIDParam, selected: true}], true); + navigateToConfirmationPage(true, reportIDParam); + return; + } + // If a reportID exists in the report object, it's because either: // - The user started this flow from using the + button in the composer inside a report. // - The user started this flow from using the global create menu by selecting the Track expense option. @@ -451,12 +467,6 @@ function IOURequestStepScan({ ); }); } else { - if (isTestTransaction) { - const managerMcTestParticipant = getManagerMcTestParticipant() ?? {}; - setMoneyRequestParticipants(transactionID, [{...managerMcTestParticipant, selected: true}]); - navigateToConfirmationPage(true); - return; - } navigateToParticipantPage(); } }, diff --git a/src/pages/iou/request/step/IOURequestStepScan/index.tsx b/src/pages/iou/request/step/IOURequestStepScan/index.tsx index 14a098b8b2ba..1d7aa5a60110 100644 --- a/src/pages/iou/request/step/IOURequestStepScan/index.tsx +++ b/src/pages/iou/request/step/IOURequestStepScan/index.tsx @@ -43,7 +43,7 @@ import Navigation from '@libs/Navigation/Navigation'; import {getIsUserSubmittedExpenseOrScannedReceipt, getManagerMcTestParticipant, getParticipantsOption, getReportOption} from '@libs/OptionsListUtils'; import Permissions from '@libs/Permissions'; import {isPaidGroupPolicy} from '@libs/PolicyUtils'; -import {getPolicyExpenseChat, isArchivedReport, isPolicyExpenseChat} from '@libs/ReportUtils'; +import {generateReportID, getPolicyExpenseChat, isArchivedReport, isPolicyExpenseChat} from '@libs/ReportUtils'; import playSound, {SOUNDS} from '@libs/Sound'; import {shouldRestrictUserBillableActions} from '@libs/SubscriptionUtils'; import {getDefaultTaxCode} from '@libs/TransactionUtils'; @@ -279,7 +279,7 @@ function IOURequestStepScan({ }, [iouType, reportID, transactionID]); const navigateToConfirmationPage = useCallback( - (isTestTransaction = false) => { + (isTestTransaction = false, reportIDParam: string | undefined = undefined) => { switch (iouType) { case CONST.IOU.TYPE.REQUEST: Navigation.navigate(ROUTES.MONEY_REQUEST_STEP_CONFIRMATION.getRoute(CONST.IOU.ACTION.CREATE, CONST.IOU.TYPE.SUBMIT, transactionID, reportID)); @@ -289,7 +289,12 @@ function IOURequestStepScan({ break; default: Navigation.navigate( - ROUTES.MONEY_REQUEST_STEP_CONFIRMATION.getRoute(CONST.IOU.ACTION.CREATE, isTestTransaction ? CONST.IOU.TYPE.SUBMIT : iouType, transactionID, reportID), + ROUTES.MONEY_REQUEST_STEP_CONFIRMATION.getRoute( + CONST.IOU.ACTION.CREATE, + isTestTransaction ? CONST.IOU.TYPE.SUBMIT : iouType, + transactionID, + reportIDParam ?? reportID, + ), ); } }, @@ -343,6 +348,17 @@ function IOURequestStepScan({ return; } + if (isTestTransaction) { + const managerMcTestParticipant = getManagerMcTestParticipant() ?? {}; + let reportIDParam = managerMcTestParticipant.reportID; + if (!managerMcTestParticipant.reportID && report?.reportID) { + reportIDParam = generateReportID(); + } + setMoneyRequestParticipants(transactionID, [{...managerMcTestParticipant, reportID: reportIDParam, selected: true}], true); + navigateToConfirmationPage(true, reportIDParam); + return; + } + // If a reportID exists in the report object, it's because either: // - The user started this flow from using the + button in the composer inside a report. // - The user started this flow from using the global create menu by selecting the Track expense option. @@ -475,12 +491,6 @@ function IOURequestStepScan({ ); }); } else { - if (isTestTransaction) { - const managerMcTestParticipant = getManagerMcTestParticipant() ?? {}; - setMoneyRequestParticipants(transactionID, [{...managerMcTestParticipant, selected: true}]); - navigateToConfirmationPage(true); - return; - } navigateToParticipantPage(); } }, From b0b507c8527b844a90c487f4d30cf832eeb4a86b Mon Sep 17 00:00:00 2001 From: nkdengineer Date: Sat, 19 Apr 2025 23:52:48 +0700 Subject: [PATCH 2/5] fix lint --- .../step/IOURequestStepScan/index.native.tsx | 16 ++++++++-------- .../request/step/IOURequestStepScan/index.tsx | 12 ++++++------ 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/pages/iou/request/step/IOURequestStepScan/index.native.tsx b/src/pages/iou/request/step/IOURequestStepScan/index.native.tsx index 4602c864ebff..ad7f90d2fd85 100644 --- a/src/pages/iou/request/step/IOURequestStepScan/index.native.tsx +++ b/src/pages/iou/request/step/IOURequestStepScan/index.native.tsx @@ -43,7 +43,7 @@ import Navigation from '@libs/Navigation/Navigation'; import {getIsUserSubmittedExpenseOrScannedReceipt, getManagerMcTestParticipant, getParticipantsOption, getReportOption} from '@libs/OptionsListUtils'; import Permissions from '@libs/Permissions'; import {isPaidGroupPolicy} from '@libs/PolicyUtils'; -import {getPolicyExpenseChat, isArchivedReport, isPolicyExpenseChat} from '@libs/ReportUtils'; +import {generateReportID, getPolicyExpenseChat, isArchivedReport, isPolicyExpenseChat} from '@libs/ReportUtils'; import playSound, {SOUNDS} from '@libs/Sound'; import {shouldRestrictUserBillableActions} from '@libs/SubscriptionUtils'; import {getDefaultTaxCode} from '@libs/TransactionUtils'; @@ -94,15 +94,15 @@ function IOURequestStepScan({ const [startLocationPermissionFlow, setStartLocationPermissionFlow] = useState(false); const [fileResize, setFileResize] = useState(null); const [fileSource, setFileSource] = useState(''); - const [reportNameValuePairs] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_NAME_VALUE_PAIRS}${report?.reportID}`); + const [reportNameValuePairs] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_NAME_VALUE_PAIRS}${report?.reportID}`, {canBeMissing: true}); const policy = usePolicy(report?.policyID); - const [personalDetails] = useOnyx(ONYXKEYS.PERSONAL_DETAILS_LIST); - const [skipConfirmation] = useOnyx(`${ONYXKEYS.COLLECTION.SKIP_CONFIRMATION}${transactionID}`); - const [activePolicyID] = useOnyx(ONYXKEYS.NVP_ACTIVE_POLICY_ID); - const [activePolicy] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY}${activePolicyID}`); - const [betas] = useOnyx(ONYXKEYS.BETAS); + const [personalDetails] = useOnyx(ONYXKEYS.PERSONAL_DETAILS_LIST, {canBeMissing: false}); + const [skipConfirmation] = useOnyx(`${ONYXKEYS.COLLECTION.SKIP_CONFIRMATION}${transactionID}`, {canBeMissing: true}); + const [activePolicyID] = useOnyx(ONYXKEYS.NVP_ACTIVE_POLICY_ID, {canBeMissing: false}); + const [activePolicy] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY}${activePolicyID}`, {canBeMissing: true}); + const [betas] = useOnyx(ONYXKEYS.BETAS, {canBeMissing: false}); const platform = getPlatform(true); - const [mutedPlatforms = {}] = useOnyx(ONYXKEYS.NVP_MUTED_PLATFORMS); + const [mutedPlatforms = {}] = useOnyx(ONYXKEYS.NVP_MUTED_PLATFORMS, {canBeMissing: false}); const isPlatformMuted = mutedPlatforms[platform]; const [cameraPermissionStatus, setCameraPermissionStatus] = useState(null); const [didCapturePhoto, setDidCapturePhoto] = useState(false); diff --git a/src/pages/iou/request/step/IOURequestStepScan/index.tsx b/src/pages/iou/request/step/IOURequestStepScan/index.tsx index 1d7aa5a60110..196c285902e5 100644 --- a/src/pages/iou/request/step/IOURequestStepScan/index.tsx +++ b/src/pages/iou/request/step/IOURequestStepScan/index.tsx @@ -111,13 +111,13 @@ function IOURequestStepScan({ const [elementTop, setElementTop] = useState(0); const getScreenshotTimeoutRef = useRef(null); - const [reportNameValuePairs] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_NAME_VALUE_PAIRS}${report?.reportID}`); + const [reportNameValuePairs] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_NAME_VALUE_PAIRS}${report?.reportID}`, {canBeMissing: true}); const policy = usePolicy(report?.policyID); - const [personalDetails] = useOnyx(ONYXKEYS.PERSONAL_DETAILS_LIST); - const [skipConfirmation] = useOnyx(`${ONYXKEYS.COLLECTION.SKIP_CONFIRMATION}${transactionID}`); - const [activePolicyID] = useOnyx(ONYXKEYS.NVP_ACTIVE_POLICY_ID); - const [activePolicy] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY}${activePolicyID}`); - const [betas] = useOnyx(ONYXKEYS.BETAS); + const [personalDetails] = useOnyx(ONYXKEYS.PERSONAL_DETAILS_LIST, {canBeMissing: false}); + const [skipConfirmation] = useOnyx(`${ONYXKEYS.COLLECTION.SKIP_CONFIRMATION}${transactionID}`, {canBeMissing: true}); + const [activePolicyID] = useOnyx(ONYXKEYS.NVP_ACTIVE_POLICY_ID, {canBeMissing: false}); + const [activePolicy] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY}${activePolicyID}`, {canBeMissing: true}); + const [betas] = useOnyx(ONYXKEYS.BETAS, {canBeMissing: false}); const [isLoadingReceipt, setIsLoadingReceipt] = useState(false); const [videoConstraints, setVideoConstraints] = useState(); From 489adf6b136edae76222fb1686f9673487bc5290 Mon Sep 17 00:00:00 2001 From: nkdengineer Date: Sun, 20 Apr 2025 00:07:01 +0700 Subject: [PATCH 3/5] fix change file lint error --- src/libs/OptionsListUtils.ts | 11 ++++++++++- src/libs/actions/IOU.ts | 13 +++++++++++-- .../step/IOURequestStepScan/index.native.tsx | 2 +- 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/src/libs/OptionsListUtils.ts b/src/libs/OptionsListUtils.ts index f0cbaef9d7a6..3055d27691bf 100644 --- a/src/libs/OptionsListUtils.ts +++ b/src/libs/OptionsListUtils.ts @@ -356,6 +356,15 @@ Onyx.connect({ }, }); +let allReportNameValuePairs: OnyxCollection; +Onyx.connect({ + key: ONYXKEYS.COLLECTION.REPORT_NAME_VALUE_PAIRS, + waitForCollectionCallback: true, + callback: (value) => { + allReportNameValuePairs = value; + }, +}); + const lastReportActions: ReportActions = {}; const allSortedReportActions: Record = {}; let allReportActions: OnyxCollection; @@ -854,7 +863,7 @@ function createOption( result.participantsList = personalDetailList; result.isOptimisticPersonalDetail = personalDetail?.isOptimisticPersonalDetail; if (report) { - const reportNameValuePairs = getReportNameValuePairs(report.reportID); + const reportNameValuePairs = allReportNameValuePairs?.[`${ONYXKEYS.COLLECTION.REPORT_NAME_VALUE_PAIRS}${report.reportID}`]; result.isChatRoom = reportUtilsIsChatRoom(report); result.isDefaultRoom = isDefaultRoom(report); result.private_isArchived = reportNameValuePairs?.private_isArchived; diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index 230ba18d0222..14e9bbeffb1b 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -667,6 +667,15 @@ Onyx.connect({ }, }); +let allReportNameValuePairs: OnyxCollection; +Onyx.connect({ + key: ONYXKEYS.COLLECTION.REPORT_NAME_VALUE_PAIRS, + waitForCollectionCallback: true, + callback: (value) => { + allReportNameValuePairs = value; + }, +}); + let userAccountID = -1; let currentUserEmail = ''; Onyx.connect({ @@ -8674,7 +8683,7 @@ function canApproveIOU(iouReport: OnyxTypes.OnyxInputOrEntry | const isOpenExpenseReport = isOpenExpenseReportReportUtils(iouReport); const isApproved = isReportApproved({report: iouReport}); const iouSettled = isSettled(iouReport); - const reportNameValuePairs = getReportNameValuePairs(iouReport?.reportID); + const reportNameValuePairs = allReportNameValuePairs?.[`${ONYXKEYS.COLLECTION.REPORT_NAME_VALUE_PAIRS}${iouReport?.reportID}`]; const isArchivedExpenseReport = isArchivedReport(reportNameValuePairs); const reportTransactions = getReportTransactions(iouReport?.reportID); const hasOnlyPendingCardOrScanningTransactions = reportTransactions.length > 0 && reportTransactions.every(isPendingCardOrScanningTransaction); @@ -8709,7 +8718,7 @@ function canIOUBePaid( shouldCheckApprovedState = true, ) { const isPolicyExpenseChat = isPolicyExpenseChatReportUtil(chatReport); - const reportNameValuePairs = chatReportRNVP ?? getReportNameValuePairs(chatReport?.reportID); + const reportNameValuePairs = chatReportRNVP ?? allReportNameValuePairs?.[`${ONYXKEYS.COLLECTION.REPORT_NAME_VALUE_PAIRS}${chatReport?.reportID}`]; const isChatReportArchived = isArchivedReport(reportNameValuePairs); const iouSettled = isSettled(iouReport); diff --git a/src/pages/iou/request/step/IOURequestStepScan/index.native.tsx b/src/pages/iou/request/step/IOURequestStepScan/index.native.tsx index ad7f90d2fd85..4892e04e7f54 100644 --- a/src/pages/iou/request/step/IOURequestStepScan/index.native.tsx +++ b/src/pages/iou/request/step/IOURequestStepScan/index.native.tsx @@ -102,7 +102,7 @@ function IOURequestStepScan({ const [activePolicy] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY}${activePolicyID}`, {canBeMissing: true}); const [betas] = useOnyx(ONYXKEYS.BETAS, {canBeMissing: false}); const platform = getPlatform(true); - const [mutedPlatforms = {}] = useOnyx(ONYXKEYS.NVP_MUTED_PLATFORMS, {canBeMissing: false}); + const [mutedPlatforms = {}] = useOnyx(ONYXKEYS.NVP_MUTED_PLATFORMS, {canBeMissing: true}); const isPlatformMuted = mutedPlatforms[platform]; const [cameraPermissionStatus, setCameraPermissionStatus] = useState(null); const [didCapturePhoto, setDidCapturePhoto] = useState(false); From 893cfdb88685efd9ef963bd46ece804f584796f2 Mon Sep 17 00:00:00 2001 From: nkdengineer Date: Sun, 20 Apr 2025 00:09:14 +0700 Subject: [PATCH 4/5] remove unused function --- src/libs/OptionsListUtils.ts | 1 - src/libs/actions/IOU.ts | 1 - 2 files changed, 2 deletions(-) diff --git a/src/libs/OptionsListUtils.ts b/src/libs/OptionsListUtils.ts index 3055d27691bf..f9c7f3dc128e 100644 --- a/src/libs/OptionsListUtils.ts +++ b/src/libs/OptionsListUtils.ts @@ -98,7 +98,6 @@ import { getReportAutomaticallySubmittedMessage, getReportLastMessage, getReportName, - getReportNameValuePairs, getReportNotificationPreference, getReportOrDraftReport, getReportParticipantsTitle, diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index 14e9bbeffb1b..8556da33b182 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -123,7 +123,6 @@ import { getOutstandingChildRequest, getParsedComment, getPersonalDetailsForAccountID, - getReportNameValuePairs, getReportNotificationPreference, getReportOrDraftReport, getReportTransactions, From ba7b52aec6c7369b160e3ee90ca0b7052551cb43 Mon Sep 17 00:00:00 2001 From: nkdengineer Date: Tue, 22 Apr 2025 19:33:44 +0700 Subject: [PATCH 5/5] prevent empty reportID --- src/pages/iou/request/step/IOURequestStepScan/index.native.tsx | 3 ++- src/pages/iou/request/step/IOURequestStepScan/index.tsx | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/pages/iou/request/step/IOURequestStepScan/index.native.tsx b/src/pages/iou/request/step/IOURequestStepScan/index.native.tsx index 4892e04e7f54..fca429a74da6 100644 --- a/src/pages/iou/request/step/IOURequestStepScan/index.native.tsx +++ b/src/pages/iou/request/step/IOURequestStepScan/index.native.tsx @@ -269,7 +269,8 @@ function IOURequestStepScan({ CONST.IOU.ACTION.CREATE, isTestTransaction ? CONST.IOU.TYPE.SUBMIT : iouType, transactionID, - reportIDParam ?? reportID, + // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing + reportIDParam || reportID, ), ); } diff --git a/src/pages/iou/request/step/IOURequestStepScan/index.tsx b/src/pages/iou/request/step/IOURequestStepScan/index.tsx index 196c285902e5..545cc8b0d5a8 100644 --- a/src/pages/iou/request/step/IOURequestStepScan/index.tsx +++ b/src/pages/iou/request/step/IOURequestStepScan/index.tsx @@ -293,7 +293,8 @@ function IOURequestStepScan({ CONST.IOU.ACTION.CREATE, isTestTransaction ? CONST.IOU.TYPE.SUBMIT : iouType, transactionID, - reportIDParam ?? reportID, + // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing + reportIDParam || reportID, ), ); }