From 812b13423a9305be38a53ceef9b0d80e8085afcb Mon Sep 17 00:00:00 2001
From: FitseTLT <engfitsum@gmail.com>
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<Record<ViolationField, {isError: boolean; translationPath: TranslationPaths}>> = {
@@ -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 <engfitsum@gmail.com>
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 <engfitsum@gmail.com>
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<Record<ViolationField, {isError: boolean; translationPath: TranslationPaths}>> = {
@@ -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 && (
                     <View style={[styles.flexRow, styles.alignItemsCenter, styles.gap1, styles.mh4, styles.mb2]}>
