feat(herramientas): impresion de etiquetas QR y manifiesto HTML responsive para escaneo de cajas de herramientas
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
const mysql = require('mysql2/promise');
|
||||
const crypto = require('crypto');
|
||||
require('dotenv').config();
|
||||
|
||||
async function setup() {
|
||||
@@ -201,6 +202,7 @@ async function setup() {
|
||||
company_id INT NOT NULL,
|
||||
nombre VARCHAR(150) NOT NULL,
|
||||
codigo VARCHAR(50) NULL,
|
||||
qr_token VARCHAR(64) NULL,
|
||||
descripcion TEXT NULL,
|
||||
categoria VARCHAR(100) DEFAULT 'general',
|
||||
foto_url VARCHAR(255) NULL,
|
||||
@@ -209,6 +211,7 @@ async function setup() {
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
INDEX (company_id),
|
||||
INDEX (codigo),
|
||||
INDEX (qr_token),
|
||||
FOREIGN KEY (company_id) REFERENCES companies(id) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
`);
|
||||
@@ -236,6 +239,7 @@ async function setup() {
|
||||
herramienta_id INT NULL,
|
||||
ticket_visita_id INT NULL,
|
||||
tipo_asignacion ENUM('dotacion_fija', 'visita_fsm') DEFAULT 'dotacion_fija',
|
||||
qr_token VARCHAR(64) NULL,
|
||||
fecha_asignacion DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
fecha_devolucion DATETIME NULL,
|
||||
estado ENUM('asignado', 'devuelto', 'observado') DEFAULT 'asignado',
|
||||
@@ -249,6 +253,7 @@ async function setup() {
|
||||
INDEX (company_id),
|
||||
INDEX (tecnico_id),
|
||||
INDEX (ticket_visita_id),
|
||||
INDEX (qr_token),
|
||||
FOREIGN KEY (company_id) REFERENCES companies(id) ON DELETE CASCADE,
|
||||
FOREIGN KEY (tecnico_id) REFERENCES users(id) ON DELETE CASCADE,
|
||||
FOREIGN KEY (set_id) REFERENCES herramientas_sets(id) ON DELETE SET NULL,
|
||||
@@ -264,6 +269,24 @@ async function setup() {
|
||||
await migrateColumn('tecnico_herramientas_asignaciones', 'foto_entrega_url', 'foto_entrega_url VARCHAR(255) NULL AFTER observaciones_entrega');
|
||||
await migrateColumn('tecnico_herramientas_asignaciones', 'foto_devolucion_url', 'foto_devolucion_url VARCHAR(255) NULL AFTER observaciones_devolucion');
|
||||
|
||||
// Migraciones de tokens QR para escaneo e impresión de etiquetas
|
||||
await migrateColumn('herramientas_sets', 'qr_token', 'qr_token VARCHAR(64) NULL AFTER codigo');
|
||||
await migrateColumn('tecnico_herramientas_asignaciones', 'qr_token', 'qr_token VARCHAR(64) NULL AFTER tipo_asignacion');
|
||||
|
||||
// Backfill de qr_token para sets que aún no tengan uno generado
|
||||
const [setsSinToken] = await conn.query('SELECT id FROM herramientas_sets WHERE qr_token IS NULL');
|
||||
for (const s of setsSinToken) {
|
||||
const token = crypto.randomBytes(12).toString('hex');
|
||||
await conn.query('UPDATE herramientas_sets SET qr_token = ? WHERE id = ?', [token, s.id]);
|
||||
}
|
||||
|
||||
// Backfill de qr_token para asignaciones sin token
|
||||
const [asigSinToken] = await conn.query('SELECT id FROM tecnico_herramientas_asignaciones WHERE qr_token IS NULL');
|
||||
for (const a of asigSinToken) {
|
||||
const token = crypto.randomBytes(12).toString('hex');
|
||||
await conn.query('UPDATE tecnico_herramientas_asignaciones SET qr_token = ? WHERE id = ?', [token, a.id]);
|
||||
}
|
||||
|
||||
// Seed herramientas y sets iniciales para Telcotronics si no existen
|
||||
const [existingTools] = await conn.query('SELECT COUNT(*) as c FROM herramientas WHERE company_id = 1');
|
||||
if (existingTools[0].c === 0) {
|
||||
|
||||
Reference in New Issue
Block a user