updated reports
gitea/salix/1466-print_refactor There was a failure building this commit Details

This commit is contained in:
Joan Sanchez 2019-11-04 13:55:20 +01:00
parent d063bb4568
commit 14cb32d1c8
66 changed files with 595 additions and 1103 deletions

View File

@ -8,9 +8,13 @@
<form name="form" ng-submit="$ctrl.onSubmit()" compact>
<vn-card class="vn-pa-lg">
<vn-horizontal>
<vn-autocomplete
vn-one
vn-id="sampleType"
<vn-textfield vn-one
label="Recipient"
ng-model="$ctrl.clientSample.recipient">
</vn-textfield>
</vn-horizontal>
<vn-horizontal>
<vn-autocomplete vn-one vn-id="sampleType"
ng-model="$ctrl.clientSample.typeFk"
model="ClientSample.typeFk"
fields="['code','hasCompany']"
@ -19,8 +23,7 @@
value-field="id"
label="Sample">
</vn-autocomplete>
<vn-autocomplete
vn-one
<vn-autocomplete vn-one
ng-model="$ctrl.clientSample.companyFk"
model="ClientSample.companyFk"
url="/client/api/Companies"

View File

@ -2,18 +2,30 @@ import ngModule from '../../module';
import './style.scss';
class Controller {
constructor($scope, $state, $http, vnApp, $translate) {
constructor($scope, $state, $http, vnApp, $translate, $httpParamSerializer) {
this.$scope = $scope;
this.$state = $state;
this.$stateParams = $state.params;
this.$http = $http;
this.vnApp = vnApp;
this.$translate = $translate;
this.$httpParamSerializer = $httpParamSerializer;
this.clientSample = {
clientFk: this.$stateParams.id
};
}
get client() {
return this._client;
}
set client(value) {
this._client = value;
if (value)
this.clientSample.recipient = value.email;
}
jsonToQuery(json) {
let query = '';
for (let param in json) {
@ -27,7 +39,6 @@ class Controller {
showPreview() {
let sampleType = this.$scope.sampleType.selection;
let params = {clientFk: this.$stateParams.id};
if (!sampleType)
return this.vnApp.showError(this.$translate.instant('Choose a sample'));
@ -35,21 +46,26 @@ class Controller {
if (sampleType.hasCompany && !this.clientSample.companyFk)
return this.vnApp.showError(this.$translate.instant('Choose a company'));
const params = {
clientId: this.$stateParams.id,
recipient: this.clientSample.recipient,
isPreview: true
};
if (sampleType.hasCompany)
params.companyFk = this.clientSample.companyFk;
params.companyId = this.clientSample.companyFk;
let query = `/api/email/${sampleType.code}?${this.jsonToQuery(params)}`;
const serializedParams = this.$httpParamSerializer(params);
const query = `/api/email/${sampleType.code}?${serializedParams}`;
this.$http.get(query).then(res => {
if (res.data) {
let dialog = this.$scope.showPreview.element;
let body = dialog.querySelector('tpl-body');
let scroll = dialog.querySelector('div:first-child');
let dialog = this.$scope.showPreview.element;
let body = dialog.querySelector('tpl-body');
let scroll = dialog.querySelector('div:first-child');
body.innerHTML = res.data;
this.$scope.showPreview.show();
body.innerHTML = res.data;
this.$scope.showPreview.show();
scroll.scrollTop = 0;
}
scroll.scrollTop = 0;
});
}
@ -62,24 +78,34 @@ class Controller {
sendSample() {
let sampleType = this.$scope.sampleType.selection;
let params = {clientFk: this.$stateParams.id};
let params = {
clientId: this.$stateParams.id,
recipient: this.clientSample.recipient
};
if (!sampleType)
return this.vnApp.showError(this.$translate.instant('Choose a sample'));
if (sampleType.hasCompany && !this.clientSample.companyFk)
return this.vnApp.showError(this.$translate.instant('Choose a company'));
if (sampleType.hasCompany)
params.companyFk = this.clientSample.companyFk;
params.companyId = this.clientSample.companyFk;
let query = `/api/email/${sampleType.code}?${this.jsonToQuery(params)}`;
this.$http.post(query).then(res => {
if (res) {
this.vnApp.showSuccess(this.$translate.instant('Notification sent!'));
this.$state.go('client.card.sample.index');
}
const serializedParams = this.$httpParamSerializer(params);
const query = `/api/email/${sampleType.code}?${serializedParams}`;
this.$http.get(query).then(res => {
this.vnApp.showSuccess(this.$translate.instant('Notification sent!'));
this.$state.go('client.card.sample.index');
});
}
}
Controller.$inject = ['$scope', '$state', '$http', 'vnApp', '$translate'];
Controller.$inject = ['$scope', '$state', '$http', 'vnApp', '$translate', '$httpParamSerializer'];
ngModule.component('vnClientSampleCreate', {
template: require('./index.html'),
controller: Controller
controller: Controller,
bindings: {
client: '<'
}
});

View File

@ -1,12 +1,15 @@
<!DOCTYPE html>
<html lang="es">
<html v-bind:lang="locale">
<head>
<title>{{ $t('subject') }}</title>
</head>
<body>
<section class="container">
<!-- Header component -->
<email-header :is-preview="isPreview" :locale="locale"></email-header>
<email-header
v-bind:is-preview="isPreview"
v-bind:locale="locale">
</email-header>
<!-- End header component -->
<section class="main">
<!-- Title block -->
@ -26,7 +29,10 @@
</section>
</section>
<!-- Footer component -->
<email-footer :is-preview="isPreview" :locale="locale"></email-footer>
<email-footer
v-bind:is-preview="isPreview"
v-bind:locale="locale">
</email-footer>
<!-- End footer component -->
</section>
</body>

View File

@ -1,29 +1,16 @@
const Component = require(`${appPath}/core/component`);
const emailHeader = new Component('email-header');
const emailFooter = new Component('email-footer');
const db = require(`${appPath}/core/database`);
module.exports = {
name: 'delivery-note',
methods: {
fetchTicket(ticketId) {
return db.findOne(`
SELECT
t.id,
u.lang locale,
c.email recipient
FROM ticket t
JOIN client c ON c.id = t.clientFk
JOIN account.user u ON u.id = c.id
WHERE t.id = ?`, [ticketId]);
},
},
components: {
'email-header': emailHeader.build(),
'email-footer': emailFooter.build()
},
props: {
ticketId: {
type: String,
required: true
}
}

View File

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

View File

@ -1,12 +1,15 @@
<!DOCTYPE html>
<html lang="es">
<html v-bind:lang="locale">
<head>
<title>{{ $t('subject') }}</title>
</head>
<body>
<section class="container">
<!-- Header component -->
<email-header></email-header>
<email-header
v-bind:is-preview="isPreview"
v-bind:locale="locale">
</email-header>
<!-- End header component -->
<section class="main">
<!-- Title block -->
@ -17,7 +20,10 @@
<p>{{$t('description.instructions')}}</p>
</section>
<!-- Footer component -->
<email-footer :locale="locale"></email-footer>
<email-footer
v-bind:is-preview="isPreview"
v-bind:locale="locale">
</email-footer>
<!-- End footer component -->
</section>
</body>

View File

@ -0,0 +1,17 @@
const Component = require(`${appPath}/core/component`);
const emailHeader = new Component('email-header');
const emailFooter = new Component('email-footer');
module.exports = {
name: 'driver-route',
components: {
'email-header': emailHeader.build(),
'email-footer': emailFooter.build()
},
props: {
routeId: {
type: String,
required: true
}
}
};

View File

@ -1,54 +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: 'driver-route',
async asyncData(ctx, params) {
const promises = [];
const data = {
isPreview: ctx.method === 'GET',
};
if (!params.routeFk)
throw new UserException('No route id specified');
promises.push(reportEngine.toPdf('rpt-route', ctx));
promises.push(this.methods.fetchRoute(params.routeFk));
return Promise.all(promises).then(result => {
const stream = result[0];
const [[route]] = result[1];
Object.assign(data, route);
Object.assign(data, {attachments: [{filename: 'driver-route.pdf', content: stream}]});
return data;
});
},
created() {
if (this.locale)
this.$i18n.locale = this.locale;
},
methods: {
fetchRoute(routeFk) {
return database.pool.query(`
SELECT
u.id,
u.lang AS locale,
mu.email AS recipient
FROM route r
LEFT JOIN worker w ON w.id = r.workerFk
LEFT JOIN account.user u ON u.id = w.userFk
LEFT JOIN account.emailUser mu ON mu.userFk = u.id
WHERE r.id = ?`, [routeFk]);
},
},
components: {
emailHeader,
emailFooter,
},
};

View File

@ -1,11 +0,0 @@
module.exports = {
messages: {
es: {
subject: 'Hoja de ruta',
title: 'Hoja de ruta',
description: {
instructions: 'Adjuntamos tu hoja de ruta.'
},
},
},
};

View File

@ -0,0 +1,4 @@
subject: Hoja de ruta
title: Hoja de ruta
description:
instructions: Adjuntamos tu hoja de ruta.

View File

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

View File

@ -0,0 +1 @@
[{"filename": "letter-debtor.pdf"}]

View File

@ -1,58 +0,0 @@
const database = require(`${appPath}/lib/database`);
const reportEngine = require(`${appPath}/lib/reportEngine.js`);
const UserException = require(`${appPath}/lib/exceptions/userException`);
module.exports = {
name: 'letter-debtor-nd',
async asyncData(ctx, params) {
const promises = [];
const data = {
isPreview: ctx.method === 'GET',
};
if (!params.clientFk)
throw new UserException('No client id specified');
if (!params.companyFk)
throw new UserException('No company id specified');
promises.push(reportEngine.toPdf('rpt-letter-debtor', ctx));
promises.push(this.methods.fetchClient(params.clientFk, params.companyFk));
return Promise.all(promises).then(result => {
const stream = result[0];
const [[client]] = result[1];
Object.assign(data, client);
Object.assign(data, {attachments: [{filename: 'rpt-letter-debtor.pdf', content: stream}]});
return data;
});
},
created() {
if (this.locale)
this.$i18n.locale = this.locale;
},
methods: {
fetchClient(clientFk, companyFk) {
return database.pool.query(`
SELECT
u.lang locale,
c.email recipient,
c.dueDay,
c.iban,
sa.iban,
be.name AS bankName
FROM client c
JOIN company AS cny
JOIN supplierAccount AS sa ON sa.id = cny.supplierAccountFk
JOIN bankEntity be ON be.id = sa.bankEntityFk
JOIN account.user u ON u.id = c.id
WHERE c.id = ? AND cny.id = ?`, [clientFk, companyFk]);
},
},
components: {
'email-header': require('../email-header'),
'email-footer': require('../email-footer'),
},
};

View File

@ -1,12 +1,15 @@
<!DOCTYPE html>
<html lang="es">
<html v-bind:lang="locale">
<head>
<title>{{ $t('subject') }}</title>
</head>
<body>
<section class="container">
<!-- Header component -->
<email-header></email-header>
<email-header
v-bind:is-preview="isPreview"
v-bind:locale="locale">
</email-header>
<!-- End header component -->
<section class="main">
<!-- Title block -->
@ -42,16 +45,23 @@
<p>
<div class="row">
<div class="text">{{bankName}}</div>
<div class="control">{{iban}}</div>
<div class="text">{{debtor.bankName}}</div>
<div class="control">{{debtor.iban}}</div>
<div class="description">
<div class="line"><span>{{$t('transferAccount') }}</span></div>
</div>
</div>
</p>
<section>
<a href="/api/report/letter-debtor?clientId=101&companyId=442" target="_blank">Ver PDF</a>
</section>
</section>
<!-- Footer component -->
<email-footer :locale="locale"></email-footer>
<email-footer
v-bind:is-preview="isPreview"
v-bind:locale="locale">
</email-footer>
<!-- End footer component -->
</section>
</body>

View File

@ -0,0 +1,41 @@
const Component = require(`${appPath}/core/component`);
const emailHeader = new Component('email-header');
const emailFooter = new Component('email-footer');
const db = require(`${appPath}/core/database`);
module.exports = {
name: 'letter-debtor-nd',
async serverPrefetch() {
this.debtor = await this.fetchDebtor(this.clientId, this.companyId);
if (!this.debtor)
throw new Error('Something went wrong');
},
methods: {
fetchDebtor(clientId, companyId) {
return db.findOne(`
SELECT
c.dueDay,
c.iban,
sa.iban,
be.name AS bankName
FROM client c
JOIN company AS cny
JOIN supplierAccount AS sa ON sa.id = cny.supplierAccountFk
JOIN bankEntity be ON be.id = sa.bankEntityFk
WHERE c.id = ? AND cny.id = ?`, [clientId, companyId]);
}
},
components: {
'email-header': emailHeader.build(),
'email-footer': emailFooter.build()
},
props: {
clientId: {
required: true
},
companyId: {
required: true
}
}
};

View File

@ -1,35 +0,0 @@
module.exports = {
messages: {
es: {
subject: 'Reiteración de aviso por saldo deudor',
title: 'Aviso reiterado',
sections: {
introduction: {
title: 'Estimado cliente',
description: `Nos dirigimos a ti nuevamente para informarte que sigue
pendiente tu deuda con nuestra empresa, tal y como puedes comprobar en el extracto adjunto.`,
terms: `Dado que los plazos de pago acordados están ampliamente superados, no procede mayor dilación en la liquidación del importe adeudado.`,
},
payMethod: {
description: 'Para ello dispones de las siguientes formas de pago',
options: [
'Pago online desde nuestra web.',
'Ingreso o transferencia al número de cuenta que detallamos al pie de esta carta, indicando el número de cliente.',
],
},
legalAction: {
description: `En caso de no ser atendido este apremio de pago, nos veremos obligados
a iniciar las acciones legales que procedan, entre las que están`,
options: [
'Inclusión en ficheros negativos sobre solvencia patrimonial y crédito.',
'Reclamación judicial.',
'Cesión de deuda a una empresa de gestión de cobro.',
],
},
},
contactPhone: 'Para consultas, puedes ponerte en contacto con nosotros en el <strong>96 324 21 00</strong>.',
conclusion: 'En espera de tus noticias. <br/> Gracias por tu atención.',
transferAccount: 'Datos para transferencia bancaria',
},
},
};

View File

@ -0,0 +1,26 @@
subject: Reiteración de aviso por saldo deudor
title: Aviso reiterado
sections:
introduction:
title: Estimado cliente
description: Nos dirigimos a ti nuevamente para informarte que sigue pendiente
tu deuda con nuestra empresa, tal y como puedes comprobar en el extracto adjunto.
terms: Dado que los plazos de pago acordados están ampliamente superados, no procede
mayor dilación en la liquidación del importe adeudado.
payMethod:
description: Para ello dispones de las siguientes formas de pago
options:
- Pago online desde nuestra web.
- Ingreso o transferencia al número de cuenta que detallamos al pie de esta carta,
indicando el número de cliente.
legalAction:
description: En caso de no ser atendido este apremio de pago, nos veremos obligados
a iniciar las acciones legales que procedan, entre las que están
options:
- Inclusión en ficheros negativos sobre solvencia patrimonial y crédito.
- Reclamación judicial.
- Cesión de deuda a una empresa de gestión de cobro.
contactPhone: Para consultas, puedes ponerte en contacto con nosotros en el <strong>96
324 21 00</strong>.
conclusion: En espera de tus noticias. <br/> Gracias por tu atención.
transferAccount: Datos para transferencia bancaria

View File

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

View File

@ -0,0 +1 @@
[{"filename": "letter-debtor.pdf"}]

View File

@ -1,59 +0,0 @@
const database = require(`${appPath}/lib/database`);
const reportEngine = require(`${appPath}/lib/reportEngine.js`);
const UserException = require(`${appPath}/lib/exceptions/userException`);
module.exports = {
name: 'letter-debtor-st',
async asyncData(ctx, params) {
const promises = [];
const data = {
isPreview: ctx.method === 'GET',
};
if (!params.clientFk)
throw new UserException('No client id specified');
if (!params.companyFk)
throw new UserException('No company id specified');
promises.push(reportEngine.toPdf('rpt-letter-debtor', ctx));
promises.push(this.methods.fetchClient(params.clientFk, params.companyFk));
return Promise.all(promises).then(result => {
const stream = result[0];
const [[client]] = result[1];
Object.assign(data, client);
Object.assign(data, {attachments: [{filename: 'rpt-letter-debtor.pdf', content: stream}]});
return data;
});
},
created() {
if (this.locale)
this.$i18n.locale = this.locale;
},
methods: {
fetchClient(clientFk, companyFk) {
return database.pool.query(`
SELECT
u.lang locale,
c.email recipient,
c.dueDay,
c.iban,
sa.iban,
be.name AS bankName
FROM client c
JOIN company AS cny
JOIN supplierAccount AS sa ON sa.id = cny.supplierAccountFk
JOIN bankEntity be ON be.id = sa.bankEntityFk
JOIN account.user u ON u.id = c.id
WHERE c.id = ? AND cny.id = ?`, [clientFk, companyFk]);
}
},
components: {
'email-header': require('../email-header'),
'email-footer': require('../email-footer'),
},
};

View File

@ -1,12 +1,15 @@
<!DOCTYPE html>
<html lang="es">
<html v-bind:lang="locale">
<head>
<title>{{ $t('subject') }}</title>
</head>
<body>
<section class="container">
<!-- Header component -->
<email-header></email-header>
<email-header
v-bind:is-preview="isPreview"
v-bind:locale="locale">
</email-header>
<!-- End header component -->
<section class="main">
<!-- Title block -->
@ -25,8 +28,8 @@
<p>
<div class="row">
<div class="text">{{bankName}}</div>
<div class="control">{{iban}}</div>
<div class="text">{{debtor.bankName}}</div>
<div class="control">{{debtor.iban}}</div>
<div class="description">
<div class="line"><span>{{$t('transferAccount') }}</span></div>
</div>
@ -34,7 +37,10 @@
</p>
</section>
<!-- Footer component -->
<email-footer :locale="locale"></email-footer>
<email-footer
v-bind:is-preview="isPreview"
v-bind:locale="locale">
</email-footer>
<!-- End footer component -->
</section>
</body>

View File

@ -0,0 +1,41 @@
const Component = require(`${appPath}/core/component`);
const emailHeader = new Component('email-header');
const emailFooter = new Component('email-footer');
const db = require(`${appPath}/core/database`);
module.exports = {
name: 'letter-debtor-st',
async serverPrefetch() {
this.debtor = await this.fetchDebtor(this.clientId, this.companyId);
if (!this.debtor)
throw new Error('Something went wrong');
},
methods: {
fetchDebtor(clientId, companyId) {
return db.findOne(`
SELECT
c.dueDay,
c.iban,
sa.iban,
be.name AS bankName
FROM client c
JOIN company AS cny
JOIN supplierAccount AS sa ON sa.id = cny.supplierAccountFk
JOIN bankEntity be ON be.id = sa.bankEntityFk
WHERE c.id = ? AND cny.id = ?`, [clientId, companyId]);
}
},
components: {
'email-header': emailHeader.build(),
'email-footer': emailFooter.build()
},
props: {
clientId: {
required: true
},
companyId: {
required: true
}
}
};

View File

@ -1,27 +0,0 @@
module.exports = {
messages: {
es: {
subject: 'Aviso inicial por saldo deudor',
title: 'Aviso inicial',
sections: {
introduction: {
title: 'Estimado cliente',
description: `Por el presente escrito te comunicamos que, según nuestros
datos contables, tu cuenta tiene un saldo pendiente de liquidar.`,
},
},
checkExtract: `Te solicitamos compruebes que el extracto adjunto corresponde con los datos de que dispones.
Nuestro departamento de administración te aclarará gustosamente cualquier duda que puedas tener,
e igualmente te facilitará cualquier documento que solicites.`,
checkValidData: `Si al comprobar los datos aportados resultaran correctos,
te rogamos procedas a regularizar tu situación.`,
payMethod: `Si no deseas desplazarte personalmente hasta nuestras oficinas,
puedes realizar el pago mediante transferencia bancaria a la cuenta que figura al pie del comunicado,
indicando tu número de cliente, o bien puedes realizar el pago online desde nuestra página web.`,
conclusion: 'De antemano te agradecemos tu amable colaboración.',
transferAccount: 'Datos para transferencia bancaria',
},
},
};

View File

@ -0,0 +1,19 @@
subject: Aviso inicial por saldo deudor
title: Aviso inicial
sections:
introduction:
title: Estimado cliente
description: Por el presente escrito te comunicamos que, según nuestros datos
contables, tu cuenta tiene un saldo pendiente de liquidar.
checkExtract: Te solicitamos compruebes que el extracto adjunto corresponde con los
datos de que dispones. Nuestro departamento de administración te aclarará gustosamente
cualquier duda que puedas tener, e igualmente te facilitará cualquier documento
que solicites.
checkValidData: Si al comprobar los datos aportados resultaran correctos, te rogamos
procedas a regularizar tu situación.
payMethod: Si no deseas desplazarte personalmente hasta nuestras oficinas, puedes
realizar el pago mediante transferencia bancaria a la cuenta que figura al pie del
comunicado, indicando tu número de cliente, o bien puedes realizar el pago online
desde nuestra página web.
conclusion: De antemano te agradecemos tu amable colaboración.
transferAccount: Datos para transferencia bancaria

View File

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

View File

@ -1,52 +0,0 @@
const database = require(`${appPath}/lib/database`);
const emailHeader = require('../email-header');
const emailFooter = require('../email-footer');
const UserException = require(`${appPath}/lib/exceptions/userException`);
module.exports = {
name: 'payment-update',
async asyncData(ctx, params) {
const data = {
isPreview: ctx.method === 'GET',
};
if (!params.clientFk)
throw new UserException('No client id specified');
return this.methods.fetchClient(params.clientFk)
.then(([result]) => {
if (!result)
throw new UserException('No client data found');
return Object.assign(data, result[0]);
});
},
created() {
if (this.locale)
this.$i18n.locale = this.locale;
},
methods: {
fetchClient(clientFk) {
return database.pool.query(`
SELECT
u.lang locale,
c.email recipient,
c.dueDay,
c.iban,
pm.id payMethodFk,
pm.name payMethodName
FROM client c
JOIN payMethod pm ON pm.id = c.payMethodFk
JOIN account.user u ON u.id = c.id
WHERE c.id = ?`, [clientFk]);
},
},
computed: {
accountAddress: function() {
return this.iban.slice(-4);
},
},
components: {
'email-header': emailHeader,
'email-footer': emailFooter,
},
};

View File

@ -1,49 +0,0 @@
module.exports = {
messages: {
es: {
subject: 'Cambios en las condiciones de pago',
title: 'Cambios en las condiciones',
sections: {
introduction: {
title: 'Estimado cliente',
description: `Te informamos que han cambiado las condiciones de pago de tu cuenta.
<br/>A continuación te indicamos las nuevas condiciones`,
},
pay: {
method: 'Método de pago',
day: 'Día de pago',
dueDay: '{0} de cada mes',
cardImplicates: `Tu modo de pago actual implica que deberás abonar el
importe de los pedidos realizados en el mismo día para que se puedan enviar.`,
accountImplicates: `Tu modo de pago actual implica que se te pasará un cargo a la
cuenta terminada en <strong>"{0}"</strong> por el importe pendiente, al vencimiento establecido en las condiciones.`,
},
},
notifyAnError: `En el caso de detectar algún error en los datos indicados
o para cualquier aclaración, debes dirigirte a tu comercial.`,
},
fr: {
subject: 'Changement des C.G.V',
title: 'Changement des C.G.V',
sections: {
introduction: {
title: 'Chèr client',
description: `Nous vous informons que les conditions de paiement ont changé.
<br/>Voici les nouvelles conditions`,
},
pay: {
method: 'Méthode de paiement',
day: 'Date paiement',
dueDay: '{0} de chaque mois',
cardImplicates: `Avec votre mode de règlement vous devrez
payer le montant des commandes avant son départ.`,
accountImplicates: `Avec ce mode de règlement nous vous passerons un prélèvement automatique dans votre compte bancaire
se termine dans <strong>"{0}"</strong> our le montant dû, au date à terme établi en nos conditions.`,
},
},
notifyAnError: `Pour tout renseignement contactez votre commercial.`,
},
},
};

View File

@ -0,0 +1,18 @@
subject: Cambios en las condiciones de pago
title: Cambios en las condiciones
sections:
introduction:
title: Estimado cliente
description: Te informamos que han cambiado las condiciones de pago de tu cuenta.
<br/>A continuación te indicamos las nuevas condiciones
pay:
method: Método de pago
day: Día de pago
dueDay: "{0} de cada mes"
cardImplicates: Tu modo de pago actual implica que deberás abonar el importe de
los pedidos realizados en el mismo día para que se puedan enviar.
accountImplicates: Tu modo de pago actual implica que se te pasará un cargo a
la cuenta terminada en <strong>'{0}'</strong> por el importe pendiente, al vencimiento
establecido en las condiciones.
notifyAnError: En el caso de detectar algún error en los datos indicados o para cualquier
aclaración, debes dirigirte a tu comercial.

View File

@ -0,0 +1,17 @@
subject: Changement des C.G.V
title: Changement des C.G.V
sections:
introduction:
title: Chèr client
description: Nous vous informons que les conditions de paiement ont changé. <br/>Voici
les nouvelles conditions
pay:
method: Méthode de paiement
day: Date paiement
dueDay: "{0} de chaque mois"
cardImplicates: Avec votre mode de règlement vous devrez payer le montant des
commandes avant son départ.
accountImplicates: Avec ce mode de règlement nous vous passerons un prélèvement
automatique dans votre compte bancaire se termine dans <strong>'{0}'</strong>
our le montant dû, au date à terme établi en nos conditions.
notifyAnError: Pour tout renseignement contactez votre commercial.

View File

@ -1,12 +1,15 @@
<!DOCTYPE html>
<html lang="es">
<html v-bind:lang="locale">
<head>
<title>{{ $t('subject') }}</title>
</head>
<body>
<section class="container">
<!-- Header component -->
<email-header></email-header>
<email-header
v-bind:is-preview="isPreview"
v-bind:locale="locale">
</email-header>
<!-- End header component -->
<section class="main">
<!-- Title block -->
@ -21,23 +24,26 @@
<p>
<section>
<span>{{ $t('sections.pay.method') }}:</span>
<strong>{{ payMethodName }}</strong>
<strong>{{client.payMethodName}}</strong>
</section>
<section v-if="payMethodFk != 5">
<section v-if="client.payMethodId != 5">
<span>{{ $t('sections.pay.day') }}:</span>
<strong>{{ $t('sections.pay.dueDay', [dueDay]) }}</strong>
<strong>{{ $t('sections.pay.dueDay', [client.dueDay]) }}</strong>
</section>
</p>
<p v-if="payMethodFk == 4" v-html="$t('sections.pay.accountImplicates', [accountAddress])"></p>
<p v-else-if="payMethodFk == 5">
<p v-if="client.payMethodId == 4" v-html="$t('sections.pay.accountImplicates', [client.accountAddress])"></p>
<p v-else-if="client.payMethodId == 5">
{{ $t('sections.pay.cardImplicates') }}
</p>
<p>{{ $t('notifyAnError') }}</p>
</section>
<!-- Footer component -->
<email-footer :locale="locale"></email-footer>
<email-footer
v-bind:is-preview="isPreview"
v-bind:locale="locale">
</email-footer>
<!-- End footer component -->
</section>
</body>

View File

@ -0,0 +1,43 @@
const Component = require(`${appPath}/core/component`);
const emailHeader = new Component('email-header');
const emailFooter = new Component('email-footer');
const db = require(`${appPath}/core/database`);
module.exports = {
name: 'payment-update',
async serverPrefetch() {
this.client = await this.fetchClient(this.clientId);
if (!this.client)
throw new Error('Something went wrong');
},
computed: {
accountAddress: function() {
return this.iban.slice(-4);
},
},
methods: {
// Redmine #1854 Replace payMethodId by code
fetchClient(id) {
return db.findOne(
`SELECT
c.dueDay,
c.iban,
pm.id payMethodId,
pm.name payMethodName
FROM client c
JOIN payMethod pm ON pm.id = c.payMethodFk
JOIN account.user u ON u.id = c.id
WHERE c.id = :clientId`, {clientId: id});
}
},
components: {
'email-header': emailHeader.build(),
'email-footer': emailFooter.build()
},
props: {
clientId: {
required: true
}
}
};

View File

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

View File

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

View File

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

View File

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

View File

@ -1,12 +1,15 @@
<!DOCTYPE html>
<html lang="es">
<html v-bind:lang="locale">
<head>
<title>{{ $t('subject') }}</title>
</head>
<body>
<section class="container">
<!-- Header component -->
<email-header :is-preview="isPreview"></email-header>
<email-header
v-bind:is-preview="isPreview"
v-bind:locale="locale">
</email-header>
<!-- End header component -->
<section class="main">
<!-- Title block -->
@ -48,7 +51,10 @@
</p>
</section>
<!-- Footer component -->
<email-footer :is-preview="isPreview" :locale="client.locale"></email-footer>
<email-footer
v-bind:is-preview="isPreview"
v-bind:locale="locale">
</email-footer>
<!-- End footer component -->
</section>
</body>

View File

@ -1,5 +1,5 @@
const db = require(`${appPath}/lib/database`);
const Component = require(`${appPath}/lib/component`);
const db = require(`${appPath}/core/database`);
const Component = require(`${appPath}/core/component`);
const emailHeader = new Component('email-header');
const emailFooter = new Component('email-footer');
@ -8,10 +8,6 @@ module.exports = {
async serverPrefetch() {
this.client = await this.fetchClient(this.clientId);
},
created() {
/* if (this.locale)
this.$i18n.locale = this.locale; */
},
methods: {
fetchClient(clientId) {
return db.findOne(`
@ -34,5 +30,9 @@ module.exports = {
'email-header': emailHeader.build(),
'email-footer': emailFooter.build()
},
props: ['clientId', 'isPreview']
props: {
clientId: {
required: true
}
}
};

View File

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

View File

@ -1,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();

View File

@ -0,0 +1,3 @@
[{
"filename": "sepa-core.pdf"
}]

View File

@ -1,49 +0,0 @@
const database = require(`${appPath}/lib/database`);
const reportEngine = require(`${appPath}/lib/reportEngine.js`);
const UserException = require(`${appPath}/lib/exceptions/userException`);
module.exports = {
name: 'sepa-core',
async asyncData(ctx, params) {
const promises = [];
const data = {
isPreview: ctx.method === 'GET',
};
if (!params.clientFk)
throw new UserException('No client id specified');
promises.push(reportEngine.toPdf('rpt-sepa-core', ctx));
promises.push(this.methods.fetchClient(params.clientFk));
return Promise.all(promises).then(result => {
const stream = result[0];
const [[client]] = result[1];
Object.assign(data, client);
Object.assign(data, {attachments: [{filename: 'rpt-sepa-core.pdf', content: stream}]});
return data;
});
},
created() {
if (this.locale)
this.$i18n.locale = this.locale;
},
methods: {
fetchClient(clientFk) {
return database.pool.query(`
SELECT
u.lang locale,
c.email recipient
FROM client c
JOIN account.user u ON u.id = c.id
WHERE c.id = ?`, [clientFk]);
},
},
components: {
'email-header': require('../email-header'),
'email-footer': require('../email-footer'),
},
};

View File

@ -1,24 +0,0 @@
module.exports = {
messages: {
es: {
subject: 'Solicitud de domiciliación bancaria',
title: 'Domiciliación SEPA CORE',
description: {
dear: 'Estimado cliente',
instructions: `Para poder tramitar tu solicitud de cambio de tu forma de pago a giro bancario,
te adjuntamos los documentos correspondientes a la ley de pago, que tienes que cumplimentar y enviarnos.`,
conclusion: 'Gracias por tu atención.'
},
},
pt: {
subject: 'Autorização de débito directo SEPA CORE',
title: 'Débito directo SEPA CORE',
description: {
dear: 'Prezado Cliente',
instructions: `Para poder tramitar vossa solicitação de forma de pagamento a Débito Automático, anexamos os
documentos correspondentes à Lei de Pagamentos, que deves preencher e reenviar-nos.`,
conclusion: 'Obrigado pela atenção.'
},
}
},
};

View File

@ -0,0 +1,8 @@
subject: Solicitud de domiciliación bancaria
title: Domiciliación SEPA CORE
description:
dear: Estimado cliente
instructions: Para poder tramitar tu solicitud de cambio de tu forma de pago a giro
bancario, te adjuntamos los documentos correspondientes a la ley de pago, que
tienes que cumplimentar y enviarnos.
conclusion: Gracias por tu atención.

View File

@ -0,0 +1,8 @@
subject: Autorização de débito directo SEPA CORE
title: Débito directo SEPA CORE
description:
dear: Prezado Cliente
instructions: Para poder tramitar vossa solicitação de forma de pagamento a Débito
Automático, anexamos os documentos correspondentes à Lei de Pagamentos, que deves
preencher e reenviar-nos.
conclusion: Obrigado pela atenção.

View File

@ -1,12 +1,15 @@
<!DOCTYPE html>
<html lang="es">
<html v-bind:lang="locale">
<head>
<title>{{ $t('subject') }}</title>
</head>
<body>
<section class="container">
<!-- Header component -->
<email-header></email-header>
<email-header
v-bind:is-preview="isPreview"
v-bind:locale="locale">
</email-header>
<!-- End header component -->
<section class="main">
<!-- Title block -->
@ -20,7 +23,10 @@
<p>{{$t('description.conclusion')}}</p>
</section>
<!-- Footer component -->
<email-footer :locale="locale"></email-footer>
<email-footer
v-bind:is-preview="isPreview"
v-bind:locale="locale">
</email-footer>
<!-- End footer component -->
</section>
</body>

View File

@ -0,0 +1,11 @@
const Component = require(`${appPath}/core/component`);
const emailHeader = new Component('email-header');
const emailFooter = new Component('email-footer');
module.exports = {
name: 'sepa-core',
components: {
'email-header': emailHeader.build(),
'email-footer': emailFooter.build()
}
};

View File

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

View File

@ -0,0 +1,24 @@
title: Hoja de ruta
information: Información
date: Fecha
time: Hora
volume: Cubicaje
driver: Conductor
vehicle: Vehículo
agency: Agencia
order: Orden
client: Cliente
address: Consignatario
packages: Bultos
street: Dirección
postcode: Código Postal
city: Ciudad
mobile: Móvil
phone: Teléfono
warehouse: Almacén
salesPerson: Comercial
import: Importe
stowaway: Encajado dentro del ticket
route: Ruta
routeId: Ruta {0}
ticket: Tiquet

View File

@ -1,40 +1,43 @@
<!DOCTYPE html>
<html lang="es">
<html v-bind:lang="locale">
<body>
<section class="container" id="report">
<!-- Header component -->
<report-header :locale="route.locale"></report-header>
<report-header
v-bind:is-preview="isPreview"
v-bind:locale="locale">
</report-header>
<!-- End header component -->
<section class="main">
<h1 class="title uppercase">{{$t('Title')}}</h1>
<h1 class="title uppercase">{{$t('title')}}</h1>
<section class="panel">
<section class="header">{{$t('Information')}}</section>
<section class="header">{{$t('information')}}</section>
<section class="body">
<section>
<table width="100%">
<tbody>
<tr>
<th class="font gray align-right">{{$t('Route')}}</th>
<th class="font gray align-right">{{$t('route')}}</th>
<td>{{route.id}}</td>
<th class="font gray align-right">{{$t('Driver')}}</th>
<th class="font gray align-right">{{$t('driver')}}</th>
<td>{{route.userNickName}}</td>
</tr>
<tr>
<th class="font gray align-right">{{$t('Date')}}</th>
<td>{{date(route.created)}}</td>
<th class="font gray align-right">{{$t('Vehicle')}}</th>
<th class="font gray align-right">{{$t('date')}}</th>
<td>{{route.created | date('%d-%m-%Y')}}</td>
<th class="font gray align-right">{{$t('vehicle')}}</th>
<td>{{route.vehicleTradeMark}} {{route.vehicleModel}}</td>
</tr>
<tr>
<th class="font gray align-right">{{$t('Time')}}</th>
<td>{{time(route.time)}}</td>
<th class="font gray align-right">{{$t('time')}}</th>
<td>{{route.time | date('%H:%M')}}</td>
<td></td>
<td>{{route.plateNumber}}</td>
</tr>
<tr>
<th class="font gray align-right">{{$t('Volume')}}</th>
<th class="font gray align-right">{{$t('volume')}}</th>
<td>{{route.m3}}</td>
<th class="font gray align-right">{{$t('Agency')}}</th>
<th class="font gray align-right">{{$t('agency')}}</th>
<td>{{route.agencyName}}</td>
</tr>
</tbody>
@ -81,11 +84,11 @@
<table class="column-oriented repeatable">
<thead>
<tr>
<td class="number">{{$t('Order')}}</td>
<td class="number">{{$t('Ticket')}}</td>
<td>{{$t('Client')}}</td>
<td class="number">{{$t('Address')}}</td>
<td class="number">{{$t('Packages')}}</td>
<td class="number">{{$t('order')}}</td>
<td class="number">{{$t('ticket')}}</td>
<td>{{$t('client')}}</td>
<td class="number">{{$t('address')}}</td>
<td class="number">{{$t('packages')}}</td>
</tr>
</thead>
<tbody>
@ -108,31 +111,31 @@
<table width="100%">
<tbody>
<tr>
<th class="font gray align-right">{{$t('Street')}}</th>
<th class="font gray align-right">{{$t('street')}}</th>
<td>{{ticket.street}}</td>
<th class="font gray align-right">{{$t('Postcode')}}</th>
<th class="font gray align-right">{{$t('postcode')}}</th>
<td>{{ticket.postalCode}}</td>
</tr>
<tr>
<th class="font gray align-right">{{$t('City')}}</th>
<th class="font gray align-right">{{$t('city')}}</th>
<td>{{ticket.city}}</td>
<th class="font gray align-right">{{$t('Agency')}}</th>
<th class="font gray align-right">{{$t('agency')}}</th>
<td>{{ticket.ticketAgency}}</td>
</tr>
<tr>
<th class="font gray align-right">{{$t('Mobile')}}</th>
<th class="font gray align-right">{{$t('mobile')}}</th>
<td>{{ticket.mobile}}</td>
<th class="font gray align-right">{{$t('Phone')}}</th>
<th class="font gray align-right">{{$t('phone')}}</th>
<td>{{ticket.phone}}</td>
</tr>
<tr>
<th class="font gray align-right">{{$t('Warehouse')}}</th>
<th class="font gray align-right">{{$t('warehouse')}}</th>
<td>{{ticket.warehouseName}}</td>
<th class="font gray align-right">{{$t('salesPerson')}}</th>
<td>{{ticket.salesPersonName}}</td>
</tr>
<tr>
<th class="font gray align-right">{{$t('Import')}}</th>
<th class="font gray align-right">{{$t('import')}}</th>
<td>{{ticket.import}}</td>
</tr>
</tbody>
@ -147,8 +150,9 @@
</section>
<!-- Footer component -->
<report-footer id="pageFooter"
:left-text="$t('route', [route.id])"
:locale="route.locale">
v-bind:left-text="$t('routeId', [route.id])"
v-bind:is-preview="isPreview"
v-bind:locale="locale">
</report-footer>
<!-- End footer component -->
</section>

View File

@ -1,49 +1,47 @@
const strftime = require('strftime');
const database = require(`${appPath}/lib/database`);
const UserException = require(`${appPath}/lib/exceptions/userException`);
const Component = require(`${appPath}/core/component`);
const reportHeader = new Component('report-header');
const reportFooter = new Component('report-footer');
const db = require(`${appPath}/core/database`);
module.exports = {
name: 'rpt-route',
async asyncData(ctx, params) {
Object.assign(this, this.methods);
name: 'route',
async serverPrefetch() {
this.route = await this.fetchRoute(this.routeId);
this.tickets = await this.fetchTickets(this.routeId);
const [[route]] = await this.fetchRoute(params.routeFk);
const [tickets] = await this.fetchTickets(params.routeFk);
if (!this.route)
throw new Error('Something went wrong');
},
computed: {
dated: function() {
const filters = this.$options.filters;
if (!route)
throw new UserException('No route data found');
if (!tickets)
throw new UserException('No ticket data found');
return {route, tickets};
return filters.date(new Date(), '%d-%m-%Y');
}
},
methods: {
fetchRoute(routeFk) {
return database.pool.query(
fetchRoute(id) {
return db.findOne(
`SELECT
r.id,
r.m3,
r.created,
r.time,
u.nickName userNickName,
u.lang AS locale,
v.tradeMark vehicleTradeMark,
v.model vehicleModel,
v.numberPlate plateNumber,
am.name agencyName
FROM route r
LEFT JOIN ticket t ON t.routeFk = r.id
LEFT JOIN sale s ON s.ticketFk = t.id
LEFT JOIN cache.last_buy lb ON lb.item_id = s.itemFk
LEFT JOIN vehicle v ON v.id = r.vehicleFk
LEFT JOIN worker w ON w.id = r.workerFk
LEFT JOIN account.user u ON u.id = w.userFk
LEFT JOIN agencyMode am ON am.id = r.agencyModeFk
WHERE r.id = ?`, [routeFk]);
WHERE r.id = :routeId`, {routeId: id});
},
fetchTickets(routeFk) {
return database.pool.query(
// Redmine #1855 Replace function Averiguar_ComercialCliente_Id()
fetchTickets(routeId) {
return db.find(
`SELECT
t.nickname addressName,
t.packages,
@ -76,19 +74,17 @@ module.exports = {
LEFT JOIN agencyMode am ON am.id = t.agencyModeFk
LEFT JOIN stowaway s ON s.id = t.id
WHERE r.id = ?
ORDER BY t.priority, t.id`, [routeFk]);
},
date(date) {
if (date)
return strftime('%d-%m-%Y', date);
},
time: time => {
if (time)
return strftime('%H:%M', time);
},
ORDER BY t.priority, t.id`, [routeId]);
}
},
components: {
'report-header': require('../report-header'),
'report-footer': require('../report-footer'),
'report-header': reportHeader.build(),
'report-footer': reportFooter.build()
},
props: {
routeId: {
type: String,
required: true
}
}
};

View File

@ -1,29 +0,0 @@
module.exports = {
messages: {
es: {
Title: 'Hoja de ruta',
Information: 'Información',
Route: 'Ruta',
Date: 'Fecha',
Time: 'Hora',
Volume: 'Cubicaje',
Driver: 'Conductor',
Vehicle: 'Vehículo',
Agency: 'Agencia',
Order: 'Orden',
Client: 'Cliente',
Address: 'Consignatario',
Packages: 'Bultos',
Street: 'Dirección',
Postcode: 'Código Postal',
City: 'Ciudad',
Mobile: 'Móvil',
Phone: 'Teléfono',
Warehouse: 'Almacén',
salesPerson: 'Comercial',
Import: 'Importe',
stowaway: 'Encajado dentro del ticket',
route: 'Ruta {0}'
}
},
};

View File

@ -1,7 +0,0 @@
const CssReader = require(`${appPath}/lib/cssReader`);
module.exports = new CssReader([
`${appPath}/common/css/layout.css`,
`${appPath}/common/css/report.css`,
`${__dirname}/style.css`])
.mergeStyles();

View File

@ -1,36 +0,0 @@
const strftime = require('strftime');
const database = require(`${appPath}/lib/database`);
const UserException = require(`${appPath}/lib/exceptions/userException`);
module.exports = {
name: 'rpt-zone',
async asyncData(ctx, params) {
if (!params.routeFk)
throw new UserException('No route id specified');
let [[zone]] = await this.methods.fetchRoute(params.routeFk);
if (!zone)
throw new UserException('Route not ready');
return {zone};
},
methods: {
fetchRoute(routeFk) {
return database.pool.query(
`SELECT
r.id,
r.time,
am.name agencyName,
v.numberPlate plateNumber
FROM route r
JOIN agencyMode am ON am.id = r.agencyModeFk
JOIN vehicle v ON v.id = r.vehicleFk
WHERE r.id = ?`, [routeFk]);
},
zoneTime: zoneTime => {
if (zoneTime)
return strftime('%H:%M', zoneTime);
},
},
};

View File

@ -1,3 +0,0 @@
table.column-oriented {
margin-top: 50px !important
}

View File

@ -1,39 +0,0 @@
<!DOCTYPE html>
<html lang="es">
<body>
<section class="container" id="report">
<!-- Header component -->
<report-header :locale="locale"></report-header>
<!-- End header component -->
<section class="main">
<!-- Report start -->
<h1 class="title">{{$t('title')}}</h1>
<p>{{$t('date')}} {{dated()}}</p>
<table class="column-oriented">
<thead>
<tr>
<th>Id</th>
<th>{{$t('concept')}}</th>
<th>{{$t('quantity')}}</th>
</tr>
</thead>
<tbody>
<tr v-for="sale in sales" :key="sale.id">
<td class="font gray">{{sale.id}}</td>
<td>{{sale.concept}}</td>
<td>{{sale.quantity}}</td>
</tr>
</tbody>
</table>
<!-- Report end -->
</section>
<!-- Footer component -->
<report-footer id="pageFooter"
:left-text="$t('client', [client.id])"
:center-text="client.name"
:locale="locale">
</report-footer>
<!-- End footer component -->
</section>
</body>
</html>

View File

@ -1,32 +0,0 @@
const strftime = require('strftime');
module.exports = {
name: 'sample-report',
created() {
if (this.locale)
this.$i18n.locale = this.locale;
},
data() {
return {
client: {
id: 10252,
name: 'Batman',
},
sales: [
{id: 1, concept: 'My item 1', quantity: 25},
{id: 2, concept: 'My item 2', quantity: 50},
{id: 3, concept: 'My item 3', quantity: 150}
],
locale: 'es'
};
},
methods: {
dated: () => {
return strftime('%d-%m-%Y', new Date());
},
},
components: {
'report-header': require('../report-header'),
'report-footer': require('../report-footer'),
},
};

View File

@ -1,11 +0,0 @@
module.exports = {
messages: {
es: {
title: 'Sample report',
date: 'Fecha',
quantity: 'Cantidad',
concept: 'Concepto',
client: 'Cliente {0}',
},
},
};

View File

@ -7,7 +7,7 @@
<!-- End header component -->
<section class="main">
<h1 class="title centered">{{$t('title')}}</h1>
<section class="panel supplierPanel">
<section class="panel supplierPanel" style="width: 99%">
<section class="body">
<section class="vertical-text">
{{$t('supplier.toCompleteBySupplier')}}
@ -17,7 +17,7 @@
<tbody>
<tr>
<td>{{$t('supplier.orderReference')}}</td>
<th>{{mandateCode}}</th>
<th>{{supplier.mandateCode}}</th>
</tr>
<tr>
<td>{{$t('supplier.identifier')}}</td>
@ -25,19 +25,19 @@
</tr>
<tr>
<td>{{$t('supplier.name')}}</td>
<th>{{supplierName}}</th>
<th>{{supplier.name}}</th>
</tr>
<tr>
<td>{{$t('supplier.street')}}</td>
<th>{{supplierStreet}}</th>
<th>{{supplier.street}}</th>
</tr>
<tr>
<td>{{$t('supplier.location')}}</td>
<th>{{supplierPostCode}}, {{supplierCity}} ({{supplierProvince}})</th>
<th>{{supplier.postCode}}, {{supplier.city}} ({{supplier.province}})</th>
</tr>
<tr>
<td>{{$t('supplier.country')}}</td>
<th>{{supplierCountry}}</th>
<th>{{supplier.country}}</th>
</tr>
</tbody>
</table>
@ -49,7 +49,7 @@
<strong>{{$t('documentCopy')}}</strong>
</p>
<!-- <section class="panel">
<section class="panel" style="width: 99%">
<section class="body">
<section class="vertical-text">
{{$t('client.toCompleteByClient')}}
@ -62,19 +62,19 @@
{{$t('client.name')}}
<section class="description">{{$t('client.accountHolder')}}</section>
</td>
<th>{{clientName}}</th>
<th>{{client.socialName}}</th>
</tr>
<tr>
<td>{{$t('client.street')}}</td>
<th>{{clientStreet}}</th>
<th>{{client.street}}</th>
</tr>
<tr>
<td>{{$t('client.location')}}</td>
<th>{{clientPostCode}}, {{clientCity}} ({{clientProvince}})</th>
<th>{{client.postcode}}, {{client.city}} ({{client.province}})</th>
</tr>
<tr>
<td>{{$t('client.country')}}</td>
<th>{{clientCountry}}</th>
<th>{{client.country}}</th>
</tr>
<tr>
<td>{{$t('client.swift')}}</td>
@ -88,18 +88,18 @@
<td colspan="2">{{$t('client.accountNumber')}}</td>
</tr>
<tr>
<td colspan="2" v-if=!ibanLength>
<td colspan="2" v-if="!client.ibanLength">
<section class="field square">
<span>{{clientCountryCode.substr(0, 1)}}</span>
<span>{{clientCountryCode.substr(1, 1)}}</span>
<span>{{client.countryCode.substr(0, 1)}}</span>
<span>{{client.countryCode.substr(1, 1)}}</span>
<span class="wide"></span>
</section>
</td>
<td colspan="2" v-if=ibanLength>
<td colspan="2" v-if="client.ibanLength">
<section class="field square">
<span>{{clientCountryCode.substr(0, 1)}}</span>
<span>{{clientCountryCode.substr(1, 1)}}</span>
<span v-for="i in ibanLength"></span>
<span>{{client.countryCode.substr(0, 1)}}</span>
<span>{{client.countryCode.substr(1, 1)}}</span>
<span v-for="i in client.ibanLength"></span>
</section>
</td>
</tr>
@ -134,7 +134,7 @@
</tr>
<tr>
<td>{{$t('client.signLocation')}}</td>
<th>{{dated()}}, {{supplierProvince}}</th>
<th>{{dated}}, {{supplier.province}}</th>
</tr>
<tr>
<td>{{$t('client.sign')}}</td>
@ -144,14 +144,14 @@
</table>
</section>
</section>
-->
<p class="font small">{{$t('mandatoryFields')}}</p>
<p class="font small">{{$t('sendOrder')}}</p>
</section>
<!-- Footer component -->
<report-footer id="pageFooter"
:left-text="$t('order', [mandateCode])"
:center-text="clientName"
:left-text="$t('order', [supplier.mandateCode])"
:center-text="client.socialName"
:locale="locale">
</report-footer>
<!-- End footer component -->

View File

@ -7,12 +7,13 @@ const rptSepaCore = {
name: 'sepa-core',
async serverPrefetch() {
this.client = await this.fetchClient(this.clientId, this.companyId);
this.supplier = await this.fetchSupplier(this.clientId, this.companyId);
if (!this.client)
throw new Error('Something went wrong');
},
computed: {
dated: () => {
dated: function() {
const filters = this.$options.filters;
return filters.date(new Date(), '%d-%m-%Y');
@ -22,27 +23,35 @@ const rptSepaCore = {
fetchClient(clientId, companyId) {
return db.findOne(
`SELECT
c.id clientId,
u.lang locale,
c.id,
m.code mandateCode,
c.email AS recipient,
c.socialName AS clientName,
c.street AS clientStreet,
c.postcode AS clientPostCode,
c.city AS clientCity,
p.name AS clientProvince,
ct.country AS clientCountry,
ct.code AS clientCountryCode,
ct.ibanLength AS ibanLength,
s.name AS supplierName,
s.street AS supplierStreet,
sc.country AS supplierCountry,
s.postCode AS supplierPostCode,
s.city AS supplierCity,
sp.name AS supplierProvince
c.socialName,
c.street,
c.postcode,
c.city,
p.name AS province,
ct.country,
ct.code AS countryCode,
ct.ibanLength AS ibanLength
FROM client c
JOIN account.user u ON u.id = c.id
JOIN country ct ON ct.id = c.countryFk
LEFT JOIN mandate m ON m.clientFk = c.id
AND m.companyFk = :companyId AND m.finished IS NULL
LEFT JOIN province p ON p.id = c.provinceFk
WHERE (m.companyFk = :companyId OR m.companyFk IS NULL) AND c.id = :clientId
ORDER BY m.created DESC LIMIT 1`, {companyId, clientId});
},
fetchSupplier(clientId, companyId) {
return db.findOne(
`SELECT
m.code mandateCode,
s.name,
s.street,
sc.country,
s.postCode,
s.city,
sp.name province
FROM client c
LEFT JOIN mandate m ON m.clientFk = c.id
AND m.companyFk = :companyId AND m.finished IS NULL
LEFT JOIN supplier s ON s.id = m.companyFk

View File

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

View File

@ -6,7 +6,7 @@
<!-- Report start -->
<section class="text">{{zone.agencyName}}</section>
<section class="text">{{zone.id}}</section>
<section class="text">{{zone.plateNumber}} {{zoneTime(zone.time)}}</section>
<section class="text">{{zone.plateNumber}} {{zone.time | date('%H:%M')}}</section>
<section></section>
<!-- Report end -->
</section>

View File

@ -0,0 +1,31 @@
const db = require(`${appPath}/core/database`);
module.exports = {
name: 'zone',
async serverPrefetch() {
this.zone = await this.fetchZone(this.routeId);
if (!this.zone)
throw new Error('Something went wrong');
},
methods: {
fetchZone(routeId) {
return db.findOne(
`SELECT
r.id,
r.time,
am.name agencyName,
v.numberPlate plateNumber
FROM route r
JOIN agencyMode am ON am.id = r.agencyModeFk
JOIN vehicle v ON v.id = r.vehicleFk
WHERE r.id = :routeId`, {routeId});
}
},
props: {
routeId: {
type: String,
required: true
}
}
};