fix(money-input): toFixed(2) при allowFractional=true для правильного отображения

formatFromValue использовал String(v) для дробного режима, поэтому
целые значения в БД (1317, 1860) показывались как «1317» / «1860»
даже при включённой галке «Разрешить дробные цены». Теперь:
- fractional=true → v.toFixed(2): 1317 → «1317.00», 1317.5 → «1317.50»;
- fractional=false → String(Math.round(v)): 1317.5 → «1318».

Хелпер используется в init useState, useEffect-синке и commitDraft —
таким образом при onBlur поле всегда возвращается к корректному
формату «1317.00».

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
nns 2026-04-25 12:55:33 +05:00
parent 71b749fb35
commit 9077c07584

View file

@ -60,8 +60,14 @@ export function MoneyInput({
const settingKnown = allowFractional !== undefined || org.data !== undefined
const fractional = allowFractional ?? org.data?.allowFractionalPrices ?? true
const formatFromValue = (v: number | null | undefined, frac: boolean) =>
v == null ? '' : (frac ? String(v) : String(Math.round(v)))
const formatFromValue = (v: number | null | undefined, frac: boolean) => {
if (v == null) return ''
// При fractional=true всегда показываем ровно 2 знака после запятой
// (1317 → «1317.00», 1317.5 → «1317.50»). Так юзеру визуально понятно,
// что поле допускает копейки и текущее значение — это целое.
if (frac) return v.toFixed(2)
return String(Math.round(v))
}
// Локальный draft — то что юзер реально печатает. Может быть промежуточным
// ("100.", "100.5", "0."). Sync с внешним value только когда поле не в фокусе.