From ca8216e0249545c495ded6fb7b47c583f6293b5f Mon Sep 17 00:00:00 2001 From: Nicolay Arefyeu Date: Wed, 19 Mar 2025 16:13:35 +0200 Subject: [PATCH 1/7] Show submit button if not all transactions has violation --- src/libs/TransactionUtils/index.ts | 23 +++++ src/libs/actions/IOU.ts | 5 +- tests/unit/IOUUtilsTest.ts | 155 +++++++++++++++++++++++++++++ 3 files changed, 181 insertions(+), 2 deletions(-) diff --git a/src/libs/TransactionUtils/index.ts b/src/libs/TransactionUtils/index.ts index 82987ce754bd..f3c1a9d1cc00 100644 --- a/src/libs/TransactionUtils/index.ts +++ b/src/libs/TransactionUtils/index.ts @@ -803,6 +803,17 @@ function hasPendingRTERViolation(transactionViolations?: TransactionViolations | ); } +/** + * Check if there is rter violation in all transactionViolations with given transactionIDs. + */ +function hasRTERViolation(transactionViolations?: TransactionViolations | null): boolean { + return !!transactionViolations?.every( + (violation: TransactionViolation) => + violation.name === CONST.VIOLATIONS.RTER && + (violation.data?.rterType === CONST.RTER_VIOLATION_TYPES.BROKEN_CARD_CONNECTION || violation.data?.rterType === CONST.RTER_VIOLATION_TYPES.BROKEN_CARD_CONNECTION_530), + ); +} + /** * Check if there is broken connection violation. */ @@ -879,6 +890,17 @@ function allHavePendingRTERViolation(transactionIds: string[], transactionViolat return transactionsWithRTERViolations.length > 0 && transactionsWithRTERViolations.every((value) => value === true); } +/** + * Check if there is rter violation in all transactionViolations with given transactionIDs. + */ +function allHaveRTERViolation(transactionIds: string[], transactionViolations: OnyxCollection | undefined): boolean { + const transactionsWithRTERViolations = transactionIds.map((transactionId) => { + const filteredTransactionViolations = getTransactionViolations(transactionId, transactionViolations); + return hasRTERViolation(filteredTransactionViolations); + }); + return transactionsWithRTERViolations.length > 0 && transactionsWithRTERViolations.every((value) => value === true); +} + /** * Check if the transaction is pending or has a pending rter violation. */ @@ -1490,6 +1512,7 @@ export { getOriginalAmount, getFormattedAttendees, getMerchant, + allHaveRTERViolation, getMerchantOrDescription, getMCCGroup, getCreated, diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index 343e25e27ba0..be92ff8b0e8c 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -147,6 +147,7 @@ import playSound, {SOUNDS} from '@libs/Sound'; import {shouldRestrictUserBillableActions} from '@libs/SubscriptionUtils'; import { allHavePendingRTERViolation, + allHaveRTERViolation, buildOptimisticTransaction, getAmount, getCategoryTaxCodeAndAmount, @@ -8405,7 +8406,7 @@ function canSubmitReport( const transactionIDList = transactions.map((transaction) => transaction.transactionID); const hasAllPendingRTERViolations = allHavePendingRTERViolation(transactionIDList, allViolations); const hasBrokenConnectionViolation = shouldShowBrokenConnectionViolationForMultipleTransactions(transactionIDList, report, policy, allViolations); - + const hasAllRTEViolations = allHaveRTERViolation(transactionIDList, allViolations); const hasOnlyPendingCardOrScanFailTransactions = transactions.length > 0 && transactions.every((t) => (isExpensifyCardTransaction(t) && isPending(t)) || (isPartialMerchant(getMerchant(t)) && isAmountMissing(t)) || isReceiptBeingScannedTransactionUtils(t)); @@ -8416,7 +8417,7 @@ function canSubmitReport( !isArchived && !hasOnlyPendingCardOrScanFailTransactions && !hasAllPendingRTERViolations && - !hasBrokenConnectionViolation && + (!hasBrokenConnectionViolation || !hasAllRTEViolations) && (report?.ownerAccountID === currentUserAccountID || isAdmin || report?.managerID === currentUserAccountID) ); } diff --git a/tests/unit/IOUUtilsTest.ts b/tests/unit/IOUUtilsTest.ts index 6eb96b57c804..ae1530528564 100644 --- a/tests/unit/IOUUtilsTest.ts +++ b/tests/unit/IOUUtilsTest.ts @@ -1,13 +1,24 @@ import Onyx from 'react-native-onyx'; +import type {OnyxCollection} from 'react-native-onyx'; +import DateUtils from '@libs/DateUtils'; +import {canSubmitReport} from '@userActions/IOU'; import CONST from '@src/CONST'; import * as IOUUtils from '@src/libs/IOUUtils'; import * as ReportUtils from '@src/libs/ReportUtils'; import * as TransactionUtils from '@src/libs/TransactionUtils'; +import {allHaveRTERViolation} from '@src/libs/TransactionUtils'; import ONYXKEYS from '@src/ONYXKEYS'; +import type {Policy, Report, Transaction, TransactionViolations} from '@src/types/onyx'; import type {TransactionCollectionDataSet} from '@src/types/onyx/Transaction'; +import createRandomPolicy from '../utils/collections/policies'; +import createRandomReport from '../utils/collections/reports'; +import createRandomTransaction from '../utils/collections/transaction'; import waitForBatchedUpdates from '../utils/waitForBatchedUpdates'; import currencyList from './currencyList.json'; +const testDate = DateUtils.getDBTime(); +const currentUserAccountID = 5; + function initCurrencyList() { Onyx.init({ keys: ONYXKEYS, @@ -171,6 +182,150 @@ describe('isValidMoneyRequestType', () => { }); }); +describe('allHaveRTERViolation', () => { + test('Return false if there is rter violation in all transactionViolations with given transactionIDs.', async () => { + const transactionIDWithViolation = 1; + const transactionIDWithoutViolation = 2; + const currentReportId = ''; + const transactionWithViolation: Transaction = { + ...createRandomTransaction(transactionIDWithViolation), + category: '', + tag: '', + created: testDate, + reportID: currentReportId, + }; + const transactionWithoutViolation: Transaction = { + ...createRandomTransaction(transactionIDWithoutViolation), + category: '', + tag: '', + created: testDate, + reportID: currentReportId, + }; + const transactionViolations = `transactionViolations_${transactionIDWithViolation}`; + const violations: OnyxCollection = { + [transactionViolations]: [ + { + type: 'warning', + name: 'rter', + data: { + tooltip: "Personal Cards: Fix your card from Account Settings. Corporate Cards: ask your Expensify admin to fix your company's card connection.", + rterType: 'brokenCardConnection', + }, + showInReview: true, + }, + ], + }; + + await Onyx.merge(`${ONYXKEYS.COLLECTION.TRANSACTION}${transactionIDWithViolation}`, transactionWithViolation); + await Onyx.merge(`${ONYXKEYS.COLLECTION.TRANSACTION}${transactionIDWithoutViolation}`, transactionWithoutViolation); + expect(allHaveRTERViolation([String(transactionIDWithoutViolation), String(transactionIDWithViolation)], violations)).toBe(false); + }); + + test('Return true if there is rter violation in all transactionViolations with given transactionIDs.', async () => { + const transactionIDWithViolation = 1; + const currentReportId = ''; + const transactionWithViolation: Transaction = { + ...createRandomTransaction(transactionIDWithViolation), + category: '', + tag: '', + created: testDate, + reportID: currentReportId, + }; + const transactionViolations = `transactionViolations_${transactionIDWithViolation}`; + const violations: OnyxCollection = { + [transactionViolations]: [ + { + type: 'warning', + name: 'rter', + data: { + tooltip: "Personal Cards: Fix your card from Account Settings. Corporate Cards: ask your Expensify admin to fix your company's card connection.", + rterType: 'brokenCardConnection', + }, + showInReview: true, + }, + ], + }; + + await Onyx.merge(`${ONYXKEYS.COLLECTION.TRANSACTION}${transactionIDWithViolation}`, transactionWithViolation); + expect(allHaveRTERViolation([String(transactionIDWithViolation)], violations)).toBe(true); + }); +}); + +describe('canSubmitReport', () => { + test('Return true if report can be submitted', async () => { + await Onyx.merge(ONYXKEYS.SESSION, {accountID: currentUserAccountID}); + const fakePolicy: Policy = { + ...createRandomPolicy(6), + ownerAccountID: currentUserAccountID, + areRulesEnabled: true, + preventSelfApproval: false, + }; + const expenseReport: Report = { + ...createRandomReport(6), + type: CONST.REPORT.TYPE.EXPENSE, + managerID: currentUserAccountID, + ownerAccountID: currentUserAccountID, + policyID: fakePolicy.id, + stateNum: CONST.REPORT.STATE_NUM.OPEN, + statusNum: CONST.REPORT.STATUS_NUM.OPEN, + }; + + const transactionIDWithViolation = 1; + const transactionIDWithoutViolation = 2; + const transactionWithViolation: Transaction = { + ...createRandomTransaction(transactionIDWithViolation), + category: '', + tag: '', + created: testDate, + reportID: expenseReport?.reportID, + }; + const transactionWithoutViolation: Transaction = { + ...createRandomTransaction(transactionIDWithoutViolation), + category: '', + tag: '', + created: testDate, + reportID: expenseReport?.reportID, + }; + const transactionViolations = `transactionViolations_${transactionIDWithViolation}`; + const violations: OnyxCollection = { + [transactionViolations]: [ + { + type: 'warning', + name: 'rter', + data: { + tooltip: "Personal Cards: Fix your card from Account Settings. Corporate Cards: ask your Expensify admin to fix your company's card connection.", + rterType: 'brokenCardConnection', + }, + showInReview: true, + }, + ], + }; + + await Onyx.merge(`${ONYXKEYS.COLLECTION.TRANSACTION}${transactionIDWithViolation}`, transactionWithViolation); + await Onyx.merge(`${ONYXKEYS.COLLECTION.TRANSACTION}${transactionIDWithoutViolation}`, transactionWithoutViolation); + expect(canSubmitReport(expenseReport, fakePolicy, [transactionWithViolation, transactionWithoutViolation], violations)).toBe(true); + }); + + test('Return false if report can not be submitted', async () => { + await Onyx.merge(ONYXKEYS.SESSION, {accountID: currentUserAccountID}); + const fakePolicy: Policy = { + ...createRandomPolicy(6), + ownerAccountID: currentUserAccountID, + areRulesEnabled: true, + preventSelfApproval: false, + }; + const expenseReport: Report = { + ...createRandomReport(6), + type: CONST.REPORT.TYPE.EXPENSE, + managerID: currentUserAccountID, + ownerAccountID: currentUserAccountID, + policyID: fakePolicy.id, + }; + + expect(canSubmitReport(expenseReport, fakePolicy, [], undefined)).toBe(false); + }); +}); + describe('Check valid amount for IOU/Expense request', () => { test('IOU amount should be positive', () => { const iouReport = ReportUtils.buildOptimisticIOUReport(1, 2, 100, '1', 'USD'); From d0730e0ec4498c4e20445d9ab1889920805d5587 Mon Sep 17 00:00:00 2001 From: Nicolay Arefyeu Date: Fri, 21 Mar 2025 10:59:08 +0200 Subject: [PATCH 2/7] clean up --- src/libs/TransactionUtils/index.ts | 6 +----- src/libs/actions/IOU.ts | 4 +--- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/src/libs/TransactionUtils/index.ts b/src/libs/TransactionUtils/index.ts index f3c1a9d1cc00..1333e1041a82 100644 --- a/src/libs/TransactionUtils/index.ts +++ b/src/libs/TransactionUtils/index.ts @@ -807,11 +807,7 @@ function hasPendingRTERViolation(transactionViolations?: TransactionViolations | * Check if there is rter violation in all transactionViolations with given transactionIDs. */ function hasRTERViolation(transactionViolations?: TransactionViolations | null): boolean { - return !!transactionViolations?.every( - (violation: TransactionViolation) => - violation.name === CONST.VIOLATIONS.RTER && - (violation.data?.rterType === CONST.RTER_VIOLATION_TYPES.BROKEN_CARD_CONNECTION || violation.data?.rterType === CONST.RTER_VIOLATION_TYPES.BROKEN_CARD_CONNECTION_530), - ); + return !!transactionViolations?.every((violation: TransactionViolation) => isBrokenConnectionViolation(violation)); } /** diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index be92ff8b0e8c..c5753ddd4355 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -169,7 +169,6 @@ import { isReceiptBeingScanned as isReceiptBeingScannedTransactionUtils, isScanRequest as isScanRequestTransactionUtils, removeSettledAndApprovedTransactions, - shouldShowBrokenConnectionViolationForMultipleTransactions, } from '@libs/TransactionUtils'; import ViolationsUtils from '@libs/Violations/ViolationsUtils'; import type {IOUAction, IOUType} from '@src/CONST'; @@ -8405,7 +8404,6 @@ function canSubmitReport( const isAdmin = policy?.role === CONST.POLICY.ROLE.ADMIN; const transactionIDList = transactions.map((transaction) => transaction.transactionID); const hasAllPendingRTERViolations = allHavePendingRTERViolation(transactionIDList, allViolations); - const hasBrokenConnectionViolation = shouldShowBrokenConnectionViolationForMultipleTransactions(transactionIDList, report, policy, allViolations); const hasAllRTEViolations = allHaveRTERViolation(transactionIDList, allViolations); const hasOnlyPendingCardOrScanFailTransactions = transactions.length > 0 && @@ -8417,7 +8415,7 @@ function canSubmitReport( !isArchived && !hasOnlyPendingCardOrScanFailTransactions && !hasAllPendingRTERViolations && - (!hasBrokenConnectionViolation || !hasAllRTEViolations) && + !hasAllRTEViolations && (report?.ownerAccountID === currentUserAccountID || isAdmin || report?.managerID === currentUserAccountID) ); } From 4eb4af3c0782a824362a815abc51b4fa0003def9 Mon Sep 17 00:00:00 2001 From: Nicolay Arefyeu Date: Fri, 21 Mar 2025 11:17:13 +0200 Subject: [PATCH 3/7] clean up --- src/libs/TransactionUtils/index.ts | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/src/libs/TransactionUtils/index.ts b/src/libs/TransactionUtils/index.ts index 1333e1041a82..f3e40ee38122 100644 --- a/src/libs/TransactionUtils/index.ts +++ b/src/libs/TransactionUtils/index.ts @@ -803,13 +803,6 @@ function hasPendingRTERViolation(transactionViolations?: TransactionViolations | ); } -/** - * Check if there is rter violation in all transactionViolations with given transactionIDs. - */ -function hasRTERViolation(transactionViolations?: TransactionViolations | null): boolean { - return !!transactionViolations?.every((violation: TransactionViolation) => isBrokenConnectionViolation(violation)); -} - /** * Check if there is broken connection violation. */ @@ -891,8 +884,7 @@ function allHavePendingRTERViolation(transactionIds: string[], transactionViolat */ function allHaveRTERViolation(transactionIds: string[], transactionViolations: OnyxCollection | undefined): boolean { const transactionsWithRTERViolations = transactionIds.map((transactionId) => { - const filteredTransactionViolations = getTransactionViolations(transactionId, transactionViolations); - return hasRTERViolation(filteredTransactionViolations); + return hasBrokenConnectionViolation(transactionId, transactionViolations); }); return transactionsWithRTERViolations.length > 0 && transactionsWithRTERViolations.every((value) => value === true); } From fcb2069ab2c6ebc9db1d08b28cc517135d23f410 Mon Sep 17 00:00:00 2001 From: Nicolay Arefyeu Date: Fri, 21 Mar 2025 11:29:39 +0200 Subject: [PATCH 4/7] clean up --- src/libs/TransactionUtils/index.ts | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/libs/TransactionUtils/index.ts b/src/libs/TransactionUtils/index.ts index f3e40ee38122..39382fc793ce 100644 --- a/src/libs/TransactionUtils/index.ts +++ b/src/libs/TransactionUtils/index.ts @@ -883,10 +883,12 @@ function allHavePendingRTERViolation(transactionIds: string[], transactionViolat * Check if there is rter violation in all transactionViolations with given transactionIDs. */ function allHaveRTERViolation(transactionIds: string[], transactionViolations: OnyxCollection | undefined): boolean { - const transactionsWithRTERViolations = transactionIds.map((transactionId) => { - return hasBrokenConnectionViolation(transactionId, transactionViolations); - }); - return transactionsWithRTERViolations.length > 0 && transactionsWithRTERViolations.every((value) => value === true); + return ( + transactionIds.length > 0 && + transactionIds.every((transactionId) => { + return hasBrokenConnectionViolation(transactionId, transactionViolations); + }) + ); } /** From a78055e0c43026a1a9889632399edcc3f9cd0c5e Mon Sep 17 00:00:00 2001 From: Nicolay Arefyeu Date: Thu, 3 Apr 2025 11:00:14 +0300 Subject: [PATCH 5/7] update to better handling --- src/libs/TransactionUtils/index.ts | 10 +++++----- src/libs/actions/IOU.ts | 6 +++--- tests/unit/IOUUtilsTest.ts | 12 ++++++------ 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/libs/TransactionUtils/index.ts b/src/libs/TransactionUtils/index.ts index 3f6a09a6ee3b..1b57ce323a06 100644 --- a/src/libs/TransactionUtils/index.ts +++ b/src/libs/TransactionUtils/index.ts @@ -921,13 +921,13 @@ function allHavePendingRTERViolation(transactionIds: string[], transactionViolat } /** - * Check if there is rter violation in all transactionViolations with given transactionIDs. + * Check if there is rter without violation in all transactionViolations with given transactionIDs. */ -function allHaveRTERViolation(transactionIds: string[], transactionViolations: OnyxCollection | undefined): boolean { +function hasRTERWithoutViolation(transactionIds: string[], transactionViolations: OnyxCollection | undefined): boolean { return ( transactionIds.length > 0 && - transactionIds.every((transactionId) => { - return hasBrokenConnectionViolation(transactionId, transactionViolations); + !!transactionIds.find((transactionId) => { + return !hasBrokenConnectionViolation(transactionId, transactionViolations); }) ); } @@ -1551,7 +1551,7 @@ export { getOriginalAmount, getFormattedAttendees, getMerchant, - allHaveRTERViolation, + hasRTERWithoutViolation, getMerchantOrDescription, getMCCGroup, getCreated, diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index 0469edb9b84a..f41ae5e0a7c1 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -150,7 +150,6 @@ import playSound, {SOUNDS} from '@libs/Sound'; import {shouldRestrictUserBillableActions} from '@libs/SubscriptionUtils'; import { allHavePendingRTERViolation, - allHaveRTERViolation, buildOptimisticTransaction, getAmount, getCategoryTaxCodeAndAmount, @@ -161,6 +160,7 @@ import { getUpdatedTransaction, hasDuplicateTransactions, hasReceipt as hasReceiptTransactionUtils, + hasRTERWithoutViolation, isAmountMissing, isCustomUnitRateIDForP2P, isDistanceRequest as isDistanceRequestTransactionUtils, @@ -8588,7 +8588,7 @@ function canSubmitReport( const isAdmin = policy?.role === CONST.POLICY.ROLE.ADMIN; const transactionIDList = transactions.map((transaction) => transaction.transactionID); const hasAllPendingRTERViolations = allHavePendingRTERViolation(transactionIDList, allViolations); - const hasAllRTEViolations = allHaveRTERViolation(transactionIDList, allViolations); + const isRTERWithoutViolation = hasRTERWithoutViolation(transactionIDList, allViolations); const hasOnlyPendingCardOrScanFailTransactions = transactions.length > 0 && transactions.every((t) => (isExpensifyCardTransaction(t) && isPending(t)) || (isPartialMerchant(getMerchant(t)) && isAmountMissing(t)) || isReceiptBeingScannedTransactionUtils(t)); @@ -8599,7 +8599,7 @@ function canSubmitReport( !isArchived && !hasOnlyPendingCardOrScanFailTransactions && !hasAllPendingRTERViolations && - !hasAllRTEViolations && + isRTERWithoutViolation && (report?.ownerAccountID === currentUserAccountID || isAdmin || report?.managerID === currentUserAccountID) ); } diff --git a/tests/unit/IOUUtilsTest.ts b/tests/unit/IOUUtilsTest.ts index ae1530528564..a72c9e02aeb7 100644 --- a/tests/unit/IOUUtilsTest.ts +++ b/tests/unit/IOUUtilsTest.ts @@ -6,7 +6,7 @@ import CONST from '@src/CONST'; import * as IOUUtils from '@src/libs/IOUUtils'; import * as ReportUtils from '@src/libs/ReportUtils'; import * as TransactionUtils from '@src/libs/TransactionUtils'; -import {allHaveRTERViolation} from '@src/libs/TransactionUtils'; +import {hasRTERWithoutViolation} from '@src/libs/TransactionUtils'; import ONYXKEYS from '@src/ONYXKEYS'; import type {Policy, Report, Transaction, TransactionViolations} from '@src/types/onyx'; import type {TransactionCollectionDataSet} from '@src/types/onyx/Transaction'; @@ -182,8 +182,8 @@ describe('isValidMoneyRequestType', () => { }); }); -describe('allHaveRTERViolation', () => { - test('Return false if there is rter violation in all transactionViolations with given transactionIDs.', async () => { +describe('hasRTERWithoutViolation', () => { + test('Return true if there is at least one rter without violation in transactionViolations with given transactionIDs.', async () => { const transactionIDWithViolation = 1; const transactionIDWithoutViolation = 2; const currentReportId = ''; @@ -218,10 +218,10 @@ describe('allHaveRTERViolation', () => { await Onyx.merge(`${ONYXKEYS.COLLECTION.TRANSACTION}${transactionIDWithViolation}`, transactionWithViolation); await Onyx.merge(`${ONYXKEYS.COLLECTION.TRANSACTION}${transactionIDWithoutViolation}`, transactionWithoutViolation); - expect(allHaveRTERViolation([String(transactionIDWithoutViolation), String(transactionIDWithViolation)], violations)).toBe(false); + expect(hasRTERWithoutViolation([String(transactionIDWithoutViolation), String(transactionIDWithViolation)], violations)).toBe(true); }); - test('Return true if there is rter violation in all transactionViolations with given transactionIDs.', async () => { + test('Return false if there is no rter without violation in all transactionViolations with given transactionIDs.', async () => { const transactionIDWithViolation = 1; const currentReportId = ''; const transactionWithViolation: Transaction = { @@ -247,7 +247,7 @@ describe('allHaveRTERViolation', () => { }; await Onyx.merge(`${ONYXKEYS.COLLECTION.TRANSACTION}${transactionIDWithViolation}`, transactionWithViolation); - expect(allHaveRTERViolation([String(transactionIDWithViolation)], violations)).toBe(true); + expect(hasRTERWithoutViolation([String(transactionIDWithViolation)], violations)).toBe(false); }); }); From d348b79abe3f561cbfe22c17fde7d1a1be14add1 Mon Sep 17 00:00:00 2001 From: Nicolay Arefyeu Date: Thu, 3 Apr 2025 20:40:30 +0300 Subject: [PATCH 6/7] updates after review --- src/libs/TransactionUtils/index.ts | 8 ++++---- src/libs/actions/IOU.ts | 6 +++--- tests/unit/IOUUtilsTest.ts | 6 +++--- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/libs/TransactionUtils/index.ts b/src/libs/TransactionUtils/index.ts index 1b57ce323a06..b2ce04a6e20c 100644 --- a/src/libs/TransactionUtils/index.ts +++ b/src/libs/TransactionUtils/index.ts @@ -921,12 +921,12 @@ function allHavePendingRTERViolation(transactionIds: string[], transactionViolat } /** - * Check if there is rter without violation in all transactionViolations with given transactionIDs. + * Check if there is any transaction without RTER violation within the given transactionIDs. */ -function hasRTERWithoutViolation(transactionIds: string[], transactionViolations: OnyxCollection | undefined): boolean { +function hasAnyTransactionWithoutRTERViolation(transactionIds: string[], transactionViolations: OnyxCollection | undefined): boolean { return ( transactionIds.length > 0 && - !!transactionIds.find((transactionId) => { + transactionIds.some((transactionId) => { return !hasBrokenConnectionViolation(transactionId, transactionViolations); }) ); @@ -1551,7 +1551,7 @@ export { getOriginalAmount, getFormattedAttendees, getMerchant, - hasRTERWithoutViolation, + hasAnyTransactionWithoutRTERViolation, getMerchantOrDescription, getMCCGroup, getCreated, diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index f41ae5e0a7c1..4e3f66b43a39 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -160,7 +160,7 @@ import { getUpdatedTransaction, hasDuplicateTransactions, hasReceipt as hasReceiptTransactionUtils, - hasRTERWithoutViolation, + hasAnyTransactionWithoutRTERViolation, isAmountMissing, isCustomUnitRateIDForP2P, isDistanceRequest as isDistanceRequestTransactionUtils, @@ -8588,7 +8588,7 @@ function canSubmitReport( const isAdmin = policy?.role === CONST.POLICY.ROLE.ADMIN; const transactionIDList = transactions.map((transaction) => transaction.transactionID); const hasAllPendingRTERViolations = allHavePendingRTERViolation(transactionIDList, allViolations); - const isRTERWithoutViolation = hasRTERWithoutViolation(transactionIDList, allViolations); + const hasTransactionWithoutRTERViolation = hasAnyTransactionWithoutRTERViolation(transactionIDList, allViolations); const hasOnlyPendingCardOrScanFailTransactions = transactions.length > 0 && transactions.every((t) => (isExpensifyCardTransaction(t) && isPending(t)) || (isPartialMerchant(getMerchant(t)) && isAmountMissing(t)) || isReceiptBeingScannedTransactionUtils(t)); @@ -8599,7 +8599,7 @@ function canSubmitReport( !isArchived && !hasOnlyPendingCardOrScanFailTransactions && !hasAllPendingRTERViolations && - isRTERWithoutViolation && + hasTransactionWithoutRTERViolation && (report?.ownerAccountID === currentUserAccountID || isAdmin || report?.managerID === currentUserAccountID) ); } diff --git a/tests/unit/IOUUtilsTest.ts b/tests/unit/IOUUtilsTest.ts index a72c9e02aeb7..c74fdd10b511 100644 --- a/tests/unit/IOUUtilsTest.ts +++ b/tests/unit/IOUUtilsTest.ts @@ -6,7 +6,7 @@ import CONST from '@src/CONST'; import * as IOUUtils from '@src/libs/IOUUtils'; import * as ReportUtils from '@src/libs/ReportUtils'; import * as TransactionUtils from '@src/libs/TransactionUtils'; -import {hasRTERWithoutViolation} from '@src/libs/TransactionUtils'; +import {hasAnyTransactionWithoutRTERViolation} from '@src/libs/TransactionUtils'; import ONYXKEYS from '@src/ONYXKEYS'; import type {Policy, Report, Transaction, TransactionViolations} from '@src/types/onyx'; import type {TransactionCollectionDataSet} from '@src/types/onyx/Transaction'; @@ -218,7 +218,7 @@ describe('hasRTERWithoutViolation', () => { await Onyx.merge(`${ONYXKEYS.COLLECTION.TRANSACTION}${transactionIDWithViolation}`, transactionWithViolation); await Onyx.merge(`${ONYXKEYS.COLLECTION.TRANSACTION}${transactionIDWithoutViolation}`, transactionWithoutViolation); - expect(hasRTERWithoutViolation([String(transactionIDWithoutViolation), String(transactionIDWithViolation)], violations)).toBe(true); + expect(hasAnyTransactionWithoutRTERViolation([String(transactionIDWithoutViolation), String(transactionIDWithViolation)], violations)).toBe(true); }); test('Return false if there is no rter without violation in all transactionViolations with given transactionIDs.', async () => { @@ -247,7 +247,7 @@ describe('hasRTERWithoutViolation', () => { }; await Onyx.merge(`${ONYXKEYS.COLLECTION.TRANSACTION}${transactionIDWithViolation}`, transactionWithViolation); - expect(hasRTERWithoutViolation([String(transactionIDWithViolation)], violations)).toBe(false); + expect(hasAnyTransactionWithoutRTERViolation([String(transactionIDWithViolation)], violations)).toBe(false); }); }); From f533660956a58b4161fc25b651605ea8c9a8f819 Mon Sep 17 00:00:00 2001 From: Nicolay Arefyeu Date: Thu, 3 Apr 2025 20:42:19 +0300 Subject: [PATCH 7/7] linter --- src/libs/actions/IOU.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index 4e3f66b43a39..ad170e9383b7 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -158,9 +158,9 @@ import { getMerchant, getTransaction, getUpdatedTransaction, + hasAnyTransactionWithoutRTERViolation, hasDuplicateTransactions, hasReceipt as hasReceiptTransactionUtils, - hasAnyTransactionWithoutRTERViolation, isAmountMissing, isCustomUnitRateIDForP2P, isDistanceRequest as isDistanceRequestTransactionUtils,