const db = require('../core/database'); const Email = require('../core/email'); const smtp = require('../core/smtp'); const config = require('../core/config'); module.exports = app => { app.get('/api/closure/all', async function(req, res, next) { try { res.status(200).json({ message: 'Task executed successfully' }); await db.rawSql(`DROP TEMPORARY TABLE IF EXISTS tmp.ticket_close`); await db.rawSql(` CREATE TEMPORARY TABLE tmp.ticket_close ENGINE = MEMORY ( SELECT t.id AS ticketFk FROM expedition e JOIN ticket t ON t.id = e.ticketFk JOIN warehouse wh ON wh.id = t.warehouseFk AND wh.hasComission JOIN ticketState ts ON ts.ticketFk = t.id JOIN alertLevel al ON al.alertLevel = ts.alertLevel WHERE al.code = 'PACKED' AND DATE(t.shipped) BETWEEN DATE_ADD(CURDATE(), INTERVAL -2 DAY) AND CURDATE() AND t.refFk IS NULL GROUP BY e.ticketFk)`); await closeAll(req.args); await db.rawSql(` UPDATE ticket t JOIN ticketState ts ON t.id = ts.ticketFk JOIN alertLevel al ON al.alertLevel = ts.alertLevel JOIN agencyMode am ON am.id = t.agencyModeFk JOIN deliveryMethod dm ON dm.id = am.deliveryMethodFk JOIN zone z ON z.id = t.zoneFk SET t.routeFk = NULL WHERE shipped BETWEEN CURDATE() AND util.dayEnd(CURDATE()) AND al.code NOT IN('DELIVERED','PACKED') AND t.routeFk AND z.name LIKE '%MADRID%'`); } catch (error) { next(error); } }); app.get('/api/closure/by-ticket', async function(req, res, next) { try { const reqArgs = req.args; if (!reqArgs.ticketId) throw new Error('The argument ticketId is required'); res.status(200).json({ message: 'Task executed successfully' }); await db.rawSql(`DROP TEMPORARY TABLE IF EXISTS tmp.ticket_close`); await db.rawSql(` CREATE TEMPORARY TABLE tmp.ticket_close ENGINE = MEMORY ( SELECT t.id AS ticketFk FROM expedition e JOIN ticket t ON t.id = e.ticketFk JOIN ticketState ts ON ts.ticketFk = t.id JOIN alertLevel al ON al.alertLevel = ts.alertLevel WHERE al.code = 'PACKED' AND t.id = :ticketId AND t.refFk IS NULL GROUP BY e.ticketFk)`, { ticketId: reqArgs.ticketId }); await closeAll(reqArgs); } catch (error) { next(error); } }); app.get('/api/closure/by-agency', async function(req, res) { try { const reqArgs = req.args; if (!reqArgs.agencyModeId) throw new Error('The argument agencyModeId is required'); if (!reqArgs.warehouseId) throw new Error('The argument warehouseId is required'); if (!reqArgs.to) throw new Error('The argument to is required'); res.status(200).json({ message: 'Task executed successfully' }); await db.rawSql(`DROP TEMPORARY TABLE IF EXISTS tmp.ticket_close`); await db.rawSql(` CREATE TEMPORARY TABLE tmp.ticket_close ENGINE = MEMORY ( SELECT t.id AS ticketFk FROM expedition e JOIN ticket t ON t.id = e.ticketFk JOIN ticketState ts ON ts.ticketFk = t.id JOIN alertLevel al ON al.alertLevel = ts.alertLevel WHERE al.code = 'PACKED' AND t.agencyModeFk = :agencyModeId AND t.warehouseFk = :warehouseId AND DATE(t.shipped) BETWEEN DATE_ADD(:to, INTERVAL -2 DAY) AND :to AND t.refFk IS NULL GROUP BY e.ticketFk)`, { agencyModeId: reqArgs.agencyModeId, warehouseId: reqArgs.warehouseId, to: reqArgs.to }); await closeAll(reqArgs); } catch (error) { next(error); } }); app.get('/api/closure/by-route', async function(req, res) { try { const reqArgs = req.args; if (!reqArgs.routeId) throw new Error('The argument routeId is required'); res.status(200).json({ message: 'Task executed successfully' }); await db.rawSql(`DROP TEMPORARY TABLE IF EXISTS tmp.ticket_close`); await db.rawSql(` CREATE TEMPORARY TABLE tmp.ticket_close ENGINE = MEMORY ( SELECT t.id AS ticketFk FROM expedition e JOIN ticket t ON t.id = e.ticketFk JOIN ticketState ts ON ts.ticketFk = t.id JOIN alertLevel al ON al.alertLevel = ts.alertLevel WHERE al.code = 'PACKED' AND t.routeFk = :routeId AND t.refFk IS NULL GROUP BY e.ticketFk)`, { routeId: reqArgs.routeId }); await closeAll(reqArgs); } catch (error) { next(error); } }); async function closeAll(reqArgs) { const failedtickets = []; const tickets = await db.rawSql(` SELECT t.id, t.clientFk, c.email recipient, c.salesPersonFk, c.isToBeMailed, c.hasToInvoice, co.hasDailyInvoice, eu.email salesPersonEmail FROM tmp.ticket_close tt JOIN ticket t ON t.id = tt.ticketFk JOIN client c ON c.id = t.clientFk JOIN province p ON p.id = c.provinceFk JOIN country co ON co.id = p.countryFk LEFT JOIN account.emailUser eu ON eu.userFk = c.salesPersonFk`); for (const ticket of tickets) { try { await db.rawSql(`CALL vn.ticket_close(:ticketId)`, { ticketId: ticket.id }); const hasToInvoice = ticket.hasToInvoice && ticket.hasDailyInvoice; if (!ticket.salesPersonFk || !ticket.isToBeMailed || hasToInvoice) continue; if (!ticket.recipient) { const body = `No se ha podido enviar el albarán ${ticket.id} al cliente ${ticket.clientFk} porque no tiene un email especificado.

Para dejar de recibir esta notificación, asígnale un email o desactiva la notificación por email para este cliente.`; smtp.send({ to: ticket.salesPersonEmail, subject: 'No se ha podido enviar el albarán', html: body }); continue; } const args = Object.assign({ ticketId: ticket.id, recipientId: ticket.clientFk, recipient: ticket.recipient, replyTo: ticket.salesPersonEmail }, reqArgs); const email = new Email('delivery-note-link', args); await email.send(); } catch (error) { // Save tickets on a list of failed ids failedtickets.push({ id: ticket.id, stacktrace: error }); } } // Send email with failed tickets if (failedtickets.length > 0) { let body = 'This following tickets have failed:

'; for (ticket of failedtickets) { body += `Ticket: ${ticket.id}
${ticket.stacktrace}

`; } smtp.send({ to: config.app.reportEmail, subject: '[API] Nightly ticket closure report', html: body }); } await db.rawSql(`DROP TEMPORARY TABLE tmp.ticket_close`); } };