From a103c8d7fc6f677521a68d71d8a3808332c8cb19 Mon Sep 17 00:00:00 2001 From: joan Date: Fri, 21 May 2021 08:49:32 +0200 Subject: [PATCH 1/4] 2891 - Get ticket problems for every sale --- .../10320-monitors/00-ticket_getProblems.sql | 180 ++++++++++++++++++ .../ticket/back/methods/ticket/getSales.js | 97 ++++++++-- modules/ticket/front/sale/index.html | 13 ++ 3 files changed, 269 insertions(+), 21 deletions(-) create mode 100644 db/changes/10320-monitors/00-ticket_getProblems.sql diff --git a/db/changes/10320-monitors/00-ticket_getProblems.sql b/db/changes/10320-monitors/00-ticket_getProblems.sql new file mode 100644 index 000000000..48a3df419 --- /dev/null +++ b/db/changes/10320-monitors/00-ticket_getProblems.sql @@ -0,0 +1,180 @@ +DROP PROCEDURE IF EXISTS `vn`.`ticket_getProblems`; + +DELIMITER $$ +$$ +CREATE + DEFINER = root@`%` PROCEDURE `vn`.`ticket_getProblems`(IN vTicketFk INT, IN vIsTodayRelative TINYINT(1)) +BEGIN + DECLARE vWarehouse INT; + DECLARE vDate DATE; + DECLARE vAvailableCache INT; + DECLARE vDone INT DEFAULT 0; + + DECLARE vCursor CURSOR FOR + SELECT DISTINCT tt.warehouseFk, IF(vIsTodayRelative, CURDATE(), date(tt.shipped)) + FROM tmp.ticket_getProblems tt + WHERE DATE(tt.shipped) BETWEEN CURDATE() + AND TIMESTAMPADD(DAY, IF(vIsTodayRelative, 9.9, 1.9), CURDATE()); + + DECLARE CONTINUE HANDLER FOR NOT FOUND SET vDone = 1; + + IF NOT ISNULL(vTicketFk) THEN + DROP TEMPORARY TABLE IF EXISTS tmp.ticket_getProblems; + CREATE TEMPORARY TABLE tmp.ticket_getProblems + (INDEX (ticketFk)) + ENGINE = MEMORY + SELECT t.id ticketFk, t.clientFk, t.warehouseFk, t.shipped + FROM ticket t + WHERE t.id = vTicketFk; + END IF; + + DROP TEMPORARY TABLE IF EXISTS tmp.ticket_problems; + CREATE TEMPORARY TABLE tmp.ticket_problems ( + ticketFk INT(11) PRIMARY KEY, + saleFk INT(11), + isFreezed INTEGER(1) DEFAULT 0, + risk DECIMAL(10,2) DEFAULT 0, + hasTicketRequest INTEGER(1) DEFAULT 0, + isAvailable INTEGER(1) DEFAULT 1, + itemShortage VARCHAR(250), + isTaxDataChecked INTEGER(1) DEFAULT 1, + itemDelay VARCHAR(250) + ) ENGINE = MEMORY; + + DROP TEMPORARY TABLE IF EXISTS tmp.ticket_list; + CREATE TEMPORARY TABLE tmp.ticket_list + (PRIMARY KEY (ticketFk)) + ENGINE = MEMORY + SELECT tp.ticketFk, c.id clientFk + FROM tmp.ticket_getProblems tp + JOIN vn.client c ON c.id = tp.clientFk; + + INSERT INTO tmp.ticket_problems(ticketFk, isFreezed) + SELECT DISTINCT tl.ticketFk, 1 + FROM tmp.ticket_list tl + JOIN vn.client c ON c.id = tl.clientFk + WHERE c.isFreezed; + + DROP TEMPORARY TABLE IF EXISTS tmp.clientGetDebt; + CREATE TEMPORARY TABLE tmp.clientGetDebt + (PRIMARY KEY (clientFk)) + ENGINE = MEMORY + SELECT DISTINCT clientFk + FROM tmp.ticket_list; + + CALL clientGetDebt(CURDATE()); + + INSERT INTO tmp.ticket_problems(ticketFk, risk) + SELECT DISTINCT tl.ticketFk, r.risk + FROM tmp.ticket_list tl + JOIN vn.ticket t ON t.id = tl.ticketFk + JOIN vn.agencyMode a ON t.agencyModeFk = a.id + JOIN tmp.risk r ON r.clientFk = t.clientFk + JOIN vn.client c ON c.id = t.clientFk + JOIN vn.clientConfig cc + WHERE r.risk - cc.riskTolerance > c.credit + 10 + AND a.isRiskFree = FALSE + ON DUPLICATE KEY UPDATE + risk = r.risk; + + INSERT INTO tmp.ticket_problems(ticketFk, hasTicketRequest, saleFk) + SELECT DISTINCT tl.ticketFk, 1, tr.saleFk + FROM tmp.ticket_list tl + JOIN vn.ticketRequest tr ON tr.ticketFk = tl.ticketFk + WHERE tr.isOK IS NULL AND tr.saleFk IS NOT NULL + ON DUPLICATE KEY UPDATE + hasTicketRequest = 1, saleFk = tr.saleFk; + + OPEN vCursor; + + WHILE NOT vDone + DO + FETCH vCursor INTO vWarehouse, vDate; + + CALL cache.available_refresh(vAvailableCache, FALSE, vWarehouse, vDate); + + INSERT INTO tmp.ticket_problems(ticketFk, isAvailable, saleFk) + SELECT tl.ticketFk, 0, s.id + FROM tmp.ticket_list tl + JOIN vn.ticket t ON t.id = tl.ticketFk + JOIN vn.sale s ON s.ticketFk = t.id + JOIN vn.item i ON i.id = s.itemFk + JOIN vn.itemType it on it.id = i.typeFk + LEFT JOIN cache.available av ON av.item_id = i.id + AND av.calc_id = vAvailableCache + WHERE date(t.shipped) = vDate + AND it.categoryFk != 6 + AND IFNULL(av.available, 0) < 0 + AND s.isPicked = FALSE + AND NOT i.generic + AND vWarehouse = t.warehouseFk + GROUP BY tl.ticketFk + ON DUPLICATE KEY UPDATE + isAvailable = 0, saleFk = s.id; + + INSERT INTO tmp.ticket_problems(ticketFk, itemShortage, saleFk) + SELECT ticketFk, problem, saleFk + FROM ( + SELECT tl.ticketFk, CONCAT('F: ',GROUP_CONCAT(i.id, ' ', i.longName, ' ')) problem, s.id AS saleFk + FROM tmp.ticket_list tl + JOIN vn.ticket t ON t.id = tl.ticketFk + JOIN vn.sale s ON s.ticketFk = t.id + JOIN vn.item i ON i.id = s.itemFk + JOIN vn.itemType it on it.id = i.typeFk + LEFT JOIN vn.itemShelvingStock_byWarehouse issw ON issw.itemFk = i.id AND issw.warehouseFk = t.warehouseFk + LEFT JOIN cache.available av ON av.item_id = i.id AND av.calc_id = vAvailableCache + WHERE IFNULL(av.available, 0) < 0 + AND s.quantity > IFNULL(issw.visible, 0) + AND s.quantity > 0 + AND s.isPicked = FALSE + AND s.reserved = FALSE + AND it.categoryFk != 6 + AND IF(vIsTodayRelative, TRUE, date(t.shipped) = vDate) + AND NOT i.generic + AND CURDATE() = vDate + AND t.warehouseFk = vWarehouse + GROUP BY tl.ticketFk) sub + ON DUPLICATE KEY UPDATE + itemShortage = sub.problem, saleFk = sub.saleFk; + + INSERT INTO tmp.ticket_problems(ticketFk, itemDelay, saleFk) + SELECT ticketFk, problem, saleFk + FROM ( + SELECT tl.ticketFk, GROUP_CONCAT('I: ',i.id, ' ', i.longName, ' ') problem, s.id AS saleFk + FROM tmp.ticket_list tl + JOIN vn.ticket t ON t.id = tl.ticketFk + JOIN vn.sale s ON s.ticketFk = t.id + JOIN vn.item i ON i.id = s.itemFk + JOIN vn.itemType it on it.id = i.typeFk + LEFT JOIN vn.itemShelvingStock_byWarehouse issw ON issw.itemFk = i.id AND issw.warehouseFk = t.warehouseFk + WHERE s.quantity > IFNULL(issw.visible, 0) + AND s.quantity > 0 + AND s.isPicked = FALSE + AND s.reserved = FALSE + AND it.categoryFk != 6 + AND IF(vIsTodayRelative, TRUE, date(t.shipped) = vDate) + AND NOT i.generic + AND CURDATE() = vDate + AND t.warehouseFk = vWarehouse + GROUP BY tl.ticketFk) sub + ON DUPLICATE KEY UPDATE + itemDelay = sub.problem, saleFk = sub.saleFk; + END WHILE; + + CLOSE vCursor; + + INSERT INTO tmp.ticket_problems(ticketFk, isTaxDataChecked) + SELECT DISTINCT tl.ticketFk, FALSE + FROM tmp.ticket_list tl + JOIN vn.client c ON c.id = tl.clientFk + WHERE c.isTaxDataChecked= FALSE + ON DUPLICATE KEY UPDATE + isTaxDataChecked = FALSE; + + DROP TEMPORARY TABLE + tmp.clientGetDebt, + tmp.ticket_list; + + SELECT * FROM tmp.ticket_problems; +END;;$$ +DELIMITER ; diff --git a/modules/ticket/back/methods/ticket/getSales.js b/modules/ticket/back/methods/ticket/getSales.js index d522ffe98..59bbd5bd4 100644 --- a/modules/ticket/back/methods/ticket/getSales.js +++ b/modules/ticket/back/methods/ticket/getSales.js @@ -1,12 +1,13 @@ + module.exports = Self => { Self.remoteMethod('getSales', { description: 'New filter', accessType: 'READ', accepts: [{ - arg: 'ticketFk', + arg: 'id', type: 'number', required: true, - description: 'ticket id', + description: 'The ticket id', http: {source: 'path'} }], returns: { @@ -14,13 +15,81 @@ module.exports = Self => { root: true }, http: { - path: `/:ticketFk/getSales`, + path: `/:id/getSales`, verb: 'get' } }); - Self.getSales = async ticketFk => { - let query = `CALL vn.ticketGetVisibleAvailable(?)`; + Self.getSales = async id => { + // implementar transacciones + const models = Self.app.models; + const sales = await models.Sale.find({ + include: { + relation: 'item', + scope: { + fields: [ + 'id', + 'name', + 'tag5', + 'value5', + 'tag6', + 'value6', + 'tag7', + 'value7', + 'tag8', + 'value8', + 'tag9', + 'value9', + 'tag10', + 'value10' + ] + } + }, + where: {ticketFk: id} + }); + + // Get items available + const query = `CALL ticketGetVisibleAvailable(?)`; + const [salesAvailable] = await Self.rawSql(query, [id]); + + const itemAvailable = new Map(); + for (let sale of salesAvailable) + itemAvailable.set(sale.itemFk, sale.available); + + // Get claimed sales + const saleIds = sales.map(sale => sale.id); + const claims = await models.ClaimBeginning.find({ + fields: ['claimFk', 'saleFk'], + where: {saleFk: {inq: saleIds}}, + }); + + const claimedSales = new Map(); + for (let claim of claims) + claimedSales.set(claim.saleFk, claim); + + // Get problems + const problemsQuery = `CALL ticket_getProblems(?, FALSE)`; + const [problems] = await Self.rawSql(problemsQuery, [id]); + + const saleProblems = new Map(); + for (let problem of problems) + saleProblems.set(problem.saleFk, problem); + + console.log(problems); + + for (let sale of sales) { + const problems = saleProblems.get(sale.id); + sale.available = itemAvailable.get(sale.itemFk); + sale.claim = claimedSales.get(sale.id); + if (problems) { + sale.isAvailable = problems.isAvailable; + sale.isFreezed = problems.isFreezed; + } + } + + return sales; + + /* let query = `CALL vn.ticketGetVisibleAvailable(?)`; let [lines] = await Self.rawSql(query, [ticketFk]); let ids = []; let salesIds = []; @@ -31,21 +100,7 @@ module.exports = Self => { } let filter = { - fields: [ - 'id', - 'name', - 'tag5', - 'value5', - 'tag6', - 'value6', - 'tag7', - 'value7', - 'tag8', - 'value8', - 'tag9', - 'value9', - 'tag10', - 'value10'], + fields: ['id', 'name', 'tag5', 'value5', 'tag6', 'value6', 'tag7', 'value7', 'tag8', 'value8', 'tag9', 'value9', 'tag10', 'value10'], where: {id: {inq: ids}} }; let items = await Self.app.models.Item.find(filter); @@ -68,6 +123,6 @@ module.exports = Self => { line.item = map[line.itemFk]; line.claim = claimMap[line.id]; } - return lines; + return lines; */ }; }; diff --git a/modules/ticket/front/sale/index.html b/modules/ticket/front/sale/index.html index 5bba457ca..419369e02 100644 --- a/modules/ticket/front/sale/index.html +++ b/modules/ticket/front/sale/index.html @@ -91,6 +91,19 @@ icon="icon-reserve" vn-tooltip="{{::$ctrl.$t('Reserved')}}"> + + + + Date: Tue, 25 May 2021 10:01:18 +0200 Subject: [PATCH 2/4] 2891 - Show problems on tickets sales --- .../10320-monitors/00-sale_getProblems.sql | 186 ++++++++++++++++++ .../00-sale_getProblemsByTicket.sql | 24 +++ .../10320-monitors/00-ticket_getProblems.sql | 185 ++--------------- .../core/components/scroll-up/scroll-up.html | 4 +- front/core/components/scroll-up/style.scss | 10 +- .../back/methods/sales-monitor/salesFilter.js | 16 +- .../monitor/front/index/tickets/index.html | 9 +- modules/ticket/back/methods/ticket/filter.js | 16 +- .../ticket/back/methods/ticket/getSales.js | 5 +- modules/ticket/front/index/index.html | 7 + modules/ticket/front/sale/index.html | 19 +- modules/ticket/front/summary/index.html | 36 +++- 12 files changed, 313 insertions(+), 204 deletions(-) create mode 100644 db/changes/10320-monitors/00-sale_getProblems.sql create mode 100644 db/changes/10320-monitors/00-sale_getProblemsByTicket.sql diff --git a/db/changes/10320-monitors/00-sale_getProblems.sql b/db/changes/10320-monitors/00-sale_getProblems.sql new file mode 100644 index 000000000..23f433aec --- /dev/null +++ b/db/changes/10320-monitors/00-sale_getProblems.sql @@ -0,0 +1,186 @@ +DROP PROCEDURE IF EXISTS `vn`.`sale_getProblems`; + +DELIMITER $$ +$$ +CREATE + DEFINER = root@`%` PROCEDURE `vn`.`sale_getProblems`(IN vIsTodayRelative TINYINT(1)) +BEGIN + DECLARE vWarehouse INT; + DECLARE vDate DATE; + DECLARE vAvailableCache INT; + DECLARE vDone INT DEFAULT 0; + DECLARE vComponentCount INT; + + DECLARE vCursor CURSOR FOR + SELECT DISTINCT tt.warehouseFk, IF(vIsTodayRelative, CURDATE(), date(tt.shipped)) + FROM tmp.sale_getProblems tt + WHERE DATE(tt.shipped) BETWEEN CURDATE() + AND TIMESTAMPADD(DAY, IF(vIsTodayRelative, 9.9, 1.9), CURDATE()); + + DECLARE CONTINUE HANDLER FOR NOT FOUND SET vDone = 1; + + DROP TEMPORARY TABLE IF EXISTS tmp.sale_problems; + CREATE TEMPORARY TABLE tmp.sale_problems ( + ticketFk INT(11), + saleFk INT(11), + isFreezed INTEGER(1) DEFAULT 0, + risk DECIMAL(10,2) DEFAULT 0, + hasTicketRequest INTEGER(1) DEFAULT 0, + isAvailable INTEGER(1) DEFAULT 1, + itemShortage VARCHAR(250), + isTaxDataChecked INTEGER(1) DEFAULT 1, + itemDelay VARCHAR(250), + hasComponentLack INTEGER(1), + PRIMARY KEY (ticketFk, saleFk) + ) ENGINE = MEMORY; + + DROP TEMPORARY TABLE IF EXISTS tmp.ticket_list; + CREATE TEMPORARY TABLE tmp.ticket_list + (PRIMARY KEY (ticketFk)) + ENGINE = MEMORY + SELECT tp.ticketFk, c.id clientFk + FROM tmp.sale_getProblems tp + JOIN vn.client c ON c.id = tp.clientFk; + + SELECT COUNT(*) INTO vComponentCount + FROM vn.component c + WHERE c.isRequired; + + INSERT INTO tmp.sale_problems(ticketFk, hasComponentLack, saleFk) + SELECT tl.ticketFk, (COUNT(DISTINCT s.id) * vComponentCount > COUNT(c.id)), s.id + FROM tmp.ticket_list tl + JOIN vn.sale s ON s.ticketFk = tl.ticketFk + LEFT JOIN vn.saleComponent sc ON sc.saleFk = s.id + LEFT JOIN vn.component c ON c.id = sc.componentFk AND c.isRequired + GROUP BY tl.ticketFk, s.id; + + INSERT INTO tmp.sale_problems(ticketFk, isFreezed) + SELECT DISTINCT tl.ticketFk, TRUE + FROM tmp.ticket_list tl + JOIN vn.client c ON c.id = tl.clientFk + WHERE c.isFreezed + ON DUPLICATE KEY UPDATE + isFreezed = c.isFreezed; + + DROP TEMPORARY TABLE IF EXISTS tmp.clientGetDebt; + CREATE TEMPORARY TABLE tmp.clientGetDebt + (PRIMARY KEY (clientFk)) + ENGINE = MEMORY + SELECT DISTINCT clientFk + FROM tmp.ticket_list; + + CALL clientGetDebt(CURDATE()); + + INSERT INTO tmp.sale_problems(ticketFk, risk) + SELECT DISTINCT tl.ticketFk, r.risk + FROM tmp.ticket_list tl + JOIN vn.ticket t ON t.id = tl.ticketFk + JOIN vn.agencyMode a ON t.agencyModeFk = a.id + JOIN tmp.risk r ON r.clientFk = t.clientFk + JOIN vn.client c ON c.id = t.clientFk + JOIN vn.clientConfig cc + WHERE r.risk - cc.riskTolerance > c.credit + 10 + AND a.isRiskFree = FALSE + ON DUPLICATE KEY UPDATE + risk = r.risk; + + INSERT INTO tmp.sale_problems(ticketFk, hasTicketRequest) + SELECT DISTINCT tl.ticketFk, TRUE + FROM tmp.ticket_list tl + JOIN vn.ticketRequest tr ON tr.ticketFk = tl.ticketFk + WHERE tr.isOK IS NULL + ON DUPLICATE KEY UPDATE + hasTicketRequest = TRUE; + + OPEN vCursor; + + WHILE NOT vDone + DO + FETCH vCursor INTO vWarehouse, vDate; + + CALL cache.available_refresh(vAvailableCache, FALSE, vWarehouse, vDate); + + INSERT INTO tmp.sale_problems(ticketFk, isAvailable, saleFk) + SELECT tl.ticketFk, FALSE, s.id + FROM tmp.ticket_list tl + JOIN vn.ticket t ON t.id = tl.ticketFk + JOIN vn.sale s ON s.ticketFk = t.id + JOIN vn.item i ON i.id = s.itemFk + JOIN vn.itemType it on it.id = i.typeFk + LEFT JOIN cache.available av ON av.item_id = i.id + AND av.calc_id = vAvailableCache + WHERE date(t.shipped) = vDate + AND it.categoryFk != 6 + AND IFNULL(av.available, 0) < 0 + AND s.isPicked = FALSE + AND NOT i.generic + AND vWarehouse = t.warehouseFk + GROUP BY tl.ticketFk + ON DUPLICATE KEY UPDATE + isAvailable = FALSE, saleFk = VALUE(saleFk); + + INSERT INTO tmp.sale_problems(ticketFk, itemShortage, saleFk) + SELECT ticketFk, problem, saleFk + FROM ( + SELECT tl.ticketFk, CONCAT('F: ',GROUP_CONCAT(i.id, ' ', i.longName, ' ')) problem, s.id AS saleFk + FROM tmp.ticket_list tl + JOIN vn.ticket t ON t.id = tl.ticketFk + JOIN vn.sale s ON s.ticketFk = t.id + JOIN vn.item i ON i.id = s.itemFk + JOIN vn.itemType it on it.id = i.typeFk + LEFT JOIN vn.itemShelvingStock_byWarehouse issw ON issw.itemFk = i.id AND issw.warehouseFk = t.warehouseFk + LEFT JOIN cache.available av ON av.item_id = i.id AND av.calc_id = vAvailableCache + WHERE IFNULL(av.available, 0) < 0 + AND s.quantity > IFNULL(issw.visible, 0) + AND s.quantity > 0 + AND s.isPicked = FALSE + AND s.reserved = FALSE + AND it.categoryFk != 6 + AND IF(vIsTodayRelative, TRUE, date(t.shipped) = vDate) + AND NOT i.generic + AND CURDATE() = vDate + AND t.warehouseFk = vWarehouse + GROUP BY tl.ticketFk) sub + ON DUPLICATE KEY UPDATE + itemShortage = sub.problem, saleFk = sub.saleFk; + + INSERT INTO tmp.sale_problems(ticketFk, itemDelay, saleFk) + SELECT ticketFk, problem, saleFk + FROM ( + SELECT tl.ticketFk, GROUP_CONCAT('I: ',i.id, ' ', i.longName, ' ') problem, s.id AS saleFk + FROM tmp.ticket_list tl + JOIN vn.ticket t ON t.id = tl.ticketFk + JOIN vn.sale s ON s.ticketFk = t.id + JOIN vn.item i ON i.id = s.itemFk + JOIN vn.itemType it on it.id = i.typeFk + LEFT JOIN vn.itemShelvingStock_byWarehouse issw ON issw.itemFk = i.id AND issw.warehouseFk = t.warehouseFk + WHERE s.quantity > IFNULL(issw.visible, 0) + AND s.quantity > 0 + AND s.isPicked = FALSE + AND s.reserved = FALSE + AND it.categoryFk != 6 + AND IF(vIsTodayRelative, TRUE, date(t.shipped) = vDate) + AND NOT i.generic + AND CURDATE() = vDate + AND t.warehouseFk = vWarehouse + GROUP BY tl.ticketFk) sub + ON DUPLICATE KEY UPDATE + itemDelay = sub.problem, saleFk = sub.saleFk; + END WHILE; + + CLOSE vCursor; + + INSERT INTO tmp.sale_problems(ticketFk, isTaxDataChecked) + SELECT DISTINCT tl.ticketFk, FALSE + FROM tmp.ticket_list tl + JOIN vn.client c ON c.id = tl.clientFk + WHERE c.isTaxDataChecked = FALSE + ON DUPLICATE KEY UPDATE + isTaxDataChecked = FALSE; + + DROP TEMPORARY TABLE + tmp.clientGetDebt, + tmp.ticket_list; +END;;$$ +DELIMITER ; + diff --git a/db/changes/10320-monitors/00-sale_getProblemsByTicket.sql b/db/changes/10320-monitors/00-sale_getProblemsByTicket.sql new file mode 100644 index 000000000..75ece20de --- /dev/null +++ b/db/changes/10320-monitors/00-sale_getProblemsByTicket.sql @@ -0,0 +1,24 @@ +DROP PROCEDURE IF EXISTS `vn`.`sale_getProblemsByTicket`; + +DELIMITER $$ +$$ +CREATE + DEFINER = root@`%` PROCEDURE `vn`.`sale_getProblemsByTicket`(IN vTicketFk INT, IN vIsTodayRelative TINYINT(1)) +BEGIN + DROP TEMPORARY TABLE IF EXISTS tmp.sale_getProblems; + CREATE TEMPORARY TABLE tmp.sale_getProblems + (INDEX (ticketFk)) + ENGINE = MEMORY + SELECT t.id ticketFk, t.clientFk, t.warehouseFk, t.shipped + FROM ticket t + WHERE t.id = vTicketFk; + + CALL sale_getProblems(vIsTodayRelative); + + SELECT * FROM tmp.sale_problems; + + DROP TEMPORARY TABLE + tmp.sale_getProblems, + tmp.sale_problems; +END;;$$ +DELIMITER ; diff --git a/db/changes/10320-monitors/00-ticket_getProblems.sql b/db/changes/10320-monitors/00-ticket_getProblems.sql index 48a3df419..9bf38c401 100644 --- a/db/changes/10320-monitors/00-ticket_getProblems.sql +++ b/db/changes/10320-monitors/00-ticket_getProblems.sql @@ -3,178 +3,27 @@ DROP PROCEDURE IF EXISTS `vn`.`ticket_getProblems`; DELIMITER $$ $$ CREATE - DEFINER = root@`%` PROCEDURE `vn`.`ticket_getProblems`(IN vTicketFk INT, IN vIsTodayRelative TINYINT(1)) + DEFINER = root@`%` PROCEDURE `vn`.`ticket_getProblems`(IN vIsTodayRelative TINYINT(1)) BEGIN - DECLARE vWarehouse INT; - DECLARE vDate DATE; - DECLARE vAvailableCache INT; - DECLARE vDone INT DEFAULT 0; - - DECLARE vCursor CURSOR FOR - SELECT DISTINCT tt.warehouseFk, IF(vIsTodayRelative, CURDATE(), date(tt.shipped)) - FROM tmp.ticket_getProblems tt - WHERE DATE(tt.shipped) BETWEEN CURDATE() - AND TIMESTAMPADD(DAY, IF(vIsTodayRelative, 9.9, 1.9), CURDATE()); - - DECLARE CONTINUE HANDLER FOR NOT FOUND SET vDone = 1; - - IF NOT ISNULL(vTicketFk) THEN - DROP TEMPORARY TABLE IF EXISTS tmp.ticket_getProblems; - CREATE TEMPORARY TABLE tmp.ticket_getProblems - (INDEX (ticketFk)) - ENGINE = MEMORY - SELECT t.id ticketFk, t.clientFk, t.warehouseFk, t.shipped - FROM ticket t - WHERE t.id = vTicketFk; - END IF; + CALL sale_getProblems(vIsTodayRelative); DROP TEMPORARY TABLE IF EXISTS tmp.ticket_problems; - CREATE TEMPORARY TABLE tmp.ticket_problems ( - ticketFk INT(11) PRIMARY KEY, - saleFk INT(11), - isFreezed INTEGER(1) DEFAULT 0, - risk DECIMAL(10,2) DEFAULT 0, - hasTicketRequest INTEGER(1) DEFAULT 0, - isAvailable INTEGER(1) DEFAULT 1, - itemShortage VARCHAR(250), - isTaxDataChecked INTEGER(1) DEFAULT 1, - itemDelay VARCHAR(250) - ) ENGINE = MEMORY; - - DROP TEMPORARY TABLE IF EXISTS tmp.ticket_list; - CREATE TEMPORARY TABLE tmp.ticket_list - (PRIMARY KEY (ticketFk)) - ENGINE = MEMORY - SELECT tp.ticketFk, c.id clientFk - FROM tmp.ticket_getProblems tp - JOIN vn.client c ON c.id = tp.clientFk; - - INSERT INTO tmp.ticket_problems(ticketFk, isFreezed) - SELECT DISTINCT tl.ticketFk, 1 - FROM tmp.ticket_list tl - JOIN vn.client c ON c.id = tl.clientFk - WHERE c.isFreezed; - - DROP TEMPORARY TABLE IF EXISTS tmp.clientGetDebt; - CREATE TEMPORARY TABLE tmp.clientGetDebt - (PRIMARY KEY (clientFk)) - ENGINE = MEMORY - SELECT DISTINCT clientFk - FROM tmp.ticket_list; - - CALL clientGetDebt(CURDATE()); - - INSERT INTO tmp.ticket_problems(ticketFk, risk) - SELECT DISTINCT tl.ticketFk, r.risk - FROM tmp.ticket_list tl - JOIN vn.ticket t ON t.id = tl.ticketFk - JOIN vn.agencyMode a ON t.agencyModeFk = a.id - JOIN tmp.risk r ON r.clientFk = t.clientFk - JOIN vn.client c ON c.id = t.clientFk - JOIN vn.clientConfig cc - WHERE r.risk - cc.riskTolerance > c.credit + 10 - AND a.isRiskFree = FALSE - ON DUPLICATE KEY UPDATE - risk = r.risk; - - INSERT INTO tmp.ticket_problems(ticketFk, hasTicketRequest, saleFk) - SELECT DISTINCT tl.ticketFk, 1, tr.saleFk - FROM tmp.ticket_list tl - JOIN vn.ticketRequest tr ON tr.ticketFk = tl.ticketFk - WHERE tr.isOK IS NULL AND tr.saleFk IS NOT NULL - ON DUPLICATE KEY UPDATE - hasTicketRequest = 1, saleFk = tr.saleFk; - - OPEN vCursor; - - WHILE NOT vDone - DO - FETCH vCursor INTO vWarehouse, vDate; - - CALL cache.available_refresh(vAvailableCache, FALSE, vWarehouse, vDate); - - INSERT INTO tmp.ticket_problems(ticketFk, isAvailable, saleFk) - SELECT tl.ticketFk, 0, s.id - FROM tmp.ticket_list tl - JOIN vn.ticket t ON t.id = tl.ticketFk - JOIN vn.sale s ON s.ticketFk = t.id - JOIN vn.item i ON i.id = s.itemFk - JOIN vn.itemType it on it.id = i.typeFk - LEFT JOIN cache.available av ON av.item_id = i.id - AND av.calc_id = vAvailableCache - WHERE date(t.shipped) = vDate - AND it.categoryFk != 6 - AND IFNULL(av.available, 0) < 0 - AND s.isPicked = FALSE - AND NOT i.generic - AND vWarehouse = t.warehouseFk - GROUP BY tl.ticketFk - ON DUPLICATE KEY UPDATE - isAvailable = 0, saleFk = s.id; - - INSERT INTO tmp.ticket_problems(ticketFk, itemShortage, saleFk) - SELECT ticketFk, problem, saleFk - FROM ( - SELECT tl.ticketFk, CONCAT('F: ',GROUP_CONCAT(i.id, ' ', i.longName, ' ')) problem, s.id AS saleFk - FROM tmp.ticket_list tl - JOIN vn.ticket t ON t.id = tl.ticketFk - JOIN vn.sale s ON s.ticketFk = t.id - JOIN vn.item i ON i.id = s.itemFk - JOIN vn.itemType it on it.id = i.typeFk - LEFT JOIN vn.itemShelvingStock_byWarehouse issw ON issw.itemFk = i.id AND issw.warehouseFk = t.warehouseFk - LEFT JOIN cache.available av ON av.item_id = i.id AND av.calc_id = vAvailableCache - WHERE IFNULL(av.available, 0) < 0 - AND s.quantity > IFNULL(issw.visible, 0) - AND s.quantity > 0 - AND s.isPicked = FALSE - AND s.reserved = FALSE - AND it.categoryFk != 6 - AND IF(vIsTodayRelative, TRUE, date(t.shipped) = vDate) - AND NOT i.generic - AND CURDATE() = vDate - AND t.warehouseFk = vWarehouse - GROUP BY tl.ticketFk) sub - ON DUPLICATE KEY UPDATE - itemShortage = sub.problem, saleFk = sub.saleFk; - - INSERT INTO tmp.ticket_problems(ticketFk, itemDelay, saleFk) - SELECT ticketFk, problem, saleFk - FROM ( - SELECT tl.ticketFk, GROUP_CONCAT('I: ',i.id, ' ', i.longName, ' ') problem, s.id AS saleFk - FROM tmp.ticket_list tl - JOIN vn.ticket t ON t.id = tl.ticketFk - JOIN vn.sale s ON s.ticketFk = t.id - JOIN vn.item i ON i.id = s.itemFk - JOIN vn.itemType it on it.id = i.typeFk - LEFT JOIN vn.itemShelvingStock_byWarehouse issw ON issw.itemFk = i.id AND issw.warehouseFk = t.warehouseFk - WHERE s.quantity > IFNULL(issw.visible, 0) - AND s.quantity > 0 - AND s.isPicked = FALSE - AND s.reserved = FALSE - AND it.categoryFk != 6 - AND IF(vIsTodayRelative, TRUE, date(t.shipped) = vDate) - AND NOT i.generic - AND CURDATE() = vDate - AND t.warehouseFk = vWarehouse - GROUP BY tl.ticketFk) sub - ON DUPLICATE KEY UPDATE - itemDelay = sub.problem, saleFk = sub.saleFk; - END WHILE; - - CLOSE vCursor; - - INSERT INTO tmp.ticket_problems(ticketFk, isTaxDataChecked) - SELECT DISTINCT tl.ticketFk, FALSE - FROM tmp.ticket_list tl - JOIN vn.client c ON c.id = tl.clientFk - WHERE c.isTaxDataChecked= FALSE - ON DUPLICATE KEY UPDATE - isTaxDataChecked = FALSE; + CREATE TEMPORARY TABLE tmp.ticket_problems + (INDEX (ticketFk)) + ENGINE = MEMORY + SELECT + ticketFk, + MAX(p.isFreezed) AS isFreezed, + MAX(p.risk) AS risk, + MAX(p.hasTicketRequest) AS hasTicketRequest, + MIN(p.isAvailable) AS isAvailable, + MAX(p.itemShortage) AS itemShortage, + MIN(p.isTaxDataChecked) AS isTaxDataChecked, + MAX(p.hasComponentLack) AS hasComponentLack + FROM tmp.sale_problems p + GROUP BY ticketFk; DROP TEMPORARY TABLE - tmp.clientGetDebt, - tmp.ticket_list; - - SELECT * FROM tmp.ticket_problems; + tmp.sale_problems; END;;$$ DELIMITER ; diff --git a/front/core/components/scroll-up/scroll-up.html b/front/core/components/scroll-up/scroll-up.html index a3748acc6..e686bb077 100644 --- a/front/core/components/scroll-up/scroll-up.html +++ b/front/core/components/scroll-up/scroll-up.html @@ -1,6 +1,6 @@ - - \ No newline at end of file + \ No newline at end of file diff --git a/front/core/components/scroll-up/style.scss b/front/core/components/scroll-up/style.scss index c6dae16ef..4b6fe70c1 100644 --- a/front/core/components/scroll-up/style.scss +++ b/front/core/components/scroll-up/style.scss @@ -1,10 +1,14 @@ @import "variables"; vn-scroll-up { - right: 0; + left: 50%; top: $topbar-height; - margin: $float-spacing; + margin: 0; display: none; position: fixed; - z-index: 10 + z-index: 10; + + vn-icon { + font-size: 60px + } } \ No newline at end of file diff --git a/modules/monitor/back/methods/sales-monitor/salesFilter.js b/modules/monitor/back/methods/sales-monitor/salesFilter.js index 726e5bfaf..ecbdc4895 100644 --- a/modules/monitor/back/methods/sales-monitor/salesFilter.js +++ b/modules/monitor/back/methods/sales-monitor/salesFilter.js @@ -247,10 +247,9 @@ module.exports = Self => { stmt.merge(conn.makeWhere(filter.where)); stmts.push(stmt); - stmts.push('DROP TEMPORARY TABLE IF EXISTS tmp.ticketGetProblems'); - + stmts.push('DROP TEMPORARY TABLE IF EXISTS tmp.sale_getProblems'); stmts.push(` - CREATE TEMPORARY TABLE tmp.ticketGetProblems + CREATE TEMPORARY TABLE tmp.sale_getProblems (INDEX (ticketFk)) ENGINE = MEMORY SELECT f.id ticketFk, f.clientFk, f.warehouseFk, f.shipped @@ -258,15 +257,12 @@ module.exports = Self => { LEFT JOIN alertLevel al ON al.alertLevel = f.alertLevel WHERE (al.code = 'FREE' OR f.alertLevel IS NULL) AND f.shipped >= CURDATE()`); - - stmts.push('CALL ticketGetProblems(FALSE)'); + stmts.push('CALL ticket_getProblems(FALSE)'); stmt = new ParameterizedSQL(` - SELECT - f.*, - tp.* + SELECT f.*, tp.* FROM tmp.filter f - LEFT JOIN tmp.ticketProblems tp ON tp.ticketFk = f.id`); + LEFT JOIN tmp.ticket_problems tp ON tp.ticketFk = f.id`); if (args.problems != undefined && (!args.from && !args.to)) throw new UserError('Choose a date range or days forward'); @@ -309,7 +305,7 @@ module.exports = Self => { `DROP TEMPORARY TABLE tmp.filter, tmp.ticket, - tmp.ticketGetProblems`); + tmp.ticket_problems`); let sql = ParameterizedSQL.join(stmts, ';'); let result = await conn.executeStmt(sql); diff --git a/modules/monitor/front/index/tickets/index.html b/modules/monitor/front/index/tickets/index.html index e410be4e5..fef62fbe9 100644 --- a/modules/monitor/front/index/tickets/index.html +++ b/modules/monitor/front/index/tickets/index.html @@ -30,7 +30,7 @@ - + @@ -82,6 +82,13 @@ class="bright" icon="icon-risk"> + + { stmt.merge(conn.makeWhere(filter.where)); stmts.push(stmt); - stmts.push('DROP TEMPORARY TABLE IF EXISTS tmp.ticketGetProblems'); - + stmts.push('DROP TEMPORARY TABLE IF EXISTS tmp.sale_getProblems'); stmts.push(` - CREATE TEMPORARY TABLE tmp.ticketGetProblems + CREATE TEMPORARY TABLE tmp.sale_getProblems (INDEX (ticketFk)) ENGINE = MEMORY SELECT f.id ticketFk, f.clientFk, f.warehouseFk, f.shipped @@ -258,15 +257,12 @@ module.exports = Self => { LEFT JOIN alertLevel al ON al.alertLevel = f.alertLevel WHERE (al.code = 'FREE' OR f.alertLevel IS NULL) AND f.shipped >= CURDATE()`); - - stmts.push('CALL ticketGetProblems(FALSE)'); + stmts.push('CALL ticket_getProblems(FALSE)'); stmt = new ParameterizedSQL(` - SELECT - f.*, - tp.* + SELECT f.*, tp.* FROM tmp.filter f - LEFT JOIN tmp.ticketProblems tp ON tp.ticketFk = f.id`); + LEFT JOIN tmp.ticket_problems tp ON tp.ticketFk = f.id`); if (args.problems != undefined && (!args.from && !args.to)) throw new UserError('Choose a date range or days forward'); @@ -309,7 +305,7 @@ module.exports = Self => { `DROP TEMPORARY TABLE tmp.filter, tmp.ticket, - tmp.ticketGetProblems`); + tmp.ticket_problems`); let sql = ParameterizedSQL.join(stmts, ';'); let result = await conn.executeStmt(sql); diff --git a/modules/ticket/back/methods/ticket/getSales.js b/modules/ticket/back/methods/ticket/getSales.js index 59bbd5bd4..a39d6a257 100644 --- a/modules/ticket/back/methods/ticket/getSales.js +++ b/modules/ticket/back/methods/ticket/getSales.js @@ -68,7 +68,7 @@ module.exports = Self => { claimedSales.set(claim.saleFk, claim); // Get problems - const problemsQuery = `CALL ticket_getProblems(?, FALSE)`; + const problemsQuery = `CALL sale_getProblemsByTicket(?, FALSE)`; const [problems] = await Self.rawSql(problemsQuery, [id]); const saleProblems = new Map(); @@ -83,7 +83,8 @@ module.exports = Self => { sale.claim = claimedSales.get(sale.id); if (problems) { sale.isAvailable = problems.isAvailable; - sale.isFreezed = problems.isFreezed; + sale.hasTicketRequest = problems.hasTicketRequest; + sale.hasComponentLack = problems.hasComponentLack; } } diff --git a/modules/ticket/front/index/index.html b/modules/ticket/front/index/index.html index 915e16a11..1ec31c236 100644 --- a/modules/ticket/front/index/index.html +++ b/modules/ticket/front/index/index.html @@ -70,6 +70,13 @@ class="bright" icon="icon-risk"> + + {{::ticket.id}} diff --git a/modules/ticket/front/sale/index.html b/modules/ticket/front/sale/index.html index 419369e02..954e969a3 100644 --- a/modules/ticket/front/sale/index.html +++ b/modules/ticket/front/sale/index.html @@ -59,6 +59,7 @@ + Available Id Quantity Item @@ -82,10 +83,10 @@ + vn-tooltip="Visible: {{::sale.visible || 0}}"> + vn-tooltip="Component lack" + icon="icon-components"> @@ -111,6 +113,13 @@ zoom-image="{{::$root.imagePath('catalog', '1600x900', sale.itemFk)}}" on-error-src/> + + + {{::sale.available}} + + diff --git a/modules/ticket/front/summary/index.html b/modules/ticket/front/summary/index.html index 1441024ba..42b853a27 100644 --- a/modules/ticket/front/summary/index.html +++ b/modules/ticket/front/summary/index.html @@ -138,7 +138,30 @@ vn-tooltip="{{::$ctrl.$t('Claim')}}: {{::sale.claimBeginning.claimFk}}"> - + + + + + + + + - {{::sale.available}} + + {{::sale.available}} {{::sale.quantity}} @@ -218,7 +244,11 @@ {{::service.quantity}} {{::service.description}} {{::service.price | currency: 'EUR':2}} - {{::service.taxClass.description}} + + + {{::service.taxClass.description}} + + {{::service.quantity * service.price | currency: 'EUR':2}} -- 2.40.1 From 920e7b1daf889351a46f09a0954b7da1af2591d4 Mon Sep 17 00:00:00 2001 From: joan Date: Wed, 26 May 2021 13:05:58 +0200 Subject: [PATCH 3/4] E2E fixes --- .../10320-monitors/00-sale_getProblems.sql | 11 +- .../00-sale_getProblemsByTicket.sql | 6 + .../10320-monitors/00-ticketGetProblems.sql | 188 ++++++++++++++++++ .../10320-monitors/00-ticket_getProblems.sql | 7 + e2e/helpers/selectors.js | 14 +- .../sales-monitor/specs/salesFilter.spec.js | 2 +- modules/monitor/front/index/locale/es.yml | 3 +- .../monitor/front/index/tickets/index.html | 2 - .../back/methods/sale/specs/reserve.spec.js | 8 +- .../ticket/back/methods/ticket/getSales.js | 58 ++---- .../back/methods/ticket/specs/filter.spec.js | 2 +- modules/ticket/front/index/locale/es.yml | 3 +- 12 files changed, 240 insertions(+), 64 deletions(-) create mode 100644 db/changes/10320-monitors/00-ticketGetProblems.sql diff --git a/db/changes/10320-monitors/00-sale_getProblems.sql b/db/changes/10320-monitors/00-sale_getProblems.sql index 23f433aec..290dcddb2 100644 --- a/db/changes/10320-monitors/00-sale_getProblems.sql +++ b/db/changes/10320-monitors/00-sale_getProblems.sql @@ -5,6 +5,13 @@ $$ CREATE DEFINER = root@`%` PROCEDURE `vn`.`sale_getProblems`(IN vIsTodayRelative TINYINT(1)) BEGIN +/** + * Calcula los problemas de cada venta + * para un conjunto de tickets. + * + * @table tmp.sale_getProblems(ticketFk, clientFk, warehouseFk, shipped) Identificadores de los tickets a calcular + * @return tmp.sale_problems + */ DECLARE vWarehouse INT; DECLARE vDate DATE; DECLARE vAvailableCache INT; @@ -140,7 +147,7 @@ BEGIN AND NOT i.generic AND CURDATE() = vDate AND t.warehouseFk = vWarehouse - GROUP BY tl.ticketFk) sub + GROUP BY tl.ticketFk LIMIT 1) sub ON DUPLICATE KEY UPDATE itemShortage = sub.problem, saleFk = sub.saleFk; @@ -163,7 +170,7 @@ BEGIN AND NOT i.generic AND CURDATE() = vDate AND t.warehouseFk = vWarehouse - GROUP BY tl.ticketFk) sub + GROUP BY tl.ticketFk LIMIT 1) sub ON DUPLICATE KEY UPDATE itemDelay = sub.problem, saleFk = sub.saleFk; END WHILE; diff --git a/db/changes/10320-monitors/00-sale_getProblemsByTicket.sql b/db/changes/10320-monitors/00-sale_getProblemsByTicket.sql index 75ece20de..1f30014d4 100644 --- a/db/changes/10320-monitors/00-sale_getProblemsByTicket.sql +++ b/db/changes/10320-monitors/00-sale_getProblemsByTicket.sql @@ -5,6 +5,12 @@ $$ CREATE DEFINER = root@`%` PROCEDURE `vn`.`sale_getProblemsByTicket`(IN vTicketFk INT, IN vIsTodayRelative TINYINT(1)) BEGIN +/** + * Calcula los problemas de cada venta + * para un conjunto de tickets. + * + * @return Problems result + */ DROP TEMPORARY TABLE IF EXISTS tmp.sale_getProblems; CREATE TEMPORARY TABLE tmp.sale_getProblems (INDEX (ticketFk)) diff --git a/db/changes/10320-monitors/00-ticketGetProblems.sql b/db/changes/10320-monitors/00-ticketGetProblems.sql new file mode 100644 index 000000000..85d6e4018 --- /dev/null +++ b/db/changes/10320-monitors/00-ticketGetProblems.sql @@ -0,0 +1,188 @@ +DROP PROCEDURE IF EXISTS `vn`.`ticketGetProblems`; + +DELIMITER $$ +$$ +CREATE + DEFINER = root@`%` PROCEDURE `vn`.`ticketGetProblems`(IN vIsTodayRelative TINYINT(1)) +BEGIN +/** + * @deprecated Use ticket_getProblems() instead + * + */ + DECLARE vWarehouse INT; + DECLARE vDate DATE; + DECLARE vAvailableCache INT; + DECLARE vDone INT DEFAULT 0; + DECLARE vComponentCount INT; + + DECLARE vCursor CURSOR FOR + SELECT DISTINCT tt.warehouseFk, IF(vIsTodayRelative, CURDATE(), date(tt.shipped)) + FROM tmp.ticketGetProblems tt + WHERE DATE(tt.shipped) BETWEEN CURDATE() + AND TIMESTAMPADD(DAY, IF(vIsTodayRelative, 9.9, 1.9), CURDATE()); + + DECLARE CONTINUE HANDLER FOR NOT FOUND SET vDone = 1; + + DROP TEMPORARY TABLE IF EXISTS tmp.ticketProblems; + CREATE TEMPORARY TABLE tmp.ticketProblems ( + ticketFk INT(11) PRIMARY KEY, + isFreezed INTEGER(1) DEFAULT 0, + risk DECIMAL(10,2) DEFAULT 0, + hasTicketRequest INTEGER(1) DEFAULT 0, + isAvailable INTEGER(1) DEFAULT 1, + itemShortage VARCHAR(250), + isTaxDataChecked INTEGER(1) DEFAULT 1, + itemDelay VARCHAR(250), + componentLack INTEGER(1) + ) ENGINE = MEMORY; + + DROP TEMPORARY TABLE IF EXISTS tmp.ticketList; + CREATE TEMPORARY TABLE tmp.ticketList + (PRIMARY KEY (ticketFk)) + ENGINE = MEMORY + SELECT tp.ticketFk, c.id clientFk + FROM tmp.ticketGetProblems tp + JOIN vn.client c ON c.id = tp.clientFk; + + SELECT COUNT(*) INTO vComponentCount + FROM vn.component c + WHERE c.isRequired; + + INSERT INTO tmp.ticketProblems(ticketFk, componentLack) + SELECT tl.ticketFk, (COUNT(DISTINCT s.id) * vComponentCount > COUNT(c.id)) + FROM tmp.ticketList tl + JOIN vn.sale s ON s.ticketFk = tl.ticketFk + LEFT JOIN vn.saleComponent sc ON sc.saleFk = s.id + LEFT JOIN vn.component c ON c.id = sc.componentFk AND c.isRequired + GROUP BY tl.ticketFk; + + INSERT INTO tmp.ticketProblems(ticketFk, isFreezed) + SELECT DISTINCT tl.ticketFk, 1 + FROM tmp.ticketList tl + JOIN vn.client c ON c.id = tl.clientFk + WHERE c.isFreezed + ON DUPLICATE KEY UPDATE + isFreezed = c.isFreezed; + + DROP TEMPORARY TABLE IF EXISTS tmp.clientGetDebt; + CREATE TEMPORARY TABLE tmp.clientGetDebt + (PRIMARY KEY (clientFk)) + ENGINE = MEMORY + SELECT DISTINCT clientFk + FROM tmp.ticketList; + + CALL clientGetDebt(CURDATE()); + + INSERT INTO tmp.ticketProblems(ticketFk, risk) + SELECT DISTINCT tl.ticketFk, r.risk + FROM tmp.ticketList tl + JOIN vn.ticket t ON t.id = tl.ticketFk + JOIN vn.agencyMode a ON t.agencyModeFk = a.id + JOIN tmp.risk r ON r.clientFk = t.clientFk + JOIN vn.client c ON c.id = t.clientFk + JOIN vn.clientConfig cc + WHERE r.risk - cc.riskTolerance > c.credit + 10 + AND a.isRiskFree = FALSE + ON DUPLICATE KEY UPDATE + risk = r.risk; + + INSERT INTO tmp.ticketProblems(ticketFk, hasTicketRequest) + SELECT DISTINCT tl.ticketFk, 1 + FROM tmp.ticketList tl + JOIN vn.ticketRequest tr ON tr.ticketFk = tl.ticketFk + WHERE tr.isOK IS NULL AND tr.saleFk IS NOT NULL + ON DUPLICATE KEY UPDATE + hasTicketRequest = 1; + + OPEN vCursor; + + WHILE NOT vDone + DO + FETCH vCursor INTO vWarehouse, vDate; + + CALL cache.available_refresh(vAvailableCache, FALSE, vWarehouse, vDate); + + INSERT INTO tmp.ticketProblems(ticketFk, isAvailable) + SELECT tl.ticketFk, 0 + FROM tmp.ticketList tl + JOIN vn.ticket t ON t.id = tl.ticketFk + JOIN vn.sale s ON s.ticketFk = t.id + JOIN vn.item i ON i.id = s.itemFk + JOIN vn.itemType it on it.id = i.typeFk + LEFT JOIN cache.available av ON av.item_id = i.id + AND av.calc_id = vAvailableCache + WHERE date(t.shipped) = vDate + AND it.categoryFk != 6 + AND IFNULL(av.available, 0) < 0 + AND s.isPicked = FALSE + AND NOT i.generic + AND vWarehouse = t.warehouseFk + GROUP BY tl.ticketFk + ON DUPLICATE KEY UPDATE + isAvailable = 0; +/* + INSERT INTO tmp.ticketProblems(ticketFk, itemShortage) + SELECT ticketFk, problem + FROM ( + SELECT tl.ticketFk, CONCAT('F: ',GROUP_CONCAT(i.id, ' ', i.longName, ' ')) problem + FROM tmp.ticketList tl + JOIN vn.ticket t ON t.id = tl.ticketFk + JOIN vn.sale s ON s.ticketFk = t.id + JOIN vn.item i ON i.id = s.itemFk + JOIN vn.itemType it on it.id = i.typeFk + LEFT JOIN vn.itemShelvingStock_byWarehouse issw ON issw.itemFk = i.id AND issw.warehouseFk = t.warehouseFk + LEFT JOIN cache.available av ON av.item_id = i.id AND av.calc_id = vAvailableCache + WHERE IFNULL(av.available, 0) < 0 + AND s.quantity > IFNULL(issw.visible, 0) + AND s.quantity > 0 + AND s.isPicked = FALSE + AND s.reserved = FALSE + AND it.categoryFk != 6 + AND IF(vIsTodayRelative, TRUE, date(t.shipped) = vDate) + AND NOT i.generic + AND CURDATE() = vDate + AND t.warehouseFk = vWarehouse + GROUP BY tl.ticketFk LIMIT 1) sub + ON DUPLICATE KEY UPDATE + itemShortage = sub.problem; +*/ + INSERT INTO tmp.ticketProblems(ticketFk, itemDelay) + SELECT ticketFk, problem + FROM ( + SELECT tl.ticketFk, GROUP_CONCAT('I: ',i.id, ' ', i.longName, ' ') problem + FROM tmp.ticketList tl + JOIN vn.ticket t ON t.id = tl.ticketFk + JOIN vn.sale s ON s.ticketFk = t.id + JOIN vn.item i ON i.id = s.itemFk + JOIN vn.itemType it on it.id = i.typeFk + LEFT JOIN vn.itemShelvingStock_byWarehouse issw ON issw.itemFk = i.id AND issw.warehouseFk = t.warehouseFk + WHERE s.quantity > IFNULL(issw.visible, 0) + AND s.quantity > 0 + AND s.isPicked = FALSE + AND s.reserved = FALSE + AND it.categoryFk != 6 + AND IF(vIsTodayRelative, TRUE, date(t.shipped) = vDate) + AND NOT i.generic + AND CURDATE() = vDate + AND t.warehouseFk = vWarehouse + GROUP BY tl.ticketFk LIMIT 1) sub + ON DUPLICATE KEY UPDATE + itemDelay = sub.problem; + END WHILE; + + CLOSE vCursor; + + INSERT INTO tmp.ticketProblems(ticketFk, isTaxDataChecked) + SELECT DISTINCT tl.ticketFk, FALSE + FROM tmp.ticketList tl + JOIN vn.client c ON c.id = tl.clientFk + WHERE c.isTaxDataChecked= FALSE + ON DUPLICATE KEY UPDATE + isTaxDataChecked = FALSE; + + DROP TEMPORARY TABLE + tmp.clientGetDebt, + tmp.ticketList; + +END;;$$ +DELIMITER ; diff --git a/db/changes/10320-monitors/00-ticket_getProblems.sql b/db/changes/10320-monitors/00-ticket_getProblems.sql index 9bf38c401..290a083df 100644 --- a/db/changes/10320-monitors/00-ticket_getProblems.sql +++ b/db/changes/10320-monitors/00-ticket_getProblems.sql @@ -5,6 +5,13 @@ $$ CREATE DEFINER = root@`%` PROCEDURE `vn`.`ticket_getProblems`(IN vIsTodayRelative TINYINT(1)) BEGIN +/** + * Calcula los problemas para un conjunto de tickets. + * Agrupados por ticket + * + * @table tmp.sale_getProblems(ticketFk, clientFk, warehouseFk, shipped) Identificadores de los tickets a calcular + * @return tmp.ticket_problems + */ CALL sale_getProblems(vIsTodayRelative); DROP TEMPORARY TABLE IF EXISTS tmp.ticket_problems; diff --git a/e2e/helpers/selectors.js b/e2e/helpers/selectors.js index b5bf46dd5..7b50935cc 100644 --- a/e2e/helpers/selectors.js +++ b/e2e/helpers/selectors.js @@ -565,18 +565,18 @@ export default { moreMenuUpdateDiscountInput: 'vn-input-number[ng-model="$ctrl.edit.discount"] input', transferQuantityInput: '.vn-popover.shown vn-table > div > vn-tbody > vn-tr > vn-td-editable > span > text', transferQuantityCell: '.vn-popover.shown vn-table > div > vn-tbody > vn-tr > vn-td-editable', - firstSaleId: 'vn-ticket-sale vn-tbody > vn-tr:nth-child(1) > vn-td:nth-child(4) > span', + firstSaleId: 'vn-ticket-sale vn-tbody > vn-tr:nth-child(1) > vn-td:nth-child(5) > span', firstSaleClaimIcon: 'vn-ticket-sale vn-table vn-tbody > vn-tr:nth-child(1) vn-icon[icon="icon-claims"]', firstSaleDescriptorImage: '.vn-popover.shown vn-item-descriptor img', firstSaleThumbnailImage: 'vn-ticket-sale:nth-child(1) vn-tr:nth-child(1) vn-td:nth-child(3) > img', firstSaleZoomedImage: 'body > div > div > img', firstSaleQuantity: 'vn-ticket-sale [ng-model="sale.quantity"]', - firstSaleQuantityCell: 'vn-ticket-sale vn-tr:nth-child(1) > vn-td-editable:nth-child(5)', - firstSalePrice: 'vn-ticket-sale vn-table vn-tr:nth-child(1) > vn-td:nth-child(7) > span', + firstSaleQuantityCell: 'vn-ticket-sale vn-tr:nth-child(1) > vn-td-editable:nth-child(6)', + firstSalePrice: 'vn-ticket-sale vn-table vn-tr:nth-child(1) > vn-td:nth-child(8) > span', firstSalePriceInput: '.vn-popover.shown input[ng-model="$ctrl.field"]', - firstSaleDiscount: 'vn-ticket-sale vn-table vn-tr:nth-child(1) > vn-td:nth-child(8) > span', + firstSaleDiscount: 'vn-ticket-sale vn-table vn-tr:nth-child(1) > vn-td:nth-child(9) > span', firstSaleDiscountInput: '.vn-popover.shown [ng-model="$ctrl.field"]', - firstSaleImport: 'vn-ticket-sale:nth-child(1) vn-td:nth-child(9)', + firstSaleImport: 'vn-ticket-sale:nth-child(1) vn-td:nth-child(10)', firstSaleReservedIcon: 'vn-ticket-sale vn-tr:nth-child(1) > vn-td:nth-child(2) > vn-icon:nth-child(3)', firstSaleColour: 'vn-ticket-sale vn-tr:nth-child(1) vn-fetched-tags section', firstSaleCheckbox: 'vn-ticket-sale vn-tr:nth-child(1) vn-check[ng-model="sale.checked"]', @@ -584,8 +584,8 @@ export default { secondSaleId: 'vn-ticket-sale:nth-child(2) vn-td-editable:nth-child(4) text > span', secondSaleIdAutocomplete: 'vn-ticket-sale vn-tr:nth-child(2) vn-autocomplete[ng-model="sale.itemFk"]', secondSaleQuantity: 'vn-ticket-sale vn-table vn-tr:nth-child(2) vn-input-number', - secondSaleQuantityCell: 'vn-ticket-sale > div > vn-card > vn-table > div > vn-tbody > vn-tr:nth-child(2) > vn-td-editable:nth-child(5)', - secondSaleConceptCell: 'vn-ticket-sale vn-tbody > :nth-child(2) > :nth-child(6)', + secondSaleQuantityCell: 'vn-ticket-sale > div > vn-card > vn-table > div > vn-tbody > vn-tr:nth-child(2) > vn-td-editable:nth-child(6)', + secondSaleConceptCell: 'vn-ticket-sale vn-tbody > :nth-child(2) > :nth-child(7)', secondSaleConceptInput: 'vn-ticket-sale vn-tbody > :nth-child(2) > vn-td-editable.ng-isolate-scope.selected vn-textfield', totalImport: 'vn-ticket-sale vn-one.taxes > p:nth-child(3) > strong', selectAllSalesCheckbox: 'vn-ticket-sale vn-thead vn-check', diff --git a/modules/monitor/back/methods/sales-monitor/specs/salesFilter.spec.js b/modules/monitor/back/methods/sales-monitor/specs/salesFilter.spec.js index 0666544e7..54615b22b 100644 --- a/modules/monitor/back/methods/sales-monitor/specs/salesFilter.spec.js +++ b/modules/monitor/back/methods/sales-monitor/specs/salesFilter.spec.js @@ -23,7 +23,7 @@ describe('SalesMonitor salesFilter()', () => { const filter = {}; const result = await app.models.SalesMonitor.salesFilter(ctx, filter); - expect(result.length).toEqual(3); + expect(result.length).toEqual(4); }); it('should return the tickets matching the problems on false', async() => { diff --git a/modules/monitor/front/index/locale/es.yml b/modules/monitor/front/index/locale/es.yml index 1f69de222..cb94d41a7 100644 --- a/modules/monitor/front/index/locale/es.yml +++ b/modules/monitor/front/index/locale/es.yml @@ -3,4 +3,5 @@ Clients on website: Clientes activos en la web Recent order actions: Acciones recientes en pedidos Search tickets: Buscar tickets Delete selected elements: Eliminar los elementos seleccionados -All the selected elements will be deleted. Are you sure you want to continue?: Todos los elementos seleccionados serán eliminados. ¿Seguro que quieres continuar? \ No newline at end of file +All the selected elements will be deleted. Are you sure you want to continue?: Todos los elementos seleccionados serán eliminados. ¿Seguro que quieres continuar? +Component lack: Faltan componentes \ No newline at end of file diff --git a/modules/monitor/front/index/tickets/index.html b/modules/monitor/front/index/tickets/index.html index fef62fbe9..dffc1ee8d 100644 --- a/modules/monitor/front/index/tickets/index.html +++ b/modules/monitor/front/index/tickets/index.html @@ -67,7 +67,6 @@ ng-show="::ticket.isAvailable === 0" translate-attr="{title: 'Not available'}" class="bright" - vn-tooltip="Not available" icon="icon-unavailable"> diff --git a/modules/ticket/back/methods/sale/specs/reserve.spec.js b/modules/ticket/back/methods/sale/specs/reserve.spec.js index 5379b1487..fce7bd95e 100644 --- a/modules/ticket/back/methods/sale/specs/reserve.spec.js +++ b/modules/ticket/back/methods/sale/specs/reserve.spec.js @@ -35,8 +35,8 @@ describe('sale reserve()', () => { it('should update the given sales of a ticket to reserved', async() => { originalTicketSales = await app.models.Ticket.getSales(11); - expect(originalTicketSales[0].reserved).toEqual(0); - expect(originalTicketSales[1].reserved).toEqual(0); + expect(originalTicketSales[0].reserved).toEqual(false); + expect(originalTicketSales[1].reserved).toEqual(false); const ticketId = 11; const sales = [{id: 7}, {id: 8}]; @@ -46,7 +46,7 @@ describe('sale reserve()', () => { const reservedTicketSales = await app.models.Ticket.getSales(ticketId); - expect(reservedTicketSales[0].reserved).toEqual(1); - expect(reservedTicketSales[1].reserved).toEqual(1); + expect(reservedTicketSales[0].reserved).toEqual(true); + expect(reservedTicketSales[1].reserved).toEqual(true); }); }); diff --git a/modules/ticket/back/methods/ticket/getSales.js b/modules/ticket/back/methods/ticket/getSales.js index a39d6a257..7520e7270 100644 --- a/modules/ticket/back/methods/ticket/getSales.js +++ b/modules/ticket/back/methods/ticket/getSales.js @@ -20,9 +20,14 @@ module.exports = Self => { } }); - Self.getSales = async id => { - // implementar transacciones + Self.getSales = async(id, options) => { const models = Self.app.models; + + let myOptions = {}; + + if (typeof options == 'object') + Object.assign(myOptions, options); + const sales = await models.Sale.find({ include: { relation: 'item', @@ -45,12 +50,13 @@ module.exports = Self => { ] } }, - where: {ticketFk: id} - }); + where: {ticketFk: id}, + order: 'concept' + }, myOptions); // Get items available const query = `CALL ticketGetVisibleAvailable(?)`; - const [salesAvailable] = await Self.rawSql(query, [id]); + const [salesAvailable] = await Self.rawSql(query, [id], myOptions); const itemAvailable = new Map(); for (let sale of salesAvailable) @@ -61,7 +67,7 @@ module.exports = Self => { const claims = await models.ClaimBeginning.find({ fields: ['claimFk', 'saleFk'], where: {saleFk: {inq: saleIds}}, - }); + }, myOptions); const claimedSales = new Map(); for (let claim of claims) @@ -69,14 +75,12 @@ module.exports = Self => { // Get problems const problemsQuery = `CALL sale_getProblemsByTicket(?, FALSE)`; - const [problems] = await Self.rawSql(problemsQuery, [id]); + const [problems] = await Self.rawSql(problemsQuery, [id], myOptions); const saleProblems = new Map(); for (let problem of problems) saleProblems.set(problem.saleFk, problem); - console.log(problems); - for (let sale of sales) { const problems = saleProblems.get(sale.id); sale.available = itemAvailable.get(sale.itemFk); @@ -89,41 +93,5 @@ module.exports = Self => { } return sales; - - /* let query = `CALL vn.ticketGetVisibleAvailable(?)`; - let [lines] = await Self.rawSql(query, [ticketFk]); - let ids = []; - let salesIds = []; - - for (line of lines) { - ids.push(line.itemFk); - salesIds.push(line.id); - } - - let filter = { - fields: ['id', 'name', 'tag5', 'value5', 'tag6', 'value6', 'tag7', 'value7', 'tag8', 'value8', 'tag9', 'value9', 'tag10', 'value10'], - where: {id: {inq: ids}} - }; - let items = await Self.app.models.Item.find(filter); - - filter = { - fields: ['claimFk', 'saleFk'], - where: {saleFk: {inq: salesIds}}, - }; - let claims = await Self.app.models.ClaimBeginning.find(filter); - - let map = {}; - for (item of items) - map[item.id] = item; - - let claimMap = {}; - for (claim of claims) - claimMap[claim.saleFk] = claim; - - for (line of lines) { - line.item = map[line.itemFk]; - line.claim = claimMap[line.id]; - } - return lines; */ }; }; diff --git a/modules/ticket/back/methods/ticket/specs/filter.spec.js b/modules/ticket/back/methods/ticket/specs/filter.spec.js index 0f4a1660e..c742de41d 100644 --- a/modules/ticket/back/methods/ticket/specs/filter.spec.js +++ b/modules/ticket/back/methods/ticket/specs/filter.spec.js @@ -23,7 +23,7 @@ describe('ticket filter()', () => { const filter = {}; const result = await app.models.Ticket.filter(ctx, filter); - expect(result.length).toEqual(3); + expect(result.length).toEqual(4); }); it('should return the tickets matching the problems on false', async() => { diff --git a/modules/ticket/front/index/locale/es.yml b/modules/ticket/front/index/locale/es.yml index 1545c5e53..9ff8d1568 100644 --- a/modules/ticket/front/index/locale/es.yml +++ b/modules/ticket/front/index/locale/es.yml @@ -10,4 +10,5 @@ Exclude selection: Excluir selección Remove filter: Quitar filtro por selección Remove all filters: Eliminar todos los filtros Copy value: Copiar valor -No verified data: Sin datos comprobados \ No newline at end of file +No verified data: Sin datos comprobados +Component lack: Faltan componentes \ No newline at end of file -- 2.40.1 From 27cd54bef17497b17ff7d8cb104253155a124fb3 Mon Sep 17 00:00:00 2001 From: joan Date: Thu, 27 May 2021 11:41:45 +0200 Subject: [PATCH 4/4] Updated icons title --- modules/route/front/tickets/index.html | 2 +- modules/ticket/front/index/index.html | 2 -- modules/ticket/front/sale/index.html | 4 +--- modules/ticket/front/summary/index.html | 4 +--- 4 files changed, 3 insertions(+), 9 deletions(-) diff --git a/modules/route/front/tickets/index.html b/modules/route/front/tickets/index.html index 6a5a4ce7c..858215854 100644 --- a/modules/route/front/tickets/index.html +++ b/modules/route/front/tickets/index.html @@ -74,7 +74,7 @@ {{::ticket.packages}} - {{::ticket.volume | number:1}} + {{::ticket.volume | number:2}} diff --git a/modules/ticket/front/sale/index.html b/modules/ticket/front/sale/index.html index b5fd44ee6..0a5c8e841 100644 --- a/modules/ticket/front/sale/index.html +++ b/modules/ticket/front/sale/index.html @@ -90,20 +90,18 @@ + translate-attr="{title: 'Reserved'}"> diff --git a/modules/ticket/front/summary/index.html b/modules/ticket/front/summary/index.html index 07bdb058a..a2a17fb11 100644 --- a/modules/ticket/front/summary/index.html +++ b/modules/ticket/front/summary/index.html @@ -146,20 +146,18 @@ + translate-attr="{title: 'Reserved'}"> -- 2.40.1