diff --git a/db/dump/fixtures.sql b/db/dump/fixtures.sql index efdd0e315..3e99bd39e 100644 --- a/db/dump/fixtures.sql +++ b/db/dump/fixtures.sql @@ -618,8 +618,10 @@ INSERT INTO `vn`.`ticket`(`id`, `priority`, `agencyModeFk`,`warehouseFk`,`routeF (21, NULL, 5, 5, 5, DATE_ADD(CURDATE(), INTERVAL +1 MONTH), DATE_ADD(DATE_ADD(CURDATE(),INTERVAL +1 MONTH), INTERVAL +1 DAY), 1109, 'Somewhere in Holland', 102, NULL, 0, 13, 5, 1, DATE_ADD(CURDATE(), INTERVAL +1 MONTH)), (22, NULL, 5, 5, 5, DATE_ADD(CURDATE(), INTERVAL +1 MONTH), DATE_ADD(DATE_ADD(CURDATE(),INTERVAL +1 MONTH), INTERVAL +1 DAY), 1109, 'Somewhere in Japan', 103, NULL, 0, 13, 5, 1, DATE_ADD(CURDATE(), INTERVAL +1 MONTH)), (23, NULL, 8, 1, 7, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 1101, 'address 21', 121, NULL, 0, 5, 5, 1, CURDATE()), - (24 ,NULL, 8, 1, 7, CURDATE(), CURDATE(), 1101, 'Bruce Wayne', 1, NULL, 0, 5, 5, 1, CURDATE()); - + (24 ,NULL, 8, 1, 7, CURDATE(), CURDATE(), 1101, 'Bruce Wayne', 1, NULL, 0, 5, 5, 1, CURDATE()), + (25 ,NULL, 8, 1, NULL, CURDATE(), CURDATE(), 1101, 'Bruce Wayne', 1, NULL, 0, 1, 5, 1, CURDATE()), + (26 ,NULL, 8, 1, NULL, CURDATE(), CURDATE(), 1101, 'An incredibly long alias for testing purposes', 1, NULL, 0, 1, 5, 1, CURDATE()), + (27 ,NULL, 8, 1, NULL, CURDATE(), CURDATE(), 1101, 'Wolverine', 1, NULL, 0, 1, 5, 1, CURDATE()); INSERT INTO `vn`.`ticketObservation`(`id`, `ticketFk`, `observationTypeFk`, `description`) VALUES (1, 11, 1, 'ready'), diff --git a/e2e/paths/04-item/08_regularize.spec.js b/e2e/paths/04-item/08_regularize.spec.js index 97c45643f..400df666f 100644 --- a/e2e/paths/04-item/08_regularize.spec.js +++ b/e2e/paths/04-item/08_regularize.spec.js @@ -127,8 +127,8 @@ describe('Item regularize path', () => { await page.waitForState('ticket.index'); }); - it('should search for the ticket with id 25 once again', async() => { - await page.accessToSearchResult('25'); + it('should search for the ticket with id 28 once again', async() => { + await page.accessToSearchResult('28'); await page.waitForState('ticket.card.summary'); }); diff --git a/e2e/paths/05-ticket/18_index_payout.spec.js b/e2e/paths/05-ticket/18_index_payout.spec.js index c3325360a..220dacf61 100644 --- a/e2e/paths/05-ticket/18_index_payout.spec.js +++ b/e2e/paths/05-ticket/18_index_payout.spec.js @@ -33,7 +33,7 @@ describe('Ticket index payout path', () => { await page.waitToClick(selectors.ticketsIndex.openAdvancedSearchButton); await page.write(selectors.ticketsIndex.advancedSearchClient, '1101'); await page.keyboard.press('Enter'); - await page.waitForNumberOfElements(selectors.ticketsIndex.anySearchResult, 6); + await page.waitForNumberOfElements(selectors.ticketsIndex.anySearchResult, 9); await page.waitToClick(selectors.ticketsIndex.firstTicketCheckbox); await page.waitToClick(selectors.ticketsIndex.secondTicketCheckbox); diff --git a/loopback/locale/es.json b/loopback/locale/es.json index aa60f975e..d5989a3c3 100644 --- a/loopback/locale/es.json +++ b/loopback/locale/es.json @@ -52,8 +52,6 @@ "Agency cannot be blank": "La agencia no puede quedar en blanco", "You can't make changes on a client with verified data": "No puedes hacer cambios en un cliente con datos comprobados", "This address doesn't exist": "Este consignatario no existe", - "You can't create an order for a inactive client": "You can't create an order for a inactive client", - "You can't create an order for a client that doesn't has tax data verified": "You can't create an order for a client that doesn't has tax data verified", "You must delete the claim id %d first": "Antes debes borrar la reclamación %d", "You don't have enough privileges": "No tienes suficientes permisos", "Cannot check Equalization Tax in this NIF/CIF": "No se puede marcar RE en este NIF/CIF", diff --git a/modules/entry/back/methods/entry/specs/addBuy.spec.js b/modules/entry/back/methods/entry/specs/addBuy.spec.js index ef1177ed5..ead75f2d2 100644 --- a/modules/entry/back/methods/entry/specs/addBuy.spec.js +++ b/modules/entry/back/methods/entry/specs/addBuy.spec.js @@ -1,4 +1,4 @@ -const app = require('vn-loopback/server/server'); +const models = require('vn-loopback/server/server').models; const LoopBackContext = require('loopback-context'); describe('entry addBuy()', () => { @@ -25,11 +25,11 @@ describe('entry addBuy()', () => { packageFk: 3 }; - const tx = await app.models.Entry.beginTransaction({}); + const tx = await models.Entry.beginTransaction({}); const options = {transaction: tx}; try { - const newBuy = await app.models.Entry.addBuy(ctx, options); + const newBuy = await models.Entry.addBuy(ctx, options); expect(newBuy.itemFk).toEqual(itemId); diff --git a/modules/entry/back/methods/entry/specs/deleteBuys.spec.js b/modules/entry/back/methods/entry/specs/deleteBuys.spec.js index b937b7474..6fe0d4d67 100644 --- a/modules/entry/back/methods/entry/specs/deleteBuys.spec.js +++ b/modules/entry/back/methods/entry/specs/deleteBuys.spec.js @@ -1,4 +1,4 @@ -const app = require('vn-loopback/server/server'); +const models = require('vn-loopback/server/server').models; const LoopBackContext = require('loopback-context'); describe('sale deleteBuys()', () => { @@ -15,13 +15,13 @@ describe('sale deleteBuys()', () => { active: activeCtx }); - const tx = await app.models.Entry.beginTransaction({}); + const tx = await models.Entry.beginTransaction({}); const options = {transaction: tx}; ctx.args = {buys: [{id: 1}]}; try { - const result = await app.models.Buy.deleteBuys(ctx, options); + const result = await models.Buy.deleteBuys(ctx, options); expect(result).toEqual([{count: 1}]); await tx.rollback(); diff --git a/modules/entry/back/methods/entry/specs/editLatestBuys.spec.js b/modules/entry/back/methods/entry/specs/editLatestBuys.spec.js index 40be5f70e..b17b0ab21 100644 --- a/modules/entry/back/methods/entry/specs/editLatestBuys.spec.js +++ b/modules/entry/back/methods/entry/specs/editLatestBuys.spec.js @@ -1,9 +1,8 @@ -const app = require('vn-loopback/server/server'); -const model = app.models.Buy; +const models = require('vn-loopback/server/server').models; describe('Buy editLatestsBuys()', () => { it('should change the value of a given column for the selected buys', async() => { - const tx = await app.models.Entry.beginTransaction({}); + const tx = await models.Buy.beginTransaction({}); const options = {transaction: tx}; try { @@ -13,15 +12,15 @@ describe('Buy editLatestsBuys()', () => { } }; - const [original] = await model.latestBuysFilter(ctx, null, options); + const [original] = await models.Buy.latestBuysFilter(ctx, null, options); const field = 'size'; const newValue = 99; const lines = [{itemFk: original.itemFk, id: original.id}]; - await model.editLatestBuys(field, newValue, lines, options); + await models.Buy.editLatestBuys(field, newValue, lines, options); - const [result] = await model.latestBuysFilter(ctx, null, options); + const [result] = await models.Buy.latestBuysFilter(ctx, null, options); expect(result[field]).toEqual(newValue); diff --git a/modules/entry/back/methods/entry/specs/filter.spec.js b/modules/entry/back/methods/entry/specs/filter.spec.js index 25d2da0b4..dcad13320 100644 --- a/modules/entry/back/methods/entry/specs/filter.spec.js +++ b/modules/entry/back/methods/entry/specs/filter.spec.js @@ -1,77 +1,137 @@ -const app = require('vn-loopback/server/server'); +const models = require('vn-loopback/server/server').models; describe('Entry filter()', () => { it('should return the entry matching "search"', async() => { - let ctx = { - args: { - search: 1 - } - }; + const tx = await models.Entry.beginTransaction({}); + const options = {transaction: tx}; - let result = await app.models.Entry.filter(ctx); + try { + const ctx = { + args: { + search: 1 + } + }; - expect(result.length).toEqual(1); - expect(result[0].id).toEqual(1); + const result = await models.Entry.filter(ctx, options); + + expect(result.length).toEqual(1); + expect(result[0].id).toEqual(1); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } }); it('should return the entry matching the currency', async() => { - let ctx = { - args: { - currencyFk: 1 - } - }; + const tx = await models.Entry.beginTransaction({}); + const options = {transaction: tx}; - let result = await app.models.Entry.filter(ctx); + try { + const ctx = { + args: { + currencyFk: 1 + } + }; - expect(result.length).toEqual(8); + const result = await models.Entry.filter(ctx, options); + + expect(result.length).toEqual(8); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } }); it('should return the entry matching the supplier', async() => { - let ctx = { - args: { - supplierFk: 2 - } - }; + const tx = await models.Entry.beginTransaction({}); + const options = {transaction: tx}; - let result = await app.models.Entry.filter(ctx); + try { + const ctx = { + args: { + supplierFk: 2 + } + }; - expect(result.length).toEqual(6); + const result = await models.Entry.filter(ctx, options); + + expect(result.length).toEqual(6); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } }); it('should return the entry matching the company', async() => { - let ctx = { - args: { - companyFk: 442 - } - }; + const tx = await models.Entry.beginTransaction({}); + const options = {transaction: tx}; - let result = await app.models.Entry.filter(ctx); + try { + const ctx = { + args: { + companyFk: 442 + } + }; - expect(result.length).toEqual(7); + const result = await models.Entry.filter(ctx, options); + + expect(result.length).toEqual(7); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } }); it('should return the entries matching isBooked', async() => { - let ctx = { - args: { - isBooked: true, - } - }; + const tx = await models.Entry.beginTransaction({}); + const options = {transaction: tx}; - let result = await app.models.Entry.filter(ctx); + try { + const ctx = { + args: { + isBooked: true, + } + }; - expect(result.length).toEqual(0); + const result = await models.Entry.filter(ctx, options); + + expect(result.length).toEqual(0); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } }); it('should return the routes matching the reference and travel', async() => { - let ctx = { - args: { - reference: 'movement', - travelFk: '2' - } - }; + const tx = await models.Entry.beginTransaction({}); + const options = {transaction: tx}; - let result = await app.models.Entry.filter(ctx); + try { + const ctx = { + args: { + reference: 'movement', + travelFk: '2' + } + }; - expect(result.length).toEqual(2); + const result = await models.Entry.filter(ctx, options); + + expect(result.length).toEqual(2); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } }); }); diff --git a/modules/entry/back/methods/entry/specs/getBuys.spec.js b/modules/entry/back/methods/entry/specs/getBuys.spec.js index b660ab2ad..cf4462e48 100644 --- a/modules/entry/back/methods/entry/specs/getBuys.spec.js +++ b/modules/entry/back/methods/entry/specs/getBuys.spec.js @@ -1,14 +1,24 @@ -const app = require('vn-loopback/server/server'); +const models = require('vn-loopback/server/server').models; describe('entry getBuys()', () => { const entryId = 4; it('should get the buys and items of an entry', async() => { - const result = await app.models.Entry.getBuys(entryId); + const tx = await models.Entry.beginTransaction({}); + const options = {transaction: tx}; - const length = result.length; - const anyResult = result[Math.floor(Math.random() * Math.floor(length))]; + try { + const result = await models.Entry.getBuys(entryId, options); - expect(result.length).toEqual(4); - expect(anyResult.item).toBeDefined(); + const length = result.length; + const anyResult = result[Math.floor(Math.random() * Math.floor(length))]; + + expect(result.length).toEqual(4); + expect(anyResult.item).toBeDefined(); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } }); }); diff --git a/modules/entry/back/methods/entry/specs/getEntry.spec.js b/modules/entry/back/methods/entry/specs/getEntry.spec.js index 3791a3703..bf96015c5 100644 --- a/modules/entry/back/methods/entry/specs/getEntry.spec.js +++ b/modules/entry/back/methods/entry/specs/getEntry.spec.js @@ -1,31 +1,71 @@ -const app = require('vn-loopback/server/server'); +const models = require('vn-loopback/server/server').models; describe('travel getEntry()', () => { const entryId = 1; it('should check the entry contains the id', async() => { - const entry = await app.models.Entry.getEntry(entryId); + const tx = await models.Entry.beginTransaction({}); + const options = {transaction: tx}; - expect(entry.id).toEqual(entryId); + try { + const entry = await models.Entry.getEntry(entryId, options); + + expect(entry.id).toEqual(entryId); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } }); it('should check the entry contains the supplier name', async() => { - const entry = await app.models.Entry.getEntry(entryId); - const supplierName = entry.supplier().nickname; + const tx = await models.Entry.beginTransaction({}); + const options = {transaction: tx}; - expect(supplierName).toEqual('Plants nick'); + try { + const entry = await models.Entry.getEntry(entryId, options); + const supplierName = entry.supplier().nickname; + + expect(supplierName).toEqual('Plants nick'); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } }); it('should check the entry contains the receiver warehouse name', async() => { - const entry = await app.models.Entry.getEntry(entryId); - const receiverWarehouseName = entry.travel().warehouseIn().name; + const tx = await models.Entry.beginTransaction({}); + const options = {transaction: tx}; - expect(receiverWarehouseName).toEqual('Warehouse One'); + try { + const entry = await models.Entry.getEntry(entryId, options); + const receiverWarehouseName = entry.travel().warehouseIn().name; + + expect(receiverWarehouseName).toEqual('Warehouse One'); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } }); it('should check the entry contains the company code', async() => { - const entry = await app.models.Entry.getEntry(entryId); - const companyCode = entry.company().code; + const tx = await models.Entry.beginTransaction({}); + const options = {transaction: tx}; - expect(companyCode).toEqual('VNL'); + try { + const entry = await models.Entry.getEntry(entryId, options); + const companyCode = entry.company().code; + + expect(companyCode).toEqual('VNL'); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } }); }); diff --git a/modules/entry/back/methods/entry/specs/importBuys.spec.js b/modules/entry/back/methods/entry/specs/importBuys.spec.js index 467c21e90..f6da44f2a 100644 --- a/modules/entry/back/methods/entry/specs/importBuys.spec.js +++ b/modules/entry/back/methods/entry/specs/importBuys.spec.js @@ -1,4 +1,4 @@ -const app = require('vn-loopback/server/server'); +const models = require('vn-loopback/server/server').models; const LoopBackContext = require('loopback-context'); describe('entry import()', () => { @@ -48,10 +48,10 @@ describe('entry import()', () => { ] } }; - const tx = await app.models.Entry.beginTransaction({}); + const tx = await models.Entry.beginTransaction({}); try { const options = {transaction: tx}; - const newEntry = await app.models.Entry.create({ + const newEntry = await models.Entry.create({ dated: new Date(), supplierFk: supplierId, travelFk: travelId, @@ -60,10 +60,10 @@ describe('entry import()', () => { ref: 'Entry ref' }, options); - await app.models.Entry.importBuys(ctx, newEntry.id, options); + await models.Entry.importBuys(ctx, newEntry.id, options); - const updatedEntry = await app.models.Entry.findById(newEntry.id, null, options); - const entryBuys = await app.models.Buy.find({ + const updatedEntry = await models.Entry.findById(newEntry.id, null, options); + const entryBuys = await models.Buy.find({ where: {entryFk: newEntry.id} }, options); diff --git a/modules/entry/back/methods/entry/specs/importBuysPreview.spec.js b/modules/entry/back/methods/entry/specs/importBuysPreview.spec.js index e62272c15..edfdac988 100644 --- a/modules/entry/back/methods/entry/specs/importBuysPreview.spec.js +++ b/modules/entry/back/methods/entry/specs/importBuysPreview.spec.js @@ -1,4 +1,4 @@ -const app = require('vn-loopback/server/server'); +const models = require('vn-loopback/server/server').models; const LoopBackContext = require('loopback-context'); describe('entry importBuysPreview()', () => { @@ -10,30 +10,40 @@ describe('entry importBuysPreview()', () => { }); it('should return the buys with the calculated packageFk', async() => { - const expectedPackageFk = '3'; - const buys = [ - { - itemFk: 1, - buyingValue: 5.77, - description: 'Bow', - grouping: 1, - size: 1, - volume: 1200 - }, - { - itemFk: 4, - buyingValue: 2.16, - description: 'Arrow', - grouping: 1, - size: 25, - volume: 1125 - } - ]; + const tx = await models.Entry.beginTransaction({}); + const options = {transaction: tx}; - const result = await app.models.Entry.importBuysPreview(entryId, buys); - const randomIndex = Math.floor(Math.random() * result.length); - const buy = result[randomIndex]; + try { + const expectedPackageFk = '3'; + const buys = [ + { + itemFk: 1, + buyingValue: 5.77, + description: 'Bow', + grouping: 1, + size: 1, + volume: 1200 + }, + { + itemFk: 4, + buyingValue: 2.16, + description: 'Arrow', + grouping: 1, + size: 25, + volume: 1125 + } + ]; - expect(buy.packageFk).toEqual(expectedPackageFk); + const result = await models.Entry.importBuysPreview(entryId, buys, options); + const randomIndex = Math.floor(Math.random() * result.length); + const buy = result[randomIndex]; + + expect(buy.packageFk).toEqual(expectedPackageFk); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } }); }); diff --git a/modules/entry/back/methods/entry/specs/latestBuysFilter.spec.js b/modules/entry/back/methods/entry/specs/latestBuysFilter.spec.js index 2a26dfa55..aa8f23a85 100644 --- a/modules/entry/back/methods/entry/specs/latestBuysFilter.spec.js +++ b/modules/entry/back/methods/entry/specs/latestBuysFilter.spec.js @@ -1,195 +1,345 @@ -const app = require('vn-loopback/server/server'); +const models = require('vn-loopback/server/server').models; describe('Buy latests buys filter()', () => { it('should return the entry matching "search"', async() => { - let ctx = { - args: { - search: 'Ranged weapon longbow 2m' - } - }; + const tx = await models.Buy.beginTransaction({}); + const options = {transaction: tx}; - let results = await app.models.Buy.latestBuysFilter(ctx); - let firstBuy = results[0]; + try { + const ctx = { + args: { + search: 'Ranged weapon longbow 2m' + } + }; - expect(results.length).toEqual(1); - expect(firstBuy.size).toEqual(70); + const results = await models.Buy.latestBuysFilter(ctx); + const firstBuy = results[0]; + + expect(results.length).toEqual(1); + expect(firstBuy.size).toEqual(70); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } }); it('should return the entry matching "id"', async() => { - let ctx = { - args: { - id: 1 - } - }; + const tx = await models.Buy.beginTransaction({}); + const options = {transaction: tx}; - let results = await app.models.Buy.latestBuysFilter(ctx); + try { + const ctx = { + args: { + id: 1 + } + }; - expect(results.length).toEqual(1); + const results = await models.Buy.latestBuysFilter(ctx, options); + + expect(results.length).toEqual(1); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } }); it('should return results matching "tags"', async() => { - let ctx = { - args: { - tags: [ - {tagFk: 27, value: '2m'} - ] - } - }; + const tx = await models.Buy.beginTransaction({}); + const options = {transaction: tx}; - let results = await app.models.Buy.latestBuysFilter(ctx); + try { + const ctx = { + args: { + tags: [ + {tagFk: 27, value: '2m'} + ] + } + }; - expect(results.length).toBe(2); + const results = await models.Buy.latestBuysFilter(ctx, options); + + expect(results.length).toBe(2); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } }); it('should return results matching "categoryFk"', async() => { - let ctx = { - args: { - categoryFk: 1 - } - }; + const tx = await models.Buy.beginTransaction({}); + const options = {transaction: tx}; - let results = await app.models.Buy.latestBuysFilter(ctx); + try { + const ctx = { + args: { + categoryFk: 1 + } + }; - expect(results.length).toBe(4); + const results = await models.Buy.latestBuysFilter(ctx, options); + + expect(results.length).toBe(4); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } }); it('should return results matching "typeFk"', async() => { - let ctx = { - args: { - typeFk: 2 - } - }; + const tx = await models.Buy.beginTransaction({}); + const options = {transaction: tx}; - let results = await app.models.Buy.latestBuysFilter(ctx); + try { + const ctx = { + args: { + typeFk: 2 + } + }; - expect(results.length).toBe(4); + const results = await models.Buy.latestBuysFilter(ctx, options); + + expect(results.length).toBe(4); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } }); it('should return results matching "active"', async() => { - let ctx = { - args: { - active: true - } - }; + const tx = await models.Buy.beginTransaction({}); + const options = {transaction: tx}; - let results = await app.models.Buy.latestBuysFilter(ctx); + try { + const ctx = { + args: { + active: true + } + }; - expect(results.length).toBe(6); + const results = await models.Buy.latestBuysFilter(ctx, options); + + expect(results.length).toBe(6); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } }); it('should return results matching "not active"', async() => { - let ctx = { - args: { - active: false - } - }; + const tx = await models.Buy.beginTransaction({}); + const options = {transaction: tx}; - let results = await app.models.Buy.latestBuysFilter(ctx); + try { + const ctx = { + args: { + active: false + } + }; - expect(results.length).toBe(0); + const results = await models.Buy.latestBuysFilter(ctx, options); + + expect(results.length).toBe(0); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } }); it('should return results matching "visible"', async() => { - let ctx = { - args: { - visible: true - } - }; + const tx = await models.Buy.beginTransaction({}); + const options = {transaction: tx}; - let results = await app.models.Buy.latestBuysFilter(ctx); + try { + const ctx = { + args: { + visible: true + } + }; - expect(results.length).toBe(5); + const results = await models.Buy.latestBuysFilter(ctx, options); + + expect(results.length).toBe(5); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } }); it('should return results matching "not visible"', async() => { - let ctx = { - args: { - visible: false - } - }; + const tx = await models.Buy.beginTransaction({}); + const options = {transaction: tx}; - let results = await app.models.Buy.latestBuysFilter(ctx); + try { + const ctx = { + args: { + visible: false + } + }; - expect(results.length).toBe(0); + const results = await models.Buy.latestBuysFilter(ctx, options); + + expect(results.length).toBe(0); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } }); it('should return results matching "floramondo"', async() => { - let ctx = { - args: { - floramondo: true - } - }; + const tx = await models.Buy.beginTransaction({}); + const options = {transaction: tx}; - let results = await app.models.Buy.latestBuysFilter(ctx); + try { + const ctx = { + args: { + floramondo: true + } + }; - expect(results.length).toBe(1); + const results = await models.Buy.latestBuysFilter(ctx, options); + + expect(results.length).toBe(1); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } }); it('should return results matching "not floramondo"', async() => { - let ctx = { - args: { - floramondo: false - } - }; + const tx = await models.Buy.beginTransaction({}); + const options = {transaction: tx}; - let results = await app.models.Buy.latestBuysFilter(ctx); + try { + const ctx = { + args: { + floramondo: false + } + }; - expect(results.length).toBe(5); + const results = await models.Buy.latestBuysFilter(ctx, options); + + expect(results.length).toBe(5); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } }); it('should return results matching "salesPersonFk"', async() => { - let ctx = { - args: { - salesPersonFk: 35 - } - }; + const tx = await models.Buy.beginTransaction({}); + const options = {transaction: tx}; - let results = await app.models.Buy.latestBuysFilter(ctx); + try { + const ctx = { + args: { + salesPersonFk: 35 + } + }; - expect(results.length).toBe(6); + const results = await models.Buy.latestBuysFilter(ctx, options); + + expect(results.length).toBe(6); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } }); it('should return results matching "description"', async() => { - let ctx = { - args: { - description: 'Increases block' - } - }; + const tx = await models.Buy.beginTransaction({}); + const options = {transaction: tx}; - let results = await app.models.Buy.latestBuysFilter(ctx); + try { + const ctx = { + args: { + description: 'Increases block' + } + }; - expect(results.length).toBe(1); + const results = await models.Buy.latestBuysFilter(ctx, options); + + expect(results.length).toBe(1); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } }); it('should return results matching "supplierFk"', async() => { - let ctx = { - args: { - supplierFk: 1 - } - }; + const tx = await models.Buy.beginTransaction({}); + const options = {transaction: tx}; - let results = await app.models.Buy.latestBuysFilter(ctx); + try { + const ctx = { + args: { + supplierFk: 1 + } + }; - expect(results.length).toBe(2); + const results = await models.Buy.latestBuysFilter(ctx, options); + + expect(results.length).toBe(2); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } }); it('should return results matching "from" and "to"', async() => { - const from = new Date(); - from.setHours(0, 0, 0, 0); + const tx = await models.Buy.beginTransaction({}); + const options = {transaction: tx}; - const to = new Date(); - to.setHours(23, 59, 59, 999); + try { + const from = new Date(); + from.setHours(0, 0, 0, 0); - let ctx = { - args: { - from: from, - to: to - } - }; + const to = new Date(); + to.setHours(23, 59, 59, 999); - let results = await app.models.Buy.latestBuysFilter(ctx); + const ctx = { + args: { + from: from, + to: to + } + }; - expect(results.length).toBe(2); + const results = await models.Buy.latestBuysFilter(ctx, options); + + expect(results.length).toBe(2); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } }); }); diff --git a/modules/monitor/back/methods/sales-monitor/specs/salesFilter.spec.js b/modules/monitor/back/methods/sales-monitor/specs/salesFilter.spec.js index 61bd9ecc6..1ace5f6ef 100644 --- a/modules/monitor/back/methods/sales-monitor/specs/salesFilter.spec.js +++ b/modules/monitor/back/methods/sales-monitor/specs/salesFilter.spec.js @@ -11,7 +11,7 @@ describe('SalesMonitor salesFilter()', () => { const filter = {order: 'id DESC'}; const result = await models.SalesMonitor.salesFilter(ctx, filter, options); - expect(result.length).toEqual(24); + expect(result.length).toEqual(27); await tx.rollback(); } catch (e) { @@ -39,7 +39,7 @@ describe('SalesMonitor salesFilter()', () => { const filter = {}; const result = await models.SalesMonitor.salesFilter(ctx, filter, options); - expect(result.length).toEqual(13); + expect(result.length).toEqual(16); await tx.rollback(); } catch (e) { @@ -87,7 +87,7 @@ describe('SalesMonitor salesFilter()', () => { const filter = {}; const result = await models.SalesMonitor.salesFilter(ctx, filter, options); - expect(result.length).toEqual(24); + expect(result.length).toEqual(27); await tx.rollback(); } catch (e) { @@ -130,7 +130,7 @@ describe('SalesMonitor salesFilter()', () => { const length = result.length; const anyResult = result[Math.floor(Math.random() * Math.floor(length))]; - expect(length).toEqual(7); + expect(length).toEqual(10); expect(anyResult.state).toMatch(/(Libre|Arreglar)/); await tx.rollback(); @@ -175,7 +175,7 @@ describe('SalesMonitor salesFilter()', () => { const filter = {}; const result = await models.SalesMonitor.salesFilter(ctx, filter, options); - expect(result.length).toEqual(20); + expect(result.length).toEqual(23); await tx.rollback(); } catch (e) { diff --git a/modules/order/back/methods/order-row/addToOrder.js b/modules/order/back/methods/order-row/addToOrder.js index 45304917c..639fa8be7 100644 --- a/modules/order/back/methods/order-row/addToOrder.js +++ b/modules/order/back/methods/order-row/addToOrder.js @@ -21,22 +21,42 @@ module.exports = Self => { } }); - Self.addToOrder = async params => { - let isEditable = await Self.app.models.Order.isEditable(params.orderFk); + Self.addToOrder = async(params, options) => { + const myOptions = {}; + let tx; - if (!isEditable) - throw new UserError('This order is not editable'); + if (typeof options == 'object') + Object.assign(myOptions, options); - let promises = []; - params.items.forEach(item => { - promises.push( - Self.rawSql( - `CALL hedera.order_addItem(?, ?, ?, ?)`, - [params.orderFk, item.warehouseFk, item.itemFk, item.quantity] - ) - ); - }); - await Promise.all(promises); - return true; + if (!myOptions.transaction) { + tx = await Self.beginTransaction({}); + myOptions.transaction = tx; + } + + try { + const isEditable = await Self.app.models.Order.isEditable(params.orderFk, myOptions); + + if (!isEditable) + throw new UserError('This order is not editable'); + + const promises = []; + for (const item of params.items) { + promises.push( + Self.rawSql( + `CALL hedera.order_addItem(?, ?, ?, ?)`, + [params.orderFk, item.warehouseFk, item.itemFk, item.quantity], + myOptions + ) + ); + } + await Promise.all(promises); + + if (tx) await tx.commit(); + + return true; + } catch (e) { + if (tx) await tx.rollback(); + throw e; + } }; }; diff --git a/modules/order/back/methods/order-row/removes.js b/modules/order/back/methods/order-row/removes.js index 86f0e70d7..614761aed 100644 --- a/modules/order/back/methods/order-row/removes.js +++ b/modules/order/back/methods/order-row/removes.js @@ -21,19 +21,39 @@ module.exports = Self => { } }); - Self.removes = async params => { - if (!params.rows || !params.rows.length) - throw new UserError('There is nothing to delete'); + Self.removes = async(params, options) => { + const myOptions = {}; + let tx; - let isEditable = await Self.app.models.Order.isEditable(params.actualOrderId); + if (typeof options == 'object') + Object.assign(myOptions, options); - if (!isEditable) - throw new UserError('This order is not editable'); + if (!myOptions.transaction) { + tx = await Self.beginTransaction({}); + myOptions.transaction = tx; + } - let promises = []; - for (let i = 0; i < params.rows.length; i++) - promises.push(Self.app.models.OrderRow.destroyById(params.rows[i])); + try { + if (!params.rows || !params.rows.length) + throw new UserError('There is nothing to delete'); - return await Promise.all(promises); + const isEditable = await Self.app.models.Order.isEditable(params.actualOrderId, myOptions); + + if (!isEditable) + throw new UserError('This order is not editable'); + + const promises = []; + for (let i = 0; i < params.rows.length; i++) + promises.push(Self.app.models.OrderRow.destroyById(params.rows[i], myOptions)); + + const deletions = await Promise.all(promises); + + if (tx) await tx.commit(); + + return deletions; + } catch (e) { + if (tx) await tx.rollback(); + throw e; + } }; }; diff --git a/modules/order/back/methods/order-row/specs/addToOrder.spec.js b/modules/order/back/methods/order-row/specs/addToOrder.spec.js index 6e937176d..d902a1062 100644 --- a/modules/order/back/methods/order-row/specs/addToOrder.spec.js +++ b/modules/order/back/methods/order-row/specs/addToOrder.spec.js @@ -1,32 +1,36 @@ -const app = require('vn-loopback/server/server'); +const models = require('vn-loopback/server/server').models; describe('order addToOrder()', () => { const orderId = 8; - let rowToDelete; - afterAll(async() => { - await app.models.OrderRow.removes({rows: [rowToDelete], actualOrderId: orderId}); - }); - it('should add a row to a given order', async() => { - let unmodifiedRows = await app.models.OrderRow.find({where: {orderFk: orderId}}); + const tx = await models.Order.beginTransaction({}); - expect(unmodifiedRows.length).toBe(2); + try { + const options = {transaction: tx}; - let params = { - orderFk: orderId, - items: [{ - itemFk: 1, - quantity: 10, - warehouseFk: 1 - }] - }; + const unmodifiedRows = await models.OrderRow.find({where: {orderFk: orderId}}, options); - await app.models.OrderRow.addToOrder(params); + expect(unmodifiedRows.length).toBe(2); - let modifiedRows = await app.models.OrderRow.find({where: {orderFk: orderId}}); + const params = { + orderFk: orderId, + items: [{ + itemFk: 1, + quantity: 10, + warehouseFk: 1 + }] + }; - rowToDelete = modifiedRows[modifiedRows.length - 1].id; + await models.OrderRow.addToOrder(params, options); - expect(modifiedRows.length).toBe(3); + const modifiedRows = await models.OrderRow.find({where: {orderFk: orderId}}, options); + + expect(modifiedRows.length).toBe(3); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } }); }); diff --git a/modules/order/back/methods/order-row/specs/removes.spec.js b/modules/order/back/methods/order-row/specs/removes.spec.js index 510676aa0..34c1789cc 100644 --- a/modules/order/back/methods/order-row/specs/removes.spec.js +++ b/modules/order/back/methods/order-row/specs/removes.spec.js @@ -1,20 +1,18 @@ -const app = require('vn-loopback/server/server'); +const models = require('vn-loopback/server/server').models; describe('order removes()', () => { - let row; - let newRow; - - beforeAll(async() => { - row = await app.models.OrderRow.findOne({where: {id: 12}}); - row.id = null; - newRow = await app.models.OrderRow.create(row); - }); - it('should throw an error if rows property is empty', async() => { + const tx = await models.Order.beginTransaction({}); + let error; try { - await app.models.OrderRow.removes({rows: []}); + const options = {transaction: tx}; + + await models.OrderRow.removes({rows: []}, options); + + await tx.rollback(); } catch (e) { + await tx.rollback(); error = e; } @@ -22,10 +20,17 @@ describe('order removes()', () => { }); it('should throw an error if the row selected is not editable', async() => { + const tx = await models.Order.beginTransaction({}); + let error; try { - await app.models.OrderRow.removes({rows: [2]}); + const options = {transaction: tx}; + + await models.OrderRow.removes({rows: [2]}, options); + + await tx.rollback(); } catch (e) { + await tx.rollback(); error = e; } @@ -33,13 +38,24 @@ describe('order removes()', () => { }); it('should delete the row', async() => { - let params = { - rows: [newRow.id], - actualOrderId: 16 - }; + const tx = await models.Order.beginTransaction({}); - let res = await app.models.OrderRow.removes(params); + try { + const options = {transaction: tx}; - expect(res).toEqual([{count: 1}]); + const params = { + rows: [12], + actualOrderId: 16 + }; + + const res = await models.OrderRow.removes(params, options); + + expect(res).toEqual([{count: 1}]); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } }); }); diff --git a/modules/order/back/methods/order/catalogFilter.js b/modules/order/back/methods/order/catalogFilter.js index 4502435b5..0d83f9f4a 100644 --- a/modules/order/back/methods/order/catalogFilter.js +++ b/modules/order/back/methods/order/catalogFilter.js @@ -7,28 +7,28 @@ module.exports = Self => { accepts: [ { arg: 'orderFk', - type: 'Number', + type: 'number', required: true }, { arg: 'orderBy', - type: 'Object', + type: 'object', description: 'Items order', required: true }, { arg: 'filter', - type: 'Object', + type: 'object', description: 'Filter defining where, order, offset, and limit - must be a JSON-encoded string' }, { arg: 'tagGroups', - type: ['Object'], + type: ['object'], description: 'Filter by tag' }, ], returns: { - type: ['Object'], + type: ['object'], root: true, }, http: { @@ -37,8 +37,13 @@ module.exports = Self => { }, }); - Self.catalogFilter = async(orderFk, orderBy, filter, tagGroups) => { - let conn = Self.dataSource.connector; + Self.catalogFilter = async(orderFk, orderBy, filter, tagGroups, options) => { + const conn = Self.dataSource.connector; + const myOptions = {}; + + if (typeof options == 'object') + Object.assign(myOptions, options); + const stmts = []; let stmt; @@ -85,7 +90,7 @@ module.exports = Self => { stmts.push(stmt); // Calculate items - const order = await Self.findById(orderFk); + const order = await Self.findById(orderFk, null, myOptions); stmts.push(new ParameterizedSQL( 'CALL vn.catalog_calculate(?, ?, ?)', [ order.landed, @@ -131,9 +136,9 @@ module.exports = Self => { params: [orderBy.field], }); - let way = orderBy.way == 'DESC' ? 'DESC' : 'ASC'; - let tag = await Self.app.models.Tag.findById(orderBy.field); - let orderSql = ` + const way = orderBy.way == 'DESC' ? 'DESC' : 'ASC'; + const tag = await Self.app.models.Tag.findById(orderBy.field, null, myOptions); + const orderSql = ` ORDER BY itg.value IS NULL, ${tag.isQuantitative ? 'CAST(itg.value AS SIGNED)' : 'itg.value'} @@ -181,7 +186,7 @@ module.exports = Self => { stmts.push('CALL vn.ticketCalculatePurge()'); const sql = ParameterizedSQL.join(stmts, ';'); - const result = await conn.executeStmt(sql); + const result = await conn.executeStmt(sql, myOptions); // Add prices to items result[itemsIndex].forEach(item => { diff --git a/modules/order/back/methods/order/confirm.js b/modules/order/back/methods/order/confirm.js index b9e4f5ab2..52acc8648 100644 --- a/modules/order/back/methods/order/confirm.js +++ b/modules/order/back/methods/order/confirm.js @@ -21,7 +21,10 @@ module.exports = Self => { Self.confirm = async(ctx, orderFk) => { const userId = ctx.req.accessToken.userId; - let query = `CALL hedera.order_confirmWithUser(?, ?)`; - return await Self.rawSql(query, [orderFk, userId]); + + const query = `CALL hedera.order_confirmWithUser(?, ?)`; + const response = await Self.rawSql(query, [orderFk, userId]); + + return response; }; }; diff --git a/modules/order/back/methods/order/filter.js b/modules/order/back/methods/order/filter.js index ddbaba5bd..27cacdd62 100644 --- a/modules/order/back/methods/order/filter.js +++ b/modules/order/back/methods/order/filter.js @@ -9,60 +9,60 @@ module.exports = Self => { accepts: [ { arg: 'ctx', - type: 'Object', + type: 'object', http: {source: 'context'} }, { arg: 'filter', - type: 'Object', - description: `Filter defining where, order, offset, and limit - must be a JSON-encoded string` + type: 'object', + description: 'Filter defining where, order, offset, and limit - must be a JSON-encoded string' }, { arg: 'search', - type: 'String', + type: 'string', description: `If it's and integer searchs by id, otherwise it searchs by nickname` }, { arg: 'from', - type: 'Date', - description: `The from date` + type: 'date', + description: 'The from date' }, { arg: 'to', - type: 'Date', - description: `The to date` + type: 'date', + description: 'The to date' }, { arg: 'id', - type: 'Integer', - description: `The ticket id` + type: 'integer', + description: 'The ticket id' }, { arg: 'clientFk', - type: 'Integer', - description: `The client id` + type: 'integer', + description: 'The client id' }, { arg: 'ticketFk', - type: 'Integer', - description: `The ticket id` + type: 'integer', + description: 'The ticket id' }, { arg: 'agencyModeFk', - type: 'Integer', - description: `The agency mode id` + type: 'integer', + description: 'The agency mode id' }, { arg: 'workerFk', - type: 'Integer', - description: `The salesperson id` + type: 'integer', + description: 'The salesperson id' }, { arg: 'myTeam', - type: 'Boolean', - description: `Whether to show only tickets for the current logged user team (For now it shows only the current user tickets)` + type: 'boolean', + description: 'Whether to show only tickets for the current logged user team (currently user tickets)' }, { arg: 'isConfirmed', - type: 'Boolean', - description: `Order is confirmed` + type: 'boolean', + description: 'Order is confirmed' }, { arg: 'showEmpty', type: 'boolean', - description: `Show empty orders` + description: 'Show empty orders' } ], returns: { - type: ['Object'], + type: ['object'], root: true }, http: { @@ -71,34 +71,35 @@ module.exports = Self => { } }); - Self.filter = async(ctx, filter) => { - let conn = Self.dataSource.connector; - let worker = await Self.app.models.Worker.findOne({ - where: {userFk: ctx.req.accessToken.userId}, - include: [ - {relation: 'collegues'} - ] - }); + Self.filter = async(ctx, filter, options) => { + const conn = Self.dataSource.connector; + const myOptions = {}; + + if (typeof options == 'object') + Object.assign(myOptions, options); + const args = ctx.args; - let teamIds = []; - if (worker.collegues().length && args.myTeam) { - worker.collegues().forEach(collegue => { - teamIds.push(collegue.collegueFk); - }); - } + // Apply filter by team + const teamMembersId = []; + if (args.myTeam != null) { + const worker = await models.Worker.findById(userId, { + include: { + relation: 'collegues' + } + }, myOptions); + const collegues = worker.collegues() || []; + for (let collegue of collegues) + teamMembersId.push(collegue.collegueFk); - if (worker.collegues().length === 0 && args.myTeam) { - worker = await Self.app.models.Worker.findOne({ - fields: ['id'], - where: {userFk: ctx.req.accessToken.userId} - }); - teamIds = [worker && worker.id]; + if (teamMembersId.length == 0) + teamMembersId.push(userId); } if (args && args.myTeam) args.teamIds = teamIds; - let where = buildFilter(args, (param, value) => { + + const where = buildFilter(args, (param, value) => { switch (param) { case 'search': return /^\d+$/.test(value) @@ -123,7 +124,10 @@ module.exports = Self => { case 'isConfirmed': return {'o.confirmed': value ? 1 : 0}; case 'myTeam': - return {'c.salesPersonFk': {inq: teamIds}}; + if (value) + return {'c.salesPersonFk': {inq: teamMembersId}}; + else + return {'c.salesPersonFk': {nin: teamMembersId}}; case 'showEmpty': return {'o.total': {neq: value}}; case 'id': @@ -133,7 +137,7 @@ module.exports = Self => { }); filter = mergeFilters(filter, {where}); - let stmts = []; + const stmts = []; let stmt; stmt = new ParameterizedSQL( @@ -183,7 +187,7 @@ module.exports = Self => { stmts.push(`DROP TEMPORARY TABLE tmp.filter`); const sql = ParameterizedSQL.join(stmts, ';'); - const result = await conn.executeStmt(sql); + const result = await conn.executeStmt(sql, myOptions); return result[ordersIndex]; }; diff --git a/modules/order/back/methods/order/getItemTypeAvailable.js b/modules/order/back/methods/order/getItemTypeAvailable.js index 906095f41..b62adebb5 100644 --- a/modules/order/back/methods/order/getItemTypeAvailable.js +++ b/modules/order/back/methods/order/getItemTypeAvailable.js @@ -3,7 +3,7 @@ const ParameterizedSQL = require('loopback-connector').ParameterizedSQL; module.exports = Self => { Self.remoteMethod('getItemTypeAvailable', { - description: 'Gets the item types available for an rder and item category ', + description: 'Gets the item types available for an order and item category', accessType: 'READ', accepts: [{ arg: 'id', @@ -27,11 +27,16 @@ module.exports = Self => { } }); - Self.getItemTypeAvailable = async(orderId, itemCategoryId) => { + Self.getItemTypeAvailable = async(orderId, itemCategoryId, options) => { + const myOptions = {}; + + if (typeof options == 'object') + Object.assign(myOptions, options); + const stmts = []; let stmt; - const order = await app.models.Order.findById(orderId); + const order = await app.models.Order.findById(orderId, null, myOptions); stmt = new ParameterizedSQL('call vn.available_calc(?, ?, ?)', [ order.landed, order.addressFk, @@ -78,7 +83,7 @@ module.exports = Self => { stmts.push('DROP TEMPORARY TABLE tmp.item'); const sql = ParameterizedSQL.join(stmts, ';'); - const result = await Self.rawStmt(sql); + const result = await Self.rawStmt(sql, myOptions); return result[categoriesIndex]; }; diff --git a/modules/order/back/methods/order/getSourceValues.js b/modules/order/back/methods/order/getSourceValues.js index 5e9f0e6dc..4f1737e62 100644 --- a/modules/order/back/methods/order/getSourceValues.js +++ b/modules/order/back/methods/order/getSourceValues.js @@ -3,7 +3,7 @@ module.exports = Self => { description: 'Gets the sourceApp type set', accessType: 'READ', returns: { - type: ['String'], + type: ['string'], root: true }, http: { diff --git a/modules/order/back/methods/order/getTaxes.js b/modules/order/back/methods/order/getTaxes.js index 3003b08d8..dd06ac561 100644 --- a/modules/order/back/methods/order/getTaxes.js +++ b/modules/order/back/methods/order/getTaxes.js @@ -21,10 +21,14 @@ module.exports = Self => { } }); - Self.getTaxes = async orderFk => { - let conn = Self.dataSource.connector; - let stmts = []; + Self.getTaxes = async(orderFk, options) => { + const conn = Self.dataSource.connector; + const stmts = []; let stmt; + const myOptions = {}; + + if (typeof options == 'object') + Object.assign(myOptions, options); stmts.push('DROP TEMPORARY TABLE IF EXISTS tmp.order'); @@ -37,15 +41,15 @@ module.exports = Self => { stmts.push('CALL hedera.order_getTax()'); - let orderTaxIndex = stmts.push('SELECT * FROM tmp.orderAmount') - 1; + const orderTaxIndex = stmts.push('SELECT * FROM tmp.orderAmount') - 1; stmts.push(` DROP TEMPORARY TABLE tmp.order, tmp.orderTax`); - let sql = ParameterizedSQL.join(stmts, ';'); - let result = await conn.executeStmt(sql); + const sql = ParameterizedSQL.join(stmts, ';'); + const result = await conn.executeStmt(sql, myOptions); return result[orderTaxIndex]; }; diff --git a/modules/order/back/methods/order/getTotal.js b/modules/order/back/methods/order/getTotal.js index 32d46f605..0404a1e96 100644 --- a/modules/order/back/methods/order/getTotal.js +++ b/modules/order/back/methods/order/getTotal.js @@ -19,9 +19,14 @@ module.exports = Self => { } }); - Self.getTotal = async orderFk => { - let query = `SELECT hedera.order_getTotal(?) total;`; - let [total] = await Self.rawSql(query, [orderFk]); + Self.getTotal = async(orderFk, options) => { + const myOptions = {}; + + if (typeof options == 'object') + Object.assign(myOptions, options); + + const query = `SELECT hedera.order_getTotal(?) total;`; + const [total] = await Self.rawSql(query, [orderFk], myOptions); return total.total; }; diff --git a/modules/order/back/methods/order/getTotalVolume.js b/modules/order/back/methods/order/getTotalVolume.js index 93dbcbee8..a1b5fdb1d 100644 --- a/modules/order/back/methods/order/getTotalVolume.js +++ b/modules/order/back/methods/order/getTotalVolume.js @@ -19,9 +19,14 @@ module.exports = Self => { } }); - Self.getTotalVolume = async orderFk => { - let query = `SELECT vn.orderTotalVolume(?) totalVolume, vn.orderTotalVolumeBoxes(?) totalBoxes`; - let [res] = await Self.rawSql(query, [orderFk, orderFk]); + Self.getTotalVolume = async(orderFk, options) => { + const myOptions = {}; + + if (typeof options == 'object') + Object.assign(myOptions, options); + + const query = `SELECT vn.orderTotalVolume(?) totalVolume, vn.orderTotalVolumeBoxes(?) totalBoxes`; + const [res] = await Self.rawSql(query, [orderFk, orderFk], myOptions); return res; }; }; diff --git a/modules/order/back/methods/order/getVAT.js b/modules/order/back/methods/order/getVAT.js index 146d1254b..6bc0bd1b6 100644 --- a/modules/order/back/methods/order/getVAT.js +++ b/modules/order/back/methods/order/getVAT.js @@ -19,9 +19,14 @@ module.exports = Self => { } }); - Self.getVAT = async orderId => { + Self.getVAT = async(orderId, options) => { + const myOptions = {}; + + if (typeof options == 'object') + Object.assign(myOptions, options); + let totalTax = 0.00; - let taxes = await Self.app.models.Order.getTaxes(orderId); + const taxes = await Self.app.models.Order.getTaxes(orderId, myOptions); taxes.forEach(tax => { totalTax += tax.tax; }); diff --git a/modules/order/back/methods/order/getVolumes.js b/modules/order/back/methods/order/getVolumes.js index de3f87912..b56de6cfb 100644 --- a/modules/order/back/methods/order/getVolumes.js +++ b/modules/order/back/methods/order/getVolumes.js @@ -18,8 +18,13 @@ module.exports = Self => { } }); - Self.getVolumes = async orderFk => { - let [volume] = await Self.rawSql(`CALL vn.orderListVolume(?)`, [orderFk]); + Self.getVolumes = async(orderFk, options) => { + const myOptions = {}; + + if (typeof options == 'object') + Object.assign(myOptions, options); + + const [volume] = await Self.rawSql(`CALL vn.orderListVolume(?)`, [orderFk], myOptions); return volume; }; }; diff --git a/modules/order/back/methods/order/isEditable.js b/modules/order/back/methods/order/isEditable.js index 5f1fc7872..4ef76c11f 100644 --- a/modules/order/back/methods/order/isEditable.js +++ b/modules/order/back/methods/order/isEditable.js @@ -19,8 +19,13 @@ module.exports = Self => { } }); - Self.isEditable = async orderId => { - let exists = await Self.app.models.Order.findOne({ + Self.isEditable = async(orderId, options) => { + const myOptions = {}; + + if (typeof options == 'object') + Object.assign(myOptions, options); + + const exists = await Self.app.models.Order.findOne({ where: {id: orderId}, fields: ['isConfirmed', 'clientFk'], include: [ @@ -32,7 +37,7 @@ module.exports = Self => { } } ] - }); + }, myOptions); if (exists && exists.client().type().code !== 'normal') return true; diff --git a/modules/order/back/methods/order/new.js b/modules/order/back/methods/order/new.js index 4f1f2c3aa..147859dcc 100644 --- a/modules/order/back/methods/order/new.js +++ b/modules/order/back/methods/order/new.js @@ -32,34 +32,52 @@ module.exports = Self => { } }); - Self.new = async(landed, addressId, agencyModeId) => { - let address = await Self.app.models.Address.findOne({ - where: {id: addressId}, - fields: ['clientFk'], - include: [ - {relation: 'client', - scope: { - include: { - relation: 'type' - } - } - } - ] - }); + Self.new = async(landed, addressId, agencyModeId, options) => { + const myOptions = {}; + let tx; - if (address.client().type().code === 'normal') { - if (!address.client().isActive) - throw new UserError(`You can't create an order for a inactive client`); + if (typeof options == 'object') + Object.assign(myOptions, options); + + if (!myOptions.transaction) { + tx = await Self.beginTransaction({}); + myOptions.transaction = tx; } - query = `CALL vn.orderListCreate(?, ?, ?, ?);`; - [result] = await Self.rawSql(query, [ - landed, - agencyModeId, - addressId, - 'SALIX' - ]); + try { + const address = await Self.app.models.Address.findOne({ + where: {id: addressId}, + fields: ['clientFk'], + include: [ + {relation: 'client', + scope: { + include: { + relation: 'type' + } + } + } + ] + }, myOptions); - return result[0].vOrderId; + if (address.client().type().code === 'normal') { + if (!address.client().isActive) + throw new UserError(`You can't create an order for an inactive client`); + } + + query = `CALL vn.orderListCreate(?, ?, ?, ?);`; + [result] = await Self.rawSql(query, [ + landed, + agencyModeId, + addressId, + 'SALIX' + ], myOptions); + + if (tx) await tx.commit(); + + return result[0].vOrderId; + } catch (e) { + if (tx) await tx.rollback(); + throw e; + } }; }; diff --git a/modules/order/back/methods/order/newFromTicket.js b/modules/order/back/methods/order/newFromTicket.js index 285f60ee8..e0578ff9a 100644 --- a/modules/order/back/methods/order/newFromTicket.js +++ b/modules/order/back/methods/order/newFromTicket.js @@ -18,17 +18,35 @@ module.exports = Self => { } }); - Self.newFromTicket = async ticketFk => { - let ticket = await Self.app.models.Ticket.findOne({ - where: {id: ticketFk} - }); + Self.newFromTicket = async(ticketFk, options) => { + const myOptions = {}; + let tx; - let landed = ticket.landed; - let addressFk = ticket.addressFk; - let agencyModeFk = ticket.agencyModeFk; + if (typeof options == 'object') + Object.assign(myOptions, options); - let orderID = await Self.app.models.Order.new(landed, addressFk, agencyModeFk); + if (!myOptions.transaction) { + tx = await Self.beginTransaction({}); + myOptions.transaction = tx; + } - return orderID; + try { + const ticket = await Self.app.models.Ticket.findOne({ + where: {id: ticketFk} + }, myOptions); + + const landed = ticket.landed; + const addressFk = ticket.addressFk; + const agencyModeFk = ticket.agencyModeFk; + + const orderID = await Self.app.models.Order.new(landed, addressFk, agencyModeFk, myOptions); + + if (tx) await tx.commit(); + + return orderID; + } catch (e) { + if (tx) await tx.rollback(); + throw e; + } }; }; diff --git a/modules/order/back/methods/order/specs/catalogFilter.spec.js b/modules/order/back/methods/order/specs/catalogFilter.spec.js index 64bf4f17c..f025abb14 100644 --- a/modules/order/back/methods/order/specs/catalogFilter.spec.js +++ b/modules/order/back/methods/order/specs/catalogFilter.spec.js @@ -1,51 +1,73 @@ -const app = require('vn-loopback/server/server'); +const models = require('vn-loopback/server/server').models; describe('order catalogFilter()', () => { const colorTagId = 1; const categoryTagId = 67; it('should return an array of items', async() => { - let filter = { - where: { - categoryFk: 1, - typeFk: 2 - } - }; - let tags = []; - let orderFk = 11; - let orderBy = {field: 'relevancy DESC, name', way: 'DESC'}; - let result = await app.models.Order.catalogFilter(orderFk, orderBy, filter, tags); - let firstItemId = result[0].id; + const tx = await models.Order.beginTransaction({}); - expect(result.length).toEqual(4); - expect(firstItemId).toEqual(1); + try { + const options = {transaction: tx}; + + const filter = { + where: { + categoryFk: 1, + typeFk: 2 + } + }; + const tags = []; + const orderFk = 11; + const orderBy = {field: 'relevancy DESC, name', way: 'DESC'}; + const result = await models.Order.catalogFilter(orderFk, orderBy, filter, tags, options); + const firstItemId = result[0].id; + + expect(result.length).toEqual(4); + expect(firstItemId).toEqual(1); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } }); it('should now return an array of items based on tag filter', async() => { - const filter = { - where: { - categoryFk: 1, - typeFk: 2 - } - }; + const tx = await models.Order.beginTransaction({}); - const tagGroups = [ - {tagFk: colorTagId, values: [{value: 'Silver'}, {value: 'Brown'}]}, - {tagFk: categoryTagId, values: [{value: 'Concussion'}]} - ]; - const orderFk = 11; - const orderBy = {field: 'relevancy DESC, name', way: 'DESC'}; - const result = await app.models.Order.catalogFilter(orderFk, orderBy, filter, tagGroups); + try { + const options = {transaction: tx}; - const randomIndex = Math.round(Math.random()); - const item = result[randomIndex]; - const itemTags = item.tags; + const filter = { + where: { + categoryFk: 1, + typeFk: 2 + } + }; - const colorTag = itemTags.find(tag => tag.tagFk == colorTagId); - const categoryTag = itemTags.find(tag => tag.tagFk == categoryTagId); + const tagGroups = [ + {tagFk: colorTagId, values: [{value: 'Silver'}, {value: 'Brown'}]}, + {tagFk: categoryTagId, values: [{value: 'Concussion'}]} + ]; + const orderFk = 11; + const orderBy = {field: 'relevancy DESC, name', way: 'DESC'}; + const result = await models.Order.catalogFilter(orderFk, orderBy, filter, tagGroups, options); - expect(result.length).toEqual(2); - expect(colorTag.value).toEqual('Silver'); - expect(categoryTag.value).toEqual('Concussion'); + const randomIndex = Math.round(Math.random()); + const item = result[randomIndex]; + const itemTags = item.tags; + + const colorTag = itemTags.find(tag => tag.tagFk == colorTagId); + const categoryTag = itemTags.find(tag => tag.tagFk == categoryTagId); + + expect(result.length).toEqual(2); + expect(colorTag.value).toEqual('Silver'); + expect(categoryTag.value).toEqual('Concussion'); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } }); }); diff --git a/modules/order/back/methods/order/specs/filter.spec.js b/modules/order/back/methods/order/specs/filter.spec.js index 1cc434cf1..53b666c10 100644 --- a/modules/order/back/methods/order/specs/filter.spec.js +++ b/modules/order/back/methods/order/specs/filter.spec.js @@ -1,4 +1,4 @@ -const app = require('vn-loopback/server/server'); +const models = require('vn-loopback/server/server').models; describe('order filter()', () => { const ctx = { @@ -8,51 +8,107 @@ describe('order filter()', () => { }; it('should call the filter method with a basic search', async() => { - const filter = {where: {'o.id': 2}}; - const result = await app.models.Order.filter(ctx, filter); - const orderId = result[0].id; + const myCtx = Object.assign({}, ctx); + const tx = await models.Order.beginTransaction({}); - expect(orderId).toEqual(2); + try { + const options = {transaction: tx}; + + const filter = {where: {'o.id': 2}}; + const result = await models.Order.filter(myCtx, filter, options); + const orderId = result[0].id; + + expect(orderId).toEqual(2); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } }); it('should call the filter method with a single advanced search', async() => { - const filter = {where: {'o.confirmed': false}}; - const result = await app.models.Order.filter(ctx, filter); + const myCtx = Object.assign({}, ctx); + const tx = await models.Order.beginTransaction({}); - expect(result.length).toEqual(16); + try { + const options = {transaction: tx}; + + const filter = {where: {'o.confirmed': false}}; + const result = await models.Order.filter(myCtx, filter, options); + + expect(result.length).toEqual(16); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } }); it('should call the filter method with a complex advanced search', async() => { - const filter = {where: {'o.confirmed': false, 'c.salesPersonFk': 18}}; - const result = await app.models.Order.filter(ctx, filter); + const myCtx = Object.assign({}, ctx); + const tx = await models.Order.beginTransaction({}); - expect(result.length).toEqual(9); - expect(result[0].id).toEqual(7); + try { + const options = {transaction: tx}; + + const filter = {where: {'o.confirmed': false, 'c.salesPersonFk': 18}}; + const result = await models.Order.filter(myCtx, filter, options); + + expect(result.length).toEqual(9); + expect(result[0].id).toEqual(7); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } }); it('should return the orders matching the showEmpty on false', async() => { - const filter = {}; - ctx.args = {showEmpty: false}; - const result = await app.models.Order.filter(ctx, filter); - const hasEmptyLines = result.some(order => { - return order.total === 0; - }); + const myCtx = Object.assign({}, ctx); + const tx = await models.Order.beginTransaction({}); - expect(hasEmptyLines).toBeFalsy(); + try { + const options = {transaction: tx}; - ctx.args = {showEmpty: null}; + const filter = {}; + myCtx.args = {showEmpty: false}; + const result = await models.Order.filter(myCtx, filter, options); + const hasEmptyLines = result.some(order => { + return order.total === 0; + }); + + expect(hasEmptyLines).toBeFalsy(); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } }); it('should return the orders matching the showEmpty on true', async() => { - const filter = {}; - ctx.args = {showEmpty: true}; - const result = await app.models.Order.filter(ctx, filter); - const hasEmptyLines = result.some(order => { - return order.total === 0; - }); + const myCtx = Object.assign({}, ctx); + const tx = await models.Order.beginTransaction({}); - expect(hasEmptyLines).toBeTruthy(); + try { + const options = {transaction: tx}; - ctx.args = {showEmpty: null}; + const filter = {}; + myCtx.args = {showEmpty: true}; + const result = await models.Order.filter(myCtx, filter, options); + const hasEmptyLines = result.some(order => { + return order.total === 0; + }); + + expect(hasEmptyLines).toBeTruthy(); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } }); }); diff --git a/modules/order/back/methods/order/specs/getItemTypeAvailable.spec.js b/modules/order/back/methods/order/specs/getItemTypeAvailable.spec.js index 66be6462a..b29b01c71 100644 --- a/modules/order/back/methods/order/specs/getItemTypeAvailable.spec.js +++ b/modules/order/back/methods/order/specs/getItemTypeAvailable.spec.js @@ -1,19 +1,41 @@ -const app = require('vn-loopback/server/server'); +const models = require('vn-loopback/server/server').models; describe('order getItemTypeAvailable()', () => { it('should call the getItemTypeAvailable method with a valid order and item category', async() => { - let orderId = 11; - let itemCategoryId = 1; - let result = await app.models.Order.getItemTypeAvailable(orderId, itemCategoryId); + const tx = await models.Order.beginTransaction({}); - expect(result.length).toEqual(1); + try { + const options = {transaction: tx}; + + const orderId = 11; + const itemCategoryId = 1; + const result = await models.Order.getItemTypeAvailable(orderId, itemCategoryId, options); + + expect(result.length).toEqual(1); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } }); it('should call the getItemTypeAvailable method with the same order and different item category', async() => { - let orderId = 11; - let itemCategoryId = 4;// - let result = await app.models.Order.getItemTypeAvailable(orderId, itemCategoryId); + const tx = await models.Order.beginTransaction({}); - expect(result.length).toEqual(0); + try { + const options = {transaction: tx}; + + const orderId = 11; + const itemCategoryId = 4; + const result = await models.Order.getItemTypeAvailable(orderId, itemCategoryId, options); + + expect(result.length).toEqual(0); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } }); }); diff --git a/modules/order/back/methods/order/specs/getTaxes.spec.js b/modules/order/back/methods/order/specs/getTaxes.spec.js index 303b72050..a4ebb5222 100644 --- a/modules/order/back/methods/order/specs/getTaxes.spec.js +++ b/modules/order/back/methods/order/specs/getTaxes.spec.js @@ -1,31 +1,75 @@ -const app = require('vn-loopback/server/server'); +const models = require('vn-loopback/server/server').models; describe('order getTaxes()', () => { it('should call the getTaxes method and return undefined if its called with a string', async() => { - let result = await app.models.Order.getTaxes('string'); + const tx = await models.Order.beginTransaction({}); - expect(result.length).toEqual(0); + try { + const options = {transaction: tx}; + + const result = await models.Order.getTaxes('string', options); + + expect(result.length).toEqual(0); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } }); it('should call the getTaxes method and return undefined if its called with unknown id', async() => { - let result = await app.models.Order.getTaxes(99999999999999999999999); + const tx = await models.Order.beginTransaction({}); - expect(result.length).toEqual(0); + try { + const options = {transaction: tx}; + + const result = await models.Order.getTaxes(9999, options); + + expect(result.length).toEqual(0); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } }); it('should call the getTaxes method and return the taxes splited if different type of taxes', async() => { - let result = await app.models.Order.getTaxes(1); + const tx = await models.Order.beginTransaction({}); - const expectedResult = result[0].tax + result[1].tax; + try { + const options = {transaction: tx}; - expect(expectedResult).toEqual(20.29); - expect(result.length).toEqual(2); + const result = await models.Order.getTaxes(1, options); + + const expectedResult = result[0].tax + result[1].tax; + + expect(expectedResult).toEqual(20.29); + expect(result.length).toEqual(2); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } }); it('should call the getTaxes method and return the taxes for them same type', async() => { - let result = await app.models.Order.getTaxes(2); + const tx = await models.Order.beginTransaction({}); - expect(result[0].tax).toEqual(9.1); - expect(result.length).toEqual(1); + try { + const options = {transaction: tx}; + + const result = await models.Order.getTaxes(2, options); + + expect(result[0].tax).toEqual(9.1); + expect(result.length).toEqual(1); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } }); }); diff --git a/modules/order/back/methods/order/specs/getTotal.spec.js b/modules/order/back/methods/order/specs/getTotal.spec.js index 613f00241..a49441860 100644 --- a/modules/order/back/methods/order/specs/getTotal.spec.js +++ b/modules/order/back/methods/order/specs/getTotal.spec.js @@ -1,9 +1,19 @@ -const app = require('vn-loopback/server/server'); +const models = require('vn-loopback/server/server').models; describe('order getTotal()', () => { it('should return the order total', async() => { - let result = await app.models.Order.getTotal(1); + const tx = await models.Order.beginTransaction({}); - expect(result).toEqual(155.89); + try { + const options = {transaction: tx}; + const result = await models.Order.getTotal(1, options); + + expect(result).toEqual(155.89); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } }); }); diff --git a/modules/order/back/methods/order/specs/getTotalVolume.spec.js b/modules/order/back/methods/order/specs/getTotalVolume.spec.js index 7cd9c9e64..56cad4df0 100644 --- a/modules/order/back/methods/order/specs/getTotalVolume.spec.js +++ b/modules/order/back/methods/order/specs/getTotalVolume.spec.js @@ -1,10 +1,21 @@ -const app = require('vn-loopback/server/server'); +const models = require('vn-loopback/server/server').models; describe('order getTotalVolume()', () => { it('should return the total', async() => { - let result = await app.models.Order.getTotalVolume(1); + const tx = await models.Order.beginTransaction({}); - expect(result.totalVolume).toEqual(1.568); - expect(result.totalBoxes).toEqual(11.1); + try { + const options = {transaction: tx}; + + const result = await models.Order.getTotalVolume(1, options); + + expect(result.totalVolume).toEqual(1.568); + expect(result.totalBoxes).toEqual(11.1); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } }); }); diff --git a/modules/order/back/methods/order/specs/getVAT.spec.js b/modules/order/back/methods/order/specs/getVAT.spec.js index 5306535d2..ba0777cf8 100644 --- a/modules/order/back/methods/order/specs/getVAT.spec.js +++ b/modules/order/back/methods/order/specs/getVAT.spec.js @@ -1,9 +1,20 @@ -const app = require('vn-loopback/server/server'); +const models = require('vn-loopback/server/server').models; describe('order getVAT()', () => { it('should return the order VAT', async() => { - const result = await app.models.Order.getVAT(1); + const tx = await models.Order.beginTransaction({}); - expect(result).toEqual(20.29); + try { + const options = {transaction: tx}; + + const result = await models.Order.getVAT(1, options); + + expect(result).toEqual(20.29); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } }); }); diff --git a/modules/order/back/methods/order/specs/getVolumes.spec.js b/modules/order/back/methods/order/specs/getVolumes.spec.js index 4113a8e07..7b33ce496 100644 --- a/modules/order/back/methods/order/specs/getVolumes.spec.js +++ b/modules/order/back/methods/order/specs/getVolumes.spec.js @@ -1,9 +1,20 @@ -const app = require('vn-loopback/server/server'); +const models = require('vn-loopback/server/server').models; describe('order getVolumes()', () => { it('should return the volumes of a given order id', async() => { - let [result] = await app.models.Order.getVolumes(1); + const tx = await models.Order.beginTransaction({}); - expect(result.volume).toEqual(1.09); + try { + const options = {transaction: tx}; + + const [result] = await models.Order.getVolumes(1, options); + + expect(result.volume).toEqual(1.09); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } }); }); diff --git a/modules/order/back/methods/order/specs/isEditable.spec.js b/modules/order/back/methods/order/specs/isEditable.spec.js index 2a7b54225..05bc5477b 100644 --- a/modules/order/back/methods/order/specs/isEditable.spec.js +++ b/modules/order/back/methods/order/specs/isEditable.spec.js @@ -1,21 +1,54 @@ -const app = require('vn-loopback/server/server'); +const models = require('vn-loopback/server/server').models; describe('order isEditable()', () => { it('should return false when the given order is not editable', async() => { - let isEditable = await app.models.Order.isEditable(2); + const tx = await models.Order.beginTransaction({}); - expect(isEditable).toBeFalsy(); + try { + const options = {transaction: tx}; + + const isEditable = await models.Order.isEditable(2, options); + + expect(isEditable).toBeFalsy(); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } }); it('should return false when the given order doesnt exists', async() => { - let isEditable = await app.models.Order.isEditable(99999); + const tx = await models.Order.beginTransaction({}); - expect(isEditable).toBeFalsy(); + try { + const options = {transaction: tx}; + + const isEditable = await models.Order.isEditable(999, options); + + expect(isEditable).toBeFalsy(); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } }); it('should return true when the given order is editable', async() => { - let isEditable = await app.models.Order.isEditable(16); + const tx = await models.Order.beginTransaction({}); - expect(isEditable).toBeTruthy(); + try { + const options = {transaction: tx}; + + const isEditable = await models.Order.isEditable(16, options); + + expect(isEditable).toBeTruthy(); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } }); }); diff --git a/modules/order/back/methods/order/specs/new.spec.js b/modules/order/back/methods/order/specs/new.spec.js index 8caed2452..5873189f8 100644 --- a/modules/order/back/methods/order/specs/new.spec.js +++ b/modules/order/back/methods/order/specs/new.spec.js @@ -1,36 +1,49 @@ -const app = require('vn-loopback/server/server'); -let UserError = require('vn-loopback/util/user-error'); +const models = require('vn-loopback/server/server').models; +const UserError = require('vn-loopback/util/user-error'); describe('order new()', () => { - let orderId; - - afterAll(async() => { - await app.models.Order.destroyById(orderId); - }); - it('should throw an error if the client isnt active', async() => { + const tx = await models.Order.beginTransaction({}); + let error; - let landed = new Date(); - let addressFk = 6; - let agencyModeFk = 1; + try { + const options = {transaction: tx}; - await app.models.Order.new(landed, addressFk, agencyModeFk) - .catch(e => { - error = e; - }); + const landed = new Date(); + const addressFk = 6; + const agencyModeFk = 1; - expect(error).toEqual(new UserError(`You can't create an order for a inactive client`)); + await models.Order.new(landed, addressFk, agencyModeFk, options); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + error = e; + } + + expect(error).toEqual(new UserError(`You can't create an order for an inactive client`)); }); it('should now create a new order when all conditions are met', async() => { - let landed = new Date(); - let addressFk = 121; - let agencyModeFk = 1; + const tx = await models.Order.beginTransaction({}); - orderId = await app.models.Order.new(landed, addressFk, agencyModeFk); + try { + const options = {transaction: tx}; - let highestOrderIdInFixtures = 3; + const landed = new Date(); + const addressFk = 121; + const agencyModeFk = 1; - expect(orderId).toBeGreaterThan(highestOrderIdInFixtures); + orderId = await models.Order.new(landed, addressFk, agencyModeFk, options); + + const highestOrderIdInFixtures = 3; + + expect(orderId).toBeGreaterThan(highestOrderIdInFixtures); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } }); }); diff --git a/modules/order/back/methods/order/specs/newFromTicket.spec.js b/modules/order/back/methods/order/specs/newFromTicket.spec.js new file mode 100644 index 000000000..6f18d1751 --- /dev/null +++ b/modules/order/back/methods/order/specs/newFromTicket.spec.js @@ -0,0 +1,24 @@ +const models = require('vn-loopback/server/server').models; + +describe('order newFromTicket()', () => { + it('should create a new order from an existing ticket', async() => { + const tx = await models.Order.beginTransaction({}); + + try { + const options = {transaction: tx}; + + const ticketId = 11; + + const orderId = await models.Order.newFromTicket(ticketId, options); + + const highestOrderIdInFixtures = 3; + + expect(orderId).toBeGreaterThan(highestOrderIdInFixtures); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } + }); +}); diff --git a/modules/order/back/methods/order/specs/summary.spec.js b/modules/order/back/methods/order/specs/summary.spec.js index f23ad570e..601af9ab4 100644 --- a/modules/order/back/methods/order/specs/summary.spec.js +++ b/modules/order/back/methods/order/specs/summary.spec.js @@ -1,36 +1,91 @@ -const app = require('vn-loopback/server/server'); +const models = require('vn-loopback/server/server').models; describe('order summary()', () => { it('should return a summary object containing data from 1 order', async() => { - let result = await app.models.Order.summary(1); + const tx = await models.Order.beginTransaction({}); - expect(result.id).toEqual(1); - expect(result.clientFk).toEqual(1101); + try { + const options = {transaction: tx}; + + const result = await models.Order.summary(1, options); + + expect(result.id).toEqual(1); + expect(result.clientFk).toEqual(1101); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } }); it('should return a summary object containing sales from 1 order', async() => { - let result = await app.models.Order.summary(1); + const tx = await models.Order.beginTransaction({}); - expect(result.rows.length).toEqual(3); + try { + const options = {transaction: tx}; + + const result = await models.Order.summary(1, options); + + expect(result.rows.length).toEqual(3); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } }); it('should return a summary object containing subTotal for 1 order', async() => { - let result = await app.models.Order.summary(1); + const tx = await models.Order.beginTransaction({}); - expect(Math.round(result.subTotal * 100) / 100).toEqual(135.60); + try { + const options = {transaction: tx}; + + const result = await models.Order.summary(1, options); + + expect(Math.round(result.subTotal * 100) / 100).toEqual(135.60); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } }); it('should return a summary object containing VAT for 1 order', async() => { - let result = await app.models.Order.summary(1); + const tx = await models.Order.beginTransaction({}); - expect(Math.round(result.VAT * 100) / 100).toEqual(20.29); + try { + const options = {transaction: tx}; + + const result = await models.Order.summary(1, options); + + expect(Math.round(result.VAT * 100) / 100).toEqual(20.29); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } }); it('should return a summary object containing total for 1 order', async() => { - let result = await app.models.Order.summary(1); - let total = result.subTotal + result.VAT; - let expectedTotal = Math.round(total * 100) / 100; + const tx = await models.Order.beginTransaction({}); - expect(result.total).toEqual(expectedTotal); + try { + const options = {transaction: tx}; + + const result = await models.Order.summary(1, options); + const total = result.subTotal + result.VAT; + const expectedTotal = Math.round(total * 100) / 100; + + expect(result.total).toEqual(expectedTotal); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } }); }); diff --git a/modules/order/back/methods/order/specs/updateBasicData.spec.js b/modules/order/back/methods/order/specs/updateBasicData.spec.js index adf009bc1..ad63fa9b5 100644 --- a/modules/order/back/methods/order/specs/updateBasicData.spec.js +++ b/modules/order/back/methods/order/specs/updateBasicData.spec.js @@ -1,61 +1,93 @@ -const app = require('vn-loopback/server/server'); +const models = require('vn-loopback/server/server').models; +const UserError = require('vn-loopback/util/user-error'); describe('Order updateBasicData', () => { const orderId = 21; - afterAll(async() => { - let validparams = {note: null}; - - await app.models.Order.updateBasicData(orderId, validparams); - }); - it('should return an error if the order is confirmed', async() => { + const tx = await models.Order.beginTransaction({}); + let error; + try { + const options = {transaction: tx}; + const params = []; + const orderConfirmed = 1; - let params = []; - let orderConfirmed = 1; + await models.Order.updateBasicData(orderConfirmed, params, options); - await app.models.Order.updateBasicData(orderConfirmed, params) - .catch(e => { - error = e; - }); + await tx.rollback(); + } catch (e) { + await tx.rollback(); + error = e; + } + const expectedError = `You can't make changes on the basic data of an confirmed order or with rows`; - expect(error.toString()).toContain(`You can't make changes on the basic data of an confirmed order or with rows`); + expect(error).toEqual(new UserError(expectedError)); }); it('should return an error if the order has rows', async() => { + const tx = await models.Order.beginTransaction({}); + let error; + try { + const options = {transaction: tx}; - let params = []; - let orderWithRows = 16; + const params = []; + const orderWithRows = 16; - await app.models.Order.updateBasicData(orderWithRows, params) - .catch(e => { - error = e; - }); + await models.Order.updateBasicData(orderWithRows, params, options); - expect(error.toString()).toContain(`You can't make changes on the basic data of an confirmed order or with rows`); + await tx.rollback(); + } catch (e) { + await tx.rollback(); + error = e; + } + + const expectedError = `You can't make changes on the basic data of an confirmed order or with rows`; + + expect(error).toEqual(new UserError(expectedError)); }); it('should skip invalid params', async() => { - let success; + const tx = await models.Order.beginTransaction({}); - let invalidparams = {invalid: 'param for update'}; + try { + const options = {transaction: tx}; + let success; - await app.models.Order.updateBasicData(orderId, invalidparams) - .then(() => success = true); + const invalidparams = {invalid: 'param for update'}; - expect(success).toBeTruthy(); + await models.Order.updateBasicData(orderId, invalidparams, options) + .then(() => success = true); + + expect(success).toBeTruthy(); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } }); it('should update the client fiscal data and return the count if changes made', async() => { - let validparams = {note: 'test note'}; + const tx = await models.Order.beginTransaction({}); - let order = await app.models.Order.findById(orderId); + try { + const options = {transaction: tx}; - expect(order.note).toEqual(null); + const validparams = {note: 'test note'}; - let result = await app.models.Order.updateBasicData(orderId, validparams); + const order = await models.Order.findById(orderId, null, options); - expect(result.note).toEqual('test note'); + expect(order.note).toEqual(null); + + const result = await models.Order.updateBasicData(orderId, validparams, options); + + expect(result.note).toEqual('test note'); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } }); }); diff --git a/modules/order/back/methods/order/summary.js b/modules/order/back/methods/order/summary.js index eb34141c1..c48abb78f 100644 --- a/modules/order/back/methods/order/summary.js +++ b/modules/order/back/methods/order/summary.js @@ -19,17 +19,22 @@ module.exports = Self => { } }); - Self.summary = async orderId => { - let models = Self.app.models; - let summary = await getOrderData(Self, orderId); + Self.summary = async(orderId, options) => { + const models = Self.app.models; + const myOptions = {}; + + if (typeof options == 'object') + Object.assign(myOptions, options); + + const summary = await getOrderData(Self, orderId, myOptions); summary.subTotal = getSubTotal(summary.rows); - summary.VAT = await models.Order.getVAT(orderId); - summary.total = await models.Order.getTotal(orderId); + summary.VAT = await models.Order.getVAT(orderId, myOptions); + summary.total = await models.Order.getTotal(orderId, myOptions); return summary; }; - async function getOrderData(Self, orderId) { - let filter = { + async function getOrderData(Self, orderId, options) { + const filter = { include: [ { relation: 'agencyMode', scope: {fields: ['name']}}, @@ -69,7 +74,7 @@ module.exports = Self => { where: {id: orderId} }; - return await Self.findOne(filter); + return Self.findOne(filter, options); } function getSubTotal(rows) { diff --git a/modules/order/back/methods/order/updateBasicData.js b/modules/order/back/methods/order/updateBasicData.js index 8f4393c04..5104db87f 100644 --- a/modules/order/back/methods/order/updateBasicData.js +++ b/modules/order/back/methods/order/updateBasicData.js @@ -31,25 +31,42 @@ module.exports = Self => { } }); - Self.updateBasicData = async(id, params) => { - let models = Self.app.models; + Self.updateBasicData = async(id, params, options) => { + const models = Self.app.models; + const myOptions = {}; + let tx; - let order = await models.Order.findById(id); - let orderRows = await models.OrderRow.find({where: {orderFk: id}}); + if (typeof options == 'object') + Object.assign(myOptions, options); - if (order.isConfirmed || orderRows.length != 0) - throw new UserError(`You can't make changes on the basic data of an confirmed order or with rows`); + if (!myOptions.transaction) { + tx = await Self.beginTransaction({}); + myOptions.transaction = tx; + } - let updateParams = pick(params, [ - 'clientFk', - 'addressFk', - 'landed', - 'agencyModeFk', - 'note', - ]); - if (Object.keys(updateParams).length) - await order.updateAttributes(updateParams); + try { + const order = await models.Order.findById(id, null, myOptions); + const orderRows = await models.OrderRow.find({where: {orderFk: id}}, myOptions); - return await order; + if (order.isConfirmed || orderRows.length != 0) + throw new UserError(`You can't make changes on the basic data of an confirmed order or with rows`); + + const updateParams = pick(params, [ + 'clientFk', + 'addressFk', + 'landed', + 'agencyModeFk', + 'note', + ]); + if (Object.keys(updateParams).length) + await order.updateAttributes(updateParams, myOptions); + + if (tx) await tx.commit(); + + return order; + } catch (e) { + if (tx) await tx.rollback(); + throw e; + } }; }; diff --git a/modules/order/front/create/locale/es.yml b/modules/order/front/create/locale/es.yml index df21d09f4..49cd64c4a 100644 --- a/modules/order/front/create/locale/es.yml +++ b/modules/order/front/create/locale/es.yml @@ -1,5 +1,5 @@ You can't create an order for a frozen client: No puedes crear una orden a un cliente congelado -You can't create an order for a inactive client: No puedes crear una orden a un cliente inactivo +You can't create an order for an inactive client: No puedes crear una orden a un cliente inactivo You can't create an order for a client that doesn't has tax data verified: No puedes crear una orden a un cliente cuyos datos fiscales no han sido verificados You can't create an order for a client that has a debt: No puedes crear una orden a un cliente que tiene deuda diff --git a/modules/route/back/methods/route/specs/getSuggestedTickets.spec.js b/modules/route/back/methods/route/specs/getSuggestedTickets.spec.js index 3583df7cd..beb494d43 100644 --- a/modules/route/back/methods/route/specs/getSuggestedTickets.spec.js +++ b/modules/route/back/methods/route/specs/getSuggestedTickets.spec.js @@ -29,9 +29,9 @@ describe('route getSuggestedTickets()', () => { const length = result.length; const anyResult = result[Math.floor(Math.random() * Math.floor(length))]; - expect(result.length).toEqual(1); + expect(result.length).toEqual(4); expect(anyResult.zoneFk).toEqual(1); - expect(anyResult.agencyModeFk).toEqual(1); + expect(anyResult.agencyModeFk).toEqual(8); await tx.rollback(); } catch (e) { diff --git a/modules/ticket/back/methods/ticket/specs/filter.spec.js b/modules/ticket/back/methods/ticket/specs/filter.spec.js index 01a652b73..14ada5c6e 100644 --- a/modules/ticket/back/methods/ticket/specs/filter.spec.js +++ b/modules/ticket/back/methods/ticket/specs/filter.spec.js @@ -11,7 +11,7 @@ describe('ticket filter()', () => { const filter = {order: 'id DESC'}; const result = await models.Ticket.filter(ctx, filter, options); - expect(result.length).toEqual(24); + expect(result.length).toEqual(27); await tx.rollback(); } catch (e) { @@ -87,7 +87,7 @@ describe('ticket filter()', () => { const filter = {}; const result = await models.Ticket.filter(ctx, filter, options); - expect(result.length).toEqual(24); + expect(result.length).toEqual(27); await tx.rollback(); } catch (e) { @@ -130,7 +130,7 @@ describe('ticket filter()', () => { const length = result.length; const anyResult = result[Math.floor(Math.random() * Math.floor(length))]; - expect(length).toEqual(7); + expect(length).toEqual(10); expect(anyResult.state).toMatch(/(Libre|Arreglar)/); await tx.rollback(); @@ -175,7 +175,7 @@ describe('ticket filter()', () => { const filter = {}; const result = await models.Ticket.filter(ctx, filter, options); - expect(result.length).toEqual(20); + expect(result.length).toEqual(23); await tx.rollback(); } catch (e) { diff --git a/modules/ticket/front/descriptor/index.html b/modules/ticket/front/descriptor/index.html index 85cca1c4f..8d7688826 100644 --- a/modules/ticket/front/descriptor/index.html +++ b/modules/ticket/front/descriptor/index.html @@ -10,6 +10,10 @@
+ + diff --git a/print/templates/reports/cmr-authorization/assets/css/import.js b/print/templates/reports/cmr-authorization/assets/css/import.js new file mode 100644 index 000000000..a2a9334cb --- /dev/null +++ b/print/templates/reports/cmr-authorization/assets/css/import.js @@ -0,0 +1,8 @@ +const Stylesheet = require(`${appPath}/core/stylesheet`); + +module.exports = new Stylesheet([ + `${appPath}/common/css/layout.css`, + `${appPath}/common/css/report.css`, + `${appPath}/common/css/misc.css`, + `${__dirname}/style.css`]) + .mergeStyles(); diff --git a/print/templates/reports/cmr-authorization/assets/css/style.css b/print/templates/reports/cmr-authorization/assets/css/style.css new file mode 100644 index 000000000..adfe4b4c9 --- /dev/null +++ b/print/templates/reports/cmr-authorization/assets/css/style.css @@ -0,0 +1,31 @@ +.grid-block { + font-size: 1.2em +} + +.signature .dummy-signature { + width: 400px; + height: 190px; + display: block; + content: ''; + overflow: hidden; + clear:both +} + +.signature img { + width: 400px +} + +.signature table { + width: 100%; + font-size: inherit; + border-collapse: separate; + border-spacing: 0 10px; +} + +.signature table tr > td:first-child { + width: 50% +} + +.signature table tr > td:last-child { + border-bottom: 1px dashed #CCC +} \ No newline at end of file diff --git a/print/templates/reports/cmr-authorization/assets/images/signature.png b/print/templates/reports/cmr-authorization/assets/images/signature.png new file mode 100644 index 000000000..c69cc4798 Binary files /dev/null and b/print/templates/reports/cmr-authorization/assets/images/signature.png differ diff --git a/print/templates/reports/cmr-authorization/cmr-authorization.html b/print/templates/reports/cmr-authorization/cmr-authorization.html new file mode 100644 index 000000000..2d8342a47 --- /dev/null +++ b/print/templates/reports/cmr-authorization/cmr-authorization.html @@ -0,0 +1,99 @@ + + + + + + + + + +
+ + + +
+
+

+

+

+

+ +
+
+

{{client.name}}

+
+

+ + + + + + + + + + + + + + + +
{{$t('signer.representative')}}:
{{$t('signer.representativeRole')}}:
{{$t('signer.signed')}}:
+

+
+
+

{{$t('signature')}}

+ +

+

Juan Vicente Ferrer Roig
+
Director
+

{{$t('issued', [ + 'Algemesí', + issued.getDate(), + $t('months')[issued.getMonth()], + issued.getFullYear()]) + }} +

+

+
+
+ +
+
+ + + +
+ + \ No newline at end of file diff --git a/print/templates/reports/cmr-authorization/cmr-authorization.js b/print/templates/reports/cmr-authorization/cmr-authorization.js new file mode 100755 index 000000000..da08b6ec8 --- /dev/null +++ b/print/templates/reports/cmr-authorization/cmr-authorization.js @@ -0,0 +1,29 @@ +const Component = require(`${appPath}/core/component`); +const reportHeader = new Component('report-header'); +const reportFooter = new Component('report-footer'); + +module.exports = { + name: 'cmr-authorization', + async serverPrefetch() { + this.ticket = await this.findOneFromDef('ticket', [this.ticketId]); + if (!this.ticket) + throw new Error('Something went wrong'); + + this.client = await this.findOneFromDef('client', [this.ticket.clientFk]); + + }, + computed: { + issued: function() { + return new Date(); + } + }, + components: { + 'report-header': reportHeader.build(), + 'report-footer': reportFooter.build() + }, + props: { + ticketId: { + required: true + } + } +}; diff --git a/print/templates/reports/cmr-authorization/locale/es.yml b/print/templates/reports/cmr-authorization/locale/es.yml new file mode 100644 index 000000000..779dc0c8f --- /dev/null +++ b/print/templates/reports/cmr-authorization/locale/es.yml @@ -0,0 +1,41 @@ +description: '{socialName} una sociedad debidamente constituida con responsabilidad limitada +y registrada conforme al derecho de sociedades de {country} y aquí representada por +___________________. {socialName}, con domicilio en {address}, +CIF {fiscalID}. En adelante denominada {name}.' +issued: 'En {0}, a {1} de {2} de {3}' +client: 'Client {0}' +declaration: '{socialName} declara por la presente que:' +declarations: + - 'Todas las compras realizadas por {socialName} con Verdnatura Levante, S.L. se +entregan, Ex Works (Incoterms), en el almacén de Verdnatura Levante, S.L. situado en +{destinationWarehouse}.' + - '{socialName} reconoce que es importante para Verdnatura Levante, S.L. tener +comprobante de la entrega intracomunitaria de la mercancía a {destinationCountry} para +poder facturar con 0% de IVA.' + - 'Por tanto, al firmar este acuerdo, {socialName} declara que todos los bienes que +se compren a Verdnatura Levante, S.L. serán entregados a {destinationCountry}.' + - 'Además, {socialName} deberá, a primera solicitud de Verdnatura Levante, S.L., +proporcionar una prueba de que todos los productos comprados a Verdnatura Levante, S.L. han +sido entregados en {destinationCountry}.' + - 'Además de lo anterior, Verdnatura Levante, S.L. proporcionará a {socialName} +un resumen mensual en el que se incluyen todas las facturas (y las entregas correspondientes). +{socialName} firmará y devolverá el resumen mensual a Verdnatura Levante, +S.L. dentro de los 5 días posteriores a la recepción del resumen.' +signature: Verdnatura Levante, S.L. +signer: + representative: Representante + representativeRole: Cargo del representante + signed: Fecha de firma +months: + - 'Enero' + - 'Febrero' + - 'Marzo' + - 'Abril' + - 'Mayo' + - 'Junio' + - 'Julio' + - 'Agosto' + - 'Septiembre' + - 'Octubre' + - 'Noviembre' + - 'Diciembre' \ No newline at end of file diff --git a/print/templates/reports/cmr-authorization/sql/client.sql b/print/templates/reports/cmr-authorization/sql/client.sql new file mode 100644 index 000000000..bb17afd1d --- /dev/null +++ b/print/templates/reports/cmr-authorization/sql/client.sql @@ -0,0 +1,10 @@ +SELECT + c.id, + c.socialName, + c.name, + c.fi, + c.street, + cty.country +FROM client c + JOIN country cty ON cty.id = c.countryFk +WHERE c.id = ? \ No newline at end of file diff --git a/print/templates/reports/cmr-authorization/sql/ticket.sql b/print/templates/reports/cmr-authorization/sql/ticket.sql new file mode 100644 index 000000000..c6c994f7d --- /dev/null +++ b/print/templates/reports/cmr-authorization/sql/ticket.sql @@ -0,0 +1,12 @@ +SELECT + t.id, + t.clientFk, + cty.country, + w.name AS warehouse +FROM ticket t + JOIN warehouse w ON w.id = t.warehouseFk + JOIN address a ON a.id = t.addressFk + JOIN province p ON p.id = a.provinceFk + JOIN autonomy au ON au.id = p.autonomyFk + JOIN country cty ON cty.id = au.countryFk +WHERE t.id = ? \ No newline at end of file