feat(invoiceIn): email
gitea/salix/pipeline/head There was a failure building this commit Details

This commit is contained in:
Alex Moreno 2022-10-24 15:15:23 +02:00
parent d29d1ff538
commit 9e0eab5a77
21 changed files with 199 additions and 10 deletions

View File

@ -0,0 +1,4 @@
INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`)
VALUES
('InvoiceIn', 'invoiceInPdf', 'READ', 'ALLOW', 'ROLE', 'administrative'),
('InvoiceIn', 'invoiceInEmail', 'WRITE', 'ALLOW', 'ROLE', 'administrative'),

View File

@ -0,0 +1,56 @@
const {Email} = require('vn-print');
module.exports = Self => {
Self.remoteMethodCtx('invoiceInEmail', {
description: 'Sends the invoice in email with an attached PDF',
accessType: 'WRITE',
accepts: [
{
arg: 'id',
type: 'number',
required: true,
description: 'The invoice id',
http: {source: 'path'}
},
{
arg: 'recipient',
type: 'string',
description: 'The recipient email',
required: true,
},
{
arg: 'recipientId',
type: 'number',
description: 'The recipient id to send to the recipient preferred language',
required: false
}
],
returns: {
type: ['object'],
root: true
},
http: {
path: '/:id/invoice-in-email',
verb: 'POST'
}
});
Self.invoiceInEmail = async(ctx, id) => {
const args = Object.assign({}, ctx.args);
const params = {
recipient: 'alexm@verdnatura.es', // args.recipient,
lang: ctx.req.getLocale()
};
console.log(id);
delete args.ctx;
for (const param in args)
params[param] = args[param];
console.log(params);
const email = new Email('invoiceIn', params);
return email.send();
};
};

View File

@ -29,17 +29,16 @@ module.exports = Self => {
}
],
http: {
path: '/:id/invoiceInPdf',
path: '/:id/invoice-in-pdf',
verb: 'GET'
}
});
Self.invoiceInPdf = async(ctx, id) => {
console.log(id);
const args = Object.assign({}, ctx.args);
const params = {lang: ctx.req.getLocale()};
delete args.ctx;
console.log(args);
for (const param in args)
params[param] = args[param];

View File

@ -5,4 +5,5 @@ module.exports = Self => {
require('../methods/invoice-in/toBook')(Self);
require('../methods/invoice-in/getTotals')(Self);
require('../methods/invoice-in/invoiceInPdf')(Self);
require('../methods/invoice-in/invoiceInEmail')(Self);
};

View File

@ -94,6 +94,11 @@
"model": "Supplier",
"foreignKey": "supplierFk"
},
"supplierContact": {
"type": "hasMany",
"model": "SupplierContact",
"foreignKey": "supplierFk"
},
"currency": {
"type": "belongsTo",
"model": "Currency",

View File

@ -8,6 +8,14 @@ class Controller extends ModuleCard {
{
relation: 'supplier'
},
{
relation: 'supplierContact',
scope: {
where: {
email: {neq: null}
}
}
},
{
relation: 'invoiceInDueDay'
},

View File

@ -31,7 +31,7 @@
Show Invoice as PDF
</vn-item>
<vn-item
ng-click="sendPdfConfirmation.show({email: $ctrl.entity})"
ng-click="sendPdfConfirmation.show({email: $ctrl.entity.supplierContact[0].email})"
translate>
Send Invoice as PDF
</vn-item>
@ -99,7 +99,6 @@
on-accept="$ctrl.sendPdfInvoice($data)"
message="Send PDF invoice">
<tpl-body>
{{sendPdfConfirmation.data.email}}
<span translate>Are you sure you want to send it?</span>
<vn-textfield vn-one
label="Email"

View File

@ -8,6 +8,7 @@ class Controller extends Descriptor {
set invoiceIn(value) {
this.entity = value;
console.log(value);
}
get entryFilter() {
@ -96,8 +97,19 @@ class Controller extends Descriptor {
.then(() => this.$state.reload())
.then(() => this.vnApp.showSuccess(this.$t('InvoiceIn booked')));
}
showPdfInvoice() {
this.vnReport.show(`InvoiceIns/${this.id}/invoiceInPdf`);
this.vnReport.show(`InvoiceIns/${this.id}/invoice-in-pdf`);
}
sendPdfInvoice($data) {
if (!$data.email)
return this.vnApp.showError(this.$t(`The email can't be empty`));
return this.vnEmail.send(`InvoiceIns/${this.entity.id}/invoice-in-email`, {
recipient: $data.email,
recipientId: this.entity.supplier.id
});
}
}

View File

@ -7,4 +7,4 @@ copyLink: 'Como alternativa, podes copiar o siguinte link no teu navegador:'
poll: Si o deseja, podes responder nosso questionário de satiscação para ajudar-nos a prestar-vos um melhor serviço. Tua opinião é muito importante para nós!
help: Cualquer dúvida que surja, no hesites em consultar-la, <strong>Estamos aqui para
atender-te!</strong>
conclusion: Obrigado por tua atenção!
conclusion: Obrigado por tua atenção!

View File

@ -0,0 +1,11 @@
const Stylesheet = require(`vn-print/core/stylesheet`);
const path = require('path');
const vnPrintPath = path.resolve('print');
module.exports = new Stylesheet([
`${vnPrintPath}/common/css/spacing.css`,
`${vnPrintPath}/common/css/misc.css`,
`${vnPrintPath}/common/css/layout.css`,
`${vnPrintPath}/common/css/email.css`])
.mergeStyles();

View File

@ -0,0 +1,6 @@
[
{
"filename": "invoiceIn.pdf",
"component": "invoiceIn"
}
]

View File

@ -0,0 +1,47 @@
<!DOCTYPE html>
<html v-bind:lang="$i18n.locale">
<head>
<meta name="viewport" content="width=device-width">
<meta name="format-detection" content="telephone=no">
<title>{{ $t('subject') }}</title>
</head>
<body>
<table class="grid">
<tbody>
<tr>
<td>
<!-- Empty block -->
<div class="grid-row">
<div class="grid-block empty"></div>
</div>
<!-- Header block -->
<div class="grid-row">
<div class="grid-block">
<email-header v-bind="$props"></email-header>
</div>
</div>
<!-- Block -->
<div class="grid-row">
<div class="grid-block vn-pa-ml">
<h1>{{ $t('title') }}</h1>
<p>{{$t('dear')}},</p>
<p v-html="$t('description')"></p>
<p v-html="$t('conclusion')"></p>
</div>
</div>
<!-- Footer block -->
<div class="grid-row">
<div class="grid-block">
<email-footer v-bind="$props"></email-footer>
</div>
</div>
<!-- Empty block -->
<div class="grid-row">
<div class="grid-block empty"></div>
</div>
</td>
</tr>
</tbody>
</table>
</body>
</html>

View File

@ -0,0 +1,19 @@
const Component = require(`vn-print/core/component`);
const emailHeader = new Component('email-header');
const emailFooter = new Component('email-footer');
module.exports = {
name: 'invoiceIn',
async serverPrefetch() {
this.invoice = await this.fetchInvoice(this.id);
},
methods: {
fetchInvoice(reference) {
return this.findOneFromDef('invoice', [reference]);
},
},
components: {
'email-header': emailHeader.build(),
'email-footer': emailFooter.build()
}
};

View File

@ -0,0 +1,5 @@
subject: Your agricultural invoice
title: Your agricultural invoice
dear: Dear supplier
description: Attached you can find agricultural receipt generated from your last deliveries. Please return a signed and stamped copy to our administration department.
conclusion: Thanks for your attention!

View File

@ -0,0 +1,5 @@
subject: Tu factura agrícola
title: Tu factura agrícola
dear: Estimado proveedor
description: Adjunto puede encontrar recibo agrícola generado de sus últimas entregas. Por favor, devuelva una copia firmada y sellada a nuestro de departamento de administración.
conclusion: ¡Gracias por tu atención!

View File

@ -0,0 +1,5 @@
subject: Votre facture agricole
title: Votre facture agricole
dear: Cher Fournisseur
description: Vous trouverez en pièce jointe le reçu agricole généré à partir de vos dernières livraisons. Veuillez retourner une copie signée et tamponnée à notre service administratif.
conclusion: Merci pour votre attention!

View File

@ -0,0 +1,5 @@
subject: A sua fatura agrícola
title: A sua fatura agrícola
dear: Caro Fornecedor
description: Em anexo encontra-se o recibo agrícola gerado a partir das suas últimas entregas. Por favor, devolva uma cópia assinada e carimbada ao nosso departamento de administração.
conclusion: Obrigado pela atenção.

View File

@ -201,6 +201,7 @@
</div>
<!-- Footer block -->
<report-footer id="pageFooter"
v-bind:company-code="invoice.companyCode"
v-bind:left-text="$t('invoice', [invoice.id])"
v-bind:center-text="invoice.name"
v-bind="$props">

View File

@ -1,6 +1,6 @@
reportName: invoice
title: Agrobusiness invoice
invoiceId: Agrobusiness invoice
title: Agricultural invoice
invoiceId: Agricultural invoice
supplierId: Proveedor
invoiceData: Invoice data
reference: Reference

View File

@ -6,7 +6,8 @@ SELECT
s.street AS postalAddress,
s.nif,
s.phone,
p.name payMethod
p.name payMethod,
c.companyCode
FROM invoiceIn i
JOIN supplier s ON s.id = i.supplierFk
JOIN company c ON c.id = i.companyFk