diff --git a/db/dump/fixtures.sql b/db/dump/fixtures.sql
index e33494836..9d7f61116 100644
--- a/db/dump/fixtures.sql
+++ b/db/dump/fixtures.sql
@@ -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
diff --git a/modules/invoiceOut/back/methods/invoiceOut/createPdf.js b/modules/invoiceOut/back/methods/invoiceOut/createPdf.js
index f4f4567ea..50582d3c2 100644
--- a/modules/invoiceOut/back/methods/invoiceOut/createPdf.js
+++ b/modules/invoiceOut/back/methods/invoiceOut/createPdf.js
@@ -1,7 +1,7 @@
const UserError = require('vn-loopback/util/user-error');
const fs = require('fs-extra');
-const got = require('got');
const path = require('path');
+const axios = require('axios');
module.exports = Self => {
Self.remoteMethodCtx('createPdf', {
@@ -57,39 +57,35 @@ module.exports = Self => {
hasPdf: true
}, myOptions);
- const response = got.stream(`${origin}/api/report/invoice`, {
- searchParams: {
+ return axios.get(`${origin}/api/report/invoice`, {
+ responseType: 'stream',
+ params: {
authorization: auth.id,
invoiceId: id
}
- });
+ }).then(async response => {
+ const issued = invoiceOut.issued;
+ const year = issued.getFullYear().toString();
+ const month = (issued.getMonth() + 1).toString();
+ const day = issued.getDate().toString();
- const issued = invoiceOut.issued;
- const year = issued.getFullYear().toString();
- const month = (issued.getMonth() + 1).toString();
- const day = issued.getDate().toString();
+ const container = await models.InvoiceContainer.container(year);
+ const rootPath = container.client.root;
+ const fileName = `${year}${invoiceOut.ref}.pdf`;
+ const src = path.join(rootPath, year, month, day);
+ fileSrc = path.join(src, fileName);
- const container = await models.InvoiceContainer.container(year);
- const rootPath = container.client.root;
- const fileName = `${year}${invoiceOut.ref}.pdf`;
- const src = path.join(rootPath, year, month, day);
- fileSrc = path.join(src, fileName);
+ await fs.mkdir(src, {recursive: true});
- await fs.mkdir(src, {recursive: true});
+ if (tx) await tx.commit();
- if (tx) await tx.commit();
-
- const writeStream = fs.createWriteStream(fileSrc);
- writeStream.on('open', () => response.pipe(writeStream));
- writeStream.on('finish', () => writeStream.end());
-
- return new Promise(resolve => {
- writeStream.on('close', () => resolve(invoiceOut));
+ response.data.pipe(fs.createWriteStream(fileSrc));
+ }).catch(async() => {
+ if (fs.existsSync(fileSrc))
+ await fs.unlink(fileSrc);
});
} catch (e) {
if (tx) await tx.rollback();
- if (fs.existsSync(fileSrc))
- await fs.unlink(fileSrc);
throw e;
}
};
diff --git a/modules/invoiceOut/front/descriptor-menu/index.js b/modules/invoiceOut/front/descriptor-menu/index.js
index b6e7e0261..7e80a4a7c 100644
--- a/modules/invoiceOut/front/descriptor-menu/index.js
+++ b/modules/invoiceOut/front/descriptor-menu/index.js
@@ -19,6 +19,10 @@ class Controller extends Section {
this.id = value.id;
}
+ get hasInvoicing() {
+ return this.aclService.hasAny(['invoicing']);
+ }
+
loadData() {
const filter = {
include: [
diff --git a/package.json b/package.json
index dc132131a..e5b817e20 100644
--- a/package.json
+++ b/package.json
@@ -12,6 +12,7 @@
"node": ">=14"
},
"dependencies": {
+ "axios": "^0.25.0",
"bmp-js": "^0.1.0",
"compression": "^1.7.3",
"fs-extra": "^5.0.0",
@@ -42,6 +43,7 @@
"strong-error-handler": "^2.3.2",
"uuid": "^3.3.3",
"vn-loopback": "file:./loopback",
+ "vn-print": "file:./print",
"xml2js": "^0.4.23"
},
"devDependencies": {
diff --git a/print/boot.js b/print/boot.js
index 8cd0eaad7..d5c06264c 100644
--- a/print/boot.js
+++ b/print/boot.js
@@ -1,11 +1,9 @@
const express = require('express');
const path = require('path');
const fs = require('fs');
-const puppeteer = require('puppeteer');
const templatesPath = path.resolve(__dirname, './templates');
const componentsPath = path.resolve(__dirname, './core/components');
-const config = require('./core/config');
module.exports = async app => {
global.appPath = __dirname;
@@ -53,21 +51,4 @@ module.exports = async app => {
app.use(`/api/${templateName}/assets`, express.static(assetsDir));
});
});
-
- // Instantiate Puppeteer browser
- async function launchBrowser() {
- config.browser = await puppeteer.launch({
- headless: true,
- args: [
- '--no-sandbox',
- '--disable-setuid-sandbox',
- '--single-process',
- '--no-zygote'
- ]
- });
-
- config.browser.on('disconnected', launchBrowser);
- }
-
- launchBrowser();
};
diff --git a/print/common/css/layout.css b/print/common/css/layout.css
index 4f521bea4..c1af4807d 100644
--- a/print/common/css/layout.css
+++ b/print/common/css/layout.css
@@ -6,6 +6,8 @@
.grid {
font-family: Arial, Helvetica, sans-serif;
font-size: 16px !important;
+ max-width: 1200px;
+ margin: 0 auto;
width: 100%
}
diff --git a/print/config/print.json b/print/config/print.json
index ceb7cbb28..d288c585d 100755
--- a/print/config/print.json
+++ b/print/config/print.json
@@ -48,6 +48,12 @@
"pool": true
},
"storage": {
- "root": "./storage/dms"
+ "root": "./storage/dms",
+ "invoice": {
+ "root": "./storage/pdfs/invoice"
+ },
+ "signature": {
+ "root": "./storage/signatures"
+ }
}
}
\ No newline at end of file
diff --git a/print/core/component.js b/print/core/component.js
index 12474566e..37656c240 100644
--- a/print/core/component.js
+++ b/print/core/component.js
@@ -27,29 +27,50 @@ class Component {
get locale() {
if (!this._locale)
- this.getLocale();
+ this._locale = this.getLocales();
return this._locale;
}
- getLocale() {
- const mergedLocale = {messages: {}};
+ getLocales() {
+ const mergedLocales = {messages: {}};
const localePath = path.resolve(__dirname, `${this.path}/locale`);
if (!fs.existsSync(localePath))
- return mergedLocale;
+ return mergedLocales;
const localeDir = fs.readdirSync(localePath);
- localeDir.forEach(locale => {
+ for (const locale of localeDir) {
const fullPath = path.join(localePath, '/', locale);
const yamlLocale = fs.readFileSync(fullPath, 'utf8');
const jsonLocale = yaml.safeLoad(yamlLocale);
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() {
@@ -75,7 +96,7 @@ class Component {
build() {
const fullPath = path.resolve(__dirname, this.path);
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}`);
component.i18n = this.locale;
diff --git a/print/core/email.js b/print/core/email.js
index 620c1e083..bc8345cab 100644
--- a/print/core/email.js
+++ b/print/core/email.js
@@ -19,22 +19,7 @@ class Email extends Component {
}
async getSubject() {
- const component = await this.component();
- 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;
+ return (await this.getUserLocale())['subject'];
}
/**
@@ -63,6 +48,7 @@ class Email extends Component {
const reportName = fileName.replace('.pdf', '');
const report = new Report(reportName, this.args);
fileCopy.content = await report.toPdfStream();
+ fileCopy.filename = await report.getFileName();
}
attachments.push(fileCopy);
diff --git a/print/core/report.js b/print/core/report.js
index b20b8e5df..093f5e99e 100644
--- a/print/core/report.js
+++ b/print/core/report.js
@@ -2,6 +2,7 @@ const fs = require('fs');
const path = require('path');
const config = require('./config');
const Component = require('./component');
+const puppeteer = require('puppeteer');
if (!process.env.OPENSSL_CONF)
process.env.OPENSSL_CONF = '/etc/ssl/';
@@ -17,6 +18,10 @@ class Report extends Component {
return `../templates/reports/${this.name}`;
}
+ async getName() {
+ return (await this.getUserLocale())['reportName'];
+ }
+
async toPdfStream() {
const template = await this.render();
const defaultOptions = Object.assign({}, config.pdf);
@@ -27,7 +32,17 @@ class Report extends Component {
if (fs.existsSync(fullPath))
options = require(optionsPath);
- const page = (await config.browser.pages())[0];
+ const browser = await puppeteer.launch({
+ headless: true,
+ args: [
+ '--no-sandbox',
+ '--disable-setuid-sandbox',
+ '--single-process',
+ '--no-zygote'
+ ]
+ });
+
+ const page = (await browser.pages())[0];
await page.emulateMedia('screen');
await page.setContent(template);
@@ -47,8 +62,43 @@ class Report extends Component {
const buffer = await page.pdf(options);
+ await browser.close();
+
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;
diff --git a/print/core/router.js b/print/core/router.js
index c0f20dd9a..cd64ba07e 100644
--- a/print/core/router.js
+++ b/print/core/router.js
@@ -1,43 +1,30 @@
-const path = require('path');
-const fs = require('fs');
const db = require('./database');
module.exports = app => {
- const methodsPath = path.resolve(__dirname, '../methods');
- const methodsDir = fs.readdirSync(methodsPath);
- const methods = [];
+ const routes = require('../methods/routes');
- // Get all methods
- for (let method of methodsDir) {
- if (method.includes('.js'))
- methods.push(method.replace('.js', ''));
- }
-
- // Auth middleware
- const paths = [];
- for (let method of methods)
- paths.push(`/api/${method}/*`);
-
- app.use(paths, async function(req, res, next) {
- const token = getToken(req);
- 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 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({}, req.query);
- const props = Object.assign(args, req.body);
+ const args = Object.assign({}, request.query);
+ const props = Object.assign(args, request.body);
props.authorization = auth.id;
- req.args = props;
- req.args.auth = {
+ response.locals = props;
+ response.locals.auth = {
userId: auth.userId,
token: auth.id,
email: auth.email,
@@ -50,6 +37,10 @@ module.exports = app => {
}
});
+ // Register routes
+ for (let route of routes)
+ app.use(route.url, route.cb);
+
function getToken(request) {
const headers = request.headers;
const queryParams = request.query;
@@ -68,8 +59,4 @@ module.exports = app => {
return false;
}
-
- // Mount methods
- for (let method of methods)
- require(`../methods/${method}`)(app);
};
diff --git a/print/core/smtp.js b/print/core/smtp.js
index 36a76dbaf..50a413673 100644
--- a/print/core/smtp.js
+++ b/print/core/smtp.js
@@ -25,14 +25,17 @@ module.exports = {
throw err;
}).finally(async() => {
const attachments = [];
- for (let attachment of options.attachments) {
- const fileName = attachment.filename;
- const filePath = attachment.path;
- if (fileName.includes('.png')) return;
+ if (options.attachments) {
+ for (let attachment of options.attachments) {
+ const fileName = attachment.filename;
+ const filePath = attachment.path;
+ if (fileName.includes('.png')) return;
- if (fileName || filePath)
- attachments.push(filePath ? filePath : fileName);
+ if (fileName || filePath)
+ attachments.push(filePath ? filePath : fileName);
+ }
}
+
const fileNames = attachments.join(',\n');
await db.rawSql(`
INSERT INTO vn.mail (receiver, replyTo, sent, subject, body, attachment, status)
diff --git a/print/core/storage.js b/print/core/storage.js
new file mode 100644
index 000000000..063a2fbec
--- /dev/null
+++ b/print/core/storage.js
@@ -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) {
+
+ }
+};
diff --git a/print/core/stylesheet.js b/print/core/stylesheet.js
index ffa141968..42a44fb57 100644
--- a/print/core/stylesheet.js
+++ b/print/core/stylesheet.js
@@ -7,9 +7,8 @@ class Stylesheet {
}
mergeStyles() {
- this.files.forEach(file => {
+ for (const file of this.files)
this.css.push(fs.readFileSync(file));
- });
return this.css.join('\n');
}
diff --git a/print/methods/closure.js b/print/methods/closure.js
deleted file mode 100644
index 07bd1768d..000000000
--- a/print/methods/closure.js
+++ /dev/null
@@ -1,311 +0,0 @@
-const db = require('../core/database');
-const Email = require('../core/email');
-const Report = require('../core/report');
-const smtp = require('../core/smtp');
-const config = require('../core/config');
-
-module.exports = app => {
- app.get('/api/closure/all', async function(req, res, next) {
- try {
- const reqArgs = req.args;
- if (!reqArgs.to)
- throw new Error('The argument to is required');
-
- res.status(200).json({
- message: 'Task executed successfully'
- });
-
- const tickets = await db.rawSql(`
- SELECT
- t.id
- 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.id = ts.alertLevel
- WHERE al.code = 'PACKED'
- AND DATE(t.shipped) BETWEEN DATE_ADD(?, INTERVAL -2 DAY)
- AND util.dayEnd(?)
- AND t.refFk IS NULL
- GROUP BY e.ticketFk`, [reqArgs.to, reqArgs.to]);
- const ticketIds = tickets.map(ticket => ticket.id);
-
- 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);
- }
- });
-
- 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'
- });
-
- 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]);
- const ticketIds = tickets.map(ticket => ticket.id);
-
- await closeAll(ticketIds, reqArgs);
- } catch (error) {
- next(error);
- }
- });
-
- app.get('/api/closure/by-agency', async function(req, res, next) {
- 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'
- });
-
- const agenciesId = 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(:to, INTERVAL -2 DAY)
- AND util.dayEnd(?)
- AND t.refFk IS NULL
- GROUP BY e.ticketFk`, [
- agenciesId,
- reqArgs.warehouseId,
- reqArgs.to,
- reqArgs.to
- ]);
- const ticketIds = tickets.map(ticket => ticket.id);
-
- await closeAll(ticketIds, reqArgs);
- } catch (error) {
- next(error);
- }
- });
-
- app.get('/api/closure/by-route', async function(req, res, next) {
- try {
- const reqArgs = req.args;
- if (!reqArgs.routeId)
- throw new Error('The argument routeId is required');
-
- res.status(200).json({
- message: 'Task executed successfully'
- });
-
- 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]);
- const ticketIds = tickets.map(ticket => ticket.id);
- await closeAll(ticketIds, reqArgs);
-
- // 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: reqArgs.routeId,
- recipient: agencyMail
- }, reqArgs);
-
- const email = new Email('driver-route', args);
- await email.send();
- }
- } catch (error) {
- next(error);
- }
- });
-
- async function closeAll(ticketIds, reqArgs) {
- const failedtickets = [];
- 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 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 t.id IN(?)`, [ticketIds]);
-
- for (const ticket of tickets) {
- try {
- await db.rawSql(`CALL vn.ticket_closeByTicket(?)`, [ticket.id]);
-
- if (!ticket.salesPersonFk || !ticket.isToBeMailed) 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 hasToInvoice = ticket.hasToInvoice && ticket.hasDailyInvoice;
- if (hasToInvoice) {
- const invoice = await db.findOne(`
- SELECT io.id, io.ref, io.serial, cny.code companyCode
- 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,
- recipient: ticket.recipient,
- replyTo: ticket.salesPersonEmail
- }, reqArgs);
-
- let mailOptions = {};
- if (invoice.serial == 'E' && invoice.companyCode == 'VNL') {
- const exportation = new Report('exportation', args);
- const stream = await exportation.toPdfStream();
- const fileName = `exportation-${invoice.ref}.pdf`;
- mailOptions = {
- overrideAttachments: false,
- attachments: [{
- filename: fileName,
- content: stream
- }]
- };
- }
-
- const email = new Email('invoice', args);
- await email.send(mailOptions);
- } else {
- 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)
- return invalidEmail(ticket);
-
- // 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
- });
- }
- }
-
- async function 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 ${ticket.id}
- al cliente ${ticket.clientFk} - ${ticket.clientName}
- porque la dirección de email "${ticket.recipient}" no es correcta o no está disponible.
- 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
- });
- }
-};
diff --git a/print/methods/closure/closeAll.js b/print/methods/closure/closeAll.js
new file mode 100644
index 000000000..7af3676f2
--- /dev/null
+++ b/print/methods/closure/closeAll.js
@@ -0,0 +1,58 @@
+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'
+ 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, response.locals);
+
+ 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);
+ }
+};
diff --git a/print/methods/closure/closeByAgency.js b/print/methods/closure/closeByAgency.js
new file mode 100644
index 000000000..7807de23a
--- /dev/null
+++ b/print/methods/closure/closeByAgency.js
@@ -0,0 +1,58 @@
+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,
+ t.clientFk,
+ c.name clientName,
+ c.email recipient,
+ c.salesPersonFk,
+ c.isToBeMailed,
+ c.hasToInvoice,
+ co.hasDailyInvoice,
+ eu.email salesPersonEmail
+ 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
+ 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'
+ 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);
+ }
+};
diff --git a/print/methods/closure/closeByRoute.js b/print/methods/closure/closeByRoute.js
new file mode 100644
index 000000000..2c0bfd1eb
--- /dev/null
+++ b/print/methods/closure/closeByRoute.js
@@ -0,0 +1,61 @@
+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,
+ t.clientFk,
+ c.name clientName,
+ c.email recipient,
+ c.salesPersonFk,
+ c.isToBeMailed,
+ c.hasToInvoice,
+ co.hasDailyInvoice,
+ eu.email salesPersonEmail
+ 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
+ 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'
+ 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);
+ }
+};
diff --git a/print/methods/closure/closeByTicket.js b/print/methods/closure/closeByTicket.js
new file mode 100644
index 000000000..c71b3ecd0
--- /dev/null
+++ b/print/methods/closure/closeByTicket.js
@@ -0,0 +1,43 @@
+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,
+ t.clientFk,
+ c.name clientName,
+ c.email recipient,
+ c.salesPersonFk,
+ c.isToBeMailed,
+ c.hasToInvoice,
+ co.hasDailyInvoice,
+ eu.email salesPersonEmail
+ 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
+ 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'
+ AND t.id = ?
+ AND t.refFk IS NULL
+ GROUP BY e.ticketFk`, [reqArgs.ticketId]);
+
+ await closure.start(tickets, response.locals);
+ } catch (error) {
+ next(error);
+ }
+};
diff --git a/print/methods/closure/closure.js b/print/methods/closure/closure.js
new file mode 100644
index 000000000..8cce8237c
--- /dev/null
+++ b/print/methods/closure/closure.js
@@ -0,0 +1,153 @@
+const db = require('vn-print/core/database');
+const Report = require('vn-print/core/report');
+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, reqArgs) {
+ if (tickets.length == 0) return;
+
+ const failedtickets = [];
+ for (const ticket of tickets) {
+ try {
+ await db.rawSql('START TRANSACTION');
+
+ 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 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();
+
+ 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`;
+
+ // Store invoice
+ storage.write(stream, {
+ type: 'invoice',
+ path: `${year}/${month}/${day}`,
+ fileName: fileName
+ });
+
+ await db.rawSql('UPDATE invoiceOut SET hasPdf = true WHERE id = ?', [invoiceOut.id]);
+
+ 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();
+ }
+ await db.rawSql('COMMIT');
+ } catch (error) {
+ await db.rawSql('ROLLBACK');
+ // 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
+ });
+ }
+ }
+
+ // Send email with failed tickets
+ if (failedtickets.length > 0) {
+ let body = 'This following tickets have failed:
';
+
+ for (const ticket of failedtickets) {
+ body += `Ticket: ${ticket.id}
+
${ticket.stacktrace}
`;
+ }
+
+ 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 ${ticket.id}
+ al cliente ${ticket.clientFk} - ${ticket.clientName}
+ porque la dirección de email "${ticket.recipient}" no es correcta o no está disponible.
+ 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
+ });
+ }
+};
diff --git a/print/methods/closure/index.js b/print/methods/closure/index.js
new file mode 100644
index 000000000..fcca76f71
--- /dev/null
+++ b/print/methods/closure/index.js
@@ -0,0 +1,9 @@
+const express = require('express');
+const router = new express.Router();
+
+router.get('/all', require('./closeAll'));
+router.get('/by-ticket', require('./closeByTicket'));
+router.get('/by-agency', require('./closeByAgency'));
+router.get('/by-route', require('./closeByRoute'));
+
+module.exports = router;
diff --git a/print/methods/csv.js b/print/methods/csv.js
deleted file mode 100644
index 4f4cdf2af..000000000
--- a/print/methods/csv.js
+++ /dev/null
@@ -1,31 +0,0 @@
-module.exports = app => {
- app.use('/api/csv/delivery-note', require('./csv/delivery-note')(app));
- app.use('/api/csv/invoice', require('./csv/invoice')(app));
-
- app.toCSV = function toCSV(rows) {
- const [columns] = rows;
- let content = Object.keys(columns).join('\t');
- for (let row of rows) {
- const values = Object.values(row);
- const finalValues = values.map(value => {
- if (value instanceof Date) return formatDate(value);
- if (value === null) return '';
- return value;
- });
- content += '\n';
- content += finalValues.join('\t');
- }
- return content;
- };
-
- function formatDate(date) {
- return new Intl.DateTimeFormat('es', {
- year: 'numeric',
- month: 'numeric',
- day: 'numeric',
- hour: '2-digit',
- minute: '2-digit',
- second: '2-digit'
- }).format(date);
- }
-};
diff --git a/print/methods/csv/csv.js b/print/methods/csv/csv.js
new file mode 100644
index 000000000..d8725582d
--- /dev/null
+++ b/print/methods/csv/csv.js
@@ -0,0 +1,31 @@
+function toCSV(rows) {
+ const [columns] = rows;
+ let content = Object.keys(columns).join('\t');
+ for (let row of rows) {
+ const values = Object.values(row);
+ const finalValues = values.map(value => {
+ if (value instanceof Date) return formatDate(value);
+ if (value === null) return '';
+ return value;
+ });
+ content += '\n';
+ content += finalValues.join('\t');
+ }
+ return content;
+}
+
+function formatDate(date) {
+ return new Intl.DateTimeFormat('es', {
+ year: 'numeric',
+ month: 'numeric',
+ day: 'numeric',
+ hour: '2-digit',
+ minute: '2-digit',
+ second: '2-digit'
+ }).format(date);
+}
+
+module.exports = {
+ toCSV,
+ formatDate
+};
diff --git a/print/methods/csv/delivery-note/download.js b/print/methods/csv/delivery-note/download.js
new file mode 100644
index 000000000..d369d5f4a
--- /dev/null
+++ b/print/methods/csv/delivery-note/download.js
@@ -0,0 +1,24 @@
+const path = require('path');
+const db = require('vn-print/core/database');
+
+const {toCSV} = require('../csv');
+const sqlPath = path.join(__dirname, 'sql');
+
+module.exports = async function(request, response, next) {
+ try {
+ const reqArgs = request.query;
+ if (!reqArgs.ticketId)
+ throw new Error('The argument ticketId is required');
+
+ const ticketId = reqArgs.ticketId;
+ const sales = await db.rawSqlFromDef(`${sqlPath}/sales`, [ticketId]);
+ const content = toCSV(sales);
+ const fileName = `ticket_${ticketId}.csv`;
+
+ response.setHeader('Content-type', 'text/csv');
+ response.setHeader('Content-Disposition', `inline; filename="${fileName}"`);
+ response.end(content);
+ } catch (error) {
+ next(error);
+ }
+};
diff --git a/print/methods/csv/delivery-note/index.js b/print/methods/csv/delivery-note/index.js
deleted file mode 100644
index 9ef0e33fa..000000000
--- a/print/methods/csv/delivery-note/index.js
+++ /dev/null
@@ -1,82 +0,0 @@
-const express = require('express');
-const router = new express.Router();
-const path = require('path');
-const db = require('../../../core/database');
-const sqlPath = path.join(__dirname, 'sql');
-
-module.exports = app => {
- router.get('/preview', async function(req, res, next) {
- try {
- const reqArgs = req.args;
- if (!reqArgs.ticketId)
- throw new Error('The argument ticketId is required');
-
- const ticketId = reqArgs.ticketId;
- const sales = await db.rawSqlFromDef(`${sqlPath}/sales`, [ticketId]);
- const content = app.toCSV(sales);
- const fileName = `ticket_${ticketId}.csv`;
-
- res.setHeader('Content-type', 'application/json; charset=utf-8');
- res.setHeader('Content-Disposition', `inline; filename="${fileName}"`);
- res.end(content);
- } catch (error) {
- next(error);
- }
- });
-
- router.get('/download', async function(req, res, next) {
- try {
- const reqArgs = req.args;
- if (!reqArgs.ticketId)
- throw new Error('The argument ticketId is required');
-
- const ticketId = reqArgs.ticketId;
- const sales = await db.rawSqlFromDef(`${sqlPath}/sales`, [ticketId]);
- const content = app.toCSV(sales);
- const fileName = `ticket_${ticketId}.csv`;
-
- res.setHeader('Content-type', 'text/csv');
- res.setHeader('Content-Disposition', `inline; filename="${fileName}"`);
- res.end(content);
- } catch (error) {
- next(error);
- }
- });
-
- const Email = require('../../../core/email');
- router.get('/send', async function(req, res, next) {
- try {
- const reqArgs = req.args;
- if (!reqArgs.ticketId)
- throw new Error('The argument ticketId is required');
-
- const ticketId = reqArgs.ticketId;
- const ticket = await db.findOneFromDef(`${sqlPath}/ticket`, [ticketId]);
- const sales = await db.rawSqlFromDef(`${sqlPath}/sales`, [ticketId]);
-
- const args = Object.assign({
- ticketId: (String(ticket.id)),
- recipientId: ticket.clientFk,
- recipient: ticket.recipient,
- replyTo: ticket.salesPersonEmail
- }, reqArgs);
-
- const content = app.toCSV(sales);
- const fileName = `ticket_${ticketId}.csv`;
- const email = new Email('delivery-note', args);
- await email.send({
- overrideAttachments: true,
- attachments: [{
- filename: fileName,
- content: content
- }]
- });
-
- res.status(200).json({message: 'ok'});
- } catch (error) {
- next(error);
- }
- });
-
- return router;
-};
diff --git a/print/methods/csv/delivery-note/send.js b/print/methods/csv/delivery-note/send.js
new file mode 100644
index 000000000..478f20f57
--- /dev/null
+++ b/print/methods/csv/delivery-note/send.js
@@ -0,0 +1,40 @@
+const path = require('path');
+const db = require('vn-print/core/database');
+const Email = require('vn-print/core/email');
+
+const {toCSV} = require('../csv');
+const sqlPath = path.join(__dirname, 'sql');
+
+module.exports = async function(request, response, next) {
+ try {
+ const reqArgs = request.query;
+ if (!reqArgs.ticketId)
+ throw new Error('The argument ticketId is required');
+
+ const ticketId = reqArgs.ticketId;
+ const ticket = await db.findOneFromDef(`${sqlPath}/ticket`, [ticketId]);
+ const sales = await db.rawSqlFromDef(`${sqlPath}/sales`, [ticketId]);
+
+ const args = Object.assign({
+ ticketId: (String(ticket.id)),
+ recipientId: ticket.clientFk,
+ recipient: ticket.recipient,
+ replyTo: ticket.salesPersonEmail
+ }, response.locals);
+
+ const content = toCSV(sales);
+ const fileName = `ticket_${ticketId}.csv`;
+ const email = new Email('delivery-note', args);
+ await email.send({
+ overrideAttachments: true,
+ attachments: [{
+ filename: fileName,
+ content: content
+ }]
+ });
+
+ response.status(200).json({message: 'Success'});
+ } catch (error) {
+ next(error);
+ }
+};
diff --git a/print/methods/csv/index.js b/print/methods/csv/index.js
new file mode 100644
index 000000000..6bdd1b60d
--- /dev/null
+++ b/print/methods/csv/index.js
@@ -0,0 +1,9 @@
+const express = require('express');
+const router = new express.Router();
+
+router.get('/delivery-note/download', require('./delivery-note/download'));
+router.get('/delivery-note/send', require('./delivery-note/send'));
+router.get('/invoice/download', require('./invoice/download'));
+router.get('/invoice/send', require('./invoice/send'));
+
+module.exports = router;
diff --git a/print/methods/csv/invoice/download.js b/print/methods/csv/invoice/download.js
new file mode 100644
index 000000000..593d2d8d0
--- /dev/null
+++ b/print/methods/csv/invoice/download.js
@@ -0,0 +1,24 @@
+const path = require('path');
+const db = require('vn-print/core/database');
+
+const {toCSV} = require('../csv');
+const sqlPath = path.join(__dirname, 'sql');
+
+module.exports = async function(request, response, next) {
+ try {
+ const reqArgs = request.query;
+ if (!reqArgs.invoiceId)
+ throw new Error('The argument invoiceId is required');
+
+ const invoiceId = reqArgs.invoiceId;
+ const sales = await db.rawSqlFromDef(`${sqlPath}/sales`, [invoiceId]);
+ const content = toCSV(sales);
+ const fileName = `invoice_${invoiceId}.csv`;
+
+ response.setHeader('Content-type', 'text/csv');
+ response.setHeader('Content-Disposition', `inline; filename="${fileName}"`);
+ response.end(content);
+ } catch (error) {
+ next(error);
+ }
+};
diff --git a/print/methods/csv/invoice/index.js b/print/methods/csv/invoice/index.js
deleted file mode 100644
index 8f325be02..000000000
--- a/print/methods/csv/invoice/index.js
+++ /dev/null
@@ -1,82 +0,0 @@
-const express = require('express');
-const router = new express.Router();
-const path = require('path');
-const db = require('../../../core/database');
-const sqlPath = path.join(__dirname, 'sql');
-
-module.exports = app => {
- router.get('/preview', async function(req, res, next) {
- try {
- const reqArgs = req.args;
- if (!reqArgs.invoiceId)
- throw new Error('The argument invoiceId is required');
-
- const invoiceId = reqArgs.invoiceId;
- const sales = await db.rawSqlFromDef(`${sqlPath}/sales`, [invoiceId]);
- const content = app.toCSV(sales);
- const fileName = `invoice_${invoiceId}.csv`;
-
- res.setHeader('Content-type', 'application/json; charset=utf-8');
- res.setHeader('Content-Disposition', `inline; filename="${fileName}"`);
- res.end(content);
- } catch (error) {
- next(error);
- }
- });
-
- router.get('/download', async function(req, res, next) {
- try {
- const reqArgs = req.args;
- if (!reqArgs.invoiceId)
- throw new Error('The argument invoiceId is required');
-
- const invoiceId = reqArgs.invoiceId;
- const sales = await db.rawSqlFromDef(`${sqlPath}/sales`, [invoiceId]);
- const content = app.toCSV(sales);
- const fileName = `invoice_${invoiceId}.csv`;
-
- res.setHeader('Content-type', 'text/csv');
- res.setHeader('Content-Disposition', `inline; filename="${fileName}"`);
- res.end(content);
- } catch (error) {
- next(error);
- }
- });
-
- const Email = require('../../../core/email');
- router.get('/send', async function(req, res, next) {
- try {
- const reqArgs = req.args;
- if (!reqArgs.invoiceId)
- throw new Error('The argument invoiceId is required');
-
- const invoiceId = reqArgs.invoiceId;
- const invoice = await db.findOneFromDef(`${sqlPath}/invoice`, [invoiceId]);
- const sales = await db.rawSqlFromDef(`${sqlPath}/sales`, [invoiceId]);
-
- const args = Object.assign({
- invoiceId: (String(invoice.id)),
- recipientId: invoice.clientFk,
- recipient: invoice.recipient,
- replyTo: invoice.salesPersonEmail
- }, reqArgs);
-
- const content = app.toCSV(sales);
- const fileName = `invoice_${invoiceId}.csv`;
- const email = new Email('invoice', args);
- await email.send({
- overrideAttachments: true,
- attachments: [{
- filename: fileName,
- content: content
- }]
- });
-
- res.status(200).json({message: 'ok'});
- } catch (error) {
- next(error);
- }
- });
-
- return router;
-};
diff --git a/print/methods/csv/invoice/send.js b/print/methods/csv/invoice/send.js
new file mode 100644
index 000000000..919d7aeb1
--- /dev/null
+++ b/print/methods/csv/invoice/send.js
@@ -0,0 +1,40 @@
+const path = require('path');
+const db = require('vn-print/core/database');
+const Email = require('vn-print/core/email');
+
+const {toCSV} = require('../csv');
+const sqlPath = path.join(__dirname, 'sql');
+
+module.exports = async function(request, response, next) {
+ try {
+ const reqArgs = request.query;
+ if (!reqArgs.invoiceId)
+ throw new Error('The argument invoiceId is required');
+
+ const invoiceId = reqArgs.invoiceId;
+ const invoice = await db.findOneFromDef(`${sqlPath}/invoice`, [invoiceId]);
+ const sales = await db.rawSqlFromDef(`${sqlPath}/sales`, [invoiceId]);
+
+ const args = Object.assign({
+ invoiceId: (String(invoice.id)),
+ recipientId: invoice.clientFk,
+ recipient: invoice.recipient,
+ replyTo: invoice.salesPersonEmail
+ }, response.locals);
+
+ const content = toCSV(sales);
+ const fileName = `invoice_${invoiceId}.csv`;
+ const email = new Email('invoice', args);
+ await email.send({
+ overrideAttachments: true,
+ attachments: [{
+ filename: fileName,
+ content: content
+ }]
+ });
+
+ response.status(200).json({message: 'Success'});
+ } catch (error) {
+ next(error);
+ }
+};
diff --git a/print/methods/email.js b/print/methods/email.js
deleted file mode 100644
index cc4590e5d..000000000
--- a/print/methods/email.js
+++ /dev/null
@@ -1,33 +0,0 @@
-const Email = require('../core/email');
-
-module.exports = app => {
- app.get(`/api/email/:name`, async(req, res, next) => {
- try {
- const reportName = req.params.name;
- const email = new Email(reportName, req.args);
-
- await email.send();
-
- res.status(200).json({
- message: 'Sent'
- });
- } catch (e) {
- next(e);
- }
- });
-
- app.get(`/api/email/:name/preview`, async(req, res, next) => {
- try {
- const reportName = req.params.name;
- const args = req.args;
- args.isPreview = true;
-
- const email = new Email(reportName, args);
- const rendered = await email.render();
-
- res.send(rendered);
- } catch (e) {
- next(e);
- }
- });
-};
diff --git a/print/methods/email/email.js b/print/methods/email/email.js
new file mode 100644
index 000000000..5d6882f7d
--- /dev/null
+++ b/print/methods/email/email.js
@@ -0,0 +1,16 @@
+const Email = require('vn-print/core/email');
+
+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);
+ }
+};
diff --git a/print/methods/email/index.js b/print/methods/email/index.js
new file mode 100644
index 000000000..10c2d2325
--- /dev/null
+++ b/print/methods/email/index.js
@@ -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;
diff --git a/print/methods/email/preview.js b/print/methods/email/preview.js
new file mode 100644
index 000000000..e6a1aaf35
--- /dev/null
+++ b/print/methods/email/preview.js
@@ -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);
+ }
+};
diff --git a/print/methods/report.js b/print/methods/report.js
deleted file mode 100644
index 750fec4c8..000000000
--- a/print/methods/report.js
+++ /dev/null
@@ -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`;
- }
-};
diff --git a/print/methods/report/document.js b/print/methods/report/document.js
new file mode 100644
index 000000000..b24abf4ac
--- /dev/null
+++ b/print/methods/report/document.js
@@ -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);
+ }
+};
diff --git a/print/methods/report/index.js b/print/methods/report/index.js
new file mode 100644
index 000000000..c422c76df
--- /dev/null
+++ b/print/methods/report/index.js
@@ -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;
diff --git a/print/methods/report/preview.js b/print/methods/report/preview.js
new file mode 100644
index 000000000..0d6ad6f43
--- /dev/null
+++ b/print/methods/report/preview.js
@@ -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);
+ }
+};
diff --git a/print/methods/routes.js b/print/methods/routes.js
new file mode 100644
index 000000000..0c452028e
--- /dev/null
+++ b/print/methods/routes.js
@@ -0,0 +1,18 @@
+module.exports = [
+ {
+ url: '/api/report',
+ cb: require('./report')
+ },
+ {
+ url: '/api/email',
+ cb: require('./email')
+ },
+ {
+ url: '/api/csv',
+ cb: require('./csv')
+ },
+ {
+ url: '/api/closure',
+ cb: require('./closure')
+ },
+];
diff --git a/print/templates/email/campaign-metrics/campaign-metrics.js b/print/templates/email/campaign-metrics/campaign-metrics.js
index 0ace0fc25..2bd93b725 100755
--- a/print/templates/email/campaign-metrics/campaign-metrics.js
+++ b/print/templates/email/campaign-metrics/campaign-metrics.js
@@ -21,6 +21,7 @@ module.exports = {
},
props: {
recipientId: {
+ type: [Number, String],
required: true
},
from: {
diff --git a/print/templates/email/claim-pickup-order/claim-pickup-order.js b/print/templates/email/claim-pickup-order/claim-pickup-order.js
index 4396b144a..cf4ba7d12 100755
--- a/print/templates/email/claim-pickup-order/claim-pickup-order.js
+++ b/print/templates/email/claim-pickup-order/claim-pickup-order.js
@@ -10,6 +10,7 @@ module.exports = {
},
props: {
claimId: {
+ type: [Number, String],
required: true
}
}
diff --git a/print/templates/email/client-debt-statement/client-debt-statement.js b/print/templates/email/client-debt-statement/client-debt-statement.js
index c32e68943..f32f9e239 100755
--- a/print/templates/email/client-debt-statement/client-debt-statement.js
+++ b/print/templates/email/client-debt-statement/client-debt-statement.js
@@ -16,6 +16,7 @@ module.exports = {
},
props: {
recipientId: {
+ type: [Number, String],
required: true
},
from: {
diff --git a/print/templates/email/client-welcome/client-welcome.js b/print/templates/email/client-welcome/client-welcome.js
index f562339cc..eeb11bb78 100755
--- a/print/templates/email/client-welcome/client-welcome.js
+++ b/print/templates/email/client-welcome/client-welcome.js
@@ -18,6 +18,7 @@ module.exports = {
},
props: {
recipientId: {
+ type: [Number, String],
required: true
}
}
diff --git a/print/templates/email/delivery-note-link/delivery-note-link.js b/print/templates/email/delivery-note-link/delivery-note-link.js
index 009fe7b5b..471b370d9 100755
--- a/print/templates/email/delivery-note-link/delivery-note-link.js
+++ b/print/templates/email/delivery-note-link/delivery-note-link.js
@@ -10,6 +10,7 @@ module.exports = {
},
props: {
ticketId: {
+ type: [Number, String],
required: true
}
}
diff --git a/print/templates/email/delivery-note/delivery-note.js b/print/templates/email/delivery-note/delivery-note.js
index 64839b8e0..ffd2fe202 100755
--- a/print/templates/email/delivery-note/delivery-note.js
+++ b/print/templates/email/delivery-note/delivery-note.js
@@ -10,7 +10,7 @@ module.exports = {
},
props: {
ticketId: {
- type: String,
+ type: [Number, String],
required: true
}
}
diff --git a/print/templates/email/driver-route/driver-route.js b/print/templates/email/driver-route/driver-route.js
index de1dd9c39..378cd82ce 100755
--- a/print/templates/email/driver-route/driver-route.js
+++ b/print/templates/email/driver-route/driver-route.js
@@ -10,7 +10,7 @@ module.exports = {
},
props: {
routeId: {
- type: String,
+ type: [Number, String],
required: true
}
}
diff --git a/print/templates/email/invoice/invoice.js b/print/templates/email/invoice/invoice.js
index b8d3b8282..d92b65cb3 100755
--- a/print/templates/email/invoice/invoice.js
+++ b/print/templates/email/invoice/invoice.js
@@ -18,7 +18,7 @@ module.exports = {
},
props: {
invoiceId: {
- type: String,
+ type: [Number, String],
required: true
}
}
diff --git a/print/templates/email/letter-debtor-nd/letter-debtor-nd.js b/print/templates/email/letter-debtor-nd/letter-debtor-nd.js
index ba9f7957d..5e010d1ba 100755
--- a/print/templates/email/letter-debtor-nd/letter-debtor-nd.js
+++ b/print/templates/email/letter-debtor-nd/letter-debtor-nd.js
@@ -30,9 +30,11 @@ module.exports = {
required: true
},
recipientId: {
+ type: [Number, String],
required: true
},
companyId: {
+ type: [Number, String],
required: true
}
}
diff --git a/print/templates/email/letter-debtor-st/letter-debtor-st.js b/print/templates/email/letter-debtor-st/letter-debtor-st.js
index 56fc7c8a8..a514097cf 100755
--- a/print/templates/email/letter-debtor-st/letter-debtor-st.js
+++ b/print/templates/email/letter-debtor-st/letter-debtor-st.js
@@ -1,5 +1,4 @@
const Component = require(`${appPath}/core/component`);
-const db = require(`${appPath}/core/database`);
const emailHeader = new Component('email-header');
const emailFooter = new Component('email-footer');
const attachment = new Component('attachment');
@@ -28,9 +27,11 @@ module.exports = {
},
props: {
recipientId: {
+ type: [Number, String],
required: true
},
companyId: {
+ type: [Number, String],
required: true
},
}
diff --git a/print/templates/email/payment-update/payment-update.js b/print/templates/email/payment-update/payment-update.js
index eb6690c02..2b92976a3 100755
--- a/print/templates/email/payment-update/payment-update.js
+++ b/print/templates/email/payment-update/payment-update.js
@@ -26,6 +26,7 @@ module.exports = {
},
props: {
recipientId: {
+ type: [Number, String],
required: true
}
}
diff --git a/print/templates/email/printer-setup/printer-setup.js b/print/templates/email/printer-setup/printer-setup.js
index f6f168163..95dff8ebb 100755
--- a/print/templates/email/printer-setup/printer-setup.js
+++ b/print/templates/email/printer-setup/printer-setup.js
@@ -24,6 +24,7 @@ module.exports = {
},
props: {
recipientId: {
+ type: [Number, String],
required: true
}
}
diff --git a/print/templates/email/sepa-core/sepa-core.js b/print/templates/email/sepa-core/sepa-core.js
index 76f8d842f..743c6719c 100755
--- a/print/templates/email/sepa-core/sepa-core.js
+++ b/print/templates/email/sepa-core/sepa-core.js
@@ -16,9 +16,11 @@ module.exports = {
},
props: {
recipientId: {
+ type: [Number, String],
required: true
},
companyId: {
+ type: [Number, String],
required: true
}
}
diff --git a/print/templates/email/supplier-campaign-metrics/supplier-campaign-metrics.js b/print/templates/email/supplier-campaign-metrics/supplier-campaign-metrics.js
index 20113d8ea..3cf290e4d 100755
--- a/print/templates/email/supplier-campaign-metrics/supplier-campaign-metrics.js
+++ b/print/templates/email/supplier-campaign-metrics/supplier-campaign-metrics.js
@@ -21,6 +21,7 @@ module.exports = {
},
props: {
recipientId: {
+ type: [Number, String],
required: true
},
from: {
diff --git a/print/templates/reports/campaign-metrics/campaign-metrics.js b/print/templates/reports/campaign-metrics/campaign-metrics.js
index 07d261a61..6669ce067 100755
--- a/print/templates/reports/campaign-metrics/campaign-metrics.js
+++ b/print/templates/reports/campaign-metrics/campaign-metrics.js
@@ -25,6 +25,7 @@ module.exports = {
},
props: {
recipientId: {
+ type: [Number, String],
required: true
},
from: {
diff --git a/print/templates/reports/campaign-metrics/locale/es.yml b/print/templates/reports/campaign-metrics/locale/es.yml
index 8a4cc4637..c455be5a8 100644
--- a/print/templates/reports/campaign-metrics/locale/es.yml
+++ b/print/templates/reports/campaign-metrics/locale/es.yml
@@ -1,3 +1,4 @@
+reportName: consumo-cliente
title: Consumo
Client: Cliente
clientData: Datos del cliente
diff --git a/print/templates/reports/claim-pickup-order/claim-pickup-order.js b/print/templates/reports/claim-pickup-order/claim-pickup-order.js
index 0d1228a4e..fa2124057 100755
--- a/print/templates/reports/claim-pickup-order/claim-pickup-order.js
+++ b/print/templates/reports/claim-pickup-order/claim-pickup-order.js
@@ -32,6 +32,7 @@ module.exports = {
},
props: {
claimId: {
+ type: [Number, String],
required: true
}
}
diff --git a/print/templates/reports/claim-pickup-order/locale/es.yml b/print/templates/reports/claim-pickup-order/locale/es.yml
index 9faf9ac06..faa6eac33 100644
--- a/print/templates/reports/claim-pickup-order/locale/es.yml
+++ b/print/templates/reports/claim-pickup-order/locale/es.yml
@@ -1,3 +1,4 @@
+reportName: orden-de-recogida
title: Ord. recogida
claimId: Reclamación
clientId: Cliente
diff --git a/print/templates/reports/client-debt-statement/client-debt-statement.js b/print/templates/reports/client-debt-statement/client-debt-statement.js
index 09b99590b..f006b0a92 100755
--- a/print/templates/reports/client-debt-statement/client-debt-statement.js
+++ b/print/templates/reports/client-debt-statement/client-debt-statement.js
@@ -69,6 +69,7 @@ module.exports = {
},
props: {
recipientId: {
+ type: [Number, String],
required: true
},
from: {
diff --git a/print/templates/reports/client-debt-statement/locale/es.yml b/print/templates/reports/client-debt-statement/locale/es.yml
index ccdce7b5b..2c8e18ee1 100644
--- a/print/templates/reports/client-debt-statement/locale/es.yml
+++ b/print/templates/reports/client-debt-statement/locale/es.yml
@@ -1,3 +1,4 @@
+reportName: extracto-cliente
title: Extracto
clientId: Cliente
clientData: Datos del cliente
diff --git a/print/templates/reports/client-debt-statement/locale/fr.yml b/print/templates/reports/client-debt-statement/locale/fr.yml
index 12534f9ff..4edb29d8a 100644
--- a/print/templates/reports/client-debt-statement/locale/fr.yml
+++ b/print/templates/reports/client-debt-statement/locale/fr.yml
@@ -1,3 +1,4 @@
+reportName: releve-de-compte
title: Relevé de compte
clientId: Client
clientData: Données client
diff --git a/print/templates/reports/cmr-authorization/cmr-authorization.js b/print/templates/reports/cmr-authorization/cmr-authorization.js
index da08b6ec8..1adc75fa6 100755
--- a/print/templates/reports/cmr-authorization/cmr-authorization.js
+++ b/print/templates/reports/cmr-authorization/cmr-authorization.js
@@ -8,9 +8,8 @@ module.exports = {
this.ticket = await this.findOneFromDef('ticket', [this.ticketId]);
if (!this.ticket)
throw new Error('Something went wrong');
-
- this.client = await this.findOneFromDef('client', [this.ticket.clientFk]);
+ this.client = await this.findOneFromDef('client', [this.ticket.clientFk]);
},
computed: {
issued: function() {
@@ -23,6 +22,7 @@ module.exports = {
},
props: {
ticketId: {
+ type: [Number, String],
required: true
}
}
diff --git a/print/templates/reports/cmr-authorization/locale/es.yml b/print/templates/reports/cmr-authorization/locale/es.yml
index 779dc0c8f..37e40202d 100644
--- a/print/templates/reports/cmr-authorization/locale/es.yml
+++ b/print/templates/reports/cmr-authorization/locale/es.yml
@@ -1,3 +1,4 @@
+reportName: autorizacion-cmr
description: '{socialName} una sociedad debidamente constituida con responsabilidad limitada
y registrada conforme al derecho de sociedades de {country} y aquí representada por
___________________. {socialName}, con domicilio en {address},
diff --git a/print/templates/reports/credit-request/locale/es.yml b/print/templates/reports/credit-request/locale/es.yml
index e4e9739a5..cd6f92dc5 100644
--- a/print/templates/reports/credit-request/locale/es.yml
+++ b/print/templates/reports/credit-request/locale/es.yml
@@ -1,3 +1,4 @@
+reportName: solicitud-de-credito
fields:
title: Solicitud de crédito
date: Fecha
diff --git a/print/templates/reports/delivery-note/delivery-note.js b/print/templates/reports/delivery-note/delivery-note.js
index 9b3328d05..0ee7c8c91 100755
--- a/print/templates/reports/delivery-note/delivery-note.js
+++ b/print/templates/reports/delivery-note/delivery-note.js
@@ -117,7 +117,7 @@ module.exports = {
},
props: {
ticketId: {
- type: String,
+ type: [Number, String],
required: true
}
}
diff --git a/print/templates/reports/delivery-note/locale/en.yml b/print/templates/reports/delivery-note/locale/en.yml
index 8a3ff834b..16d0954e2 100644
--- a/print/templates/reports/delivery-note/locale/en.yml
+++ b/print/templates/reports/delivery-note/locale/en.yml
@@ -1,3 +1,4 @@
+reportName: delivery-note
title: Delivery note
ticketId: Delivery note
clientId: Client
diff --git a/print/templates/reports/delivery-note/locale/es.yml b/print/templates/reports/delivery-note/locale/es.yml
index f9c2e02f3..ca670ad59 100644
--- a/print/templates/reports/delivery-note/locale/es.yml
+++ b/print/templates/reports/delivery-note/locale/es.yml
@@ -1,3 +1,4 @@
+reportName: albaran
title: Albarán
ticketId: Albarán
clientId: Cliente
diff --git a/print/templates/reports/delivery-note/locale/fr.yml b/print/templates/reports/delivery-note/locale/fr.yml
index 72ca771e1..6b3779a5b 100644
--- a/print/templates/reports/delivery-note/locale/fr.yml
+++ b/print/templates/reports/delivery-note/locale/fr.yml
@@ -1,3 +1,4 @@
+reportName: bon-de-livraison
title: Bon de livraison
ticketId: BL
clientId: Client
diff --git a/print/templates/reports/delivery-note/locale/pt.yml b/print/templates/reports/delivery-note/locale/pt.yml
index e83087142..1a9c1fbd1 100644
--- a/print/templates/reports/delivery-note/locale/pt.yml
+++ b/print/templates/reports/delivery-note/locale/pt.yml
@@ -1,3 +1,4 @@
+reportName: nota-de-entrega
title: Nota de Entrega
ticketId: Nota de Entrega
clientId: Cliente
diff --git a/print/templates/reports/driver-route/driver-route.js b/print/templates/reports/driver-route/driver-route.js
index 0b2638239..c34de37cc 100755
--- a/print/templates/reports/driver-route/driver-route.js
+++ b/print/templates/reports/driver-route/driver-route.js
@@ -39,6 +39,7 @@ module.exports = {
},
props: {
routeId: {
+ type: [Number, String],
required: true
}
}
diff --git a/print/templates/reports/driver-route/locale/es.yml b/print/templates/reports/driver-route/locale/es.yml
index 4f0f3ac3c..4c922ba64 100644
--- a/print/templates/reports/driver-route/locale/es.yml
+++ b/print/templates/reports/driver-route/locale/es.yml
@@ -1,3 +1,4 @@
+reportName: hoja-de-ruta
title: Hoja de ruta
information: Información
date: Fecha
diff --git a/print/templates/reports/entry-order/entry-order.js b/print/templates/reports/entry-order/entry-order.js
index de396df2c..52a56bf03 100755
--- a/print/templates/reports/entry-order/entry-order.js
+++ b/print/templates/reports/entry-order/entry-order.js
@@ -40,7 +40,7 @@ module.exports = {
},
props: {
entryId: {
- type: String,
+ type: [Number, String],
required: true
}
}
diff --git a/print/templates/reports/entry-order/locale/es.yml b/print/templates/reports/entry-order/locale/es.yml
index 3c29d6401..5c633aeaa 100644
--- a/print/templates/reports/entry-order/locale/es.yml
+++ b/print/templates/reports/entry-order/locale/es.yml
@@ -1,3 +1,4 @@
+reportName: pedido-de-entrada
title: Pedido
supplierName: Proveedor
supplierStreet: Dirección
diff --git a/print/templates/reports/exportation/exportation.js b/print/templates/reports/exportation/exportation.js
index f63d17930..fbf663249 100755
--- a/print/templates/reports/exportation/exportation.js
+++ b/print/templates/reports/exportation/exportation.js
@@ -28,6 +28,7 @@ module.exports = {
},
props: {
invoiceId: {
+ type: [Number, String],
required: true
}
}
diff --git a/print/templates/reports/exportation/locale/es.yml b/print/templates/reports/exportation/locale/es.yml
index d5fb78b4c..a689e245b 100644
--- a/print/templates/reports/exportation/locale/es.yml
+++ b/print/templates/reports/exportation/locale/es.yml
@@ -1,3 +1,4 @@
+reportName: carta-CITES
title: 'Carta CITES'
toAttention: 'A la atención del Sr. Administrador de la Aduana de la Farga de Moles.'
declaration: 'Por la presente DECLARO, bajo mi responsabilidad, que las mercancías detalladas en la factura
diff --git a/print/templates/reports/extra-community/locale/es.yml b/print/templates/reports/extra-community/locale/es.yml
index 1112b0fe8..36201400f 100644
--- a/print/templates/reports/extra-community/locale/es.yml
+++ b/print/templates/reports/extra-community/locale/es.yml
@@ -1,3 +1,4 @@
+reportName: orden-de-carga
title: Orden de carga
reference: Referencia
information: Información
diff --git a/print/templates/reports/invoice-incoterms/invoice-incoterms.js b/print/templates/reports/invoice-incoterms/invoice-incoterms.js
index 95bf1f397..99e23e15f 100755
--- a/print/templates/reports/invoice-incoterms/invoice-incoterms.js
+++ b/print/templates/reports/invoice-incoterms/invoice-incoterms.js
@@ -32,7 +32,7 @@ module.exports = {
},
props: {
invoiceId: {
- type: String,
+ type: [Number, String],
required: true
}
}
diff --git a/print/templates/reports/invoice-incoterms/locale/es.yml b/print/templates/reports/invoice-incoterms/locale/es.yml
index 9828564d7..a69805935 100644
--- a/print/templates/reports/invoice-incoterms/locale/es.yml
+++ b/print/templates/reports/invoice-incoterms/locale/es.yml
@@ -1,3 +1,4 @@
+reportName: factura
title: Factura
invoice: Factura
clientId: Cliente
diff --git a/print/templates/reports/invoice/invoice.js b/print/templates/reports/invoice/invoice.js
index b56a5533c..bd85a812c 100755
--- a/print/templates/reports/invoice/invoice.js
+++ b/print/templates/reports/invoice/invoice.js
@@ -115,7 +115,7 @@ module.exports = {
},
props: {
invoiceId: {
- type: String,
+ type: [Number, String],
required: true
}
}
diff --git a/print/templates/reports/invoice/locale/en.yml b/print/templates/reports/invoice/locale/en.yml
new file mode 100644
index 000000000..4e4688b55
--- /dev/null
+++ b/print/templates/reports/invoice/locale/en.yml
@@ -0,0 +1,36 @@
+reportName: invoice
+title: Invoice
+invoice: Invoice
+clientId: Client
+invoiceData: Invoice data
+fiscalId: FI / NIF
+invoiceRef: Invoice {0}
+deliveryNote: Delivery note
+shipped: Shipped
+date: Date
+reference: Ref.
+quantity: Qty.
+concept: Concept
+price: PSP/u
+discount: Disc.
+vat: VAT
+amount: Amount
+type: Type
+taxBase: Tax base
+tax: Tax
+fee: Fee
+total: Total
+subtotal: Subtotal
+taxBreakdown: Tax breakdown
+notes: Notes
+intrastat: Intrastat
+code: Code
+description: Description
+stems: Stems
+netKg: Net kg
+rectifiedInvoices: Rectified invoices
+issued: Issued
+plantPassport: Plant passport
+observations: Observations
+wireTransfer: "Pay method: Transferencia"
+accountNumber: "Account number: {0}"
\ No newline at end of file
diff --git a/print/templates/reports/invoice/locale/es.yml b/print/templates/reports/invoice/locale/es.yml
index 6fdfc8a14..d37e77943 100644
--- a/print/templates/reports/invoice/locale/es.yml
+++ b/print/templates/reports/invoice/locale/es.yml
@@ -1,3 +1,4 @@
+reportName: factura
title: Factura
invoice: Factura
clientId: Cliente
diff --git a/print/templates/reports/letter-debtor/letter-debtor.js b/print/templates/reports/letter-debtor/letter-debtor.js
index bdb3a504a..354b1d8d8 100755
--- a/print/templates/reports/letter-debtor/letter-debtor.js
+++ b/print/templates/reports/letter-debtor/letter-debtor.js
@@ -63,9 +63,11 @@ module.exports = {
},
props: {
recipientId: {
+ type: [Number, String],
required: true
},
companyId: {
+ type: [Number, String],
required: true
}
}
diff --git a/print/templates/reports/letter-debtor/locale/es.yml b/print/templates/reports/letter-debtor/locale/es.yml
index a9bd8c796..6c66f0717 100644
--- a/print/templates/reports/letter-debtor/locale/es.yml
+++ b/print/templates/reports/letter-debtor/locale/es.yml
@@ -1,3 +1,4 @@
+reportName: extracto-de-cuenta
title: Extracto
claimId: Reclamación
clientId: Cliente
diff --git a/print/templates/reports/letter-debtor/locale/fr.yml b/print/templates/reports/letter-debtor/locale/fr.yml
index eff39d783..277c1162f 100644
--- a/print/templates/reports/letter-debtor/locale/fr.yml
+++ b/print/templates/reports/letter-debtor/locale/fr.yml
@@ -1,3 +1,4 @@
+reportName: releve-de-compte
title: Relevé de compte
claimId: Réclamation
clientId: Client
diff --git a/print/templates/reports/receipt/locale/es.yml b/print/templates/reports/receipt/locale/es.yml
index 67b9a948f..41be106df 100644
--- a/print/templates/reports/receipt/locale/es.yml
+++ b/print/templates/reports/receipt/locale/es.yml
@@ -1,3 +1,4 @@
+reportName: receipt
title: 'Recibo'
date: 'Fecha'
payed: 'En {0}, a {1} de {2} de {3}'
diff --git a/print/templates/reports/receipt/receipt.js b/print/templates/reports/receipt/receipt.js
index d34735bb7..d7f4dd6da 100755
--- a/print/templates/reports/receipt/receipt.js
+++ b/print/templates/reports/receipt/receipt.js
@@ -25,6 +25,7 @@ module.exports = {
},
props: {
receiptId: {
+ type: [Number, String],
required: true
}
}
diff --git a/print/templates/reports/sepa-core/locale/es.yml b/print/templates/reports/sepa-core/locale/es.yml
index bb9cc4e49..5f3f08fc3 100644
--- a/print/templates/reports/sepa-core/locale/es.yml
+++ b/print/templates/reports/sepa-core/locale/es.yml
@@ -1,3 +1,4 @@
+reportName: orden-de-domiciliacion
title: Orden de domiciliación de adeudo SEPA CORE
description: Mediante la firma de esta orden de domiciliación, el deudor autoriza
(A) al acreedor a enviar instrucciones a la entidad del deudor para adeudar su cuenta
diff --git a/print/templates/reports/sepa-core/locale/fr.yml b/print/templates/reports/sepa-core/locale/fr.yml
index 45a9039ea..354c06114 100644
--- a/print/templates/reports/sepa-core/locale/fr.yml
+++ b/print/templates/reports/sepa-core/locale/fr.yml
@@ -1,3 +1,4 @@
+reportName: direct-debit
title: Direct Debit
description: En signant ce formulaire de mandat, vous autorisez VERDNATURA LEVANTE SL
à envoyer des instructions à votre banque pour débiter votre compte, et (B) votre banque
diff --git a/print/templates/reports/sepa-core/locale/pt.yml b/print/templates/reports/sepa-core/locale/pt.yml
index e7127d06b..5459779ec 100644
--- a/print/templates/reports/sepa-core/locale/pt.yml
+++ b/print/templates/reports/sepa-core/locale/pt.yml
@@ -1,3 +1,4 @@
+reportName: autorizacao-de-debito
title: Autorização de débito directo SEPA CORE
description: Ao subscrever esta autorização, está a autorizar a (A) Verdnatura Levante
S.L. a enviar instruções ao seu banco para debitar a sua conta e (B) seu banco a
diff --git a/print/templates/reports/sepa-core/sepa-core.js b/print/templates/reports/sepa-core/sepa-core.js
index 55487d829..7e3dd3566 100755
--- a/print/templates/reports/sepa-core/sepa-core.js
+++ b/print/templates/reports/sepa-core/sepa-core.js
@@ -40,9 +40,11 @@ const rptSepaCore = {
},
props: {
recipientId: {
+ type: [Number, String],
required: true
},
companyId: {
+ type: [Number, String],
required: true
}
}
diff --git a/print/templates/reports/supplier-campaign-metrics/locale/es.yml b/print/templates/reports/supplier-campaign-metrics/locale/es.yml
index 31c1e17dd..1a38541fa 100644
--- a/print/templates/reports/supplier-campaign-metrics/locale/es.yml
+++ b/print/templates/reports/supplier-campaign-metrics/locale/es.yml
@@ -1,3 +1,4 @@
+reportName: consumo-proveedor
title: Consumo
Supplier: Proveedor
supplierData: Datos del proveedor
diff --git a/print/templates/reports/supplier-campaign-metrics/supplier-campaign-metrics.js b/print/templates/reports/supplier-campaign-metrics/supplier-campaign-metrics.js
index c37155556..1a460daa9 100755
--- a/print/templates/reports/supplier-campaign-metrics/supplier-campaign-metrics.js
+++ b/print/templates/reports/supplier-campaign-metrics/supplier-campaign-metrics.js
@@ -49,6 +49,7 @@ module.exports = {
},
props: {
recipientId: {
+ type: [Number, String],
required: true
},
from: {
diff --git a/print/templates/reports/zone/zone.js b/print/templates/reports/zone/zone.js
index 61c6cddfe..d611e1e53 100755
--- a/print/templates/reports/zone/zone.js
+++ b/print/templates/reports/zone/zone.js
@@ -13,6 +13,7 @@ module.exports = {
},
props: {
routeId: {
+ type: [Number, String],
required: true
}
}
diff --git a/storage/pdfs/invoice/.keep b/storage/pdfs/invoice/.keep
deleted file mode 100644
index e69de29bb..000000000