This commit is contained in:
Bernat 2019-11-05 08:56:59 +01:00
commit 1be61b16d5
167 changed files with 2579 additions and 487 deletions

View File

@ -1,4 +1,4 @@
FROM mysql:5.6
FROM mysql:5.6.42
ENV MYSQL_ROOT_PASSWORD root
ENV TZ Europe/Madrid
@ -9,7 +9,7 @@ RUN apt-get update \
&& curl -sL https://apt.verdnatura.es/conf/verdnatura.gpg | apt-key add - \
&& echo "deb http://apt.verdnatura.es/ jessie main" > /etc/apt/sources.list.d/vn.list \
&& apt-get update \
&& apt-get install -y vn-mysql \
&& apt-get install -y --allow-unauthenticated vn-mysql \
&& apt-get purge -y --auto-remove curl ca-certificates \
&& rm -rf /var/lib/apt/lists/*

View File

@ -0,0 +1,117 @@
DROP procedure IF EXISTS `vn`.`catalog_calculate`;
DELIMITER $$
CREATE DEFINER=`root`@`%` PROCEDURE `vn`.`catalog_calculate`(
vLanded DATE,
vAddressFk INT,
vAgencyModeFk INT)
proc: BEGIN
/**
* Calcula los articulos disponibles y sus precios
*
* @table tmp.item(itemFk) Listado de artículos a calcular
* @param vLanded Fecha de recepcion de mercancia
* @param vAddressFk Id del consignatario
* @param vAgencyModeFk Id de la agencia
* @return tmp.ticketCalculateItem(itemFk, available, producer,
* item, size, stems, category, inkFk, image, origin, price)
* @return tmp.ticketLot(warehouseFk, itemFk, available, buyFk)
* @return tmp.ticketComponent
* @return tmp.ticketComponentPrice
* @return tmp.zoneGetShipped
**/
DECLARE vAvailableCalc INT;
DECLARE vShipped DATE;
DECLARE vClient INT;
DECLARE vWarehouseFk SMALLINT;
DECLARE vZoneFk INT;
DECLARE vDone BOOL;
DECLARE cTravelTree CURSOR FOR
SELECT zoneFk, warehouseFk, shipped FROM tmp.zoneGetShipped;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET vDone = TRUE;
-- Establece los almacenes y las fechas que van a entrar al disponible
SELECT clientFk INTO vClient
FROM address WHERE id = vAddressFk;
CALL vn.zoneGetShippedWarehouse(vLanded, vAddressFk, vAgencyModeFk);
DROP TEMPORARY TABLE IF EXISTS tmp.ticketLot;
CREATE TEMPORARY TABLE tmp.ticketLot(
`warehouseFk` smallint(5) unsigned NOT NULL,
`itemFk` int(11) NOT NULL,
`available` double DEFAULT NULL,
`buyFk` int(11) DEFAULT NULL,
`fix` tinyint(3) unsigned DEFAULT '0',
KEY `itemFk` (`itemFk`),
KEY `item_warehouse` (`itemFk`,`warehouseFk`) USING HASH
) ENGINE=MEMORY DEFAULT CHARSET=utf8;
OPEN cTravelTree;
l: LOOP
SET vDone = FALSE;
FETCH cTravelTree INTO vZoneFk, vWarehouseFk, vShipped;
IF vDone THEN
LEAVE l;
END IF;
CALL `cache`.available_refresh (vAvailableCalc, FALSE, vWarehouseFk, vShipped);
CALL buyUltimate (vWarehouseFk, vShipped);
INSERT INTO tmp.ticketLot (warehouseFk, itemFk, available, buyFk)
SELECT vWarehouseFk,
i.item_id,
IFNULL(i.available, 0),
bu.buyFk
FROM `cache`.available i
JOIN tmp.item br ON br.itemFk = i.item_id
LEFT JOIN item it ON it.id = i.item_id
LEFT JOIN tmp.buyUltimate bu ON bu.itemFk = i.item_id
WHERE i.calc_id = vAvailableCalc
AND it.id != 100
AND i.available > 0;
DROP TEMPORARY TABLE tmp.buyUltimate;
END LOOP;
CLOSE cTravelTree;
CALL vn.catalog_componentCalculate(vZoneFk, vAddressFk, vShipped);
DROP TEMPORARY TABLE IF EXISTS tmp.ticketCalculateItem;
CREATE TEMPORARY TABLE tmp.ticketCalculateItem
ENGINE = MEMORY
SELECT
b.itemFk,
SUM(b.available) available,
p.name producer,
i.name item,
i.size size,
i.stems,
i.category,
i.inkFk,
i.image,
o.code origin,
bl.price,
bl.priceKg
FROM tmp.ticketLot b
JOIN item i ON b.itemFk = i.id
LEFT JOIN producer p ON p.id = i.producerFk AND p.isVisible
JOIN origin o ON o.id = i.originFk
JOIN (
SELECT MIN(price) price, itemFk, priceKg
FROM tmp.ticketComponentPrice
GROUP BY itemFk
) bl ON bl.itemFk = b.itemFk
GROUP BY b.itemFk;
END$$
DELIMITER ;

View File

@ -4,7 +4,7 @@ DELIMITER $$
CREATE DEFINER=`root`@`%` PROCEDURE `vn`.`zone_getAvailable`(vAddress INT, vLanded DATE)
BEGIN
CALL zone_getFromGeo(address_getGeo(vAddress));
CALL zone_getOptionsForDate(vLanded);
CALL zone_getOptionsForLanding(vLanded);
SELECT * FROM tmp.zoneOption;

View File

@ -1,7 +1,7 @@
DROP PROCEDURE IF EXISTS `vn`.`zone_getOptionsForDate`;
DROP PROCEDURE IF EXISTS `vn`.`zone_getOptionsForLanding`;
DELIMITER $$
CREATE DEFINER=`root`@`%` PROCEDURE `vn`.`zone_getOptionsForDate`(vLanded DATE)
CREATE DEFINER=`root`@`%` PROCEDURE `vn`.`zone_getOptionsForLanding`(vLanded DATE)
BEGIN
/**
* Gets computed options for the passed zones and delivery date.

View File

@ -0,0 +1,42 @@
USE `vn`;
DROP procedure IF EXISTS `zone_getAgency`;
DELIMITER $$
USE `vn`$$
CREATE DEFINER=`root`@`%` PROCEDURE `zone_getAgency`(vAddress INT, vLanded DATE)
BEGIN
/**
* Devuelve el listado de agencias disponibles para la fecha
* y dirección pasadas.
*
* @param vAddress Id de dirección de envío, %NULL si es recogida
* @param vLanded Fecha de recogida
* @select Listado de agencias disponibles
*/
CALL zone_getFromGeo(address_getGeo(vAddress));
CALL zone_getOptionsForLanding(vLanded);
DROP TEMPORARY TABLE IF EXISTS tmp.zoneGetAgency;
CREATE TEMPORARY TABLE tmp.zoneGetAgency
(INDEX (agencyModeFk)) ENGINE = MEMORY
SELECT am.name agencyMode,
am.description,
z.agencyModeFk,
am.deliveryMethodFk,
TIMESTAMPADD(DAY,-zo.travelingDays, vLanded) shipped,
TRUE isIncluded,
zo.zoneFk
FROM tmp.zoneOption zo
JOIN zone z ON z.id = zo.zoneFk
JOIN agencyMode am ON am.id = z.agencyModeFk
GROUP BY agencyModeFk;
DROP TEMPORARY TABLE
tmp.zone,
tmp.zoneOption;
END$$
DELIMITER ;

View File

@ -0,0 +1,25 @@
USE `vn`;
DROP procedure IF EXISTS `zone_getFirstShipped`;
DELIMITER $$
USE `vn`$$
CREATE DEFINER=`root`@`%` PROCEDURE `zone_getFirstShipped`(vAgencyModeFk INT, vAddress INT, vWarehouseFk INT)
BEGIN
/**
* Devuelve la primera fecha de envio disponible para una agencia en una direccion y un warehouse
*
* @param vAgencyMode id de la agencia en vn.agencyMode
* @param vAddress id de la direccion
* @param vWarehouse id del warehouse
* @return vShipped la primera fecha disponible y vLanded la fecha de llegada/recojida
*/
SELECT CURDATE() shipped, CURDATE() landed, TRUE isIncluded;
/*
?? No hay landing
*/
END$$
DELIMITER ;

View File

@ -0,0 +1,37 @@
USE `vn`;
DROP procedure IF EXISTS `zone_getLanded`;
DELIMITER $$
USE `vn`$$
CREATE DEFINER=`root`@`%` PROCEDURE `zone_getLanded`(vShipped DATE, vAddressFk INT, vAgencyModeFk INT, vWarehouseFk INT)
BEGIN
/**
* Devuelve una tabla temporal con el dia de recepcion para vShipped.
*
* @param vShipped Fecha de preparacion de mercancia
* @param vAddressFk Id de consignatario, %NULL para recogida
* @param vAgencyModeFk Id agencia
* @param vWarehouseFk vWarehouseFk
* @table tmp.zoneGetLanded Datos de recepción
*/
CALL zone_getFromGeo(address_getGeo(vAddressFk));
CALL zone_getOptionsForLanding(vShipped);
DROP TEMPORARY TABLE IF EXISTS tmp.zoneGetLanded;
CREATE TEMPORARY TABLE tmp.zoneGetLanded
ENGINE = MEMORY
SELECT vWarehouseFk warehouseFk,
TIMESTAMPADD(DAY,zo.travelingDays, vShipped) landed,
zo.zoneFk
FROM tmp.zoneOption zo
JOIN zone z ON z.id = zo.zoneFk
WHERE agencyModeFk = vAgencyModeFk;
DROP TEMPORARY TABLE
tmp.zone,
tmp.zoneOption;
END$$
DELIMITER ;

View File

@ -0,0 +1,38 @@
USE `vn`;
DROP procedure IF EXISTS `zone_getShippedWarehouse`;
DELIMITER $$
USE `vn`$$
CREATE DEFINER=`root`@`%` PROCEDURE `zone_getShippedWarehouse`(vLanded DATE, vAddressFk INT, vAgencyModeFk INT)
BEGIN
/**
* Devuelve la ­nima fecha de envío para cada warehouse
*
* @param vLanded La fecha de recepcion
* @param vAddressFk Id del consignatario
* @param vAgencyModeFk Id de la agencia
* @return tmp.zoneGetShipped
*/
CALL zone_getFromGeo(address_getGeo(vAddressFk));
CALL zone_getOptionsForLanding(vLanded);
DROP TEMPORARY TABLE IF EXISTS tmp.zoneGetShipped;
CREATE TEMPORARY TABLE tmp.zoneGetShipped
ENGINE = MEMORY
SELECT * FROM (
SELECT zo.zoneFk,
TIMESTAMPADD(DAY,-zo.travelingDays, vLanded) shipped,
zw.warehouseFk
FROM tmp.zoneOption zo
JOIN zoneWarehouse zw ON zw.zoneFk = zo.zoneFk
ORDER BY shipped) t
GROUP BY warehouseFk;
DROP TEMPORARY TABLE
tmp.zone,
tmp.zoneOption;
END$$
DELIMITER ;

View File

@ -0,0 +1,39 @@
USE `vn`;
DROP procedure IF EXISTS `vn`.`zoneGetWarehouse`;
DELIMITER $$
USE `vn`$$
CREATE DEFINER=`root`@`%` PROCEDURE `zone_getWarehouse`(vAddress INT, vLanded DATE, vWarehouse INT)
BEGIN
/**
* Devuelve el listado de agencias disponibles para la fecha,
* dirección y warehouse pasadas
*
* @param vAddress
* @param vWarehouse warehouse
* @param vLanded Fecha de recogida
* @select Listado de agencias disponibles
*/
CALL zone_getFromGeo(address_getGeo(vAddress));
CALL zone_getOptionsForLanding(vLanded);
SELECT am.id agencyModeFk,
am.name agencyMode,
am.description,
am.deliveryMethodFk,
TIMESTAMPADD(DAY, -zo.travelingDays, vLanded) shipped,
zw.warehouseFk,
z.id zoneFk
FROM tmp.zoneOption zo
JOIN zone z ON z.id = zo.zoneFk
JOIN agencyMode am ON am.id = z.agencyModeFk
JOIN zoneWarehouse zw ON zw.zoneFk = zo.zoneFk
WHERE zw.warehouseFk
GROUP BY z.agencyModeFk;
END$$
DELIMITER ;
;

View File

@ -0,0 +1,60 @@
USE `vn`;
DROP procedure IF EXISTS `vn`.`zoneGetAgency`;
DELIMITER $$
USE `vn`$$
CREATE DEFINER=`root`@`%` PROCEDURE `zoneGetAgency__`(vAddress INT, vLanded DATE)
BEGIN
/**
* OBSOLETO USAR vn.zone_getAvailable
* Devuelve el listado de agencias disponibles para la fecha
* y dirección pasadas.
*
* @param vAddress Id de dirección de envío, %NULL si es recogida
* @param vDate Fecha de recogida
* @select Listado de agencias disponibles
*/
DECLARE vGeoFk INT;
SELECT p.geoFk INTO vGeoFk
FROM address a
JOIN town t ON t.provinceFk = a.provinceFk
JOIN postCode p ON p.townFk = t.id AND p.code = a.postalCode
WHERE a.id = vAddress
ORDER BY (a.city SOUNDS LIKE t.`name`) DESC
LIMIT 1;
DROP TEMPORARY TABLE IF EXISTS tmp.zoneGetAgency;
CREATE TEMPORARY TABLE tmp.zoneGetAgency
(INDEX (agencyModeFk)) ENGINE = MEMORY
SELECT * FROM (
SELECT * FROM (
SELECT am.id agencyModeFk,
am.name agencyMode,
am.description,
am.deliveryMethodFk,
TIMESTAMPADD(DAY,-z.travelingDays, vLanded) shipped,
zi.isIncluded,
z.warehouseFk,
z.id zoneFk
FROM zoneGeo zgSon
JOIN zoneGeo zgFather ON zgSon.lft BETWEEN zgFather.lft AND zgFather.rgt
JOIN zoneIncluded zi ON zi.geoFk = zgFather.id
JOIN zone z ON z.id = zi.zoneFk
JOIN zoneCalendar zc ON zc.zoneFk = z.id
JOIN agencyMode am ON am.id = z.agencyModeFk
WHERE zgSon.`id` = vGeoFk
AND zc.delivered = vLanded
AND TIMESTAMPADD(DAY,-z.travelingDays, vLanded) >= CURDATE()
AND IF(TIMESTAMPADD(DAY,-z.travelingDays, vLanded) = CURDATE(), hour(now()) < hour(z.`hour`),TRUE)
ORDER BY z.id, zgFather.depth DESC, zi.isIncluded DESC) t
GROUP BY zoneFk
HAVING isIncluded > 0
ORDER BY shipped) t
GROUP BY agencyModeFk;
END$$
DELIMITER ;
;

View File

@ -0,0 +1,48 @@
USE `vn`;
DROP procedure IF EXISTS `vn`.`zoneGetFirstShipped`;
DELIMITER $$
USE `vn`$$
CREATE DEFINER=`root`@`%` PROCEDURE `zoneGetFirstShipped__`(vAgencyModeFk INT, vAddress INT, vWarehouseFk INT)
BEGIN
/**
* Devuelve la primera fecha de envio disponible para una agencia en una direccion y un warehouse
*
* @param vAgencyMode id de la agencia en vn.agencyMode
* @param vAddress id de la direccion
* @param vWarehouse id del warehouse
* @return vShipped la primera fecha disponible y vLanded la fecha de llegada/recojida
*/
DECLARE vGeoFk INT;
SELECT p.geoFk INTO vGeoFk
FROM address a
JOIN town t ON t.provinceFk = a.provinceFk
JOIN postCode p ON p.townFk = t.id AND p.code = a.postalCode
WHERE a.id = vAddress
ORDER BY (a.city SOUNDS LIKE t.`name`) DESC
LIMIT 1;
SELECT * FROM (
SELECT TIMESTAMPADD(DAY,-z.travelingDays, zc.delivered) shipped,
zc.delivered landed,
zi.isIncluded
FROM zoneGeo zgSon
JOIN zoneGeo zgFather ON zgSon.lft BETWEEN zgFather.lft AND zgFather.rgt
JOIN zoneIncluded zi ON zi.geoFk = zgFather.id
JOIN zone z ON z.id = zi.zoneFk
JOIN zoneCalendar zc ON zc.zoneFk = z.id
WHERE zgSon.`id` = vGeoFk
AND z.agencyModeFk = vAgencyModeFk
AND z.warehouseFk = vWarehouseFk
AND TIMESTAMPADD(DAY,-z.travelingDays, zc.delivered) >= CURDATE()
AND IF(TIMESTAMPADD(DAY,-z.travelingDays, zc.delivered) = CURDATE(), hour(now()) < hour(z.`hour`),TRUE)
ORDER BY landed ASC, zgFather.depth DESC) t
HAVING isIncluded > 0 LIMIT 1;
END$$
DELIMITER ;
;

View File

@ -0,0 +1,51 @@
USE `vn`;
DROP procedure IF EXISTS `vn`.`zoneGetLanded`;
DELIMITER $$
USE `vn`$$
CREATE DEFINER=`root`@`%` PROCEDURE `zoneGetLanded__`(vShipped DATE, vAddressFk INT, vAgencyModeFk INT, vWarehouseFk INT)
BEGIN
/**
* Devuelve una tabla temporal con el dia de recepcion para vShipped.
*
* @param vShipped Fecha de preparacion de mercancia
* @param vAddressFk Id de consignatario, %NULL para recogida
* @param vAgencyModeFk Id agencia
* @table tmp.zoneGetLanded Datos de recepción
*/
DECLARE vPostalCode varchar(10);
SELECT postalCode INTO vPostalCode
FROM address WHERE id = vAddressFk;
DROP TEMPORARY TABLE IF EXISTS tmp.zoneGetLanded;
CREATE TEMPORARY TABLE tmp.zoneGetLanded
ENGINE = MEMORY
SELECT
id zoneFk,
vShipped shipped,
delivered landed,
vWarehouseFk warehouseFk,
agencyModeFk,
isIncluded
FROM (
SELECT zi.isIncluded, zc.delivered, z.id, z.agencyModeFk
FROM vn.zoneGeo zgSon
JOIN vn.zoneGeo zgFather ON zgSon.lft BETWEEN zgFather.lft AND zgFather.rgt
JOIN zoneIncluded zi ON zi.geoFk = zgFather.id
JOIN zone z ON z.id = zi.zoneFk
JOIN zoneCalendar zc ON zc.zoneFk = z.id
WHERE zgSon.`name` LIKE vPostalCode
AND zc.delivered = TIMESTAMPADD(DAY,z.travelingDays, vShipped)
AND IF(vShipped = CURDATE(), hour(now()) < hour(z.`hour`),TRUE)
AND z.agencyModeFk = vAgencyModeFk
AND z.warehouseFk = vWarehouseFk
ORDER BY zgFather.depth DESC) t
GROUP BY zoneFk
HAVING isIncluded > 0
LIMIT 1;
END$$
DELIMITER ;
;

View File

@ -0,0 +1,54 @@
USE `vn`;
DROP procedure IF EXISTS `vn`.`zoneGetShippedWarehouse`;
DELIMITER $$
USE `vn`$$
CREATE DEFINER=`root`@`%` PROCEDURE `zoneGetShippedWarehouse__`(vLanded DATE, vAddressFk INT, vAgencyModeFk INT)
BEGIN
/**
* Devuelve la mínima fecha de envío para cada warehouse
*
* @param vLanded La fecha de recepcion
* @param vAddressFk Id del consignatario
* @param vAgencyModeFk Id de la agencia
* @return tmp.zoneGetShipped
*/
DECLARE vGeoFk INT;
SELECT p.geoFk INTO vGeoFk
FROM address a
JOIN town t ON t.provinceFk = a.provinceFk
JOIN postCode p ON p.townFk = t.id AND p.code = a.postalCode
WHERE a.id = vAddressFk
ORDER BY (a.city SOUNDS LIKE t.`name`) DESC
LIMIT 1;
DROP TEMPORARY TABLE IF EXISTS tmp.zoneGetShipped;
CREATE TEMPORARY TABLE tmp.zoneGetShipped
ENGINE = MEMORY
SELECT * FROM (
SELECT * FROM (
SELECT z.id,
TIMESTAMPADD(DAY,-z.travelingDays, vLanded) shipped,
zi.isIncluded,z.warehouseFk
FROM zoneGeo zgSon
JOIN zoneGeo zgFather ON zgSon.lft BETWEEN zgFather.lft AND zgFather.rgt
JOIN zoneIncluded zi ON zi.geoFk = zgFather.id
JOIN zone z ON z.id = zi.zoneFk
JOIN zoneCalendar zc ON zc.zoneFk = z.id
WHERE zgSon.`id` = vGeoFk
AND zc.delivered = vLanded
AND z.agencyModeFk = vAgencyModeFk
AND IF(TIMESTAMPADD(DAY,-z.travelingDays, vLanded) = CURDATE(), hour(now()) < hour(z.`hour`),TRUE)
ORDER BY z.id, shipped ASC, zgFather.depth DESC, zi.isIncluded DESC) t
GROUP BY warehouseFk, id
HAVING isIncluded > 0
ORDER BY shipped) t
GROUP BY warehouseFk;
END$$
DELIMITER ;
;

View File

@ -0,0 +1,50 @@
USE `vn`;
DROP procedure IF EXISTS `vn`.`zoneGetShipped`;
DELIMITER $$
USE `vn`$$
CREATE DEFINER=`root`@`%` PROCEDURE `zoneGetShipped__`(vLanded DATE, vAddressFk INT, vAgencyModeFk INT, vWarehouseFk INT)
BEGIN
/**
* Devuelve la ­nima fecha de envía para cada warehouse
*
* @param vLanded La fecha de recepcion
* @param vAddressFk Id del consignatario
* @param vAgencyModeFk Id de la agencia
* @return tmp.zoneGetShipped
*/
DECLARE vPostalCode varchar(10);
SELECT postalCode INTO vPostalCode
FROM address WHERE id = vAddressFk;
SELECT * FROM (
SELECT * FROM (
SELECT z.id zoneFk,
TIMESTAMPADD(DAY,-z.travelingDays, vLanded) shipped,
vLanded landed,
vWarehouseFk warehouseFk,
z.agencyModeFk,
zi.isIncluded
FROM zoneGeo zgSon
JOIN zoneGeo zgFather ON zgSon.lft BETWEEN zgFather.lft AND zgFather.rgt
JOIN zoneIncluded zi ON zi.geoFk = zgFather.id
JOIN zone z ON z.id = zi.zoneFk
JOIN zoneCalendar zc ON zc.zoneFk = z.id
WHERE zgSon.`name` LIKE vPostalCode
AND zc.delivered = vLanded
AND z.agencyModeFk = vAgencyModeFk
AND z.warehouseFk = vWarehouseFk
AND IF(TIMESTAMPADD(DAY,-z.travelingDays, vLanded) = CURDATE(), hour(now()) < hour(z.`hour`),TRUE)
ORDER BY z.id, zgFather.depth DESC, isIncluded DESC) t
GROUP BY zoneFk
HAVING isIncluded > 0
ORDER BY shipped)
t
GROUP BY agencyModeFk;
END$$
DELIMITER ;
;

View File

@ -0,0 +1,63 @@
USE `vn`;
DROP procedure IF EXISTS `available_calc`;
DELIMITER $$
USE `vn`$$
CREATE DEFINER=`root`@`%` PROCEDURE `available_calc`(
vDate DATE,
vAddress INT,
vAgencyMode INT)
BEGIN
/**
* Calculates the available for all available stores
* according to the given parameters.
*
* @param vDate The delivery date
* @param vAddress The delivery address id
* @param vAgencyMode The shipping agency
* @return tmp.availableCalc(calcFk) The available cache ids
*/
DECLARE vCalcFk INT;
DECLARE vShipment DATE;
DECLARE vWarehouse INT;
DECLARE vDone BOOL;
DECLARE cWarehouses CURSOR FOR
SELECT warehouseFk, shipped FROM tmp.zoneGetShipped;
DECLARE CONTINUE HANDLER FOR NOT FOUND
SET vDone = TRUE;
-- Establecemos los almacenes y las fechas que van a entrar al disponible
CALL vn.zone_getShippedWarehouse(vDate, vAddress, vAgencyMode);
DROP TEMPORARY TABLE IF EXISTS tmp.availableCalc;
CREATE TEMPORARY TABLE tmp.availableCalc(
calcFk INT UNSIGNED,
PRIMARY KEY (calcFk)
)
ENGINE = MEMORY;
OPEN cWarehouses;
l: LOOP
SET vDone = FALSE;
FETCH cWarehouses INTO vWarehouse, vShipment;
IF vDone THEN
LEAVE l;
END IF;
CALL `cache`.available_refresh(vCalcFk, FALSE, vWarehouse, vShipment);
INSERT IGNORE INTO tmp.availableCalc
SET calcFk = vCalcFk;
END LOOP;
CLOSE cWarehouses;
DROP TEMPORARY TABLE tmp.zoneGetShipped;
END$$
DELIMITER ;

View File

@ -0,0 +1,119 @@
USE `vn`;
DROP procedure IF EXISTS `catalog_calculate`;
DELIMITER $$
USE `vn`$$
CREATE DEFINER=`root`@`%` PROCEDURE `catalog_calculate`(
vLanded DATE,
vAddressFk INT,
vAgencyModeFk INT)
proc: BEGIN
/**
* Calcula los articulos disponibles y sus precios
*
* @table tmp.item(itemFk) Listado de artículos a calcular
* @param vLanded Fecha de recepcion de mercancia
* @param vAddressFk Id del consignatario
* @param vAgencyModeFk Id de la agencia
* @return tmp.ticketCalculateItem(itemFk, available, producer,
* item, size, stems, category, inkFk, image, origin, price)
* @return tmp.ticketLot(warehouseFk, itemFk, available, buyFk)
* @return tmp.ticketComponent
* @return tmp.ticketComponentPrice
* @return tmp.zoneGetShipped
**/
DECLARE vAvailableCalc INT;
DECLARE vShipped DATE;
DECLARE vClient INT;
DECLARE vWarehouseFk SMALLINT;
DECLARE vZoneFk INT;
DECLARE vDone BOOL;
DECLARE cTravelTree CURSOR FOR
SELECT zoneFk, warehouseFk, shipped FROM tmp.zoneGetShipped;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET vDone = TRUE;
-- Establece los almacenes y las fechas que van a entrar al disponible
SELECT clientFk INTO vClient
FROM address WHERE id = vAddressFk;
CALL vn.zone_getShippedWarehouse(vLanded, vAddressFk, vAgencyModeFk);
DROP TEMPORARY TABLE IF EXISTS tmp.ticketLot;
CREATE TEMPORARY TABLE tmp.ticketLot(
`warehouseFk` smallint(5) unsigned NOT NULL,
`itemFk` int(11) NOT NULL,
`available` double DEFAULT NULL,
`buyFk` int(11) DEFAULT NULL,
`fix` tinyint(3) unsigned DEFAULT '0',
KEY `itemFk` (`itemFk`),
KEY `item_warehouse` (`itemFk`,`warehouseFk`) USING HASH
) ENGINE=MEMORY DEFAULT CHARSET=utf8;
OPEN cTravelTree;
l: LOOP
SET vDone = FALSE;
FETCH cTravelTree INTO vZoneFk, vWarehouseFk, vShipped;
IF vDone THEN
LEAVE l;
END IF;
CALL `cache`.available_refresh (vAvailableCalc, FALSE, vWarehouseFk, vShipped);
CALL buyUltimate (vWarehouseFk, vShipped);
INSERT INTO tmp.ticketLot (warehouseFk, itemFk, available, buyFk)
SELECT vWarehouseFk,
i.item_id,
IFNULL(i.available, 0),
bu.buyFk
FROM `cache`.available i
JOIN tmp.item br ON br.itemFk = i.item_id
LEFT JOIN item it ON it.id = i.item_id
LEFT JOIN tmp.buyUltimate bu ON bu.itemFk = i.item_id
WHERE i.calc_id = vAvailableCalc
AND it.id != 100
AND i.available > 0;
DROP TEMPORARY TABLE tmp.buyUltimate;
END LOOP;
CLOSE cTravelTree;
CALL vn.catalog_componentCalculate(vZoneFk, vAddressFk, vShipped);
DROP TEMPORARY TABLE IF EXISTS tmp.ticketCalculateItem;
CREATE TEMPORARY TABLE tmp.ticketCalculateItem
ENGINE = MEMORY
SELECT
b.itemFk,
SUM(b.available) available,
p.name producer,
i.name item,
i.size size,
i.stems,
i.category,
i.inkFk,
i.image,
o.code origin,
bl.price,
bl.priceKg
FROM tmp.ticketLot b
JOIN item i ON b.itemFk = i.id
LEFT JOIN producer p ON p.id = i.producerFk AND p.isVisible
JOIN origin o ON o.id = i.originFk
JOIN (
SELECT MIN(price) price, itemFk, priceKg
FROM tmp.ticketComponentPrice
GROUP BY itemFk
) bl ON bl.itemFk = b.itemFk
GROUP BY b.itemFk;
END$$
DELIMITER ;

View File

@ -0,0 +1,246 @@
USE `hedera`;
DROP procedure IF EXISTS `order_confirmWithUser`;
DELIMITER $$
USE `hedera`$$
CREATE DEFINER=`root`@`%` PROCEDURE `order_confirmWithUser`(IN `vOrder` INT, IN `vUserId` INT)
BEGIN
/**
* Confirms an order, creating each of its tickets on the corresponding
* date, store and user.
*
* @param vOrder The order identifier
* @param vUser The user identifier
*/
DECLARE vOk BOOL;
DECLARE vDone BOOL DEFAULT FALSE;
DECLARE vWarehouse INT;
DECLARE vShipment DATETIME;
DECLARE vTicket INT;
DECLARE vNotes VARCHAR(255);
DECLARE vItem INT;
DECLARE vConcept VARCHAR(30);
DECLARE vAmount INT;
DECLARE vPrice DECIMAL(10,2);
DECLARE vSale INT;
DECLARE vRate INT;
DECLARE vRowId INT;
DECLARE vDelivery DATE;
DECLARE vAddress INT;
DECLARE vIsConfirmed BOOL;
DECLARE vClientId INT;
DECLARE vCompanyId INT;
DECLARE vAgencyModeId INT;
DECLARE TICKET_FREE INT DEFAULT 2;
DECLARE SYSTEM_WORKER INT DEFAULT 20;
DECLARE cDates CURSOR FOR
SELECT zgs.shipped, r.warehouse_id
FROM `order` o
JOIN order_row r ON r.order_id = o.id
LEFT JOIN tmp.zoneGetShipped zgs ON zgs.warehouseFk = r.warehouse_id
WHERE o.id = vOrder AND r.amount != 0
GROUP BY r.warehouse_id;
DECLARE cRows CURSOR FOR
SELECT r.id, r.item_id, a.Article, r.amount, r.price, r.rate
FROM order_row r
JOIN vn2008.Articles a ON a.Id_Article = r.item_id
WHERE r.amount != 0
AND r.warehouse_id = vWarehouse
AND r.order_id = vOrder
ORDER BY r.rate DESC;
DECLARE CONTINUE HANDLER FOR NOT FOUND
SET vDone = TRUE;
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
ROLLBACK;
RESIGNAL;
END;
-- Carga los datos del pedido
SELECT o.date_send, o.address_id, o.note,
o.confirmed, cs.Id_Cliente, o.company_id, o.agency_id
INTO vDelivery, vAddress, vNotes,
vIsConfirmed, vClientId, vCompanyId, vAgencyModeId
FROM hedera.`order` o
JOIN vn2008.Consignatarios cs ON cs.Id_Consigna = o.address_id
WHERE id = vOrder;
-- Comprueba que el pedido no está confirmado
IF vIsConfirmed THEN
CALL util.throw ('ORDER_ALREADY_CONFIRMED');
END IF;
-- Comprueba que el pedido no está vacío
SELECT COUNT(*) > 0 INTO vOk
FROM order_row WHERE order_id = vOrder AND amount > 0;
IF !vOk THEN
CALL util.throw ('ORDER_EMPTY');
END IF;
-- Carga las fechas de salida de cada almacén
CALL vn.zone_getShippedWarehouse (vDelivery, vAddress, vAgencyModeId);
-- Trabajador que realiza la acción
IF vUserId IS NULL THEN
SELECT employeeFk INTO vUserId FROM orderConfig;
END IF;
-- Crea los tickets del pedido
START TRANSACTION;
OPEN cDates;
lDates:
LOOP
SET vTicket = NULL;
SET vDone = FALSE;
FETCH cDates INTO vShipment, vWarehouse;
IF vDone THEN
LEAVE lDates;
END IF;
-- Busca un ticket existente que coincida con los parametros
SELECT Id_Ticket INTO vTicket
FROM vn2008.Tickets t
LEFT JOIN vn.ticketState tls on tls.ticket = t.Id_Ticket
JOIN `order` o
ON o.address_id = t.Id_Consigna
AND vWarehouse = t.warehouse_id
AND o.agency_id = t.Id_Agencia
AND t.landing = o.date_send
AND vShipment = DATE(t.Fecha)
WHERE o.id = vOrder
AND t.Factura IS NULL
AND IFNULL(tls.alertLevel,0) = 0
AND t.Id_Cliente <> 1118
LIMIT 1;
-- Crea el ticket en el caso de no existir uno adecuado
IF vTicket IS NULL
THEN
CALL vn.ticketCreateWithUser(
vClientId,
IFNULL(vShipment, CURDATE()),
vWarehouse,
vCompanyId,
vAddress,
vAgencyModeId,
NULL,
vDelivery,
vUserId,
vTicket
);
ELSE
INSERT INTO vncontrol.inter
SET Id_Ticket = vTicket,
Id_Trabajador = SYSTEM_WORKER,
state_id = TICKET_FREE;
END IF;
INSERT IGNORE INTO vn2008.order_Tickets
SET order_id = vOrder,
Id_Ticket = vTicket;
-- Añade las notas
IF vNotes IS NOT NULL AND vNotes != ''
THEN
INSERT INTO vn2008.ticket_observation SET
Id_Ticket = vTicket,
observation_type_id = 4 /* salesperson */ ,
`text` = vNotes
ON DUPLICATE KEY UPDATE
`text` = CONCAT(VALUES(`text`),'. ', `text`);
END IF;
-- Añade los movimientos y sus componentes
OPEN cRows;
lRows:
LOOP
SET vDone = FALSE;
FETCH cRows INTO vRowId, vItem, vConcept, vAmount, vPrice, vRate;
IF vDone THEN
LEAVE lRows;
END IF;
INSERT INTO vn2008.Movimientos
SET
Id_Article = vItem,
Id_Ticket = vTicket,
Concepte = vConcept,
Cantidad = vAmount,
Preu = vPrice,
CostFixat = 0,
PrecioFijado = TRUE;
SET vSale = LAST_INSERT_ID();
INSERT INTO vn2008.Movimientos_componentes
(Id_Movimiento, Id_Componente, Valor)
SELECT vSale, cm.component_id, cm.price
FROM order_component cm
JOIN bi.tarifa_componentes tc
ON tc.Id_Componente = cm.component_id
WHERE cm.order_row_id = vRowId
GROUP BY vSale, cm.component_id;
UPDATE order_row SET Id_Movimiento = vSale
WHERE id = vRowId;
END LOOP;
CLOSE cRows;
-- Fija el coste
DROP TEMPORARY TABLE IF EXISTS tComponents;
CREATE TEMPORARY TABLE tComponents
(INDEX (saleFk))
ENGINE = MEMORY
SELECT SUM(mc.Valor) valueSum, mc.Id_Movimiento saleFk
FROM vn2008.Movimientos_componentes mc
JOIN bi.tarifa_componentes tc USING(Id_Componente)
JOIN bi.tarifa_componentes_series tcs
ON tcs.tarifa_componentes_series_id = tc.tarifa_componentes_series_id
AND tcs.base
JOIN vn2008.Movimientos m
ON m.Id_Movimiento = mc.Id_Movimiento
WHERE m.Id_Ticket = vTicket
GROUP BY mc.Id_Movimiento;
UPDATE vn2008.Movimientos m
JOIN tComponents mc ON mc.saleFk = m.Id_Movimiento
SET m.CostFixat = valueSum;
DROP TEMPORARY TABLE tComponents;
END LOOP;
CLOSE cDates;
DELETE FROM basketOrder WHERE orderFk = vOrder;
UPDATE `order` SET confirmed = TRUE, confirm_date = NOW()
WHERE id = vOrder;
COMMIT;
END$$
DELIMITER ;

View File

@ -0,0 +1,86 @@
USE `vn`;
DROP procedure IF EXISTS `ticketCalculateClon`;
DELIMITER $$
USE `vn`$$
CREATE DEFINER=`root`@`%` PROCEDURE `ticketCalculateClon`(IN vTicketNew INT, vTicketOld INT)
BEGIN
/*
* @vTicketNew id del nuevo ticket clonado
* @vTicketOld id ticket original, a partir del qual se clonara el nuevo
* Este procedimiento "rebioniza" una linea, eliminando los componentes existentes e insertandolos de nuevo
*/
DECLARE vShipped DATE;
DECLARE vClient INT;
DECLARE vWarehouse SMALLINT;
DECLARE vAgencyMode INT;
DECLARE vAddress INT;
DECLARE vLanded DATE;
DECLARE vAgency INT;
REPLACE INTO orderTicket(orderFk,ticketFk)
SELECT orderFk, vTicketNew
FROM orderTicket
WHERE ticketFk = vTicketOld;
SELECT t.clientFk, t.warehouseFk, date(t.shipped), t.addressFk, t.agencyModeFk, t.landed, a.agencyFk
INTO vClient, vWarehouse, vShipped, vAddress, vAgencyMode, vLanded, vAgency
FROM vn.agencyMode a
JOIN vn.ticket t ON t.agencyModeFk = a.id
WHERE t.id = vTicketNew;
DROP TEMPORARY TABLE IF EXISTS tmp.zoneGetShipped;
CALL zone_getShippedWarehouse(vLanded, vAddress, vAgencyMode);
DELETE FROM tmp.zoneGetShipped WHERE warehouseFk <> vWarehouse;
CALL buyUltimate(vWarehouse, vShipped); -- rellena la tabla tmp.buyUltimate con la ultima compra
DROP TEMPORARY TABLE IF EXISTS tmp.ticketLot;
CREATE TEMPORARY TABLE tmp.ticketLot
SELECT vWarehouse warehouseFk, NULL available, s.itemFk, bu.buyFk
FROM sale s
LEFT JOIN tmp.buyUltimate bu ON bu.itemFk = s.itemFk
WHERE s.ticketFk = vTicketOld GROUP BY s.itemFk;
CALL catalog_componentCalculate(vAddress,vAgencyMode);
-- Bionizamos lineas con Preu = 0
DROP TEMPORARY TABLE IF EXISTS tmp.sale;
CREATE TEMPORARY TABLE tmp.sale
(PRIMARY KEY (saleFk)) ENGINE = MEMORY
SELECT s.id saleFk, vWarehouse warehouseFk
FROM sale s
JOIN ticket t on t.id = s.ticketFk WHERE s.ticketFk = vTicketNew AND s.price = 0;
CALL ticketComponentUpdateSale(1);
-- Bionizamos lineas con Preu > 0
DROP TEMPORARY TABLE IF EXISTS tmp.sale;
CREATE TEMPORARY TABLE tmp.sale
(PRIMARY KEY (saleFk)) ENGINE = MEMORY
SELECT s.id saleFk, vWarehouse warehouseFk
FROM sale s
JOIN ticket t on t.id = s.ticketFk WHERE s.ticketFk = vTicketNew
AND s.price > 0;
CALL ticketComponentUpdateSale(6);
IF vLanded IS NULL THEN
CALL zone_getLanded(vShipped, vAddress, vAgency,vWarehouse);
UPDATE ticket t
JOIN tmp.zoneGetLanded zgl ON t.warehouseFk = zgl.warehouseFk
SET t.landed = zgl.landed
WHERE t.id = vTicketNew;
END IF;
-- Log
CALL `logAdd`(vTicketNew, 'update', ' ticket' , 'Bioniza Ticket');
-- Limpieza
DROP TEMPORARY TABLE IF EXISTS tmp.buyUltimate;
DROP TEMPORARY TABLE IF EXISTS tmp.sale;
DROP TEMPORARY TABLE IF EXISTS tmp.ticketLot;
DROP TEMPORARY TABLE IF EXISTS tmp.zoneGetLanded;
END$$
DELIMITER ;

View File

@ -0,0 +1,86 @@
USE `vn`;
DROP procedure IF EXISTS `ticketCalculateClon`;
DELIMITER $$
USE `vn`$$
CREATE DEFINER=`root`@`%` PROCEDURE `ticketCalculateClon`(IN vTicketNew INT, vTicketOld INT)
BEGIN
/*
* @vTicketNew id del nuevo ticket clonado
* @vTicketOld id ticket original, a partir del qual se clonara el nuevo
* Este procedimiento "rebioniza" una linea, eliminando los componentes existentes e insertandolos de nuevo
*/
DECLARE vShipped DATE;
DECLARE vClient INT;
DECLARE vWarehouse SMALLINT;
DECLARE vAgencyMode INT;
DECLARE vAddress INT;
DECLARE vLanded DATE;
DECLARE vAgency INT;
REPLACE INTO orderTicket(orderFk,ticketFk)
SELECT orderFk, vTicketNew
FROM orderTicket
WHERE ticketFk = vTicketOld;
SELECT t.clientFk, t.warehouseFk, date(t.shipped), t.addressFk, t.agencyModeFk, t.landed, a.agencyFk
INTO vClient, vWarehouse, vShipped, vAddress, vAgencyMode, vLanded, vAgency
FROM vn.agencyMode a
JOIN vn.ticket t ON t.agencyModeFk = a.id
WHERE t.id = vTicketNew;
DROP TEMPORARY TABLE IF EXISTS tmp.zoneGetShipped;
CALL zone_getShippedWarehouse(vLanded, vAddress, vAgencyMode);
DELETE FROM tmp.zoneGetShipped WHERE warehouseFk <> vWarehouse;
CALL buyUltimate(vWarehouse, vShipped); -- rellena la tabla tmp.buyUltimate con la ultima compra
DROP TEMPORARY TABLE IF EXISTS tmp.ticketLot;
CREATE TEMPORARY TABLE tmp.ticketLot
SELECT vWarehouse warehouseFk, NULL available, s.itemFk, bu.buyFk
FROM sale s
LEFT JOIN tmp.buyUltimate bu ON bu.itemFk = s.itemFk
WHERE s.ticketFk = vTicketOld GROUP BY s.itemFk;
CALL catalog_componentCalculate(vAddress,vAgencyMode);
-- Bionizamos lineas con Preu = 0
DROP TEMPORARY TABLE IF EXISTS tmp.sale;
CREATE TEMPORARY TABLE tmp.sale
(PRIMARY KEY (saleFk)) ENGINE = MEMORY
SELECT s.id saleFk, vWarehouse warehouseFk
FROM sale s
JOIN ticket t on t.id = s.ticketFk WHERE s.ticketFk = vTicketNew AND s.price = 0;
CALL ticketComponentUpdateSale(1);
-- Bionizamos lineas con Preu > 0
DROP TEMPORARY TABLE IF EXISTS tmp.sale;
CREATE TEMPORARY TABLE tmp.sale
(PRIMARY KEY (saleFk)) ENGINE = MEMORY
SELECT s.id saleFk, vWarehouse warehouseFk
FROM sale s
JOIN ticket t on t.id = s.ticketFk WHERE s.ticketFk = vTicketNew
AND s.price > 0;
CALL ticketComponentUpdateSale(6);
IF vLanded IS NULL THEN
CALL zone_getLanded(vShipped, vAddress, vAgency,vWarehouse);
UPDATE ticket t
JOIN tmp.zoneGetLanded zgl ON t.warehouseFk = zgl.warehouseFk
SET t.landed = zgl.landed
WHERE t.id = vTicketNew;
END IF;
-- Log
CALL `logAdd`(vTicketNew, 'update', ' ticket' , 'Bioniza Ticket');
-- Limpieza
DROP TEMPORARY TABLE IF EXISTS tmp.buyUltimate;
DROP TEMPORARY TABLE IF EXISTS tmp.sale;
DROP TEMPORARY TABLE IF EXISTS tmp.ticketLot;
DROP TEMPORARY TABLE IF EXISTS tmp.zoneGetLanded;
END$$
DELIMITER ;

View File

@ -0,0 +1,88 @@
USE `vn`;
DROP procedure IF EXISTS `ticketCreateWithUser`;
DELIMITER $$
USE `vn`$$
CREATE DEFINER=`root`@`%` PROCEDURE `ticketCreateWithUser`(
vClientId INT
,vShipped DATE
,vWarehouseFk INT
,vCompanyFk INT
,vAddressFk INT
,vAgencyModeFk INT
,vRouteFk INT
,vlanded DATE
,vUserId INT
,OUT vNewTicket INT)
BEGIN
DECLARE vZoneFk INT;
IF vClientId IS NULL THEN
CALL util.throw ('CLIENT_NOT_ESPECIFIED');
END IF;
IF NOT vAddressFk OR vAddressFk IS NULL THEN
SELECT id INTO vAddressFk
FROM address
WHERE clientFk = vClientId AND isDefaultAddress;
END IF;
IF vAgencyModeFk IS NOT NULL THEN
CALL vn.zone_getShippedWarehouse(vlanded, vAddressFk, vAgencyModeFk);
SELECT zoneFk INTO vZoneFk FROM tmp.zoneGetShipped
WHERE shipped = vShipped AND warehouseFk = vWarehouseFk LIMIT 1;
IF vZoneFk IS NULL OR vZoneFk = 0 THEN
CALL util.throw ('NOT_ZONE_WITH_THIS_PARAMETERS');
END IF;
END IF;
INSERT INTO vn2008.Tickets (
Id_Cliente,
Fecha,
Id_Consigna,
Id_Agencia,
Alias,
warehouse_id,
Id_Ruta,
empresa_id,
landing,
zoneFk
)
SELECT
vClientId,
vShipped,
a.id,
vAgencyModeFk,
a.nickname,
vWarehouseFk,
IF(vRouteFk,vRouteFk,NULL),
vCompanyFk,
vlanded,
vZoneFk
FROM address a
JOIN agencyMode am ON am.id = a.agencyModeFk
WHERE a.id = vAddressFk;
SET vNewTicket = LAST_INSERT_ID();
INSERT INTO ticketObservation(ticketFk, observationTypeFk, description)
SELECT vNewTicket, ao.observationTypeFk, ao.description
FROM addressObservation ao
JOIN address a ON a.id = ao.addressFk
WHERE a.id = vAddressFk;
INSERT INTO vn.ticketLog
SET originFk = vNewTicket, userFk = vUserId, `action` = 'insert', description = CONCAT('Ha creado el ticket:', ' ', vNewTicket);
IF (SELECT ct.isCreatedAsServed FROM vn.clientType ct JOIN vn.client c ON c.typeFk = ct.code WHERE c.id = vClientId ) <> FALSE THEN
INSERT INTO vncontrol.inter(state_id, Id_Ticket, Id_Trabajador)
SELECT id, vNewTicket, getWorker()
FROM state
WHERE `code` = 'DELIVERED';
END IF;
END$$
DELIMITER ;

View File

@ -0,0 +1,90 @@
USE `vn`;
DROP procedure IF EXISTS `ticketCreateWithoutZone`;
DELIMITER $$
USE `vn`$$
CREATE DEFINER=`root`@`%` PROCEDURE `ticketCreateWithoutZone`(
vClientId INT
,vShipped DATE
,vWarehouseFk INT
,vCompanyFk INT
,vAddressFk INT
,vAgencyModeFk INT
,vRouteFk INT
,vlanded DATE
,vUserId INT
,OUT vNewTicket INT)
BEGIN
DECLARE vZoneFk INT;
IF vClientId IS NULL THEN
CALL util.throw ('CLIENT_NOT_ESPECIFIED');
END IF;
IF NOT vAddressFk OR vAddressFk IS NULL THEN
SELECT id INTO vAddressFk
FROM address
WHERE clientFk = vClientId AND isDefaultAddress;
END IF;
IF NOT vAgencyModeFk OR vAgencyModeFk IS NULL THEN
SELECT agencyModeFk INTO vAgencyModeFk
FROM address
WHERE clientFk = vClientId AND isDefaultAddress;
END IF;
CALL vn.zone_getShippedWarehouse(vlanded, vAddressFk, vAgencyModeFk);
SELECT id INTO vZoneFk FROM tmp.zoneGetShipped
WHERE shipped = vShipped AND warehouseFk = vWarehouseFk LIMIT 1;
INSERT INTO vn2008.Tickets (
Id_Cliente,
Fecha,
Id_Consigna,
Id_Agencia,
Alias,
warehouse_id,
Id_Ruta,
empresa_id,
landing,
zoneFk
)
SELECT
vClientId,
vShipped,
a.id,
IF(vAgencyModeFk, vAgencyModeFk, a.agencyModeFk),
a.nickname,
vWarehouseFk,
IF(vRouteFk,vRouteFk,NULL),
vCompanyFk,
vlanded,
vZoneFk
FROM address a
JOIN agencyMode am ON am.id = a.agencyModeFk
WHERE a.id = vAddressFk;
SET vNewTicket = LAST_INSERT_ID();
INSERT INTO ticketObservation(ticketFk, observationTypeFk, description)
SELECT vNewTicket, ao.observationTypeFk, ao.description
FROM addressObservation ao
JOIN address a ON a.id = ao.addressFk
WHERE a.id = vAddressFk;
-- CALL logAddWithUser(vNewTicket, vUserId, 'insert', 'ticket', CONCAT('Ha creado el ticket', ' ', vNewTicket));
INSERT INTO vn.ticketLog
SET originFk = vNewTicket, userFk = vUserId, `action` = 'insert', description = CONCAT('Ha creado el ticket:', ' ', vNewTicket);
IF (SELECT ct.isCreatedAsServed FROM vn.clientType ct JOIN vn.client c ON c.typeFk = ct.code WHERE c.id = vClientId ) <> FALSE THEN
INSERT INTO vncontrol.inter(state_id, Id_Ticket, Id_Trabajador)
SELECT id, vNewTicket, getWorker()
FROM state
WHERE `code` = 'DELIVERED';
END IF;
END$$
DELIMITER ;

View File

@ -0,0 +1,88 @@
USE `vn`;
DROP procedure IF EXISTS `ticketCreateWithUser`;
DELIMITER $$
USE `vn`$$
CREATE DEFINER=`root`@`%` PROCEDURE `ticketCreateWithUser`(
vClientId INT
,vShipped DATE
,vWarehouseFk INT
,vCompanyFk INT
,vAddressFk INT
,vAgencyModeFk INT
,vRouteFk INT
,vlanded DATE
,vUserId INT
,OUT vNewTicket INT)
BEGIN
DECLARE vZoneFk INT;
IF vClientId IS NULL THEN
CALL util.throw ('CLIENT_NOT_ESPECIFIED');
END IF;
IF NOT vAddressFk OR vAddressFk IS NULL THEN
SELECT id INTO vAddressFk
FROM address
WHERE clientFk = vClientId AND isDefaultAddress;
END IF;
IF vAgencyModeFk IS NOT NULL THEN
CALL vn.zone_getShippedWarehouse(vlanded, vAddressFk, vAgencyModeFk);
SELECT zoneFk INTO vZoneFk FROM tmp.zoneGetShipped
WHERE shipped = vShipped AND warehouseFk = vWarehouseFk LIMIT 1;
IF vZoneFk IS NULL OR vZoneFk = 0 THEN
CALL util.throw ('NOT_ZONE_WITH_THIS_PARAMETERS');
END IF;
END IF;
INSERT INTO vn2008.Tickets (
Id_Cliente,
Fecha,
Id_Consigna,
Id_Agencia,
Alias,
warehouse_id,
Id_Ruta,
empresa_id,
landing,
zoneFk
)
SELECT
vClientId,
vShipped,
a.id,
vAgencyModeFk,
a.nickname,
vWarehouseFk,
IF(vRouteFk,vRouteFk,NULL),
vCompanyFk,
vlanded,
vZoneFk
FROM address a
JOIN agencyMode am ON am.id = a.agencyModeFk
WHERE a.id = vAddressFk;
SET vNewTicket = LAST_INSERT_ID();
INSERT INTO ticketObservation(ticketFk, observationTypeFk, description)
SELECT vNewTicket, ao.observationTypeFk, ao.description
FROM addressObservation ao
JOIN address a ON a.id = ao.addressFk
WHERE a.id = vAddressFk;
INSERT INTO vn.ticketLog
SET originFk = vNewTicket, userFk = vUserId, `action` = 'insert', description = CONCAT('Ha creado el ticket:', ' ', vNewTicket);
IF (SELECT ct.isCreatedAsServed FROM vn.clientType ct JOIN vn.client c ON c.typeFk = ct.code WHERE c.id = vClientId ) <> FALSE THEN
INSERT INTO vncontrol.inter(state_id, Id_Ticket, Id_Trabajador)
SELECT id, vNewTicket, getWorker()
FROM state
WHERE `code` = 'DELIVERED';
END IF;
END$$
DELIMITER ;

View File

@ -0,0 +1,83 @@
USE `vn`;
DROP procedure IF EXISTS `vn`.`zone_getOptionsForLanding`;
DELIMITER $$
USE `vn`$$
CREATE DEFINER=`root`@`%` PROCEDURE `zone_getOptionsForLanding`(vLanded DATE)
BEGIN
/**
* Gets computed options for the passed zones and delivery date.
*
* @table tmp.zones(id) The zones ids
* @param vLanded The delivery date
* @return tmp.zoneOption The computed options
*/
DECLARE vHour TIME DEFAULT TIME(NOW());
DROP TEMPORARY TABLE IF EXISTS tTemp;
CREATE TEMPORARY TABLE tTemp
ENGINE = MEMORY
SELECT t.id zoneFk,
TIME(e.`hour`) `hour`,
e.travelingDays,
e.price,
e.bonus,
CASE
WHEN e.`from` IS NULL AND e.`to` IS NULL
THEN 3
WHEN e.`to` IS NULL
THEN 2
ELSE 1
END specificity
FROM tmp.zone t
JOIN zoneEvent e ON e.zoneFk = t.id
WHERE (e.`from` = vLanded AND e.`to` IS NULL)
OR (
(e.`from` IS NULL OR vLanded BETWEEN e.`from` AND e.`to`)
AND e.weekDays & (1 << WEEKDAY(vLanded))
);
-- XXX: Compatibility with the deprecated #zoneCalendar table
INSERT INTO tTemp
SELECT t.id zoneFk,
NULL,
NULL,
c.price,
c.bonus,
4
FROM tmp.zone t
JOIN zoneCalendar c ON c.zoneFk = t.id
WHERE c.delivered = vLanded;
DELETE t FROM tTemp t
JOIN zoneExclusion e
ON e.zoneFk = t.zoneFk AND e.`day` = vLanded;
UPDATE tTemp t
JOIN zone z ON z.id = t.zoneFk
SET t.`hour` = IFNULL(t.`hour`, TIME(z.`hour`)),
t.travelingDays = IFNULL(t.travelingDays, z.travelingDays),
t.price = IFNULL(t.price, z.price),
t.bonus = IFNULL(t.bonus, z.bonus);
DELETE FROM tTemp
WHERE (@shipped := TIMESTAMPADD(DAY, -travelingDays, vLanded)) < CURDATE()
OR @shipped = CURDATE() AND vHour > `hour`;
DROP TEMPORARY TABLE IF EXISTS tmp.zoneOption;
CREATE TEMPORARY TABLE tmp.zoneOption
ENGINE = MEMORY
SELECT *
FROM (
SELECT * FROM tTemp
ORDER BY zoneFk, specificity
) t
GROUP BY zoneFk;
DROP TEMPORARY TABLE tTemp;
END$$
DELIMITER ;
;

View File

@ -0,0 +1,79 @@
USE `vn`;
DROP procedure IF EXISTS `zone_getOptionsForShipment`;
DELIMITER $$
USE `vn`$$
CREATE DEFINER=`root`@`%` PROCEDURE `zone_getOptionsForShipment`(vShipped DATE)
BEGIN
/**
* Gets computed options for the passed zones and shipping date.
*
* @table tmp.zones(id) The zones ids
* @param vShipped The shipping date
* @return tmp.zoneOption(zoneFk, hour, travelingDays, price, bonus, specificity) The computed options
*/
DECLARE vHour TIME DEFAULT TIME(NOW());
DROP TEMPORARY TABLE IF EXISTS tTemp;
CREATE TEMPORARY TABLE tTemp
ENGINE = MEMORY
SELECT t.id zoneFk,
TIME(e.`hour`) `hour`,
e.travelingDays,
e.price,
e.bonus,
CASE
WHEN e.`from` IS NULL AND e.`to` IS NULL
THEN 3
WHEN e.`to` IS NULL
THEN 2
ELSE 1
END specificity
FROM tmp.zone t
JOIN zoneEvent e ON e.zoneFk = t.id
WHERE (e.`from` = TIMESTAMPADD(DAY, e.travelingDays, vShipped) AND e.`to` IS NULL)
OR (
(e.`from` IS NULL OR TIMESTAMPADD(DAY, e.travelingDays, vShipped) BETWEEN e.`from` AND e.`to`)
AND e.weekDays & (1 << WEEKDAY(TIMESTAMPADD(DAY, e.travelingDays, vShipped)))
);
-- XXX: Compatibility with the deprecated #zoneCalendar table
INSERT INTO tTemp
SELECT t.id zoneFk,
z.`hour`,
z.travelingDays,
c.price,
c.bonus,
4
FROM tmp.zone t
JOIN zone z ON z.id = t.id
JOIN zoneCalendar c ON c.zoneFk = t.id
WHERE TIMESTAMPADD(DAY,-z.travelingDays, c.delivered) = vShipped;
DELETE t FROM tTemp t
JOIN zoneExclusion e
ON e.zoneFk = t.zoneFk AND TIMESTAMPADD(DAY,-t.travelingDays, e.`day`) = vShipped;
UPDATE tTemp t
JOIN zone z ON z.id = t.zoneFk
SET t.`hour` = IFNULL(t.`hour`, TIME(z.`hour`)),
t.travelingDays = IFNULL(t.travelingDays, z.travelingDays),
t.price = IFNULL(t.price, z.price),
t.bonus = IFNULL(t.bonus, z.bonus);
DROP TEMPORARY TABLE IF EXISTS tmp.zoneOption;
CREATE TEMPORARY TABLE tmp.zoneOption
ENGINE = MEMORY
SELECT *
FROM (
SELECT * FROM tTemp
ORDER BY zoneFk, specificity
) t
GROUP BY zoneFk;
DROP TEMPORARY TABLE tTemp;
END$$
DELIMITER ;

View File

@ -0,0 +1,79 @@
USE `vn`;
DROP procedure IF EXISTS `zone_getOptionsForShipment`;
DELIMITER $$
USE `vn`$$
CREATE DEFINER=`root`@`%` PROCEDURE `zone_getOptionsForShipment`(vShipped DATE)
BEGIN
/**
* Gets computed options for the passed zones and shipping date.
*
* @table tmp.zones(id) The zones ids
* @param vShipped The shipping date
* @return tmp.zoneOption(zoneFk, hour, travelingDays, price, bonus, specificity) The computed options
*/
DECLARE vHour TIME DEFAULT TIME(NOW());
DROP TEMPORARY TABLE IF EXISTS tTemp;
CREATE TEMPORARY TABLE tTemp
ENGINE = MEMORY
SELECT t.id zoneFk,
TIME(e.`hour`) `hour`,
e.travelingDays,
e.price,
e.bonus,
CASE
WHEN e.`from` IS NULL AND e.`to` IS NULL
THEN 3
WHEN e.`to` IS NULL
THEN 2
ELSE 1
END specificity
FROM tmp.zone t
JOIN zoneEvent e ON e.zoneFk = t.id
WHERE (e.`from` = TIMESTAMPADD(DAY, e.travelingDays, vShipped) AND e.`to` IS NULL)
OR (
(e.`from` IS NULL OR TIMESTAMPADD(DAY, e.travelingDays, vShipped) BETWEEN e.`from` AND e.`to`)
AND e.weekDays & (1 << WEEKDAY(TIMESTAMPADD(DAY, e.travelingDays, vShipped)))
);
-- XXX: Compatibility with the deprecated #zoneCalendar table
INSERT INTO tTemp
SELECT t.id zoneFk,
z.`hour`,
z.travelingDays,
c.price,
c.bonus,
4
FROM tmp.zone t
JOIN zone z ON z.id = t.id
JOIN zoneCalendar c ON c.zoneFk = t.id
WHERE TIMESTAMPADD(DAY,-z.travelingDays, c.delivered) = vShipped;
DELETE t FROM tTemp t
JOIN zoneExclusion e
ON e.zoneFk = t.zoneFk AND TIMESTAMPADD(DAY,-t.travelingDays, e.`day`) = vShipped;
UPDATE tTemp t
JOIN zone z ON z.id = t.zoneFk
SET t.`hour` = IFNULL(t.`hour`, TIME(z.`hour`)),
t.travelingDays = IFNULL(t.travelingDays, z.travelingDays),
t.price = IFNULL(t.price, z.price),
t.bonus = IFNULL(t.bonus, z.bonus);
DROP TEMPORARY TABLE IF EXISTS tmp.zoneOption;
CREATE TEMPORARY TABLE tmp.zoneOption
ENGINE = MEMORY
SELECT *
FROM (
SELECT * FROM tTemp
ORDER BY zoneFk, specificity
) t
GROUP BY zoneFk;
DROP TEMPORARY TABLE tTemp;
END$$
DELIMITER ;

View File

@ -446,6 +446,22 @@ INSERT INTO `vn`.`zone` (`id`, `name`, `hour`, `warehouseFk`, `agencyModeFk`, `t
(12, 'Zone entanglement', CONCAT(CURRENT_DATE(), ' ', TIME('22:00')), 4, 4, 0, 0, 0),
(13, 'Zone quantum break', CONCAT(CURRENT_DATE(), ' ', TIME('22:00')), 5, 5, 0, 0, 0);
INSERT INTO `vn`.`zoneWarehouse` (`id`, `zoneFk`, `warehouseFk`)
VALUES
(1, 1, 1),
(2, 2, 2),
(3, 3, 1),
(4, 4, 2),
(5, 5, 1),
(6, 6, 2),
(7, 7, 1),
(8, 8, 1),
(9, 9, 1),
(10, 10, 3),
(11, 11, 5),
(12, 12, 4),
(13, 13, 5);
INSERT INTO `vn`.`route`(`id`, `time`, `workerFk`, `created`, `vehicleFk`, `agencyModeFk`, `description`, `m3`, `cost`, `started`, `finished`, `zoneFk`)
VALUES
(1, '1899-12-30 12:15:00', 56, CURDATE(), 1, 1, 'first route', 1.8, 10, CURDATE(), CURDATE(), 1),
@ -1598,7 +1614,7 @@ INSERT INTO `vn`.`zoneIncluded` (`zoneFk`, `geoFk`, `isIncluded`)
(8, 5, 0),
(8, 1, 1);
INSERT INTO `vn`.`zoneCalendar`(`zoneFk`, `delivered`)
INSERT INTO `vn`.`zoneEvent`(`zoneFk`, `from`)
VALUES
(1, DATE_ADD(CURDATE(), INTERVAL (IF(DAYOFWEEK(CURDATE())<=2, 2, 9 ) - DAYOFWEEK(CURDATE())) DAY)),
(1, DATE_ADD(CURDATE(), INTERVAL (IF(DAYOFWEEK(CURDATE())<=3, 3, 10) - DAYOFWEEK(CURDATE())) DAY)),

View File

@ -52,7 +52,7 @@ let actions = {
let logoutClicked = await this.clickIfExists('#logout');
if (logoutClicked) {
let buttonSelector = '.vn-dialog.shown button[response=ACCEPT]';
let buttonSelector = '.vn-dialog.shown button[response=accept]';
await this.wait(buttonSelector => {
return document.querySelector(buttonSelector) != null
|| location.hash == '#!/login';
@ -392,7 +392,7 @@ let actions = {
forceReloadSection: function(sectionRoute) {
return this.waitToClick('vn-icon[icon="desktop_windows"]')
.waitToClick('button[response="ACCEPT"]')
.waitToClick('button[response="accept"]')
.wait('vn-card.summary')
.waitToClick(`vn-left-menu li > a[ui-sref="${sectionRoute}"]`);
},

View File

@ -18,7 +18,7 @@ export default {
userConfigFirstAutocompleteClear: '#localWarehouse .icons > vn-icon[icon=clear]',
userConfigSecondAutocompleteClear: '#localBank .icons > vn-icon[icon=clear]',
userConfigThirdAutocompleteClear: '#localCompany .icons > vn-icon[icon=clear]',
acceptButton: '.vn-confirm.shown button[response=ACCEPT]'
acceptButton: '.vn-confirm.shown button[response=accept]'
},
clientsIndex: {
searchClientInput: `vn-textfield input`,
@ -62,7 +62,7 @@ export default {
socialNameInput: `vn-textfield input[name="socialName"]`,
fiscalIdInput: `vn-textfield input[name="fi"]`,
equalizationTaxCheckbox: 'vn-check[ng-model="$ctrl.client.isEqualizated"]',
acceptPropagationButton: '.vn-confirm.shown button[response=ACCEPT]',
acceptPropagationButton: '.vn-confirm.shown button[response=accept]',
addressInput: `vn-textfield input[name="street"]`,
postcodeInput: `vn-textfield input[name="postcode"]`,
cityInput: `vn-textfield input[name="city"]`,
@ -90,7 +90,7 @@ export default {
newBankEntityName: '.vn-dialog.shown vn-textfield[label="Name"] input',
newBankEntityBIC: '.vn-dialog.shown vn-textfield[label="Swift / BIC"] input',
newBankEntityCode: '.vn-dialog.shown vn-textfield[label="Entity Code"] input',
acceptBankEntityButton: '.vn-dialog.shown button[response="ACCEPT"]',
acceptBankEntityButton: '.vn-dialog.shown button[response="accept"]',
saveButton: `button[type=submit]`
},
clientAddresses: {
@ -177,7 +177,7 @@ export default {
deleteFileButton: 'vn-client-dms-index vn-tr:nth-child(1) vn-icon-button[icon="delete"]',
firstDocWorker: 'vn-client-dms-index vn-td:nth-child(8) > span',
firstDocWorkerDescriptor: '.vn-popover.shown vn-worker-descriptor',
acceptDeleteButton: '.vn-confirm.shown button[response="ACCEPT"]'
acceptDeleteButton: '.vn-confirm.shown button[response="accept"]'
},
itemsIndex: {
searchIcon: 'vn-item-index vn-searchbar vn-icon[icon="search"]',
@ -185,7 +185,7 @@ export default {
searchResult: 'vn-item-index a.vn-tr',
searchResultPreviewButton: 'vn-item-index .buttons > [icon="desktop_windows"]',
searchResultCloneButton: 'vn-item-index .buttons > [icon="icon-clone"]',
acceptClonationAlertButton: '.vn-confirm.shown [response="ACCEPT"]',
acceptClonationAlertButton: '.vn-confirm.shown [response="accept"]',
searchItemInput: 'vn-searchbar vn-textfield input',
searchButton: 'vn-searchbar vn-icon[icon="search"]',
closeItemSummaryPreview: '.vn-popup.shown',
@ -340,7 +340,7 @@ export default {
sixthWeeklyTicket: 'vn-ticket-weekly-index vn-table vn-tr:nth-child(6) vn-autocomplete[ng-model="weekly.weekDay"] input',
weeklyTicket: 'vn-ticket-weekly-index vn-table > div > vn-tbody > vn-tr',
firstWeeklyTicketDeleteIcon: 'vn-ticket-weekly-index vn-tr:nth-child(1) vn-icon-button[icon="delete"]',
acceptDeleteTurn: '.vn-confirm.shown button[response="ACCEPT"]'
acceptDeleteTurn: '.vn-confirm.shown button[response="accept"]'
},
createTicketView: {
clientAutocomplete: 'vn-ticket-create vn-autocomplete[ng-model="$ctrl.clientFk"]',
@ -368,11 +368,11 @@ export default {
thursdayButton: '.vn-popup.shown vn-tool-bar > vn-button:nth-child(4)',
saturdayButton: '.vn-popup.shown vn-tool-bar > vn-button:nth-child(6)',
closeStowawayDialog: '.vn-dialog.shown button[class="close"]',
acceptDeleteButton: '.vn-dialog.shown button[response="ACCEPT"]',
acceptChangeHourButton: '.vn-dialog.shown button[response="ACCEPT"]',
acceptDeleteButton: '.vn-dialog.shown button[response="accept"]',
acceptChangeHourButton: '.vn-dialog.shown button[response="accept"]',
descriptorDeliveryDate: 'vn-ticket-descriptor > div > div.body > div.attributes > vn-label-value:nth-child(6) > section > span',
acceptInvoiceOutButton: '.vn-confirm.shown button[response="ACCEPT"]',
acceptDeleteStowawayButton: '.vn-dialog.shown button[response="ACCEPT"]'
acceptInvoiceOutButton: '.vn-confirm.shown button[response="accept"]',
acceptDeleteStowawayButton: '.vn-dialog.shown button[response="accept"]'
},
ticketNotes: {
firstNoteRemoveButton: 'vn-icon[icon="delete"]',
@ -384,7 +384,7 @@ export default {
ticketExpedition: {
expeditionButton: 'vn-left-menu a[ui-sref="ticket.card.expedition"]',
secondExpeditionRemoveButton: 'vn-ticket-expedition vn-table div > vn-tbody > vn-tr:nth-child(2) > vn-td:nth-child(1) > vn-icon-button[icon="delete"]',
acceptDeleteRowButton: '.vn-confirm.shown button[response=ACCEPT]',
acceptDeleteRowButton: '.vn-confirm.shown button[response=accept]',
expeditionRow: 'vn-ticket-expedition vn-table vn-tbody > vn-tr'
},
ticketPackages: {
@ -453,8 +453,8 @@ export default {
moveToTicketInputClearButton: '.vn-popover.shown i[title="Clear"]',
moveToTicketButton: '.vn-popover.shown vn-icon[icon="arrow_forward_ios"]',
moveToNewTicketButton: '.vn-popover.shown vn-button[label="New ticket"]',
acceptDeleteLineButton: '.vn-confirm.shown button[response=ACCEPT]',
acceptDeleteTicketButton: '.vn-confirm.shown button[response=ACCEPT]',
acceptDeleteLineButton: '.vn-confirm.shown button[response=accept]',
acceptDeleteTicketButton: '.vn-confirm.shown button[response=accept]',
stateMenuButton: 'vn-ticket-sale vn-tool-bar > vn-button-menu[label="State"]'
},
ticketTracking: {
@ -523,7 +523,7 @@ export default {
claimDescriptor: {
moreMenu: 'vn-claim-descriptor vn-icon-menu[icon=more_vert]',
moreMenuDeleteClaim: '.vn-drop-down.shown li[name="Delete claim"]',
acceptDeleteClaim: '.vn-confirm.shown button[response="ACCEPT"]'
acceptDeleteClaim: '.vn-confirm.shown button[response="accept"]'
},
claimSummary: {
header: 'vn-claim-summary > vn-card > h5',
@ -589,7 +589,7 @@ export default {
},
orderDescriptor: {
returnToModuleIndexButton: 'vn-order-descriptor a[ui-sref="order.index"]',
acceptNavigationButton: '.vn-confirm.shown button[response=ACCEPT]'
acceptNavigationButton: '.vn-confirm.shown button[response=accept]'
},
createOrderView: {
clientAutocomplete: 'vn-autocomplete[label="Client"]',
@ -618,13 +618,13 @@ export default {
agencyAutocomplete: 'vn-autocomplete[label="Agency"]',
observationInput: 'vn-textarea[label="Observation"] textarea',
saveButton: `button[type=submit]`,
acceptButton: '.vn-confirm.shown button[response="ACCEPT"]'
acceptButton: '.vn-confirm.shown button[response="accept"]'
},
orderLine: {
orderSubtotal: 'vn-order-line .header :first-child',
firstLineDeleteButton: 'vn-order-line vn-tbody > vn-tr:nth-child(1) vn-icon[icon="delete"]',
confirmOrder: 'vn-order-line vn-float-button',
confirmButton: '.vn-confirm.shown button[response="ACCEPT"]',
confirmButton: '.vn-confirm.shown button[response="accept"]',
},
routeIndex: {
addNewRouteButton: 'vn-route-index > a[ui-sref="route.create"]'
@ -663,7 +663,7 @@ export default {
firstTicketCheckbox: 'vn-route-tickets vn-tr:nth-child(1) vn-check',
buscamanButton: 'vn-route-tickets vn-button[icon="icon-buscaman"]',
firstTicketDeleteButton: 'vn-route-tickets vn-tr:nth-child(1) vn-icon[icon="delete"]',
confirmButton: '.vn-confirm.shown button[response="ACCEPT"]'
confirmButton: '.vn-confirm.shown button[response="accept"]'
},
workerPbx: {
extensionInput: 'vn-worker-pbx vn-textfield[ng-model="$ctrl.worker.sip.extension"] input',
@ -729,8 +729,8 @@ export default {
moreMenuDeleteInvoiceOut: '.vn-drop-down.shown li[name="Delete Invoice"]',
moreMenuBookInvoiceOut: '.vn-drop-down.shown li[name="Book invoice"]',
moreMenuShowInvoiceOutPdf: '.vn-drop-down.shown li[name="Show invoice PDF"]',
acceptDeleteButton: '.vn-confirm.shown button[response="ACCEPT"]',
acceptBookingButton: '.vn-confirm.shown button[response="ACCEPT"]'
acceptDeleteButton: '.vn-confirm.shown button[response="accept"]',
acceptBookingButton: '.vn-confirm.shown button[response="accept"]'
},
invoiceOutSummary: {
bookedLabel: 'vn-invoice-out-summary > vn-card > vn-horizontal > vn-one > vn-label-value:nth-child(4) > section > span'

View File

@ -110,7 +110,7 @@ describe('Client Add address path', () => {
it(`should go back to the addreses section by clicking the cancel button`, async() => {
const url = await nightmare
.waitToClick(selectors.clientAddresses.cancelEditAddressButton)
.waitToClick('.vn-confirm.shown button[response="ACCEPT"]')
.waitToClick('.vn-confirm.shown button[response="accept"]')
.waitForURL('address/index')
.parsedUrl();

View File

@ -1,19 +1,16 @@
@import "variables";
vn-chip {
border-radius: 16px;
border-radius: 1em;
background-color: $color-bg;
margin: 0 0.5em 0.5em 0;
color: $color-font;
font-size: 14px;
font-size: .9rem;
margin: .25em;
display: inline-flex;
align-items: center;
text-overflow: ellipsis;
white-space: nowrap;
height: 28px;
padding: 0 .7em;
overflow: hidden;
height: 2em;
max-width: 100%;
box-sizing: border-box;
&.colored {
background-color: $color-main;
@ -22,17 +19,24 @@ vn-chip {
& > div {
display: flex;
align-items: center;
max-width: 100%;
height: 100%;
padding: 0 .7em;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
line-height: 2em;
& > vn-avatar {
margin-left: -0.7em;
margin-right: .4em;
margin-right: .3em;
vertical-align: middle;
height: 1.9em;
width: 2em;
}
}
& > vn-icon {
margin-left: .2em;
margin-right: -0.3em;
margin-right: .12em;
margin-left: -.12em;
vertical-align: middle;
opacity: .6;
cursor: pointer;
@ -47,7 +51,6 @@ vn-chip {
vn-avatar {
display: inline-block;
height: 28px;
width: 28px;
min-width: 2em;
border-radius: 50%;
}

View File

@ -4,7 +4,7 @@
<span translate>{{::$ctrl.question}}</span>
</tpl-body>
<tpl-buttons>
<button response="CANCEL" translate>Cancel</button>
<button response="ACCEPT" translate>Accept</button>
<button response="cancel" translate>Cancel</button>
<button response="accept" translate vn-focus>Accept</button>
</tpl-buttons>
</div>

View File

@ -1,3 +1,8 @@
<div
ng-if="$ctrl.loading"
class="loading-overlap shown">
<vn-spinner enable="true"></vn-spinner>
</div>
<vn-button
ng-click="$ctrl.hide()"
translate-attr="{title: 'Close'}"

View File

@ -4,10 +4,16 @@ import template from './index.html';
import './style.scss';
/**
* Dialog component.
* Dialog component that allows to register function handlers for responses. If
* any of the handlers returns false or a promise that resolves to false,
* the dialog closing is cancelled. Also, if promise is returned, the dialog
* will wait until it is resolved by locking itself and displaying a loading
* animation.
*
* @property {HTMLElement} body The dialog HTML body
* @property {HTMLElement} buttons The dialog HTML buttons
* @property {Function} onResponse Handler for dialog response
* @property {Function} onAccept Shortcut handler for accept response
* @slot body The dialog HTML body
* @slot buttons The dialog HTML buttons
*/
export default class Dialog extends Popup {
constructor($element, $, $transclude) {
@ -16,24 +22,92 @@ export default class Dialog extends Popup {
}
/**
* Hides the dialog calling the response handler.
* Shows the dialog and optionally registers a handler for the response.
*
* @param {*} data Optional user data to pass to response handler
* @param {Function} responseHandler An optional response handler
* @return {Promise} A promise that will be resolved with response when dialog is closed
*/
hide() {
this.fireResponse();
show(data, responseHandler) {
if (typeof data == 'function') {
responseHandler = data;
data = null;
}
this.data = data;
this.showHandler = responseHandler;
super.show();
return this.$q(resolve => {
this.resolve = resolve;
});
}
/**
* Hides the dialog.
*
* @param {String} response The response
*/
hide(response) {
if (!this.shown) return;
this.showHandler = null;
super.hide();
if (this.resolve)
this.resolve(response);
}
/**
* Calls the response handler.
*
* @param {String} response The response code
* @return {Boolean} %true if response was canceled, %false otherwise
* @return {Boolean} The response handler return
*/
fireResponse(response) {
let cancel;
respond(response) {
if (!this.shown)
return this.$q.resolve();
let handlerArgs = {
$response: response,
$data: this.data
};
let cancellers = [];
if (this.onResponse)
cancel = this.onResponse({response: response});
return cancel;
cancellers.push(this.onResponse(handlerArgs));
if (response == 'accept' && this.onAccept)
cancellers.push(this.onAccept(handlerArgs));
if (this.showHandler)
cancellers.push(this.showHandler(response, this.data));
let promises = [];
let resolvedCancellers = [];
for (let canceller of cancellers) {
if (canceller instanceof Object && canceller.then)
promises.push(canceller);
else
resolvedCancellers.push(canceller);
}
let close = () => {
if (resolvedCancellers.indexOf(false) == -1)
this.hide(response);
else
return false;
};
if (promises.length) {
this.loading = true;
return this.$q.all(promises)
.then(res => {
resolvedCancellers = resolvedCancellers.concat(res);
return close();
})
.finally(() => {
this.loading = false;
});
} else
return this.$q.resolve(close());
}
onButtonClick(event) {
@ -45,17 +119,7 @@ export default class Dialog extends Popup {
node = node.parentNode;
}
let response = node.getAttribute('response');
let cancel = this.fireResponse(response);
let close = res => {
if (res !== false) super.hide();
};
if (cancel instanceof Object && cancel.then)
cancel.then(close);
else
close(cancel);
this.respond(node.getAttribute('response'));
}
}
@ -66,6 +130,7 @@ ngModule.vnComponent('vnDialog', {
buttons: '?tplButtons'
},
bindings: {
onResponse: '&?'
onResponse: '&?',
onAccept: '&?'
}
});

View File

@ -1,36 +1,106 @@
describe('Component vnDialog', () => {
let $element;
let $scope;
let controller;
beforeEach(ngModule('vnCore'));
beforeEach(angular.mock.inject(($rootScope, $compile) => {
$element = $compile('<vn-dialog><tpl-body>Body</tpl-body></vn-dialog>')($rootScope);
$scope = $rootScope.$new();
$element = $compile('<vn-dialog><tpl-body>Body</tpl-body></vn-dialog>')($scope);
controller = $element.controller('vnDialog');
controller.emit = jasmine.createSpy('emit');
}));
afterEach(() => {
$scope.$destroy();
$element.remove();
});
describe('show()', () => {
it(`should call the show handler when response is given`, () => {
let called;
let showHandler = () => called = true;
controller.show(showHandler);
controller.respond();
expect(called).toBeTruthy();
});
it(`should hide the dialog when response is given`, () => {
controller.show();
spyOn(controller, 'hide');
controller.respond('answer');
expect(controller.hide).toHaveBeenCalledWith('answer');
});
it(`should not hide the dialog when false is returned from response handler`, () => {
controller.show(() => false);
spyOn(controller, 'hide');
controller.respond('answer');
expect(controller.hide).not.toHaveBeenCalled();
});
});
describe('hide()', () => {
describe('fireResponse()', () => {
it(`should call onResponse() if it's defined in the controller`, () => {
controller.onResponse = () => {};
spyOn(controller, 'onResponse');
controller.hide();
it(`should do nothing if it's already hidden`, () => {
controller.onResponse = () => {};
spyOn(controller, 'onResponse');
controller.hide();
expect(controller.onResponse).toHaveBeenCalledWith(jasmine.any(Object));
});
expect(controller.onResponse).not.toHaveBeenCalledWith();
});
});
it(`should call onResponse() with a response`, () => {
let responseRes;
controller.onResponse = response => {
responseRes = response;
return false;
};
let responseRet = controller.fireResponse('answer');
describe('respond()', () => {
it(`should do nothing if dialog is already hidden`, () => {
controller.onResponse = () => {};
spyOn(controller, 'onResponse');
controller.respond();
expect(responseRes).toEqual({response: 'answer'});
expect(responseRet).toEqual(false);
});
expect(controller.onResponse).not.toHaveBeenCalledWith();
});
it(`should call onResponse() if it's defined`, () => {
controller.onResponse = () => {};
spyOn(controller, 'onResponse');
controller.show();
controller.respond();
expect(controller.onResponse).toHaveBeenCalledWith(jasmine.any(Object));
});
it(`should call onResponse() with the response`, () => {
controller.onResponse = () => {};
spyOn(controller, 'onResponse');
controller.show();
controller.respond('response');
expect(controller.onResponse).toHaveBeenCalledWith({$response: 'response'});
});
it(`should call onAccept() when accept response is given`, () => {
controller.onAccept = () => {};
spyOn(controller, 'onAccept');
controller.show();
controller.respond('accept');
expect(controller.onAccept).toHaveBeenCalledWith({$response: 'accept'});
});
it(`should resolve the promise returned by show() with response when hidden`, () => {
let response;
controller.show().then(res => response = res);
controller.respond('response');
$scope.$apply();
expect(response).toEqual('response');
});
});
});

View File

@ -1,7 +1,7 @@
@import "effects";
.vn-dialog > .window {
padding: $spacing-lg;
position: relative;
& > .close {
@extend %clickable;
@ -16,6 +16,8 @@
color: #666;
}
& > form {
padding: $spacing-lg;
& > .body > tpl-body {
display: block;
min-width: 16em;
@ -42,4 +44,20 @@
}
}
}
& > .loading-overlap {
position: absolute;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, .2);
display: flex;
align-items: center;
justify-content: center;
z-index: 1;
opacity: 0;
transition: opacity 200ms ease-in-out;
&.shown {
opacity: 1;
}
}
}

0
front/core/components/drop-down/index.html Executable file → Normal file
View File

0
front/core/components/drop-down/index.js Executable file → Normal file
View File

View File

@ -2,5 +2,5 @@
vn-id="confirm"
question="Are you sure exit without saving?"
message="Unsaved changes will be lost"
on-response="$ctrl.onConfirmResponse(response)">
on-response="$ctrl.onConfirmResponse($response)">
</vn-confirm>

View File

@ -203,7 +203,7 @@ export default class Watcher extends Component {
}
onConfirmResponse(response) {
if (response === 'ACCEPT') {
if (response === 'accept') {
if (this.data)
Object.assign(this.data, this.orgData);
this.$state.go(this.state);

View File

@ -223,9 +223,9 @@ describe('Component vnWatcher', () => {
});
describe(`onConfirmResponse()`, () => {
describe(`when response is ACCEPT`, () => {
describe(`when response is accept`, () => {
it(`should call Object.assing on controlle.data with controller.orgData then call go() on state`, () => {
let response = 'ACCEPT';
let response = 'accept';
controller.data = {};
controller.orgData = {name: 'Batman'};
controller.$state = {go: jasmine.createSpy('go')};
@ -237,9 +237,9 @@ describe('Component vnWatcher', () => {
});
});
describe(`when response is not ACCEPT`, () => {
describe(`when response is not accept`, () => {
it(`should set controller.state to null`, () => {
let response = 'anything but ACCEPT';
let response = 'anything but accept';
controller.state = 'Batman';
controller.onConfirmResponse(response);

View File

@ -21,9 +21,12 @@ export function focus($scope, input) {
}
input.focus();
$scope.$applyAsync(() => {
input.select();
});
if (input.select) {
$scope.$applyAsync(() => {
input.select();
});
}
}
/**

View File

@ -1,22 +1,21 @@
import isEqual from './equals';
export default function getModifiedData(object, objectOld) {
var newObject = {};
let newObject = {};
if (objectOld === null)
return object;
for (var k in object) {
var val = object[k];
var valOld = objectOld[k] === undefined ? null : objectOld[k];
for (let k in object) {
let val = object[k];
let valOld = objectOld[k] === undefined ? null : objectOld[k];
if (!isEqual(val, valOld)) {
if (val instanceof Date) {
if (val instanceof Date)
newObject[k] = new Date(val.getTime());
} else if (val instanceof Object) {
else if (val instanceof Object)
newObject[k] = getModifiedData(val, valOld);
} else {
else
newObject[k] = val;
}
}
}

View File

@ -3,64 +3,80 @@ import moduleImport from 'module-import';
factory.$inject = ['$http', '$window', '$ocLazyLoad', '$translatePartialLoader', '$translate', '$q'];
export function factory($http, $window, $ocLazyLoad, $translatePartialLoader, $translate, $q) {
/**
* Used to load application modules lazily.
*/
class ModuleLoader {
constructor() {
this._loaded = {};
this.loaded = {};
this.imports = {};
this.moduleImport = moduleImport;
this.modelInfo = $http.get(`modelInfo`)
.then(json => {
this.onModelInfoReady(json);
this.modelInfo = true;
});
}
load(moduleName, validations) {
let moduleConf = $window.routes.find(i => i && i.module == moduleName);
/**
* Loads the passed module and it's dependencies. Loading a module
* implies load the webpack chunk, translations, recursively load
* module dependencies and finally register all of them into Angular.
*
* @param {String} mod The module name to load
* @return {Promise} Will be resolved when loaded, when module is
* already loaded it returns a resolved promise
*/
load(mod) {
let mods = [];
return this.loadRec(mod, mods);
}
loadRec(mod, mods) {
let loaded = this.loaded[mod];
if (loaded === true || mods.indexOf(mod) != -1)
return $q.resolve(true);
if (loaded instanceof $q)
return loaded;
let moduleConf = $window.routes.find(i => i && i.module == mod);
if (!moduleConf)
return $q.reject(new Error(`Module not found: ${moduleName}`));
return $q.reject(new Error(`Module not found: ${mod}`));
let loaded = this._loaded;
let promises = [];
if (loaded[moduleName] === true)
return Promise.resolve(true);
if (loaded[moduleName] instanceof Promise)
return loaded[moduleName];
if (loaded[moduleName] === false)
return Promise.resolve(true);
if (this.modelInfo instanceof $q)
promises.push(this.modelInfo);
loaded[moduleName] = false;
$translatePartialLoader.addPart(mod);
promises.push($translate.refresh());
let modImport = this.imports[mod];
if (!modImport) {
modImport = this.imports[mod] = this.moduleImport(mod)
.then(() => this.imports[mod] = true);
}
if (modImport && modImport.then)
promises.push(modImport);
let depPromises = [];
let deps = moduleConf.dependencies;
if (deps) {
mods.push(mod);
for (let dep of deps)
depPromises.push(this.load(dep, validations));
promises.push(this.loadRec(dep, mods));
mods.pop();
}
loaded[moduleName] = new Promise((resolve, reject) => {
Promise.all(depPromises).then(() => {
let promises = [];
$translatePartialLoader.addPart(moduleName);
promises.push(new Promise(resolve => {
$translate.refresh().then(resolve, resolve);
}));
if (validations) {
promises.push(new Promise(resolve => {
$http.get(`/${moduleName}/api/modelInfo`).then(
json => this.onValidationsReady(json, resolve),
() => resolve()
);
}));
}
promises.push(moduleImport(moduleName));
Promise.all(promises).then(() => {
loaded[moduleName] = true;
resolve($ocLazyLoad.load({name: moduleName}));
}).catch(reject);
}).catch(reject);
});
return loaded[moduleName];
this.loaded[mod] = $q.all(promises)
.then(() => $ocLazyLoad.load({name: mod}))
.then(() => this.loaded[mod] = true);
return this.loaded[mod];
}
onValidationsReady(json, resolve) {
onModelInfoReady(json) {
let entities = json.data;
for (let entity in entities) {
let fields = entities[entity].validations;
@ -72,12 +88,13 @@ export function factory($http, $window, $ocLazyLoad, $translatePartialLoader, $t
}
Object.assign($window.validations, json.data);
resolve();
}
parseValidation(val) {
switch (val.validation) {
case 'custom':
// TODO: Replace eval
// TODO: Don't use eval() because it's "evil".
// How to do the same without eval?
val.bindedFunction = eval(`(${val.bindedFunction})`);
break;
case 'format':

View File

@ -1,30 +1,108 @@
describe('factory vnModuleLoader', () => {
let vnModuleLoader;
let $rootScope;
let $window;
beforeEach(ngModule('vnCore'));
beforeEach(angular.mock.inject((_vnModuleLoader_, $rootScope, $window) => {
beforeEach(angular.mock.inject((_vnModuleLoader_, _$rootScope_, $httpBackend, _$window_, $q) => {
vnModuleLoader = _vnModuleLoader_;
$window.routes = [{module: 'myModule'}];
$rootScope = _$rootScope_;
$window = _$window_;
$window.validations = {};
$window.routes = [
{
module: 'myModule',
dependencies: ['fooModule', 'barModule']
}, {
module: 'fooModule',
dependencies: ['myModule']
}, {
module: 'barModule'
}
];
$httpBackend.whenGET('modelInfo')
.respond({
FooModel: {
properties: {
id: {type: 'Number'},
email: {type: 'String'},
field: {type: 'Boolean'}
},
validations: {
id: [{
validation: 'presence'
}],
email: [{
validation: 'format',
with: '/@/'
}],
field: [{
validation: 'custom',
bindedFunction: '() => true'
}]
}
}
});
$httpBackend.flush();
vnModuleLoader.moduleImport = () => $q.resolve();
}));
describe('load()', () => {
it('should return truthy promise if the module was loaded', async() => {
vnModuleLoader._loaded.myModule = true;
it('should throw error if module does not exist', async() => {
let errorThrown;
let result = await vnModuleLoader.load('myModule', {myValidations: () => {}});
vnModuleLoader.load('unexistentModule')
.catch(() => errorThrown = true);
$rootScope.$apply();
expect(result).toEqual(true);
expect(errorThrown).toBeTruthy();
});
it('should return a promise if the module was still a promise', () => {
vnModuleLoader._loaded.myModule = new Promise(() => {
return 'I promise you a module!';
});
it('should set module loaded to true when it is loaded', async() => {
vnModuleLoader.load('barModule');
$rootScope.$apply();
let result = vnModuleLoader.load('myModule', {myValidations: () => {}});
expect(vnModuleLoader.loaded['barModule']).toBeTruthy();
});
expect(result).toEqual(jasmine.any(Promise));
it('should resolve returned promise when module is loaded', async() => {
let loaded;
vnModuleLoader.load('barModule')
.then(() => loaded = true);
$rootScope.$apply();
expect(loaded).toBeTruthy();
});
it('should load dependencies', async() => {
vnModuleLoader.load('fooModule');
$rootScope.$apply();
expect(vnModuleLoader.loaded['barModule']).toBeTruthy();
});
it('should work with circular dependencies', async() => {
vnModuleLoader.load('myModule');
$rootScope.$apply();
expect(vnModuleLoader.loaded['fooModule']).toBeTruthy();
});
it('should load models information and parse validations', async() => {
vnModuleLoader.load('barModule');
let FooModel = $window.validations.FooModel;
let validations = FooModel && FooModel.validations;
expect(FooModel).toBeDefined();
expect(validations).toBeDefined();
expect(validations.email[0].with).toBeInstanceOf(RegExp);
expect(validations.field[0].bindedFunction).toBeInstanceOf(Function);
});
});
});

View File

@ -8,9 +8,11 @@ export default class Modules {
$window
});
}
reset() {
this.modules = null;
}
get() {
if (this.modules)
return this.modules;

View File

@ -1,10 +1,10 @@
import ngModule from './module';
import getMainRoute from 'core/lib/get-main-route';
function loader(moduleName, validations) {
function loader(moduleName) {
load.$inject = ['vnModuleLoader'];
function load(moduleLoader) {
return moduleLoader.load(moduleName, validations);
return moduleLoader.load(moduleName);
}
return load;
}
@ -31,7 +31,6 @@ function config($stateProvider, $urlRouterProvider) {
if (!route.params)
return params;
Object.keys(route.params).forEach(key => {
temporalParams.push(`${key} = "${route.params[key]}"`);
});

View File

@ -112,5 +112,6 @@
"This phone already exists": "Este teléfono ya existe",
"You cannot move a parent to any of its sons": "You cannot move a parent to any of its sons",
"You cannot move a parent to its own sons": "You cannot move a parent to its own sons",
"You can't create a claim for a removed ticket": "No puedes crear una reclamación para un ticket eliminado"
"You can't create a claim for a removed ticket": "No puedes crear una reclamación para un ticket eliminado",
"AMOUNT_NOT_MATCH_GROUPING": "AMOUNT_NOT_MATCH_GROUPING"
}

View File

@ -18,7 +18,7 @@ module.exports = Self => {
});
Self.getAgenciesWithWarehouse = async filter => {
let query = `CALL vn.zoneGetWarehouse(?, ?, ?)`;
let query = `CALL vn.zone_getWarehouse(?, ?, ?)`;
let result = await Self.rawSql(query, [filter.addressFk, filter.landed, filter.warehouseFk]);
return result;

View File

@ -18,7 +18,7 @@ module.exports = Self => {
});
Self.getFirstShipped = async params => {
let query = `CALL vn.zoneGetFirstShipped(?, ?, ?)`;
let query = `CALL vn.zone_getFirstShipped(?, ?, ?)`;
let [result] = await Self.rawSql(query, [params.agencyModeFk, params.addressFk, params.warehouseFk]);
return result[0];

View File

@ -37,7 +37,7 @@ module.exports = Self => {
Self.getLanded = async(shipped, addressFk, agencyModeFk, warehouseFk) => {
let stmts = [];
stmts.push(new ParameterizedSQL(
`CALL vn.zoneGetLanded(?, ?, ?, ?)`, [
`CALL vn.zone_getLanded(?, ?, ?, ?)`, [
shipped,
addressFk,
agencyModeFk,

View File

@ -1,3 +1,5 @@
const ParameterizedSQL = require('loopback-connector').ParameterizedSQL;
module.exports = Self => {
Self.remoteMethod('getShipped', {
description: 'Returns the first shipped possible for params',
@ -33,13 +35,24 @@ module.exports = Self => {
});
Self.getShipped = async(landed, addressFk, agencyModeFk, warehouseFk)=> {
let query = `CALL vn.zoneGetShipped(?, ?, ?, ?)`;
let [[response]] = await Self.rawSql(query, [
landed,
addressFk,
agencyModeFk,
warehouseFk
]);
return response;
let stmts = [];
stmts.push(new ParameterizedSQL(
`CALL vn.zone_getShippedWarehouse(?, ?, ?)`, [
landed,
addressFk,
agencyModeFk
]
));
let rsIndex = stmts.push(new ParameterizedSQL(
`SELECT * FROM tmp.zoneGetShipped WHERE warehouseFk = ?`, [
warehouseFk
]
)) - 1;
let sql = ParameterizedSQL.join(stmts, ';');
let shipped = await Self.rawStmt(sql);
return shipped[rsIndex][0];
};
};

View File

@ -18,8 +18,7 @@ module.exports = Self => {
});
Self.landsThatDay = async filter => {
let query = `CALL vn.zoneGetAgency(?, ?);
SELECT * FROM tmp.zoneGetAgency`;
let query = `CALL vn.zone_getAvailable(?, ?);`;
let result = await Self.rawSql(query, [filter.addressFk, filter.landed]);
return result[1];

View File

@ -12,12 +12,10 @@ describe('Agency getAgenciesWithWarehouse()', () => {
let result = await app.models.Agency.getAgenciesWithWarehouse(filter);
let agencies = result[0];
expect(agencies.length).toEqual(5);
expect(agencies.length).toEqual(3);
expect(agencies[0].agencyMode).toEqual('inhouse pickup');
expect(agencies[1].agencyMode).toEqual('Silla247');
expect(agencies[2].agencyMode).toEqual('Silla247Expensive');
expect(agencies[3].agencyMode).toEqual('Other agency');
expect(agencies[4].agencyMode).toEqual('Refund');
expect(agencies[1].agencyMode).toEqual('Other agency');
expect(agencies[2].agencyMode).toEqual('Refund');
});
it('should return no agencies if the date is incorrect', async() => {

View File

@ -1,6 +1,6 @@
const app = require('vn-loopback/server/server');
describe('agency getLanded()', () => {
// Petición #1848
xdescribe('agency getLanded()', () => {
it('should return a landing date', async() => {
const shipped = new Date();
const addressFk = 121;

View File

@ -1,6 +1,8 @@
const app = require('vn-loopback/server/server');
describe('agency getShipped()', () => {
// Petición #1848
xdescribe('agency getShipped()', () => {
it('should return a shipment date', async() => {
const landed = new Date();
const addressFk = 121;

View File

@ -1,6 +1,6 @@
const app = require('vn-loopback/server/server');
describe('Agency landsThatDay()', () => {
// Petición #1848
xdescribe('Agency landsThatDay()', () => {
const today = new Date();
it('should return a list of agencies that can land a shipment on a day for an address', async() => {
let filter = {

View File

@ -1,6 +1,6 @@
const app = require('vn-loopback/server/server');
describe('agency editPrices()', () => {
// Petición #1848
xdescribe('agency editPrices()', () => {
const zoneId = 1;
let originalZone;

View File

@ -60,9 +60,9 @@ class Controller extends Component {
if (this.events) {
let codes = ['sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat'];
for (event of this.events) {
event.wdays = [];
if (!event.weekDays) continue;
let weekDays = event.weekDays.split(',');
event.wdays = [];
for (let wday of weekDays) {
let index = codes.indexOf(wday);
if (index !== -1) event.wdays[index] = true;
@ -91,7 +91,7 @@ class Controller extends Component {
this.days = {};
let day = new Date(this.firstDay.getTime());
while (day < this.lastDay) {
while (day <= this.lastDay) {
let stamp = day.getTime();
let wday = day.getDay();
let dayEvents = [];

View File

@ -47,7 +47,7 @@
</div>
<vn-confirm
vn-id="delete-zone"
on-response="$ctrl.returnDialog(response)"
on-response="$ctrl.returnDialog($response)"
question="Are you sure you want to delete this zone?"
message="This zone will be removed">
</vn-confirm>

View File

@ -19,7 +19,7 @@ class Controller {
}
returnDialog(response) {
if (response === 'ACCEPT') {
if (response === 'accept') {
this.$http.delete(`Zones/${this.zone.id}`).then(() => {
this.$state.go('zone.index');
});

View File

@ -94,7 +94,7 @@
</vn-side-menu>
<vn-dialog
vn-id="dialog"
on-response="$ctrl.onSave(response)">
on-response="$ctrl.onIncludeResponse($response)">
<tpl-body>
<vn-vertical>
<vn-vertical class="vn-pb-md">
@ -162,7 +162,7 @@
<tpl-buttons>
<input
type="button"
response="CANCEL"
response="cancel"
translate-attr="{value: 'Cancel'}">
</input>
<button
@ -171,7 +171,7 @@
translate>
Delete
</button>
<button response="ACCEPT">
<button response="accept">
<span ng-if="$ctrl.isNew" translate>Add</span>
<span ng-if="!$ctrl.isNew" translate>Save</span>
</button>
@ -180,6 +180,5 @@
<vn-confirm
vn-id="confirm"
message="This item will be deleted"
question="Are you sure you want to continue?"
on-response="$ctrl.delete(response)">
question="Are you sure you want to continue?">
</vn-confirm>

View File

@ -101,8 +101,9 @@ class Controller extends Component {
this.$.dialog.show();
}
onSave(response) {
if (response == 'ACCEPT') {
onIncludeResponse(response) {
switch (response) {
case 'accept': {
let selected = this.selected;
if (this.eventType == 'indefinitely') {
@ -131,17 +132,15 @@ class Controller extends Component {
else
req = this.$http.put(`${this.path}/${selected.id}`, selected);
req.then(() => {
return req.then(() => {
this.selected = null;
this.isNew = null;
this.$.dialog.hide();
this.refresh();
});
return false;
} else if (response == 'DELETE') {
this.onDelete(this.selected.id);
return false;
}
case 'DELETE':
return this.onDelete(this.selected.id)
.then(response => response == 'accept');
}
}
@ -152,19 +151,14 @@ class Controller extends Component {
}
onDelete(id) {
this.deleteId = id;
this.$.confirm.show();
return this.$.confirm.show(
response => this.onDeleteResponse(response, id));
}
delete(response) {
if (response != 'ACCEPT') return;
if (!this.deleteId) return;
this.$http.delete(`${this.path}/${this.deleteId}`)
.then(() => {
this.refresh();
this.deleteId = null;
this.$.dialog.hide();
});
onDeleteResponse(response, id) {
if (response != 'accept' || !id) return;
return this.$http.delete(`${this.path}/${id}`)
.then(() => this.refresh());
}
exclusionCreate(days) {

View File

@ -68,7 +68,7 @@
</vn-popup>
<vn-confirm
vn-id="clone"
on-response="$ctrl.onCloneAccept(response)"
on-response="$ctrl.onCloneAccept($response)"
question="Do you want to clone this zone?"
message="All it's properties will be copied">
</vn-confirm>

View File

@ -39,10 +39,10 @@ export default class Controller {
/**
* Clone response callback
* @param {String} response - Response string (['ACCEPT', 'CANCEL'])
* @param {String} response - Response string (['accept', 'cancel'])
*/
onCloneAccept(response) {
if (!(response == 'ACCEPT' && this.selectedZone)) return;
if (!(response == 'accept' && this.selectedZone)) return;
const query = `Zones/${this.selectedZone.id}/clone`;
this.$http.post(query).then(res => {
if (res && res.data)

View File

@ -28,7 +28,7 @@
</vn-float-button>
<vn-dialog
vn-id="dialog"
on-response="$ctrl.onSave(response)">
on-response="$ctrl.onSave($response)">
<tpl-body>
<vn-vertical>
<vn-autocomplete
@ -41,13 +41,13 @@
</vn-vertical>
</tpl-body>
<tpl-buttons>
<input type="button" response="CANCEL" translate-attr="{value: 'Cancel'}"/>
<button response="ACCEPT" translate>Save</button>
<input type="button" response="cancel" translate-attr="{value: 'Cancel'}"/>
<button response="accept" translate>Save</button>
</tpl-buttons>
</vn-dialog>
<vn-confirm
vn-id="confirm"
message="This item will be deleted"
question="Are you sure you want to continue?"
on-response="$ctrl.delete(response)">
on-response="$ctrl.delete($response)">
</vn-confirm>

View File

@ -21,7 +21,7 @@ class Controller extends Component {
}
onSave(response) {
if (response != 'ACCEPT') return;
if (response != 'accept') return;
this.$http.post(this.path, this.selected)
.then(() => {
@ -40,7 +40,7 @@ class Controller extends Component {
}
delete(response) {
if (response != 'ACCEPT') return;
if (response != 'accept') return;
let id = this.$.data[this.deleteIndex].id;
if (!id) return;
this.$http.delete(`${this.path}/${id}`)

View File

@ -1,6 +1,6 @@
const app = require('vn-loopback/server/server');
describe('claimBeginning', () => {
// Petición #1848
xdescribe('claimBeginning', () => {
let ticket;
let refundTicketSales;
let salesInsertedInClaimEnd;

View File

@ -201,5 +201,5 @@
vn-id="update-greuge"
question="Insert greuges on client card"
message="Do you want to insert greuges?"
on-response="$ctrl.onUpdateGreugeResponse(response)">
on-response="$ctrl.onUpdateGreugeResponse($response)">
</vn-confirm>

View File

@ -133,7 +133,7 @@ class Controller {
}
onUpdateGreugeResponse(response) {
if (response !== 'ACCEPT')
if (response !== 'accept')
return;
let greugeTypeFreight = 7;
let query = `Greuges/`;

View File

@ -154,7 +154,7 @@ describe('claim', () => {
spyOn(controller.card, 'reload');
spyOn(controller.vnApp, 'showSuccess');
controller.onUpdateGreugeResponse('CANCEL');
controller.onUpdateGreugeResponse('cancel');
expect(controller.$http.post).not.toHaveBeenCalledWith();
expect(controller.card.reload).not.toHaveBeenCalledWith();
@ -174,7 +174,7 @@ describe('claim', () => {
ticketFk: controller.claim.ticketFk
};
$httpBackend.expect('POST', `Greuges/`, data).respond();
controller.onUpdateGreugeResponse('ACCEPT');
controller.onUpdateGreugeResponse('accept');
$httpBackend.flush();
expect(controller.card.reload).toHaveBeenCalledWith();

View File

@ -49,13 +49,13 @@
</div>
<vn-confirm
vn-id="confirm-pickup-order"
on-response="$ctrl.sendPickupOrder(response)"
on-response="$ctrl.sendPickupOrder($response)"
question="Send Pickup order"
message="Are you sure you want to send it?">
</vn-confirm>
<vn-confirm
vn-id="confirm-delete-claim"
on-response="$ctrl.deleteClaim(response)"
on-response="$ctrl.deleteClaim($response)"
question="Delete claim"
message="Are you sure you want to delete this claim?">
</vn-confirm>

View File

@ -69,7 +69,7 @@ class Controller {
}
sendPickupOrder(response) {
if (response === 'ACCEPT') {
if (response === 'accept') {
this.$http.post(`email/claim-pickup-order`, {claimFk: this.claim.id}).then(
() => this.vnApp.showMessage(this.$translate.instant('Notification sent!'))
);
@ -81,7 +81,7 @@ class Controller {
}
deleteClaim(response) {
if (response === 'ACCEPT') {
if (response === 'accept') {
this.$http.delete(`Claims/${this.claim.id}`).then(() => {
this.vnApp.showSuccess(this.$translate.instant('Claim deleted!'));
this.$state.go('claim.index');

View File

@ -35,12 +35,12 @@ describe('Item Component vnClaimDescriptor', () => {
});
describe('sendPickupOrder(response)', () => {
it('should make a query and call vnApp.showMessage() if the response is ACCEPT', () => {
it('should make a query and call vnApp.showMessage() if the response is accept', () => {
spyOn(controller.vnApp, 'showMessage');
$httpBackend.when('POST', `email/claim-pickup-order`, {claimFk: 2}).respond();
$httpBackend.expect('POST', `email/claim-pickup-order`, {claimFk: 2}).respond();
controller.sendPickupOrder('ACCEPT');
controller.sendPickupOrder('accept');
$httpBackend.flush();
expect(controller.vnApp.showMessage).toHaveBeenCalledWith('Notification sent!');
@ -60,8 +60,8 @@ describe('Item Component vnClaimDescriptor', () => {
});
describe('deleteClaime(response)', () => {
it('should perform a query and call showSuccess if the response is ACCEPT', () => {
let response = 'ACCEPT';
it('should perform a query and call showSuccess if the response is accept', () => {
let response = 'accept';
controller.claim = {id: 2};
spyOn(controller.vnApp, 'showSuccess');

View File

@ -37,5 +37,5 @@
vn-id="confirm"
message="This file will be deleted"
question="Are you sure you want to continue?"
on-response="$ctrl.deleteDms(response)">
on-response="$ctrl.deleteDms($response)">
</vn-confirm>

View File

@ -26,7 +26,7 @@ class Controller {
}
deleteDms(response) {
if (response === 'ACCEPT') {
if (response === 'accept') {
const dmsFk = this.photos[this.dmsIndex].dmsFk;
const query = `claimDms/${dmsFk}/removeFile`;
this.$http.post(query).then(() => {

View File

@ -35,7 +35,7 @@ describe('Claim', () => {
$httpBackend.when('POST', `claimDms/${dmsId}/removeFile`).respond({});
$httpBackend.expect('POST', `claimDms/${dmsId}/removeFile`);
controller.deleteDms('ACCEPT');
controller.deleteDms('accept');
$httpBackend.flush();
expect(controller.$.model.remove).toHaveBeenCalledWith(dmsIndex);

View File

@ -128,5 +128,5 @@
<!-- New postcode dialog -->
<vn-client-postcode vn-id="postcode"
on-response="$ctrl.onResponse(response)">
on-response="$ctrl.onResponse($response)">
</vn-client-postcode>

View File

@ -174,6 +174,6 @@
<!-- New postcode dialog -->
<vn-client-postcode vn-id="postcode"
on-response="$ctrl.onResponse(response)">
on-response="$ctrl.onResponse($response)">
</vn-client-postcode>

View File

@ -99,7 +99,7 @@
<vn-dialog class="edit"
vn-id="bankEntityDialog"
on-open="$ctrl.onBankEntityOpen()"
on-response="$ctrl.onBankEntityResponse(response)">
on-response="$ctrl.onBankEntityResponse($response)">
<tpl-body>
<h5 class="vn-py-sm" translate>New bank entity</h5>
<vn-horizontal>
@ -141,7 +141,7 @@
</vn-horizontal>
</tpl-body>
<tpl-buttons>
<input type="button" response="CANCEL" translate-attr="{value: 'Cancel'}"/>
<button response="ACCEPT" translate>Create</button>
<input type="button" response="cancel" translate-attr="{value: 'Cancel'}"/>
<button response="accept" translate>Create</button>
</tpl-buttons>
</vn-dialog>

View File

@ -55,7 +55,7 @@ export default class Controller {
}
onBankEntityResponse(response) {
if (response == 'ACCEPT') {
if (response == 'accept') {
try {
if (!this.newBankEntity.name)
throw new Error(`Name can't be empty`);

View File

@ -53,7 +53,7 @@ describe('Client', () => {
countryFk: 1,
id: 999
};
controller.onBankEntityResponse('ACCEPT');
controller.onBankEntityResponse('accept');
expect(vnApp.showError).toHaveBeenCalledWith(`Name can't be empty`);
});
@ -65,7 +65,7 @@ describe('Client', () => {
countryFk: 1,
id: 999
};
controller.onBankEntityResponse('ACCEPT');
controller.onBankEntityResponse('accept');
expect(vnApp.showError).toHaveBeenCalledWith(`Swift / BIC can't be empty`);
});
@ -80,7 +80,7 @@ describe('Client', () => {
controller.newBankEntity = newBankEntity;
$httpBackend.when('POST', 'BankEntities').respond('done');
$httpBackend.expectPOST('BankEntities', newBankEntity);
controller.onBankEntityResponse('ACCEPT');
controller.onBankEntityResponse('accept');
$httpBackend.flush();
});
});

View File

@ -149,6 +149,6 @@
<!-- New postcode dialog -->
<vn-client-postcode vn-id="postcode"
on-response="$ctrl.onResponse(response)">
on-response="$ctrl.onResponse($response)">
</vn-client-postcode>
</div>

View File

@ -60,7 +60,7 @@
</vn-float-button>
<vn-confirm
vn-id="close-contract"
on-response="$ctrl.returnDialog(response)"
on-response="$ctrl.returnDialog($response)"
question="Close contract"
message="Are you sure you want to close this contract?">
</vn-confirm>

View File

@ -56,7 +56,7 @@ class Controller {
}
returnDialog(response) {
if (response === 'ACCEPT') {
if (response === 'accept') {
let params = {finished: Date.now()};
this.$http.patch(`CreditClassifications/${this.classificationId}`, params).then(() => {
this._getClassifications(this.client.id);

View File

@ -76,7 +76,7 @@ describe('Client', () => {
controller.classificationId = 1;
$httpBackend.when('PATCH', `CreditClassifications/1`).respond(200);
$httpBackend.expect('PATCH', `CreditClassifications/1`);
controller.returnDialog('ACCEPT');
controller.returnDialog('accept');
$httpBackend.flush();
expect(controller._getClassifications).toHaveBeenCalledWith(101);

View File

@ -25,7 +25,7 @@
</form>
<vn-confirm
vn-id="confirmation"
on-response="$ctrl.returnDialog(response)"
on-response="$ctrl.returnDialog($response)"
question="Esta modificación retrasará el plazo del próximo recobro"
message="¿Desea continuar?">
</vn-confirm>

View File

@ -22,7 +22,7 @@ class Controller {
}
returnDialog(response) {
if (response === 'ACCEPT')
if (response === 'accept')
this.addCredit();
}

View File

@ -72,9 +72,9 @@ describe('Client', () => {
});
describe('returnDialog()', () => {
it('should call addCredit() when is called with ACCEPT', () => {
it('should call addCredit() when is called with accept', () => {
spyOn(controller, 'addCredit');
controller.returnDialog('ACCEPT');
controller.returnDialog('accept');
expect(controller.addCredit).toHaveBeenCalledWith();
});

View File

@ -113,5 +113,5 @@
vn-id="confirm"
message="This file will be deleted"
question="Are you sure you want to continue?"
on-response="$ctrl.deleteDms(response)">
on-response="$ctrl.deleteDms($response)">
</vn-confirm>

View File

@ -60,7 +60,7 @@ class Controller {
}
deleteDms(response) {
if (response === 'ACCEPT') {
if (response === 'accept') {
const dmsFk = this.clientDms[this.dmsIndex].dmsFk;
const query = `clientDms/${dmsFk}/removeFile`;
this.$http.post(query).then(() => {

View File

@ -29,7 +29,7 @@ describe('Client', () => {
$httpBackend.when('POST', `clientDms/${dmsId}/removeFile`).respond({});
$httpBackend.expect('POST', `clientDms/${dmsId}/removeFile`);
controller.deleteDms('ACCEPT');
controller.deleteDms('accept');
$httpBackend.flush();
expect(controller.$.model.remove).toHaveBeenCalledWith(dmsIndex);

View File

@ -148,5 +148,5 @@
vn-id="propagate-isEqualizated"
question="You changed the equalization tax"
message="Do you want to spread the change?"
on-response="$ctrl.returnDialogEt(response)">
on-response="$ctrl.returnDialogEt($response)">
</vn-confirm>

View File

@ -41,13 +41,13 @@ export default class Controller {
if (!equals && !this.oldHasToInvoiceByAddress)
this.$.propagateIsEqualizated.show();
else if (!equals)
this.returnDialogEt('ACCEPT');
this.returnDialogEt('accept');
delete this.oldHasToInvoiceByAddress;
}
returnDialogEt(response) {
if (response === 'ACCEPT') {
if (response === 'accept') {
this.$http.patch(`Clients/${this.client.id}/addressesPropagateRe`, {isEqualizated: this.client.isEqualizated}).then(
res => {
if (res.data)

View File

@ -20,7 +20,7 @@ describe('Client', () => {
controller.client = {id: 123, isEqualizated: false};
$httpBackend.when('PATCH', `Clients/${controller.client.id}/addressesPropagateRe`, {isEqualizated: controller.client.isEqualizated}).respond('done');
$httpBackend.expectPATCH(`Clients/${controller.client.id}/addressesPropagateRe`, {isEqualizated: controller.client.isEqualizated});
controller.returnDialogEt('ACCEPT');
controller.returnDialogEt('accept');
$httpBackend.flush();
});
});

View File

@ -1,7 +1,7 @@
<vn-dialog class="edit"
vn-id="postcodeDialog"
on-open="$ctrl.onOpen()"
on-response="$ctrl.onResponse(response)">
on-response="$ctrl.onResponse($response)">
<tpl-body>
<h5 class="vn-py-sm" translate>New postcode</h5>
<p translate>Please, ensure you put the correct data!</p>
@ -44,7 +44,7 @@
</vn-horizontal>
</tpl-body>
<tpl-buttons>
<input type="button" response="CANCEL" translate-attr="{value: 'Cancel'}"/>
<button response="ACCEPT" translate>Save</button>
<input type="button" response="cancel" translate-attr="{value: 'Cancel'}"/>
<button response="accept" translate>Save</button>
</tpl-buttons>
</vn-dialog>

View File

@ -36,7 +36,7 @@ class Controller extends Component {
}
onResponse(response) {
if (response == 'ACCEPT') {
if (response == 'accept') {
try {
if (!this.data.code)
throw new Error(`The postcode can't be empty`);

View File

@ -24,7 +24,7 @@ describe('Client', () => {
$httpBackend.when('PATCH', `postcodes`, params).respond(200, params);
$httpBackend.expect('PATCH', `postcodes`, params).respond(params);
controller.onResponse('ACCEPT');
controller.onResponse('accept');
$httpBackend.flush();
expect(controller.vnApp.showMessage).toHaveBeenCalledWith('The postcode has been saved');

View File

@ -1,6 +1,6 @@
<vn-dialog
vn-id="SMSDialog"
on-response="$ctrl.onResponse(response)">
on-response="$ctrl.onResponse($response)">
<tpl-body>
<h5 class="vn-py-sm" translate>Send SMS</h5>
<vn-horizontal>
@ -20,7 +20,7 @@
</vn-horizontal>
</tpl-body>
<tpl-buttons>
<input type="button" response="CANCEL" translate-attr="{value: 'Cancel'}"/>
<button response="ACCEPT" translate>Send</button>
<input type="button" response="cancel" translate-attr="{value: 'Cancel'}"/>
<button response="accept" translate>Send</button>
</tpl-buttons>
</vn-dialog>

View File

@ -17,7 +17,7 @@ class Controller extends Component {
}
onResponse(response) {
if (response === 'ACCEPT') {
if (response === 'accept') {
this.$http.post(`Sms/send`, this.sms).then(res => {
this.vnApp.showMessage(this.$translate.instant('SMS sent!'));

Some files were not shown because too many files have changed in this diff Show More