diff --git a/src/CONST.ts b/src/CONST.ts index d13c3b374f5a..d109b9f76456 100755 --- a/src/CONST.ts +++ b/src/CONST.ts @@ -4149,6 +4149,8 @@ const CONST = { }, }, }, + + MAX_TAX_RATE_DECIMAL_PLACES: 4, } as const; type Country = keyof typeof CONST.ALL_COUNTRIES; diff --git a/src/components/AmountForm.tsx b/src/components/AmountForm.tsx index 48035dd884bd..e947c74f7c60 100644 --- a/src/components/AmountForm.tsx +++ b/src/components/AmountForm.tsx @@ -37,6 +37,9 @@ type AmountFormProps = { /** Whether the currency symbol is pressable */ isCurrencyPressable?: boolean; + + /** Custom max amount length. It defaults to CONST.IOU.AMOUNT_MAX_LENGTH */ + amountMaxLength?: number; } & Pick & Pick; @@ -53,7 +56,7 @@ const NUM_PAD_CONTAINER_VIEW_ID = 'numPadContainerView'; const NUM_PAD_VIEW_ID = 'numPadView'; function AmountForm( - {value: amount, currency = CONST.CURRENCY.USD, extraDecimals = 0, errorText, onInputChange, onCurrencyButtonPress, isCurrencyPressable = true, ...rest}: AmountFormProps, + {value: amount, currency = CONST.CURRENCY.USD, extraDecimals = 0, amountMaxLength, errorText, onInputChange, onCurrencyButtonPress, isCurrencyPressable = true, ...rest}: AmountFormProps, forwardedRef: ForwardedRef, ) { const styles = useThemeStyles(); @@ -101,7 +104,7 @@ function AmountForm( const newAmountWithoutSpaces = MoneyRequestUtils.stripSpacesFromAmount(newAmount); // Use a shallow copy of selection to trigger setSelection // More info: https://github.com/Expensify/App/issues/16385 - if (!MoneyRequestUtils.validateAmount(newAmountWithoutSpaces, decimals)) { + if (!MoneyRequestUtils.validateAmount(newAmountWithoutSpaces, decimals, amountMaxLength)) { setSelection((prevSelection) => ({...prevSelection})); return; } @@ -111,13 +114,13 @@ function AmountForm( setSelection((prevSelection) => getNewSelection(prevSelection, isForwardDelete ? strippedAmount.length : currentAmount.length, strippedAmount.length)); onInputChange?.(strippedAmount); }, - [currentAmount, decimals, onInputChange], + [amountMaxLength, currentAmount, decimals, onInputChange], ); // Modifies the amount to match the decimals for changed currency. useEffect(() => { // If the changed currency supports decimals, we can return - if (MoneyRequestUtils.validateAmount(currentAmount, decimals)) { + if (MoneyRequestUtils.validateAmount(currentAmount, decimals, amountMaxLength)) { return; } diff --git a/src/libs/API/parameters/UpdatePolicyTaxValueParams.ts b/src/libs/API/parameters/UpdatePolicyTaxValueParams.ts index 1124755ea9ef..63fd1a1e85d9 100644 --- a/src/libs/API/parameters/UpdatePolicyTaxValueParams.ts +++ b/src/libs/API/parameters/UpdatePolicyTaxValueParams.ts @@ -1,7 +1,8 @@ type UpdatePolicyTaxValueParams = { policyID: string; taxCode: string; - taxAmount: number; + // String in the format: "1.1234%" + taxRate: string; }; export default UpdatePolicyTaxValueParams; diff --git a/src/libs/MoneyRequestUtils.ts b/src/libs/MoneyRequestUtils.ts index da8a5b843ec1..d3969558dab9 100644 --- a/src/libs/MoneyRequestUtils.ts +++ b/src/libs/MoneyRequestUtils.ts @@ -49,13 +49,13 @@ function calculateAmountLength(amount: string, decimals: number): number { /** * Check if amount is a decimal up to 3 digits */ -function validateAmount(amount: string, decimals: number): boolean { +function validateAmount(amount: string, decimals: number, amountMaxLength: number = CONST.IOU.AMOUNT_MAX_LENGTH): boolean { const regexString = decimals === 0 ? `^\\d+(,\\d*)*$` // Don't allow decimal point if decimals === 0 : `^\\d+(,\\d*)*(\\.\\d{0,${decimals}})?$`; // Allow the decimal point and the desired number of digits after the point const decimalNumberRegex = new RegExp(regexString, 'i'); - return amount === '' || (decimalNumberRegex.test(amount) && calculateAmountLength(amount, decimals) <= CONST.IOU.AMOUNT_MAX_LENGTH); + return amount === '' || (decimalNumberRegex.test(amount) && calculateAmountLength(amount, decimals) <= amountMaxLength); } /** diff --git a/src/libs/actions/TaxRate.ts b/src/libs/actions/TaxRate.ts index 3f2420c76f87..115c6543a216 100644 --- a/src/libs/actions/TaxRate.ts +++ b/src/libs/actions/TaxRate.ts @@ -380,7 +380,7 @@ function updatePolicyTaxValue(policyID: string, taxID: string, taxValue: number) const parameters = { policyID, taxCode: taxID, - taxAmount: Number(taxValue), + taxRate: stringTaxValue, } satisfies UpdatePolicyTaxValueParams; API.write(WRITE_COMMANDS.UPDATE_POLICY_TAX_VALUE, parameters, onyxData); diff --git a/src/pages/workspace/taxes/ValuePage.tsx b/src/pages/workspace/taxes/ValuePage.tsx index 6487b3a752b8..4ec932fbcc14 100644 --- a/src/pages/workspace/taxes/ValuePage.tsx +++ b/src/pages/workspace/taxes/ValuePage.tsx @@ -1,5 +1,5 @@ import type {StackScreenProps} from '@react-navigation/stack'; -import React, {useCallback, useState} from 'react'; +import React, {useCallback} from 'react'; import AmountForm from '@components/AmountForm'; import FormProvider from '@components/Form/FormProvider'; import InputWrapper from '@components/Form/InputWrapper'; @@ -38,7 +38,7 @@ function ValuePage({ const {translate} = useLocalize(); const {inputCallbackRef} = useAutoFocusInput(); const currentTaxRate = PolicyUtils.getTaxByID(policy, taxID); - const [value, setValue] = useState(currentTaxRate?.value?.replace('%', '')); + const defaultValue = currentTaxRate?.value?.replace('%', ''); const goBack = useCallback(() => Navigation.goBack(ROUTES.WORKSPACE_TAX_EDIT.getRoute(policyID ?? '', taxID)), [policyID, taxID]); @@ -87,9 +87,12 @@ function ValuePage({ %} ref={inputCallbackRef} /> diff --git a/src/pages/workspace/taxes/WorkspaceCreateTaxPage.tsx b/src/pages/workspace/taxes/WorkspaceCreateTaxPage.tsx index ccc0d4ad9e7b..9d7c1a400870 100644 --- a/src/pages/workspace/taxes/WorkspaceCreateTaxPage.tsx +++ b/src/pages/workspace/taxes/WorkspaceCreateTaxPage.tsx @@ -106,6 +106,10 @@ function WorkspaceCreateTaxPage({ description={translate('workspace.taxes.value')} rightLabel={translate('common.required')} hideCurrencySymbol + // The default currency uses 2 decimal places, so we substract it + extraDecimals={CONST.MAX_TAX_RATE_DECIMAL_PLACES - 2} + // We increase the amount max length. We have to add 2 places for one digit and comma. + amountMaxLength={CONST.MAX_TAX_RATE_DECIMAL_PLACES + 2} extraSymbol={%} />