diff --git a/back/methods/image/upload.js b/back/methods/image/upload.js index a93ead6510..676a4b5fb5 100644 --- a/back/methods/image/upload.js +++ b/back/methods/image/upload.js @@ -48,7 +48,7 @@ module.exports = Self => { throw new UserError(`You don't have enough privileges`); if (process.env.NODE_ENV == 'test') - throw new UserError(`You can't upload images on the test environment`); + throw new UserError(`Action not allowed on the test environment`); // Upload file to temporary path const tempContainer = await TempContainer.container(args.collection); diff --git a/loopback/locale/es.json b/loopback/locale/es.json index 8d51568420..0a6c88f083 100644 --- a/loopback/locale/es.json +++ b/loopback/locale/es.json @@ -164,7 +164,7 @@ "Amount cannot be zero": "El importe no puede ser cero", "Company has to be official": "Empresa inválida", "You can not select this payment method without a registered bankery account": "No se puede utilizar este método de pago si no has registrado una cuenta bancaria", - "You can't upload images on the test environment": "No puedes subir imágenes en el entorno de pruebas", + "Action not allowed on the test environment": "Esta acción no está permitida en el entorno de pruebas", "The selected ticket is not suitable for this route": "El ticket seleccionado no es apto para esta ruta", "Sorts whole route": "Reordena ruta entera", "New ticket request has been created with price": "Se ha creado una nueva petición de compra '{{description}}' para el día {{shipped}}, con una cantidad de {{quantity}} y un precio de {{price}} €", diff --git a/modules/claim/front/summary/index.html b/modules/claim/front/summary/index.html index e9ec1e765f..0d52c7f473 100644 --- a/modules/claim/front/summary/index.html +++ b/modules/claim/front/summary/index.html @@ -199,7 +199,7 @@ - {{::action.sale.ticket.id | zeroFill:6}} + {{::action.sale.ticket.id}} {{::action.claimBeggining.description}} diff --git a/modules/invoiceOut/back/methods/invoiceOut/book.js b/modules/invoiceOut/back/methods/invoiceOut/book.js index 358de8fd5a..af495c1f0a 100644 --- a/modules/invoiceOut/back/methods/invoiceOut/book.js +++ b/modules/invoiceOut/back/methods/invoiceOut/book.js @@ -21,10 +21,20 @@ module.exports = Self => { }); Self.book = async ref => { - let ticketAddress = await Self.app.models.Ticket.findOne({where: {invoiceOut: ref}}); - let invoiceCompany = await Self.app.models.InvoiceOut.findOne({where: {ref: ref}}); - let [taxArea] = await Self.rawSql(`Select vn.addressTaxArea(?, ?) AS code`, [ticketAddress.address, invoiceCompany.company]); + const models = Self.app.models; + const ticketAddress = await models.Ticket.findOne({ + where: {invoiceOut: ref} + }); + const invoiceCompany = await models.InvoiceOut.findOne({ + where: {ref: ref} + }); + let query = 'SELECT vn.addressTaxArea(?, ?) AS code'; + const [taxArea] = await Self.rawSql(query, [ + ticketAddress.address, + invoiceCompany.company + ]); - return Self.rawSql(`CALL vn.invoiceOutAgain(?, ?)`, [ref, taxArea.code]); + query = 'CALL vn.invoiceOutAgain(?, ?)'; + return Self.rawSql(query, [ref, taxArea.code]); }; }; diff --git a/modules/invoiceOut/back/methods/invoiceOut/createPdf.js b/modules/invoiceOut/back/methods/invoiceOut/createPdf.js index c423d2cdbc..9bf4e93a3d 100644 --- a/modules/invoiceOut/back/methods/invoiceOut/createPdf.js +++ b/modules/invoiceOut/back/methods/invoiceOut/createPdf.js @@ -5,37 +5,26 @@ const path = require('path'); module.exports = Self => { Self.remoteMethodCtx('createPdf', { description: 'Creates an invoice PDF', - accessType: 'READ', + accessType: 'WRITE', accepts: [ { arg: 'id', - type: 'String', + type: 'number', description: 'The invoice id', http: {source: 'path'} } ], - returns: [ - { - arg: 'body', - type: 'file', - root: true - }, { - arg: 'Content-Type', - type: 'String', - http: {target: 'header'} - }, { - arg: 'Content-Disposition', - type: 'String', - http: {target: 'header'} - } - ], + returns: { + type: 'object', + root: true + }, http: { path: `/:id/createPdf`, - verb: 'GET' + verb: 'POST' } }); - Self.createPdf = async function(ctx, id, options = {}) { + Self.createPdf = async function(ctx, id, options) { const models = Self.app.models; const headers = ctx.req.headers; const origin = headers.origin; @@ -44,31 +33,54 @@ module.exports = Self => { if (process.env.NODE_ENV == 'test') throw new UserError(`Action not allowed on the test environment`); - const invoiceOut = await Self.findById(id); - await invoiceOut.updateAttributes({ - hasPdf: true - }); + let tx; + let newOptions = {}; - const response = got.stream(`${origin}/api/report/invoice`, { - query: { - authorization: authorization, - invoiceId: id - } - }); + if (typeof options == 'object') + Object.assign(newOptions, options); - const invoiceYear = invoiceOut.created.getFullYear().toString(); - const container = await models.InvoiceContainer.container(invoiceYear); - const rootPath = container.client.root; - const fileName = `${invoiceOut.ref}.pdf`; - const fileSrc = path.join(rootPath, invoiceYear, fileName); + if (!newOptions.transaction) { + tx = await Self.beginTransaction({}); + newOptions.transaction = tx; + } - const writeStream = fs.createWriteStream(fileSrc); - writeStream.on('open', () => { - response.pipe(writeStream); - }); + let fileSrc; + try { + const invoiceOut = await Self.findById(id, null, newOptions); + await invoiceOut.updateAttributes({ + hasPdf: true + }, newOptions); - writeStream.on('finish', async function() { - writeStream.end(); - }); + const response = got.stream(`${origin}/api/report/invoice`, { + query: { + authorization: authorization, + invoiceId: id + } + }); + + const invoiceYear = invoiceOut.created.getFullYear().toString(); + const container = await models.InvoiceContainer.container(invoiceYear); + const rootPath = container.client.root; + const fileName = `${invoiceOut.ref}.pdf`; + fileSrc = path.join(rootPath, invoiceYear, fileName); + + const writeStream = fs.createWriteStream(fileSrc); + writeStream.on('open', () => { + response.pipe(writeStream); + }); + + writeStream.on('finish', async function() { + writeStream.end(); + }); + + if (tx) await tx.commit(); + + return invoiceOut; + } catch (e) { + if (tx) await tx.rollback(); + if (fs.existsSync(fileSrc)) + await fs.unlink(fileSrc); + throw e; + } }; }; diff --git a/modules/invoiceOut/back/methods/invoiceOut/regenerate.js b/modules/invoiceOut/back/methods/invoiceOut/regenerate.js deleted file mode 100644 index 828db4c988..0000000000 --- a/modules/invoiceOut/back/methods/invoiceOut/regenerate.js +++ /dev/null @@ -1,46 +0,0 @@ -module.exports = Self => { - Self.remoteMethodCtx('regenerate', { - description: 'Sends an invoice to a regeneration queue', - accessType: 'WRITE', - accepts: [{ - arg: 'id', - type: 'number', - required: true, - description: 'The invoiceOut id', - http: {source: 'path'} - }], - returns: { - type: 'object', - root: true - }, - http: { - path: '/:id/regenerate', - verb: 'POST' - } - }); - - Self.regenerate = async(ctx, id) => { - const models = Self.app.models; - const tx = await Self.beginTransaction({}); - - try { - let options = {transaction: tx}; - - // Remove all invoice references from tickets - const invoiceOut = await models.InvoiceOut.findById(id, null, options); - await invoiceOut.updateAttributes({ - hasPdf: false - }); - - // Create invoice PDF - await models.InvoiceOut.createPdf(ctx, id); - - await tx.commit(); - - return invoiceOut; - } catch (e) { - await tx.rollback(); - throw e; - } - }; -}; diff --git a/modules/invoiceOut/back/methods/invoiceOut/specs/regenerate.spec.js b/modules/invoiceOut/back/methods/invoiceOut/specs/regenerate.spec.js deleted file mode 100644 index 2d495ea0e7..0000000000 --- a/modules/invoiceOut/back/methods/invoiceOut/specs/regenerate.spec.js +++ /dev/null @@ -1,36 +0,0 @@ -const app = require('vn-loopback/server/server'); - -describe('invoiceOut regenerate()', () => { - const invoiceReportFk = 30; - const invoiceOutId = 1; - - it('should check that the invoice has a PDF and is not in print generation queue', async() => { - const invoiceOut = await app.models.InvoiceOut.findById(invoiceOutId); - const [queue] = await app.models.InvoiceOut.rawSql(` - SELECT COUNT(*) AS total - FROM vn.printServerQueue - WHERE reportFk = ?`, [invoiceReportFk]); - - expect(invoiceOut.hasPdf).toBeTruthy(); - expect(queue.total).toEqual(0); - }); - - it(`should mark the invoice as doesn't have PDF and add it to a print queue`, async() => { - const ctx = {req: {accessToken: {userId: 5}}}; - const invoiceOut = await app.models.InvoiceOut.regenerate(ctx, invoiceOutId); - const [queue] = await app.models.InvoiceOut.rawSql(` - SELECT COUNT(*) AS total - FROM vn.printServerQueue - WHERE reportFk = ?`, [invoiceReportFk]); - - expect(invoiceOut.hasPdf).toBeFalsy(); - expect(queue.total).toEqual(1); - - // restores - const invoiceOutToRestore = await app.models.InvoiceOut.findById(invoiceOutId); - await invoiceOutToRestore.updateAttributes({hasPdf: true}); - await app.models.InvoiceOut.rawSql(` - DELETE FROM vn.printServerQueue - WHERE reportFk = ?`, [invoiceReportFk]); - }); -}); diff --git a/modules/invoiceOut/back/models/invoiceOut.js b/modules/invoiceOut/back/models/invoiceOut.js index 10c36b37ca..e84a0495e1 100644 --- a/modules/invoiceOut/back/models/invoiceOut.js +++ b/modules/invoiceOut/back/models/invoiceOut.js @@ -2,7 +2,6 @@ module.exports = Self => { require('../methods/invoiceOut/filter')(Self); require('../methods/invoiceOut/summary')(Self); require('../methods/invoiceOut/download')(Self); - require('../methods/invoiceOut/regenerate')(Self); require('../methods/invoiceOut/delete')(Self); require('../methods/invoiceOut/book')(Self); require('../methods/invoiceOut/createPdf')(Self); diff --git a/modules/invoiceOut/front/descriptor/index.html b/modules/invoiceOut/front/descriptor/index.html index fe22e4dd82..b4c76d8085 100644 --- a/modules/invoiceOut/front/descriptor/index.html +++ b/modules/invoiceOut/front/descriptor/index.html @@ -25,6 +25,14 @@ translate> Book invoice + + Regenerate invoice PDF +
@@ -81,4 +89,12 @@ - \ No newline at end of file + + + + + \ No newline at end of file diff --git a/modules/invoiceOut/front/descriptor/index.js b/modules/invoiceOut/front/descriptor/index.js index cb4b131ac7..3e859478d0 100644 --- a/modules/invoiceOut/front/descriptor/index.js +++ b/modules/invoiceOut/front/descriptor/index.js @@ -22,6 +22,16 @@ class Controller extends Descriptor { .then(() => this.vnApp.showSuccess(this.$t('InvoiceOut booked'))); } + createInvoicePdf() { + const invoiceId = this.invoiceOut.id; + return this.$http.post(`InvoiceOuts/${invoiceId}/createPdf`) + .then(() => { + const snackbarMessage = this.$t( + `The invoice PDF document has been regenerated`); + this.vnApp.showSuccess(snackbarMessage); + }); + } + get filter() { if (this.invoiceOut) return JSON.stringify({refFk: this.invoiceOut.ref}); diff --git a/modules/invoiceOut/front/descriptor/locale/es.yml b/modules/invoiceOut/front/descriptor/locale/es.yml index e85be96bfa..dd67660ee4 100644 --- a/modules/invoiceOut/front/descriptor/locale/es.yml +++ b/modules/invoiceOut/front/descriptor/locale/es.yml @@ -8,4 +8,6 @@ InvoiceOut deleted: Factura eliminada Are you sure you want to delete this invoice?: Estas seguro de eliminar esta factura? Book invoice: Asentar factura InvoiceOut booked: Factura asentada -Are you sure you want to book this invoice?: Estas seguro de querer asentar esta factura? \ No newline at end of file +Are you sure you want to book this invoice?: Estas seguro de querer asentar esta factura? +Regenerate invoice PDF: Regenerar PDF factura +The invoice PDF document has been regenerated: El documento PDF de la factura ha sido regenerado \ No newline at end of file diff --git a/modules/ticket/back/methods/ticket/makeInvoice.js b/modules/ticket/back/methods/ticket/makeInvoice.js index 9500ab2a28..a44c41e169 100644 --- a/modules/ticket/back/methods/ticket/makeInvoice.js +++ b/modules/ticket/back/methods/ticket/makeInvoice.js @@ -67,7 +67,7 @@ module.exports = function(Self) { if (serial != 'R' && invoiceId) { await Self.rawSql('CALL invoiceOutBooking(?)', [invoiceId], options); - await models.InvoiceOut.createPdf(ctx, invoiceId); + await models.InvoiceOut.createPdf(ctx, invoiceId, options); } await tx.commit(); diff --git a/modules/ticket/front/descriptor-menu/index.html b/modules/ticket/front/descriptor-menu/index.html index 80ad71d5fe..390d9daf7c 100644 --- a/modules/ticket/front/descriptor-menu/index.html +++ b/modules/ticket/front/descriptor-menu/index.html @@ -80,13 +80,13 @@ Make invoice - Regenerate invoice + Regenerate invoice PDF - + + vn-id="createInvoicePdfConfirmation" + on-accept="$ctrl.createInvoicePdf()" + question="Are you sure you want to regenerate the invoice PDF document?" + message="You are going to regenerate the invoice PDF document"> diff --git a/modules/ticket/front/descriptor-menu/index.js b/modules/ticket/front/descriptor-menu/index.js index d2dea6c0ab..09783ec20e 100644 --- a/modules/ticket/front/descriptor-menu/index.js +++ b/modules/ticket/front/descriptor-menu/index.js @@ -219,12 +219,12 @@ class Controller extends Section { .then(() => this.vnApp.showSuccess(this.$t('Ticket invoiced'))); } - regenerateInvoice() { + createInvoicePdf() { const invoiceId = this.ticket.invoiceOut.id; - return this.$http.post(`InvoiceOuts/${invoiceId}/regenerate`) + return this.$http.post(`InvoiceOuts/${invoiceId}/createPdf`) .then(() => { const snackbarMessage = this.$t( - `Invoice sent for a regeneration, will be available in a few minutes`); + `The invoice PDF document has been regenerated`); this.vnApp.showSuccess(snackbarMessage); }); } diff --git a/modules/ticket/front/descriptor/locale/es.yml b/modules/ticket/front/descriptor/locale/es.yml index 6524df353c..c2b181c97e 100644 --- a/modules/ticket/front/descriptor/locale/es.yml +++ b/modules/ticket/front/descriptor/locale/es.yml @@ -17,12 +17,12 @@ Make a payment: "Verdnatura le comunica:\rSu pedido está pendiente de pago.\rPo Minimum is needed: "Verdnatura le recuerda:\rEs necesario un importe mínimo de 50€ (Sin IVA) en su pedido {{ticketId}} del día {{created | date: 'dd/MM/yyyy'}} para recibirlo sin portes adicionales." Ticket invoiced: Ticket facturado Make invoice: Crear factura -Regenerate invoice: Regenerar factura +Regenerate invoice PDF: Regenerar PDF factura +The invoice PDF document has been regenerated: El documento PDF de la factura ha sido regenerado You are going to invoice this ticket: Vas a facturar este ticket Are you sure you want to invoice this ticket?: ¿Seguro que quieres facturar este ticket? -You are going to regenerate the invoice: Vas a regenerar la factura -Are you sure you want to regenerate the invoice?: ¿Seguro que quieres regenerar la factura? -Invoice sent for a regeneration, will be available in a few minutes: La factura ha sido enviada para ser regenerada, estará disponible en unos minutos +You are going to regenerate the invoice PDF document: Vas a regenerar el documento PDF de la factura +Are you sure you want to regenerate the invoice PDF document?: ¿Seguro que quieres regenerar el documento PDF de la factura? Shipped hour updated: Hora de envio modificada Deleted ticket: Ticket eliminado Recalculate components: Recalcular componentes