Closure refactor

This commit is contained in:
Joan Sanchez 2022-01-17 12:33:11 +01:00
parent 63ea0902d1
commit 7d16d7aaf2
14 changed files with 244 additions and 27 deletions

View File

@ -104,17 +104,17 @@ INSERT INTO `vn`.`currency`(`id`, `code`, `name`, `ratio`)
(3, 'GBP', 'Libra', 1),
(4, 'JPY', 'Yen Japones', 1);
INSERT INTO `vn`.`country`(`id`, `country`, `isUeeMember`, `code`, `currencyFk`, `ibanLength`, `continentFk`)
INSERT INTO `vn`.`country`(`id`, `country`, `isUeeMember`, `code`, `currencyFk`, `ibanLength`, `continentFk`, `hasDailyInvoice`, `CEE`)
VALUES
(1, 'España', 1, 'ES', 1, 24, 4),
(2, 'Italia', 1, 'IT', 1, 27, 4),
(3, 'Alemania', 1, 'DE', 1, 22, 4),
(4, 'Rumania', 1, 'RO', 1, 24, 4),
(5, 'Holanda', 1, 'NL', 1, 18, 4),
(8, 'Portugal', 1, 'PT', 1, 27, 4),
(13,'Ecuador', 0, 'EC', 1, 24, 2),
(19,'Francia', 1, 'FR', 1, 27, 4),
(30,'Canarias', 1, 'IC', 1, 24, 4);
(1, 'España', 1, 'ES', 1, 24, 4, 0, 1),
(2, 'Italia', 1, 'IT', 1, 27, 4, 0, 1),
(3, 'Alemania', 1, 'DE', 1, 22, 4, 0, 1),
(4, 'Rumania', 1, 'RO', 1, 24, 4, 0, 1),
(5, 'Holanda', 1, 'NL', 1, 18, 4, 0, 1),
(8, 'Portugal', 1, 'PT', 1, 27, 4, 0, 1),
(13,'Ecuador', 0, 'EC', 1, 24, 2, 1, 2),
(19,'Francia', 1, 'FR', 1, 27, 4, 0, 1),
(30,'Canarias', 1, 'IC', 1, 24, 4, 1, 2);
INSERT INTO `hedera`.`language` (`code`, `name`, `orgName`, `isActive`)
VALUES
@ -243,7 +243,7 @@ INSERT INTO `vn`.`province`(`id`, `name`, `countryFk`, `autonomyFk`, `warehouseF
VALUES
(1, 'Province one', 1, 1, NULL),
(2, 'Province two', 1, 1, NULL),
(3, 'Province three', 1, 2, NULL),
(3, 'Province three', 30, 2, NULL),
(4, 'Province four', 2, 3, NULL),
(5, 'Province five', 13, 4, NULL);
@ -486,7 +486,9 @@ INSERT INTO `vn`.`invoiceOutSerial` (`code`, `description`, `isTaxed`, `taxAreaF
('A', 'Global nacional', 1, 'NATIONAL', 0),
('T', 'Española rapida', 1, 'NATIONAL', 0),
('V', 'Intracomunitaria global', 0, 'CEE', 1),
('M', 'Múltiple nacional', 1, 'NATIONAL', 0);
('M', 'Múltiple nacional', 1, 'NATIONAL', 0),
('E', 'Exportación rápida', 0, 'WORLD', 0);
;
INSERT INTO `vn`.`invoiceOut`(`id`, `serial`, `amount`, `issued`,`clientFk`, `created`, `companyFk`, `dued`, `booked`, `bankFk`, `hasPdf`)
VALUES

View File

@ -1,5 +1,6 @@
const db = require('vn-print/core/database');
const closure = require('./closure');
module.exports = async function(request, response, next) {
try {
const reqArgs = request.query;
@ -40,9 +41,8 @@ module.exports = async function(request, response, next) {
AND t.refFk IS NULL
GROUP BY t.id`, [reqArgs.to, reqArgs.to]);
await closure.start(tickets);
await closure.start(tickets, response.locals);
// await closeAll(ticketIds, req.args);
await db.rawSql(`
UPDATE ticket t
JOIN ticketState ts ON t.id = ts.ticketFk

View File

@ -0,0 +1,46 @@
const db = require('vn-print/core/database');
const closure = require('./closure');
module.exports = async function(request, response, next) {
try {
const reqArgs = request.query;
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');
response.status(200).json({
message: 'Success'
});
const agencyIds = reqArgs.agencyModeId.split(',');
const tickets = await db.rawSql(`
SELECT
t.id
FROM expedition e
JOIN ticket t ON t.id = e.ticketFk
JOIN ticketState ts ON ts.ticketFk = t.id
JOIN alertLevel al ON al.id = ts.alertLevel
WHERE al.code = 'PACKED'
AND t.agencyModeFk IN(?)
AND t.warehouseFk = ?
AND DATE(t.shipped) BETWEEN DATE_ADD(?, INTERVAL -2 DAY)
AND util.dayEnd(?)
AND t.refFk IS NULL
GROUP BY e.ticketFk`, [
agencyIds,
reqArgs.warehouseId,
reqArgs.to,
reqArgs.to
]);
await closure.start(tickets, response.locals);
} catch (error) {
next(error);
}
};

View File

@ -0,0 +1,49 @@
const db = require('vn-print/core/database');
const Email = require('vn-print/core/email');
const closure = require('./closure');
module.exports = async function(request, response, next) {
try {
const reqArgs = request.query;
if (!reqArgs.routeId)
throw new Error('The argument routeId is required');
response.status(200).json({
message: 'Success'
});
const tickets = await db.rawSql(`
SELECT
t.id
FROM expedition e
JOIN ticket t ON t.id = e.ticketFk
JOIN ticketState ts ON ts.ticketFk = t.id
JOIN alertLevel al ON al.id = ts.alertLevel
WHERE al.code = 'PACKED'
AND t.routeFk = ?
AND t.refFk IS NULL
GROUP BY e.ticketFk`, [reqArgs.routeId]);
await closure.start(tickets, response.locals);
// Send route report to the agency
const agencyMail = await db.findValue(`
SELECT am.reportMail
FROM route r
JOIN agencyMode am ON am.id = r.agencyModeFk
WHERE r.id = ?`, [reqArgs.routeId]);
if (agencyMail) {
const args = Object.assign({
routeId: Number.parseInt(reqArgs.routeId),
recipient: agencyMail
}, response.locals);
const email = new Email('driver-route', args);
await email.send();
}
} catch (error) {
next(error);
}
};

View File

@ -0,0 +1,31 @@
const db = require('vn-print/core/database');
const closure = require('./closure');
module.exports = async function(request, response, next) {
try {
const reqArgs = request.query;
if (!reqArgs.ticketId)
throw new Error('The argument ticketId is required');
response.status(200).json({
message: 'Success'
});
const tickets = await db.rawSql(`
SELECT
t.id
FROM expedition e
JOIN ticket t ON t.id = e.ticketFk
JOIN ticketState ts ON ts.ticketFk = t.id
JOIN alertLevel al ON al.id = ts.alertLevel
WHERE al.code = 'PACKED'
AND t.id = ?
AND t.refFk IS NULL
GROUP BY e.ticketFk`, [reqArgs.ticketId]);
await closure.start(tickets, response.locals);
} catch (error) {
next(error);
}
};

View File

@ -1,7 +1,12 @@
const db = require('vn-print/core/database');
const Report = require('vn-print/core/report'); // Put inside block to avoid circular dependency
const Email = require('vn-print/core/email');
const smtp = require('vn-print/core/smtp');
const config = require('vn-print/core/config');
const storage = require('vn-print/core/storage');
module.exports = {
async start(tickets) {
async start(tickets, reqArgs) {
if (tickets.length == 0) return;
const failedtickets = [];
@ -17,14 +22,21 @@ module.exports = {
WHERE t.id = ?
`, [ticket.id]);
const mailOptions = {
overrideAttachments: true,
attachments: []
};
// Store invoice
const isToBeMailed = ticket.recipient && ticket.salesPersonFk && ticket.isToBeMailed;
if (invoiceOut) {
const args = Object.assign({
invoiceId: invoiceOut.id,
recipientId: ticket.clientFk,
recipient: ticket.recipient,
replyTo: ticket.salesPersonEmail
}, reqArgs);
const invoiceReport = new Report('invoice', args);
const stream = await invoiceReport.toPdfStream();
@ -35,19 +47,46 @@ module.exports = {
const fileName = `${year}${invoiceOut.ref}.pdf`;
// Store invoice
storage.write(stream, {
type: 'invoice',
path: `${year}/${month}/${day}`,
fileName: fileName
});
mailOptions.attachments.push({
filename: fileName,
content: stream
});
if (isToBeMailed) {
const invoiceAttachment = {
filename: fileName,
content: stream
};
if (invoiceOut.serial == 'E' && invoiceOut.companyCode == 'VNL') {
const exportation = new Report('exportation', args);
const stream = await exportation.toPdfStream();
const fileName = `CITES-${invoiceOut.ref}.pdf`;
mailOptions.attachments.push({
filename: fileName,
content: stream
});
}
mailOptions.attachments.push(invoiceAttachment);
const email = new Email('invoice', args);
await email.send(mailOptions);
}
} else if (isToBeMailed) {
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) {
// Domain not found
if (error.responseCode == 450)
@ -59,5 +98,50 @@ module.exports = {
stacktrace: error
});
}
}
// Send email with failed tickets
if (failedtickets.length > 0) {
let body = 'This following tickets have failed:<br/><br/>';
for (const ticket of failedtickets) {
body += `Ticket: <strong>${ticket.id}</strong>
<br/> <strong>${ticket.stacktrace}</strong><br/><br/>`;
}
smtp.send({
to: config.app.reportEmail,
subject: '[API] Nightly ticket closure report',
html: body
});
}
},
async invalidEmail(ticket) {
await db.rawSql(`UPDATE client SET email = NULL WHERE id = ?`, [
ticket.clientFk
]);
const oldInstance = `{"email": "${ticket.recipient}"}`;
const newInstance = `{"email": ""}`;
await db.rawSql(`
INSERT INTO clientLog (originFk, userFk, action, changedModel, oldInstance, newInstance)
VALUES (?, NULL, 'UPDATE', 'Client', ?, ?)`, [
ticket.clientFk,
oldInstance,
newInstance
]);
const body = `No se ha podido enviar el albarán <strong>${ticket.id}</strong>
al cliente <strong>${ticket.clientFk} - ${ticket.clientName}</strong>
porque la dirección de email <strong>"${ticket.recipient}"</strong> no es correcta o no está disponible.<br/><br/>
Para evitar que se repita este error, se ha eliminado la dirección de email de la ficha del cliente.
Actualiza la dirección de email con una correcta.`;
smtp.send({
to: ticket.salesPersonEmail,
subject: 'No se ha podido enviar el albarán',
html: body
});
}
};

View File

@ -2,6 +2,8 @@ const express = require('express');
const router = new express.Router();
router.get('/all', require('./closeAll'));
// router.get('/byTicket', require('./preview'));
router.get('/by-ticket', require('./closeByTicket'));
router.get('/by-agency', require('./closeByAgency'));
router.get('/by-route', require('./closeByRoute'));
module.exports = router;

View File

@ -18,7 +18,7 @@ module.exports = {
},
props: {
invoiceId: {
type: String,
type: Number,
required: true
}
}

View File

@ -39,6 +39,7 @@ module.exports = {
},
props: {
routeId: {
type: Number,
required: true
}
}

View File

@ -1,3 +1,4 @@
reportName: 'hoja_de_ruta'
title: Hoja de ruta
information: Información
date: Fecha

View File

@ -28,6 +28,7 @@ module.exports = {
},
props: {
invoiceId: {
type: Number,
required: true
}
}

View File

@ -32,7 +32,7 @@ module.exports = {
},
props: {
invoiceId: {
type: String,
type: Number,
required: true
}
}

View File

@ -115,7 +115,7 @@ module.exports = {
},
props: {
invoiceId: {
type: String,
type: Number,
required: true
}
}