From 9ae27e104e006a964f7feb2cf8aa51a16f12a3a7 Mon Sep 17 00:00:00 2001 From: jgallego Date: Thu, 19 Dec 2024 07:07:56 +0100 Subject: [PATCH 1/2] feat: refs #8167 update canBeInvoiced method to include active status check and improve test cases --- .../back/methods/client/canBeInvoiced.js | 9 +-- .../client/specs/canBeInvoiced.spec.js | 67 ++++++++----------- 2 files changed, 30 insertions(+), 46 deletions(-) diff --git a/modules/client/back/methods/client/canBeInvoiced.js b/modules/client/back/methods/client/canBeInvoiced.js index cdb865500..536606b0b 100644 --- a/modules/client/back/methods/client/canBeInvoiced.js +++ b/modules/client/back/methods/client/canBeInvoiced.js @@ -2,7 +2,7 @@ const UserError = require('vn-loopback/util/user-error'); module.exports = function(Self) { Self.remoteMethod('canBeInvoiced', { - description: 'Change property isEqualizated in all client addresses', + description: 'Check if a client can be invoiced', accessType: 'READ', accepts: [ { @@ -38,7 +38,7 @@ module.exports = function(Self) { Object.assign(myOptions, options); const client = await models.Client.findById(id, { - fields: ['id', 'isTaxDataChecked', 'hasToInvoice', 'payMethodFk'], + fields: ['id', 'isTaxDataChecked', 'hasToInvoice', 'payMethodFk', 'isActive'], include: { relation: 'payMethod', @@ -53,9 +53,6 @@ module.exports = function(Self) { if (client.payMethod().code === 'wireTransfer' && !company.supplierAccountFk) throw new UserError('The company has not informed the supplier account for bank transfers'); - if (client.isTaxDataChecked && client.hasToInvoice) - return true; - - return false; + return client.isTaxDataChecked && client.hasToInvoice && client.isActive; }; }; diff --git a/modules/client/back/methods/client/specs/canBeInvoiced.spec.js b/modules/client/back/methods/client/specs/canBeInvoiced.spec.js index 397be3c92..4012b7409 100644 --- a/modules/client/back/methods/client/specs/canBeInvoiced.spec.js +++ b/modules/client/back/methods/client/specs/canBeInvoiced.spec.js @@ -8,6 +8,8 @@ describe('client canBeInvoiced()', () => { const activeCtx = { accessToken: {userId: userId} }; + let tx; + let options; beforeAll(async() => { spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({ @@ -15,60 +17,45 @@ describe('client canBeInvoiced()', () => { }); }); + beforeEach(async() => { + tx = await models.Client.beginTransaction({}); + options = {transaction: tx}; + }); + + afterEach(async() => { + await tx.rollback(); + }); + it('should return falsy for a client without the data checked', async() => { - const tx = await models.Client.beginTransaction({}); + const client = await models.Client.findById(clientId, null, options); + await client.updateAttribute('isTaxDataChecked', false, options); - try { - const options = {transaction: tx}; + const canBeInvoiced = await models.Client.canBeInvoiced(clientId, companyId, options); - const client = await models.Client.findById(clientId, null, options); - await client.updateAttribute('isTaxDataChecked', false, options); + expect(canBeInvoiced).toEqual(false); + }); - const canBeInvoiced = await models.Client.canBeInvoiced(clientId, companyId, options); + it('should return falsy for a client not active', async() => { + const client = await models.Client.findById(clientId, null, options); + await client.updateAttribute('isActive', false, options); - expect(canBeInvoiced).toEqual(false); + const canBeInvoiced = await models.Client.canBeInvoiced(clientId, companyId, options); - await tx.rollback(); - } catch (e) { - await tx.rollback(); - throw e; - } + expect(canBeInvoiced).toEqual(false); }); it('should return falsy for a client with invoicing disabled', async() => { - const tx = await models.Client.beginTransaction({}); + const client = await models.Client.findById(clientId, null, options); + await client.updateAttribute('hasToInvoice', false, options); - try { - const options = {transaction: tx}; + const canBeInvoiced = await models.Client.canBeInvoiced(clientId, companyId, options); - const client = await models.Client.findById(clientId, null, options); - await client.updateAttribute('hasToInvoice', false, options); - - const canBeInvoiced = await models.Client.canBeInvoiced(clientId, companyId, options); - - expect(canBeInvoiced).toEqual(false); - - await tx.rollback(); - } catch (e) { - await tx.rollback(); - throw e; - } + expect(canBeInvoiced).toEqual(false); }); it('should return truthy for an invoiceable client', async() => { - const tx = await models.Client.beginTransaction({}); + const canBeInvoiced = await models.Client.canBeInvoiced(clientId, companyId, options); - try { - const options = {transaction: tx}; - - const canBeInvoiced = await models.Client.canBeInvoiced(clientId, companyId, options); - - expect(canBeInvoiced).toEqual(true); - - await tx.rollback(); - } catch (e) { - await tx.rollback(); - throw e; - } + expect(canBeInvoiced).toEqual(true); }); }); -- 2.40.1 From 98e2483565754146a05fe7dd3f2a2773b13ceba3 Mon Sep 17 00:00:00 2001 From: jgallego Date: Sun, 29 Dec 2024 09:38:51 +0100 Subject: [PATCH 2/2] feat: refs #8167 update locale and improve invoicing logic with error handling --- loopback/locale/en.json | 9 +++++---- .../back/methods/invoiceOut/clientsToInvoice.js | 12 ++++++++---- .../invoiceOut/specs/clientsToInvoice.spec.js | 4 ++-- .../back/methods/ticket/specs/makeInvoice.spec.js | 4 +++- 4 files changed, 18 insertions(+), 11 deletions(-) diff --git a/loopback/locale/en.json b/loopback/locale/en.json index e6ec52d63..80da13ae5 100644 --- a/loopback/locale/en.json +++ b/loopback/locale/en.json @@ -246,8 +246,9 @@ "ticketLostExpedition": "The ticket [{{ticketId}}]({{{ticketUrl}}}) has the following lost expedition:{{ expeditionId }}", "The raid information is not correct": "The raid information is not correct", "Payment method is required": "Payment method is required", - "Sales already moved": "Sales already moved", - "Holidays to past days not available": "Holidays to past days not available", + "Sales already moved": "Sales already moved", + "Holidays to past days not available": "Holidays to past days not available", "Price cannot be blank": "Price cannot be blank", - "There are tickets to be invoiced": "There are tickets to be invoiced" -} + "There are tickets to be invoiced": "There are tickets to be invoiced", + "The address of the customer must have information about Incoterms and Customs Agent": "The address of the customer must have information about Incoterms and Customs Agent" +} \ No newline at end of file diff --git a/modules/invoiceOut/back/methods/invoiceOut/clientsToInvoice.js b/modules/invoiceOut/back/methods/invoiceOut/clientsToInvoice.js index 5526d214a..7befdcbeb 100644 --- a/modules/invoiceOut/back/methods/invoiceOut/clientsToInvoice.js +++ b/modules/invoiceOut/back/methods/invoiceOut/clientsToInvoice.js @@ -1,3 +1,5 @@ +const UserError = require('vn-loopback/util/user-error'); + module.exports = Self => { Self.remoteMethodCtx('clientsToInvoice', { description: 'Get the clients to make global invoicing', @@ -47,7 +49,12 @@ module.exports = Self => { } try { - // Packaging liquidation + const clientCanBeInvoiced = + await Self.app.models.Client.canBeInvoiced(clientId, companyFk, myOptions); + + if (!clientCanBeInvoiced) + throw new UserError(`This client can't be invoiced`); + const vIsAllInvoiceable = false; await Self.rawSql('CALL ticketPackaging_add(?, ?, ?, ?)', [ clientId, @@ -71,9 +78,6 @@ module.exports = Self => { AND t.shipped BETWEEN ? AND util.dayEnd(?) AND (t.clientFk = ? OR ? IS NULL ) AND t.companyFk = ? - AND c.hasToInvoice - AND c.isTaxDataChecked - AND c.isActive AND NOT t.isDeleted GROUP BY IF(c.hasToInvoiceByAddress, a.id, c.id) HAVING SUM(t.totalWithVat) > 0;`; diff --git a/modules/invoiceOut/back/methods/invoiceOut/specs/clientsToInvoice.spec.js b/modules/invoiceOut/back/methods/invoiceOut/specs/clientsToInvoice.spec.js index 470690c5a..df0566c54 100644 --- a/modules/invoiceOut/back/methods/invoiceOut/specs/clientsToInvoice.spec.js +++ b/modules/invoiceOut/back/methods/invoiceOut/specs/clientsToInvoice.spec.js @@ -4,11 +4,11 @@ describe('InvoiceOut clientsToInvoice()', () => { const userId = 1; const clientId = 1101; const companyFk = 442; - const maxShipped = new Date(); + const maxShipped = Date.vnNew(); maxShipped.setMonth(11); maxShipped.setDate(31); maxShipped.setHours(23, 59, 59, 999); - const invoiceDate = new Date(); + const invoiceDate = Date.vnNew(); const activeCtx = { getLocale: () => { return 'en'; diff --git a/modules/ticket/back/methods/ticket/specs/makeInvoice.spec.js b/modules/ticket/back/methods/ticket/specs/makeInvoice.spec.js index 88812dc92..f9e4bcac0 100644 --- a/modules/ticket/back/methods/ticket/specs/makeInvoice.spec.js +++ b/modules/ticket/back/methods/ticket/specs/makeInvoice.spec.js @@ -77,6 +77,8 @@ describe('ticket makeInvoice()', () => { await tx.rollback(); } - expect(error.message).toEqual(`The address of the customer must have information about Incoterms and Customs Agent`); + expect(error.message).toEqual( + `The address of the customer must have information about Incoterms and Customs Agent` + ); }); }); -- 2.40.1