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-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 new file mode 100644 index 000000000..1f7f5fdeb --- /dev/null +++ b/db/changes/10300-newFacility/01-waste.sql @@ -0,0 +1,22 @@ +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; + +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 new file mode 100644 index 000000000..df6db2d2c --- /dev/null +++ b/db/changes/10300-newFacility/02-waste_addSales.sql @@ -0,0 +1,38 @@ +UPDATE `bs`.nightTask t SET t.`procedure` = 'waste_addSales' WHERE t.id = 54; + +DROP PROCEDURE IF EXISTS `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, itemFk + + ) sub + ORDER BY mermas DESC; + +END; + + diff --git a/db/dump/fixtures.sql b/db/dump/fixtures.sql index a9ebb9e29..b215d0edd 100644 --- a/db/dump/fixtures.sql +++ b/db/dump/fixtures.sql @@ -1300,18 +1300,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/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 new file mode 100644 index 000000000..21a68c359 --- /dev/null +++ b/modules/item/back/methods/item/getWasteByItem.js @@ -0,0 +1,69 @@ +module.exports = Self => { + Self.remoteMethod('getWasteByItem', { + description: 'Returns the details of losses by worker and item', + accessType: 'READ', + 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 + }, + http: { + path: `/getWasteByItem`, + verb: 'GET' + } + }); + + 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 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 family, percentage DESC`, [buyer, family]); + + 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, + family: waste.family, + lines: [] + }; + details.push(buyerDetail); + } + + buyerDetail.lines.push(waste); + } + + return details; + }; +}; diff --git a/modules/item/back/methods/item/getWasteDetail.js b/modules/item/back/methods/item/getWasteByWorker.js similarity index 53% rename from modules/item/back/methods/item/getWasteDetail.js rename to modules/item/back/methods/item/getWasteByWorker.js index b8b55b275..032472696 100644 --- a/modules/item/back/methods/item/getWasteDetail.js +++ b/modules/item/back/methods/item/getWasteByWorker.js @@ -1,5 +1,5 @@ module.exports = Self => { - Self.remoteMethod('getWasteDetail', { + Self.remoteMethod('getWasteByWorker', { description: 'Returns the details of losses by worker', accessType: 'READ', accepts: [], @@ -8,13 +8,25 @@ module.exports = Self => { root: true }, http: { - path: `/getWasteDetail`, + path: `/getWasteByWorker`, verb: 'GET' } }); - Self.getWasteDetail = async() => { - const [wastes] = await Self.rawSql(`CALL bs.weekWaste_getDetail()`); + 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 = []; 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/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/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 4b4be3c3d..f6b3bfe29 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?buyer&family", + "state": "item.waste.detail", + "component": "vn-item-waste-detail", + "description": "Waste breakdown by item", + "acl": ["buyer"] + }, { "url" : "/fixed-price?q", "state": "item.fixedPrice", diff --git a/modules/item/front/waste/detail/index.html b/modules/item/front/waste/detail/index.html new file mode 100644 index 000000000..9d4475b56 --- /dev/null +++ b/modules/item/front/waste/detail/index.html @@ -0,0 +1,42 @@ + + + + +
+ +
{{detail.family}} ({{detail.buyer}})
+
+ + + + Item + Percentage + Dwindle + Total + + + + + + + {{::waste.itemFk}} + + + {{::(waste.percentage / 100) | percentage: 2}} + {{::waste.dwindle | currency: 'EUR'}} + {{::waste.total | currency: 'EUR'}} + + + +
+
+
+ + \ No newline at end of file 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.html b/modules/item/front/waste/index/index.html similarity index 80% rename from modules/item/front/waste/index.html rename to modules/item/front/waste/index/index.html index d363f0ce0..7ad985ea8 100644 --- a/modules/item/front/waste/index.html +++ b/modules/item/front/waste/index/index.html @@ -1,13 +1,14 @@ +
-
{{detail.buyer}}
+
{{detail.buyer}}
@@ -19,7 +20,8 @@ - + {{::waste.family}} {{::(waste.percentage / 100) | percentage: 2}} {{::waste.dwindle | 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 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