2891 - Get ticket problems for every sale #629
|
@ -0,0 +1,193 @@
|
||||||
|
DROP PROCEDURE IF EXISTS `vn`.`sale_getProblems`;
|
||||||
|
|
||||||
|
DELIMITER $$
|
||||||
|
$$
|
||||||
|
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;
|
||||||
|
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 LIMIT 1) 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 LIMIT 1) 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 ;
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
DROP PROCEDURE IF EXISTS `vn`.`sale_getProblemsByTicket`;
|
||||||
|
|
||||||
|
DELIMITER $$
|
||||||
|
$$
|
||||||
|
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))
|
||||||
|
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 ;
|
|
@ -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 ;
|
|
@ -0,0 +1,36 @@
|
||||||
|
DROP PROCEDURE IF EXISTS `vn`.`ticket_getProblems`;
|
||||||
|
|
||||||
|
DELIMITER $$
|
||||||
|
$$
|
||||||
|
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;
|
||||||
|
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.sale_problems;
|
||||||
|
END;;$$
|
||||||
|
DELIMITER ;
|
|
@ -565,18 +565,18 @@ export default {
|
||||||
moreMenuUpdateDiscountInput: 'vn-input-number[ng-model="$ctrl.edit.discount"] input',
|
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',
|
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',
|
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"]',
|
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',
|
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',
|
firstSaleThumbnailImage: 'vn-ticket-sale:nth-child(1) vn-tr:nth-child(1) vn-td:nth-child(3) > img',
|
||||||
firstSaleZoomedImage: 'body > div > div > img',
|
firstSaleZoomedImage: 'body > div > div > img',
|
||||||
firstSaleQuantity: 'vn-ticket-sale [ng-model="sale.quantity"]',
|
firstSaleQuantity: 'vn-ticket-sale [ng-model="sale.quantity"]',
|
||||||
firstSaleQuantityCell: 'vn-ticket-sale vn-tr:nth-child(1) > vn-td-editable:nth-child(5)',
|
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(7) > span',
|
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"]',
|
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"]',
|
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)',
|
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',
|
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"]',
|
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',
|
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"]',
|
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',
|
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)',
|
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(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',
|
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',
|
totalImport: 'vn-ticket-sale vn-one.taxes > p:nth-child(3) > strong',
|
||||||
selectAllSalesCheckbox: 'vn-ticket-sale vn-thead vn-check',
|
selectAllSalesCheckbox: 'vn-ticket-sale vn-thead vn-check',
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<vn-button
|
<vn-icon-button
|
||||||
icon="keyboard_arrow_up"
|
icon="keyboard_arrow_up"
|
||||||
ng-click="$ctrl.goUp()"
|
ng-click="$ctrl.goUp()"
|
||||||
vn-tooltip="Go up"
|
vn-tooltip="Go up"
|
||||||
class="round">
|
class="round">
|
||||||
</vn-button>
|
</vn-icon-button>
|
|
@ -1,10 +1,14 @@
|
||||||
@import "variables";
|
@import "variables";
|
||||||
|
|
||||||
vn-scroll-up {
|
vn-scroll-up {
|
||||||
right: 0;
|
left: 50%;
|
||||||
top: $topbar-height;
|
top: $topbar-height;
|
||||||
margin: $float-spacing;
|
margin: 0;
|
||||||
display: none;
|
display: none;
|
||||||
position: fixed;
|
position: fixed;
|
||||||
z-index: 10
|
z-index: 10;
|
||||||
|
|
||||||
|
vn-icon {
|
||||||
|
font-size: 60px
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -247,10 +247,9 @@ module.exports = Self => {
|
||||||
stmt.merge(conn.makeWhere(filter.where));
|
stmt.merge(conn.makeWhere(filter.where));
|
||||||
stmts.push(stmt);
|
stmts.push(stmt);
|
||||||
|
|
||||||
stmts.push('DROP TEMPORARY TABLE IF EXISTS tmp.ticketGetProblems');
|
stmts.push('DROP TEMPORARY TABLE IF EXISTS tmp.sale_getProblems');
|
||||||
|
|
||||||
stmts.push(`
|
stmts.push(`
|
||||||
CREATE TEMPORARY TABLE tmp.ticketGetProblems
|
CREATE TEMPORARY TABLE tmp.sale_getProblems
|
||||||
(INDEX (ticketFk))
|
(INDEX (ticketFk))
|
||||||
ENGINE = MEMORY
|
ENGINE = MEMORY
|
||||||
SELECT f.id ticketFk, f.clientFk, f.warehouseFk, f.shipped
|
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
|
LEFT JOIN alertLevel al ON al.alertLevel = f.alertLevel
|
||||||
WHERE (al.code = 'FREE' OR f.alertLevel IS NULL)
|
WHERE (al.code = 'FREE' OR f.alertLevel IS NULL)
|
||||||
AND f.shipped >= CURDATE()`);
|
AND f.shipped >= CURDATE()`);
|
||||||
|
stmts.push('CALL ticket_getProblems(FALSE)');
|
||||||
stmts.push('CALL ticketGetProblems(FALSE)');
|
|
||||||
|
|
||||||
stmt = new ParameterizedSQL(`
|
stmt = new ParameterizedSQL(`
|
||||||
SELECT
|
SELECT f.*, tp.*
|
||||||
f.*,
|
|
||||||
tp.*
|
|
||||||
FROM tmp.filter f
|
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))
|
if (args.problems != undefined && (!args.from && !args.to))
|
||||||
throw new UserError('Choose a date range or days forward');
|
throw new UserError('Choose a date range or days forward');
|
||||||
|
@ -309,7 +305,7 @@ module.exports = Self => {
|
||||||
`DROP TEMPORARY TABLE
|
`DROP TEMPORARY TABLE
|
||||||
tmp.filter,
|
tmp.filter,
|
||||||
tmp.ticket,
|
tmp.ticket,
|
||||||
tmp.ticketGetProblems`);
|
tmp.ticket_problems`);
|
||||||
|
|
||||||
let sql = ParameterizedSQL.join(stmts, ';');
|
let sql = ParameterizedSQL.join(stmts, ';');
|
||||||
let result = await conn.executeStmt(sql);
|
let result = await conn.executeStmt(sql);
|
||||||
|
|
|
@ -23,7 +23,7 @@ describe('SalesMonitor salesFilter()', () => {
|
||||||
const filter = {};
|
const filter = {};
|
||||||
const result = await app.models.SalesMonitor.salesFilter(ctx, 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() => {
|
it('should return the tickets matching the problems on false', async() => {
|
||||||
|
|
|
@ -3,4 +3,5 @@ Clients on website: Clientes activos en la web
|
||||||
Recent order actions: Acciones recientes en pedidos
|
Recent order actions: Acciones recientes en pedidos
|
||||||
Search tickets: Buscar tickets
|
Search tickets: Buscar tickets
|
||||||
Delete selected elements: Eliminar los elementos seleccionados
|
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?
|
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
|
|
@ -30,7 +30,7 @@
|
||||||
</vn-none>
|
</vn-none>
|
||||||
</vn-horizontal>
|
</vn-horizontal>
|
||||||
<vn-card>
|
<vn-card>
|
||||||
<vn-table model="model" class="scrollable">
|
<vn-table model="model">
|
||||||
<vn-thead>
|
<vn-thead>
|
||||||
<vn-tr>
|
<vn-tr>
|
||||||
<vn-th class="icon-field"></vn-th>
|
<vn-th class="icon-field"></vn-th>
|
||||||
|
@ -67,7 +67,6 @@
|
||||||
ng-show="::ticket.isAvailable === 0"
|
ng-show="::ticket.isAvailable === 0"
|
||||||
translate-attr="{title: 'Not available'}"
|
translate-attr="{title: 'Not available'}"
|
||||||
class="bright"
|
class="bright"
|
||||||
vn-tooltip="Not available"
|
|
||||||
icon="icon-unavailable">
|
icon="icon-unavailable">
|
||||||
</vn-icon>
|
</vn-icon>
|
||||||
<vn-icon
|
<vn-icon
|
||||||
|
@ -82,6 +81,12 @@
|
||||||
class="bright"
|
class="bright"
|
||||||
icon="icon-risk">
|
icon="icon-risk">
|
||||||
</vn-icon>
|
</vn-icon>
|
||||||
|
<vn-icon
|
||||||
|
ng-show="::ticket.hasComponentLack"
|
||||||
|
translate-attr="{title: 'Component lack'}"
|
||||||
|
class="bright"
|
||||||
|
icon="icon-components">
|
||||||
|
</vn-icon>
|
||||||
</vn-td>
|
</vn-td>
|
||||||
<vn-td expand>
|
<vn-td expand>
|
||||||
<span
|
<span
|
||||||
|
|
|
@ -74,7 +74,7 @@
|
||||||
</span>
|
</span>
|
||||||
</vn-td>
|
</vn-td>
|
||||||
<vn-td shrink>{{::ticket.packages}}</vn-td>
|
<vn-td shrink>{{::ticket.packages}}</vn-td>
|
||||||
<vn-td shrink>{{::ticket.volume | number:1}}</vn-td>
|
<vn-td shrink>{{::ticket.volume | number:2}}</vn-td>
|
||||||
<vn-td number>
|
<vn-td number>
|
||||||
<span
|
<span
|
||||||
ng-click="ticketDescriptor.show($event, ticket.id)"
|
ng-click="ticketDescriptor.show($event, ticket.id)"
|
||||||
|
|
|
@ -35,8 +35,8 @@ describe('sale reserve()', () => {
|
||||||
it('should update the given sales of a ticket to reserved', async() => {
|
it('should update the given sales of a ticket to reserved', async() => {
|
||||||
originalTicketSales = await app.models.Ticket.getSales(11);
|
originalTicketSales = await app.models.Ticket.getSales(11);
|
||||||
|
|
||||||
expect(originalTicketSales[0].reserved).toEqual(0);
|
expect(originalTicketSales[0].reserved).toEqual(false);
|
||||||
expect(originalTicketSales[1].reserved).toEqual(0);
|
expect(originalTicketSales[1].reserved).toEqual(false);
|
||||||
|
|
||||||
const ticketId = 11;
|
const ticketId = 11;
|
||||||
const sales = [{id: 7}, {id: 8}];
|
const sales = [{id: 7}, {id: 8}];
|
||||||
|
@ -46,7 +46,7 @@ describe('sale reserve()', () => {
|
||||||
|
|
||||||
const reservedTicketSales = await app.models.Ticket.getSales(ticketId);
|
const reservedTicketSales = await app.models.Ticket.getSales(ticketId);
|
||||||
|
|
||||||
expect(reservedTicketSales[0].reserved).toEqual(1);
|
expect(reservedTicketSales[0].reserved).toEqual(true);
|
||||||
expect(reservedTicketSales[1].reserved).toEqual(1);
|
expect(reservedTicketSales[1].reserved).toEqual(true);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -247,10 +247,9 @@ module.exports = Self => {
|
||||||
stmt.merge(conn.makeWhere(filter.where));
|
stmt.merge(conn.makeWhere(filter.where));
|
||||||
stmts.push(stmt);
|
stmts.push(stmt);
|
||||||
|
|
||||||
stmts.push('DROP TEMPORARY TABLE IF EXISTS tmp.ticketGetProblems');
|
stmts.push('DROP TEMPORARY TABLE IF EXISTS tmp.sale_getProblems');
|
||||||
|
|
||||||
stmts.push(`
|
stmts.push(`
|
||||||
CREATE TEMPORARY TABLE tmp.ticketGetProblems
|
CREATE TEMPORARY TABLE tmp.sale_getProblems
|
||||||
(INDEX (ticketFk))
|
(INDEX (ticketFk))
|
||||||
ENGINE = MEMORY
|
ENGINE = MEMORY
|
||||||
SELECT f.id ticketFk, f.clientFk, f.warehouseFk, f.shipped
|
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
|
LEFT JOIN alertLevel al ON al.alertLevel = f.alertLevel
|
||||||
WHERE (al.code = 'FREE' OR f.alertLevel IS NULL)
|
WHERE (al.code = 'FREE' OR f.alertLevel IS NULL)
|
||||||
AND f.shipped >= CURDATE()`);
|
AND f.shipped >= CURDATE()`);
|
||||||
|
stmts.push('CALL ticket_getProblems(FALSE)');
|
||||||
stmts.push('CALL ticketGetProblems(FALSE)');
|
|
||||||
|
|
||||||
stmt = new ParameterizedSQL(`
|
stmt = new ParameterizedSQL(`
|
||||||
SELECT
|
SELECT f.*, tp.*
|
||||||
f.*,
|
|
||||||
tp.*
|
|
||||||
FROM tmp.filter f
|
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))
|
if (args.problems != undefined && (!args.from && !args.to))
|
||||||
throw new UserError('Choose a date range or days forward');
|
throw new UserError('Choose a date range or days forward');
|
||||||
|
@ -309,7 +305,7 @@ module.exports = Self => {
|
||||||
`DROP TEMPORARY TABLE
|
`DROP TEMPORARY TABLE
|
||||||
tmp.filter,
|
tmp.filter,
|
||||||
tmp.ticket,
|
tmp.ticket,
|
||||||
tmp.ticketGetProblems`);
|
tmp.ticket_problems`);
|
||||||
|
|
||||||
let sql = ParameterizedSQL.join(stmts, ';');
|
let sql = ParameterizedSQL.join(stmts, ';');
|
||||||
let result = await conn.executeStmt(sql);
|
let result = await conn.executeStmt(sql);
|
||||||
|
|
|
@ -1,12 +1,13 @@
|
||||||
|
|
||||||
module.exports = Self => {
|
module.exports = Self => {
|
||||||
Self.remoteMethod('getSales', {
|
Self.remoteMethod('getSales', {
|
||||||
description: 'New filter',
|
description: 'New filter',
|
||||||
accessType: 'READ',
|
accessType: 'READ',
|
||||||
accepts: [{
|
accepts: [{
|
||||||
arg: 'ticketFk',
|
arg: 'id',
|
||||||
type: 'number',
|
type: 'number',
|
||||||
required: true,
|
required: true,
|
||||||
description: 'ticket id',
|
description: 'The ticket id',
|
||||||
http: {source: 'path'}
|
http: {source: 'path'}
|
||||||
}],
|
}],
|
||||||
returns: {
|
returns: {
|
||||||
|
@ -14,60 +15,83 @@ module.exports = Self => {
|
||||||
root: true
|
root: true
|
||||||
},
|
},
|
||||||
http: {
|
http: {
|
||||||
path: `/:ticketFk/getSales`,
|
path: `/:id/getSales`,
|
||||||
verb: 'get'
|
verb: 'get'
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Self.getSales = async ticketFk => {
|
Self.getSales = async(id, options) => {
|
||||||
let query = `CALL vn.ticketGetVisibleAvailable(?)`;
|
const models = Self.app.models;
|
||||||
let [lines] = await Self.rawSql(query, [ticketFk]);
|
|
||||||
let ids = [];
|
|
||||||
let salesIds = [];
|
|
||||||
|
|
||||||
for (line of lines) {
|
let myOptions = {};
|
||||||
ids.push(line.itemFk);
|
|
||||||
salesIds.push(line.id);
|
|
||||||
}
|
|
||||||
|
|
||||||
let filter = {
|
if (typeof options == 'object')
|
||||||
fields: [
|
Object.assign(myOptions, options);
|
||||||
'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 = {
|
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},
|
||||||
|
order: 'concept'
|
||||||
|
}, myOptions);
|
||||||
|
|
||||||
|
// Get items available
|
||||||
|
const query = `CALL ticketGetVisibleAvailable(?)`;
|
||||||
|
const [salesAvailable] = await Self.rawSql(query, [id], myOptions);
|
||||||
|
|
||||||
|
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'],
|
fields: ['claimFk', 'saleFk'],
|
||||||
where: {saleFk: {inq: salesIds}},
|
where: {saleFk: {inq: saleIds}},
|
||||||
};
|
}, myOptions);
|
||||||
let claims = await Self.app.models.ClaimBeginning.find(filter);
|
|
||||||
|
|
||||||
let map = {};
|
const claimedSales = new Map();
|
||||||
for (item of items)
|
for (let claim of claims)
|
||||||
map[item.id] = item;
|
claimedSales.set(claim.saleFk, claim);
|
||||||
|
|
||||||
let claimMap = {};
|
// Get problems
|
||||||
for (claim of claims)
|
const problemsQuery = `CALL sale_getProblemsByTicket(?, FALSE)`;
|
||||||
claimMap[claim.saleFk] = claim;
|
const [problems] = await Self.rawSql(problemsQuery, [id], myOptions);
|
||||||
|
|
||||||
for (line of lines) {
|
const saleProblems = new Map();
|
||||||
line.item = map[line.itemFk];
|
for (let problem of problems)
|
||||||
line.claim = claimMap[line.id];
|
saleProblems.set(problem.saleFk, problem);
|
||||||
|
|
||||||
|
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.hasTicketRequest = problems.hasTicketRequest;
|
||||||
|
sale.hasComponentLack = problems.hasComponentLack;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return lines;
|
|
||||||
|
return sales;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -23,7 +23,7 @@ describe('ticket filter()', () => {
|
||||||
const filter = {};
|
const filter = {};
|
||||||
const result = await app.models.Ticket.filter(ctx, 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() => {
|
it('should return the tickets matching the problems on false', async() => {
|
||||||
|
|
|
@ -55,7 +55,6 @@
|
||||||
ng-show="::ticket.isAvailable === 0"
|
ng-show="::ticket.isAvailable === 0"
|
||||||
translate-attr="{title: 'Not available'}"
|
translate-attr="{title: 'Not available'}"
|
||||||
class="bright"
|
class="bright"
|
||||||
vn-tooltip="Not available"
|
|
||||||
icon="icon-unavailable">
|
icon="icon-unavailable">
|
||||||
</vn-icon>
|
</vn-icon>
|
||||||
<vn-icon
|
<vn-icon
|
||||||
|
@ -70,6 +69,12 @@
|
||||||
class="bright"
|
class="bright"
|
||||||
icon="icon-risk">
|
icon="icon-risk">
|
||||||
</vn-icon>
|
</vn-icon>
|
||||||
|
<vn-icon
|
||||||
|
ng-show="::ticket.hasComponentLack"
|
||||||
|
translate-attr="{title: 'Component lack'}"
|
||||||
|
class="bright"
|
||||||
|
icon="icon-components">
|
||||||
|
</vn-icon>
|
||||||
</vn-td>
|
</vn-td>
|
||||||
<vn-td shrink>{{::ticket.id}}</vn-td>
|
<vn-td shrink>{{::ticket.id}}</vn-td>
|
||||||
<vn-td class="expendable">
|
<vn-td class="expendable">
|
||||||
|
|
|
@ -10,4 +10,5 @@ Exclude selection: Excluir selección
|
||||||
Remove filter: Quitar filtro por selección
|
Remove filter: Quitar filtro por selección
|
||||||
Remove all filters: Eliminar todos los filtros
|
Remove all filters: Eliminar todos los filtros
|
||||||
Copy value: Copiar valor
|
Copy value: Copiar valor
|
||||||
No verified data: Sin datos comprobados
|
No verified data: Sin datos comprobados
|
||||||
|
Component lack: Faltan componentes
|
|
@ -59,6 +59,7 @@
|
||||||
</vn-th>
|
</vn-th>
|
||||||
<vn-th shrink></vn-th>
|
<vn-th shrink></vn-th>
|
||||||
<vn-th shrink></vn-th>
|
<vn-th shrink></vn-th>
|
||||||
|
<vn-th number shrink>Available</vn-th>
|
||||||
<vn-th shrink id="ticketId">Id</vn-th>
|
<vn-th shrink id="ticketId">Id</vn-th>
|
||||||
<vn-th shrink>Quantity</vn-th>
|
<vn-th shrink>Quantity</vn-th>
|
||||||
<vn-th>Item</vn-th>
|
<vn-th>Item</vn-th>
|
||||||
|
@ -82,14 +83,26 @@
|
||||||
</vn-icon>
|
</vn-icon>
|
||||||
</a>
|
</a>
|
||||||
<vn-icon
|
<vn-icon
|
||||||
ng-show="::(sale.visible < 0 || sale.available < 0)"
|
ng-show="::(sale.visible < 0)"
|
||||||
color-main
|
color-main
|
||||||
icon="warning"
|
icon="warning"
|
||||||
vn-tooltip="Visible: {{::sale.visible || 0}} <br> {{::$ctrl.$t('Available')}}: {{::sale.available || 0}}">
|
vn-tooltip="Visible: {{::sale.visible || 0}}">
|
||||||
</vn-icon>
|
</vn-icon>
|
||||||
<vn-icon ng-show="sale.reserved"
|
<vn-icon ng-show="sale.reserved"
|
||||||
icon="icon-reserve"
|
icon="icon-reserve"
|
||||||
vn-tooltip="{{::$ctrl.$t('Reserved')}}">
|
translate-attr="{title: 'Reserved'}">
|
||||||
|
</vn-icon>
|
||||||
|
<vn-icon
|
||||||
|
ng-show="::sale.isAvailable === 0"
|
||||||
|
translate-attr="{title: 'Not available'}"
|
||||||
|
class="bright"
|
||||||
|
icon="icon-unavailable">
|
||||||
|
</vn-icon>
|
||||||
|
<vn-icon
|
||||||
|
ng-show="::sale.hasComponentLack"
|
||||||
|
translate-attr="{title: 'Component lack'}"
|
||||||
|
class="bright"
|
||||||
|
icon="icon-components">
|
||||||
</vn-icon>
|
</vn-icon>
|
||||||
</vn-td>
|
</vn-td>
|
||||||
<vn-td shrink>
|
<vn-td shrink>
|
||||||
|
@ -98,6 +111,13 @@
|
||||||
zoom-image="{{::$root.imagePath('catalog', '1600x900', sale.itemFk)}}"
|
zoom-image="{{::$root.imagePath('catalog', '1600x900', sale.itemFk)}}"
|
||||||
on-error-src/>
|
on-error-src/>
|
||||||
</vn-td>
|
</vn-td>
|
||||||
|
<vn-td number shrink>
|
||||||
|
<vn-chip
|
||||||
|
class="transparent"
|
||||||
|
ng-class="{'message': sale.available < 0}">
|
||||||
|
{{::sale.available}}
|
||||||
|
</vn-chip>
|
||||||
|
</vn-td>
|
||||||
<vn-td shrink>
|
<vn-td shrink>
|
||||||
<span class="link" ng-if="sale.id"
|
<span class="link" ng-if="sale.id"
|
||||||
ng-click="itemDescriptor.show($event, sale.itemFk, sale.id)">
|
ng-click="itemDescriptor.show($event, sale.itemFk, sale.id)">
|
||||||
|
|
|
@ -138,7 +138,28 @@
|
||||||
vn-tooltip="{{::$ctrl.$t('Claim')}}: {{::sale.claimBeginning.claimFk}}">
|
vn-tooltip="{{::$ctrl.$t('Claim')}}: {{::sale.claimBeginning.claimFk}}">
|
||||||
</vn-icon>
|
</vn-icon>
|
||||||
</a>
|
</a>
|
||||||
<vn-icon ng-show="sale.reserved" icon="icon-reserva"></vn-icon>
|
<vn-icon
|
||||||
|
ng-show="::(sale.visible < 0)"
|
||||||
|
color-main
|
||||||
|
icon="warning"
|
||||||
|
vn-tooltip="Visible: {{::sale.visible || 0}}">
|
||||||
|
</vn-icon>
|
||||||
|
<vn-icon ng-show="sale.reserved"
|
||||||
|
icon="icon-reserve"
|
||||||
|
translate-attr="{title: 'Reserved'}">
|
||||||
|
</vn-icon>
|
||||||
|
<vn-icon
|
||||||
|
ng-show="::sale.isAvailable === 0"
|
||||||
|
translate-attr="{title: 'Not available'}"
|
||||||
|
class="bright"
|
||||||
|
icon="icon-unavailable">
|
||||||
|
</vn-icon>
|
||||||
|
<vn-icon
|
||||||
|
ng-show="::sale.hasComponentLack"
|
||||||
|
translate-attr="{title: 'Component lack'}"
|
||||||
|
class="bright"
|
||||||
|
icon="icon-components">
|
||||||
|
</vn-icon>
|
||||||
</vn-td>
|
</vn-td>
|
||||||
<vn-td number shrink>
|
<vn-td number shrink>
|
||||||
<span
|
<span
|
||||||
|
@ -148,7 +169,10 @@
|
||||||
</span>
|
</span>
|
||||||
</vn-td>
|
</vn-td>
|
||||||
<vn-td number shrink>
|
<vn-td number shrink>
|
||||||
<vn-chip class="transparent" ng-class="{'message': sale.available < 0}">{{::sale.available}}
|
<vn-chip
|
||||||
|
class="transparent"
|
||||||
|
ng-class="{'message': sale.available < 0}">
|
||||||
|
{{::sale.available}}
|
||||||
</vn-chip>
|
</vn-chip>
|
||||||
</vn-td>
|
</vn-td>
|
||||||
<vn-td number shrink>{{::sale.quantity}}</vn-td>
|
<vn-td number shrink>{{::sale.quantity}}</vn-td>
|
||||||
|
@ -218,7 +242,11 @@
|
||||||
<vn-td number shrink>{{::service.quantity}}</vn-td>
|
<vn-td number shrink>{{::service.quantity}}</vn-td>
|
||||||
<vn-td expand>{{::service.description}}</vn-td>
|
<vn-td expand>{{::service.description}}</vn-td>
|
||||||
<vn-td number shrink>{{::service.price | currency: 'EUR':2}}</vn-td>
|
<vn-td number shrink>{{::service.price | currency: 'EUR':2}}</vn-td>
|
||||||
<vn-td class="tax-class"><span title="{{::service.taxClass.description}}">{{::service.taxClass.description}}</span></vn-td>
|
<vn-td class="tax-class">
|
||||||
|
<span title="{{::service.taxClass.description}}">
|
||||||
|
{{::service.taxClass.description}}
|
||||||
|
</span>
|
||||||
|
</vn-td>
|
||||||
<vn-td number>{{::service.quantity * service.price | currency: 'EUR':2}}</vn-td>
|
<vn-td number>{{::service.quantity * service.price | currency: 'EUR':2}}</vn-td>
|
||||||
</vn-tr>
|
</vn-tr>
|
||||||
</vn-tbody>
|
</vn-tbody>
|
||||||
|
|
Loading…
Reference in New Issue