From 4aa616601e4705ada31baa8ed228939b51dce3b7 Mon Sep 17 00:00:00 2001 From: joan Date: Tue, 30 Mar 2021 10:28:44 +0200 Subject: [PATCH 1/5] 2615 - Waste changes --- db/changes/10300-newFacility/.keep | 1 - db/changes/10300-newFacility/00-saleValue.sql | 26 +++++++++ db/changes/10300-newFacility/00-waste.sql | 16 ++++++ .../10300-newFacility/00-waste_addSales.sql | 38 +++++++++++++ db/dump/fixtures.sql | 27 ++++++---- .../{getWasteDetail.js => getWasteByItem.js} | 20 +++++-- .../back/methods/item/getWasteByWorker.js | 53 +++++++++++++++++++ modules/item/back/models/item.js | 3 +- modules/item/front/index.js | 3 +- modules/item/front/routes.json | 19 +++++-- .../item/front/waste/{ => detail}/index.html | 2 +- modules/item/front/waste/detail/index.js | 7 +++ .../item/front/waste/{ => detail}/style.scss | 0 modules/item/front/waste/index/index.html | 34 ++++++++++++ modules/item/front/waste/{ => index}/index.js | 4 +- modules/item/front/waste/index/style.scss | 26 +++++++++ 16 files changed, 255 insertions(+), 24 deletions(-) delete mode 100644 db/changes/10300-newFacility/.keep create mode 100644 db/changes/10300-newFacility/00-saleValue.sql create mode 100644 db/changes/10300-newFacility/00-waste.sql create mode 100644 db/changes/10300-newFacility/00-waste_addSales.sql rename modules/item/back/methods/item/{getWasteDetail.js => getWasteByItem.js} (53%) create mode 100644 modules/item/back/methods/item/getWasteByWorker.js rename modules/item/front/waste/{ => detail}/index.html (97%) create mode 100644 modules/item/front/waste/detail/index.js rename modules/item/front/waste/{ => detail}/style.scss (100%) create mode 100644 modules/item/front/waste/index/index.html rename modules/item/front/waste/{ => index}/index.js (63%) create mode 100644 modules/item/front/waste/index/style.scss diff --git a/db/changes/10300-newFacility/.keep b/db/changes/10300-newFacility/.keep deleted file mode 100644 index 3ece1d69e..000000000 --- a/db/changes/10300-newFacility/.keep +++ /dev/null @@ -1 +0,0 @@ -Delete this \ No newline at end of file diff --git a/db/changes/10300-newFacility/00-saleValue.sql b/db/changes/10300-newFacility/00-saleValue.sql new file mode 100644 index 000000000..5165bd4a5 --- /dev/null +++ b/db/changes/10300-newFacility/00-saleValue.sql @@ -0,0 +1,26 @@ +CREATE OR REPLACE DEFINER = root@`%` VIEW `vn`.`saleValue` AS +SELECT `wh`.`name` AS `warehouse`, + `c`.`name` AS `client`, + `c`.`typeFk` AS `clientTypeFk`, + `u`.`name` AS `buyer`, + `it`.`id` AS `itemTypeFk`, + `it`.`name` AS `family`, + `s`.`itemFk` AS `itemFk`, + `s`.`concept` AS `concept`, + `s`.`quantity` AS `quantity`, + `b`.`buyingValue` + `b`.`freightValue` + `b`.`comissionValue` + `b`.`packageValue` AS `cost`, + (`b`.`buyingValue` + `b`.`freightValue` + `b`.`comissionValue` + `b`.`packageValue`) * `s`.`quantity` AS `value`, + `tm`.`year` AS `year`, + `tm`.`week` AS `week` +FROM `vn`.`sale` `s` + JOIN `vn`.`item` `i` ON `i`.`id` = `s`.`itemFk` + JOIN `vn`.`itemType` `it` ON `it`.`id` = `i`.`typeFk` + JOIN `account`.`user` `u` ON `u`.`id` = `it`.`workerFk` + JOIN `vn`.`ticket` `t` ON `t`.`id` = `s`.`ticketFk` + JOIN `vn`.`client` `c` ON `c`.`id` = `t`.`clientFk` + JOIN `vn`.`warehouse` `wh` ON `wh`.`id` = `t`.`warehouseFk` + JOIN `vn`.`time` `tm` ON `tm`.`dated` = CAST(`t`.`shipped` AS DATE) + JOIN `cache`.`last_buy` `lb` ON `lb`.`item_id` = `i`.`id` AND `lb`.`warehouse_id` = `wh`.`id` + JOIN `vn`.`buy` `b` ON `b`.`id` = `lb`.`buy_id` +WHERE `wh`.`isManaged` <> 0; + diff --git a/db/changes/10300-newFacility/00-waste.sql b/db/changes/10300-newFacility/00-waste.sql new file mode 100644 index 000000000..1f4eed063 --- /dev/null +++ b/db/changes/10300-newFacility/00-waste.sql @@ -0,0 +1,16 @@ +ALTER TABLE `bs`.`waste` + ADD itemFk INT NULL AFTER `family`; + +ALTER TABLE `bs`.`waste` + ADD itemTypeFk SMALLINT(5) UNSIGNED NULL AFTER `itemFk`; + +ALTER TABLE `bs`.`waste` + ADD CONSTRAINT waste_itemType_id + FOREIGN KEY (itemTypeFk) REFERENCES vn.itemType (id) + ON UPDATE CASCADE; + +ALTER TABLE `bs`.`waste` + ADD CONSTRAINT waste_item_id + FOREIGN KEY (itemFk) REFERENCES vn.item (id) + ON UPDATE CASCADE; + diff --git a/db/changes/10300-newFacility/00-waste_addSales.sql b/db/changes/10300-newFacility/00-waste_addSales.sql new file mode 100644 index 000000000..8e971048d --- /dev/null +++ b/db/changes/10300-newFacility/00-waste_addSales.sql @@ -0,0 +1,38 @@ +UPDATE `bs`.nightTask t SET t.`procedure` = 'waste_addSales' WHERE t.id = 54; + +DROP PROCEDURE`bs`.`waste_Add`; + +CREATE + DEFINER = root@`%` PROCEDURE `bs`.`waste_addSales`() +BEGIN + + DECLARE vWeek INT; + DECLARE vYear INT; + + SELECT week, year + INTO vWeek, vYear + FROM vn.time + WHERE dated = CURDATE(); + + REPLACE bs.waste + SELECT *, 100 * mermas / total as porcentaje + FROM ( + SELECT buyer, + year, + week, + family, + itemFk, + itemTypeFk, + floor(sum(value)) as total, + floor(sum(IF(clientTypeFk = 'loses', value, 0))) as mermas + FROM vn.saleValue + where year = vYear and week = vWeek + + GROUP BY family + + ) sub + ORDER BY mermas DESC; + +END; + + diff --git a/db/dump/fixtures.sql b/db/dump/fixtures.sql index 0492ee980..6163dd8a9 100644 --- a/db/dump/fixtures.sql +++ b/db/dump/fixtures.sql @@ -1296,18 +1296,23 @@ INSERT INTO `vn`.`claimRatio`(`clientFk`, `yearSale`, `claimAmount`, `claimingRa (103, 2000, 0.00, 0.00, 0.02, 1.00), (104, 2500, 150.00, 0.02, 0.10, 1.00); -INSERT INTO `bs`.`waste`(`buyer`, `year`, `week`, `family`, `saleTotal`, `saleWaste`, `rate`) +INSERT INTO `bs`.`waste`(`buyer`, `year`, `week`, `family`, `itemFk`, `itemTypeFk`, `saleTotal`, `saleWaste`, `rate`) VALUES - ('CharlesXavier', YEAR(DATE_ADD(CURDATE(), INTERVAL -1 WEEK)), WEEK(DATE_ADD(CURDATE(), INTERVAL -1 WEEK), 1), 'Carnation', '1062', '51', '4.8'), - ('CharlesXavier', YEAR(DATE_ADD(CURDATE(), INTERVAL -1 WEEK)), WEEK(DATE_ADD(CURDATE(), INTERVAL -1 WEEK), 1), 'Carnation Colombia', '35074', '687', '2.0'), - ('CharlesXavier', YEAR(DATE_ADD(CURDATE(), INTERVAL -1 WEEK)), WEEK(DATE_ADD(CURDATE(), INTERVAL -1 WEEK), 1), 'Carnation Mini', '1777', '13', '0.7'), - ('CharlesXavier', YEAR(DATE_ADD(CURDATE(), INTERVAL -1 WEEK)), WEEK(DATE_ADD(CURDATE(), INTERVAL -1 WEEK), 1), 'Carnation Short', '9182', '59', '0.6'), - ('DavidCharlesHaller', YEAR(DATE_ADD(CURDATE(), INTERVAL -1 WEEK)), WEEK(DATE_ADD(CURDATE(), INTERVAL -1 WEEK), 1), 'Containers', '-74', '0', '0.0'), - ('DavidCharlesHaller', YEAR(DATE_ADD(CURDATE(), INTERVAL -1 WEEK)), WEEK(DATE_ADD(CURDATE(), INTERVAL -1 WEEK), 1), 'Packagings', '-7', '0', '0.0'), - ('DavidCharlesHaller', YEAR(DATE_ADD(CURDATE(), INTERVAL -1 WEEK)), WEEK(DATE_ADD(CURDATE(), INTERVAL -1 WEEK), 1), 'Freight', '1100', '0', '0.0'), - ('HankPym', YEAR(DATE_ADD(CURDATE(), INTERVAL -1 WEEK)), WEEK(DATE_ADD(CURDATE(), INTERVAL -1 WEEK), 1), 'Funeral Accessories', '848', '-187', '-22.1'), - ('HankPym', YEAR(DATE_ADD(CURDATE(), INTERVAL -1 WEEK)), WEEK(DATE_ADD(CURDATE(), INTERVAL -1 WEEK), 1), 'Miscellaneous Accessories', '186', '0', '0.0'), - ('HankPym', YEAR(DATE_ADD(CURDATE(), INTERVAL -1 WEEK)), WEEK(DATE_ADD(CURDATE(), INTERVAL -1 WEEK), 1), 'Adhesives', '277', '0', '0.0'); + ('CharlesXavier', YEAR(DATE_ADD(CURDATE(), INTERVAL -1 WEEK)), WEEK(DATE_ADD(CURDATE(), INTERVAL -1 WEEK), 1), 'Carnation', 1, 1, '1062', '51', '4.8'), + ('CharlesXavier', YEAR(DATE_ADD(CURDATE(), INTERVAL -1 WEEK)), WEEK(DATE_ADD(CURDATE(), INTERVAL -1 WEEK), 1), 'Carnation Colombia', 2, 1, '35074', '687', '2.0'), + ('CharlesXavier', YEAR(DATE_ADD(CURDATE(), INTERVAL -1 WEEK)), WEEK(DATE_ADD(CURDATE(), INTERVAL -1 WEEK), 1), 'Carnation Mini', 3, 1, '1777', '13', '0.7'), + ('CharlesXavier', YEAR(DATE_ADD(CURDATE(), INTERVAL -1 WEEK)), WEEK(DATE_ADD(CURDATE(), INTERVAL -1 WEEK), 1), 'Carnation Short', 4, 1, '3182', '59', '0.6'), + ('CharlesXavier', YEAR(DATE_ADD(CURDATE(), INTERVAL -1 WEEK)), WEEK(DATE_ADD(CURDATE(), INTERVAL -1 WEEK), 1), 'Crisantemo', 5, 1, '1747', '13', '0.7'), + ('CharlesXavier', YEAR(DATE_ADD(CURDATE(), INTERVAL -1 WEEK)), WEEK(DATE_ADD(CURDATE(), INTERVAL -1 WEEK), 1), 'Lilium Oriental', 6, 1, '7182', '59', '0.6'), + ('CharlesXavier', YEAR(DATE_ADD(CURDATE(), INTERVAL -1 WEEK)), WEEK(DATE_ADD(CURDATE(), INTERVAL -1 WEEK), 1), 'Alstroemeria', 7, 1, '1777', '13', '0.7'), + ('CharlesXavier', YEAR(DATE_ADD(CURDATE(), INTERVAL -1 WEEK)), WEEK(DATE_ADD(CURDATE(), INTERVAL -1 WEEK), 1), 'Cymbidium', 1, 1, '4181', '59', '0.6'), + ('CharlesXavier', YEAR(DATE_ADD(CURDATE(), INTERVAL -1 WEEK)), WEEK(DATE_ADD(CURDATE(), INTERVAL -1 WEEK), 1), 'Cymbidium', 2, 1, '7268', '59', '0.6'), + ('DavidCharlesHaller', YEAR(DATE_ADD(CURDATE(), INTERVAL -1 WEEK)), WEEK(DATE_ADD(CURDATE(), INTERVAL -1 WEEK), 1), 'Containers', 2, 1, '-74', '0', '0.0'), + ('DavidCharlesHaller', YEAR(DATE_ADD(CURDATE(), INTERVAL -1 WEEK)), WEEK(DATE_ADD(CURDATE(), INTERVAL -1 WEEK), 1), 'Packagings', 3, 1, '-7', '0', '0.0'), + ('DavidCharlesHaller', YEAR(DATE_ADD(CURDATE(), INTERVAL -1 WEEK)), WEEK(DATE_ADD(CURDATE(), INTERVAL -1 WEEK), 1), 'Freight', 4, 1, '1100', '0', '0.0'), + ('HankPym', YEAR(DATE_ADD(CURDATE(), INTERVAL -1 WEEK)), WEEK(DATE_ADD(CURDATE(), INTERVAL -1 WEEK), 1), 'Funeral Accessories', 5, 1, '848', '-187', '-22.1'), + ('HankPym', YEAR(DATE_ADD(CURDATE(), INTERVAL -1 WEEK)), WEEK(DATE_ADD(CURDATE(), INTERVAL -1 WEEK), 1), 'Miscellaneous Accessories', 6, 1, '186', '0', '0.0'), + ('HankPym', YEAR(DATE_ADD(CURDATE(), INTERVAL -1 WEEK)), WEEK(DATE_ADD(CURDATE(), INTERVAL -1 WEEK), 1), 'Adhesives', 7, 1, '277', '0', '0.0'); INSERT INTO `vn`.`buy`(`id`,`entryFk`,`itemFk`,`buyingValue`,`quantity`,`packageFk`,`stickers`,`freightValue`,`packageValue`,`comissionValue`,`packing`,`grouping`,`groupingMode`,`location`,`price1`,`price2`,`price3`,`producer`,`printedStickers`,`isChecked`,`isIgnored`,`weight`, `created`) VALUES diff --git a/modules/item/back/methods/item/getWasteDetail.js b/modules/item/back/methods/item/getWasteByItem.js similarity index 53% rename from modules/item/back/methods/item/getWasteDetail.js rename to modules/item/back/methods/item/getWasteByItem.js index b8b55b275..6fb96c660 100644 --- a/modules/item/back/methods/item/getWasteDetail.js +++ b/modules/item/back/methods/item/getWasteByItem.js @@ -1,5 +1,5 @@ module.exports = Self => { - Self.remoteMethod('getWasteDetail', { + Self.remoteMethod('getWasteByItem', { description: 'Returns the details of losses by worker', accessType: 'READ', accepts: [], @@ -8,13 +8,25 @@ module.exports = Self => { root: true }, http: { - path: `/getWasteDetail`, + path: `/getWasteByItem`, verb: 'GET' } }); - Self.getWasteDetail = async() => { - const [wastes] = await Self.rawSql(`CALL bs.weekWaste_getDetail()`); + Self.getWasteByItem = async() => { + const wastes = await Self.rawSql(` + 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 = YEAR(TIMESTAMPADD(WEEK,-1,CURDATE())) + AND week = WEEK(TIMESTAMPADD(WEEK,-1,CURDATE()), 1) + GROUP BY buyer, itemFk + ) sub + ORDER BY percentage DESC`); const details = []; diff --git a/modules/item/back/methods/item/getWasteByWorker.js b/modules/item/back/methods/item/getWasteByWorker.js new file mode 100644 index 000000000..032472696 --- /dev/null +++ b/modules/item/back/methods/item/getWasteByWorker.js @@ -0,0 +1,53 @@ +module.exports = Self => { + Self.remoteMethod('getWasteByWorker', { + description: 'Returns the details of losses by worker', + accessType: 'READ', + accepts: [], + returns: { + type: ['Object'], + root: true + }, + http: { + path: `/getWasteByWorker`, + verb: 'GET' + } + }); + + Self.getWasteByWorker = async() => { + const wastes = await Self.rawSql(` + 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 = YEAR(TIMESTAMPADD(WEEK,-1,CURDATE())) + AND week = WEEK(TIMESTAMPADD(WEEK,-1,CURDATE()), 1) + GROUP BY buyer, family + ) sub + ORDER BY percentage DESC`); + + const details = []; + + for (let waste of wastes) { + const buyerName = waste.buyer; + + let buyerDetail = details.find(waste => { + return waste.buyer == buyerName; + }); + + if (!buyerDetail) { + buyerDetail = { + buyer: buyerName, + lines: [] + }; + details.push(buyerDetail); + } + + buyerDetail.lines.push(waste); + } + + return details; + }; +}; diff --git a/modules/item/back/models/item.js b/modules/item/back/models/item.js index 9ddd056e6..6cf5ba625 100644 --- a/modules/item/back/models/item.js +++ b/modules/item/back/models/item.js @@ -11,7 +11,8 @@ module.exports = Self => { require('../methods/item/regularize')(Self); require('../methods/item/getVisibleAvailable')(Self); require('../methods/item/new')(Self); - require('../methods/item/getWasteDetail')(Self); + require('../methods/item/getWasteByWorker')(Self); + require('../methods/item/getWasteByItem')(Self); require('../methods/item/createIntrastat')(Self); Self.validatesPresenceOf('originFk', {message: 'Cannot be blank'}); diff --git a/modules/item/front/index.js b/modules/item/front/index.js index e6a37abfc..8cb22ef40 100644 --- a/modules/item/front/index.js +++ b/modules/item/front/index.js @@ -20,7 +20,8 @@ import './niche'; import './botanical'; import './barcode'; import './summary'; -import './waste'; +import './waste/index/'; +import './waste/detail'; import './fixed-price'; import './fixed-price-search-panel'; diff --git a/modules/item/front/routes.json b/modules/item/front/routes.json index 4b4be3c3d..d0275ff29 100644 --- a/modules/item/front/routes.json +++ b/modules/item/front/routes.json @@ -8,7 +8,7 @@ "main": [ {"state": "item.index", "icon": "icon-item"}, {"state": "item.request", "icon": "pan_tool"}, - {"state": "item.waste", "icon": "icon-claims"}, + {"state": "item.waste.index", "icon": "icon-claims"}, {"state": "item.fixedPrice", "icon": "contact_support"} ], "card": [ @@ -155,12 +155,25 @@ "acl": ["employee"] }, { - "url" : "/waste", + "url": "/waste", "state": "item.waste", - "component": "vn-item-waste", + "component": "ui-view", + "abstract": true + }, + { + "url" : "/index", + "state": "item.waste.index", + "component": "vn-item-waste-index", "description": "Waste breakdown", "acl": ["buyer"] }, + { + "url" : "/detail", + "state": "item.waste.detail", + "component": "vn-item-waste-detail", + "description": "Waste breakdown by type", + "acl": ["buyer"] + }, { "url" : "/fixed-price?q", "state": "item.fixedPrice", diff --git a/modules/item/front/waste/index.html b/modules/item/front/waste/detail/index.html similarity index 97% rename from modules/item/front/waste/index.html rename to modules/item/front/waste/detail/index.html index d363f0ce0..69214c273 100644 --- a/modules/item/front/waste/index.html +++ b/modules/item/front/waste/detail/index.html @@ -1,6 +1,6 @@ diff --git a/modules/item/front/waste/detail/index.js b/modules/item/front/waste/detail/index.js new file mode 100644 index 000000000..2949a493b --- /dev/null +++ b/modules/item/front/waste/detail/index.js @@ -0,0 +1,7 @@ +import ngModule from '../../module'; +import Section from 'salix/components/section'; + +ngModule.vnComponent('vnItemWasteDetail', { + template: require('./index.html'), + controller: Section +}); diff --git a/modules/item/front/waste/style.scss b/modules/item/front/waste/detail/style.scss similarity index 100% rename from modules/item/front/waste/style.scss rename to modules/item/front/waste/detail/style.scss diff --git a/modules/item/front/waste/index/index.html b/modules/item/front/waste/index/index.html new file mode 100644 index 000000000..6c123fc19 --- /dev/null +++ b/modules/item/front/waste/index/index.html @@ -0,0 +1,34 @@ + + + + + +
+ +
{{detail.buyer}}
+
+ + + + Family + Percentage + Dwindle + Total + + + + + {{::waste.family}} + {{::(waste.percentage / 100) | percentage: 2}} + {{::waste.dwindle | currency: 'EUR'}} + {{::waste.total | currency: 'EUR'}} + + + +
+
+
diff --git a/modules/item/front/waste/index.js b/modules/item/front/waste/index/index.js similarity index 63% rename from modules/item/front/waste/index.js rename to modules/item/front/waste/index/index.js index 3c5d1a6be..15e6b063f 100644 --- a/modules/item/front/waste/index.js +++ b/modules/item/front/waste/index/index.js @@ -1,8 +1,8 @@ -import ngModule from '../module'; +import ngModule from '../../module'; import Section from 'salix/components/section'; import './style.scss'; -ngModule.vnComponent('vnItemWaste', { +ngModule.vnComponent('vnItemWasteIndex', { template: require('./index.html'), controller: Section }); diff --git a/modules/item/front/waste/index/style.scss b/modules/item/front/waste/index/style.scss new file mode 100644 index 000000000..09e3a2a4c --- /dev/null +++ b/modules/item/front/waste/index/style.scss @@ -0,0 +1,26 @@ +@import "variables"; + +vn-item-waste-index, +vn-item-waste-detail { + .header { + margin-bottom: 16px; + text-transform: uppercase; + font-size: 1.25rem; + line-height: 1; + padding: 7px; + padding-bottom: 7px; + padding-bottom: 4px; + font-weight: lighter; + background-color: #fde6ca; + border-bottom: 1px solid #f7931e; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + } + + vn-table vn-th.waste-family, + vn-table vn-td.waste-family { + max-width: 64px; + width: 64px + } +} \ No newline at end of file From 5712f1c43bebf519b3388eb754f0e85c84534602 Mon Sep 17 00:00:00 2001 From: joan Date: Thu, 1 Apr 2021 13:12:02 +0200 Subject: [PATCH 2/5] Changes --- db/changes/10300-newFacility/{00-waste.sql => 01-waste.sql} | 0 .../{00-waste_addSales.sql => 02-waste_addSales.sql} | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename db/changes/10300-newFacility/{00-waste.sql => 01-waste.sql} (100%) rename db/changes/10300-newFacility/{00-waste_addSales.sql => 02-waste_addSales.sql} (94%) diff --git a/db/changes/10300-newFacility/00-waste.sql b/db/changes/10300-newFacility/01-waste.sql similarity index 100% rename from db/changes/10300-newFacility/00-waste.sql rename to db/changes/10300-newFacility/01-waste.sql diff --git a/db/changes/10300-newFacility/00-waste_addSales.sql b/db/changes/10300-newFacility/02-waste_addSales.sql similarity index 94% rename from db/changes/10300-newFacility/00-waste_addSales.sql rename to db/changes/10300-newFacility/02-waste_addSales.sql index 8e971048d..a01150c4a 100644 --- a/db/changes/10300-newFacility/00-waste_addSales.sql +++ b/db/changes/10300-newFacility/02-waste_addSales.sql @@ -1,6 +1,6 @@ UPDATE `bs`.nightTask t SET t.`procedure` = 'waste_addSales' WHERE t.id = 54; -DROP PROCEDURE`bs`.`waste_Add`; +DROP PROCEDURE IF EXISTS `bs`.`waste_Add`; CREATE DEFINER = root@`%` PROCEDURE `bs`.`waste_addSales`() From 65dc0e3780c15ec3fe17779bf93270ab81c93ff4 Mon Sep 17 00:00:00 2001 From: joan Date: Tue, 6 Apr 2021 13:46:38 +0200 Subject: [PATCH 3/5] 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 000000000..efa988aea --- /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 000000000..2da098ae6 --- /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 000000000..4dd0cab6c --- /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 1f4eed063..1f7f5fdeb 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 a01150c4a..df6db2d2c 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 bc2cee39d..63f8be7b5 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 6fb96c660..4ecd195af 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 000000000..dabad4fc6 --- /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 5f11513e1..9ffe96bf7 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 46e40e412..6166622e5 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 d0275ff29..f6b3bfe29 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 69214c273..035c677f8 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 6c123fc19..7ad985ea8 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 7fd557410..c36039c1a 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 69f880a0a..cc4590e5d 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 4639e7d5b..9af477e82 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 000000000..943c085d0 --- /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 From 6c36ab3905d68b6be0846aafc28e90c0ce12f6f2 Mon Sep 17 00:00:00 2001 From: joan Date: Wed, 7 Apr 2021 10:47:31 +0200 Subject: [PATCH 4/5] Removed back button --- modules/item/front/waste/detail/index.html | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/modules/item/front/waste/detail/index.html b/modules/item/front/waste/detail/index.html index 035c677f8..9d4475b56 100644 --- a/modules/item/front/waste/detail/index.html +++ b/modules/item/front/waste/detail/index.html @@ -8,12 +8,7 @@
-
- - < Back - - - {{detail.family}} ({{detail.buyer}}) -
+
{{detail.family}} ({{detail.buyer}})
From 93399d6de69eae410c2f5216223d7341cb08e547 Mon Sep 17 00:00:00 2001 From: joan Date: Wed, 7 Apr 2021 11:18:44 +0200 Subject: [PATCH 5/5] Updated description --- modules/item/back/methods/item/getWasteByItem.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/item/back/methods/item/getWasteByItem.js b/modules/item/back/methods/item/getWasteByItem.js index 4ecd195af..21a68c359 100644 --- a/modules/item/back/methods/item/getWasteByItem.js +++ b/modules/item/back/methods/item/getWasteByItem.js @@ -1,6 +1,6 @@ module.exports = Self => { Self.remoteMethod('getWasteByItem', { - description: 'Returns the details of losses by worker', + description: 'Returns the details of losses by worker and item', accessType: 'READ', accepts: [ {