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 @@
+
+
+
+
+
+
+
+
+
+ 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 @@
+
@@ -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