diff --git a/db/changes/10140-kings/00-waste_getDetail.sql b/db/changes/10140-kings/00-waste_getDetail.sql
deleted file mode 100644
index 9bf6cf049..000000000
--- a/db/changes/10140-kings/00-waste_getDetail.sql
+++ /dev/null
@@ -1,30 +0,0 @@
-USE `bs`;
-DROP procedure IF EXISTS `waste_getDetail`;
-
-DELIMITER $$
-USE `bs`$$
-CREATE DEFINER=`root`@`%`PROCEDURE `waste_getDetail` ()
-BEGIN
- DECLARE vWeek INT;
- DECLARE vYear INT;
-
- SELECT week, year
- INTO vWeek, vYear
- FROM vn.time
- WHERE dated = CURDATE();
-
- 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$$
-
-DELIMITER ;
-
diff --git a/db/dump/fixtures.sql b/db/dump/fixtures.sql
index d54b28bb7..c27d8a445 100644
--- a/db/dump/fixtures.sql
+++ b/db/dump/fixtures.sql
@@ -1119,6 +1119,19 @@ INSERT INTO `bi`.`claims_ratio`(`id_Cliente`, `Consumo`, `Reclamaciones`, `Ratio
(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`)
+ VALUES
+ ('CharlesXavier', YEAR(CURDATE()), WEEK(CURDATE(), 1), 'Clavel', '1062', '51', '4.8'),
+ ('CharlesXavier', YEAR(CURDATE()), WEEK(CURDATE(), 1), 'Clavel Colombia', '35074', '687', '2.0'),
+ ('CharlesXavier', YEAR(CURDATE()), WEEK(CURDATE(), 1), 'Clavel Mini', '1777', '13', '0.7'),
+ ('CharlesXavier', YEAR(CURDATE()), WEEK(CURDATE(), 1), 'Clavel Short', '9182', '59', '0.6'),
+ ('DavidCharlesHaller', YEAR(CURDATE()), WEEK(CURDATE(), 1), 'Contenedores', '-74', '0', '0.0'),
+ ('DavidCharlesHaller', YEAR(CURDATE()), WEEK(CURDATE(), 1), 'Embalajes', '-7', '0', '0.0'),
+ ('DavidCharlesHaller', YEAR(CURDATE()), WEEK(CURDATE(), 1), 'Portes', '1100', '0', '0.0'),
+ ('HankPym', YEAR(CURDATE()), WEEK(CURDATE(), 1), 'Accesorios Funerarios', '848', '-187', '-22.1'),
+ ('HankPym', YEAR(CURDATE()), WEEK(CURDATE(), 1), 'Accesorios Varios', '186', '0', '0.0'),
+ ('HankPym', YEAR(CURDATE()), WEEK(CURDATE(), 1), 'Adhesivos', '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`,`minPrice`,`producer`,`printedStickers`,`isChecked`,`isIgnored`, `created`)
VALUES
(1, 1, 1, 50, 5000, 4, 1, 1.500, 1.500, 0.000, 1, 1, 1, NULL, 0.00, 99.6, 99.4, 0.00, NULL, 0, 1, 0, DATE_ADD(CURDATE(), INTERVAL -2 MONTH)),
diff --git a/e2e/paths/05-ticket-module/01-sale/01_list_sales.spec.js b/e2e/paths/05-ticket-module/01-sale/01_list_sales.spec.js
index a5f7aa423..a755cd940 100644
--- a/e2e/paths/05-ticket-module/01-sale/01_list_sales.spec.js
+++ b/e2e/paths/05-ticket-module/01-sale/01_list_sales.spec.js
@@ -29,7 +29,7 @@ describe('Ticket List sale path', () => {
const value = await nightmare
.waitToGetProperty(selectors.ticketSales.firstSaleDiscount, 'innerText');
- expect(value).toContain('0 %');
+ expect(value).toContain('0.00%');
});
it('should confirm the first sale contains the total import', async() => {
diff --git a/e2e/paths/05-ticket-module/01-sale/02_edit_sale.spec.js b/e2e/paths/05-ticket-module/01-sale/02_edit_sale.spec.js
index 5a6d6cd62..898a1fe53 100644
--- a/e2e/paths/05-ticket-module/01-sale/02_edit_sale.spec.js
+++ b/e2e/paths/05-ticket-module/01-sale/02_edit_sale.spec.js
@@ -173,10 +173,10 @@ xdescribe('Ticket Edit sale path', () => {
it('should confirm the discount have been updated', async() => {
const result = await nightmare
- .waitForTextInElement(`${selectors.ticketSales.firstSaleDiscount} > span`, '50 %')
+ .waitForTextInElement(`${selectors.ticketSales.firstSaleDiscount} > span`, '50.00%')
.waitToGetProperty(`${selectors.ticketSales.firstSaleDiscount} > span`, 'innerText');
- expect(result).toContain('50 %');
+ expect(result).toContain('50.00%');
});
it('should confirm the total import for that item have been updated', async() => {
diff --git a/front/core/filters/percentage.js b/front/core/filters/percentage.js
index 58e67ffa6..41e3f8288 100644
--- a/front/core/filters/percentage.js
+++ b/front/core/filters/percentage.js
@@ -1,15 +1,22 @@
import ngModule from '../module';
-/**
- * Formats a number multiplying by 100 and adding character %.
- *
- * @return {String} The formated number
- */
-export default function percentage() {
- return function(input) {
+export default function percentage($translate) {
+ function percentage(input, fractionSize = 2) {
if (input == null || input === '')
return null;
- return `${input} %`;
- };
+
+ return new Intl.NumberFormat($translate.use(), {
+ style: 'percent',
+ minimumFractionDigits: fractionSize,
+ maximumFractionDigits: fractionSize
+ }).format(parseFloat(input));
+ }
+
+ percentage.$stateful = true;
+
+ return percentage;
}
+
+percentage.$inject = ['$translate'];
+
ngModule.filter('percentage', percentage);
diff --git a/modules/item/back/methods/item/getWasteDetail.js b/modules/item/back/methods/item/getWasteDetail.js
new file mode 100644
index 000000000..edaebf2f2
--- /dev/null
+++ b/modules/item/back/methods/item/getWasteDetail.js
@@ -0,0 +1,52 @@
+module.exports = Self => {
+ Self.remoteMethod('getWasteDetail', {
+ description: 'Returns the ',
+ accessType: 'READ',
+ accepts: [],
+ returns: {
+ type: ['Object'],
+ root: true
+ },
+ http: {
+ path: `/getWasteDetail`,
+ verb: 'GET'
+ }
+ });
+
+ Self.getWasteDetail = 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(CURDATE()) AND week = WEEK(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/methods/item/specs/getWasteDetail.spec.js b/modules/item/back/methods/item/specs/getWasteDetail.spec.js
new file mode 100644
index 000000000..1874371a0
--- /dev/null
+++ b/modules/item/back/methods/item/specs/getWasteDetail.spec.js
@@ -0,0 +1,23 @@
+const app = require('vn-loopback/server/server');
+
+describe('item getWasteDetail()', () => {
+ it('should check for the waste breakdown for every worker', async() => {
+ let result = await app.models.Item.getWasteDetail();
+
+ const firstBuyer = result[0].buyer;
+ const firstBuyerLines = result[0].lines;
+ const secondBuyer = result[1].buyer;
+ const secondBuyerLines = result[1].lines;
+ const thirdBuyer = result[2].buyer;
+ const thirdBuyerLines = result[2].lines;
+
+ expect(result.length).toEqual(3);
+ expect(firstBuyer).toEqual('CharlesXavier');
+ expect(firstBuyerLines.length).toEqual(4);
+ expect(secondBuyer).toEqual('DavidCharlesHaller');
+ expect(secondBuyerLines.length).toEqual(3);
+
+ expect(thirdBuyer).toEqual('HankPym');
+ expect(thirdBuyerLines.length).toEqual(3);
+ });
+});
diff --git a/modules/item/back/models/item.js b/modules/item/back/models/item.js
index 628bd5a03..6c221e94d 100644
--- a/modules/item/back/models/item.js
+++ b/modules/item/back/models/item.js
@@ -11,6 +11,7 @@ module.exports = Self => {
require('../methods/item/regularize')(Self);
require('../methods/item/getVisibleAvailable')(Self);
require('../methods/item/new')(Self);
+ require('../methods/item/getWasteDetail')(Self);
Self.validatesPresenceOf('originFk', {message: 'Cannot be blank'});
diff --git a/modules/item/front/locale/es.yml b/modules/item/front/locale/es.yml
index c071d2c69..9580fd156 100644
--- a/modules/item/front/locale/es.yml
+++ b/modules/item/front/locale/es.yml
@@ -60,4 +60,5 @@ Barcodes: Códigos de barras
Diary: Histórico
Item diary: Registro de compra-venta
Last entries: Últimas entradas
-Tags: Etiquetas
\ No newline at end of file
+Tags: Etiquetas
+Waste breakdown: Desglose de mermas
\ No newline at end of file
diff --git a/modules/item/front/routes.json b/modules/item/front/routes.json
index 611bba785..a3cf0bee6 100644
--- a/modules/item/front/routes.json
+++ b/modules/item/front/routes.json
@@ -7,7 +7,8 @@
"menus": {
"main": [
{"state": "item.index", "icon": "icon-item"},
- {"state": "item.request", "icon": "pan_tool"}
+ {"state": "item.request", "icon": "pan_tool"},
+ {"state": "item.waste", "icon": "icon-claims"}
],
"card": [
{"state": "item.card.basicData", "icon": "settings"},
@@ -141,11 +142,8 @@
"url" : "/waste",
"state": "item.waste",
"component": "vn-item-waste",
- "description": "Waste",
- "params": {
- "item": "$ctrl.item"
- },
- "acl": ["employee"]
+ "description": "Waste breakdown",
+ "acl": ["buyer"]
}
]
}
\ No newline at end of file
diff --git a/modules/item/front/waste/index.html b/modules/item/front/waste/index.html
index e7ddb25fd..059f82db8 100644
--- a/modules/item/front/waste/index.html
+++ b/modules/item/front/waste/index.html
@@ -1,120 +1,32 @@
{{detail.buyer}}
+ Specify the reasons to deny this request
-