diff --git a/CHANGELOG.md b/CHANGELOG.md index 5aaa57192..a672e7986 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed - (Worker -> time-control) Corrección de errores +- (InvoiceOut -> Crear factura) Cuando falla al crear una factura, se devuelve un error ## [24.18.01] - 2024-05-07 diff --git a/e2e/paths/09-invoice-out/03_manualInvoice.spec.js b/e2e/paths/09-invoice-out/03_manualInvoice.spec.js index dfaa55ef9..6addbbe56 100644 --- a/e2e/paths/09-invoice-out/03_manualInvoice.spec.js +++ b/e2e/paths/09-invoice-out/03_manualInvoice.spec.js @@ -40,7 +40,7 @@ describe('InvoiceOut manual invoice path', () => { await page.waitToClick(selectors.invoiceOutIndex.createInvoice); await page.waitForSelector(selectors.invoiceOutIndex.manualInvoiceForm); - await page.autocompleteSearch(selectors.invoiceOutIndex.manualInvoiceClient, 'Max Eisenhardt'); + await page.autocompleteSearch(selectors.invoiceOutIndex.manualInvoiceClient, 'Bruce Wayne'); await page.autocompleteSearch(selectors.invoiceOutIndex.manualInvoiceSerial, 'Global nacional'); await page.autocompleteSearch(selectors.invoiceOutIndex.manualInvoiceTaxArea, 'national'); await page.waitToClick(selectors.invoiceOutIndex.saveInvoice); diff --git a/loopback/locale/es.json b/loopback/locale/es.json index d7f9564fe..61b2d1425 100644 --- a/loopback/locale/es.json +++ b/loopback/locale/es.json @@ -353,5 +353,7 @@ "This password can only be changed by the user themselves": "Esta contraseña solo puede ser modificada por el propio usuario", "They're not your subordinate": "No es tu subordinado/a.", "No results found": "No se han encontrado resultados", - "InvoiceIn is already booked": "La factura recibida está contabilizada" -} \ No newline at end of file + "InvoiceIn is already booked": "La factura recibida está contabilizada", + "Select ticket or client": "Elija un ticket o un client", + "It was not able to create the invoice": "No se pudo crear la factura" +} diff --git a/modules/invoiceOut/back/methods/invoiceOut/createManualInvoice.js b/modules/invoiceOut/back/methods/invoiceOut/createManualInvoice.js index 043dfbead..c46da0ba5 100644 --- a/modules/invoiceOut/back/methods/invoiceOut/createManualInvoice.js +++ b/modules/invoiceOut/back/methods/invoiceOut/createManualInvoice.js @@ -46,12 +46,11 @@ module.exports = Self => { } }); - Self.createManualInvoice = async(ctx, options) => { + Self.createManualInvoice = async(ctx, clientFk, ticketFk, maxShipped, serial, taxArea, reference, options) => { + if (!clientFk && !ticketFk) throw new UserError(`Select ticket or client`); const models = Self.app.models; - const args = ctx.args; - - let tx; const myOptions = {userId: ctx.req.accessToken.userId}; + let tx; if (typeof options == 'object') Object.assign(myOptions, options); @@ -61,18 +60,15 @@ module.exports = Self => { myOptions.transaction = tx; } - const ticketId = args.ticketFk; - let clientId = args.clientFk; - let maxShipped = args.maxShipped; let companyId; let newInvoice; let query; try { - if (ticketId) { - const ticket = await models.Ticket.findById(ticketId, null, myOptions); + if (ticketFk) { + const ticket = await models.Ticket.findById(ticketFk, null, myOptions); const company = await models.Company.findById(ticket.companyFk, null, myOptions); - clientId = ticket.clientFk; + clientFk = ticket.clientFk; maxShipped = ticket.shipped; companyId = ticket.companyFk; @@ -85,7 +81,7 @@ module.exports = Self => { throw new UserError(`A ticket with an amount of zero can't be invoiced`); // Validates ticket nagative base - const hasNegativeBase = await getNegativeBase(maxShipped, clientId, companyId, myOptions); + const hasNegativeBase = await getNegativeBase(maxShipped, clientFk, companyId, myOptions); if (hasNegativeBase && company.code == 'VNL') throw new UserError(`A ticket with a negative base can't be invoiced`); } else { @@ -95,7 +91,7 @@ module.exports = Self => { const company = await models.Ticket.findOne({ fields: ['companyFk'], where: { - clientFk: clientId, + clientFk: clientFk, shipped: {lte: maxShipped} } }, myOptions); @@ -103,7 +99,7 @@ module.exports = Self => { } // Validate invoiceable client - const isClientInvoiceable = await isInvoiceable(clientId, myOptions); + const isClientInvoiceable = await isInvoiceable(clientFk, myOptions); if (!isClientInvoiceable) throw new UserError(`This client is not invoiceable`); @@ -114,27 +110,27 @@ module.exports = Self => { if (maxShipped >= tomorrow) throw new UserError(`Can't invoice to future`); - const maxInvoiceDate = await getMaxIssued(args.serial, companyId, myOptions); + const maxInvoiceDate = await getMaxIssued(serial, companyId, myOptions); if (Date.vnNew() < maxInvoiceDate) throw new UserError(`Can't invoice to past`); - if (ticketId) { + if (ticketFk) { query = `CALL invoiceOut_newFromTicket(?, ?, ?, ?, @newInvoiceId)`; await Self.rawSql(query, [ - ticketId, - args.serial, - args.taxArea, - args.reference + ticketFk, + serial, + taxArea, + reference ], myOptions); } else { query = `CALL invoiceOut_newFromClient(?, ?, ?, ?, ?, ?, @newInvoiceId)`; await Self.rawSql(query, [ - clientId, - args.serial, + clientFk, + serial, maxShipped, companyId, - args.taxArea, - args.reference + taxArea, + reference ], myOptions); } @@ -146,26 +142,27 @@ module.exports = Self => { throw e; } - if (newInvoice.id) - await Self.createPdf(ctx, newInvoice.id); + if (!newInvoice.id) throw new UserError('It was not able to create the invoice'); + + await Self.createPdf(ctx, newInvoice.id); return newInvoice; }; - async function isInvoiceable(clientId, options) { + async function isInvoiceable(clientFk, options) { const models = Self.app.models; const query = `SELECT (hasToInvoice AND isTaxDataChecked) AS invoiceable FROM client WHERE id = ?`; - const [result] = await models.InvoiceOut.rawSql(query, [clientId], options); + const [result] = await models.InvoiceOut.rawSql(query, [clientFk], options); return result.invoiceable; } - async function getNegativeBase(maxShipped, clientId, companyId, options) { + async function getNegativeBase(maxShipped, clientFk, companyId, options) { const models = Self.app.models; await models.InvoiceOut.rawSql('CALL invoiceOut_exportationFromClient(?,?,?)', - [maxShipped, clientId, companyId], options + [maxShipped, clientFk, companyId], options ); const query = 'SELECT vn.hasAnyNegativeBase() AS base'; const [result] = await models.InvoiceOut.rawSql(query, [], options); diff --git a/modules/invoiceOut/back/methods/invoiceOut/specs/createManualInvoice.spec.js b/modules/invoiceOut/back/methods/invoiceOut/specs/createManualInvoice.spec.js index b166caf78..55739e570 100644 --- a/modules/invoiceOut/back/methods/invoiceOut/specs/createManualInvoice.spec.js +++ b/modules/invoiceOut/back/methods/invoiceOut/specs/createManualInvoice.spec.js @@ -1,13 +1,10 @@ -const models = require('vn-loopback/server/server').models; +const {models} = require('vn-loopback/server/server'); const LoopBackContext = require('loopback-context'); describe('InvoiceOut createManualInvoice()', () => { - const userId = 1; const ticketId = 16; const clientId = 1106; - const activeCtx = { - accessToken: {userId: userId}, - }; + const activeCtx = {accessToken: {userId: 1}}; const ctx = {req: activeCtx}; it('should throw an error trying to invoice again', async() => { @@ -18,13 +15,8 @@ describe('InvoiceOut createManualInvoice()', () => { let error; try { - ctx.args = { - ticketFk: ticketId, - serial: 'T', - taxArea: 'CEE' - }; - await models.InvoiceOut.createManualInvoice(ctx, options); - await models.InvoiceOut.createManualInvoice(ctx, options); + await createInvoice(ctx, options, undefined, ticketId); + await createInvoice(ctx, options, undefined, ticketId); await tx.rollback(); } catch (e) { @@ -47,17 +39,9 @@ describe('InvoiceOut createManualInvoice()', () => { let error; try { const ticket = await models.Ticket.findById(ticketId, null, options); - await ticket.updateAttributes({ - totalWithVat: 0 - }, options); - - ctx.args = { - ticketFk: ticketId, - serial: 'T', - taxArea: 'CEE' - }; - await models.InvoiceOut.createManualInvoice(ctx, options); + await ticket.updateAttributes({totalWithVat: 0}, options); + await createInvoice(ctx, options, undefined, ticketId); await tx.rollback(); } catch (e) { error = e; @@ -75,13 +59,7 @@ describe('InvoiceOut createManualInvoice()', () => { let error; try { - ctx.args = { - clientFk: clientId, - serial: 'T', - taxArea: 'CEE' - }; - await models.InvoiceOut.createManualInvoice(ctx, options); - + await createInvoice(ctx, options, clientId); await tx.rollback(); } catch (e) { error = e; @@ -103,16 +81,9 @@ describe('InvoiceOut createManualInvoice()', () => { let error; try { const client = await models.Client.findById(clientId, null, options); - await client.updateAttributes({ - isTaxDataChecked: false - }, options); + await client.updateAttributes({isTaxDataChecked: false}, options); - ctx.args = { - ticketFk: ticketId, - serial: 'T', - taxArea: 'CEE' - }; - await models.InvoiceOut.createManualInvoice(ctx, options); + await createInvoice(ctx, options, undefined, ticketId); await tx.rollback(); } catch (e) { @@ -130,12 +101,7 @@ describe('InvoiceOut createManualInvoice()', () => { const options = {transaction: tx}; try { - ctx.args = { - ticketFk: ticketId, - serial: 'T', - taxArea: 'CEE' - }; - const result = await models.InvoiceOut.createManualInvoice(ctx, options); + const result = await createInvoice(ctx, options, undefined, ticketId); expect(result.id).toEqual(jasmine.any(Number)); @@ -146,3 +112,18 @@ describe('InvoiceOut createManualInvoice()', () => { } }); }); + +function createInvoice( + ctx, + options, + clientFk = undefined, + ticketFk = undefined, + maxShipped = undefined, + serial = 'T', + taxArea = 'CEE', + reference = undefined +) { + return models.InvoiceOut.createManualInvoice( + ctx, clientFk, ticketFk, maxShipped, serial, taxArea, reference, options + ); +}