feat(exportation): added exportation report & send report with client invoicing
gitea/salix/pipeline/head This commit looks good
Details
gitea/salix/pipeline/head This commit looks good
Details
Refs: 3254
This commit is contained in:
parent
b055618577
commit
66830f32fd
|
@ -9,19 +9,19 @@
|
||||||
"properties": {
|
"properties": {
|
||||||
"id": {
|
"id": {
|
||||||
"id": true,
|
"id": true,
|
||||||
"type": "Number"
|
"type": "number"
|
||||||
},
|
},
|
||||||
"sender": {
|
"receiver": {
|
||||||
"type": "String"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"replyTo": {
|
"replyTo": {
|
||||||
"type": "String"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"subject": {
|
"subject": {
|
||||||
"type": "String"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"body": {
|
"body": {
|
||||||
"type": "String"
|
"type": "string"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"acls": [
|
"acls": [
|
||||||
|
|
|
@ -8,6 +8,7 @@ class Controller extends ModuleCard {
|
||||||
'id',
|
'id',
|
||||||
'ref',
|
'ref',
|
||||||
'issued',
|
'issued',
|
||||||
|
'serial',
|
||||||
'amount',
|
'amount',
|
||||||
'clientFk',
|
'clientFk',
|
||||||
'companyFk',
|
'companyFk',
|
||||||
|
|
|
@ -69,6 +69,12 @@
|
||||||
translate>
|
translate>
|
||||||
{{!$ctrl.invoiceOut.hasPdf ? 'Generate PDF invoice': 'Regenerate PDF invoice'}}
|
{{!$ctrl.invoiceOut.hasPdf ? 'Generate PDF invoice': 'Regenerate PDF invoice'}}
|
||||||
</vn-item>
|
</vn-item>
|
||||||
|
<vn-item
|
||||||
|
ng-click="$ctrl.showExportationLetter()"
|
||||||
|
ng-show="$ctrl.invoiceOut.serial == 'E'"
|
||||||
|
translate>
|
||||||
|
Show CIES letter
|
||||||
|
</vn-item>
|
||||||
</slot-menu>
|
</slot-menu>
|
||||||
<slot-body>
|
<slot-body>
|
||||||
<div class="attributes">
|
<div class="attributes">
|
||||||
|
|
|
@ -98,6 +98,13 @@ class Controller extends Descriptor {
|
||||||
invoiceId: this.id
|
invoiceId: this.id
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
showExportationLetter() {
|
||||||
|
this.vnReport.show('exportation', {
|
||||||
|
recipientId: this.invoiceOut.client.id,
|
||||||
|
invoiceId: this.id,
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ngModule.vnComponent('vnInvoiceOutDescriptor', {
|
ngModule.vnComponent('vnInvoiceOutDescriptor', {
|
||||||
|
|
|
@ -8,12 +8,13 @@ Send PDF invoice: Enviar factura en PDF
|
||||||
Send CSV invoice: Enviar factura en CSV
|
Send CSV invoice: Enviar factura en CSV
|
||||||
Delete Invoice: Eliminar factura
|
Delete Invoice: Eliminar factura
|
||||||
Clone Invoice: Clonar factura
|
Clone Invoice: Clonar factura
|
||||||
|
Book invoice: Asentar factura
|
||||||
|
Generate PDF invoice: Generar PDF factura
|
||||||
|
Show CIES letter: Ver carta CIES
|
||||||
InvoiceOut deleted: Factura eliminada
|
InvoiceOut deleted: Factura eliminada
|
||||||
Are you sure you want to delete this invoice?: Estas seguro de eliminar esta factura?
|
Are you sure you want to delete this invoice?: Estas seguro de eliminar esta factura?
|
||||||
Are you sure you want to clone this invoice?: Estas seguro de clonar esta factura?
|
Are you sure you want to clone this invoice?: Estas seguro de clonar esta factura?
|
||||||
Book invoice: Asentar factura
|
|
||||||
InvoiceOut booked: Factura asentada
|
InvoiceOut booked: Factura asentada
|
||||||
Are you sure you want to book this invoice?: Estas seguro de querer asentar esta factura?
|
Are you sure you want to book this invoice?: Estas seguro de querer asentar esta factura?
|
||||||
Generate PDF invoice: Generar PDF factura
|
|
||||||
Regenerate PDF invoice: Regenerar PDF factura
|
Regenerate PDF invoice: Regenerar PDF factura
|
||||||
The invoice PDF document has been regenerated: El documento PDF de la factura ha sido regenerado
|
The invoice PDF document has been regenerated: El documento PDF de la factura ha sido regenerado
|
|
@ -26,7 +26,7 @@ module.exports = Self => {
|
||||||
const user = await models.user.findById(loopBackContext.active.accessToken.userId);
|
const user = await models.user.findById(loopBackContext.active.accessToken.userId);
|
||||||
const bankEntity = await models.BankEntity.findById(ctx.instance.bankEntityFk);
|
const bankEntity = await models.BankEntity.findById(ctx.instance.bankEntityFk);
|
||||||
await Self.app.models.Mail.create({
|
await Self.app.models.Mail.create({
|
||||||
sender: 'finanzas@verdnatura.es',
|
receiver: 'finanzas@verdnatura.es',
|
||||||
subject: 'Añadida cuenta bancaria al proveedor' + ctx.instance.supplierFk,
|
subject: 'Añadida cuenta bancaria al proveedor' + ctx.instance.supplierFk,
|
||||||
body: user.username + ' ha añadido: ' +
|
body: user.username + ' ha añadido: ' +
|
||||||
ctx.instance.iban + ', entidad: ' + bankEntity.name + ', bic: ' + bankEntity.bic
|
ctx.instance.iban + ', entidad: ' + bankEntity.name + ', bic: ' + bankEntity.bic
|
||||||
|
|
|
@ -174,7 +174,7 @@ module.exports = Self => {
|
||||||
const emailSubject = subject + ' ' + user.name;
|
const emailSubject = subject + ' ' + user.name;
|
||||||
|
|
||||||
await Self.app.models.Mail.create({
|
await Self.app.models.Mail.create({
|
||||||
sender: sendTo,
|
receiver: sendTo,
|
||||||
subject: emailSubject,
|
subject: emailSubject,
|
||||||
body: emailBody
|
body: emailBody
|
||||||
});
|
});
|
||||||
|
|
|
@ -87,7 +87,7 @@ module.exports = Self => {
|
||||||
await models.Mail.create({
|
await models.Mail.create({
|
||||||
subject: $t('Absence change notification on the labour calendar'),
|
subject: $t('Absence change notification on the labour calendar'),
|
||||||
body: body,
|
body: body,
|
||||||
sender: department.notificationEmail
|
receiver: department.notificationEmail
|
||||||
}, myOptions);
|
}, myOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -71,7 +71,7 @@ module.exports = Self => {
|
||||||
await models.Mail.create({
|
await models.Mail.create({
|
||||||
subject: $t('Absence change notification on the labour calendar'),
|
subject: $t('Absence change notification on the labour calendar'),
|
||||||
body: body,
|
body: body,
|
||||||
sender: department.notificationEmail
|
receiver: department.notificationEmail
|
||||||
}, myOptions);
|
}, myOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -257,16 +257,3 @@ table {
|
||||||
background-color: #FFF;
|
background-color: #FFF;
|
||||||
padding: 5px
|
padding: 5px
|
||||||
}
|
}
|
||||||
|
|
||||||
.signature {
|
|
||||||
width: 100%
|
|
||||||
}
|
|
||||||
|
|
||||||
.signature section {
|
|
||||||
height: 150px
|
|
||||||
}
|
|
||||||
|
|
||||||
.signature p {
|
|
||||||
margin-right: 50%;
|
|
||||||
margin-top: 140px
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
const db = require('../core/database');
|
const db = require('../core/database');
|
||||||
const Email = require('../core/email');
|
const Email = require('../core/email');
|
||||||
|
const Report = require('../core/report');
|
||||||
const smtp = require('../core/smtp');
|
const smtp = require('../core/smtp');
|
||||||
const config = require('../core/config');
|
const config = require('../core/config');
|
||||||
|
|
||||||
|
@ -195,7 +196,8 @@ module.exports = app => {
|
||||||
if (!ticket.recipient) {
|
if (!ticket.recipient) {
|
||||||
const body = `No se ha podido enviar el albarán <strong>${ticket.id}</strong>
|
const body = `No se ha podido enviar el albarán <strong>${ticket.id}</strong>
|
||||||
al cliente <strong>${ticket.clientFk}</strong> porque no tiene un email especificado.<br/><br/>
|
al cliente <strong>${ticket.clientFk}</strong> porque no tiene un email especificado.<br/><br/>
|
||||||
Para dejar de recibir esta notificación, asígnale un email o desactiva la notificación por email para este cliente.`;
|
Para dejar de recibir esta notificación, asígnale un email o desactiva
|
||||||
|
la notificación por email para este cliente.`;
|
||||||
smtp.send({
|
smtp.send({
|
||||||
to: ticket.salesPersonEmail,
|
to: ticket.salesPersonEmail,
|
||||||
subject: 'No se ha podido enviar el albarán',
|
subject: 'No se ha podido enviar el albarán',
|
||||||
|
@ -207,22 +209,37 @@ module.exports = app => {
|
||||||
|
|
||||||
const hasToInvoice = ticket.hasToInvoice && ticket.hasDailyInvoice;
|
const hasToInvoice = ticket.hasToInvoice && ticket.hasDailyInvoice;
|
||||||
if (hasToInvoice) {
|
if (hasToInvoice) {
|
||||||
const invoiceId = await db.findValue(`
|
const invoice = await db.findOne(`
|
||||||
SELECT io.id
|
SELECT io.id, io.ref, io.serial, cny.code companyCode
|
||||||
FROM ticket t
|
FROM ticket t
|
||||||
JOIN invoiceOut io ON io.ref = t.refFk
|
JOIN invoiceOut io ON io.ref = t.refFk
|
||||||
|
JOIN company cny ON cny.id = io.companyFk
|
||||||
WHERE t.id = ?
|
WHERE t.id = ?
|
||||||
`, [ticket.id]);
|
`, [ticket.id]);
|
||||||
|
|
||||||
const args = Object.assign({
|
const args = Object.assign({
|
||||||
invoiceId: invoiceId,
|
invoiceId: invoice.id,
|
||||||
recipientId: ticket.clientFk,
|
recipientId: ticket.clientFk,
|
||||||
recipient: ticket.recipient,
|
recipient: ticket.recipient,
|
||||||
replyTo: ticket.salesPersonEmail
|
replyTo: ticket.salesPersonEmail
|
||||||
}, reqArgs);
|
}, reqArgs);
|
||||||
|
|
||||||
|
let mailOptions = {};
|
||||||
|
if (invoice.serial == 'E' && invoice.companyCode == 'VNL') {
|
||||||
|
const exportation = new Report('exportation', args);
|
||||||
|
const stream = await exportation.toPdfStream();
|
||||||
|
const fileName = `exportation-${invoice.ref}.pdf`;
|
||||||
|
mailOptions = {
|
||||||
|
overrideAttachments: false,
|
||||||
|
attachments: [{
|
||||||
|
filename: fileName,
|
||||||
|
content: stream
|
||||||
|
}]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
const email = new Email('invoice', args);
|
const email = new Email('invoice', args);
|
||||||
await email.send();
|
await email.send(mailOptions);
|
||||||
} else {
|
} else {
|
||||||
const args = Object.assign({
|
const args = Object.assign({
|
||||||
ticketId: ticket.id,
|
ticketId: ticket.id,
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
const Stylesheet = require(`${appPath}/core/stylesheet`);
|
||||||
|
|
||||||
|
module.exports = new Stylesheet([
|
||||||
|
`${appPath}/common/css/layout.css`,
|
||||||
|
`${appPath}/common/css/report.css`,
|
||||||
|
`${appPath}/common/css/misc.css`,
|
||||||
|
`${__dirname}/style.css`])
|
||||||
|
.mergeStyles();
|
|
@ -0,0 +1,12 @@
|
||||||
|
.grid-block {
|
||||||
|
font-size: 1.2em
|
||||||
|
}
|
||||||
|
|
||||||
|
ul li {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
text-align: justify;
|
||||||
|
}
|
||||||
|
|
||||||
|
.signature img {
|
||||||
|
width: 400px
|
||||||
|
}
|
Binary file not shown.
After Width: | Height: | Size: 101 KiB |
|
@ -0,0 +1,51 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html v-bind:lang="$i18n.locale">
|
||||||
|
<body>
|
||||||
|
<table class="grid">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<!-- Header block -->
|
||||||
|
<report-header v-bind="$props"></report-header>
|
||||||
|
<!-- Block -->
|
||||||
|
<div class="grid-row">
|
||||||
|
<div class="grid-block">
|
||||||
|
<h1 class="title centered uppercase">{{$t('title')}}</h1>
|
||||||
|
<p>{{$t('toAttention')}}</p>
|
||||||
|
<p v-html="$t('declaration', [invoice.ref, issued])"></p>
|
||||||
|
<p>
|
||||||
|
<ul>
|
||||||
|
<li v-for="responsibility in $t('responsibilities')">
|
||||||
|
{{responsibility}}
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</p>
|
||||||
|
<div class="signature">
|
||||||
|
<p>{{$t('issued', [
|
||||||
|
'Algemesí',
|
||||||
|
invoice.issued.getDate(),
|
||||||
|
$t('months')[invoice.issued.getMonth()],
|
||||||
|
invoice.issued.getFullYear()])
|
||||||
|
}}
|
||||||
|
</p>
|
||||||
|
<p><em>({{$t('signature')}})</em></p>
|
||||||
|
<img v-bind:src="getReportSrc('signature.png')">
|
||||||
|
<p>
|
||||||
|
<div>{{$t('signer.name')}}: JUAN VICENTE FERRER ROIG</div>
|
||||||
|
<div>{{$t('signer.ID')}}: 73943586N</div>
|
||||||
|
<div>{{$t('signer.position')}}: ADMINISTRADOR</div>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- Footer block -->
|
||||||
|
<report-footer id="pageFooter"
|
||||||
|
v-bind:left-text="$t('invoice', [invoice.ref])"
|
||||||
|
v-bind="$props">
|
||||||
|
</report-footer>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,34 @@
|
||||||
|
const Component = require(`${appPath}/core/component`);
|
||||||
|
const reportHeader = new Component('report-header');
|
||||||
|
const reportFooter = new Component('report-footer');
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
name: 'exportation',
|
||||||
|
async serverPrefetch() {
|
||||||
|
this.invoice = await this.fetchInvoice(this.invoiceId);
|
||||||
|
|
||||||
|
if (!this.invoice)
|
||||||
|
throw new Error('Something went wrong');
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
fetchInvoice(invoiceId) {
|
||||||
|
return this.findOneFromDef('invoice', [invoiceId]);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
issued: function() {
|
||||||
|
const filters = this.$options.filters;
|
||||||
|
|
||||||
|
return filters.date(this.invoice.issued, '%d-%m-%Y');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
'report-header': reportHeader.build(),
|
||||||
|
'report-footer': reportFooter.build()
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
invoiceId: {
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
|
@ -0,0 +1,50 @@
|
||||||
|
title: 'Carta CITES'
|
||||||
|
toAttention: 'A la atención del Sr. Administrador de la Aduana de la Farga de Moles.'
|
||||||
|
declaration: 'Por la presente DECLARO, bajo mi responsabilidad, que las mercancías detalladas en la factura
|
||||||
|
n° <strong>{0}</strong> de fecha <strong>{1}</strong>
|
||||||
|
asi como ninguno de sus componentes,'
|
||||||
|
issued: 'En {0}, a {1} de {2} de {3}'
|
||||||
|
invoice: 'Factura {0}'
|
||||||
|
responsibilities:
|
||||||
|
- 'NO están comprendidas en la Convención de Washington (CITES). Reglamento (CE) n° 338/1997
|
||||||
|
DO L61 de 3.3.1997 y sus últimas modificaciones, relativo a la protección de especies de fauna y
|
||||||
|
flora silvestres.'
|
||||||
|
- 'NO están incluidas en las listas del Anexo I del R/CE 428/2009 y sus posteriores modificaciones,
|
||||||
|
por lo que NO puede considerarse productos ni tecnologias de Doble Uso ni de uso militar.
|
||||||
|
No estando incluidas en la Relación de Material de Defensa del Anexo I del Real Decreto
|
||||||
|
679/2014, estando exentas a todos los efectos de autorizaciones administrativas para su comercio
|
||||||
|
exterior.'
|
||||||
|
- 'NO están incluidas los Anexos II, III y IV del R/UE 2019/125 L-30 de 31/01/2019
|
||||||
|
y sus modificaciones, sobre el comercio de determinados productos que pueden utilizarse para
|
||||||
|
aplicar la pena de muerte o infligir tortura u otros tratos o penas crueles, inhumanos o
|
||||||
|
degradantes.'
|
||||||
|
- 'NO están incluidas en el ANEXO ni en el ANEXO V del Reglamento (UE) N° 649/2012 y
|
||||||
|
sus modificaciones, relativo a la exportación e importación de productos químicos
|
||||||
|
peligrosos. ni tampoco contienen mercurio.'
|
||||||
|
- 'NO están sujetas al Reglamento/CE 1005/2009 L-286 de 30-10-2009 y sus
|
||||||
|
modificaciones, relativo a las mercancías que agotan la capa de ozono.'
|
||||||
|
- 'NO están afectadas por la prohibición a las importaciones de gases fluorados de
|
||||||
|
efecto invernadero, de acuerdo con el R/UE 517/2014.'
|
||||||
|
- 'NO están sujetas al Reglamento (CE) 116/2009 relativo a la exportación de bienes
|
||||||
|
culturales; y NO están sujetas a la Ley 16/1985, de 25 de junio, del Patrimonio
|
||||||
|
Histórico Español, estando exentas de Autorización Administrativa de Exportación.'
|
||||||
|
- 'NO están sujetos a las disposiciones del Reglamento (CE) Nº 1013/2006, relativo
|
||||||
|
a los traslados de residuos, y que en ningún modo pueden considerarse afectados por este control.'
|
||||||
|
signature: Firma y sello de la empresa
|
||||||
|
signer:
|
||||||
|
name: Nombre del firmante
|
||||||
|
ID: DNI del firmante
|
||||||
|
position: Cargo del firmante
|
||||||
|
months:
|
||||||
|
- 'Enero'
|
||||||
|
- 'Febrero'
|
||||||
|
- 'Marzo'
|
||||||
|
- 'Abril'
|
||||||
|
- 'Mayo'
|
||||||
|
- 'Junio'
|
||||||
|
- 'Julio'
|
||||||
|
- 'Agosto'
|
||||||
|
- 'Septiembre'
|
||||||
|
- 'Octubre'
|
||||||
|
- 'Noviembre'
|
||||||
|
- 'Diciembre'
|
|
@ -0,0 +1,6 @@
|
||||||
|
SELECT
|
||||||
|
io.id,
|
||||||
|
io.ref,
|
||||||
|
io.issued
|
||||||
|
FROM invoiceOut io
|
||||||
|
WHERE io.id = ?
|
Loading…
Reference in New Issue