Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 3 additions & 6 deletions src/components/ReportActionItem/MoneyRequestView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ import {
isTimeRequest as isTimeRequestTransactionUtils,
shouldShowAttendees as shouldShowAttendeesTransactionUtils,
} from '@libs/TransactionUtils';
import {isInvalidMerchantValue} from '@libs/ValidationUtils';
import ViolationsUtils from '@libs/Violations/ViolationsUtils';
import Navigation from '@navigation/Navigation';
import AnimatedEmptyStateBackground from '@pages/inbox/report/AnimatedEmptyStateBackground';
Expand Down Expand Up @@ -278,8 +279,7 @@ function MoneyRequestView({
convertedAmount: transactionConvertedAmount,
} = getTransactionDetails(transaction, undefined, undefined, allowNegativeAmount, false, currentUserPersonalDetails) ?? {};
const isZeroTransactionAmount = transactionAmount === 0;
const isEmptyMerchant =
transactionMerchant === '' || transactionMerchant === CONST.TRANSACTION.PARTIAL_TRANSACTION_MERCHANT || transactionMerchant === CONST.TRANSACTION.DEFAULT_MERCHANT;
const isEmptyMerchant = isInvalidMerchantValue(transactionMerchant);
const isDistanceRequest = isDistanceRequestTransactionUtils(transaction);
const isManualDistanceRequest = isManualDistanceRequestTransactionUtils(transaction, !!mergeTransactionID);
const isGPSDistanceRequest = isGPSDistanceRequestTransactionUtils(transaction);
Expand Down Expand Up @@ -436,10 +436,7 @@ function MoneyRequestView({

const shouldNavigateToUpgradePath = !policyForMovingExpenses && !shouldSelectPolicy;
const updatedTransactionDescription = getDescription(updatedTransaction) || undefined;
const isEmptyUpdatedMerchant =
updatedTransaction?.modifiedMerchant === '' ||
updatedTransaction?.modifiedMerchant === CONST.TRANSACTION.PARTIAL_TRANSACTION_MERCHANT ||
updatedTransaction?.modifiedMerchant === CONST.TRANSACTION.DEFAULT_MERCHANT;
const isEmptyUpdatedMerchant = isInvalidMerchantValue(updatedTransaction?.modifiedMerchant);
const updatedMerchantTitle = isEmptyUpdatedMerchant ? '' : (updatedTransaction?.modifiedMerchant ?? merchantTitle);
Comment thread
situchan marked this conversation as resolved.

const shouldShowConvertedAmount =
Expand Down
6 changes: 5 additions & 1 deletion src/components/Rule/TextBase.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import useAutoFocusInput from '@hooks/useAutoFocusInput';
import useLocalize from '@hooks/useLocalize';
import useOnyx from '@hooks/useOnyx';
import useThemeStyles from '@hooks/useThemeStyles';
import {isRequiredFulfilled, isValidInputLength} from '@libs/ValidationUtils';
import {isInvalidMerchantValue, isRequiredFulfilled, isValidInputLength} from '@libs/ValidationUtils';
import variables from '@styles/variables';
import CONST from '@src/CONST';
import type {OnyxFormKey} from '@src/ONYXKEYS';
Expand Down Expand Up @@ -62,6 +62,10 @@ function TextBase<TFormID extends OnyxFormKey>({

if (!isValid) {
(errors as Record<string, string>)[fieldID] = translate('common.error.characterLimitExceedCounter', byteLength, characterLimit);
} else if (fieldID === CONST.EXPENSE_RULES.FIELDS.RENAME_MERCHANT || fieldID === CONST.MERCHANT_RULES.FIELDS.MERCHANT) {
if (isInvalidMerchantValue(trimmedValue)) {
(errors as Record<string, string>)[fieldID] = translate('iou.error.invalidMerchant');
}
}
}

Expand Down
13 changes: 5 additions & 8 deletions src/libs/SearchUIUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@ import {
isScanning,
isViolationDismissed,
} from './TransactionUtils';
import {isInvalidMerchantValue} from './ValidationUtils';
import ViolationsUtils from './Violations/ViolationsUtils';

type ColumnSortMapping<T> = Partial<Record<SearchColumnType, keyof T | null>>;
Expand Down Expand Up @@ -889,7 +890,7 @@ function getTransactionItemCommonFormattedProperties(
const formattedTotal = getTransactionAmount(transactionItem, isExpenseReport);
const date = transactionItem?.modifiedCreated ? transactionItem.modifiedCreated : transactionItem?.created;
const merchant = getTransactionMerchant(transactionItem, policy);
const formattedMerchant = merchant === CONST.TRANSACTION.PARTIAL_TRANSACTION_MERCHANT || merchant === CONST.TRANSACTION.DEFAULT_MERCHANT ? '' : merchant;
const formattedMerchant = isInvalidMerchantValue(merchant) ? '' : merchant;
const submitted = report?.submitted;
const approved = report?.approved;

Expand Down Expand Up @@ -955,7 +956,7 @@ function getShouldShowMerchant(data: OnyxTypes.SearchResults['data']): boolean {
if (isTransactionEntry(key)) {
const item = data[key];
const merchant = item.modifiedMerchant ? item.modifiedMerchant : (item.merchant ?? '');
return merchant !== '' && merchant !== CONST.TRANSACTION.PARTIAL_TRANSACTION_MERCHANT && merchant !== CONST.TRANSACTION.DEFAULT_MERCHANT;
return !isInvalidMerchantValue(merchant);
}
return false;
});
Expand Down Expand Up @@ -2361,11 +2362,7 @@ function getMerchantSections(data: OnyxTypes.SearchResults['data'], queryJSON: S
// - UNKNOWN_MERCHANT ('Unknown Merchant') - used when merchant cannot be determined
const rawMerchant = merchantGroup.merchant;
const isEmptyMerchant =
!rawMerchant ||
rawMerchant === CONST.SEARCH.MERCHANT_EMPTY_VALUE ||
rawMerchant === CONST.TRANSACTION.DEFAULT_MERCHANT ||
rawMerchant === CONST.TRANSACTION.PARTIAL_TRANSACTION_MERCHANT ||
rawMerchant === CONST.TRANSACTION.UNKNOWN_MERCHANT;
!rawMerchant || rawMerchant === CONST.SEARCH.MERCHANT_EMPTY_VALUE || rawMerchant === CONST.TRANSACTION.UNKNOWN_MERCHANT || isInvalidMerchantValue(rawMerchant);
const formattedMerchant = isEmptyMerchant ? translate('search.noMerchant') : rawMerchant;

merchantSections[key] = {
Expand Down Expand Up @@ -4258,7 +4255,7 @@ function getColumnsToShow(
const {moneyRequestReportActionsByTransactionID} = Array.isArray(data) ? {} : createReportActionsLookupMaps(data);
const updateColumns = (transaction: OnyxTypes.Transaction) => {
const merchant = transaction.modifiedMerchant ? transaction.modifiedMerchant : (transaction.merchant ?? '');
if ((merchant !== '' && merchant !== CONST.TRANSACTION.PARTIAL_TRANSACTION_MERCHANT && merchant !== CONST.TRANSACTION.DEFAULT_MERCHANT) || isScanning(transaction)) {
if (!isInvalidMerchantValue(merchant) || isScanning(transaction)) {
columns[CONST.SEARCH.TABLE_COLUMNS.MERCHANT] = true;
}

Expand Down
7 changes: 2 additions & 5 deletions src/libs/TransactionPreviewUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ import {
isScanning,
isUnreportedAndHasInvalidDistanceRateTransaction,
} from './TransactionUtils';
import {isInvalidMerchantValue} from './ValidationUtils';
import {filterReceiptViolations} from './Violations/ViolationsUtils';

const emptyPersonalDetails: OnyxTypes.PersonalDetails = {
Expand Down Expand Up @@ -432,11 +433,7 @@ function createTransactionPreviewConditionals({
- the expense is not a distance expense with a pending route and amount = 0 - in this case,
the merchant says: "Route pending...", which is already shown in the amount field;
*/
const shouldShowMerchant =
!!requestMerchant &&
requestMerchant !== CONST.TRANSACTION.PARTIAL_TRANSACTION_MERCHANT &&
requestMerchant !== CONST.TRANSACTION.DEFAULT_MERCHANT &&
!(isFetchingWaypoints && !requestAmount);
const shouldShowMerchant = !isInvalidMerchantValue(requestMerchant) && !(isFetchingWaypoints && !requestAmount);
const shouldShowDescription = !!description && !shouldShowMerchant && !isScanning(transaction);

return {
Expand Down
8 changes: 3 additions & 5 deletions src/libs/TransactionUtils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
isSettled,
isThread,
} from '@libs/ReportUtils';
import {isInvalidMerchantValue} from '@libs/ValidationUtils';
import type {IOURequestType, UpdateMoneyRequestDataKeys} from '@userActions/IOU';
import CONST from '@src/CONST';
import type {IOUType} from '@src/CONST';
Expand Down Expand Up @@ -139,7 +140,7 @@
});

let allPolicyTags: OnyxCollection<PolicyTagLists> = {};
Onyx.connect({

Check warning on line 143 in src/libs/TransactionUtils/index.ts

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

Onyx.connect() is deprecated. Use useOnyx() hook instead and pass the data as parameters to a pure function
key: ONYXKEYS.COLLECTION.POLICY_TAGS,
waitForCollectionCallback: true,
callback: (value) => {
Expand Down Expand Up @@ -592,12 +593,9 @@

function isMerchantMissing(transaction: OnyxEntry<Transaction>) {
if (transaction?.modifiedMerchant && transaction.modifiedMerchant !== '') {
return transaction.modifiedMerchant === CONST.TRANSACTION.PARTIAL_TRANSACTION_MERCHANT || transaction.modifiedMerchant === CONST.TRANSACTION.DEFAULT_MERCHANT;
return isInvalidMerchantValue(transaction.modifiedMerchant);
}
const isMerchantEmpty =
transaction?.merchant === CONST.TRANSACTION.PARTIAL_TRANSACTION_MERCHANT || transaction?.merchant === CONST.TRANSACTION.DEFAULT_MERCHANT || transaction?.merchant === '';

return isMerchantEmpty;
return isInvalidMerchantValue(transaction?.merchant);
}

/**
Expand Down
8 changes: 8 additions & 0 deletions src/libs/ValidationUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -763,6 +763,13 @@ function isValidTaxIDEINNumber(number: string, country: Country | '') {
}
}

/**
* Checks if a merchant string value is considered invalid/empty
*/
function isInvalidMerchantValue(merchant?: string): boolean {
return !merchant || merchant === CONST.TRANSACTION.PARTIAL_TRANSACTION_MERCHANT || merchant === CONST.TRANSACTION.DEFAULT_MERCHANT;
}

export {
meetsMinimumAgeRequirement,
meetsMaximumAgeRequirement,
Expand Down Expand Up @@ -816,4 +823,5 @@ export {
isValidRegistrationNumber,
isValidInputLength,
isValidTaxIDEINNumber,
isInvalidMerchantValue,
};
9 changes: 3 additions & 6 deletions src/pages/iou/request/step/IOURequestStepMerchant.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import useThemeStyles from '@hooks/useThemeStyles';
import getNonEmptyStringOnyxID from '@libs/getNonEmptyStringOnyxID';
import Navigation from '@libs/Navigation/Navigation';
import {getTransactionDetails, isExpenseRequest, isPolicyExpenseChat} from '@libs/ReportUtils';
import {isValidInputLength} from '@libs/ValidationUtils';
import {isInvalidMerchantValue, isValidInputLength} from '@libs/ValidationUtils';
import {setDraftSplitTransaction, setMoneyRequestMerchant, updateMoneyRequestMerchant} from '@userActions/IOU';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
Expand Down Expand Up @@ -57,7 +57,7 @@ function IOURequestStepMerchant({
// In the split flow, when editing we use SPLIT_TRANSACTION_DRAFT to save draft value
const isEditingSplitBill = iouType === CONST.IOU.TYPE.SPLIT && isEditing;
const merchant = getTransactionDetails(isEditingSplitBill && !isEmptyObject(splitDraftTransaction) ? splitDraftTransaction : transaction)?.merchant;
const isEmptyMerchant = merchant === '' || merchant === CONST.TRANSACTION.PARTIAL_TRANSACTION_MERCHANT || merchant === CONST.TRANSACTION.DEFAULT_MERCHANT;
const isEmptyMerchant = isInvalidMerchantValue(merchant);
const initialMerchant = isEmptyMerchant ? '' : merchant;
const [currentMerchant, setCurrentMerchant] = useState(initialMerchant);
const [isSaved, setIsSaved] = useState(false);
Expand Down Expand Up @@ -89,10 +89,7 @@ function IOURequestStepMerchant({

if (isMerchantRequired && !value.moneyRequestMerchant) {
errors.moneyRequestMerchant = translate('common.error.fieldRequired');
} else if (
isMerchantRequired &&
(value.moneyRequestMerchant === CONST.TRANSACTION.PARTIAL_TRANSACTION_MERCHANT || value.moneyRequestMerchant === CONST.TRANSACTION.DEFAULT_MERCHANT)
) {
} else if (isMerchantRequired && isInvalidMerchantValue(value.moneyRequestMerchant)) {
errors.moneyRequestMerchant = translate('iou.error.invalidMerchant');
} else if (!isValid) {
errors.moneyRequestMerchant = translate('common.error.characterLimitExceedCounter', byteLength, CONST.MERCHANT_NAME_MAX_BYTES);
Expand Down
16 changes: 16 additions & 0 deletions tests/unit/ValidationUtilsTest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import CONST from '@src/CONST';
import type {Country} from '@src/CONST';
import {
getAgeRequirementError,
isInvalidMerchantValue,
isRequiredFulfilled,
isValidAccountRoute,
isValidDate,
Expand Down Expand Up @@ -550,4 +551,19 @@ describe('ValidationUtils', () => {
});
});
});

describe('isInvalidMerchantValue', () => {
test('Valid merchnt name', () => {
expect(isInvalidMerchantValue('test name')).toBe(false);
expect(isInvalidMerchantValue('none')).toBe(false);
expect(isInvalidMerchantValue('Unknown Merchant')).toBe(false);
expect(isInvalidMerchantValue('X Æ A test')).toBe(false);
});

test('Invalid merchant name', () => {
expect(isInvalidMerchantValue('')).toBe(true);
expect(isInvalidMerchantValue('Expense')).toBe(true);
expect(isInvalidMerchantValue('(none)')).toBe(true);
});
});
});
Loading