From f62814e81e061d17e5f846d719a783aada51e754 Mon Sep 17 00:00:00 2001 From: carlosjr Date: Mon, 25 Oct 2021 13:13:05 +0200 Subject: [PATCH 01/19] refactor(order): catalogFilter, confirm and filter transactions --- .../order/back/methods/order/catalogFilter.js | 29 +++--- modules/order/back/methods/order/confirm.js | 26 +++++- modules/order/back/methods/order/filter.js | 70 +++++++------- .../methods/order/specs/catalogFilter.spec.js | 92 ++++++++++++------- 4 files changed, 136 insertions(+), 81 deletions(-) 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..ee1613cf6 100644 --- a/modules/order/back/methods/order/confirm.js +++ b/modules/order/back/methods/order/confirm.js @@ -19,9 +19,29 @@ module.exports = Self => { } }); - Self.confirm = async(ctx, orderFk) => { + Self.confirm = async(ctx, orderFk, option) => { const userId = ctx.req.accessToken.userId; - let query = `CALL hedera.order_confirmWithUser(?, ?)`; - return await Self.rawSql(query, [orderFk, userId]); + const myOptions = {}; + let tx; + + if (typeof options == 'object') + Object.assign(myOptions, options); + + if (!myOptions.transaction) { + tx = await Self.beginTransaction({}); + myOptions.transaction = tx; + } + + try { + const query = `CALL hedera.order_confirmWithUser(?, ?)`; + const response = await Self.rawSql(query, [orderFk, userId], myOptions); + + if (tx) await tx.commit(); + + return response; + } catch (e) { + if (tx) await tx.rollback(); + throw e; + } }; }; diff --git a/modules/order/back/methods/order/filter.js b/modules/order/back/methods/order/filter.js index bd987dd5b..f91373651 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,14 +71,20 @@ module.exports = Self => { } }); - Self.filter = async(ctx, filter) => { - let conn = Self.dataSource.connector; + Self.filter = async(ctx, filter, options) => { + const conn = Self.dataSource.connector; + const myOptions = {}; + + if (typeof options == 'object') + Object.assign(myOptions, options); + let worker = await Self.app.models.Worker.findOne({ where: {userFk: ctx.req.accessToken.userId}, include: [ {relation: 'collegues'} ] - }); + }, myOptions); + const args = ctx.args; let teamIds = []; @@ -92,13 +98,15 @@ module.exports = Self => { worker = await Self.app.models.Worker.findOne({ fields: ['id'], where: {userFk: ctx.req.accessToken.userId} - }); + }, myOptions); + teamIds = [worker && worker.id]; } 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) @@ -133,7 +141,7 @@ module.exports = Self => { }); filter = mergeFilters(filter, {where}); - let stmts = []; + const stmts = []; let stmt; stmt = new ParameterizedSQL( @@ -183,7 +191,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/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; + } }); }); From c4bc89ee296142c5492e3776f76f120950033f71 Mon Sep 17 00:00:00 2001 From: carlosjr Date: Wed, 24 Nov 2021 14:29:15 +0100 Subject: [PATCH 02/19] refactor(entry): back unit tests refactor to transactions --- .../back/methods/entry/specs/addBuy.spec.js | 6 +- .../methods/entry/specs/deleteBuys.spec.js | 6 +- .../entry/specs/editLatestBuys.spec.js | 11 +- .../back/methods/entry/specs/filter.spec.js | 150 ++++--- .../back/methods/entry/specs/getBuys.spec.js | 22 +- .../back/methods/entry/specs/getEntry.spec.js | 64 ++- .../methods/entry/specs/importBuys.spec.js | 12 +- .../entry/specs/importBuysPreview.spec.js | 58 +-- .../entry/specs/latestBuysFilter.spec.js | 380 ++++++++++++------ 9 files changed, 489 insertions(+), 220 deletions(-) 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; + } }); }); From 8ea330723051865bf0150e3b2d9543580c005b41 Mon Sep 17 00:00:00 2001 From: alexm Date: Mon, 29 Nov 2021 08:30:36 +0100 Subject: [PATCH 03/19] feat(ticket_sale): allow multi-check for recalculatePrice --- e2e/helpers/selectors.js | 1 + e2e/paths/05-ticket/01-sale/02_edit_sale.spec.js | 11 +++++++++++ modules/ticket/front/sale/index.html | 2 +- modules/ticket/front/sale/index.js | 11 +++++------ 4 files changed, 18 insertions(+), 7 deletions(-) diff --git a/e2e/helpers/selectors.js b/e2e/helpers/selectors.js index d8ebaa069..84f5cdd0f 100644 --- a/e2e/helpers/selectors.js +++ b/e2e/helpers/selectors.js @@ -556,6 +556,7 @@ export default { moreMenuReserve: 'vn-item[name="reserve"]', moreMenuUnmarkReseved: 'vn-item[name="unreserve"]', moreMenuUpdateDiscount: 'vn-item[name="discount"]', + moreMenuRecalculatePrice: 'vn-item[name="calculatePrice"]', moreMenuUpdateDiscountInput: 'vn-input-number[ng-model="$ctrl.edit.discount"] input', transferQuantityInput: '.vn-popover.shown vn-table > div > vn-tbody > vn-tr > vn-td-editable > span > text', transferQuantityCell: '.vn-popover.shown vn-table > div > vn-tbody > vn-tr > vn-td-editable', diff --git a/e2e/paths/05-ticket/01-sale/02_edit_sale.spec.js b/e2e/paths/05-ticket/01-sale/02_edit_sale.spec.js index 55bbdf9ff..dfda4dcfb 100644 --- a/e2e/paths/05-ticket/01-sale/02_edit_sale.spec.js +++ b/e2e/paths/05-ticket/01-sale/02_edit_sale.spec.js @@ -195,6 +195,17 @@ describe('Ticket Edit sale path', () => { expect(result).toContain('22.50'); }); + it('should recalculate price of sales', async() => { + await page.waitToClick(selectors.ticketSales.firstSaleCheckbox); + await page.waitToClick(selectors.ticketSales.secondSaleCheckbox); + + await page.waitToClick(selectors.ticketSales.moreMenu); + await page.waitToClick(selectors.ticketSales.moreMenuRecalculatePrice); + const message = await page.waitForSnackbar(); + + expect(message.text).toContain('Data saved!'); + }); + it('should select the third sale and create a claim of it', async() => { await page.waitToClick(selectors.ticketSales.thirdSaleCheckbox); await page.waitToClick(selectors.ticketSales.moreMenu); diff --git a/modules/ticket/front/sale/index.html b/modules/ticket/front/sale/index.html index 996135c1e..f7a279d9a 100644 --- a/modules/ticket/front/sale/index.html +++ b/modules/ticket/front/sale/index.html @@ -464,7 +464,7 @@ + ng-if="$ctrl.isEditable"> Recalculate price { - this.vnApp.showSuccess(this.$t('Data saved!')); - this.$.model.refresh(); + const sales = this.selectedValidSales(); + sales.forEach(sale => { + this.$http.post(`Sales/${sale.id}/recalculatePrice`); }); + this.vnApp.showSuccess(this.$t('Data saved!')); + this.$.model.refresh(); } itemSearchFunc($search) { From d5c0be5a9d8b2a819dd0f5836138334b9e23a943 Mon Sep 17 00:00:00 2001 From: alexm Date: Tue, 30 Nov 2021 13:47:16 +0100 Subject: [PATCH 04/19] refactor(ticket_sale): logic and tests --- .../00-sale_calculateComponent2.sql | 118 ++++++++++++++++++ .../back/methods/sale/recalculatePrice.js | 39 ++++-- .../sale/specs/recalculatePrice.spec.js | 16 +-- modules/ticket/front/sale/index.js | 11 +- modules/ticket/front/sale/index.spec.js | 8 +- 5 files changed, 166 insertions(+), 26 deletions(-) create mode 100644 db/changes/10390-constitution/00-sale_calculateComponent2.sql diff --git a/db/changes/10390-constitution/00-sale_calculateComponent2.sql b/db/changes/10390-constitution/00-sale_calculateComponent2.sql new file mode 100644 index 000000000..72a6b9fc1 --- /dev/null +++ b/db/changes/10390-constitution/00-sale_calculateComponent2.sql @@ -0,0 +1,118 @@ +DROP PROCEDURE IF EXISTS `vn`.`sale_calculateComponentSalix`; + +DELIMITER $$ +$$ +CREATE DEFINER=`root`@`%` PROCEDURE `vn`.`sale_calculateComponentSalix`() +proc: BEGIN +/** + * Actualiza los componentes + * + * @table tmp.recalculateSales + */ + DECLARE vShipped DATE; + DECLARE vWarehouseFk SMALLINT; + DECLARE vAgencyModeFk INT; + DECLARE vAddressFk INT; + DECLARE vTicketFk BIGINT; + DECLARE vItemFk BIGINT; + DECLARE vLanded DATE; + DECLARE vIsEditable BOOLEAN; + DECLARE vZoneFk INTEGER; + DECLARE vOption INTEGER; + + DECLARE vSale INTEGER; + DECLARE vDone BOOL DEFAULT FALSE; + + DECLARE vCur CURSOR FOR + SELECT id from tmp.recalculateSales; + + DECLARE CONTINUE HANDLER FOR NOT FOUND SET vDone = TRUE; + + OPEN vCur; + + l: LOOP + SET vDone = FALSE; + FETCH vCur INTO vSale; + + IF vDone THEN + LEAVE l; + END IF; + + SELECT t.refFk IS NULL AND (IFNULL(ts.alertLevel, 0) = 0 OR s.price = 0), + s.ticketFk, + s.itemFk , + t.zoneFk, + t.warehouseFk, + t.shipped, + t.addressFk, + t.agencyModeFk, + t.landed + INTO vIsEditable, + vTicketFk, + vItemFk, + vZoneFk, + vWarehouseFk, + vShipped, + vAddressFk, + vAgencyModeFk, + vLanded + FROM ticket t + JOIN sale s ON s.ticketFk = t.id + LEFT JOIN ticketState ts ON ts.ticketFk = t.id + WHERE s.id = vSale; + + CALL zone_getLanded(vShipped, vAddressFk, vAgencyModeFk, vWarehouseFk, TRUE); + + IF (SELECT COUNT(*) FROM tmp.zoneGetLanded LIMIT 1) = 0 THEN + CALL util.throw('There is no zone for these parameters'); + END IF; + + IF vLanded IS NULL OR vZoneFk IS NULL THEN + + UPDATE ticket t + SET t.landed = (SELECT landed FROM tmp.zoneGetLanded LIMIT 1) + WHERE t.id = vTicketFk AND t.landed IS NULL; + + IF vZoneFk IS NULL THEN + SELECT zoneFk INTO vZoneFk FROM tmp.zoneGetLanded LIMIT 1; + UPDATE ticket t + SET t.zoneFk = vZoneFk + WHERE t.id = vTicketFk AND t.zoneFk IS NULL; + END IF; + + END IF; + + DROP TEMPORARY TABLE tmp.zoneGetLanded; + + -- rellena la tabla buyUltimate con la ultima compra + CALL buyUltimate (vWarehouseFk, vShipped); + + DELETE FROM tmp.buyUltimate WHERE itemFk != vItemFk; + + DROP TEMPORARY TABLE IF EXISTS tmp.ticketLot; + CREATE TEMPORARY TABLE tmp.ticketLot + SELECT vWarehouseFk warehouseFk, NULL available, vItemFk itemFk, buyFk, vZoneFk zoneFk + FROM tmp.buyUltimate + WHERE itemFk = vItemFk; + + CALL catalog_componentPrepare(); + CALL catalog_componentCalculate(vZoneFk, vAddressFk, vShipped, vWarehouseFk); + + DROP TEMPORARY TABLE IF EXISTS tmp.sale; + CREATE TEMPORARY TABLE tmp.sale + (PRIMARY KEY (saleFk)) ENGINE = MEMORY + SELECT vSale saleFk,vWarehouseFk warehouseFk; + + SET vOption = IF(vIsEditable, 1, 6); + + CALL ticketComponentUpdateSale(vOption); + CALL catalog_componentPurge(); + + DROP TEMPORARY TABLE tmp.buyUltimate; + DROP TEMPORARY TABLE tmp.sale; + + END LOOP; + CLOSE vCur; + +END$$ +DELIMITER ; diff --git a/modules/ticket/back/methods/sale/recalculatePrice.js b/modules/ticket/back/methods/sale/recalculatePrice.js index 3ffc23c3b..7b8a0e157 100644 --- a/modules/ticket/back/methods/sale/recalculatePrice.js +++ b/modules/ticket/back/methods/sale/recalculatePrice.js @@ -1,26 +1,26 @@ const UserError = require('vn-loopback/util/user-error'); module.exports = Self => { Self.remoteMethodCtx('recalculatePrice', { - description: 'Calculates the price of a sale and its components', + description: 'Calculates the price of sales and its components', accessType: 'WRITE', accepts: [{ - arg: 'id', - description: 'The sale id', - type: 'number', + arg: 'sales', + description: 'The sales', + type: ['object'], required: true, - http: {source: 'path'} + http: {source: 'body'} }], returns: { type: 'Number', root: true }, http: { - path: `/:id/recalculatePrice`, + path: `/recalculatePrice`, verb: 'post' } }); - Self.recalculatePrice = async(ctx, id, options) => { + Self.recalculatePrice = async(ctx, sales, options) => { const models = Self.app.models; const myOptions = {}; let tx; @@ -34,18 +34,33 @@ module.exports = Self => { } try { - const sale = await Self.findById(id, null, myOptions); - const isEditable = await models.Ticket.isEditable(ctx, sale.ticketFk, myOptions); + const salesIds = []; + const params = []; + sales.forEach(sale => { + salesIds.push(sale.id); + params.push('?'); + }); + const isEditable = await models.Ticket.isEditable(ctx, sales[0].ticketFk, myOptions); if (!isEditable) throw new UserError(`The sales of this ticket can't be modified`); - const canEditSale = await models.Sale.canEdit(ctx, [id], myOptions); - + const canEditSale = await models.Sale.canEdit(ctx, sales, myOptions); if (!canEditSale) throw new UserError(`Sale(s) blocked, please contact production`); - const recalculation = await Self.rawSql('CALL vn.sale_calculateComponent(?, null)', [id], myOptions); + const paramsString = params.join(); + + const query = ` + DROP TEMPORARY TABLE IF EXISTS tmp.recalculateSales; + CREATE TEMPORARY TABLE tmp.recalculateSales + SELECT s.id + FROM sale s + WHERE s.id IN (${paramsString}); + CALL vn.sale_calculateComponentSalix(); + DROP TEMPORARY TABLE tmp.recalculateSales;`; + + const recalculation = await Self.rawSql(query, salesIds, myOptions); if (tx) await tx.commit(); diff --git a/modules/ticket/back/methods/sale/specs/recalculatePrice.spec.js b/modules/ticket/back/methods/sale/specs/recalculatePrice.spec.js index 4f6579d32..0fc68dee7 100644 --- a/modules/ticket/back/methods/sale/specs/recalculatePrice.spec.js +++ b/modules/ticket/back/methods/sale/specs/recalculatePrice.spec.js @@ -1,18 +1,20 @@ const models = require('vn-loopback/server/server').models; describe('sale recalculatePrice()', () => { - const saleId = 7; - it('should update the sale price', async() => { const tx = await models.Sale.beginTransaction({}); - + const sales = [ + {id: 7, ticketFk: 11}, + {id: 8, ticketFk: 11} + ]; try { const options = {transaction: tx}; const ctx = {req: {accessToken: {userId: 9}}}; - const response = await models.Sale.recalculatePrice(ctx, saleId, options); + const response = await models.Sale.recalculatePrice(ctx, sales, options); - expect(response.affectedRows).toBeDefined(); + expect(response[0].affectedRows).toBeDefined(); + expect(response[1].affectedRows).toBeDefined(); await tx.rollback(); } catch (e) { @@ -29,8 +31,8 @@ describe('sale recalculatePrice()', () => { const options = {transaction: tx}; const ctx = {req: {accessToken: {userId: 9}}}; - const immutableSaleId = 1; - await models.Sale.recalculatePrice(ctx, immutableSaleId, options); + const immutableSale = [{id: 1, ticketFk: 1}]; + await models.Sale.recalculatePrice(ctx, immutableSale, options); await tx.rollback(); } catch (e) { diff --git a/modules/ticket/front/sale/index.js b/modules/ticket/front/sale/index.js index d9d7221bd..bbf33417c 100644 --- a/modules/ticket/front/sale/index.js +++ b/modules/ticket/front/sale/index.js @@ -451,11 +451,14 @@ class Controller extends Section { calculateSalePrice() { const sales = this.selectedValidSales(); - sales.forEach(sale => { - this.$http.post(`Sales/${sale.id}/recalculatePrice`); + if (!sales) return; + + const params = sales; + const query = `Sales/recalculatePrice`; + this.$http.post(query, params).then(() => { + this.vnApp.showSuccess(this.$t('Data saved!')); + this.$.model.refresh(); }); - this.vnApp.showSuccess(this.$t('Data saved!')); - this.$.model.refresh(); } itemSearchFunc($search) { diff --git a/modules/ticket/front/sale/index.spec.js b/modules/ticket/front/sale/index.spec.js index d543c1b81..f04d8ea54 100644 --- a/modules/ticket/front/sale/index.spec.js +++ b/modules/ticket/front/sale/index.spec.js @@ -688,10 +688,12 @@ describe('Ticket', () => { jest.spyOn(controller.vnApp, 'showSuccess').mockReturnThis(); jest.spyOn(controller.$.model, 'refresh').mockReturnThis(); - const selectedSale = controller.sales[0]; - selectedSale.checked = true; + const selectedSaleOne = controller.sales[0]; + const selectedSaleTwo = controller.sales[1]; + selectedSaleOne.checked = true; + selectedSaleTwo.checked = true; - $httpBackend.expect('POST', `Sales/1/recalculatePrice`).respond(200); + $httpBackend.expect('POST', `Sales/recalculatePrice`).respond(200); controller.calculateSalePrice(); $httpBackend.flush(); From decd4b5a9521390a240f8f00272a5ae75b3bd0d1 Mon Sep 17 00:00:00 2001 From: alexm Date: Tue, 30 Nov 2021 15:13:20 +0100 Subject: [PATCH 05/19] separate sql procedures --- ...onent2.sql => 00-sale_recalcComponent.sql} | 8 ++++--- .../01-sale_calculateComponent.sql | 23 +++++++++++++++++++ .../back/methods/sale/recalculatePrice.js | 2 +- 3 files changed, 29 insertions(+), 4 deletions(-) rename db/changes/10390-constitution/{00-sale_calculateComponent2.sql => 00-sale_recalcComponent.sql} (93%) create mode 100644 db/changes/10390-constitution/01-sale_calculateComponent.sql diff --git a/db/changes/10390-constitution/00-sale_calculateComponent2.sql b/db/changes/10390-constitution/00-sale_recalcComponent.sql similarity index 93% rename from db/changes/10390-constitution/00-sale_calculateComponent2.sql rename to db/changes/10390-constitution/00-sale_recalcComponent.sql index 72a6b9fc1..c28115470 100644 --- a/db/changes/10390-constitution/00-sale_calculateComponent2.sql +++ b/db/changes/10390-constitution/00-sale_recalcComponent.sql @@ -1,8 +1,8 @@ -DROP PROCEDURE IF EXISTS `vn`.`sale_calculateComponentSalix`; +DROP PROCEDURE IF EXISTS `vn`.`sale_recalcComponent`; DELIMITER $$ $$ -CREATE DEFINER=`root`@`%` PROCEDURE `vn`.`sale_calculateComponentSalix`() +CREATE DEFINER=`root`@`%` PROCEDURE `vn`.`sale_recalcComponent`(vOption INT) proc: BEGIN /** * Actualiza los componentes @@ -103,7 +103,9 @@ proc: BEGIN (PRIMARY KEY (saleFk)) ENGINE = MEMORY SELECT vSale saleFk,vWarehouseFk warehouseFk; - SET vOption = IF(vIsEditable, 1, 6); + IF vOption IS NULL THEN + SET vOption = IF(vIsEditable, 1, 6); + END IF; CALL ticketComponentUpdateSale(vOption); CALL catalog_componentPurge(); diff --git a/db/changes/10390-constitution/01-sale_calculateComponent.sql b/db/changes/10390-constitution/01-sale_calculateComponent.sql new file mode 100644 index 000000000..97a154362 --- /dev/null +++ b/db/changes/10390-constitution/01-sale_calculateComponent.sql @@ -0,0 +1,23 @@ +DROP PROCEDURE IF EXISTS `vn`.`sale_calculateComponent`; + +DELIMITER $$ +$$ +CREATE DEFINER=`root`@`%` PROCEDURE `vn`.`sale_calculateComponent`(vSale INT, vOption INT) +proc: BEGIN +/** + * Crea tabla temporal para vn.sale_recalcComponent() para recalcular los componentes + * + * @param vSale Id de la venta + * @param vOption indica en que componente pone el descuadre, NULL en casos habituales + */ + DROP TEMPORARY TABLE IF EXISTS tmp.recalculateSales; + CREATE TEMPORARY TABLE tmp.recalculateSales + SELECT s.id + FROM sale s + WHERE s.id = vSale; + + CALL vn.sale_recalcComponent(vOption); + + DROP TEMPORARY TABLE tmp.recalculateSales; +END$$ +DELIMITER ; \ No newline at end of file diff --git a/modules/ticket/back/methods/sale/recalculatePrice.js b/modules/ticket/back/methods/sale/recalculatePrice.js index 7b8a0e157..7a92ba08b 100644 --- a/modules/ticket/back/methods/sale/recalculatePrice.js +++ b/modules/ticket/back/methods/sale/recalculatePrice.js @@ -57,7 +57,7 @@ module.exports = Self => { SELECT s.id FROM sale s WHERE s.id IN (${paramsString}); - CALL vn.sale_calculateComponentSalix(); + CALL vn.sale_recalcComponent(null); DROP TEMPORARY TABLE tmp.recalculateSales;`; const recalculation = await Self.rawSql(query, salesIds, myOptions); From b9893220cd2e8ac5a58634041486ef14dfb1a370 Mon Sep 17 00:00:00 2001 From: vicent Date: Wed, 1 Dec 2021 08:19:28 +0100 Subject: [PATCH 06/19] export database --- db/dump/dumpedFixtures.sql | 32 +-- db/dump/fixtures.sql | 2 +- db/dump/structure.sql | 390 ++++++++++++++++++++++++++++++++----- 3 files changed, 360 insertions(+), 64 deletions(-) diff --git a/db/dump/dumpedFixtures.sql b/db/dump/dumpedFixtures.sql index 71a216b46..3021b6f6d 100644 --- a/db/dump/dumpedFixtures.sql +++ b/db/dump/dumpedFixtures.sql @@ -1,6 +1,6 @@ USE `util`; --- MariaDB dump 10.19 Distrib 10.6.4-MariaDB, for Linux (x86_64) +-- MariaDB dump 10.19 Distrib 10.6.5-MariaDB, for debian-linux-gnu (x86_64) -- -- Host: db.verdnatura.es Database: util -- ------------------------------------------------------ @@ -34,9 +34,9 @@ UNLOCK TABLES; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; --- Dump completed on 2021-11-24 12:27:34 +-- Dump completed on 2021-12-01 7:59:57 USE `account`; --- MariaDB dump 10.19 Distrib 10.6.4-MariaDB, for Linux (x86_64) +-- MariaDB dump 10.19 Distrib 10.6.5-MariaDB, for debian-linux-gnu (x86_64) -- -- Host: db.verdnatura.es Database: account -- ------------------------------------------------------ @@ -120,9 +120,9 @@ UNLOCK TABLES; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; --- Dump completed on 2021-11-24 12:27:35 +-- Dump completed on 2021-12-01 7:59:59 USE `salix`; --- MariaDB dump 10.19 Distrib 10.6.4-MariaDB, for Linux (x86_64) +-- MariaDB dump 10.19 Distrib 10.6.5-MariaDB, for debian-linux-gnu (x86_64) -- -- Host: db.verdnatura.es Database: salix -- ------------------------------------------------------ @@ -186,9 +186,9 @@ UNLOCK TABLES; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; --- Dump completed on 2021-11-24 12:27:36 +-- Dump completed on 2021-12-01 8:00:00 USE `vn`; --- MariaDB dump 10.19 Distrib 10.6.4-MariaDB, for Linux (x86_64) +-- MariaDB dump 10.19 Distrib 10.6.5-MariaDB, for debian-linux-gnu (x86_64) -- -- Host: db.verdnatura.es Database: vn -- ------------------------------------------------------ @@ -452,9 +452,9 @@ UNLOCK TABLES; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; --- Dump completed on 2021-11-24 12:27:41 +-- Dump completed on 2021-12-01 8:00:05 USE `cache`; --- MariaDB dump 10.19 Distrib 10.6.4-MariaDB, for Linux (x86_64) +-- MariaDB dump 10.19 Distrib 10.6.5-MariaDB, for debian-linux-gnu (x86_64) -- -- Host: db.verdnatura.es Database: cache -- ------------------------------------------------------ @@ -488,9 +488,9 @@ UNLOCK TABLES; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; --- Dump completed on 2021-11-24 12:27:42 +-- Dump completed on 2021-12-01 8:00:06 USE `hedera`; --- MariaDB dump 10.19 Distrib 10.6.4-MariaDB, for Linux (x86_64) +-- MariaDB dump 10.19 Distrib 10.6.5-MariaDB, for debian-linux-gnu (x86_64) -- -- Host: db.verdnatura.es Database: hedera -- ------------------------------------------------------ @@ -554,9 +554,9 @@ UNLOCK TABLES; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; --- Dump completed on 2021-11-24 12:27:43 +-- Dump completed on 2021-12-01 8:00:07 USE `postgresql`; --- MariaDB dump 10.19 Distrib 10.6.4-MariaDB, for Linux (x86_64) +-- MariaDB dump 10.19 Distrib 10.6.5-MariaDB, for debian-linux-gnu (x86_64) -- -- Host: db.verdnatura.es Database: postgresql -- ------------------------------------------------------ @@ -640,9 +640,9 @@ UNLOCK TABLES; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; --- Dump completed on 2021-11-24 12:27:44 +-- Dump completed on 2021-12-01 8:00:08 USE `sage`; --- MariaDB dump 10.19 Distrib 10.6.4-MariaDB, for Linux (x86_64) +-- MariaDB dump 10.19 Distrib 10.6.5-MariaDB, for debian-linux-gnu (x86_64) -- -- Host: db.verdnatura.es Database: sage -- ------------------------------------------------------ @@ -696,4 +696,4 @@ UNLOCK TABLES; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; --- Dump completed on 2021-11-24 12:27:44 +-- Dump completed on 2021-12-01 8:00:09 diff --git a/db/dump/fixtures.sql b/db/dump/fixtures.sql index 16e6ba5b2..efdd0e315 100644 --- a/db/dump/fixtures.sql +++ b/db/dump/fixtures.sql @@ -1870,7 +1870,7 @@ INSERT INTO `vn`.`workCenterHoliday` (`workCenterFk`, `days`, `year`) VALUES ('1', '27.5', YEAR(CURDATE())), ('5', '22', YEAR(CURDATE())), - ('1', '24.5', YEAR(DATE_ADD(CURDATE(), INTERVAL -1 YEAR))), + ('1', '24.5', YEAR(DATE_ADD(CURDATE(), INTERVAL -1 YEAR))), ('5', '23', YEAR(DATE_ADD(CURDATE(), INTERVAL -1 YEAR))); INSERT INTO `postgresql`.`calendar_state` (`calendar_state_id`, `type`, `rgb`, `code`, `holidayEntitlementRate`) diff --git a/db/dump/structure.sql b/db/dump/structure.sql index 24af1ca05..6eb8af6ca 100644 --- a/db/dump/structure.sql +++ b/db/dump/structure.sql @@ -1,4 +1,4 @@ --- MariaDB dump 10.19 Distrib 10.6.4-MariaDB, for Linux (x86_64) +-- MariaDB dump 10.19 Distrib 10.6.5-MariaDB, for debian-linux-gnu (x86_64) -- -- Host: db.verdnatura.es Database: account -- ------------------------------------------------------ @@ -14652,9 +14652,9 @@ DELIMITER ; /*!50003 SET @saved_cs_client = @@character_set_client */ ; /*!50003 SET @saved_cs_results = @@character_set_results */ ; /*!50003 SET @saved_col_connection = @@collation_connection */ ; -/*!50003 SET character_set_client = utf8 */ ; -/*!50003 SET character_set_results = utf8 */ ; -/*!50003 SET collation_connection = utf8_general_ci */ ; +/*!50003 SET character_set_client = utf8mb4 */ ; +/*!50003 SET character_set_results = utf8mb4 */ ; +/*!50003 SET collation_connection = utf8mb4_general_ci */ ; /*!50003 SET @saved_sql_mode = @@sql_mode */ ; /*!50003 SET sql_mode = 'NO_ENGINE_SUBSTITUTION' */ ; DELIMITER ;; @@ -14703,8 +14703,8 @@ BEGIN SELECT r.id, r.item_id, i.name, r.amount, r.price, r.rate FROM order_row r JOIN vn.item i ON i.id = r.item_id - WHERE /*r.amount != 0 JGF 2021-11-15 - AND*/ r.warehouse_id = vWarehouse + WHERE r.amount != 0 + AND r.warehouse_id = vWarehouse AND r.order_id = vOrder ORDER BY r.rate DESC; @@ -25233,11 +25233,11 @@ CREATE TABLE `buy` ( /*!50003 SET @saved_cs_client = @@character_set_client */ ; /*!50003 SET @saved_cs_results = @@character_set_results */ ; /*!50003 SET @saved_col_connection = @@collation_connection */ ; -/*!50003 SET character_set_client = utf8 */ ; -/*!50003 SET character_set_results = utf8 */ ; -/*!50003 SET collation_connection = utf8_general_ci */ ; +/*!50003 SET character_set_client = utf8mb4 */ ; +/*!50003 SET character_set_results = utf8mb4 */ ; +/*!50003 SET collation_connection = utf8mb4_general_ci */ ; /*!50003 SET @saved_sql_mode = @@sql_mode */ ; -/*!50003 SET sql_mode = 'NO_ENGINE_SUBSTITUTION' */ ; +/*!50003 SET sql_mode = 'STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION' */ ; DELIMITER ;; /*!50003 CREATE*/ /*!50017 DEFINER=`root`@`%`*/ /*!50003 TRIGGER `buy_beforeInsert` BEFORE INSERT ON `buy` @@ -25327,11 +25327,11 @@ DELIMITER ; /*!50003 SET @saved_cs_client = @@character_set_client */ ; /*!50003 SET @saved_cs_results = @@character_set_results */ ; /*!50003 SET @saved_col_connection = @@collation_connection */ ; -/*!50003 SET character_set_client = utf8 */ ; -/*!50003 SET character_set_results = utf8 */ ; -/*!50003 SET collation_connection = utf8_general_ci */ ; +/*!50003 SET character_set_client = utf8mb4 */ ; +/*!50003 SET character_set_results = utf8mb4 */ ; +/*!50003 SET collation_connection = utf8mb4_general_ci */ ; /*!50003 SET @saved_sql_mode = @@sql_mode */ ; -/*!50003 SET sql_mode = 'NO_ENGINE_SUBSTITUTION' */ ; +/*!50003 SET sql_mode = 'STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION' */ ; DELIMITER ;; /*!50003 CREATE*/ /*!50017 DEFINER=`root`@`%`*/ /*!50003 TRIGGER `buy_beforeUpdate` BEFORE UPDATE ON `buy` @@ -29855,9 +29855,17 @@ CREATE TABLE `genericAllocation` ( `color` varchar(50) COLLATE utf8_unicode_ci DEFAULT NULL, `quality` varchar(10) COLLATE utf8_unicode_ci DEFAULT NULL, `numFlores` varchar(10) COLLATE utf8_unicode_ci DEFAULT NULL, + `category` varchar(50) COLLATE utf8_unicode_ci DEFAULT NULL, + `productor` varchar(50) COLLATE utf8_unicode_ci DEFAULT NULL, PRIMARY KEY (`id`), KEY `genericAllocation_FK` (`itemFk`), KEY `genericAllocation_FK_1` (`typeFk`), + KEY `genericAllocation_origin_IDX` (`origin`) USING BTREE, + KEY `genericAllocation_color_IDX` (`color`) USING BTREE, + KEY `genericAllocation_quality_IDX` (`quality`) USING BTREE, + KEY `genericAllocation_numFlores_IDX` (`numFlores`) USING BTREE, + KEY `genericAllocation_category_IDX` (`category`) USING BTREE, + KEY `genericAllocation_productor_IDX` (`productor`) USING BTREE, CONSTRAINT `genericAllocation_FK` FOREIGN KEY (`itemFk`) REFERENCES `item` (`id`) ON DELETE CASCADE ON UPDATE CASCADE ) ENGINE=InnoDBDEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci COMMENT='Almacena los filtros para asignar códigos genéricos a los items'; /*!40101 SET character_set_client = @saved_cs_client */; @@ -35838,11 +35846,12 @@ DELIMITER ;; AFTER INSERT ON saleBuy FOR EACH ROW BEGIN - +/* Activar de nuevo cuando volvamos a vender fruta y verdura + * UPDATE vn.sale s SET s.concept = CONCAT(s.concept, ' Lote: ', NEW.buyFk) WHERE s.id = NEW.saleFk; - +*/ END */;; DELIMITER ; /*!50003 SET sql_mode = @saved_sql_mode */ ; @@ -36590,6 +36599,33 @@ DELIMITER ; /*!50003 SET character_set_results = @saved_cs_results */ ; /*!50003 SET collation_connection = @saved_col_connection */ ; +-- +-- Table structure for table `shelvingLog` +-- + +DROP TABLE IF EXISTS `shelvingLog`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `shelvingLog` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `originFk` varchar(10) CHARACTER SET utf8 NOT NULL, + `userFk` int(10) unsigned DEFAULT NULL, + `action` set('insert','update','delete') COLLATE utf8_unicode_ci NOT NULL, + `creationDate` timestamp NULL DEFAULT CURRENT_TIMESTAMP, + `description` text CHARACTER SET utf8, + `changedModel` varchar(45) COLLATE utf8_unicode_ci DEFAULT NULL, + `oldInstance` text COLLATE utf8_unicode_ci, + `newInstance` text COLLATE utf8_unicode_ci, + `changedModelId` int(11) DEFAULT NULL, + `changedModelValue` varchar(45) COLLATE utf8_unicode_ci DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `userFk` (`userFk`), + KEY `originFk` (`originFk`), + CONSTRAINT `shelvingLog_FK_ibfk_1` FOREIGN KEY (`originFk`) REFERENCES `shelving` (`code`) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT `shelvingLog_ibfk_2` FOREIGN KEY (`userFk`) REFERENCES `account`.`user` (`id`) ON DELETE CASCADE ON UPDATE CASCADE +) ENGINE=InnoDBDEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + -- -- Table structure for table `silexACL` -- @@ -48640,7 +48676,7 @@ BEGIN DELETE g FROM glsExpedition g JOIN expedition e ON e.id = g.expeditionFk WHERE e.created < v26Month; - DELETE FROM expedition WHERE created < v26Month; + DELETE IGNORE FROM expedition WHERE created < v26Month; DELETE FROM sms WHERE created < v18Month; DELETE FROM saleTracking WHERE created < vDateShort; DELETE tobs FROM ticketObservation tobs @@ -50260,6 +50296,50 @@ BEGIN AND MONTH(c.created) = MONTH(CURDATE() - INTERVAL 1 MONTH) AND YEAR(c.created) = YEAR(CURDATE() - INTERVAL 1 MONTH); -- END IF; +END ;; +DELIMITER ; +/*!50003 SET sql_mode = @saved_sql_mode */ ; +/*!50003 SET character_set_client = @saved_cs_client */ ; +/*!50003 SET character_set_results = @saved_cs_results */ ; +/*!50003 SET collation_connection = @saved_col_connection */ ; +/*!50003 DROP PROCEDURE IF EXISTS `collectionOrTicket_printSticker` */; +/*!50003 SET @saved_cs_client = @@character_set_client */ ; +/*!50003 SET @saved_cs_results = @@character_set_results */ ; +/*!50003 SET @saved_col_connection = @@collation_connection */ ; +/*!50003 SET character_set_client = utf8mb4 */ ; +/*!50003 SET character_set_results = utf8mb4 */ ; +/*!50003 SET collation_connection = utf8mb4_general_ci */ ; +/*!50003 SET @saved_sql_mode = @@sql_mode */ ; +/*!50003 SET sql_mode = 'NO_ENGINE_SUBSTITUTION' */ ; +DELIMITER ;; +CREATE DEFINER=`root`@`%` PROCEDURE `collectionOrTicket_printSticker`(vParam INT, vSectorFk INT) +BEGIN + + /*Imprime una etiqueta amarilla a partir de una colección o ticket + * + * @param vParam colección o ticket a imprimir + * @param vSectorFk id del sector + */ + + DECLARE vLabelReport INT; + + SELECT labelReportFk INTO vLabelReport + FROM sector + WHERE id = vSectorFk; + + IF vLabelReport THEN + + INSERT INTO ticketTrolley(ticket, labelCount) + SELECT ticketFk, 1 + FROM ticketCollection + WHERE collectionFk = vParam OR ticketFK = vParam + ON DUPLICATE KEY UPDATE labelCount = labelCount + 1; + + INSERT INTO printServerQueue(labelReportFk, param1, workerFk) + SELECT vLabelReport, vParam, getUser(); + + END IF; + END ;; DELIMITER ; /*!50003 SET sql_mode = @saved_sql_mode */ ; @@ -50603,6 +50683,9 @@ DELIMITER ; DELIMITER ;; CREATE DEFINER=`root`@`%` PROCEDURE `collectionSticker_print`(vCollectionFk INT, vSectorFk INT) BEGIN + + /*@deprecated :utilizar collectionOrTicket_printSticker*/ + DECLARE vLabelReport INT; SELECT labelReportFk INTO vLabelReport @@ -54382,7 +54465,7 @@ BEGIN SELECT COUNT(*) INTO vIsDepartment FROM vn.workerDepartment dp JOIN department d ON d.id = dp.departmentFk - WHERE dp.workerFk = vUserFk AND d.name = "PRODUCCION"; + WHERE dp.workerFk = vUserFk AND (d.name = "PRODUCCION" OR d.name = "CAMARA" OR d.name = "PALETIZADO" OR d.name = "ARTIFICIAL" OR d.name="NATURAL" OR d.name="TALLER ARTIFICIAL" OR d.name="TALLER NATURAL") ; IF vIsDepartment THEN SELECT COUNT(*) INTO vIsAuthorized @@ -56147,9 +56230,7 @@ BEGIN DECLARE vEntryFk INTEGER; DECLARE vCur CURSOR FOR - SELECT e.id FROM vn.entry e - JOIN vn.travel t ON t.id = e.travelFk - WHERE t.shipped >= '2021-10-08' AND t.warehouseInFk= 60; + SELECT id FROM tmp.recalcEntryCommision; DECLARE CONTINUE HANDLER FOR NOT FOUND SET v_done = TRUE; @@ -62140,6 +62221,67 @@ BEGIN DROP TEMPORARY TABLE tmp.item; +END ;; +DELIMITER ; +/*!50003 SET sql_mode = @saved_sql_mode */ ; +/*!50003 SET character_set_client = @saved_cs_client */ ; +/*!50003 SET character_set_results = @saved_cs_results */ ; +/*!50003 SET collation_connection = @saved_col_connection */ ; +/*!50003 DROP PROCEDURE IF EXISTS `itemSale_byWeek` */; +/*!50003 SET @saved_cs_client = @@character_set_client */ ; +/*!50003 SET @saved_cs_results = @@character_set_results */ ; +/*!50003 SET @saved_col_connection = @@collation_connection */ ; +/*!50003 SET character_set_client = utf8 */ ; +/*!50003 SET character_set_results = utf8 */ ; +/*!50003 SET collation_connection = utf8_general_ci */ ; +/*!50003 SET @saved_sql_mode = @@sql_mode */ ; +/*!50003 SET sql_mode = 'NO_ENGINE_SUBSTITUTION' */ ; +DELIMITER ;; +CREATE DEFINER=`root`@`%` PROCEDURE `itemSale_byWeek`(vWeek INT, IN vYear INT, vItemFk INT, vWarehouseFk INT) +BEGIN + + DECLARE datSTART DATE; + DECLARE datEND DATETIME; + + SELECT MIN(dated), TIMESTAMP(MAX(dated),'23:59:59') INTO datSTART, datEND + FROM vn.`time` t + WHERE t.`week` = vWeek + AND t.`year` = vYear; + + SELECT + t.shipped, + w.name warehouse, + s.ticketFk, + c.quality, + t.nickname AS client, + am.name AS agencyName, + wk.code AS salesPerson, + s.itemFk, + IFNULL(CONCAT(ig.longName,' ',ig.`size`,' ',ig.subName), s.concept) AS concept, + s.quantity, + s.price, + s.priceFixed, + s.discount, + tls.name stateName, + sb.buyFk, + s.id saleFk, + wk.id salesPersonFk + FROM vn.sale s + JOIN vn.ticket t ON t.id = s.ticketFk + JOIN vn.warehouse w ON w.id = t.warehouseFk + JOIN vn.address a ON a.id = t.addressFk + JOIN vn.agencyMode am ON am.id = t.agencyModeFk + JOIN vn.client c ON c.id = a.clientFk + JOIN vn.worker wk ON wk.id = c.salesPersonFk + LEFT JOIN vn.ticketLastState tls ON tls.ticketFk = t.id + LEFT JOIN vn.saleBuy sb ON sb.saleFk = s.id + LEFT JOIN vn.buy b ON b.id = sb.buyFk + LEFT JOIN vn.item ig ON ig.id = b.itemOriginalFk + WHERE s.itemFk = vItemFk + AND t.shipped BETWEEN datSTART and datEND + AND IF(vWarehouseFk = 0, w.hasComission , t.warehouseFk= vWarehouseFk) + ORDER BY t.shipped, t.id; + END ;; DELIMITER ; /*!50003 SET sql_mode = @saved_sql_mode */ ; @@ -64353,7 +64495,7 @@ DELIMITER ; /*!50003 SET character_set_client = @saved_cs_client */ ; /*!50003 SET character_set_results = @saved_cs_results */ ; /*!50003 SET collation_connection = @saved_col_connection */ ; -/*!50003 DROP PROCEDURE IF EXISTS `itemTagReplace` */; +/*!50003 DROP PROCEDURE IF EXISTS `itemTagReplace__` */; /*!50003 SET @saved_cs_client = @@character_set_client */ ; /*!50003 SET @saved_cs_results = @@character_set_results */ ; /*!50003 SET @saved_col_connection = @@collation_connection */ ; @@ -64363,10 +64505,12 @@ DELIMITER ; /*!50003 SET @saved_sql_mode = @@sql_mode */ ; /*!50003 SET sql_mode = 'NO_ENGINE_SUBSTITUTION' */ ; DELIMITER ;; -CREATE DEFINER=`root`@`%` PROCEDURE `itemTagReplace`(fromItemFk INT, toItemFk INT) +CREATE DEFINER=`root`@`%` PROCEDURE `itemTagReplace__`(fromItemFk INT, toItemFk INT) BEGIN - +/* + * deprecated use itemTag_replace + */ DELETE FROM itemTag WHERE itemFk = toItemFk; @@ -64375,6 +64519,54 @@ BEGIN FROM itemTag WHERE itemFk = fromItemFk; +END ;; +DELIMITER ; +/*!50003 SET sql_mode = @saved_sql_mode */ ; +/*!50003 SET character_set_client = @saved_cs_client */ ; +/*!50003 SET character_set_results = @saved_cs_results */ ; +/*!50003 SET collation_connection = @saved_col_connection */ ; +/*!50003 DROP PROCEDURE IF EXISTS `itemTag_replace` */; +/*!50003 SET @saved_cs_client = @@character_set_client */ ; +/*!50003 SET @saved_cs_results = @@character_set_results */ ; +/*!50003 SET @saved_col_connection = @@collation_connection */ ; +/*!50003 SET character_set_client = utf8 */ ; +/*!50003 SET character_set_results = utf8 */ ; +/*!50003 SET collation_connection = utf8_general_ci */ ; +/*!50003 SET @saved_sql_mode = @@sql_mode */ ; +/*!50003 SET sql_mode = 'NO_ENGINE_SUBSTITUTION' */ ; +DELIMITER ;; +CREATE DEFINER=`root`@`%` PROCEDURE `itemTag_replace`(vItemFromFk INT, vItemToFk INT, vPicture VARCHAR(100)) +BEGIN + + /* Reemplaza los tags de un artículo por los de otro, así como su imagen + * + * @param vItemFromFk id de vn.item con el artículo del que se toman los tags + * @param vItemToFk id de vn.item con el artículo del que se toman los tags + * @param vPicture imagen del artículo. Opcional. Si no se especifica, hereada la del vItemFromFk + */ + + DELETE FROM vn.itemTag + WHERE itemFk = vItemToFk; + + INSERT INTO vn.itemTag(itemFk, tagFk, value, priority) + SELECT vItemToFk, tagFk, value, priority + FROM vn.itemTag + WHERE itemFk = vItemFromFk; + + IF ISNULL(vPicture) THEN + + SELECT image INTO vPicture + FROM vn.item + WHERE id = vItemFromFk; + + END IF; + + UPDATE vn.item i + SET i.image = vPicture + WHERE i.id = vItemToFk; + + CALL vn.itemRefreshTags(vItemToFk); + END ;; DELIMITER ; /*!50003 SET sql_mode = @saved_sql_mode */ ; @@ -65072,7 +65264,7 @@ BEGIN LEFT JOIN itemTag it1 ON it1.priority = 1 AND it1.itemFk = i.id LEFT JOIN tagAbbreviation ta1 ON ta1.`value` = it1.`value` LEFT JOIN itemTag it2 ON it2.priority = 2 AND it2.itemFk = i.id - LEFT JOIN tagAbbreviation ta2 ON ta2.`value` = it2.`value` + LEFT JOIN tagAbbreviation ta2 ON ta2.`value` = it2.`value` AND ta2.`value` != 'Rosa' LEFT JOIN itemTag it3 ON it3.priority = 3 AND it3.itemFk = i.id LEFT JOIN tagAbbreviation ta3 ON ta3.`value` = it3.`value` SET i.`name` = CONCAT_WS(' ', @@ -65563,13 +65755,17 @@ BEGIN SELECT ga.itemFk INTO vGenericFk FROM vn.genericAllocation ga - JOIN vn.item i ON i.typeFk = ga.typeFk OR ISNULL(ga.typeFk) + JOIN vn.item i ON (i.typeFk = ga.typeFk OR ISNULL(ga.typeFk)) JOIN vn.itemTag it1 ON it1.itemFk = i.id AND (it1.value = ga.origin OR ISNULL(ga.origin)) JOIN vn.itemTag it2 ON it2.itemFk = i.id AND (it2.value = ga.color OR ISNULL(ga.color)) JOIN vn.itemTag it3 ON it3.itemFk = i.id AND (it3.value = ga.quality OR ISNULL(ga.quality)) JOIN vn.itemTag it4 ON it4.itemFk = i.id AND (it4.value = ga.numFlores OR ISNULL(ga.numFlores)) + JOIN vn.itemTag it5 ON it5.itemFk = i.id AND (it5.value = ga.category OR ISNULL(ga.category)) + JOIN vn.itemTag it6 ON it6.itemFk = i.id AND (it6.value = ga.productor OR ISNULL(ga.productor)) WHERE i.id = vSelf - AND NOT i.isFloramondo; + AND ga.itemFk != vSelf + AND NOT i.isFloramondo + LIMIT 1; UPDATE vn.item SET genericFk = vGenericFk @@ -70469,16 +70665,21 @@ DELIMITER ;; CREATE DEFINER=`root`@`%` PROCEDURE `saleBuy_Add`(vSaleFk INT, vBuyFk INT) BEGIN - DECLARE isFood BOOLEAN; - - IF (SELECT COUNT(*) + /* Añade un registro a la tabla saleBuy en el caso de que sea posible mantener la trazabilidad + * + * @param vSaleFk clave primaria de vn.sale + * @param vBuyFk clave primaria de vn.buy + */ + /*IF (SELECT COUNT(*) FROM vn.sale s JOIN vn.item i ON i.id = s.itemFk JOIN vn.itemType it ON it.id = i.typeFk JOIN vn.itemCategory ic ON ic.id = it.categoryFk WHERE s.id = vSaleFk - AND ic.code = 'fruit') THEN - + AND ic.code = 'fruit') THEN */ + + IF (SELECT COUNT(*) FROM vn.buy WHERE id = vBuyFk AND itemOriginalFk) THEN + INSERT INTO vn.saleBuy (saleFk, buyFk) VALUES(vSaleFk, vBuyFk); @@ -72322,6 +72523,36 @@ BEGIN SELECT * FROM tmp.result ORDER BY created, visible; +END ;; +DELIMITER ; +/*!50003 SET sql_mode = @saved_sql_mode */ ; +/*!50003 SET character_set_client = @saved_cs_client */ ; +/*!50003 SET character_set_results = @saved_cs_results */ ; +/*!50003 SET collation_connection = @saved_col_connection */ ; +/*!50003 DROP PROCEDURE IF EXISTS `shelvingLog_get` */; +/*!50003 SET @saved_cs_client = @@character_set_client */ ; +/*!50003 SET @saved_cs_results = @@character_set_results */ ; +/*!50003 SET @saved_col_connection = @@collation_connection */ ; +/*!50003 SET character_set_client = utf8mb4 */ ; +/*!50003 SET character_set_results = utf8mb4 */ ; +/*!50003 SET collation_connection = utf8mb4_general_ci */ ; +/*!50003 SET @saved_sql_mode = @@sql_mode */ ; +/*!50003 SET sql_mode = 'NO_ENGINE_SUBSTITUTION' */ ; +DELIMITER ;; +CREATE DEFINER=`root`@`%` PROCEDURE `shelvingLog_get`(shelvingFk VARCHAR(10)) +BEGIN + + /* Lista el log de un carro + * + * @param shelvingFk matrícula del carro + * + */ + + SELECT originFk, name, creationDate, description + FROM shelvingLog sl + JOIN user u ON u.id = sl.userFk + WHERE sl.originFk = shelvingFk COLLATE utf8_general_ci; + END ;; DELIMITER ; /*!50003 SET sql_mode = @saved_sql_mode */ ; @@ -72382,6 +72613,12 @@ proc: BEGIN ELSE + INSERT INTO vn.shelvingLog (originFk, userFk, action , description) + SELECT vShelvingFk, getUser(), 'update', CONCAT("Cambio parking ",vShelvingFk," de ", p.code," a ", vParkingCode) + FROM parking p + JOIN shelving s ON s.parkingFk = p.id + WHERE s.code = vShelvingFk COLLATE utf8_unicode_ci; + UPDATE vn.shelving SET parkingFk = vParkingFk, parked = NOW(), isPrinted = 1 WHERE `code` = vShelvingFk COLLATE utf8_unicode_ci; @@ -74541,7 +74778,7 @@ BEGIN AND sc.componentFk = tc.componentFk LEFT JOIN `component` c ON c.id = tc.componentFk WHERE IF(sc.componentFk IS NULL AND NOT c.isRenewable, FALSE, TRUE); - /* + -- Añadir componente venta por paquete DROP TEMPORARY TABLE IF EXISTS tmp.sale2; CREATE TEMPORARY TABLE tmp.sale2 @@ -74576,7 +74813,7 @@ BEGIN DROP TEMPORARY TABLE IF EXISTS tmp.sale2, - tmp.ticketComponent2;*/ + tmp.ticketComponent2; END IF; IF vKeepPrices THEN @@ -76133,6 +76370,45 @@ BEGIN END IF; +END ;; +DELIMITER ; +/*!50003 SET sql_mode = @saved_sql_mode */ ; +/*!50003 SET character_set_client = @saved_cs_client */ ; +/*!50003 SET character_set_results = @saved_cs_results */ ; +/*!50003 SET collation_connection = @saved_col_connection */ ; +/*!50003 DROP PROCEDURE IF EXISTS `ticketStateToday_setOnPreviousChecking` */; +/*!50003 SET @saved_cs_client = @@character_set_client */ ; +/*!50003 SET @saved_cs_results = @@character_set_results */ ; +/*!50003 SET @saved_col_connection = @@collation_connection */ ; +/*!50003 SET character_set_client = utf8mb4 */ ; +/*!50003 SET character_set_results = utf8mb4 */ ; +/*!50003 SET collation_connection = utf8mb4_general_ci */ ; +/*!50003 SET @saved_sql_mode = @@sql_mode */ ; +/*!50003 SET sql_mode = 'NO_ENGINE_SUBSTITUTION' */ ; +DELIMITER ;; +CREATE DEFINER=`root`@`%` PROCEDURE `ticketStateToday_setOnPreviousChecking`(vParamFk INT) +BEGIN + + /* + * Cambia el estado del ticket al estado de "control previa" + * + * @param vParamFk ticket a cambiar el estado + * + */ + DECLARE vAlertLevel INT; + + SELECT s.alertLevel INTO vAlertLevel + FROM state s + JOIN ticketStateToday tst ON tst.state = s.id + WHERE tst.ticket = vParamFk + LIMIT 1; + + IF vAlertLevel < 2 THEN + + CALL ticketStateUpdate(vParamFk, 'PREVIOUS_CONTROL'); + + END IF; + END ;; DELIMITER ; /*!50003 SET sql_mode = @saved_sql_mode */ ; @@ -77131,9 +77407,9 @@ DELIMITER ; /*!50003 SET @saved_cs_client = @@character_set_client */ ; /*!50003 SET @saved_cs_results = @@character_set_results */ ; /*!50003 SET @saved_col_connection = @@collation_connection */ ; -/*!50003 SET character_set_client = utf8mb4 */ ; -/*!50003 SET character_set_results = utf8mb4 */ ; -/*!50003 SET collation_connection = utf8mb4_general_ci */ ; +/*!50003 SET character_set_client = utf8 */ ; +/*!50003 SET character_set_results = utf8 */ ; +/*!50003 SET collation_connection = utf8_general_ci */ ; /*!50003 SET @saved_sql_mode = @@sql_mode */ ; /*!50003 SET sql_mode = 'NO_ENGINE_SUBSTITUTION' */ ; DELIMITER ;; @@ -82229,7 +82505,7 @@ DELIMITER ; /*!50003 SET character_set_client = @saved_cs_client */ ; /*!50003 SET character_set_results = @saved_cs_results */ ; /*!50003 SET collation_connection = @saved_col_connection */ ; -/*!50003 DROP PROCEDURE IF EXISTS `workerTimeControlNonDays` */; +/*!50003 DROP PROCEDURE IF EXISTS `workerTimeControlNonDays__` */; /*!50003 SET @saved_cs_client = @@character_set_client */ ; /*!50003 SET @saved_cs_results = @@character_set_results */ ; /*!50003 SET @saved_col_connection = @@collation_connection */ ; @@ -82239,7 +82515,7 @@ DELIMITER ; /*!50003 SET @saved_sql_mode = @@sql_mode */ ; /*!50003 SET sql_mode = 'NO_ENGINE_SUBSTITUTION' */ ; DELIMITER ;; -CREATE DEFINER=`root`@`%` PROCEDURE `workerTimeControlNonDays`() +CREATE DEFINER=`root`@`%` PROCEDURE `workerTimeControlNonDays__`() BEGIN SET @cont := 0; SELECT sub2.userFk, sub2.dated Fecha, CONCAT (w.firstName," ", w.lastName) worker, au.name Boss, d.name @@ -84080,7 +84356,7 @@ BEGIN GROUP BY tm.userFk,t.dated ORDER BY tm.userFk,t.dated; - -- INSERT INTO vn.mail (receiver, replyTo, subject, body) + INSERT INTO vn.mail (receiver, replyTo, subject, body) SELECT eu.email, 'laboral@verdnatura.es', CONCAT('Registro de horas semana ', WEEK(CURDATE())-1, ' año ', YEAR(CURDATE())) , CONCAT(' @@ -87525,9 +87801,9 @@ DELIMITER ; /*!50003 SET @saved_cs_client = @@character_set_client */ ; /*!50003 SET @saved_cs_results = @@character_set_results */ ; /*!50003 SET @saved_col_connection = @@collation_connection */ ; -/*!50003 SET character_set_client = utf8mb4 */ ; -/*!50003 SET character_set_results = utf8mb4 */ ; -/*!50003 SET collation_connection = utf8mb4_general_ci */ ; +/*!50003 SET character_set_client = utf8 */ ; +/*!50003 SET character_set_results = utf8 */ ; +/*!50003 SET collation_connection = utf8_general_ci */ ; /*!50003 SET @saved_sql_mode = @@sql_mode */ ; /*!50003 SET sql_mode = 'NO_ENGINE_SUBSTITUTION' */ ; DELIMITER ;; @@ -87536,11 +87812,31 @@ DELIMITER ;; FOR EACH ROW BEGIN + DECLARE vNumTicketsPrepared INT; + REPLACE vn.ticketLastState(ticketFk, ticketTrackingFk, name) SELECT NEW.Id_Ticket, NEW.inter_id, `name` FROM vn.state - WHERE id = NEW.state_id; - + WHERE id = NEW.state_id; +/* + SELECT count(*) INTO vNumTicketsPrepared + FROM vn.ticketCollection tc2 + JOIN vn.ticketState ts2 ON ts2.ticketFk = tc2.ticketFk + WHERE tc2.collectionFk IN + (SELECT tc.collectionFk + FROM vn.ticketCollection tc + WHERE tc.ticketFk IN + (SELECT ts.ticketFk + FROM vn.ticketState ts + WHERE code = 'ON_PREPARATION' + ) + AND tc.collectionFk IN (SELECT collectionFk FROM vn.ticketCollection WHERE ticketFk = NEW.Id_Ticket)); + + IF vNumTicketsPrepared = 0 THEN + UPDATE vn.collection SET stateFk = (SELECT id FROM vn.state WHERE code = 'ON_CHECKING') + WHERE id = (SELECT tc.collectionFk FROM vn.ticketCollection tc WHERE tc.ticketFk = NEW.Id_Ticket); + END IF; +*/ END */;; DELIMITER ; /*!50003 SET sql_mode = @saved_sql_mode */ ; @@ -91030,7 +91326,7 @@ USE `vn`; /*!50001 SET collation_connection = utf8_general_ci */; /*!50001 CREATE ALGORITHM=UNDEFINED */ /*!50013 DEFINER=`root`@`%` SQL SECURITY DEFINER */ -/*!50001 VIEW `traceabilityBuy` AS select `b`.`id` AS `buyFk`,`b`.`quantity` AS `quantity`,`tr`.`landed` AS `landed`,`w`.`name` AS `warehouseName`,`b`.`entryFk` AS `entryFk`,`s`.`name` AS `supplierName`,`b`.`itemFk` AS `itemFk` from ((((`buy` `b` join `entry` `e` on((`e`.`id` = `b`.`entryFk`))) join `travel` `tr` on((`tr`.`id` = `e`.`travelFk`))) join `supplier` `s` on((`s`.`id` = `e`.`supplierFk`))) join `warehouse` `w` on((`w`.`id` = `tr`.`warehouseInFk`))) */; +/*!50001 VIEW `traceabilityBuy` AS select `b`.`id` AS `buyFk`,`b`.`quantity` AS `quantity`,`tr`.`landed` AS `landed`,`w`.`name` AS `warehouseName`,`b`.`entryFk` AS `entryFk`,`s`.`name` AS `supplierName`,ifnull(`b`.`itemOriginalFk`,`b`.`itemFk`) AS `itemFk` from ((((`buy` `b` join `entry` `e` on((`e`.`id` = `b`.`entryFk`))) join `travel` `tr` on((`tr`.`id` = `e`.`travelFk`))) join `supplier` `s` on((`s`.`id` = `e`.`supplierFk`))) join `warehouse` `w` on((`w`.`id` = `tr`.`warehouseInFk`))) */; /*!50001 SET character_set_client = @saved_cs_client */; /*!50001 SET character_set_results = @saved_cs_results */; /*!50001 SET collation_connection = @saved_col_connection */; @@ -91430,4 +91726,4 @@ USE `vncontrol`; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; --- Dump completed on 2021-11-23 14:44:10 +-- Dump completed on 2021-12-01 7:52:52 From 75e32feb16713b68380563203ae343d8bfa32e4a Mon Sep 17 00:00:00 2001 From: alexm Date: Wed, 1 Dec 2021 11:39:48 +0100 Subject: [PATCH 07/19] refactor ticket_sale --- modules/ticket/back/methods/sale/recalculatePrice.js | 2 +- modules/ticket/front/sale/index.js | 3 +-- modules/ticket/front/sale/index.spec.js | 9 ++++----- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/modules/ticket/back/methods/sale/recalculatePrice.js b/modules/ticket/back/methods/sale/recalculatePrice.js index 7a92ba08b..8a390223d 100644 --- a/modules/ticket/back/methods/sale/recalculatePrice.js +++ b/modules/ticket/back/methods/sale/recalculatePrice.js @@ -11,7 +11,7 @@ module.exports = Self => { http: {source: 'body'} }], returns: { - type: 'Number', + type: 'number', root: true }, http: { diff --git a/modules/ticket/front/sale/index.js b/modules/ticket/front/sale/index.js index bbf33417c..752ed23ba 100644 --- a/modules/ticket/front/sale/index.js +++ b/modules/ticket/front/sale/index.js @@ -453,9 +453,8 @@ class Controller extends Section { const sales = this.selectedValidSales(); if (!sales) return; - const params = sales; const query = `Sales/recalculatePrice`; - this.$http.post(query, params).then(() => { + this.$http.post(query, sales).then(() => { this.vnApp.showSuccess(this.$t('Data saved!')); this.$.model.refresh(); }); diff --git a/modules/ticket/front/sale/index.spec.js b/modules/ticket/front/sale/index.spec.js index f04d8ea54..673e9a3f9 100644 --- a/modules/ticket/front/sale/index.spec.js +++ b/modules/ticket/front/sale/index.spec.js @@ -684,14 +684,13 @@ describe('Ticket', () => { }); describe('calculateSalePrice()', () => { - it('should make an HTTP post query ', () => { + it('should make an HTTP post query', () => { jest.spyOn(controller.vnApp, 'showSuccess').mockReturnThis(); jest.spyOn(controller.$.model, 'refresh').mockReturnThis(); - const selectedSaleOne = controller.sales[0]; - const selectedSaleTwo = controller.sales[1]; - selectedSaleOne.checked = true; - selectedSaleTwo.checked = true; + controller.sales.forEach(sale => { + sale.checked = true; + }); $httpBackend.expect('POST', `Sales/recalculatePrice`).respond(200); controller.calculateSalePrice(); From 8285a8a8e96b22d1035039200164577cd2d265af Mon Sep 17 00:00:00 2001 From: carlosjr Date: Wed, 1 Dec 2021 15:26:01 +0100 Subject: [PATCH 08/19] refactor(route.tickets): updated error description --- modules/route/front/tickets/index.js | 2 +- modules/route/front/tickets/locale/es.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/route/front/tickets/index.js b/modules/route/front/tickets/index.js index f78542395..fd763e32f 100644 --- a/modules/route/front/tickets/index.js +++ b/modules/route/front/tickets/index.js @@ -56,7 +56,7 @@ class Controller extends Section { this.$http.get(query).then(response => { if (!response.data) - throw new UserError(`The route's vehicle doesn't have a departing warehouse`); + throw new UserError(`The route's vehicle doesn't have a delivery point`); return response.data; }).then(address => { diff --git a/modules/route/front/tickets/locale/es.yml b/modules/route/front/tickets/locale/es.yml index d4ab440a7..c38d4115c 100644 --- a/modules/route/front/tickets/locale/es.yml +++ b/modules/route/front/tickets/locale/es.yml @@ -9,6 +9,6 @@ Tickets to add: Tickets a añadir Ticket not found: No se ha encontrado el ticket The selected ticket is not suitable for this route: El ticket seleccionado no es apto para esta ruta PC: CP -The route's vehicle doesn't have a departing warehouse: El vehículo de la ruta no tiene un almacén de salida +The route's vehicle doesn't have a delivery point: El vehículo de la ruta no tiene un punto de entrega The route doesn't have a vehicle: La ruta no tiene un vehículo Population: Población \ No newline at end of file From f63426304f525b49c576c3de06b7d7d186fda292 Mon Sep 17 00:00:00 2001 From: joan Date: Thu, 2 Dec 2021 09:20:45 +0100 Subject: [PATCH 09/19] Removed font color --- front/core/styles/icons/salixfont.css | 2 -- 1 file changed, 2 deletions(-) diff --git a/front/core/styles/icons/salixfont.css b/front/core/styles/icons/salixfont.css index 29f956379..6c7a90051 100644 --- a/front/core/styles/icons/salixfont.css +++ b/front/core/styles/icons/salixfont.css @@ -28,7 +28,6 @@ } .icon-account:before { content: "\e900"; - color: #000; } .icon-actions:before { content: "\e901"; @@ -71,7 +70,6 @@ } .icon-bucket:before { content: "\e90e"; - color: #000; } .icon-buscaman:before { content: "\e90f"; From f2a89924101ccfb1d6bc446220fcdbef402fb9e1 Mon Sep 17 00:00:00 2001 From: joan Date: Tue, 14 Dec 2021 09:17:00 +0100 Subject: [PATCH 10/19] fix(ticketIndex): excluded collectionFk property from date ranges Refs: 3431 --- modules/ticket/back/methods/ticket/filter.js | 7 ++++--- modules/ticket/front/main/index.js | 1 + 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/modules/ticket/back/methods/ticket/filter.js b/modules/ticket/back/methods/ticket/filter.js index a015d2165..44ef7c486 100644 --- a/modules/ticket/back/methods/ticket/filter.js +++ b/modules/ticket/back/methods/ticket/filter.js @@ -177,6 +177,8 @@ module.exports = Self => { return {'a.provinceFk': value}; case 'stateFk': return {'ts.stateFk': value}; + case 'collectionFk': + return {'cll.id': value}; case 'mine': case 'myTeam': if (value) @@ -276,9 +278,8 @@ module.exports = Self => { if (args.collectionFk) { stmt.merge({ sql: ` - JOIN collection cll ON cll.id = ? - JOIN ticketCollection tc ON tc.collectionFk = cll.id AND tc.ticketFk = t.id`, - params: [args.collectionFk] + JOIN collection cll + JOIN ticketCollection tc ON tc.collectionFk = cll.id AND tc.ticketFk = t.id` }); } diff --git a/modules/ticket/front/main/index.js b/modules/ticket/front/main/index.js index 35a955e55..1b807216b 100644 --- a/modules/ticket/front/main/index.js +++ b/modules/ticket/front/main/index.js @@ -8,6 +8,7 @@ export default class Ticket extends ModuleMain { 'to', 'search', 'clientFk', + 'collectionFk', 'orderFk', 'refFk', 'scopeDays' From 9de1d59d9815246a590d7991ed33f34ff775ce68 Mon Sep 17 00:00:00 2001 From: vicent Date: Tue, 14 Dec 2021 09:56:38 +0100 Subject: [PATCH 11/19] fix: deleted repeated tickets --- db/changes/10390-constitution/00-item_getBalance.sql | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/db/changes/10390-constitution/00-item_getBalance.sql b/db/changes/10390-constitution/00-item_getBalance.sql index 54f612eae..f0c4d1c41 100644 --- a/db/changes/10390-constitution/00-item_getBalance.sql +++ b/db/changes/10390-constitution/00-item_getBalance.sql @@ -130,8 +130,7 @@ BEGIN END LEFT JOIN state stPrep ON stPrep.`code` = 'PREPARED' LEFT JOIN saleTracking stk ON stk.saleFk = s.id AND stk.stateFk = stPrep.id - LEFT JOIN claim cl ON cl.ticketFk = t.id - LEFT JOIN claimBeginning cb ON cl.id = cb.claimFk AND s.id = cb.saleFk + LEFT JOIN claimBeginning cb ON s.id = cb.saleFk WHERE t.shipped >= vDateInventory AND s.itemFk = vItemId AND vWarehouse =t.warehouseFk From 15b78787dfbd6d81d41d34851800b6bc2436de6c Mon Sep 17 00:00:00 2001 From: joan Date: Tue, 14 Dec 2021 10:46:05 +0100 Subject: [PATCH 12/19] Added version 10400-christmas --- db/changes/10400-christmas/delete.keep | 1 + 1 file changed, 1 insertion(+) create mode 100644 db/changes/10400-christmas/delete.keep diff --git a/db/changes/10400-christmas/delete.keep b/db/changes/10400-christmas/delete.keep new file mode 100644 index 000000000..603d82d74 --- /dev/null +++ b/db/changes/10400-christmas/delete.keep @@ -0,0 +1 @@ +Delete me! \ No newline at end of file From 2fb1c728874bce9bab4435f63755a85049ffcf09 Mon Sep 17 00:00:00 2001 From: joan Date: Wed, 15 Dec 2021 09:03:44 +0100 Subject: [PATCH 13/19] fix(styles): style changes for better readability --- front/core/components/chip/style.scss | 4 ++-- front/core/components/label/style.scss | 2 +- front/core/components/smart-table/table.scss | 4 ++-- front/core/components/table/style.scss | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/front/core/components/chip/style.scss b/front/core/components/chip/style.scss index cc0554509..7651638be 100644 --- a/front/core/components/chip/style.scss +++ b/front/core/components/chip/style.scss @@ -55,8 +55,8 @@ vn-chip { &.message, &.message.clickable:hover, &.message.clickable:focus { - color: $color-font-dark; - background-color: $color-bg-dark; + background-color: $color-font-bg-dark; + color: $color-font-bg; } &.clickable { @extend %clickable; diff --git a/front/core/components/label/style.scss b/front/core/components/label/style.scss index ef9080f65..5faf1eba0 100644 --- a/front/core/components/label/style.scss +++ b/front/core/components/label/style.scss @@ -1,7 +1,7 @@ @import "variables"; vn-label { - color: $color-font-secondary; + color: $color-font-light; &::after { content: ':'; diff --git a/front/core/components/smart-table/table.scss b/front/core/components/smart-table/table.scss index b38ca7d82..c38c149ca 100644 --- a/front/core/components/smart-table/table.scss +++ b/front/core/components/smart-table/table.scss @@ -94,8 +94,8 @@ smart-table table { color: $color-font-bg; } &.message { - background-color: $color-bg-dark; - color: $color-font-dark; + background-color: $color-font-bg-dark; + color: $color-font-bg; } } } diff --git a/front/core/components/table/style.scss b/front/core/components/table/style.scss index 28d5a4f36..d0a29a3ba 100644 --- a/front/core/components/table/style.scss +++ b/front/core/components/table/style.scss @@ -150,8 +150,8 @@ vn-table { color: $color-font-bg; } &.message { - background-color: $color-bg-dark; - color: $color-font-dark; + background-color: $color-font-bg-dark; + color: $color-font-bg; } } vn-icon-menu { From b4f1e66fed22ff2b3e258e2b13aa8dfc62e5f556 Mon Sep 17 00:00:00 2001 From: carlosjr Date: Wed, 15 Dec 2021 15:29:22 +0100 Subject: [PATCH 14/19] order module transactions --- loopback/locale/es.json | 2 - .../back/methods/order-row/addToOrder.js | 25 +++- .../order/back/methods/order-row/removes.js | 19 +++- .../order-row/specs/addToOrder.spec.js | 44 +++---- .../methods/order-row/specs/removes.spec.js | 52 ++++++--- modules/order/back/methods/order/confirm.js | 25 +--- .../methods/order/getItemTypeAvailable.js | 13 ++- .../back/methods/order/getSourceValues.js | 2 +- modules/order/back/methods/order/getTaxes.js | 16 ++- modules/order/back/methods/order/getTotal.js | 11 +- .../back/methods/order/getTotalVolume.js | 11 +- modules/order/back/methods/order/getVAT.js | 9 +- .../order/back/methods/order/getVolumes.js | 9 +- .../order/back/methods/order/isEditable.js | 11 +- modules/order/back/methods/order/new.js | 21 +++- .../order/back/methods/order/newFromTicket.js | 25 ++-- .../back/methods/order/specs/filter.spec.js | 107 +++++++++++++----- .../order/specs/getItemTypeAvailable.spec.js | 40 +++++-- .../back/methods/order/specs/getTaxes.spec.js | 68 +++++++++-- .../back/methods/order/specs/getTotal.spec.js | 16 ++- .../order/specs/getTotalVolume.spec.js | 19 +++- .../back/methods/order/specs/getVAT.spec.js | 17 ++- .../methods/order/specs/getVolumes.spec.js | 17 ++- .../methods/order/specs/isEditable.spec.js | 47 ++++++-- .../back/methods/order/specs/new.spec.js | 57 ++++++---- .../methods/order/specs/newFromTicket.spec.js | 24 ++++ .../back/methods/order/specs/summary.spec.js | 83 +++++++++++--- .../order/specs/updateBasicData.spec.js | 94 ++++++++++----- modules/order/back/methods/order/summary.js | 21 ++-- .../back/methods/order/updateBasicData.js | 24 ++-- modules/order/front/create/locale/es.yml | 2 +- 31 files changed, 672 insertions(+), 259 deletions(-) create mode 100644 modules/order/back/methods/order/specs/newFromTicket.spec.js diff --git a/loopback/locale/es.json b/loopback/locale/es.json index 2611ee0dd..00c642192 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/order/back/methods/order-row/addToOrder.js b/modules/order/back/methods/order-row/addToOrder.js index 45304917c..b4866e259 100644 --- a/modules/order/back/methods/order-row/addToOrder.js +++ b/modules/order/back/methods/order-row/addToOrder.js @@ -21,22 +21,35 @@ 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 (typeof options == 'object') + Object.assign(myOptions, options); + + if (!myOptions.transaction) { + tx = await Self.beginTransaction({}); + myOptions.transaction = tx; + } + + const isEditable = await Self.app.models.Order.isEditable(params.orderFk, myOptions); if (!isEditable) throw new UserError('This order is not editable'); - let promises = []; - params.items.forEach(item => { + const promises = []; + for (const item of params.items) { promises.push( Self.rawSql( `CALL hedera.order_addItem(?, ?, ?, ?)`, - [params.orderFk, item.warehouseFk, item.itemFk, item.quantity] + [params.orderFk, item.warehouseFk, item.itemFk, item.quantity], + myOptions ) ); - }); + } await Promise.all(promises); + return true; }; }; diff --git a/modules/order/back/methods/order-row/removes.js b/modules/order/back/methods/order-row/removes.js index 86f0e70d7..7d28cba22 100644 --- a/modules/order/back/methods/order-row/removes.js +++ b/modules/order/back/methods/order-row/removes.js @@ -22,18 +22,29 @@ module.exports = Self => { }); Self.removes = async params => { + const myOptions = {}; + let tx; + + if (typeof options == 'object') + Object.assign(myOptions, options); + + if (!myOptions.transaction) { + tx = await Self.beginTransaction({}); + myOptions.transaction = tx; + } + if (!params.rows || !params.rows.length) throw new UserError('There is nothing to delete'); - let isEditable = await Self.app.models.Order.isEditable(params.actualOrderId); + const isEditable = await Self.app.models.Order.isEditable(params.actualOrderId, myOptions); if (!isEditable) throw new UserError('This order is not editable'); - let promises = []; + const promises = []; for (let i = 0; i < params.rows.length; i++) - promises.push(Self.app.models.OrderRow.destroyById(params.rows[i])); + promises.push(Self.app.models.OrderRow.destroyById(params.rows[i], myOptions)); - return await Promise.all(promises); + return Promise.all(promises); }; }; 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/confirm.js b/modules/order/back/methods/order/confirm.js index ee1613cf6..52acc8648 100644 --- a/modules/order/back/methods/order/confirm.js +++ b/modules/order/back/methods/order/confirm.js @@ -19,29 +19,12 @@ module.exports = Self => { } }); - Self.confirm = async(ctx, orderFk, option) => { + Self.confirm = async(ctx, orderFk) => { const userId = ctx.req.accessToken.userId; - const myOptions = {}; - let tx; - if (typeof options == 'object') - Object.assign(myOptions, options); + const query = `CALL hedera.order_confirmWithUser(?, ?)`; + const response = await Self.rawSql(query, [orderFk, userId]); - if (!myOptions.transaction) { - tx = await Self.beginTransaction({}); - myOptions.transaction = tx; - } - - try { - const query = `CALL hedera.order_confirmWithUser(?, ?)`; - const response = await Self.rawSql(query, [orderFk, userId], myOptions); - - if (tx) await tx.commit(); - - return response; - } catch (e) { - if (tx) await tx.rollback(); - throw e; - } + return response; }; }; 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..b05e24e47 100644 --- a/modules/order/back/methods/order/new.js +++ b/modules/order/back/methods/order/new.js @@ -32,8 +32,19 @@ module.exports = Self => { } }); - Self.new = async(landed, addressId, agencyModeId) => { - let address = await Self.app.models.Address.findOne({ + Self.new = async(landed, addressId, agencyModeId, options) => { + const myOptions = {}; + let tx; + + if (typeof options == 'object') + Object.assign(myOptions, options); + + if (!myOptions.transaction) { + tx = await Self.beginTransaction({}); + myOptions.transaction = tx; + } + + const address = await Self.app.models.Address.findOne({ where: {id: addressId}, fields: ['clientFk'], include: [ @@ -45,11 +56,11 @@ module.exports = Self => { } } ] - }); + }, myOptions); if (address.client().type().code === 'normal') { if (!address.client().isActive) - throw new UserError(`You can't create an order for a inactive client`); + throw new UserError(`You can't create an order for an inactive client`); } query = `CALL vn.orderListCreate(?, ?, ?, ?);`; @@ -58,7 +69,7 @@ module.exports = Self => { agencyModeId, addressId, 'SALIX' - ]); + ], myOptions); return result[0].vOrderId; }; diff --git a/modules/order/back/methods/order/newFromTicket.js b/modules/order/back/methods/order/newFromTicket.js index 285f60ee8..c21ae136d 100644 --- a/modules/order/back/methods/order/newFromTicket.js +++ b/modules/order/back/methods/order/newFromTicket.js @@ -18,16 +18,27 @@ module.exports = Self => { } }); - Self.newFromTicket = async ticketFk => { - let ticket = await Self.app.models.Ticket.findOne({ + Self.newFromTicket = async(ticketFk, options) => { + const myOptions = {}; + let tx; + + if (typeof options == 'object') + Object.assign(myOptions, options); + + if (!myOptions.transaction) { + tx = await Self.beginTransaction({}); + myOptions.transaction = tx; + } + + const ticket = await Self.app.models.Ticket.findOne({ where: {id: ticketFk} - }); + }, myOptions); - let landed = ticket.landed; - let addressFk = ticket.addressFk; - let agencyModeFk = ticket.agencyModeFk; + const landed = ticket.landed; + const addressFk = ticket.addressFk; + const agencyModeFk = ticket.agencyModeFk; - let orderID = await Self.app.models.Order.new(landed, addressFk, agencyModeFk); + const orderID = await Self.app.models.Order.new(landed, addressFk, agencyModeFk, myOptions); return orderID; }; diff --git a/modules/order/back/methods/order/specs/filter.spec.js b/modules/order/back/methods/order/specs/filter.spec.js index 1cc434cf1..84e293840 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,102 @@ 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 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(ctx, 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 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(ctx, 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 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(ctx, 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 tx = await models.Order.beginTransaction({}); - expect(hasEmptyLines).toBeFalsy(); + try { + const options = {transaction: tx}; - ctx.args = {showEmpty: null}; + const filter = {}; + ctx.args = {showEmpty: false}; + const result = await models.Order.filter(ctx, 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 tx = await models.Order.beginTransaction({}); - expect(hasEmptyLines).toBeTruthy(); + try { + const options = {transaction: tx}; - ctx.args = {showEmpty: null}; + const filter = {}; + ctx.args = {showEmpty: true}; + const result = await models.Order.filter(ctx, 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..25cf9daa7 100644 --- a/modules/order/back/methods/order/updateBasicData.js +++ b/modules/order/back/methods/order/updateBasicData.js @@ -31,16 +31,26 @@ 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 (!myOptions.transaction) { + tx = await Self.beginTransaction({}); + myOptions.transaction = tx; + } + + const order = await models.Order.findById(id, null, myOptions); + const orderRows = await models.OrderRow.find({where: {orderFk: id}}, myOptions); 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`); - let updateParams = pick(params, [ + const updateParams = pick(params, [ 'clientFk', 'addressFk', 'landed', @@ -48,8 +58,8 @@ module.exports = Self => { 'note', ]); if (Object.keys(updateParams).length) - await order.updateAttributes(updateParams); + await order.updateAttributes(updateParams, myOptions); - return await order; + return order; }; }; 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 From 5a448234d61ef486cb353a03ba5dc24db63b59fa Mon Sep 17 00:00:00 2001 From: carlosjr Date: Thu, 16 Dec 2021 10:56:10 +0100 Subject: [PATCH 15/19] transtaction commits on several endpoints --- .../back/methods/order-row/addToOrder.js | 37 ++++++++----- .../order/back/methods/order-row/removes.js | 27 ++++++--- modules/order/back/methods/order/new.js | 55 +++++++++++-------- .../order/back/methods/order/newFromTicket.js | 23 +++++--- .../back/methods/order/updateBasicData.js | 34 +++++++----- 5 files changed, 106 insertions(+), 70 deletions(-) diff --git a/modules/order/back/methods/order-row/addToOrder.js b/modules/order/back/methods/order-row/addToOrder.js index b4866e259..639fa8be7 100644 --- a/modules/order/back/methods/order-row/addToOrder.js +++ b/modules/order/back/methods/order-row/addToOrder.js @@ -33,23 +33,30 @@ module.exports = Self => { myOptions.transaction = tx; } - const isEditable = await Self.app.models.Order.isEditable(params.orderFk, myOptions); + try { + const isEditable = await Self.app.models.Order.isEditable(params.orderFk, myOptions); - if (!isEditable) - throw new UserError('This order is not editable'); + 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 - ) - ); + 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; } - await Promise.all(promises); - - return true; }; }; diff --git a/modules/order/back/methods/order-row/removes.js b/modules/order/back/methods/order-row/removes.js index 7d28cba22..7f35ec69d 100644 --- a/modules/order/back/methods/order-row/removes.js +++ b/modules/order/back/methods/order-row/removes.js @@ -33,18 +33,27 @@ module.exports = Self => { myOptions.transaction = tx; } - if (!params.rows || !params.rows.length) - throw new UserError('There is nothing to delete'); + try { + if (!params.rows || !params.rows.length) + throw new UserError('There is nothing to delete'); - const isEditable = await Self.app.models.Order.isEditable(params.actualOrderId, myOptions); + const isEditable = await Self.app.models.Order.isEditable(params.actualOrderId, myOptions); - if (!isEditable) - throw new UserError('This order is not editable'); + 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 promises = []; + for (let i = 0; i < params.rows.length; i++) + promises.push(Self.app.models.OrderRow.destroyById(params.rows[i], myOptions)); - return Promise.all(promises); + 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/new.js b/modules/order/back/methods/order/new.js index b05e24e47..147859dcc 100644 --- a/modules/order/back/methods/order/new.js +++ b/modules/order/back/methods/order/new.js @@ -44,33 +44,40 @@ module.exports = Self => { myOptions.transaction = tx; } - const address = await Self.app.models.Address.findOne({ - where: {id: addressId}, - fields: ['clientFk'], - include: [ - {relation: 'client', - scope: { - include: { - relation: 'type' + try { + const address = await Self.app.models.Address.findOne({ + where: {id: addressId}, + fields: ['clientFk'], + include: [ + {relation: 'client', + scope: { + include: { + relation: 'type' + } } } - } - ] - }, myOptions); + ] + }, myOptions); - if (address.client().type().code === 'normal') { - if (!address.client().isActive) - throw new UserError(`You can't create an order for an inactive client`); + 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; } - - query = `CALL vn.orderListCreate(?, ?, ?, ?);`; - [result] = await Self.rawSql(query, [ - landed, - agencyModeId, - addressId, - 'SALIX' - ], myOptions); - - return result[0].vOrderId; }; }; diff --git a/modules/order/back/methods/order/newFromTicket.js b/modules/order/back/methods/order/newFromTicket.js index c21ae136d..e0578ff9a 100644 --- a/modules/order/back/methods/order/newFromTicket.js +++ b/modules/order/back/methods/order/newFromTicket.js @@ -30,16 +30,23 @@ module.exports = Self => { myOptions.transaction = tx; } - const ticket = await Self.app.models.Ticket.findOne({ - where: {id: ticketFk} - }, myOptions); + 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 landed = ticket.landed; + const addressFk = ticket.addressFk; + const agencyModeFk = ticket.agencyModeFk; - const orderID = await Self.app.models.Order.new(landed, addressFk, agencyModeFk, myOptions); + const orderID = await Self.app.models.Order.new(landed, addressFk, agencyModeFk, myOptions); - return orderID; + if (tx) await tx.commit(); + + return orderID; + } catch (e) { + if (tx) await tx.rollback(); + throw e; + } }; }; diff --git a/modules/order/back/methods/order/updateBasicData.js b/modules/order/back/methods/order/updateBasicData.js index 25cf9daa7..ae5e5b74a 100644 --- a/modules/order/back/methods/order/updateBasicData.js +++ b/modules/order/back/methods/order/updateBasicData.js @@ -43,23 +43,29 @@ module.exports = Self => { tx = await Self.beginTransaction({}); myOptions.transaction = tx; } + try { + const order = await models.Order.findById(id, null, myOptions); + const orderRows = await models.OrderRow.find({where: {orderFk: id}}, myOptions); - const order = await models.Order.findById(id, null, myOptions); - const orderRows = await models.OrderRow.find({where: {orderFk: id}}, myOptions); + 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 (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); - 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; + return order; + } catch (e) { + if (tx) await tx.rollback(); + throw e; + } }; }; From d83995e64e94cac3e561ddacde8dc09a71e7d624 Mon Sep 17 00:00:00 2001 From: carlosjr Date: Fri, 17 Dec 2021 10:41:59 +0100 Subject: [PATCH 16/19] filter worker id refactor --- .../order/back/methods/order-row/removes.js | 2 +- modules/order/back/methods/order/filter.js | 36 +++++++++---------- .../back/methods/order/updateBasicData.js | 1 + 3 files changed, 18 insertions(+), 21 deletions(-) diff --git a/modules/order/back/methods/order-row/removes.js b/modules/order/back/methods/order-row/removes.js index 7f35ec69d..614761aed 100644 --- a/modules/order/back/methods/order-row/removes.js +++ b/modules/order/back/methods/order-row/removes.js @@ -21,7 +21,7 @@ module.exports = Self => { } }); - Self.removes = async params => { + Self.removes = async(params, options) => { const myOptions = {}; let tx; diff --git a/modules/order/back/methods/order/filter.js b/modules/order/back/methods/order/filter.js index 8481ce3ba..27cacdd62 100644 --- a/modules/order/back/methods/order/filter.js +++ b/modules/order/back/methods/order/filter.js @@ -78,29 +78,22 @@ module.exports = Self => { if (typeof options == 'object') Object.assign(myOptions, options); - let worker = await Self.app.models.Worker.findOne({ - where: {userFk: ctx.req.accessToken.userId}, - include: [ - {relation: 'collegues'} - ] - }, myOptions); - const args = ctx.args; - let teamIds = []; - if (worker.collegues().length && args.myTeam) { - worker.collegues().forEach(collegue => { - teamIds.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} + // 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); - teamIds = [worker && worker.id]; + if (teamMembersId.length == 0) + teamMembersId.push(userId); } if (args && args.myTeam) @@ -131,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': diff --git a/modules/order/back/methods/order/updateBasicData.js b/modules/order/back/methods/order/updateBasicData.js index ae5e5b74a..5104db87f 100644 --- a/modules/order/back/methods/order/updateBasicData.js +++ b/modules/order/back/methods/order/updateBasicData.js @@ -43,6 +43,7 @@ module.exports = Self => { tx = await Self.beginTransaction({}); myOptions.transaction = tx; } + try { const order = await models.Order.findById(id, null, myOptions); const orderRows = await models.OrderRow.find({where: {orderFk: id}}, myOptions); From 4cb346c2a8d930641d5af700630e6262226e30dd Mon Sep 17 00:00:00 2001 From: joan Date: Fri, 17 Dec 2021 12:40:23 +0100 Subject: [PATCH 17/19] fix(monitor): changed order to prevent row duplication Refs: 3458 --- modules/monitor/back/methods/sales-monitor/salesFilter.js | 6 +++--- modules/monitor/front/index/tickets/index.html | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/monitor/back/methods/sales-monitor/salesFilter.js b/modules/monitor/back/methods/sales-monitor/salesFilter.js index b5de38f60..1f1d4d88a 100644 --- a/modules/monitor/back/methods/sales-monitor/salesFilter.js +++ b/modules/monitor/back/methods/sales-monitor/salesFilter.js @@ -160,7 +160,7 @@ module.exports = Self => { stmts.push('DROP TEMPORARY TABLE IF EXISTS tmp.filter'); stmt = new ParameterizedSQL( `CREATE TEMPORARY TABLE tmp.filter - (INDEX (id)) + (PRIMARY KEY (id)) ENGINE = MEMORY SELECT t.id, @@ -221,7 +221,7 @@ module.exports = Self => { stmts.push('DROP TEMPORARY TABLE IF EXISTS tmp.clientGetDebt'); stmts.push(` CREATE TEMPORARY TABLE tmp.clientGetDebt - (INDEX (clientFk)) + (PRIMARY KEY (clientFk)) ENGINE = MEMORY SELECT DISTINCT clientFk FROM tmp.filter`); @@ -232,7 +232,7 @@ module.exports = Self => { stmts.push('DROP TEMPORARY TABLE IF EXISTS tmp.tickets'); stmt = new ParameterizedSQL(` CREATE TEMPORARY TABLE tmp.tickets - (INDEX (id)) + (PRIMARY KEY (id)) ENGINE = MEMORY SELECT f.*, r.risk AS debt FROM tmp.filter f diff --git a/modules/monitor/front/index/tickets/index.html b/modules/monitor/front/index/tickets/index.html index 7c0eb83da..a059e0685 100644 --- a/modules/monitor/front/index/tickets/index.html +++ b/modules/monitor/front/index/tickets/index.html @@ -2,7 +2,7 @@ vn-id="model" url="SalesMonitors/salesFilter" limit="20" - order="shippedDate DESC, preparationHour ASC, zoneLanding ASC, id"> + order="shippedDate DESC, theoreticalhour, id"> Date: Fri, 17 Dec 2021 13:09:00 +0100 Subject: [PATCH 18/19] refactor(monitor): limited width to the client and zone columns Refs: 3458 --- modules/monitor/front/index/tickets/index.html | 2 +- modules/monitor/front/index/tickets/style.scss | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/modules/monitor/front/index/tickets/index.html b/modules/monitor/front/index/tickets/index.html index a059e0685..0d7f265f8 100644 --- a/modules/monitor/front/index/tickets/index.html +++ b/modules/monitor/front/index/tickets/index.html @@ -167,7 +167,7 @@ {{::ticket.state}} - + Date: Fri, 17 Dec 2021 15:14:31 +0100 Subject: [PATCH 19/19] ctx was poluted by tests --- .../back/methods/order/specs/filter.spec.js | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/modules/order/back/methods/order/specs/filter.spec.js b/modules/order/back/methods/order/specs/filter.spec.js index 84e293840..53b666c10 100644 --- a/modules/order/back/methods/order/specs/filter.spec.js +++ b/modules/order/back/methods/order/specs/filter.spec.js @@ -8,13 +8,14 @@ describe('order filter()', () => { }; it('should call the filter method with a basic search', async() => { + const myCtx = Object.assign({}, ctx); const tx = await models.Order.beginTransaction({}); try { const options = {transaction: tx}; const filter = {where: {'o.id': 2}}; - const result = await models.Order.filter(ctx, filter, options); + const result = await models.Order.filter(myCtx, filter, options); const orderId = result[0].id; expect(orderId).toEqual(2); @@ -27,13 +28,14 @@ describe('order filter()', () => { }); it('should call the filter method with a single advanced search', async() => { + const myCtx = Object.assign({}, ctx); const tx = await models.Order.beginTransaction({}); try { const options = {transaction: tx}; const filter = {where: {'o.confirmed': false}}; - const result = await models.Order.filter(ctx, filter, options); + const result = await models.Order.filter(myCtx, filter, options); expect(result.length).toEqual(16); @@ -45,13 +47,14 @@ describe('order filter()', () => { }); it('should call the filter method with a complex advanced search', async() => { + const myCtx = Object.assign({}, ctx); const tx = await models.Order.beginTransaction({}); try { const options = {transaction: tx}; const filter = {where: {'o.confirmed': false, 'c.salesPersonFk': 18}}; - const result = await models.Order.filter(ctx, filter, options); + const result = await models.Order.filter(myCtx, filter, options); expect(result.length).toEqual(9); expect(result[0].id).toEqual(7); @@ -64,14 +67,15 @@ describe('order filter()', () => { }); it('should return the orders matching the showEmpty on false', async() => { + const myCtx = Object.assign({}, ctx); const tx = await models.Order.beginTransaction({}); try { const options = {transaction: tx}; const filter = {}; - ctx.args = {showEmpty: false}; - const result = await models.Order.filter(ctx, filter, options); + myCtx.args = {showEmpty: false}; + const result = await models.Order.filter(myCtx, filter, options); const hasEmptyLines = result.some(order => { return order.total === 0; }); @@ -86,14 +90,15 @@ describe('order filter()', () => { }); it('should return the orders matching the showEmpty on true', async() => { + const myCtx = Object.assign({}, ctx); const tx = await models.Order.beginTransaction({}); try { const options = {transaction: tx}; const filter = {}; - ctx.args = {showEmpty: true}; - const result = await models.Order.filter(ctx, filter, options); + myCtx.args = {showEmpty: true}; + const result = await models.Order.filter(myCtx, filter, options); const hasEmptyLines = result.some(order => { return order.total === 0; });