Skip to content

Commit

Permalink
fix: move validate to util
Browse files Browse the repository at this point in the history
  • Loading branch information
MrMuzyk committed Mar 15, 2024
1 parent 9522399 commit 78bd350
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 43 deletions.
26 changes: 26 additions & 0 deletions src/libs/PolicyDistanceRatesUtils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import type {FormInputErrors, FormOnyxValues} from '@components/Form/types';
import type ONYXKEYS from '@src/ONYXKEYS';
import * as CurrencyUtils from './CurrencyUtils';
import getPermittedDecimalSeparator from './getPermittedDecimalSeparator';
import * as MoneyRequestUtils from './MoneyRequestUtils';
import * as NumberUtils from './NumberUtils';

type RateValueForm = typeof ONYXKEYS.FORMS.WORKSPACE_RATE_AND_UNIT_FORM | typeof ONYXKEYS.FORMS.POLICY_CREATE_DISTANCE_RATE_FORM;

function validateRateValue(values: FormOnyxValues<RateValueForm>, currency: string, toLocaleDigit: (arg: string) => string): FormInputErrors<RateValueForm> {
const errors: FormInputErrors<RateValueForm> = {};
const rate = values.rate;
const parsedRate = MoneyRequestUtils.replaceAllDigits(rate, toLocaleDigit);
const decimalSeparator = toLocaleDigit('.');

// Allow one more decimal place for accuracy
const rateValueRegex = RegExp(String.raw`^-?\d{0,8}([${getPermittedDecimalSeparator(decimalSeparator)}]\d{1,${CurrencyUtils.getCurrencyDecimals(currency) + 1}})?$`, 'i');
if (!rateValueRegex.test(parsedRate) || parsedRate === '') {
errors.rate = 'workspace.reimburse.invalidRateError';
} else if (NumberUtils.parseFloatAnyLocale(parsedRate) <= 0) {
errors.rate = 'workspace.reimburse.lowRateError';
}
return errors;
}

export default validateRateValue;
30 changes: 8 additions & 22 deletions src/pages/workspace/distanceRates/CreateDistanceRatePage.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,17 @@
import type {StackScreenProps} from '@react-navigation/stack';
import React from 'react';
import React, {useCallback} from 'react';
import type {OnyxEntry} from 'react-native-onyx';
import {withOnyx} from 'react-native-onyx';
import AmountForm from '@components/AmountForm';
import FormProvider from '@components/Form/FormProvider';
import InputWrapperWithRef from '@components/Form/InputWrapper';
import type {FormInputErrors, FormOnyxValues} from '@components/Form/types';
import type {FormOnyxValues} from '@components/Form/types';
import HeaderWithBackButton from '@components/HeaderWithBackButton';
import ScreenWrapper from '@components/ScreenWrapper';
import useAutoFocusInput from '@hooks/useAutoFocusInput';
import useLocalize from '@hooks/useLocalize';
import useThemeStyles from '@hooks/useThemeStyles';
import * as CurrencyUtils from '@libs/CurrencyUtils';
import getPermittedDecimalSeparator from '@libs/getPermittedDecimalSeparator';
import * as MoneyRequestUtils from '@libs/MoneyRequestUtils';
import * as NumberUtils from '@libs/NumberUtils';
import validateRateValue from '@libs/PolicyDistanceRatesUtils';
import Navigation from '@navigation/Navigation';
import type {SettingsNavigatorParamList} from '@navigation/types';
import AdminPolicyAccessOrNotFoundWrapper from '@pages/workspace/AdminPolicyAccessOrNotFoundWrapper';
Expand All @@ -36,27 +33,16 @@ type CreateDistanceRatePageProps = CreateDistanceRatePageOnyxProps & StackScreen
function CreateDistanceRatePage({policy, route}: CreateDistanceRatePageProps) {
const styles = useThemeStyles();
const {translate, toLocaleDigit} = useLocalize();
const currency = policy !== null ? policy?.outputCurrency : CONST.CURRENCY.USD;
const currency = policy?.outputCurrency ?? CONST.CURRENCY.USD;
const customUnits = policy?.customUnits ?? {};
const customUnitID = customUnits[Object.keys(customUnits)[0]]?.customUnitID ?? '';
const customUnitRateID = generateCustomUnitID();
const {inputCallbackRef} = useAutoFocusInput();

const validate = (values: FormOnyxValues<typeof ONYXKEYS.FORMS.POLICY_CREATE_DISTANCE_RATE_FORM>): FormInputErrors<typeof ONYXKEYS.FORMS.POLICY_CREATE_DISTANCE_RATE_FORM> => {
const errors: FormInputErrors<typeof ONYXKEYS.FORMS.POLICY_CREATE_DISTANCE_RATE_FORM> = {};
const rate = values.rate;
const parsedRate = MoneyRequestUtils.replaceAllDigits(rate, toLocaleDigit);
const decimalSeparator = toLocaleDigit('.');

// Allow one more decimal place for accuracy
const rateValueRegex = RegExp(String.raw`^-?\d{0,8}([${getPermittedDecimalSeparator(decimalSeparator)}]\d{1,${CurrencyUtils.getCurrencyDecimals(currency) + 1}})?$`, 'i');
if (!rateValueRegex.test(parsedRate) || parsedRate === '') {
errors.rate = 'workspace.reimburse.invalidRateError';
} else if (NumberUtils.parseFloatAnyLocale(parsedRate) <= 0) {
errors.rate = 'workspace.reimburse.lowRateError';
}
return errors;
};
const validate = useCallback(
(values: FormOnyxValues<typeof ONYXKEYS.FORMS.POLICY_CREATE_DISTANCE_RATE_FORM>) => validateRateValue(values, currency, toLocaleDigit),
[currency, toLocaleDigit],
);

const submit = (values: FormOnyxValues<typeof ONYXKEYS.FORMS.POLICY_CREATE_DISTANCE_RATE_FORM>) => {
const newRate: Rate = {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,15 @@
import React, {useEffect, useMemo} from 'react';
import React, {useCallback, useEffect, useMemo} from 'react';
import {withOnyx} from 'react-native-onyx';
import type {OnyxEntry} from 'react-native-onyx';
import AmountForm from '@components/AmountForm';
import FormProvider from '@components/Form/FormProvider';
import InputWrapperWithRef from '@components/Form/InputWrapper';
import type {FormInputErrors, FormOnyxValues} from '@components/Form/types';
import type {FormOnyxValues} from '@components/Form/types';
import useLocalize from '@hooks/useLocalize';
import useThemeStyles from '@hooks/useThemeStyles';
import compose from '@libs/compose';
import * as CurrencyUtils from '@libs/CurrencyUtils';
import getPermittedDecimalSeparator from '@libs/getPermittedDecimalSeparator';
import * as MoneyRequestUtils from '@libs/MoneyRequestUtils';
import Navigation from '@libs/Navigation/Navigation';
import * as NumberUtils from '@libs/NumberUtils';
import validateRateValue from '@libs/PolicyDistanceRatesUtils';
import withPolicy from '@pages/workspace/withPolicy';
import type {WithPolicyProps} from '@pages/workspace/withPolicy';
import WorkspacePageWithSections from '@pages/workspace/WorkspacePageWithSections';
Expand All @@ -34,6 +31,7 @@ type WorkspaceRatePageProps = WorkspaceRatePageBaseProps & WorkspaceRateAndUnitO
function WorkspaceRatePage(props: WorkspaceRatePageProps) {
const styles = useThemeStyles();
const {translate, toLocaleDigit} = useLocalize();
const outputCurrency = props.policy?.outputCurrency ?? CONST.CURRENCY.USD;

useEffect(() => {
if (props.workspaceRateAndUnit?.policyID === props.policy?.id) {
Expand All @@ -49,21 +47,10 @@ function WorkspaceRatePage(props: WorkspaceRatePageProps) {
Navigation.navigate(ROUTES.WORKSPACE_RATE_AND_UNIT.getRoute(props.policy?.id ?? ''));
};

const validate = (values: FormOnyxValues<typeof ONYXKEYS.FORMS.WORKSPACE_RATE_AND_UNIT_FORM>): FormInputErrors<typeof ONYXKEYS.FORMS.WORKSPACE_RATE_AND_UNIT_FORM> => {
const errors: FormInputErrors<typeof ONYXKEYS.FORMS.WORKSPACE_RATE_AND_UNIT_FORM> = {};
const rate = values.rate;
const parsedRate = MoneyRequestUtils.replaceAllDigits(rate, toLocaleDigit);
const decimalSeparator = toLocaleDigit('.');
const outputCurrency = props.policy?.outputCurrency ?? CONST.CURRENCY.USD;
// Allow one more decimal place for accuracy
const rateValueRegex = RegExp(String.raw`^-?\d{0,8}([${getPermittedDecimalSeparator(decimalSeparator)}]\d{1,${CurrencyUtils.getCurrencyDecimals(outputCurrency) + 1}})?$`, 'i');
if (!rateValueRegex.test(parsedRate) || parsedRate === '') {
errors.rate = 'workspace.reimburse.invalidRateError';
} else if (NumberUtils.parseFloatAnyLocale(parsedRate) <= 0) {
errors.rate = 'workspace.reimburse.lowRateError';
}
return errors;
};
const validate = useCallback(
(values: FormOnyxValues<typeof ONYXKEYS.FORMS.POLICY_CREATE_DISTANCE_RATE_FORM>) => validateRateValue(values, outputCurrency, toLocaleDigit),
[outputCurrency, toLocaleDigit],
);

const defaultValue = useMemo(() => {
const defaultDistanceCustomUnit = Object.values(props.policy?.customUnits ?? {}).find((unit) => unit.name === CONST.CUSTOM_UNITS.NAME_DISTANCE);
Expand Down

0 comments on commit 78bd350

Please sign in to comment.