refactor
gitea/salix/1466-print_refactor This commit looks good Details

This commit is contained in:
Joan Sanchez 2019-10-31 12:43:04 +01:00
parent 443aa56fed
commit a2ea532fc1
86 changed files with 1091 additions and 2227 deletions

View File

@ -1,3 +1,3 @@
module.exports = function(app) {
require('../../../print/server.js')(app);
require('../../../print/boot.js')(app);
};

57
print/boot.js Normal file
View File

@ -0,0 +1,57 @@
const express = require('express');
const path = require('path');
const fs = require('fs');
const templatesPath = path.resolve(__dirname, './templates');
const componentsPath = path.resolve(__dirname, './core/components');
module.exports = app => {
global.appPath = __dirname;
process.env.OPENSSL_CONF = '/etc/ssl/';
// Extended locale intl polyfill
const IntlPolyfill = require('intl');
Intl.NumberFormat = IntlPolyfill.NumberFormat;
Intl.DateTimeFormat = IntlPolyfill.DateTimeFormat;
// Init database instance
require('./core/database').init();
// Init SMTP Instance
require('./core/smtp').init();
//
require('./core/mixins');
require('./core/filters');
require('./core/directives');
// Init router
require('./core/router')(app);
/**
* Serve component static files
*/
const componentsDir = fs.readdirSync(componentsPath);
componentsDir.forEach(componentName => {
const componentDir = path.join(componentsPath, '/', componentName);
const assetsDir = `${componentDir}/assets`;
app.use(`/api/assets/${componentName}`, express.static(assetsDir));
});
/**
* Serve static files
*/
const templatesDir = fs.readdirSync(templatesPath);
templatesDir.forEach(directory => {
const templateTypeDir = path.join(templatesPath, '/', directory);
const templates = fs.readdirSync(templateTypeDir);
templates.forEach(templateName => {
const templateDir = path.join(templatesPath, '/', directory, '/', templateName);
const assetsDir = `${templateDir}/assets`;
app.use(`/api/assets/${templateName}`, express.static(assetsDir));
});
});
};

View File

@ -1,5 +1,6 @@
{
"app": {
"host": "http://localhost:5000",
"port": 3000,
"senderMail": "nocontestar@verdnatura.es",
"senderName": "Verdnatura"

View File

@ -7,7 +7,6 @@ const fs = require('fs');
const yaml = require('js-yaml');
const juice = require('juice');
const path = require('path');
const config = require('./config');
class Component {
@ -27,6 +26,13 @@ class Component {
}
get locale() {
if (!this._locale)
this.getLocale();
return this._locale;
}
getLocale() {
const mergedLocale = {messages: {}};
const localePath = path.resolve(__dirname, `${this.path}/locale`);
@ -43,7 +49,7 @@ class Component {
mergedLocale.messages[localeName] = jsonLocale;
});
return mergedLocale;
this._locale = mergedLocale;
}
get stylesheet() {
@ -53,15 +59,7 @@ class Component {
if (!fs.existsSync(stylePath))
return mergedStyles;
const styleDir = fs.readdirSync(stylePath);
styleDir.forEach(fileName => {
const fullPath = path.join(stylePath, '/', fileName);
const contents = fs.readFileSync(fullPath, 'utf8');
mergedStyles += contents;
});
return mergedStyles;
return require(`${stylePath}/import`);
}
get attachments() {
@ -75,8 +73,11 @@ class Component {
}
build() {
const component = require(`${this.path}/${this.name}`);
const fullPath = path.resolve(__dirname, this.path);
if (!fs.existsSync(fullPath))
throw new Error(`Sample "${this.name}" not found`);
const component = require(`${this.path}/${this.name}`);
component.i18n = this.locale;
component.attachments = this.attachments;
component.template = juice.inlineContent(this.template, this.stylesheet, {

View File

@ -0,0 +1,8 @@
const Stylesheet = require(`${appPath}/core/stylesheet`);
module.exports = new Stylesheet([
`${appPath}/common/css/layout.css`,
`${appPath}/common/css/email.css`,
`${appPath}/common/css/misc.css`,
`${__dirname}/style.css`])
.mergeStyles();

View File

@ -19,22 +19,22 @@
<!-- Networks block -->
<section class="networks">
<a href="https://www.facebook.com/Verdnatura" target="_blank">
<img :src="getSrc('facebook.png')" alt="Facebook"/>
<img :src="getEmailSrc('facebook.png')" alt="Facebook"/>
</a>
<a href="https://www.twitter.com/Verdnatura" target="_blank">
<img :src="getSrc('twitter.png')" alt="Twitter"/>
<img :src="getEmailSrc('twitter.png')" alt="Twitter"/>
</a>
<a href="https://www.youtube.com/Verdnatura" target="_blank">
<img :src="getSrc('youtube.png')" alt="Youtube"/>
<img :src="getEmailSrc('youtube.png')" alt="Youtube"/>
</a>
<a href="https://www.pinterest.com/Verdnatura" target="_blank">
<img :src="getSrc('pinterest.png')" alt="Pinterest"/>
<img :src="getEmailSrc('pinterest.png')" alt="Pinterest"/>
</a>
<a href="https://www.instagram.com/Verdnatura" target="_blank">
<img :src="getSrc('instagram.png')" alt="Instagram"/>
<img :src="getEmailSrc('instagram.png')" alt="Instagram"/>
</a>
<a href="https://www.linkedin.com/company/verdnatura" target="_blank">
<img :src="getSrc('linkedin.png')" alt="Linkedin"/>
<img :src="getEmailSrc('linkedin.png')" alt="Linkedin"/>
</a>
</section>
<!-- Networks block end -->

View File

@ -4,7 +4,7 @@ buttons:
privacy:
fiscalAddress: VERDNATURA LEVANTE SL, B97367486 Avda. Espioca, 100, 46460 Silla
· www.verdnatura.es · clientes@verdnatura.es
disclaimer: '- AVISO - Ce message est privé et confidentiel et doit être utilisé.exclusivamente
disclaimer: '- AVIS - Ce message est privé et confidentiel et doit être utilisé.exclusivamente
por la persona destinataria del mismo. Si has recibido este mensajepor error,
te rogamos lo comuniques al remitente y borres dicho mensaje y cualquier documentoadjunto
que pudiera contener. Verdnatura Levante SL no renuncia a la confidencialidad
@ -12,7 +12,7 @@ privacy:
no se haceresponsable de los cambios, alteraciones, errores u omisiones que pudieran
hacerse al mensaje una vez enviado.'
law: En cumplimiento de lo dispuesto en la Ley Orgánica 15/1999, de Protección de
Datos de Carácter Personal,te comunicamos que los datos personales que facilites
Datos de Carácter Personal, te comunicamos que los datos personales que facilites
se incluirán en ficheros automatizados de VERDNATURA LEVANTE S.L.,pudiendo en
todo momento ejercitar los derechos de acceso, rectificación, cancelación y oposición,
comunicándolo porescrito al domicilio social de la entidad. La finalidad del fichero

View File

@ -0,0 +1,8 @@
const Stylesheet = require(`${appPath}/core/stylesheet`);
module.exports = new Stylesheet([
`${appPath}/common/css/layout.css`,
`${appPath}/common/css/email.css`,
`${appPath}/common/css/misc.css`,
`${__dirname}/style.css`])
.mergeStyles();

View File

@ -1,5 +1,5 @@
<header>
<a href="https://www.verdnatura.es" target="_blank">
<img :src="getSrc('email-logo.png')" alt="VerdNatura"/>
<img :src="getEmailSrc('email-logo.png')" alt="VerdNatura"/>
</a>
</header>

View File

@ -1,4 +1,4 @@
module.exports = {
name: 'email-header',
props: ['isPreview']
props: ['locale']
};

View File

@ -1,6 +1,6 @@
const CssReader = require(`${appPath}/lib/cssReader`);
const Stylesheet = require(`${appPath}/core/stylesheet`);
module.exports = new CssReader([
module.exports = new Stylesheet([
`${appPath}/common/css/layout.css`,
`${appPath}/common/css/report.css`,
`${appPath}/common/css/misc.css`,

View File

@ -1,7 +1,7 @@
<footer>
<section class="page">
<section :if="leftText">{{leftText}}</section>
<section :if="centerText" class="uppercase">{{centerText}}</section>
<section v-if="leftText">{{leftText}}</section>
<section v-if="centerText" class="uppercase">{{centerText}}</section>
<section class="number">{{$t('numPages')}}</section>
</section>
<p class="phytosanitary">{{$t('law.phytosanitary')}}</p>

View File

@ -1,8 +1,4 @@
module.exports = {
name: 'report-footer',
created() {
if (this.locale)
this.$i18n.locale = this.locale;
},
props: ['leftText', 'centerText', 'locale']
};

View File

@ -1,6 +1,6 @@
const CssReader = require(`${appPath}/lib/cssReader`);
const Stylesheet = require(`${appPath}/core/stylesheet`);
module.exports = new CssReader([
module.exports = new Stylesheet([
`${appPath}/common/css/layout.css`,
`${appPath}/common/css/report.css`,
`${appPath}/common/css/misc.css`,

View File

@ -1,5 +1,5 @@
<header>
<img :src="embeded['/assets/images/report-logo.svg']" alt="Verdnatura"/>
<img v-bind:src="getReportSrc('report-logo.svg')" alt="Verdnatura"/>
<section>{{$t('company.fiscalAddress')}}</section>
<section>{{$t('company.registry')}}</section>
</header>

View File

@ -1,19 +1,4 @@
module.exports = {
name: 'report-header',
created() {
if (this.locale)
this.$i18n.locale = this.locale;
const embeded = [];
this.files.map(file => {
embeded[file] = `file://${__dirname + file}`;
});
this.embeded = embeded;
},
data() {
return {
files: ['/assets/images/report-logo.svg'],
};
},
props: ['locale']
props: ['isPreview', 'locale']
};

View File

@ -6,11 +6,14 @@ module.exports = {
if (!this.pool)
this.pool = mysql.createPool(config.mysql);
},
findOne(query, params) {
find(query, params) {
return this.pool.query(query, params).then(([rows]) => {
return rows[0];
return rows;
});
},
findOne(query, params) {
return this.find(query, params).then(([rows]) => rows);
},
findFromDef() {
}

View File

@ -1 +1,2 @@
// Import global directives
require('./pin');

View File

@ -0,0 +1,12 @@
// DIRECTIVES NOT WORKING
const Vue = require('vue');
Vue.directive('pin', {
bind: function(el, binding, vnode) {
el.style.position = 'fixed';
el.style.top = binding.value + 'px';
el.style.backgroundColor = 'red';
},
update() {
console.log('asd');
}
});

View File

@ -2,6 +2,8 @@ const path = require('path');
const smtp = require('./smtp');
const Component = require('./component');
const Report = require('./report');
const db = require('./database');
const config = require('./config');
if (!process.env.OPENSSL_CONF)
process.env.OPENSSL_CONF = '/etc/ssl/';
@ -18,8 +20,28 @@ class Email extends Component {
}
get subject() {
return null;
async getSubject() {
if (!this.lang) await this.getLang();
const locale = this.locale.messages;
const userLocale = locale[this.lang];
if (!userLocale) {
const fallbackLocale = config.i18n.fallbackLocale;
return locale[fallbackLocale].subject;
}
return userLocale.subject;
}
async getLang() {
const clientId = this.args.clientId;
const lang = await db.findOne(`
SELECT lang FROM account.user
WHERE id = ?`, [clientId]).then(rows => {
return rows.lang;
});
this.lang = lang;
}
async send() {
@ -48,30 +70,18 @@ class Email extends Component {
const components = instance.components;
for (let componentName in components) {
const component = components[componentName];
const componentPath = `../components/${componentName}`;
const componentPath = `./components/${componentName}`;
await getAttachments(componentPath, component.attachments);
}
}
if (this.attachments)
await getAttachments(this.path, this.attachments);
/*
this.attachments.forEach(file => {
const fileCopy = Object.assign({}, file);
if (fileCopy.path) {
const templatePath = `${this.path}/${file.path}`;
const fullFilePath = path.resolve(__dirname, templatePath);
fileCopy.path = path.resolve(__dirname, fullFilePath);
}
attachments.push(fileCopy);
}); */
const localeSubject = await this.getSubject();
const options = {
to: this.args.recipient,
subject: 'Test',
subject: localeSubject,
html: rendered,
attachments: attachments
};
@ -81,133 +91,3 @@ class Email extends Component {
}
module.exports = Email;
/* module.exports = {
path: `${appPath}/report`,
async render(name, ctx) {
const component = require(`${this.path}/${name}`);
const result = await this.preFetch(component, ctx);
const i18n = new VueI18n({
locale: 'es',
fallbackLocale
});
const app = new Vue({i18n,
render: h => h(result.component)});
return renderer.renderToString(app).then(renderedHtml => {
return {
html: renderedHtml,
data: result.mergedData,
};
});
},
async preFetch(orgComponent, ctx) {
let component = Object.create(orgComponent);
let mergedData = {attachments: []};
let asyncData = {};
let data = {};
let params = {};
if (Object.keys(ctx.body).length > 0)
params = ctx.body;
if (Object.keys(ctx.query).length > 0)
params = ctx.query;
await this.attachAssets(component);
if (orgComponent.hasOwnProperty('data'))
data = orgComponent.data();
if (orgComponent.hasOwnProperty('asyncData')) {
asyncData = await orgComponent.asyncData(ctx, params);
if (asyncData.locale) {
let locale = component.i18n.messages[asyncData.locale];
if (!locale)
locale = component.i18n.messages[fallbackLocale];
mergedData.subject = locale.subject;
}
}
mergedData = Object.assign(mergedData, data, asyncData);
component.data = function data() {
return mergedData;
};
if (data.hasOwnProperty('files')) {
const files = data.files;
files.forEach(file => {
const componentPath = `${this.path}/${orgComponent.name}`;
let fileSrc = componentPath + file;
if (file.slice(0, 4) === 'http' || file.slice(0, 5) === 'https')
fileSrc = file;
const fileName = file.split('/').pop();
mergedData.attachments.push({
filename: fileName,
path: fileSrc,
cid: file,
});
});
}
const components = orgComponent.components;
if (components) {
const promises = [];
const childNames = [];
component.components = {};
Object.keys(components).forEach(childName => {
childNames.push(childName);
promises.push(this.preFetch(components[childName], ctx));
});
await Promise.all(promises).then(results => {
results.forEach((result, i) => {
result.mergedData.attachments.forEach(atth => {
mergedData.attachments.push(atth);
});
component.components[childNames[i]] = result.component;
});
});
}
return {component, mergedData};
},
async attachAssets(component) {
const localePath = `${this.path}/${component.name}/locale.js`;
const templatePath = `${this.path}/${component.name}/index.html`;
const stylePath = `${this.path}/${component.name}/assets/css/index.js`;
const template = await fs.readFile(templatePath, 'utf8');
const css = require(stylePath);
component.i18n = require(localePath);
component.template = juice.inlineContent(template, css);
},
async toEmail(name, ctx) {
const rendered = await this.render(name, ctx);
const data = rendered.data;
const options = {
to: data.recipient,
subject: data.subject,
html: rendered.html,
attachments: data.attachments,
};
return smtp.send(options);
},
};
*/

View File

@ -1,12 +0,0 @@
module.exports = class UserException extends Error {
/**
* UserException
* @param {String} message - Error message
*/
constructor(message) {
super(message);
this.httpStatusCode = 400;
this.name = 'UserException';
}
};

View File

@ -1,7 +1,9 @@
const Vue = require('vue');
const currency = {
methods: {
},
};
const config = require('../config');
const defaultLocale = config.i18n.locale;
Vue.mixin(currency);
Vue.filter('currency', function(value, currency = 'EUR', locale = defaultLocale) {
return new Intl.NumberFormat(locale, {
style: 'currency', currency
}).format(parseFloat(value));
});

View File

@ -0,0 +1,6 @@
const Vue = require('vue');
const strftime = require('strftime');
Vue.filter('date', function(value, specifiers) {
return strftime(specifiers, value);
});

View File

@ -1 +1,4 @@
// Import global filters
require('./date');
require('./currency');
require('./percentage');

View File

@ -0,0 +1,11 @@
const Vue = require('vue');
const config = require('../config');
const defaultLocale = config.i18n.locale;
Vue.filter('percentage', function(value, minFraction = 2, maxFraction = 2, locale = defaultLocale) {
return new Intl.NumberFormat(locale, {
style: 'percent',
minimumFractionDigits: minFraction,
maximumFractionDigits: maxFraction
}).format(parseFloat(value));
});

View File

@ -1,13 +1,22 @@
const Vue = require('vue');
const config = require('../config');
const imageSrc = {
methods: {
getSrc(image) {
getEmailSrc(image) {
let src = `cid:${image}`;
if (this.isPreview === 'true')
src = `/api/assets/${this.$options.name}/images/${image}`;
return src;
},
getReportSrc(image) {
const assetsPath = `${config.app.host}/api/assets`;
const imagePath = `${assetsPath}/${this.$options.name}/images/${image}`;
console.log(imagePath);
return imagePath;
}
},
};

View File

@ -1,2 +1,4 @@
// Import global mixins
require('./image-src');
require('./user-locale');
require('./prop-validator');

View File

@ -0,0 +1,26 @@
const Vue = require('vue');
const validator = {
created() {
const props = this.$options.props;
const invalidProps = [];
for (prop in props) {
const isObject = typeof props[prop] === 'object';
const isRequired = props[prop].required;
const isNotDefined = this[prop] === undefined;
if (isObject && isRequired && isNotDefined)
invalidProps.push(prop);
}
if (invalidProps.length > 0) {
const required = invalidProps.join(', ');
throw new Error(`Required params not found [${required}]`);
}
},
props: ['isPreview']
};
Vue.mixin(validator);

View File

@ -0,0 +1,24 @@
const Vue = require('vue');
const db = require('../database');
const userLocale = {
async serverPrefetch() {
if (this.clientId)
this.locale = await this.getLocale(this.clientId);
if (this.locale)
this.$i18n.locale = this.locale;
},
methods: {
getLocale(clientId) {
return db.findOne(`
SELECT lang FROM account.user
WHERE id = ?`, [clientId]).then(rows => {
return rows.lang;
});
}
},
props: ['clientId']
};
Vue.mixin(userLocale);

View File

@ -1,5 +1,6 @@
const fs = require('fs');
const pdf = require('html-pdf');
const path = require('path');
const config = require('./config');
const Component = require('./component');
@ -22,9 +23,12 @@ class Report extends Component {
let options = config.pdf;
const optionsPath = `${this.path}/options.json`;
if (fs.existsSync(optionsPath))
const fullPath = path.resolve(__dirname, optionsPath);
if (fs.existsSync(fullPath))
options = Object.assign(options, require(optionsPath));
console.log(fs.existsSync(optionsPath));
return new Promise(resolve => {
pdf.create(template, options).toStream((err, stream) => {
resolve(stream);
@ -34,101 +38,3 @@ class Report extends Component {
}
module.exports = Report;
/* module.exports = {
path: `${appPath}/report`,
async render(name, ctx) {
const component = require(`${this.path}/${name}`);
const i18n = new VueI18n(config.i18n);
const app = new Vue({
i18n: i18n,
render: h => h(component, {
props: {
myProp: 'asd1'
}
})
});
return renderer.renderToString(app);
},
async preFetch(orgComponent, ctx) {
let component = Object.create(orgComponent);
let mergedData = {};
let asyncData = {};
let data = {};
let params = {};
if (Object.keys(ctx.body).length > 0)
params = ctx.body;
if (Object.keys(ctx.query).length > 0)
params = ctx.query;
await this.attachAssets(component);
if (orgComponent.hasOwnProperty('data'))
data = orgComponent.data();
if (orgComponent.hasOwnProperty('asyncData'))
asyncData = await orgComponent.asyncData(ctx, params);
mergedData = Object.assign(mergedData, data, asyncData);
component.data = function data() {
return mergedData;
};
const components = orgComponent.components;
if (components) {
const promises = [];
const childNames = [];
component.components = {};
Object.keys(components).forEach(childName => {
childNames.push(childName);
promises.push(this.preFetch(components[childName], ctx));
});
await Promise.all(promises).then(results => {
results.forEach((result, i) => {
component.components[childNames[i]] = result.component;
});
});
}
return {component};
},
async attachAssets(component) {
const localePath = `${this.path}/${component.name}/locale`;
const templatePath = `${this.path}/${component.name}/index.html`;
const stylePath = `${this.path}/${component.name}/assets/css/index`;
const template = await fs.readFile(templatePath, 'utf8');
const css = require(stylePath);
const cssOptions = {inlinePseudoElements: true};
component.i18n = require(localePath);
component.template = juice.inlineContent(template, css, cssOptions);
},
async toPdf(name, ctx) {
const html = await this.render(name, ctx);
let options = config.pdf;
const optionsPath = `${this.path}/${name}/options.json`;
if (fs.existsSync(optionsPath))
options = Object.assign(options, require(optionsPath));
return new Promise(resolve => {
pdf.create(html, options).toStream((err, stream) => {
resolve(stream);
});
});
},
};
*/

View File

@ -1,92 +1,45 @@
const express = require('express');
const path = require('path');
const fs = require('fs');
const Report = require('./report');
const Email = require('./email');
const templatesPath = path.resolve(__dirname, '../templates');
const componentsPath = path.resolve(__dirname, './components');
module.exports = app => {
/**
* Serve component static files
*/
const componentsDir = fs.readdirSync(componentsPath);
componentsDir.forEach(componentName => {
const componentDir = path.join(componentsPath, '/', componentName);
const assetsDir = `${componentDir}/assets`;
app.use(`/api/assets/${componentName}`, express.static(assetsDir));
});
/**
* Serve static files
*/
const templatesDir = fs.readdirSync(templatesPath);
templatesDir.forEach(directory => {
const templateTypeDir = path.join(templatesPath, '/', directory);
const templates = fs.readdirSync(templateTypeDir);
templates.forEach(templateName => {
const templateDir = path.join(templatesPath, '/', directory, '/', templateName);
const assetsDir = `${templateDir}/assets`;
app.use(`/api/assets/${templateName}`, express.static(assetsDir));
});
});
app.get(`/api/report/:name`, async(req, res) => {
app.get(`/api/report/:name`, async(req, res, next) => {
const args = Object.assign({}, req.body, req.query);
const report = new Report(req.params.name, args);
const stream = await report.toPdfStream();
res.setHeader('Content-type', 'application/pdf');
stream.pipe(res);
try {
const report = new Report(req.params.name, args);
const stream = await report.toPdfStream();
res.setHeader('Content-type', 'application/pdf');
stream.pipe(res);
} catch (e) {
next(e);
}
});
app.get(`/api/email/:name`, async(req, res) => {
app.get(`/api/email/:name`, async(req, res, next) => {
const args = req.query;
const requiredArgs = ['userId'];
const requiredArgs = ['recipient', 'clientId'];
const hasRequiredArgs = requiredArgs.every(arg => {
return args[arg];
});
if (!hasRequiredArgs)
res.json({message: 'userId'});
res.json({message: 'Required params recipient, clientId'});
const email = new Email(req.params.name, args);
if (args.isPreview === 'true') {
const rendered = await email.render();
try {
const email = new Email(req.params.name, args);
if (args.isPreview === 'true') {
const rendered = await email.render();
res.send(rendered);
} else {
await email.send();
res.status(200).json({message: 'Sent'});
res.send(rendered);
} else {
await email.send();
res.status(200).json({message: 'Sent'});
}
} catch (e) {
next(e);
}
});
/*
app.post(`/api/email/${name}`, (request, response, next) => {
emailEngine.toEmail(name, request).then(() => {
response.status(200).json({status: 200});
}).catch(e => {
next(e);
});
}); */
/* routes.forEach(route => {
if (route.type === 'email')
registerEmail(route.name);
else if (route.type === 'report')
registerReport(route.name);
const staticPath = this.path + `/${route.name}/assets`;
}); */
/**
* Enables a report

View File

@ -1,6 +1,6 @@
const fs = require('fs-extra');
class CssReader {
class Stylesheet {
constructor(files) {
this.files = files;
this.css = [];
@ -15,4 +15,4 @@ class CssReader {
}
}
module.exports = CssReader;
module.exports = Stylesheet;

556
print/package-lock.json generated
View File

@ -21,9 +21,12 @@
"integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8="
},
"ansi-styles": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
"integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4="
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
"integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
"requires": {
"color-convert": "^1.9.0"
}
},
"argparse": {
"version": "1.0.10",
@ -47,12 +50,9 @@
"integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU="
},
"async": {
"version": "2.6.1",
"resolved": "https://registry.npmjs.org/async/-/async-2.6.1.tgz",
"integrity": "sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ==",
"requires": {
"lodash": "^4.17.10"
}
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/async/-/async-3.1.0.tgz",
"integrity": "sha512-4vx/aaY6j/j3Lw3fbCHNWP0pPaTCew3F6F3hYyl/tHs/ndmV1q7NW9T5yuJ2XAGwdQrP+6Wu20x06U4APo/iQQ=="
},
"asynckit": {
"version": "0.4.0",
@ -88,21 +88,24 @@
"integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==",
"optional": true
},
"camelcase": {
"version": "5.3.1",
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
"integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg=="
},
"caseless": {
"version": "0.12.0",
"resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
"integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw="
},
"chalk": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
"integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
"version": "2.4.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
"integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
"requires": {
"ansi-styles": "^2.2.1",
"escape-string-regexp": "^1.0.2",
"has-ansi": "^2.0.0",
"strip-ansi": "^3.0.0",
"supports-color": "^2.0.0"
"ansi-styles": "^3.2.1",
"escape-string-regexp": "^1.0.5",
"supports-color": "^5.3.0"
}
},
"cheerio": {
@ -128,6 +131,44 @@
"lodash.some": "^4.4.0"
}
},
"cliui": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz",
"integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==",
"requires": {
"string-width": "^3.1.0",
"strip-ansi": "^5.2.0",
"wrap-ansi": "^5.1.0"
},
"dependencies": {
"ansi-regex": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
"integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg=="
},
"strip-ansi": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
"integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
"requires": {
"ansi-regex": "^4.1.0"
}
}
}
},
"color-convert": {
"version": "1.9.3",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
"integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
"requires": {
"color-name": "1.1.3"
}
},
"color-name": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU="
},
"combined-stream": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.7.tgz",
@ -137,9 +178,9 @@
}
},
"commander": {
"version": "2.19.0",
"resolved": "https://registry.npmjs.org/commander/-/commander-2.19.0.tgz",
"integrity": "sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg=="
"version": "2.20.3",
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
"integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ=="
},
"concat-stream": {
"version": "1.6.2",
@ -208,9 +249,9 @@
}
},
"css-what": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.2.tgz",
"integrity": "sha512-wan8dMWQ0GUeF7DGEPVjhHemVW/vy6xUYmFzRY8RYqgA0JtXC9rJmbScBjqSu6dg9q0lwPQy6ZAmJVr3PPTvqQ=="
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.3.tgz",
"integrity": "sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg=="
},
"dashdash": {
"version": "1.14.1",
@ -221,13 +262,12 @@
}
},
"datauri": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/datauri/-/datauri-1.1.0.tgz",
"integrity": "sha512-0q+cTTKx7q8eDteZRIQLTFJuiIsVing17UbWTPssY4JLSMaYsk/VKpNulBDo9NSgQWcvlPrkEHW8kUO67T/7mQ==",
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/datauri/-/datauri-2.0.0.tgz",
"integrity": "sha512-zS2HSf9pI5XPlNZgIqJg/wCJpecgU/HA6E/uv2EfaWnW1EiTGLfy/EexTIsC9c99yoCOTXlqeeWk4FkCSuO3/g==",
"requires": {
"image-size": "^0.6.2",
"mimer": "^0.3.2",
"semver": "^5.5.0"
"image-size": "^0.7.3",
"mimer": "^1.0.0"
}
},
"debug": {
@ -239,6 +279,11 @@
"ms": "2.0.0"
}
},
"decamelize": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
"integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA="
},
"deep-extend": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
@ -250,24 +295,22 @@
"integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk="
},
"denque": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/denque/-/denque-1.4.0.tgz",
"integrity": "sha512-gh513ac7aiKrAgjiIBWZG0EASyDF9p4JMWwKA8YU5s9figrL5SRNEMT6FDynsegakuhWd1wVqTvqvqAoDxw7wQ=="
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/denque/-/denque-1.4.1.tgz",
"integrity": "sha512-OfzPuSZKGcgr96rf1oODnfjqBFmr1DVoc/TrItj3Ohe0Ah1C5WX5Baquw/9U9KovnQ88EqmJbD66rKYUQYN1tQ=="
},
"dijkstrajs": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/dijkstrajs/-/dijkstrajs-1.0.1.tgz",
"integrity": "sha1-082BIh4+pAdCz83lVtTpnpjdxxs="
},
"dom-serializer": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.0.tgz",
"integrity": "sha1-BzxpdUbOB4DOI75KKOKT5AvDDII=",
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.1.tgz",
"integrity": "sha512-l0IU0pPzLWSHBcieZbpOKgkIn3ts3vAh7ZuFyXNwJxJXk/c4Gwj9xaTJwIDVQCXawWD0qb3IzMGH5rglQaO0XA==",
"requires": {
"domelementtype": "~1.1.1",
"entities": "~1.1.1"
},
"dependencies": {
"domelementtype": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.1.3.tgz",
"integrity": "sha1-vSh3PiZCiBrsUVRJJCmcXNgiGFs="
}
"domelementtype": "^1.3.0",
"entities": "^1.1.1"
}
},
"domelementtype": {
@ -301,6 +344,11 @@
"safer-buffer": "^2.1.0"
}
},
"emoji-regex": {
"version": "7.0.3",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz",
"integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA=="
},
"entities": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz",
@ -363,6 +411,14 @@
"pend": "~1.2.0"
}
},
"find-up": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
"integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
"requires": {
"locate-path": "^3.0.0"
}
},
"forever-agent": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
@ -396,6 +452,11 @@
"is-property": "^1.0.2"
}
},
"get-caller-file": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
"integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg=="
},
"getpass": {
"version": "0.1.7",
"resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
@ -431,6 +492,11 @@
"ansi-regex": "^2.0.0"
}
},
"has-flag": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
"integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0="
},
"hash-sum": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/hash-sum/-/hash-sum-1.0.2.tgz",
@ -460,16 +526,16 @@
}
},
"htmlparser2": {
"version": "3.10.0",
"resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.0.tgz",
"integrity": "sha512-J1nEUGv+MkXS0weHNWVKJJ+UrLfePxRWpN3C9bEi9fLxL2+ggW94DQvgYVXsaT30PGwYRIZKNZXuyMhp3Di4bQ==",
"version": "3.10.1",
"resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz",
"integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==",
"requires": {
"domelementtype": "^1.3.0",
"domelementtype": "^1.3.1",
"domhandler": "^2.3.0",
"domutils": "^1.5.1",
"entities": "^1.1.1",
"inherits": "^2.0.1",
"readable-stream": "^3.0.6"
"readable-stream": "^3.1.1"
}
},
"http-signature": {
@ -483,23 +549,33 @@
}
},
"iconv-lite": {
"version": "0.4.24",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
"integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
"version": "0.5.0",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.5.0.tgz",
"integrity": "sha512-NnEhI9hIEKHOzJ4f697DMz9IQEXr/MMJ5w64vN2/4Ai+wRnvV7SBrL0KLoRlwaKVghOc7LQ5YkPLuX146b6Ydw==",
"requires": {
"safer-buffer": ">= 2.1.2 < 3"
}
},
"image-size": {
"version": "0.6.3",
"resolved": "https://registry.npmjs.org/image-size/-/image-size-0.6.3.tgz",
"integrity": "sha512-47xSUiQioGaB96nqtp5/q55m0aBQSQdyIloMOc/x+QVTDZLNmXE892IIDrJ0hM1A5vcNUDD5tDffkSP5lCaIIA=="
"version": "0.7.5",
"resolved": "https://registry.npmjs.org/image-size/-/image-size-0.7.5.tgz",
"integrity": "sha512-Hiyv+mXHfFEP7LzUL/llg9RwFxxY+o9N3JVLIeG5E7iFIFAalxvRU9UZthBdYDEVnzHMgjnKJPPpay5BWf1g9g=="
},
"inherits": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
},
"intl": {
"version": "1.2.5",
"resolved": "https://registry.npmjs.org/intl/-/intl-1.2.5.tgz",
"integrity": "sha1-giRKIZDE5Bn4Nx9ao02qNCDiq94="
},
"is-fullwidth-code-point": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
"integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8="
},
"is-property": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz",
@ -581,9 +657,9 @@
}
},
"juice": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/juice/-/juice-5.1.0.tgz",
"integrity": "sha512-SRfLv0y7xwAKnsd6HWS9aSF0+a9ozXEatKlXHiiTvozdZu0Vwz9dDk7NEpy/N2icFTnhYtk1Du3rPNtH7fFVHw==",
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/juice/-/juice-5.2.0.tgz",
"integrity": "sha512-0l6GZmT3efexyaaay3SchKT5kG311N59TEFP5lfvEy0nz9SNqjx311plJ3b4jze7arsmDsiHQLh/xnAuk0HFTQ==",
"requires": {
"cheerio": "^0.22.0",
"commander": "^2.15.1",
@ -591,7 +667,7 @@
"deep-extend": "^0.6.0",
"mensch": "^0.3.3",
"slick": "^1.12.2",
"web-resource-inliner": "^4.2.1"
"web-resource-inliner": "^4.3.1"
}
},
"kew": {
@ -609,10 +685,14 @@
"graceful-fs": "^4.1.9"
}
},
"lodash": {
"version": "4.17.11",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz",
"integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg=="
"locate-path": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
"integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
"requires": {
"p-locate": "^3.0.0",
"path-exists": "^3.0.0"
}
},
"lodash._reinterpolate": {
"version": "3.0.0",
@ -655,9 +735,9 @@
"integrity": "sha1-dx7Hg540c9nEzeKLGTlMNWL09tM="
},
"lodash.merge": {
"version": "4.6.1",
"resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.1.tgz",
"integrity": "sha512-AOYza4+Hf5z1/0Hztxpm2/xiPZgi/cjMqdnKTUWTBSKchJlxXXuUSxCCl8rJlf4g6yww/j6mA8nC8Hw/EZWxKQ=="
"version": "4.6.2",
"resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
"integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ=="
},
"lodash.pick": {
"version": "4.4.0",
@ -680,20 +760,20 @@
"integrity": "sha1-G7nzFO9ri63tE7VJFpsqlF62jk0="
},
"lodash.template": {
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.4.0.tgz",
"integrity": "sha1-5zoDhcg1VZF0bgILmWecaQ5o+6A=",
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.5.0.tgz",
"integrity": "sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A==",
"requires": {
"lodash._reinterpolate": "~3.0.0",
"lodash._reinterpolate": "^3.0.0",
"lodash.templatesettings": "^4.0.0"
}
},
"lodash.templatesettings": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.1.0.tgz",
"integrity": "sha1-K01OlbpEDZFf8IvImeRVNmZxMxY=",
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz",
"integrity": "sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ==",
"requires": {
"lodash._reinterpolate": "~3.0.0"
"lodash._reinterpolate": "^3.0.0"
}
},
"lodash.unescape": {
@ -712,12 +792,11 @@
"integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA=="
},
"lru-cache": {
"version": "4.1.5",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz",
"integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==",
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
"integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
"requires": {
"pseudomap": "^1.0.2",
"yallist": "^2.1.2"
"yallist": "^3.0.2"
}
},
"mensch": {
@ -739,9 +818,9 @@
}
},
"mimer": {
"version": "0.3.2",
"resolved": "https://registry.npmjs.org/mimer/-/mimer-0.3.2.tgz",
"integrity": "sha512-N6NcgDQAevhP/02DQ/epK6daLy4NKrIHyTlJcO6qBiYn98q+Y4a/knNsAATCe1xLS2F0nEmJp+QYli2s8vKwyQ=="
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/mimer/-/mimer-1.0.0.tgz",
"integrity": "sha512-4ZJvCzfcwsBgPbkKXUzGoVZMWjv8IDIygkGzVc7uUYhgnK0t2LmGxxjdgH1i+pn0/KQfB5F/VKUJlfyTSOFQjg=="
},
"minimist": {
"version": "0.0.8",
@ -765,15 +844,15 @@
"optional": true
},
"mysql2": {
"version": "1.6.5",
"resolved": "https://registry.npmjs.org/mysql2/-/mysql2-1.6.5.tgz",
"integrity": "sha512-zedaOOyb3msuuZcJJnxIX/EGOpmljDG7B+UevRH5lqcv+yhy9eCwkArBz8/AO+/rlY3/oCsOdG8R5oD6k0hNfg==",
"version": "1.7.0",
"resolved": "https://registry.npmjs.org/mysql2/-/mysql2-1.7.0.tgz",
"integrity": "sha512-xTWWQPjP5rcrceZQ7CSTKR/4XIDeH/cRkNH/uzvVGQ7W5c7EJ0dXeJUusk7OKhIoHj7uFKUxDVSCfLIl+jluog==",
"requires": {
"denque": "^1.4.0",
"denque": "^1.4.1",
"generate-function": "^2.3.1",
"iconv-lite": "^0.4.24",
"iconv-lite": "^0.5.0",
"long": "^4.0.0",
"lru-cache": "^4.1.3",
"lru-cache": "^5.1.1",
"named-placeholders": "^1.1.2",
"seq-queue": "^0.0.5",
"sqlstring": "^2.3.1"
@ -785,6 +864,22 @@
"integrity": "sha512-wiFWqxoLL3PGVReSZpjLVxyJ1bRqe+KKJVbr4hGs1KWfTZTQyezHFBbuKj9hsizHyGV2ne7EMjHdxEGAybD5SA==",
"requires": {
"lru-cache": "^4.1.3"
},
"dependencies": {
"lru-cache": {
"version": "4.1.5",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz",
"integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==",
"requires": {
"pseudomap": "^1.0.2",
"yallist": "^2.1.2"
}
},
"yallist": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
"integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI="
}
}
},
"nice-try": {
@ -810,6 +905,32 @@
"resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
"integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ=="
},
"p-limit": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.1.tgz",
"integrity": "sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg==",
"requires": {
"p-try": "^2.0.0"
}
},
"p-locate": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz",
"integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
"requires": {
"p-limit": "^2.0.0"
}
},
"p-try": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
"integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ=="
},
"path-exists": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
"integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU="
},
"path-key": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz",
@ -885,6 +1006,11 @@
"pinkie": "^2.0.0"
}
},
"pngjs": {
"version": "3.4.0",
"resolved": "https://registry.npmjs.org/pngjs/-/pngjs-3.4.0.tgz",
"integrity": "sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w=="
},
"process-nextick-args": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz",
@ -912,15 +1038,33 @@
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
"integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A=="
},
"qrcode": {
"version": "1.4.2",
"resolved": "https://registry.npmjs.org/qrcode/-/qrcode-1.4.2.tgz",
"integrity": "sha512-eR6RgxFYPDFH+zFLTJKtoNP/RlsHANQb52AUmQ2bGDPMuUw7jJb0F+DNEgx7qQGIElrbFxWYMc0/B91zLZPF9Q==",
"requires": {
"dijkstrajs": "^1.0.1",
"isarray": "^2.0.1",
"pngjs": "^3.3.0",
"yargs": "^13.2.4"
},
"dependencies": {
"isarray": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz",
"integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw=="
}
}
},
"qs": {
"version": "6.5.2",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz",
"integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA=="
},
"readable-stream": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.1.1.tgz",
"integrity": "sha512-DkN66hPyqDhnIQ6Jcsvx9bFjhw214O4poMBcIMgPVpQvNy9a0e0Uhg5SqySyDKAmUlwt8LonTBz1ezOnM8pUdA==",
"version": "3.4.0",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.4.0.tgz",
"integrity": "sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==",
"requires": {
"inherits": "^2.0.3",
"string_decoder": "^1.1.1",
@ -963,10 +1107,20 @@
"throttleit": "^1.0.0"
}
},
"require-directory": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
"integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I="
},
"require-main-filename": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz",
"integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg=="
},
"resolve": {
"version": "1.10.0",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.10.0.tgz",
"integrity": "sha512-3sUr9aq5OfSg2S9pNtPA9hL1FVEAjvfOC4leW0SNf/mpnaakz2a9femSd6LqAww2RaFctwyf1lCqnTHuF1rxDg==",
"version": "1.12.0",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.12.0.tgz",
"integrity": "sha512-B/dOmuoAik5bKcD6s6nXDCjzUKnaDvdkRyAk6rsmsKLipWj4797iothd7jmmUhWTfinVMU+wc56rYKsit2Qy4w==",
"requires": {
"path-parse": "^1.0.6"
}
@ -982,9 +1136,9 @@
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
},
"semver": {
"version": "5.6.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz",
"integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg=="
"version": "5.7.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ=="
},
"seq-queue": {
"version": "0.0.5",
@ -992,9 +1146,14 @@
"integrity": "sha1-1WgS4cAXpuTnw+Ojeh2m143TyT4="
},
"serialize-javascript": {
"version": "1.6.1",
"resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-1.6.1.tgz",
"integrity": "sha512-A5MOagrPFga4YaKQSWHryl7AXvbQkEqpw4NNYMTNYUNV51bA8ABHgYFpqKx+YFFrw59xMV1qGH1R4AgoNIVgCw=="
"version": "1.9.1",
"resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-1.9.1.tgz",
"integrity": "sha512-0Vb/54WJ6k5v8sSWN09S0ora+Hnr+cX40r9F170nT+mSkaxltoE/7R3OrIdBSUv1OoiobH1QoWQbCnAO+e8J1A=="
},
"set-blocking": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
"integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc="
},
"shebang-command": {
"version": "1.2.0",
@ -1050,12 +1209,44 @@
"resolved": "https://registry.npmjs.org/strftime/-/strftime-0.10.0.tgz",
"integrity": "sha1-s/D6QZKVICpaKJ9ta+n0kJphcZM="
},
"string_decoder": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.2.0.tgz",
"integrity": "sha512-6YqyX6ZWEYguAxgZzHGL7SsCeGx3V2TtOTqZz1xSTSWnqsbWwbptafNyvf/ACquZUXV3DANr5BDIwNYe1mN42w==",
"string-width": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
"integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
"requires": {
"safe-buffer": "~5.1.0"
"emoji-regex": "^7.0.1",
"is-fullwidth-code-point": "^2.0.0",
"strip-ansi": "^5.1.0"
},
"dependencies": {
"ansi-regex": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
"integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg=="
},
"strip-ansi": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
"integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
"requires": {
"ansi-regex": "^4.1.0"
}
}
}
},
"string_decoder": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
"integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
"requires": {
"safe-buffer": "~5.2.0"
},
"dependencies": {
"safe-buffer": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz",
"integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg=="
}
}
},
"strip-ansi": {
@ -1067,9 +1258,12 @@
}
},
"supports-color": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
"integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc="
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
"integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
"requires": {
"has-flag": "^3.0.0"
}
},
"throttleit": {
"version": "1.0.0",
@ -1136,9 +1330,9 @@
"integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA=="
},
"valid-data-url": {
"version": "0.1.6",
"resolved": "https://registry.npmjs.org/valid-data-url/-/valid-data-url-0.1.6.tgz",
"integrity": "sha512-FXg2qXMzfAhZc0y2HzELNfUeiOjPr+52hU1DNBWiJJ2luXD+dD1R9NA48Ug5aj0ibbxroeGDc/RJv6ThiGgkDw=="
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/valid-data-url/-/valid-data-url-2.0.0.tgz",
"integrity": "sha512-dyCZnv3aCey7yfTgIqdZanKl7xWAEEKCbgmR7SKqyK6QT/Z07ROactrgD1eA37C69ODRj7rNOjzKWVPh0EUjBA=="
},
"verror": {
"version": "1.10.0",
@ -1151,19 +1345,19 @@
}
},
"vue": {
"version": "2.6.7",
"resolved": "https://registry.npmjs.org/vue/-/vue-2.6.7.tgz",
"integrity": "sha512-g7ADfQ82QU+j6F/bVDioVQf2ccIMYLuR4E8ev+RsDBlmwRkhGO3HhgF4PF9vpwjdPpxyb1zzLur2nQ2oIMAMEg=="
"version": "2.6.10",
"resolved": "https://registry.npmjs.org/vue/-/vue-2.6.10.tgz",
"integrity": "sha512-ImThpeNU9HbdZL3utgMCq0oiMzAkt1mcgy3/E6zWC/G6AaQoeuFdsl9nDhTDU3X1R6FK7nsIUuRACVcjI+A2GQ=="
},
"vue-i18n": {
"version": "8.8.2",
"resolved": "https://registry.npmjs.org/vue-i18n/-/vue-i18n-8.8.2.tgz",
"integrity": "sha512-P09ZN2S0mX1AmhSR/+wP2owP3izGVx1pSoDFcOXTLya5xvP95dG7kc9LQUnboPgSzK/JKe9FkYmoYdDTKDjPSw=="
"version": "8.15.0",
"resolved": "https://registry.npmjs.org/vue-i18n/-/vue-i18n-8.15.0.tgz",
"integrity": "sha512-juJ/avAP39bOMycC+qQDLJ8U9z9LtLF/9PsRoJLBSfsYZo9bqYntyyX5QPicwlb1emJKjgxhZ3YofHiQcXBu0Q=="
},
"vue-server-renderer": {
"version": "2.6.7",
"resolved": "https://registry.npmjs.org/vue-server-renderer/-/vue-server-renderer-2.6.7.tgz",
"integrity": "sha512-CVtGR+bE63y4kyIeOcCEF2UNKquSquFQAsTHZ5R1cGM4L4Z0BXgAUEcngTOy8kN+tubt3c1zpRvbrok/bHKeDg==",
"version": "2.6.10",
"resolved": "https://registry.npmjs.org/vue-server-renderer/-/vue-server-renderer-2.6.10.tgz",
"integrity": "sha512-UYoCEutBpKzL2fKCwx8zlRtRtwxbPZXKTqbl2iIF4yRZUNO/ovrHyDAJDljft0kd+K0tZhN53XRHkgvCZoIhug==",
"requires": {
"chalk": "^1.1.3",
"hash-sum": "^1.0.2",
@ -1173,21 +1367,46 @@
"resolve": "^1.2.0",
"serialize-javascript": "^1.3.0",
"source-map": "0.5.6"
},
"dependencies": {
"ansi-styles": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
"integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4="
},
"chalk": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
"integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
"requires": {
"ansi-styles": "^2.2.1",
"escape-string-regexp": "^1.0.2",
"has-ansi": "^2.0.0",
"strip-ansi": "^3.0.0",
"supports-color": "^2.0.0"
}
},
"supports-color": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
"integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc="
}
}
},
"web-resource-inliner": {
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/web-resource-inliner/-/web-resource-inliner-4.2.1.tgz",
"integrity": "sha512-fOWnBQHVX8zHvEbECDTxtYL0FXIIZZ5H3LWoez8mGopYJK7inEru1kVMDzM1lVdeJBNEqUnNP5FBGxvzuMcwwQ==",
"version": "4.3.3",
"resolved": "https://registry.npmjs.org/web-resource-inliner/-/web-resource-inliner-4.3.3.tgz",
"integrity": "sha512-Qk19pohqZs3SoFUW4ZlOHlM8hsOnXhTpCrQ16b1qtJtKzJgO7NZLGP+/lcb2g3hWDQD39/LE/JYOn1Sjy7tn1A==",
"requires": {
"async": "^2.1.2",
"chalk": "^1.1.3",
"datauri": "^1.0.4",
"async": "^3.1.0",
"chalk": "^2.4.2",
"datauri": "^2.0.0",
"htmlparser2": "^3.9.2",
"lodash.unescape": "^4.0.1",
"request": "^2.78.0",
"valid-data-url": "^0.1.4",
"xtend": "^4.0.0"
"safer-buffer": "^2.1.2",
"valid-data-url": "^2.0.0",
"xtend": "^4.0.2"
}
},
"which": {
@ -1198,15 +1417,84 @@
"isexe": "^2.0.0"
}
},
"which-module": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz",
"integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho="
},
"wrap-ansi": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz",
"integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==",
"requires": {
"ansi-styles": "^3.2.0",
"string-width": "^3.0.0",
"strip-ansi": "^5.0.0"
},
"dependencies": {
"ansi-regex": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
"integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg=="
},
"ansi-styles": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
"integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
"requires": {
"color-convert": "^1.9.0"
}
},
"strip-ansi": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
"integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
"requires": {
"ansi-regex": "^4.1.0"
}
}
}
},
"xtend": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz",
"integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68="
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
"integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ=="
},
"y18n": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz",
"integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w=="
},
"yallist": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
"integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI="
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
"integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="
},
"yargs": {
"version": "13.3.0",
"resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.0.tgz",
"integrity": "sha512-2eehun/8ALW8TLoIl7MVaRUrg+yCnenu8B4kBlRxj3GJGDKU1Og7sMXPNm1BYyM1DOJmTZ4YeN/Nwxv+8XJsUA==",
"requires": {
"cliui": "^5.0.0",
"find-up": "^3.0.0",
"get-caller-file": "^2.0.1",
"require-directory": "^2.1.1",
"require-main-filename": "^2.0.0",
"set-blocking": "^2.0.0",
"string-width": "^3.0.0",
"which-module": "^2.0.0",
"y18n": "^4.0.0",
"yargs-parser": "^13.1.1"
}
},
"yargs-parser": {
"version": "13.1.1",
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.1.tgz",
"integrity": "sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ==",
"requires": {
"camelcase": "^5.0.0",
"decamelize": "^1.2.0"
}
},
"yauzl": {
"version": "2.4.1",

View File

@ -15,14 +15,15 @@
"dependencies": {
"fs-extra": "^7.0.1",
"html-pdf": "^2.2.0",
"intl": "^1.2.5",
"js-yaml": "^3.13.1",
"juice": "^5.0.1",
"mysql2": "^1.6.5",
"juice": "^5.2.0",
"mysql2": "^1.7.0",
"nodemailer": "^4.7.0",
"qrcode": "^1.4.2",
"strftime": "^0.10.0",
"vue": "^2.6.7",
"vue-i18n": "^8.8.2",
"vue-server-renderer": "^2.6.7"
"vue": "^2.6.10",
"vue-i18n": "^8.15.0",
"vue-server-renderer": "^2.6.10"
}
}

View File

@ -1,19 +0,0 @@
module.exports = app => {
global.appPath = __dirname;
process.env.OPENSSL_CONF = '/etc/ssl/';
// Init database instance
require('./core/database').init();
// Init SMTP Instance
require('./core/smtp').init();
require('./core/router')(app);
require('./core/mixins');
require('./core/filters');
require('./core/directives');
// require('./core/components/email-header/email-header');
};

View File

@ -1,44 +0,0 @@
/**
* Email only stylesheet
*
*/
body {
background-color: #EEE
}
.container {
max-width: 600px;
min-width: 320px;
margin: 0 auto;
color: #555
}
.main {
background-color: #FFF;
padding: 20px
}
.main a {
color: #8dba25
}
.main h1 {
color: #999
}
.main h3 {
font-size: 16px
}
.title {
background-color: #95d831;
text-transform: uppercase;
text-align: center;
padding: 35px 0
}
.title h1 {
font-size: 32px;
color: #333;
margin: 0
}

View File

@ -0,0 +1,7 @@
const Stylesheet = require(`${appPath}/core/stylesheet`);
module.exports = new Stylesheet([
`${appPath}/common/css/layout.css`,
`${appPath}/common/css/email.css`,
`${appPath}/common/css/misc.css`])
.mergeStyles();

View File

@ -1,233 +0,0 @@
/**
* CSS layout elements
*
*/
.container {
font-family: "Roboto", "Helvetica", "Arial", sans-serif;
font-size: 16px
}
.columns {
overflow: hidden
}
.columns .size100 {
width: 100%;
float: left
}
.columns .size75 {
width: 75%;
float: left
}
.columns .size50 {
width: 50%;
float: left
}
.columns .size33 {
width: 33.33%;
float: left
}
.columns .size25 {
width: 25%;
float: left
}
.clearfix {
overflow: hidden;
display: block;
clear: both
}
.panel {
position: relative;
margin-bottom: 15px;
padding-top: 10px;
break-inside: avoid;
break-before: always;
break-after: always;
}
.panel .header {
background-color: #FFF;
padding: 2.5px 10px;
position: absolute;
font-weight: bold;
top: 0px;
left: 17.5px;
}
.panel .body {
border: 1px solid #CCC;
overflow: hidden;
padding: 20px
}
.panel .body h3 {
margin-top: 0
}
.panel.dark .header {
border: 1px solid #808080;
background-color: #FFF;
}
.panel.dark .body {
border: 1px solid #808080;
background-color: #c0c0c0
}
.field {
border-bottom: 1px solid #CCC;
border-left: 1px solid #CCC;
border-top: 1px solid #CCC;
float: left
}
.field span {
border-right: 1px solid #CCC;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
display: table-cell;
vertical-align: middle;
text-align: center;
font-weight: bold
}
.field.square span {
height: 35.4px;
width: 35.4px
}
.emptyField {
border-bottom: 1px dotted grey;
min-height: 1em;
display: block
}
.field.rectangle span {
height: 2em;
width: 8em
}
.pull-left {
float: left !important
}
.pull-right {
float: right !important
}
.vertical-text {
-moz-transform: rotate(90deg);
-webkit-transform: rotate(90deg);
transform: rotate(90deg);
position: absolute;
text-align: center;
font-size: .65em;
right: -108px;
width: 200px;
top: 50%
}
table {
border-collapse: collapse;
border-spacing: 0;
}
.row-oriented, .column-oriented {
text-align: left;
width: 100%
}
.column-oriented {
margin-bottom: 15px
}
.column-oriented td,
.column-oriented th {
padding: 5px 10px
}
.column-oriented thead {
background-color: #e5e5e5
}
.column-oriented thead tr {
border-bottom: 1px solid #808080;
border-top: 1px solid #808080;
background-color: #e5e5e5
}
.column-oriented tfoot {
border-top: 2px solid #808080;
}
.column-oriented tfoot tr:first-child td {
padding-top: 20px !important;
}
.column-oriented .description {
border-bottom: 1px solid #DDD;
font-size: 0.8em
}
.panel .row-oriented td, .panel .row-oriented th {
padding: 10px 0
}
.row-oriented > tbody > tr > td {
width: 30%
}
.row-oriented > tbody > tr > th {
padding-left: 30px;
width: 70%
}
.row-oriented .description {
padding: 0 !important;
font-size: 0.6em;
color: #888
}
.line {
border-bottom: 1px solid #DDD;
border-right: 1px solid #DDD;
border-left: 1px solid #DDD;
position: relative;
margin-left: -1px;
margin-right: 1px;
margin-top: 10px;
color: #999;
padding: 5px 0
}
.line .vertical-aligned {
position: absolute;
text-align: center;
width: 100%;
}
.line span {
background-color: #FFF;
padding: 5px
}
.signature {
width: 100%
}
.signature section {
height: 150px
}
.signature p {
margin-right: 50%;
margin-top: 140px
}

View File

@ -1,47 +0,0 @@
/**
* CSS misc classes
*
*/
.uppercase {
text-transform: uppercase
}
.justified {
text-align: justify
}
.centered {
text-align: center
}
.align-right {
text-align: right
}
.align-left {
text-align: left
}
.number {
text-align: right
}
.font.gray {
color: #555
}
.font.light-gray {
color: #888
}
.font.small {
font-size: 0.65em
}
.font.bold {
font-weight: bold
}
.non-page-break {
page-break-inside: avoid;
}

View File

@ -1,3 +1 @@
[{
"filename": "claim-pickup-order.pdf"
}]
[{"filename": "claim-pickup-order.pdf"}]

View File

@ -6,7 +6,7 @@
<body>
<section class="container">
<!-- Header component -->
<email-header :is-preview="isPreview"></email-header>
<email-header :is-preview="isPreview" :locale="locale"></email-header>
<!-- End header component -->
<section class="main">
<!-- Title block -->
@ -15,20 +15,9 @@
</div>
<!-- Title block end -->
{{$t('testing')}}
<p>{{$t('description.dear')}},</p>
<p>{{$t('description.instructions')}}</p>
<!-- <h1>{{$t('sections.howToBuy.title')}}</h1>
<p>{{$t('sections.howToBuy.description')}}</p>
<ol>
<li v-for="requeriment in $t('sections.howToBuy.requeriments')">
<span v-html="requeriment"></span>
</li>
</ol>
<p>{{$t('sections.howToBuy.stock')}}</p>
<p>{{$t('sections.howToBuy.delivery')}}</p> -->
<section>
<section v-for="attachment in attachments">
<a href="/api/report/claim-pickup-order?userId=106&claimId=5" target="_blank">Ver PDF</a>

View File

@ -1,8 +1,8 @@
const db = require(`${appPath}/core/database`);
const Component = require(`${appPath}/core/component`);
const emailHeader = new Component('email-header');
const emailFooter = new Component('email-footer');
const attachments = require('./attachments.json');
const db = require(`${appPath}/core/database`);
module.exports = {
name: 'claim-pickup-order',
@ -35,5 +35,5 @@ module.exports = {
'email-header': emailHeader.build(),
'email-footer': emailFooter.build()
},
props: ['claimId', 'isPreview']
props: ['clientId', 'claimId', 'isPreview']
};

View File

@ -1 +0,0 @@
../../../../../common/css/email.css

View File

@ -0,0 +1,7 @@
const Stylesheet = require(`${appPath}/core/stylesheet`);
module.exports = new Stylesheet([
`${appPath}/common/css/layout.css`,
`${appPath}/common/css/email.css`,
`${appPath}/common/css/misc.css`])
.mergeStyles();

View File

@ -1,233 +0,0 @@
/**
* CSS layout elements
*
*/
.container {
font-family: "Roboto", "Helvetica", "Arial", sans-serif;
font-size: 16px
}
.columns {
overflow: hidden
}
.columns .size100 {
width: 100%;
float: left
}
.columns .size75 {
width: 75%;
float: left
}
.columns .size50 {
width: 50%;
float: left
}
.columns .size33 {
width: 33.33%;
float: left
}
.columns .size25 {
width: 25%;
float: left
}
.clearfix {
overflow: hidden;
display: block;
clear: both
}
.panel {
position: relative;
margin-bottom: 15px;
padding-top: 10px;
break-inside: avoid;
break-before: always;
break-after: always;
}
.panel .header {
background-color: #FFF;
padding: 2.5px 10px;
position: absolute;
font-weight: bold;
top: 0px;
left: 17.5px;
}
.panel .body {
border: 1px solid #CCC;
overflow: hidden;
padding: 20px
}
.panel .body h3 {
margin-top: 0
}
.panel.dark .header {
border: 1px solid #808080;
background-color: #FFF;
}
.panel.dark .body {
border: 1px solid #808080;
background-color: #c0c0c0
}
.field {
border-bottom: 1px solid #CCC;
border-left: 1px solid #CCC;
border-top: 1px solid #CCC;
float: left
}
.field span {
border-right: 1px solid #CCC;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
display: table-cell;
vertical-align: middle;
text-align: center;
font-weight: bold
}
.field.square span {
height: 35.4px;
width: 35.4px
}
.emptyField {
border-bottom: 1px dotted grey;
min-height: 1em;
display: block
}
.field.rectangle span {
height: 2em;
width: 8em
}
.pull-left {
float: left !important
}
.pull-right {
float: right !important
}
.vertical-text {
-moz-transform: rotate(90deg);
-webkit-transform: rotate(90deg);
transform: rotate(90deg);
position: absolute;
text-align: center;
font-size: .65em;
right: -108px;
width: 200px;
top: 50%
}
table {
border-collapse: collapse;
border-spacing: 0;
}
.row-oriented, .column-oriented {
text-align: left;
width: 100%
}
.column-oriented {
margin-bottom: 15px
}
.column-oriented td,
.column-oriented th {
padding: 5px 10px
}
.column-oriented thead {
background-color: #e5e5e5
}
.column-oriented thead tr {
border-bottom: 1px solid #808080;
border-top: 1px solid #808080;
background-color: #e5e5e5
}
.column-oriented tfoot {
border-top: 2px solid #808080;
}
.column-oriented tfoot tr:first-child td {
padding-top: 20px !important;
}
.column-oriented .description {
border-bottom: 1px solid #DDD;
font-size: 0.8em
}
.panel .row-oriented td, .panel .row-oriented th {
padding: 10px 0
}
.row-oriented > tbody > tr > td {
width: 30%
}
.row-oriented > tbody > tr > th {
padding-left: 30px;
width: 70%
}
.row-oriented .description {
padding: 0 !important;
font-size: 0.6em;
color: #888
}
.line {
border-bottom: 1px solid #DDD;
border-right: 1px solid #DDD;
border-left: 1px solid #DDD;
position: relative;
margin-left: -1px;
margin-right: 1px;
margin-top: 10px;
color: #999;
padding: 5px 0
}
.line .vertical-aligned {
position: absolute;
text-align: center;
width: 100%;
}
.line span {
background-color: #FFF;
padding: 5px
}
.signature {
width: 100%
}
.signature section {
height: 150px
}
.signature p {
margin-right: 50%;
margin-top: 140px
}

View File

@ -1,47 +0,0 @@
/**
* CSS misc classes
*
*/
.uppercase {
text-transform: uppercase
}
.justified {
text-align: justify
}
.centered {
text-align: center
}
.align-right {
text-align: right
}
.align-left {
text-align: left
}
.number {
text-align: right
}
.font.gray {
color: #555
}
.font.light-gray {
color: #888
}
.font.small {
font-size: 0.65em
}
.font.bold {
font-weight: bold
}
.non-page-break {
page-break-inside: avoid;
}

View File

@ -6,7 +6,7 @@
<body>
<section class="container">
<!-- Header component -->
<email-header :is-preview="isPreview"></email-header>
<email-header :is-preview="isPreview" :locale="locale"></email-header>
<!-- End header component -->
<section class="main">
<!-- Title block -->
@ -47,7 +47,7 @@
<h1>{{$t('sections.toConsider.title')}}</h1>
<p>{{$t('sections.toConsider.description')}}</p>
<h3>{{$t('sections.claimsPolicy.title')}}</h3>
<h4>{{$t('sections.claimsPolicy.title')}}</h4>
<p>{{$t('sections.claimsPolicy.description')}}</p>
<p v-html="$t('help')"></p>
@ -64,9 +64,8 @@
</section>
</p>
</section>
{{isPreview}}
<!-- Footer component -->
<email-footer :is-preview="isPreview" :locale="client.locale"></email-footer>
<email-footer :is-preview="isPreview" :locale="locale"></email-footer>
<!-- End footer component -->
</section>
</body>

View File

@ -1,41 +1,19 @@
const db = require(`${appPath}/lib/database`);
const Component = require(`${appPath}/lib/component`);
const Component = require(`${appPath}/core/component`);
const emailHeader = new Component('email-header');
const emailFooter = new Component('email-footer');
const db = require(`${appPath}/core/database`);
module.exports = {
name: 'client-welcome',
async serverPrefetch() {
this.client = await this.fetchClient(this.clientId);
},
/* async asyncData(ctx, params) {
const data = {
isPreview: ctx.method === 'GET',
};
if (!params.clientFk)
throw new UserException('No client id specified');
return this.methods.fetchClient(params.clientFk)
.then(([result]) => {
if (!result)
throw new UserException('No client data found');
return Object.assign(data, result[0]);
});
}, */
created() {
if (this.locale)
this.$i18n.locale = this.locale;
},
methods: {
fetchClient(clientId) {
return db.findOne(`
SELECT
c.id,
u.lang locale,
u.name AS userName,
c.email recipient,
CONCAT(w.lastName, ' ', w.firstName) salesPersonName,
w.phone AS salesPersonPhone,
CONCAT(wu.name, '@verdnatura.es') AS salesPersonEmail
@ -50,5 +28,9 @@ module.exports = {
'email-header': emailHeader.build(),
'email-footer': emailFooter.build()
},
props: ['clientId', 'isPreview']
props: {
clientId: {
required: true
}
}
};

View File

@ -1,44 +0,0 @@
/**
* Email only stylesheet
*
*/
body {
background-color: #EEE
}
.container {
max-width: 600px;
min-width: 320px;
margin: 0 auto;
color: #555
}
.main {
background-color: #FFF;
padding: 20px
}
.main a {
color: #8dba25
}
.main h1 {
color: #999
}
.main h3 {
font-size: 16px
}
.title {
background-color: #95d831;
text-transform: uppercase;
text-align: center;
padding: 35px 0
}
.title h1 {
font-size: 32px;
color: #333;
margin: 0
}

View File

@ -0,0 +1,7 @@
const Stylesheet = require(`${appPath}/core/stylesheet`);
module.exports = new Stylesheet([
`${appPath}/common/css/layout.css`,
`${appPath}/common/css/email.css`,
`${appPath}/common/css/misc.css`])
.mergeStyles();

View File

@ -1,233 +0,0 @@
/**
* CSS layout elements
*
*/
.container {
font-family: "Roboto", "Helvetica", "Arial", sans-serif;
font-size: 16px
}
.columns {
overflow: hidden
}
.columns .size100 {
width: 100%;
float: left
}
.columns .size75 {
width: 75%;
float: left
}
.columns .size50 {
width: 50%;
float: left
}
.columns .size33 {
width: 33.33%;
float: left
}
.columns .size25 {
width: 25%;
float: left
}
.clearfix {
overflow: hidden;
display: block;
clear: both
}
.panel {
position: relative;
margin-bottom: 15px;
padding-top: 10px;
break-inside: avoid;
break-before: always;
break-after: always;
}
.panel .header {
background-color: #FFF;
padding: 2.5px 10px;
position: absolute;
font-weight: bold;
top: 0px;
left: 17.5px;
}
.panel .body {
border: 1px solid #CCC;
overflow: hidden;
padding: 20px
}
.panel .body h3 {
margin-top: 0
}
.panel.dark .header {
border: 1px solid #808080;
background-color: #FFF;
}
.panel.dark .body {
border: 1px solid #808080;
background-color: #c0c0c0
}
.field {
border-bottom: 1px solid #CCC;
border-left: 1px solid #CCC;
border-top: 1px solid #CCC;
float: left
}
.field span {
border-right: 1px solid #CCC;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
display: table-cell;
vertical-align: middle;
text-align: center;
font-weight: bold
}
.field.square span {
height: 35.4px;
width: 35.4px
}
.emptyField {
border-bottom: 1px dotted grey;
min-height: 1em;
display: block
}
.field.rectangle span {
height: 2em;
width: 8em
}
.pull-left {
float: left !important
}
.pull-right {
float: right !important
}
.vertical-text {
-moz-transform: rotate(90deg);
-webkit-transform: rotate(90deg);
transform: rotate(90deg);
position: absolute;
text-align: center;
font-size: .65em;
right: -108px;
width: 200px;
top: 50%
}
table {
border-collapse: collapse;
border-spacing: 0;
}
.row-oriented, .column-oriented {
text-align: left;
width: 100%
}
.column-oriented {
margin-bottom: 15px
}
.column-oriented td,
.column-oriented th {
padding: 5px 10px
}
.column-oriented thead {
background-color: #e5e5e5
}
.column-oriented thead tr {
border-bottom: 1px solid #808080;
border-top: 1px solid #808080;
background-color: #e5e5e5
}
.column-oriented tfoot {
border-top: 2px solid #808080;
}
.column-oriented tfoot tr:first-child td {
padding-top: 20px !important;
}
.column-oriented .description {
border-bottom: 1px solid #DDD;
font-size: 0.8em
}
.panel .row-oriented td, .panel .row-oriented th {
padding: 10px 0
}
.row-oriented > tbody > tr > td {
width: 30%
}
.row-oriented > tbody > tr > th {
padding-left: 30px;
width: 70%
}
.row-oriented .description {
padding: 0 !important;
font-size: 0.6em;
color: #888
}
.line {
border-bottom: 1px solid #DDD;
border-right: 1px solid #DDD;
border-left: 1px solid #DDD;
position: relative;
margin-left: -1px;
margin-right: 1px;
margin-top: 10px;
color: #999;
padding: 5px 0
}
.line .vertical-aligned {
position: absolute;
text-align: center;
width: 100%;
}
.line span {
background-color: #FFF;
padding: 5px
}
.signature {
width: 100%
}
.signature section {
height: 150px
}
.signature p {
margin-right: 50%;
margin-top: 140px
}

View File

@ -1,47 +0,0 @@
/**
* CSS misc classes
*
*/
.uppercase {
text-transform: uppercase
}
.justified {
text-align: justify
}
.centered {
text-align: center
}
.align-right {
text-align: right
}
.align-left {
text-align: left
}
.number {
text-align: right
}
.font.gray {
color: #555
}
.font.light-gray {
color: #888
}
.font.small {
font-size: 0.65em
}
.font.bold {
font-weight: bold
}
.non-page-break {
page-break-inside: avoid;
}

View File

@ -1,4 +1 @@
[{
"filename": "delivery-note.pdf",
"href": "http://localhost:5000/pi"
}]
[{"filename": "delivery-note.pdf"}]

View File

@ -18,6 +18,12 @@
<p>{{$t('dearClient')}},</p>
<p v-html="$t('clientData')"></p>
<p v-html="$t('help')"></p>
<section>
<a href="/api/report/delivery-note?userId=106&ticketId=11" target="_blank">Ver PDF</a>
</section>
</section>
<!-- Footer component -->
<email-footer :is-preview="isPreview" :locale="locale"></email-footer>

View File

@ -1,35 +1,10 @@
const db = require(`${appPath}/lib/database`);
const Component = require(`${appPath}/lib/component`);
const Component = require(`${appPath}/core/component`);
const emailHeader = new Component('email-header');
const emailFooter = new Component('email-footer');
const db = require(`${appPath}/core/database`);
module.exports = {
name: 'delivery-note',
async asyncData(ctx, params) {
const promises = [];
const data = {
isPreview: ctx.method === 'GET',
};
if (!params.ticketFk)
throw new UserException('No ticket id specified');
promises.push(reportEngine.toPdf('rpt-delivery-note', ctx));
promises.push(this.methods.fetchTicket(params.ticketFk));
return Promise.all(promises).then(result => {
const stream = result[0];
const [[ticket]] = result[1];
Object.assign(data, ticket);
Object.assign(data, {attachments: [{filename: 'rpt-delivery-note.pdf', content: stream}]});
return data;
});
},
created() {
this.locale = 'es';
},
methods: {
fetchTicket(ticketId) {
return db.findOne(`
@ -47,5 +22,9 @@ module.exports = {
'email-header': emailHeader.build(),
'email-footer': emailFooter.build()
},
props: ['ticketId', 'isPreview']
props: {
ticketId: {
required: true
}
}
};

View File

@ -1,6 +1,6 @@
const CssReader = require(`${appPath}/lib/cssReader`);
const Stylesheet = require(`${appPath}/core/stylesheet`);
module.exports = new CssReader([
module.exports = new Stylesheet([
`${appPath}/common/css/layout.css`,
`${appPath}/common/css/report.css`,
`${appPath}/common/css/misc.css`,

View File

@ -1,233 +0,0 @@
/**
* CSS layout elements
*
*/
.container {
font-family: "Roboto", "Helvetica", "Arial", sans-serif;
font-size: 16px
}
.columns {
overflow: hidden
}
.columns .size100 {
width: 100%;
float: left
}
.columns .size75 {
width: 75%;
float: left
}
.columns .size50 {
width: 50%;
float: left
}
.columns .size33 {
width: 33.33%;
float: left
}
.columns .size25 {
width: 25%;
float: left
}
.clearfix {
overflow: hidden;
display: block;
clear: both
}
.panel {
position: relative;
margin-bottom: 15px;
padding-top: 10px;
break-inside: avoid;
break-before: always;
break-after: always;
}
.panel .header {
background-color: #FFF;
padding: 2.5px 10px;
position: absolute;
font-weight: bold;
top: 0px;
left: 17.5px;
}
.panel .body {
border: 1px solid #CCC;
overflow: hidden;
padding: 20px
}
.panel .body h3 {
margin-top: 0
}
.panel.dark .header {
border: 1px solid #808080;
background-color: #FFF;
}
.panel.dark .body {
border: 1px solid #808080;
background-color: #c0c0c0
}
.field {
border-bottom: 1px solid #CCC;
border-left: 1px solid #CCC;
border-top: 1px solid #CCC;
float: left
}
.field span {
border-right: 1px solid #CCC;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
display: table-cell;
vertical-align: middle;
text-align: center;
font-weight: bold
}
.field.square span {
height: 35.4px;
width: 35.4px
}
.emptyField {
border-bottom: 1px dotted grey;
min-height: 1em;
display: block
}
.field.rectangle span {
height: 2em;
width: 8em
}
.pull-left {
float: left !important
}
.pull-right {
float: right !important
}
.vertical-text {
-moz-transform: rotate(90deg);
-webkit-transform: rotate(90deg);
transform: rotate(90deg);
position: absolute;
text-align: center;
font-size: .65em;
right: -108px;
width: 200px;
top: 50%
}
table {
border-collapse: collapse;
border-spacing: 0;
}
.row-oriented, .column-oriented {
text-align: left;
width: 100%
}
.column-oriented {
margin-bottom: 15px
}
.column-oriented td,
.column-oriented th {
padding: 5px 10px
}
.column-oriented thead {
background-color: #e5e5e5
}
.column-oriented thead tr {
border-bottom: 1px solid #808080;
border-top: 1px solid #808080;
background-color: #e5e5e5
}
.column-oriented tfoot {
border-top: 2px solid #808080;
}
.column-oriented tfoot tr:first-child td {
padding-top: 20px !important;
}
.column-oriented .description {
border-bottom: 1px solid #DDD;
font-size: 0.8em
}
.panel .row-oriented td, .panel .row-oriented th {
padding: 10px 0
}
.row-oriented > tbody > tr > td {
width: 30%
}
.row-oriented > tbody > tr > th {
padding-left: 30px;
width: 70%
}
.row-oriented .description {
padding: 0 !important;
font-size: 0.6em;
color: #888
}
.line {
border-bottom: 1px solid #DDD;
border-right: 1px solid #DDD;
border-left: 1px solid #DDD;
position: relative;
margin-left: -1px;
margin-right: 1px;
margin-top: 10px;
color: #999;
padding: 5px 0
}
.line .vertical-aligned {
position: absolute;
text-align: center;
width: 100%;
}
.line span {
background-color: #FFF;
padding: 5px
}
.signature {
width: 100%
}
.signature section {
height: 150px
}
.signature p {
margin-right: 50%;
margin-top: 140px
}

View File

@ -1,47 +0,0 @@
/**
* CSS misc classes
*
*/
.uppercase {
text-transform: uppercase
}
.justified {
text-align: justify
}
.centered {
text-align: center
}
.align-right {
text-align: right
}
.align-left {
text-align: left
}
.number {
text-align: right
}
.font.gray {
color: #555
}
.font.light-gray {
color: #888
}
.font.small {
font-size: 0.65em
}
.font.bold {
font-weight: bold
}
.non-page-break {
page-break-inside: avoid;
}

View File

@ -1,14 +0,0 @@
/**
* Report only stylesheet
*
*/
body {
zoom: 0.55
}
.title {
margin-bottom: 20px;
font-weight: 100;
margin-top: 0;
font-size: 2em
}

View File

@ -1,9 +1,12 @@
<!DOCTYPE html>
<html lang="es">
<html v-bind:lang="locale">
<body>
<section class="container">
<!-- Header component -->
<report-header :is-preview="isPreview" :locale="locale"></report-header>
<report-header
v-bind:is-preview="isPreview"
v-bind:locale="locale">
</report-header>
<!-- End header component -->
<section class="main">
<section class="columns">
@ -18,11 +21,11 @@
</tr>
<tr>
<td class="font gray uppercase">{{$t('clientId')}}</td>
<th>{{clientId}}</th>
<th>{{client.id}}</th>
</tr>
<tr>
<td class="font gray uppercase">{{$t('date')}}</td>
<th>{{dated()}}</th>
<th>{{currentDate}}</th>
</tr>
</tbody>
</table>
@ -32,15 +35,15 @@
<section class="panel">
<section class="header">{{$t('clientData')}}</section>
<section class="body">
<h3 class="uppercase">{{nickname}}</h3>
<h3 class="uppercase">{{client.nickname}}</h3>
<section>
{{street}}
{{client.street}}
</section>
<section>
{{postalCode}}, {{city}} ({{province}})
{{client.postalCode}}, {{client.city}} ({{client.province}})
</section>
<section>
{{country}}
{{client.country}}
</section>
</section>
</section>
@ -57,7 +60,7 @@
</tr>
</thead>
<tbody>
<tr v-for="sale in sales" :key="sale.id">
<tr v-for="sale in sales" v-bind:key="sale.id">
<td class="font gray">{{sale.id}}</td>
<td class="number">{{sale.quantity}}</td>
<td class="number">{{sale.claimQuantity}}</td>
@ -69,7 +72,7 @@
<section class="panel sign">
<section class="header">{{$t('clientSignature')}}</section>
<section class="body centered">
<h3>{{clientName}}</h3>
<h3>{{client.name}}</h3>
</section>
</section>
@ -77,10 +80,10 @@
</section>
<!-- Footer component -->
<report-footer id="pageFooter"
:is-preview="isPreview"
:left-text="$t('claim', [claimId])"
:center-text="clientName"
:locale="locale">
v-bind:left-text="$t('claim', [claimId])"
v-bind:center-text="client.name"
v-bind:is-preview="isPreview"
v-bind:locale="locale">
</report-footer>
<!-- End footer component -->
</section>

View File

@ -1,32 +1,31 @@
const strftime = require('strftime');
const db = require(`${appPath}/core/database`);
const Component = require(`${appPath}/core/component`);
const reportHeader = new Component('report-header');
const reportFooter = new Component('report-footer');
const db = require(`${appPath}/core/database`);
module.exports = {
name: 'rpt-claim-pickup-order',
name: 'claim-pickup-order',
async serverPrefetch() {
this.claim = await this.fetchClaim(this.claimId);
this.client = await this.fetchClient(this.claimId);
this.sales = await this.fetchSales(this.claimId);
if (!this.client)
throw new Error('Something went wrong');
},
created() {
if (this.locale)
this.$i18n.locale = this.locale;
computed: {
currentDate: function() {
const filters = this.$options.filters;
return filters.date(new Date(), '%d-%m-%Y');
}
},
methods: {
dated: () => {
return strftime('%d-%m-%Y', new Date());
},
fetchClaim(claimId) {
fetchClient(claimId) {
return db.findOne(
`SELECT
u.lang locale,
c.id clientId,
cl.id claimId,
c.email AS recipient,
c.id,
c.socialName,
c.name AS clientName,
c.name,
c.fi,
a.city,
a.postalCode,
@ -44,7 +43,7 @@ module.exports = {
WHERE cl.id = ?`, [claimId]);
},
fetchSales(claimId) {
return db.pool.query(
return db.find(
`SELECT
s.id,
s.quantity,
@ -59,5 +58,10 @@ module.exports = {
'report-header': reportHeader.build(),
'report-footer': reportFooter.build()
},
props: ['claimId', 'isPreview']
props: {
claimId: {
type: String,
required: true
}
}
};

View File

@ -0,0 +1,8 @@
const Stylesheet = require(`${appPath}/core/stylesheet`);
module.exports = new Stylesheet([
`${appPath}/common/css/layout.css`,
`${appPath}/common/css/report.css`,
`${appPath}/common/css/misc.css`,
`${__dirname}/style.css`])
.mergeStyles();

View File

@ -1,9 +1,12 @@
<!DOCTYPE html>
<html lang="es">
<html v-bind:lang="locale">
<body>
<section class="container">
<!-- Header component -->
<report-header :locale="ticket.locale"></report-header>
<report-header
v-bind:is-preview="isPreview"
v-bind:locale="locale">
</report-header>
<!-- End header component -->
<section class="main">
<section class="columns">
@ -22,7 +25,7 @@
</tr>
<tr>
<td class="font gray uppercase">{{$t('date')}}</td>
<th>{{shipped}}</th>
<th>{{ticket.shipped | date('%d-%m-%Y')}}</th>
</tr>
</tbody>
</table>
@ -75,14 +78,14 @@
</thead>
<tbody>
<template v-for="sale in sales">
<tr class="font bold" :key="sale.id">
<tr class="font bold">
<td>{{sale.itemFk}}</td>
<td class="number">{{sale.quantity}}</td>
<td>{{sale.concept}}</td>
<td class="number">{{sale.price | currency('EUR')}}</td>
<td class="centered">{{sale.discount | percent}}</td>
<td class="number">{{sale.price | currency('EUR', locale)}}</td>
<td class="centered">{{sale.discount | percentage}}</td>
<td class="centered">{{sale.vatType}}</td>
<td class="number">{{sale.price * sale.quantity * (1 - sale.discount / 100) | currency('EUR')}}</td>
<td class="number">{{sale.price * sale.quantity * (1 - sale.discount / 100) | currency('EUR', locale)}}</td>
</tr>
<tr class="description">
<td colspan="2" class="centered">
@ -114,7 +117,7 @@
<td colspan="6">
<span class="pull-right">{{$t('subtotal')}}</span>
</td>
<td class="number">{{getSubTotal() | currency('EUR')}}</td>
<td class="number">{{getSubTotal() | currency('EUR', locale)}}</td>
</tr>
</tfoot>
</table>
@ -138,13 +141,13 @@
<td>{{service.description}}</td>
<td class="number">{{service.quantity}}</td>
<td>{{service.taxDescription}}</td>
<td class="number">{{service.price | currency('EUR')}}</td>
<td class="number">{{service.price | currency('EUR', locale)}}</td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="3"></td>
<td class="number">{{$t('total')}} {{serviceTotal | currency('EUR')}}</td>
<td class="number">{{$t('total')}} {{serviceTotal | currency('EUR', locale)}}</td>
</tr>
</tfoot>
</table>
@ -166,21 +169,21 @@
<tbody>
<tr v-for="tax in taxes">
<td>{{tax.name}}</td>
<td class="number">{{tax.Base | currency('EUR')}}</td>
<td>{{tax.vatPercent | percent}}</td>
<td class="number">{{tax.tax | currency('EUR')}}</td>
<td class="number">{{tax.Base | currency('EUR', locale)}}</td>
<td>{{tax.vatPercent | percentage}}</td>
<td class="number">{{tax.tax | currency('EUR', locale)}}</td>
</tr>
</tbody>
<tfoot>
<tr class="font bold">
<td>{{$t('subtotal')}}</td>
<td class="number">{{getTotalBase() | currency('EUR')}}</td>
<td class="number">{{getTotalBase() | currency('EUR', locale)}}</td>
<td></td>
<td class="number">{{getTotalTax()| currency('EUR')}}</td>
<td class="number">{{getTotalTax()| currency('EUR', locale)}}</td>
</tr>
<tr class="font bold">
<td colspan="2">{{$t('total')}}</td>
<td colspan="2" class="number">{{getTotal() | currency('EUR')}}</td>
<td colspan="2" class="number">{{getTotal() | currency('EUR', locale)}}</td>
</tr>
</tfoot>
</table>
@ -224,9 +227,10 @@
</section>
<!-- Footer component -->
<report-footer id="pageFooter"
:left-text="$t('ticket', [ticket.id])"
:center-text="client.socialName"
:locale="client.locale">
v-bind:left-text="$t('ticket', [ticket.id])"
v-bind:center-text="client.socialName"
v-bind:is-preview="isPreview"
v-bind:locale="locale">
</report-footer>
<!-- End footer component -->
</section>

View File

@ -1,31 +1,24 @@
const strftime = require('strftime');
const database = require(`${appPath}/lib/database`);
const config = require(`${appPath}/lib/config.js`);
const UserException = require(`${appPath}/lib/exceptions/userException`);
const config = require(`${appPath}/core/config`);
const Component = require(`${appPath}/core/component`);
const reportHeader = new Component('report-header');
const reportFooter = new Component('report-footer');
const db = require(`${appPath}/core/database`);
const md5 = require('md5');
module.exports = {
name: 'rpt-delivery-note',
async asyncData(ctx, params) {
Object.assign(this, this.methods);
name: 'delivery-note',
async serverPrefetch() {
this.client = await this.fetchClient(this.ticketId);
this.ticket = await this.fetchTicket(this.ticketId);
this.sales = await this.fetchSales(this.ticketId);
this.address = await this.fetchAddress(this.ticketId);
this.services = await this.fetchServices(this.ticketId);
this.taxes = await this.fetchTaxes(this.ticketId);
this.packagings = await this.fetchPackagings(this.ticketId);
this.signature = await this.fetchSignature(this.ticketId);
const [[client]] = await this.fetchClient(params.ticketFk);
const [[ticket]] = await this.fetchTicket(params.ticketFk);
const [[address]] = await this.fetchAddress(params.ticketFk);
const [[signature]] = await this.fetchSignature(params.ticketFk);
const [[taxes]] = await this.fetchTaxes(params.ticketFk);
const [sales] = await this.fetchSales(params.ticketFk);
const [packagings] = await this.fetchPackagings(params.ticketFk);
const [services] = await this.fetchServices(params.ticketFk);
if (!ticket)
throw new UserException('No ticket data found');
return {client, ticket, address, sales, taxes, packagings, services, signature};
},
created() {
if (this.client.locale)
this.$i18n.locale = this.client.locale;
if (!this.ticket)
throw new Error('Something went wrong');
},
data() {
return {totalBalance: 0.00};
@ -38,9 +31,6 @@ module.exports = {
if (this.signature && this.signature.id)
return `${hostPath}/${this.signature.id}.png`;
},
shipped() {
return strftime('%d-%m-%Y', this.ticket.shipped);
},
serviceTotal() {
let total = 0.00;
this.services.forEach(service => {
@ -50,51 +40,29 @@ module.exports = {
return total;
}
},
filters: {
currency(input, currency = 'EUR') {
return new Intl.NumberFormat('es', {
style: 'currency', currency
}).format(parseFloat(input));
},
percent(input) {
return new Intl.NumberFormat('es', {
style: 'percent',
minimumFractionDigits: 2,
maximumFractionDigits: 2
}).format(parseFloat(input));
},
date(input) {
return strftime('%d-%m-%Y %H:%I:%S', input);
}
},
methods: {
fetchClient(ticketFk) {
return database.pool.query(
fetchClient(ticketId) {
return db.findOne(
`SELECT
c.id,
c.email AS recipient,
c.socialName,
c.street,
c.fi,
u.lang locale
c.fi
FROM ticket t
JOIN client c ON c.id = t.clientFk
JOIN account.user u ON u.id = c.id
WHERE t.id = ?`, [ticketFk]);
WHERE t.id = ?`, [ticketId]);
},
fetchTicket(ticketFk) {
return database.pool.query(
fetchTicket(ticketId) {
return db.findOne(
`SELECT
t.id,
t.shipped,
t.companyFk
FROM ticket t
JOIN client c ON c.id = t.clientFk
JOIN account.user u ON u.id = c.id
WHERE t.id = ?`, [ticketFk]);
WHERE t.id = ?`, [ticketId]);
},
fetchAddress(ticketFk) {
return database.pool.query(
fetchAddress(ticketId) {
return db.findOne(
`SELECT
a.nickname,
a.street,
@ -104,11 +72,11 @@ module.exports = {
FROM ticket t
JOIN address a ON a.clientFk = t.clientFk
LEFT JOIN province p ON p.id = a.provinceFk
WHERE t.id = ?`, [ticketFk]);
WHERE t.id = ?`, [ticketId]);
},
fetchSales(ticketFk) {
return database.pool.query(
fetchSales(ticketId) {
return db.find(
`SELECT
s.id,
s.itemFk,
@ -157,14 +125,15 @@ module.exports = {
'%')
WHERE s.ticketFk = ?
GROUP BY s.id
ORDER BY (it.isPackaging), s.concept, s.itemFk`, [ticketFk]);
ORDER BY (it.isPackaging), s.concept, s.itemFk`, [ticketId]);
},
fetchTaxes(ticketFk) {
return database.pool.query(
`CALL vn.ticketGetTaxAdd(?)`, [ticketFk]);
fetchTaxes(ticketId) {
return db.find(`CALL vn.ticketGetTaxAdd(?)`, [ticketId]).then(rows => {
return rows[0];
});
},
fetchPackagings(ticketFk) {
return database.pool.query(
fetchPackagings(ticketId) {
return db.find(
`SELECT
tp.quantity,
i.name,
@ -173,10 +142,10 @@ module.exports = {
JOIN packaging p ON p.id = tp.packagingFk
JOIN item i ON i.id = p.itemFk
WHERE tp.ticketFk = ?
ORDER BY itemFk`, [ticketFk]);
ORDER BY itemFk`, [ticketId]);
},
fetchServices(ticketFk) {
return database.pool.query(
fetchServices(ticketId) {
return db.find(
`SELECT
tc.description taxDescription,
ts.description,
@ -184,10 +153,10 @@ module.exports = {
ts.price
FROM ticketService ts
JOIN taxClass tc ON tc.id = ts.taxClassFk
WHERE ts.ticketFk = ?`, [ticketFk]);
WHERE ts.ticketFk = ?`, [ticketId]);
},
fetchSignature(ticketFk) {
return database.pool.query(
fetchSignature(ticketId) {
return db.findOne(
`SELECT
d.id,
d.created
@ -195,7 +164,7 @@ module.exports = {
JOIN ticketDms dt ON dt.ticketFk = t.id
JOIN dms d ON d.id = dt.dmsFk
AND d.file LIKE '%.png'
WHERE t.id = ?`, [ticketFk]);
WHERE t.id = ?`, [ticketId]);
},
getSubTotal() {
let subTotal = 0.00;
@ -226,8 +195,13 @@ module.exports = {
},
},
components: {
'email-header': emailHeader.build(),
'email-footer': emailFooter.build()
'report-header': reportHeader.build(),
'report-footer': reportFooter.build()
},
props: ['clientId', 'isPreview']
props: {
ticketId: {
type: String,
required: true
}
}
};

View File

@ -0,0 +1,8 @@
const Stylesheet = require(`${appPath}/core/stylesheet`);
module.exports = new Stylesheet([
`${appPath}/common/css/layout.css`,
`${appPath}/common/css/report.css`,
`${appPath}/common/css/misc.css`,
`${__dirname}/style.css`])
.mergeStyles();

View File

@ -1,5 +1,5 @@
<!DOCTYPE html>
<html lang="es">
<html v-bind:lang="locale">
<body>
<section class="container" id="report">
<section class="label">
@ -17,7 +17,7 @@
<section class="package">
<section class="packing">{{packing()}}</section>
<section class="dated">{{dated}}</section>
<section class="labelNumber">{{labelPage()}}</section>
<section class="labelNumber">{{labelPage}}</section>
</section>
<section class="size">{{item.size}}</section>
</section>

View File

@ -0,0 +1,87 @@
const Component = require(`${appPath}/core/component`);
const reportHeader = new Component('report-header');
const reportFooter = new Component('report-footer');
const db = require(`${appPath}/core/database`);
const qrcode = require('qrcode');
module.exports = {
name: 'item-label',
async serverPrefetch() {
this.item = await this.fetchItem(this.itemId, this.warehouseId);
this.tags = await this.fetchItemTags(this.itemId);
this.barcode = await this.getBarcodeBase64(this.itemId);
if (!this.item)
throw new Error('Something went wrong');
},
computed: {
dated() {
const filters = this.$options.filters;
return filters.date(new Date(), '%W/%d');
},
labelPage() {
const labelNumber = this.labelNumber ? this.labelNumber : 1;
const totalLabels = this.totalLabels ? this.totalLabels : 1;
return `${labelNumber}/${totalLabels}`;
}
},
methods: {
fetchItem(id, warehouseId) {
return db.findOne(
`SELECT
i.id,
i.name,
i.stems,
i.size,
b.packing
FROM vn.item i
JOIN cache.last_buy clb ON clb.item_id = i.id
JOIN vn.buy b ON b.id = clb.buy_id
JOIN vn.entry e ON e.id = b.entryFk
WHERE i.id = ? AND clb.warehouse_id = ?`, [id, warehouseId]);
},
fetchItemTags(itemId) {
return db.find(
`SELECT t.code, t.name, it.value
FROM vn.itemTag it
JOIN vn.tag t ON t.id = it.tagFk
WHERE it.itemFk = ?
`, [itemId]).then(rows => {
const tags = {};
rows.forEach(row => tags[row.code] = row.value);
return tags;
});
},
getBarcodeBase64(itemId) {
return qrcode.toDataURL(itemId, {margin: 0});
},
packing() {
const stems = this.item.stems ? this.item.stems : 1;
return `${this.item.packing}x${stems}`;
}
},
components: {
'report-header': reportHeader.build(),
'report-footer': reportFooter.build()
},
props: {
itemId: {
type: String,
required: true
},
warehouseId: {
type: String,
required: true
},
labelNumber: {
type: String
},
totalLabels: {
type: String
}
}
};

View File

@ -0,0 +1,8 @@
const Stylesheet = require(`${appPath}/core/stylesheet`);
module.exports = new Stylesheet([
`${appPath}/common/css/layout.css`,
`${appPath}/common/css/report.css`,
`${appPath}/common/css/misc.css`,
`${__dirname}/style.css`])
.mergeStyles();

View File

@ -1 +0,0 @@
../../../../../common/css/layout.css

View File

@ -1 +0,0 @@
../../../../../common/css/misc.css

View File

@ -1 +0,0 @@
../../../../../common/css/report.css

View File

@ -1,9 +1,12 @@
<!DOCTYPE html>
<html lang="es">
<html v-bind:lang="locale">
<body>
<section class="container" id="report">
<!-- Header component -->
<report-header :locale="client.locale"></report-header>
<report-header
v-bind:is-preview="isPreview"
v-bind:locale="locale">
</report-header>
<!-- End header component -->
<section class="main">
<!-- Report start -->
@ -16,7 +19,7 @@
un saldo de <strong>{{receipt.amountUnpaid}} €</strong>.
</p>
<section class="signature">
<img :src="embeded['/assets/images/signature.png']">
<img v-bind:src="getReportSrc('signature.png')">
<p class="centered">{{$t('payed', [
'Silla',
receipt.payed.getDate(),
@ -30,9 +33,10 @@
</section>
<!-- Footer component -->
<report-footer id="pageFooter"
:left-text="$t('client', [client.id])"
:center-text="client.socialName"
:locale="client.locale">
v-bind:left-text="$t('client', [client.id])"
v-bind:center-text="client.socialName"
v-bind:is-preview="isPreview"
v-bind:locale="locale">
</report-footer>
<!-- End footer component -->
</section>

View File

@ -1,29 +1,16 @@
const strftime = require('strftime');
const db = require(`${appPath}/lib/database`);
const Component = require(`${appPath}/lib/component`);
const Component = require(`${appPath}/core/component`);
const reportHeader = new Component('report-header');
const reportFooter = new Component('report-footer');
const db = require(`${appPath}/core/database`);
module.exports = {
name: 'receipt',
async serverPrefetch() {
this.client = await this.fetchClient(this.receiptId);
this.receipt = await this.fetchReceipt(this.receiptId);
},
created() {
/* if (this.client.locale)
this.$i18n.locale = this.client.locale; */
const embeded = [];
this.files.map(file => {
embeded[file] = `file://${__dirname + file}`;
});
this.embeded = embeded;
},
data() {
return {
files: ['/assets/images/signature.png']
};
if (!this.receipt)
throw new Error('Something went wrong');
},
methods: {
fetchClient(receiptId) {
@ -48,14 +35,16 @@ module.exports = {
FROM receipt r
JOIN client c ON c.id = r.clientFk
WHERE r.id = ?`, [receiptId]);
},
dated: () => {
return strftime('%d-%m-%Y', new Date());
},
}
},
components: {
'report-header': reportHeader.build(),
'report-footer': reportFooter.build()
},
props: ['userId', 'receiptId']
props: {
receiptId: {
type: String,
required: true
}
}
};

View File

@ -1,83 +0,0 @@
const database = require(`${appPath}/lib/database`);
const UserException = require(`${appPath}/lib/exceptions/userException`);
const strftime = require('strftime');
const qrcode = require('qrcode');
module.exports = {
name: 'rpt-item-label',
async asyncData(ctx, params) {
Object.assign(this, this.methods);
if (!params.itemId)
throw new UserException('No item id specified');
if (!params.warehouseId)
throw new UserException('No warehouse id specified');
const data = {
item: await this.fetchItem(params.itemId, params.warehouseId),
tags: await this.fetchItemTags(params.itemId),
barcode: await this.getBarcodeBase64(params.itemId),
labelNumber: params.labelNumber,
totalLabels: params.totalLabels
};
return data;
},
computed: {
dated() {
return strftime('%W/%d', new Date());
}
},
methods: {
fetchItem(id, warehouseId) {
return database.pool.query(
`SELECT
i.id,
i.name,
i.stems,
i.size,
b.packing
FROM vn.item i
JOIN cache.last_buy clb ON clb.item_id = i.id
JOIN vn.buy b ON b.id = clb.buy_id
JOIN vn.entry e ON e.id = b.entryFk
WHERE i.id = ? AND clb.warehouse_id = ?`, [id, warehouseId])
.then(([rows]) => {
if (rows.length == 0)
throw new UserException(`Item #${id} not found on warehouse #${warehouseId}`);
return rows[0];
});
},
fetchItemTags(itemId) {
return database.pool.query(
`SELECT t.code, t.name, it.value
FROM vn.itemTag it
JOIN vn.tag t ON t.id = it.tagFk
WHERE it.itemFk = ?`, [itemId])
.then(([rows]) => {
const tags = {};
rows.forEach(row => tags[row.code] = row.value);
return tags;
});
},
getBarcodeBase64(itemId) {
return qrcode.toDataURL(itemId, {margin: 0});
},
packing() {
const stems = this.item.stems ? this.item.stems : 1;
return `${this.item.packing}x${stems}`;
},
labelPage() {
const labelNumber = this.labelNumber ? this.labelNumber : 1;
const totalLabels = this.totalLabels ? this.totalLabels : 1;
return `${labelNumber}/${totalLabels}`;
}
},
components: {
'report-header': require('../report-header'),
'report-footer': require('../report-footer'),
},
};

View File

@ -1,24 +0,0 @@
module.exports = {
messages: {
es: {
title: 'Recibo',
date: 'Fecha',
payed: 'En {0}, a {1} de {2} de {3}',
client: 'Cliente {0}',
months: [
'Enero',
'Febrero',
'Marzo',
'Abril',
'Mayo',
'Junio',
'Julio',
'Agosto',
'Septiembre',
'Octubre',
'Noviembre',
'Diciembre'
]
},
},
};

View File

@ -1,81 +0,0 @@
module.exports = {
messages: {
es: {
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 y (B) a la entidad para efectuar los adeudos en su cuenta siguiendo las
instrucciones del acreedor.Como parte de sus derechos, el deudor está legitimado al reembolso por su entidad en los
términos y condiciones del contrato suscrito con la misma. La solicitud de reembolso deberá efectuarse dentro de las
ocho semanas que adeudo en cuenta. Puede obtener información adicional sobre sus derechos en su entidad financiera.`,
documentCopy: `Debe llevar a su Entidad Bancaria una copia
del documento firmado para que lo registre y evitar la devolución.`,
mandatoryFields: `TODOS LOS CAMPOS HAN DE SER CUMPLIMENTADOS OBLIGATORIAMENTE.`,
sendOrder: `UNA VEZ FIRMADA ESTA ORDEN DE DOMICILIACIÓN DEBE SER ENVIADA AL ACREEDOR PARA SU CUSTODIA Y ES RECOMENDABLE FACILITAR UNA COPIA A SU ENTIDAD BANCARIA.`,
supplier: {
toCompleteBySupplier: 'A cumplimentar por el acreedor',
orderReference: 'Referencia de la orden de domiciliación',
identifier: 'Identificador del acreedor',
name: 'Nombre del acreedor',
street: 'Dirección',
location: 'CP - Población - Provincia',
country: 'País'
},
client: {
toCompleteByClient: 'A cumplimentar por el deudor',
name: 'Nombre del deudor/es',
street: 'Dirección del deudor',
location: 'CP - Población - Provincia',
country: 'País del deudor',
swift: 'Swift BIC',
accountNumber: 'Número de cuenta - IBAN',
accountHolder: '(Titular/es de la cuenta de cargo)',
accountNumberFormat: 'En España el IBAN consta de 24 posiciones comenzando siempre por ES',
paymentType: 'Tipo de pago',
recurrent: 'Recurrente',
unique: 'Único',
signLocation: 'Fecha - Localidad',
sign: 'Firma del deudor y sello',
},
order: 'Ord. domiciliación {0}',
},
pt: {
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 debitar a sua conta, de acordo com as instruções da
Verdnatura Levante S.L. Os seus direitos incluem a possibilidade de exigir do seu banco o reembolso do
montante debitado, nos termos e condições acordados com o seu banco. O reembolso deve ser solicitado até um
prazo de oito semanas, a contar da data do débito na sua conta. Os seus direitos, referentes à autorização
acima referida, são explicados em declaração que pode obter no seu banco.`,
documentCopy: `Deve levar à sua Entidade Bancária uma cópia do documento assinado para que o registre e evitar a devolução`,
mandatoryFields: `TODOS OS CAMPOS DEVEM SER PREENCHIDOS OBRIGATORIAMENTE.`,
sendOrder: `UMA VEZ ASSINADA, ESTA AUTORIZAÇÃO DE DÉBITO DEVE SER ENVIADA AO CREDOR PARA SUA CUSTÓDIA E É RECOMENDÁVEL
FACILITAR UMA CÓPIA À SUA ENTIDADE BANCÁRIA.`,
supplier: {
toCompleteBySupplier: 'A preencher pelo credor',
orderReference: 'Referência da ordem',
identifier: 'Identificador do Credor',
name: 'Nome do Credor',
street: 'Morada',
location: 'CP - Município - Distrito',
country: 'País'
},
client: {
toCompleteByClient: 'A preencher pelo devedor',
name: 'Nome do devedor (Titular da conta)',
street: 'Dirección del deudor',
location: 'Cod. Postal - Município - Distrito',
country: 'País do devedor',
swift: 'Swift BIC',
accountNumber: 'Número de Conta IBAN',
accountHolder: '(Titular/es de la cuenta de cargo)',
accountNumberFormat: 'Em Portugal o IBAN é composto por 25 dígitos e começa sempre por PT',
paymentType: 'Tipos de pagamento Pagamento',
recurrent: 'Recorrente',
unique: 'Pagamento pontual',
signLocation: 'Data - Localidade',
sign: 'Assinatura e carimbo do devedor',
},
order: 'Referência da ordem {0}',
},
},
};

View File

@ -0,0 +1,8 @@
const Stylesheet = require(`${appPath}/core/stylesheet`);
module.exports = new Stylesheet([
`${appPath}/common/css/layout.css`,
`${appPath}/common/css/report.css`,
`${appPath}/common/css/misc.css`,
`${__dirname}/style.css`])
.mergeStyles();

View File

@ -0,0 +1,38 @@
{
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 y (B) a la entidad para efectuar los adeudos en su cuenta siguiendo las
instrucciones del acreedor.Como parte de sus derechos, el deudor está legitimado al reembolso por su entidad en los
términos y condiciones del contrato suscrito con la misma. La solicitud de reembolso deberá efectuarse dentro de las
ocho semanas que adeudo en cuenta. Puede obtener información adicional sobre sus derechos en su entidad financiera.`,
documentCopy: `Debe llevar a su Entidad Bancaria una copia
del documento firmado para que lo registre y evitar la devolución.`,
mandatoryFields: `TODOS LOS CAMPOS HAN DE SER CUMPLIMENTADOS OBLIGATORIAMENTE.`,
sendOrder: `UNA VEZ FIRMADA ESTA ORDEN DE DOMICILIACIÓN DEBE SER ENVIADA AL ACREEDOR PARA SU CUSTODIA Y ES RECOMENDABLE FACILITAR UNA COPIA A SU ENTIDAD BANCARIA.`,
supplier: {
toCompleteBySupplier: 'A cumplimentar por el acreedor',
orderReference: 'Referencia de la orden de domiciliación',
identifier: 'Identificador del acreedor',
name: 'Nombre del acreedor',
street: 'Dirección',
location: 'CP - Población - Provincia',
country: 'País'
},
client: {
toCompleteByClient: 'A cumplimentar por el deudor',
name: 'Nombre del deudor/es',
street: 'Dirección del deudor',
location: 'CP - Población - Provincia',
country: 'País del deudor',
swift: 'Swift BIC',
accountNumber: 'Número de cuenta - IBAN',
accountHolder: '(Titular/es de la cuenta de cargo)',
accountNumberFormat: 'En España el IBAN consta de 24 posiciones comenzando siempre por ES',
paymentType: 'Tipo de pago',
recurrent: 'Recurrente',
unique: 'Único',
signLocation: 'Fecha - Localidad',
sign: 'Firma del deudor y sello',
},
order: 'Ord. domiciliación {0}',
}

View File

@ -0,0 +1,39 @@
{
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 debitar a sua conta, de acordo com as instruções da
Verdnatura Levante S.L. Os seus direitos incluem a possibilidade de exigir do seu banco o reembolso do
montante debitado, nos termos e condições acordados com o seu banco. O reembolso deve ser solicitado até um
prazo de oito semanas, a contar da data do débito na sua conta. Os seus direitos, referentes à autorização
acima referida, são explicados em declaração que pode obter no seu banco.`,
documentCopy: `Deve levar à sua Entidade Bancária uma cópia do documento assinado para que o registre e evitar a devolução`,
mandatoryFields: `TODOS OS CAMPOS DEVEM SER PREENCHIDOS OBRIGATORIAMENTE.`,
sendOrder: `UMA VEZ ASSINADA, ESTA AUTORIZAÇÃO DE DÉBITO DEVE SER ENVIADA AO CREDOR PARA SUA CUSTÓDIA E É RECOMENDÁVEL
FACILITAR UMA CÓPIA À SUA ENTIDADE BANCÁRIA.`,
supplier: {
toCompleteBySupplier: 'A preencher pelo credor',
orderReference: 'Referência da ordem',
identifier: 'Identificador do Credor',
name: 'Nome do Credor',
street: 'Morada',
location: 'CP - Município - Distrito',
country: 'País'
},
client: {
toCompleteByClient: 'A preencher pelo devedor',
name: 'Nome do devedor (Titular da conta)',
street: 'Dirección del deudor',
location: 'Cod. Postal - Município - Distrito',
country: 'País do devedor',
swift: 'Swift BIC',
accountNumber: 'Número de Conta IBAN',
accountHolder: '(Titular/es de la cuenta de cargo)',
accountNumberFormat: 'Em Portugal o IBAN é composto por 25 dígitos e começa sempre por PT',
paymentType: 'Tipos de pagamento Pagamento',
recurrent: 'Recorrente',
unique: 'Pagamento pontual',
signLocation: 'Data - Localidade',
sign: 'Assinatura e carimbo do devedor',
},
order: 'Referência da ordem {0}',
},

View File

@ -1,37 +1,18 @@
const fs = require('fs');
const strftime = require('strftime');
const database = require(`${appPath}/lib/database`);
const template = fs.readFileSync(__dirname + '/index.html').toString();
const lang = require('./locale.js');
const UserException = require(`${appPath}/lib/exceptions/userException`);
const Component = require(`${appPath}/core/component`);
const reportHeader = new Component('report-header');
const reportFooter = new Component('report-footer');
const db = require(`${appPath}/core/database`);
const rptSepaCore = {
name: 'rpt-sepa-core',
name: 'sepa-core',
async serverPrefetch() {
this.client = await this.fetchClient(this.receiptId);
async asyncData(ctx, params) {
if (!params.clientFk)
throw new UserException('No client id specified');
if (!params.companyFk)
throw new UserException('No company id specified');
return this.methods.fetchClient(params.clientFk, params.companyFk)
.then(([[client]]) => {
if (!client)
throw new UserException('No client data found');
return client;
});
},
created() {
this.clientId = 101;
if (this.locale)
this.$i18n.locale = this.locale;
if (!this.client)
throw new Error('Something went wrong');
},
methods: {
fetchClient(clientFk, companyFk) {
fetchClient(clientId, companyId) {
return database.pool.query(
`SELECT
c.id clientId,