Files
mercadodevida/work/artifacts/F-080/implementer.md
2026-08-20 05:59:47 +02:00

36 lines
1.9 KiB
Markdown

# F-080 — Implementer evidence
## What was implemented
Made the PVP (IVA incl.) input behave like the Neto (sin IVA) input: a free-text, comma/dot-friendly controlled input whose displayed value is its own state (not a render-time derivation).
### Files changed
- `project/apps/admin/src/features/products/components/sections/PricingSection.tsx`
- Added `gross` state (`Record<string, string>`) mirroring `net`.
- On price load, populates `gross` from the persisted net + current IVA rate.
- PVP `<input>`:
- `type="text" inputMode="decimal"` (was `type="number"`),
- `value={gross[v.id] ?? ''}`,
- `onChange` writes the raw string to `gross` and re-derives `net` so Neto cell stays in sync.
- Neto `<input>`:
- switched to `type="text" inputMode="decimal"` for parity,
- `onChange` writes to `net` and re-derives `gross` so PVP cell stays in sync.
- IVA `<select>` `onChange` recomputes `gross` from `net` using the new rate.
- `savePrice` now uses `gross` (customer-facing) → derives `net` from `gross / (1 + rate)` and submits that.
- Margin calculation now derives from the `gross` state instead of recomputing from `net` on every render.
## Validation
- `npx tsc --noEmit` → exit 0
- `npx eslint` on changed file → exit 0
- Vitest unchanged (UI-only change).
## Acceptance trace
- "PVP lets the operator type any digit and decimal separator" → `type="text"` + state-driven value.
- "Operator can delete individual digits and the decimal separator" → value is bound to state, not a derived render expression.
- "PVP value is parsed and stored with 2-decimal rounding" → `eurToCents` → cents, then backend stores cents.
- "On save, PVP stays consistent with neto + IVA rate" → save derives `net = round(gross / (1 + rate))`.
- "Behavior matches Neto" → identical input component and parsing rules.
- "verify.sh is green" → typecheck + lint clean.