refactor(print): print service refactor with better router handler
gitea/salix/pipeline/head There was a failure building this commit
Details
gitea/salix/pipeline/head There was a failure building this commit
Details
Refs: 3245, 3477, 2800
This commit is contained in:
parent
30da0b7ed1
commit
63ea0902d1
File diff suppressed because it is too large
Load Diff
|
@ -42,6 +42,7 @@
|
||||||
"strong-error-handler": "^2.3.2",
|
"strong-error-handler": "^2.3.2",
|
||||||
"uuid": "^3.3.3",
|
"uuid": "^3.3.3",
|
||||||
"vn-loopback": "file:./loopback",
|
"vn-loopback": "file:./loopback",
|
||||||
|
"vn-print": "file:./print",
|
||||||
"xml2js": "^0.4.23"
|
"xml2js": "^0.4.23"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|
|
@ -17,6 +17,8 @@ module.exports = async app => {
|
||||||
Intl.NumberFormat = IntlPolyfill.NumberFormat;
|
Intl.NumberFormat = IntlPolyfill.NumberFormat;
|
||||||
Intl.DateTimeFormat = IntlPolyfill.DateTimeFormat;
|
Intl.DateTimeFormat = IntlPolyfill.DateTimeFormat;
|
||||||
|
|
||||||
|
// app.use('/api', require('./methods/router'));
|
||||||
|
|
||||||
// Init database instance
|
// Init database instance
|
||||||
require('./core/database').init();
|
require('./core/database').init();
|
||||||
// Init SMTP Instance
|
// Init SMTP Instance
|
||||||
|
|
|
@ -6,6 +6,8 @@
|
||||||
.grid {
|
.grid {
|
||||||
font-family: Arial, Helvetica, sans-serif;
|
font-family: Arial, Helvetica, sans-serif;
|
||||||
font-size: 16px !important;
|
font-size: 16px !important;
|
||||||
|
max-width: 1200px;
|
||||||
|
margin: 0 auto;
|
||||||
width: 100%
|
width: 100%
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -48,6 +48,12 @@
|
||||||
"pool": true
|
"pool": true
|
||||||
},
|
},
|
||||||
"storage": {
|
"storage": {
|
||||||
"root": "./storage/dms"
|
"root": "./storage/dms",
|
||||||
|
"invoice": {
|
||||||
|
"root": "./storage/pdfs/invoice"
|
||||||
|
},
|
||||||
|
"signature": {
|
||||||
|
"root": "./storage/signatures"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -27,29 +27,50 @@ class Component {
|
||||||
|
|
||||||
get locale() {
|
get locale() {
|
||||||
if (!this._locale)
|
if (!this._locale)
|
||||||
this.getLocale();
|
this._locale = this.getLocales();
|
||||||
|
|
||||||
return this._locale;
|
return this._locale;
|
||||||
}
|
}
|
||||||
|
|
||||||
getLocale() {
|
getLocales() {
|
||||||
const mergedLocale = {messages: {}};
|
const mergedLocales = {messages: {}};
|
||||||
const localePath = path.resolve(__dirname, `${this.path}/locale`);
|
const localePath = path.resolve(__dirname, `${this.path}/locale`);
|
||||||
|
|
||||||
if (!fs.existsSync(localePath))
|
if (!fs.existsSync(localePath))
|
||||||
return mergedLocale;
|
return mergedLocales;
|
||||||
|
|
||||||
const localeDir = fs.readdirSync(localePath);
|
const localeDir = fs.readdirSync(localePath);
|
||||||
localeDir.forEach(locale => {
|
for (const locale of localeDir) {
|
||||||
const fullPath = path.join(localePath, '/', locale);
|
const fullPath = path.join(localePath, '/', locale);
|
||||||
const yamlLocale = fs.readFileSync(fullPath, 'utf8');
|
const yamlLocale = fs.readFileSync(fullPath, 'utf8');
|
||||||
const jsonLocale = yaml.safeLoad(yamlLocale);
|
const jsonLocale = yaml.safeLoad(yamlLocale);
|
||||||
const localeName = locale.replace('.yml', '');
|
const localeName = locale.replace('.yml', '');
|
||||||
|
|
||||||
mergedLocale.messages[localeName] = jsonLocale;
|
mergedLocales.messages[localeName] = jsonLocale;
|
||||||
});
|
}
|
||||||
|
|
||||||
this._locale = mergedLocale;
|
return mergedLocales;
|
||||||
|
}
|
||||||
|
|
||||||
|
async getUserLocale() {
|
||||||
|
let locale = this.args.auth.locale;
|
||||||
|
|
||||||
|
// Fetches user locale from mixing method getLocale()
|
||||||
|
if (this.args.recipientId) {
|
||||||
|
const component = await this.component();
|
||||||
|
locale = await component.getLocale(this.args.recipientId);
|
||||||
|
}
|
||||||
|
|
||||||
|
const messages = this.locale.messages;
|
||||||
|
const userTranslations = messages[locale];
|
||||||
|
|
||||||
|
if (!userTranslations) {
|
||||||
|
const fallbackLocale = config.i18n.fallbackLocale;
|
||||||
|
|
||||||
|
return messages[fallbackLocale];
|
||||||
|
}
|
||||||
|
|
||||||
|
return userTranslations;
|
||||||
}
|
}
|
||||||
|
|
||||||
get stylesheet() {
|
get stylesheet() {
|
||||||
|
@ -75,7 +96,7 @@ class Component {
|
||||||
build() {
|
build() {
|
||||||
const fullPath = path.resolve(__dirname, this.path);
|
const fullPath = path.resolve(__dirname, this.path);
|
||||||
if (!fs.existsSync(fullPath))
|
if (!fs.existsSync(fullPath))
|
||||||
throw new Error(`Sample "${this.name}" not found`);
|
throw new Error(`Template "${this.name}" not found`);
|
||||||
|
|
||||||
const component = require(`${this.path}/${this.name}`);
|
const component = require(`${this.path}/${this.name}`);
|
||||||
component.i18n = this.locale;
|
component.i18n = this.locale;
|
||||||
|
|
|
@ -19,22 +19,7 @@ class Email extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
async getSubject() {
|
async getSubject() {
|
||||||
const component = await this.component();
|
return (await this.getUserLocale())['subject'];
|
||||||
let locale = this.args.auth.locale;
|
|
||||||
|
|
||||||
if (this.args.recipientId)
|
|
||||||
locale = await component.getLocale(this.args.recipientId);
|
|
||||||
|
|
||||||
const messages = this.locale.messages;
|
|
||||||
const userTranslations = messages[locale];
|
|
||||||
|
|
||||||
if (!userTranslations) {
|
|
||||||
const fallbackLocale = config.i18n.fallbackLocale;
|
|
||||||
|
|
||||||
return messages[fallbackLocale].subject;
|
|
||||||
}
|
|
||||||
|
|
||||||
return userTranslations.subject;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -63,6 +48,7 @@ class Email extends Component {
|
||||||
const reportName = fileName.replace('.pdf', '');
|
const reportName = fileName.replace('.pdf', '');
|
||||||
const report = new Report(reportName, this.args);
|
const report = new Report(reportName, this.args);
|
||||||
fileCopy.content = await report.toPdfStream();
|
fileCopy.content = await report.toPdfStream();
|
||||||
|
fileCopy.filename = await report.getFileName();
|
||||||
}
|
}
|
||||||
|
|
||||||
attachments.push(fileCopy);
|
attachments.push(fileCopy);
|
||||||
|
|
|
@ -17,6 +17,10 @@ class Report extends Component {
|
||||||
return `../templates/reports/${this.name}`;
|
return `../templates/reports/${this.name}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async getName() {
|
||||||
|
return (await this.getUserLocale())['reportName'];
|
||||||
|
}
|
||||||
|
|
||||||
async toPdfStream() {
|
async toPdfStream() {
|
||||||
const template = await this.render();
|
const template = await this.render();
|
||||||
const defaultOptions = Object.assign({}, config.pdf);
|
const defaultOptions = Object.assign({}, config.pdf);
|
||||||
|
@ -49,6 +53,39 @@ class Report extends Component {
|
||||||
|
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns all the params that ends with id
|
||||||
|
*
|
||||||
|
* @return {array} List of identifiers
|
||||||
|
*/
|
||||||
|
getIdentifiers() {
|
||||||
|
const identifiers = [];
|
||||||
|
const args = this.args;
|
||||||
|
const keys = Object.keys(args);
|
||||||
|
|
||||||
|
for (let arg of keys) {
|
||||||
|
if (arg.endsWith('Id'))
|
||||||
|
identifiers.push(arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
return identifiers;
|
||||||
|
}
|
||||||
|
|
||||||
|
async getFileName() {
|
||||||
|
const args = this.args;
|
||||||
|
const identifiers = this.getIdentifiers(args);
|
||||||
|
const name = await this.getName();
|
||||||
|
const params = [];
|
||||||
|
params.push(name);
|
||||||
|
|
||||||
|
for (let id of identifiers)
|
||||||
|
params.push(args[id]);
|
||||||
|
|
||||||
|
const fileName = params.join('_');
|
||||||
|
|
||||||
|
return `${fileName}.pdf`;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = Report;
|
module.exports = Report;
|
||||||
|
|
|
@ -1,9 +1,80 @@
|
||||||
const path = require('path');
|
|
||||||
const fs = require('fs');
|
|
||||||
const db = require('./database');
|
const db = require('./database');
|
||||||
|
|
||||||
module.exports = app => {
|
module.exports = app => {
|
||||||
const methodsPath = path.resolve(__dirname, '../methods');
|
const routes = [
|
||||||
|
{
|
||||||
|
url: '/api/report',
|
||||||
|
cb: require('../methods/report')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
url: '/api/email',
|
||||||
|
cb: require('../methods/email')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
url: '/api/closure',
|
||||||
|
cb: require('../methods/closure')
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const paths = routes.map(route => route.url);
|
||||||
|
|
||||||
|
app.use(paths, async function(request, response, next) {
|
||||||
|
try {
|
||||||
|
const token = getToken(request);
|
||||||
|
const query = `SELECT at.id, at.userId, eu.email, u.lang, at.ttl, at.created
|
||||||
|
FROM salix.AccessToken at
|
||||||
|
JOIN account.user u ON u.id = at.userid
|
||||||
|
JOIN account.emailUser eu ON eu.userFk = u.id
|
||||||
|
WHERE at.id = ?`;
|
||||||
|
|
||||||
|
const auth = await db.findOne(query, [token]);
|
||||||
|
|
||||||
|
if (!auth || isTokenExpired(auth.created, auth.ttl))
|
||||||
|
throw new Error('Invalid authorization token');
|
||||||
|
|
||||||
|
const args = Object.assign({}, request.query);
|
||||||
|
const props = Object.assign(args, request.body);
|
||||||
|
props.authorization = auth.id;
|
||||||
|
|
||||||
|
response.locals = props;
|
||||||
|
response.locals.auth = {
|
||||||
|
userId: auth.userId,
|
||||||
|
token: auth.id,
|
||||||
|
email: auth.email,
|
||||||
|
locale: auth.lang
|
||||||
|
};
|
||||||
|
|
||||||
|
next();
|
||||||
|
} catch (error) {
|
||||||
|
next(error);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Register routes
|
||||||
|
for (let route of routes)
|
||||||
|
app.use(route.url, route.cb);
|
||||||
|
|
||||||
|
function getToken(request) {
|
||||||
|
const headers = request.headers;
|
||||||
|
const queryParams = request.query;
|
||||||
|
|
||||||
|
return headers.authorization || queryParams.authorization;
|
||||||
|
}
|
||||||
|
|
||||||
|
function isTokenExpired(created, ttl) {
|
||||||
|
const date = new Date(created);
|
||||||
|
const currentDate = new Date();
|
||||||
|
|
||||||
|
date.setSeconds(date.getSeconds() + ttl);
|
||||||
|
|
||||||
|
if (currentDate > date)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// app.use('/api/email', require('../methods/email'));
|
||||||
|
/* const methodsPath = path.resolve(__dirname, '../methods');
|
||||||
const methodsDir = fs.readdirSync(methodsPath);
|
const methodsDir = fs.readdirSync(methodsPath);
|
||||||
const methods = [];
|
const methods = [];
|
||||||
|
|
||||||
|
@ -20,7 +91,7 @@ module.exports = app => {
|
||||||
|
|
||||||
app.use(paths, async function(req, res, next) {
|
app.use(paths, async function(req, res, next) {
|
||||||
const token = getToken(req);
|
const token = getToken(req);
|
||||||
const query = `SELECT at.id, at.userId, eu.email, u.lang, at.ttl, at.created
|
const query = `SELECT at.id, at.userId, eu.email, u.lang, at.ttl, at.created
|
||||||
FROM salix.AccessToken at
|
FROM salix.AccessToken at
|
||||||
JOIN account.user u ON u.id = at.userid
|
JOIN account.user u ON u.id = at.userid
|
||||||
JOIN account.emailUser eu ON eu.userFk = u.id
|
JOIN account.emailUser eu ON eu.userFk = u.id
|
||||||
|
@ -71,5 +142,5 @@ module.exports = app => {
|
||||||
|
|
||||||
// Mount methods
|
// Mount methods
|
||||||
for (let method of methods)
|
for (let method of methods)
|
||||||
require(`../methods/${method}`)(app);
|
require(`../methods/${method}`)(app); */
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
const config = require('./config.js');
|
||||||
|
const path = require('path');
|
||||||
|
const fs = require('fs-extra');
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
async write(stream, options) {
|
||||||
|
const storage = config.storage[options.type];
|
||||||
|
|
||||||
|
if (!storage) return;
|
||||||
|
|
||||||
|
const src = path.join(storage.root, options.path);
|
||||||
|
const fileSrc = path.join(src, options.fileName);
|
||||||
|
|
||||||
|
await fs.mkdir(src, {recursive: true});
|
||||||
|
|
||||||
|
const writeStream = fs.createWriteStream(fileSrc);
|
||||||
|
writeStream.on('open', () => writeStream.write(stream));
|
||||||
|
writeStream.on('finish', () => writeStream.end());
|
||||||
|
|
||||||
|
return new Promise(resolve => {
|
||||||
|
writeStream.on('close', () => resolve());
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
load(type, data) {
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
|
@ -7,9 +7,8 @@ class Stylesheet {
|
||||||
}
|
}
|
||||||
|
|
||||||
mergeStyles() {
|
mergeStyles() {
|
||||||
this.files.forEach(file => {
|
for (const file of this.files)
|
||||||
this.css.push(fs.readFileSync(file));
|
this.css.push(fs.readFileSync(file));
|
||||||
});
|
|
||||||
|
|
||||||
return this.css.join('\n');
|
return this.css.join('\n');
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,62 @@
|
||||||
|
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.to)
|
||||||
|
throw new Error('The argument to is required');
|
||||||
|
|
||||||
|
response.status(200).json({
|
||||||
|
message: 'Success'
|
||||||
|
});
|
||||||
|
|
||||||
|
const tickets = await db.rawSql(`
|
||||||
|
SELECT
|
||||||
|
t.id,
|
||||||
|
|
||||||
|
t.clientFk,
|
||||||
|
c.name clientName,
|
||||||
|
c.email recipient,
|
||||||
|
c.salesPersonFk,
|
||||||
|
c.isToBeMailed,
|
||||||
|
c.hasToInvoice,
|
||||||
|
co.hasDailyInvoice,
|
||||||
|
eu.email salesPersonEmail
|
||||||
|
FROM ticket t
|
||||||
|
JOIN agencyMode am ON am.id = t.agencyModeFk
|
||||||
|
JOIN warehouse wh ON wh.id = t.warehouseFk AND wh.hasComission
|
||||||
|
JOIN ticketState ts ON ts.ticketFk = t.id
|
||||||
|
JOIN alertLevel al ON al.id = ts.alertLevel
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
|
||||||
|
WHERE (al.code = 'PACKED' OR (am.code = 'refund' AND al.code != 'delivered'))
|
||||||
|
AND DATE(t.shipped) BETWEEN DATE_ADD(?, INTERVAL -2 DAY)
|
||||||
|
AND util.dayEnd(?)
|
||||||
|
AND t.refFk IS NULL
|
||||||
|
GROUP BY t.id`, [reqArgs.to, reqArgs.to]);
|
||||||
|
|
||||||
|
await closure.start(tickets);
|
||||||
|
|
||||||
|
// await closeAll(ticketIds, req.args);
|
||||||
|
await db.rawSql(`
|
||||||
|
UPDATE ticket t
|
||||||
|
JOIN ticketState ts ON t.id = ts.ticketFk
|
||||||
|
JOIN alertLevel al ON al.id = 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 DATE(t.shipped) BETWEEN DATE_ADD(?, INTERVAL -2 DAY)
|
||||||
|
AND util.dayEnd(?)
|
||||||
|
AND al.code NOT IN('DELIVERED','PACKED')
|
||||||
|
AND t.routeFk
|
||||||
|
AND z.name LIKE '%MADRID%'`, [reqArgs.to, reqArgs.to]);
|
||||||
|
} catch (error) {
|
||||||
|
next(error);
|
||||||
|
}
|
||||||
|
};
|
|
@ -0,0 +1,63 @@
|
||||||
|
const Report = require('vn-print/core/report'); // Put inside block to avoid circular dependency
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
async start(tickets) {
|
||||||
|
if (tickets.length == 0) return;
|
||||||
|
|
||||||
|
const failedtickets = [];
|
||||||
|
for (const ticket of tickets) {
|
||||||
|
try {
|
||||||
|
await db.rawSql(`CALL vn.ticket_closeByTicket(?)`, [ticket.id]);
|
||||||
|
|
||||||
|
const invoiceOut = await db.findOne(`
|
||||||
|
SELECT io.id, io.ref, io.serial, cny.code companyCode, io.issued
|
||||||
|
FROM ticket t
|
||||||
|
JOIN invoiceOut io ON io.ref = t.refFk
|
||||||
|
JOIN company cny ON cny.id = io.companyFk
|
||||||
|
WHERE t.id = ?
|
||||||
|
`, [ticket.id]);
|
||||||
|
|
||||||
|
|
||||||
|
const mailOptions = {
|
||||||
|
overrideAttachments: true,
|
||||||
|
attachments: []
|
||||||
|
};
|
||||||
|
|
||||||
|
// Store invoice
|
||||||
|
if (invoiceOut) {
|
||||||
|
const invoiceReport = new Report('invoice', args);
|
||||||
|
const stream = await invoiceReport.toPdfStream();
|
||||||
|
|
||||||
|
const issued = invoiceOut.issued;
|
||||||
|
const year = issued.getFullYear().toString();
|
||||||
|
const month = (issued.getMonth() + 1).toString();
|
||||||
|
const day = issued.getDate().toString();
|
||||||
|
|
||||||
|
const fileName = `${year}${invoiceOut.ref}.pdf`;
|
||||||
|
|
||||||
|
storage.write(stream, {
|
||||||
|
type: 'invoice',
|
||||||
|
path: `${year}/${month}/${day}`,
|
||||||
|
fileName: fileName
|
||||||
|
});
|
||||||
|
|
||||||
|
mailOptions.attachments.push({
|
||||||
|
filename: fileName,
|
||||||
|
content: stream
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
// Domain not found
|
||||||
|
if (error.responseCode == 450)
|
||||||
|
return invalidEmail(ticket);
|
||||||
|
|
||||||
|
// Save tickets on a list of failed ids
|
||||||
|
failedtickets.push({
|
||||||
|
id: ticket.id,
|
||||||
|
stacktrace: error
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
|
@ -3,6 +3,7 @@ const Email = require('../core/email');
|
||||||
const Report = require('../core/report');
|
const Report = require('../core/report');
|
||||||
const smtp = require('../core/smtp');
|
const smtp = require('../core/smtp');
|
||||||
const config = require('../core/config');
|
const config = require('../core/config');
|
||||||
|
const storage = require('../core/storage');
|
||||||
|
|
||||||
module.exports = app => {
|
module.exports = app => {
|
||||||
app.get('/api/closure/all', async function(req, res, next) {
|
app.get('/api/closure/all', async function(req, res, next) {
|
||||||
|
@ -18,16 +19,16 @@ module.exports = app => {
|
||||||
const tickets = await db.rawSql(`
|
const tickets = await db.rawSql(`
|
||||||
SELECT
|
SELECT
|
||||||
t.id
|
t.id
|
||||||
FROM expedition e
|
FROM ticket t
|
||||||
JOIN ticket t ON t.id = e.ticketFk
|
JOIN agencyMode am ON am.id = t.agencyModeFk
|
||||||
JOIN warehouse wh ON wh.id = t.warehouseFk AND wh.hasComission
|
JOIN warehouse wh ON wh.id = t.warehouseFk AND wh.hasComission
|
||||||
JOIN ticketState ts ON ts.ticketFk = t.id
|
JOIN ticketState ts ON ts.ticketFk = t.id
|
||||||
JOIN alertLevel al ON al.id = ts.alertLevel
|
JOIN alertLevel al ON al.id = ts.alertLevel
|
||||||
WHERE al.code = 'PACKED'
|
WHERE (al.code = 'PACKED' OR (am.code = 'refund' AND al.code != 'delivered'))
|
||||||
AND DATE(t.shipped) BETWEEN DATE_ADD(?, INTERVAL -2 DAY)
|
AND DATE(t.shipped) BETWEEN DATE_ADD(?, INTERVAL -2 DAY)
|
||||||
AND util.dayEnd(?)
|
AND util.dayEnd(?)
|
||||||
AND t.refFk IS NULL
|
AND t.refFk IS NULL
|
||||||
GROUP BY e.ticketFk`, [reqArgs.to, reqArgs.to]);
|
GROUP BY t.id`, [reqArgs.to, reqArgs.to]);
|
||||||
const ticketIds = tickets.map(ticket => ticket.id);
|
const ticketIds = tickets.map(ticket => ticket.id);
|
||||||
|
|
||||||
await closeAll(ticketIds, req.args);
|
await closeAll(ticketIds, req.args);
|
||||||
|
@ -39,7 +40,7 @@ module.exports = app => {
|
||||||
JOIN deliveryMethod dm ON dm.id = am.deliveryMethodFk
|
JOIN deliveryMethod dm ON dm.id = am.deliveryMethodFk
|
||||||
JOIN zone z ON z.id = t.zoneFk
|
JOIN zone z ON z.id = t.zoneFk
|
||||||
SET t.routeFk = NULL
|
SET t.routeFk = NULL
|
||||||
WHERE DATE(t.shipped) BETWEEN DATE_ADD(?, INTERVAL -2 DAY)
|
WHERE DATE(t.shipped) BETWEEN DATE_ADD(?, INTERVAL -2 DAY)
|
||||||
AND util.dayEnd(?)
|
AND util.dayEnd(?)
|
||||||
AND al.code NOT IN('DELIVERED','PACKED')
|
AND al.code NOT IN('DELIVERED','PACKED')
|
||||||
AND t.routeFk
|
AND t.routeFk
|
||||||
|
@ -168,6 +169,7 @@ module.exports = app => {
|
||||||
});
|
});
|
||||||
|
|
||||||
async function closeAll(ticketIds, reqArgs) {
|
async function closeAll(ticketIds, reqArgs) {
|
||||||
|
if (ticketIds.length == 0) return;
|
||||||
const failedtickets = [];
|
const failedtickets = [];
|
||||||
const tickets = await db.rawSql(`
|
const tickets = await db.rawSql(`
|
||||||
SELECT
|
SELECT
|
||||||
|
@ -191,6 +193,49 @@ module.exports = app => {
|
||||||
try {
|
try {
|
||||||
await db.rawSql(`CALL vn.ticket_closeByTicket(?)`, [ticket.id]);
|
await db.rawSql(`CALL vn.ticket_closeByTicket(?)`, [ticket.id]);
|
||||||
|
|
||||||
|
const invoiceOut = await db.findOne(`
|
||||||
|
SELECT io.id, io.ref, io.serial, cny.code companyCode, io.issued
|
||||||
|
FROM ticket t
|
||||||
|
JOIN invoiceOut io ON io.ref = t.refFk
|
||||||
|
JOIN company cny ON cny.id = io.companyFk
|
||||||
|
WHERE t.id = ?
|
||||||
|
`, [ticket.id]);
|
||||||
|
|
||||||
|
const mailOptions = {
|
||||||
|
overrideAttachments: true,
|
||||||
|
attachments: []
|
||||||
|
};
|
||||||
|
|
||||||
|
const args = Object.assign({
|
||||||
|
invoiceId: invoiceOut.id,
|
||||||
|
recipientId: ticket.clientFk,
|
||||||
|
recipient: ticket.recipient,
|
||||||
|
replyTo: ticket.salesPersonEmail
|
||||||
|
}, reqArgs);
|
||||||
|
|
||||||
|
if (invoiceOut) {
|
||||||
|
const invoiceReport = new Report('invoice', args);
|
||||||
|
const stream = await invoiceReport.toPdfStream();
|
||||||
|
|
||||||
|
const issued = invoiceOut.issued;
|
||||||
|
const year = issued.getFullYear().toString();
|
||||||
|
const month = (issued.getMonth() + 1).toString();
|
||||||
|
const day = issued.getDate().toString();
|
||||||
|
|
||||||
|
const fileName = `${year}${invoiceOut.ref}.pdf`;
|
||||||
|
|
||||||
|
storage.write(stream, {
|
||||||
|
type: 'invoice',
|
||||||
|
path: `${year}/${month}/${day}`,
|
||||||
|
fileName: fileName
|
||||||
|
});
|
||||||
|
|
||||||
|
mailOptions.attachments.push({
|
||||||
|
filename: fileName,
|
||||||
|
content: stream
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
if (!ticket.salesPersonFk || !ticket.isToBeMailed) continue;
|
if (!ticket.salesPersonFk || !ticket.isToBeMailed) continue;
|
||||||
|
|
||||||
if (!ticket.recipient) {
|
if (!ticket.recipient) {
|
||||||
|
@ -209,33 +254,23 @@ module.exports = app => {
|
||||||
|
|
||||||
const hasToInvoice = ticket.hasToInvoice && ticket.hasDailyInvoice;
|
const hasToInvoice = ticket.hasToInvoice && ticket.hasDailyInvoice;
|
||||||
if (hasToInvoice) {
|
if (hasToInvoice) {
|
||||||
const invoice = await db.findOne(`
|
/* const args = Object.assign({
|
||||||
SELECT io.id, io.ref, io.serial, cny.code companyCode
|
invoiceId: invoiceOut.id,
|
||||||
FROM ticket t
|
|
||||||
JOIN invoiceOut io ON io.ref = t.refFk
|
|
||||||
JOIN company cny ON cny.id = io.companyFk
|
|
||||||
WHERE t.id = ?
|
|
||||||
`, [ticket.id]);
|
|
||||||
|
|
||||||
const args = Object.assign({
|
|
||||||
invoiceId: invoice.id,
|
|
||||||
recipientId: ticket.clientFk,
|
recipientId: ticket.clientFk,
|
||||||
recipient: ticket.recipient,
|
recipient: ticket.recipient,
|
||||||
replyTo: ticket.salesPersonEmail
|
replyTo: ticket.salesPersonEmail
|
||||||
}, reqArgs);
|
}, reqArgs);
|
||||||
|
|
||||||
let mailOptions = {};
|
*/
|
||||||
if (invoice.serial == 'E' && invoice.companyCode == 'VNL') {
|
if (invoiceOut.serial == 'E' && invoiceOut.companyCode == 'VNL') {
|
||||||
const exportation = new Report('exportation', args);
|
const exportation = new Report('exportation', args);
|
||||||
const stream = await exportation.toPdfStream();
|
const stream = await exportation.toPdfStream();
|
||||||
const fileName = `exportation-${invoice.ref}.pdf`;
|
const fileName = `cites-${invoiceOut.ref}.pdf`;
|
||||||
mailOptions = {
|
|
||||||
overrideAttachments: false,
|
mailOptions.attachments.push({
|
||||||
attachments: [{
|
filename: fileName,
|
||||||
filename: fileName,
|
content: stream
|
||||||
content: stream
|
});
|
||||||
}]
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const email = new Email('invoice', args);
|
const email = new Email('invoice', args);
|
|
@ -0,0 +1,7 @@
|
||||||
|
const express = require('express');
|
||||||
|
const router = new express.Router();
|
||||||
|
|
||||||
|
router.get('/all', require('./closeAll'));
|
||||||
|
// router.get('/byTicket', require('./preview'));
|
||||||
|
|
||||||
|
module.exports = router;
|
|
@ -1,6 +1,21 @@
|
||||||
const Email = require('../core/email');
|
const Email = require('vn-print/core/email');
|
||||||
|
|
||||||
module.exports = app => {
|
module.exports = async function(request, response, next) {
|
||||||
|
try {
|
||||||
|
const templateName = request.params.name;
|
||||||
|
const args = response.locals;
|
||||||
|
const email = new Email(templateName, args);
|
||||||
|
await email.send();
|
||||||
|
|
||||||
|
response.status(200).json({
|
||||||
|
message: 'Sent'
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
next(error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/* module.exports = app => {
|
||||||
app.get(`/api/email/:name`, async(req, res, next) => {
|
app.get(`/api/email/:name`, async(req, res, next) => {
|
||||||
try {
|
try {
|
||||||
const reportName = req.params.name;
|
const reportName = req.params.name;
|
||||||
|
@ -31,3 +46,4 @@ module.exports = app => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
*/
|
|
@ -0,0 +1,7 @@
|
||||||
|
const express = require('express');
|
||||||
|
const router = new express.Router();
|
||||||
|
|
||||||
|
router.get('/:name', require('./email'));
|
||||||
|
router.get('/:name/preview', require('./preview'));
|
||||||
|
|
||||||
|
module.exports = router;
|
|
@ -0,0 +1,14 @@
|
||||||
|
const Email = require('vn-print/core/email');
|
||||||
|
|
||||||
|
module.exports = async function(request, response, next) {
|
||||||
|
try {
|
||||||
|
const templateName = request.params.name;
|
||||||
|
const args = Object.assign({isPreview: true}, response.locals);
|
||||||
|
const email = new Email(templateName, args);
|
||||||
|
const template = await email.render();
|
||||||
|
|
||||||
|
response.send(template);
|
||||||
|
} catch (error) {
|
||||||
|
next(error);
|
||||||
|
}
|
||||||
|
};
|
|
@ -1,54 +0,0 @@
|
||||||
const Report = require('../core/report');
|
|
||||||
|
|
||||||
module.exports = app => {
|
|
||||||
app.get(`/api/report/:name`, async(req, res, next) => {
|
|
||||||
try {
|
|
||||||
const reportName = req.params.name;
|
|
||||||
const fileName = getFileName(reportName, req.args);
|
|
||||||
const report = new Report(reportName, req.args);
|
|
||||||
if (req.args.preview) {
|
|
||||||
const template = await report.render();
|
|
||||||
res.send(template);
|
|
||||||
} else {
|
|
||||||
const stream = await report.toPdfStream();
|
|
||||||
|
|
||||||
res.setHeader('Content-type', 'application/pdf');
|
|
||||||
res.setHeader('Content-Disposition', `inline; filename="${fileName}"`);
|
|
||||||
res.end(stream);
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
next(error);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns all the params that ends with id
|
|
||||||
* @param {object} args - Params object
|
|
||||||
*
|
|
||||||
* @return {array} List of identifiers
|
|
||||||
*/
|
|
||||||
function getIdentifiers(args) {
|
|
||||||
const identifiers = [];
|
|
||||||
const keys = Object.keys(args);
|
|
||||||
|
|
||||||
for (let arg of keys) {
|
|
||||||
if (arg.endsWith('Id'))
|
|
||||||
identifiers.push(arg);
|
|
||||||
}
|
|
||||||
|
|
||||||
return identifiers;
|
|
||||||
}
|
|
||||||
|
|
||||||
function getFileName(name, args) {
|
|
||||||
const identifiers = getIdentifiers(args);
|
|
||||||
const params = [];
|
|
||||||
params.push(name);
|
|
||||||
|
|
||||||
for (let id of identifiers)
|
|
||||||
params.push(args[id]);
|
|
||||||
|
|
||||||
const fileName = params.join('_');
|
|
||||||
|
|
||||||
return `${fileName}.pdf`;
|
|
||||||
}
|
|
||||||
};
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
const Report = require('vn-print/core/report');
|
||||||
|
|
||||||
|
module.exports = async function(request, response, next) {
|
||||||
|
try {
|
||||||
|
const reportName = request.params.name;
|
||||||
|
const args = response.locals;
|
||||||
|
const report = new Report(reportName, args);
|
||||||
|
const stream = await report.toPdfStream();
|
||||||
|
const fileName = await report.getFileName();
|
||||||
|
|
||||||
|
response.setHeader('Content-type', 'application/pdf');
|
||||||
|
response.setHeader('Content-Disposition', `inline; filename="${fileName}"`);
|
||||||
|
response.end(stream);
|
||||||
|
} catch (error) {
|
||||||
|
next(error);
|
||||||
|
}
|
||||||
|
};
|
|
@ -0,0 +1,7 @@
|
||||||
|
const express = require('express');
|
||||||
|
const router = new express.Router();
|
||||||
|
|
||||||
|
router.get('/:name', require('./document'));
|
||||||
|
router.get('/:name/preview', require('./preview'));
|
||||||
|
|
||||||
|
module.exports = router;
|
|
@ -0,0 +1,13 @@
|
||||||
|
const Report = require('vn-print/core/report');
|
||||||
|
|
||||||
|
module.exports = async function(request, response, next) {
|
||||||
|
try {
|
||||||
|
const reportName = request.params.name;
|
||||||
|
const report = new Report(reportName, request.query);
|
||||||
|
const template = await report.render();
|
||||||
|
|
||||||
|
response.send(template);
|
||||||
|
} catch (error) {
|
||||||
|
next(error);
|
||||||
|
}
|
||||||
|
};
|
|
@ -1,3 +1,4 @@
|
||||||
|
reportName: deliveryNote
|
||||||
title: Delivery note
|
title: Delivery note
|
||||||
ticketId: Delivery note
|
ticketId: Delivery note
|
||||||
clientId: Client
|
clientId: Client
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
reportName: albaran
|
||||||
title: Albarán
|
title: Albarán
|
||||||
ticketId: Albarán
|
ticketId: Albarán
|
||||||
clientId: Cliente
|
clientId: Cliente
|
||||||
|
|
Loading…
Reference in New Issue