diff --git a/services/manso/src/index.js b/services/manso/src/index.js
index 651985e..3401511 100644
--- a/services/manso/src/index.js
+++ b/services/manso/src/index.js
@@ -56,6 +56,8 @@ app.use(favicon(path.join(__dirname, 'public', 'favicon', 'favicon.ico'), {
maxAge: '1y'
}));
+const url = v => !v ? "" : (v.startsWith("http") ? v : `/img/productos/${v}`);
+
// ----------------------------------------------------------
// Configuración de conexión PostgreSQL
// ----------------------------------------------------------
@@ -228,6 +230,11 @@ app.get("/estadoComandas", (req, res) => {
// res.sendFile(path.join(__dirname, 'pages', 'estadoComandas.html'));
// });
+app.get("/productos", (req, res) => {
+ res.locals.pageTitle = "Productos";
+ res.locals.pageId = "productos";
+ res.render("productos");
+});
// ----------------------------------------------------------
// API
// ----------------------------------------------------------
@@ -513,6 +520,64 @@ app.post('/api/comandas/:id/abrir', async (req, res, next) => {
// } catch (e) { next(e); }
// });
+// GET producto + receta
+app.get('/api/rpc/get_producto/:id', async (req, res) => {
+ const id = Number(req.params.id);
+ const { rows } = await pool.query('SELECT public.get_producto($1) AS data', [id]);
+ res.json(rows[0]?.data || {});
+});
+
+// POST guardar producto + receta
+
+app.post('/api/rpc/save_producto', async (req, res) => {
+ try {
+ // console.debug('receta payload:', req.body?.receta); // habilitalo si lo necesitás
+ const q = 'SELECT public.save_producto($1,$2,$3,$4,$5,$6,$7::jsonb) AS id_producto';
+ const { id_producto=null, nombre, img_producto=null, precio=0, activo=true, id_categoria=null, receta=[] } = req.body || {};
+ const params = [id_producto, nombre, img_producto, precio, activo, id_categoria, JSON.stringify(receta||[])];
+ const { rows } = await pool.query(q, params);
+ res.json(rows[0] || {});
+ } catch(e) {
+ console.error(e);
+ res.status(500).json({ error: 'save_producto failed' });
+ }
+});
+
+
+// app.post('/api/rpc/save_producto', async (req, res) => {
+// const { id_producto=null, nombre, img_producto=null, precio=0, activo=true, id_categoria=null, receta=[] } = req.body || {};
+// const q = 'SELECT * FROM public.save_producto($1,$2,$3,$4,$5,$6,$7::jsonb)';
+// const params = [id_producto, nombre, img_producto, precio, activo, id_categoria, JSON.stringify(receta||[])];
+// const { rows } = await pool.query(q, params);
+// res.json(rows[0] || {});
+// });
+
+// GET MP + proveedores
+app.get('/api/rpc/get_materia/:id', async (req, res) => {
+ const id = Number(req.params.id);
+ try {
+ const { rows } = await pool.query('SELECT public.get_materia_prima($1) AS data', [id]);
+ res.json(rows[0]?.data || {});
+ } catch (e) {
+ console.error(e);
+ res.status(500).json({ error: 'get_materia failed' });
+ }
+});
+
+// SAVE MP + proveedores (array)
+app.post('/api/rpc/save_materia', async (req, res) => {
+ const { id_mat_prima=null, nombre, unidad, activo=true, proveedores=[] } = req.body || {};
+ try {
+ const q = 'SELECT public.save_materia_prima($1,$2,$3,$4,$5::jsonb) AS id_mat_prima';
+ const params = [id_mat_prima, nombre, unidad, activo, JSON.stringify(proveedores||[])];
+ const { rows } = await pool.query(q, params);
+ res.json(rows[0] || {});
+ } catch (e) {
+ console.error(e);
+ res.status(500).json({ error: 'save_materia failed' });
+ }
+});
+
// ----------------------------------------------------------
// Verificación de conexión
// ----------------------------------------------------------
diff --git a/services/manso/src/public/img/productos/img_producto.png b/services/manso/src/public/img/productos/img_producto.png
new file mode 100644
index 0000000..a0529b4
Binary files /dev/null and b/services/manso/src/public/img/productos/img_producto.png differ
diff --git a/services/manso/src/views/productos.ejs b/services/manso/src/views/productos.ejs
new file mode 100644
index 0000000..c67fe8b
--- /dev/null
+++ b/services/manso/src/views/productos.ejs
@@ -0,0 +1,559 @@
+
+
+
🛒 Productos
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ | # |
+ Nombre |
+ Precio |
+ Activo |
+ Categoría |
+
+
+
+ | Cargando… |
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
![]()
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ | Materia prima |
+ Cantidad |
+ |
+
+
+
+ | Sin ingredientes. |
+
+
+
+
+
+
+
+
+
+
+
+
+
⚙️ Materias primas
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ | # |
+ Nombre |
+ Unidad |
+ Activo |
+
+
+
+ | Cargando… |
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Mantén presionadas Ctrl/⌘ para seleccionar varios.
+
+
+
+
+
+
+
+
+
+