diff --git a/services/manso/package-lock.json b/services/manso/package-lock.json
index 0a0679e..c775380 100644
--- a/services/manso/package-lock.json
+++ b/services/manso/package-lock.json
@@ -1,17 +1,18 @@
{
- "name": "aplication",
+ "name": "workarround",
"version": "1.0.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
- "name": "aplication",
+ "name": "workarround",
"version": "1.0.0",
"license": "ISC",
"dependencies": {
"chalk": "^5.6.0",
"cors": "^2.8.5",
"dotenv": "^17.2.1",
+ "ejs": "^3.1.10",
"express": "^5.1.0",
"express-ejs-layouts": "^2.5.1",
"pg": "^8.16.3",
@@ -56,11 +57,16 @@
"node": ">= 8"
}
},
+ "node_modules/async": {
+ "version": "3.2.6",
+ "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz",
+ "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==",
+ "license": "MIT"
+ },
"node_modules/balanced-match": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
- "dev": true,
"license": "MIT"
},
"node_modules/binary-extensions": {
@@ -345,6 +351,21 @@
"integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==",
"license": "MIT"
},
+ "node_modules/ejs": {
+ "version": "3.1.10",
+ "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz",
+ "integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "jake": "^10.8.5"
+ },
+ "bin": {
+ "ejs": "bin/cli.js"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/encodeurl": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz",
@@ -446,6 +467,36 @@
"resolved": "https://registry.npmjs.org/express-ejs-layouts/-/express-ejs-layouts-2.5.1.tgz",
"integrity": "sha512-IXROv9n3xKga7FowT06n1Qn927JR8ZWDn5Dc9CJQoiiaaDqbhW5PDmWShzbpAa2wjWT1vJqaIM1S6vJwwX11gA=="
},
+ "node_modules/filelist": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz",
+ "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "minimatch": "^5.0.1"
+ }
+ },
+ "node_modules/filelist/node_modules/brace-expansion": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz",
+ "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0"
+ }
+ },
+ "node_modules/filelist/node_modules/minimatch": {
+ "version": "5.1.6",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz",
+ "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==",
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
"node_modules/fill-range": {
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
@@ -732,6 +783,23 @@
"dev": true,
"license": "ISC"
},
+ "node_modules/jake": {
+ "version": "10.9.4",
+ "resolved": "https://registry.npmjs.org/jake/-/jake-10.9.4.tgz",
+ "integrity": "sha512-wpHYzhxiVQL+IV05BLE2Xn34zW1S223hvjtqk0+gsPrwd/8JNLXJgZZM/iPFsYc1xyphF+6M6EvdE5E9MBGkDA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "async": "^3.2.6",
+ "filelist": "^1.0.4",
+ "picocolors": "^1.1.1"
+ },
+ "bin": {
+ "jake": "bin/cli.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
"node_modules/math-intrinsics": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
@@ -1018,6 +1086,12 @@
"split2": "^4.1.0"
}
},
+ "node_modules/picocolors": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
+ "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
+ "license": "ISC"
+ },
"node_modules/picomatch": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
diff --git a/services/manso/package.json b/services/manso/package.json
index de9666f..8b22432 100644
--- a/services/manso/package.json
+++ b/services/manso/package.json
@@ -18,6 +18,7 @@
"chalk": "^5.6.0",
"cors": "^2.8.5",
"dotenv": "^17.2.1",
+ "ejs": "^3.1.10",
"express": "^5.1.0",
"express-ejs-layouts": "^2.5.1",
"pg": "^8.16.3",
diff --git a/services/manso/src/index.js b/services/manso/src/index.js
index d428d8c..b4fd77c 100644
--- a/services/manso/src/index.js
+++ b/services/manso/src/index.js
@@ -35,6 +35,18 @@ app.use(express.json());
app.use(express.json({ limit: '1mb' }));
app.use(express.static(path.join(__dirname, 'pages')));
+
+// ----------------------------------------------------------
+// Motor de vistas EJS
+// ----------------------------------------------------------
+app.set("views", path.join(__dirname, "views"));
+app.set("view engine", "ejs");
+app.use(expressLayouts);
+app.set("layout", "layouts/main");
+
+// Archivos estáticos
+app.use(express.static(path.join(__dirname, "public")));
+
// ----------------------------------------------------------
// Configuración de conexión PostgreSQL
// ----------------------------------------------------------
@@ -50,16 +62,6 @@ const dbConfig = {
const pool = new Pool(dbConfig);
-// Helper de consulta con acquire/release explícito (del código original, referencial)
-// async function q(text, params) {
-// const client = await pool.connect();
-// try {
-// return await client.query(text, params);
-// } finally {
-// client.release();
-// }
-// }
-
// ----------------------------------------------------------
// Seguridad: Tablas permitidas
// ----------------------------------------------------------
@@ -167,13 +169,45 @@ async function pickLabelColumn(client, refTable) {
return rows[0]?.column_name || 'id';
}
+// ----------------------------------------------------------
+// Middleware para datos globales
+// ----------------------------------------------------------
+app.use((req, res, next) => {
+ res.locals.currentPath = req.path;
+ res.locals.pageTitle = "SuiteCoffee";
+ res.locals.pageId = "";
+ next();
+});
+
+
// ----------------------------------------------------------
// Rutas de UI
// ----------------------------------------------------------
-app.get('/', (req, res) => {
- res.sendFile(path.join(__dirname, 'pages', 'dashboard.html'));
+
+app.get("/", (req, res) => {
+ res.locals.pageTitle = "Inicio";
+ res.locals.pageId = "home";
+ res.render("estadoComandas");
});
+// app.get('/', (req, res) => {
+// res.sendFile(path.join(__dirname, 'pages', 'dashboard.html'));
+// });
+
+app.get('/comandas', (req, res) => {
+ res.sendFile(path.join(__dirname, 'pages', 'comandas.html'));
+});
+
+app.get("/estadoComandas", (req, res) => {
+ res.locals.pageTitle = "Estado de Comandas";
+ res.locals.pageId = "estadoComandas";
+ res.render("estadoComandas");
+});
+
+// app.get('/estadoComandas', (req, res) => {
+// res.sendFile(path.join(__dirname, 'pages', 'estadoComandas.html'));
+// });
+
// ----------------------------------------------------------
// API
// ----------------------------------------------------------
@@ -291,6 +325,85 @@ app.post('/api/table/:table', async (req, res) => {
}
});
+// Listado (con join) y totales por comanda
+app.get('/api/comandas', async (req, res, next) => {
+ try {
+ const estado = (req.query.estado || '').trim();
+ const limit = Math.min(parseInt(req.query.limit || '200', 10), 1000);
+ const params = [];
+ let where = '';
+ if (estado) { params.push(estado); where = `WHERE c.estado = $${params.length}`; }
+ params.push(limit);
+
+ const sql = `
+ WITH items AS (
+ SELECT d.id_comanda,
+ COUNT(*) AS items,
+ SUM(d.cantidad * d.pre_unitario) AS total
+ FROM deta_comandas d
+ GROUP BY d.id_comanda
+ )
+ SELECT
+ c.id_comanda, c.fec_creacion, c.estado, c.observaciones,
+ u.id_usuario, u.nombre AS usuario_nombre, u.apellido AS usuario_apellido,
+ m.id_mesa, m.numero AS mesa_numero, m.apodo AS mesa_apodo,
+ COALESCE(i.items, 0) AS items,
+ COALESCE(i.total, 0) AS total
+ FROM comandas c
+ JOIN usuarios u ON u.id_usuario = c.id_usuario
+ JOIN mesas m ON m.id_mesa = c.id_mesa
+ LEFT JOIN items i ON i.id_comanda = c.id_comanda
+ ${where}
+ ORDER BY c.id_comanda DESC
+ LIMIT $${params.length}
+ `;
+ const client = await pool.connect();
+ try {
+ const { rows } = await client.query(sql, params);
+ res.json(rows);
+ } finally { client.release(); }
+ } catch (e) { next(e); }
+});
+
+// Detalle de una comanda (con nombres de productos)
+app.get('/api/comandas/:id/detalle', async (req, res, next) => {
+ try {
+ const id = parseInt(req.params.id, 10);
+ if (!id) return res.status(400).json({ error: 'id inválido' });
+
+ const sql = `
+ SELECT d.id_det_comanda, d.id_producto, p.nombre AS producto_nombre,
+ d.cantidad, d.pre_unitario, (d.cantidad * d.pre_unitario) AS subtotal,
+ d.observaciones
+ FROM deta_comandas d
+ JOIN productos p ON p.id_producto = d.id_producto
+ WHERE d.id_comanda = $1
+ ORDER BY d.id_det_comanda
+ `;
+ const { rows } = await pool.query(sql, [id]);
+ res.json(rows);
+ } catch (e) { next(e); }
+});
+
+// Cambiar estado (abrir/cerrar)
+app.post('/api/comandas/:id/estado', async (req, res, next) => {
+ try {
+ const id = parseInt(req.params.id, 10);
+ let { estado } = req.body || {};
+ if (!id) return res.status(400).json({ error: 'id inválido' });
+
+ const allowed = new Set(['abierta','cerrada','pagada','anulada']);
+ if (!allowed.has(estado)) return res.status(400).json({ error: 'estado inválido' });
+
+ const { rows } = await pool.query(
+ `UPDATE comandas SET estado = $2 WHERE id_comanda = $1 RETURNING *`,
+ [id, estado]
+ );
+ if (!rows.length) return res.status(404).json({ error: 'comanda no encontrada' });
+ res.json({ updated: rows[0] });
+ } catch (e) { next(e); }
+});
+
// ----------------------------------------------------------
// Verificación de conexión
// ----------------------------------------------------------
@@ -310,7 +423,6 @@ async function verificarConexion() {
// ----------------------------------------------------------
// Inicio del servidor
// ----------------------------------------------------------
-app.use(expressLayouts);
const PORT = process.env.PORT ? Number(process.env.PORT) : 3000;
app.listen(PORT, () => {
diff --git a/services/manso/src/pages/categorias.html b/services/manso/src/pages/categorias.html
deleted file mode 100644
index 0a61191..0000000
--- a/services/manso/src/pages/categorias.html
+++ /dev/null
@@ -1,70 +0,0 @@
-
-
-
-
- Categorías
-
-
- Categorías
-
- Crear categoría
-
-
- Listado
-
-
-
-
-
-
diff --git a/services/manso/src/pages/comandas.html b/services/manso/src/pages/comandas.html
new file mode 100644
index 0000000..93c6e5d
--- /dev/null
+++ b/services/manso/src/pages/comandas.html
@@ -0,0 +1,355 @@
+
+
+
+
+
+ Comandas
+
+
+
+
+ 📋 Nueva Comanda
+
+ /api/*
+
+
+
+
+
+
+
Productos
+
+
+ 0 ítems
+
+
+
+
+
+
+
+ Detalles
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
La fecha se completa automáticamente y los estados/activos usan sus valores por defecto.
+
+
+
Carrito
+
+
Aún no agregaste productos.
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/services/manso/src/pages/estadoComandas.html.bak b/services/manso/src/pages/estadoComandas.html.bak
new file mode 100644
index 0000000..dd69c9a
--- /dev/null
+++ b/services/manso/src/pages/estadoComandas.html.bak
@@ -0,0 +1,280 @@
+
+
+
+
+
+
+ Estado de Comandas
+
+
+
+
+
+
+
+
+
+
Listado
+
+
+
+
+
+
+
+
+
+
+
Selecciona una comanda para ver el detalle.
+
+
+
+
+
+
+
+
+
diff --git a/services/manso/src/pages/productos.html b/services/manso/src/pages/productos.html
deleted file mode 100644
index 82f164f..0000000
--- a/services/manso/src/pages/productos.html
+++ /dev/null
@@ -1,106 +0,0 @@
-
-
-
-
- Productos
-
-
- Productos
-
- Crear producto
-
-
- Listado
-
-
-
- | ID | Nombre | Precio | Activo | ID Categoría |
-
-
-
-
-
-
-
diff --git a/services/manso/src/pages/roles.html b/services/manso/src/pages/roles.html
deleted file mode 100644
index 4f26d36..0000000
--- a/services/manso/src/pages/roles.html
+++ /dev/null
@@ -1,62 +0,0 @@
-
-
-
-
- Roles
-
-
- Roles
-
- Crear rol
-
-
- Listado
-
-
-
-
-
-
diff --git a/services/manso/src/pages/usuarios.html b/services/manso/src/pages/usuarios.html
deleted file mode 100644
index 9c6e7b9..0000000
--- a/services/manso/src/pages/usuarios.html
+++ /dev/null
@@ -1,104 +0,0 @@
-
-
-
-
- Usuarios
-
-
- Usuarios
-
- Crear usuario
-
-
- Listado
-
-
-
-
- | ID | Documento | Nombre | Apellido |
- Correo | Teléfono | Nacimiento | Activo |
-
-
-
-
-
-
-
-
diff --git a/services/manso/src/views/estadoComanas.ejs b/services/manso/src/views/estadoComanas.ejs
new file mode 100644
index 0000000..4cbd3aa
--- /dev/null
+++ b/services/manso/src/views/estadoComanas.ejs
@@ -0,0 +1,18 @@
+
+
Estado de Comandas
+
+
+
+
+
+
+
+
+ | ID | Mesa | Estado |
+
+
+ | 1 | 5 |
+ Abierta |
+
+
+
diff --git a/services/manso/src/views/layouts/main.ejs b/services/manso/src/views/layouts/main.ejs
new file mode 100644
index 0000000..6e29644
--- /dev/null
+++ b/services/manso/src/views/layouts/main.ejs
@@ -0,0 +1,16 @@
+
+
+
+ <% include ../partials/_head %>
+
+
+ <% include ../partials/_navbar %>
+
+
+ <%- body %>
+
+
+ <% include ../partials/_sidebar %>
+ <% include ../partials/_footer %>
+
+
diff --git a/services/manso/src/views/partials/_footer.ejs b/services/manso/src/views/partials/_footer.ejs
new file mode 100644
index 0000000..b6c9840
--- /dev/null
+++ b/services/manso/src/views/partials/_footer.ejs
@@ -0,0 +1,42 @@
+
+
+
+
diff --git a/services/manso/src/views/partials/_head.ejs b/services/manso/src/views/partials/_head.ejs
new file mode 100644
index 0000000..c449c6d
--- /dev/null
+++ b/services/manso/src/views/partials/_head.ejs
@@ -0,0 +1,22 @@
+
+
+
+<%= typeof pageTitle !== "undefined" ? pageTitle : "SuiteCoffee" %>
+
+
+
+
diff --git a/services/manso/src/views/partials/_navbar.ejs b/services/manso/src/views/partials/_navbar.ejs
new file mode 100644
index 0000000..9d6cdc3
--- /dev/null
+++ b/services/manso/src/views/partials/_navbar.ejs
@@ -0,0 +1,29 @@
+
+
diff --git a/services/manso/src/views/partials/_sidebar.ejs b/services/manso/src/views/partials/_sidebar.ejs
new file mode 100644
index 0000000..06069af
--- /dev/null
+++ b/services/manso/src/views/partials/_sidebar.ejs
@@ -0,0 +1,62 @@
+
+
+
+