fix(18-07): money accepts trailing zeros beyond the field scale
A scale-2 money field over a four-decimal column (the documented fee example) was served "12.5000" and answered money.too_precise when the untouched value was saved back. Trailing zeros carry no precision, so the server check and the SPA parser count only significant fraction digits; the value still reaches the column unchanged, never rounded or truncated. - cabana validateMoneyValue and admin parseMoneyInput trim trailing zeros before the scale comparison - forms docs and cabana README name the rule; embedded dist rebuilt - MoneyField spec asserts 12.5000 at scale 2 is accepted, 12.5010 refused
This commit is contained in:
@@ -20,8 +20,10 @@ const digitsOnly = /^[0-9]+$/
|
||||
* Turns typed text into the canonical money string: spaces and U+00A0 are
|
||||
* stripped, one comma or dot is the decimal separator, an optional leading
|
||||
* minus is kept, digits only otherwise. Empty text is null. More than
|
||||
* `scale` fraction digits is `too_precise`: the value is never rounded or
|
||||
* truncated. Anything else (letters, two separators, grouping) is `invalid`.
|
||||
* `scale` significant fraction digits is `too_precise`: the value is never
|
||||
* rounded or truncated, and trailing zeros beyond the scale are kept and
|
||||
* accepted (they carry no precision), as the server does. Anything else
|
||||
* (letters, two separators, grouping) is `invalid`.
|
||||
*/
|
||||
export function parseMoneyInput(text: string, scale: number): MoneyParseResult {
|
||||
const compact = text.replace(/[\s ]/g, '')
|
||||
@@ -42,7 +44,7 @@ export function parseMoneyInput(text: string, scale: number): MoneyParseResult {
|
||||
if (!digitsOnly.test(whole ?? '') || (separators.length === 1 && !digitsOnly.test(fraction))) {
|
||||
return { value: null, error: 'invalid' }
|
||||
}
|
||||
if (fraction.length > scale) {
|
||||
if (fraction.replace(/0+$/, '').length > scale) {
|
||||
return { value: null, error: 'too_precise' }
|
||||
}
|
||||
const canonical = fraction === '' ? whole : `${whole}.${fraction}`
|
||||
|
||||
Reference in New Issue
Block a user