L'Espai
Cargando…
L'Espai
Planificación estratégica y operativa

📜 Convenio y salarios

Restricciones legales y tabla salarial del convenio

Convenio LaboralRestricciones legales que afectan al generador de horarios y la validación. 3 niveles de horas: ideal (1ª opción), flexible (2ª), puntual (excepcional). Turno seguido = pausa corta, turno partido = pausa larga.
Variables: maxday maxday-flex maxday-punt max6wks (16 sem/año) break-cont break-split rest-between

Restricciones legales. Afectan al generador de cuadrantes y la validación antes de publicar.
8 meses al año
~4 meses al año
1ª opción generador
2ª opción
3ª excepcional
Siempre descontada

Tabla Salarial (Convenio)Niveles salariales del convenio de hostelería. El coste de cada empleado se calcula según su nivel. Se usa para calcular el coste total de personal y la rentabilidad.
Variables: state.salaryLevels base extras coste/hora

Niveles salariales según convenio de hostelería. El coste de cada empleado se calcula automáticamente según su nivel.

📅 Temporadas y festivos

Períodos del año y días especiales

TemporadasPeríodos del año con diferente demanda. Todo se configura por temporada: turnos, horarios, cuadrantes. Las fechas determinan qué semanas del CSV se usan para cada temporada.
Variables: state.seasons name start end color seasonToWeeks()

Define los períodos del año y sus características

📅 Festivos y EventosDías especiales que modifican la demanda esperada. Impacto alto = se comporta como sábado. Medio = +30% sobre día normal. Bajo = +10%.
Variables: state.events date name impact afecta a renderDashboard()

Días especiales que afectan la demanda. Los festivos se comportan como el tipo de día seleccionado para planificación.

🍽 Servicios

Duración, gaps y tickets de cada servicio

Parámetros de Servicio

Duración y gaps entre mesas

📋 Lista de servicios

Crea los servicios base del restaurante. Luego en Calendario servicios los activas por temporada.

👥 Equipos y roles

Equipos, ratios de personal, responsabilidades y aptitudes

Equipos y RolesDefine los equipos de trabajo (Cocina, Sala...) y sus roles. Cada rol tiene un ratio (1 persona cada X pax) y un máximo. El rol principal (⭐) absorbe las responsabilidades de los roles que no existen a baja ocupación.
Variables: state.teams ratio max principal resp[] calcTeamStaff(pax)

Equipos, roles con ratios, y responsabilidades. Fuente única de verdad para todo el sistema.

Aptitudes

Define las habilidades y capacidades que pueden tener los empleados. Los roles pueden requerir aptitudes específicas.

🛡 Reglas de validación

Reglas que se evalúan automáticamente sobre los cuadrantes y horarios. Los avisos aparecen en un panel encima del cuadrante. Tipos: 🛡 Cobertura (mín. de empleados por categoría 4R, equipo y día — se evalúa en cuadrantes) y ⏰ Horario (alguien con una categoría debe estar activo en un tramo concreto — se evalúa en horarios).
💡 Las aptitudes por rol y la cobertura mínima de roles especializados se validan automáticamente desde la configuración de cada rol (Equipos → rol → "Aptitudes:" y "1 cada X"). Verás los avisos marcados como [auto] en el panel de Horarios.

🔐 Acceso por roles

Qué secciones ve cada rol al iniciar sesión con nombre + PIN

Permisos por rol

Activar una sección muestra su grupo desplegable y auto-marca todas sus subsecciones (puedes desmarcarlas individualmente). Si no activas la sección pero marcas subsecciones, estas se muestran sueltas, sin grupo. El Gestor y la cuenta de administración ven todo.

👥 Empleados

Datos de tu plantilla. Nombre, equipo, nivel salarial, contrato.

🏷 Categorías de empleados

Define las categorías de tu equipo. Se usan en Empleados y Horarios.

Plantilla contratada

Cada persona con su equipo (Cocina/Sala), nivel del convenio, horas y fechas de contrato.

📋 Horarios del equipo

Plantillas de horario por tamaño de equipo. Guarda presets para cada configuración.

Temporada:
Día:
Sin configurar

🍽 Servicios activos

🗺 Distribución del equipo

Organización de zonas automática según quién trabaja y sus preferencias

Distribución por nº empleados Presets por cocina × sala. Define zonas y responsabilidades por puesto. Se carga en Servicio del día.

Mapa del restaurante

Arrastra para mover · Esquina ↘ para redimensionar

Zonas del restaurante

📅 Cuadrantes

Quién va a cada puesto cada día de la semana

TEMPORADA:
Sin configurar

📋 Cuadrante semanal

⚖️ Resumen

📅 Vista Semanal

Planificación semana a semana

📊 Cuadrante anual

Click o arrastra para activar/desactivar

📊 Dashboard

Resumen operativo del día

🍽 PAX esperados
Comida:
Cena:
📋 Reservas
Grupos:
PAX grupos:
👥 Staff hoy
🔥 Cocina:
🍽 Sala:
📊 Cobertura
🎭 Grupos y eventos
🌤 Tiempo — Tossa de Mar
Cargando…

📋 Horario del día

🗺 Distribución del día

Cambios solo afectan al día de hoy
Distribución por nº empleados
🔥 Cocina
🍽 Sala
Mapa del restaurante

Análisis de Demanda

Datos reales del CSV · Abr–Nov 2025 · Condicionados por la configuración de reservas activa en ese momento

📈 Ajuste previsión 100%

📂 Importar CSV de Reservas

Sube el CSV exportado de tu gestor de reservas. Se procesa y guarda en el navegador — no necesitas subirlo cada vez.
💡 El CSV debe tener las columnas: Fecha, Hora, Estado, Turno, Personas, Origen (separado por ;)
📌 Actualmente cargado: datos embebidos 2025

🏷 Asignación de semanas CSV a temporadasVincula cada semana del CSV histórico con la temporada correcta. "Auto" usa el número de semana. Si Semana Santa cae en semanas diferentes cada año, asígnala manualmente aquí.
Variables: state.csvSeasonMap getCSVWeeksForSeason_v2() isoWeek() seasonToWeeks()

Vincula cada semana del CSV con la temporada correcta para mejorar las recomendaciones.

📊 Análisis de demanda

Patrones, tendencias y distribución de la demanda histórica

Turno:
Días:
Temporada:
Métrica:

Mesas por franja horaria — Cena

Reserva vs Walk-in · Acumulado

Media diaria por día de la semana — Cena

Mesas promedio por franja horaria según día

Demanda intuida vs Datos reales

Ajusta los sliders para reflejar lo que TÚ crees que la gente querría reservar (sin restricciones de hora).

Ranking de franjas

Heatmap semanal

Mesas por franja horaria, semana a semana · Las bandas de color indican temporadas

🔮 Planificador por temporada

Simula el impacto de tus decisiones. Cambia variables y ve el resultado en tiempo real.

Temporada:

📊 Demanda Cálculo: getCSVWeeksForSeason(temporada) → suma reservas × avgPPR (media pax/reserva). Resultado: pax estimados por semana para esta temporada.

👥 Personal calcTeamStaff(avgPaxDay): para cada rol, base = ceil(pax/ratio_principal). Ratios en Config → Equipos y roles.

💰 Resultado Revenue = pax × ticket. Coste = Σ empleados × salario. Margen = (revenue-coste)/revenue × 100.

📋 Plantilla recomendada por temporada Plantilla = ceil(staff_necesario × días_abiertos / max_días_semana). Compara con empleados contratados activos.

Personal necesario por equipo, comparado con tu plantilla actual. Basado en demanda CSV × ratios × convenio.

🔮 ¿Y si...?

Simula contrataciones o cambios de apertura.

Simulador de Rentabilidad

¿Me sale rentable abrir? Estimaciones basadas en demanda y costes

P&L Semanal Estimado Revenue de turnos × ticket × días. Coste = Σ salarios. Margen = beneficio/revenue.

Ingresos vs Costes por semana — semanas en rojo no alcanzan el % de rentabilidad mínimo

Análisis por Semana

Detalle de rentabilidad estimada

💰 Coste por servicioP&L desglosado por servicio (Comida vs Cena). Revenue de cada servicio (ticket × pax estimados) menos el coste de personal asignado a ese servicio.
Variables: shiftPresets services staffCost revenue per service

P&L desglosado por servicio (Comida vs Cena vs otros)

Objetivos por Categoría de Gasto (%)

Porcentaje objetivo sobre facturación para cada tipo de gasto
Total costes: 0%
Rentabilidad resultante: 0%

Turnos de Reserva

Configura servicios, turnos, comensales y revenue estimado

Temporada:
Día:

💰 Revenue estimado

📊 Comparativa de presets

📅 Calendario de servicios

Decide qué días abres, qué servicios ofreces y la operativa de cada temporada

Temporada:
Día:

📊 Vista semanal de servicios

Servicios activos por día — clic para activar/desactivar

⏱ Horas disponibles vs necesarias Base = empleados × horas contrato/sem. Redist = +% redistribuible del convenio. 6d/sem = +8h por empleado con 6d activo. Fijas = tareas que no dependen del servicio.

🔧 Tareas fijas Horas que se necesitan independientemente de la demanda. Semanal = fijo. Diario = × días abiertos. Por comensal = × pax estimados (en minutos por persona).

Mise en place, limpieza, producción... Se restan de las horas disponibles.

💡 Recomendación de apertura Calcula opciones de días abiertos comparando horas disponibles con horas necesarias (servicio + tareas fijas). Ordena los días a cerrar por menor demanda.

Operativa Config manual por temporada × día: apertura, cierre, prep, limpieza, pausa.

Días abiertos, horarios al público y tiempos de montaje/cierre. Varía por temporada.

Servicios Activos Pax por servicio = estPaxDía × (franjas en rango / total franjas). Los servicios base vienen de Config → Servicios.

Qué servicios ofreces esta temporada y sus franjas horarias

📊 Demanda semanal Barras = avgPaxWeek × dayWeight. Solo varía por temporada seleccionada.

Promedio de pax por día según CSV para esta temporada

💡 Vista semanal Tabla resumen: días, pax, staff (calcTeamStaff), servicios activos, horarios.

Resumen completo de la temporada

📅 Horarios por roles

Estaciones de trabajo generadas automáticamente desde la demanda. Ajusta si lo necesitas.

Temporada:
Día:

📊 Horario del día Pax = OCUPACIÓN (reservas × duración servicio). Ideal = calcTeamStaff(pax) por equipo. Real = tus roles. Rojo = faltan.

📆 Calendario Anual

Horarios publicados semana a semana. Clic en una semana para ver, editar o descargar.

👥 Asignación persona → puesto

Asigna empleados a estaciones para la semana

📤 Publicar

Publica para que los empleados la vean

Año 2026

⬜ Vacía ✅ Publicada ✏ Editada 🚫 Cerrado

📋 Cuadrante de descansos

Quién trabaja y quién descansa cada día. Auto-generado respetando el convenio.

Temporada:
Régimen:

💡 Necesidades por día Staff = calcTeamStaff(estPax). estPax = avgPaxWeek × dayWeight. Solo días abiertos.

Calculado desde Horarios por roles

📋 Cuadrante semanal Grid persona × día. Auto-generar reparte descansos priorizando días de baja demanda.

Clic en una celda para cambiar trabajo/descanso

⚖️ Equidad Días y fines de semana trabajados por persona. Objetivo: distribución equitativa.

🎯 Servicio del día

Herramienta operativa pre-servicio

🗺 Mapa de zonas

Distribución automática según preset más cercano

EntradaInput operativo: previsión de pax (slider) y equipo disponible hoy (nº por rol). Debajo de cada input aparece "rec:X" con la recomendación de calcTeamStaff para los pax seleccionados.
Variables: calcTeamStaff(pax) actual por rol

Previsión
50 pax
Equipo hoy

📋 Mi horario

Vista de tu semana — extraído de la Vista Semanal publicada

Semana actual
Selecciona un empleado para ver su horario

✅ Checklist de pruebas

Prueba cada sección de arriba a abajo. Los checks se guardan en el navegador.

✅ Checklist de pruebas

Prueba cada sección de arriba a abajo. Los checks se guardan en el navegador.

📖 Carta (platos)

Todos los platos con su PVP y coste. La rentabilidad y el margen se calculan solos.

Platos
0
en la carta
Categorías
0
PVP medio
0 €
Margen medio
0 €
Rentabilidad media
0x
food cost —
ℹ️
Rentabilidad vs Food cost % — son la misma métrica al revés. Xx = cuántas veces multiplico el coste (más alto, mejor). % = qué porcentaje del PVP se va en materia prima (más bajo, mejor, objetivo ≤ 30%). Ejemplos: 3,3x = 30% · 4x = 25% · 5x = 20% · 2x = 50%. Ajustar umbrales de color →

🏷 Categorías de platos

Organiza la carta en secciones. Arrástralas con las flechas para cambiar el orden.

🏷 Prioridad de venta

Gestiona qué platos priorizar hoy, qué no está disponible, y el ranking general por rentabilidad.

⭐ Priorizar hoy

❌ No disponible hoy

Ordenar:

📋 Menús

Crea y guarda menús por categoría. Cada menú tiene un tamaño base (pax) y escala proporcionalmente.

➕ Extras

Lista maestra de extras reutilizables. Añádelos a los eventos desde aquí sin repetirte.

ℹ️
Los extras se crean aquí una sola vez y luego se seleccionan desde cada evento (sección "Grupos y Eventos"). Si editas un extra aquí, se actualizará automáticamente en todos los eventos que lo usen.

🧾 Extras maestros

Cada extra tiene un nombre, precio y modo (total o por pax).

⚙️ Configuración

Ajusta los umbrales de color (verde / amarillo / rojo) usados en toda la aplicación.

ℹ️
Estos valores determinan cuándo los números de margen, rentabilidad y food cost se muestran en color en toda la app (Carta, Prioridad venta, Menús y Cocina). Rentabilidad y food cost son la misma métrica al revés — al cambiar uno te actualizo el equivalente.

🎨 Umbrales de color

Verde = bueno, amarillo = aceptable, rojo = revisar.

👁 Vista previa

Así se verán los colores con los valores actuales.

📅 Grupos y Eventos

Crea el evento: selecciona menú, pax, bebida, extras y opciones. Cocina verá qué y cuánto hay que cocinar.

✕ Salir

🔧 Desarrollo

Roadmap, documentación, arquitectura y notas de producto

🗺 Mapa de procesos

Todo el flujo del producto en una pantalla
🟠 CONFIGURAR
1× al año · 👔 Gestor
1. Reglas convenio, salarial, temporadas, equipos
2. Zonas mapa, distribución tipo
3. Empleados equipo, nivel, contrato
4. Demanda CSV reservas históricas
🔵 SIMULAR
×temporada · 👔 Gestor
5. Planificador ¿cuántos? ¿rentable? ¿y si...?
6. Turnos escalones, capacidad, ticket
7. Rentabilidad P&L, objetivos, márgenes
DECISIÓN: ¿contrato? ¿qué días abro?
🟢 PROGRAMAR
×semana · 📋 Encargado
8. Cuadrante quién trabaja/descansa
9. Horarios estaciones × día + recomendación
10. Publicar calendario → empleados ven
DECISIÓN: horarios y descansos
🟣 OPERAR
×día · 🎯 Jefe turno · 👤 Empleado
11. Dashboard pax, staff, cobertura
12. Servicio distribución zonas+resp
13. Portal mi horario, fichar
DECISIÓN: distribución del día
Flujo de datos: CSV Demanda → calcTeamStaff(pax) → Necesito vs Tengo → Revenue − Coste = Margen → Horarios auto → Cuadrante auto → Servicio auto

📋 Roadmap del producto

V1 ✓Configuración, demanda CSV, turnos, personal, rentabilidad básica
V2 ✓Equipos y roles, convenio, cuadrante, portal empleado, dashboard
V3 · ActualSimulador, 4 espacios, per-day config, festivos, zonas restauradas
V3.2 ✓Timeline de recomendación en Horarios, sidebar colapsable, Finanzas
V3.3📅 Calendario de apertura: vista anual días/servicios recomendados vs decididos
V3.4📋 Flujo de programación: 1)Apertura → 2)Horarios → 3)Cuadrante → 4)Asignar personas → 5)Publicar
V4Generador automático completo (horarios + cuadrante + distribución)
V5CSV facturación real, nacionalidad clientes, Google Script finanzas

📝 Pendientes y próximos pasos

🔴 Bugs urgentes
autoGenRolesFromDemand arreglado (v3.2.6)
generateSchedule reemplazado por autoAssignRoles (v3.3.6)
Timeline pax arreglado con fallback global (v3.3.7)
🟠 V3.3 — Calendario de apertura
📅 Análisis demanda por día — En "Análisis demanda" añadir charts de demanda por día de la semana × temporada. No solo por hora.
📅 Vista calendario anual — Subsección en Programación: cada día del año = recomendado abrir/cerrar + qué servicios. Vista tipo heatmap anual.
📅 Decisión Planificador → Apertura — El Planificador decide días de apertura por temporada. Eso alimenta el calendario de apertura.
🔵 V3.4 — Flujo de programación (5 pasos)
1️⃣ Apertura — ¿Qué días abro? ¿Qué servicios? (calendario anual con recomendación)
2️⃣ Horarios — ¿Cómo es cada día? Timeline 30min con estaciones + zonas + responsabilidades
3️⃣ Cuadrante — ¿Quién descansa? Grid personas × días con auto-rotación
4️⃣ Asignar personas — ¿Quién va a qué puesto? Grid personas × estaciones
5️⃣ Publicar — Calendario → empleados ven su horario
🟢 Zonas y distribución
🗺 Presets por cocina × sala — Inputs de cocina/sala FUERA de los recuadros. Son los "presets". Al cambiar nº, el mapa y zonas cambian también.
🗺 Guardar distribución por preset — Mapa + zonas abiertas + mesas asignadas se guardan por combinación cocina×sala
🗺 Validación de mesas — Avisar si asigno más mesas de las que el ratio permite cubrir
🟣 Mejoras pendientes
🏷 Nivel salarial — Mostrar nombre descriptivo al lado del número en Empleados
📊 Tooltips ⓘ — Cada subsección con explicación de cómo se calcula (hover)
🔄 Deprecar state.depts — 28 refs restantes, safe via syncDeptsFromTeams
🎯 Servicio del día — Mostrar mapa de zonas automático según preset de distribución

📄 Documentación del producto

Clic en un documento para ver el resumen
📈 Manual Inversor ▸ clic
📋 Manual Equipo v2 ▸ clic
🔮 Rediseño v3 ▸ clic
🏗 Guía del Sistema ▸ clic
📊 Análisis Producto v1+v2 ▸ clic
📋 Manual Equipo v1
📖 Manual Usuario v3.4
🟡 Pendientes v3.16
🐛 moveToOtherTeam ghost columns — Al mover un empleado de vuelta a su equipo original, se crea una columna fantasma. Refactor para usar datos en vez de DOM.
👥 Grid headers + cuadrante — Filtrar empleados en headers del grid por los que están activos ese día (cruzar staffRoster + trData).
🧹 Zona columns cleanup — Verificar celdas huérfanas de Zona 1/2/3 en tabla empleados.
🖥 Screen modes polish — Ajustar CSS screen-lg/screen-xl para todos los módulos.
📊 Apertura hours calc — Bug de renderizado en cálculo de horas.
📂 CSV re-import — Re-importar para formato rawByDate.
Flujo completo, fórmulas de cálculo, problemas conocidos. Generado abril 2026.

🏗 Arquitectura técnica

Para replicar como app real. Clic en cada sección para expandir.
📦 Modelo de datos
state.teams[] = {id, name, icon, color, roles: [{id, name, ratio, max, principal, resp[]}]}
state.seasons[] = {name, start, end, color}
state.salaryLevels[] = {name, base, extras}
state.services[] = {name, start, end, active, prep}
state.events[] = {date, name, impact}
state.responsibilities[] = {id, name, icon, tipo}
state.aptitudes[] = {id, name, icon, items[]}
staffRoster[] = {name, team, role, category, salaryLevel, hours, contractStart, contractEnd, daysAvail, redistOk, sixDayOk, aptitudes[], responsibilities[], blocks[]}
seasonSchConfigs{} = {[season_dN]: {roles[], open, close, prep, cleanup, pauseStart, pauseEnd}}
rosterData{} = {[season_regime]: {[empName]: [0,1,1,1,1,1,0]}}
alignPresets[] = {name, zones: [{id,name,color,mesas,pax,x,y}], _assignments{}}
🔧 Funciones clave
calcTeamStaff(pax) → {total, cocina, sala, [roleId]:count} // La función central
_rawTeamCalc(pax, team) → base=ceil(pax/principal.ratio), specialists...
getCSVWeeksForSeason(season) → [{w, ws, d:{}}] // CSV data filtered
renderSimulator() → 3 paneles: demanda, personal, resultado
autoGenRolesFromDemand() → CSV curve → calcTeamStaff(peak) → schRoles[]
generateFromRoster() → cuadrante × horarios = asignación persona→puesto
generateSchedule() → roles + staff → optimized schedule
renderServicioDia() → pax slider + staff → distribución + cascada resp
syncDeptsFromTeams() → state.teams → state.depts (legacy compat)
getTipo(roleOrDept) → 'cocina'|'sala' // reads state.teams first
💾 AppStorage schema
lespai-config → {seasons, teams, salaryLevels, services, events, staffRoster, costs, conv*, ...}
lespai-calendar → {weeks: {[weekKey]: {schedule, closed[]}}}
lespai-shift-presets → {presets[], active, seasonMap{}}
lespai-align-presets → {presets[], active, seasonMap{}}
lespai-csv-data → parsed CSV object
lespai-roster → {[season_regime]: {[name]: [0,1,1,1,1,1,0]}}
lespai-role → 'owner'|'manager'|'shift'|'employee'|'all'
lespai-clock-{name} → [{type:'entrada',time,date}]
⚙️ Stack técnico
Frontend: HTML standalone (single file), vanilla JS, CSS custom properties
Fonts: DM Sans (UI), Playfair Display (títulos) — Google Fonts CDN
Charts: Chart.js (via CDN) para gráficos de demanda
Storage: AppStorage (8 keys, ~500KB max total)
Export: JSON bundled (config + calendar + presets)
Theme: Dark mode con --accent:#F97316, --green:#34D399, --blue:#38BDF8
Para migrar a app real: Separar estado en backend (API REST), autenticación por usuario, base de datos relacional (PostgreSQL recomendado), PWA para móvil, WebSocket para actualizaciones en tiempo real del servicio del día.
🎨 Design tokens
--bg:#0f0f0f · --bg2:#1a1a1a · --bg3:#242424
--text:#e8e6df · --text2:#b8b6ad · --text3:#888680 · --text4:#555
--accent:#F97316 · --green:#34D399 · --blue:#38BDF8
--purple:#A78BFA · --red:#EF4444 · --yellow:#FBBF24
--teal:#0D9488 · --pink:#F472B6
--border:rgba(255,255,255,.06)
Font body: 'DM Sans' 13px · Font headers: 'Playfair Display'
PASE 1
>