diff --git a/back/models/autonomy.json b/back/models/autonomy.json index 8c9d82936..214061cf5 100644 --- a/back/models/autonomy.json +++ b/back/models/autonomy.json @@ -16,6 +16,10 @@ "name": { "type": "string", "required": true + }, + "hasDailyInvoice": { + "type": "boolean", + "description": "Indicates if the autonomy has daily invoice enabled" } }, "relations": { @@ -40,4 +44,4 @@ "permission": "ALLOW" } ] -} \ No newline at end of file +} diff --git a/back/models/country.json b/back/models/country.json index 5b9d842a8..80d456702 100644 --- a/back/models/country.json +++ b/back/models/country.json @@ -28,6 +28,10 @@ }, "continentFk": { "type": "number" + }, + "hasDailyInvoice": { + "type": "boolean", + "description": "Indicates if the autonomy has daily invoice enabled" } }, "relations": { diff --git a/back/models/province.json b/back/models/province.json index 77e0b24a6..61a1574d7 100644 --- a/back/models/province.json +++ b/back/models/province.json @@ -16,6 +16,9 @@ "name": { "type": "string", "required": true + }, + "autonomyFk": { + "type": "number" } }, "relations": { @@ -55,4 +58,4 @@ "permission": "ALLOW" } ] -} \ No newline at end of file +} diff --git a/db/routines/vn/procedures/client_create.sql b/db/routines/vn/procedures/client_create.sql index 3df3df905..fad01c107 100644 --- a/db/routines/vn/procedures/client_create.sql +++ b/db/routines/vn/procedures/client_create.sql @@ -34,22 +34,19 @@ BEGIN DECLARE vIsTaxDataChecked TINYINT(1); DECLARE vHasCoreVnl BOOLEAN; DECLARE vMandateTypeFk INT; - DECLARE vHasDailyInvoice BOOLEAN; SELECT cc.defaultPayMethodFk, cc.defaultDueDay, cc.defaultCredit, cc.defaultIsTaxDataChecked, cc.defaultHasCoreVnl, - cc.defaultMandateTypeFk, - c.hasDailyInvoice + cc.defaultMandateTypeFk INTO vPayMethodFk, vDueDay, vDefaultCredit, vIsTaxDataChecked, vHasCoreVnl, - vMandateTypeFk, - vHasDailyInvoice + vMandateTypeFk FROM clientConfig cc LEFT JOIN province p ON p.id = vProvinceFk LEFT JOIN country c ON c.id = p.countryFk; @@ -70,8 +67,7 @@ BEGIN credit = vDefaultCredit, isTaxDataChecked = vIsTaxDataChecked, hasCoreVnl = vHasCoreVnl, - isEqualizated = FALSE, - hasDailyInvoice = vHasDailyInvoice + isEqualizated = FALSE ON duplicate KEY UPDATE payMethodFk = vPayMethodFk, dueDay = vDueDay, diff --git a/db/routines/vn/procedures/ticket_close.sql b/db/routines/vn/procedures/ticket_close.sql index 0da001ffa..e2dcef9a5 100644 --- a/db/routines/vn/procedures/ticket_close.sql +++ b/db/routines/vn/procedures/ticket_close.sql @@ -43,7 +43,7 @@ BEGIN c.isTaxDataChecked, t.companyFk, t.shipped, - IFNULL(a.hasDailyInvoice, co.hasDailyInvoice), + c.hasDailyInvoice, w.isManaged, c.hasToInvoice INTO vClientFk, @@ -55,9 +55,6 @@ BEGIN vHasToInvoice FROM ticket t JOIN `client` c ON c.id = t.clientFk - JOIN province p ON p.id = c.provinceFk - LEFT JOIN autonomy a ON a.id = p.autonomyFk - JOIN country co ON co.id = p.countryFk JOIN warehouse w ON w.id = t.warehouseFk WHERE t.id = vCurTicketFk; @@ -85,7 +82,7 @@ BEGIN IF(vHasDailyInvoice) AND vHasToInvoice THEN SELECT invoiceSerial(vClientFk, vCompanyFk, 'quick') INTO vSerial; - IF vSerial IS NULL THEN + IF vSerial IS NULL THEN CALL util.throw('Cannot booking without a serial'); END IF; diff --git a/db/versions/11302-limeTulip/00-firstScript.sql b/db/versions/11302-limeTulip/00-firstScript.sql new file mode 100644 index 000000000..7bda31b64 --- /dev/null +++ b/db/versions/11302-limeTulip/00-firstScript.sql @@ -0,0 +1,13 @@ + +UPDATE `vn`.`client` c + JOIN `vn`.`country` co ON co.id=c.countryFk +SET c.hasDailyInvoice = co.hasDailyInvoice +WHERE co.hasDailyInvoice IS NOT NULL + AND c.hasDailyInvoice = FALSE; + +UPDATE `vn`.`client` c + JOIN `vn`.`province` p ON p.id=c.provinceFk + JOIN `vn`.`autonomy` a ON a.id = p.autonomyFk +SET c.hasDailyInvoice = a.hasDailyInvoice +WHERE a.hasDailyInvoice IS NOT NULL + AND c.hasDailyInvoice = FALSE; diff --git a/modules/client/back/methods/client/createWithUser.js b/modules/client/back/methods/client/createWithUser.js index 06b885ab8..c8cd282e1 100644 --- a/modules/client/back/methods/client/createWithUser.js +++ b/modules/client/back/methods/client/createWithUser.js @@ -43,6 +43,23 @@ module.exports = function(Self) { }; try { + const province = await models.Province.findOne({ + where: {id: data.provinceFk}, + fields: ['autonomyFk'] + }); + + const autonomy = province ? await models.Autonomy.findOne({ + where: {id: province.autonomyFk}, + fields: ['hasDailyInvoice'] + }) : null; + + const country = await models.Country.findOne({ + where: {id: data.countryFk}, + fields: ['hasDailyInvoice'] + }); + + const hasDailyInvoice = (autonomy?.hasDailyInvoice ?? country?.hasDailyInvoice) || false; + const account = await models.VnUser.create(user, myOptions); const client = await Self.create({ id: account.id, @@ -57,7 +74,8 @@ module.exports = function(Self) { provinceFk: data.provinceFk, countryFk: data.countryFk, isEqualizated: data.isEqualizated, - businessTypeFk: data.businessTypeFk + businessTypeFk: data.businessTypeFk, + hasDailyInvoice: hasDailyInvoice }, myOptions); const address = await models.Address.create({ diff --git a/modules/client/back/methods/client/specs/createWithUser.spec.js b/modules/client/back/methods/client/specs/createWithUser.spec.js index 5b1ff5da9..8cff96ac5 100644 --- a/modules/client/back/methods/client/specs/createWithUser.spec.js +++ b/modules/client/back/methods/client/specs/createWithUser.spec.js @@ -1,67 +1,78 @@ const models = require('vn-loopback/server/server').models; + describe('Client Create', () => { - const newAccount = { - userName: 'deadpool', - email: 'deadpool@marvel.com', - fi: '16195279J', - name: 'Wade', - socialName: 'DEADPOOL MARVEL', - street: 'WALL STREET', - city: 'New York', - businessTypeFk: 'florist', - provinceFk: 1 - }; - const newAccountWithoutEmail = JSON.parse(JSON.stringify(newAccount)); - delete newAccountWithoutEmail.email; + let options; + let tx; beforeAll.mockLoopBackContext(); - it(`should not find deadpool as he's not created yet`, async() => { - const tx = await models.Client.beginTransaction({}); + beforeEach(async() => { + tx = await models.Client.beginTransaction({}); + options = {transaction: tx}; + }); + afterEach(async() => await tx.rollback()); + + it('should not find deadpool as he is not created yet', async() => { try { - const options = {transaction: tx}; + const account = await models.VnUser.findOne({where: {name: 'deadpool'}}, options); + const client = await models.Client.findOne({where: {name: 'Wade'}}, options); - const account = await models.VnUser.findOne({where: {name: newAccount.userName}}, options); - const client = await models.Client.findOne({where: {name: newAccount.name}}, options); - - expect(account).toEqual(null); - expect(client).toEqual(null); - - await tx.rollback(); + expect(account).toBeNull(); + expect(client).toBeNull(); } catch (e) { await tx.rollback(); throw e; } }); - it('should not create a new account', async() => { - const tx = await models.Client.beginTransaction({}); - + it('should throw an error when creating a new account without email', async() => { let error; + const newAccountWithoutEmail = { + userName: 'deadpool', + fi: '16195279J', + name: 'Wade', + socialName: 'DEADPOOL MARVEL', + street: 'WALL STREET', + city: 'New York', + businessTypeFk: 'florist', + provinceFk: 1 + }; + try { - const options = {transaction: tx}; await models.Client.createWithUser(newAccountWithoutEmail, options); - - await tx.rollback(); } catch (e) { - error = e.message; - - await tx.rollback(); + error = e; } - expect(error).toEqual(`An email is necessary`); + expect(error.message).toEqual('An email is necessary'); }); - it('should create a new account', async() => { - const tx = await models.Client.beginTransaction({}); + it('should create a new account with dailyInvoice', async() => { + const newAccount = { + userName: 'deadpool', + email: 'deadpool@marvel.com', + fi: '16195279J', + name: 'Wade', + socialName: 'DEADPOOL MARVEL', + street: 'WALL STREET', + city: 'New York', + businessTypeFk: 'florist', + provinceFk: 1 + }; try { - const options = {transaction: tx}; + const province = await models.Province.findById(newAccount.provinceFk, { + fields: ['id', 'name', 'autonomyFk'], + include: { + relation: 'autonomy' + } + }, options); const client = await models.Client.createWithUser(newAccount, options); const account = await models.VnUser.findOne({where: {name: newAccount.userName}}, options); + expect(province.autonomy().hasDailyInvoice).toBeTruthy(); expect(account.name).toEqual(newAccount.userName); expect(client.id).toEqual(account.id); expect(client.name).toEqual(newAccount.name); @@ -69,8 +80,38 @@ describe('Client Create', () => { expect(client.fi).toEqual(newAccount.fi); expect(client.socialName).toEqual(newAccount.socialName); expect(client.businessTypeFk).toEqual(newAccount.businessTypeFk); - + expect(client.hasDailyInvoice).toBeTruthy(); + } catch (e) { await tx.rollback(); + throw e; + } + }); + + it('should create a new account without dailyInvoice', async() => { + const newAccount = { + userName: 'deadpool', + email: 'deadpool@marvel.com', + fi: '16195279J', + name: 'Wade', + socialName: 'DEADPOOL MARVEL', + street: 'WALL STREET', + city: 'New York', + businessTypeFk: 'florist', + provinceFk: 3 + }; + + try { + const province = await models.Province.findById(newAccount.provinceFk, { + fields: ['id', 'name', 'autonomyFk'], + include: { + relation: 'autonomy' + } + }, options); + + const client = await models.Client.createWithUser(newAccount, options); + + expect(province.autonomy.hasDailyInvoice).toBeFalsy(); + expect(client.hasDailyInvoice).toBeFalsy(); } catch (e) { await tx.rollback(); throw e; @@ -78,26 +119,25 @@ describe('Client Create', () => { }); it('should not be able to create a user if exists', async() => { - const tx = await models.Client.beginTransaction({}); - let error; - + const newAccount = { + userName: 'deadpool', + email: 'deadpool@marvel.com', + fi: '16195279J', + name: 'Wade', + socialName: 'DEADPOOL MARVEL', + street: 'WALL STREET', + city: 'New York', + businessTypeFk: 'florist', + provinceFk: 1 + }; try { - const options = {transaction: tx}; - await models.Client.createWithUser(newAccount, options); - const client = await models.Client.createWithUser(newAccount, options); - - expect(client).toBeNull(); - - await tx.rollback(); + await models.Client.createWithUser(newAccount, options); } catch (e) { - await tx.rollback(); error = e; } - const errorName = error.details.codes.name[0]; - - expect(errorName).toEqual('uniqueness'); + expect(error.message).toContain('already exists'); }); }); diff --git a/modules/ticket/back/methods/ticket/closeAll.js b/modules/ticket/back/methods/ticket/closeAll.js index 4fd72d454..b9060d2f2 100644 --- a/modules/ticket/back/methods/ticket/closeAll.js +++ b/modules/ticket/back/methods/ticket/closeAll.js @@ -41,7 +41,7 @@ module.exports = Self => { c.salesPersonFk, c.isToBeMailed, c.hasToInvoice, - co.hasDailyInvoice, + c.hasDailyInvoice, eu.email salesPersonEmail, t.addressFk FROM ticket t @@ -120,7 +120,7 @@ module.exports = Self => { WHERE (al.code = 'PACKED' OR (am.code = 'refund' AND al.code <> 'delivered')) AND t.shipped BETWEEN ? - INTERVAL tc.closureDaysAgo DAY AND util.dayEnd(?) AND t.refFk IS NULL - AND IFNULL(a.hasDailyInvoice, co.hasDailyInvoice) + AND c.hasDailyInvoice GROUP BY ticketFk HAVING hasErrorToInvoice OR hasErrorTaxDataChecked diff --git a/modules/ticket/back/methods/ticket/closeByTicket.js b/modules/ticket/back/methods/ticket/closeByTicket.js index 40fe048a5..8a21267b6 100644 --- a/modules/ticket/back/methods/ticket/closeByTicket.js +++ b/modules/ticket/back/methods/ticket/closeByTicket.js @@ -50,7 +50,7 @@ module.exports = Self => { c.salesPersonFk, c.isToBeMailed, c.hasToInvoice, - co.hasDailyInvoice, + c.hasDailyInvoice, eu.email salesPersonEmail, t.addressFk FROM expedition e @@ -58,8 +58,6 @@ module.exports = Self => { JOIN ticketState ts ON ts.ticketFk = t.id JOIN alertLevel al ON al.id = ts.alertLevel JOIN client c ON c.id = t.clientFk - JOIN province p ON p.id = c.provinceFk - JOIN country co ON co.id = p.countryFk LEFT JOIN account.emailUser eu ON eu.userFk = c.salesPersonFk WHERE al.code = 'PACKED' AND t.id = ?