feat(herramientas): impresion de etiquetas QR y manifiesto HTML responsive para escaneo de cajas de herramientas

This commit is contained in:
2026-11-01 09:13:39 -05:00
parent 83cbfcefa8
commit e71e531b51
15 changed files with 1252 additions and 22 deletions
+42 -3
View File
@@ -1,4 +1,5 @@
const db = require('../config/db');
const crypto = require('crypto');
class HerramientaSet {
static async findAll(companyId) {
@@ -27,10 +28,45 @@ class HerramientaSet {
);
if (!rows[0]) return null;
const set = rows[0];
if (!set.qr_token) {
set.qr_token = crypto.randomBytes(12).toString('hex');
await db.query('UPDATE herramientas_sets SET qr_token = ? WHERE id = ?', [set.qr_token, set.id]);
}
set.herramientas = await this.getItems(set.id);
return set;
}
static async findByToken(token) {
if (!token) return null;
const [rows] = await db.query(
`SELECT hs.*, c.name as company_name, c.plan as company_plan
FROM herramientas_sets hs
INNER JOIN companies c ON hs.company_id = c.id
WHERE hs.qr_token = ?`,
[token]
);
if (!rows[0]) return null;
const set = rows[0];
set.herramientas = await this.getItems(set.id);
// Obtener asignación activa de custodia si existe
const [custodia] = await db.query(
`SELECT tha.*, u.nombre as tecnico_nombre, u.email as tecnico_email,
tv.titulo as visita_titulo, tv.ticket_id, t.asunto as ticket_asunto
FROM tecnico_herramientas_asignaciones tha
INNER JOIN users u ON tha.tecnico_id = u.id
LEFT JOIN ticket_visitas tv ON tha.ticket_visita_id = tv.id
LEFT JOIN tickets t ON tv.ticket_id = t.id
WHERE tha.set_id = ? AND tha.estado = 'asignado'
ORDER BY tha.id DESC LIMIT 1`,
[set.id]
);
set.custodia = custodia[0] || null;
return set;
}
static async getItems(setId) {
const [items] = await db.query(
`SELECT h.*, hsi.cantidad
@@ -51,13 +87,16 @@ class HerramientaSet {
descripcion = null,
categoria = 'general',
foto_url = null,
qr_token = null,
is_active = 1
} = data;
const finalQrToken = qr_token || crypto.randomBytes(12).toString('hex');
const [res] = await db.query(
`INSERT INTO herramientas_sets (company_id, nombre, codigo, descripcion, categoria, foto_url, is_active)
VALUES (?, ?, ?, ?, ?, ?, ?)`,
[company_id, nombre, codigo, descripcion, categoria, foto_url, is_active]
`INSERT INTO herramientas_sets (company_id, nombre, codigo, qr_token, descripcion, categoria, foto_url, is_active)
VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,
[company_id, nombre, codigo, finalQrToken, descripcion, categoria, foto_url, is_active]
);
const setId = res.insertId;