Presupuesto al cliente
Tutorial paso a paso sobre el módulo Presupuesto al cliente
en Despiece: armar un PDF branded con datos del cliente, cinco
secciones de costos (Mueble · Materiales · Herraje · Mano de obra
· Extras) y el total con margen y multiplicador de obra. El
modelo de ejemplo es CocinaV9.despiece; el módulo
está separado del flujo 2D (BOM/nest) y vive en un panel propio
que se abre con Shift+Q.
parts.quoteDraft) es un
campo soft del proyecto .despiece — no bump
de schema. Se guarda en el IDB
despiece-quote-drafts y se restaura con la sesión.
El PDF final se descarga como
presupuesto-{nombre}-{yyyymmdd}.pdf.
01 Cargar el modelo y abrir el panel
[Q] del topbar.
Al importar el modelo, la sidebar izquierda muestra el árbol jerárquico. Para abrir el módulo Presupuesto hay dos formas:
- Atajo Shift+Q (también ⇧+Q en Mac).
- Botón
[Q]del topbar entre Herraje y Lineales.
Se abre un panel sheet full-screen con header Presupuesto y número correlativo. La primera sección visible es Cliente con los datos cargados del catálogo del taller o del proyecto activo.
Configuración → Presupuesto →
Activar módulo Presupuesto está apagado, el botón
[Q] del topbar y Shift+Q no
hacen nada — aparece el toast "Módulo Presupuesto
desactivado". Lo que sigue asume módulo on (default
off — hay que activarlo).
02 Header y datos del cliente
El header del panel expone:
- Kicker
Presupuesto+ número correlativo (defaultSin número) - Fecha de emisión y fecha de vencimiento (auto-calculada como
emisión + validez días) - Botón Exportar PDF (en la barra inferior; el header solo tiene el cierre)
- Botón × para cerrar el panel
La sección Cliente debajo del header carga desde state.project.client (catálogo per-proyecto o workshop-global linkeado) y muestra: nombre, teléfono, email, dirección, CUIT y notas. Click en el chevron colapsa/expande la sección (persiste en localStorage).
openClientPanel() desde la topbar. Editar el
cliente actualiza el presupuesto en vivo — sin recargar ni
perder foco.
03 Sección Mueble
La sección Mueble resume el modelo cargado en una sola línea:
| Campo | Significado |
|---|---|
| Descripción | Nombre del proyecto activo (editable vía state.project.activeName) |
| Cantidad | state.settings.projectMultiplier (default 1) |
| Unidad | unidad |
| Unit price | Subtotal / ×N (sin margen) |
| Subtotal | Subtotal calculado sin multiplicar por ×N |
Si no hay modelo cargado, la sección queda con warning: "Sin modelo cargado" y computable: false. Las notas del cliente se linkean al PDF como descripción extendida de la línea Mueble.
04 Sección Materiales (overrides)
(material × thickness) del BOM. Filas con is-override muestran borde sutil cuando el catálogo no tiene costPerM2.
La sección Materiales agrega una línea por cada combinación (material × thickness) del BOM actual. Las columnas son descripción (auto-gen del catálogo), cantidad (m² o ml según tipo), unidad, unit price (del costPerM2 o costPerMl del catálogo), y subtotal.
costPerM2 para un material, la fila se renderiza
con borde sutil (is-override) y permite tipear
Cant., $ U. y Descripción directamente desde el panel.
La multiplicación cant × unitPrice corre en vivo y
los totales reflejan al instante. La key del override es
bucketKey(material)|thicknessMm — el mismo que usa
src/export-purchase/row-builders.ts:27.
El override vive en parts.quoteDraft.materialesOverrides (campo soft en el .despiece). Si después cargás costPerM2 en el catálogo, el override sigue ganando hasta que se borre manualmente.
05 Sección Herraje
hardwareList está vacía, la sección queda con warning y no aporta al subtotal.
La sección Herraje agrega una línea por cada SKU del catálogo de herraje del proyecto (state.project.hardwareList[]). Las columnas son descripción, cantidad (×N global), unidad, unit price (del costPerUnit del SKU), y subtotal.
Si el proyecto no tiene herraje configurado (hardwareList.length === 0), la sección queda vacía con warning: "Sin herraje" y no aporta al subtotal. Toggle incluir en el header de la sección la apaga del PDF sin perder los datos.
06 Sección Mano de obra (cycle-time del nest)
La sección Mano de obra se calcula desde el cycle-time del último resultado de nest (state.nesting.lastResult.cycleTimeMinutes) y la tarifa por hora configurada en el tab Corte de Settings.
Fórmula:
computable: false.
El resto del presupuesto se puede editar y exportar igual — la
mano de obra es la única sección gateada por el nest.
La tarifa por hora (hourlyRate) es la misma del settings de corte, aplicada por hora. Default 0 (la sección queda en $0 si no la configurás).
07 Sección Extras (CRUD libre)
La sección Extras es un CRUD libre de líneas para agregar costos que no entran en las otras secciones: flete, instalación, mano de obra adicional, descuentos, etc.
Cada línea expone 4 inputs editables: Descripción, Cant., Unidad, $ U.. El subtotal se calcula como cant × unitPrice y se actualiza en vivo. Botones + Agregar y × (en cada row) para agregar/quitar filas. Sin filas, la sección queda vacía y no aporta al subtotal.
08 Totales: subtotal, margen, ×N, total
El footer de totales se renderiza debajo de las 5 secciones y explica la cascada:
Tres inputs editables (sin recargar el panel):
| Campo | Rango | Default |
|---|---|---|
| Moneda | string hasta 8 chars | ARS |
| Margen (%) | 0–200 | 30 |
| ×N (multiplicador de obra) | 1–99 | 1 |
El multiplicador se lee del proyecto (state.settings.projectMultiplier) y se aplica después del margen: un proyecto ×3 con $1000 subtotal y 30% margen da total = (1000 + 300) × 3 = 3900. Toggle incluir en cada sección la apaga del PDF sin perder los datos — el subtotal refleja solamente lo efectivamente cotizado.
09 Términos y Exportar PDF
presupuesto-{nombre}-{yyyymmdd}.pdf.
La sección Términos y condiciones es un textarea libre. Si está vacía, se omite del PDF; si tiene texto, se imprime al pie del documento antes de la firma. Persiste en localStorage (settings) y sobrevive al cierre del panel.
La barra inferior tiene el botón Exportar PDF + un indicador de último cálculo. Click dispara exportHandler() que serializa el draft a PDF vía src/presupuesto/builder.ts:buildPresupuestoPdfOptions → export-build-pdf.ts. El archivo se descarga con la forma:
presupuesto-{nombre-proyecto}-{yyyymmdd}.pdf
src/assembly-sheet/) — son dos exports distintos
con dos botones distintos.
10 Configuración → Presupuesto
10.1 · Master toggle
[Q], Shift+Q y la persistencia de borradores.
Activar módulo Presupuesto (default off)
controla el módulo entero:
- Off → el botón
[Q]del topbar desaparece, Shift+Q no hace nada, los borradores existentes se preservan enparts.quoteDraft(campo soft del.despiece). - On → todo vuelve a funcionar.
parts.quoteDraft es soft
(src/types/project.ts) — no bump de schema del
.despiece. Sobrevive entre proyectos. Los proyectos
viejos sin presupuesto siguen abriendo normalmente.
10.2 · Cotización por defecto
Cuatro campos que prefilledan cada nuevo presupuesto:
| Campo | Tipo | Default | Significado |
|---|---|---|---|
quoteCurrency | string (≤8 chars) | ARS | Prefijo/sufijo del importe ($, US$, €) |
quoteMarginPct | número (0–200) | 30 | Porcentaje sobre el subtotal |
quoteValidityDays | número (1–365) | 15 | Días hasta la fecha de vencimiento |
quoteFooterTerms | textarea (≤6000) | "" | Texto libre al pie del PDF |
Persiste en localStorage (vía
despiece.settings.v1) y sí entra en el export de
Configuración (la sección presupuesto del IO
config).
getWorkshopBrand(). Si querés
cambiar el logo, editás en Configuración → Taller
(no en Presupuesto).
11 Atajos de teclado
Help (botón de la topbar o ?) abre la hoja completa. Los más usados en el flujo de presupuesto:
| Atajo | Acción |
|---|---|
| Shift+Q | Abre / cierra el panel Presupuesto |
| Esc | Cierra el panel |
| Shift+C | Abre el panel Cliente (per-proyecto) |
| Shift+K | Abre la Agenda de clientes (workshop-global CRM; gated por Settings → Agenda) |
| / | Filtrar lista de piezas (sidebar 2D) |
| B / Shift+B | Auto-cantos ✦ (complementario) |
| I | Aislar selección |
| F / Home | Fit / Fit + iso |
En Mac el modificador de sistema es ⌘; en otros sistemas Ctrl.
settingsEpoch, nestingEpoch,
modelKind, hardwareEpoch,
herrajeriaEpoch). Las ediciones del usuario
(cliente, extras CRUD, margin, currency local edits) NO
causan re-render — los handlers aplican updates quirúrgicos al
DOM preservando foco y scroll entre keystrokes.
Ver también
- Tutorial · Glue-up y Auto-glueup — patrón análogo de settings soft + módulo gated.
- Tutorial · Listones y Auto-lineales — módulo 1D paralelo con su propio catálogo.
- Tutorial · Cantos y auto-cantos — flujo 2D análogo.
- Tutorial · Roles y auto-roles — flujo análogo para
partRole. - Manual § 16 · Presupuesto al cliente — referencia corta de la feature.
- Manual § 11 · Configuración — tab Presupuesto en contexto de la sección de taller.
- Spec
2026-07-19-presupuesto-cliente.md— diseño del módulo, builder y totales.