diff --git a/db/changes/10451-april/00-invoiceOut_queue.sql b/db/changes/10451-april/00-invoiceOut_queue.sql new file mode 100644 index 000000000..f60bcab77 --- /dev/null +++ b/db/changes/10451-april/00-invoiceOut_queue.sql @@ -0,0 +1,14 @@ +create table `vn`.`invoiceOut_queue` +( + invoiceFk int(10) unsigned not null, + queued datetime default now() not null, + printed datetime null, + `status` VARCHAR(50) default '' null, + constraint invoiceOut_queue_pk + primary key (invoiceFk), + constraint invoiceOut_queue_invoiceOut_id_fk + foreign key (invoiceFk) references invoiceOut (id) + on update cascade on delete cascade +) + comment 'Queue for PDF invoicing'; + diff --git a/modules/client/front/notification/index.js b/modules/client/front/notification/index.js index 12a1a4acb..0506ea4ba 100644 --- a/modules/client/front/notification/index.js +++ b/modules/client/front/notification/index.js @@ -81,7 +81,7 @@ export default class Controller extends Section { clientIds: clientIds }, this.campaign); - this.$http.post('notify/consumption', params) + this.$http.post('schedule/consumption', params) .then(() => this.$.filters.hide()) .then(() => this.vnApp.showSuccess(this.$t('Notifications sent!'))); } diff --git a/modules/client/front/notification/index.spec.js b/modules/client/front/notification/index.spec.js index 13c6bc513..8847357f7 100644 --- a/modules/client/front/notification/index.spec.js +++ b/modules/client/front/notification/index.spec.js @@ -74,7 +74,7 @@ describe('Client notification', () => { clientIds: [1101, 1102] }, controller.campaign); - $httpBackend.expect('POST', `notify/consumption`, params).respond(200, params); + $httpBackend.expect('POST', `schedule/consumption`, params).respond(200, params); controller.onSendClientConsumption(); $httpBackend.flush(); diff --git a/modules/invoiceOut/back/methods/invoiceOut/globalInvoicing.js b/modules/invoiceOut/back/methods/invoiceOut/globalInvoicing.js index 6b901872e..7f2cbb442 100644 --- a/modules/invoiceOut/back/methods/invoiceOut/globalInvoicing.js +++ b/modules/invoiceOut/back/methods/invoiceOut/globalInvoicing.js @@ -1,5 +1,3 @@ -const UserError = require('vn-loopback/util/user-error'); - module.exports = Self => { Self.remoteMethodCtx('globalInvoicing', { description: 'Make a global invoice', @@ -140,6 +138,9 @@ module.exports = Self => { if (newInvoice.id) { await Self.rawSql('CALL invoiceOutBooking(?)', [newInvoice.id], myOptions); + query = `INSERT IGNORE INTO invoiceOut_queue(invoiceFk) VALUES(?)`; + await Self.rawSql(query, [newInvoice.id], myOptions); + invoicesIds.push(newInvoice.id); } } catch (e) { @@ -160,10 +161,6 @@ module.exports = Self => { throw e; } - // Print invoices PDF - for (let invoiceId of invoicesIds) - await Self.createPdf(ctx, invoiceId); - return invoicesIds; }; @@ -212,7 +209,13 @@ module.exports = Self => { const query = `SELECT c.id, - SUM(IFNULL(s.quantity * s.price * (100-s.discount)/100, 0) + IFNULL(ts.quantity * ts.price,0)) AS sumAmount, + SUM(IFNULL + ( + s.quantity * + s.price * (100-s.discount)/100, + 0) + + IFNULL(ts.quantity * ts.price,0) + ) AS sumAmount, c.hasToInvoiceByAddress, c.email, c.isToBeMailed, diff --git a/modules/invoiceOut/front/index/global-invoicing/index.html b/modules/invoiceOut/front/index/global-invoicing/index.html index 9fd412d0e..3d245b8d8 100644 --- a/modules/invoiceOut/front/index/global-invoicing/index.html +++ b/modules/invoiceOut/front/index/global-invoicing/index.html @@ -19,7 +19,7 @@ ng-if="$ctrl.isInvoicing"> - Invoicing in progress... + Adding invoices to queue... @@ -66,5 +66,5 @@ - + \ No newline at end of file diff --git a/modules/invoiceOut/front/index/global-invoicing/locale/es.yml b/modules/invoiceOut/front/index/global-invoicing/locale/es.yml index 51e165e2a..1a6e15656 100644 --- a/modules/invoiceOut/front/index/global-invoicing/locale/es.yml +++ b/modules/invoiceOut/front/index/global-invoicing/locale/es.yml @@ -1,7 +1,7 @@ Create global invoice: Crear factura global Some fields are required: Algunos campos son obligatorios Max date: Fecha límite -Invoicing in progress...: Facturación en progreso... +Adding invoices to queue...: Añadiendo facturas a la cola... Invoice date: Fecha de factura From client: Desde el cliente To client: Hasta el cliente diff --git a/print/methods/routes.js b/print/methods/routes.js index ea40e0743..28671b3da 100644 --- a/print/methods/routes.js +++ b/print/methods/routes.js @@ -16,7 +16,7 @@ module.exports = [ cb: require('./closure') }, { - url: '/api/notify', - cb: require('./notify') + url: '/api/schedule', + cb: require('./schedule') } ]; diff --git a/print/methods/notify/consumption.js b/print/methods/schedule/consumption.js similarity index 100% rename from print/methods/notify/consumption.js rename to print/methods/schedule/consumption.js diff --git a/print/methods/notify/index.js b/print/methods/schedule/index.js similarity index 76% rename from print/methods/notify/index.js rename to print/methods/schedule/index.js index df4705d1e..05d54b2ed 100644 --- a/print/methods/notify/index.js +++ b/print/methods/schedule/index.js @@ -2,5 +2,6 @@ const express = require('express'); const router = new express.Router(); router.post('/consumption', require('./consumption')); +router.post('/invoice', require('./invoice')); module.exports = router; diff --git a/print/methods/schedule/invoice.js b/print/methods/schedule/invoice.js new file mode 100644 index 000000000..c76ca85b5 --- /dev/null +++ b/print/methods/schedule/invoice.js @@ -0,0 +1,114 @@ +const db = require('vn-print/core/database'); +const Email = require('vn-print/core/email'); +const Report = require('vn-print/core/report'); +const storage = require('vn-print/core/storage'); + +module.exports = async function(request, response, next) { + try { + response.status(200).json({ + message: 'Success' + }); + + const invoices = await db.rawSql(` + SELECT + io.id, + io.clientFk, + io.issued, + io.ref, + c.email recipient, + c.salesPersonFk, + c.isToBeMailed, + c.hasToInvoice, + co.hasDailyInvoice, + eu.email salesPersonEmail + FROM invoiceOut_queue ioq + JOIN invoiceOut io ON io.id = ioq.invoiceFk + JOIN client c ON c.id = io.clientFk + JOIN province p ON p.id = c.provinceFk + JOIN country co ON co.id = p.countryFk + LEFT JOIN account.emailUser eu ON eu.userFk = c.salesPersonFk + WHERE status = ''`); + + let connection; + let invoiceId; + for (const invoiceOut of invoices) { + try { + invoiceId = invoiceOut.id; + connection = await db.getConnection(); + connection.query('START TRANSACTION'); + + const args = Object.assign({ + invoiceId: invoiceOut.id, + recipientId: invoiceOut.clientFk, + recipient: invoiceOut.recipient, + replyTo: invoiceOut.salesPersonEmail + }, response.locals); + + const invoiceReport = new Report('invoice', args); + const stream = await invoiceReport.toPdfStream(); + + const issued = invoiceOut.issued; + const year = issued.getFullYear().toString(); + const month = (issued.getMonth() + 1).toString(); + const day = issued.getDate().toString(); + + const fileName = `${year}${invoiceOut.ref}.pdf`; + + // Store invoice + storage.write(stream, { + type: 'invoice', + path: `${year}/${month}/${day}`, + fileName: fileName + }); + + connection.query('UPDATE invoiceOut SET hasPdf = true WHERE id = ?', [invoiceOut.id]); + + const isToBeMailed = invoiceOut.recipient && invoiceOut.salesPersonFk && invoiceOut.isToBeMailed; + + if (isToBeMailed) { + const mailOptions = { + overrideAttachments: true, + attachments: [] + }; + + const invoiceAttachment = { + filename: fileName, + content: stream + }; + + if (invoiceOut.serial == 'E' && invoiceOut.companyCode == 'VNL') { + const exportation = new Report('exportation', args); + const stream = await exportation.toPdfStream(); + const fileName = `CITES-${invoiceOut.ref}.pdf`; + + mailOptions.attachments.push({ + filename: fileName, + content: stream + }); + } + + mailOptions.attachments.push(invoiceAttachment); + + const email = new Email('invoice', args); + await email.send(mailOptions); + } + // Update queue status + sql = `UPDATE invoiceOut_queue + SET status = "printed", + printed = NOW() + WHERE invoiceFk = ?`; + connection.query(sql, [invoiceOut.id]); + connection.query('COMMIT'); + } catch (error) { + connection.query('ROLLBACK'); + connection.release(); + sql = `UPDATE invoiceOut_queue + SET status = ? + WHERE invoiceFk = ?`; + await db.rawSql(sql, [error.message, invoiceId]); + } + } + } catch (error) { + next(error); + } +};