From 5f27bb9f924a7012272a978b725cbfb3ceb961d3 Mon Sep 17 00:00:00 2001 From: joan Date: Tue, 28 Sep 2021 21:41:26 +0200 Subject: [PATCH 01/13] Storage folder rollback --- docker-compose.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 1d80a4b62d..f8d1c808b3 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -29,9 +29,9 @@ services: - source: print_local target: /etc/salix/print.local.json volumes: - - /mnt/appdata/pdfs:/var/lib/salix/pdfs - - /mnt/appdata/dms:/var/lib/salix/dms - - /mnt/appdata/image:/var/lib/salix/image + - /mnt/storage/pdfs:/var/lib/salix/pdfs + - /mnt/storage/dms:/var/lib/salix/dms + - /mnt/storage/image:/var/lib/salix/image deploy: replicas: ${BACK_REPLICAS:?} placement: From 148e40c71f7e20549260d859278a133bd2f481d7 Mon Sep 17 00:00:00 2001 From: joan Date: Tue, 28 Sep 2021 21:52:17 +0200 Subject: [PATCH 02/13] Changed again --- docker-compose.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index f8d1c808b3..1d80a4b62d 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -29,9 +29,9 @@ services: - source: print_local target: /etc/salix/print.local.json volumes: - - /mnt/storage/pdfs:/var/lib/salix/pdfs - - /mnt/storage/dms:/var/lib/salix/dms - - /mnt/storage/image:/var/lib/salix/image + - /mnt/appdata/pdfs:/var/lib/salix/pdfs + - /mnt/appdata/dms:/var/lib/salix/dms + - /mnt/appdata/image:/var/lib/salix/image deploy: replicas: ${BACK_REPLICAS:?} placement: From 197ed2009f7f13135f6f30043807539920ecad8f Mon Sep 17 00:00:00 2001 From: joan Date: Wed, 29 Sep 2021 12:15:42 +0200 Subject: [PATCH 03/13] fix(invoicePdf): Create PDF document on invoice download Refs: 3109, 3110 --- loopback/locale/en.json | 3 +- loopback/locale/es.json | 3 +- .../back/methods/client/hasCustomerRole.js | 6 ++- .../client/specs/hasCustomerRole.spec.js | 16 +++--- modules/client/front/web-access/index.js | 2 +- .../back/methods/invoiceOut/createPdf.js | 4 +- .../back/methods/invoiceOut/download.js | 52 ++++++++++++------- .../methods/invoiceOut/specs/download.spec.js | 15 +++++- 8 files changed, 64 insertions(+), 37 deletions(-) diff --git a/loopback/locale/en.json b/loopback/locale/en.json index 70f3984a6d..bc97eae195 100644 --- a/loopback/locale/en.json +++ b/loopback/locale/en.json @@ -115,5 +115,6 @@ "A ticket with a negative base can't be invoiced": "A ticket with a negative base can't be invoiced", "This client is not invoiceable": "This client is not invoiceable", "INACTIVE_PROVIDER": "Inactive provider", - "reference duplicated": "reference duplicated" + "reference duplicated": "reference duplicated", + "The PDF document does not exists": "The PDF document does not exists. Try regenerating it from 'Regenerate invoice PDF' option" } \ No newline at end of file diff --git a/loopback/locale/es.json b/loopback/locale/es.json index 7a670d2edd..cdf15c6744 100644 --- a/loopback/locale/es.json +++ b/loopback/locale/es.json @@ -209,5 +209,6 @@ "Wasn't able to invoice the following clients": "No se han podido facturar los siguientes clientes", "Can't verify data unless the client has a business type": "No se puede verificar datos de un cliente que no tiene tipo de negocio", "You don't have enough privileges to set this credit amount": "No tienes suficientes privilegios para establecer esta cantidad de crédito", - "You can't change the credit set to zero from a manager": "No puedes cambiar el cŕedito establecido a cero por un gerente" + "You can't change the credit set to zero from a manager": "No puedes cambiar el cŕedito establecido a cero por un gerente", + "The PDF document does not exists": "El documento PDF no existe. Prueba a regenerarlo desde la opción 'Regenerar PDF factura'" } \ No newline at end of file diff --git a/modules/client/back/methods/client/hasCustomerRole.js b/modules/client/back/methods/client/hasCustomerRole.js index d668399362..e790d6e3ae 100644 --- a/modules/client/back/methods/client/hasCustomerRole.js +++ b/modules/client/back/methods/client/hasCustomerRole.js @@ -19,7 +19,7 @@ module.exports = Self => { } }); - Self.hasCustomerRole = (id, options) => { + Self.hasCustomerRole = async(id, options) => { const myOptions = {}; if (typeof options == 'object') @@ -31,7 +31,9 @@ module.exports = Self => { JOIN salix.Role r ON r.id = A.roleFK WHERE r.name = 'customer' AND A.id IN (?)`; + const [result] = await Self.rawSql(query, [id], myOptions); + const {isCustomer} = result; - return Self.rawSql(query, [id], myOptions); + return isCustomer; }; }; diff --git a/modules/client/back/methods/client/specs/hasCustomerRole.spec.js b/modules/client/back/methods/client/specs/hasCustomerRole.spec.js index 08b13a88eb..0fe83b7388 100644 --- a/modules/client/back/methods/client/specs/hasCustomerRole.spec.js +++ b/modules/client/back/methods/client/specs/hasCustomerRole.spec.js @@ -9,9 +9,9 @@ describe('Client hasCustomerRole', () => { const id = 1101; - const [result] = await models.Client.hasCustomerRole(id, options); + const result = await models.Client.hasCustomerRole(id, options); - expect(result).toEqual(jasmine.objectContaining({isCustomer: 1})); + expect(result).toBeTruthy(); await tx.rollback(); } catch (e) { @@ -27,9 +27,9 @@ describe('Client hasCustomerRole', () => { const options = {transaction: tx}; const id = 8; - const [result] = await models.Client.hasCustomerRole(id, options); + const result = await models.Client.hasCustomerRole(id, options); - expect(result).toEqual(jasmine.objectContaining({isCustomer: 0})); + expect(result).toBeFalsy(); await tx.rollback(); } catch (e) { @@ -46,9 +46,9 @@ describe('Client hasCustomerRole', () => { const id = 999; - const [result] = await models.Client.hasCustomerRole(id, options); + const result = await models.Client.hasCustomerRole(id, options); - expect(result).toEqual(jasmine.objectContaining({isCustomer: 0})); + expect(result).toBeFalsy(); await tx.rollback(); } catch (e) { @@ -65,9 +65,9 @@ describe('Client hasCustomerRole', () => { const id = 'WRONG!'; - const [result] = await models.Client.hasCustomerRole(id, options); + const result = await models.Client.hasCustomerRole(id, options); - expect(result).toEqual(jasmine.objectContaining({isCustomer: 0})); + expect(result).toBeFalsy(); await tx.rollback(); } catch (e) { diff --git a/modules/client/front/web-access/index.js b/modules/client/front/web-access/index.js index 03c1292d06..a37e72a9dd 100644 --- a/modules/client/front/web-access/index.js +++ b/modules/client/front/web-access/index.js @@ -19,7 +19,7 @@ export default class Controller extends Section { isCustomer() { if (this.client.id) { this.$http.get(`Clients/${this.client.id}/hasCustomerRole`).then(res => { - this.canChangePassword = res.data && res.data.isCustomer; + this.canChangePassword = res.data && res.data; }); } } diff --git a/modules/invoiceOut/back/methods/invoiceOut/createPdf.js b/modules/invoiceOut/back/methods/invoiceOut/createPdf.js index a787e48a1a..15ba79ba06 100644 --- a/modules/invoiceOut/back/methods/invoiceOut/createPdf.js +++ b/modules/invoiceOut/back/methods/invoiceOut/createPdf.js @@ -28,8 +28,8 @@ module.exports = Self => { Self.createPdf = async function(ctx, id, options) { const models = Self.app.models; const headers = ctx.req.headers; - const origin = headers.origin; - const authorization = headers.authorization; + const origin = headers.origin || headers.referer; + const authorization = ctx.req.accessToken.id; if (process.env.NODE_ENV == 'test') throw new UserError(`Action not allowed on the test environment`); diff --git a/modules/invoiceOut/back/methods/invoiceOut/download.js b/modules/invoiceOut/back/methods/invoiceOut/download.js index 9836479823..21459e2282 100644 --- a/modules/invoiceOut/back/methods/invoiceOut/download.js +++ b/modules/invoiceOut/back/methods/invoiceOut/download.js @@ -1,8 +1,9 @@ const fs = require('fs-extra'); const path = require('path'); +const UserError = require('vn-loopback/util/user-error'); module.exports = Self => { - Self.remoteMethod('download', { + Self.remoteMethodCtx('download', { description: 'Download an invoice PDF', accessType: 'READ', accepts: [ @@ -34,34 +35,45 @@ module.exports = Self => { } }); - Self.download = async function(id, options) { + Self.download = async function(ctx, id, options) { const models = Self.app.models; const myOptions = {}; if (typeof options == 'object') Object.assign(myOptions, options); - const invoiceOut = await models.InvoiceOut.findById(id, null, myOptions); + try { + const invoiceOut = await models.InvoiceOut.findById(id, null, myOptions); - const created = invoiceOut.created; - const year = created.getFullYear().toString(); - const month = created.getMonth().toString(); - const day = created.getDate().toString(); + const created = invoiceOut.created; + const year = created.getFullYear().toString(); + const month = created.getMonth().toString(); + const day = created.getDate().toString(); - const container = await models.InvoiceContainer.container(year); - const rootPath = container.client.root; - const src = path.join(rootPath, year, month, day); - const fileName = `${invoiceOut.ref}.pdf`; - const fileSrc = path.join(src, fileName); + const container = await models.InvoiceContainer.container(year); + const rootPath = container.client.root; + const src = path.join(rootPath, year, month, day); + const fileName = `${invoiceOut.ref}.pdf`; + const fileSrc = path.join(src, fileName); - const file = { - path: fileSrc, - contentType: 'application/pdf', - name: `${id}.pdf` - }; + // Creates PDF document if it has not been created + if (!invoiceOut.hasPdf || !fs.existsSync(fileSrc)) + await Self.createPdf(ctx, invoiceOut.id, myOptions); - await fs.access(file.path); - let stream = fs.createReadStream(file.path); - return [stream, file.contentType, `filename="${file.name}"`]; + const file = { + path: fileSrc, + contentType: 'application/pdf', + name: `${id}.pdf` + }; + + await fs.access(file.path); + let stream = fs.createReadStream(file.path); + return [stream, file.contentType, `filename="${file.name}"`]; + } catch (error) { + if (error.code === 'ENOENT') + throw new UserError('The PDF document does not exists'); + + throw error; + } }; }; diff --git a/modules/invoiceOut/back/methods/invoiceOut/specs/download.spec.js b/modules/invoiceOut/back/methods/invoiceOut/specs/download.spec.js index c053adde16..6319911614 100644 --- a/modules/invoiceOut/back/methods/invoiceOut/specs/download.spec.js +++ b/modules/invoiceOut/back/methods/invoiceOut/specs/download.spec.js @@ -2,14 +2,25 @@ const models = require('vn-loopback/server/server').models; const fs = require('fs-extra'); describe('InvoiceOut download()', () => { - it('should return the downloaded fine name', async() => { + const userId = 9; + const invoiceId = 1; + const ctx = { + req: { + + accessToken: {userId: userId}, + headers: {origin: 'http://localhost:5000'}, + } + }; + + it('should return the downloaded file name', async() => { spyOn(models.InvoiceContainer, 'container').and.returnValue({ client: {root: '/path'} }); spyOn(fs, 'createReadStream').and.returnValue(new Promise(resolve => resolve('streamObject'))); spyOn(fs, 'access').and.returnValue(true); + spyOn(models.InvoiceOut, 'createPdf').and.returnValue(new Promise(resolve => resolve(true))); - const result = await models.InvoiceOut.download(1); + const result = await models.InvoiceOut.download(ctx, invoiceId); expect(result[1]).toEqual('application/pdf'); expect(result[2]).toEqual('filename="1.pdf"'); From 458d2670b3aa5db0c6987f3ea141f8ea99187e35 Mon Sep 17 00:00:00 2001 From: joan Date: Wed, 29 Sep 2021 12:17:21 +0200 Subject: [PATCH 04/13] Updated unit test --- modules/client/front/web-access/index.spec.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/client/front/web-access/index.spec.js b/modules/client/front/web-access/index.spec.js index 73c4f10436..00fa12781a 100644 --- a/modules/client/front/web-access/index.spec.js +++ b/modules/client/front/web-access/index.spec.js @@ -33,7 +33,7 @@ describe('Component VnClientWebAccess', () => { it('should return true if the password can be modified', () => { controller.client = {id: '1234'}; - $httpBackend.expectGET(`Clients/${controller.client.id}/hasCustomerRole`).respond({isCustomer: true}); + $httpBackend.expectGET(`Clients/${controller.client.id}/hasCustomerRole`).respond(true); controller.isCustomer(); $httpBackend.flush(); @@ -43,7 +43,7 @@ describe('Component VnClientWebAccess', () => { it(`should return a false if the password can't be modified`, () => { controller.client = {id: '1234'}; - $httpBackend.expectGET(`Clients/${controller.client.id}/hasCustomerRole`).respond({isCustomer: false}); + $httpBackend.expectGET(`Clients/${controller.client.id}/hasCustomerRole`).respond(false); controller.isCustomer(); $httpBackend.flush(); From a7c75fcbd4ee1c33311058855c44a877b190bbc7 Mon Sep 17 00:00:00 2001 From: joan Date: Wed, 29 Sep 2021 12:15:42 +0200 Subject: [PATCH 05/13] fix(invoicePdf): Create PDF document on invoice download Refs: 3109, 3110 --- loopback/locale/en.json | 3 +- loopback/locale/es.json | 3 +- .../back/methods/client/hasCustomerRole.js | 6 ++- .../client/specs/hasCustomerRole.spec.js | 16 +++--- modules/client/front/web-access/index.js | 2 +- .../back/methods/invoiceOut/createPdf.js | 4 +- .../back/methods/invoiceOut/download.js | 52 ++++++++++++------- .../methods/invoiceOut/specs/download.spec.js | 15 +++++- 8 files changed, 64 insertions(+), 37 deletions(-) diff --git a/loopback/locale/en.json b/loopback/locale/en.json index 70f3984a6d..bc97eae195 100644 --- a/loopback/locale/en.json +++ b/loopback/locale/en.json @@ -115,5 +115,6 @@ "A ticket with a negative base can't be invoiced": "A ticket with a negative base can't be invoiced", "This client is not invoiceable": "This client is not invoiceable", "INACTIVE_PROVIDER": "Inactive provider", - "reference duplicated": "reference duplicated" + "reference duplicated": "reference duplicated", + "The PDF document does not exists": "The PDF document does not exists. Try regenerating it from 'Regenerate invoice PDF' option" } \ No newline at end of file diff --git a/loopback/locale/es.json b/loopback/locale/es.json index 7a670d2edd..cdf15c6744 100644 --- a/loopback/locale/es.json +++ b/loopback/locale/es.json @@ -209,5 +209,6 @@ "Wasn't able to invoice the following clients": "No se han podido facturar los siguientes clientes", "Can't verify data unless the client has a business type": "No se puede verificar datos de un cliente que no tiene tipo de negocio", "You don't have enough privileges to set this credit amount": "No tienes suficientes privilegios para establecer esta cantidad de crédito", - "You can't change the credit set to zero from a manager": "No puedes cambiar el cŕedito establecido a cero por un gerente" + "You can't change the credit set to zero from a manager": "No puedes cambiar el cŕedito establecido a cero por un gerente", + "The PDF document does not exists": "El documento PDF no existe. Prueba a regenerarlo desde la opción 'Regenerar PDF factura'" } \ No newline at end of file diff --git a/modules/client/back/methods/client/hasCustomerRole.js b/modules/client/back/methods/client/hasCustomerRole.js index d668399362..e790d6e3ae 100644 --- a/modules/client/back/methods/client/hasCustomerRole.js +++ b/modules/client/back/methods/client/hasCustomerRole.js @@ -19,7 +19,7 @@ module.exports = Self => { } }); - Self.hasCustomerRole = (id, options) => { + Self.hasCustomerRole = async(id, options) => { const myOptions = {}; if (typeof options == 'object') @@ -31,7 +31,9 @@ module.exports = Self => { JOIN salix.Role r ON r.id = A.roleFK WHERE r.name = 'customer' AND A.id IN (?)`; + const [result] = await Self.rawSql(query, [id], myOptions); + const {isCustomer} = result; - return Self.rawSql(query, [id], myOptions); + return isCustomer; }; }; diff --git a/modules/client/back/methods/client/specs/hasCustomerRole.spec.js b/modules/client/back/methods/client/specs/hasCustomerRole.spec.js index 08b13a88eb..0fe83b7388 100644 --- a/modules/client/back/methods/client/specs/hasCustomerRole.spec.js +++ b/modules/client/back/methods/client/specs/hasCustomerRole.spec.js @@ -9,9 +9,9 @@ describe('Client hasCustomerRole', () => { const id = 1101; - const [result] = await models.Client.hasCustomerRole(id, options); + const result = await models.Client.hasCustomerRole(id, options); - expect(result).toEqual(jasmine.objectContaining({isCustomer: 1})); + expect(result).toBeTruthy(); await tx.rollback(); } catch (e) { @@ -27,9 +27,9 @@ describe('Client hasCustomerRole', () => { const options = {transaction: tx}; const id = 8; - const [result] = await models.Client.hasCustomerRole(id, options); + const result = await models.Client.hasCustomerRole(id, options); - expect(result).toEqual(jasmine.objectContaining({isCustomer: 0})); + expect(result).toBeFalsy(); await tx.rollback(); } catch (e) { @@ -46,9 +46,9 @@ describe('Client hasCustomerRole', () => { const id = 999; - const [result] = await models.Client.hasCustomerRole(id, options); + const result = await models.Client.hasCustomerRole(id, options); - expect(result).toEqual(jasmine.objectContaining({isCustomer: 0})); + expect(result).toBeFalsy(); await tx.rollback(); } catch (e) { @@ -65,9 +65,9 @@ describe('Client hasCustomerRole', () => { const id = 'WRONG!'; - const [result] = await models.Client.hasCustomerRole(id, options); + const result = await models.Client.hasCustomerRole(id, options); - expect(result).toEqual(jasmine.objectContaining({isCustomer: 0})); + expect(result).toBeFalsy(); await tx.rollback(); } catch (e) { diff --git a/modules/client/front/web-access/index.js b/modules/client/front/web-access/index.js index 03c1292d06..a37e72a9dd 100644 --- a/modules/client/front/web-access/index.js +++ b/modules/client/front/web-access/index.js @@ -19,7 +19,7 @@ export default class Controller extends Section { isCustomer() { if (this.client.id) { this.$http.get(`Clients/${this.client.id}/hasCustomerRole`).then(res => { - this.canChangePassword = res.data && res.data.isCustomer; + this.canChangePassword = res.data && res.data; }); } } diff --git a/modules/invoiceOut/back/methods/invoiceOut/createPdf.js b/modules/invoiceOut/back/methods/invoiceOut/createPdf.js index a787e48a1a..15ba79ba06 100644 --- a/modules/invoiceOut/back/methods/invoiceOut/createPdf.js +++ b/modules/invoiceOut/back/methods/invoiceOut/createPdf.js @@ -28,8 +28,8 @@ module.exports = Self => { Self.createPdf = async function(ctx, id, options) { const models = Self.app.models; const headers = ctx.req.headers; - const origin = headers.origin; - const authorization = headers.authorization; + const origin = headers.origin || headers.referer; + const authorization = ctx.req.accessToken.id; if (process.env.NODE_ENV == 'test') throw new UserError(`Action not allowed on the test environment`); diff --git a/modules/invoiceOut/back/methods/invoiceOut/download.js b/modules/invoiceOut/back/methods/invoiceOut/download.js index 9836479823..21459e2282 100644 --- a/modules/invoiceOut/back/methods/invoiceOut/download.js +++ b/modules/invoiceOut/back/methods/invoiceOut/download.js @@ -1,8 +1,9 @@ const fs = require('fs-extra'); const path = require('path'); +const UserError = require('vn-loopback/util/user-error'); module.exports = Self => { - Self.remoteMethod('download', { + Self.remoteMethodCtx('download', { description: 'Download an invoice PDF', accessType: 'READ', accepts: [ @@ -34,34 +35,45 @@ module.exports = Self => { } }); - Self.download = async function(id, options) { + Self.download = async function(ctx, id, options) { const models = Self.app.models; const myOptions = {}; if (typeof options == 'object') Object.assign(myOptions, options); - const invoiceOut = await models.InvoiceOut.findById(id, null, myOptions); + try { + const invoiceOut = await models.InvoiceOut.findById(id, null, myOptions); - const created = invoiceOut.created; - const year = created.getFullYear().toString(); - const month = created.getMonth().toString(); - const day = created.getDate().toString(); + const created = invoiceOut.created; + const year = created.getFullYear().toString(); + const month = created.getMonth().toString(); + const day = created.getDate().toString(); - const container = await models.InvoiceContainer.container(year); - const rootPath = container.client.root; - const src = path.join(rootPath, year, month, day); - const fileName = `${invoiceOut.ref}.pdf`; - const fileSrc = path.join(src, fileName); + const container = await models.InvoiceContainer.container(year); + const rootPath = container.client.root; + const src = path.join(rootPath, year, month, day); + const fileName = `${invoiceOut.ref}.pdf`; + const fileSrc = path.join(src, fileName); - const file = { - path: fileSrc, - contentType: 'application/pdf', - name: `${id}.pdf` - }; + // Creates PDF document if it has not been created + if (!invoiceOut.hasPdf || !fs.existsSync(fileSrc)) + await Self.createPdf(ctx, invoiceOut.id, myOptions); - await fs.access(file.path); - let stream = fs.createReadStream(file.path); - return [stream, file.contentType, `filename="${file.name}"`]; + const file = { + path: fileSrc, + contentType: 'application/pdf', + name: `${id}.pdf` + }; + + await fs.access(file.path); + let stream = fs.createReadStream(file.path); + return [stream, file.contentType, `filename="${file.name}"`]; + } catch (error) { + if (error.code === 'ENOENT') + throw new UserError('The PDF document does not exists'); + + throw error; + } }; }; diff --git a/modules/invoiceOut/back/methods/invoiceOut/specs/download.spec.js b/modules/invoiceOut/back/methods/invoiceOut/specs/download.spec.js index c053adde16..6319911614 100644 --- a/modules/invoiceOut/back/methods/invoiceOut/specs/download.spec.js +++ b/modules/invoiceOut/back/methods/invoiceOut/specs/download.spec.js @@ -2,14 +2,25 @@ const models = require('vn-loopback/server/server').models; const fs = require('fs-extra'); describe('InvoiceOut download()', () => { - it('should return the downloaded fine name', async() => { + const userId = 9; + const invoiceId = 1; + const ctx = { + req: { + + accessToken: {userId: userId}, + headers: {origin: 'http://localhost:5000'}, + } + }; + + it('should return the downloaded file name', async() => { spyOn(models.InvoiceContainer, 'container').and.returnValue({ client: {root: '/path'} }); spyOn(fs, 'createReadStream').and.returnValue(new Promise(resolve => resolve('streamObject'))); spyOn(fs, 'access').and.returnValue(true); + spyOn(models.InvoiceOut, 'createPdf').and.returnValue(new Promise(resolve => resolve(true))); - const result = await models.InvoiceOut.download(1); + const result = await models.InvoiceOut.download(ctx, invoiceId); expect(result[1]).toEqual('application/pdf'); expect(result[2]).toEqual('filename="1.pdf"'); From 479d4892ce02dd39b634944620ffad057c931e12 Mon Sep 17 00:00:00 2001 From: joan Date: Wed, 29 Sep 2021 12:17:21 +0200 Subject: [PATCH 06/13] Updated unit test --- modules/client/front/web-access/index.spec.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/client/front/web-access/index.spec.js b/modules/client/front/web-access/index.spec.js index 73c4f10436..00fa12781a 100644 --- a/modules/client/front/web-access/index.spec.js +++ b/modules/client/front/web-access/index.spec.js @@ -33,7 +33,7 @@ describe('Component VnClientWebAccess', () => { it('should return true if the password can be modified', () => { controller.client = {id: '1234'}; - $httpBackend.expectGET(`Clients/${controller.client.id}/hasCustomerRole`).respond({isCustomer: true}); + $httpBackend.expectGET(`Clients/${controller.client.id}/hasCustomerRole`).respond(true); controller.isCustomer(); $httpBackend.flush(); @@ -43,7 +43,7 @@ describe('Component VnClientWebAccess', () => { it(`should return a false if the password can't be modified`, () => { controller.client = {id: '1234'}; - $httpBackend.expectGET(`Clients/${controller.client.id}/hasCustomerRole`).respond({isCustomer: false}); + $httpBackend.expectGET(`Clients/${controller.client.id}/hasCustomerRole`).respond(false); controller.isCustomer(); $httpBackend.flush(); From 54fa4192553d5eee62a738d7a92b58a1b4610997 Mon Sep 17 00:00:00 2001 From: joan Date: Thu, 30 Sep 2021 14:43:37 +0200 Subject: [PATCH 07/13] fix(invoice): was storing invoices on incorrect path folder --- modules/invoiceOut/back/methods/invoiceOut/createPdf.js | 4 ++-- modules/invoiceOut/back/methods/invoiceOut/download.js | 7 ++++--- .../back/methods/invoiceOut/specs/download.spec.js | 2 +- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/modules/invoiceOut/back/methods/invoiceOut/createPdf.js b/modules/invoiceOut/back/methods/invoiceOut/createPdf.js index 15ba79ba06..f264cdd43f 100644 --- a/modules/invoiceOut/back/methods/invoiceOut/createPdf.js +++ b/modules/invoiceOut/back/methods/invoiceOut/createPdf.js @@ -61,12 +61,12 @@ module.exports = Self => { const created = invoiceOut.created; const year = created.getFullYear().toString(); - const month = created.getMonth().toString(); + const month = (created.getMonth() + 1).toString(); const day = created.getDate().toString(); const container = await models.InvoiceContainer.container(year); const rootPath = container.client.root; - const fileName = `${invoiceOut.ref}.pdf`; + const fileName = `${year}${invoiceOut.ref}.pdf`; const src = path.join(rootPath, year, month, day); fileSrc = path.join(src, fileName); diff --git a/modules/invoiceOut/back/methods/invoiceOut/download.js b/modules/invoiceOut/back/methods/invoiceOut/download.js index 21459e2282..a8ec7e945b 100644 --- a/modules/invoiceOut/back/methods/invoiceOut/download.js +++ b/modules/invoiceOut/back/methods/invoiceOut/download.js @@ -47,13 +47,13 @@ module.exports = Self => { const created = invoiceOut.created; const year = created.getFullYear().toString(); - const month = created.getMonth().toString(); + const month = (created.getMonth() + 1).toString(); const day = created.getDate().toString(); const container = await models.InvoiceContainer.container(year); const rootPath = container.client.root; const src = path.join(rootPath, year, month, day); - const fileName = `${invoiceOut.ref}.pdf`; + const fileName = `${year}${invoiceOut.ref}.pdf`; const fileSrc = path.join(src, fileName); // Creates PDF document if it has not been created @@ -63,13 +63,14 @@ module.exports = Self => { const file = { path: fileSrc, contentType: 'application/pdf', - name: `${id}.pdf` + name: fileName }; await fs.access(file.path); let stream = fs.createReadStream(file.path); return [stream, file.contentType, `filename="${file.name}"`]; } catch (error) { + console.log(error); if (error.code === 'ENOENT') throw new UserError('The PDF document does not exists'); diff --git a/modules/invoiceOut/back/methods/invoiceOut/specs/download.spec.js b/modules/invoiceOut/back/methods/invoiceOut/specs/download.spec.js index 6319911614..3a46311ad4 100644 --- a/modules/invoiceOut/back/methods/invoiceOut/specs/download.spec.js +++ b/modules/invoiceOut/back/methods/invoiceOut/specs/download.spec.js @@ -23,6 +23,6 @@ describe('InvoiceOut download()', () => { const result = await models.InvoiceOut.download(ctx, invoiceId); expect(result[1]).toEqual('application/pdf'); - expect(result[2]).toEqual('filename="1.pdf"'); + expect(result[2]).toEqual('filename="2021T1111111.pdf"'); }); }); From 26df12a70a662418b06f1efd131e47b09c74a224 Mon Sep 17 00:00:00 2001 From: joan Date: Thu, 30 Sep 2021 15:28:34 +0200 Subject: [PATCH 08/13] fix(invoice): fixed pdf generation condition race --- .../invoiceOut/back/methods/invoiceOut/createPdf.js | 11 +++-------- .../invoiceOut/back/methods/invoiceOut/download.js | 1 - 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/modules/invoiceOut/back/methods/invoiceOut/createPdf.js b/modules/invoiceOut/back/methods/invoiceOut/createPdf.js index f264cdd43f..58f8c47336 100644 --- a/modules/invoiceOut/back/methods/invoiceOut/createPdf.js +++ b/modules/invoiceOut/back/methods/invoiceOut/createPdf.js @@ -75,16 +75,11 @@ module.exports = Self => { if (tx) await tx.commit(); const writeStream = fs.createWriteStream(fileSrc); - writeStream.on('open', () => { - response.pipe(writeStream); - }); + writeStream.on('open', () => response.pipe(writeStream)); + writeStream.on('finish', () => writeStream.end()); return new Promise(resolve => { - writeStream.on('finish', () => { - writeStream.end(); - - resolve(invoiceOut); - }); + writeStream.on('close', () => resolve(invoiceOut)); }); } catch (e) { if (tx) await tx.rollback(); diff --git a/modules/invoiceOut/back/methods/invoiceOut/download.js b/modules/invoiceOut/back/methods/invoiceOut/download.js index a8ec7e945b..a42da48bab 100644 --- a/modules/invoiceOut/back/methods/invoiceOut/download.js +++ b/modules/invoiceOut/back/methods/invoiceOut/download.js @@ -70,7 +70,6 @@ module.exports = Self => { let stream = fs.createReadStream(file.path); return [stream, file.contentType, `filename="${file.name}"`]; } catch (error) { - console.log(error); if (error.code === 'ENOENT') throw new UserError('The PDF document does not exists'); From a41ae85226c74a68f388a945af0a815357f3c5de Mon Sep 17 00:00:00 2001 From: joan Date: Fri, 1 Oct 2021 08:11:26 +0200 Subject: [PATCH 09/13] Removed PDF creation on download --- modules/invoiceOut/back/methods/invoiceOut/createPdf.js | 2 +- modules/invoiceOut/back/methods/invoiceOut/download.js | 4 ---- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/modules/invoiceOut/back/methods/invoiceOut/createPdf.js b/modules/invoiceOut/back/methods/invoiceOut/createPdf.js index 58f8c47336..2a0aec2bb0 100644 --- a/modules/invoiceOut/back/methods/invoiceOut/createPdf.js +++ b/modules/invoiceOut/back/methods/invoiceOut/createPdf.js @@ -28,7 +28,7 @@ module.exports = Self => { Self.createPdf = async function(ctx, id, options) { const models = Self.app.models; const headers = ctx.req.headers; - const origin = headers.origin || headers.referer; + const origin = headers.origin; const authorization = ctx.req.accessToken.id; if (process.env.NODE_ENV == 'test') diff --git a/modules/invoiceOut/back/methods/invoiceOut/download.js b/modules/invoiceOut/back/methods/invoiceOut/download.js index a42da48bab..0dcbd0e925 100644 --- a/modules/invoiceOut/back/methods/invoiceOut/download.js +++ b/modules/invoiceOut/back/methods/invoiceOut/download.js @@ -56,10 +56,6 @@ module.exports = Self => { const fileName = `${year}${invoiceOut.ref}.pdf`; const fileSrc = path.join(src, fileName); - // Creates PDF document if it has not been created - if (!invoiceOut.hasPdf || !fs.existsSync(fileSrc)) - await Self.createPdf(ctx, invoiceOut.id, myOptions); - const file = { path: fileSrc, contentType: 'application/pdf', From 7ccb325eccedb44a53516981f2427afdbac3b066 Mon Sep 17 00:00:00 2001 From: joan Date: Fri, 1 Oct 2021 08:39:42 +0200 Subject: [PATCH 10/13] fix(model): added everyone ACL to model --- back/models/{emailUser.json => email-user.json} | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) rename back/models/{emailUser.json => email-user.json} (72%) diff --git a/back/models/emailUser.json b/back/models/email-user.json similarity index 72% rename from back/models/emailUser.json rename to back/models/email-user.json index d612d5d297..e983635ce5 100644 --- a/back/models/emailUser.json +++ b/back/models/email-user.json @@ -23,5 +23,13 @@ "model": "Account", "foreignKey": "userFk" } - } + }, + "acls": [ + { + "accessType": "READ", + "principalType": "ROLE", + "principalId": "$everyone", + "permission": "ALLOW" + } + ] } From 3df03b31a354ac8231851527aecac1786747e98f Mon Sep 17 00:00:00 2001 From: joan Date: Fri, 1 Oct 2021 10:56:40 +0200 Subject: [PATCH 11/13] fix(invoice): invalid date for PDF storage --- modules/invoiceOut/back/methods/invoiceOut/createPdf.js | 8 ++++---- modules/invoiceOut/back/methods/invoiceOut/download.js | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/modules/invoiceOut/back/methods/invoiceOut/createPdf.js b/modules/invoiceOut/back/methods/invoiceOut/createPdf.js index 2a0aec2bb0..b866a5cf2d 100644 --- a/modules/invoiceOut/back/methods/invoiceOut/createPdf.js +++ b/modules/invoiceOut/back/methods/invoiceOut/createPdf.js @@ -59,10 +59,10 @@ module.exports = Self => { } }); - const created = invoiceOut.created; - const year = created.getFullYear().toString(); - const month = (created.getMonth() + 1).toString(); - const day = created.getDate().toString(); + const issued = invoiceOut.issued; + const year = issued.getFullYear().toString(); + const month = (issued.getMonth() + 1).toString(); + const day = issued.getDate().toString(); const container = await models.InvoiceContainer.container(year); const rootPath = container.client.root; diff --git a/modules/invoiceOut/back/methods/invoiceOut/download.js b/modules/invoiceOut/back/methods/invoiceOut/download.js index 0dcbd0e925..f1138dd51d 100644 --- a/modules/invoiceOut/back/methods/invoiceOut/download.js +++ b/modules/invoiceOut/back/methods/invoiceOut/download.js @@ -45,10 +45,10 @@ module.exports = Self => { try { const invoiceOut = await models.InvoiceOut.findById(id, null, myOptions); - const created = invoiceOut.created; - const year = created.getFullYear().toString(); - const month = (created.getMonth() + 1).toString(); - const day = created.getDate().toString(); + const issued = invoiceOut.issued; + const year = issued.getFullYear().toString(); + const month = (issued.getMonth() + 1).toString(); + const day = issued.getDate().toString(); const container = await models.InvoiceContainer.container(year); const rootPath = container.client.root; From f60c754c59433fd3b13d227724f9b672efc11130 Mon Sep 17 00:00:00 2001 From: joan Date: Fri, 1 Oct 2021 14:31:42 +0200 Subject: [PATCH 12/13] refactor(invoice): Show generate PDF option if it was never generated before Refs: 3162 --- db/changes/10370-pickles/00-ACL.sql | 1 + db/dump/fixtures.sql | 10 +++++----- .../back/methods/invoiceOut/createPdf.js | 9 +++++++-- .../methods/invoiceOut/specs/filter.spec.js | 5 ++++- modules/invoiceOut/front/card/index.html | 5 ++++- modules/invoiceOut/front/card/index.js | 3 ++- .../invoiceOut/front/descriptor/index.html | 9 ++++----- modules/invoiceOut/front/descriptor/index.js | 19 ++++++++++++++++++- .../invoiceOut/front/descriptor/index.spec.js | 2 ++ .../invoiceOut/front/descriptor/locale/es.yml | 3 ++- modules/ticket/front/card/index.html | 5 ++++- .../ticket/front/descriptor-menu/index.html | 10 ++++------ modules/ticket/front/descriptor-menu/index.js | 1 + .../front/descriptor-menu/index.spec.js | 1 + modules/ticket/front/descriptor/index.js | 4 ++++ modules/ticket/front/descriptor/locale/es.yml | 4 ++-- 16 files changed, 65 insertions(+), 26 deletions(-) create mode 100644 db/changes/10370-pickles/00-ACL.sql diff --git a/db/changes/10370-pickles/00-ACL.sql b/db/changes/10370-pickles/00-ACL.sql new file mode 100644 index 0000000000..c5e10dec51 --- /dev/null +++ b/db/changes/10370-pickles/00-ACL.sql @@ -0,0 +1 @@ +UPDATE salix.ACL t SET t.principalId = 'employee' WHERE t.id = 269; diff --git a/db/dump/fixtures.sql b/db/dump/fixtures.sql index 2b65efbc10..1635335c45 100644 --- a/db/dump/fixtures.sql +++ b/db/dump/fixtures.sql @@ -489,11 +489,11 @@ INSERT INTO `vn`.`invoiceOutSerial` (`code`, `description`, `isTaxed`, `taxAreaF INSERT INTO `vn`.`invoiceOut`(`id`, `serial`, `amount`, `issued`,`clientFk`, `created`, `companyFk`, `dued`, `booked`, `bankFk`, `hasPdf`) VALUES - (1, 'T', 1014.24, CURDATE(), 1101, CURDATE(), 442, CURDATE(), CURDATE(), 1, 1), - (2, 'T', 121.36, CURDATE(), 1102, CURDATE(), 442, CURDATE(), CURDATE(), 1, 1), - (3, 'T', 8.88, CURDATE(), 1103, CURDATE(), 442, CURDATE(), CURDATE(), 1, 1), - (4, 'T', 8.88, CURDATE(), 1103, CURDATE(), 442, CURDATE(), CURDATE(), 1, 1), - (5, 'A', 8.88, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 1103, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 442, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 1, 1); + (1, 'T', 1014.24, CURDATE(), 1101, CURDATE(), 442, CURDATE(), CURDATE(), 1, 0), + (2, 'T', 121.36, CURDATE(), 1102, CURDATE(), 442, CURDATE(), CURDATE(), 1, 0), + (3, 'T', 8.88, CURDATE(), 1103, CURDATE(), 442, CURDATE(), CURDATE(), 1, 0), + (4, 'T', 8.88, CURDATE(), 1103, CURDATE(), 442, CURDATE(), CURDATE(), 1, 0), + (5, 'A', 8.88, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 1103, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 442, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 1, 0); UPDATE `vn`.`invoiceOut` SET ref = 'T1111111' WHERE id = 1; UPDATE `vn`.`invoiceOut` SET ref = 'T2222222' WHERE id = 2; diff --git a/modules/invoiceOut/back/methods/invoiceOut/createPdf.js b/modules/invoiceOut/back/methods/invoiceOut/createPdf.js index b866a5cf2d..ac79f0d5d0 100644 --- a/modules/invoiceOut/back/methods/invoiceOut/createPdf.js +++ b/modules/invoiceOut/back/methods/invoiceOut/createPdf.js @@ -29,7 +29,7 @@ module.exports = Self => { const models = Self.app.models; const headers = ctx.req.headers; const origin = headers.origin; - const authorization = ctx.req.accessToken.id; + const auth = ctx.req.accessToken; if (process.env.NODE_ENV == 'test') throw new UserError(`Action not allowed on the test environment`); @@ -48,13 +48,18 @@ module.exports = Self => { let fileSrc; try { const invoiceOut = await Self.findById(id, null, myOptions); + const hasInvoicing = await models.Account.hasRole(auth.userId, 'invoicing', myOptions); + + if (invoiceOut.hasPdf && !hasInvoicing) + throw new UserError(`You don't have enough privileges`); + await invoiceOut.updateAttributes({ hasPdf: true }, myOptions); const response = got.stream(`${origin}/api/report/invoice`, { query: { - authorization: authorization, + authorization: auth.id, invoiceId: id } }); diff --git a/modules/invoiceOut/back/methods/invoiceOut/specs/filter.spec.js b/modules/invoiceOut/back/methods/invoiceOut/specs/filter.spec.js index 2a530048e3..ededc5679b 100644 --- a/modules/invoiceOut/back/methods/invoiceOut/specs/filter.spec.js +++ b/modules/invoiceOut/back/methods/invoiceOut/specs/filter.spec.js @@ -61,9 +61,12 @@ describe('InvoiceOut filter()', () => { } }; + const invoiceOut = await models.InvoiceOut.findById(1, null, options); + await invoiceOut.updateAttribute('hasPdf', true, options); + const result = await models.InvoiceOut.filter(ctx, {}, options); - expect(result.length).toEqual(5); + expect(result.length).toEqual(1); await tx.rollback(); } catch (e) { diff --git a/modules/invoiceOut/front/card/index.html b/modules/invoiceOut/front/card/index.html index c70ac06e1c..a6f56f7755 100644 --- a/modules/invoiceOut/front/card/index.html +++ b/modules/invoiceOut/front/card/index.html @@ -1,5 +1,8 @@ - + + diff --git a/modules/invoiceOut/front/card/index.js b/modules/invoiceOut/front/card/index.js index 093fcdf669..85d03537b3 100644 --- a/modules/invoiceOut/front/card/index.js +++ b/modules/invoiceOut/front/card/index.js @@ -10,7 +10,8 @@ class Controller extends ModuleCard { 'issued', 'amount', 'clientFk', - 'companyFk' + 'companyFk', + 'hasPdf' ], include: [ { diff --git a/modules/invoiceOut/front/descriptor/index.html b/modules/invoiceOut/front/descriptor/index.html index 1da487d15a..4d9a4ffd88 100644 --- a/modules/invoiceOut/front/descriptor/index.html +++ b/modules/invoiceOut/front/descriptor/index.html @@ -33,11 +33,10 @@ - Regenerate invoice PDF + {{!$ctrl.invoiceOut.hasPdf ? 'Generate PDF invoice': 'Regenerate PDF invoice'}} @@ -101,8 +100,8 @@ + question="Are you sure you want to generate/regenerate the PDF invoice?" + message="Generate PDF invoice document"> diff --git a/modules/invoiceOut/front/descriptor/index.js b/modules/invoiceOut/front/descriptor/index.js index 5a535c9b52..0600ffa5b9 100644 --- a/modules/invoiceOut/front/descriptor/index.js +++ b/modules/invoiceOut/front/descriptor/index.js @@ -10,6 +10,10 @@ class Controller extends Descriptor { this.entity = value; } + get hasInvoicing() { + return this.aclService.hasAny(['invoicing']); + } + deleteInvoiceOut() { return this.$http.post(`InvoiceOuts/${this.id}/delete`) .then(() => this.$state.go('invoiceOut.index')) @@ -25,6 +29,7 @@ class Controller extends Descriptor { createInvoicePdf() { const invoiceId = this.invoiceOut.id; return this.$http.post(`InvoiceOuts/${invoiceId}/createPdf`) + .then(() => this.reload()) .then(() => { const snackbarMessage = this.$t( `The invoice PDF document has been regenerated`); @@ -60,6 +65,17 @@ class Controller extends Descriptor { .then(res => this.entity = res.data); } + reload() { + return this.loadData().then(() => { + if (this.cardReload) + this.cardReload(); + }); + } + + cardReload() { + // Prevents error when not defined + } + sendInvoice($data) { return this.vnEmail.send('invoice', { recipientId: this.invoiceOut.client.id, @@ -73,6 +89,7 @@ ngModule.vnComponent('vnInvoiceOutDescriptor', { template: require('./index.html'), controller: Controller, bindings: { - invoiceOut: '<' + invoiceOut: '<', + cardReload: '&' } }); diff --git a/modules/invoiceOut/front/descriptor/index.spec.js b/modules/invoiceOut/front/descriptor/index.spec.js index c16900a0ad..6bf49d32b1 100644 --- a/modules/invoiceOut/front/descriptor/index.spec.js +++ b/modules/invoiceOut/front/descriptor/index.spec.js @@ -18,6 +18,8 @@ describe('vnInvoiceOutDescriptor', () => { controller.invoiceOut = invoiceOut; + $httpBackend.whenGET(`InvoiceOuts/${invoiceOut.id}`).respond(); + $httpBackend.whenGET(`Tickets/16`).respond(); $httpBackend.expectPOST(`InvoiceOuts/${invoiceOut.id}/createPdf`).respond(); controller.createInvoicePdf(); $httpBackend.flush(); diff --git a/modules/invoiceOut/front/descriptor/locale/es.yml b/modules/invoiceOut/front/descriptor/locale/es.yml index ec9cd33100..3430fe4e70 100644 --- a/modules/invoiceOut/front/descriptor/locale/es.yml +++ b/modules/invoiceOut/front/descriptor/locale/es.yml @@ -12,5 +12,6 @@ Are you sure you want to clone this invoice?: Estas seguro de clonar esta factur Book invoice: Asentar factura InvoiceOut booked: Factura asentada Are you sure you want to book this invoice?: Estas seguro de querer asentar esta factura? -Regenerate invoice PDF: Regenerar PDF factura +Generate PDF invoice: Generar PDF factura +Regenerate PDF invoice: 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/front/card/index.html b/modules/ticket/front/card/index.html index a7c70c484b..110ffeed40 100644 --- a/modules/ticket/front/card/index.html +++ b/modules/ticket/front/card/index.html @@ -1,5 +1,8 @@ - + + diff --git a/modules/ticket/front/descriptor-menu/index.html b/modules/ticket/front/descriptor-menu/index.html index 4f65fe0085..555246f9f2 100644 --- a/modules/ticket/front/descriptor-menu/index.html +++ b/modules/ticket/front/descriptor-menu/index.html @@ -80,12 +80,10 @@ - Regenerate invoice PDF + {{!$ctrl.ticket.invoiceOut.hasPdf ? 'Generate PDF invoice': 'Regenerate PDF invoice'}} + question="Are you sure you want to generate/regenerate the PDF invoice?" + message="Generate PDF invoice document"> diff --git a/modules/ticket/front/descriptor-menu/index.js b/modules/ticket/front/descriptor-menu/index.js index 5da9544e2b..01709cf339 100644 --- a/modules/ticket/front/descriptor-menu/index.js +++ b/modules/ticket/front/descriptor-menu/index.js @@ -226,6 +226,7 @@ class Controller extends Section { createInvoicePdf() { const invoiceId = this.ticket.invoiceOut.id; return this.$http.post(`InvoiceOuts/${invoiceId}/createPdf`) + .then(() => this.reload()) .then(() => { const snackbarMessage = this.$t( `The invoice PDF document has been regenerated`); diff --git a/modules/ticket/front/descriptor-menu/index.spec.js b/modules/ticket/front/descriptor-menu/index.spec.js index b102b1f445..d10f4e9580 100644 --- a/modules/ticket/front/descriptor-menu/index.spec.js +++ b/modules/ticket/front/descriptor-menu/index.spec.js @@ -153,6 +153,7 @@ describe('Ticket Component vnTicketDescriptorMenu', () => { it('should make a query and show a success snackbar', () => { jest.spyOn(controller.vnApp, 'showSuccess'); + $httpBackend.whenGET(`InvoiceOuts/${ticket.invoiceOut.id}`).respond(); $httpBackend.expectPOST(`InvoiceOuts/${ticket.invoiceOut.id}/createPdf`).respond(); controller.createInvoicePdf(); $httpBackend.flush(); diff --git a/modules/ticket/front/descriptor/index.js b/modules/ticket/front/descriptor/index.js index 28d5eb953e..172e2767e6 100644 --- a/modules/ticket/front/descriptor/index.js +++ b/modules/ticket/front/descriptor/index.js @@ -18,6 +18,10 @@ class Controller extends Descriptor { super.entity = value; } + get hasInvoicing() { + return this.aclService.hasAny(['invoicing']); + } + loadData() { const filter = { include: [ diff --git a/modules/ticket/front/descriptor/locale/es.yml b/modules/ticket/front/descriptor/locale/es.yml index c2b181c97e..c72b2e9233 100644 --- a/modules/ticket/front/descriptor/locale/es.yml +++ b/modules/ticket/front/descriptor/locale/es.yml @@ -21,8 +21,8 @@ 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 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? +Generate PDF invoice document: Generar PDF de la factura +Are you sure you want to generate/regenerate the PDF invoice?: ¿Seguro que quieres generar/regenerar el PDF de la factura? Shipped hour updated: Hora de envio modificada Deleted ticket: Ticket eliminado Recalculate components: Recalcular componentes From 68178bdb1faac2880be62471d5658f8af1509f54 Mon Sep 17 00:00:00 2001 From: joan Date: Fri, 1 Oct 2021 14:48:25 +0200 Subject: [PATCH 13/13] Updated unit tests --- modules/invoiceOut/front/descriptor/index.spec.js | 1 - modules/ticket/front/descriptor-menu/index.spec.js | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/modules/invoiceOut/front/descriptor/index.spec.js b/modules/invoiceOut/front/descriptor/index.spec.js index 6bf49d32b1..0a5494b9ab 100644 --- a/modules/invoiceOut/front/descriptor/index.spec.js +++ b/modules/invoiceOut/front/descriptor/index.spec.js @@ -19,7 +19,6 @@ describe('vnInvoiceOutDescriptor', () => { controller.invoiceOut = invoiceOut; $httpBackend.whenGET(`InvoiceOuts/${invoiceOut.id}`).respond(); - $httpBackend.whenGET(`Tickets/16`).respond(); $httpBackend.expectPOST(`InvoiceOuts/${invoiceOut.id}/createPdf`).respond(); controller.createInvoicePdf(); $httpBackend.flush(); diff --git a/modules/ticket/front/descriptor-menu/index.spec.js b/modules/ticket/front/descriptor-menu/index.spec.js index d10f4e9580..eabb772355 100644 --- a/modules/ticket/front/descriptor-menu/index.spec.js +++ b/modules/ticket/front/descriptor-menu/index.spec.js @@ -153,7 +153,7 @@ describe('Ticket Component vnTicketDescriptorMenu', () => { it('should make a query and show a success snackbar', () => { jest.spyOn(controller.vnApp, 'showSuccess'); - $httpBackend.whenGET(`InvoiceOuts/${ticket.invoiceOut.id}`).respond(); + $httpBackend.whenGET(`Tickets/16`).respond(); $httpBackend.expectPOST(`InvoiceOuts/${ticket.invoiceOut.id}/createPdf`).respond(); controller.createInvoicePdf(); $httpBackend.flush();