Skip to content
Merged
14 changes: 8 additions & 6 deletions src/libs/Violations/ViolationsUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -257,14 +257,16 @@ const ViolationsUtils = {
}
}

const shouldShowSmartScanFailedError = isScanRequest && updatedTransaction.receipt?.state === CONST.IOU.RECEIPT_STATE.SCAN_FAILED;
// Only show SmartScan failed when scan failed AND the user hasn't filled required fields yet
const hasUserStartedFixingSmartscan = !TransactionUtils.isAmountMissing(updatedTransaction) || !TransactionUtils.isMerchantMissing(updatedTransaction);
const shouldShowSmartScanFailedError =
isScanRequest &&
updatedTransaction.receipt?.state === CONST.IOU.RECEIPT_STATE.SCAN_FAILED &&
TransactionUtils.hasMissingSmartscanFields(updatedTransaction, iouReport ?? undefined) &&
!hasUserStartedFixingSmartscan;
const hasSmartScanFailedError = transactionViolations.some((violation) => violation.name === CONST.VIOLATIONS.SMARTSCAN_FAILED);
if (shouldShowSmartScanFailedError && !hasSmartScanFailedError) {
return {
onyxMethod: Onyx.METHOD.SET,
key: `${ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS}${updatedTransaction.transactionID}`,
value: [{name: CONST.VIOLATIONS.SMARTSCAN_FAILED, type: CONST.VIOLATION_TYPES.WARNING, showInReview: true}],
};
newTransactionViolations.push({name: CONST.VIOLATIONS.SMARTSCAN_FAILED, type: CONST.VIOLATION_TYPES.WARNING, showInReview: true});
}
if (!shouldShowSmartScanFailedError && hasSmartScanFailedError) {
newTransactionViolations = reject(newTransactionViolations, {name: CONST.VIOLATIONS.SMARTSCAN_FAILED});
Expand Down
40 changes: 38 additions & 2 deletions tests/unit/ViolationUtilsTest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -365,7 +365,7 @@ describe('getViolationsOnyxData', () => {
expect(result.value).toEqual(expect.arrayContaining([missingCategoryViolation, ...transactionViolations]));
});

it('should only return smartscanFailed violation for smart scan failed transactions', () => {
it('should keep other violations while adding smartscanFailed for smart scan failed transactions', () => {
const partialTransaction = {
...transaction,
amount: 0,
Expand All @@ -375,7 +375,43 @@ describe('getViolationsOnyxData', () => {
receipt: {state: CONST.IOU.RECEIPT_STATE.SCAN_FAILED},
};
const result = ViolationsUtils.getViolationsOnyxData(partialTransaction, transactionViolations, policy, policyTags, policyCategories, false, false);
expect(result.value).toEqual([{name: CONST.VIOLATIONS.SMARTSCAN_FAILED, type: CONST.VIOLATION_TYPES.WARNING, showInReview: true}]);
expect(result.value).toEqual(
expect.arrayContaining([{name: CONST.VIOLATIONS.SMARTSCAN_FAILED, type: CONST.VIOLATION_TYPES.WARNING, showInReview: true}, missingCategoryViolation]),
);
});

it('should not add smartscanFailed when scan failed but required fields are filled', () => {
const transactionWithEnteredDetails = {
...transaction,
amount: 10000,
merchant: 'Coffee Shop',
iouRequestType: CONST.IOU.REQUEST_TYPE.SCAN,
receipt: {state: CONST.IOU.RECEIPT_STATE.SCAN_FAILED},
};
const result = ViolationsUtils.getViolationsOnyxData(transactionWithEnteredDetails, transactionViolations, policy, policyTags, policyCategories, false, false);
expect(result.value).not.toContainEqual(expect.objectContaining({name: CONST.VIOLATIONS.SMARTSCAN_FAILED}));
});

it('should not add smartscanFailed when scan failed but modified fields are filled (amount and merchant)', () => {
const transactionWithModifiedDetails = {
...transaction,
amount: 0,
modifiedAmount: 12345,
merchant: '',
modifiedMerchant: 'Manual Merchant',
iouRequestType: CONST.IOU.REQUEST_TYPE.SCAN,
receipt: {state: CONST.IOU.RECEIPT_STATE.SCAN_FAILED},
};
const result = ViolationsUtils.getViolationsOnyxData(
transactionWithModifiedDetails as unknown as Transaction,
transactionViolations,
policy,
policyTags,
policyCategories,
false,
false,
);
expect(result.value).not.toContainEqual(expect.objectContaining({name: CONST.VIOLATIONS.SMARTSCAN_FAILED}));
});
});

Expand Down
Loading