From 65dc0e3780c15ec3fe17779bf93270ab81c93ff4 Mon Sep 17 00:00:00 2001 From: joan Date: Tue, 6 Apr 2021 13:46:38 +0200 Subject: [PATCH] 2615 - Waste breakdown --- db/changes/10300-newFacility/00-weekWaste.sql | 24 ++++++++++++++++ .../00-weekWaste_byWorker.sql | 28 +++++++++++++++++++ .../00-weekWaste_getDetail.sql | 25 +++++++++++++++++ db/changes/10300-newFacility/01-waste.sql | 6 ++++ .../10300-newFacility/02-waste_addSales.sql | 2 +- modules/client/front/sample/create/index.js | 5 ++-- .../item/back/methods/item/getWasteByItem.js | 26 +++++++++++++---- .../methods/item/specs/getWasteByItem.spec.js | 14 ++++++++++ ...etail.spec.js => getWasteByWorker.spec.js} | 4 +-- modules/item/front/locale/es.yml | 3 +- modules/item/front/routes.json | 4 +-- modules/item/front/waste/detail/index.html | 23 ++++++++++++--- modules/item/front/waste/index/index.html | 4 +-- print/core/mixins/image-src.js | 2 +- print/methods/email.js | 27 ++++++++++++------ .../buyer-week-waste/buyer-week-waste.js | 3 +- .../buyer-week-waste/sql/wasteWeekly.sql | 11 ++++++++ 17 files changed, 180 insertions(+), 31 deletions(-) create mode 100644 db/changes/10300-newFacility/00-weekWaste.sql create mode 100644 db/changes/10300-newFacility/00-weekWaste_byWorker.sql create mode 100644 db/changes/10300-newFacility/00-weekWaste_getDetail.sql create mode 100644 modules/item/back/methods/item/specs/getWasteByItem.spec.js rename modules/item/back/methods/item/specs/{getWasteDetail.spec.js => getWasteByWorker.spec.js} (79%) create mode 100644 print/templates/email/buyer-week-waste/sql/wasteWeekly.sql diff --git a/db/changes/10300-newFacility/00-weekWaste.sql b/db/changes/10300-newFacility/00-weekWaste.sql new file mode 100644 index 0000000000..efa988aea8 --- /dev/null +++ b/db/changes/10300-newFacility/00-weekWaste.sql @@ -0,0 +1,24 @@ +drop procedure weekWaste; + +create definer = root@`%` procedure weekWaste__() +BEGIN + DECLARE vWeek INT; + DECLARE vYear INT; + + SELECT week, year + INTO vWeek, vYear + FROM vn.time + WHERE dated = DATE_ADD(CURDATE(), INTERVAL -1 WEEK); + + SELECT *, 100 * dwindle / total AS percentage + FROM ( + SELECT buyer, + sum(saleTotal) as total, + sum(saleWaste) as dwindle + FROM bs.waste + WHERE year = vYear and week = vWeek + GROUP BY buyer + ) sub + ORDER BY percentage DESC; +END; + diff --git a/db/changes/10300-newFacility/00-weekWaste_byWorker.sql b/db/changes/10300-newFacility/00-weekWaste_byWorker.sql new file mode 100644 index 0000000000..2da098ae69 --- /dev/null +++ b/db/changes/10300-newFacility/00-weekWaste_byWorker.sql @@ -0,0 +1,28 @@ +drop procedure weekWaste_byWorker; + +create definer = root@`%` procedure weekWaste_byWorker__(IN vWorkerFk int) +BEGIN + + DECLARE vWeek INT; + DECLARE vYear INT; + + SELECT week, year + INTO vWeek, vYear + FROM vn.time + WHERE dated = TIMESTAMPADD(WEEK,-1,CURDATE()); + + SELECT *, 100 * mermas / total as porcentaje + FROM ( + SELECT ws.family, + sum(ws.saleTotal) as total, + sum(ws.saleWaste) as mermas + FROM bs.waste ws + JOIN vn.worker w ON w.user = ws.buyer + WHERE year = vYear AND week = vWeek + AND w.id = vWorkerFk + GROUP BY family + + ) sub + ORDER BY porcentaje DESC; +END; + diff --git a/db/changes/10300-newFacility/00-weekWaste_getDetail.sql b/db/changes/10300-newFacility/00-weekWaste_getDetail.sql new file mode 100644 index 0000000000..4dd0cab6c3 --- /dev/null +++ b/db/changes/10300-newFacility/00-weekWaste_getDetail.sql @@ -0,0 +1,25 @@ +drop procedure weekWaste_getDetail; + +create definer = root@`%` procedure weekWaste_getDetail__() +BEGIN + DECLARE vLastWeek DATE; + DECLARE vWeek INT; + DECLARE vYear INT; + + SET vLastWeek = TIMESTAMPADD(WEEK,-1,CURDATE()); + SET vYear = YEAR(vLastWeek); + SET vWeek = WEEK(vLastWeek, 1); + + SELECT *, 100 * dwindle / total AS percentage + FROM ( + SELECT buyer, + ws.family, + sum(ws.saleTotal) AS total, + sum(ws.saleWaste) AS dwindle + FROM bs.waste ws + WHERE year = vYear AND week = vWeek + GROUP BY buyer, family + ) sub + ORDER BY percentage DESC; +END; + diff --git a/db/changes/10300-newFacility/01-waste.sql b/db/changes/10300-newFacility/01-waste.sql index 1f4eed0636..1f7f5fdebc 100644 --- a/db/changes/10300-newFacility/01-waste.sql +++ b/db/changes/10300-newFacility/01-waste.sql @@ -14,3 +14,9 @@ ALTER TABLE `bs`.`waste` FOREIGN KEY (itemFk) REFERENCES vn.item (id) ON UPDATE CASCADE; +ALTER TABLE `bs`.`waste` DROP PRIMARY KEY; + +ALTER TABLE `bs`.`waste` + AD PRIMARY KEY (buyer, year, week, family, itemFk); + + diff --git a/db/changes/10300-newFacility/02-waste_addSales.sql b/db/changes/10300-newFacility/02-waste_addSales.sql index a01150c4a2..df6db2d2c9 100644 --- a/db/changes/10300-newFacility/02-waste_addSales.sql +++ b/db/changes/10300-newFacility/02-waste_addSales.sql @@ -28,7 +28,7 @@ BEGIN FROM vn.saleValue where year = vYear and week = vWeek - GROUP BY family + GROUP BY family, itemFk ) sub ORDER BY mermas DESC; diff --git a/modules/client/front/sample/create/index.js b/modules/client/front/sample/create/index.js index bc2cee39d4..63f8be7b58 100644 --- a/modules/client/front/sample/create/index.js +++ b/modules/client/front/sample/create/index.js @@ -77,9 +77,10 @@ class Controller extends Section { if (sampleType.hasCompany) params.companyId = this.clientSample.companyFk; - if (isPreview) params.isPreview = true; + let query = `email/${sampleType.code}`; + if (isPreview) + query = `email/${sampleType.code}/preview`; - const query = `email/${sampleType.code}`; this.$http.get(query, {params}).then(cb); } } diff --git a/modules/item/back/methods/item/getWasteByItem.js b/modules/item/back/methods/item/getWasteByItem.js index 6fb96c6602..4ecd195afd 100644 --- a/modules/item/back/methods/item/getWasteByItem.js +++ b/modules/item/back/methods/item/getWasteByItem.js @@ -2,7 +2,20 @@ module.exports = Self => { Self.remoteMethod('getWasteByItem', { description: 'Returns the details of losses by worker', accessType: 'READ', - accepts: [], + accepts: [ + { + arg: 'buyer', + type: 'string', + required: true, + description: 'The buyer name' + }, + { + arg: 'family', + type: 'string', + required: true, + description: 'The item family name' + } + ], returns: { type: ['Object'], root: true @@ -13,20 +26,22 @@ module.exports = Self => { } }); - Self.getWasteByItem = async() => { + Self.getWasteByItem = async(buyer, family) => { const wastes = await Self.rawSql(` SELECT *, 100 * dwindle / total AS percentage FROM ( SELECT buyer, ws.family, + ws.itemFk, sum(ws.saleTotal) AS total, sum(ws.saleWaste) AS dwindle FROM bs.waste ws - WHERE year = YEAR(TIMESTAMPADD(WEEK,-1,CURDATE())) - AND week = WEEK(TIMESTAMPADD(WEEK,-1,CURDATE()), 1) + WHERE buyer = ? AND family = ? + AND year = YEAR(TIMESTAMPADD(WEEK,-1,CURDATE())) + AND week = WEEK(TIMESTAMPADD(WEEK,-1,CURDATE()), 1) GROUP BY buyer, itemFk ) sub - ORDER BY percentage DESC`); + ORDER BY family, percentage DESC`, [buyer, family]); const details = []; @@ -40,6 +55,7 @@ module.exports = Self => { if (!buyerDetail) { buyerDetail = { buyer: buyerName, + family: waste.family, lines: [] }; details.push(buyerDetail); diff --git a/modules/item/back/methods/item/specs/getWasteByItem.spec.js b/modules/item/back/methods/item/specs/getWasteByItem.spec.js new file mode 100644 index 0000000000..dabad4fc67 --- /dev/null +++ b/modules/item/back/methods/item/specs/getWasteByItem.spec.js @@ -0,0 +1,14 @@ +const app = require('vn-loopback/server/server'); + +describe('Item getWasteByItem()', () => { + it('should check for the waste breakdown by worker and item', async() => { + const result = await app.models.Item.getWasteByItem('CharlesXavier', 'Cymbidium'); + + const length = result.length; + const anyResult = result[Math.floor(Math.random() * Math.floor(length))]; + + expect(anyResult.buyer).toEqual('CharlesXavier'); + expect(anyResult.family).toEqual('Cymbidium'); + expect(anyResult.lines.length).toBeGreaterThanOrEqual(2); + }); +}); diff --git a/modules/item/back/methods/item/specs/getWasteDetail.spec.js b/modules/item/back/methods/item/specs/getWasteByWorker.spec.js similarity index 79% rename from modules/item/back/methods/item/specs/getWasteDetail.spec.js rename to modules/item/back/methods/item/specs/getWasteByWorker.spec.js index 5f11513e12..9ffe96bf72 100644 --- a/modules/item/back/methods/item/specs/getWasteDetail.spec.js +++ b/modules/item/back/methods/item/specs/getWasteByWorker.spec.js @@ -1,8 +1,8 @@ const app = require('vn-loopback/server/server'); -describe('item getWasteDetail()', () => { +describe('Item getWasteByWorker()', () => { it('should check for the waste breakdown for every worker', async() => { - const result = await app.models.Item.getWasteDetail(); + const result = await app.models.Item.getWasteByWorker(); const length = result.length; const anyResult = result[Math.floor(Math.random() * Math.floor(length))]; diff --git a/modules/item/front/locale/es.yml b/modules/item/front/locale/es.yml index 46e40e412e..6166622e57 100644 --- a/modules/item/front/locale/es.yml +++ b/modules/item/front/locale/es.yml @@ -63,4 +63,5 @@ Diary: Histórico Item diary: Registro de compra-venta Last entries: Últimas entradas Tags: Etiquetas -Waste breakdown: Desglose de mermas \ No newline at end of file +Waste breakdown: Desglose de mermas +Waste breakdown by item: Desglose de mermas por artículo \ No newline at end of file diff --git a/modules/item/front/routes.json b/modules/item/front/routes.json index d0275ff29e..f6b3bfe293 100644 --- a/modules/item/front/routes.json +++ b/modules/item/front/routes.json @@ -168,10 +168,10 @@ "acl": ["buyer"] }, { - "url" : "/detail", + "url" : "/detail?buyer&family", "state": "item.waste.detail", "component": "vn-item-waste-detail", - "description": "Waste breakdown by type", + "description": "Waste breakdown by item", "acl": ["buyer"] }, { diff --git a/modules/item/front/waste/detail/index.html b/modules/item/front/waste/detail/index.html index 69214c2732..035c677f8c 100644 --- a/modules/item/front/waste/detail/index.html +++ b/modules/item/front/waste/detail/index.html @@ -1,18 +1,24 @@ - +
-
{{detail.buyer}}
+
+ + < Back + + - {{detail.family}} ({{detail.buyer}}) +
- Family + Item Percentage Dwindle Total @@ -20,7 +26,13 @@ - {{::waste.family}} + + + {{::waste.itemFk}} + + {{::(waste.percentage / 100) | percentage: 2}} {{::waste.dwindle | currency: 'EUR'}} {{::waste.total | currency: 'EUR'}} @@ -30,3 +42,6 @@
+ + \ No newline at end of file diff --git a/modules/item/front/waste/index/index.html b/modules/item/front/waste/index/index.html index 6c123fc19b..7ad985ea8b 100644 --- a/modules/item/front/waste/index/index.html +++ b/modules/item/front/waste/index/index.html @@ -8,7 +8,7 @@
-
{{detail.buyer}}
+
{{detail.buyer}}
@@ -21,7 +21,7 @@ + ui-sref="item.waste.detail({buyer: waste.buyer, family: waste.family})" > {{::waste.family}} {{::(waste.percentage / 100) | percentage: 2}} {{::waste.dwindle | currency: 'EUR'}} diff --git a/print/core/mixins/image-src.js b/print/core/mixins/image-src.js index 7fd557410e..c36039c1a2 100644 --- a/print/core/mixins/image-src.js +++ b/print/core/mixins/image-src.js @@ -6,7 +6,7 @@ const imageSrc = { getEmailSrc(image) { let src = `cid:${image}`; - if (this.isPreview === 'true') + if (this.isPreview) src = `/api/${this.$options.name}/assets/images/${image}`; return src; diff --git a/print/methods/email.js b/print/methods/email.js index 69f880a0a3..cc4590e5de 100644 --- a/print/methods/email.js +++ b/print/methods/email.js @@ -6,17 +6,26 @@ module.exports = app => { const reportName = req.params.name; const email = new Email(reportName, req.args); - if (req.args.isPreview === 'true') { - const rendered = await email.render(); + await email.send(); - res.send(rendered); - } else { - await email.send(); + res.status(200).json({ + message: 'Sent' + }); + } catch (e) { + next(e); + } + }); - res.status(200).json({ - message: 'Sent' - }); - } + app.get(`/api/email/:name/preview`, async(req, res, next) => { + try { + const reportName = req.params.name; + const args = req.args; + args.isPreview = true; + + const email = new Email(reportName, args); + const rendered = await email.render(); + + res.send(rendered); } catch (e) { next(e); } diff --git a/print/templates/email/buyer-week-waste/buyer-week-waste.js b/print/templates/email/buyer-week-waste/buyer-week-waste.js index 4639e7d5bd..9af477e82e 100755 --- a/print/templates/email/buyer-week-waste/buyer-week-waste.js +++ b/print/templates/email/buyer-week-waste/buyer-week-waste.js @@ -1,5 +1,4 @@ const Component = require(`${appPath}/core/component`); -const db = require(`${appPath}/core/database`); const emailHeader = new Component('email-header'); const emailFooter = new Component('email-footer'); @@ -20,7 +19,7 @@ module.exports = { }, methods: { fetchWastes() { - return db.findOne(`CALL bs.weekWaste()`); + return this.rawSqlFromDef('wasteWeekly'); } }, components: { diff --git a/print/templates/email/buyer-week-waste/sql/wasteWeekly.sql b/print/templates/email/buyer-week-waste/sql/wasteWeekly.sql new file mode 100644 index 0000000000..943c085d0f --- /dev/null +++ b/print/templates/email/buyer-week-waste/sql/wasteWeekly.sql @@ -0,0 +1,11 @@ +SELECT *, 100 * dwindle / total AS percentage + FROM ( + SELECT buyer, + sum(saleTotal) as total, + sum(saleWaste) as dwindle + FROM bs.waste w + JOIN vn.time t ON w.year = t.year AND w.week = t.week + WHERE t.dated = DATE_ADD(CURDATE(), INTERVAL -1 WEEK) + GROUP BY buyer + ) sub + ORDER BY percentage DESC; \ No newline at end of file