fix(invoicePdf): Create PDF document on invoice download
gitea/salix/pipeline/head There was a failure building this commit Details

Refs: 3109, 3110
This commit is contained in:
Joan Sanchez 2021-09-29 12:15:42 +02:00
parent debbf1e089
commit 197ed2009f
8 changed files with 64 additions and 37 deletions

View File

@ -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"
}

View File

@ -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'"
}

View File

@ -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;
};
};

View File

@ -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) {

View File

@ -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;
});
}
}

View File

@ -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`);

View File

@ -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;
}
};
};

View File

@ -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"');