Sincronizando con Google Drive...
Formulario de Reserva
Gestionar mi Reserva
Introduce el código único de tu reserva enviado en tu confirmación (ej: RES-1001) para modificar tu mesa o cancelarla.
Información del Restaurante
Nuestra propuesta culinaria se basa en productos frescos de temporada con técnicas innovadoras. Rogamos puntualidad para garantizar una experiencia gastronómica óptima.
Garantía de Confirmación Inmediata
Al reservar, tu mesa queda bloqueada en nuestra base de datos al instante. No requerimos fianza excepto para grupos de más de 8 personas.
Acceso Privado
Introduce las credenciales para acceder al Panel de Control
Panel de Control de Reservas
Sesión ActivaAdministra el aforo, gestiona la programación semanal de turnos y consulta la base de datos.
Hoy Reservado
0
Total comensales esperados hoy
Total Histórico
0
Reservas registradas
Turno Más Solicitado
Cena 21:00
Mayor volumen acumulado
Sincronización
Drive Desvinculado
Auto-organizado por pestañas
Programación Semanal
Configura los turnos activos y aforos para cada día de la semana.
Modificando: Lunes
➕ Añadir turno para este día
🔗 Vincular Google Sheets
Envía las reservas automáticamente a tu hoja real en Google Drive.
A: ID | B: Fecha | C: Nombre | D: Teléfono | E: Email | F: Pax | G: Menús Niños | H: Tronas | I: Intolerantes | J: Para Llevar | K: Turno | L: Notas
⚠️ PASO CRUCIAL EN GOOGLE DRIVE:
Tras pegar el código, ve a Implementar > Gestionar implementaciones > Editar (icono lápiz) > Versión: Nueva versión y haz clic en Implementar. Si no creas una nueva versión, Google seguirá ejecutando el script antiguo y no guardará las tronas ni los intolerantes.
- Abre tu hoja de Google Drive: Reservas_Bistro_Principal.
- En el menú superior, ve a Extensiones > Apps Script.
- Sustituye todo el código por el bloque inteligente de abajo (detecta y auto-corrige encabezados antiguos).
- Guarda y crea una Nueva Versión de la implementación.
function doGet(e) {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var rows = sheet.getDataRange().getValues();
if (rows.length <= 1) {
return ContentService.createTextOutput(JSON.stringify([])).setMimeType(ContentService.MimeType.JSON);
}
var headers = rows[0].map(function(h) { return h.toString().toLowerCase().trim(); });
function getColIdx(name, defaultIdx) {
var idx = headers.indexOf(name);
return idx !== -1 ? idx : defaultIdx;
}
var idxId = getColIdx("id reserva", 0);
var idxFecha = getColIdx("fecha", 1);
var idxNombre = getColIdx("nombre", 2);
var idxTel = headers.indexOf("teléfono") !== -1 ? headers.indexOf("teléfono") : getColIdx("telefono", 3);
var idxEmail = getColIdx("email", 4);
var idxPax = getColIdx("pax", 5);
var idxNinos = headers.indexOf("menús niños") !== -1 ? headers.indexOf("menús niños") : getColIdx("menus ninos", 6);
var idxTronas = getColIdx("tronas", 7);
var idxIntol = headers.indexOf("intolerantes") !== -1 ? headers.indexOf("intolerantes") : getColIdx("intolerancias", 8);
var idxLlevar = getColIdx("para llevar", 9);
var idxTurno = getColIdx("turno", 10);
var idxNotas = getColIdx("notas", 11);
var reservations = [];
for (var i = 1; i < rows.length; i++) {
var row = rows[i];
if (!row[0] && !row[idxId]) continue;
var dateVal = row[idxFecha];
if (dateVal instanceof Date) {
dateVal = Utilities.formatDate(dateVal, Session.getScriptTimeZone(), "yyyy-MM-dd");
} else {
dateVal = dateVal ? dateVal.toString() : "";
}
reservations.push({
id: row[idxId] ? row[idxId].toString() : "",
fecha: dateVal,
nombre: row[idxNombre] ? row[idxNombre].toString() : "",
telefono: row[idxTel] ? row[idxTel].toString() : "",
email: row[idxEmail] ? row[idxEmail].toString() : "",
personas: parseInt(row[idxPax]) || 0,
menu_infantil: parseInt(row[idxNinos]) || 0,
tronas: parseInt(row[idxTronas]) || 0,
num_intolerancias: parseInt(row[idxIntol]) || 0,
para_llevar: row[idxLlevar] ? row[idxLlevar].toString() : "NO",
turno: row[idxTurno] ? row[idxTurno].toString() : "",
notas: row[idxNotas] ? row[idxNotas].toString() : ""
});
}
return ContentService.createTextOutput(JSON.stringify(reservations))
.setMimeType(ContentService.MimeType.JSON);
}
function doPost(e) {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var payload = JSON.parse(e.postData.contents);
var action = payload.action;
var data = payload.data;
var standardHeaders = ["ID Reserva", "Fecha", "Nombre", "Teléfono", "Email", "Pax", "Menús Niños", "Tronas", "Intolerantes", "Para Llevar", "Turno", "Notas"];
if (sheet.getLastRow() === 0) {
sheet.appendRow(standardHeaders);
sheet.getRange(1, 1, 1, 12).setFontWeight("bold").setBackground("#065f46").setFontColor("#ffffff");
sheet.setFrozenRows(1);
} else {
var firstRow = sheet.getRange(1, 1, 1, 12).getValues()[0];
if (!firstRow[0] || firstRow[0].toString().toLowerCase().indexOf("id") === -1) {
sheet.insertRowBefore(1);
sheet.getRange(1, 1, 1, 12).setValues([standardHeaders]).setFontWeight("bold").setBackground("#065f46").setFontColor("#ffffff");
sheet.setFrozenRows(1);
}
}
var rows = sheet.getDataRange().getValues();
var currentHeaders = sheet.getRange(1, 1, 1, Math.max(sheet.getLastColumn(), 12)).getValues()[0].map(function(h) { return h.toString().toLowerCase().trim(); });
function getColIdx(name, defaultIdx) {
var idx = currentHeaders.indexOf(name);
return idx !== -1 ? idx : defaultIdx;
}
var idxId = getColIdx("id reserva", 0);
var idxFecha = getColIdx("fecha", 1);
var idxNombre = getColIdx("nombre", 2);
var idxTel = currentHeaders.indexOf("teléfono") !== -1 ? currentHeaders.indexOf("teléfono") : getColIdx("telefono", 3);
var idxEmail = getColIdx("email", 4);
var idxPax = getColIdx("pax", 5);
var idxNinos = currentHeaders.indexOf("menús niños") !== -1 ? currentHeaders.indexOf("menús niños") : getColIdx("menus ninos", 6);
var idxTronas = getColIdx("tronas", 7);
var idxIntol = currentHeaders.indexOf("intolerantes") !== -1 ? currentHeaders.indexOf("intolerantes") : getColIdx("intolerancias", 8);
var idxLlevar = getColIdx("para llevar", 9);
var idxTurno = getColIdx("turno", 10);
var idxNotas = getColIdx("notas", 11);
if (action === 'create') {
var newRow = new Array(12);
newRow[idxId] = data.id;
newRow[idxFecha] = data.fecha;
newRow[idxNombre] = data.nombre;
newRow[idxTel] = data.telefono;
newRow[idxEmail] = data.email;
newRow[idxPax] = data.personas;
newRow[idxNinos] = data.menu_infantil;
newRow[idxTronas] = data.tronas;
newRow[idxIntol] = data.num_intolerancias;
newRow[idxLlevar] = data.para_llevar;
newRow[idxTurno] = data.turno;
newRow[idxNotas] = data.notas;
sheet.appendRow(newRow);
return ContentService.createTextOutput(JSON.stringify({status: "success"})).setMimeType(ContentService.MimeType.JSON);
}
var rowIndex = -1;
for (var i = 1; i < rows.length; i++) {
if (rows[i][idxId] && rows[i][idxId].toString().trim() === data.id.toString().trim()) {
rowIndex = i + 1;
break;
}
}
if (rowIndex !== -1) {
if (action === 'update') {
var rowRange = sheet.getRange(rowIndex, 1, 1, 12);
var rowVals = rowRange.getValues()[0];
rowVals[idxId] = data.id;
rowVals[idxFecha] = data.fecha;
rowVals[idxNombre] = data.nombre;
rowVals[idxTel] = data.telefono;
rowVals[idxEmail] = data.email;
rowVals[idxPax] = data.personas;
rowVals[idxNinos] = data.menu_infantil;
rowVals[idxTronas] = data.tronas;
rowVals[idxIntol] = data.num_intolerancias;
rowVals[idxLlevar] = data.para_llevar;
rowVals[idxTurno] = data.turno;
rowVals[idxNotas] = data.notas;
rowRange.setValues([rowVals]);
return ContentService.createTextOutput(JSON.stringify({status: "success"})).setMimeType(ContentService.MimeType.JSON);
} else if (action === 'delete') {
sheet.deleteRow(rowIndex);
return ContentService.createTextOutput(JSON.stringify({status: "success"})).setMimeType(ContentService.MimeType.JSON);
}
}
return ContentService.createTextOutput(JSON.stringify({status: "error"})).setMimeType(ContentService.MimeType.JSON);
}Reservas_Bistro_Principal.xlsx Google Drive Linked
Actualizado bidireccionalmente con tu hoja de Google Drive
| ID | Fecha Reserva | Nombre Cliente | Teléfono | Pax | Menús Niños | Tronas | Intolerantes | Para Llevar | Turno / Horario | Notas / Petición | Acciones |
|---|
No hay reservas en esta pestaña mensual
Las reservas que coincidan con este mes se filtrarán aquí automáticamente.
Añadir Reserva Manual
Usa esto para reservas telefónicas o clientes de paso.
Editar Reserva
Modifica los detalles de la reserva de forma manual.
Editar Turno
Modifica el nombre y aforo de este turno para los .
