Files
mercadodevida/work/artifacts/F-081/architect.md
2026-08-20 06:01:32 +02:00

2.9 KiB

F-081 — Architect: Inventory PRECIO NETO wrong format and no save

Root cause

InventorySection.tsx (the inventory tab inside the product editor) initialises priceValue with String(price.netUnitAmountCents). The input is type="number" so it shows a cents value (1000 for €10.00), and savePrice reads it back with parseInt(r.priceValue, 10) which it sends as cents. Two consequences:

  1. The visible number (1000) does not look like a price — operators either type "10" thinking euros and end up saving 10 cents, or paste euros and corrupt the price.
  2. The OK button does exist and does call PATCH /variants/:id/set-price, but the persisted value is wrong by ~100x.

The Prices tab (PricingSection.tsx) already does this right with centsToEur and eurToCents helpers — same component pattern should be reused here.

Design

Inventory-only fix in InventorySection.tsx:

  1. Add two local helpers (mirroring PricingSection):
    const centsToEur = (cents: number) => (cents / 100).toFixed(2);
    const eurToCents = (input: string) => {
      if (!input) return 0;
      const v = parseFloat(String(input).replace(',', '.'));
      return isNaN(v) ? 0 : Math.round(v * 100);
    };
    
  2. Initialise priceValue from centsToEur(price.netUnitAmountCents).
  3. Display the read-only cell with formatCents (already exists) — no change.
  4. Edit cell: switch <input type="number"> to <input type="text" inputMode="decimal"> so comma/dot are accepted and digits can be deleted freely (same UX as PricingSection).
  5. savePrice: parse with eurToCents(r.priceValue) → call existing pricingApi.setVariantPrice(variantId, cents, r.vatRate) (no contract change).
  6. cancelEditPrice: restore from r.price.netUnitAmountCents using centsToEur.
  7. On save success, refresh priceValue from the cents returned by the API so the cell shows exactly what was persisted.

The standalone /inventory page is not affected — it doesn't render Precio Neto at all (out of F-081 scope; addressed in F-082 for the InventorySection row when needed).

Risk

Low. Behaviour-equivalent on the wire: cents go to the same endpoint. Format-only change in the cell.

Acceptance mapping

  • "Inventory PRECIO NETO accepts ',' and '.' as decimal separator" → type="text" + eurToCents.
  • "Operator can freely type, delete digits and decimal separator" → text input + state-driven value.
  • "Editing triggers PATCH /variants/:id" → existing savePrice flow.
  • "On success the new value is persisted and shown back" → setRows updates price.netUnitAmountCents and priceValue to the API-returned cents.
  • "On error inline error is shown and old value is restored" → existing saveMsg + cancelEditPrice pattern.
  • "Format identical to Prices tab Neto (sin IVA)" → uses centsToEur and eurToCents mirroring PricingSection.
  • "verify.sh is green" → typecheck + lint clean.