updated delivery-note, fixed fallback locale

This commit is contained in:
Joan Sanchez 2019-02-11 10:06:26 +01:00
parent 1ea032eba8
commit 7365a1e001
25 changed files with 441 additions and 260 deletions

View File

@ -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 \

View File

@ -51,6 +51,7 @@ function backWatch(done) {
nodemon({
exec: commands.join(' && '),
ext: 'js html css',
args: ['backOnly'],
watch: backSources,
done: done

View File

@ -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>

View File

@ -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'];

View File

@ -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);
});
});
});

View File

@ -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

View File

@ -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
}

View File

@ -25,3 +25,7 @@
.font.small {
font-size: 0.65em
}
.font.bold {
font-weight: bold
}

View File

View File

@ -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',
}

View File

@ -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

View File

@ -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>

View File

@ -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.`,
}
},
},

View File

@ -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 {

View File

@ -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>

View File

@ -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>

View File

@ -10,6 +10,7 @@ module.exports = {
claims: 'Reclama',
reference: 'Referencia',
concept: 'Concepto',
clientSignature: 'Firma del cliente',
claim: 'Reclamación {0}',
sections: {
agency: {

View File

@ -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
}

View File

@ -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>

View File

@ -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: {

View File

@ -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}'
},
},

View File

@ -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 -->

View File

@ -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>

View File

@ -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>

View File

@ -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 -->