From 1903185e14bef3b11db8ecf22edc4ba7af63b415 Mon Sep 17 00:00:00 2001 From: Srikar Parsi Date: Thu, 23 Jan 2025 21:13:31 -0500 Subject: [PATCH 1/7] fix some imports --- .../LHNOptionsList/LHNOptionsList.tsx | 26 +++++++++---------- .../LHNOptionsList/OptionRowLHNData.tsx | 8 +++--- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/components/LHNOptionsList/LHNOptionsList.tsx b/src/components/LHNOptionsList/LHNOptionsList.tsx index 6c5c856443c4..c341c05a8e49 100644 --- a/src/components/LHNOptionsList/LHNOptionsList.tsx +++ b/src/components/LHNOptionsList/LHNOptionsList.tsx @@ -16,10 +16,10 @@ import usePrevious from '@hooks/usePrevious'; import useResponsiveLayout from '@hooks/useResponsiveLayout'; import useTheme from '@hooks/useTheme'; import useThemeStyles from '@hooks/useThemeStyles'; -import * as DraftCommentUtils from '@libs/DraftCommentUtils'; -import * as OptionsListUtils from '@libs/OptionsListUtils'; -import * as ReportActionsUtils from '@libs/ReportActionsUtils'; -import * as ReportUtils from '@libs/ReportUtils'; +import {isValidDraftComment} from '@libs/DraftCommentUtils'; +import {getIOUReportIDOfLastAction, getLastMessageTextForReport} from '@libs/OptionsListUtils'; +import {getOriginalMessage, getSortedReportActionsForDisplay, isMoneyRequestAction} from '@libs/ReportActionsUtils'; +import {canUserPerformWriteAction} from '@libs/ReportUtils'; import variables from '@styles/variables'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; @@ -133,25 +133,25 @@ function LHNOptionsList({style, contentContainerStyles, data, onSelectRow, optio } const itemInvoiceReceiverPolicy = policy?.[`${ONYXKEYS.COLLECTION.POLICY}${invoiceReceiverPolicyID}`]; - const iouReportIDOfLastAction = OptionsListUtils.getIOUReportIDOfLastAction(itemFullReport); + const iouReportIDOfLastAction = getIOUReportIDOfLastAction(itemFullReport); const itemIouReportReportActions = iouReportIDOfLastAction ? reportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${iouReportIDOfLastAction}`] : undefined; const itemPolicy = policy?.[`${ONYXKEYS.COLLECTION.POLICY}${itemFullReport?.policyID}`]; - const transactionID = ReportActionsUtils.isMoneyRequestAction(itemParentReportAction) - ? ReportActionsUtils.getOriginalMessage(itemParentReportAction)?.IOUTransactionID ?? '-1' + const transactionID = isMoneyRequestAction(itemParentReportAction) + ? getOriginalMessage(itemParentReportAction)?.IOUTransactionID ?? '-1' : '-1'; const itemTransaction = transactions?.[`${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`]; - const hasDraftComment = DraftCommentUtils.isValidDraftComment(draftComments?.[`${ONYXKEYS.COLLECTION.REPORT_DRAFT_COMMENT}${reportID}`]); + const hasDraftComment = isValidDraftComment(draftComments?.[`${ONYXKEYS.COLLECTION.REPORT_DRAFT_COMMENT}${reportID}`]); - const canUserPerformWriteAction = ReportUtils.canUserPerformWriteAction(itemFullReport); - const sortedReportActions = ReportActionsUtils.getSortedReportActionsForDisplay(itemReportActions, canUserPerformWriteAction); + const canUserPerformWrite = canUserPerformWriteAction(itemFullReport); + const sortedReportActions = getSortedReportActionsForDisplay(itemReportActions, canUserPerformWrite); const lastReportAction = sortedReportActions.at(0); // Get the transaction for the last report action let lastReportActionTransactionID = ''; - if (ReportActionsUtils.isMoneyRequestAction(lastReportAction)) { - lastReportActionTransactionID = ReportActionsUtils.getOriginalMessage(lastReportAction)?.IOUTransactionID ?? '-1'; + if (isMoneyRequestAction(lastReportAction)) { + lastReportActionTransactionID = getOriginalMessage(lastReportAction)?.IOUTransactionID ?? '-1'; } const lastReportActionTransaction = transactions?.[`${ONYXKEYS.COLLECTION.TRANSACTION}${lastReportActionTransactionID}`]; @@ -167,7 +167,7 @@ function LHNOptionsList({style, contentContainerStyles, data, onSelectRow, optio } : null; } - const lastMessageTextFromReport = OptionsListUtils.getLastMessageTextForReport(itemFullReport, lastActorDetails, itemPolicy); + const lastMessageTextFromReport = getLastMessageTextForReport(itemFullReport, lastActorDetails, itemPolicy); return ( (); - const shouldDisplayViolations = ReportUtils.shouldDisplayViolationsRBRInLHN(fullReport, transactionViolations); - const isSettled = ReportUtils.isSettled(fullReport); - const shouldDisplayReportViolations = !isSettled && ReportUtils.isReportOwner(fullReport) && ReportUtils.hasReportViolations(reportID); + const shouldDisplayViolations = shouldDisplayViolationsRBRInLHN(fullReport, transactionViolations); + const isReportSettled = isSettled(fullReport); + const shouldDisplayReportViolations = !isReportSettled && isReportOwner(fullReport) && hasReportViolations(reportID); const optionItem = useMemo(() => { // Note: ideally we'd have this as a dependent selector in onyx! From 53ddc2e5d431ffcbad7d1ab3c9b0d005fce73b4f Mon Sep 17 00:00:00 2001 From: Srikar Parsi Date: Thu, 23 Jan 2025 21:34:37 -0500 Subject: [PATCH 2/7] more lint files and errors --- .../LHNOptionsList/LHNOptionsList.tsx | 4 +- .../step/IOURequestStepScan/index.native.tsx | 62 ++++++------ .../request/step/IOURequestStepScan/index.tsx | 70 ++++++++------ tests/ui/LHNItemsPresence.tsx | 18 ++-- tests/unit/SidebarOrderTest.ts | 96 +++++++++---------- 5 files changed, 132 insertions(+), 118 deletions(-) diff --git a/src/components/LHNOptionsList/LHNOptionsList.tsx b/src/components/LHNOptionsList/LHNOptionsList.tsx index c341c05a8e49..5ec011d68382 100644 --- a/src/components/LHNOptionsList/LHNOptionsList.tsx +++ b/src/components/LHNOptionsList/LHNOptionsList.tsx @@ -137,9 +137,7 @@ function LHNOptionsList({style, contentContainerStyles, data, onSelectRow, optio const itemIouReportReportActions = iouReportIDOfLastAction ? reportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${iouReportIDOfLastAction}`] : undefined; const itemPolicy = policy?.[`${ONYXKEYS.COLLECTION.POLICY}${itemFullReport?.policyID}`]; - const transactionID = isMoneyRequestAction(itemParentReportAction) - ? getOriginalMessage(itemParentReportAction)?.IOUTransactionID ?? '-1' - : '-1'; + const transactionID = isMoneyRequestAction(itemParentReportAction) ? getOriginalMessage(itemParentReportAction)?.IOUTransactionID ?? '-1' : '-1'; const itemTransaction = transactions?.[`${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`]; const hasDraftComment = isValidDraftComment(draftComments?.[`${ONYXKEYS.COLLECTION.REPORT_DRAFT_COMMENT}${reportID}`]); diff --git a/src/pages/iou/request/step/IOURequestStepScan/index.native.tsx b/src/pages/iou/request/step/IOURequestStepScan/index.native.tsx index 1c3f337c268d..ec32b709ad8f 100644 --- a/src/pages/iou/request/step/IOURequestStepScan/index.native.tsx +++ b/src/pages/iou/request/step/IOURequestStepScan/index.native.tsx @@ -28,22 +28,30 @@ import useLocalize from '@hooks/useLocalize'; import usePolicy from '@hooks/usePolicy'; import useTheme from '@hooks/useTheme'; import useThemeStyles from '@hooks/useThemeStyles'; -import * as FileUtils from '@libs/fileDownload/FileUtils'; +import {readFileAsync, resizeImageIfNeeded, showCameraPermissionsAlert, splitExtensionFromFileName} from '@libs/fileDownload/FileUtils'; import getPhotoSource from '@libs/fileDownload/getPhotoSource'; import getCurrentPosition from '@libs/getCurrentPosition'; import getPlatform from '@libs/getPlatform'; import getReceiptsUploadFolderPath from '@libs/getReceiptsUploadFolderPath'; -import * as IOUUtils from '@libs/IOUUtils'; +import {shouldStartLocationPermissionFlow} from '@libs/IOUUtils'; import Log from '@libs/Log'; import Navigation from '@libs/Navigation/Navigation'; -import * as OptionsListUtils from '@libs/OptionsListUtils'; -import * as ReportUtils from '@libs/ReportUtils'; +import {getParticipantsOption, getReportOption} from '@libs/OptionsListUtils'; +import {isArchivedReport, isPolicyExpenseChat} from '@libs/ReportUtils'; import playSound, {SOUNDS} from '@libs/Sound'; -import * as TransactionUtils from '@libs/TransactionUtils'; +import {getDefaultTaxCode} from '@libs/TransactionUtils'; import StepScreenWrapper from '@pages/iou/request/step/StepScreenWrapper'; import withFullTransactionOrNotFound from '@pages/iou/request/step/withFullTransactionOrNotFound'; import withWritableReportOrNotFound from '@pages/iou/request/step/withWritableReportOrNotFound'; -import * as IOU from '@userActions/IOU'; +import { + replaceReceipt, + requestMoney, + setMoneyRequestParticipantsFromReport, + setMoneyRequestReceipt, + startSplitBill, + trackExpense, + updateLastLocationPermissionPrompt, +} from '@userActions/IOU'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; @@ -87,7 +95,7 @@ function IOURequestStepScan({ const [pdfFile, setPdfFile] = useState(null); - const defaultTaxCode = TransactionUtils.getDefaultTaxCode(policy, transaction); + const defaultTaxCode = getDefaultTaxCode(policy, transaction); const transactionTaxCode = (transaction?.taxCode ? transaction?.taxCode : defaultTaxCode) ?? ''; const transactionTaxAmount = transaction?.taxAmount ?? 0; @@ -98,7 +106,7 @@ function IOURequestStepScan({ return false; } - return !ReportUtils.isArchivedReport(reportNameValuePairs) && !(ReportUtils.isPolicyExpenseChat(report) && ((policy?.requiresCategory ?? false) || (policy?.requiresTag ?? false))); + return !isArchivedReport(reportNameValuePairs) && !(isPolicyExpenseChat(report) && ((policy?.requiresCategory ?? false) || (policy?.requiresTag ?? false))); }, [report, skipConfirmation, policy, reportNameValuePairs]); const {translate} = useLocalize(); @@ -111,7 +119,7 @@ function IOURequestStepScan({ setCameraPermissionStatus(status); if (status === RESULTS.BLOCKED) { - FileUtils.showCameraPermissionsAlert(); + showCameraPermissionsAlert(); } }) .catch(() => { @@ -185,7 +193,7 @@ function IOURequestStepScan({ ); const validateReceipt = (file: FileObject) => { - const {fileExtension} = FileUtils.splitExtensionFromFileName(file?.name ?? ''); + const {fileExtension} = splitExtensionFromFileName(file?.name ?? ''); if ( !CONST.API_ATTACHMENT_VALIDATIONS.ALLOWED_RECEIPT_EXTENSIONS.includes( fileExtension.toLowerCase() as TupleToUnion, @@ -243,7 +251,7 @@ function IOURequestStepScan({ const createTransaction = useCallback( (receipt: Receipt, participant: Participant) => { if (iouType === CONST.IOU.TYPE.TRACK && report) { - IOU.trackExpense( + trackExpense( report, 0, transaction?.currency ?? 'USD', @@ -257,7 +265,7 @@ function IOURequestStepScan({ receipt, ); } else { - IOU.requestMoney({ + requestMoney({ report, participantParams: { payeeEmail: currentUserPersonalDetails.login, @@ -294,10 +302,10 @@ function IOURequestStepScan({ // If the transaction was created from the + menu from the composer inside of a chat, the participants can automatically // be added to the transaction (taken from the chat report participants) and then the person is taken to the confirmation step. - const selectedParticipants = IOU.setMoneyRequestParticipantsFromReport(transactionID, report); + const selectedParticipants = setMoneyRequestParticipantsFromReport(transactionID, report); const participants = selectedParticipants.map((participant) => { const participantAccountID = participant?.accountID ?? CONST.DEFAULT_NUMBER_ID; - return participantAccountID ? OptionsListUtils.getParticipantsOption(participant, personalDetails) : OptionsListUtils.getReportOption(participant); + return participantAccountID ? getParticipantsOption(participant, personalDetails) : getReportOption(participant); }); if (shouldSkipConfirmation) { @@ -306,7 +314,7 @@ function IOURequestStepScan({ receipt.state = CONST.IOU.RECEIPT_STATE.SCANREADY; if (iouType === CONST.IOU.TYPE.SPLIT) { playSound(SOUNDS.DONE); - IOU.startSplitBill({ + startSplitBill({ participants, currentUserLogin: currentUserPersonalDetails?.login ?? '', currentUserAccountID: currentUserPersonalDetails.accountID, @@ -331,7 +339,7 @@ function IOURequestStepScan({ (successData) => { playSound(SOUNDS.DONE); if (iouType === CONST.IOU.TYPE.TRACK && report) { - IOU.trackExpense( + trackExpense( report, 0, transaction?.currency ?? 'USD', @@ -357,7 +365,7 @@ function IOURequestStepScan({ }, ); } else { - IOU.requestMoney({ + requestMoney({ report, participantParams: { payeeEmail: currentUserPersonalDetails.login, @@ -428,7 +436,7 @@ function IOURequestStepScan({ const updateScanAndNavigate = useCallback( (file: FileObject, source: string) => { navigateBack(); - IOU.replaceReceipt(transactionID, file as File, source); + replaceReceipt(transactionID, file as File, source); }, [transactionID], ); @@ -452,12 +460,12 @@ function IOURequestStepScan({ if (Str.isImage(originalFile.name ?? '') && (originalFile?.size ?? 0) > CONST.API_ATTACHMENT_VALIDATIONS.MAX_SIZE) { setIsLoadingReceipt(true); } - FileUtils.resizeImageIfNeeded(originalFile).then((file) => { + resizeImageIfNeeded(originalFile).then((file) => { setIsLoadingReceipt(false); // Store the receipt on the transaction object in Onyx // On Android devices, fetching blob for a file with name containing spaces fails to retrieve the type of file. // So, let us also save the file type in receipt for later use during blob fetch - IOU.setMoneyRequestReceipt(transactionID, file?.uri ?? '', file.name ?? '', !isEditing, file.type); + setMoneyRequestReceipt(transactionID, file?.uri ?? '', file.name ?? '', !isEditing, file.type); if (isEditing) { updateScanAndNavigate(file, file?.uri ?? ''); @@ -469,8 +477,8 @@ function IOURequestStepScan({ const gpsRequired = transaction?.amount === 0 && iouType !== CONST.IOU.TYPE.SPLIT && file; if (gpsRequired) { - const shouldStartLocationPermissionFlow = IOUUtils.shouldStartLocationPermissionFlow(); - if (shouldStartLocationPermissionFlow) { + const beginLocationPermissionFlow = shouldStartLocationPermissionFlow(); + if (beginLocationPermissionFlow) { setStartLocationPermissionFlow(true); return; } @@ -526,9 +534,9 @@ function IOURequestStepScan({ .then((photo: PhotoFile) => { // Store the receipt on the transaction object in Onyx const source = getPhotoSource(photo.path); - IOU.setMoneyRequestReceipt(transactionID, source, photo.path, !isEditing); + setMoneyRequestReceipt(transactionID, source, photo.path, !isEditing); - FileUtils.readFileAsync( + readFileAsync( source, photo.path, (file) => { @@ -541,8 +549,8 @@ function IOURequestStepScan({ setFileSource(source); const gpsRequired = transaction?.amount === 0 && iouType !== CONST.IOU.TYPE.SPLIT && file; if (gpsRequired) { - const shouldStartLocationPermissionFlow = IOUUtils.shouldStartLocationPermissionFlow(); - if (shouldStartLocationPermissionFlow) { + const beginLocationPermissionFlow = shouldStartLocationPermissionFlow(); + if (beginLocationPermissionFlow) { setStartLocationPermissionFlow(true); return; } @@ -718,7 +726,7 @@ function IOURequestStepScan({ resetPermissionFlow={() => setStartLocationPermissionFlow(false)} onGrant={() => navigateToConfirmationStep(fileResize, fileSource, true)} onDeny={() => { - IOU.updateLastLocationPermissionPrompt(); + updateLastLocationPermissionPrompt(); navigateToConfirmationStep(fileResize, fileSource, false); }} /> diff --git a/src/pages/iou/request/step/IOURequestStepScan/index.tsx b/src/pages/iou/request/step/IOURequestStepScan/index.tsx index 50c18c8d7e9f..ece844eca301 100644 --- a/src/pages/iou/request/step/IOURequestStepScan/index.tsx +++ b/src/pages/iou/request/step/IOURequestStepScan/index.tsx @@ -28,21 +28,29 @@ import usePolicy from '@hooks/usePolicy'; import useResponsiveLayout from '@hooks/useResponsiveLayout'; import useTheme from '@hooks/useTheme'; import useThemeStyles from '@hooks/useThemeStyles'; -import * as Browser from '@libs/Browser'; -import * as FileUtils from '@libs/fileDownload/FileUtils'; +import {isMobile, isMobileWebKit} from '@libs/Browser'; +import {base64ToFile, resizeImageIfNeeded, splitExtensionFromFileName, validateImageForCorruption} from '@libs/fileDownload/FileUtils'; import getCurrentPosition from '@libs/getCurrentPosition'; -import * as IOUUtils from '@libs/IOUUtils'; +import {shouldStartLocationPermissionFlow} from '@libs/IOUUtils'; import Log from '@libs/Log'; import Navigation from '@libs/Navigation/Navigation'; -import * as OptionsListUtils from '@libs/OptionsListUtils'; +import {getParticipantsOption, getReportOption} from '@libs/OptionsListUtils'; import * as ReportUtils from '@libs/ReportUtils'; import playSound, {SOUNDS} from '@libs/Sound'; -import * as TransactionUtils from '@libs/TransactionUtils'; +import {getDefaultTaxCode} from '@libs/TransactionUtils'; import ReceiptDropUI from '@pages/iou/ReceiptDropUI'; import StepScreenDragAndDropWrapper from '@pages/iou/request/step/StepScreenDragAndDropWrapper'; import withFullTransactionOrNotFound from '@pages/iou/request/step/withFullTransactionOrNotFound'; import withWritableReportOrNotFound from '@pages/iou/request/step/withWritableReportOrNotFound'; -import * as IOU from '@userActions/IOU'; +import { + replaceReceipt, + requestMoney, + setMoneyRequestParticipantsFromReport, + setMoneyRequestReceipt, + startSplitBill, + trackExpense, + updateLastLocationPermissionPrompt, +} from '@userActions/IOU'; import CONST from '@src/CONST'; import type {TranslationPaths} from '@src/languages/types'; import ONYXKEYS from '@src/ONYXKEYS'; @@ -96,7 +104,7 @@ function IOURequestStepScan({ const isTabActive = useIsFocused(); const isEditing = action === CONST.IOU.ACTION.EDIT; - const defaultTaxCode = TransactionUtils.getDefaultTaxCode(policy, transaction); + const defaultTaxCode = getDefaultTaxCode(policy, transaction); const transactionTaxCode = (transaction?.taxCode ? transaction?.taxCode : defaultTaxCode) ?? ''; const transactionTaxAmount = transaction?.taxAmount ?? 0; @@ -115,7 +123,7 @@ function IOURequestStepScan({ * The last deviceId is of regular len camera. */ const requestCameraPermission = useCallback(() => { - if (!Browser.isMobile()) { + if (!isMobile()) { return; } @@ -126,7 +134,7 @@ function IOURequestStepScan({ setCameraPermissionState('granted'); stream.getTracks().forEach((track) => track.stop()); // Only Safari 17+ supports zoom constraint - if (Browser.isMobileWebKit() && stream.getTracks().length > 0) { + if (isMobileWebKit() && stream.getTracks().length > 0) { let deviceId; for (const track of stream.getTracks()) { const setting = track.getSettings(); @@ -167,7 +175,7 @@ function IOURequestStepScan({ }, []); useEffect(() => { - if (!Browser.isMobile() || !isTabActive) { + if (!isMobile() || !isTabActive) { setVideoConstraints(undefined); return; } @@ -206,9 +214,9 @@ function IOURequestStepScan({ }; function validateReceipt(file: FileObject) { - return FileUtils.validateImageForCorruption(file) + return validateImageForCorruption(file) .then(() => { - const {fileExtension} = FileUtils.splitExtensionFromFileName(file?.name ?? ''); + const {fileExtension} = splitExtensionFromFileName(file?.name ?? ''); if ( !CONST.API_ATTACHMENT_VALIDATIONS.ALLOWED_RECEIPT_EXTENSIONS.includes( fileExtension.toLowerCase() as TupleToUnion, @@ -268,7 +276,7 @@ function IOURequestStepScan({ const createTransaction = useCallback( (receipt: Receipt, participant: Participant) => { if (iouType === CONST.IOU.TYPE.TRACK && report) { - IOU.trackExpense( + trackExpense( report, 0, transaction?.currency ?? 'USD', @@ -282,7 +290,7 @@ function IOURequestStepScan({ receipt, ); } else { - IOU.requestMoney({ + requestMoney({ report, participantParams: { payeeEmail: currentUserPersonalDetails.login, @@ -320,10 +328,10 @@ function IOURequestStepScan({ // If the transaction was created from the + menu from the composer inside of a chat, the participants can automatically // be added to the transaction (taken from the chat report participants) and then the person is taken to the confirmation step. - const selectedParticipants = IOU.setMoneyRequestParticipantsFromReport(transactionID, report); + const selectedParticipants = setMoneyRequestParticipantsFromReport(transactionID, report); const participants = selectedParticipants.map((participant) => { const participantAccountID = participant?.accountID ?? CONST.DEFAULT_NUMBER_ID; - return participantAccountID ? OptionsListUtils.getParticipantsOption(participant, personalDetails) : OptionsListUtils.getReportOption(participant); + return participantAccountID ? getParticipantsOption(participant, personalDetails) : getReportOption(participant); }); if (shouldSkipConfirmation) { @@ -332,7 +340,7 @@ function IOURequestStepScan({ receipt.state = CONST.IOU.RECEIPT_STATE.SCANREADY; if (iouType === CONST.IOU.TYPE.SPLIT) { playSound(SOUNDS.DONE); - IOU.startSplitBill({ + startSplitBill({ participants, currentUserLogin: currentUserPersonalDetails?.login ?? '', currentUserAccountID: currentUserPersonalDetails.accountID, @@ -357,7 +365,7 @@ function IOURequestStepScan({ (successData) => { playSound(SOUNDS.DONE); if (iouType === CONST.IOU.TYPE.TRACK && report) { - IOU.trackExpense( + trackExpense( report, 0, transaction?.currency ?? 'USD', @@ -383,7 +391,7 @@ function IOURequestStepScan({ }, ); } else { - IOU.requestMoney({ + requestMoney({ report, participantParams: { payeeEmail: currentUserPersonalDetails.login, @@ -453,7 +461,7 @@ function IOURequestStepScan({ const updateScanAndNavigate = useCallback( (file: FileObject, source: string) => { - IOU.replaceReceipt(transactionID, file as File, source); + replaceReceipt(transactionID, file as File, source); navigateBack(); }, [transactionID, navigateBack], @@ -479,12 +487,12 @@ function IOURequestStepScan({ if (Str.isImage(originalFile.name ?? '') && (originalFile?.size ?? 0) > CONST.API_ATTACHMENT_VALIDATIONS.MAX_SIZE) { setIsLoadingReceipt(true); } - FileUtils.resizeImageIfNeeded(originalFile).then((file) => { + resizeImageIfNeeded(originalFile).then((file) => { setIsLoadingReceipt(false); // Store the receipt on the transaction object in Onyx const source = URL.createObjectURL(file as Blob); // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing - IOU.setMoneyRequestReceipt(transactionID, source, file.name || '', !isEditing); + setMoneyRequestReceipt(transactionID, source, file.name || '', !isEditing); if (isEditing) { updateScanAndNavigate(file, source); @@ -495,9 +503,9 @@ function IOURequestStepScan({ setFileSource(source); const gpsRequired = transaction?.amount === 0 && iouType !== CONST.IOU.TYPE.SPLIT && file; if (gpsRequired) { - const shouldStartLocationPermissionFlow = IOUUtils.shouldStartLocationPermissionFlow(); + const beginLocationPermissionFlow = shouldStartLocationPermissionFlow(); - if (shouldStartLocationPermissionFlow) { + if (beginLocationPermissionFlow) { setStartLocationPermissionFlow(true); return; } @@ -533,9 +541,9 @@ function IOURequestStepScan({ } const filename = `receipt_${Date.now()}.png`; - const file = FileUtils.base64ToFile(imageBase64 ?? '', filename); + const file = base64ToFile(imageBase64 ?? '', filename); const source = URL.createObjectURL(file); - IOU.setMoneyRequestReceipt(transactionID, source, file.name, !isEditing); + setMoneyRequestReceipt(transactionID, source, file.name, !isEditing); if (isEditing) { updateScanAndNavigate(file, source); @@ -546,8 +554,8 @@ function IOURequestStepScan({ setFileSource(source); const gpsRequired = transaction?.amount === 0 && iouType !== CONST.IOU.TYPE.SPLIT && file; if (gpsRequired) { - const shouldStartLocationPermissionFlow = IOUUtils.shouldStartLocationPermissionFlow(); - if (shouldStartLocationPermissionFlow) { + const beginLocationPermissionFlow = shouldStartLocationPermissionFlow(); + if (beginLocationPermissionFlow) { setStartLocationPermissionFlow(true); return; } @@ -785,8 +793,8 @@ function IOURequestStepScan({ {(isDraggingOverWrapper) => ( <> {isLoadingReceipt && } - - {!(isDraggingOver ?? isDraggingOverWrapper) && (Browser.isMobile() ? mobileCameraView() : desktopUploadView())} + + {!(isDraggingOver ?? isDraggingOverWrapper) && (isMobile() ? mobileCameraView() : desktopUploadView())} { const file = e?.dataTransfer?.files[0]; @@ -812,7 +820,7 @@ function IOURequestStepScan({ resetPermissionFlow={() => setStartLocationPermissionFlow(false)} onGrant={() => navigateToConfirmationStep(fileResize, fileSource, true)} onDeny={() => { - IOU.updateLastLocationPermissionPrompt(); + updateLastLocationPermissionPrompt(); navigateToConfirmationStep(fileResize, fileSource, false); }} /> diff --git a/tests/ui/LHNItemsPresence.tsx b/tests/ui/LHNItemsPresence.tsx index 528c565969fd..aa121fa81727 100644 --- a/tests/ui/LHNItemsPresence.tsx +++ b/tests/ui/LHNItemsPresence.tsx @@ -5,9 +5,9 @@ import type {OnyxMultiSetInput} from 'react-native-onyx'; import type {ValueOf} from 'type-fest'; import type {WithCurrentUserPersonalDetailsProps} from '@components/withCurrentUserPersonalDetails'; import DateUtils from '@libs/DateUtils'; -import * as Localize from '@libs/Localize'; -import * as ReportUtils from '@libs/ReportUtils'; -import * as TransactionUtils from '@libs/TransactionUtils'; +import {translateLocal} from '@libs/Localize'; +import {buildOptimisticExpenseReport, buildOptimisticIOUReportAction, buildTransactionThread} from '@libs/ReportUtils'; +import {buildOptimisticTransaction} from '@libs/TransactionUtils'; import FontUtils from '@styles/utils/FontUtils'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; @@ -62,12 +62,12 @@ const signUpWithTestUser = () => { }; const getOptionRows = () => { - const hintText = Localize.translateLocal('accessibilityHints.navigatesToChat'); + const hintText = translateLocal('accessibilityHints.navigatesToChat'); return screen.queryAllByAccessibilityHint(hintText); }; const getDisplayNames = () => { - const hintText = Localize.translateLocal('accessibilityHints.chatUserDisplayNames'); + const hintText = translateLocal('accessibilityHints.chatUserDisplayNames'); return screen.queryAllByLabelText(hintText); }; @@ -417,15 +417,15 @@ describe('SidebarLinksData', () => { it('should not display the single transaction thread', async () => { // Given the SidebarLinks are rendered LHNTestUtils.getDefaultRenderedSidebarLinks(); - const expenseReport = ReportUtils.buildOptimisticExpenseReport('212', '123', 100, 122, 'USD'); - const expenseTransaction = TransactionUtils.buildOptimisticTransaction({ + const expenseReport = buildOptimisticExpenseReport('212', '123', 100, 122, 'USD'); + const expenseTransaction = buildOptimisticTransaction({ transactionParams: { amount: 100, currency: 'USD', reportID: expenseReport.reportID, }, }); - const expenseCreatedAction = ReportUtils.buildOptimisticIOUReportAction( + const expenseCreatedAction = buildOptimisticIOUReportAction( 'create', 100, 'USD', @@ -440,7 +440,7 @@ describe('SidebarLinksData', () => { undefined, undefined, ); - const transactionThreadReport = ReportUtils.buildTransactionThread(expenseCreatedAction, expenseReport); + const transactionThreadReport = buildTransactionThread(expenseCreatedAction, expenseReport); expenseCreatedAction.childReportID = transactionThreadReport.reportID; // When a single transaction thread is initialized in Onyx diff --git a/tests/unit/SidebarOrderTest.ts b/tests/unit/SidebarOrderTest.ts index 6ba663f1c863..46c448b00056 100644 --- a/tests/unit/SidebarOrderTest.ts +++ b/tests/unit/SidebarOrderTest.ts @@ -1,8 +1,8 @@ import {screen} from '@testing-library/react-native'; import Onyx from 'react-native-onyx'; -import * as Report from '@libs/actions/Report'; +import {addComment} from '@libs/actions/Report'; import DateUtils from '@libs/DateUtils'; -import * as Localize from '@libs/Localize'; +import {translateLocal} from '@libs/Localize'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import type * as OnyxTypes from '@src/types/onyx'; @@ -67,7 +67,7 @@ describe('Sidebar', () => { // Then the component should be rendered with an empty list since it will get past the early return .then(() => { expect(screen.toJSON()).not.toBe(null); - const navigatesToChatHintText = Localize.translateLocal('accessibilityHints.navigatesToChat'); + const navigatesToChatHintText = translateLocal('accessibilityHints.navigatesToChat'); expect(screen.queryAllByAccessibilityHint(navigatesToChatHintText)).toHaveLength(0); })); @@ -107,9 +107,9 @@ describe('Sidebar', () => { const report3 = LHNTestUtils.getFakeReport([1, 4], 1); // Each report has at least one ADD_COMMENT action so should be rendered in the LNH - Report.addComment(report1.reportID, 'Hi, this is a comment'); - Report.addComment(report2.reportID, 'Hi, this is a comment'); - Report.addComment(report3.reportID, 'Hi, this is a comment'); + addComment(report1.reportID, 'Hi, this is a comment'); + addComment(report2.reportID, 'Hi, this is a comment'); + addComment(report3.reportID, 'Hi, this is a comment'); const reportCollectionDataSet: ReportCollectionDataSet = { [`${ONYXKEYS.COLLECTION.REPORT}${report1.reportID}`]: report1, @@ -133,7 +133,7 @@ describe('Sidebar', () => { // Then the component should be rendered with the mostly recently updated report first .then(() => { - const hintText = Localize.translateLocal('accessibilityHints.chatUserDisplayNames'); + const hintText = translateLocal('accessibilityHints.chatUserDisplayNames'); const displayNames = screen.queryAllByLabelText(hintText); expect(displayNames).toHaveLength(3); @@ -155,9 +155,9 @@ describe('Sidebar', () => { const report3 = LHNTestUtils.getFakeReport([1, 4], 1); // Each report has at least one ADD_COMMENT action so should be rendered in the LNH - Report.addComment(report1.reportID, 'Hi, this is a comment'); - Report.addComment(report2.reportID, 'Hi, this is a comment'); - Report.addComment(report3.reportID, 'Hi, this is a comment'); + addComment(report1.reportID, 'Hi, this is a comment'); + addComment(report2.reportID, 'Hi, this is a comment'); + addComment(report3.reportID, 'Hi, this is a comment'); const currentReportId = report1.reportID; const reportCollectionDataSet: ReportCollectionDataSet = { @@ -187,7 +187,7 @@ describe('Sidebar', () => { const pencilIcon = screen.queryAllByTestId('Pencil Icon'); expect(pencilIcon).toHaveLength(1); - const hintText = Localize.translateLocal('accessibilityHints.chatUserDisplayNames'); + const hintText = translateLocal('accessibilityHints.chatUserDisplayNames'); const displayNames = screen.queryAllByLabelText(hintText); expect(displayNames).toHaveLength(3); expect(displayNames.at(0)).toHaveTextContent('Email Two'); // this has `hasDraft` flag enabled so it will be on top @@ -204,9 +204,9 @@ describe('Sidebar', () => { const report3 = LHNTestUtils.getFakeReport([1, 4], 1); // Each report has at least one ADD_COMMENT action so should be rendered in the LNH - Report.addComment(report1.reportID, 'Hi, this is a comment'); - Report.addComment(report2.reportID, 'Hi, this is a comment'); - Report.addComment(report3.reportID, 'Hi, this is a comment'); + addComment(report1.reportID, 'Hi, this is a comment'); + addComment(report2.reportID, 'Hi, this is a comment'); + addComment(report3.reportID, 'Hi, this is a comment'); const reportCollectionDataSet: ReportCollectionDataSet = { [`${ONYXKEYS.COLLECTION.REPORT}${report1.reportID}`]: report1, @@ -238,7 +238,7 @@ describe('Sidebar', () => { // Then the order of the reports should be 1 > 3 > 2 // ^--- (1 goes to the front and pushes other two down) .then(() => { - const hintText = Localize.translateLocal('accessibilityHints.chatUserDisplayNames'); + const hintText = translateLocal('accessibilityHints.chatUserDisplayNames'); const displayNames = screen.queryAllByLabelText(hintText); expect(displayNames).toHaveLength(3); expect(displayNames.at(0)).toHaveTextContent('Email Two'); @@ -265,9 +265,9 @@ describe('Sidebar', () => { }; // Each report has at least one ADD_COMMENT action so should be rendered in the LNH - Report.addComment(report1.reportID, 'Hi, this is a comment'); - Report.addComment(report2.reportID, 'Hi, this is a comment'); - Report.addComment(report3.reportID, 'Hi, this is a comment'); + addComment(report1.reportID, 'Hi, this is a comment'); + addComment(report2.reportID, 'Hi, this is a comment'); + addComment(report3.reportID, 'Hi, this is a comment'); const reportCollectionDataSet: ReportCollectionDataSet = { [`${ONYXKEYS.COLLECTION.REPORT}${report1.reportID}`]: report1, @@ -292,7 +292,7 @@ describe('Sidebar', () => { // Then the order of the reports should be 4 > 3 > 2 > 1 .then(() => { - const hintText = Localize.translateLocal('accessibilityHints.chatUserDisplayNames'); + const hintText = translateLocal('accessibilityHints.chatUserDisplayNames'); const displayNames = screen.queryAllByLabelText(hintText); expect(displayNames).toHaveLength(4); expect(displayNames.at(0)).toHaveTextContent(taskReportName); @@ -339,9 +339,9 @@ describe('Sidebar', () => { report3.iouReportID = iouReport.reportID; // Each report has at least one ADD_COMMENT action so should be rendered in the LNH - Report.addComment(report1.reportID, 'Hi, this is a comment'); - Report.addComment(report3.reportID, 'Hi, this is a comment'); - Report.addComment(report2.reportID, 'Hi, this is a comment'); + addComment(report1.reportID, 'Hi, this is a comment'); + addComment(report3.reportID, 'Hi, this is a comment'); + addComment(report2.reportID, 'Hi, this is a comment'); const reportCollectionDataSet: ReportCollectionDataSet = { [`${ONYXKEYS.COLLECTION.REPORT}${report1.reportID}`]: report1, @@ -366,7 +366,7 @@ describe('Sidebar', () => { // Then the order of the reports should be 4 > 3 > 2 > 1 .then(() => { - const hintText = Localize.translateLocal('accessibilityHints.chatUserDisplayNames'); + const hintText = translateLocal('accessibilityHints.chatUserDisplayNames'); const displayNames = screen.queryAllByLabelText(hintText); expect(displayNames).toHaveLength(4); expect(displayNames.at(0)).toHaveTextContent('Email Four'); @@ -417,9 +417,9 @@ describe('Sidebar', () => { report3.iouReportID = expenseReport.reportID; // Each report has at least one ADD_COMMENT action so should be rendered in the LNH - Report.addComment(report1.reportID, 'Hi, this is a comment'); - Report.addComment(report3.reportID, 'Hi, this is a comment'); - Report.addComment(report2.reportID, 'Hi, this is a comment'); + addComment(report1.reportID, 'Hi, this is a comment'); + addComment(report3.reportID, 'Hi, this is a comment'); + addComment(report2.reportID, 'Hi, this is a comment'); const reportCollectionDataSet: ReportCollectionDataSet = { [`${ONYXKEYS.COLLECTION.REPORT}${report1.reportID}`]: report1, @@ -445,7 +445,7 @@ describe('Sidebar', () => { // Then the order of the reports should be 4 > 3 > 2 > 1 .then(() => { - const hintText = Localize.translateLocal('accessibilityHints.chatUserDisplayNames'); + const hintText = translateLocal('accessibilityHints.chatUserDisplayNames'); const displayNames = screen.queryAllByLabelText(hintText); expect(displayNames).toHaveLength(4); expect(displayNames.at(0)).toHaveTextContent('Email One'); @@ -467,9 +467,9 @@ describe('Sidebar', () => { const report3 = LHNTestUtils.getFakeReport([1, 4], 1); // Each report has at least one ADD_COMMENT action so should be rendered in the LNH - Report.addComment(report1.reportID, 'Hi, this is a comment'); - Report.addComment(report2.reportID, 'Hi, this is a comment'); - Report.addComment(report3.reportID, 'Hi, this is a comment'); + addComment(report1.reportID, 'Hi, this is a comment'); + addComment(report2.reportID, 'Hi, this is a comment'); + addComment(report3.reportID, 'Hi, this is a comment'); const currentReportId = report2.reportID; @@ -505,7 +505,7 @@ describe('Sidebar', () => { // Then the order of the reports should be 2 > 3 > 1 // ^--- (2 goes to the front and pushes 3 down) .then(() => { - const hintText = Localize.translateLocal('accessibilityHints.chatUserDisplayNames'); + const hintText = translateLocal('accessibilityHints.chatUserDisplayNames'); const displayNames = screen.queryAllByLabelText(hintText); expect(displayNames).toHaveLength(3); expect(displayNames.at(0)).toHaveTextContent('Email Three'); @@ -616,7 +616,7 @@ describe('Sidebar', () => { iouReportID: undefined, }; const report4 = LHNTestUtils.getFakeReport([1, 5], 1); - Report.addComment(report4.reportID, 'Hi, this is a comment'); + addComment(report4.reportID, 'Hi, this is a comment'); const iouReport: OnyxTypes.Report = { ...LHNTestUtils.getFakeReport([1, 4]), @@ -671,7 +671,7 @@ describe('Sidebar', () => { // there is a pencil icon // there is a pinned icon .then(() => { - const hintText = Localize.translateLocal('accessibilityHints.chatUserDisplayNames'); + const hintText = translateLocal('accessibilityHints.chatUserDisplayNames'); const displayNames = screen.queryAllByLabelText(hintText); expect(displayNames).toHaveLength(4); expect(screen.queryAllByTestId('Pin Icon')).toHaveLength(1); @@ -726,7 +726,7 @@ describe('Sidebar', () => { // Then the reports are in alphabetical order .then(() => { - const hintText = Localize.translateLocal('accessibilityHints.chatUserDisplayNames'); + const hintText = translateLocal('accessibilityHints.chatUserDisplayNames'); const displayNames = screen.queryAllByLabelText(hintText); expect(displayNames).toHaveLength(3); expect(displayNames.at(0)).toHaveTextContent('Email Four'); @@ -739,7 +739,7 @@ describe('Sidebar', () => { // Then they are still in alphabetical order .then(() => { - const hintText = Localize.translateLocal('accessibilityHints.chatUserDisplayNames'); + const hintText = translateLocal('accessibilityHints.chatUserDisplayNames'); const displayNames = screen.queryAllByLabelText(hintText); expect(displayNames).toHaveLength(4); expect(displayNames.at(0)).toHaveTextContent('Email Five'); @@ -795,7 +795,7 @@ describe('Sidebar', () => { // Then the reports are in alphabetical order .then(() => { - const hintText = Localize.translateLocal('accessibilityHints.chatUserDisplayNames'); + const hintText = translateLocal('accessibilityHints.chatUserDisplayNames'); const displayNames = screen.queryAllByLabelText(hintText); expect(displayNames).toHaveLength(3); expect(displayNames.at(0)).toHaveTextContent('Email Four'); @@ -815,7 +815,7 @@ describe('Sidebar', () => { // Then they are still in alphabetical order .then(() => { - const hintText = Localize.translateLocal('accessibilityHints.chatUserDisplayNames'); + const hintText = translateLocal('accessibilityHints.chatUserDisplayNames'); const displayNames = screen.queryAllByLabelText(hintText); expect(displayNames).toHaveLength(4); expect(displayNames.at(0)).toHaveTextContent('Email Five'); @@ -836,9 +836,9 @@ describe('Sidebar', () => { const report3 = LHNTestUtils.getFakeReport([1, 4]); // Each report has at least one ADD_COMMENT action so should be rendered in the LNH - Report.addComment(report1.reportID, 'Hi, this is a comment'); - Report.addComment(report2.reportID, 'Hi, this is a comment'); - Report.addComment(report3.reportID, 'Hi, this is a comment'); + addComment(report1.reportID, 'Hi, this is a comment'); + addComment(report2.reportID, 'Hi, this is a comment'); + addComment(report3.reportID, 'Hi, this is a comment'); // Given the user is in all betas const betas = [CONST.BETAS.DEFAULT_ROOMS]; @@ -874,7 +874,7 @@ describe('Sidebar', () => { // Then the first report is in last position .then(() => { - const hintText = Localize.translateLocal('accessibilityHints.chatUserDisplayNames'); + const hintText = translateLocal('accessibilityHints.chatUserDisplayNames'); const displayNames = screen.queryAllByLabelText(hintText); expect(displayNames).toHaveLength(3); expect(displayNames.at(0)).toHaveTextContent('Email Four'); @@ -891,9 +891,9 @@ describe('Sidebar', () => { const report3: OnyxTypes.Report = LHNTestUtils.getFakeReport([1, 4]); // Each report has at least one ADD_COMMENT action so should be rendered in the LNH - Report.addComment(report1.reportID, 'Hi, this is a comment'); - Report.addComment(report2.reportID, 'Hi, this is a comment'); - Report.addComment(report3.reportID, 'Hi, this is a comment'); + addComment(report1.reportID, 'Hi, this is a comment'); + addComment(report2.reportID, 'Hi, this is a comment'); + addComment(report3.reportID, 'Hi, this is a comment'); const reportCollectionDataSet: ReportCollectionDataSet = { [`${ONYXKEYS.COLLECTION.REPORT}${report1.reportID}`]: report1, @@ -917,7 +917,7 @@ describe('Sidebar', () => { // Then the reports are ordered alphabetically since their lastVisibleActionCreated are the same .then(() => { - const hintText = Localize.translateLocal('accessibilityHints.chatUserDisplayNames'); + const hintText = translateLocal('accessibilityHints.chatUserDisplayNames'); const displayNames = screen.queryAllByLabelText(hintText); expect(displayNames).toHaveLength(3); expect(displayNames.at(0)).toHaveTextContent('Email Four'); @@ -957,7 +957,7 @@ describe('Sidebar', () => { // Then the reports are in alphabetical order .then(() => { - const hintText = Localize.translateLocal('accessibilityHints.chatUserDisplayNames'); + const hintText = translateLocal('accessibilityHints.chatUserDisplayNames'); const displayNames = screen.queryAllByLabelText(hintText); expect(displayNames).toHaveLength(3); expect(displayNames.at(0)).toHaveTextContent('Email Four'); @@ -970,7 +970,7 @@ describe('Sidebar', () => { // Then they are still in alphabetical order .then(() => { - const hintText = Localize.translateLocal('accessibilityHints.chatUserDisplayNames'); + const hintText = translateLocal('accessibilityHints.chatUserDisplayNames'); const displayNames = screen.queryAllByLabelText(hintText); expect(displayNames).toHaveLength(4); expect(displayNames.at(0)).toHaveTextContent('Email Five'); @@ -1028,7 +1028,7 @@ describe('Sidebar', () => { // Then the first report is in last position .then(() => { - const hintText = Localize.translateLocal('accessibilityHints.chatUserDisplayNames'); + const hintText = translateLocal('accessibilityHints.chatUserDisplayNames'); const displayNames = screen.queryAllByLabelText(hintText); expect(displayNames).toHaveLength(3); expect(displayNames.at(0)).toHaveTextContent('Email Four'); From 453d362b0897475a19a2c83946c94cd8027a0654 Mon Sep 17 00:00:00 2001 From: Srikar Parsi Date: Thu, 23 Jan 2025 21:48:57 -0500 Subject: [PATCH 3/7] debug and option list changes --- src/components/OptionListContextProvider.tsx | 18 +++---- src/libs/DebugUtils.ts | 16 +++--- .../BaseReportActionContextMenu.tsx | 50 +++++++++++-------- .../withReportAndPrivateNotesOrNotFound.tsx | 8 +-- 4 files changed, 50 insertions(+), 42 deletions(-) diff --git a/src/components/OptionListContextProvider.tsx b/src/components/OptionListContextProvider.tsx index c2fde1649bf3..09b996dc826e 100644 --- a/src/components/OptionListContextProvider.tsx +++ b/src/components/OptionListContextProvider.tsx @@ -1,9 +1,9 @@ import React, {createContext, useCallback, useContext, useEffect, useMemo, useRef, useState} from 'react'; import {useOnyx} from 'react-native-onyx'; import usePrevious from '@hooks/usePrevious'; -import * as OptionsListUtils from '@libs/OptionsListUtils'; -import type {OptionList} from '@libs/OptionsListUtils'; -import * as ReportUtils from '@libs/ReportUtils'; +import {createOptionFromReport, createOptionList} from '@libs/OptionsListUtils'; +import type {OptionList, SearchOption} from '@libs/OptionsListUtils'; +import {isSelfDM} from '@libs/ReportUtils'; import ONYXKEYS from '@src/ONYXKEYS'; import type {PersonalDetails, Report} from '@src/types/onyx'; import {usePersonalDetails} from './OnyxProvider'; @@ -62,7 +62,7 @@ function OptionsListContextProvider({children}: OptionsListProviderProps) { return; } // Since reports updates can happen in bulk, and some reports depend on other reports, we need to recreate the whole list from scratch. - const newReports = OptionsListUtils.createOptionList(personalDetails, reports).reports; + const newReports = createOptionList(personalDetails, reports).reports; setOptions((prevOptions) => { const newOptions = { @@ -90,7 +90,7 @@ function OptionsListContextProvider({children}: OptionsListProviderProps) { const newReportOptions: Array<{ replaceIndex: number; - newReportOption: OptionsListUtils.SearchOption; + newReportOption: SearchOption; }> = []; Object.keys(personalDetails).forEach((accountID) => { @@ -102,12 +102,12 @@ function OptionsListContextProvider({children}: OptionsListProviderProps) { } Object.values(reports ?? {}) - .filter((report) => !!Object.keys(report?.participants ?? {}).includes(accountID) || (ReportUtils.isSelfDM(report) && report?.ownerAccountID === Number(accountID))) + .filter((report) => !!Object.keys(report?.participants ?? {}).includes(accountID) || (isSelfDM(report) && report?.ownerAccountID === Number(accountID))) .forEach((report) => { if (!report) { return; } - const newReportOption = OptionsListUtils.createOptionFromReport(report, personalDetails); + const newReportOption = createOptionFromReport(report, personalDetails); const replaceIndex = options.reports.findIndex((option) => option.reportID === report.reportID); newReportOptions.push({ newReportOption, @@ -117,7 +117,7 @@ function OptionsListContextProvider({children}: OptionsListProviderProps) { }); // since personal details are not a collection, we need to recreate the whole list from scratch - const newPersonalDetailsOptions = OptionsListUtils.createOptionList(personalDetails).personalDetails; + const newPersonalDetailsOptions = createOptionList(personalDetails).personalDetails; setOptions((prevOptions) => { const newOptions = {...prevOptions}; @@ -131,7 +131,7 @@ function OptionsListContextProvider({children}: OptionsListProviderProps) { }, [personalDetails]); const loadOptions = useCallback(() => { - const optionLists = OptionsListUtils.createOptionList(personalDetails, reports); + const optionLists = createOptionList(personalDetails, reports); setOptions({ reports: optionLists.reports, personalDetails: optionLists.personalDetails, diff --git a/src/libs/DebugUtils.ts b/src/libs/DebugUtils.ts index 41b40fd683a7..1eb54383734d 100644 --- a/src/libs/DebugUtils.ts +++ b/src/libs/DebugUtils.ts @@ -9,10 +9,10 @@ import CONST from '@src/CONST'; import type {TranslationPaths} from '@src/languages/types'; import ONYXKEYS from '@src/ONYXKEYS'; import type {Beta, Policy, Report, ReportAction, ReportActions, ReportNameValuePairs, Transaction, TransactionViolation} from '@src/types/onyx'; -import * as ReportActionsUtils from './ReportActionsUtils'; -import * as ReportUtils from './ReportUtils'; +import {getLinkedTransactionID} from './ReportActionsUtils'; +import {getReasonAndReportActionThatRequiresAttention, reasonForReportToBeInOptionList, shouldDisplayViolationsRBRInLHN} from './ReportUtils'; import SidebarUtils from './SidebarUtils'; -import * as TransactionUtils from './TransactionUtils'; +import {getTransactionID as TransactionUtilsGetTransactionID} from './TransactionUtils'; class NumberError extends SyntaxError { constructor() { @@ -1299,9 +1299,9 @@ function getReasonForShowingRowInLHN(report: OnyxEntry, hasRBR = false): return null; } - const doesReportHaveViolations = ReportUtils.shouldDisplayViolationsRBRInLHN(report, transactionViolations); + const doesReportHaveViolations = shouldDisplayViolationsRBRInLHN(report, transactionViolations); - const reason = ReportUtils.reasonForReportToBeInOptionList({ + const reason = reasonForReportToBeInOptionList({ report, // We can't pass report.reportID because it will cause reason to always be isFocused currentReportId: '-1', @@ -1339,7 +1339,7 @@ function getReasonAndReportActionForGBRInLHNRow(report: OnyxEntry): GBRR return null; } - const {reason, reportAction} = ReportUtils.getReasonAndReportActionThatRequiresAttention(report) ?? {}; + const {reason, reportAction} = getReasonAndReportActionThatRequiresAttention(report) ?? {}; if (reason) { return {reason: `debug.reasonGBR.${reason}`, reportAction}; @@ -1367,12 +1367,12 @@ function getReasonAndReportActionForRBRInLHNRow(report: Report, reportActions: O } function getTransactionID(report: OnyxEntry, reportActions: OnyxEntry) { - const transactionID = TransactionUtils.getTransactionID(report?.reportID); + const transactionID = TransactionUtilsGetTransactionID(report?.reportID); return Number(transactionID) > 0 ? transactionID : Object.values(reportActions ?? {}) - .map((reportAction) => ReportActionsUtils.getLinkedTransactionID(reportAction)) + .map((reportAction) => getLinkedTransactionID(reportAction)) .find(Boolean); } diff --git a/src/pages/home/report/ContextMenu/BaseReportActionContextMenu.tsx b/src/pages/home/report/ContextMenu/BaseReportActionContextMenu.tsx index 2b3269c28796..b97e7f2c3dd7 100755 --- a/src/pages/home/report/ContextMenu/BaseReportActionContextMenu.tsx +++ b/src/pages/home/report/ContextMenu/BaseReportActionContextMenu.tsx @@ -18,11 +18,19 @@ import usePaginatedReportActions from '@hooks/usePaginatedReportActions'; import useResponsiveLayout from '@hooks/useResponsiveLayout'; import useRestoreInputFocus from '@hooks/useRestoreInputFocus'; import useStyleUtils from '@hooks/useStyleUtils'; -import * as PolicyUtils from '@libs/PolicyUtils'; -import * as ReportActionsUtils from '@libs/ReportActionsUtils'; -import * as ReportUtils from '@libs/ReportUtils'; +import {getPolicy, getWorkspaceAccountID, isPolicyAdmin as PolicyUtilsIsPolicyAdmin} from '@libs/PolicyUtils'; +import {getLinkedTransactionID, getOneTransactionThreadReportID, getOriginalMessage, getReportAction, isActionOfType} from '@libs/ReportActionsUtils'; +import { + chatIncludesChronosWithID, + getSourceIDFromReportAction, + isArchivedNonExpenseReport, + isArchivedNonExpenseReportWithID, + isInvoiceReport as ReportUtilsIsInvoiceReport, + isMoneyRequestReport as ReportUtilsIsMoneyRequestReport, + isTrackExpenseReport as ReportUtilsIsTrackExpenseReport, +} from '@libs/ReportUtils'; import shouldEnableContextMenuEnterShortcut from '@libs/shouldEnableContextMenuEnterShortcut'; -import * as Session from '@userActions/Session'; +import {isAnonymousUser, signOutAndRedirectToSignIn} from '@userActions/Session'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import type {ReportAction} from '@src/types/onyx'; @@ -132,12 +140,12 @@ function BaseReportActionContextMenu({ const [reportActions] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${originalReportID}`, { canEvict: false, }); - const transactionID = ReportActionsUtils.getLinkedTransactionID(reportActionID, reportID); + const transactionID = getLinkedTransactionID(reportActionID, reportID); const [transaction] = useOnyx(`${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`); const [user] = useOnyx(ONYXKEYS.USER); const [report] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${reportID}`); const policyID = report?.policyID; - const workspaceAccountID = PolicyUtils.getWorkspaceAccountID(policyID); + const workspaceAccountID = getWorkspaceAccountID(policyID); const [cardList = {}] = useOnyx(ONYXKEYS.CARD_LIST); const [cardsList] = useOnyx(`${ONYXKEYS.COLLECTION.WORKSPACE_CARDS_LIST}${workspaceAccountID}_${CONST.EXPENSIFY_CARD.BANK}`); @@ -148,23 +156,23 @@ function BaseReportActionContextMenu({ return reportActions[reportActionID]; }, [reportActions, reportActionID]); - const sourceID = ReportUtils.getSourceIDFromReportAction(reportAction); + const sourceID = getSourceIDFromReportAction(reportAction); const [download] = useOnyx(`${ONYXKEYS.COLLECTION.DOWNLOAD}${sourceID}`); const [childReport] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${reportAction?.childReportID}`); - const parentReportAction = ReportActionsUtils.getReportAction(childReport?.parentReportID, childReport?.parentReportActionID); + const parentReportAction = getReportAction(childReport?.parentReportID, childReport?.parentReportActionID); const {reportActions: paginatedReportActions} = usePaginatedReportActions(childReport?.reportID); const transactionThreadReportID = useMemo( - () => ReportActionsUtils.getOneTransactionThreadReportID(childReport?.reportID, paginatedReportActions ?? [], isOffline), + () => getOneTransactionThreadReportID(childReport?.reportID, paginatedReportActions ?? [], isOffline), [childReport?.reportID, paginatedReportActions, isOffline], ); const [transactionThreadReport] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${transactionThreadReportID}`); - const isMoneyRequestReport = useMemo(() => ReportUtils.isMoneyRequestReport(childReport), [childReport]); - const isInvoiceReport = useMemo(() => ReportUtils.isInvoiceReport(childReport), [childReport]); + const isMoneyRequestReport = useMemo(() => ReportUtilsIsMoneyRequestReport(childReport), [childReport]); + const isInvoiceReport = useMemo(() => ReportUtilsIsInvoiceReport(childReport), [childReport]); const requestParentReportAction = useMemo(() => { if (isMoneyRequestReport || isInvoiceReport) { @@ -182,15 +190,15 @@ function BaseReportActionContextMenu({ const [parentReportNameValuePairs] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_NAME_VALUE_PAIRS}${childReport?.parentReportID}`); const [parentReport] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${childReport?.parentReportID}`); - const isMoneyRequest = useMemo(() => ReportUtils.isMoneyRequest(childReport), [childReport]); - const isTrackExpenseReport = ReportUtils.isTrackExpenseReport(childReport); + const isMoneyRequest = useMemo(() => ReportUtilsIsMoneyRequestReport(childReport), [childReport]); + const isTrackExpenseReport = ReportUtilsIsTrackExpenseReport(childReport); const isSingleTransactionView = isMoneyRequest || isTrackExpenseReport; const isMoneyRequestOrReport = isMoneyRequestReport || isSingleTransactionView; const areHoldRequirementsMet = !isInvoiceReport && isMoneyRequestOrReport && - !ReportUtils.isArchivedNonExpenseReport(transactionThreadReportID ? childReport : parentReport, transactionThreadReportID ? childReportNameValuePairs : parentReportNameValuePairs); + !isArchivedNonExpenseReport(transactionThreadReportID ? childReport : parentReport, transactionThreadReportID ? childReportNameValuePairs : parentReportNameValuePairs); const shouldEnableArrowNavigation = !isMini && (isVisible || shouldKeepOpen); let filteredContextMenuActions = ContextMenuActions.filter( @@ -245,11 +253,11 @@ function BaseReportActionContextMenu({ * shows the sign in modal. Else, executes the callback. */ const interceptAnonymousUser = (callback: () => void, isAnonymousAction = false) => { - if (Session.isAnonymousUser() && !isAnonymousAction) { + if (isAnonymousUser() && !isAnonymousAction) { hideContextMenu(false); InteractionManager.runAfterInteractions(() => { - Session.signOutAndRedirectToSignIn(); + signOutAndRedirectToSignIn(); }); } else { callback(); @@ -290,8 +298,8 @@ function BaseReportActionContextMenu({ checkIfContextMenuActive?.(); setShouldKeepOpen(false); }, - ReportUtils.isArchivedNonExpenseReportWithID(originalReportID), - ReportUtils.chatIncludesChronosWithID(originalReportID), + isArchivedNonExpenseReportWithID(originalReportID), + chatIncludesChronosWithID(originalReportID), undefined, undefined, filteredContextMenuActions, @@ -302,16 +310,16 @@ function BaseReportActionContextMenu({ ); }; - const cardIssuedActionOriginalMessage = ReportActionsUtils.isActionOfType( + const cardIssuedActionOriginalMessage = isActionOfType( reportAction, CONST.REPORT.ACTIONS.TYPE.CARD_ISSUED, CONST.REPORT.ACTIONS.TYPE.CARD_ISSUED_VIRTUAL, CONST.REPORT.ACTIONS.TYPE.CARD_MISSING_ADDRESS, ) - ? ReportActionsUtils.getOriginalMessage(reportAction) + ? getOriginalMessage(reportAction) : undefined; const cardID = cardIssuedActionOriginalMessage?.cardID ?? CONST.DEFAULT_NUMBER_ID; - const isPolicyAdmin = PolicyUtils.isPolicyAdmin(PolicyUtils.getPolicy(policyID)); + const isPolicyAdmin = PolicyUtilsIsPolicyAdmin(getPolicy(policyID)); const card = isPolicyAdmin ? cardsList?.[cardID] : cardList[cardID]; return ( diff --git a/src/pages/home/report/withReportAndPrivateNotesOrNotFound.tsx b/src/pages/home/report/withReportAndPrivateNotesOrNotFound.tsx index ab5edff7be8c..2632c08c478f 100644 --- a/src/pages/home/report/withReportAndPrivateNotesOrNotFound.tsx +++ b/src/pages/home/report/withReportAndPrivateNotesOrNotFound.tsx @@ -4,9 +4,9 @@ import {useOnyx} from 'react-native-onyx'; import useLocalize from '@hooks/useLocalize'; import useNetwork from '@hooks/useNetwork'; import usePrevious from '@hooks/usePrevious'; -import * as Report from '@libs/actions/Report'; +import {getReportPrivateNote} from '@libs/actions/Report'; import getComponentDisplayName from '@libs/getComponentDisplayName'; -import * as ReportUtils from '@libs/ReportUtils'; +import {isArchivedReport, isSelfDM} from '@libs/ReportUtils'; import NotFoundPage from '@pages/ErrorPage/NotFoundPage'; import LoadingPage from '@pages/LoadingPage'; import type {TranslationPaths} from '@src/languages/types'; @@ -47,7 +47,7 @@ export default function (pageTitle: TranslationPaths) { return; } - Report.getReportPrivateNote(report?.reportID); + getReportPrivateNote(report?.reportID); // eslint-disable-next-line react-compiler/react-compiler, react-hooks/exhaustive-deps -- do not add report.isLoadingPrivateNotes to dependencies }, [report?.reportID, isOffline, isPrivateNotesFetchTriggered, isReconnecting]); @@ -56,7 +56,7 @@ export default function (pageTitle: TranslationPaths) { // eslint-disable-next-line rulesdir/no-negated-variables const shouldShowNotFoundPage = useMemo(() => { // Show not found view if the report is archived, or if the note is not of current user or if report is a self DM. - if (ReportUtils.isArchivedReport(reportNameValuePairs) || isOtherUserNote || ReportUtils.isSelfDM(report)) { + if (isArchivedReport(reportNameValuePairs) || isOtherUserNote || isSelfDM(report)) { return true; } From e62915b0b7edf61bbb3414cb12662a32c24cded9 Mon Sep 17 00:00:00 2001 From: Srikar Parsi Date: Thu, 23 Jan 2025 21:57:34 -0500 Subject: [PATCH 4/7] iou lint --- .../iou/request/step/IOURequestStepAmount.tsx | 72 +++++++++---------- 1 file changed, 36 insertions(+), 36 deletions(-) diff --git a/src/pages/iou/request/step/IOURequestStepAmount.tsx b/src/pages/iou/request/step/IOURequestStepAmount.tsx index 1e139d07a2d6..489f8abdcd5a 100644 --- a/src/pages/iou/request/step/IOURequestStepAmount.tsx +++ b/src/pages/iou/request/step/IOURequestStepAmount.tsx @@ -6,16 +6,16 @@ import type {BaseTextInputRef} from '@components/TextInput/BaseTextInput/types'; import withCurrentUserPersonalDetails from '@components/withCurrentUserPersonalDetails'; import type {WithCurrentUserPersonalDetailsProps} from '@components/withCurrentUserPersonalDetails'; import useLocalize from '@hooks/useLocalize'; -import * as TransactionEdit from '@libs/actions/TransactionEdit'; -import * as CurrencyUtils from '@libs/CurrencyUtils'; +import { createDraftTransaction, removeDraftTransaction } from '@libs/actions/TransactionEdit'; +import { convertToBackendAmount, isValidCurrencyCode } from '@libs/CurrencyUtils'; import Navigation from '@libs/Navigation/Navigation'; -import * as OptionsListUtils from '@libs/OptionsListUtils'; -import * as ReportUtils from '@libs/ReportUtils'; +import { getParticipantsOption, getReportOption } from '@libs/OptionsListUtils'; +import { getBankAccountRoute, getTransactionDetails, isArchivedReport, isPolicyExpenseChat } from '@libs/ReportUtils'; import playSound, {SOUNDS} from '@libs/Sound'; -import * as TransactionUtils from '@libs/TransactionUtils'; +import { calculateTaxAmount, getAmount, getCurrency, getDefaultTaxCode, getTaxValue } from '@libs/TransactionUtils'; import {getRequestType} from '@libs/TransactionUtils'; import MoneyRequestAmountForm from '@pages/iou/MoneyRequestAmountForm'; -import * as IOU from '@userActions/IOU'; +import { requestMoney, resetSplitShares, sendMoneyElsewhere, sendMoneyWithWallet, setDraftSplitTransaction, setMoneyRequestAmount, setMoneyRequestParticipantsFromReport, setMoneyRequestTaxAmount, setSplitShares, trackExpense, updateMoneyRequestAmountAndCurrency } from '@userActions/IOU'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; @@ -69,9 +69,9 @@ function IOURequestStepAmount({ const isSplitBill = iouType === CONST.IOU.TYPE.SPLIT; const isEditingSplitBill = isEditing && isSplitBill; const currentTransaction = isEditingSplitBill && !isEmptyObject(splitDraftTransaction) ? splitDraftTransaction : transaction; - const {amount: transactionAmount} = ReportUtils.getTransactionDetails(currentTransaction) ?? {amount: 0}; - const {currency: originalCurrency} = ReportUtils.getTransactionDetails(isEditing && !isEmptyObject(draftTransaction) ? draftTransaction : transaction) ?? {currency: CONST.CURRENCY.USD}; - const currency = CurrencyUtils.isValidCurrencyCode(selectedCurrency) ? selectedCurrency : originalCurrency; + const {amount: transactionAmount} = getTransactionDetails(currentTransaction) ?? {amount: 0}; + const {currency: originalCurrency} = getTransactionDetails(isEditing && !isEmptyObject(draftTransaction) ? draftTransaction : transaction) ?? {currency: CONST.CURRENCY.USD}; + const currency = isValidCurrencyCode(selectedCurrency) ? selectedCurrency : originalCurrency; // For quick button actions, we'll skip the confirmation page unless the report is archived or this is a workspace request, as // the user will have to add a merchant. @@ -80,7 +80,7 @@ function IOURequestStepAmount({ return false; } - return !(ReportUtils.isArchivedReport(reportNameValuePairs) || ReportUtils.isPolicyExpenseChat(report)); + return !(isArchivedReport(reportNameValuePairs) || isPolicyExpenseChat(report)); }, [report, isSplitBill, skipConfirmation, reportNameValuePairs]); useFocusEffect( @@ -102,13 +102,13 @@ function IOURequestStepAmount({ // A temporary solution to not prevent users from editing the currency // We create a backup transaction and use it to save the currency and remove this transaction backup if we don't save the amount // It should be removed after this issue https://github.com/Expensify/App/issues/34607 is fixed - TransactionEdit.createDraftTransaction(isEditingSplitBill && !isEmptyObject(splitDraftTransaction) ? splitDraftTransaction : transaction); + createDraftTransaction(isEditingSplitBill && !isEmptyObject(splitDraftTransaction) ? splitDraftTransaction : transaction); return () => { if (isSaveButtonPressed.current) { return; } - TransactionEdit.removeDraftTransaction(transaction?.transactionID); + removeDraftTransaction(transaction?.transactionID); }; // eslint-disable-next-line react-compiler/react-compiler, react-hooks/exhaustive-deps }, []); @@ -149,14 +149,14 @@ function IOURequestStepAmount({ const navigateToNextPage = ({amount, paymentMethod}: AmountParams) => { isSaveButtonPressed.current = true; - const amountInSmallestCurrencyUnits = CurrencyUtils.convertToBackendAmount(Number.parseFloat(amount)); + const amountInSmallestCurrencyUnits = convertToBackendAmount(Number.parseFloat(amount)); // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing - IOU.setMoneyRequestAmount(transactionID, amountInSmallestCurrencyUnits, currency || CONST.CURRENCY.USD, shouldKeepUserInput); + setMoneyRequestAmount(transactionID, amountInSmallestCurrencyUnits, currency || CONST.CURRENCY.USD, shouldKeepUserInput); // Initially when we're creating money request, we do not know the participant and hence if the request is with workspace with tax tracking enabled // So, we reset the taxAmount here and calculate it in the hook in MoneyRequestConfirmationList component - IOU.setMoneyRequestTaxAmount(transactionID, null); + setMoneyRequestTaxAmount(transactionID, null); if (backTo) { Navigation.goBack(backTo); @@ -169,27 +169,27 @@ function IOURequestStepAmount({ // In this case, the participants can be automatically assigned from the report and the user can skip the participants step and go straight // to the confirm step. // If the user is started this flow using the Create expense option (combined submit/track flow), they should be redirected to the participants page. - if (report?.reportID && !ReportUtils.isArchivedReport(reportNameValuePairs) && iouType !== CONST.IOU.TYPE.CREATE) { - const selectedParticipants = IOU.setMoneyRequestParticipantsFromReport(transactionID, report); + if (report?.reportID && !isArchivedReport(reportNameValuePairs) && iouType !== CONST.IOU.TYPE.CREATE) { + const selectedParticipants = setMoneyRequestParticipantsFromReport(transactionID, report); const participants = selectedParticipants.map((participant) => { const participantAccountID = participant?.accountID ?? CONST.DEFAULT_NUMBER_ID; - return participantAccountID ? OptionsListUtils.getParticipantsOption(participant, personalDetails) : OptionsListUtils.getReportOption(participant); + return participantAccountID ? getParticipantsOption(participant, personalDetails) : getReportOption(participant); }); - const backendAmount = CurrencyUtils.convertToBackendAmount(Number.parseFloat(amount)); + const backendAmount = convertToBackendAmount(Number.parseFloat(amount)); if (shouldSkipConfirmation) { if (iouType === CONST.IOU.TYPE.PAY || iouType === CONST.IOU.TYPE.SEND) { if (paymentMethod && paymentMethod === CONST.IOU.PAYMENT_TYPE.EXPENSIFY) { - IOU.sendMoneyWithWallet(report, backendAmount, currency, '', currentUserPersonalDetails.accountID, participants.at(0) ?? {}); + sendMoneyWithWallet(report, backendAmount, currency, '', currentUserPersonalDetails.accountID, participants.at(0) ?? {}); return; } - IOU.sendMoneyElsewhere(report, backendAmount, currency, '', currentUserPersonalDetails.accountID, participants.at(0) ?? {}); + sendMoneyElsewhere(report, backendAmount, currency, '', currentUserPersonalDetails.accountID, participants.at(0) ?? {}); return; } if (iouType === CONST.IOU.TYPE.SUBMIT || iouType === CONST.IOU.TYPE.REQUEST) { playSound(SOUNDS.DONE); - IOU.requestMoney({ + requestMoney({ report, participantParams: { participant: participants.at(0) ?? {}, @@ -208,7 +208,7 @@ function IOURequestStepAmount({ } if (iouType === CONST.IOU.TYPE.TRACK) { playSound(SOUNDS.DONE); - IOU.trackExpense( + trackExpense( report, backendAmount, currency ?? 'USD', @@ -223,10 +223,10 @@ function IOURequestStepAmount({ return; } } - IOU.setMoneyRequestParticipantsFromReport(transactionID, report); + setMoneyRequestParticipantsFromReport(transactionID, report); if (isSplitBill && !report.isOwnPolicyExpenseChat && report.participants) { const participantAccountIDs = Object.keys(report.participants).map((accountID) => Number(accountID)); - IOU.setSplitShares(transaction, amountInSmallestCurrencyUnits, currency || CONST.CURRENCY.USD, participantAccountIDs); + setSplitShares(transaction, amountInSmallestCurrencyUnits, currency || CONST.CURRENCY.USD, participantAccountIDs); } navigateToConfirmationPage(); return; @@ -238,11 +238,11 @@ function IOURequestStepAmount({ }; const saveAmountAndCurrency = ({amount, paymentMethod}: AmountParams) => { - const newAmount = CurrencyUtils.convertToBackendAmount(Number.parseFloat(amount)); + const newAmount = convertToBackendAmount(Number.parseFloat(amount)); // Edits to the amount from the splits page should reset the split shares. if (transaction?.splitShares) { - IOU.resetSplitShares(transaction, newAmount, currency); + resetSplitShares(transaction, newAmount, currency); } if (!isEditing) { @@ -251,26 +251,26 @@ function IOURequestStepAmount({ } // If the value hasn't changed, don't request to save changes on the server and just close the modal - const transactionCurrency = TransactionUtils.getCurrency(currentTransaction); - if (newAmount === TransactionUtils.getAmount(currentTransaction) && currency === transactionCurrency) { + const transactionCurrency = getCurrency(currentTransaction); + if (newAmount === getAmount(currentTransaction) && currency === transactionCurrency) { navigateBack(); return; } // If currency has changed, then we get the default tax rate based on currency, otherwise we use the current tax rate selected in transaction, if we have it. - const transactionTaxCode = ReportUtils.getTransactionDetails(currentTransaction)?.taxCode; - const defaultTaxCode = TransactionUtils.getDefaultTaxCode(policy, currentTransaction, currency) ?? ''; + const transactionTaxCode = getTransactionDetails(currentTransaction)?.taxCode; + const defaultTaxCode = getDefaultTaxCode(policy, currentTransaction, currency) ?? ''; const taxCode = (currency !== transactionCurrency ? defaultTaxCode : transactionTaxCode) ?? defaultTaxCode; - const taxPercentage = TransactionUtils.getTaxValue(policy, currentTransaction, taxCode) ?? ''; - const taxAmount = CurrencyUtils.convertToBackendAmount(TransactionUtils.calculateTaxAmount(taxPercentage, newAmount, currency ?? CONST.CURRENCY.USD)); + const taxPercentage = getTaxValue(policy, currentTransaction, taxCode) ?? ''; + const taxAmount = convertToBackendAmount(calculateTaxAmount(taxPercentage, newAmount, currency ?? CONST.CURRENCY.USD)); if (isSplitBill) { - IOU.setDraftSplitTransaction(transactionID, {amount: newAmount, currency, taxCode, taxAmount}); + setDraftSplitTransaction(transactionID, {amount: newAmount, currency, taxCode, taxAmount}); navigateBack(); return; } - IOU.updateMoneyRequestAmountAndCurrency({transactionID, transactionThreadReportID: reportID, currency, amount: newAmount, taxAmount, policy, taxCode}); + updateMoneyRequestAmountAndCurrency({transactionID, transactionThreadReportID: reportID, currency, amount: newAmount, taxAmount, policy, taxCode}); navigateBack(); }; @@ -289,7 +289,7 @@ function IOURequestStepAmount({ skipConfirmation={shouldSkipConfirmation ?? false} iouType={iouType} policyID={policy?.id} - bankAccountRoute={ReportUtils.getBankAccountRoute(report)} + bankAccountRoute={getBankAccountRoute(report)} ref={(e) => (textInput.current = e)} shouldKeepUserInput={transaction?.shouldShowOriginalAmount} onCurrencyButtonPress={navigateToCurrencySelectionPage} From 0bedde6874a33cb3a6c6f860c3c68e0a7bd9e316 Mon Sep 17 00:00:00 2001 From: Srikar Parsi Date: Thu, 23 Jan 2025 22:20:14 -0500 Subject: [PATCH 5/7] fix errors --- .../LHNOptionsList/LHNOptionsList.tsx | 12 ++++----- .../iou/request/step/IOURequestStepAmount.tsx | 25 +++++++++++++------ .../request/step/IOURequestStepScan/index.tsx | 4 +-- 3 files changed, 25 insertions(+), 16 deletions(-) diff --git a/src/components/LHNOptionsList/LHNOptionsList.tsx b/src/components/LHNOptionsList/LHNOptionsList.tsx index 5ec011d68382..8cb852fa8ac6 100644 --- a/src/components/LHNOptionsList/LHNOptionsList.tsx +++ b/src/components/LHNOptionsList/LHNOptionsList.tsx @@ -118,11 +118,11 @@ function LHNOptionsList({style, contentContainerStyles, data, onSelectRow, optio const renderItem = useCallback( ({item: reportID}: RenderItemProps): ReactElement => { const itemFullReport = reports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]; - const itemParentReport = reports?.[`${ONYXKEYS.COLLECTION.REPORT}${itemFullReport?.parentReportID ?? '-1'}`]; + const itemParentReport = reports?.[`${ONYXKEYS.COLLECTION.REPORT}${itemFullReport?.parentReportID ?? CONST.DEFAULT_NUMBER_ID}`]; const itemReportNameValuePairs = reportNameValuePairs?.[`${ONYXKEYS.COLLECTION.REPORT_NAME_VALUE_PAIRS}${reportID}`]; const itemReportActions = reportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${reportID}`]; const itemParentReportActions = reportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${itemFullReport?.parentReportID}`]; - const itemParentReportAction = itemParentReportActions?.[itemFullReport?.parentReportActionID ?? '-1']; + const itemParentReportAction = itemParentReportActions?.[itemFullReport?.parentReportActionID ?? CONST.DEFAULT_NUMBER_ID]; let invoiceReceiverPolicyID = '-1'; if (itemFullReport?.invoiceReceiver && 'policyID' in itemFullReport.invoiceReceiver) { @@ -146,11 +146,9 @@ function LHNOptionsList({style, contentContainerStyles, data, onSelectRow, optio const lastReportAction = sortedReportActions.at(0); // Get the transaction for the last report action - let lastReportActionTransactionID = ''; - - if (isMoneyRequestAction(lastReportAction)) { - lastReportActionTransactionID = getOriginalMessage(lastReportAction)?.IOUTransactionID ?? '-1'; - } + const lastReportActionTransactionID = isMoneyRequestAction(lastReportAction) + ? getOriginalMessage(lastReportAction)?.IOUTransactionID ?? CONST.DEFAULT_NUMBER_ID + : CONST.DEFAULT_NUMBER_ID; const lastReportActionTransaction = transactions?.[`${ONYXKEYS.COLLECTION.TRANSACTION}${lastReportActionTransactionID}`]; // SidebarUtils.getOptionData in OptionRowLHNData does not get re-evaluated when the linked task report changes, so we have the lastMessageTextFromReport evaluation logic here diff --git a/src/pages/iou/request/step/IOURequestStepAmount.tsx b/src/pages/iou/request/step/IOURequestStepAmount.tsx index 489f8abdcd5a..32a75380f88a 100644 --- a/src/pages/iou/request/step/IOURequestStepAmount.tsx +++ b/src/pages/iou/request/step/IOURequestStepAmount.tsx @@ -6,16 +6,27 @@ import type {BaseTextInputRef} from '@components/TextInput/BaseTextInput/types'; import withCurrentUserPersonalDetails from '@components/withCurrentUserPersonalDetails'; import type {WithCurrentUserPersonalDetailsProps} from '@components/withCurrentUserPersonalDetails'; import useLocalize from '@hooks/useLocalize'; -import { createDraftTransaction, removeDraftTransaction } from '@libs/actions/TransactionEdit'; -import { convertToBackendAmount, isValidCurrencyCode } from '@libs/CurrencyUtils'; +import {createDraftTransaction, removeDraftTransaction} from '@libs/actions/TransactionEdit'; +import {convertToBackendAmount, isValidCurrencyCode} from '@libs/CurrencyUtils'; import Navigation from '@libs/Navigation/Navigation'; -import { getParticipantsOption, getReportOption } from '@libs/OptionsListUtils'; -import { getBankAccountRoute, getTransactionDetails, isArchivedReport, isPolicyExpenseChat } from '@libs/ReportUtils'; +import {getParticipantsOption, getReportOption} from '@libs/OptionsListUtils'; +import {getBankAccountRoute, getTransactionDetails, isArchivedReport, isPolicyExpenseChat} from '@libs/ReportUtils'; import playSound, {SOUNDS} from '@libs/Sound'; -import { calculateTaxAmount, getAmount, getCurrency, getDefaultTaxCode, getTaxValue } from '@libs/TransactionUtils'; -import {getRequestType} from '@libs/TransactionUtils'; +import {calculateTaxAmount, getAmount, getCurrency, getDefaultTaxCode, getRequestType, getTaxValue} from '@libs/TransactionUtils'; import MoneyRequestAmountForm from '@pages/iou/MoneyRequestAmountForm'; -import { requestMoney, resetSplitShares, sendMoneyElsewhere, sendMoneyWithWallet, setDraftSplitTransaction, setMoneyRequestAmount, setMoneyRequestParticipantsFromReport, setMoneyRequestTaxAmount, setSplitShares, trackExpense, updateMoneyRequestAmountAndCurrency } from '@userActions/IOU'; +import { + requestMoney, + resetSplitShares, + sendMoneyElsewhere, + sendMoneyWithWallet, + setDraftSplitTransaction, + setMoneyRequestAmount, + setMoneyRequestParticipantsFromReport, + setMoneyRequestTaxAmount, + setSplitShares, + trackExpense, + updateMoneyRequestAmountAndCurrency, +} from '@userActions/IOU'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; diff --git a/src/pages/iou/request/step/IOURequestStepScan/index.tsx b/src/pages/iou/request/step/IOURequestStepScan/index.tsx index ece844eca301..e31b13a4091e 100644 --- a/src/pages/iou/request/step/IOURequestStepScan/index.tsx +++ b/src/pages/iou/request/step/IOURequestStepScan/index.tsx @@ -35,7 +35,7 @@ import {shouldStartLocationPermissionFlow} from '@libs/IOUUtils'; import Log from '@libs/Log'; import Navigation from '@libs/Navigation/Navigation'; import {getParticipantsOption, getReportOption} from '@libs/OptionsListUtils'; -import * as ReportUtils from '@libs/ReportUtils'; +import {isArchivedReport, isPolicyExpenseChat} from '@libs/ReportUtils'; import playSound, {SOUNDS} from '@libs/Sound'; import {getDefaultTaxCode} from '@libs/TransactionUtils'; import ReceiptDropUI from '@pages/iou/ReceiptDropUI'; @@ -115,7 +115,7 @@ function IOURequestStepScan({ return false; } - return !ReportUtils.isArchivedReport(reportNameValuePairs) && !(ReportUtils.isPolicyExpenseChat(report) && ((policy?.requiresCategory ?? false) || (policy?.requiresTag ?? false))); + return !isArchivedReport(reportNameValuePairs) && !(isPolicyExpenseChat(report) && ((policy?.requiresCategory ?? false) || (policy?.requiresTag ?? false))); }, [report, skipConfirmation, policy, reportNameValuePairs]); /** From e1c542fce08a320d60fbdbd00774466197a16dc6 Mon Sep 17 00:00:00 2001 From: Srikar Parsi Date: Thu, 23 Jan 2025 22:30:01 -0500 Subject: [PATCH 6/7] hopefully last number change --- src/components/LHNOptionsList/LHNOptionsList.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/components/LHNOptionsList/LHNOptionsList.tsx b/src/components/LHNOptionsList/LHNOptionsList.tsx index 8cb852fa8ac6..64f3204c52ac 100644 --- a/src/components/LHNOptionsList/LHNOptionsList.tsx +++ b/src/components/LHNOptionsList/LHNOptionsList.tsx @@ -137,7 +137,9 @@ function LHNOptionsList({style, contentContainerStyles, data, onSelectRow, optio const itemIouReportReportActions = iouReportIDOfLastAction ? reportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${iouReportIDOfLastAction}`] : undefined; const itemPolicy = policy?.[`${ONYXKEYS.COLLECTION.POLICY}${itemFullReport?.policyID}`]; - const transactionID = isMoneyRequestAction(itemParentReportAction) ? getOriginalMessage(itemParentReportAction)?.IOUTransactionID ?? '-1' : '-1'; + const transactionID = isMoneyRequestAction(itemParentReportAction) + ? getOriginalMessage(itemParentReportAction)?.IOUTransactionID ?? CONST.DEFAULT_NUMBER_ID + : CONST.DEFAULT_NUMBER_ID; const itemTransaction = transactions?.[`${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`]; const hasDraftComment = isValidDraftComment(draftComments?.[`${ONYXKEYS.COLLECTION.REPORT_DRAFT_COMMENT}${reportID}`]); From c8df75fb2cee8a65a505ac458f5c6ac10f981c90 Mon Sep 17 00:00:00 2001 From: Srikar Parsi Date: Thu, 23 Jan 2025 22:53:55 -0500 Subject: [PATCH 7/7] use undefined instead of number --- src/components/LHNOptionsList/LHNOptionsList.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/LHNOptionsList/LHNOptionsList.tsx b/src/components/LHNOptionsList/LHNOptionsList.tsx index 64f3204c52ac..894f5ddc2477 100644 --- a/src/components/LHNOptionsList/LHNOptionsList.tsx +++ b/src/components/LHNOptionsList/LHNOptionsList.tsx @@ -118,11 +118,11 @@ function LHNOptionsList({style, contentContainerStyles, data, onSelectRow, optio const renderItem = useCallback( ({item: reportID}: RenderItemProps): ReactElement => { const itemFullReport = reports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]; - const itemParentReport = reports?.[`${ONYXKEYS.COLLECTION.REPORT}${itemFullReport?.parentReportID ?? CONST.DEFAULT_NUMBER_ID}`]; + const itemParentReport = reports?.[`${ONYXKEYS.COLLECTION.REPORT}${itemFullReport?.parentReportID}`]; const itemReportNameValuePairs = reportNameValuePairs?.[`${ONYXKEYS.COLLECTION.REPORT_NAME_VALUE_PAIRS}${reportID}`]; const itemReportActions = reportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${reportID}`]; const itemParentReportActions = reportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${itemFullReport?.parentReportID}`]; - const itemParentReportAction = itemParentReportActions?.[itemFullReport?.parentReportActionID ?? CONST.DEFAULT_NUMBER_ID]; + const itemParentReportAction = itemFullReport?.parentReportActionID ? itemParentReportActions?.[itemFullReport?.parentReportActionID] : undefined; let invoiceReceiverPolicyID = '-1'; if (itemFullReport?.invoiceReceiver && 'policyID' in itemFullReport.invoiceReceiver) {