diff --git a/mvp/b2c/src/app/panel/precios/actions.ts b/mvp/b2c/src/app/panel/precios/actions.ts index 6765ed1..4dc4cc0 100644 --- a/mvp/b2c/src/app/panel/precios/actions.ts +++ b/mvp/b2c/src/app/panel/precios/actions.ts @@ -7,6 +7,24 @@ import { catalogItems, pricingConfig } from '@/db/schema'; import { getTenantId } from '@/db/pricing-queries'; import { parseCatalogCsv } from '@/budget/csv'; +// Valida un importe en euros del formulario y lo convierte a céntimos. +// Lanza un error en español si el valor no es un número finito >= 0. +function eurosToCents(raw: FormDataEntryValue | null, campo: string): number { + const euros = Number(raw); + if (!Number.isFinite(euros) || euros < 0) { + throw new Error(`El valor de "${campo}" debe ser un número mayor o igual que 0.`); + } + return Math.round(euros * 100); +} + +function parsePositive(raw: FormDataEntryValue | null, campo: string): number { + const n = Number(raw); + if (!Number.isFinite(n) || n <= 0) { + throw new Error(`El valor de "${campo}" debe ser un número mayor que 0.`); + } + return n; +} + export async function crearMaterial(formData: FormData) { const tenantId = await getTenantId(); await db.insert(catalogItems).values({ @@ -14,7 +32,7 @@ export async function crearMaterial(formData: FormData) { categoria: formData.get('categoria') as 'suelo' | 'pared' | 'pintura' | 'mobiliario', nombre: String(formData.get('nombre') ?? ''), calidad: formData.get('calidad') as 'basica' | 'media' | 'premium', - precioUnit: Math.round(Number(formData.get('precioEuros') ?? 0) * 100), + precioUnit: eurosToCents(formData.get('precioEuros'), 'precio'), unidad: formData.get('unidad') as 'm2' | 'ml' | 'ud', descriptorRender: String(formData.get('descriptorRender') ?? ''), esDefault: formData.get('esDefault') === 'on', @@ -28,7 +46,7 @@ export async function actualizarPrecio(formData: FormData) { const id = String(formData.get('id') ?? ''); await db .update(catalogItems) - .set({ precioUnit: Math.round(Number(formData.get('precioEuros') ?? 0) * 100) }) + .set({ precioUnit: eurosToCents(formData.get('precioEuros'), 'precio') }) .where(and(eq(catalogItems.id, id), eq(catalogItems.tenantId, tenantId))); revalidatePath('/panel/precios'); } @@ -45,12 +63,12 @@ export async function actualizarConfig(formData: FormData) { await db .update(pricingConfig) .set({ - alturaTechoDefault: Number(formData.get('alturaTechoDefault') ?? 2.5), + alturaTechoDefault: parsePositive(formData.get('alturaTechoDefault'), 'altura de techo'), manoObra: { - demolicion: Math.round(Number(formData.get('mo_demolicion') ?? 0) * 100), - fontaneria: Math.round(Number(formData.get('mo_fontaneria') ?? 0) * 100), - electricidad: Math.round(Number(formData.get('mo_electricidad') ?? 0) * 100), - mano_de_obra: Math.round(Number(formData.get('mo_mano_de_obra') ?? 0) * 100), + demolicion: eurosToCents(formData.get('mo_demolicion'), 'demolición'), + fontaneria: eurosToCents(formData.get('mo_fontaneria'), 'fontanería'), + electricidad: eurosToCents(formData.get('mo_electricidad'), 'electricidad'), + mano_de_obra: eurosToCents(formData.get('mo_mano_de_obra'), 'mano de obra'), }, updatedAt: new Date(), }) diff --git a/mvp/b2c/src/app/panel/precios/page.tsx b/mvp/b2c/src/app/panel/precios/page.tsx index 6ab826c..6322c17 100644 --- a/mvp/b2c/src/app/panel/precios/page.tsx +++ b/mvp/b2c/src/app/panel/precios/page.tsx @@ -1,5 +1,4 @@ import { getPricingConfig, getCatalog } from '@/db/pricing-queries'; -import { formatEuros } from '@/lib/funnel'; import { crearMaterial, actualizarPrecio,