Merge branch 'dev' of https://gitea.verdnatura.es/verdnatura/salix into dev
gitea/salix/dev There was a failure building this commit Details

This commit is contained in:
Javi Gallego 2019-04-16 08:09:20 +02:00
commit ce2615e2d0
30 changed files with 558 additions and 63 deletions

View File

@ -31,4 +31,3 @@ rules:
curly: [error, multi-or-nest] curly: [error, multi-or-nest]
indent: [error, 4] indent: [error, 4]
arrow-parens: [error, as-needed] arrow-parens: [error, as-needed]
jasmine/no-focused-tests: 0

View File

@ -440,9 +440,12 @@ INSERT INTO `vn`.`ticket`(`id`, `agencyModeFk`,`warehouseFk`,`routeFk`, `shipped
INSERT INTO `vn`.`ticketObservation`(`id`, `ticketFk`, `observationTypeFk`, `description`) INSERT INTO `vn`.`ticketObservation`(`id`, `ticketFk`, `observationTypeFk`, `description`)
VALUES VALUES
( 1, 1 , 1, 'ready' ), (1, 1 , 1, 'ready' ),
( 2, 2 , 2, 'do it fast please'), (2, 2 , 2, 'do it fast please'),
( 3, 3 , 3, ''); (3, 3 , 3, 'Faster faster fasteeeeeer!!!'),
(4, 4 , 3, 'Deliver before 8am'),
(5, 13 , 3, 'You can run from the disappointments you are trying to forget. But its only when you embrace your past that you truly move forward. Maybe I never get to go home again, but I found my way there. And I am glad I did.'),
(6, 14, 3, 'Careful, armed warhead');
INSERT INTO `vn`.`ticketTracking`(`id`, `ticketFk`, `stateFk`, `workerFk`, `created`) INSERT INTO `vn`.`ticketTracking`(`id`, `ticketFk`, `stateFk`, `workerFk`, `created`)
VALUES VALUES

View File

@ -6,11 +6,11 @@ module.exports = Self => {
Self.remoteMethodCtx('send', { Self.remoteMethodCtx('send', {
description: 'Sends SMS to a destination phone', description: 'Sends SMS to a destination phone',
accepts: [{ accepts: [{
arg: 'recipientFk', arg: 'destinationFk',
type: 'Integer' type: 'Integer'
}, },
{ {
arg: 'recipient', arg: 'destination',
type: 'String', type: 'String',
required: true, required: true,
}, },
@ -20,7 +20,7 @@ module.exports = Self => {
required: true, required: true,
}], }],
returns: { returns: {
type: 'boolean', type: 'Object',
root: true root: true
}, },
http: { http: {
@ -29,7 +29,7 @@ module.exports = Self => {
} }
}); });
Self.send = async(ctx, recipientFk, recipient, message) => { Self.send = async(ctx, destinationFk, destination, message) => {
const userId = ctx.req.accessToken.userId; const userId = ctx.req.accessToken.userId;
const smsConfig = await Self.app.models.SmsConfig.findOne(); const smsConfig = await Self.app.models.SmsConfig.findOne();
const soapClient = await soap.createClientAsync(smsConfig.uri); const soapClient = await soap.createClientAsync(smsConfig.uri);
@ -37,7 +37,7 @@ module.exports = Self => {
user: smsConfig.user, user: smsConfig.user,
pass: smsConfig.password, pass: smsConfig.password,
src: smsConfig.title, src: smsConfig.title,
dst: recipient, dst: destination,
msg: message msg: message
}; };
@ -61,18 +61,21 @@ module.exports = Self => {
console.error(e); console.error(e);
} }
const statusCode = status.codigo[0];
const statusDescription = status.descripcion[0];
const newSms = { const newSms = {
senderFk: userId, senderFk: userId,
destinationFk: recipientFk || null, destinationFk: destinationFk || null,
destination: recipient, destination: destination,
message: message, message: message,
statusCode: status.codigo, statusCode: statusCode,
status: status.descripcion status: statusDescription
}; };
const sms = Self.create(newSms); const sms = await Self.create(newSms);
if (status.codigo != 200) if (statusCode != 200)
throw new UserError(`We weren't able to send this SMS`); throw new UserError(`We weren't able to send this SMS`);
return sms; return sms;

View File

@ -1,7 +1,11 @@
{ {
"name": "Sms", "name": "Sms",
"description": "Sms sent to client", "description": "Sms sent to client",
"base": "VnModel", "base": "Loggable",
"log": {
"model":"ClientLog",
"relation": "recipient"
},
"options": { "options": {
"mysql": { "mysql": {
"table": "sms" "table": "sms"

View File

@ -5,8 +5,8 @@
<h5 pad-small-v translate>Send SMS</h5> <h5 pad-small-v translate>Send SMS</h5>
<vn-horizontal> <vn-horizontal>
<vn-textfield vn-one <vn-textfield vn-one
label="Recipient" label="Destination"
model="$ctrl.sms.recipient"> model="$ctrl.sms.destination">
</vn-textfield> </vn-textfield>
</vn-horizontal> </vn-horizontal>
<vn-horizontal > <vn-horizontal >

View File

@ -18,11 +18,7 @@ class Controller extends Component {
onResponse(response) { onResponse(response) {
if (response === 'ACCEPT') { if (response === 'ACCEPT') {
let params = { this.$http.post(`/client/api/Sms/send`, this.sms).then(res => {
recipient: this.sms.recipient,
message: this.sms.message
};
this.$http.post(`/client/api/Sms/send`, params).then(res => {
this.vnApp.showMessage(this.$translate.instant('SMS sent!')); this.vnApp.showMessage(this.$translate.instant('SMS sent!'));
if (res.data) this.emit('send', {response: res.data}); if (res.data) this.emit('send', {response: res.data});

View File

@ -1,4 +1,4 @@
Send SMS: Enviar SMS Send SMS: Enviar SMS
Recipient: Destinatario Destination: Destinatario
Message: Mensaje Message: Mensaje
SMS sent!: ¡SMS enviado! SMS sent!: ¡SMS enviado!

View File

@ -6,6 +6,15 @@
<a translate-attr="{title: 'Preview'}" ui-sref="route.card.summary({id: $ctrl.route.id})"> <a translate-attr="{title: 'Preview'}" ui-sref="route.card.summary({id: $ctrl.route.id})">
<vn-icon icon="desktop_windows"></vn-icon> <vn-icon icon="desktop_windows"></vn-icon>
</a> </a>
<vn-icon-menu
vn-id="more-button"
icon="more_vert"
show-filter="false"
value-field="callback"
translate-fields="['name']"
data="$ctrl.moreOptions"
on-change="$ctrl.onMoreChange(value)">
</vn-icon-menu>
</div> </div>
<div class="body"> <div class="body">
<div class="attributes"> <div class="attributes">

View File

@ -1,6 +1,16 @@
import ngModule from '../module'; import ngModule from '../module';
class Controller { class Controller {
constructor($, $http, vnApp, $translate) {
this.$http = $http;
this.vnApp = vnApp;
this.$translate = $translate;
this.$ = $;
this.moreOptions = [
{callback: this.showRouteReport, name: 'Show route report'},
{callback: this.sendRouteReport, name: 'Send route report'}
];
}
set quicklinks(value = {}) { set quicklinks(value = {}) {
this._quicklinks = Object.assign(value, this._quicklinks); this._quicklinks = Object.assign(value, this._quicklinks);
} }
@ -8,9 +18,25 @@ class Controller {
get quicklinks() { get quicklinks() {
return this._quicklinks; return this._quicklinks;
} }
onMoreChange(callback) {
callback.call(this);
}
showRouteReport() {
let url = `/api/report/rpt-route?routeFk=${this.route.id}`;
window.open(url);
}
sendRouteReport() {
let url = `/api/email/driver-route?routeFk=${this.route.id}`;
this.$http.post(url).then(() => {
this.vnApp.showSuccess(this.$translate.instant('Report sent'));
});
}
} }
Controller.$inject = ['$http', '$state']; Controller.$inject = ['$scope', '$http', 'vnApp', '$translate'];
ngModule.component('vnRouteDescriptor', { ngModule.component('vnRouteDescriptor', {
template: require('./index.html'), template: require('./index.html'),

View File

@ -1,2 +1,4 @@
Volume exceded: Volumen excedido Volume exceded: Volumen excedido
Volume: Volumen Volume: Volumen
Send route report: Enviar informe de ruta
Show route report: Ver informe de ruta

View File

@ -65,13 +65,13 @@ class Controller {
} }
onMoreOpen() { onMoreOpen() {
let options = this.moreOptions.filter(o => { let options = this.moreOptions.filter(option => {
const hasShowProperty = Object.hasOwnProperty.call(o, 'show'); const hasShowProperty = Object.hasOwnProperty.call(option, 'show');
const hasAclProperty = Object.hasOwnProperty.call(o, 'acl'); const hasAclProperty = Object.hasOwnProperty.call(option, 'acl');
const hasAcl = !hasAclProperty || (hasAclProperty && this.aclService.hasAny([o.acl])); const hasAcl = !hasAclProperty || (hasAclProperty && this.aclService.hasAny([option.acl]));
return (!hasShowProperty || o.show === true || return (!hasShowProperty || option.show === true ||
typeof o.show === 'function' && o.show()) && hasAcl; typeof option.show === 'function' && option.show()) && hasAcl;
}); });
this.$scope.moreButton.data = options; this.$scope.moreButton.data = options;
} }
@ -182,7 +182,8 @@ class Controller {
showSMSDialog() { showSMSDialog() {
const address = this.ticket.address; const address = this.ticket.address;
this.newSMS = { this.newSMS = {
recipient: address.mobile || null, destinationFk: this.ticket.clientFk,
destination: address.mobile || null,
message: this.$translate.instant('SMSPayment') message: this.$translate.instant('SMSPayment')
}; };
this.$scope.sms.open(); this.$scope.sms.open();

View File

@ -61,7 +61,8 @@
</vn-td> </vn-td>
<vn-td number> <vn-td number>
<vn-check vn-one <vn-check vn-one
field="::request.isOk" field="::request.isOk"
triple-state="true"
disabled="true"> disabled="true">
</vn-check> </vn-check>
</vn-td> </vn-td>

View File

@ -331,7 +331,8 @@ class Controller {
notAvailables notAvailables
}; };
this.newSMS = { this.newSMS = {
recipient: address.mobile || null, destinationFk: this.ticket.clientFk,
destination: address.mobile || null,
message: this.$translate.instant('SMSAvailability', params) message: this.$translate.instant('SMSAvailability', params)
}; };
this.$scope.sms.open(); this.$scope.sms.open();

View File

@ -99,6 +99,11 @@
width: 35.4px width: 35.4px
} }
.field.rectangle span {
height: 2em;
width: 8em
}
.pull-left { .pull-left {
float: left !important float: left !important
} }

View File

@ -10,6 +10,14 @@
text-align: center text-align: center
} }
.align-right {
text-align: right
}
.align-left {
text-align: left
}
.number { .number {
text-align: right text-align: right
} }
@ -28,4 +36,8 @@
.font.bold { .font.bold {
font-weight: bold font-weight: bold
}
.non-page-break {
page-break-inside: avoid;
} }

View File

@ -6,12 +6,13 @@
{"type": "email", "name": "letter-debtor-nd"}, {"type": "email", "name": "letter-debtor-nd"},
{"type": "email", "name": "claim-pickup-order"}, {"type": "email", "name": "claim-pickup-order"},
{"type": "email", "name": "sepa-core"}, {"type": "email", "name": "sepa-core"},
{"type": "email", "name": "driver-route"},
{"type": "report", "name": "rpt-delivery-note"}, {"type": "report", "name": "rpt-delivery-note"},
{"type": "report", "name": "rpt-invoice"},
{"type": "report", "name": "rpt-claim-pickup-order"}, {"type": "report", "name": "rpt-claim-pickup-order"},
{"type": "report", "name": "rpt-letter-debtor"}, {"type": "report", "name": "rpt-letter-debtor"},
{"type": "report", "name": "rpt-sepa-core"}, {"type": "report", "name": "rpt-sepa-core"},
{"type": "report", "name": "rpt-receipt"}, {"type": "report", "name": "rpt-receipt"},
{"type": "report", "name": "rpt-zone"},
{"type": "report", "name": "rpt-route"}, {"type": "report", "name": "rpt-route"},
{"type": "static", "name": "email-header"}, {"type": "static", "name": "email-header"},
{"type": "static", "name": "email-footer"}, {"type": "static", "name": "email-footer"},

View File

@ -0,0 +1,7 @@
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,24 @@
<!DOCTYPE html>
<html lang="es">
<head>
<title>{{ $t('subject') }}</title>
</head>
<body>
<section class="container">
<!-- Header component -->
<email-header></email-header>
<!-- End header component -->
<section class="main">
<!-- Title block -->
<div class="title">
<h1>{{ $t('title') }}</h1>
</div>
<!-- Title block end -->
<p>{{$t('description.instructions')}}</p>
</section>
<!-- Footer component -->
<email-footer :locale="locale"></email-footer>
<!-- End footer component -->
</section>
</body>
</html>

View File

@ -0,0 +1,54 @@
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

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

View File

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

View File

@ -1,9 +1,49 @@
section .text { h1 {
font-family: Tahoma;
font-weight: bold;
color: white;
font-size: 7.5em;
text-align: center; text-align: center;
}
th.align-right {
padding-right: 1em;
}
.gap {
width: 3em;
}
.contained {
padding-top: 20px;
}
.middle {
margin: auto;
}
p.small {
width: 8em;
}
.black-container {
padding-top: 0.19em;
padding-right: 0.2em;
padding-left: 0.2em;
background-color: black; background-color: black;
margin-bottom: 0.2em color: white;
} font-size: 1.3em;
}
table.repeatable {
margin-top: 1em;
margin-bottom: 1em;
}
table.repeatable > tbody > tr > td {
padding-top: 0.5em;
}
section.text-area {
margin-top: 1em;
padding: 0.19em;
padding-left: 1em;
padding-right: 1em;
background-color: #e5e5e5;
}

View File

@ -2,14 +2,155 @@
<html lang="es"> <html lang="es">
<body> <body>
<section class="container" id="report"> <section class="container" id="report">
<!-- Header component -->
<report-header :locale="route.locale"></report-header>
<!-- End header component -->
<section class="main"> <section class="main">
<!-- Report start --> <h1 class="title uppercase">{{$t('Title')}}</h1>
<section class="text">{{route.agencyName}}</section> <section class="panel">
<section class="text">{{route.id}}</section> <section class="header">{{$t('Information')}}</section>
<section class="text">{{route.plateNumber}} {{routeTime(route.time)}}</section> <section class="body">
<section></section> <section>
<!-- Report end --> <table width="100%">
<tbody>
<tr>
<th class="font gray align-right">{{$t('Route')}}</th>
<td>{{route.id}}</td>
<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>
<td>{{route.vehicleTradeMark}} {{route.vehicleModel}}</td>
</tr>
<tr>
<th class="font gray align-right">{{$t('Time')}}</th>
<td>{{time(route.time)}}</td>
<td></td>
<td>{{route.plateNumber}}</td>
</tr>
<tr>
<th class="font gray align-right">{{$t('Volume')}}</th>
<td>{{route.m3}}</td>
<th class="font gray align-right">{{$t('Agency')}}</th>
<td>{{route.agencyName}}</td>
</tr>
</tbody>
</table>
<section class="contained">
<table class="middle centered" width="70%">
<tbody>
<tr>
<td>
<p class="small">Hora inicio</p>
</td>
<td>
<p class="small">Hora fin</p>
</td>
<td class="gap"></td>
<td>
<p class="small">Km inicio</p>
</td>
<td>
<p class="small">Km fin</p>
</td>
</tr>
<tr>
<td v-for="i in 2">
<section class="field rectangle">
<span></span>
</section>
</td>
<td class="gap"></td>
<td v-for="i in 2">
<section class="field rectangle">
<span></span>
</section>
</td>
</tr>
</tbody>
</table>
</section>
</section>
</section>
</section>
<section class="non-page-break" v-for="ticket in tickets">
<section>
<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>
</tr>
</thead>
<tbody>
<tr>
<td class="number">{{ticket.priority}}</td>
<td class="number">{{ticket.id}}</td>
<td>{{ticket.clientFk}} {{ticket.addressName}}</td>
<td v-if="ticket.addressFk" class="number">
{{ticket.addressFk.toString().substr(0, ticket.addressFk.toString().length - 3)}}
<span class="black-container">
{{ticket.addressFk.toString().substr(-3, 3)}}
</span>
</td>
<td class="number">{{ticket.packages}}</td>
</tr>
</tbody>
</table>
</section>
<section>
<table width="100%">
<tbody>
<tr>
<th class="font gray align-right">{{$t('Street')}}</th>
<td>{{ticket.street}}</td>
<th class="font gray align-right">{{$t('Postcode')}}</th>
<td>{{ticket.postalCode}}</td>
</tr>
<tr>
<th class="font gray align-right">{{$t('City')}}</th>
<td>{{ticket.city}}</td>
<th class="font gray align-right">{{$t('Agency')}}</th>
<td>{{ticket.ticketAgency}}</td>
</tr>
<tr>
<th class="font gray align-right">{{$t('Mobile')}}</th>
<td>{{ticket.mobile}}</td>
<th class="font gray align-right">{{$t('Phone')}}</th>
<td>{{ticket.phone}}</td>
</tr>
<tr>
<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>
<td>{{ticket.import}}</td>
</tr>
</tbody>
</table>
<section v-if="ticket.description || ticket.shipFk" class="text-area">
<p>{{ticket.description}}</p>
<p v-if="ticket.shipFk">{{$t('stowaway')}}: {{ticket.shipFk}}</p>
</section>
</section>
</section>
</section>
</section> </section>
<!-- Footer component -->
<report-footer id="pageFooter"
:left-text="$t('route', [route.id])"
:locale="route.locale">
</report-footer>
<!-- End footer component -->
</section> </section>
</body> </body>
</html> </html>

View File

@ -5,32 +5,90 @@ const UserException = require(`${appPath}/lib/exceptions/userException`);
module.exports = { module.exports = {
name: 'rpt-route', name: 'rpt-route',
async asyncData(ctx, params) { async asyncData(ctx, params) {
if (!params.routeFk) Object.assign(this, this.methods);
throw new UserException('No route id specified');
let [[route]] = await this.methods.fetchRoute(params.routeFk); const [[route]] = await this.fetchRoute(params.routeFk);
const [tickets] = await this.fetchTickets(params.routeFk);
if (!route) if (!route)
throw new UserException('Route not ready'); throw new UserException('No route data found');
return {route}; if (!tickets)
throw new UserException('No ticket data found');
return {route, tickets};
}, },
methods: { methods: {
fetchRoute(routeFk) { fetchRoute(routeFk) {
return database.pool.query( return database.pool.query(
`SELECT `SELECT
r.id, r.id,
r.m3,
r.created,
r.time, r.time,
am.name agencyName, u.nickName userNickName,
v.numberPlate plateNumber u.lang AS locale,
v.tradeMark vehicleTradeMark,
v.model vehicleModel,
v.numberPlate plateNumber,
am.name agencyName
FROM route r FROM route r
JOIN agencyMode am ON am.id = r.agencyModeFk LEFT JOIN ticket t ON t.routeFk = r.id
JOIN vehicle v ON v.id = r.vehicleFk 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 = ?`, [routeFk]);
}, },
routeTime: routeTime => { fetchTickets(routeFk) {
if (routeTime) return database.pool.query(
return strftime('%H:%M', routeTime); `SELECT
t.nickname addressName,
t.packages,
t.priority,
t.id,
t.clientFk,
t.companyFk,
if(a.phone, a.phone, c.phone) AS phone,
if(a.mobile, a.mobile, c.mobile) AS mobile,
wh.name warehouseName,
a.city,
a.street,
a.postalCode,
LPAD(a.id, 5, '0') AS addressFk,
p.name province,
vn.ticketGetTotal(t.id) AS import,
am.name ticketAgency,
tob.description,
s.shipFk,
u.nickName salesPersonName
FROM route r
LEFT JOIN ticket t ON t.routeFk = r.id
LEFT JOIN address a ON a.id = t.addressFk
LEFT JOIN client c ON c.id = t.clientFk
LEFT JOIN worker w ON w.id = vn2008.Averiguar_ComercialCliente_Id(t.clientFk, CURDATE())
LEFT JOIN account.user u ON u.id = w.userFk
LEFT JOIN ticketObservation tob ON tob.ticketFk = t.id AND tob.observationTypeFk = 3
LEFT JOIN province p ON a.provinceFk = p.id
LEFT JOIN warehouse wh ON wh.id = t.warehouseFk
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);
}, },
}, },
components: {
'report-header': require('../report-header'),
'report-footer': require('../report-footer'),
},
}; };

View File

@ -0,0 +1,29 @@
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

@ -0,0 +1,7 @@
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

@ -0,0 +1,9 @@
section .text {
font-family: Tahoma;
font-weight: bold;
color: white;
font-size: 7.5em;
text-align: center;
background-color: black;
margin-bottom: 0.2em
}

View File

@ -0,0 +1,15 @@
<!DOCTYPE html>
<html lang="es">
<body>
<section class="container" id="report">
<section class="main">
<!-- Report start -->
<section class="text">{{zone.agencyName}}</section>
<section class="text">{{zone.id}}</section>
<section class="text">{{zone.plateNumber}} {{zoneTime(zone.time)}}</section>
<section></section>
<!-- Report end -->
</section>
</section>
</body>
</html>

36
print/report/rpt-zone/index.js Executable file
View File

@ -0,0 +1,36 @@
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