diff --git a/db/changes/230601/00-acl_receiptEmail.sql b/db/changes/230601/00-acl_receiptEmail.sql new file mode 100644 index 000000000..2de8adf50 --- /dev/null +++ b/db/changes/230601/00-acl_receiptEmail.sql @@ -0,0 +1,3 @@ +INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) + VALUES + ('Receipt', 'receiptEmail', '*', 'ALLOW', 'ROLE', 'salesAssistant'); diff --git a/modules/client/back/methods/receipt/receiptEmail.js b/modules/client/back/methods/receipt/receiptEmail.js new file mode 100644 index 000000000..cd529eece --- /dev/null +++ b/modules/client/back/methods/receipt/receiptEmail.js @@ -0,0 +1,57 @@ +const {Email} = require('vn-print'); + +module.exports = Self => { + Self.remoteMethodCtx('receiptEmail', { + description: 'Returns the receipt pdf', + accepts: [ + { + arg: 'id', + type: 'number', + required: true, + description: 'The claim id', + http: {source: 'path'} + }, + { + arg: 'recipient', + type: 'string', + description: 'The recipient email', + required: true, + } + ], + returns: [ + { + arg: 'body', + type: 'file', + root: true + }, { + arg: 'Content-Type', + type: 'String', + http: {target: 'header'} + }, { + arg: 'Content-Disposition', + type: 'String', + http: {target: 'header'} + } + ], + http: { + path: '/:id/receipt-email', + verb: 'POST' + } + }); + + Self.receiptEmail = async(ctx, id) => { + const args = Object.assign({}, ctx.args); + const params = { + recipient: args.recipient, + lang: ctx.req.getLocale() + }; + + delete args.ctx; + for (const param in args) + params[param] = args[param]; + + const email = new Email('receipt', params); + + return email.send(); + }; +}; diff --git a/modules/client/back/methods/receipt/receiptPdf.js b/modules/client/back/methods/receipt/receiptPdf.js index f55e05040..2dfae4e83 100644 --- a/modules/client/back/methods/receipt/receiptPdf.js +++ b/modules/client/back/methods/receipt/receiptPdf.js @@ -8,7 +8,7 @@ module.exports = Self => { arg: 'id', type: 'number', required: true, - description: 'The claim id', + description: 'The receipt id', http: {source: 'path'} }, { diff --git a/modules/client/back/models/receipt.js b/modules/client/back/models/receipt.js index 3118cc239..feb8ca053 100644 --- a/modules/client/back/models/receipt.js +++ b/modules/client/back/models/receipt.js @@ -5,6 +5,7 @@ module.exports = function(Self) { require('../methods/receipt/balanceCompensationEmail')(Self); require('../methods/receipt/balanceCompensationPdf')(Self); require('../methods/receipt/receiptPdf')(Self); + require('../methods/receipt/receiptEmail')(Self); Self.validateBinded('amountPaid', isNotZero, { message: 'Amount cannot be zero', diff --git a/modules/client/front/balance/create/index.html b/modules/client/front/balance/create/index.html index 56e505463..4f9fa07d2 100644 --- a/modules/client/front/balance/create/index.html +++ b/modules/client/front/balance/create/index.html @@ -11,7 +11,7 @@ @@ -80,13 +80,17 @@ - + + - \ No newline at end of file + diff --git a/modules/client/front/balance/create/index.js b/modules/client/front/balance/create/index.js index 68d19209d..57088c31f 100644 --- a/modules/client/front/balance/create/index.js +++ b/modules/client/front/balance/create/index.js @@ -2,10 +2,12 @@ import ngModule from '../../module'; import Dialog from 'core/components/dialog'; class Controller extends Dialog { - constructor($element, $, $transclude, vnReport) { + constructor($element, $, $transclude, vnReport, vnEmail) { super($element, $, $transclude); this.viewReceipt = true; + this.sendEmail = true; this.vnReport = vnReport; + this.vnEmail = vnEmail; this.receipt = {}; } @@ -24,6 +26,18 @@ class Controller extends Dialog { set clientFk(value) { this.receipt.clientFk = value; + + const filter = { + fields: ['email'], + where: { + id: value + } + }; + + this.$http.get(`Clients/findOne`, {filter}) + .then(res => { + this.receipt.email = res.data.email; + }); } get clientFk() { @@ -65,7 +79,8 @@ class Controller extends Dialog { this.receipt.description.push(accountingType.receiptDescription); if (this.originalDescription) this.receipt.description.push(this.originalDescription); - this.receipt.description.join(', '); + + this.receipt.description = this.receipt.description.join(', ').toString(); this.maxAmount = accountingType && accountingType.maxAmount; @@ -133,10 +148,13 @@ class Controller extends Dialog { return super.responseHandler(response); const exceededAmount = this.receipt.amountPaid > this.maxAmount; - - if (this.bankSelection.accountingType.code == 'cash' && exceededAmount) + const isCash = this.bankSelection.accountingType.code == 'cash'; + if (isCash && exceededAmount) return this.vnApp.showError(this.$t('Amount exceeded', {maxAmount: this.maxAmount})); + if (isCash && this.sendEmail && !this.receipt.email) + return this.vnApp.showError(this.$t('There is no assigned email for this client')); + let receiptId; return this.$http.post(`Clients/${this.clientFk}/createReceipt`, this.receipt) .then(res => { @@ -144,6 +162,13 @@ class Controller extends Dialog { super.responseHandler(response); }) .then(() => this.vnApp.showSuccess(this.$t('Data saved!'))) + .then(() => { + if (!this.sendEmail || !isCash) return; + const params = { + recipient: this.receipt.email + }; + this.vnEmail.send(`Receipts/${receiptId}/receipt-email`, params); + }) .then(() => { if (this.viewReceipt) this.vnReport.show(`Receipts/${receiptId}/receipt-pdf`); @@ -157,7 +182,7 @@ class Controller extends Dialog { } } -Controller.$inject = ['$element', '$scope', '$transclude', 'vnReport']; +Controller.$inject = ['$element', '$scope', '$transclude', 'vnReport', 'vnEmail']; ngModule.vnComponent('vnClientBalanceCreate', { slotTemplate: require('./index.html'), diff --git a/modules/client/front/balance/create/locale/es.yml b/modules/client/front/balance/create/locale/es.yml index 056590966..f8c23afdb 100644 --- a/modules/client/front/balance/create/locale/es.yml +++ b/modules/client/front/balance/create/locale/es.yml @@ -1,2 +1,4 @@ View receipt: Ver recibo -Amount exceeded: Según ley contra el fraude no se puede recibir cobros por importe igual o superior a {{maxAmount}} \ No newline at end of file +Amount exceeded: Según ley contra el fraude no se puede recibir cobros por importe igual o superior a {{maxAmount}} +Send email: Enviar correo +There is no assigned email for this client: No hay correo asignado para este cliente diff --git a/modules/ticket/front/descriptor-menu/index.js b/modules/ticket/front/descriptor-menu/index.js index ff029db78..1a88b00d5 100644 --- a/modules/ticket/front/descriptor-menu/index.js +++ b/modules/ticket/front/descriptor-menu/index.js @@ -326,8 +326,13 @@ class Controller extends Section { return this.$http.post(`Docuwares/${this.id}/upload`, {fileCabinet: 'deliveryNote'}) .then(() => { - this.vnApp.showSuccess(this.$t('PDF sent!')); + this.$.balanceCreate.amountPaid = this.ticket.totalWithVat; + this.$.balanceCreate.clientFk = this.ticket.clientFk; + this.$.balanceCreate.description = 'Albaran: '; + this.$.balanceCreate.description += this.ticket.id; + this.$.balanceCreate.show(); + this.vnApp.showSuccess(this.$t('PDF sent!')); }); } } diff --git a/print/templates/email/receipt/assets/css/import.js b/print/templates/email/receipt/assets/css/import.js new file mode 100644 index 000000000..4b4bb7086 --- /dev/null +++ b/print/templates/email/receipt/assets/css/import.js @@ -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(); diff --git a/print/templates/email/receipt/attachments.json b/print/templates/email/receipt/attachments.json new file mode 100644 index 000000000..9930596e0 --- /dev/null +++ b/print/templates/email/receipt/attachments.json @@ -0,0 +1,6 @@ +[ + { + "filename": "receipt.pdf", + "component": "receipt" + } +] diff --git a/print/templates/email/receipt/locale/es.yml b/print/templates/email/receipt/locale/es.yml new file mode 100644 index 000000000..95883afaa --- /dev/null +++ b/print/templates/email/receipt/locale/es.yml @@ -0,0 +1,5 @@ +subject: Recibo +title: Recibo +dear: Estimado cliente +description: Ya está disponible el recibo {0}.
+ Puedes descargarlo haciendo clic en el adjunto de este correo. diff --git a/print/templates/email/receipt/receipt.html b/print/templates/email/receipt/receipt.html new file mode 100644 index 000000000..734552014 --- /dev/null +++ b/print/templates/email/receipt/receipt.html @@ -0,0 +1,9 @@ + +
+
+

{{ $t('title') }}

+

{{$t('dear')}},

+

+
+
+
diff --git a/print/templates/email/receipt/receipt.js b/print/templates/email/receipt/receipt.js new file mode 100755 index 000000000..606534f4d --- /dev/null +++ b/print/templates/email/receipt/receipt.js @@ -0,0 +1,15 @@ +const Component = require(`vn-print/core/component`); +const emailBody = new Component('email-body'); + +module.exports = { + name: 'receipt', + components: { + 'email-body': emailBody.build(), + }, + props: { + id: { + type: Number, + required: true + } + } +};