Added invoice incoterms report
gitea/salix/pipeline/head There was a failure building this commit Details

This commit is contained in:
Joan Sanchez 2021-03-01 11:25:37 +01:00
parent cc00587b66
commit 1e36b460a1
14 changed files with 351 additions and 8 deletions

View File

@ -46,3 +46,7 @@
page-break-inside: avoid;
break-inside: avoid
}
.page-break-after {
page-break-after: always;
}

View File

@ -83,6 +83,11 @@ class Component {
component.template = juice.inlineContent(this.template, this.stylesheet, {
inlinePseudoElements: true
});
const tplPath = this.path;
if (!component.computed) component.computed = {};
component.computed.path = function() {
return tplPath;
};
return component;
}
@ -93,7 +98,7 @@ class Component {
const component = this.build();
const i18n = new VueI18n(config.i18n);
const props = {tplPath: this.path, ...this.args};
const props = {...this.args};
this._component = new Vue({
i18n: i18n,
render: h => h(component, {

View File

@ -24,7 +24,7 @@ const dbHelper = {
* @return {Object} - Result promise
*/
rawSqlFromDef(queryName, params, connection) {
const absolutePath = path.join(__dirname, '../', this.tplPath, 'sql', queryName);
const absolutePath = path.join(__dirname, '../', this.path, 'sql', queryName);
return db.rawSqlFromDef(absolutePath, params, connection);
},
@ -78,11 +78,11 @@ const dbHelper = {
* @return {Object} - SQL
*/
getSqlFromDef(queryName) {
const absolutePath = path.join(__dirname, '../', this.tplPath, 'sql', queryName);
const absolutePath = path.join(__dirname, '../', this.path, 'sql', queryName);
return db.getSqlFromDef(absolutePath);
},
},
props: ['tplPath']
props: ['tplPath', 'name']
};
Vue.mixin(dbHelper);

View File

@ -0,0 +1,9 @@
const Stylesheet = require(`${appPath}/core/stylesheet`);
module.exports = new Stylesheet([
`${appPath}/common/css/spacing.css`,
`${appPath}/common/css/misc.css`,
`${appPath}/common/css/layout.css`,
`${appPath}/common/css/report.css`,
`${__dirname}/style.css`])
.mergeStyles();

View File

@ -0,0 +1,29 @@
h2 {
font-weight: 100;
color: #555
}
.table-title {
margin-bottom: 15px;
font-size: 0.8rem
}
.table-title h2 {
margin: 0 15px 0 0
}
.ticket-info {
font-size: 22px
}
#incoterms table {
font-size: 1.2rem
}
#incoterms table th {
width: 10%
}
#incoterms p {
font-size: 1.2rem
}

View File

@ -0,0 +1,124 @@
<!DOCTYPE html>
<html v-bind:lang="$i18n.locale">
<body>
<table class="grid no-page-break page-break-after">
<tbody>
<tr>
<td>
<!-- Header block -->
<report-header v-bind="$props"
v-bind:company-code="invoice.companyCode">
</report-header>
<!-- Block -->
<div class="grid-row">
<div class="grid-block">
<div class="columns vn-mb-lg">
<div class="size50">
<div class="size75 vn-mt-ml">
<h1 class="title uppercase">{{$t('title')}}</h1>
<table class="row-oriented ticket-info">
<tbody>
<tr>
<td class="font gray uppercase">{{$t('clientId')}}</td>
<th>{{client.id}}</th>
</tr>
<tr>
<td class="font gray uppercase">{{$t('invoice')}}</td>
<th>{{invoice.ref}}</th>
</tr>
<tr>
<td class="font gray uppercase">{{$t('date')}}</td>
<th>{{invoice.issued | date('%d-%m-%Y')}}</th>
</tr>
</tbody>
</table>
</div>
</div>
<div class="size50">
<div class="panel">
<div class="header">{{$t('invoiceData')}}</div>
<div class="body">
<h3 class="uppercase">{{client.socialName}}</h3>
<div>
{{client.postalAddress}}
</div>
<div>
{{client.postcodeCity}}
</div>
<div>
{{$t('fiscalId')}}: {{client.fi}}
</div>
</div>
</div>
</div>
</div>
<div id="incoterms" class="panel">
<div class="header">{{$t('incotermsTitle')}}</div>
<div class="body">
<table class="row-oriented">
<tbody>
<tr>
<th>
{{$t('incoterms')}}
<div class="description">asd</div>
</th>
<td>{{incoterms.incotermsFk}} - {{incoterms.incotermsName}}</td>
</tr>
<tr>
<th>
{{$t('productDescription')}}
</th>
<td>{{incoterms.intrastat}}</td>
</tr>
<tr>
<th>{{$t('expeditionDescription')}}</th>
<td></td>
</tr>
<tr>
<th>{{$t('packageNumber')}}</th>
<td>{{incoterms.packages}}</td>
</tr>
<tr>
<th>{{$t('packageGrossWeight')}}</th>
<td>{{incoterms.weight}} KG</td>
</tr>
<tr>
<th>{{$t('packageCubing')}}</th>
<td>{{incoterms.volume}} m3</td>
</tr>
</tbody>
</table>
<p>
<div class="font bold">
<span>{{$t('customsInfo')}}</span>
<span>{{incoterms.customsAgentName}}</span>
</div>
<div class="font bold">
<span>(</span>
<span>{{incoterms.customsAgentNif}}</span>
<span>{{incoterms.customsAgentStreet}}</span>
<span v-if="incoterms.customsAgentPhone">
&#9742; {{incoterms.customsAgentPhone}}
</span>
<span v-if="incoterms.customsAgentEmail">
&#9993; {{incoterms.customsAgentEmail}}
</span>
<span>)</span>
</div>
</p>
<p>
<strong>{{$t('productDisclaimer')}}</strong>
</p>
</div>
</div>
</div>
</div>
</td>
</tr>
</tbody>
</table>
</body>
</html>

View File

@ -0,0 +1,40 @@
const Component = require(`${appPath}/core/component`);
const reportHeader = new Component('report-header');
const reportFooter = new Component('report-footer');
const db = require(`${appPath}/core/database`);
module.exports = {
name: 'invoice-incoterms',
async serverPrefetch() {
this.invoice = await this.fetchInvoice(this.invoiceId);
this.client = await this.fetchClient(this.invoiceId);
this.incoterms = await this.fetchIncoterms(this.invoiceId);
if (!this.invoice)
throw new Error('Something went wrong');
},
computed: {
},
methods: {
fetchInvoice(invoiceId) {
return this.findOneFromDef('invoice', [invoiceId]);
},
fetchClient(invoiceId) {
return this.findOneFromDef('client', [invoiceId]);
},
fetchIncoterms(invoiceId) {
return this.findOneFromDef('incoterms', {invoiceId});
}
},
components: {
'report-header': reportHeader.build(),
'report-footer': reportFooter.build()
},
props: {
invoiceId: {
type: String,
required: true
}
}
};

View File

@ -0,0 +1,16 @@
title: Factura
invoice: Factura
clientId: Cliente
date: Fecha
invoiceData: Datos de facturación
fiscalId: CIF / NIF
invoiceRef: Factura {0}
incotermsTitle: Información para la exportación
incoterms: Incoterms
productDescription: Descripción de la mercancia
expeditionDescription: INFORMACIÓN DE LA EXPEDICIÓN
packageNumber: Número de bultos
packageGrossWeight: Peso bruto
packageCubing: Cubicaje
customsInfo: A despachar por la agencia de aduanas
productDisclaimer: Mercancía destinada a la exportación, EXENTA de IVA (Ley 37/1992 - Art. 21)

View File

@ -0,0 +1,12 @@
SELECT
c.id,
c.socialName,
c.street AS postalAddress,
IF (ios.taxAreaFk IS NOT NULL, CONCAT(cty.code, c.fi), c.fi) fi,
CONCAT(c.postcode, ' - ', c.city) postcodeCity
FROM vn.invoiceOut io
JOIN vn.client c ON c.id = io.clientFk
JOIN vn.country cty ON cty.id = c.countryFk
LEFT JOIN vn.invoiceOutSerial ios ON ios.code = io.serial
AND ios.taxAreaFk = 'CEE'
WHERE io.id = ?

View File

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

@ -0,0 +1,17 @@
SELECT
io.id,
io.issued,
io.clientFk,
io.companyFk,
io.ref,
pm.code AS payMethodCode,
cny.code companyCode,
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 supplierAccount sa ON sa.id = cny.supplierAccountFk
LEFT JOIN invoiceOutSerial ios ON ios.code = io.serial
WHERE io.id = ?

View File

@ -6,9 +6,11 @@
<tr>
<td>
<!-- Header block -->
<delivery-note v-bind="$props"></delivery-note>
<!-- Incoterms block -->
<invoice-incoterms
v-if="hasIncoterms"
v-bind="$props">
</invoice-incoterms>
<!-- Header block -->
<report-header v-bind="$props"

View File

@ -2,6 +2,7 @@ const Component = require(`${appPath}/core/component`);
const Report = require(`${appPath}/core/report`);
const reportHeader = new Component('report-header');
const reportFooter = new Component('report-footer');
const invoiceIncoterms = new Report('invoice-incoterms');
const db = require(`${appPath}/core/database`);
module.exports = {
@ -12,6 +13,7 @@ module.exports = {
this.taxes = await this.fetchTaxes(this.invoiceId);
this.intrastat = await this.fetchIntrastat(this.invoiceId);
this.rectified = await this.fetchRectified(this.invoiceId);
this.hasIncoterms = await this.fetchHasIncoterms(this.invoiceId);
const tickets = await this.fetchTickets(this.invoiceId);
const sales = await this.fetchSales(this.invoiceId);
@ -91,6 +93,9 @@ module.exports = {
fetchRectified(invoiceId) {
return this.rawSqlFromDef(`rectified`, [invoiceId]);
},
fetchHasIncoterms(invoiceId) {
return this.findValueFromDef(`hasIncoterms`, [invoiceId]);
},
saleImport(sale) {
const price = sale.quantity * sale.price;
@ -113,7 +118,8 @@ module.exports = {
},
components: {
'report-header': reportHeader.build(),
'report-footer': reportFooter.build()
'report-footer': reportFooter.build(),
'invoice-incoterms': invoiceIncoterms.build()
},
props: {
invoiceId: {

View File

@ -0,0 +1,8 @@
SELECT IF(incotermsFk IS NULL, FALSE, TRUE) AS hasIncoterms
FROM ticket t
JOIN invoiceOut io ON io.ref = t.refFk
JOIN client c ON c.id = t.clientFk
JOIN address a ON a.id = t.addressFk
WHERE io.id = ?
AND IF(c.hasToinvoiceByAddress = FALSE, c.defaultAddressFk, TRUE)
LIMIT 1