updated delivery-note, fixed fallback locale
This commit is contained in:
parent
1ea032eba8
commit
7365a1e001
|
@ -7,7 +7,7 @@ RUN apt-get update \
|
|||
ca-certificates \
|
||||
gnupg2 \
|
||||
libfontconfig \
|
||||
&& curl -sL https://deb.nodesource.com/setup_8.x | bash - \
|
||||
&& curl -sL https://deb.nodesource.com/setup_10.x | bash - \
|
||||
&& apt-get install -y --no-install-recommends \
|
||||
nodejs \
|
||||
&& apt-get purge -y --auto-remove \
|
||||
|
|
|
@ -51,6 +51,7 @@ function backWatch(done) {
|
|||
|
||||
nodemon({
|
||||
exec: commands.join(' && '),
|
||||
ext: 'js html css',
|
||||
args: ['backOnly'],
|
||||
watch: backSources,
|
||||
done: done
|
||||
|
|
|
@ -155,3 +155,10 @@
|
|||
</vn-confirm>
|
||||
<vn-add-stowaway vn-id="addStowaway" card-reload="$ctrl.cardReload()" ticket="$ctrl.ticket"></vn-add-stowaway>
|
||||
<vn-remove-stowaway vn-id="removeStowaway" card-reload="$ctrl.cardReload()" ticket="$ctrl.ticket"></vn-remove-stowaway>
|
||||
<vn-confirm
|
||||
vn-id="confirm-dialog"
|
||||
on-response="$ctrl.returnDialog(response)"
|
||||
question="Pickup order"
|
||||
message="Do you want to send it directly?">
|
||||
<tpl-buttons>asd</tpl-buttons>
|
||||
</vn-confirm>
|
|
@ -9,9 +9,10 @@ class Controller {
|
|||
this.$translate = $translate;
|
||||
this.moreOptions = [
|
||||
{callback: this.showAddTurnDialog, name: 'Add turn', show: true},
|
||||
{callback: this.showDeleteTicketDialog, name: 'Delete ticket', show: true},
|
||||
{callback: this.showAddStowaway, name: 'Add stowaway', show: () => this.isTicketModule()},
|
||||
{callback: this.showRemoveStowaway, name: 'Remove stowaway', show: () => this.shouldShowRemoveStowaway()},
|
||||
{callback: this.showDeliveryNote, name: 'Show Delivery Note', show: true},
|
||||
{callback: this.showDeleteTicketDialog, name: 'Delete ticket', show: true},
|
||||
/* callback: this.showChangeShipped, name: 'Change shipped hour', show: true} */
|
||||
];
|
||||
}
|
||||
|
@ -157,6 +158,11 @@ class Controller {
|
|||
get quicklinks() {
|
||||
return this._quicklinks;
|
||||
}
|
||||
|
||||
showDeliveryNote() {
|
||||
let url = `/api/report/rpt-delivery-note?ticketFk=${this.ticket.id}`;
|
||||
window.open(url);
|
||||
}
|
||||
}
|
||||
|
||||
Controller.$inject = ['$state', '$scope', '$http', 'vnApp', '$translate'];
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import './index.js';
|
||||
|
||||
xdescribe('Item Component vnTicketDescriptor', () => {
|
||||
describe('Item Component vnTicketDescriptor', () => {
|
||||
let $httpBackend;
|
||||
let controller;
|
||||
|
||||
|
@ -69,5 +69,15 @@ xdescribe('Item Component vnTicketDescriptor', () => {
|
|||
expect(controller.vnApp.showSuccess).toHaveBeenCalledWith('Ticket deleted');
|
||||
});
|
||||
});
|
||||
|
||||
fdescribe('showDeliveryNote()', () => {
|
||||
it('should open a new window showing a delivery note PDF document', () => {
|
||||
let expectedPath = '/api/report/rpt-delivery-note?ticketFk=2';
|
||||
spyOn(window, 'open');
|
||||
controller.showDeliveryNote();
|
||||
|
||||
expect(window.open).toHaveBeenCalledWith(expectedPath);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -7,3 +7,4 @@ Stowaways of the ticket: Polizones del ticket
|
|||
Add stowaway: Añadir polizón
|
||||
Remove stowaway: Borrar polizón
|
||||
Are you sure you want to delete this stowaway?: ¿Estas seguro de que quieres borrar este polizón?
|
||||
Show Delivery Note: Ver albarán
|
|
@ -38,93 +38,26 @@
|
|||
clear: both
|
||||
}
|
||||
|
||||
.row {
|
||||
margin-bottom: 15px;
|
||||
overflow: hidden;
|
||||
display: block;
|
||||
clear: both;
|
||||
width: 100%
|
||||
}
|
||||
|
||||
.row.small {
|
||||
margin-bottom: 5px
|
||||
}
|
||||
|
||||
.row .text {
|
||||
margin-bottom: 5px
|
||||
}
|
||||
|
||||
.row .control {
|
||||
-webkit-box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box
|
||||
}
|
||||
|
||||
.row:last-child {
|
||||
margin-bottom: 0
|
||||
}
|
||||
|
||||
.row.inline .text {
|
||||
display: table-cell;
|
||||
margin-bottom: 0;
|
||||
width: 30%
|
||||
}
|
||||
|
||||
.row.inline .control {
|
||||
display: table-cell;
|
||||
padding-left: 20px;
|
||||
font-weight: bold;
|
||||
color: #000;
|
||||
width: 70%
|
||||
}
|
||||
|
||||
.row.inline .description {
|
||||
position: static;
|
||||
overflow: visible
|
||||
}
|
||||
|
||||
.row .description {
|
||||
position: relative;
|
||||
padding-top: 2px;
|
||||
font-size: 9px;
|
||||
overflow: hidden;
|
||||
display: block;
|
||||
clear: both
|
||||
}
|
||||
|
||||
.row .line {
|
||||
border-bottom: 1px solid #DDD;
|
||||
border-right: 1px solid #DDD;
|
||||
border-left: 1px solid #DDD;
|
||||
margin-top: 10px;
|
||||
color: #999;
|
||||
padding: 5px
|
||||
}
|
||||
|
||||
.row .description span {
|
||||
background-color: #FFF;
|
||||
margin: -5px 0 0 50px;
|
||||
display: block;
|
||||
padding: 5px;
|
||||
float: left
|
||||
}
|
||||
|
||||
.panel {
|
||||
position: relative
|
||||
position: relative;
|
||||
margin-bottom: 20px;
|
||||
padding-top: 10px;
|
||||
break-inside: avoid;
|
||||
break-before: always;
|
||||
break-after: always;
|
||||
}
|
||||
|
||||
.panel .header {
|
||||
background-color: #FFF;
|
||||
padding: 2.5px 5px;
|
||||
padding: 2.5px 10px;
|
||||
position: absolute;
|
||||
font-weight: bold;
|
||||
top: 0px;
|
||||
left: 17.5px;
|
||||
top: -12px
|
||||
}
|
||||
|
||||
.panel .body {
|
||||
border: 1px solid #CCC;
|
||||
margin-top: 10px;
|
||||
overflow: hidden;
|
||||
padding: 20px
|
||||
}
|
||||
|
@ -133,6 +66,16 @@
|
|||
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;
|
||||
|
@ -157,11 +100,11 @@
|
|||
}
|
||||
|
||||
.pull-left {
|
||||
float: left
|
||||
float: left !important
|
||||
}
|
||||
|
||||
.pull-right {
|
||||
float: right
|
||||
float: right !important
|
||||
}
|
||||
|
||||
.vertical-text {
|
||||
|
@ -186,58 +129,38 @@ table {
|
|||
width: 100%
|
||||
}
|
||||
|
||||
.row-oriented .description,
|
||||
.column-oriented .description {
|
||||
font-size: 0.6em;
|
||||
color: #888;
|
||||
padding: 0 !important
|
||||
}
|
||||
|
||||
.row-oriented .description .line,
|
||||
.column-oriented .description .line {
|
||||
border-bottom: 1px solid #DDD;
|
||||
border-right: 1px solid #DDD;
|
||||
border-left: 1px solid #DDD;
|
||||
margin-top: 10px;
|
||||
color: #999;
|
||||
padding: 5px
|
||||
}
|
||||
|
||||
.row-oriented .description span,
|
||||
.column-oriented .description span {
|
||||
background-color: #FFF;
|
||||
margin: -5px 0 0 50px;
|
||||
display: block;
|
||||
padding: 5px;
|
||||
float: left
|
||||
}
|
||||
|
||||
.column-oriented {
|
||||
margin: 20px 0
|
||||
}
|
||||
|
||||
.column-oriented tfoot {
|
||||
border-top: 1px solid #808080;
|
||||
}
|
||||
|
||||
.column-oriented td, .column-oriented th {
|
||||
.column-oriented td,
|
||||
.column-oriented th {
|
||||
padding: 5px 10px
|
||||
}
|
||||
|
||||
.column-oriented thead {
|
||||
background-color: #c0c0c0
|
||||
background-color: #e5e5e5
|
||||
}
|
||||
|
||||
.column-oriented thead tr {
|
||||
border-bottom: 1px solid #808080;
|
||||
border-top: 1px solid #808080;
|
||||
background-color: #c0c0c0
|
||||
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
|
||||
}
|
||||
|
@ -250,3 +173,27 @@ table {
|
|||
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;
|
||||
margin-top: 10px;
|
||||
color: #999;
|
||||
padding: 5px
|
||||
}
|
||||
|
||||
.line span {
|
||||
background-color: #FFF;
|
||||
margin: -5px 0 0 50px;
|
||||
display: block;
|
||||
padding: 5px;
|
||||
float: left
|
||||
}
|
||||
|
|
|
@ -25,3 +25,7 @@
|
|||
.font.small {
|
||||
font-size: 0.65em
|
||||
}
|
||||
|
||||
.font.bold {
|
||||
font-weight: bold
|
||||
}
|
|
@ -26,7 +26,7 @@ module.exports = {
|
|||
const result = await this.preFetch(component, ctx);
|
||||
const i18n = new VueI18n({
|
||||
locale: 'es',
|
||||
fallbackLocale: 'en'
|
||||
fallbackLocale: 'es'
|
||||
});
|
||||
const app = new Vue({i18n,
|
||||
render: h => h(result.component)});
|
||||
|
@ -106,9 +106,6 @@ module.exports = {
|
|||
const options = {
|
||||
format: 'A4',
|
||||
border: '1.5cm',
|
||||
header: {
|
||||
height: '80px',
|
||||
},
|
||||
footer: {
|
||||
height: '60px',
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
footer {
|
||||
font-family: verdana, sans-serif;
|
||||
font-family: "Roboto", "Helvetica", "Arial", sans-serif;
|
||||
font-size: 0.55em;
|
||||
color: #555;
|
||||
zoom: 0.65
|
||||
|
@ -9,6 +9,10 @@ footer, footer p {
|
|||
text-align: center
|
||||
}
|
||||
|
||||
p.privacy {
|
||||
font-size: 0.8em
|
||||
}
|
||||
|
||||
footer .page {
|
||||
border-bottom: 2px solid #CCC;
|
||||
padding-bottom: 2px
|
||||
|
|
|
@ -5,5 +5,5 @@
|
|||
<section class="number">{{$t('numPages')}}</section>
|
||||
</section>
|
||||
<p class="phytosanitary">{{$t('law.phytosanitary')}}</p>
|
||||
<p v-html="$t('law.privacy')"></p>
|
||||
<p class="privacy" v-html="$t('law.privacy')"></p>
|
||||
</footer>
|
||||
|
|
|
@ -7,8 +7,7 @@ module.exports = {
|
|||
privacy: `En cumplimiento de lo dispuesto en la Ley Orgánica 15/1999, de Protección de Datos de Carácter Personal,
|
||||
le comunicamos que los datos personales que facilite se incluirán en ficheros automatizados de VERDNATURA LEVANTE S.L.,
|
||||
pudiendo en todo momento ejercitar los derechos de acceso, rectificación, cancelación y oposición, comunicándolo
|
||||
por escrito al domicilio social de la entidad. <br/>
|
||||
La finalidad del fichero es la gestión administrativa, contabilidad, y facturación.`,
|
||||
por escrito al domicilio social de la entidad. La finalidad del fichero es la gestión administrativa, contabilidad, y facturación.`,
|
||||
}
|
||||
},
|
||||
},
|
||||
|
|
|
@ -2,10 +2,10 @@ header {
|
|||
font-family: "Roboto", "Helvetica", "Arial", sans-serif;
|
||||
border-bottom: 1px solid #DDD;
|
||||
padding-bottom: 10px;
|
||||
margin-bottom: 20px;
|
||||
text-align: center;
|
||||
font-size: 0.60em;
|
||||
color: #555;
|
||||
zoom: 0.65
|
||||
font-size: 0.55em;
|
||||
color: #555
|
||||
}
|
||||
|
||||
header img {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<header>
|
||||
<img :src="embeded['/assets/images/report-logo.svg']" alt="Verdnatura"/>
|
||||
<section>{{$t('company.registry')}}</section>
|
||||
<section>{{$t('company.fiscalAddress')}}</section>
|
||||
<section>{{$t('company.registry')}}</section>
|
||||
</header>
|
||||
|
|
|
@ -3,9 +3,7 @@
|
|||
<body>
|
||||
<section class="container">
|
||||
<!-- Header component -->
|
||||
<report-header id="pageHeader-first"
|
||||
:locale="locale">
|
||||
</report-header>
|
||||
<report-header :locale="locale"></report-header>
|
||||
<!-- End header component -->
|
||||
<section class="main">
|
||||
<section class="columns">
|
||||
|
@ -53,22 +51,23 @@
|
|||
<thead>
|
||||
<tr>
|
||||
<th>{{$t('reference')}}</th>
|
||||
<th>{{$t('quantity')}}</th>
|
||||
<th>{{$t('claims')}}</th>
|
||||
<th class="number">{{$t('quantity')}}</th>
|
||||
<th class="number">{{$t('claims')}}</th>
|
||||
<th>{{$t('concept')}}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="sale in sales" :key="sale.id">
|
||||
<td class="font gray">{{sale.id}}</td>
|
||||
<td>{{sale.quantity}}</td>
|
||||
<td>{{sale.claimQuantity}}</td>
|
||||
<td class="number">{{sale.quantity}}</td>
|
||||
<td class="number">{{sale.claimQuantity}}</td>
|
||||
<td>{{sale.concept}}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<section class="panel sign">
|
||||
<section class="header">{{$t('clientSignature')}}</section>
|
||||
<section class="body centered">
|
||||
<h3>{{clientName}}</h3>
|
||||
</section>
|
||||
|
|
|
@ -10,6 +10,7 @@ module.exports = {
|
|||
claims: 'Reclama',
|
||||
reference: 'Referencia',
|
||||
concept: 'Concepto',
|
||||
clientSignature: 'Firma del cliente',
|
||||
claim: 'Reclamación {0}',
|
||||
sections: {
|
||||
agency: {
|
||||
|
|
|
@ -1,3 +1,22 @@
|
|||
table.column-oriented {
|
||||
margin-top: 50px !important
|
||||
#signature {
|
||||
margin-top: 80px
|
||||
}
|
||||
|
||||
#signature img {
|
||||
margin-bottom: 20px;
|
||||
width: 150px
|
||||
}
|
||||
|
||||
#packagings {
|
||||
box-sizing: border-box;
|
||||
padding-right: 10px
|
||||
}
|
||||
|
||||
#taxes {
|
||||
box-sizing: border-box;
|
||||
padding-left: 10px
|
||||
}
|
||||
|
||||
.description.phytosanitary {
|
||||
background-color: #e5e5e5
|
||||
}
|
|
@ -1,13 +1,11 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="es">
|
||||
<body>
|
||||
<section class="container" id="report">
|
||||
<section class="container">
|
||||
<!-- Header component -->
|
||||
<report-header id="pageHeader-first"
|
||||
:locale="locale">
|
||||
</report-header>
|
||||
<report-header :locale="ticket.locale"></report-header>
|
||||
<!-- End header component -->
|
||||
<section class="main">
|
||||
<section class="main" style="margin-bottom:100px">
|
||||
<section class="columns">
|
||||
<section class="size50">
|
||||
<section class="size75">
|
||||
|
@ -16,15 +14,15 @@
|
|||
<tbody>
|
||||
<tr>
|
||||
<td class="font gray uppercase">{{$t('clientId')}}</td>
|
||||
<th>{{clientId}}</th>
|
||||
<th>{{client.id}}</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="font gray uppercase">{{$t('ticketId')}}</td>
|
||||
<th>{{ticketId}}</th>
|
||||
<th>{{ticket.id}}</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="font gray uppercase">{{$t('date')}}</td>
|
||||
<th>{{dated()}}</th>
|
||||
<th>{{shipped}}</th>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
@ -32,70 +30,165 @@
|
|||
</section>
|
||||
<section class="size50">
|
||||
<section class="panel">
|
||||
<section class="header">{{$t('clientData')}}</section>
|
||||
<section class="header">{{$t('deliveryAddress')}}</section>
|
||||
<section class="body">
|
||||
<h3 class="uppercase">{{clientName}}</h3>
|
||||
<h3 class="uppercase">{{address.nickname}}</h3>
|
||||
<section>
|
||||
{{street}}
|
||||
{{address.street}}
|
||||
</section>
|
||||
<section>
|
||||
{{postcode}}, {{city}} ({{province}})
|
||||
</section>
|
||||
<section>
|
||||
{{country}}
|
||||
</section>
|
||||
</section>
|
||||
{{address.postalCode}}, {{address.city}} ({{address.province}})
|
||||
</section>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
<section class="panel">
|
||||
<section class="header">{{$t('fiscalData')}}</section>
|
||||
<section class="body">
|
||||
<section>
|
||||
{{client.socialName}}
|
||||
</section>
|
||||
<section>
|
||||
{{client.street}}
|
||||
</section>
|
||||
<section>
|
||||
{{client.fi}}
|
||||
</section>
|
||||
</section>
|
||||
</section>
|
||||
</section>
|
||||
</section>
|
||||
<table class="column-oriented">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{{$t('reference')}}</th>
|
||||
<th>{{$t('quantity')}}</th>
|
||||
<th>{{$t('concept')}}</th>
|
||||
<th class="number">{{$t('size')}}</th>
|
||||
<th>{{$t('cat')}}</th>
|
||||
<th>{{$t('col')}}</th>
|
||||
<th>{{$t('VAT')}}</th>
|
||||
<th>{{$t('price')}}</th>
|
||||
<th>{{$t('%')}}</th>
|
||||
<th>{{$t('amount')}}</th>
|
||||
<td>{{$t('reference')}}</td>
|
||||
<td class="number">{{$t('quantity')}}</td>
|
||||
<td>{{$t('concept')}}</td>
|
||||
<td class="number">{{$t('price')}}</td>
|
||||
<td class="centered">{{$t('discount')}}</td>
|
||||
<td class="centered">{{$t('vat')}}</td>
|
||||
<td class="number">{{$t('amount')}}</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="sale in sales" :key="sale.id">
|
||||
<td>{{sale.ref</td>
|
||||
<td>{{sale}}</td>
|
||||
<td class="number">{{sale}}</td>
|
||||
<td class="number">{{sale}}</td>
|
||||
<td class="number">{{a}}</td>
|
||||
<template v-for="sale in sales">
|
||||
<tr class="font bold" :key="sale.id">
|
||||
<td>{{sale.itemFk}}</td>
|
||||
<td class="number">{{sale.quantity}}</td>
|
||||
<td>{{sale.concept}}</td>
|
||||
<td class="number">{{sale.price | currency('EUR')}}</td>
|
||||
<td class="centered">{{sale.discount | percent}}</td>
|
||||
<td class="centered">{{sale.vatType}}</td>
|
||||
<td class="number">{{sale.price * sale.quantity * (1 - sale.discount / 100) | currency('EUR')}}</td>
|
||||
</tr>
|
||||
<tr class="description">
|
||||
<td colspan="2" class="centered">
|
||||
<strong class="font gray" v-if="sale.val1">{{sale.tag1}}</strong>
|
||||
<span>{{sale.val1}}</span>
|
||||
</td>
|
||||
<td colspan="3" class="centered">
|
||||
<strong class="font gray" v-if="sale.val2">{{sale.tag2}}</strong>
|
||||
<span>{{sale.val2}}</span>
|
||||
</td>
|
||||
<td colspan="2" class="centered">
|
||||
<strong class="font gray" v-if="sale.val3">{{sale.tag3}}</strong>
|
||||
<span>{{sale.val3}}</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="description phytosanitary" v-if="sale.passportNumber">
|
||||
<td colspan="7">
|
||||
{{sale.ediBotanic}} {{sale.denomination}} {{sale.countryCode}}-{{sale.passportNumber}}
|
||||
<span v-if="sale.isProtectedZone">ZP</span>
|
||||
</td>
|
||||
</tr>
|
||||
</template>
|
||||
<!-- FIXME - APPLY CSS POST-RENDER -->
|
||||
<tr >
|
||||
<td colspan="7"></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<!-- <tr>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td class="number"><strong class="pull-left">Total</strong> {{getTotalDebtOut()}}</td>
|
||||
<td class="number">{{getTotalDebtIn()}}</td>
|
||||
<td class="number">{{totalBalance}}</td>
|
||||
</tr> -->
|
||||
<tr>
|
||||
<td colspan="6">
|
||||
<span class="pull-right">{{$t('subtotal')}}</span>
|
||||
</td>
|
||||
<td class="number">{{getSubTotal() | currency('EUR')}}</td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
|
||||
<div class="panel" style="text-align:center;background-color:red">
|
||||
<div class="header">Firma digital</div>
|
||||
<img width="200" src="http://windows.verdnatura.es/signatures/tickets/1161229.png"/>
|
||||
<section>{{dmsCreated}}</section>
|
||||
</div>
|
||||
</div>
|
||||
<section class="columns">
|
||||
<section id="packagings" class="size50 pull-left" v-if="packagings.length > 0">
|
||||
<h3>{{$t('packaging')}}</h3>
|
||||
<table class="column-oriented">
|
||||
<thead>
|
||||
<tr>
|
||||
<td>Id</td>
|
||||
<td>{{$t('concept')}}</td>
|
||||
<td class="number">{{$t('quantity')}}</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="packaging in packagings">
|
||||
<td>{{packaging.itemFk}}</td>
|
||||
<td>{{packaging.name}}</td>
|
||||
<td class="number">{{packaging.quantity}}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr class="font bold">
|
||||
<td colspan="2">{{$t('total')}}</td>
|
||||
<td class="number">0</td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
</section>
|
||||
<section id="taxes" class="size50 pull-right" v-if="taxes">
|
||||
<h3>{{$t('taxBreakdown')}}</h3>
|
||||
<table class="column-oriented">
|
||||
<thead>
|
||||
<tr>
|
||||
<td>{{$t('type')}}</td>
|
||||
<td class="number">{{$t('taxBase')}}</td>
|
||||
<td>{{$t('tax')}}</td>
|
||||
<td class="number">{{$t('fee')}}</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="tax in taxes">
|
||||
<td>{{tax.name}}</td>
|
||||
<td class="number">{{tax.Base | currency('EUR')}}</td>
|
||||
<td>{{tax.vatPercent | percent}}</td>
|
||||
<td class="number">{{tax.tax | currency('EUR')}}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr class="font bold">
|
||||
<td>{{$t('subtotal')}}</td>
|
||||
<td class="number">{{getTotalBase() | currency('EUR')}}</td>
|
||||
<td></td>
|
||||
<td class="number">{{getTotalTax()| currency('EUR')}}</td>
|
||||
</tr>
|
||||
<tr class="font bold">
|
||||
<td colspan="2">{{$t('total')}}</td>
|
||||
<td colspan="2" class="number">{{getTotal() | currency('EUR')}}</td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
</section>
|
||||
</section>
|
||||
<section id="signature" class="panel dark" v-if="signature && signature.id">
|
||||
<section class="header">Firma digital</section>
|
||||
<section class="body centered">
|
||||
<img v-bind:src="dmsPath"/>
|
||||
<section>{{signature.created | date}}</section>
|
||||
</section>
|
||||
</section>
|
||||
</section>
|
||||
<!-- Footer component -->
|
||||
<report-footer id="pageFooter"
|
||||
:left-text="$t('ticket', [ticketId])"
|
||||
:center-text="clientName"
|
||||
:locale="locale">
|
||||
:left-text="$t('ticket', [ticket.id])"
|
||||
:center-text="client.socialName"
|
||||
:locale="client.locale">
|
||||
</report-footer>
|
||||
<!-- End footer component -->
|
||||
</section>
|
||||
|
|
|
@ -5,65 +5,94 @@ const UserException = require(`${appPath}/lib/exceptions/userException`);
|
|||
module.exports = {
|
||||
name: 'rpt-delivery-note',
|
||||
async asyncData(ctx, params) {
|
||||
const promises = [];
|
||||
const data = {};
|
||||
Object.assign(this, this.methods);
|
||||
|
||||
if (!params.ticketFk)
|
||||
throw new UserException('No ticket id specified');
|
||||
const [[client]] = await this.fetchClient(params.ticketFk);
|
||||
const [[ticket]] = await this.fetchTicket(params.ticketFk);
|
||||
const [[address]] = await this.fetchAddress(params.ticketFk);
|
||||
const [[signature]] = await this.fetchSignature(params.ticketFk);
|
||||
const [[taxes]] = await this.fetchTaxes(params.ticketFk);
|
||||
const [sales] = await this.fetchSales(params.ticketFk);
|
||||
const [packagings] = await this.fetchPackagings(params.ticketFk);
|
||||
|
||||
promises.push(this.methods.fetchClient(params.ticketFk));
|
||||
promises.push(this.methods.fetchSales(params.ticketFk));
|
||||
if (!ticket)
|
||||
throw new UserException('No ticket data found');
|
||||
|
||||
return Promise.all(promises).then(result => {
|
||||
const [[client]] = result[0];
|
||||
const [sales] = result[1];
|
||||
|
||||
if (!client)
|
||||
throw new UserException('No client data found');
|
||||
|
||||
Object.assign(data, client, {sales});
|
||||
|
||||
return data;
|
||||
});
|
||||
return {client, ticket, address, sales, taxes, packagings, signature};
|
||||
},
|
||||
created() {
|
||||
if (this.locale)
|
||||
this.$i18n.locale = this.locale;
|
||||
if (this.client.locale)
|
||||
this.$i18n.locale = this.client.locale;
|
||||
},
|
||||
data() {
|
||||
return {totalBalance: 0.00};
|
||||
},
|
||||
computed: {
|
||||
dmsPath() {
|
||||
return `http://windows.verdnatura.es/signatures/tickets/1161229.png`;
|
||||
const hostPath = 'http://windows.verdnatura.es/signatures/tickets';
|
||||
if (this.signature && this.signature.id)
|
||||
return `${hostPath}/${this.signature.id}.png`;
|
||||
},
|
||||
shipped() {
|
||||
return strftime('%d-%m-%Y', this.ticket.shipped);
|
||||
}
|
||||
},
|
||||
filters: {
|
||||
currency(input, currency = 'EUR') {
|
||||
return new Intl.NumberFormat('es', {
|
||||
style: 'currency', currency
|
||||
}).format(parseFloat(input));
|
||||
},
|
||||
percent(input) {
|
||||
return new Intl.NumberFormat('es', {
|
||||
style: 'percent',
|
||||
minimumFractionDigits: 0,
|
||||
maximumFractionDigits: 0
|
||||
}).format(parseFloat(input));
|
||||
},
|
||||
date(input) {
|
||||
return strftime('%d-%m-%Y', input);
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
fetchClient(ticketFk) {
|
||||
return database.pool.query(
|
||||
`SELECT
|
||||
c.id clientId,
|
||||
t.id ticketId,
|
||||
u.lang locale,
|
||||
c.id,
|
||||
c.email AS recipient,
|
||||
c.socialName AS clientName,
|
||||
c.socialName,
|
||||
c.street,
|
||||
c.postcode,
|
||||
c.city,
|
||||
c.fi,
|
||||
p.name AS province,
|
||||
ct.country,
|
||||
dt.dmsFk,
|
||||
d.created AS dmsCreated
|
||||
u.lang locale
|
||||
FROM ticket t
|
||||
JOIN client c ON c.id = t.clientFk
|
||||
JOIN account.user u ON u.id = c.id
|
||||
JOIN country ct ON ct.id = c.countryFk
|
||||
LEFT JOIN province p ON p.id = c.provinceFk
|
||||
LEFT JOIN dmsTicket dt ON dt.ticketFk = t.id
|
||||
LEFT JOIN dms d ON d.id = dt.dmsFk
|
||||
WHERE t.id = ?`, [ticketFk]);
|
||||
},
|
||||
fetchTicket(ticketFk) {
|
||||
return database.pool.query(
|
||||
`SELECT
|
||||
t.id,
|
||||
t.shipped
|
||||
FROM ticket t
|
||||
JOIN client c ON c.id = t.clientFk
|
||||
JOIN account.user u ON u.id = c.id
|
||||
WHERE t.id = ?`, [ticketFk]);
|
||||
},
|
||||
fetchAddress(ticketFk) {
|
||||
return database.pool.query(
|
||||
`SELECT
|
||||
a.nickname,
|
||||
a.street,
|
||||
a.postalCode,
|
||||
a.city,
|
||||
p.name province
|
||||
FROM ticket t
|
||||
JOIN address a ON a.clientFk = t.clientFk
|
||||
LEFT JOIN province p ON p.id = a.provinceFk
|
||||
WHERE t.id = ?`, [ticketFk]);
|
||||
},
|
||||
|
||||
fetchSales(ticketFk) {
|
||||
return database.pool.query(
|
||||
`SELECT
|
||||
|
@ -78,45 +107,105 @@ module.exports = {
|
|||
s.discount,
|
||||
i.size,
|
||||
i.stems,
|
||||
ic.type taxType,
|
||||
i.category,
|
||||
it.id itemTypeId,
|
||||
o.code AS origin,
|
||||
i.inkFk,
|
||||
s.ticketFk,
|
||||
tcl.code vatType,
|
||||
ibwg.ediBotanic,
|
||||
ppa.denomination,
|
||||
pp.number passportNumber,
|
||||
be.isProtectedZone,
|
||||
c.code AS countryCode,
|
||||
ita.tag1,
|
||||
ita.val1,
|
||||
ita.tag2,
|
||||
ita.val2,
|
||||
ita.tag3,
|
||||
ita.val3
|
||||
FROM sale s
|
||||
FROM vn.sale s
|
||||
LEFT JOIN saleComponent sc ON sc.saleFk = s.id
|
||||
LEFT JOIN componentRate cr ON cr.id = sc.componentFk
|
||||
LEFT JOIN componentTypeRate ctr ON ctr.id = cr.componentTypeRate
|
||||
LEFT JOIN item i ON i.id = s.itemFk
|
||||
LEFT JOIN ticket t ON t.id = s.ticketFk
|
||||
LEFT JOIN origin o ON o.id = i.originFk
|
||||
INNER JOIN supplier sp ON sp.id = t.companyFk
|
||||
INNER JOIN itemType it ON it.id = i.typeFk
|
||||
LEFT JOIN
|
||||
(SELECT *
|
||||
FROM
|
||||
(SELECT tt.countryFk, tcc.taxClassFk, tc.type
|
||||
FROM taxClassCode tcc
|
||||
JOIN taxCode tc ON tc.id = tcc.taxCodeFk
|
||||
JOIN taxType tt ON tt.id = tc.taxTypeFk
|
||||
WHERE tcc.effectived <= '2019-01-29 13:00:00'
|
||||
ORDER BY tcc.effectived DESC) tx
|
||||
GROUP BY tx.countryFk, tx.taxClassFk) ic ON ic.countryFk = sp.countryFk
|
||||
AND ic.taxClassFk = i.taxClassFk
|
||||
JOIN vn.itemTagArranged ita ON ita.itemFk = s.itemFk
|
||||
LEFT JOIN country c ON c.id = o.countryFk
|
||||
LEFT JOIN supplier sp ON sp.id = t.companyFk
|
||||
LEFT JOIN itemType it ON it.id = i.typeFk
|
||||
LEFT JOIN itemTaxCountry itc ON itc.itemFk = i.id
|
||||
AND itc.countryFk = sp.countryFk
|
||||
LEFT JOIN taxClass tcl ON tcl.id = itc.taxClassFk
|
||||
LEFT JOIN itemTagArranged ita ON ita.itemFk = s.itemFk
|
||||
LEFT JOIN plantpassport pp ON pp.producerFk = i.producerFk
|
||||
LEFT JOIN plantpassportAuthority ppa ON ppa.id = pp.plantpassportAuthorityFk
|
||||
LEFT JOIN itemBotanicalWithGenus ibwg ON ibwg.itemFk = i.id
|
||||
LEFT JOIN botanicExport be ON be.restriction = 'pasaporte fitosanitario'
|
||||
LEFT JOIN ediGenus eg ON eg.id = be.ediGenusFk
|
||||
LEFT JOIN ediSpecie es ON es.id = be.ediSpecieFk
|
||||
AND ibwg.ediBotanic LIKE CONCAT(
|
||||
IFNULL(eg.latinGenusName, ''),
|
||||
IF(es.latinSpeciesName > '',
|
||||
CONCAT(' ', es.latinSpeciesName), ''),
|
||||
'%')
|
||||
WHERE s.ticketFk = ?
|
||||
GROUP BY s.id
|
||||
ORDER BY (it.isPackaging), s.concept, s.itemFk`, [ticketFk]);
|
||||
},
|
||||
dated: () => {
|
||||
return strftime('%d-%m-%Y', new Date());
|
||||
fetchTaxes(ticketFk) {
|
||||
return database.pool.query(
|
||||
`CALL vn.ticketGetTaxAdd(?)`, [ticketFk]);
|
||||
},
|
||||
fetchPackagings(ticketFk) {
|
||||
return database.pool.query(
|
||||
`SELECT
|
||||
tp.quantity,
|
||||
i.name,
|
||||
p.itemFk
|
||||
FROM ticketPackaging tp
|
||||
JOIN packaging p ON p.id = tp.packagingFk
|
||||
JOIN item i ON i.id = p.itemFk
|
||||
WHERE tp.ticketFk = ?
|
||||
ORDER BY itemFk`, [ticketFk]);
|
||||
},
|
||||
fetchSignature(ticketFk) {
|
||||
return database.pool.query(
|
||||
`SELECT
|
||||
d.id,
|
||||
d.created
|
||||
FROM ticket t
|
||||
JOIN dmsTicket dt ON dt.ticketFk = t.id
|
||||
JOIN dms d ON d.id = dt.dmsFk
|
||||
AND d.file LIKE '%.png'
|
||||
WHERE t.id = ?`, [ticketFk]);
|
||||
},
|
||||
getSubTotal() {
|
||||
let subTotal = 0.00;
|
||||
this.sales.forEach(sale => {
|
||||
subTotal += sale.quantity * sale.price * (1 - sale.discount / 100);
|
||||
});
|
||||
|
||||
return subTotal;
|
||||
},
|
||||
getTotalBase() {
|
||||
let totalBase = 0.00;
|
||||
this.taxes.forEach(tax => {
|
||||
totalBase += parseFloat(tax.Base);
|
||||
});
|
||||
|
||||
return totalBase;
|
||||
},
|
||||
getTotalTax() {
|
||||
let totalTax = 0.00;
|
||||
this.taxes.forEach(tax => {
|
||||
totalTax += parseFloat(tax.tax);
|
||||
});
|
||||
|
||||
return totalTax;
|
||||
},
|
||||
getTotal() {
|
||||
return this.getTotalBase() + this.getTotalTax();
|
||||
},
|
||||
},
|
||||
components: {
|
||||
|
|
|
@ -4,12 +4,24 @@ module.exports = {
|
|||
title: 'Albarán',
|
||||
ticketId: 'Albarán',
|
||||
clientId: 'Cliente',
|
||||
clientData: 'Datos del cliente',
|
||||
deliveryAddress: 'Dirección de entrega',
|
||||
fiscalData: 'Datos fiscales',
|
||||
date: 'Fecha',
|
||||
reference: 'Ref.',
|
||||
quantity: 'Cant.',
|
||||
concept: 'Concepto',
|
||||
invoiced: 'Facturado',
|
||||
payed: 'Pagado',
|
||||
balance: 'Saldo',
|
||||
price: 'PVP/u',
|
||||
discount: 'Dto.',
|
||||
vat: 'IVA',
|
||||
amount: 'Importe',
|
||||
type: 'Tipo',
|
||||
taxBase: 'Base imp.',
|
||||
tax: 'Tasa',
|
||||
fee: 'Cuota',
|
||||
packaging: 'Cubos y embalajes',
|
||||
taxBreakdown: 'Desglose impositivo',
|
||||
total: 'Total',
|
||||
subtotal: 'Subtotal',
|
||||
ticket: 'Albarán {0}'
|
||||
},
|
||||
},
|
||||
|
|
|
@ -3,9 +3,7 @@
|
|||
<body>
|
||||
<section class="container" id="report">
|
||||
<!-- Header component -->
|
||||
<report-header id="pageHeader-first"
|
||||
:locale="locale">
|
||||
</report-header>
|
||||
<report-header :locale="locale"></report-header>
|
||||
<!-- End header component -->
|
||||
<section class="main">
|
||||
<!-- Report start -->
|
||||
|
|
|
@ -3,9 +3,7 @@
|
|||
<body>
|
||||
<section class="container">
|
||||
<!-- Header component -->
|
||||
<report-header id="pageHeader-first"
|
||||
:locale="locale">
|
||||
</report-header>
|
||||
<report-header :locale="locale"></report-header>
|
||||
<!-- End header component -->
|
||||
<section class="main">
|
||||
<section class="columns">
|
||||
|
@ -77,7 +75,7 @@
|
|||
</section>
|
||||
<!-- Footer component -->
|
||||
<report-footer id="pageFooter"
|
||||
:left-text="$t('claim', [claimId])"
|
||||
:left-text="$t('client', [clientId])"
|
||||
:center-text="clientName"
|
||||
:locale="locale">
|
||||
</report-footer>
|
||||
|
|
|
@ -3,9 +3,7 @@
|
|||
<body>
|
||||
<section class="container">
|
||||
<!-- Header component -->
|
||||
<report-header id="pageHeader-first"
|
||||
:locale="locale">
|
||||
</report-header>
|
||||
<report-header :locale="locale"></report-header>
|
||||
<!-- End header component -->
|
||||
<section class="main">
|
||||
<h1 class="title centered">{{$t('title')}}</h1>
|
||||
|
@ -145,7 +143,7 @@
|
|||
</section>
|
||||
<!-- Footer component -->
|
||||
<report-footer id="pageFooter"
|
||||
:left-text="$t('claim', [claimId])"
|
||||
:left-text="$t('order', [mandateCode])"
|
||||
:center-text="clientName"
|
||||
:locale="locale">
|
||||
</report-footer>
|
||||
|
|
|
@ -3,9 +3,7 @@
|
|||
<body>
|
||||
<section class="container" id="report">
|
||||
<!-- Header component -->
|
||||
<report-header id="pageHeader-first"
|
||||
:locale="locale">
|
||||
</report-header>
|
||||
<report-header :locale="locale"></report-header>
|
||||
<!-- End header component -->
|
||||
<section class="main">
|
||||
<!-- Report start -->
|
||||
|
|
Loading…
Reference in New Issue