refactor
gitea/salix/1466-print_refactor This commit looks good
Details
|
@ -18,6 +18,7 @@ export default class Controller {
|
||||||
this.$.balanceCreateDialog.show();
|
this.$.balanceCreateDialog.show();
|
||||||
}, name: 'Payment on account...', always: true}
|
}, name: 'Payment on account...', always: true}
|
||||||
];
|
];
|
||||||
|
console.log(this.$stateParams);
|
||||||
}
|
}
|
||||||
|
|
||||||
setBalanceCreateDialog() {
|
setBalanceCreateDialog() {
|
||||||
|
|
|
@ -4769,7 +4769,7 @@
|
||||||
"dot-prop": {
|
"dot-prop": {
|
||||||
"version": "4.2.0",
|
"version": "4.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-4.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-4.2.0.tgz",
|
||||||
"integrity": "sha512-tUMXrxlExSW6U2EXiiKGSBVdYgtV8qlHL+C10TsW4PURY/ic+eaysnSkwB4kA/mBlCyy/IKDJ+Lc3wbWeaXtuQ==",
|
"integrity": "sha1-HxngwuGqDjJ5fEl5nyg3rGr2nFc=",
|
||||||
"requires": {
|
"requires": {
|
||||||
"is-obj": "^1.0.0"
|
"is-obj": "^1.0.0"
|
||||||
}
|
}
|
||||||
|
@ -4937,7 +4937,7 @@
|
||||||
},
|
},
|
||||||
"jsonfile": {
|
"jsonfile": {
|
||||||
"version": "2.4.0",
|
"version": "2.4.0",
|
||||||
"resolved": "http://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz",
|
||||||
"integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=",
|
"integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
|
@ -7485,7 +7485,7 @@
|
||||||
},
|
},
|
||||||
"kind-of": {
|
"kind-of": {
|
||||||
"version": "1.1.0",
|
"version": "1.1.0",
|
||||||
"resolved": "http://registry.npmjs.org/kind-of/-/kind-of-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-1.1.0.tgz",
|
||||||
"integrity": "sha1-FAo9LUGjbS78+pN3tiwk+ElaXEQ=",
|
"integrity": "sha1-FAo9LUGjbS78+pN3tiwk+ElaXEQ=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
@ -9120,7 +9120,7 @@
|
||||||
},
|
},
|
||||||
"jasmine-core": {
|
"jasmine-core": {
|
||||||
"version": "2.99.1",
|
"version": "2.99.1",
|
||||||
"resolved": "http://registry.npmjs.org/jasmine-core/-/jasmine-core-2.99.1.tgz",
|
"resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-2.99.1.tgz",
|
||||||
"integrity": "sha1-5kAN8ea1bhMLYcS80JPap/boyhU=",
|
"integrity": "sha1-5kAN8ea1bhMLYcS80JPap/boyhU=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
@ -11194,7 +11194,7 @@
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"commander": {
|
"commander": {
|
||||||
"version": "1.0.4",
|
"version": "1.0.4",
|
||||||
"resolved": "http://registry.npmjs.org/commander/-/commander-1.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/commander/-/commander-1.0.4.tgz",
|
||||||
"integrity": "sha1-Xt6xruI8T7VBprcNaSq+8ZZpotM=",
|
"integrity": "sha1-Xt6xruI8T7VBprcNaSq+8ZZpotM=",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
|
@ -13041,7 +13041,7 @@
|
||||||
},
|
},
|
||||||
"readable-stream": {
|
"readable-stream": {
|
||||||
"version": "1.1.14",
|
"version": "1.1.14",
|
||||||
"resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
|
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
|
||||||
"integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=",
|
"integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
|
@ -13053,7 +13053,7 @@
|
||||||
},
|
},
|
||||||
"string_decoder": {
|
"string_decoder": {
|
||||||
"version": "0.10.31",
|
"version": "0.10.31",
|
||||||
"resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
|
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
|
||||||
"integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=",
|
"integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
@ -13500,7 +13500,7 @@
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"jsesc": {
|
"jsesc": {
|
||||||
"version": "0.5.0",
|
"version": "0.5.0",
|
||||||
"resolved": "http://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz",
|
||||||
"integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=",
|
"integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=",
|
||||||
"dev": true
|
"dev": true
|
||||||
}
|
}
|
||||||
|
@ -14321,7 +14321,7 @@
|
||||||
},
|
},
|
||||||
"string-width": {
|
"string-width": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "http://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
|
||||||
"integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
|
"integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
|
@ -15885,7 +15885,7 @@
|
||||||
"touch": {
|
"touch": {
|
||||||
"version": "3.1.0",
|
"version": "3.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz",
|
||||||
"integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==",
|
"integrity": "sha1-/jZfX3XsntTlaCXgu3bSSrdK+Ds=",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"nopt": "~1.0.10"
|
"nopt": "~1.0.10"
|
||||||
|
|
|
@ -1,3 +1,7 @@
|
||||||
|
/**
|
||||||
|
* Email only stylesheet
|
||||||
|
*
|
||||||
|
*/
|
||||||
body {
|
body {
|
||||||
background-color: #EEE
|
background-color: #EEE
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,7 @@
|
||||||
|
/**
|
||||||
|
* CSS layout elements
|
||||||
|
*
|
||||||
|
*/
|
||||||
.container {
|
.container {
|
||||||
font-family: "Roboto", "Helvetica", "Arial", sans-serif;
|
font-family: "Roboto", "Helvetica", "Arial", sans-serif;
|
||||||
font-size: 16px
|
font-size: 16px
|
||||||
|
|
|
@ -1,3 +1,7 @@
|
||||||
|
/**
|
||||||
|
* CSS misc classes
|
||||||
|
*
|
||||||
|
*/
|
||||||
.uppercase {
|
.uppercase {
|
||||||
text-transform: uppercase
|
text-transform: uppercase
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,7 @@
|
||||||
|
/**
|
||||||
|
* Report only stylesheet
|
||||||
|
*
|
||||||
|
*/
|
||||||
body {
|
body {
|
||||||
zoom: 0.55
|
zoom: 0.55
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,25 +0,0 @@
|
||||||
[
|
|
||||||
{"type": "email", "name": "client-welcome"},
|
|
||||||
{"type": "email", "name": "printer-setup"},
|
|
||||||
{"type": "email", "name": "payment-update"},
|
|
||||||
{"type": "email", "name": "letter-debtor-st"},
|
|
||||||
{"type": "email", "name": "letter-debtor-nd"},
|
|
||||||
{"type": "email", "name": "claim-pickup-order"},
|
|
||||||
{"type": "email", "name": "sepa-core"},
|
|
||||||
{"type": "email", "name": "client-lcr"},
|
|
||||||
{"type": "email", "name": "driver-route"},
|
|
||||||
{"type": "email", "name": "delivery-note"},
|
|
||||||
{"type": "report", "name": "rpt-delivery-note"},
|
|
||||||
{"type": "report", "name": "rpt-claim-pickup-order"},
|
|
||||||
{"type": "report", "name": "rpt-letter-debtor"},
|
|
||||||
{"type": "report", "name": "rpt-sepa-core"},
|
|
||||||
{"type": "report", "name": "rpt-receipt"},
|
|
||||||
{"type": "report", "name": "rpt-zone"},
|
|
||||||
{"type": "report", "name": "rpt-route"},
|
|
||||||
{"type": "report", "name": "rpt-lcr"},
|
|
||||||
{"type": "report", "name": "rpt-item-label"},
|
|
||||||
{"type": "static", "name": "email-header"},
|
|
||||||
{"type": "static", "name": "email-footer"},
|
|
||||||
{"type": "static", "name": "report-header"},
|
|
||||||
{"type": "static", "name": "report-footer"}
|
|
||||||
]
|
|
|
@ -0,0 +1,103 @@
|
||||||
|
const Vue = require('vue');
|
||||||
|
const VueI18n = require('vue-i18n');
|
||||||
|
const renderer = require('vue-server-renderer').createRenderer();
|
||||||
|
Vue.use(VueI18n);
|
||||||
|
|
||||||
|
const fs = require('fs');
|
||||||
|
const yaml = require('js-yaml');
|
||||||
|
const juice = require('juice');
|
||||||
|
const path = require('path');
|
||||||
|
|
||||||
|
const config = require('./config');
|
||||||
|
|
||||||
|
class Component {
|
||||||
|
constructor(name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
get path() {
|
||||||
|
return `./components/${this.name}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
get template() {
|
||||||
|
const templatePath = `${this.path}/${this.name}.html`;
|
||||||
|
const fullPath = path.resolve(__dirname, templatePath);
|
||||||
|
|
||||||
|
return fs.readFileSync(fullPath, 'utf8');
|
||||||
|
}
|
||||||
|
|
||||||
|
get locale() {
|
||||||
|
const mergedLocale = {messages: {}};
|
||||||
|
const localePath = path.resolve(__dirname, `${this.path}/locale`);
|
||||||
|
|
||||||
|
if (!fs.existsSync(localePath))
|
||||||
|
return mergedLocale;
|
||||||
|
|
||||||
|
const localeDir = fs.readdirSync(localePath);
|
||||||
|
localeDir.forEach(locale => {
|
||||||
|
const fullPath = path.join(localePath, '/', locale);
|
||||||
|
const yamlLocale = fs.readFileSync(fullPath, 'utf8');
|
||||||
|
const jsonLocale = yaml.safeLoad(yamlLocale);
|
||||||
|
const localeName = locale.replace('.yml', '');
|
||||||
|
|
||||||
|
mergedLocale.messages[localeName] = jsonLocale;
|
||||||
|
});
|
||||||
|
|
||||||
|
return mergedLocale;
|
||||||
|
}
|
||||||
|
|
||||||
|
get stylesheet() {
|
||||||
|
let mergedStyles = '';
|
||||||
|
const stylePath = path.resolve(__dirname, `${this.path}/assets/css`);
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
get attachments() {
|
||||||
|
const attachmentsPath = `${this.path}/attachments.json`;
|
||||||
|
const fullPath = path.resolve(__dirname, attachmentsPath);
|
||||||
|
|
||||||
|
if (!fs.existsSync(fullPath))
|
||||||
|
return [];
|
||||||
|
|
||||||
|
return require(fullPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
build() {
|
||||||
|
const component = require(`${this.path}/${this.name}`);
|
||||||
|
|
||||||
|
component.i18n = this.locale;
|
||||||
|
component.attachments = this.attachments;
|
||||||
|
component.template = juice.inlineContent(this.template, this.stylesheet, {
|
||||||
|
inlinePseudoElements: true
|
||||||
|
});
|
||||||
|
|
||||||
|
return component;
|
||||||
|
}
|
||||||
|
|
||||||
|
async render() {
|
||||||
|
const component = this.build();
|
||||||
|
const i18n = new VueI18n(config.i18n);
|
||||||
|
const app = new Vue({
|
||||||
|
i18n: i18n,
|
||||||
|
render: h => h(component, {
|
||||||
|
props: this.args
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
return renderer.renderToString(app);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = Component;
|
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 3.1 KiB |
Before Width: | Height: | Size: 3.5 KiB After Width: | Height: | Size: 3.5 KiB |
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 3.0 KiB |
Before Width: | Height: | Size: 3.6 KiB After Width: | Height: | Size: 3.6 KiB |
Before Width: | Height: | Size: 3.5 KiB After Width: | Height: | Size: 3.5 KiB |
Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 3.7 KiB |
Before Width: | Height: | Size: 3.6 KiB After Width: | Height: | Size: 3.6 KiB |
Before Width: | Height: | Size: 3.4 KiB After Width: | Height: | Size: 3.4 KiB |
|
@ -0,0 +1,27 @@
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"filename": "facebook.png",
|
||||||
|
"path": "/assets/images/facebook.png",
|
||||||
|
"cid": "facebook.png"
|
||||||
|
}, {
|
||||||
|
"filename": "twitter.png",
|
||||||
|
"path": "/assets/images/twitter.png",
|
||||||
|
"cid": "twitter.png"
|
||||||
|
}, {
|
||||||
|
"filename": "youtube.png",
|
||||||
|
"path": "/assets/images/youtube.png",
|
||||||
|
"cid": "youtube.png"
|
||||||
|
}, {
|
||||||
|
"filename": "pinterest.png",
|
||||||
|
"path": "/assets/images/pinterest.png",
|
||||||
|
"cid": "pinterest.png"
|
||||||
|
}, {
|
||||||
|
"filename": "instagram.png",
|
||||||
|
"path": "/assets/images/instagram.png",
|
||||||
|
"cid": "instagram.png"
|
||||||
|
}, {
|
||||||
|
"filename": "linkedin.png",
|
||||||
|
"path": "/assets/images/linkedin.png",
|
||||||
|
"cid": "linkedin.png"
|
||||||
|
}
|
||||||
|
]
|
|
@ -4,13 +4,13 @@
|
||||||
<a href="https://www.verdnatura.es" target="_blank">
|
<a href="https://www.verdnatura.es" target="_blank">
|
||||||
<div class="btn">
|
<div class="btn">
|
||||||
<span class="text">{{ $t('buttons.webAcccess')}}</span>
|
<span class="text">{{ $t('buttons.webAcccess')}}</span>
|
||||||
<span class="icon"><img :src="embeded['/assets/images/action.png']"/></span>
|
<span class="icon"><img :src="/assets/images/action.png"/></span>
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
<a href="https://goo.gl/forms/j8WSL151ZW6QtlT72" target="_blank">
|
<a href="https://goo.gl/forms/j8WSL151ZW6QtlT72" target="_blank">
|
||||||
<div class="btn">
|
<div class="btn">
|
||||||
<span class="text">{{ $t('buttons.info')}}</span>
|
<span class="text">{{ $t('buttons.info')}}</span>
|
||||||
<span class="icon"><img :src="embeded['/assets/images/info.png']"/></span>
|
<span class="icon"><img :src="/assets/images/info.png"/></span>
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
</section> -->
|
</section> -->
|
||||||
|
@ -19,22 +19,22 @@
|
||||||
<!-- Networks block -->
|
<!-- Networks block -->
|
||||||
<section class="networks">
|
<section class="networks">
|
||||||
<a href="https://www.facebook.com/Verdnatura" target="_blank">
|
<a href="https://www.facebook.com/Verdnatura" target="_blank">
|
||||||
<img :src="embeded['/assets/images/facebook.png']" alt="Facebook"/>
|
<img :src="getSrc('facebook.png')" alt="Facebook"/>
|
||||||
</a>
|
</a>
|
||||||
<a href="https://www.twitter.com/Verdnatura" target="_blank">
|
<a href="https://www.twitter.com/Verdnatura" target="_blank">
|
||||||
<img :src="embeded['/assets/images/twitter.png']" alt="Twitter"/>
|
<img :src="getSrc('twitter.png')" alt="Twitter"/>
|
||||||
</a>
|
</a>
|
||||||
<a href="https://www.youtube.com/Verdnatura" target="_blank">
|
<a href="https://www.youtube.com/Verdnatura" target="_blank">
|
||||||
<img :src="embeded['/assets/images/youtube.png']" alt="Youtube"/>
|
<img :src="getSrc('youtube.png')" alt="Youtube"/>
|
||||||
</a>
|
</a>
|
||||||
<a href="https://www.pinterest.com/Verdnatura" target="_blank">
|
<a href="https://www.pinterest.com/Verdnatura" target="_blank">
|
||||||
<img :src="embeded['/assets/images/pinterest.png']" alt="Pinterest"/>
|
<img :src="getSrc('pinterest.png')" alt="Pinterest"/>
|
||||||
</a>
|
</a>
|
||||||
<a href="https://www.instagram.com/Verdnatura" target="_blank">
|
<a href="https://www.instagram.com/Verdnatura" target="_blank">
|
||||||
<img :src="embeded['/assets/images/instagram.png']" alt="Instagram"/>
|
<img :src="getSrc('instagram.png')" alt="Instagram"/>
|
||||||
</a>
|
</a>
|
||||||
<a href="https://www.linkedin.com/company/verdnatura" target="_blank">
|
<a href="https://www.linkedin.com/company/verdnatura" target="_blank">
|
||||||
<img :src="embeded['/assets/images/linkedin.png']" alt="Linkedin"/>
|
<img :src="getSrc('linkedin.png')" alt="Linkedin"/>
|
||||||
</a>
|
</a>
|
||||||
</section>
|
</section>
|
||||||
<!-- Networks block end -->
|
<!-- Networks block end -->
|
|
@ -0,0 +1,4 @@
|
||||||
|
module.exports = {
|
||||||
|
name: 'email-footer',
|
||||||
|
props: ['isPreview', 'locale']
|
||||||
|
};
|
|
@ -0,0 +1,19 @@
|
||||||
|
buttons:
|
||||||
|
webAcccess: Visita nuestra Web
|
||||||
|
info: Ayúdanos a mejorar
|
||||||
|
privacy:
|
||||||
|
fiscalAddress: VERDNATURA LEVANTE SL, B97367486 Avda. Espioca, 100, 46460 Silla
|
||||||
|
· www.verdnatura.es · clientes@verdnatura.es
|
||||||
|
disclaimer: '- AVISO - Este mensaje es privado y confidencial, y debe ser utilizado
|
||||||
|
exclusivamente por la persona destinataria del mismo. Si has recibido este mensaje
|
||||||
|
por error, te rogamos lo comuniques al remitente y borres dicho mensaje y cualquier
|
||||||
|
documento adjunto que pudiera contener. Verdnatura Levante SL no renuncia a la
|
||||||
|
confidencialidad ni a ningún privilegio por causa de transmisión errónea o mal
|
||||||
|
funcionamiento. Igualmente no se hace responsable 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
|
||||||
|
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 por escrito al domicilio social de la entidad. La finalidad del
|
||||||
|
fichero es la gestión administrativa, contabilidad, y facturación.
|
|
@ -0,0 +1,19 @@
|
||||||
|
buttons:
|
||||||
|
webAcccess: Visitez notre site web
|
||||||
|
info: Ayúdanos a mejorar
|
||||||
|
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
|
||||||
|
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
|
||||||
|
ni aningún privilegio por causa de transmisión errónea o mal funcionamiento. Igualmente
|
||||||
|
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
|
||||||
|
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
|
||||||
|
es la gestión administrativa, contabilidad, y facturación.
|
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 30 KiB |
|
@ -0,0 +1,7 @@
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"filename": "email-logo.png",
|
||||||
|
"path": "/assets/images/email-logo.png",
|
||||||
|
"cid": "email-logo.png"
|
||||||
|
}
|
||||||
|
]
|
|
@ -0,0 +1,5 @@
|
||||||
|
<header>
|
||||||
|
<a href="https://www.verdnatura.es" target="_blank">
|
||||||
|
<img :src="getSrc('email-logo.png')" alt="VerdNatura"/>
|
||||||
|
</a>
|
||||||
|
</header>
|
|
@ -0,0 +1,4 @@
|
||||||
|
module.exports = {
|
||||||
|
name: 'email-header',
|
||||||
|
props: ['isPreview']
|
||||||
|
};
|
|
@ -0,0 +1,10 @@
|
||||||
|
numPages: Página {{page}} de {{pages}}
|
||||||
|
law:
|
||||||
|
phytosanitary: 'VERDNATURA LEVANTE SL - Pasaporte Fitosanitario R.P. Generalitat
|
||||||
|
Valenciana - Nº Comerciante: ES17462130'
|
||||||
|
privacy: En cumplimiento de lo dispuesto en la Ley Orgánica 15/1999, de Protección
|
||||||
|
de Datos de Carácter Personal, le comunicamos que los datos personales que facilite
|
||||||
|
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 por escrito al domicilio social de la entidad. La finalidad del
|
||||||
|
fichero es la gestión administrativa, contabilidad, y facturación.
|
|
@ -0,0 +1,10 @@
|
||||||
|
numPages: Page {{page}} de {{pages}}
|
||||||
|
law:
|
||||||
|
phytosanitary: 'VERDNATURA LEVANTE SL - Passeport Phytosanitaire R.P. Generalitat
|
||||||
|
Valenciana - Numéro d''opérateur: ES17462130'
|
||||||
|
privacy: Conformément aux dispositions de la loi organique 15/1999 sur la protection
|
||||||
|
des données personnelles, nous vous informons que les données personnelles que
|
||||||
|
vous fournissez seront incluses dans des dossiers. VERDNATURA LEVANTE S.L., vous
|
||||||
|
pouvez à tout moment, exercer les droits d'accès, de rectification, d'annulation
|
||||||
|
et d'opposition, en communiquant par écrit au siège social de la société. Le dossier
|
||||||
|
a pour objet la gestion administrative, la comptabilité et la facturation.
|
|
@ -0,0 +1,10 @@
|
||||||
|
numPages: Página {{page}} de {{pages}}
|
||||||
|
law:
|
||||||
|
phytosanitary: 'VERDNATURA LEVANTE S.L - Passaporte Fitossanitário R.P. Generalitat
|
||||||
|
Valenciana - Nº Comerciante: ES17462130'
|
||||||
|
privacy: Em cumprimento do disposto na lei Orgânica 15/1999, de Protecção de Dados
|
||||||
|
de Carácter Pessoal, comunicamos que os dados pessoais que facilite se incluirão
|
||||||
|
nos ficheiros automatizados de VERDNATURA LEVANTE S.L., podendo em todo momento
|
||||||
|
exercer os direitos de acesso, rectificação, cancelação e oposição, comunicando
|
||||||
|
por escrito ao domicílio social da entidade. A finalidade do ficheiro é a gestão
|
||||||
|
administrativa, contabilidade e facturação.
|
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 19 KiB |
Before Width: | Height: | Size: 9.5 KiB After Width: | Height: | Size: 9.5 KiB |
|
@ -0,0 +1,5 @@
|
||||||
|
company:
|
||||||
|
fiscalAddress: VERDNATURA LEVANTE S.L., B97367486 Avda. Espioca, 100, 46460 Silla
|
||||||
|
- www.verdnatura.es - clientes@verdnatura.es
|
||||||
|
registry: 'CIF: B97367486 Registro Mercantil de Valencia, Tomo 8041, Libro 5334,
|
||||||
|
Folio 160, Sección 8, Hoja V 102076'
|
|
@ -0,0 +1,5 @@
|
||||||
|
company:
|
||||||
|
fiscalAddress: VERDNATURA LEVANTE S.L., B97367486 Avda. Espioca, 100, 46460 Silla
|
||||||
|
- www.verdnatura.es - clientes@verdnatura.es
|
||||||
|
registry: 'CIF: B97367486 Registro Mercantil de Valencia, Tomo 8041, Libro 5334,
|
||||||
|
Folio 160, Sección 8, Hoja V 102076'
|
|
@ -0,0 +1 @@
|
||||||
|
// Import global directives
|
|
@ -1,26 +1,92 @@
|
||||||
const Vue = require('vue');
|
const path = require('path');
|
||||||
const VueI18n = require('vue-i18n');
|
|
||||||
const renderer = require('vue-server-renderer').createRenderer();
|
|
||||||
const fs = require('fs-extra');
|
|
||||||
const juice = require('juice');
|
|
||||||
const smtp = require('./smtp');
|
const smtp = require('./smtp');
|
||||||
const fallbackLocale = 'es';
|
const Component = require('./component');
|
||||||
|
const Report = require('./report');
|
||||||
|
|
||||||
if (!process.env.OPENSSL_CONF)
|
if (!process.env.OPENSSL_CONF)
|
||||||
process.env.OPENSSL_CONF = '/etc/ssl/';
|
process.env.OPENSSL_CONF = '/etc/ssl/';
|
||||||
|
|
||||||
Vue.use(VueI18n);
|
class Email extends Component {
|
||||||
|
constructor(name, args) {
|
||||||
|
super(name);
|
||||||
|
|
||||||
module.exports = {
|
this.args = args;
|
||||||
|
}
|
||||||
|
|
||||||
|
get path() {
|
||||||
|
return `../templates/email/${this.name}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
get subject() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
async send() {
|
||||||
|
const instance = this.build();
|
||||||
|
const rendered = await this.render();
|
||||||
|
const attachments = [];
|
||||||
|
const getAttachments = async(componentPath, files) => {
|
||||||
|
for (file of files) {
|
||||||
|
const fileCopy = Object.assign({}, file);
|
||||||
|
if (fileCopy.cid) {
|
||||||
|
const templatePath = `${componentPath}/${file.path}`;
|
||||||
|
const fullFilePath = path.resolve(__dirname, templatePath);
|
||||||
|
|
||||||
|
fileCopy.path = path.resolve(__dirname, fullFilePath);
|
||||||
|
} else {
|
||||||
|
const reportName = fileCopy.filename.replace('.pdf', '');
|
||||||
|
const report = new Report(reportName, this.args);
|
||||||
|
fileCopy.content = await report.toPdfStream();
|
||||||
|
}
|
||||||
|
|
||||||
|
attachments.push(fileCopy);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (instance.components) {
|
||||||
|
const components = instance.components;
|
||||||
|
for (let componentName in components) {
|
||||||
|
const component = 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 options = {
|
||||||
|
to: this.args.recipient,
|
||||||
|
subject: 'Test',
|
||||||
|
html: rendered,
|
||||||
|
attachments: attachments
|
||||||
|
};
|
||||||
|
|
||||||
|
return smtp.send(options);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = Email;
|
||||||
|
|
||||||
|
|
||||||
|
/* module.exports = {
|
||||||
|
|
||||||
path: `${appPath}/report`,
|
path: `${appPath}/report`,
|
||||||
|
|
||||||
/**
|
|
||||||
* Renders a report component
|
|
||||||
*
|
|
||||||
* @param {String} name - Report name
|
|
||||||
* @param {Object} ctx - Request context
|
|
||||||
*/
|
|
||||||
async render(name, ctx) {
|
async render(name, ctx) {
|
||||||
const component = require(`${this.path}/${name}`);
|
const component = require(`${this.path}/${name}`);
|
||||||
const result = await this.preFetch(component, ctx);
|
const result = await this.preFetch(component, ctx);
|
||||||
|
@ -39,12 +105,6 @@ module.exports = {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
|
||||||
* Prefetch all component data from asyncData method
|
|
||||||
*
|
|
||||||
* @param {Object} orgComponent - Component object
|
|
||||||
* @param {Object} ctx - Request context
|
|
||||||
*/
|
|
||||||
async preFetch(orgComponent, ctx) {
|
async preFetch(orgComponent, ctx) {
|
||||||
let component = Object.create(orgComponent);
|
let component = Object.create(orgComponent);
|
||||||
let mergedData = {attachments: []};
|
let mergedData = {attachments: []};
|
||||||
|
@ -150,3 +210,4 @@ module.exports = {
|
||||||
return smtp.send(options);
|
return smtp.send(options);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
*/
|
|
@ -0,0 +1,7 @@
|
||||||
|
const Vue = require('vue');
|
||||||
|
const currency = {
|
||||||
|
methods: {
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
Vue.mixin(currency);
|
|
@ -0,0 +1 @@
|
||||||
|
// Import global filters
|
|
@ -0,0 +1,15 @@
|
||||||
|
const Vue = require('vue');
|
||||||
|
const imageSrc = {
|
||||||
|
methods: {
|
||||||
|
getSrc(image) {
|
||||||
|
let src = `cid:${image}`;
|
||||||
|
|
||||||
|
if (this.isPreview === 'true')
|
||||||
|
src = `/api/assets/${this.$options.name}/images/${image}`;
|
||||||
|
|
||||||
|
return src;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
Vue.mixin(imageSrc);
|
|
@ -0,0 +1,2 @@
|
||||||
|
// Import global mixins
|
||||||
|
require('./image-src');
|
|
@ -1,66 +1,20 @@
|
||||||
const Vue = require('vue');
|
|
||||||
const VueI18n = require('vue-i18n');
|
|
||||||
const renderer = require('vue-server-renderer').createRenderer();
|
|
||||||
|
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const pdf = require('html-pdf');
|
const pdf = require('html-pdf');
|
||||||
const juice = require('juice');
|
|
||||||
const path = require('path');
|
|
||||||
|
|
||||||
const config = require('./config');
|
const config = require('./config');
|
||||||
const reportsPath = '../templates/reports';
|
const Component = require('./component');
|
||||||
|
|
||||||
if (!process.env.OPENSSL_CONF)
|
if (!process.env.OPENSSL_CONF)
|
||||||
process.env.OPENSSL_CONF = '/etc/ssl/';
|
process.env.OPENSSL_CONF = '/etc/ssl/';
|
||||||
|
|
||||||
Vue.use(VueI18n);
|
class Report extends Component {
|
||||||
|
|
||||||
class Report {
|
|
||||||
constructor(name, args) {
|
constructor(name, args) {
|
||||||
this.name = name;
|
super(name);
|
||||||
|
|
||||||
this.args = args;
|
this.args = args;
|
||||||
}
|
}
|
||||||
|
|
||||||
get path() {
|
get path() {
|
||||||
return `${reportsPath}/${this.name}`;
|
return `../templates/reports/${this.name}`;
|
||||||
}
|
|
||||||
|
|
||||||
get template() {
|
|
||||||
const templatePath = `${this.path}/${this.name}.html`;
|
|
||||||
const fullPath = path.resolve(__dirname, templatePath);
|
|
||||||
|
|
||||||
return fs.readFileSync(fullPath, 'utf8');
|
|
||||||
}
|
|
||||||
|
|
||||||
get locale() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
get style() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
async render() {
|
|
||||||
const localePath = `${this.path}/locale`;
|
|
||||||
const stylePath = `${this.path}/assets/css/index`;
|
|
||||||
|
|
||||||
const stylesheet = require(stylePath);
|
|
||||||
const component = require(this.path);
|
|
||||||
|
|
||||||
component.i18n = require(localePath);
|
|
||||||
component.template = juice.inlineContent(this.template, stylesheet, {
|
|
||||||
inlinePseudoElements: true
|
|
||||||
});
|
|
||||||
|
|
||||||
const i18n = new VueI18n(config.i18n);
|
|
||||||
const app = new Vue({
|
|
||||||
i18n: i18n,
|
|
||||||
render: h => h(component, {
|
|
||||||
props: this.args
|
|
||||||
})
|
|
||||||
});
|
|
||||||
|
|
||||||
return renderer.renderToString(app);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async toPdfStream() {
|
async toPdfStream() {
|
|
@ -1,13 +1,25 @@
|
||||||
const Report = require('./report');
|
|
||||||
const emailEngine = require('./emailEngine');
|
|
||||||
const express = require('express');
|
const express = require('express');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
const vue = require('vue');
|
|
||||||
|
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
|
|
||||||
|
const Report = require('./report');
|
||||||
|
const Email = require('./email');
|
||||||
|
|
||||||
const templatesPath = path.resolve(__dirname, '../templates');
|
const templatesPath = path.resolve(__dirname, '../templates');
|
||||||
|
const componentsPath = path.resolve(__dirname, './components');
|
||||||
|
|
||||||
module.exports = app => {
|
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
|
* Serve static files
|
||||||
*/
|
*/
|
||||||
|
@ -20,7 +32,7 @@ module.exports = app => {
|
||||||
const templateDir = path.join(templatesPath, '/', directory, '/', templateName);
|
const templateDir = path.join(templatesPath, '/', directory, '/', templateName);
|
||||||
const assetsDir = `${templateDir}/assets`;
|
const assetsDir = `${templateDir}/assets`;
|
||||||
|
|
||||||
app.use(`/api/assets`, express.static(assetsDir));
|
app.use(`/api/assets/${templateName}`, express.static(assetsDir));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -28,19 +40,34 @@ module.exports = app => {
|
||||||
const args = Object.assign({}, req.body, req.query);
|
const args = Object.assign({}, req.body, req.query);
|
||||||
const report = new Report(req.params.name, args);
|
const report = new Report(req.params.name, args);
|
||||||
const stream = await report.toPdfStream();
|
const stream = await report.toPdfStream();
|
||||||
|
|
||||||
res.setHeader('Content-type', 'application/pdf');
|
res.setHeader('Content-type', 'application/pdf');
|
||||||
stream.pipe(res);
|
stream.pipe(res);
|
||||||
});
|
});
|
||||||
|
|
||||||
/* app.get(`/api/email/${name}`, (request, response) => {
|
app.get(`/api/email/:name`, async(req, res) => {
|
||||||
emailEngine.render(name, request).then(rendered => {
|
const args = req.query;
|
||||||
response.send(rendered.html);
|
const requiredArgs = ['userId'];
|
||||||
}).catch(e => {
|
|
||||||
next(e);
|
const hasRequiredArgs = requiredArgs.every(arg => {
|
||||||
|
return args[arg];
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (!hasRequiredArgs)
|
||||||
|
res.json({message: 'userId'});
|
||||||
|
|
||||||
|
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'});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
app.post(`/api/email/${name}`, (request, response, next) => {
|
app.post(`/api/email/${name}`, (request, response, next) => {
|
||||||
emailEngine.toEmail(name, request).then(() => {
|
emailEngine.toEmail(name, request).then(() => {
|
||||||
response.status(200).json({status: 200});
|
response.status(200).json({status: 200});
|
|
@ -1,5 +1,5 @@
|
||||||
const nodemailer = require('nodemailer');
|
const nodemailer = require('nodemailer');
|
||||||
const config = require('./config.js');
|
const config = require('./config');
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
init() {
|
init() {
|
||||||
|
@ -11,7 +11,7 @@ module.exports = {
|
||||||
options.from = `${config.app.senderName} <${config.app.senderMail}>`;
|
options.from = `${config.app.senderName} <${config.app.senderMail}>`;
|
||||||
|
|
||||||
if (process.env.NODE_ENV !== 'production') {
|
if (process.env.NODE_ENV !== 'production') {
|
||||||
if (!config.smtp.user)
|
if (!config.smtp.auth.user)
|
||||||
return Promise.resolve(true);
|
return Promise.resolve(true);
|
||||||
|
|
||||||
options.to = config.app.senderMail;
|
options.to = config.app.senderMail;
|
|
@ -1,7 +0,0 @@
|
||||||
module.exports = {
|
|
||||||
methods: {
|
|
||||||
uFirst: (text) => {
|
|
||||||
return text;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
|
@ -25,6 +25,14 @@
|
||||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
|
||||||
"integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4="
|
"integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4="
|
||||||
},
|
},
|
||||||
|
"argparse": {
|
||||||
|
"version": "1.0.10",
|
||||||
|
"resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
|
||||||
|
"integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
|
||||||
|
"requires": {
|
||||||
|
"sprintf-js": "~1.0.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
"asn1": {
|
"asn1": {
|
||||||
"version": "0.2.4",
|
"version": "0.2.4",
|
||||||
"resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz",
|
"resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz",
|
||||||
|
@ -309,6 +317,11 @@
|
||||||
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
|
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
|
||||||
"integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ="
|
"integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ="
|
||||||
},
|
},
|
||||||
|
"esprima": {
|
||||||
|
"version": "4.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
|
||||||
|
"integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A=="
|
||||||
|
},
|
||||||
"extend": {
|
"extend": {
|
||||||
"version": "3.0.2",
|
"version": "3.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
|
||||||
|
@ -519,6 +532,15 @@
|
||||||
"resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
|
||||||
"integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo="
|
"integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo="
|
||||||
},
|
},
|
||||||
|
"js-yaml": {
|
||||||
|
"version": "3.13.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz",
|
||||||
|
"integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==",
|
||||||
|
"requires": {
|
||||||
|
"argparse": "^1.0.7",
|
||||||
|
"esprima": "^4.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"jsbn": {
|
"jsbn": {
|
||||||
"version": "0.1.1",
|
"version": "0.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
|
||||||
|
@ -997,6 +1019,11 @@
|
||||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz",
|
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz",
|
||||||
"integrity": "sha1-dc449SvwczxafwwRjYEzSiu19BI="
|
"integrity": "sha1-dc449SvwczxafwwRjYEzSiu19BI="
|
||||||
},
|
},
|
||||||
|
"sprintf-js": {
|
||||||
|
"version": "1.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
|
||||||
|
"integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw="
|
||||||
|
},
|
||||||
"sqlstring": {
|
"sqlstring": {
|
||||||
"version": "2.3.1",
|
"version": "2.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.1.tgz",
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"fs-extra": "^7.0.1",
|
"fs-extra": "^7.0.1",
|
||||||
"html-pdf": "^2.2.0",
|
"html-pdf": "^2.2.0",
|
||||||
|
"js-yaml": "^3.13.1",
|
||||||
"juice": "^5.0.1",
|
"juice": "^5.0.1",
|
||||||
"mysql2": "^1.6.5",
|
"mysql2": "^1.6.5",
|
||||||
"nodemailer": "^4.7.0",
|
"nodemailer": "^4.7.0",
|
||||||
|
|
|
@ -4,11 +4,16 @@ module.exports = app => {
|
||||||
process.env.OPENSSL_CONF = '/etc/ssl/';
|
process.env.OPENSSL_CONF = '/etc/ssl/';
|
||||||
|
|
||||||
// Init database instance
|
// Init database instance
|
||||||
require('./lib/database').init();
|
require('./core/database').init();
|
||||||
// Init SMTP Instance
|
// Init SMTP Instance
|
||||||
require('./lib/smtp').init();
|
require('./core/smtp').init();
|
||||||
|
|
||||||
require('./lib/router')(app);
|
require('./core/router')(app);
|
||||||
|
|
||||||
|
require('./core/mixins');
|
||||||
|
require('./core/filters');
|
||||||
|
require('./core/directives');
|
||||||
|
// require('./core/components/email-header/email-header');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
/**
|
||||||
|
* 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
|
||||||
|
}
|
|
@ -1,7 +0,0 @@
|
||||||
const CssReader = require(`${appPath}/lib/cssReader`);
|
|
||||||
|
|
||||||
module.exports = new CssReader([
|
|
||||||
`${appPath}/common/css/layout.css`,
|
|
||||||
`${appPath}/common/css/email.css`,
|
|
||||||
`${appPath}/common/css/misc.css`])
|
|
||||||
.mergeStyles();
|
|
|
@ -0,0 +1,233 @@
|
||||||
|
/**
|
||||||
|
* 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
|
||||||
|
}
|
|
@ -0,0 +1,47 @@
|
||||||
|
/**
|
||||||
|
* 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;
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
[{
|
||||||
|
"filename": "claim-pickup-order.pdf"
|
||||||
|
}]
|
|
@ -6,7 +6,7 @@
|
||||||
<body>
|
<body>
|
||||||
<section class="container">
|
<section class="container">
|
||||||
<!-- Header component -->
|
<!-- Header component -->
|
||||||
<email-header></email-header>
|
<email-header :is-preview="isPreview"></email-header>
|
||||||
<!-- End header component -->
|
<!-- End header component -->
|
||||||
<section class="main">
|
<section class="main">
|
||||||
<!-- Title block -->
|
<!-- Title block -->
|
||||||
|
@ -15,6 +15,8 @@
|
||||||
</div>
|
</div>
|
||||||
<!-- Title block end -->
|
<!-- Title block end -->
|
||||||
|
|
||||||
|
{{$t('testing')}}
|
||||||
|
|
||||||
<p>{{$t('description.dear')}},</p>
|
<p>{{$t('description.dear')}},</p>
|
||||||
<p>{{$t('description.instructions')}}</p>
|
<p>{{$t('description.instructions')}}</p>
|
||||||
|
|
||||||
|
@ -27,9 +29,14 @@
|
||||||
</ol>
|
</ol>
|
||||||
<p>{{$t('sections.howToBuy.stock')}}</p>
|
<p>{{$t('sections.howToBuy.stock')}}</p>
|
||||||
<p>{{$t('sections.howToBuy.delivery')}}</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>
|
||||||
|
</section>
|
||||||
|
</section>
|
||||||
</section>
|
</section>
|
||||||
<!-- Footer component -->
|
<!-- Footer component -->
|
||||||
<email-footer :locale="locale"></email-footer>
|
<email-footer :is-preview="isPreview" :locale="locale"></email-footer>
|
||||||
<!-- End footer component -->
|
<!-- End footer component -->
|
||||||
</section>
|
</section>
|
||||||
</body>
|
</body>
|
|
@ -0,0 +1,39 @@
|
||||||
|
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');
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
name: 'claim-pickup-order',
|
||||||
|
/* async serverPrefetch() {
|
||||||
|
this.client = await this.fetchClient(this.clientId);
|
||||||
|
},*/
|
||||||
|
created() {
|
||||||
|
if (this.locale)
|
||||||
|
this.$i18n.locale = this.locale;
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
attachments
|
||||||
|
};
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
fetchClient(claimId) {
|
||||||
|
return db.findOne(`
|
||||||
|
SELECT
|
||||||
|
c.id,
|
||||||
|
u.lang locale,
|
||||||
|
c.email recipient
|
||||||
|
FROM claim cl
|
||||||
|
JOIN client c ON c.id = cl.clientFk
|
||||||
|
JOIN account.user u ON u.id = c.id
|
||||||
|
WHERE cl.id = ?`, [claimId]);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
'email-header': emailHeader.build(),
|
||||||
|
'email-footer': emailFooter.build()
|
||||||
|
},
|
||||||
|
props: ['claimId', 'isPreview']
|
||||||
|
};
|
|
@ -1,53 +0,0 @@
|
||||||
const UserException = require(`${appPath}/lib/exceptions/userException`);
|
|
||||||
const reportEngine = require(`${appPath}/lib/reportEngine`);
|
|
||||||
const database = require(`${appPath}/lib/database`);
|
|
||||||
const emailHeader = require('../email-header');
|
|
||||||
const emailFooter = require('../email-footer');
|
|
||||||
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
name: 'claim-pickup-order',
|
|
||||||
async asyncData(ctx, params) {
|
|
||||||
const promises = [];
|
|
||||||
const data = {
|
|
||||||
isPreview: ctx.method === 'GET',
|
|
||||||
};
|
|
||||||
|
|
||||||
if (!params.claimFk)
|
|
||||||
throw new UserException('No claim id specified');
|
|
||||||
|
|
||||||
promises.push(reportEngine.toPdf('rpt-claim-pickup-order', ctx));
|
|
||||||
promises.push(this.methods.fetchClient(params.claimFk));
|
|
||||||
|
|
||||||
return Promise.all(promises).then(result => {
|
|
||||||
const stream = result[0];
|
|
||||||
const [[client]] = result[1];
|
|
||||||
|
|
||||||
Object.assign(data, client);
|
|
||||||
Object.assign(data, {attachments: [{filename: 'claim-pickup-order.pdf', content: stream}]});
|
|
||||||
|
|
||||||
return data;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
if (this.locale)
|
|
||||||
this.$i18n.locale = this.locale;
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
fetchClient(claimFk) {
|
|
||||||
return database.pool.query(`
|
|
||||||
SELECT
|
|
||||||
c.id,
|
|
||||||
u.lang locale,
|
|
||||||
c.email recipient
|
|
||||||
FROM claim cl
|
|
||||||
JOIN client c ON c.id = cl.clientFk
|
|
||||||
JOIN account.user u ON u.id = c.id
|
|
||||||
WHERE cl.id = ?`, [claimFk]);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
components: {
|
|
||||||
emailHeader,
|
|
||||||
emailFooter,
|
|
||||||
},
|
|
||||||
};
|
|
|
@ -1,25 +0,0 @@
|
||||||
module.exports = {
|
|
||||||
messages: {
|
|
||||||
es: {
|
|
||||||
subject: 'Orden de recogida',
|
|
||||||
title: 'Orden de recogida',
|
|
||||||
description: {
|
|
||||||
dear: 'Estimado cliente',
|
|
||||||
instructions: 'Aqui tienes tu orden de recogida.'
|
|
||||||
},
|
|
||||||
sections: {
|
|
||||||
howToBuy: {
|
|
||||||
title: 'Cómo hacer un pedido',
|
|
||||||
description: `Para realizar un pedido en nuestra web,
|
|
||||||
debes configurarlo indicando:`,
|
|
||||||
requeriments: [
|
|
||||||
'Si quieres recibir el pedido (por agencia o por nuestro propio reparto) o si lo prefieres recoger en alguno de nuestros almacenes.',
|
|
||||||
'La fecha en la que quieres recibir el pedido (se preparará el día anterior).',
|
|
||||||
'La dirección de entrega o el almacén donde quieres recoger el pedido.'],
|
|
||||||
stock: 'En nuestra web y aplicaciones puedes visualizar el stock disponible de flor cortada, verdes, plantas, complementos y artificial. Ten en cuenta que dicho stock puede variar en función de la fecha seleccionada al configurar el pedido. Es importante CONFIRMAR los pedidos para que la mercancía quede reservada.',
|
|
||||||
delivery: 'El reparto se realiza de lunes a sábado según la zona en la que te encuentres. Por regla general, los pedidos que se entregan por agencia, deben estar confirmados y pagados antes de las 17h del día en que se preparan (el día anterior a recibirlos), aunque esto puede variar si el pedido se envía a través de nuestro reparto y según la zona.',
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
subject: Orden de recogida
|
||||||
|
title: Orden de recogida
|
||||||
|
description:
|
||||||
|
dear: Estimado cliente
|
||||||
|
instructions: Aqui tienes tu orden de recogida.
|
||||||
|
sections:
|
||||||
|
howToBuy:
|
||||||
|
title: Cómo hacer un pedido
|
||||||
|
description: 'Para realizar un pedido en nuestra web, debes configurarlo indicando:'
|
||||||
|
requeriments:
|
||||||
|
- Si quieres recibir el pedido (por agencia o por nuestro propio reparto) o si
|
||||||
|
lo prefieres recoger en alguno de nuestros almacenes.
|
||||||
|
- La fecha en la que quieres recibir el pedido (se preparará el día anterior).
|
||||||
|
- La dirección de entrega o el almacén donde quieres recoger el pedido.
|
||||||
|
stock: En nuestra web y aplicaciones puedes visualizar el stock disponible de
|
||||||
|
flor cortada, verdes, plantas, complementos y artificial. Ten en cuenta que
|
||||||
|
dicho stock puede variar en función de la fecha seleccionada al configurar el
|
||||||
|
pedido. Es importante CONFIRMAR los pedidos para que la mercancía quede reservada.
|
||||||
|
delivery: El reparto se realiza de lunes a sábado según la zona en la que te encuentres.
|
||||||
|
Por regla general, los pedidos que se entregan por agencia, deben estar confirmados
|
||||||
|
y pagados antes de las 17h del día en que se preparan (el día anterior a recibirlos),
|
||||||
|
aunque esto puede variar si el pedido se envía a través de nuestro reparto y
|
||||||
|
según la zona.
|
|
@ -0,0 +1 @@
|
||||||
|
../../../../../common/css/email.css
|
|
@ -1,7 +0,0 @@
|
||||||
const CssReader = require(`${appPath}/lib/cssReader`);
|
|
||||||
|
|
||||||
module.exports = new CssReader([
|
|
||||||
`${appPath}/common/css/layout.css`,
|
|
||||||
`${appPath}/common/css/email.css`,
|
|
||||||
`${appPath}/common/css/misc.css`])
|
|
||||||
.mergeStyles();
|
|
|
@ -0,0 +1,233 @@
|
||||||
|
/**
|
||||||
|
* 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
|
||||||
|
}
|
|
@ -0,0 +1,47 @@
|
||||||
|
/**
|
||||||
|
* 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;
|
||||||
|
}
|
|
@ -6,7 +6,7 @@
|
||||||
<body>
|
<body>
|
||||||
<section class="container">
|
<section class="container">
|
||||||
<!-- Header component -->
|
<!-- Header component -->
|
||||||
<email-header></email-header>
|
<email-header :is-preview="isPreview"></email-header>
|
||||||
<!-- End header component -->
|
<!-- End header component -->
|
||||||
<section class="main">
|
<section class="main">
|
||||||
<!-- Title block -->
|
<!-- Title block -->
|
||||||
|
@ -19,8 +19,8 @@
|
||||||
<p v-html="$t('clientData')"></p>
|
<p v-html="$t('clientData')"></p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
<div>{{$t('clientId')}}: <strong>{{ id }}</strong></div>
|
<div>{{$t('clientId')}}: <strong>{{client.id}}</strong></div>
|
||||||
<div>{{$t('user')}}: <strong>{{userName}}</strong></div>
|
<div>{{$t('user')}}: <strong>{{client.userName}}</strong></div>
|
||||||
<div>{{$t('password')}}: <strong>********</strong>
|
<div>{{$t('password')}}: <strong>********</strong>
|
||||||
(<a href="https://verdnatura.es">{{$t('passwordResetText')}}</a>)
|
(<a href="https://verdnatura.es">{{$t('passwordResetText')}}</a>)
|
||||||
</div>
|
</div>
|
||||||
|
@ -52,20 +52,21 @@
|
||||||
|
|
||||||
<p v-html="$t('help')"></p>
|
<p v-html="$t('help')"></p>
|
||||||
<p>
|
<p>
|
||||||
<section v-if="salesPersonName">
|
<section v-if="client.salesPersonName">
|
||||||
{{$t('salesPersonName')}}: <strong>{{salesPersonName}}</strong>
|
{{$t('salesPersonName')}}: <strong>{{client.salesPersonName}}</strong>
|
||||||
</section>
|
</section>
|
||||||
<section v-if="salesPersonPhone">
|
<section v-if="client.salesPersonPhone">
|
||||||
{{$t('salesPersonPhone')}}: <strong>{{salesPersonPhone}}</strong>
|
{{$t('salesPersonPhone')}}: <strong>{{client.salesPersonPhone}}</strong>
|
||||||
</section>
|
</section>
|
||||||
<section v-if="salesPersonEmail">
|
<section v-if="client.salesPersonEmail">
|
||||||
{{$t('salesPersonEmail')}}:
|
{{$t('salesPersonEmail')}}:
|
||||||
<strong><a v-bind:href="`mailto: ${salesPersonEmail}`" target="_blank">{{salesPersonEmail}}</strong>
|
<strong><a v-bind:href="`mailto: ${client.salesPersonEmail}`" target="_blank">{{client.salesPersonEmail}}</strong>
|
||||||
</section>
|
</section>
|
||||||
</p>
|
</p>
|
||||||
</section>
|
</section>
|
||||||
|
{{isPreview}}
|
||||||
<!-- Footer component -->
|
<!-- Footer component -->
|
||||||
<email-footer :locale="locale"></email-footer>
|
<email-footer :is-preview="isPreview" :locale="client.locale"></email-footer>
|
||||||
<!-- End footer component -->
|
<!-- End footer component -->
|
||||||
</section>
|
</section>
|
||||||
</body>
|
</body>
|
|
@ -1,9 +1,15 @@
|
||||||
const database = require(`${appPath}/lib/database`);
|
const db = require(`${appPath}/lib/database`);
|
||||||
const UserException = require(`${appPath}/lib/exceptions/userException`);
|
const Component = require(`${appPath}/lib/component`);
|
||||||
|
const emailHeader = new Component('email-header');
|
||||||
|
const emailFooter = new Component('email-footer');
|
||||||
|
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
name: 'client-welcome',
|
name: 'client-welcome',
|
||||||
async asyncData(ctx, params) {
|
async serverPrefetch() {
|
||||||
|
this.client = await this.fetchClient(this.clientId);
|
||||||
|
},
|
||||||
|
/* async asyncData(ctx, params) {
|
||||||
const data = {
|
const data = {
|
||||||
isPreview: ctx.method === 'GET',
|
isPreview: ctx.method === 'GET',
|
||||||
};
|
};
|
||||||
|
@ -17,14 +23,14 @@ module.exports = {
|
||||||
throw new UserException('No client data found');
|
throw new UserException('No client data found');
|
||||||
return Object.assign(data, result[0]);
|
return Object.assign(data, result[0]);
|
||||||
});
|
});
|
||||||
},
|
}, */
|
||||||
created() {
|
created() {
|
||||||
if (this.locale)
|
if (this.locale)
|
||||||
this.$i18n.locale = this.locale;
|
this.$i18n.locale = this.locale;
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
fetchClient(clientFk) {
|
fetchClient(clientId) {
|
||||||
return database.pool.query(`
|
return db.findOne(`
|
||||||
SELECT
|
SELECT
|
||||||
c.id,
|
c.id,
|
||||||
u.lang locale,
|
u.lang locale,
|
||||||
|
@ -37,11 +43,12 @@ module.exports = {
|
||||||
JOIN account.user u ON u.id = c.id
|
JOIN account.user u ON u.id = c.id
|
||||||
LEFT JOIN worker w ON w.id = c.salesPersonFk
|
LEFT JOIN worker w ON w.id = c.salesPersonFk
|
||||||
LEFT JOIN account.user wu ON wu.id = w.userFk
|
LEFT JOIN account.user wu ON wu.id = w.userFk
|
||||||
WHERE c.id = ?`, [clientFk]);
|
WHERE c.id = ?`, [clientId]);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
'email-header': require('../email-header'),
|
'email-header': emailHeader.build(),
|
||||||
'email-footer': require('../email-footer'),
|
'email-footer': emailFooter.build()
|
||||||
},
|
},
|
||||||
|
props: ['clientId', 'isPreview']
|
||||||
};
|
};
|
|
@ -1,55 +0,0 @@
|
||||||
module.exports = {
|
|
||||||
messages: {
|
|
||||||
es: {
|
|
||||||
subject: 'Bienvenido a Verdnatura',
|
|
||||||
title: '¡Te damos la bienvenida!',
|
|
||||||
dearClient: 'Estimado cliente',
|
|
||||||
clientData: `Tus datos para poder comprar en la web de Verdnatura
|
|
||||||
(<a href="https://www.verdnatura.es" title="Visitar Verdnatura" target="_blank" style="color: #8dba25">https://www.verdnatura.es</a>)
|
|
||||||
o en nuestras aplicaciones para <a href="https://goo.gl/3hC2mG" title="App Store" target="_blank" style="color: #8dba25">iOS</a> y
|
|
||||||
<a href="https://goo.gl/8obvLc" title="Google Play" target="_blank" style="color: #8dba25">Android</a>
|
|
||||||
(<a href="https://www.youtube.com/watch?v=gGfEtFm8qkw" target="_blank" style="color: #8dba25"><strong>Ver tutorial de uso</strong></a>), son`,
|
|
||||||
clientId: 'Identificador de cliente',
|
|
||||||
user: 'Usuario',
|
|
||||||
password: 'Contraseña',
|
|
||||||
passwordResetText: 'Haz clic en "¿Has olvidado tu contraseña?"',
|
|
||||||
sections: {
|
|
||||||
howToBuy: {
|
|
||||||
title: 'Cómo hacer un pedido',
|
|
||||||
description: `Para realizar un pedido en nuestra web,
|
|
||||||
debes configurarlo indicando:`,
|
|
||||||
requeriments: [
|
|
||||||
'Si quieres recibir el pedido (por agencia o por nuestro propio reparto) o si lo prefieres recoger en alguno de nuestros almacenes.',
|
|
||||||
'La fecha en la que quieres recibir el pedido (se preparará el día anterior).',
|
|
||||||
'La dirección de entrega o el almacén donde quieres recoger el pedido.'],
|
|
||||||
stock: 'En nuestra web y aplicaciones puedes visualizar el stock disponible de flor cortada, verdes, plantas, complementos y artificial. Ten en cuenta que dicho stock puede variar en función de la fecha seleccionada al configurar el pedido. Es importante CONFIRMAR los pedidos para que la mercancía quede reservada.',
|
|
||||||
delivery: 'El reparto se realiza de lunes a sábado según la zona en la que te encuentres. Por regla general, los pedidos que se entregan por agencia, deben estar confirmados y pagados antes de las 17h del día en que se preparan (el día anterior a recibirlos), aunque esto puede variar si el pedido se envía a través de nuestro reparto y según la zona.',
|
|
||||||
},
|
|
||||||
howToPay: {
|
|
||||||
title: 'Cómo pagar',
|
|
||||||
description: 'Las formas de pago admitidas en Verdnatura son:',
|
|
||||||
options: [
|
|
||||||
'Con <strong>tarjeta</strong> a través de nuestra plataforma web (al confirmar el pedido).',
|
|
||||||
'Mediante <strong>giro bancario mensual</strong>, modalidad que hay que solicitar y tramitar.',
|
|
||||||
],
|
|
||||||
},
|
|
||||||
toConsider: {
|
|
||||||
title: 'Cosas a tener en cuenta',
|
|
||||||
description: `Verdnatura vende EXCLUSIVAMENTE a profesionales, por lo que debes
|
|
||||||
remitirnos el Modelo 036 ó 037, para comprobar que está
|
|
||||||
dado/a de alta en el epígrafe correspondiente al comercio de flores.`,
|
|
||||||
},
|
|
||||||
claimsPolicy: {
|
|
||||||
title: 'POLÍTICA DE RECLAMACIONES',
|
|
||||||
description: `Verdnatura aceptará las reclamaciones que se realicen dentro
|
|
||||||
de los dos días naturales siguientes a la recepción del pedido (incluyendo el mismo día de la recepción).
|
|
||||||
Pasado este plazo no se aceptará ninguna reclamación.`,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
help: 'Cualquier duda que te surja, no dudes en consultarla, <strong>¡estamos para atenderte!</strong>',
|
|
||||||
salesPersonName: 'Soy tu comercial y mi nombre es',
|
|
||||||
salesPersonPhone: 'Teléfono y whatsapp',
|
|
||||||
salesPersonEmail: 'Dirección de e-mail',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
|
@ -0,0 +1,55 @@
|
||||||
|
subject: Bienvenido a Verdnatura
|
||||||
|
title: "¡Te damos la bienvenida!"
|
||||||
|
dearClient: Estimado cliente
|
||||||
|
clientData: 'Tus datos para poder comprar en la web de Verdnatura (<a href="https://www.verdnatura.es"
|
||||||
|
title="Visitar Verdnatura" target="_blank" style="color: #8dba25">https://www.verdnatura.es</a>)
|
||||||
|
o en nuestras aplicaciones para <a href="https://goo.gl/3hC2mG" title="App Store"
|
||||||
|
target="_blank" style="color: #8dba25">iOS</a> y <a href="https://goo.gl/8obvLc"
|
||||||
|
title="Google Play" target="_blank" style="color: #8dba25">Android</a> (<a
|
||||||
|
href="https://www.youtube.com/watch?v=gGfEtFm8qkw" target="_blank" style="color:
|
||||||
|
#8dba25"><strong>Ver tutorial de uso</strong></a>), son'
|
||||||
|
clientId: Identificador de cliente
|
||||||
|
user: Usuario
|
||||||
|
password: Contraseña
|
||||||
|
passwordResetText: Haz clic en '¿Has olvidado tu contraseña?'
|
||||||
|
sections:
|
||||||
|
howToBuy:
|
||||||
|
title: Cómo hacer un pedido
|
||||||
|
description: 'Para realizar un pedido en nuestra web, debes configurarlo indicando:'
|
||||||
|
requeriments:
|
||||||
|
- Si quieres recibir el pedido (por agencia o por nuestro propio reparto) o si
|
||||||
|
lo prefieres recoger en alguno de nuestros almacenes.
|
||||||
|
- La fecha en la que quieres recibir el pedido (se preparará el día anterior).
|
||||||
|
- La dirección de entrega o el almacén donde quieres recoger el pedido.
|
||||||
|
stock: En nuestra web y aplicaciones puedes visualizar el stock disponible de
|
||||||
|
flor cortada, verdes, plantas, complementos y artificial. Ten en cuenta que
|
||||||
|
dicho stock puede variar en función de la fecha seleccionada al configurar el
|
||||||
|
pedido. Es importante CONFIRMAR los pedidos para que la mercancía quede reservada.
|
||||||
|
delivery: El reparto se realiza de lunes a sábado según la zona en la que te encuentres.
|
||||||
|
Por regla general, los pedidos que se entregan por agencia, deben estar confirmados
|
||||||
|
y pagados antes de las 17h del día en que se preparan (el día anterior a recibirlos),
|
||||||
|
aunque esto puede variar si el pedido se envía a través de nuestro reparto y
|
||||||
|
según la zona.
|
||||||
|
howToPay:
|
||||||
|
title: Cómo pagar
|
||||||
|
description: 'Las formas de pago admitidas en Verdnatura son:'
|
||||||
|
options:
|
||||||
|
- Con <strong>tarjeta</strong> a través de nuestra plataforma web (al confirmar
|
||||||
|
el pedido).
|
||||||
|
- Mediante <strong>giro bancario mensual</strong>, modalidad que hay que solicitar
|
||||||
|
y tramitar.
|
||||||
|
toConsider:
|
||||||
|
title: Cosas a tener en cuenta
|
||||||
|
description: Verdnatura vende EXCLUSIVAMENTE a profesionales, por lo que debes
|
||||||
|
remitirnos el Modelo 036 ó 037, para comprobar que está dado/a de alta en el
|
||||||
|
epígrafe correspondiente al comercio de flores.
|
||||||
|
claimsPolicy:
|
||||||
|
title: POLÍTICA DE RECLAMACIONES
|
||||||
|
description: Verdnatura aceptará las reclamaciones que se realicen dentro de los
|
||||||
|
dos días naturales siguientes a la recepción del pedido (incluyendo el mismo
|
||||||
|
día de la recepción). Pasado este plazo no se aceptará ninguna reclamación.
|
||||||
|
help: Cualquier duda que te surja, no dudes en consultarla, <strong>¡estamos para
|
||||||
|
atenderte!</strong>
|
||||||
|
salesPersonName: Soy tu comercial y mi nombre es
|
||||||
|
salesPersonPhone: Teléfono y whatsapp
|
||||||
|
salesPersonEmail: Dirección de e-mail
|
|
@ -0,0 +1,44 @@
|
||||||
|
/**
|
||||||
|
* 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
|
||||||
|
}
|
|
@ -1,7 +0,0 @@
|
||||||
const CssReader = require(`${appPath}/lib/cssReader`);
|
|
||||||
|
|
||||||
module.exports = new CssReader([
|
|
||||||
`${appPath}/common/css/layout.css`,
|
|
||||||
`${appPath}/common/css/email.css`,
|
|
||||||
`${appPath}/common/css/misc.css`])
|
|
||||||
.mergeStyles();
|
|
|
@ -0,0 +1,233 @@
|
||||||
|
/**
|
||||||
|
* 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
|
||||||
|
}
|
|
@ -0,0 +1,47 @@
|
||||||
|
/**
|
||||||
|
* 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;
|
||||||
|
}
|
|
@ -0,0 +1,4 @@
|
||||||
|
[{
|
||||||
|
"filename": "delivery-note.pdf",
|
||||||
|
"href": "http://localhost:5000/pi"
|
||||||
|
}]
|
|
@ -6,7 +6,7 @@
|
||||||
<body>
|
<body>
|
||||||
<section class="container">
|
<section class="container">
|
||||||
<!-- Header component -->
|
<!-- Header component -->
|
||||||
<email-header></email-header>
|
<email-header :is-preview="isPreview" :locale="locale"></email-header>
|
||||||
<!-- End header component -->
|
<!-- End header component -->
|
||||||
<section class="main">
|
<section class="main">
|
||||||
<!-- Title block -->
|
<!-- Title block -->
|
||||||
|
@ -20,7 +20,7 @@
|
||||||
<p v-html="$t('help')"></p>
|
<p v-html="$t('help')"></p>
|
||||||
</section>
|
</section>
|
||||||
<!-- Footer component -->
|
<!-- Footer component -->
|
||||||
<email-footer :locale="locale"></email-footer>
|
<email-footer :is-preview="isPreview" :locale="locale"></email-footer>
|
||||||
<!-- End footer component -->
|
<!-- End footer component -->
|
||||||
</section>
|
</section>
|
||||||
</body>
|
</body>
|
|
@ -1,6 +1,7 @@
|
||||||
const database = require(`${appPath}/lib/database`);
|
const db = require(`${appPath}/lib/database`);
|
||||||
const reportEngine = require(`${appPath}/lib/reportEngine.js`);
|
const Component = require(`${appPath}/lib/component`);
|
||||||
const UserException = require(`${appPath}/lib/exceptions/userException`);
|
const emailHeader = new Component('email-header');
|
||||||
|
const emailFooter = new Component('email-footer');
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
name: 'delivery-note',
|
name: 'delivery-note',
|
||||||
|
@ -27,12 +28,11 @@ module.exports = {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
if (this.locale)
|
this.locale = 'es';
|
||||||
this.$i18n.locale = this.locale;
|
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
fetchTicket(ticketFk) {
|
fetchTicket(ticketId) {
|
||||||
return database.pool.query(`
|
return db.findOne(`
|
||||||
SELECT
|
SELECT
|
||||||
t.id,
|
t.id,
|
||||||
u.lang locale,
|
u.lang locale,
|
||||||
|
@ -40,11 +40,12 @@ module.exports = {
|
||||||
FROM ticket t
|
FROM ticket t
|
||||||
JOIN client c ON c.id = t.clientFk
|
JOIN client c ON c.id = t.clientFk
|
||||||
JOIN account.user u ON u.id = c.id
|
JOIN account.user u ON u.id = c.id
|
||||||
WHERE t.id = ?`, [ticketFk]);
|
WHERE t.id = ?`, [ticketId]);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
'email-header': require('../email-header'),
|
'email-header': emailHeader.build(),
|
||||||
'email-footer': require('../email-footer'),
|
'email-footer': emailFooter.build()
|
||||||
},
|
},
|
||||||
|
props: ['ticketId', 'isPreview']
|
||||||
};
|
};
|
|
@ -1,11 +0,0 @@
|
||||||
module.exports = {
|
|
||||||
messages: {
|
|
||||||
es: {
|
|
||||||
subject: 'Aquí tienes tu albarán',
|
|
||||||
title: '¡Este es tu albarán!',
|
|
||||||
dearClient: 'Estimado cliente',
|
|
||||||
clientData: `A continuación adjuntamos tu albarán.`,
|
|
||||||
help: 'Cualquier duda que te surja, no dudes en consultarla, <strong>¡estamos para atenderte!</strong>'
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
subject: Aquí tienes tu albarán
|
||||||
|
title: "¡Este es tu albarán!"
|
||||||
|
dearClient: Estimado cliente
|
||||||
|
clientData: A continuación adjuntamos tu albarán.
|
||||||
|
help: Cualquier duda que te surja, no dudes en consultarla, <strong>¡estamos para
|
||||||
|
atenderte!</strong>
|
|
@ -1,4 +0,0 @@
|
||||||
const CssReader = require(`${appPath}/lib/cssReader`);
|
|
||||||
|
|
||||||
module.exports = new CssReader([`${__dirname}/style.css`])
|
|
||||||
.mergeStyles();
|
|
|
@ -1,34 +0,0 @@
|
||||||
module.exports = {
|
|
||||||
name: 'email-footer',
|
|
||||||
asyncData(ctx) {
|
|
||||||
return {
|
|
||||||
isPreview: ctx.method === 'GET',
|
|
||||||
};
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
if (this.locale)
|
|
||||||
this.$i18n.locale = this.locale;
|
|
||||||
|
|
||||||
const embeded = [];
|
|
||||||
this.files.map(file => {
|
|
||||||
const src = this.isPreview ? `/api/${file}` : `cid:${file}`;
|
|
||||||
embeded[file] = src;
|
|
||||||
});
|
|
||||||
this.embeded = embeded;
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
files: [
|
|
||||||
/* '/assets/images/action.png',
|
|
||||||
'/assets/images/info.png', */
|
|
||||||
'/assets/images/facebook.png',
|
|
||||||
'/assets/images/twitter.png',
|
|
||||||
'/assets/images/youtube.png',
|
|
||||||
'/assets/images/pinterest.png',
|
|
||||||
'/assets/images/instagram.png',
|
|
||||||
'/assets/images/linkedin.png',
|
|
||||||
],
|
|
||||||
};
|
|
||||||
},
|
|
||||||
props: ['locale']
|
|
||||||
};
|
|
|
@ -1,42 +0,0 @@
|
||||||
module.exports = {
|
|
||||||
messages: {
|
|
||||||
es: {
|
|
||||||
buttons: {
|
|
||||||
webAcccess: 'Visita nuestra Web',
|
|
||||||
info: 'Ayúdanos a mejorar',
|
|
||||||
},
|
|
||||||
privacy: {
|
|
||||||
fiscalAddress: 'VERDNATURA LEVANTE SL, B97367486 Avda. Espioca, 100, 46460 Silla · www.verdnatura.es · clientes@verdnatura.es',
|
|
||||||
disclaimer: `- AVISO - Este mensaje es privado y confidencial, y debe ser utilizado
|
|
||||||
exclusivamente por la persona destinataria del mismo. Si has recibido este mensaje
|
|
||||||
por error, te rogamos lo comuniques al remitente y borres dicho mensaje y cualquier documento
|
|
||||||
adjunto que pudiera contener. Verdnatura Levante SL no renuncia a la confidencialidad ni a
|
|
||||||
ningún privilegio por causa de transmisión errónea o mal funcionamiento. Igualmente no se hace
|
|
||||||
responsable 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 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 por
|
|
||||||
escrito al domicilio social de la entidad. La finalidad del fichero es la gestión administrativa, contabilidad, y facturación.`,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
/* fr: {
|
|
||||||
buttons: {
|
|
||||||
webAcccess: 'Visitez notre site web',
|
|
||||||
info: 'Ayúdanos a mejorar',
|
|
||||||
},
|
|
||||||
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 por la persona destinataria del mismo. Si has recibido este mensaje
|
|
||||||
por error, te rogamos lo comuniques al remitente y borres dicho mensaje y cualquier documento
|
|
||||||
adjunto que pudiera contener. Verdnatura Levante SL no renuncia a la confidencialidad ni a
|
|
||||||
ningún privilegio por causa de transmisión errónea o mal funcionamiento. Igualmente no se hace
|
|
||||||
responsable 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 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 por
|
|
||||||
escrito al domicilio social de la entidad. La finalidad del fichero es la gestión administrativa, contabilidad, y facturación.`,
|
|
||||||
},
|
|
||||||
}, */
|
|
||||||
},
|
|
||||||
};
|
|
|
@ -1,4 +0,0 @@
|
||||||
const CssReader = require(`${appPath}/lib/cssReader`);
|
|
||||||
|
|
||||||
module.exports = new CssReader([`${__dirname}/style.css`])
|
|
||||||
.mergeStyles();
|
|
|
@ -1,5 +0,0 @@
|
||||||
<header>
|
|
||||||
<a href="https://www.verdnatura.es" target="_blank"/>
|
|
||||||
<img :src="embeded['/assets/images/email-logo.png']" alt="VerdNatura"/>
|
|
||||||
</a>
|
|
||||||
</header>
|
|
|
@ -1,22 +0,0 @@
|
||||||
module.exports = {
|
|
||||||
name: 'email-header',
|
|
||||||
asyncData(ctx) {
|
|
||||||
return {
|
|
||||||
isPreview: ctx.method === 'GET',
|
|
||||||
};
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
const embeded = [];
|
|
||||||
this.files.map(file => {
|
|
||||||
const src = this.isPreview ? `/api/${file}` : `cid:${file}`;
|
|
||||||
embeded[file] = src;
|
|
||||||
});
|
|
||||||
this.embeded = embeded;
|
|
||||||
},
|
|
||||||
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
files: ['/assets/images/email-logo.png'],
|
|
||||||
};
|
|
||||||
},
|
|
||||||
};
|
|
|
@ -1,5 +0,0 @@
|
||||||
module.exports = {
|
|
||||||
messages: {
|
|
||||||
es: {},
|
|
||||||
},
|
|
||||||
};
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
/**
|
||||||
|
* 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
|
||||||
|
}
|
|
@ -1,7 +0,0 @@
|
||||||
const CssReader = require(`${appPath}/lib/cssReader`);
|
|
||||||
|
|
||||||
module.exports = new CssReader([
|
|
||||||
`${appPath}/common/css/layout.css`,
|
|
||||||
`${appPath}/common/css/email.css`,
|
|
||||||
`${appPath}/common/css/misc.css`])
|
|
||||||
.mergeStyles();
|
|
|
@ -0,0 +1,233 @@
|
||||||
|
/**
|
||||||
|
* 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
|
||||||
|
}
|
|
@ -0,0 +1,47 @@
|
||||||
|
/**
|
||||||
|
* 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;
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
[{
|
||||||
|
"filename": "model.ezp",
|
||||||
|
"path": "/assets/files/model.ezp",
|
||||||
|
"cid": "model.ezp"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "port.png",
|
||||||
|
"path": "/assets/files/port.png",
|
||||||
|
"cid": "port.png"
|
||||||
|
}]
|
|
@ -1,55 +0,0 @@
|
||||||
const database = require(`${appPath}/lib/database`);
|
|
||||||
const UserException = require(`${appPath}/lib/exceptions/userException`);
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
name: 'printer-setup',
|
|
||||||
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;
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
files: [
|
|
||||||
'/assets/files/model.ezp',
|
|
||||||
'/assets/files/port.png'
|
|
||||||
],
|
|
||||||
};
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
fetchClient(clientFk) {
|
|
||||||
return database.pool.query(`
|
|
||||||
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
|
|
||||||
FROM client c
|
|
||||||
JOIN account.user u ON u.id = c.id
|
|
||||||
LEFT JOIN worker w ON w.id = c.salesPersonFk
|
|
||||||
LEFT JOIN account.user wu ON wu.id = w.userFk
|
|
||||||
WHERE c.id = ?`, [clientFk]);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
components: {
|
|
||||||
'email-header': require('../email-header'),
|
|
||||||
'email-footer': require('../email-footer'),
|
|
||||||
},
|
|
||||||
};
|
|
|
@ -1,59 +0,0 @@
|
||||||
module.exports = {
|
|
||||||
messages: {
|
|
||||||
es: {
|
|
||||||
subject: 'Instalación y configuración de impresora',
|
|
||||||
title: '¡Gracias por tu confianza!',
|
|
||||||
description: {
|
|
||||||
dear: 'Estimado cliente',
|
|
||||||
instructions: 'Sigue las instrucciones especificadas en este correo para llevar a cabo la instalación de la impresora.',
|
|
||||||
followGuide: `Puedes utilizar como guía, el vídeo del montaje del ribon y la cinta
|
|
||||||
<a href="https://www.youtube.com/watch?v=qhb0kgQF3o8" title="Youtube" target="_blank" style="color:#8dba25">https://www.youtube.com/watch?v=qhb0kgQF3o8</a>.
|
|
||||||
También necesitarás el QLabel, el programa para imprimir las cintas.`,
|
|
||||||
downloadFrom: `Puedes descargarlo desde este enlace
|
|
||||||
<a href="https://godex.s3-accelerate.amazonaws.com/gGnOPoojkP6vC1lgmrbEqQ.file?v01" title="Descargar QLabel"
|
|
||||||
target="_blank" style="color:#8dba25">https://godex.s3-accelerate.amazonaws.com/gGnOPoojkP6vC1lgmrbEqQ.file?v01</a>`,
|
|
||||||
},
|
|
||||||
sections: {
|
|
||||||
QLabel: {
|
|
||||||
title: 'Utilización de QLabel',
|
|
||||||
description: 'Para utilizar el programa de impresión de cintas sigue estos pasos',
|
|
||||||
steps: [
|
|
||||||
'Abre el programa QLabel',
|
|
||||||
'Haz clic en el icono de la barra superior con forma de "carpeta"',
|
|
||||||
'Selecciona el archivo llamado "model.ezp" adjunto en este correo, y haz clic en abrir',
|
|
||||||
'Ve a "File" -> "Save as" y guárdalo en el escritorio con otro nombre',
|
|
||||||
'Cierra el Qlabel y abre el archivo que acabamos de guardar',
|
|
||||||
'Haz clic <strong>encima del texto</strong> con el botón secundario del ratón',
|
|
||||||
'Elige la primera opción "setup"',
|
|
||||||
'Cambia el texto para imprimir',
|
|
||||||
'Haz clic en el botón "Ok"',
|
|
||||||
'Desplázate con el ratón para ver la medida máxima que ocupa el texto',
|
|
||||||
'Haz clic <strong>encima del texto</strong> con el botón secundario del ratón',
|
|
||||||
'Elige la segunda opción "Setup printer"',
|
|
||||||
'Haz clic en la primera pestaña "Label Setup"',
|
|
||||||
'Modifica la propiedad "Paper Height" con la medida máxima consultada anteriormente',
|
|
||||||
`Comprueba el puerto de la impresora, botón de de la derecha
|
|
||||||
"SETUP PRINTER" y en la parte derecha, igual como la imagen
|
|
||||||
que adjuntamos, seleccionar la que ponga "USB00x: GODEX"`,
|
|
||||||
'Haz clic en el botón "Ok"',
|
|
||||||
'Haz clic sobre el icono de la impresora',
|
|
||||||
'Haz clic en "Print"',
|
|
||||||
],
|
|
||||||
},
|
|
||||||
help: {
|
|
||||||
title: '¿Necesitas ayuda?',
|
|
||||||
description: `Si necesitas ayuda, descárgate nuestro programa de soporte para poder conectarnos
|
|
||||||
remotamente a tu equipo y hacerte la instalación. Proporciónanos un horario de contacto para atenderte, y contactaremos contigo.`,
|
|
||||||
remoteSupport: `Puedes descargarte el programa desde este enlace
|
|
||||||
<a href="http://soporte.verdnatura.es" title="Soporte Verdnatura" target="_blank" style="color:#8dba25">http://soporte.verdnatura.es</a>.`,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
help: 'Cualquier duda que te surja, no dudes en consultarla, <strong>¡estamos para atenderte!</strong>',
|
|
||||||
salesPersonName: 'Soy tu comercial y mi nombre es',
|
|
||||||
salesPersonPhone: 'Teléfono y whatsapp',
|
|
||||||
salesPersonEmail: 'Dirección de e-mail',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,50 @@
|
||||||
|
subject: Instalación y configuración de impresora
|
||||||
|
title: "¡Gracias por tu confianza!"
|
||||||
|
description:
|
||||||
|
dear: Estimado cliente
|
||||||
|
instructions: Sigue las instrucciones especificadas en este correo para llevar a
|
||||||
|
cabo la instalación de la impresora.
|
||||||
|
followGuide: Puedes utilizar como guía, el vídeo del montaje del ribon y la cinta
|
||||||
|
<a href='https://www.youtube.com/watch?v=qhb0kgQF3o8' title='Youtube' target='_blank'
|
||||||
|
style='color:#8dba25'>https://www.youtube.com/watch?v=qhb0kgQF3o8</a>. También
|
||||||
|
necesitarás el QLabel, el programa para imprimir las cintas.
|
||||||
|
downloadFrom: Puedes descargarlo desde este enlace <a href='https://godex.s3-accelerate.amazonaws.com/gGnOPoojkP6vC1lgmrbEqQ.file?v01'
|
||||||
|
title='Descargar QLabel' target='_blank' style='color:#8dba25'>https://godex.s3-accelerate.amazonaws.com/gGnOPoojkP6vC1lgmrbEqQ.file?v01</a>
|
||||||
|
sections:
|
||||||
|
QLabel:
|
||||||
|
title: Utilización de QLabel
|
||||||
|
description: Para utilizar el programa de impresión de cintas sigue estos pasos
|
||||||
|
steps:
|
||||||
|
- Abre el programa QLabel
|
||||||
|
- Haz clic en el icono de la barra superior con forma de 'carpeta'
|
||||||
|
- Selecciona el archivo llamado 'model.ezp' adjunto en este correo, y haz clic
|
||||||
|
en abrir
|
||||||
|
- Ve a 'File' -> 'Save as' y guárdalo en el escritorio con otro nombre
|
||||||
|
- Cierra el Qlabel y abre el archivo que acabamos de guardar
|
||||||
|
- Haz clic <strong>encima del texto</strong> con el botón secundario del ratón
|
||||||
|
- Elige la primera opción 'setup'
|
||||||
|
- Cambia el texto para imprimir
|
||||||
|
- Haz clic en el botón 'Ok'
|
||||||
|
- Desplázate con el ratón para ver la medida máxima que ocupa el texto
|
||||||
|
- Haz clic <strong>encima del texto</strong> con el botón secundario del ratón
|
||||||
|
- Elige la segunda opción 'Setup printer'
|
||||||
|
- Haz clic en la primera pestaña 'Label Setup'
|
||||||
|
- Modifica la propiedad 'Paper Height' con la medida máxima consultada anteriormente
|
||||||
|
- 'Comprueba el puerto de la impresora, botón de de la derecha ''SETUP PRINTER''
|
||||||
|
y en la parte derecha, igual como la imagen que adjuntamos, seleccionar la que
|
||||||
|
ponga ''USB00x: GODEX'''
|
||||||
|
- Haz clic en el botón 'Ok'
|
||||||
|
- Haz clic sobre el icono de la impresora
|
||||||
|
- Haz clic en 'Print'
|
||||||
|
help:
|
||||||
|
title: "¿Necesitas ayuda?"
|
||||||
|
description: Si necesitas ayuda, descárgate nuestro programa de soporte para poder
|
||||||
|
conectarnos remotamente a tu equipo y hacerte la instalación. Proporciónanos
|
||||||
|
un horario de contacto para atenderte, y contactaremos contigo.
|
||||||
|
remoteSupport: Puedes descargarte el programa desde este enlace <a href='http://soporte.verdnatura.es'
|
||||||
|
title='Soporte Verdnatura' target='_blank' style='color:#8dba25'>http://soporte.verdnatura.es</a>.
|
||||||
|
help: Cualquier duda que te surja, no dudes en consultarla, <strong>¡estamos para
|
||||||
|
atenderte!</strong>
|
||||||
|
salesPersonName: Soy tu comercial y mi nombre es
|
||||||
|
salesPersonPhone: Teléfono y whatsapp
|
||||||
|
salesPersonEmail: Dirección de e-mail
|