From 812b13423a9305be38a53ceef9b0d80e8085afcb Mon Sep 17 00:00:00 2001 From: FitseTLT Date: Tue, 26 Aug 2025 20:49:34 +0300 Subject: [PATCH 1/3] hide violations for settled reports --- .../ReportActionItem/MoneyRequestView.tsx | 18 +++++++++++------- .../TransactionItemRowRBRWithOnyx.tsx | 10 +++++++++- src/components/TransactionItemRow/index.tsx | 7 ++++++- 3 files changed, 26 insertions(+), 9 deletions(-) diff --git a/src/components/ReportActionItem/MoneyRequestView.tsx b/src/components/ReportActionItem/MoneyRequestView.tsx index fcb9d8148467..c90da05798a8 100644 --- a/src/components/ReportActionItem/MoneyRequestView.tsx +++ b/src/components/ReportActionItem/MoneyRequestView.tsx @@ -387,6 +387,10 @@ function MoneyRequestView({ const getErrorForField = useCallback( (field: ViolationField, data?: OnyxTypes.TransactionViolation['data'], policyHasDependentTags = false, tagValue?: string) => { + if (readonly || isSettled) { + return ''; + } + // Checks applied when creating a new expense // NOTE: receipt field can return multiple violations, so we need to handle it separately const fieldChecks: Partial> = { @@ -406,10 +410,6 @@ function MoneyRequestView({ const {isError, translationPath} = fieldChecks[field] ?? {}; - if (readonly) { - return ''; - } - // Return form errors if there are any if (hasErrors && isError && translationPath) { return translate(translationPath); @@ -497,8 +497,12 @@ function MoneyRequestView({ const isReceiptAllowed = !isPaidReport && !isInvoice; const shouldShowReceiptEmptyState = isReceiptAllowed && !hasReceipt; const [receiptImageViolations, receiptViolations] = useMemo(() => { - const imageViolations = []; - const allViolations = []; + const imageViolations: string[] = []; + const allViolations: string[] = []; + + if (isSettled) { + return [imageViolations, allViolations]; + } for (const violation of transactionViolations ?? []) { const isReceiptFieldViolation = receiptFieldViolationNames.includes(violation.name); @@ -512,7 +516,7 @@ function MoneyRequestView({ } } return [imageViolations, allViolations]; - }, [transactionViolations, translate, canEdit]); + }, [transactionViolations, translate, canEdit, isSettled]); const receiptRequiredViolation = transactionViolations?.some((violation) => violation.name === CONST.VIOLATIONS.RECEIPT_REQUIRED); const customRulesViolation = transactionViolations?.some((violation) => violation.name === CONST.VIOLATIONS.CUSTOM_RULES); diff --git a/src/components/TransactionItemRow/TransactionItemRowRBRWithOnyx.tsx b/src/components/TransactionItemRow/TransactionItemRowRBRWithOnyx.tsx index 383d9b440d6d..45fdb6509207 100644 --- a/src/components/TransactionItemRow/TransactionItemRowRBRWithOnyx.tsx +++ b/src/components/TransactionItemRow/TransactionItemRowRBRWithOnyx.tsx @@ -10,6 +10,7 @@ import useTheme from '@hooks/useTheme'; import useThemeStyles from '@hooks/useThemeStyles'; import useTransactionViolations from '@hooks/useTransactionViolations'; import {getIOUActionForTransactionID} from '@libs/ReportActionsUtils'; +import {isSettled} from '@libs/ReportUtils'; import ViolationsUtils from '@libs/Violations/ViolationsUtils'; import variables from '@styles/variables'; import ONYXKEYS from '@src/ONYXKEYS'; @@ -44,7 +45,14 @@ function TransactionItemRowRBRWithOnyx({transaction, report, containerStyles, mi canBeMissing: true, }); - const RBRMessages = ViolationsUtils.getRBRMessages(transaction, transactionViolations, translate, missingFieldError, Object.values(transactionThreadActions ?? {}), policyTags); + const RBRMessages = ViolationsUtils.getRBRMessages( + transaction, + isSettled(report) ? [] : transactionViolations, + translate, + missingFieldError, + Object.values(transactionThreadActions ?? {}), + policyTags, + ); return ( RBRMessages.length > 0 && ( diff --git a/src/components/TransactionItemRow/index.tsx b/src/components/TransactionItemRow/index.tsx index 059fba133801..05f8036230d7 100644 --- a/src/components/TransactionItemRow/index.tsx +++ b/src/components/TransactionItemRow/index.tsx @@ -15,6 +15,7 @@ import useStyleUtils from '@hooks/useStyleUtils'; import useThemeStyles from '@hooks/useThemeStyles'; import {isCategoryMissing} from '@libs/CategoryUtils'; import Parser from '@libs/Parser'; +import {isSettled} from '@libs/ReportUtils'; import StringUtils from '@libs/StringUtils'; import { getDescription, @@ -163,6 +164,10 @@ function TransactionItemRow({ const merchantOrDescriptionName = useMemo(() => getMerchantNameWithFallback(transactionItem, translate, shouldUseNarrowLayout), [shouldUseNarrowLayout, transactionItem, translate]); const missingFieldError = useMemo(() => { + if (isSettled(report)) { + return ''; + } + const isCustomUnitOutOfPolicy = isUnreportedAndHasInvalidDistanceRateTransaction(transactionItem); const hasFieldErrors = hasMissingSmartscanFields(transactionItem) || isCustomUnitOutOfPolicy; if (hasFieldErrors) { @@ -181,7 +186,7 @@ function TransactionItemRow({ } return error; } - }, [transactionItem, translate]); + }, [transactionItem, translate, report]); const columnComponent: ColumnComponents = useMemo( () => ({ From b533282f0c6bba8ddf7e163edbf196f8628f386a Mon Sep 17 00:00:00 2001 From: FitseTLT Date: Tue, 2 Sep 2025 22:08:48 +0300 Subject: [PATCH 2/3] add isSettled prop --- .../ReportActionItem/MoneyRequestReceiptView.tsx | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/components/ReportActionItem/MoneyRequestReceiptView.tsx b/src/components/ReportActionItem/MoneyRequestReceiptView.tsx index c7d0425db61d..6db6f804af11 100644 --- a/src/components/ReportActionItem/MoneyRequestReceiptView.tsx +++ b/src/components/ReportActionItem/MoneyRequestReceiptView.tsx @@ -64,6 +64,9 @@ type MoneyRequestReceiptViewProps = { /** Merge transaction ID to show in merge transaction flow */ mergeTransactionID?: string; + + /** Whether the iou report is settled */ + isSettled: boolean; }; const receiptImageViolationNames: OnyxTypes.ViolationName[] = [ @@ -77,7 +80,7 @@ const receiptImageViolationNames: OnyxTypes.ViolationName[] = [ const receiptFieldViolationNames: OnyxTypes.ViolationName[] = [CONST.VIOLATIONS.MODIFIED_AMOUNT, CONST.VIOLATIONS.MODIFIED_DATE]; -function MoneyRequestReceiptView({allReports, report, readonly = false, updatedTransaction, isFromReviewDuplicates = false, mergeTransactionID}: MoneyRequestReceiptViewProps) { +function MoneyRequestReceiptView({allReports, report, readonly = false, updatedTransaction, isFromReviewDuplicates = false, mergeTransactionID, isSettled}: MoneyRequestReceiptViewProps) { const styles = useThemeStyles(); const {translate} = useLocalize(); const {shouldUseNarrowLayout} = useResponsiveLayout(); @@ -142,8 +145,12 @@ function MoneyRequestReceiptView({allReports, report, readonly = false, updatedT const isReceiptAllowed = !isPaidReport && !isInvoice; const shouldShowReceiptEmptyState = isReceiptAllowed && !hasReceipt; const [receiptImageViolations, receiptViolations] = useMemo(() => { - const imageViolations = []; - const allViolations = []; + const imageViolations: string[] = []; + const allViolations: string[] = []; + + if (isSettled) { + return [imageViolations, allViolations]; + } for (const violation of transactionViolations ?? []) { const isReceiptFieldViolation = receiptFieldViolationNames.includes(violation.name); @@ -157,7 +164,7 @@ function MoneyRequestReceiptView({allReports, report, readonly = false, updatedT } } return [imageViolations, allViolations]; - }, [transactionViolations, translate, canEdit]); + }, [transactionViolations, translate, canEdit, isSettled]); const receiptRequiredViolation = transactionViolations?.some((violation) => violation.name === CONST.VIOLATIONS.RECEIPT_REQUIRED); const customRulesViolation = transactionViolations?.some((violation) => violation.name === CONST.VIOLATIONS.CUSTOM_RULES); From 8457da816a56caf7e39b68c6d25018507473f18f Mon Sep 17 00:00:00 2001 From: FitseTLT Date: Fri, 26 Sep 2025 01:28:26 +0300 Subject: [PATCH 3/3] revert unnecessary change --- .../ReportActionItem/MoneyRequestReceiptView.tsx | 15 ++++----------- .../ReportActionItem/MoneyRequestView.tsx | 9 ++++----- 2 files changed, 8 insertions(+), 16 deletions(-) diff --git a/src/components/ReportActionItem/MoneyRequestReceiptView.tsx b/src/components/ReportActionItem/MoneyRequestReceiptView.tsx index 6db6f804af11..c7d0425db61d 100644 --- a/src/components/ReportActionItem/MoneyRequestReceiptView.tsx +++ b/src/components/ReportActionItem/MoneyRequestReceiptView.tsx @@ -64,9 +64,6 @@ type MoneyRequestReceiptViewProps = { /** Merge transaction ID to show in merge transaction flow */ mergeTransactionID?: string; - - /** Whether the iou report is settled */ - isSettled: boolean; }; const receiptImageViolationNames: OnyxTypes.ViolationName[] = [ @@ -80,7 +77,7 @@ const receiptImageViolationNames: OnyxTypes.ViolationName[] = [ const receiptFieldViolationNames: OnyxTypes.ViolationName[] = [CONST.VIOLATIONS.MODIFIED_AMOUNT, CONST.VIOLATIONS.MODIFIED_DATE]; -function MoneyRequestReceiptView({allReports, report, readonly = false, updatedTransaction, isFromReviewDuplicates = false, mergeTransactionID, isSettled}: MoneyRequestReceiptViewProps) { +function MoneyRequestReceiptView({allReports, report, readonly = false, updatedTransaction, isFromReviewDuplicates = false, mergeTransactionID}: MoneyRequestReceiptViewProps) { const styles = useThemeStyles(); const {translate} = useLocalize(); const {shouldUseNarrowLayout} = useResponsiveLayout(); @@ -145,12 +142,8 @@ function MoneyRequestReceiptView({allReports, report, readonly = false, updatedT const isReceiptAllowed = !isPaidReport && !isInvoice; const shouldShowReceiptEmptyState = isReceiptAllowed && !hasReceipt; const [receiptImageViolations, receiptViolations] = useMemo(() => { - const imageViolations: string[] = []; - const allViolations: string[] = []; - - if (isSettled) { - return [imageViolations, allViolations]; - } + const imageViolations = []; + const allViolations = []; for (const violation of transactionViolations ?? []) { const isReceiptFieldViolation = receiptFieldViolationNames.includes(violation.name); @@ -164,7 +157,7 @@ function MoneyRequestReceiptView({allReports, report, readonly = false, updatedT } } return [imageViolations, allViolations]; - }, [transactionViolations, translate, canEdit, isSettled]); + }, [transactionViolations, translate, canEdit]); const receiptRequiredViolation = transactionViolations?.some((violation) => violation.name === CONST.VIOLATIONS.RECEIPT_REQUIRED); const customRulesViolation = transactionViolations?.some((violation) => violation.name === CONST.VIOLATIONS.CUSTOM_RULES); diff --git a/src/components/ReportActionItem/MoneyRequestView.tsx b/src/components/ReportActionItem/MoneyRequestView.tsx index 7ed834756e1e..24639427b7aa 100644 --- a/src/components/ReportActionItem/MoneyRequestView.tsx +++ b/src/components/ReportActionItem/MoneyRequestView.tsx @@ -372,10 +372,6 @@ function MoneyRequestView({ const getErrorForField = useCallback( (field: ViolationField, data?: OnyxTypes.TransactionViolation['data'], policyHasDependentTags = false, tagValue?: string) => { - if (readonly || isSettled) { - return ''; - } - // Checks applied when creating a new expense // NOTE: receipt field can return multiple violations, so we need to handle it separately const fieldChecks: Partial> = { @@ -395,6 +391,10 @@ function MoneyRequestView({ const {isError, translationPath} = fieldChecks[field] ?? {}; + if (readonly) { + return ''; + } + // Return form errors if there are any if (hasErrors && isError && translationPath) { return translate(translationPath); @@ -580,7 +580,6 @@ function MoneyRequestView({ updatedTransaction={updatedTransaction} isFromReviewDuplicates={isFromReviewDuplicates} mergeTransactionID={mergeTransactionID} - isSettled={isSettled} /> {isCustomUnitOutOfPolicy && isPerDiemRequest && (