149 lines
5.0 KiB
JavaScript
149 lines
5.0 KiB
JavaScript
const db = require('../config/db');
|
|
const crypto = require('crypto');
|
|
|
|
class HerramientaSet {
|
|
static async findAll(companyId) {
|
|
const [sets] = await db.query(
|
|
`SELECT hs.*,
|
|
COUNT(hsi.id) as total_herramientas,
|
|
COALESCE(SUM(hsi.cantidad), 0) as total_items
|
|
FROM herramientas_sets hs
|
|
LEFT JOIN herramientas_set_items hsi ON hs.id = hsi.set_id
|
|
WHERE hs.company_id = ?
|
|
GROUP BY hs.id
|
|
ORDER BY hs.id DESC`,
|
|
[companyId]
|
|
);
|
|
|
|
for (const s of sets) {
|
|
s.herramientas = await this.getItems(s.id);
|
|
}
|
|
return sets;
|
|
}
|
|
|
|
static async findById(id, companyId) {
|
|
const [rows] = await db.query(
|
|
'SELECT * FROM herramientas_sets WHERE id = ? AND company_id = ?',
|
|
[id, companyId]
|
|
);
|
|
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
|
|
FROM herramientas_set_items hsi
|
|
INNER JOIN herramientas h ON hsi.herramienta_id = h.id
|
|
WHERE hsi.set_id = ?
|
|
ORDER BY h.nombre ASC`,
|
|
[setId]
|
|
);
|
|
return items;
|
|
}
|
|
|
|
static async create(data, itemIds = []) {
|
|
const {
|
|
company_id,
|
|
nombre,
|
|
codigo = null,
|
|
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, qr_token, descripcion, categoria, foto_url, is_active)
|
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,
|
|
[company_id, nombre, codigo, finalQrToken, descripcion, categoria, foto_url, is_active]
|
|
);
|
|
const setId = res.insertId;
|
|
|
|
if (Array.isArray(itemIds) && itemIds.length > 0) {
|
|
const values = itemIds.map(hId => [setId, parseInt(hId), 1]);
|
|
await db.query(
|
|
'INSERT INTO herramientas_set_items (set_id, herramienta_id, cantidad) VALUES ?',
|
|
[values]
|
|
);
|
|
}
|
|
|
|
return setId;
|
|
}
|
|
|
|
static async update(id, companyId, data, itemIds = null) {
|
|
const fields = [];
|
|
const values = [];
|
|
|
|
const allowed = ['nombre', 'codigo', 'descripcion', 'categoria', 'foto_url', 'is_active'];
|
|
for (const [key, val] of Object.entries(data)) {
|
|
if (allowed.includes(key)) {
|
|
fields.push(`${key} = ?`);
|
|
values.push(val);
|
|
}
|
|
}
|
|
|
|
if (fields.length > 0) {
|
|
values.push(id, companyId);
|
|
await db.query(`UPDATE herramientas_sets SET ${fields.join(', ')} WHERE id = ? AND company_id = ?`, values);
|
|
}
|
|
|
|
if (Array.isArray(itemIds)) {
|
|
await db.query('DELETE FROM herramientas_set_items WHERE set_id = ?', [id]);
|
|
if (itemIds.length > 0) {
|
|
const valuesItems = itemIds.map(hId => [id, parseInt(hId), 1]);
|
|
await db.query(
|
|
'INSERT INTO herramientas_set_items (set_id, herramienta_id, cantidad) VALUES ?',
|
|
[valuesItems]
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
static async delete(id, companyId) {
|
|
await db.query('DELETE FROM herramientas_sets WHERE id = ? AND company_id = ?', [id, companyId]);
|
|
}
|
|
}
|
|
|
|
module.exports = HerramientaSet;
|