#1339 Print - Hoja de rutas
This commit is contained in:
parent
f5fd929970
commit
82ed0078d2
|
@ -442,7 +442,10 @@ INSERT INTO `vn`.`ticketObservation`(`id`, `ticketFk`, `observationTypeFk`, `des
|
|||
VALUES
|
||||
(1, 1 , 1, 'ready' ),
|
||||
(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`)
|
||||
VALUES
|
||||
|
|
|
@ -6,6 +6,15 @@
|
|||
<a translate-attr="{title: 'Preview'}" ui-sref="route.card.summary({id: $ctrl.route.id})">
|
||||
<vn-icon icon="desktop_windows"></vn-icon>
|
||||
</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 class="body">
|
||||
<div class="attributes">
|
||||
|
|
|
@ -1,6 +1,16 @@
|
|||
import ngModule from '../module';
|
||||
|
||||
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 = {}) {
|
||||
this._quicklinks = Object.assign(value, this._quicklinks);
|
||||
}
|
||||
|
@ -8,9 +18,25 @@ class Controller {
|
|||
get quicklinks() {
|
||||
return this._quicklinks;
|
||||
}
|
||||
|
||||
onMoreChange(callback) {
|
||||
callback.call(this);
|
||||
}
|
||||
|
||||
Controller.$inject = ['$http', '$state'];
|
||||
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 = ['$scope', '$http', 'vnApp', '$translate'];
|
||||
|
||||
ngModule.component('vnRouteDescriptor', {
|
||||
template: require('./index.html'),
|
||||
|
|
|
@ -1,2 +1,4 @@
|
|||
Volume exceded: Volumen excedido
|
||||
Volume: Volumen
|
||||
Send route report: Enviar informe de ruta
|
||||
Show route report: Ver informe de ruta
|
|
@ -63,8 +63,8 @@ class Controller {
|
|||
}
|
||||
|
||||
onMoreOpen() {
|
||||
let options = this.moreOptions.filter(o => {
|
||||
return o.show === true || typeof o.show === 'function' && o.show();
|
||||
let options = this.moreOptions.filter(option => {
|
||||
return option.show === true || typeof option.show === 'function' && option.show();
|
||||
});
|
||||
this.$scope.moreButton.data = options;
|
||||
}
|
||||
|
|
|
@ -99,6 +99,11 @@
|
|||
width: 35.4px
|
||||
}
|
||||
|
||||
.field.rectangle span {
|
||||
height: 2em;
|
||||
width: 8em
|
||||
}
|
||||
|
||||
.pull-left {
|
||||
float: left !important
|
||||
}
|
||||
|
|
|
@ -10,6 +10,14 @@
|
|||
text-align: center
|
||||
}
|
||||
|
||||
.align-right {
|
||||
text-align: right
|
||||
}
|
||||
|
||||
.align-left {
|
||||
text-align: left
|
||||
}
|
||||
|
||||
.number {
|
||||
text-align: right
|
||||
}
|
||||
|
@ -29,3 +37,7 @@
|
|||
.font.bold {
|
||||
font-weight: bold
|
||||
}
|
||||
|
||||
.non-page-break {
|
||||
page-break-inside: avoid;
|
||||
}
|
|
@ -6,12 +6,13 @@
|
|||
{"type": "email", "name": "letter-debtor-nd"},
|
||||
{"type": "email", "name": "claim-pickup-order"},
|
||||
{"type": "email", "name": "sepa-core"},
|
||||
{"type": "email", "name": "driver-route"},
|
||||
{"type": "report", "name": "rpt-delivery-note"},
|
||||
{"type": "report", "name": "rpt-invoice"},
|
||||
{"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": "static", "name": "email-header"},
|
||||
{"type": "static", "name": "email-footer"},
|
||||
|
|
|
@ -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();
|
|
@ -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>
|
|
@ -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,
|
||||
},
|
||||
};
|
|
@ -0,0 +1,11 @@
|
|||
module.exports = {
|
||||
messages: {
|
||||
es: {
|
||||
subject: 'Hoja de ruta',
|
||||
title: 'Hoja de ruta',
|
||||
description: {
|
||||
instructions: 'Adjuntamos tu hoja de ruta.'
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
|
@ -3,5 +3,6 @@ const CssReader = require(`${appPath}/lib/cssReader`);
|
|||
module.exports = new CssReader([
|
||||
`${appPath}/common/css/layout.css`,
|
||||
`${appPath}/common/css/report.css`,
|
||||
`${appPath}/common/css/misc.css`,
|
||||
`${__dirname}/style.css`])
|
||||
.mergeStyles();
|
||||
|
|
|
@ -1,9 +1,49 @@
|
|||
section .text {
|
||||
font-family: Tahoma;
|
||||
font-weight: bold;
|
||||
color: white;
|
||||
font-size: 7.5em;
|
||||
h1 {
|
||||
text-align: center;
|
||||
background-color: black;
|
||||
margin-bottom: 0.2em
|
||||
}
|
||||
|
||||
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;
|
||||
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;
|
||||
}
|
|
@ -2,14 +2,155 @@
|
|||
<html lang="es">
|
||||
<body>
|
||||
<section class="container" id="report">
|
||||
<!-- Header component -->
|
||||
<report-header :locale="route.locale"></report-header>
|
||||
<!-- End header component -->
|
||||
<section class="main">
|
||||
<!-- Report start -->
|
||||
<section class="text">{{route.agencyName}}</section>
|
||||
<section class="text">{{route.id}}</section>
|
||||
<section class="text">{{route.plateNumber}} {{routeTime(route.time)}}</section>
|
||||
<section></section>
|
||||
<!-- Report end -->
|
||||
<h1 class="title uppercase">{{$t('Title')}}</h1>
|
||||
<section class="panel">
|
||||
<section class="header">{{$t('Information')}}</section>
|
||||
<section class="body">
|
||||
<section>
|
||||
<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>
|
||||
<!-- Footer component -->
|
||||
<report-footer id="pageFooter"
|
||||
:left-text="$t('route', [route.id])"
|
||||
:locale="route.locale">
|
||||
</report-footer>
|
||||
<!-- End footer component -->
|
||||
</section>
|
||||
</body>
|
||||
</html>
|
|
@ -5,32 +5,90 @@ const UserException = require(`${appPath}/lib/exceptions/userException`);
|
|||
module.exports = {
|
||||
name: 'rpt-route',
|
||||
async asyncData(ctx, params) {
|
||||
if (!params.routeFk)
|
||||
throw new UserException('No route id specified');
|
||||
Object.assign(this, this.methods);
|
||||
|
||||
let [[route]] = await this.methods.fetchRoute(params.routeFk);
|
||||
const [[route]] = await this.fetchRoute(params.routeFk);
|
||||
const [tickets] = await this.fetchTickets(params.routeFk);
|
||||
|
||||
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: {
|
||||
fetchRoute(routeFk) {
|
||||
return database.pool.query(
|
||||
`SELECT
|
||||
r.id,
|
||||
r.m3,
|
||||
r.created,
|
||||
r.time,
|
||||
am.name agencyName,
|
||||
v.numberPlate plateNumber
|
||||
u.nickName userNickName,
|
||||
u.lang AS locale,
|
||||
v.tradeMark vehicleTradeMark,
|
||||
v.model vehicleModel,
|
||||
v.numberPlate plateNumber,
|
||||
am.name agencyName
|
||||
FROM route r
|
||||
JOIN agencyMode am ON am.id = r.agencyModeFk
|
||||
JOIN vehicle v ON v.id = r.vehicleFk
|
||||
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]);
|
||||
},
|
||||
routeTime: routeTime => {
|
||||
if (routeTime)
|
||||
return strftime('%H:%M', routeTime);
|
||||
fetchTickets(routeFk) {
|
||||
return database.pool.query(
|
||||
`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'),
|
||||
},
|
||||
};
|
||||
|
|
|
@ -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}'
|
||||
}
|
||||
},
|
||||
};
|
|
@ -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();
|
|
@ -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
|
||||
}
|
|
@ -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>
|
|
@ -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);
|
||||
},
|
||||
},
|
||||
};
|
Loading…
Reference in New Issue