Changes made

This commit is contained in:
Joan Sanchez 2021-02-24 07:51:05 +01:00
parent 20d9a99f6b
commit bb45d78062
21 changed files with 491 additions and 316 deletions

View File

@ -36,13 +36,14 @@ module.exports = {
* Makes a query from a SQL file * Makes a query from a SQL file
* @param {String} queryName - The SQL file name * @param {String} queryName - The SQL file name
* @param {Object} params - Parameterized values * @param {Object} params - Parameterized values
* @param {Object} connection - Optional pool connection
* *
* @return {Object} - Result promise * @return {Object} - Result promise
*/ */
rawSqlFromDef(queryName, params) { rawSqlFromDef(queryName, params, connection) {
const query = fs.readFileSync(`${queryName}.sql`, 'utf8'); const query = fs.readFileSync(`${queryName}.sql`, 'utf8');
return this.rawSql(query, params); return this.rawSql(query, params, connection);
}, },
/** /**

View File

@ -19,12 +19,13 @@ const dbHelper = {
* Makes a query from a SQL file * Makes a query from a SQL file
* @param {String} queryName - The SQL file name * @param {String} queryName - The SQL file name
* @param {Object} params - Parameterized values * @param {Object} params - Parameterized values
* @param {Object} connection - Optional pool connection
* *
* @return {Object} - Result promise * @return {Object} - Result promise
*/ */
rawSqlFromDef(queryName, params) { rawSqlFromDef(queryName, params, connection) {
const absolutePath = path.join(__dirname, '../', this.tplPath, 'sql', queryName); const absolutePath = path.join(__dirname, '../', this.tplPath, 'sql', queryName);
return db.rawSqlFromDef(absolutePath, params); return db.rawSqlFromDef(absolutePath, params, connection);
}, },
/** /**

View File

@ -6,11 +6,16 @@ module.exports = app => {
const reportName = req.params.name; const reportName = req.params.name;
const fileName = getFileName(reportName, req.args); const fileName = getFileName(reportName, req.args);
const report = new Report(reportName, req.args); const report = new Report(reportName, req.args);
if (req.args.preview) {
const template = await report.render();
res.send(template);
} else {
const stream = await report.toPdfStream(); const stream = await report.toPdfStream();
res.setHeader('Content-type', 'application/pdf'); res.setHeader('Content-type', 'application/pdf');
res.setHeader('Content-Disposition', `inline; filename="${fileName}"`); res.setHeader('Content-Disposition', `inline; filename="${fileName}"`);
res.end(stream); res.end(stream);
}
} catch (error) { } catch (error) {
next(error); next(error);
} }

View File

@ -37,6 +37,7 @@ FROM vn.sale s
LEFT JOIN taxClass tcl ON tcl.id = itc.taxClassFk LEFT JOIN taxClass tcl ON tcl.id = itc.taxClassFk
LEFT JOIN itemBotanicalWithGenus ib ON ib.itemFk = i.id LEFT JOIN itemBotanicalWithGenus ib ON ib.itemFk = i.id
AND ic.code = 'plant' AND ic.code = 'plant'
AND ib.ediBotanic IS NOT NULL
WHERE s.ticketFk = ? WHERE s.ticketFk = ?
GROUP BY s.id GROUP BY s.id
ORDER BY (it.isPackaging), s.concept, s.itemFk ORDER BY (it.isPackaging), s.concept, s.itemFk

View File

@ -1,23 +1,16 @@
#signature {
padding-right: 10px
}
#signature img {
-webkit-filter: brightness(0%);
filter: brightness(0%);
margin-bottom: 10px;
max-width: 150px
}
.description strong {
text-transform: uppercase;
}
h2 { h2 {
font-weight: 100; font-weight: 100;
color: #555 color: #555
} }
.table-title {
margin-bottom: 15px
}
.table-title h2 {
margin: 0 15px 0 0
}
.ticket-info { .ticket-info {
font-size: 26px font-size: 26px
} }

View File

@ -5,6 +5,11 @@
<tbody> <tbody>
<tr> <tr>
<td> <td>
<!-- Header block -->
<delivery-note v-bind="$props"></delivery-note>
<!-- Header block --> <!-- Header block -->
<report-header v-bind="$props" <report-header v-bind="$props"
v-bind:company-code="invoice.companyCode"> v-bind:company-code="invoice.companyCode">
@ -12,7 +17,7 @@
<!-- Block --> <!-- Block -->
<div class="grid-row"> <div class="grid-row">
<div class="grid-block"> <div class="grid-block">
<div class="columns"> <div class="columns vn-mb-lg">
<div class="size50"> <div class="size50">
<div class="size75 vn-mt-ml"> <div class="size75 vn-mt-ml">
<h1 class="title uppercase">{{$t('title')}}</h1> <h1 class="title uppercase">{{$t('title')}}</h1>
@ -53,8 +58,53 @@
</div> </div>
</div> </div>
<!-- Rectified invoices block -->
<div class="size100 no-page-break" v-if="rectified.length > 0">
<h2>{{$t('rectifiedInvoices')}}</h2>
<table class="column-oriented">
<thead>
<tr>
<th>{{$t('invoice')}}</th>
<th>{{$t('issued')}}</th>
<th class="number">{{$t('amount')}}</th>
<th width="50%">{{$t('description')}}</th>
</tr>
</thead>
<tbody>
<tr v-for="row in rectified">
<td>{{row.ref}}</td>
<td>{{row.issued | date}}</td>
<td class="number">{{row.amount | currency('EUR', $i18n.locale)}}</td>
<td width="50%">{{row.description}}</td>
</tr>
</tbody>
</table>
</div>
<!-- End of rectified invoices block -->
<!-- Sales block --> <!-- Sales block -->
<h2>{{$t('saleLines')}}</h2> <div class="vn-mt-lg no-page-break" v-for="ticket in tickets">
<div class="table-title clearfix">
<div class="pull-left">
<h2>{{$t('deliveryNote')}}</strong>
</div>
<div class="pull-left vn-mr-md">
<div class="field rectangle">
<span>{{ticket.id}}</span>
</div>
</div>
<div class="pull-left">
<h2>Shipped</h2>
</div>
<div class="pull-left">
<div class="field rectangle">
<span>{{ticket.shipped | date}}</span>
</div>
</div>
<span class="pull-right">
<h2 style="max-width: 400px; text-overflow: ellipsis;white-space: nowrap;overflow: hidden;">{{ticket.nickname}}</h2>
</span>
</div>
<table class="column-oriented"> <table class="column-oriented">
<thead> <thead>
<tr> <tr>
@ -67,7 +117,7 @@
<th class="number">{{$t('amount')}}</th> <th class="number">{{$t('amount')}}</th>
</tr> </tr>
</thead> </thead>
<tbody v-for="sale in sales" class="no-page-break"> <tbody v-for="sale in ticket.sales" class="no-page-break">
<tr> <tr>
<td width="5%">{{sale.itemFk | zerofill('000000')}}</td> <td width="5%">{{sale.itemFk | zerofill('000000')}}</td>
<td class="number">{{sale.quantity}}</td> <td class="number">{{sale.quantity}}</td>
@ -96,78 +146,16 @@
<td colspan="6" class="font bold"> <td colspan="6" class="font bold">
<span class="pull-right">{{$t('subtotal')}}</span> <span class="pull-right">{{$t('subtotal')}}</span>
</td> </td>
<td class="number">{{getSubTotal() | currency('EUR', $i18n.locale)}}</td> <td class="number">{{subTotal(ticket) | currency('EUR', $i18n.locale)}}</td>
</tr> </tr>
</tfoot> </tfoot>
</table> </table>
</div>
<!-- End of sales block --> <!-- End of sales block -->
<div class="columns">
<!-- Services block-->
<div class="size100 no-page-break" v-if="services.length > 0">
<h2>{{$t('services')}}</h2>
<table class="column-oriented">
<thead>
<tr>
<th width="5%"></th>
<th class="number">{{$t('quantity')}}</th>
<th width="50%">{{$t('concept')}}</th>
<th class="number">{{$t('price')}}</th>
<th class="centered" width="5%"></th>
<th class="centered">{{$t('vat')}}</th>
<th class="number">{{$t('amount')}}</th>
</tr>
</thead>
<tbody>
<tr v-for="service in services">
<td width="5%"></td>
<td class="number">{{service.quantity}}</td>
<td width="50%">{{service.description}}</td>
<td class="number">{{service.price | currency('EUR', $i18n.locale)}}</td>
<td class="centered" width="5%"></td>
<td class="centered">{{service.taxDescription}}</td>
<td class="number">{{service.price | currency('EUR', $i18n.locale)}}</td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="6" class="font bold">
<span class="pull-right">{{$t('subtotal')}}</span>
</td>
<td class="number">{{serviceTotal | currency('EUR', $i18n.locale)}}</td>
</tr>
</tfoot>
</table>
</div>
<!-- End of services block -->
</div>
<div class="columns">
<!-- Packages block -->
<div id="packagings" class="size100 no-page-break" v-if="packagings.length > 0">
<h2>{{$t('packagings')}}</h2>
<table class="column-oriented">
<thead>
<tr>
<th>{{$t('reference')}}</th>
<th class="number">{{$t('quantity')}}</th>
<th wihth="75%">{{$t('concept')}}</th>
</tr>
</thead>
<tbody>
<tr v-for="packaging in packagings">
<td>{{packaging.itemFk | zerofill('000000')}}</td>
<td class="number">{{packaging.quantity}}</td>
<td width="85%">{{packaging.name}}</td>
</tr>
</tbody>
</table>
</div>
<!-- End of packages block -->
</div>
<div class="columns vn-mt-xl"> <div class="columns vn-mt-xl">
<!-- Taxes block --> <!-- Taxes block -->
<div id="taxes" class="size50 pull-right no-page-break" v-if="taxes"> <div id="taxes" class="size50 pull-right no-page-break" v-if="taxes">
<!-- <h2>{{$t('taxBreakdown')}}</h2> -->
<table class="column-oriented"> <table class="column-oriented">
<thead> <thead>
<tr> <tr>
@ -188,32 +176,39 @@
<tr v-for="tax in taxes"> <tr v-for="tax in taxes">
<td width="45%">{{tax.name}}</td> <td width="45%">{{tax.name}}</td>
<td width="25%" class="number"> <td width="25%" class="number">
{{tax.Base | currency('EUR', $i18n.locale)}} {{tax.base | currency('EUR', $i18n.locale)}}
</td> </td>
<td>{{tax.vatPercent | percentage}}</td> <td>{{tax.vatPercent | percentage}}</td>
<td class="number">{{tax.tax | currency('EUR', $i18n.locale)}}</td> <td class="number">{{tax.vat | currency('EUR', $i18n.locale)}}</td>
</tr> </tr>
</tbody> </tbody>
<tfoot> <tfoot>
<tr class="font bold"> <tr class="font bold">
<td width="45%">{{$t('subtotal')}}</td> <td width="45%">{{$t('subtotal')}}</td>
<td width="20%" class="number"> <td width="20%" class="number">
{{getTotalBase() | currency('EUR', $i18n.locale)}} {{sumTotal(taxes, 'base') | currency('EUR', $i18n.locale)}}
</td> </td>
<td></td> <td></td>
<td class="number">{{getTotalTax()| currency('EUR', $i18n.locale)}}</td> <td class="number">{{sumTotal(taxes, 'vat') | currency('EUR', $i18n.locale)}}</td>
</tr> </tr>
<tr class="font bold"> <tr class="font bold">
<td colspan="2">{{$t('total')}}</td> <td colspan="2">{{$t('total')}}</td>
<td colspan="2" class="number">{{getTotal() | currency('EUR', $i18n.locale)}}</td> <td colspan="2" class="number">{{taxTotal | currency('EUR', $i18n.locale)}}</td>
</tr> </tr>
</tfoot> </tfoot>
</table> </table>
<div class="panel" v-if="invoice.footNotes">
<div class="header">{{$t('notes')}}</div>
<div class="body">
<span>{{invoice.footNotes}}</span>
</div>
</div>
</div> </div>
<!-- End of taxes block --> <!-- End of taxes block -->
<!-- Phytosanitary block --> <!-- Phytosanitary block -->
<!-- <div id="phytosanitary" class="size50 pull-left no-page-break"> <div id="phytosanitary" class="size50 pull-left no-page-break">
<div class="panel"> <div class="panel">
<div class="body"> <div class="body">
<div class="flag"> <div class="flag">
@ -229,7 +224,7 @@
<div class="phytosanitary-info"> <div class="phytosanitary-info">
<div> <div>
<strong>A</strong> <strong>A</strong>
<span>{{getBotanical()}}</span> <span>{{botanical}}</span>
</div> </div>
<div> <div>
<strong>B</strong> <strong>B</strong>
@ -237,7 +232,7 @@
</div> </div>
<div> <div>
<strong>C</strong> <strong>C</strong>
<span>{{ticket.id}}</span> <span>{{ticketsId}}</span>
</div> </div>
<div> <div>
<strong>D</strong> <strong>D</strong>
@ -246,23 +241,66 @@
</div> </div>
</div> </div>
</div> </div>
</div> --> </div>
<!-- End of phytosanitary block --> <!-- End of phytosanitary block -->
</div> </div>
<div class="columns">
<!-- Signature block -->
<!-- <div class="size50 pull-left no-page-break"> <!-- Intrastat block -->
<div id="signature" class="panel" v-if="signature && signature.id"> <div class="size100 no-page-break" v-if="intrastat.length > 0">
<div class="header">{{$t('digitalSignature')}}</div> <h2>{{$t('intrastat')}}</h2>
<div class="body centered"> <table class="column-oriented">
<img v-bind:src="dmsPath"/> <thead>
<div>{{signature.created | date('%d-%m-%Y')}}</div> <tr>
<th>{{$t('code')}}</th>
<th width="50%">{{$t('description')}}</th>
<th class="number">{{$t('stems')}}</th>
<th class="number">{{$t('netKg')}}</th>
<th class="number">{{$t('amount')}}</th>
</tr>
</thead>
<tbody>
<tr v-for="row in intrastat">
<td>{{row.code}}</td>
<td width="50%">{{row.description}}</td>
<td class="number">{{row.stems | number($i18n.locale)}}</td>
<td class="number">{{row.netKg | number($i18n.locale)}}</td>
<td class="number">{{row.subtotal | currency('EUR', $i18n.locale)}}</td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="2"></td>
<td class="number">
<strong>{{sumTotal(intrastat, 'stems') | number($i18n.locale)}}</strong>
</td>
<td class="number">
<strong>{{sumTotal(intrastat, 'netKg') | number($i18n.locale)}}</strong>
</td>
<td class="number">
<strong>{{sumTotal(intrastat, 'subtotal') | currency('EUR', $i18n.locale)}}</strong>
</td>
</tr>
</tfoot>
</table>
</div>
<!-- End of intrastat block -->
<!-- Observations block -->
<div class="columns vn-mt-xl" v-if="invoice.payMethodCode == 'wireTransfer'">
<div class="size50 pull-left no-page-break" >
<div class="panel" >
<div class="header">{{$t('observations')}}</div>
<div class="body">
<div>{{$t('wireTransfer')}}</div>
<div>{{$t('accountNumber', [invoice.iban])}}</div>
</div> </div>
</div> </div>
</div> -->
<!-- End of signature block -->
</div> </div>
</div> </div>
<!-- End of observations block -->
</div>
</div> </div>
<!-- Footer block --> <!-- Footer block -->
<report-footer id="pageFooter" <report-footer id="pageFooter"

View File

@ -1,30 +1,34 @@
const config = require(`${appPath}/core/config`);
const Component = require(`${appPath}/core/component`); const Component = require(`${appPath}/core/component`);
const Report = require(`${appPath}/core/report`);
const reportHeader = new Component('report-header'); const reportHeader = new Component('report-header');
const reportFooter = new Component('report-footer'); const reportFooter = new Component('report-footer');
const md5 = require('md5'); const db = require(`${appPath}/core/database`);
const fs = require('fs-extra');
module.exports = { module.exports = {
name: 'invoice', name: 'invoice',
async serverPrefetch() { async serverPrefetch() {
this.invoice = await this.fetchInvoice(this.invoiceId); this.invoice = await this.fetchInvoice(this.invoiceId);
this.client = await this.fetchClient(this.invoiceId); this.client = await this.fetchClient(this.invoiceId);
this.address = {}; this.taxes = await this.fetchTaxes(this.invoiceId);
this.sales = []; this.intrastat = await this.fetchIntrastat(this.invoiceId);
this.services = []; this.rectified = await this.fetchRectified(this.invoiceId);
this.taxes = [];
this.packagings = []; const tickets = await this.fetchTickets(this.invoiceId);
/* this.client = await this.fetchClient(this.ticketId); const sales = await this.fetchSales(this.invoiceId);
this.ticket = await this.fetchTicket(this.ticketId);
this.sales = await this.fetchSales(this.ticketId); const map = new Map();
this.address = await this.fetchAddress(this.ticketId);
this.services = await this.fetchServices(this.ticketId); for (let ticket of tickets)
this.taxes = await this.fetchTaxes(this.ticketId); map.set(ticket.id, ticket);
this.packagings = await this.fetchPackagings(this.ticketId);
this.signature = await this.fetchSignature(this.ticketId); for (let sale of sales) {
const ticket = map.get(sale.ticketFk);
if (!ticket.sales) ticket.sales = [];
ticket.sales.push(sale);
}
this.tickets = tickets;
*/
if (!this.invoice) if (!this.invoice)
throw new Error('Something went wrong'); throw new Error('Something went wrong');
}, },
@ -32,16 +36,30 @@ module.exports = {
return {totalBalance: 0.00}; return {totalBalance: 0.00};
}, },
computed: { computed: {
/* dmsPath() { ticketsId() {
if (!this.signature) return; const tickets = this.tickets.map(ticket => ticket.id);
const hash = md5(this.signature.id.toString()).substring(0, 3); return tickets.join(', ');
const file = `${config.storage.root}/${hash}/${this.signature.id}.png`;
const src = fs.readFileSync(file);
const base64 = Buffer.from(src, 'utf8').toString('base64');
return `data:image/png;base64, ${base64}`;
}, },
botanical() {
let phytosanitary = [];
for (let ticket of this.tickets) {
for (let sale of ticket.sales) {
if (sale.botanical)
phytosanitary.push(sale.botanical);
}
}
return phytosanitary.filter((item, index) =>
phytosanitary.indexOf(item) == index
).join(', ');
},
taxTotal() {
const base = this.sumTotal(this.taxes, 'base');
const vat = this.sumTotal(this.taxes, 'vat');
return base + vat;
}
/*
serviceTotal() { serviceTotal() {
let total = 0.00; let total = 0.00;
this.services.forEach(service => { this.services.forEach(service => {
@ -55,65 +73,50 @@ module.exports = {
fetchInvoice(invoiceId) { fetchInvoice(invoiceId) {
return this.findOneFromDef('invoice', [invoiceId]); return this.findOneFromDef('invoice', [invoiceId]);
}, },
fetchClient(ticketId) { fetchClient(invoiceId) {
return this.findOneFromDef('client', [ticketId]); return this.findOneFromDef('client', [invoiceId]);
}, },
fetchAddress(ticketId) { fetchTickets(invoiceId) {
return this.findOneFromDef(`address`, [ticketId]); return this.rawSqlFromDef('tickets', [invoiceId]);
},
fetchSignature(ticketId) {
return this.findOneFromDef('signature', [ticketId]);
},
fetchTaxes(ticketId) {
return this.findOneFromDef(`taxes`, [ticketId]);
},
fetchSales(ticketId) {
return this.rawSqlFromDef('sales', [ticketId]);
},
fetchPackagings(ticketId) {
return this.rawSqlFromDef('packagings', [ticketId]);
},
fetchServices(ticketId) {
return this.rawSqlFromDef('services', [ticketId]);
}, },
async fetchSales(invoiceId) {
const connection = await db.pool.getConnection();
await this.rawSql(`DROP TEMPORARY TABLE IF EXISTS tmp.invoiceTickets`, connection);
await this.rawSqlFromDef('invoiceTickets', [invoiceId], connection);
getSubTotal() { const sales = this.rawSqlFromDef('sales', connection);
await this.rawSql(`DROP TEMPORARY TABLE tmp.invoiceTickets`, connection);
await connection.release();
return sales;
},
fetchTaxes(invoiceId) {
return this.rawSqlFromDef(`taxes`, [invoiceId]);
},
fetchIntrastat(invoiceId) {
return this.rawSqlFromDef(`intrastat`, [invoiceId]);
},
fetchRectified(invoiceId) {
return this.rawSqlFromDef(`rectified`, [invoiceId]);
},
subTotal(ticket) {
let subTotal = 0.00; let subTotal = 0.00;
this.sales.forEach(sale => { ticket.sales.forEach(sale => {
subTotal += sale.quantity * sale.price * (1 - sale.discount / 100); subTotal += sale.quantity * sale.price * (1 - sale.discount / 100);
}); });
return subTotal; 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() { getTotal() {
return this.getTotalBase() + this.getTotalTax(); return this.getTotalBase() + this.getTotalTax();
}, },
getBotanical() { sumTotal(rows, prop) {
let phytosanitary = []; let total = 0.00;
this.sales.forEach(sale => { for (let row of rows)
if (sale.botanical) total += parseFloat(row[prop]);
phytosanitary.push(sale.botanical);
});
return phytosanitary.filter((item, index) => return total;
phytosanitary.indexOf(item) == index
).join(', ');
} }
}, },
components: { components: {

View File

@ -4,7 +4,8 @@ clientId: Cliente
invoiceData: Datos de facturación invoiceData: Datos de facturación
fiscalId: CIF / NIF fiscalId: CIF / NIF
invoiceRef: Factura {0} invoiceRef: Factura {0}
saleLines: Líneas de pedido deliveryNote: Albarán
shipped: F. envío
date: Fecha date: Fecha
reference: Ref. reference: Ref.
quantity: Cant. quantity: Cant.
@ -20,6 +21,15 @@ fee: Cuota
total: Total total: Total
subtotal: Subtotal subtotal: Subtotal
taxBreakdown: Desglose impositivo taxBreakdown: Desglose impositivo
packagings: Cubos y embalajes notes: Notas
services: Servicios intrastat: Intrastat
code: Código
description: Descripción
stems: Tallos
netKg: KG Neto
rectifiedInvoices: Facturas rectificadas
issued: F. emisión
plantPassport: Pasaporte fitosanitario plantPassport: Pasaporte fitosanitario
observations: Observaciones
wireTransfer: "Forma de pago: Transferencia"
accountNumber: "Número de cuenta: {0}"

View File

@ -1,11 +0,0 @@
SELECT
a.nickname,
a.street,
a.postalCode,
a.city,
p.name province
FROM ticket t
JOIN address a ON a.clientFk = t.clientFk
AND a.id = t.addressFk
LEFT JOIN province p ON p.id = a.provinceFk
WHERE t.id = ?

View File

@ -1,5 +0,0 @@
SELECT io.amount, io.ref, io.issued, ict.description
FROM vn.invoiceCorrection ic
JOIN vn.invoiceOut io ON io.id = ic.correctedFk
JOIN vn.invoiceCorrectionType ict ON ict.id = ic.invoiceCorrectionTypeFk
where ic.correctingFk = #

View File

@ -0,0 +1,88 @@
SELECT
ir.id AS code,
ir.description AS description,
CAST(SUM(IFNULL(i.stems,1) * s.quantity) AS DECIMAL(10,2)) as stems,
CAST(SUM( weight) AS DECIMAL(10,2)) as netKg,
CAST(SUM((s.quantity * s.price * (100 - s.discount) / 100 )) AS DECIMAL(10,2)) AS subtotal
FROM vn.sale s
LEFT JOIN vn.saleVolume sv ON sv.saleFk = s.id
LEFT JOIN vn.ticket t ON t.id = s.ticketFk
LEFT JOIN vn.invoiceOut io ON io.ref = t.refFk
LEFT JOIN vn.item i ON i.id = s.itemFk
JOIN vn.intrastat ir ON ir.id = i.intrastatFk
WHERE io.id = ?
GROUP BY i.intrastatFk;
/* SELECT io.issued,
c.socialName,
c.street postalAddress,
IF (ios.taxAreaFk IS NOT NULL, CONCAT(cty.code, c.fi), c.fi) fi,
io.clientFk,
c.postcode,
c.city,
io.companyFk,
io.ref,
tc.code,
s.concept,
s.quantity,
s.price,
s.discount,
s.ticketFk,
t.shipped,
t.refFk,
a.nickname,
s.itemFk,
s.id saleFk,
pm.name AS pmname,
sa.iban,
c.phone,
MAX(t.packages) packages,
a.incotermsFk,
ic.name incotermsName ,
sub.description weight,
t.observations,
ca.fiscalName customsAgentName,
ca.street customsAgentStreet,
ca.nif customsAgentNif,
ca.phone customsAgentPhone,
ca.email customsAgentEmail,
CAST(sub2.volume AS DECIMAL (10,2)) volume,
sub3.intrastat
FROM vn.invoiceOut io
JOIN vn.supplier su ON su.id = io.companyFk
JOIN vn.client c ON c.id = io.clientFk
LEFT JOIN vn.province p ON p.id = c.provinceFk
JOIN vn.ticket t ON t.refFk = io.ref
LEFT JOIN (SELECT tob.ticketFk,tob.description
FROM vn.ticketObservation tob
LEFT JOIN vn.observationType ot ON ot.id = tob.observationTypeFk
WHERE ot.description = "Peso Aduana"
)sub ON sub.ticketFk = t.id
JOIN vn.address a ON a.id = t.addressFk
LEFT JOIN vn.incoterms ic ON ic.code = a.incotermsFk
LEFT JOIN vn.customsAgent ca ON ca.id = a.customsAgentFk
JOIN vn.sale s ON s.ticketFk = t.id
JOIN (SELECT SUM(volume) volume
FROM vn.invoiceOut io
JOIN vn.ticket t ON t.refFk = io.ref
JOIN vn.saleVolume sv ON sv.ticketFk = t.id
WHERE io.id = :invoiceId
)sub2 ON TRUE
JOIN vn.itemTaxCountry itc ON itc.countryFk = su.countryFk AND itc.itemFk = s.itemFk
JOIN vn.taxClass tc ON tc.id = itc.taxClassFk
LEFT JOIN vn.invoiceOutSerial ios ON ios.code = io.serial AND ios.taxAreaFk = 'CEE'
JOIN vn.country cty ON cty.id = c.countryFk
JOIN vn.payMethod pm ON pm.id = c .payMethodFk
JOIN vn.company co ON co.id=io.companyFk
JOIN vn.supplierAccount sa ON sa.id=co.supplierAccountFk
LEFT JOIN (SELECT GROUP_CONCAT(DISTINCT ir.description ORDER BY ir.description SEPARATOR '. ' ) as intrastat
FROM vn.ticket t
JOIN vn.invoiceOut io ON io.ref = t.refFk
JOIN vn.sale s ON t.id = s.ticketFk
JOIN vn.item i ON i.id = s.itemFk
JOIN vn.intrastat ir ON ir.id = i.intrastatFk
WHERE io.id = :invoiceId
)sub3 ON TRUE
WHERE io.id = :invoiceId
*/

View File

@ -3,8 +3,14 @@ SELECT
io.clientFk, io.clientFk,
io.companyFk, io.companyFk,
io.ref, io.ref,
cny.code companyCode pm.code AS payMethodCode,
FROM vn.invoiceOut io cny.code companyCode,
JOIN vn.client c ON c.id = io.clientFk sa.iban,
ios.footNotes
FROM invoiceOut io
JOIN client c ON c.id = io.clientFk
JOIN payMethod pm ON pm.id = c.payMethodFk
JOIN company cny ON cny.id = io.companyFk JOIN company cny ON cny.id = io.companyFk
JOIN supplierAccount sa ON sa.id = cny.supplierAccountFk
LEFT JOIN invoiceOutSerial ios ON ios.code = io.serial
WHERE io.id = ? WHERE io.id = ?

View File

@ -0,0 +1,20 @@
CREATE TEMPORARY TABLE tmp.invoiceTickets
ENGINE = MEMORY
SELECT
t.id AS ticketFk,
t.clientFk,
t.shipped,
t.nickname,
io.ref,
c.socialName,
sa.iban,
pm.name AS payMethod,
su.countryFk AS supplierCountryFk
FROM vn.invoiceOut io
JOIN vn.supplier su ON su.id = io.companyFk
JOIN vn.ticket t ON t.refFk = io.ref
JOIN vn.client c ON c.id = t.clientFk
JOIN vn.payMethod pm ON pm.id = c.payMethodFk
JOIN vn.company co ON co.id = io.companyFk
JOIN vn.supplierAccount sa ON sa.id = co.supplierAccountFk
WHERE io.id = ?

View File

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

View File

@ -0,0 +1,14 @@
SELECT CONCAT( 'A ', GROUP_CONCAT(DISTINCT(ib.ediBotanic) SEPARATOR ', '), CHAR(13,10), CHAR(13,10),
'B ES17462130', CHAR(13,10), CHAR(13,10),
'C ', GROUP_CONCAT(DISTINCT(t.id) SEPARATOR ', '), CHAR(13,10), CHAR(13,10),
'D ES' ) phytosanitary
FROM vn.ticket t
JOIN vn.sale s ON s.ticketFk = t.id
JOIN vn.item i ON i.id = s.itemFk
JOIN vn.itemType it ON it.id = i.typeFk
JOIN vn.itemCategory ic ON ic.id = it.categoryFk
JOIN vn.itemBotanicalWithGenus ib ON ib.itemfk = i.id
WHERE t.refFk = # AND
ic.`code` = 'plant' AND
ib.ediBotanic IS NOT NULL
ORDER BY ib.ediBotanic

View File

@ -0,0 +1,9 @@
SELECT
io.amount,
io.ref,
io.issued,
ict.description
FROM vn.invoiceCorrection ic
JOIN vn.invoiceOut io ON io.id = ic.correctedFk
JOIN vn.invoiceCorrectionType ict ON ict.id = ic.invoiceCorrectionTypeFk
where ic.correctingFk = ?

View File

@ -1,42 +1,59 @@
SELECT SELECT
s.id, it.ref,
it.socialName,
it.iban,
it.payMethod,
it.clientFk,
it.shipped,
it.nickname,
s.ticketFk,
s.itemFk, s.itemFk,
s.concept, s.concept,
s.quantity, s.quantity,
s.price, s.price,
s.price - SUM(IF(ctr.id = 6, sc.value, 0)) netPrice,
s.discount, s.discount,
i.size,
i.stems,
i.category,
it.id itemTypeId,
o.code AS origin,
i.inkFk,
s.ticketFk,
tcl.code vatType,
ib.ediBotanic botanical,
i.tag5, i.tag5,
i.value5, i.value5,
i.tag6, i.tag6,
i.value6, i.value6,
i.tag7, i.tag7,
i.value7 i.value7,
FROM vn.sale s tc.code AS vatType,
LEFT JOIN saleComponent sc ON sc.saleFk = s.id ib.ediBotanic botanical
LEFT JOIN component cr ON cr.id = sc.componentFk FROM tmp.invoiceTickets it
LEFT JOIN componentType ctr ON ctr.id = cr.typeFk JOIN vn.sale s ON s.ticketFk = it.ticketFk
LEFT JOIN item i ON i.id = s.itemFk 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
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 itemType it ON it.id = i.typeFk
LEFT JOIN itemCategory ic ON ic.id = it.categoryFk LEFT JOIN itemCategory ic ON ic.id = it.categoryFk
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 itemBotanicalWithGenus ib ON ib.itemFk = i.id LEFT JOIN itemBotanicalWithGenus ib ON ib.itemFk = i.id
AND ic.code = 'plant' AND ic.code = 'plant'
WHERE s.ticketFk = ? AND ib.ediBotanic IS NOT NULL
GROUP BY s.id JOIN vn.itemTaxCountry itc ON itc.countryFk = it.supplierCountryFk
ORDER BY (it.isPackaging), s.concept, s.itemFk AND itc.itemFk = s.itemFk
JOIN vn.taxClass tc ON tc.id = itc.taxClassFk
UNION ALL
SELECT
it.ref,
it.socialName,
it.iban,
it.payMethod,
it.clientFk,
it.shipped,
it.nickname,
it.ticketFk,
'',
ts.description concept,
ts.quantity,
ts.price,
0 discount,
NULL AS tag5,
NULL AS value5,
NULL AS tag6,
NULL AS value6,
NULL AS tag7,
NULL AS value7,
tc.code AS vatType,
NULL AS botanical
FROM tmp.invoiceTickets it
JOIN vn.ticketService ts ON ts.ticketFk = it.ticketFk
JOIN vn.taxClass tc ON tc.id = ts.taxClassFk

View File

@ -1,8 +0,0 @@
SELECT
tc.code taxDescription,
ts.description,
ts.quantity,
ts.price
FROM ticketService ts
JOIN taxClass tc ON tc.id = ts.taxClassFk
WHERE ts.ticketFk = ?

View File

@ -1,8 +0,0 @@
SELECT
d.id,
d.created
FROM ticket t
JOIN ticketDms dt ON dt.ticketFk = t.id
JOIN dms d ON d.id = dt.dmsFk
AND d.file LIKE '%.png'
WHERE t.id = ?

View File

@ -1,8 +1,11 @@
SELECT iot.* , pgc.*, IF(pe.equFk IS NULL, taxableBase, 0) AS Base, pgc.rate / 100 as vatPercent, ios.footNotes SELECT
FROM vn.invoiceOutTax iot iot.vat,
JOIN vn.pgc ON pgc.code = iot.pgcFk pgc.name,
LEFT JOIN vn.pgcEqu pe ON pe.equFk = pgc.code IF(pe.equFk IS NULL, taxableBase, 0) AS base,
JOIN vn.invoiceOut io ON io.id = iot.invoiceOutFk pgc.rate / 100 AS vatPercent
LEFT JOIN vn.invoiceOutSerial ios ON ios.code = io.serial FROM invoiceOutTax iot
WHERE invoiceOutFk = # JOIN pgc ON pgc.code = iot.pgcFk
LEFT JOIN pgcEqu pe ON pe.equFk = pgc.code
JOIN invoiceOut io ON io.id = iot.invoiceOutFk
WHERE invoiceOutFk = ?
ORDER BY iot.id ORDER BY iot.id

View File

@ -0,0 +1,7 @@
SELECT
t.id,
t.shipped,
t.nickname
FROM invoiceOut io
JOIN ticket t ON t.refFk = io.ref
WHERE io.id = ?