112 lines
3.4 KiB
JavaScript
112 lines
3.4 KiB
JavaScript
// packages/api/v1/repositories/comandasRepo.mjs
|
|
|
|
import { withTenantClient } from './db.mjs';
|
|
import { loadColumns, loadPrimaryKey } from '../routes/utils/schemaInspector.mjs';
|
|
|
|
const TABLE = 'comandas';
|
|
const VALID_IDENT = /^[a-z_][a-z0-9_]*$/i;
|
|
|
|
export async function listComandas({ schema, abierta, limit }) {
|
|
return withTenantClient(schema, async (db) => {
|
|
const max = Math.min(parseInt(limit || 200, 10), 1000);
|
|
const { rows } = await db.query(
|
|
`SELECT * FROM public.f_comandas_resumen($1, $2)`,
|
|
[abierta, max]
|
|
);
|
|
return rows;
|
|
});
|
|
}
|
|
|
|
export async function getDetalleItems({ schema, id }) {
|
|
return withTenantClient(schema, async (db) => {
|
|
const { rows } = await db.query(
|
|
`SELECT id_det_comanda, id_producto, producto_nombre,
|
|
cantidad, pre_unitario, subtotal, observaciones
|
|
FROM public.v_comandas_detalle_items
|
|
WHERE id_comanda = $1::int
|
|
ORDER BY id_det_comanda`,
|
|
[id]
|
|
);
|
|
return rows;
|
|
});
|
|
}
|
|
|
|
export async function abrirComanda({ schema, id }) {
|
|
return withTenantClient(schema, async (db) => {
|
|
const st = await db.query(`SELECT eliminada FROM public.${q(TABLE)} WHERE id_comanda = $1`, [id]);
|
|
if (!st.rowCount) return null;
|
|
if (st.rows[0].eliminada === true) {
|
|
const err = new Error('Comanda eliminada. Debe restaurarse antes de abrir.');
|
|
err.http = { status: 409 };
|
|
throw err;
|
|
}
|
|
const { rows } = await db.query(`SELECT public.f_abrir_comanda($1) AS data`, [id]);
|
|
return rows[0]?.data || null;
|
|
});
|
|
}
|
|
|
|
export async function cerrarComanda({ schema, id }) {
|
|
return withTenantClient(schema, async (db) => {
|
|
const { rows } = await db.query(`SELECT public.f_cerrar_comanda($1) AS data`, [id]);
|
|
return rows[0]?.data || null;
|
|
});
|
|
}
|
|
|
|
export async function restaurarComanda({ schema, id }) {
|
|
return withTenantClient(schema, async (db) => {
|
|
const { rows } = await db.query(`SELECT public.f_restaurar_comanda($1) AS data`, [id]);
|
|
return rows[0]?.data || null;
|
|
});
|
|
}
|
|
|
|
export async function eliminarComanda({ schema, id }) {
|
|
return withTenantClient(schema, async (db) => {
|
|
const { rows } = await db.query(`SELECT public.f_eliminar_comanda($1) AS data`, [id]);
|
|
return rows[0]?.data || null;
|
|
});
|
|
}
|
|
|
|
export async function patchComanda({ schema, id, payload }) {
|
|
return withTenantClient(schema, async (db) => {
|
|
const columns = await loadColumns(db, TABLE);
|
|
const updatable = new Set(
|
|
columns
|
|
.filter(c =>
|
|
!c.is_primary &&
|
|
!c.is_identity &&
|
|
!(String(c.column_default || '').startsWith('nextval('))
|
|
)
|
|
.map(c => c.column_name)
|
|
);
|
|
|
|
const sets = [];
|
|
const params = [];
|
|
let idx = 1;
|
|
for (const [k, v] of Object.entries(payload || {})) {
|
|
if (!VALID_IDENT.test(k)) continue;
|
|
if (!updatable.has(k)) continue;
|
|
sets.push(`${q(k)} = $${idx++}`);
|
|
params.push(v);
|
|
}
|
|
if (!sets.length) return { error: 'Nada para actualizar' };
|
|
|
|
const pks = await loadPrimaryKey(db, TABLE);
|
|
if (pks.length !== 1) {
|
|
const err = new Error('PK compuesta no soportada');
|
|
err.http = { status: 400 };
|
|
throw err;
|
|
}
|
|
params.push(id);
|
|
|
|
const { rows } = await db.query(
|
|
`UPDATE ${q(TABLE)} SET ${sets.join(', ')} WHERE ${q(pks[0])} = $${idx} RETURNING *`,
|
|
params
|
|
);
|
|
return rows[0] || null;
|
|
});
|
|
}
|
|
|
|
function q(ident) {
|
|
return `"${String(ident).replace(/"/g, '""')}"`;
|
|
}
|