dev pull request
gitea/salix/1466-print_refactor There was a failure building this commit Details

This commit is contained in:
Joan Sanchez 2019-11-05 09:16:16 +01:00
commit cac8cb6a6a
605 changed files with 11296 additions and 7102 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

@ -1,23 +0,0 @@
ALTER TABLE `vn2008`.`gestdoc`
ADD COLUMN `contentType` VARCHAR(100) NULL AFTER `file`;
CREATE
OR REPLACE ALGORITHM = UNDEFINED
DEFINER = `root`@`%`
SQL SECURITY DEFINER
VIEW `vn`.`dms` AS
SELECT
`g`.`id` AS `id`,
`g`.`gesttip_id` AS `dmsTypeFk`,
`g`.`file` AS `file`,
`g`.`contentType` AS `contentType`,
`g`.`trabajador_id` AS `workerFk`,
`g`.`warehouse_id` AS `warehouseFk`,
`g`.`emp_id` AS `companyFk`,
`g`.`orden` AS `hardCopyNumber`,
`g`.`original` AS `hasFile`,
`g`.`sref` AS `reference`,
`g`.`brief` AS `description`,
`g`.`odbc_date` AS `created`
FROM
`vn2008`.`gestdoc` `g`;

View File

@ -1,6 +0,0 @@
INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`)
VALUES
('Dms', '*', 'READ', 'ALLOW', 'ROLE', 'employee'),
('ClaimDms', 'removeFile', 'WRITE', 'ALLOW', 'ROLE', 'employee'),
('ClaimDms', '*', 'READ', 'ALLOW', 'ROLE', 'employee'),
('Claim', 'uploadFile', 'WRITE', 'ALLOW', 'ROLE', 'employee');

View File

@ -1,2 +0,0 @@
ALTER TABLE `vn`.`claimLog`
CHANGE COLUMN `id` `id` INT(11) NOT NULL AUTO_INCREMENT ;

View File

@ -1,14 +0,0 @@
DROP TRIGGER IF EXISTS `vn2008`.`ticket_afterUpdate`;
DELIMITER $$
CREATE DEFINER=`root`@`%` TRIGGER `vn2008`.`ticket_afterUpdate`
AFTER UPDATE ON `Tickets`
FOR EACH ROW
BEGIN
IF !(NEW.Id_Ticket <=> OLD.Id_Ticket)
OR !(NEW.warehouse_id <=> OLD.warehouse_id)
OR !(NEW.Fecha <=> OLD.Fecha) THEN
CALL stock.log_add('ticket', NEW.Id_Ticket, OLD.Id_Ticket);
END IF;
END$$
DELIMITER ;

View File

@ -1,2 +0,0 @@
INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`)
VALUES ('Sale', 'updateConcept', 'WRITE', 'ALLOW', 'ROLE', 'employee');

View File

@ -29,7 +29,7 @@ proc: BEGIN
DECLARE vZoneFk INT;
DECLARE vDone BOOL;
DECLARE cTravelTree CURSOR FOR
SELECT id, warehouseFk, shipped FROM tmp.zoneGetShipped;
SELECT zoneFk, warehouseFk, shipped FROM tmp.zoneGetShipped;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET vDone = TRUE;

View File

@ -1,258 +0,0 @@
DROP procedure IF EXISTS `vn`.`catalog_componentCalculate`;
DELIMITER $$
CREATE DEFINER=`root`@`%` PROCEDURE `vn`.`catalog_componentCalculate`(
vZoneFk INT,
vAddressFk INT,
vShipped DATE)
proc: BEGIN
/**
* Calcula los componentes de los articulos de tmp.ticketLot
*
* @param vZoneFk para calcular el transporte
* @param vAgencyModeFk Id del modo de agencia
* @param tmp.ticketLot (warehouseFk,available,itemFk,buyFk)
*
* @return tmp.ticketComponent(itemFk, warehouseFk, available, rate2, rate3, minPrice,
* packing, grouping, groupingMode, buyFk, typeFk)
* @return tmp.ticketComponentPrice (warehouseFk, itemFk, rate, grouping, price)
*/
DECLARE vClientFk INT;
DECLARE vGeneralInflationCoefficient INT DEFAULT 1;
DECLARE vMinimumDensityWeight INT DEFAULT 167;
DECLARE vBoxFreightItem INT DEFAULT 71;
DECLARE vBoxVolume BIGINT; -- DEFAULT 138000;
DECLARE vSpecialPriceComponent INT DEFAULT 10;
DECLARE vDeliveryComponent INT DEFAULT 15;
DECLARE vRecoveryComponent INT DEFAULT 17;
DECLARE vSellByPacketComponent INT DEFAULT 22;
DECLARE vBuyValueComponent INT DEFAULT 28;
DECLARE vMarginComponent INT DEFAULT 29;
DECLARE vDiscountLastItemComponent INT DEFAULT 32;
DECLARE vExtraBaggedComponent INT DEFAULT 38;
DECLARE vManaAutoComponent INT DEFAULT 39;
SELECT volume INTO vBoxVolume
FROM vn.packaging
WHERE id = '94';
SELECT clientFk INTO vClientFK
FROM address
WHERE id = vAddressFk;
SET @rate2 := 0;
SET @rate3 := 0;
DROP TEMPORARY TABLE IF EXISTS tmp.ticketComponentCalculate;
CREATE TEMPORARY TABLE tmp.ticketComponentCalculate
(PRIMARY KEY (itemFk, warehouseFk))
ENGINE = MEMORY
SELECT
tl.itemFk, tl.warehouseFk, tl.available,
IF((@rate2 := IFNULL(pf.rate2, b.price2)) < i.minPrice AND i.hasMinPrice, i.minPrice, @rate2) * 1.0 rate2,
IF((@rate3 := IFNULL(pf.rate3, b.price3)) < i.minPrice AND i.hasMinPrice, i.minPrice, @rate3) * 1.0 rate3,
IFNULL(pf.rate3, 0) AS minPrice,
IFNULL(pf.packing, b.packing) packing,
IFNULL(pf.`grouping`, b.`grouping`) grouping,
ABS(IFNULL(pf.box, b.groupingMode)) groupingMode,
tl.buyFk,
i.typeFk,
IF(i.hasKgPrice,(b.packing * b.weight) / 1000, NULL) weightPacking
FROM tmp.ticketLot tl
JOIN buy b ON b.id = tl.buyFk
JOIN item i ON i.id = tl.itemFk
JOIN itemType it ON it.id = i.typeFk
LEFT JOIN itemCategory ic ON ic.id = it.categoryFk
LEFT JOIN specialPrice sp ON sp.itemFk = i.id AND sp.clientFk = vClientFk
LEFT JOIN (
SELECT * FROM (
SELECT pf.itemFk, pf.`grouping`, pf.packing, pf.box, pf.rate2, pf.rate3, z.warehouseFk
FROM priceFixed pf
JOIN zone z ON z.warehouseFk = pf.warehouseFk OR pf.warehouseFk = 0
WHERE vShipped BETWEEN pf.started AND pf.ended ORDER BY pf.itemFk, pf.warehouseFk DESC
) tpf
GROUP BY tpf.itemFk, tpf.warehouseFk
) pf ON pf.itemFk = tl.itemFk AND pf.warehouseFk = tl.warehouseFk
WHERE b.buyingValue + b.freightValue + b.packageValue + b.comissionValue > 0.01 AND ic.display <> 0;
DROP TEMPORARY TABLE IF EXISTS tmp.ticketComponent;
CREATE TEMPORARY TABLE tmp.ticketComponent (
`warehouseFk` INT UNSIGNED NOT NULL,
`itemFk` INT NOT NULL,
`componentFk` INT UNSIGNED NOT NULL,
`cost` DECIMAL(10,4) NOT NULL,
INDEX `itemWarehouse` USING BTREE (`itemFk` ASC, `warehouseFk` ASC),
UNIQUE INDEX `itemWarehouseComponent` (`itemFk` ASC, `warehouseFk` ASC, `componentFk` ASC));
INSERT INTO tmp.ticketComponent (warehouseFk, itemFk, componentFk, cost)
SELECT
tcc.warehouseFk,
tcc.itemFk,
vBuyValueComponent,
b.buyingValue + b.freightValue + b.packageValue + b.comissionValue
FROM tmp.ticketComponentCalculate tcc
JOIN buy b ON b.id = tcc.buyFk;
INSERT INTO tmp.ticketComponent (warehouseFk, itemFk, componentFk, cost)
SELECT
tcc.warehouseFk,
tcc.itemFk,
vMarginComponent,
tcc.rate3 - b.buyingValue - b.freightValue - b.packageValue - b.comissionValue
FROM tmp.ticketComponentCalculate tcc
JOIN buy b ON b.id = tcc.buyFk;
DROP TEMPORARY TABLE IF EXISTS tmp.ticketComponentBase;
CREATE TEMPORARY TABLE tmp.ticketComponentBase ENGINE = MEMORY
SELECT tc.itemFk, ROUND(SUM(tc.cost), 4) AS base, tc.warehouseFk
FROM tmp.ticketComponent tc
GROUP BY tc.itemFk, warehouseFk;
INSERT INTO tmp.ticketComponent
SELECT tcb.warehouseFk, tcb.itemFk, vRecoveryComponent, ROUND(tcb.base * LEAST(cr.recobro, 0.25), 3)
FROM tmp.ticketComponentBase tcb
JOIN bi.claims_ratio cr ON cr.Id_Cliente = vClientFk
WHERE cr.recobro > 0.009;
INSERT INTO tmp.ticketComponent
SELECT tcb.warehouseFk, tcb.itemFk, vManaAutoComponent, ROUND(base * (0.01 + prices_modifier_rate), 3) as manaAuto
FROM tmp.ticketComponentBase tcb
JOIN `client` c on c.id = vClientFk
JOIN bs.mana_spellers ms ON c.salesPersonFk = ms.Id_Trabajador
WHERE ms.prices_modifier_activated
HAVING manaAuto <> 0;
INSERT INTO tmp.ticketComponent
SELECT tcb.warehouseFk,
tcb.itemFk,
cr.id,
GREATEST(IFNULL(ROUND(tcb.base * cr.tax, 4), 0), tcc.minPrice - tcc.rate3)
FROM tmp.ticketComponentBase tcb
JOIN componentRate cr
JOIN tmp.ticketComponentCalculate tcc ON tcc.itemFk = tcb.itemFk AND tcc.warehouseFk = tcb.warehouseFk
LEFT JOIN specialPrice sp ON sp.clientFk = vClientFk AND sp.itemFk = tcc.itemFk
WHERE cr.id = vDiscountLastItemComponent AND cr.tax <> 0 AND tcc.minPrice < tcc.rate3 AND sp.value IS NULL;
INSERT INTO tmp.ticketComponent
SELECT tcc.warehouseFk, tcc.itemFk, vSellByPacketComponent, tcc.rate2 - tcc.rate3
FROM tmp.ticketComponentCalculate tcc
JOIN buy b ON b.id = tcc.buyFk
LEFT JOIN specialPrice sp ON sp.clientFk = vClientFk AND sp.itemFk = tcc.itemFk
WHERE sp.value IS NULL;
INSERT INTO tmp.ticketComponent
SELECT tcc.warehouseFK,
tcc.itemFk,
vDeliveryComponent,
vGeneralInflationCoefficient
* ROUND((
i.compression
* r.cm3
* IF(am.deliveryMethodFk = 1, (GREATEST(i.density, vMinimumDensityWeight) / vMinimumDensityWeight), 1)
* IFNULL((z.price - z.bonus)
* 1/*amz.inflation*/ , 50)) / vBoxVolume, 4
) cost
FROM tmp.ticketComponentCalculate tcc
JOIN item i ON i.id = tcc.itemFk
JOIN zone z ON z.id = vZoneFk
JOIN agencyMode am ON am.id = z.agencyModeFk
LEFT JOIN bi.rotacion r ON r.warehouse_id = tcc.warehouseFk
AND r.Id_Article = tcc.itemFk
HAVING cost <> 0;
IF (SELECT COUNT(*) FROM vn.addressForPackaging WHERE addressFk = vAddressFk) THEN
INSERT INTO tmp.ticketComponent
SELECT tcc.warehouseFk, b.itemFk, vExtraBaggedComponent, ap.packagingValue cost
FROM tmp.ticketComponentCalculate tcc
JOIN vn.addressForPackaging ap
WHERE ap.addressFk = vAddressFk;
END IF;
DROP TEMPORARY TABLE IF EXISTS tmp.ticketComponentCopy;
CREATE TEMPORARY TABLE tmp.ticketComponentCopy ENGINE = MEMORY
SELECT * FROM tmp.ticketComponent;
INSERT INTO tmp.ticketComponent
SELECT tcc.warehouseFk,
tcc.itemFk,
vSpecialPriceComponent,
sp.value - SUM(tcc.cost) sumCost
FROM tmp.ticketComponentCopy tcc
JOIN componentRate cr ON cr.id = tcc.componentFk
JOIN specialPrice sp ON sp.clientFk = vClientFK AND sp.itemFk = tcc.itemFk
WHERE cr.classRate IS NULL
GROUP BY tcc.itemFk, tcc.warehouseFk
HAVING ABS(sumCost) > 0.001;
DROP TEMPORARY TABLE IF EXISTS tmp.ticketComponentSum;
CREATE TEMPORARY TABLE tmp.ticketComponentSum
(INDEX (itemFk, warehouseFk))
ENGINE = MEMORY
SELECT SUM(cost) sumCost, tc.itemFk, tc.warehouseFk, cr.classRate
FROM tmp.ticketComponent tc
JOIN componentRate cr ON cr.id = tc.componentFk
GROUP BY tc.itemFk, tc.warehouseFk, cr.classRate;
DROP TEMPORARY TABLE IF EXISTS tmp.ticketComponentRate;
CREATE TEMPORARY TABLE tmp.ticketComponentRate ENGINE = MEMORY
SELECT tcc.warehouseFk,
tcc.itemFk,
1 rate,
IF(tcc.groupingMode = 1, tcc.`grouping`, 1) grouping,
CAST(SUM(tcs.sumCost) AS DECIMAL(10,2)) price,
CAST(SUM(tcs.sumCost) AS DECIMAL(10,2)) / weightPacking priceKg
FROM tmp.ticketComponentCalculate tcc
JOIN tmp.ticketComponentSum tcs ON tcs.itemFk = tcc.itemFk
AND tcs.warehouseFk = tcc.warehouseFk
WHERE IFNULL(tcs.classRate, 1) = 1
AND tcc.groupingMode < 2 AND (tcc.packing > tcc.`grouping` or tcc.groupingMode = 0)
GROUP BY tcs.warehouseFk, tcs.itemFk;
INSERT INTO tmp.ticketComponentRate (warehouseFk, itemFk, rate, grouping, price, priceKg)
SELECT
tcc.warehouseFk,
tcc.itemFk,
2 rate,
tcc.packing grouping,
SUM(tcs.sumCost) price,
SUM(tcs.sumCost) / weightPacking priceKg
FROM tmp.ticketComponentCalculate tcc
JOIN tmp.ticketComponentSum tcs ON tcs.itemFk = tcc.itemFk
AND tcs.warehouseFk = tcc.warehouseFk
WHERE tcc.available IS NULL OR (IFNULL(tcs.classRate, 2) = 2
AND tcc.packing > 0 AND tcc.available >= tcc.packing)
GROUP BY tcs.warehouseFk, tcs.itemFk;
INSERT INTO tmp.ticketComponentRate (warehouseFk, itemFk, rate, grouping, price, priceKg)
SELECT
tcc.warehouseFk,
tcc.itemFk,
3 rate,
tcc.available grouping,
SUM(tcs.sumCost) price,
SUM(tcs.sumCost) / weightPacking priceKg
FROM tmp.ticketComponentCalculate tcc
JOIN tmp.ticketComponentSum tcs ON tcs.itemFk = tcc.itemFk
AND tcs.warehouseFk = tcc.warehouseFk
WHERE IFNULL(tcs.classRate, 3) = 3
GROUP BY tcs.warehouseFk, tcs.itemFk;
DROP TEMPORARY TABLE IF EXISTS tmp.ticketComponentPrice;
CREATE TEMPORARY TABLE tmp.ticketComponentPrice ENGINE = MEMORY
SELECT * FROM (
SELECT * FROM tmp.ticketComponentRate ORDER BY price
) t
GROUP BY itemFk, warehouseFk, `grouping`;
DROP TEMPORARY TABLE
tmp.ticketComponentCalculate,
tmp.ticketComponentSum,
tmp.ticketComponentBase,
tmp.ticketComponentRate,
tmp.ticketComponentCopy;
END$$
DELIMITER ;

View File

@ -1,2 +0,0 @@
ALTER TABLE `vn2008`.`Movimientos_componentes`
CHANGE COLUMN `Valor` `Valor` DECIMAL(10,4) NOT NULL ;

View File

@ -1,16 +0,0 @@
USE `vn`;
DROP procedure IF EXISTS `ticketCalculate`;
DELIMITER $$
USE `vn`$$
CREATE DEFINER=`root`@`%` PROCEDURE `ticketCalculate`(
vLanded DATE,
vAddressFk INT,
vAgencyModeFk INT)
proc: BEGIN
-- OBSOLETO utilizar catalog_calculate
CALL vn.catalog_calculate(vLanded, vAddressFk, vAgencyModeFk);
END$$
DELIMITER ;

View File

@ -1,26 +0,0 @@
ALTER TABLE `vn2008`.`warehouse`
ADD COLUMN `hasStowaway` TINYINT(1) NOT NULL DEFAULT 0 AFTER `hasConfectionTeam`;
UPDATE `vn2008`.`warehouse` SET `hasStowaway` = '1' WHERE (`id` = '1');
CREATE
OR REPLACE ALGORITHM = UNDEFINED
DEFINER = `root`@`%`
SQL SECURITY DEFINER
VIEW `vn`.`warehouse` AS
SELECT
`t`.`id` AS `id`,
`t`.`name` AS `name`,
`t`.`inventario` AS `isInventory`,
`t`.`fuente` AS `isFeedStock`,
`t`.`is_comparative` AS `isComparative`,
`t`.`comisionantes` AS `hasComission`,
`t`.`reserve` AS `hasAvailable`,
`t`.`isManaged` AS `isManaged`,
`t`.`tpv` AS `isForTicket`,
`t`.`hasStowaway` AS `hasStowaway`
FROM
`vn2008`.`warehouse` `t`;

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,18 @@
CREATE TABLE `vn`.`travelLog` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`originFk` int(10) unsigned NOT NULL,
`userFk` int(10) unsigned DEFAULT NULL,
`action` set('insert','update','delete') COLLATE utf8_unicode_ci NOT NULL,
`creationDate` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
`description` text CHARACTER SET utf8,
`changedModel` varchar(45) COLLATE utf8_unicode_ci DEFAULT NULL,
`oldInstance` text COLLATE utf8_unicode_ci,
`newInstance` text COLLATE utf8_unicode_ci,
`changedModelId` int(11) DEFAULT NULL,
`changedModelValue` varchar(45) COLLATE utf8_unicode_ci DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `originFk` (`originFk`),
KEY `userFk` (`userFk`),
CONSTRAINT `travelLog_ibfk_1` FOREIGN KEY (`originFk`) REFERENCES `account`.`user` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `travelLog_ibfk_2` FOREIGN KEY (`userFk`) REFERENCES `account`.`user` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

View File

@ -0,0 +1,6 @@
CREATE TABLE `vn`.`packagingConfig` (
`id` INT NOT NULL AUTO_INCREMENT,
`upperGap` INT NOT NULL,
PRIMARY KEY (`id`));
INSERT INTO `vn`.`packagingConfig` (`upperGap`) VALUES ('10');

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

@ -1,7 +1,10 @@
USE `vn`;
DROP procedure IF EXISTS `vn`.`zoneGetLanded`;
DELIMITER $$
CREATE DEFINER=`root`@`%` PROCEDURE `vn`.`zoneGetLanded`(vShipped DATE, vAddressFk INT, vAgencyModeFk INT, vWarehouseFk INT)
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.
@ -9,7 +12,7 @@ BEGIN
* @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
* @table tmp.zoneGetLanded Datos de recepción
*/
DECLARE vPostalCode varchar(10);
@ -45,3 +48,4 @@ BEGIN
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

@ -1,10 +1,13 @@
USE `vn`;
DROP procedure IF EXISTS `vn`.`zoneGetShipped`;
DELIMITER $$
CREATE DEFINER=`root`@`%` PROCEDURE `vn`.`zoneGetShipped`(vLanded DATE, vAddressFk INT, vAgencyModeFk INT, vWarehouseFk INT)
USE `vn`$$
CREATE DEFINER=`root`@`%` PROCEDURE `zoneGetShipped__`(vLanded DATE, vAddressFk INT, vAgencyModeFk INT, vWarehouseFk INT)
BEGIN
/**
* Devuelve la mínima fecha de envía para cada warehouse
* Devuelve la mínima fecha de envía para cada warehouse
*
* @param vLanded La fecha de recepcion
* @param vAddressFk Id del consignatario
@ -44,4 +47,4 @@ BEGIN
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

@ -36,7 +36,7 @@ UNLOCK TABLES;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
-- Dump completed on 2019-10-14 13:22:52
-- Dump completed on 2019-10-29 8:19:03
USE `account`;
-- MySQL dump 10.13 Distrib 5.7.27, for Linux (x86_64)
--
@ -81,7 +81,7 @@ UNLOCK TABLES;
LOCK TABLES `roleRole` WRITE;
/*!40000 ALTER TABLE `roleRole` DISABLE KEYS */;
INSERT INTO `roleRole` VALUES (0,0),(0,1),(0,2),(0,3),(0,5),(0,6),(0,9),(0,11),(0,13),(0,15),(0,16),(0,17),(0,18),(0,19),(0,20),(0,21),(0,22),(0,30),(0,31),(0,32),(0,33),(0,34),(0,35),(0,36),(0,37),(0,38),(0,39),(0,40),(0,41),(0,42),(0,43),(0,44),(0,45),(0,47),(0,48),(0,49),(0,50),(0,51),(0,52),(0,53),(0,54),(0,55),(0,56),(0,57),(0,58),(0,59),(0,60),(0,61),(0,62),(0,64),(0,65),(0,66),(1,1),(1,2),(1,3),(1,6),(1,11),(2,2),(2,6),(2,11),(3,3),(3,6),(3,11),(5,1),(5,2),(5,3),(5,5),(5,6),(5,11),(5,13),(5,18),(5,21),(5,33),(5,53),(6,6),(9,0),(9,1),(9,2),(9,3),(9,5),(9,6),(9,9),(9,11),(9,13),(9,15),(9,16),(9,17),(9,18),(9,19),(9,20),(9,21),(9,22),(9,30),(9,31),(9,32),(9,33),(9,34),(9,35),(9,36),(9,37),(9,38),(9,39),(9,40),(9,41),(9,42),(9,43),(9,44),(9,45),(9,47),(9,48),(9,49),(9,50),(9,51),(9,52),(9,53),(9,54),(9,55),(9,56),(9,57),(9,58),(9,59),(9,60),(9,61),(9,62),(9,64),(9,65),(9,66),(11,6),(11,11),(13,1),(13,2),(13,3),(13,6),(13,11),(13,13),(15,1),(15,2),(15,3),(15,6),(15,11),(15,15),(15,35),(16,1),(16,2),(16,3),(16,6),(16,11),(16,13),(16,15),(16,16),(16,35),(17,1),(17,2),(17,3),(17,5),(17,6),(17,11),(17,13),(17,15),(17,16),(17,17),(17,18),(17,19),(17,20),(17,21),(17,33),(17,35),(17,36),(17,37),(17,39),(17,44),(17,47),(17,49),(17,50),(17,53),(17,56),(17,57),(17,58),(17,59),(17,64),(17,65),(18,1),(18,2),(18,3),(18,6),(18,11),(18,18),(19,1),(19,2),(19,3),(19,6),(19,11),(19,13),(19,18),(19,19),(19,21),(19,53),(20,1),(20,2),(20,3),(20,6),(20,11),(20,13),(20,15),(20,16),(20,18),(20,19),(20,20),(20,21),(20,35),(20,36),(20,44),(20,47),(20,49),(20,50),(20,53),(20,56),(20,57),(20,58),(20,59),(20,65),(21,1),(21,2),(21,3),(21,6),(21,11),(21,13),(21,18),(21,21),(21,53),(22,1),(22,2),(22,3),(22,6),(22,11),(22,13),(22,18),(22,21),(22,22),(22,53),(30,1),(30,2),(30,3),(30,5),(30,6),(30,11),(30,13),(30,15),(30,16),(30,18),(30,19),(30,20),(30,21),(30,22),(30,30),(30,33),(30,35),(30,36),(30,44),(30,47),(30,49),(30,50),(30,53),(30,56),(30,57),(30,58),(30,59),(30,64),(30,65),(31,1),(31,2),(31,3),(31,6),(31,11),(31,31),(32,1),(32,2),(32,3),(32,6),(32,11),(32,32),(33,33),(34,1),(34,2),(34,3),(34,6),(34,11),(34,13),(34,33),(34,34),(35,1),(35,2),(35,3),(35,6),(35,11),(35,35),(36,1),(36,2),(36,3),(36,6),(36,11),(36,36),(36,44),(36,47),(37,1),(37,2),(37,3),(37,6),(37,11),(37,37),(38,1),(38,2),(38,3),(38,6),(38,11),(38,37),(38,38),(38,64),(39,1),(39,2),(39,3),(39,5),(39,6),(39,11),(39,13),(39,18),(39,21),(39,33),(39,39),(39,53),(40,1),(40,2),(40,3),(40,6),(40,11),(40,40),(41,1),(41,2),(41,3),(41,6),(41,11),(41,13),(41,35),(41,40),(41,41),(42,1),(42,2),(42,3),(42,6),(42,11),(42,42),(43,1),(43,2),(43,3),(43,6),(43,11),(43,13),(43,42),(43,43),(44,1),(44,2),(44,3),(44,6),(44,11),(44,44),(45,1),(45,2),(45,3),(45,6),(45,11),(45,13),(45,44),(45,45),(47,1),(47,2),(47,3),(47,6),(47,11),(47,47),(48,1),(48,2),(48,3),(48,6),(48,11),(48,13),(48,47),(48,48),(49,1),(49,2),(49,3),(49,6),(49,11),(49,36),(49,44),(49,47),(49,49),(49,58),(50,1),(50,2),(50,3),(50,6),(50,11),(50,13),(50,36),(50,44),(50,47),(50,49),(50,50),(50,56),(50,57),(50,58),(50,59),(51,1),(51,2),(51,3),(51,6),(51,11),(51,51),(52,1),(52,2),(52,3),(52,6),(52,11),(52,13),(52,18),(52,19),(52,21),(52,35),(52,51),(52,52),(52,53),(53,1),(53,2),(53,3),(53,6),(53,11),(53,53),(54,1),(54,2),(54,3),(54,6),(54,11),(54,54),(55,1),(55,2),(55,3),(55,6),(55,11),(55,13),(55,54),(55,55),(56,1),(56,2),(56,3),(56,6),(56,11),(56,56),(57,1),(57,2),(57,3),(57,6),(57,11),(57,13),(57,56),(57,57),(58,1),(58,2),(58,3),(58,6),(58,11),(58,58),(59,1),(59,2),(59,3),(59,6),(59,11),(59,13),(59,58),(59,59),(60,1),(60,2),(60,3),(60,5),(60,6),(60,11),(60,13),(60,18),(60,21),(60,33),(60,36),(60,44),(60,47),(60,49),(60,50),(60,53),(60,56),(60,57),(60,58),(60,59),(60,60),(61,1),(61,2),(61,3),(61,6),(61,11),(61,13),(61,36),(61,44),(61,47),(61,61),(62,62),(64,64),(65,1),(65,2),(65,3),(65,6),(65,11),(65,13),(65,18),(65,19),(65,21),(65,36),(65,44),(65,47),(65,49),(65,50),(65,53),(65,56),(65,57),(65,58),(65,59),(65,65),(66,0),(66,1),(66,2),(66,3),(66,5),(66,6),(66,9),(66,11),(66,13),(66,15),(66,16),(66,17),(66,18),(66,19),(66,20),(66,21),(66,22),(66,30),(66,31),(66,32),(66,33),(66,34),(66,35),(66,36),(66,37),(66,38),(66,39),(66,40),(66,41),(66,42),(66,43),(66,44),(66,45),(66,47),(66,48),(66,49),(66,50),(66,51),(66,52),(66,53),(66,54),(66,55),(66,56),(66,57),(66,58),(66,59),(66,60),(66,61),(66,62),(66,64),(66,65),(66,66);
INSERT INTO `roleRole` VALUES (0,0),(0,1),(0,2),(0,3),(0,5),(0,6),(0,9),(0,11),(0,13),(0,15),(0,16),(0,17),(0,18),(0,19),(0,20),(0,21),(0,22),(0,30),(0,31),(0,32),(0,33),(0,34),(0,35),(0,36),(0,37),(0,38),(0,39),(0,40),(0,41),(0,42),(0,43),(0,44),(0,45),(0,47),(0,48),(0,49),(0,50),(0,51),(0,52),(0,53),(0,54),(0,55),(0,56),(0,57),(0,58),(0,59),(0,60),(0,61),(0,62),(0,64),(0,65),(0,66),(1,1),(1,2),(1,3),(1,6),(1,11),(2,2),(2,6),(2,11),(3,3),(3,6),(3,11),(5,1),(5,2),(5,3),(5,5),(5,6),(5,11),(5,13),(5,18),(5,21),(5,33),(5,53),(6,6),(9,0),(9,1),(9,2),(9,3),(9,5),(9,6),(9,9),(9,11),(9,13),(9,15),(9,16),(9,17),(9,18),(9,19),(9,20),(9,21),(9,22),(9,30),(9,31),(9,32),(9,33),(9,34),(9,35),(9,36),(9,37),(9,38),(9,39),(9,40),(9,41),(9,42),(9,43),(9,44),(9,45),(9,47),(9,48),(9,49),(9,50),(9,51),(9,52),(9,53),(9,54),(9,55),(9,56),(9,57),(9,58),(9,59),(9,60),(9,61),(9,62),(9,64),(9,65),(9,66),(11,6),(11,11),(13,1),(13,2),(13,3),(13,6),(13,11),(13,13),(15,1),(15,2),(15,3),(15,6),(15,11),(15,15),(15,35),(16,1),(16,2),(16,3),(16,6),(16,11),(16,13),(16,15),(16,16),(16,35),(17,1),(17,2),(17,3),(17,5),(17,6),(17,11),(17,13),(17,15),(17,16),(17,17),(17,18),(17,19),(17,20),(17,21),(17,33),(17,35),(17,36),(17,37),(17,39),(17,44),(17,47),(17,49),(17,50),(17,53),(17,56),(17,57),(17,58),(17,59),(17,64),(17,65),(18,1),(18,2),(18,3),(18,6),(18,11),(18,18),(19,1),(19,2),(19,3),(19,6),(19,11),(19,13),(19,18),(19,19),(19,21),(19,53),(20,1),(20,2),(20,3),(20,6),(20,11),(20,13),(20,15),(20,16),(20,18),(20,19),(20,20),(20,21),(20,35),(20,36),(20,44),(20,47),(20,49),(20,50),(20,53),(20,56),(20,57),(20,58),(20,59),(20,65),(21,1),(21,2),(21,3),(21,6),(21,11),(21,13),(21,18),(21,21),(21,53),(22,1),(22,2),(22,3),(22,6),(22,11),(22,13),(22,18),(22,21),(22,22),(22,53),(30,1),(30,2),(30,3),(30,5),(30,6),(30,11),(30,13),(30,15),(30,16),(30,18),(30,19),(30,20),(30,21),(30,22),(30,30),(30,33),(30,35),(30,36),(30,44),(30,47),(30,49),(30,50),(30,53),(30,56),(30,57),(30,58),(30,59),(30,64),(30,65),(31,1),(31,2),(31,3),(31,6),(31,11),(31,31),(32,1),(32,2),(32,3),(32,6),(32,11),(32,32),(33,33),(34,1),(34,2),(34,3),(34,6),(34,11),(34,13),(34,33),(34,34),(35,1),(35,2),(35,3),(35,6),(35,11),(35,35),(36,1),(36,2),(36,3),(36,6),(36,11),(36,36),(36,44),(36,47),(37,1),(37,2),(37,3),(37,6),(37,11),(37,37),(38,1),(38,2),(38,3),(38,6),(38,11),(38,37),(38,38),(38,64),(39,1),(39,2),(39,3),(39,5),(39,6),(39,11),(39,13),(39,18),(39,21),(39,33),(39,39),(39,53),(39,56),(39,57),(40,1),(40,2),(40,3),(40,6),(40,11),(40,40),(41,1),(41,2),(41,3),(41,6),(41,11),(41,13),(41,35),(41,40),(41,41),(42,1),(42,2),(42,3),(42,6),(42,11),(42,42),(43,1),(43,2),(43,3),(43,6),(43,11),(43,13),(43,42),(43,43),(44,1),(44,2),(44,3),(44,6),(44,11),(44,44),(45,1),(45,2),(45,3),(45,6),(45,11),(45,13),(45,44),(45,45),(47,1),(47,2),(47,3),(47,6),(47,11),(47,47),(48,1),(48,2),(48,3),(48,6),(48,11),(48,13),(48,47),(48,48),(49,1),(49,2),(49,3),(49,6),(49,11),(49,36),(49,44),(49,47),(49,49),(49,58),(50,1),(50,2),(50,3),(50,6),(50,11),(50,13),(50,36),(50,44),(50,47),(50,49),(50,50),(50,56),(50,57),(50,58),(50,59),(51,1),(51,2),(51,3),(51,6),(51,11),(51,51),(52,1),(52,2),(52,3),(52,6),(52,11),(52,13),(52,18),(52,19),(52,21),(52,35),(52,51),(52,52),(52,53),(53,1),(53,2),(53,3),(53,6),(53,11),(53,53),(54,1),(54,2),(54,3),(54,6),(54,11),(54,54),(55,1),(55,2),(55,3),(55,6),(55,11),(55,13),(55,54),(55,55),(56,1),(56,2),(56,3),(56,6),(56,11),(56,56),(57,1),(57,2),(57,3),(57,6),(57,11),(57,13),(57,56),(57,57),(58,1),(58,2),(58,3),(58,6),(58,11),(58,58),(59,1),(59,2),(59,3),(59,6),(59,11),(59,13),(59,58),(59,59),(60,1),(60,2),(60,3),(60,5),(60,6),(60,11),(60,13),(60,18),(60,21),(60,33),(60,36),(60,44),(60,47),(60,49),(60,50),(60,53),(60,56),(60,57),(60,58),(60,59),(60,60),(61,1),(61,2),(61,3),(61,6),(61,11),(61,13),(61,36),(61,44),(61,47),(61,61),(62,62),(64,64),(65,1),(65,2),(65,3),(65,6),(65,11),(65,13),(65,18),(65,19),(65,21),(65,36),(65,44),(65,47),(65,49),(65,50),(65,53),(65,56),(65,57),(65,58),(65,59),(65,65),(66,0),(66,1),(66,2),(66,3),(66,5),(66,6),(66,9),(66,11),(66,13),(66,15),(66,16),(66,17),(66,18),(66,19),(66,20),(66,21),(66,22),(66,30),(66,31),(66,32),(66,33),(66,34),(66,35),(66,36),(66,37),(66,38),(66,39),(66,40),(66,41),(66,42),(66,43),(66,44),(66,45),(66,47),(66,48),(66,49),(66,50),(66,51),(66,52),(66,53),(66,54),(66,55),(66,56),(66,57),(66,58),(66,59),(66,60),(66,61),(66,62),(66,64),(66,65),(66,66);
/*!40000 ALTER TABLE `roleRole` ENABLE KEYS */;
UNLOCK TABLES;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
@ -94,7 +94,7 @@ UNLOCK TABLES;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
-- Dump completed on 2019-10-14 13:22:52
-- Dump completed on 2019-10-29 8:19:04
USE `salix`;
-- MySQL dump 10.13 Distrib 5.7.27, for Linux (x86_64)
--
@ -142,7 +142,7 @@ UNLOCK TABLES;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
-- Dump completed on 2019-10-14 13:22:52
-- Dump completed on 2019-10-29 8:19:04
USE `vn`;
-- MySQL dump 10.13 Distrib 5.7.27, for Linux (x86_64)
--
@ -227,7 +227,7 @@ UNLOCK TABLES;
LOCK TABLES `tag` WRITE;
/*!40000 ALTER TABLE `tag` DISABLE KEYS */;
INSERT INTO `tag` VALUES (1,'Color',0,0,'ink',NULL,NULL),(2,'Forma',1,0,NULL,NULL,NULL),(3,'Material',1,0,NULL,NULL,NULL),(4,'Longitud',1,1,NULL,'mm',NULL),(5,'Diámetro',1,1,NULL,'mm',NULL),(6,'Perímetro',1,1,NULL,'mm',NULL),(7,'Ancho de la base',1,1,NULL,'mm',NULL),(8,'Altura',1,1,NULL,'mm',NULL),(9,'Volumen',1,1,NULL,'ml',NULL),(10,'Densidad',1,1,NULL,NULL,NULL),(11,'Calidad',1,0,NULL,NULL,NULL),(12,'Textura',1,0,NULL,NULL,NULL),(13,'Material del mango',1,0,NULL,NULL,NULL),(14,'Compra mínima',1,0,NULL,NULL,NULL),(15,'Nº pétalos',1,1,NULL,NULL,NULL),(16,'Ancho',1,1,NULL,'mm',NULL),(18,'Profundidad',1,1,NULL,'mm',NULL),(19,'Largo',1,1,NULL,'mm',NULL),(20,'Ancho superior',1,1,NULL,'mm',NULL),(21,'Ancho inferior',1,1,NULL,'mm',NULL),(22,'Gramaje',1,1,NULL,'g',NULL),(23,'Tallos',1,1,NULL,NULL,NULL),(24,'Estado',1,0,NULL,NULL,NULL),(25,'Color principal',0,0,'ink',NULL,NULL),(26,'Color secundario',0,0,'ink',NULL,NULL),(27,'Longitud(cm)',1,1,NULL,'cm',NULL),(28,'Diámetro base',1,1,'','mm',NULL),(29,'Colección',1,0,NULL,NULL,NULL),(30,'Uds / caja',1,1,NULL,NULL,NULL),(31,'Contenido',1,0,NULL,NULL,NULL),(32,'Peso',1,1,NULL,'g',NULL),(33,'Grosor',1,1,NULL,'mm',NULL),(34,'Marca',1,0,NULL,NULL,NULL),(35,'Origen',0,0,'origin',NULL,NULL),(36,'Proveedor',1,0,NULL,NULL,NULL),(37,'Productor',0,0,'producer',NULL,NULL),(38,'Duración',1,1,NULL,'s',NULL),(39,'Flor',1,0,NULL,NULL,NULL),(40,'Soporte',1,0,NULL,NULL,NULL),(41,'Tamaño flor',1,0,NULL,NULL,NULL),(42,'Apertura',1,0,NULL,NULL,NULL),(43,'Tallo',1,0,NULL,NULL,NULL),(44,'Nº hojas',1,1,NULL,NULL,NULL),(45,'Dimensiones',1,0,NULL,NULL,NULL),(46,'Diámetro boca',1,1,NULL,'mm',NULL),(47,'Nº flores',1,1,NULL,NULL,NULL),(48,'Uds / paquete',1,1,NULL,NULL,NULL),(49,'Maceta',1,1,NULL,'cm',NULL),(50,'Textura flor',1,0,NULL,NULL,NULL),(51,'Textura hoja',1,0,NULL,NULL,NULL),(52,'Tipo de IVA',1,0,NULL,NULL,NULL),(53,'Tronco',1,0,NULL,NULL,NULL),(54,'Hoja',1,0,NULL,NULL,NULL),(55,'Formato',1,0,NULL,NULL,NULL),(56,'Genero',1,0,NULL,NULL,NULL),(57,'Especie',1,0,NULL,NULL,NULL),(58,'Variedad',1,0,NULL,NULL,NULL),(59,'Medida grande',1,0,NULL,NULL,NULL),(60,'Medida mediano',1,0,NULL,NULL,NULL),(61,'Medida pequeño',1,0,NULL,NULL,NULL),(62,'Medida pequeño',1,0,NULL,NULL,NULL),(63,'Recipiente interior',1,0,NULL,NULL,NULL),(64,'Material secundario',1,0,NULL,NULL,NULL),(65,'Colores',1,0,NULL,NULL,NULL),(66,'Referencia',1,0,NULL,NULL,NULL),(67,'Categoria',1,0,NULL,NULL,NULL),(68,'Amb',1,0,NULL,NULL,NULL),(69,'Anchura',1,1,NULL,'cm',NULL),(70,'Hueco interior',1,0,NULL,NULL,NULL),(71,'Tamaño',1,0,NULL,NULL,NULL),(72,'Color botón',1,0,NULL,NULL,NULL),(73,'Tamaño minimo del botón',1,0,NULL,NULL,NULL),(74,'Obtentor',1,0,NULL,NULL,NULL),(75,'Longitud del brote',1,0,NULL,NULL,NULL),(76,'Tallos / u.v.',1,0,NULL,NULL,NULL),(77,'Madera de',1,0,NULL,NULL,NULL),(78,'Unidad de venta',1,0,NULL,NULL,NULL),(79,'Temporal',1,0,NULL,NULL,NULL),(80,'Gramaje/tallo',1,1,NULL,'g',NULL),(81,'Peso/paquete',1,1,NULL,'g',NULL),(82,'Flexibilidad del tallo',1,0,NULL,NULL,NULL),(83,'Nº planchas',1,1,NULL,NULL,NULL),(84,'Nº páginas',1,1,NULL,NULL,NULL),(85,'Editorial',1,0,NULL,NULL,NULL),(86,'Idioma',1,0,NULL,NULL,NULL),(87,'Fecha publicación',1,0,NULL,NULL,NULL),(88,'Cubierta',1,0,NULL,NULL,NULL),(89,'Encuadernación',1,0,NULL,NULL,NULL),(90,'Autor',1,0,NULL,NULL,NULL),(91,'Envoltorio',1,0,NULL,NULL,NULL),(92,'Nombre temporal',1,0,NULL,NULL,NULL),(93,'Modelo',1,0,NULL,NULL,NULL),(94,'Producto',1,0,NULL,NULL,NULL),(95,'Título',1,0,NULL,NULL,NULL),(96,'Tomo',1,0,NULL,NULL,NULL),(97,'Articulo',1,0,NULL,NULL,NULL),(98,'Metodo de cultivo',1,0,NULL,NULL,NULL),(99,'Edad',1,0,NULL,NULL,NULL),(100,'Agotado',1,0,NULL,NULL,NULL),(101,'Altura con asa',1,1,NULL,'cm',NULL),(102,'Nº tallos',1,1,NULL,NULL,NULL),(103,'Cultivo',1,0,NULL,NULL,NULL),(104,'Sabor',1,0,NULL,NULL,NULL),(105,'Talla',1,0,NULL,NULL,NULL),(106,'Calibre',1,1,NULL,NULL,NULL),(107,'Dulzura',1,1,NULL,'bx',NULL),(108,'Piezas',1,0,NULL,NULL,NULL),(109,'Altura con patas',1,0,NULL,NULL,NULL);
INSERT INTO `tag` VALUES (1,'color','Color',0,0,'ink',NULL,NULL),(2,'','Forma',1,0,NULL,NULL,NULL),(3,'','Material',1,0,NULL,NULL,NULL),(4,'','Longitud',1,1,NULL,'mm',NULL),(5,'','Diámetro',1,1,NULL,'mm',NULL),(6,'','Perímetro',1,1,NULL,'mm',NULL),(7,'','Ancho de la base',1,1,NULL,'mm',NULL),(8,'','Altura',1,1,NULL,'mm',NULL),(9,'','Volumen',1,1,NULL,'ml',NULL),(10,'','Densidad',1,1,NULL,NULL,NULL),(11,'','Calidad',1,0,NULL,NULL,NULL),(12,'','Textura',1,0,NULL,NULL,NULL),(13,'','Material del mango',1,0,NULL,NULL,NULL),(14,'','Compra mínima',1,0,NULL,NULL,NULL),(15,'','Nº pétalos',1,1,NULL,NULL,NULL),(16,'','Ancho',1,1,NULL,'mm',NULL),(18,'','Profundidad',1,1,NULL,'mm',NULL),(19,'','Largo',1,1,NULL,'mm',NULL),(20,'','Ancho superior',1,1,NULL,'mm',NULL),(21,'','Ancho inferior',1,1,NULL,'mm',NULL),(22,'','Gramaje',1,1,NULL,'g',NULL),(23,'stems','Tallos',1,1,NULL,NULL,NULL),(24,'','Estado',1,0,NULL,NULL,NULL),(25,'','Color principal',0,0,'ink',NULL,NULL),(26,'','Color secundario',0,0,'ink',NULL,NULL),(27,'','Longitud(cm)',1,1,NULL,'cm',NULL),(28,'','Diámetro base',1,1,'','mm',NULL),(29,'','Colección',1,0,NULL,NULL,NULL),(30,'','Uds / caja',1,1,NULL,NULL,NULL),(31,'','Contenido',1,0,NULL,NULL,NULL),(32,'','Peso',1,1,NULL,'g',NULL),(33,'','Grosor',1,1,NULL,'mm',NULL),(34,'','Marca',1,0,NULL,NULL,NULL),(35,'origin','Origen',0,0,'origin',NULL,NULL),(36,'','Proveedor',1,0,NULL,NULL,NULL),(37,'producer','Productor',0,0,'producer',NULL,NULL),(38,'','Duración',1,1,NULL,'s',NULL),(39,'','Flor',1,0,NULL,NULL,NULL),(40,'','Soporte',1,0,NULL,NULL,NULL),(41,'','Tamaño flor',1,0,NULL,NULL,NULL),(42,'','Apertura',1,0,NULL,NULL,NULL),(43,'','Tallo',1,0,NULL,NULL,NULL),(44,'','Nº hojas',1,1,NULL,NULL,NULL),(45,'','Dimensiones',1,0,NULL,NULL,NULL),(46,'','Diámetro boca',1,1,NULL,'mm',NULL),(47,'','Nº flores',1,1,NULL,NULL,NULL),(48,'','Uds / paquete',1,1,NULL,NULL,NULL),(49,'','Maceta',1,1,NULL,'cm',NULL),(50,'','Textura flor',1,0,NULL,NULL,NULL),(51,'','Textura hoja',1,0,NULL,NULL,NULL),(52,'','Tipo de IVA',1,0,NULL,NULL,NULL),(53,'','Tronco',1,0,NULL,NULL,NULL),(54,'','Hoja',1,0,NULL,NULL,NULL),(55,'','Formato',1,0,NULL,NULL,NULL),(56,'','Genero',1,0,NULL,NULL,NULL),(57,'','Especie',1,0,NULL,NULL,NULL),(58,'','Variedad',1,0,NULL,NULL,NULL),(59,'','Medida grande',1,0,NULL,NULL,NULL),(60,'','Medida mediano',1,0,NULL,NULL,NULL),(61,'','Medida pequeño',1,0,NULL,NULL,NULL),(62,'','Medida pequeño',1,0,NULL,NULL,NULL),(63,'','Recipiente interior',1,0,NULL,NULL,NULL),(64,'','Material secundario',1,0,NULL,NULL,NULL),(65,'','Colores',1,0,NULL,NULL,NULL),(66,'','Referencia',1,0,NULL,NULL,NULL),(67,'','Categoria',1,0,NULL,NULL,NULL),(68,'','Amb',1,0,NULL,NULL,NULL),(69,'','Anchura',1,1,NULL,'cm',NULL),(70,'','Hueco interior',1,0,NULL,NULL,NULL),(71,'','Tamaño',1,0,NULL,NULL,NULL),(72,'','Color botón',1,0,NULL,NULL,NULL),(73,'','Tamaño minimo del botón',1,0,NULL,NULL,NULL),(74,'','Obtentor',1,0,NULL,NULL,NULL),(75,'','Longitud del brote',1,0,NULL,NULL,NULL),(76,'','Tallos / u.v.',1,0,NULL,NULL,NULL),(77,'','Madera de',1,0,NULL,NULL,NULL),(78,'','Unidad de venta',1,0,NULL,NULL,NULL),(79,'','Temporal',1,0,NULL,NULL,NULL),(80,'','Gramaje/tallo',1,1,NULL,'g',NULL),(81,'','Peso/paquete',1,1,NULL,'g',NULL),(82,'','Flexibilidad del tallo',1,0,NULL,NULL,NULL),(83,'','Nº planchas',1,1,NULL,NULL,NULL),(84,'','Nº páginas',1,1,NULL,NULL,NULL),(85,'','Editorial',1,0,NULL,NULL,NULL),(86,'','Idioma',1,0,NULL,NULL,NULL),(87,'','Fecha publicación',1,0,NULL,NULL,NULL),(88,'','Cubierta',1,0,NULL,NULL,NULL),(89,'','Encuadernación',1,0,NULL,NULL,NULL),(90,'','Autor',1,0,NULL,NULL,NULL),(91,'','Envoltorio',1,0,NULL,NULL,NULL),(92,'','Nombre temporal',1,0,NULL,NULL,NULL),(93,'','Modelo',1,0,NULL,NULL,NULL),(94,'','Producto',1,0,NULL,NULL,NULL),(95,'','Título',1,0,NULL,NULL,NULL),(96,'','Tomo',1,0,NULL,NULL,NULL),(97,'','Articulo',1,0,NULL,NULL,NULL),(98,'','Metodo de cultivo',1,0,NULL,NULL,NULL),(99,'','Edad',1,0,NULL,NULL,NULL),(100,'','Agotado',1,0,NULL,NULL,NULL),(101,'','Altura con asa',1,1,NULL,'cm',NULL),(102,'','Nº tallos',1,1,NULL,NULL,NULL),(103,'','Cultivo',1,0,NULL,NULL,NULL),(104,'','Sabor',1,0,NULL,NULL,NULL),(105,'','Talla',1,0,NULL,NULL,NULL),(106,'','Calibre',1,1,NULL,NULL,NULL),(107,'','Dulzura',1,1,NULL,'bx',NULL),(108,'','Piezas',1,0,NULL,NULL,NULL),(109,'','Altura con patas',1,0,NULL,NULL,NULL);
/*!40000 ALTER TABLE `tag` ENABLE KEYS */;
UNLOCK TABLES;
@ -287,7 +287,7 @@ UNLOCK TABLES;
LOCK TABLES `state` WRITE;
/*!40000 ALTER TABLE `state` DISABLE KEYS */;
INSERT INTO `state` VALUES (1,'Arreglar',2,0,'FIXING',NULL,1,0,0),(2,'Libre',1,0,'FREE',NULL,2,0,0),(3,'OK',3,0,'OK',3,28,1,0),(4,'Impreso',4,1,'PRINTED',2,29,1,0),(5,'Preparación',5,1,'ON_PREPARATION',7,5,0,0),(6,'En Revisión',7,1,'ON_CHECKING',NULL,6,0,1),(7,'Sin Acabar',2,0,'NOT_READY',NULL,7,0,0),(8,'Revisado',8,1,'CHECKED',NULL,8,0,1),(9,'Encajando',9,1,'PACKING',NULL,9,0,1),(10,'Encajado',10,2,'PACKED',NULL,10,0,1),(11,'Facturado',0,0,'INVOICED',NULL,11,0,1),(12,'Bloqueado',0,0,'BLOCKED',NULL,12,0,0),(13,'En Reparto',11,3,'ON_DELIVERY',NULL,13,0,1),(14,'Preparado',6,1,'PREPARED',NULL,14,0,1),(15,'Pte Recogida',12,3,'WAITING_FOR_PICKUP',NULL,15,0,1),(16,'Entregado',13,3,'DELIVERED',NULL,16,0,1),(17,'Eliminado',14,3,'ERASED',NULL,17,0,0),(20,'Asignado',4,1,'PICKER_DESIGNED',NULL,20,1,0),(21,'Retornado',4,1,'PRINTED_BACK',6,21,0,0),(22,'¿Fecha?',2,0,'WRONG_DATE',NULL,22,0,0),(23,'URGENTE',2,0,'LAST_CALL',NULL,23,1,0),(24,'Encadenado',3,0,'CHAINED',4,24,0,0),(25,'Embarcando',3,0,'BOARDING',5,25,0,0),(26,'Prep Previa',5,1,'PREVIOUS_PREPARATION',1,26,0,0),(27,'Prep Asistida',5,1,'ASSISTED_PREPARATION',7,27,0,0),(28,'zz Previa',3,1,'OK PREVIOUS',3,28,1,0),(29,'zzmpreso Previa',4,1,'PRINTED PREVIOUS',2,29,1,0);
INSERT INTO `state` VALUES (1,'Arreglar',2,0,'FIXING',NULL,1,0,0),(2,'Libre',1,0,'FREE',NULL,2,0,0),(3,'OK',3,0,'OK',3,28,1,0),(4,'Impreso',4,1,'PRINTED',2,29,1,0),(5,'Preparación',5,1,'ON_PREPARATION',7,5,0,0),(6,'En Revisión',7,1,'ON_CHECKING',NULL,6,0,1),(7,'Sin Acabar',2,0,'NOT_READY',NULL,7,0,0),(8,'Revisado',8,1,'CHECKED',NULL,8,0,1),(9,'Encajando',9,1,'PACKING',NULL,9,0,1),(10,'Encajado',10,2,'PACKED',NULL,10,0,1),(11,'Facturado',0,0,'INVOICED',NULL,11,0,1),(12,'Bloqueado',0,0,'BLOCKED',NULL,12,0,0),(13,'En Reparto',11,3,'ON_DELIVERY',NULL,13,0,1),(14,'Preparado',6,1,'PREPARED',NULL,14,0,1),(15,'Pte Recogida',12,3,'WAITING_FOR_PICKUP',NULL,15,0,1),(16,'Entregado',13,3,'DELIVERED',NULL,16,0,1),(17,'Eliminado',14,3,'ERASED',NULL,17,0,0),(20,'Asignado',4,1,'PICKER_DESIGNED',NULL,20,1,0),(21,'Retornado',4,1,'PRINTED_BACK',6,21,0,0),(22,'¿Fecha?',2,0,'WRONG_DATE',NULL,22,0,0),(23,'URGENTE',2,0,'LAST_CALL',NULL,23,1,0),(24,'Encadenado',3,0,'CHAINED',4,24,0,0),(25,'Embarcando',3,0,'BOARDING',5,25,0,0),(26,'Prep Previa',5,1,'PREVIOUS_PREPARATION',1,26,0,0),(27,'Prep Asistida',5,1,'ASSISTED_PREPARATION',7,27,0,0),(28,'Previa OK',3,1,'OK PREVIOUS',3,28,1,0),(29,'Previa Impreso',4,1,'PRINTED PREVIOUS',2,29,1,0);
/*!40000 ALTER TABLE `state` ENABLE KEYS */;
UNLOCK TABLES;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
@ -300,7 +300,7 @@ UNLOCK TABLES;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
-- Dump completed on 2019-10-14 13:22:53
-- Dump completed on 2019-10-29 8:19:05
USE `vn2008`;
-- MySQL dump 10.13 Distrib 5.7.27, for Linux (x86_64)
--
@ -349,16 +349,6 @@ INSERT INTO `department` VALUES (1,'VERDNATURA',1,78,1,0,NULL,NULL,NULL,0,0,0,0)
/*!40000 ALTER TABLE `department` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Dumping data for table `escritos`
--
LOCK TABLES `escritos` WRITE;
/*!40000 ALTER TABLE `escritos` DISABLE KEYS */;
INSERT INTO `escritos` VALUES (1,'Carta_1','Aviso inicial por saldo deudor',0,'0'),(2,'Carta_2','Reiteracion de aviso por saldo deudor',0,'0'),(3,'Cred_Up','Notificación de aumento de crédito',0,'0'),(4,'Cred_down','Notificación de reducción de crédito',0,'0'),(5,'Pet_CC','Petición de datos bancarios B2B',0,'0'),(6,'SolCredito','Solicitud de crédito',0,'0'),(7,'LeyPago','Ley de pagos',0,'0'),(8,'Pet_CC_Core','Petición de datos bancarios CORE',0,'0'),(9,'nueva_alta','Documento de nueva alta de cliente',0,'0'),(10,'client_welcome','Email de bienvenida para nuevo cliente',0,'0'),(11,'setup_printer','Email de instalación de impresora',0,'0'),(12,'client-welcome','Email de bienvenida como nuevo cliente',1,'0'),(13,'printer-setup','Email de instalación y configuración de impresora de coronas',1,'0'),(14,'sepa-core','Email de solicitud de datos bancarios core',1,'1'),(15,'letter-debtor-st','Email de aviso inicial por saldo deudor',1,'1'),(16,'letter-debtor-nd','Email de aviso reiterado por saldo deudor',1,'1'),(17,'client-lcr','Email de solicitud de datos bancarios LCR',1,'1');
/*!40000 ALTER TABLE `escritos` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Dumping data for table `Grupos`
--
@ -378,7 +368,7 @@ UNLOCK TABLES;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
-- Dump completed on 2019-10-14 13:22:53
-- Dump completed on 2019-10-29 8:19:05
USE `bi`;
-- MySQL dump 10.13 Distrib 5.7.27, for Linux (x86_64)
--
@ -426,7 +416,7 @@ UNLOCK TABLES;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
-- Dump completed on 2019-10-14 13:22:53
-- Dump completed on 2019-10-29 8:19:05
USE `cache`;
-- MySQL dump 10.13 Distrib 5.7.27, for Linux (x86_64)
--
@ -451,7 +441,7 @@ USE `cache`;
LOCK TABLES `cache` WRITE;
/*!40000 ALTER TABLE `cache` DISABLE KEYS */;
INSERT INTO `cache` VALUES (1,'equalizator','00:15:00'),(2,'available','00:03:00'),(3,'stock','00:30:00'),(4,'last_buy','00:30:00'),(5,'weekly_sales','12:00:00'),(6,'bionic','00:05:00'),(7,'sales','00:03:00'),(8,'visible','00:04:00'),(9,'item_range','00:03:00'),(10,'barcodes','01:00:00'),(11,'prod_graphic','00:15:00'),(12,'ticketShipping','00:01:00');
INSERT INTO `cache` VALUES (1,'equalizator','00:15:00'),(2,'available','00:06:00'),(3,'stock','00:30:00'),(4,'last_buy','00:30:00'),(5,'weekly_sales','12:00:00'),(6,'bionic','00:05:00'),(7,'sales','00:03:00'),(8,'visible','00:04:00'),(9,'item_range','00:03:00'),(10,'barcodes','01:00:00'),(11,'prod_graphic','00:15:00'),(12,'ticketShipping','00:01:00');
/*!40000 ALTER TABLE `cache` ENABLE KEYS */;
UNLOCK TABLES;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
@ -464,7 +454,7 @@ UNLOCK TABLES;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
-- Dump completed on 2019-10-14 13:22:53
-- Dump completed on 2019-10-29 8:19:05
USE `hedera`;
-- MySQL dump 10.13 Distrib 5.7.27, for Linux (x86_64)
--
@ -532,7 +522,7 @@ UNLOCK TABLES;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
-- Dump completed on 2019-10-14 13:22:53
-- Dump completed on 2019-10-29 8:19:05
USE `postgresql`;
-- MySQL dump 10.13 Distrib 5.7.27, for Linux (x86_64)
--
@ -557,7 +547,7 @@ USE `postgresql`;
LOCK TABLES `calendar_labour_type` WRITE;
/*!40000 ALTER TABLE `calendar_labour_type` DISABLE KEYS */;
INSERT INTO `calendar_labour_type` VALUES (1,'Horario general','00:20:00',40),(2,'Horario 35h/semana','00:20:00',35),(3,'Horario 20h/semana','00:00:00',20),(4,'Festivo y Fin de semana','00:00:00',0),(5,'Horario 30h/semana','00:20:00',30),(6,'Horario 25h/semana','00:20:00',25),(7,'Vacaciones trabajadas','00:00:00',0),(8,'Vacaciones','00:00:00',0),(9,'Horario 26h/semana','00:20:00',26),(10,'Horario 28h/semana','00:20:00',28),(11,'Horario 8h/semana','00:00:00',8),(12,'Horario 16h/semana','00:00:00',16),(13,'Horario 32h/semana','00:20:00',32),(14,'Horario 24h/semana','00:20:00',24),(15,'Horario 10h/semana','00:00:00',10),(16,'Horario 27,5h/semana','00:20:00',28),(17,'Horario 13,5h/semana','00:20:00',14),(18,'Horario 31h/semana',NULL,31),(19,'Horario 21,5h/semana',NULL,22),(20,'Horario 34h/semana',NULL,34),(21,'Horario 17h/semana',NULL,17),(22,'Horario 18h/semana',NULL,18),(23,'Horario 37,5 h/semana',NULL,38),(24,'Horario 29 h/semana',NULL,29),(25,'Horario 12h/semana',NULL,12),(26,'Horario 10h/semana',NULL,10),(27,'Horario 15h/semana',NULL,15),(28,'Horario 9h/semana',NULL,9),(29,'Horario 23h/semana',NULL,23),(30,'Horario 21h/semana',NULL,21),(31,'Horario 39h/semana',NULL,39);
INSERT INTO `calendar_labour_type` VALUES (1,'Horario general','00:20:00',40),(2,'Horario 35h/semana','00:20:00',35),(3,'Horario 20h/semana','00:00:00',20),(4,'Festivo y Fin de semana','00:00:00',0),(5,'Horario 30h/semana','00:20:00',30),(6,'Horario 25h/semana','00:20:00',25),(7,'Vacaciones trabajadas','00:00:00',0),(8,'Vacaciones','00:00:00',0),(9,'Horario 26h/semana','00:20:00',26),(10,'Horario 28h/semana','00:20:00',28),(11,'Horario 8h/semana','00:00:00',8),(12,'Horario 16h/semana','00:00:00',16),(13,'Horario 32h/semana','00:20:00',32),(14,'Horario 24h/semana','00:20:00',24),(15,'Horario 10h/semana','00:00:00',10),(16,'Horario 27,5h/semana','00:20:00',28),(17,'Horario 13,5h/semana','00:20:00',14),(18,'Horario 31h/semana',NULL,31),(19,'Horario 21,5h/semana',NULL,22),(20,'Horario 34h/semana',NULL,34),(21,'Horario 17h/semana',NULL,17),(22,'Horario 18h/semana',NULL,18),(23,'Horario 37,5 h/semana',NULL,38),(24,'Horario 29 h/semana',NULL,29),(25,'Horario 12h/semana',NULL,12),(26,'Horario 10h/semana',NULL,10),(27,'Horario 15h/semana',NULL,15),(28,'Horario 9h/semana',NULL,9),(29,'Horario 23h/semana',NULL,23),(30,'Horario 21h/semana',NULL,21),(31,'Horario 39h/semana',NULL,39),(32,'Horario 22/semana',NULL,22);
/*!40000 ALTER TABLE `calendar_labour_type` ENABLE KEYS */;
UNLOCK TABLES;
@ -577,7 +567,7 @@ UNLOCK TABLES;
LOCK TABLES `media_type` WRITE;
/*!40000 ALTER TABLE `media_type` DISABLE KEYS */;
INSERT INTO `media_type` VALUES (3,'email'),(8,'extension centr'),(12,'extension movil'),(6,'facebook'),(2,'fijo'),(11,'material'),(10,'movil empresa'),(1,'movil personal'),(5,'msn'),(9,'seg social'),(4,'skype'),(7,'web');
INSERT INTO `media_type` VALUES (3,'email'),(12,'extension movil'),(6,'facebook'),(2,'fijo'),(11,'material'),(10,'movil empresa'),(1,'movil personal'),(5,'msn'),(9,'seg social'),(4,'skype'),(7,'web');
/*!40000 ALTER TABLE `media_type` ENABLE KEYS */;
UNLOCK TABLES;
@ -607,7 +597,7 @@ UNLOCK TABLES;
LOCK TABLES `workcenter` WRITE;
/*!40000 ALTER TABLE `workcenter` DISABLE KEYS */;
INSERT INTO `workcenter` VALUES (1,'Silla',20,1023,1),(2,'Mercaflor',19,NULL,NULL),(3,'Marjales',26,20007,NULL),(4,'VNH',NULL,NULL,3),(5,'Madrid',28,2851,5),(6,'Vilassar',88,88031,2),(7,'Tenerife',NULL,NULL,10),(8,'Silla-Agrario',26,2,NULL);
INSERT INTO `workcenter` VALUES (1,'Silla',20,1024,1),(2,'Mercaflor',19,NULL,NULL),(3,'Marjales',26,20007,NULL),(4,'VNH',NULL,NULL,3),(5,'Madrid',28,2851,5),(6,'Vilassar',88,88031,2),(7,'Tenerife',NULL,NULL,10),(8,'Silla-Agrario',26,2,NULL);
/*!40000 ALTER TABLE `workcenter` ENABLE KEYS */;
UNLOCK TABLES;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
@ -620,4 +610,4 @@ UNLOCK TABLES;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
-- Dump completed on 2019-10-14 13:22:54
-- Dump completed on 2019-10-29 8:19:06

View File

@ -57,13 +57,13 @@ INSERT INTO `vn`.`country`(`id`, `country`, `isUeeMember`, `code`, `currencyFk`,
(19,'Francia', 1, 'FR', 1, 25),
(30,'Canarias', 1, 'IC', 1, 22);
INSERT INTO `vn`.`warehouse`(`id`, `name`, `isComparative`, `isInventory`, `hasAvailable`, `isManaged`, `hasStowaway`)
INSERT INTO `vn`.`warehouse`(`id`, `name`, `isComparative`, `isInventory`, `hasAvailable`, `isManaged`, `hasStowaway`, `hasDms`)
VALUES
(1, 'Warehouse One', 1, 1, 1, 1, 1),
(2, 'Warehouse Two', 1, 1, 1, 1, 0),
(3, 'Warehouse Three', 1, 1, 1, 1, 0),
(4, 'Warehouse Four', 1, 1, 1, 1, 0),
(5, 'Warehouse Five', 1, 1, 1, 1, 0);
(1, 'Warehouse One', 1, 1, 1, 1, 1, 1),
(2, 'Warehouse Two', 1, 1, 1, 1, 0, 0),
(3, 'Warehouse Three', 1, 1, 1, 1, 0, 0),
(4, 'Warehouse Four', 1, 1, 1, 1, 0, 0),
(5, 'Warehouse Five', 1, 1, 1, 1, 0, 0);
INSERT INTO `vn`.`sector`(`id`, `description`, `warehouseFk`, `isPreviousPreparedByPacking`, `code`, `pickingPlacement`, `path`)
VALUES
@ -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),
@ -471,7 +487,7 @@ INSERT INTO `vn`.`ticket`(`id`, `priority`, `agencyModeFk`,`warehouseFk`,`routeF
(11, 1, 7, 1, 6, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 102, 'NY roofs', 122, NULL, 0, 3, CURDATE()),
(12, 1, 1, 1, 1, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 103, 'Phone Box', 123, NULL, 0, 1, CURDATE()),
(13, 1, 7, 1, 6, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 103, 'Phone Box', 123, NULL, 0, 3, CURDATE()),
(14, 1, 2, 1, NULL, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 104, 'Malibu Point', 4, NULL, 0, 9, CURDATE()),
(14, 1, 2, 1, NULL, CURDATE(), CURDATE(), 104, 'Malibu Point', 4, NULL, 0, 9, CURDATE()),
(15, 1, 7, 1, 6, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 105, 'Plastic Cell', 125, NULL, 0, 3, CURDATE()),
(16, 1, 7, 1, 6, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 106, 'Many Places', 126, NULL, 0, 3, CURDATE()),
(17, 1, 7, 2, 6, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 106, 'Many Places', 126, NULL, 0, 3, CURDATE()),
@ -649,7 +665,9 @@ INSERT INTO `vn`.`item`(`id`, `typeFk`, `size`, `inkFk`, `stems`, `originFk`, `d
(12, 3, 30, 'GRE', 1, 2, NULL, 2, 06021010, 1, 4751000000, 0, NULL, 0, 67350, 2, NULL),
(13, 5, 30, 'GRE', 1, 2, NULL, NULL, 06021010, 0, 4751000000, 0, NULL, 0, 67350, 2, NULL),
(14, 5, 90, 'AZL', 1, 2, NULL, NULL, 06021010, 0, 4751000000, 0, NULL, 0, 67350, 2, NULL),
(71, 4, NULL, NULL, NULL, 1, NULL, NULL, 06021010, 1, 4751000000, 0, NULL, 0, NULL, 2, NULL);
(15, 4, NULL, NULL, NULL, 1, NULL, NULL, 06021010, 0, 4751000000, 0, NULL, 0, 67350, 2, NULL),
(16, 4, NULL, NULL, NULL, 1, NULL, NULL, 06021010, 0, 4751000000, 0, NULL, 0, 67350, 2, NULL),
(71, 4, NULL, NULL, NULL, 1, NULL, NULL, 06021010, 1, 4751000000, 0, NULL, 0, 67350, 2, NULL);
INSERT INTO `vn`.`expedition`(`id`, `agencyModeFk`, `ticketFk`, `isBox`, `created`, `itemFk`, `counter`, `checked`, `workerFk`)
VALUES
@ -666,12 +684,14 @@ INSERT INTO `vn`.`expedition`(`id`, `agencyModeFk`, `ticketFk`, `isBox`, `create
INSERT INTO `vn`.`packaging`(`id`, `volume`, `width`, `height`, `depth`, `isPackageReturnable`, `created`, `itemFk`, `price`)
VALUES
(1, 0.00, 10, 10, 0, 0, CURDATE(), 6, 1.50),
(2, 100.00, 20, 20, 0, 0, CURDATE(), 7, 1.00),
(3, 14000.00, 0, 0, 0, 0, CURDATE(), NULL, 0),
(4, 218000.00, 0, 0, 0, 0, CURDATE(), NULL, 0),
(5, 292000.00, 0, 0, 0, 0, CURDATE(), NULL, 0),
(94, 140875.00, 49.00, 115.00, 25.00, 0, CURDATE(), 71, 0.00);
(1, 0.00, 10, 10, 0, 1, CURDATE(), 6, 1.50),
(2, 100.00, 20, 20, 0, 1, CURDATE(), 7, 1.00),
(3, 14000.00, 0, 0, 0, 1, CURDATE(), NULL, 0),
(4, 218000.00, 0, 0, 0, 0, CURDATE(), NULL, 0),
(5, 292000.00, 0, 0, 0, 0, CURDATE(), NULL, 0),
(94, 140875.00, 49.00, 115.00, 25.00, 0, CURDATE(), 71, 0.00),
('cc', 1640038.00, 56.00, 220.00, 128.00, 1, CURDATE(), 15, 90.00),
('pallet 100', 2745600.00, 100.00, 220.00, 120.00, 1, CURDATE(), 16, 0.00);
INSERT INTO `vn`.`ticketPackaging`(`id`, `ticketFk`, `packagingFk`, `quantity`, `created`, `pvp`)
VALUES
@ -1047,25 +1067,25 @@ INSERT INTO `vn`.`ticketWeekly`(`ticketFk`, `weekDay`)
(4, 4),
(5, 6);
INSERT INTO `vn`.`travel`(`id`,`shipped`, `landed`, `warehouseInFk`, `warehouseOutFk`, `agencyFk`, `m3`, `kg`)
INSERT INTO `vn`.`travel`(`id`,`shipped`, `landed`, `warehouseInFk`, `warehouseOutFk`, `agencyFk`, `m3`, `kg`,`ref`, `totalEntries`)
VALUES
(1, DATE_ADD(CURDATE(), INTERVAL -2 MONTH), DATE_ADD(CURDATE(), INTERVAL -2 MONTH), 1, 2, 1, 100.00, 1000),
(2, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 1, 2, 1, 150, 2000),
(3, CURDATE(), CURDATE(), 1, 2, 1, 0.00, 0.00),
(4, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 1, 2, 1, 50.00, 500),
(5, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 3, 2, 1, 50.00, 500),
(6, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 4, 2, 1, 50.00, 500),
(7, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 5, 2, 1, 50.00, 500);
(1, DATE_ADD(CURDATE(), INTERVAL -2 MONTH), DATE_ADD(CURDATE(), INTERVAL -2 MONTH), 1, 2, 1, 100.00, 1000, 'first travel', 1),
(2, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 1, 2, 1, 150, 2000, 'second travel', 2),
(3, CURDATE(), CURDATE(), 1, 2, 1, 0.00, 0.00, 'third travel', 1),
(4, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 1, 2, 1, 50.00, 500, 'fourth travel', 0),
(5, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 3, 2, 1, 50.00, 500, 'fifth travel', 1),
(6, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 4, 2, 1, 50.00, 500, 'sixth travel', 1),
(7, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 5, 2, 1, 50.00, 500, 'seventh travel', 1);
INSERT INTO `vn`.`entry`(`id`, `supplierFk`, `created`, `travelFk`, `companyFk`,`ref`)
INSERT INTO `vn`.`entry`(`id`, `supplierFk`, `created`, `travelFk`, `companyFk`, `ref`, `notes`, `evaNotes`)
VALUES
(1, 1, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 1, 442, 'Movimiento 1'),
(2, 2, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 2, 442, 'Movimiento 2'),
(3, 1, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 3, 442, 'Movimiento 3'),
(4, 2, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 4, 69, 'Movimiento 4'),
(5, 2, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 5, 442, 'Movimiento 5'),
(6, 2, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 6, 442, 'Movimiento 6'),
(7, 2, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 7, 442, 'Movimiento 7');
(1, 1, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 1, 442, 'Movement 1', 'this is the note one', 'observation one'),
(2, 2, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 2, 442, 'Movement 2', 'this is the note two', 'observation two'),
(3, 1, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 3, 442, 'Movement 3', 'this is the note three', 'observation three'),
(4, 2, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 2, 69, 'Movement 4', 'this is the note four', 'observation four'),
(5, 2, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 5, 442, 'Movement 5', 'this is the note five', 'observation five'),
(6, 2, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 6, 442, 'Movement 6', 'this is the note six', 'observation six'),
(7, 2, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 7, 442, 'Movement 7', 'this is the note seven', 'observation seven');
INSERT INTO `bi`.`claims_ratio`(`id_Cliente`, `Consumo`, `Reclamaciones`, `Ratio`, `recobro`, `inflacion`)
VALUES
@ -1076,21 +1096,21 @@ INSERT INTO `bi`.`claims_ratio`(`id_Cliente`, `Consumo`, `Reclamaciones`, `Ratio
INSERT INTO `vn`.`buy`(`id`,`entryFk`,`itemFk`,`buyingValue`,`quantity`,`packageFk`,`stickers`,`freightValue`,`packageValue`,`comissionValue`,`packing`,`grouping`,`groupingMode`,`location`,`price1`,`price2`,`price3`,`minPrice`,`producer`,`printedStickers`,`isChecked`,`isIgnored`, `created`)
VALUES
(1, 1, 1, 50, 5000, 4, 1, 0.000, 0.000, 0.000, 1, 1, 1, NULL, 0.00, 99.6, 99.4, 0.00, NULL, 0, 1, 0, DATE_ADD(CURDATE(), INTERVAL -2 MONTH)),
(2, 2, 1, 50, 100, 4, 1, 0.000, 0.000, 0.000, 1, 1, 1, NULL, 0.00, 99.6, 99.4, 0.00, NULL, 0, 1, 0, DATE_ADD(CURDATE(), INTERVAL -1 MONTH)),
(3, 3, 1, 50, 100, 4, 1, 0.000, 0.000, 0.000, 1, 1, 0, NULL, 0.00, 99.6, 99.4, 0.00, NULL, 0, 1, 0, CURDATE()),
(4, 2, 2, 5, 450, 3, 1, 0.000, 0.000, 0.000, 10, 10, 0, NULL, 0.00, 7.30, 7.00, 0.00, NULL, 0, 1, 0, CURDATE()),
(5, 3, 3, 55, 500, 5, 1, 0.000, 0.000, 0.000, 1, 1, 0, NULL, 0.00, 78.3, 75.6, 0.00, NULL, 0, 1, 0, CURDATE()),
(6, 4, 8, 50, 1000, 4, 1, 0.000, 0.000, 0.000, 1, 1, 1, NULL, 0.00, 99.6, 99.4, 0.00, NULL, 0, 1, 0, CURDATE()),
(7, 4, 9, 20, 1000, 3, 1, 0.000, 0.000, 0.000, 10, 10, 1, NULL, 0.00, 30.50, 29.00, 0.00, NULL, 0, 1, 0, CURDATE()),
(8, 4, 4, 1.25, 1000, 3, 1, 0.000, 0.000, 0.000, 10, 10, 1, NULL, 0.00, 1.75, 1.67, 0.00, NULL, 0, 1, 0, CURDATE()),
(9, 4, 4, 1.25, 1000, 3, 1, 0.000, 0.000, 0.000, 10, 10, 1, NULL, 0.00, 1.75, 1.67, 0.00, NULL, 0, 1, 0, CURDATE()),
(10, 5, 1, 50, 10, 4, 1, 0.000, 0.000, 0.000, 1, 1, 1, NULL, 0.00, 99.6, 99.4, 0.00, NULL, 0, 1, 0, CURDATE()),
(11, 5, 4, 1.25, 10, 3, 1, 0.000, 0.000, 0.000, 10, 10, 1, NULL, 0.00, 1.75, 1.67, 0.00, NULL, 0, 1, 0, CURDATE()),
(12, 6, 4, 1.25, 0, 3, 1, 0.000, 0.000, 0.000, 10, 10, 1, NULL, 0.00, 1.75, 1.67, 0.00, NULL, 0, 1, 0, CURDATE()),
(13, 7, 1, 50, 0, 3, 1, 0.000, 0.000, 0.000, 1, 1, 1, NULL, 0.00, 99.6, 99.4, 0.00, NULL, 0, 1, 0, CURDATE()),
(14, 7, 2, 5, 0, 3, 1, 0.000, 0.000, 0.000, 10, 10, 1, NULL, 0.00, 7.30, 7.00, 0.00, NULL, 0, 1, 0, CURDATE()),
(15, 7, 4, 1.25, 0, 3, 1, 0.000, 0.000, 0.000, 10, 10, 1, NULL, 0.00, 1.75, 1.67, 0.00, NULL, 0, 1, 0, CURDATE());
(1, 1, 1, 50, 5000, 4, 1, 1.500, 1.500, 0.000, 1, 1, 1, NULL, 0.00, 99.6, 99.4, 0.00, NULL, 0, 1, 0, DATE_ADD(CURDATE(), INTERVAL -2 MONTH)),
(2, 2, 1, 50, 100, 4, 1, 1.500, 1.500, 0.000, 1, 1, 1, NULL, 0.00, 99.6, 99.4, 0.00, NULL, 0, 1, 0, DATE_ADD(CURDATE(), INTERVAL -1 MONTH)),
(3, 3, 1, 50, 100, 4, 1, 1.500, 1.500, 0.000, 1, 1, 0, NULL, 0.00, 99.6, 99.4, 0.00, NULL, 0, 1, 0, CURDATE()),
(4, 2, 2, 5, 450, 3, 1, 1.000, 1.000, 0.000, 10, 10, 0, NULL, 0.00, 7.30, 7.00, 0.00, NULL, 0, 1, 0, CURDATE()),
(5, 3, 3, 55, 500, 5, 1, 1.000, 1.000, 0.000, 1, 1, 0, NULL, 0.00, 78.3, 75.6, 0.00, NULL, 0, 1, 0, CURDATE()),
(6, 4, 8, 50, 1000, 4, 1, 1.000, 1.000, 0.000, 1, 1, 1, NULL, 0.00, 99.6, 99.4, 0.00, NULL, 0, 1, 0, CURDATE()),
(7, 4, 9, 20, 1000, 3, 1, 0.500, 0.500, 0.000, 10, 10, 1, NULL, 0.00, 30.50, 29.00, 0.00, NULL, 0, 1, 0, CURDATE()),
(8, 4, 4, 1.25, 1000, 3, 1, 0.500, 0.500, 0.000, 10, 10, 1, NULL, 0.00, 1.75, 1.67, 0.00, NULL, 0, 1, 0, CURDATE()),
(9, 4, 4, 1.25, 1000, 3, 1, 0.500, 0.500, 0.000, 10, 10, 1, NULL, 0.00, 1.75, 1.67, 0.00, NULL, 0, 1, 0, CURDATE()),
(10, 5, 1, 50, 10, 4, 1, 2.500, 2.500, 0.000, 1, 1, 1, NULL, 0.00, 99.6, 99.4, 0.00, NULL, 0, 1, 0, CURDATE()),
(11, 5, 4, 1.25, 10, 3, 1, 2.500, 2.500, 0.000, 10, 10, 1, NULL, 0.00, 1.75, 1.67, 0.00, NULL, 0, 1, 0, CURDATE()),
(12, 6, 4, 1.25, 0, 3, 1, 2.500, 2.500, 0.000, 10, 10, 1, NULL, 0.00, 1.75, 1.67, 0.00, NULL, 0, 1, 0, CURDATE()),
(13, 7, 1, 50, 0, 3, 1, 2.000, 2.000, 0.000, 1, 1, 1, NULL, 0.00, 99.6, 99.4, 0.00, NULL, 0, 1, 0, CURDATE()),
(14, 7, 2, 5, 0, 3, 1, 2.000, 2.000, 0.000, 10, 10, 1, NULL, 0.00, 7.30, 7.00, 0.00, NULL, 0, 1, 0, CURDATE()),
(15, 7, 4, 1.25, 0, 3, 1, 2.000, 2.000, 0.000, 10, 10, 1, NULL, 0.00, 1.75, 1.67, 0.00, NULL, 0, 1, 0, CURDATE());
INSERT INTO `vn2008`.`tblContadores`(`id`,`FechaInventario`)
VALUES
@ -1594,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)),

File diff suppressed because it is too large Load Diff

View File

@ -6,7 +6,7 @@ import config from './config.js';
let currentUser;
let asyncActions = {
let actions = {
// Generic extensions
clickIfExists: async function(selector) {
@ -15,16 +15,16 @@ let asyncActions = {
return exists;
},
hasClass: async function(selector, className) {
return await this.evaluate((selector, className) => {
document.querySelector(selector).classList.contains(className);
}, selector, className);
},
parsedUrl: async function() {
return new URL(await this.url());
},
waitUntilNotPresent: async function(selector) {
await this.wait(selector => {
return document.querySelector(selector) == null;
}, selector);
},
// Salix specific extensions
changeLanguageToEnglish: async function() {
@ -52,8 +52,8 @@ let asyncActions = {
let logoutClicked = await this.clickIfExists('#logout');
if (logoutClicked) {
let buttonSelector = '.vn-dialog.shown button[response=ACCEPT]';
this.wait(buttonSelector => {
let buttonSelector = '.vn-dialog.shown button[response=accept]';
await this.wait(buttonSelector => {
return document.querySelector(buttonSelector) != null
|| location.hash == '#!/login';
}, buttonSelector);
@ -63,7 +63,7 @@ let asyncActions = {
try {
await this.waitForURL('#!/login');
} catch (e) {
this.goto(`${config.url}/#!/login`);
await this.goto(`${config.url}/#!/login`);
}
await this.doLogin(userName, null)
@ -116,95 +116,75 @@ let asyncActions = {
}, selector, time);
},
isDisabled: async function(selector) {
return await this.hasClass(selector, 'disabled');
}
};
let actions = {
clearTextarea: function(selector, done) {
this.wait(selector)
clearTextarea: function(selector) {
return this.wait(selector)
.evaluate(inputSelector => {
return document.querySelector(inputSelector).value = '';
}, selector)
.then(done)
.catch(done);
}, selector);
},
clearInput: function(selector, done) {
this.wait(selector)
clearInput: function(selector) {
return this.wait(selector)
.evaluate(selector => {
let $ctrl = document.querySelector(selector).closest('.vn-field').$ctrl;
$ctrl.field = null;
$ctrl.$.$apply();
$ctrl.input.dispatchEvent(new Event('change'));
}, selector)
.then(done)
.catch(done);
}, selector);
},
getProperty: function(selector, property, done) {
this.evaluate_now((selector, property) => {
getProperty: function(selector, property) {
return this.evaluate((selector, property) => {
return document.querySelector(selector)[property].replace(/\s+/g, ' ').trim();
}, done, selector, property);
}, selector, property);
},
waitPropertyLength: function(selector, property, minLength, done) {
this.wait((selector, property, minLength) => {
waitPropertyLength: function(selector, property, minLength) {
return this.wait((selector, property, minLength) => {
const element = document.querySelector(selector);
return element && element[property] != null && element[property] !== '' && element[property].length >= minLength;
}, selector, property, minLength)
.getProperty(selector, property)
.then(result => done(null, result), done);
.getProperty(selector, property);
},
waitPropertyValue: function(selector, property, status, done) {
this.wait(selector)
waitPropertyValue: function(selector, property, status) {
return this.wait(selector)
.wait((selector, property, status) => {
const element = document.querySelector(selector);
return element[property] === status;
}, selector, property, status)
.then(done)
.catch(done);
}, selector, property, status);
},
waitToGetProperty: function(selector, property, done) {
this.wait((selector, property) => {
waitToGetProperty: function(selector, property) {
return this.wait((selector, property) => {
const element = document.querySelector(selector);
return element && element[property] != null && element[property] !== '';
}, selector, property)
.getProperty(selector, property)
.then(result => done(null, result), done);
.getProperty(selector, property);
},
write: function(selector, text, done) {
this.wait(selector)
.type(selector, text)
.then(done)
.catch(done);
write: function(selector, text) {
return this.wait(selector)
.type(selector, text);
},
waitToClick: function(selector, done) {
this.wait(selector)
.click(selector)
.then(done)
.catch(done);
waitToClick: function(selector) {
return this.wait(selector)
.click(selector);
},
focusElement: function(selector, done) {
this.wait(selector)
.evaluate_now(selector => {
focusElement: function(selector) {
return this.wait(selector)
.evaluate(selector => {
let element = document.querySelector(selector);
element.focus();
}, done, selector)
.then(done)
.catch(done);
}, selector);
},
isVisible: function(selector, done) {
this.wait(selector)
.evaluate_now(elementSelector => {
isVisible: function(selector) {
return this.wait(selector)
.evaluate(elementSelector => {
const selectorMatches = document.querySelectorAll(elementSelector);
const element = selectorMatches[0];
@ -242,122 +222,96 @@ let actions = {
element.removeEventListener('mouseover', eventHandler);
}
return isVisible;
}, done, selector);
}, selector);
},
waitImgLoad: function(selector, done) {
this.wait(selector)
waitImgLoad: function(selector) {
return this.wait(selector)
.wait(selector => {
const imageReady = document.querySelector(selector).complete;
return imageReady;
}, selector)
.then(done)
.catch(() => {
done(new Error(`image ${selector}, load timed out`));
});
}, selector);
},
clickIfVisible: function(selector, done) {
this.wait(selector)
clickIfVisible: function(selector) {
return this.wait(selector)
.isVisible(selector)
.then(visible => {
if (visible)
return this.click(selector);
throw new Error(`invisible selector: ${selector}`);
})
.then(done)
.catch(done);
},
countElement: function(selector, done) {
this.evaluate_now(selector => {
return document.querySelectorAll(selector).length;
}, done, selector);
},
waitForNumberOfElements: function(selector, count, done) {
this.wait((selector, count) => {
return document.querySelectorAll(selector).length === count;
}, selector, count)
.then(done)
.catch(() => {
done(new Error(`.waitForNumberOfElements() for ${selector}, count ${count} timed out`));
});
},
waitForClassNotPresent: function(selector, className, done) {
this.wait(selector)
countElement: function(selector) {
return this.evaluate(selector => {
return document.querySelectorAll(selector).length;
}, selector);
},
waitForNumberOfElements: function(selector, count) {
return this.wait((selector, count) => {
return document.querySelectorAll(selector).length === count;
}, selector, count);
},
waitForClassNotPresent: function(selector, className) {
return this.wait(selector)
.wait((selector, className) => {
if (!document.querySelector(selector).classList.contains(className))
return true;
}, selector, className)
.then(done)
.catch(() => {
done(new Error(`.waitForClassNotPresent() for ${selector}, class ${className} timed out`));
});
}, selector, className);
},
waitForClassPresent: function(selector, className, done) {
this.wait(selector)
waitForClassPresent: function(selector, className) {
return this.wait(selector)
.wait((elementSelector, targetClass) => {
if (document.querySelector(elementSelector).classList.contains(targetClass))
return true;
}, selector, className)
.then(done)
.catch(() => {
done(new Error(`.waitForClassPresent() for ${selector}, class ${className} timed out`));
});
}, selector, className);
},
waitForTextInElement: function(selector, text, done) {
this.wait(selector)
waitForTextInElement: function(selector, text) {
return this.wait(selector)
.wait((selector, text) => {
return document.querySelector(selector).innerText.toLowerCase().includes(text.toLowerCase());
}, selector, text)
.then(done)
.catch(done);
}, selector, text);
},
waitForTextInInput: function(selector, text, done) {
this.wait(selector)
waitForTextInInput: function(selector, text) {
return this.wait(selector)
.wait((selector, text) => {
return document.querySelector(selector).value.toLowerCase().includes(text.toLowerCase());
}, selector, text)
.then(done)
.catch(done);
}, selector, text);
},
waitForInnerText: function(selector, done) {
this.wait(selector)
waitForInnerText: function(selector) {
return this.wait(selector)
.wait(selector => {
const innerText = document.querySelector(selector).innerText;
return innerText != null && innerText != '';
}, selector)
.evaluate_now(selector => {
.evaluate(selector => {
return document.querySelector(selector).innerText;
}, done, selector);
}, selector);
},
waitForEmptyInnerText: function(selector, done) {
this.wait(selector => {
waitForEmptyInnerText: function(selector) {
return this.wait(selector => {
return document.querySelector(selector).innerText == '';
}, selector)
.then(done)
.catch(done);
}, selector);
},
waitForURL: function(hashURL, done) {
this.wait(hash => {
waitForURL: function(hashURL) {
return this.wait(hash => {
return document.location.hash.includes(hash);
}, hashURL)
.then(done)
.catch(done);
}, hashURL);
},
waitForShapes: function(selector, done) {
this.wait(selector)
.evaluate_now(selector => {
waitForShapes: function(selector) {
return this.wait(selector)
.evaluate(selector => {
const shapes = document.querySelectorAll(selector);
const shapesList = [];
@ -366,33 +320,29 @@ let actions = {
return shapesList;
}, done, selector);
}, selector);
},
waitForSnackbar: function(done) {
this.wait(500).waitForShapes('vn-snackbar .shape .text')
.then(shapes => {
done(null, shapes);
}).catch(done);
waitForSnackbar: function() {
return this.wait(500)
.waitForShapes('vn-snackbar .shape .text');
},
waitForLastShape: function(selector, done) {
this.wait(selector)
.evaluate_now(selector => {
waitForLastShape: function(selector) {
return this.wait(selector)
.evaluate(selector => {
const shape = document.querySelector(selector);
return shape.innerText;
}, done, selector);
}, selector);
},
waitForLastSnackbar: function(done) {
this.wait(500).waitForLastShape('vn-snackbar .shape .text')
.then(shapes => {
done(null, shapes);
}).catch(done);
waitForLastSnackbar: function() {
return this.wait(500)
.waitForLastShape('vn-snackbar .shape .text');
},
accessToSearchResult: function(searchValue, done) {
this.clearInput('vn-searchbar input')
accessToSearchResult: function(searchValue) {
return this.clearInput('vn-searchbar input')
.write('vn-searchbar input', searchValue)
.click('vn-searchbar vn-icon[icon="search"]')
.wait(100)
@ -405,13 +355,11 @@ let actions = {
return this.waitToClick('ui-view vn-card vn-td');
return this.waitToClick('ui-view vn-card a');
})
.then(done)
.catch(done);
});
},
accessToSection: function(sectionRoute, done) {
this.wait(`vn-left-menu`)
accessToSection: function(sectionRoute) {
return this.wait(`vn-left-menu`)
.evaluate(sectionRoute => {
return document.querySelector(`vn-left-menu ul li ul li > a[ui-sref="${sectionRoute}"]`) != null;
}, sectionRoute)
@ -422,45 +370,35 @@ let actions = {
return this.waitToClick('vn-left-menu .collapsed')
.wait('vn-left-menu .expanded')
.waitToClick(`vn-left-menu li > a[ui-sref="${sectionRoute}"]`);
})
.then(done)
.catch(done);
});
},
autocompleteSearch: function(autocompleteSelector, searchValue, done) {
this.waitToClick(`${autocompleteSelector} input`)
.write(`.vn-popover.shown .vn-drop-down input`, searchValue)
.waitToClick(`.vn-popover.shown .vn-drop-down li.active`)
autocompleteSearch: function(autocompleteSelector, searchValue) {
return this.waitToClick(`${autocompleteSelector} input`)
.write(`.vn-drop-down.shown input`, searchValue)
.waitToClick(`.vn-drop-down.shown li.active`)
.wait((autocompleteSelector, searchValue) => {
return document.querySelector(`${autocompleteSelector} input`).value
.toLowerCase()
.includes(searchValue.toLowerCase());
}, autocompleteSelector, searchValue)
.then(done)
.catch(() => {
done(new Error(`.autocompleteSearch() for value ${searchValue} in ${autocompleteSelector} timed out`));
});
}, autocompleteSelector, searchValue);
},
reloadSection: function(sectionRoute, done) {
this.waitToClick('vn-icon[icon="desktop_windows"]')
reloadSection: function(sectionRoute) {
return this.waitToClick('vn-icon[icon="desktop_windows"]')
.wait('vn-card.summary')
.waitToClick(`vn-left-menu li > a[ui-sref="${sectionRoute}"]`)
.then(done)
.catch(done);
.waitToClick(`vn-left-menu li > a[ui-sref="${sectionRoute}"]`);
},
forceReloadSection: function(sectionRoute, done) {
this.waitToClick('vn-icon[icon="desktop_windows"]')
.waitToClick('button[response="ACCEPT"]')
forceReloadSection: function(sectionRoute) {
return this.waitToClick('vn-icon[icon="desktop_windows"]')
.waitToClick('button[response="accept"]')
.wait('vn-card.summary')
.waitToClick(`vn-left-menu li > a[ui-sref="${sectionRoute}"]`)
.then(done)
.catch(done);
.waitToClick(`vn-left-menu li > a[ui-sref="${sectionRoute}"]`);
},
checkboxState: function(selector, done) {
this.wait(selector)
checkboxState: function(selector) {
return this.wait(selector)
.evaluate(selector => {
let checkbox = document.querySelector(selector);
switch (checkbox.$ctrl.field) {
@ -471,40 +409,39 @@ let actions = {
default:
return 'unchecked';
}
}, selector)
.then(res => done(null, res))
.catch(done);
}, selector);
},
isDisabled: function(selector, done) {
this.wait(selector)
isDisabled: function(selector) {
return this.wait(selector)
.evaluate(selector => {
let element = document.querySelector(selector);
return element.$ctrl.disabled;
}, selector)
.then(res => done(null, res))
.catch(done);
}, selector);
},
waitForSpinnerLoad: function(done) {
let spinnerSelector = 'vn-spinner > div';
this.waitForClassNotPresent(spinnerSelector, 'is-active')
.then(done)
.catch(done);
waitForSpinnerLoad: function() {
return this.waitForClassNotPresent('vn-spinner > div', 'is-active');
},
};
for (let name in asyncActions) {
let fn = asyncActions[name];
for (let name in actions) {
Nightmare.action(name, function(...args) {
let fnArgs = args.slice(0, args.length - 1);
let done = args[args.length - 1];
fn.apply(this, args)
.then(res => done(null, res), done);
actions[name].apply(this, fnArgs)
.then(res => done(null, res))
.catch(err => {
let stringArgs = fnArgs
.map(i => typeof i == 'function' ? 'Function' : i)
.join(', ');
let orgMessage = err.message.startsWith('.wait()')
? '.wait() timed out'
: err.message;
done(new Error(`.${name}(${stringArgs}) failed: ${orgMessage}`));
});
});
}
Object.keys(actions).forEach(function(name) {
let fn = actions[name];
Nightmare.action(name, fn);
});

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 button[response=ACCEPT]'
acceptButton: '.vn-confirm.shown button[response=accept]'
},
clientsIndex: {
searchClientInput: `vn-textfield input`,
@ -44,7 +44,7 @@ export default {
},
clientDescriptor: {
moreMenu: 'vn-client-descriptor vn-icon-menu[icon=more_vert]',
simpleTicketButton: '.vn-popover.shown .vn-drop-down li'
simpleTicketButton: '.vn-drop-down.shown li'
},
clientBasicData: {
basicDataButton: 'vn-left-menu a[ui-sref="client.card.basicData"]',
@ -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-client-fiscal-data > vn-confirm 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"]`,
@ -87,10 +87,10 @@ export default {
swiftBicAutocomplete: 'vn-client-billing-data vn-autocomplete[ng-model="$ctrl.client.bankEntityFk"]',
clearswiftBicButton: 'vn-client-billing-data vn-autocomplete[ng-model="$ctrl.client.bankEntityFk"] .icons > vn-icon[icon=clear]',
newBankEntityButton: 'vn-client-billing-data vn-icon-button[vn-tooltip="New bank entity"] > button',
newBankEntityName: 'vn-client-billing-data > vn-dialog vn-textfield[label="Name"] input',
newBankEntityBIC: 'vn-client-billing-data > vn-dialog vn-textfield[label="Swift / BIC"] input',
newBankEntityCode: 'vn-client-billing-data > vn-dialog vn-textfield[label="Entity Code"] input',
acceptBankEntityButton: 'vn-client-billing-data > vn-dialog button[response="ACCEPT"]',
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"]',
saveButton: `button[type=submit]`
},
clientAddresses: {
@ -136,7 +136,7 @@ export default {
addCreditFloatButton: `vn-float-button`,
creditInput: `vn-input-number input[name="credit"]`,
saveButton: `button[type=submit]`,
firstCreditText: 'vn-client-credit-index vn-card > div vn-table vn-tbody > vn-tr'
firstCreditText: 'vn-client-credit-index vn-card vn-table vn-tbody > vn-tr'
},
clientGreuge: {
addGreugeFloatButton: `vn-float-button`,
@ -144,13 +144,13 @@ export default {
descriptionInput: `vn-textfield input[name="description"]`,
typeAutocomplete: 'vn-autocomplete[ng-model="$ctrl.greuge.greugeTypeFk"]',
saveButton: `button[type=submit]`,
firstGreugeText: 'vn-client-greuge-index vn-card > div vn-table vn-tbody > vn-tr'
firstGreugeText: 'vn-client-greuge-index vn-card vn-table vn-tbody > vn-tr'
},
clientMandate: {
firstMandateText: 'vn-client-mandate vn-card > div vn-table vn-tbody > vn-tr'
firstMandateText: 'vn-client-mandate vn-card vn-table vn-tbody > vn-tr'
},
clientInvoices: {
firstInvoiceText: 'vn-client-invoice vn-card > div vn-table vn-tbody > vn-tr'
firstInvoiceText: 'vn-client-invoice vn-card vn-table vn-tbody > vn-tr'
},
clientLog: {
logButton: 'vn-left-menu a[ui-sref="client.card.log"]',
@ -163,9 +163,9 @@ export default {
balanceButton: 'vn-left-menu a[ui-sref="client.card.balance.index"]',
companyAutocomplete: 'vn-client-balance-index vn-autocomplete[ng-model="$ctrl.companyFk"]',
newPaymentButton: `vn-float-button`,
newPaymentBank: 'vn-client-balance-create vn-autocomplete[ng-model="$ctrl.receipt.bankFk"]',
newPaymentAmountInput: 'vn-client-balance-create vn-input-number[ng-model="$ctrl.receipt.amountPaid"] input',
saveButton: 'vn-client-balance-create vn-button[label="Save"]',
newPaymentBank: '.vn-dialog.shown vn-autocomplete[ng-model="$ctrl.receipt.bankFk"]',
newPaymentAmountInput: '.vn-dialog.shown vn-input-number[ng-model="$ctrl.receipt.amountPaid"] input',
saveButton: '.vn-dialog.shown vn-button[label="Save"]',
firstBalanceLine: 'vn-client-balance-index vn-tbody > vn-tr:nth-child(1) > vn-td:nth-child(8)'
},
@ -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-client-dms-index > vn-confirm button[response="ACCEPT"]'
acceptDeleteButton: '.vn-confirm.shown button[response="accept"]'
},
itemsIndex: {
searchIcon: 'vn-item-index vn-searchbar vn-icon[icon="search"]',
@ -185,26 +185,26 @@ 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-item-index [vn-id="clone"] [response="ACCEPT"]',
acceptClonationAlertButton: '.vn-confirm.shown [response="accept"]',
searchItemInput: 'vn-searchbar vn-textfield input',
searchButton: 'vn-searchbar vn-icon[icon="search"]',
closeItemSummaryPreview: 'vn-item-index [vn-id="preview"] button.close',
closeItemSummaryPreview: '.vn-popup.shown',
fieldsToShowButton: 'vn-item-index vn-table > div > div > vn-icon-button[icon="menu"]',
fieldsToShowForm: 'vn-item-index vn-table > div > div > vn-dialog > div > form',
fieldsToShowForm: '.vn-dialog.shown form',
firstItemImage: 'vn-item-index vn-tbody > a:nth-child(1) > vn-td:nth-child(1)',
firstItemId: 'vn-item-index vn-tbody > a:nth-child(1) > vn-td:nth-child(2)',
idCheckbox: 'vn-item-index vn-dialog form vn-horizontal:nth-child(2) > vn-check',
stemsCheckbox: 'vn-item-index vn-dialog form vn-horizontal:nth-child(3) > vn-check',
sizeCheckbox: 'vn-item-index vn-dialog form vn-horizontal:nth-child(4) > vn-check',
nicheCheckbox: 'vn-item-index vn-dialog form vn-horizontal:nth-child(5) > vn-check',
typeCheckbox: 'vn-item-index vn-dialog form vn-horizontal:nth-child(6) > vn-check',
categoryCheckbox: 'vn-item-index vn-dialog form vn-horizontal:nth-child(7) > vn-check',
intrastadCheckbox: 'vn-item-index vn-dialog form vn-horizontal:nth-child(8) > vn-check',
originCheckbox: 'vn-item-index vn-dialog form vn-horizontal:nth-child(9) > vn-check',
buyerCheckbox: 'vn-item-index vn-dialog form vn-horizontal:nth-child(10) > vn-check',
destinyCheckbox: 'vn-item-index vn-dialog form vn-horizontal:nth-child(11) > vn-check',
taxClassCheckbox: 'vn-item-index vn-dialog form vn-horizontal:nth-child(12) > vn-check',
saveFieldsButton: 'vn-item-index vn-dialog vn-horizontal:nth-child(16) > vn-button > button'
idCheckbox: '.vn-dialog.shown form vn-horizontal:nth-child(2) > vn-check',
stemsCheckbox: '.vn-dialog.shown form vn-horizontal:nth-child(3) > vn-check',
sizeCheckbox: '.vn-dialog.shown form vn-horizontal:nth-child(4) > vn-check',
nicheCheckbox: '.vn-dialog.shown form vn-horizontal:nth-child(5) > vn-check',
typeCheckbox: '.vn-dialog.shown form vn-horizontal:nth-child(6) > vn-check',
categoryCheckbox: '.vn-dialog.shown form vn-horizontal:nth-child(7) > vn-check',
intrastadCheckbox: '.vn-dialog.shown form vn-horizontal:nth-child(8) > vn-check',
originCheckbox: '.vn-dialog.shown form vn-horizontal:nth-child(9) > vn-check',
buyerCheckbox: '.vn-dialog.shown form vn-horizontal:nth-child(10) > vn-check',
destinyCheckbox: '.vn-dialog.shown form vn-horizontal:nth-child(11) > vn-check',
taxClassCheckbox: '.vn-dialog.shown form vn-horizontal:nth-child(12) > vn-check',
saveFieldsButton: '.vn-dialog.shown vn-horizontal:nth-child(16) > vn-button > button'
},
itemCreateView: {
temporalName: `vn-textfield input[name="provisionalName"]`,
@ -217,11 +217,11 @@ export default {
itemDescriptor: {
goBackToModuleIndexButton: 'vn-item-descriptor a[href="#!/item/index"]',
moreMenu: 'vn-item-descriptor vn-icon-menu[icon=more_vert]',
moreMenuRegularizeButton: '.vn-popover.shown .vn-drop-down li[name="Regularize stock"]',
regularizeQuantityInput: 'vn-item-descriptor vn-dialog tpl-body > div > vn-textfield input',
regularizeWarehouseAutocomplete: 'vn-item-descriptor vn-dialog vn-autocomplete[ng-model="$ctrl.warehouseFk"]',
moreMenuRegularizeButton: '.vn-drop-down.shown li[name="Regularize stock"]',
regularizeQuantityInput: '.vn-dialog.shown tpl-body > div > vn-textfield input',
regularizeWarehouseAutocomplete: '.vn-dialog.shown vn-autocomplete[ng-model="$ctrl.warehouseFk"]',
editButton: 'vn-item-card vn-item-descriptor vn-float-button[icon="edit"]',
regularizeSaveButton: 'vn-item-descriptor > vn-dialog > div > form > div.buttons > tpl-buttons > button',
regularizeSaveButton: '.vn-dialog.shown tpl-buttons > button',
inactiveIcon: 'vn-item-descriptor vn-icon[icon="icon-unavailable"]',
navigateBackToIndex: 'vn-item-descriptor vn-icon[icon="chevron_left"]'
},
@ -307,9 +307,9 @@ export default {
fifthLineCreatedProperty: 'vn-item-log > vn-log vn-tbody > vn-tr:nth-child(5) > vn-td > vn-one:nth-child(3) > div span:nth-child(3)',
},
ticketSummary: {
header: 'vn-ticket-summary > vn-card > div > h5',
header: 'vn-ticket-summary > vn-card > h5',
state: 'vn-ticket-summary vn-label-value[label="State"] > section > span',
route: 'vn-ticket-summary vn-label-value[label="Route"] > section > a',
route: 'vn-ticket-summary vn-label-value[label="Route"] > section > span > a',
total: 'vn-ticket-summary vn-one.taxes > p:nth-child(3) > strong',
sale: 'vn-ticket-summary [name="sales"] vn-table > div > vn-tbody > vn-tr',
firstSaleItemId: 'vn-ticket-summary [name="sales"] vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(2) > span',
@ -319,14 +319,14 @@ export default {
popoverDiaryButton: '.vn-popover.shown vn-item-descriptor vn-icon[icon="icon-transaction"]',
firstSaleQuantity: 'vn-ticket-summary [name="sales"] vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(3)',
firstSaleDiscount: 'vn-ticket-summary [name="sales"] vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(6)',
invoiceOutRef: 'vn-ticket-summary > vn-card > div > vn-horizontal > vn-one:nth-child(1) > vn-label-value:nth-child(6) > section > span',
invoiceOutRef: 'vn-ticket-summary > vn-card > vn-horizontal > vn-one:nth-child(1) > vn-label-value:nth-child(6) > section > span',
setOk: 'vn-ticket-summary vn-button[label="SET OK"] > button'
},
ticketsIndex: {
openAdvancedSearchButton: 'vn-ticket-index vn-searchbar .append vn-icon[icon="arrow_drop_down"]',
advancedSearchInvoiceOut: 'vn-ticket-search-panel vn-textfield[ng-model="filter.refFk"] input',
newTicketButton: 'vn-ticket-index > a',
searchResult: 'vn-ticket-index vn-card > div > vn-table > div > vn-tbody > a.vn-tr',
searchResult: 'vn-ticket-index vn-card > vn-table > div > vn-tbody > a.vn-tr',
searchWeeklyResult: 'vn-ticket-weekly-index vn-table vn-tbody > vn-tr',
searchResultDate: 'vn-ticket-index vn-table vn-tbody > a:nth-child(1) > vn-td:nth-child(5)',
searchTicketInput: `vn-ticket-index vn-textfield input`,
@ -336,11 +336,11 @@ export default {
searchButton: 'vn-ticket-index vn-searchbar vn-icon[icon="search"]',
searchWeeklyButton: 'vn-ticket-weekly-index vn-searchbar vn-icon[icon="search"]',
moreMenu: 'vn-ticket-index vn-icon-menu[icon=more_vert]',
moreMenuWeeklyTickets: '.vn-popover.shown .vn-drop-down li:nth-child(2)',
moreMenuWeeklyTickets: '.vn-drop-down.shown li:nth-child(2)',
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-ticket-weekly-index > vn-confirm[vn-id="deleteWeekly"] button[response="ACCEPT"]'
acceptDeleteTurn: '.vn-confirm.shown button[response="accept"]'
},
createTicketView: {
clientAutocomplete: 'vn-ticket-create vn-autocomplete[ng-model="$ctrl.clientFk"]',
@ -355,24 +355,24 @@ export default {
stateLabelValue: 'vn-ticket-descriptor vn-label-value[label="State"]',
goBackToModuleIndexButton: 'vn-ticket-descriptor a[ui-sref="ticket.index"]',
moreMenu: 'vn-ticket-descriptor vn-icon-menu[icon=more_vert]',
moreMenuAddStowaway: '.vn-popover.shown .vn-drop-down li[name="Add stowaway"]',
moreMenuDeleteStowawayButton: '.vn-popover.shown .vn-drop-down li[name="Remove stowaway"]',
moreMenuAddToTurn: '.vn-popover.shown .vn-drop-down li[name="Add turn"]',
moreMenuDeleteTicket: '.vn-popover.shown .vn-drop-down li[name="Delete ticket"]',
moreMenuMakeInvoice: '.vn-popover.shown .vn-drop-down li[name="Make invoice"]',
moreMenuChangeShippedHour: '.vn-popover.shown .vn-drop-down li[name="Change shipped hour"]',
changeShippedHourDialog: 'vn-ticket-descriptor vn-dialog[vn-id="changeShippedDialog"]',
changeShippedHourInput: 'vn-dialog[vn-id="changeShippedDialog"] [ng-model="$ctrl.newShipped"]',
addStowawayDialogFirstTicket: 'vn-ticket-descriptor > vn-add-stowaway > vn-dialog vn-table vn-tbody vn-tr',
moreMenuAddStowaway: '.vn-drop-down.shown li[name="Add stowaway"]',
moreMenuDeleteStowawayButton: '.vn-drop-down.shown li[name="Remove stowaway"]',
moreMenuAddToTurn: '.vn-drop-down.shown li[name="Add turn"]',
moreMenuDeleteTicket: '.vn-drop-down.shown li[name="Delete ticket"]',
moreMenuMakeInvoice: '.vn-drop-down.shown li[name="Make invoice"]',
moreMenuChangeShippedHour: '.vn-drop-down.shown li[name="Change shipped hour"]',
changeShippedHourDialog: '.vn-dialog.shown',
changeShippedHourInput: '.vn-dialog.shown [ng-model="$ctrl.newShipped"]',
addStowawayDialogFirstTicket: '.vn-dialog.shown vn-table vn-tbody vn-tr',
shipButton: 'vn-ticket-descriptor vn-icon[icon="icon-stowaway"]',
thursdayButton: 'vn-ticket-descriptor > vn-dialog > div > form > div.body > tpl-body > div > vn-tool-bar > vn-button:nth-child(4)',
saturdayButton: 'vn-ticket-descriptor > vn-dialog > div > form > div.body > tpl-body > div > vn-tool-bar > vn-button:nth-child(6)',
closeStowawayDialog: 'vn-ticket-descriptor > vn-add-stowaway > vn-dialog > div > button[class="close"]',
acceptDeleteButton: 'vn-ticket-descriptor button[response="ACCEPT"]',
acceptChangeHourButton: 'vn-ticket-descriptor vn-dialog[vn-id="changeShippedDialog"] button[response="ACCEPT"]',
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"]',
descriptorDeliveryDate: 'vn-ticket-descriptor > div > div.body > div.attributes > vn-label-value:nth-child(6) > section > span',
acceptInvoiceOutButton: 'vn-ticket-descriptor vn-confirm[vn-id="makeInvoiceConfirmation"] button[response="ACCEPT"]',
acceptDeleteStowawayButton: 'vn-ticket-descriptor > vn-remove-stowaway 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-ticket-expedition > vn-confirm[vn-id="delete-expedition"] button[response=ACCEPT]',
acceptDeleteRowButton: '.vn-confirm.shown button[response=accept]',
expeditionRow: 'vn-ticket-expedition vn-table vn-tbody > vn-tr'
},
ticketPackages: {
@ -403,13 +403,13 @@ export default {
saleDescriptorPopoverSummaryButton: '.vn-popover.shown vn-item-descriptor a[ui-sref="item.card.summary({id: $ctrl.item.id})"]',
descriptorItemDiaryButton: 'vn-item-descriptor .quicklinks.ng-scope > vn-horizontal > a > vn-icon > i',
newItemFromCatalogButton: 'vn-ticket-sale vn-float-button[icon="add"]',
newItemButton: 'vn-ticket-sale > vn-vertical > vn-card > div > vn-vertical > vn-one > vn-icon-button > button > vn-icon > i',
newItemButton: 'vn-ticket-sale > vn-vertical > vn-card > vn-vertical > vn-one > vn-icon-button > button > vn-icon > i',
moreMenu: 'vn-ticket-sale vn-tool-bar > vn-button-menu[vn-id="more-button"] > div > button',
moreMenuCreateClaim: '.vn-popover.shown .vn-drop-down li[name="Add claim"]',
moreMenuReserve: '.vn-popover.shown .vn-drop-down li[name="Mark as reserved"]',
moreMenuUnmarkReseved: '.vn-popover.shown .vn-drop-down li[name="Unmark as reserved"]',
moreMenuUpdateDiscount: '.vn-popover.shown .vn-drop-down li[name="Update discount"]',
moreMenuUpdateDiscountInput: 'vn-ticket-sale vn-dialog form vn-ticket-sale-edit-discount vn-input-number[ng-model="$ctrl.newDiscount"] input',
moreMenuCreateClaim: '.vn-drop-down.shown li[name="Add claim"]',
moreMenuReserve: '.vn-drop-down.shown li[name="Mark as reserved"]',
moreMenuUnmarkReseved: '.vn-drop-down.shown li[name="Unmark as reserved"]',
moreMenuUpdateDiscount: '.vn-drop-down.shown li[name="Update discount"]',
moreMenuUpdateDiscountInput: '.vn-dialog.shown form vn-ticket-sale-edit-discount vn-input-number[ng-model="$ctrl.newDiscount"] input',
transferQuantityInput: '.vn-popover.shown vn-table > div > vn-tbody > vn-tr > vn-td-editable > span > text',
transferQuantityCell: '.vn-popover.shown vn-table > div > vn-tbody > vn-tr > vn-td-editable',
firstSaleClaimIcon: 'vn-ticket-sale vn-table vn-tbody > vn-tr:nth-child(1) vn-icon[icon="icon-claims"]',
@ -421,7 +421,7 @@ export default {
firstSaleQuantityCell: 'vn-ticket-sale vn-tr:nth-child(1) > vn-td-editable:nth-child(5)',
firstSaleQuantityClearInput: 'vn-textfield[ng-model="sale.quantity"] div.suffix > i',
firstSaleIdAutocomplete: 'vn-ticket-sale vn-table vn-tbody > vn-tr:nth-child(1) > vn-td:nth-child(4) > vn-autocomplete',
idAutocompleteFirstResult: '.vn-popover.shown .vn-drop-down li',
idAutocompleteFirstResult: '.vn-drop-down.shown li',
firstSalePrice: 'vn-ticket-sale vn-table vn-tr:nth-child(1) > vn-td:nth-child(7) > span',
firstSalePriceInput: '.vn-popover.shown vn-input-number input',
firstSaleDiscount: 'vn-ticket-sale vn-table vn-tr:nth-child(1) > vn-td:nth-child(8) > span',
@ -443,7 +443,7 @@ export default {
secondSaleQuantity: 'vn-ticket-sale vn-table vn-tr:nth-child(2) vn-input-number input',
secondSaleConceptCell: 'vn-ticket-sale vn-table vn-tbody > vn-tr:nth-child(2) > vn-td-editable:nth-child(6)',
secondSaleConceptInput: 'vn-ticket-sale vn-table vn-tr:nth-child(2) > vn-td-editable.ng-isolate-scope.selected vn-textfield input',
totalImport: 'vn-ticket-sale > vn-vertical > vn-card > div > vn-vertical > vn-horizontal > vn-one > p:nth-child(3) > strong',
totalImport: 'vn-ticket-sale > vn-vertical > vn-card > vn-vertical > vn-horizontal > vn-one > p:nth-child(3) > strong',
selectAllSalesCheckbox: 'vn-ticket-sale vn-thead vn-check',
secondSaleCheckbox: 'vn-ticket-sale vn-tr:nth-child(2) vn-check[ng-model="sale.checked"]',
thirdSaleCheckbox: 'vn-ticket-sale vn-tr:nth-child(3) vn-check[ng-model="sale.checked"]',
@ -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-ticket-sale > vn-confirm[vn-id="delete-lines"] button[response=ACCEPT]',
acceptDeleteTicketButton: 'vn-ticket-sale > vn-confirm[vn-id="delete-ticket"] 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: {
@ -472,7 +472,7 @@ export default {
zoneAutocomplete: 'vn-autocomplete[ng-model="$ctrl.zoneId"]',
nextStepButton: 'vn-step-control .buttons > section:last-child vn-button',
finalizeButton: 'vn-step-control .buttons > section:last-child button[type=submit]',
stepTwoTotalPriceDif: 'vn-ticket-basic-data-step-two > form > vn-card > div > vn-horizontal > table > tfoot > tr > td:nth-child(4)',
stepTwoTotalPriceDif: 'vn-ticket-basic-data-step-two > form > vn-card > vn-horizontal > table > tfoot > tr > td:nth-child(4)',
chargesReasonAutocomplete: 'vn-autocomplete[ng-model="$ctrl.ticket.option"]',
},
ticketComponents: {
@ -481,7 +481,7 @@ export default {
ticketRequests: {
addRequestButton: 'vn-ticket-request-index > a > vn-float-button > button',
request: 'vn-ticket-request-index vn-table vn-tr',
descriptionInput: 'vn-ticket-request-create > form > div > vn-card > div > vn-horizontal:nth-child(1) > vn-textfield input',
descriptionInput: 'vn-ticket-request-create > form > div > vn-card > vn-horizontal:nth-child(1) > vn-textfield input',
atenderAutocomplete: 'vn-ticket-request-create vn-autocomplete[ng-model="$ctrl.ticketRequest.attenderFk"]',
quantityInput: 'vn-ticket-request-create vn-input-number input[name=quantity]',
priceInput: 'vn-ticket-request-create vn-input-number input[name=price]',
@ -504,10 +504,10 @@ export default {
firstPriceInput: 'vn-ticket-service vn-input-number[label="Price"] input',
firstVatTypeAutocomplete: 'vn-ticket-service vn-autocomplete[label="Tax class"]',
fistDeleteServiceButton: 'vn-ticket-service form vn-horizontal:nth-child(1) vn-icon-button[icon="delete"]',
newDescriptionInput: 'vn-ticket-service > vn-dialog vn-textfield[ng-model="$ctrl.newServiceType.name"] input',
serviceLine: 'vn-ticket-service > form > vn-card > div > vn-one:nth-child(2) > vn-horizontal',
newDescriptionInput: '.vn-dialog.shown vn-textfield[ng-model="$ctrl.newServiceType.name"] input',
serviceLine: 'vn-ticket-service > form > vn-card > vn-one:nth-child(2) > vn-horizontal',
saveServiceButton: `button[type=submit]`,
saveDescriptionButton: 'vn-ticket-service > vn-dialog[vn-id="createServiceTypeDialog"] > div > form > div.buttons > tpl-buttons > button'
saveDescriptionButton: '.vn-dialog.shown tpl-buttons > button'
},
createStateView: {
stateAutocomplete: 'vn-autocomplete[ng-model="$ctrl.stateFk"]',
@ -517,16 +517,16 @@ export default {
},
claimsIndex: {
searchClaimInput: `vn-claim-index vn-textfield input`,
searchResult: 'vn-claim-index vn-card > div > vn-table > div > vn-tbody > a',
searchResult: 'vn-claim-index vn-card > vn-table > div > vn-tbody > a',
searchButton: 'vn-claim-index vn-searchbar vn-icon[icon="search"]'
},
claimDescriptor: {
moreMenu: 'vn-claim-descriptor vn-icon-menu[icon=more_vert]',
moreMenuDeleteClaim: '.vn-popover.shown .vn-drop-down li[name="Delete claim"]',
acceptDeleteClaim: 'vn-claim-descriptor > vn-confirm[vn-id="confirm-delete-claim"] button[response="ACCEPT"]'
moreMenuDeleteClaim: '.vn-drop-down.shown li[name="Delete claim"]',
acceptDeleteClaim: '.vn-confirm.shown button[response="accept"]'
},
claimSummary: {
header: 'vn-claim-summary > vn-card > div > h5',
header: 'vn-claim-summary > vn-card > h5',
state: 'vn-claim-summary vn-label-value[label="State"] > section > span',
observation: 'vn-claim-summary vn-textarea[ng-model="$ctrl.summary.claim.observation"] textarea',
firstSaleItemId: 'vn-claim-summary vn-horizontal > vn-auto:nth-child(4) vn-table > div > vn-tbody > vn-tr:nth-child(1) > vn-td:nth-child(1) > span',
@ -535,7 +535,7 @@ export default {
itemDescriptorPopoverItemDiaryButton: '.vn-popover.shown vn-item-descriptor a[href="#!/item/2/diary"]',
firstDevelopmentWorker: 'vn-claim-summary vn-horizontal > vn-auto:nth-child(5) vn-table > div > vn-tbody > vn-tr:nth-child(1) > vn-td:nth-child(4) > span',
firstDevelopmentWorkerGoToClientButton: '.vn-popover.shown vn-worker-descriptor vn-quick-links > a[href="#!/client/21/summary"]',
firstActionTicketId: 'vn-claim-summary > vn-card > div > vn-horizontal > vn-auto:nth-child(6) vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(2) > span',
firstActionTicketId: 'vn-claim-summary > vn-card > vn-horizontal > vn-auto:nth-child(6) vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(2) > span',
firstActionTicketDescriptor: '.vn-popover.shown vn-ticket-descriptor'
},
claimBasicData: {
@ -545,19 +545,19 @@ export default {
saveButton: `button[type=submit]`
},
claimDetail: {
secondItemDiscount: 'vn-claim-detail > vn-vertical > vn-card > div > vn-vertical > vn-table > div > vn-tbody > vn-tr:nth-child(2) > vn-td:nth-child(6) > span',
secondItemDiscount: 'vn-claim-detail > vn-vertical > vn-card > vn-vertical > vn-table > div > vn-tbody > vn-tr:nth-child(2) > vn-td:nth-child(6) > span',
discountInput: '.vn-popover.shown vn-input-number[ng-model="$ctrl.newDiscount"] input',
discoutPopoverMana: '.vn-popover.shown .content > div > vn-horizontal > h5',
addItemButton: 'vn-claim-detail a vn-float-button',
firstClaimableSaleFromTicket: 'vn-claim-detail > vn-dialog vn-tbody > vn-tr',
claimDetailLine: 'vn-claim-detail > vn-vertical > vn-card > div > vn-vertical > vn-table > div > vn-tbody > vn-tr',
firstClaimableSaleFromTicket: '.vn-dialog.shown vn-tbody > vn-tr',
claimDetailLine: 'vn-claim-detail > vn-vertical > vn-card > vn-vertical > vn-table > div > vn-tbody > vn-tr',
firstItemQuantityInput: 'vn-claim-detail vn-tr:nth-child(1) vn-input-number[ng-model="saleClaimed.quantity"] input',
totalClaimed: 'vn-claim-detail > vn-vertical > vn-card > div > vn-vertical > vn-horizontal > div > vn-label-value:nth-child(2) > section > span',
secondItemDeleteButton: 'vn-claim-detail > vn-vertical > vn-card > div > vn-vertical > vn-table > div > vn-tbody > vn-tr:nth-child(2) > vn-td:nth-child(8) > vn-icon-button > button > vn-icon > i'
totalClaimed: 'vn-claim-detail > vn-vertical > vn-card > vn-vertical > vn-horizontal > div > vn-label-value:nth-child(2) > section > span',
secondItemDeleteButton: 'vn-claim-detail > vn-vertical > vn-card > vn-vertical > vn-table > div > vn-tbody > vn-tr:nth-child(2) > vn-td:nth-child(8) > vn-icon-button > button > vn-icon > i'
},
claimDevelopment: {
addDevelopmentButton: 'vn-claim-development > vn-vertical > vn-card > div > vn-vertical > vn-one > vn-icon-button > button > vn-icon',
firstDeleteDevelopmentButton: 'vn-claim-development > vn-vertical > vn-card > div > vn-vertical > form > vn-horizontal:nth-child(2) > vn-icon-button > button > vn-icon',
addDevelopmentButton: 'vn-claim-development > vn-vertical > vn-card > vn-vertical > vn-one > vn-icon-button > button > vn-icon',
firstDeleteDevelopmentButton: 'vn-claim-development > vn-vertical > vn-card > vn-vertical > form > vn-horizontal:nth-child(2) > vn-icon-button > button > vn-icon',
firstClaimReasonAutocomplete: 'vn-claim-development vn-horizontal:nth-child(1) vn-autocomplete[ng-model="claimDevelopment.claimReasonFk"]',
firstClaimResultAutocomplete: 'vn-claim-development vn-horizontal:nth-child(1) vn-autocomplete[ng-model="claimDevelopment.claimResultFk"]',
firstClaimResponsibleAutocomplete: 'vn-claim-development vn-horizontal:nth-child(1) vn-autocomplete[ng-model="claimDevelopment.claimResponsibleFk"]',
@ -580,7 +580,7 @@ export default {
isPaidWithManaCheckbox: 'vn-check[ng-model="$ctrl.claim.isChargedToMana"]'
},
ordersIndex: {
searchResult: 'vn-order-index vn-card > div > vn-table > div > vn-tbody > a.vn-tr',
searchResult: 'vn-order-index vn-card > vn-table > div > vn-tbody > a.vn-tr',
searchResultDate: 'vn-order-index vn-table vn-tbody > a:nth-child(1) > vn-td:nth-child(4)',
searchResultAddress: 'vn-order-index vn-table vn-tbody > a:nth-child(1) > vn-td:nth-child(6)',
searchOrderInput: `vn-order-index vn-textfield input`,
@ -589,7 +589,7 @@ export default {
},
orderDescriptor: {
returnToModuleIndexButton: 'vn-order-descriptor a[ui-sref="order.index"]',
acceptNavigationButton: 'vn-order-basic-data vn-confirm 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-order-basic-data vn-confirm[vn-id="confirm"] button[response="ACCEPT"]'
acceptButton: '.vn-confirm.shown button[response="accept"]'
},
orderLine: {
orderSubtotal: 'vn-order-line vn-horizontal.header p:nth-child(1)',
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-vertical > vn-button-bar > vn-button > button',
confirmButton: 'vn-order-line > vn-confirm button[response="ACCEPT"]',
confirmOrder: 'vn-order-line vn-float-button',
confirmButton: '.vn-confirm.shown button[response="accept"]',
},
routeIndex: {
addNewRouteButton: 'vn-route-index > a[ui-sref="route.create"]'
@ -641,7 +641,7 @@ export default {
volume: 'vn-route-descriptor vn-label-value[label="Volume"] > section > span'
},
routeSummary: {
routeId: 'vn-route-summary > vn-card > div > vn-horizontal > vn-one:nth-child(1) > vn-label-value:nth-child(1) > section > span'
routeId: 'vn-route-summary > vn-card > vn-horizontal > vn-one:nth-child(1) > vn-label-value:nth-child(1) > section > span'
},
routeBasicData: {
workerAutoComplete: 'vn-route-basic-data vn-autocomplete[ng-model="$ctrl.route.workerFk"]',
@ -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-route-tickets > vn-confirm button[response="ACCEPT"]'
confirmButton: '.vn-confirm.shown button[response="accept"]'
},
workerPbx: {
extensionInput: 'vn-worker-pbx vn-textfield[ng-model="$ctrl.worker.sip.extension"] input',
@ -671,67 +671,68 @@ export default {
},
workerTimeControl: {
timeDialogInput: '.vn-dialog.shown [ng-model="$ctrl.newTime"]',
mondayAddTimeButton: 'vn-worker-time-control > div > vn-card > div > vn-horizontal > vn-table > div > vn-tfoot > vn-tr:nth-child(2) > vn-td:nth-child(1) > vn-icon-button > button > vn-icon',
tuesdayAddTimeButton: 'vn-worker-time-control > div > vn-card > div > vn-horizontal > vn-table > div > vn-tfoot > vn-tr:nth-child(2) > vn-td:nth-child(2) > vn-icon-button > button > vn-icon',
wednesdayAddTimeButton: 'vn-worker-time-control > div > vn-card > div > vn-horizontal > vn-table > div > vn-tfoot > vn-tr:nth-child(2) > vn-td:nth-child(3) > vn-icon-button > button > vn-icon',
thursdayAddTimeButton: 'vn-worker-time-control > div > vn-card > div > vn-horizontal > vn-table > div > vn-tfoot > vn-tr:nth-child(2) > vn-td:nth-child(4) > vn-icon-button > button > vn-icon',
fridayAddTimeButton: 'vn-worker-time-control > div > vn-card > div > vn-horizontal > vn-table > div > vn-tfoot > vn-tr:nth-child(2) > vn-td:nth-child(5) > vn-icon-button > button > vn-icon',
saturdayAddTimeButton: 'vn-worker-time-control > div > vn-card > div > vn-horizontal > vn-table > div > vn-tfoot > vn-tr:nth-child(2) > vn-td:nth-child(6) > vn-icon-button > button > vn-icon',
sundayAddTimeButton: 'vn-worker-time-control > div > vn-card > div > vn-horizontal > vn-table > div > vn-tfoot > vn-tr:nth-child(2) > vn-td:nth-child(7) > vn-icon-button > button > vn-icon',
confirmButton: 'vn-worker-time-control > vn-dialog > div > form > div.buttons > tpl-buttons > button',
firstEntryOfMonday: 'vn-worker-time-control > div > vn-card > div > vn-horizontal > vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(1) > section:nth-child(1) > span',
firstEntryOfTuesday: 'vn-worker-time-control > div > vn-card > div > vn-horizontal > vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(2) > section:nth-child(1) > span',
firstEntryOfWednesday: 'vn-worker-time-control > div > vn-card > div > vn-horizontal > vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(3) > section:nth-child(1) > span',
firstEntryOfThursday: 'vn-worker-time-control > div > vn-card > div > vn-horizontal > vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(4) > section:nth-child(1) > span',
firstEntryOfFriday: 'vn-worker-time-control > div > vn-card > div > vn-horizontal > vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(5) > section:nth-child(1) > span',
firstEntryOfSaturday: 'vn-worker-time-control > div > vn-card > div > vn-horizontal > vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(6) > section:nth-child(1) > span',
firstEntryOfSunday: 'vn-worker-time-control > div > vn-card > div > vn-horizontal > vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(7) > section:nth-child(1) > span',
secondEntryOfMonday: 'vn-worker-time-control > div > vn-card > div > vn-horizontal > vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(1) > section:nth-child(2) > span',
secondEntryOfTuesday: 'vn-worker-time-control > div > vn-card > div > vn-horizontal > vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(2) > section:nth-child(2) > span',
secondEntryOfWednesday: 'vn-worker-time-control > div > vn-card > div > vn-horizontal > vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(3) > section:nth-child(2) > span',
secondEntryOfThursday: 'vn-worker-time-control > div > vn-card > div > vn-horizontal > vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(4) > section:nth-child(2) > span',
secondEntryOfFriday: 'vn-worker-time-control > div > vn-card > div > vn-horizontal > vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(5) > section:nth-child(2) > span',
secondEntryOfSaturday: 'vn-worker-time-control > div > vn-card > div > vn-horizontal > vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(6) > section:nth-child(2) > span',
secondEntryOfSunday: 'vn-worker-time-control > div > vn-card > div > vn-horizontal > vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(7) > section:nth-child(2) > span',
thirdEntryOfMonday: 'vn-worker-time-control > div > vn-card > div > vn-horizontal > vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(1) > section:nth-child(3) > span',
thirdEntryOfTuesday: 'vn-worker-time-control > div > vn-card > div > vn-horizontal > vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(2) > section:nth-child(3) > span',
thirdEntryOfWednesday: 'vn-worker-time-control > div > vn-card > div > vn-horizontal > vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(3) > section:nth-child(3) > span',
thirdEntryOfThursday: 'vn-worker-time-control > div > vn-card > div > vn-horizontal > vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(4) > section:nth-child(3) > span',
thirdEntryOfFriday: 'vn-worker-time-control > div > vn-card > div > vn-horizontal > vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(5) > section:nth-child(3) > span',
thirdEntryOfSaturday: 'vn-worker-time-control > div > vn-card > div > vn-horizontal > vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(6) > section:nth-child(3) > span',
thirdEntryOfSunday: 'vn-worker-time-control > div > vn-card > div > vn-horizontal > vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(7) > section:nth-child(3) > span',
fourthEntryOfMonday: 'vn-worker-time-control > div > vn-card > div > vn-horizontal > vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(1) > section:nth-child(4) > span',
fourthEntryOfTuesday: 'vn-worker-time-control > div > vn-card > div > vn-horizontal > vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(2) > section:nth-child(4) > span',
fourthEntryOfWednesday: 'vn-worker-time-control > div > vn-card > div > vn-horizontal > vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(3) > section:nth-child(4) > span',
fourthEntryOfThursday: 'vn-worker-time-control > div > vn-card > div > vn-horizontal > vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(4) > section:nth-child(4) > span',
fourthEntryOfFriday: 'vn-worker-time-control > div > vn-card > div > vn-horizontal > vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(5) > section:nth-child(4) > span',
fourthEntryOfSaturday: 'vn-worker-time-control > div > vn-card > div > vn-horizontal > vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(6) > section:nth-child(4) > span',
fourthEntryOfSunday: 'vn-worker-time-control > div > vn-card > div > vn-horizontal > vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(7) > section:nth-child(4) > span',
mondayWorkedHours: 'vn-worker-time-control > div > vn-card > div > vn-horizontal > vn-table > div > vn-tfoot > vn-tr:nth-child(1) > vn-td:nth-child(1)',
tuesdayWorkedHours: 'vn-worker-time-control > div > vn-card > div > vn-horizontal > vn-table > div > vn-tfoot > vn-tr:nth-child(1) > vn-td:nth-child(2)',
wednesdayWorkedHours: 'vn-worker-time-control > div > vn-card > div > vn-horizontal > vn-table > div > vn-tfoot > vn-tr:nth-child(1) > vn-td:nth-child(3)',
thursdayWorkedHours: 'vn-worker-time-control > div > vn-card > div > vn-horizontal > vn-table > div > vn-tfoot > vn-tr:nth-child(1) > vn-td:nth-child(4)',
fridayWorkedHours: 'vn-worker-time-control > div > vn-card > div > vn-horizontal > vn-table > div > vn-tfoot > vn-tr:nth-child(1) > vn-td:nth-child(5)',
saturdayWorkedHours: 'vn-worker-time-control > div > vn-card > div > vn-horizontal > vn-table > div > vn-tfoot > vn-tr:nth-child(1) > vn-td:nth-child(6)',
sundayWorkedHours: 'vn-worker-time-control > div > vn-card > div > vn-horizontal > vn-table > div > vn-tfoot > vn-tr:nth-child(1) > vn-td:nth-child(7)',
weekWorkedHours: 'vn-worker-time-control > div > vn-side-menu > div > vn-vertical > vn-vertical > vn-label-value > section > span',
nextMonthButton: 'vn-worker-time-control > div > vn-side-menu > div > vn-calendar > div > vn-horizontal > vn-auto:nth-child(3) > vn-icon',
mondayAddTimeButton: 'vn-worker-time-control vn-table > div > vn-tfoot > vn-tr:nth-child(2) > vn-td:nth-child(1) > vn-icon-button',
tuesdayAddTimeButton: 'vn-worker-time-control vn-table > div > vn-tfoot > vn-tr:nth-child(2) > vn-td:nth-child(2) > vn-icon-button',
wednesdayAddTimeButton: 'vn-worker-time-control vn-table > div > vn-tfoot > vn-tr:nth-child(2) > vn-td:nth-child(3) > vn-icon-button',
thursdayAddTimeButton: 'vn-worker-time-control vn-table > div > vn-tfoot > vn-tr:nth-child(2) > vn-td:nth-child(4) > vn-icon-button',
fridayAddTimeButton: 'vn-worker-time-control vn-table > div > vn-tfoot > vn-tr:nth-child(2) > vn-td:nth-child(5) > vn-icon-button',
saturdayAddTimeButton: 'vn-worker-time-control vn-table > div > vn-tfoot > vn-tr:nth-child(2) > vn-td:nth-child(6) > vn-icon-button',
sundayAddTimeButton: 'vn-worker-time-control vn-table > div > vn-tfoot > vn-tr:nth-child(2) > vn-td:nth-child(7) > vn-icon-button',
confirmButton: '.vn-dialog.shown tpl-buttons > button',
firstEntryOfMonday: 'vn-worker-time-control vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(1) > section:nth-child(1) > span',
firstEntryOfTuesday: 'vn-worker-time-control vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(2) > section:nth-child(1) > span',
firstEntryOfWednesday: 'vn-worker-time-control vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(3) > section:nth-child(1) > span',
firstEntryOfThursday: 'vn-worker-time-control vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(4) > section:nth-child(1) > span',
firstEntryOfFriday: 'vn-worker-time-control vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(5) > section:nth-child(1) > span',
firstEntryOfSaturday: 'vn-worker-time-control vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(6) > section:nth-child(1) > span',
firstEntryOfSunday: 'vn-worker-time-control vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(7) > section:nth-child(1) > span',
secondEntryOfMonday: 'vn-worker-time-control vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(1) > section:nth-child(2) > span',
secondEntryOfTuesday: 'vn-worker-time-control vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(2) > section:nth-child(2) > span',
secondEntryOfWednesday: 'vn-worker-time-control vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(3) > section:nth-child(2) > span',
secondEntryOfThursday: 'vn-worker-time-control vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(4) > section:nth-child(2) > span',
secondEntryOfFriday: 'vn-worker-time-control vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(5) > section:nth-child(2) > span',
secondEntryOfSaturday: 'vn-worker-time-control vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(6) > section:nth-child(2) > span',
secondEntryOfSunday: 'vn-worker-time-control vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(7) > section:nth-child(2) > span',
thirdEntryOfMonday: 'vn-worker-time-control vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(1) > section:nth-child(3) > span',
thirdEntryOfTuesday: 'vn-worker-time-control vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(2) > section:nth-child(3) > span',
thirdEntryOfWednesday: 'vn-worker-time-control vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(3) > section:nth-child(3) > span',
thirdEntryOfThursday: 'vn-worker-time-control vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(4) > section:nth-child(3) > span',
thirdEntryOfFriday: 'vn-worker-time-control vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(5) > section:nth-child(3) > span',
thirdEntryOfSaturday: 'vn-worker-time-control vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(6) > section:nth-child(3) > span',
thirdEntryOfSunday: 'vn-worker-time-control vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(7) > section:nth-child(3) > span',
fourthEntryOfMonday: 'vn-worker-time-control vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(1) > section:nth-child(4) > span',
fourthEntryOfTuesday: 'vn-worker-time-control vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(2) > section:nth-child(4) > span',
fourthEntryOfWednesday: 'vn-worker-time-control vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(3) > section:nth-child(4) > span',
fourthEntryOfThursday: 'vn-worker-time-control vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(4) > section:nth-child(4) > span',
fourthEntryOfFriday: 'vn-worker-time-control vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(5) > section:nth-child(4) > span',
fourthEntryOfSaturday: 'vn-worker-time-control vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(6) > section:nth-child(4) > span',
fourthEntryOfSunday: 'vn-worker-time-control vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(7) > section:nth-child(4) > span',
mondayWorkedHours: 'vn-worker-time-control vn-table > div > vn-tfoot > vn-tr:nth-child(1) > vn-td:nth-child(1)',
tuesdayWorkedHours: 'vn-worker-time-control vn-table > div > vn-tfoot > vn-tr:nth-child(1) > vn-td:nth-child(2)',
wednesdayWorkedHours: 'vn-worker-time-control vn-table > div > vn-tfoot > vn-tr:nth-child(1) > vn-td:nth-child(3)',
thursdayWorkedHours: 'vn-worker-time-control vn-table > div > vn-tfoot > vn-tr:nth-child(1) > vn-td:nth-child(4)',
fridayWorkedHours: 'vn-worker-time-control vn-table > div > vn-tfoot > vn-tr:nth-child(1) > vn-td:nth-child(5)',
saturdayWorkedHours: 'vn-worker-time-control vn-table > div > vn-tfoot > vn-tr:nth-child(1) > vn-td:nth-child(6)',
sundayWorkedHours: 'vn-worker-time-control vn-table > div > vn-tfoot > vn-tr:nth-child(1) > vn-td:nth-child(7)',
weekWorkedHours: 'vn-worker-time-control vn-side-menu vn-label-value > section > span',
nextMonthButton: 'vn-worker-time-control vn-side-menu vn-calendar vn-button[icon=keyboard_arrow_right]',
secondWeekDay: 'vn-worker-time-control vn-side-menu vn-calendar .day:nth-child(8) > .day-number',
navigateBackToIndex: 'vn-worker-descriptor vn-icon[icon="chevron_left"]'
},
invoiceOutIndex: {
searchInvoiceOutInput: `vn-invoice-out-index vn-textfield input`,
searchButton: 'vn-invoice-out-index vn-searchbar vn-icon[icon="search"]',
searchResult: 'vn-invoice-out-index vn-card > div > vn-table > div > vn-tbody > a.vn-tr',
searchResult: 'vn-invoice-out-index vn-card > vn-table > div > vn-tbody > a.vn-tr',
},
invoiceOutDescriptor: {
moreMenu: 'vn-invoice-out-descriptor vn-icon-menu[icon=more_vert]',
moreMenuDeleteInvoiceOut: '.vn-popover.shown .vn-drop-down li[name="Delete Invoice"]',
moreMenuBookInvoiceOut: '.vn-popover.shown .vn-drop-down li[name="Book invoice"]',
moreMenuShowInvoiceOutPdf: '.vn-popover.shown .vn-drop-down li[name="Show invoice PDF"]',
acceptDeleteButton: 'vn-invoice-out-descriptor > vn-confirm[vn-id="deleteConfirmation"] button[response="ACCEPT"]',
acceptBookingButton: 'vn-invoice-out-descriptor > vn-confirm[vn-id="bookConfirmation"] button[response="ACCEPT"]'
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"]'
},
invoiceOutSummary: {
bookedLabel: 'vn-invoice-out-summary > vn-card > div > vn-horizontal > vn-one > vn-label-value:nth-child(4) > section > span'
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 button[response="ACCEPT"]')
.waitToClick('.vn-confirm.shown button[response="accept"]')
.waitForURL('address/index')
.parsedUrl();

View File

@ -286,11 +286,11 @@ describe('Worker time control path', () => {
});
});
describe('as salesBoss', () => {
describe('as hr', () => {
describe('on Saturday', () => {
beforeAll(() => {
nightmare
.loginAndModule('salesBoss', 'worker')
.loginAndModule('hr', 'worker')
.accessToSearchResult('HankPym')
.accessToSection('worker.card.timeControl');
});
@ -358,10 +358,11 @@ describe('Worker time control path', () => {
it(`should check Hank Pym doesn't have hours set on the next months first week`, async() => {
const wholeWeekHours = await nightmare
.waitToClick(selectors.workerTimeControl.nextMonthButton)
.waitForTextInElement(selectors.workerTimeControl.weekWorkedHours, '00:00 Hours')
.waitToClick(selectors.workerTimeControl.secondWeekDay)
.waitForTextInElement(selectors.workerTimeControl.weekWorkedHours, '00:00 h.')
.waitToGetProperty(selectors.workerTimeControl.weekWorkedHours, 'innerText');
expect(wholeWeekHours).toEqual('00:00 Hours');
expect(wholeWeekHours).toEqual('00:00 h.');
});
it(`should check he didn't scan in this week yet`, async() => {
@ -371,7 +372,7 @@ describe('Worker time control path', () => {
.accessToSection('worker.card.timeControl')
.waitToGetProperty(selectors.workerTimeControl.weekWorkedHours, 'innerText');
expect(wholeWeekHours).toEqual('00:00 Hours');
expect(wholeWeekHours).toEqual('00:00 h.');
});
});
});
@ -386,10 +387,10 @@ describe('Worker time control path', () => {
it('should Hank Pym check his hours are alright', async() => {
const wholeWeekHours = await nightmare
.waitForTextInElement(selectors.workerTimeControl.weekWorkedHours, '56:00 Hours')
.waitForTextInElement(selectors.workerTimeControl.weekWorkedHours, '56:00 h.')
.waitToGetProperty(selectors.workerTimeControl.weekWorkedHours, 'innerText');
expect(wholeWeekHours).toEqual('56:00 Hours');
expect(wholeWeekHours).toEqual('56:00 h.');
});
});
});

View File

@ -21,16 +21,12 @@ describe('Item summary path', () => {
});
it(`should click on the search result summary button to open the item summary popup`, async() => {
const isVisibleBefore = await nightmare
const isVisible = await nightmare
.waitForTextInElement(selectors.itemsIndex.searchResult, 'Ranged weapon longbow 2m')
.isVisible(selectors.itemSummary.basicData);
const isVisibleAfter = await nightmare
.waitToClick(selectors.itemsIndex.searchResultPreviewButton)
.isVisible(selectors.itemSummary.basicData);
expect(isVisibleBefore).toBeFalsy();
expect(isVisibleAfter).toBeTruthy();
expect(isVisible).toBeTruthy();
});
it(`should check the item summary preview shows fields from basic data`, async() => {
@ -75,8 +71,9 @@ describe('Item summary path', () => {
it(`should close the summary popup`, async() => {
const result = await nightmare
.waitToClick(selectors.itemsIndex.closeItemSummaryPreview)
.isVisible(selectors.itemSummary.basicData);
.mousedown(selectors.itemsIndex.closeItemSummaryPreview)
.waitUntilNotPresent(selectors.itemSummary.basicData)
.visible(selectors.itemSummary.basicData);
expect(result).toBeFalsy();
});
@ -94,17 +91,13 @@ describe('Item summary path', () => {
});
it(`should now click on the search result summary button to open the item summary popup`, async() => {
const isVisibleBefore = await nightmare
const isVisible = await nightmare
.waitForTextInElement(selectors.itemsIndex.searchResult, 'Melee weapon combat fist 15cm')
.isVisible(selectors.itemSummary.basicData);
const isVisibleAfter = await nightmare
.waitToClick(selectors.itemsIndex.searchResultPreviewButton)
.isVisible(selectors.itemSummary.basicData);
expect(isVisibleBefore).toBeFalsy();
expect(isVisibleAfter).toBeTruthy();
expect(isVisible).toBeTruthy();
});
it(`should now check the item summary preview shows fields from basic data`, async() => {
@ -149,8 +142,9 @@ describe('Item summary path', () => {
it(`should now close the summary popup`, async() => {
const result = await nightmare
.waitToClick(selectors.itemsIndex.closeItemSummaryPreview)
.isVisible(selectors.itemSummary.basicData);
.mousedown(selectors.itemsIndex.closeItemSummaryPreview)
.waitUntilNotPresent(selectors.itemSummary.basicData)
.visible(selectors.itemSummary.basicData);
expect(result).toBeFalsy();
});

View File

@ -65,7 +65,7 @@ describe('Ticket services path', () => {
it('should click on the add new description to open the dialog', async() => {
const result = await nightmare
.waitToClick(selectors.ticketService.firstAddDescriptionButton)
.waitForClassPresent('vn-ticket-service > vn-dialog', 'shown')
.wait('.vn-dialog.shown')
.isVisible(selectors.ticketService.newDescriptionInput);
expect(result).toBeTruthy();

View File

@ -17,7 +17,7 @@ describe('Ticket Summary path', () => {
it(`should display details from the ticket and it's client on the top of the header`, async() => {
let result = await nightmare
.waitForSpinnerLoad()
.waitForTextInElement(selectors.ticketSummary.header, 'Bruce Banner')
.waitToGetProperty(selectors.ticketSummary.header, 'innerText');
expect(result).toContain(`Ticket #${ticketId}`);

View File

@ -3,7 +3,6 @@ import createNightmare from '../../helpers/nightmare';
describe('InvoiceOut descriptor path', () => {
const nightmare = createNightmare();
let bookedDate;
describe('as Administrative', () => {
beforeAll(() => {
@ -123,10 +122,9 @@ describe('InvoiceOut descriptor path', () => {
it(`should check the invoiceOut is booked in the summary data`, async() => {
const result = await nightmare
.waitForTextInElement(selectors.invoiceOutSummary.bookedLabel, '/')
.waitToGetProperty(selectors.invoiceOutSummary.bookedLabel, 'innerText');
bookedDate = result;
expect(result.length).toBeGreaterThan(1);
});
@ -141,10 +139,13 @@ describe('InvoiceOut descriptor path', () => {
});
it(`should check the invoiceOut booked in the summary data`, async() => {
let today = new Date();
let expectedDate = `${today.getDate()}/${(today.getMonth() + 1)}/${today.getFullYear()}`;
const result = await nightmare
.waitToGetProperty(selectors.invoiceOutSummary.bookedLabel, 'innerText');
expect(result).not.toEqual(bookedDate);
expect(result).toEqual(expectedDate);
});
});

View File

@ -100,7 +100,7 @@ export default class ArrayModel extends ModelProxy {
addFilter(user, params) {
this.userFilter = this.mergeFilters(user, this.userFilter);
Object.assign(this.userParams, params);
this.userParams = Object.assign({}, this.userParams, params);
return this.refresh();
}

View File

@ -26,7 +26,7 @@
ng-click="$ctrl.onClear($event)">
</vn-icon>
<vn-icon
ng-if="::$ctrl.info"
ng-if="::$ctrl.info != null"
icon="info_outline"
vn-tooltip="{{::$ctrl.info}}">
</vn-icon>
@ -48,5 +48,5 @@
vn-id="drop-down"
on-select="$ctrl.onDropDownSelect(item)"
on-data-ready="$ctrl.onDataReady()"
on-close-start="$ctrl.focus()">
on-close-start="$ctrl.onDropDownClose()">
</vn-drop-down>

View File

@ -17,14 +17,9 @@ import './style.scss';
* @event change Thrown when value is changed
*/
export default class Autocomplete extends Field {
constructor($element, $scope, $compile, $http, $transclude, $translate, $interpolate) {
super($element, $scope, $compile);
Object.assign(this, {
$http,
$interpolate,
$transclude,
$translate
});
constructor($element, $, $compile, $transclude) {
super($element, $, $compile);
this.$transclude = $transclude;
this._selection = null;
this.input = this.element.querySelector('input');
@ -48,7 +43,6 @@ export default class Autocomplete extends Field {
set field(value) {
super.field = value;
this.refreshSelection();
this.emit('change', {value});
}
get model() {
@ -121,7 +115,6 @@ export default class Autocomplete extends Field {
return;
const selection = this.fetchSelection();
this.selection = selection;
}
@ -206,13 +199,17 @@ export default class Autocomplete extends Field {
onDropDownSelect(item) {
const value = item[this.valueField];
this.selection = item;
this.field = value;
this.change(value);
}
onDropDownClose() {
setTimeout(() => this.focus());
}
onContainerKeyDown(event) {
if (event.defaultPrevented) return;
switch (event.code) {
switch (event.key) {
case 'ArrowUp':
case 'ArrowDown':
case 'Enter':
@ -224,13 +221,10 @@ export default class Autocomplete extends Field {
else
return;
}
event.preventDefault();
}
onContainerClick(event) {
if (event.defaultPrevented) return;
event.preventDefault();
this.showDropDown();
}
@ -240,12 +234,13 @@ export default class Autocomplete extends Field {
assignDropdownProps() {
if (!this.$.dropDown) return;
this.$.dropDown.copySlot('tplItem', this.$transclude);
assignProps(this, this.$.dropDown, [
'valueField',
'showField',
'showFilter',
'multiple',
'$transclude',
'translateFields',
'model',
'data',
@ -276,7 +271,7 @@ export default class Autocomplete extends Field {
this.refreshSelection();
}
}
Autocomplete.$inject = ['$element', '$scope', '$compile', '$http', '$transclude', '$translate', '$interpolate'];
Autocomplete.$inject = ['$element', '$scope', '$compile', '$transclude'];
ngModule.vnComponent('vnAutocomplete', {
template: require('./index.html'),

View File

@ -3,9 +3,7 @@ describe('Component vnAutocomplete', () => {
let controller;
let data = {id: 1, name: 'Bruce Wayne'};
beforeEach(angular.mock.module('vnCore', $translateProvider => {
$translateProvider.translations('en', {});
}));
beforeEach(ngModule('vnCore'));
beforeEach(inject(($compile, $rootScope) => {
$element = $compile(`<vn-autocomplete></vn-autocomplete>`)($rootScope);

View File

@ -1,6 +1,6 @@
@import "effects";
vn-autocomplete.vn-field {
.vn-autocomplete {
overflow: hidden;
& > .container {

View File

@ -15,6 +15,5 @@
</button>
<vn-drop-down
vn-id="drop-down"
on-select="$ctrl.onDropDownSelect(item)"
ng-click="$ctrl.onDropDownClick($event)">
on-select="$ctrl.onDropDownSelect(item)">
</vn-drop-down>

View File

@ -44,15 +44,10 @@ export default class ButtonMenu extends Button {
onClick(event) {
if (this.disabled) return;
if (event.defaultPrevented) return;
event.preventDefault();
this.emit('open');
this.showDropDown();
}
onDropDownClick(event) {
event.preventDefault();
}
onDropDownSelect(item) {
const value = item[this.valueField];
this.field = value;
@ -60,12 +55,13 @@ export default class ButtonMenu extends Button {
}
showDropDown() {
this.$.dropDown.copySlot('tplItem', this.$transclude);
assignProps(this, this.$.dropDown, [
'valueField',
'showField',
'showFilter',
'multiple',
'$transclude',
'translateFields',
'model',
'data',

View File

@ -2,9 +2,7 @@ describe('Component vnButtonMenu', () => {
let controller;
let $element;
beforeEach(angular.mock.module('vnCore', $translateProvider => {
$translateProvider.translations('en', {});
}));
beforeEach(ngModule('vnCore'));
beforeEach(inject(($compile, $rootScope) => {
$element = $compile(`<vn-icon-menu></vn-icon-menu>`)($rootScope);

View File

@ -1,3 +1,3 @@
vn-button-menu {
.vn-button-menu {
position: relative;
}

View File

@ -6,11 +6,7 @@ export default class Button extends FormInput {
constructor($element, $scope) {
super($element, $scope);
this.design = 'colored';
this.input = this.element.querySelector('button');
let element = this.element;
element.tabIndex = 0;
element.classList.add('vn-button');
this.initTabIndex();
this.element.addEventListener('keyup', e => this.onKeyup(e));
this.element.addEventListener('click', e => this.onClick(e));
}
@ -21,16 +17,17 @@ export default class Button extends FormInput {
}
onKeyup(event) {
if (event.code == 'Space')
this.onClick(event);
if (event.defaultPrevented) return;
switch (event.key) {
case ' ':
case 'Enter':
return this.element.click();
}
}
onClick(event) {
if (event.defaultPrevented) return;
// event.preventDefault();
// FIXME: Don't stop event propagation
if (this.disabled) event.stopImmediatePropagation();
if (this.disabled)
event.stopImmediatePropagation();
}
}
Button.$inject = ['$element', '$scope'];

View File

@ -1,82 +1,46 @@
<div>
<vn-horizontal class="header">
<vn-auto>
<vn-icon
icon="keyboard_arrow_left"
class="pointer"
ng-click="$ctrl.movePrevious($ctrl.skip)"
ng-show="$ctrl.displayControls"/>
</vn-icon>
</vn-auto>
<vn-one>
<div>
<span translate>{{$ctrl.defaultDate | date: 'MMMM'}}</span>
<span>{{$ctrl.defaultDate | date: 'yyyy'}}</span>
<div class="header">
<vn-button
icon="keyboard_arrow_left"
class="flat"
ng-click="$ctrl.movePrevious()"
translate-attr="::{title: 'Previous'}"
ng-if="$ctrl.displayControls"/>
</vn-button>
<div class="title">
<span translate>{{$ctrl.defaultDate | date: 'MMMM'}}</span>
<span ng-hide="::$ctrl.hideYear">{{$ctrl.defaultDate | date: 'yyyy'}}</span>
</div>
<vn-button
icon="keyboard_arrow_right"
class="flat"
ng-click="$ctrl.moveNext()"
translate-attr="::{title: 'Next'}"
ng-if="$ctrl.displayControls">
</vn-button>
</div>
<div class="weekdays">
<section
ng-repeat="day in ::$ctrl.weekDays"
translate-attr="::{title: day.name}"
ng-click="$ctrl.selectWeekDay(day.index)">
<span>{{::day.localeChar}}</span>
</section>
</div>
<div
class="days"
ng-class="{'hide-contiguous': $ctrl.hideContiguous}">
<section
ng-repeat="day in $ctrl.days"
class="day"
ng-class="::$ctrl.getDayClasses(day)"
vn-repeat-last
on-last="$ctrl.repeatLast()">
<div
class="day-number"
ng-click="$ctrl.select(day)">
{{::day | date: 'd'}}
</div>
</vn-one>
<vn-auto>
<vn-icon
icon="keyboard_arrow_right"
class="pointer"
ng-click="$ctrl.moveNext($ctrl.skip)"
ng-show="$ctrl.displayControls">
</vn-icon>
</vn-auto>
</vn-horizontal>
<vn-vertical class="body">
<vn-horizontal class="weekdays">
<section title="{{'Monday' | translate}}"
ng-click="$ctrl.selectAll(1)">
<span>L</span>
</section>
<section title="{{'Tuesday' | translate}}"
ng-click="$ctrl.selectAll(2)">
<span>M</span>
</section>
<section title="{{'Wednesday' | translate}}"
ng-click="$ctrl.selectAll(3)">
<span>X</span>
</section>
<section title="{{'Thursday' | translate}}"
ng-click="$ctrl.selectAll(4)">
<span>J</span>
</section>
<section title="{{'Friday' | translate}}"
ng-click="$ctrl.selectAll(5)">
<span>V</span>
</section>
<section title="{{'Saturday' | translate}}"
ng-click="$ctrl.selectAll(6)">
<span>S</span>
</section>
<section title="{{'Sunday' | translate}}"
ng-click="$ctrl.selectAll(0)">
<span>D</span>
</section>
</vn-horizontal>
<vn-horizontal class="days">
<section
ng-repeat="day in $ctrl.days"
class="day {{::$ctrl.getClass({$day: day.dated})}}"
ng-class="::{primary: day.events.length > 0 || $ctrl.hasEvents({$day: day.dated})}">
<div class="content">
<div class="day-number"
title="{{(day.eventName) | translate}}"
ng-style="$ctrl.renderStyle(day.style)"
ng-click="$ctrl.select($index)">
{{::day.dated | date: 'd'}}
</div>
<div ng-if="day.events" class="events">
<div ng-repeat="event in day.events" class="event"
title="{{(event.description || event.name) | translate}}">
<span class="chip ellipsize"
ng-style="::$ctrl.renderStyle(event.style)">
{{::event.name}}
</span>
</div>
</div>
</div>
</section>
</vn-horizontal>
</vn-vertical>
</section>
</div>
</div>

View File

@ -1,43 +1,26 @@
import ngModule from '../../module';
import Component from '../../lib/component';
import FormInput from '../form-input';
import './style.scss';
/**
* Flat calendar.
*
* @property {Array} data Array of events
* @property {Array} defaultDate Array of events
* @property {Function} hasEvents Determines if an events exists for a day
* @property {Function} getClass Class to apply to specific day
* @event selection Emitted when day or weekday is selected
* @event move Emitted when month changes
*/
export default class Calendar extends Component {
constructor($element, $scope) {
export default class Calendar extends FormInput {
constructor($element, $scope, vnWeekDays) {
super($element, $scope);
this.events = [];
this.weekDays = vnWeekDays.locales;
this.defaultDate = new Date();
this.displayControls = true;
this.disabled = false;
this.skip = 1;
this.window.addEventListener('resize', () => {
this.checkSize();
});
}
/**
* Resizes the calendar
* based on component height
*/
checkSize() {
const height = this.$element[0].clientHeight;
if (height < 530)
this.$element.addClass('small');
else
this.$element.removeClass('small');
}
/**
* Returns the initial date
* The initial date
*
* @return {Date} - Default date
*/
@ -45,11 +28,6 @@ export default class Calendar extends Component {
return this._defaultDate;
}
/**
* Sets a new initial date
*
* @param {Date} value - New default date
*/
set defaultDate(value) {
if (value) {
value = new Date(value);
@ -58,67 +36,10 @@ export default class Calendar extends Component {
}
this._defaultDate = value;
this.month = value.getMonth();
this.repaint();
}
/**
* Sets events
*
* @param {Array} value - Array of events
* @param {Date} event.dated - Day to add event
* @param {String} event.name - Tooltip description
* @param {String} event.className - ClassName style
* @param {Object} event.style - Style properties
*/
set data(value) {
if (!value) return;
this.events = [];
value.forEach(event => {
event.dated = new Date(event.dated);
event.dated.setHours(0, 0, 0, 0);
this.events.push(event);
});
if (this.defaultDate) {
this.repaint();
this.checkSize();
}
}
/**
* Gets current month date
*/
get currentMonth() {
return this.defaultDate;
}
/**
* Gets next month date
*
* @return {Date}
*/
get nextMonth() {
const newDate = new Date(this.currentMonth);
newDate.setMonth(this.currentMonth.getMonth() + 1);
return newDate;
}
/**
* Gets previous month date
*
* @return {Date}
*/
get previousMonth() {
const newDate = new Date(this.currentMonth);
newDate.setMonth(this.currentMonth.getMonth() - 1);
return newDate;
}
/**
* Returns first day of month from a given date
*
@ -126,185 +47,113 @@ export default class Calendar extends Component {
* @return {Integer}
*/
firstDay(date) {
const newDate = new Date(
return new Date(
date.getFullYear(),
date.getMonth(), 1);
return newDate;
date.getMonth(),
1
);
}
/**
* Returns last day of month from a given date
*
* @param {Date} date - Origin date
* @return {Integer}
* Repaints the calendar.
*/
lastDay(date) {
const newDate = new Date(
date.getFullYear(),
date.getMonth() + 1, 0);
return newDate;
}
repaint() {
const firstWeekday = this.firstDay(this.currentMonth).getDay();
const previousLastDay = this.lastDay(this.previousMonth).getDate();
const currentLastDay = this.lastDay(this.currentMonth).getDate();
const maxFields = 42; // Max field limit
const firstWeekday = this.firstDay(this.defaultDate).getDay() - 1;
let weekdayOffset = firstWeekday >= 0 ? firstWeekday : 6;
let weekdayOffset = firstWeekday > 0 ? firstWeekday : 7;
let dayPrevious = previousLastDay - (weekdayOffset - 2);
let dayCurrent = 1;
let dayNext = 1;
let dayIndex = new Date(this.defaultDate.getTime());
dayIndex.setDate(1 - weekdayOffset);
this.days = [];
for (let fieldIndex = 1; fieldIndex < maxFields; fieldIndex++) {
// Insert previous month days
if (fieldIndex < weekdayOffset) {
const dated = new Date(
this.previousMonth.getFullYear(),
this.previousMonth.getMonth(), dayPrevious);
this.insertDay(dated, 'gray');
dayPrevious++;
}
// Insert current month days
if (fieldIndex >= weekdayOffset && dayCurrent <= currentLastDay) {
const dated = new Date(
this.currentMonth.getFullYear(),
this.currentMonth.getMonth(), dayCurrent);
this.insertDay(dated);
dayCurrent++;
}
// Insert next month days
if (fieldIndex >= weekdayOffset && dayCurrent > currentLastDay) {
const dated = new Date(
this.nextMonth.getFullYear(),
this.nextMonth.getMonth(), dayNext);
this.insertDay(dated, 'gray');
dayNext++;
}
for (let i = 1; i <= 42; i++) {
this.days.push(new Date(dayIndex.getTime()));
dayIndex.setDate(dayIndex.getDate() + 1);
}
}
/**
* Inserts a date on an array of month days
* Gets CSS classes to apply to the specified day.
*
* @param {Date} dated - Date of month
* @param {String} className - Default class style
* @param {Date} day The day
* @return {Object} The CSS classes to apply
*/
insertDay(dated) {
let events = this.events.filter(event => {
return event.dated >= dated && event.dated <= dated;
});
getDayClasses(day) {
let wday = day.getDay();
let month = day.getMonth();
const params = {dated: dated, events: events /**/, style: {}};
const isSaturday = dated.getDay() === 6;
const isSunday = dated.getDay() === 0;
const isCurrentMonth = dated.getMonth() === this.currentMonth.getMonth();
const hasEvents = events.length > 0;
let classes = {
weekend: wday === 6 || wday === 0,
previous: month < this.month,
current: month == this.month,
next: month > this.month,
event: this.hasEvents({$day: day})
};
if (isCurrentMonth && isSunday && !hasEvents)
params.style = {color: '#999'};
let userClass = this.getClass({$day: day});
if (userClass) classes[userClass] = true;
if (isCurrentMonth && isSaturday && !hasEvents)
params.style = {color: '#999'};
if (!isCurrentMonth)
params.style = {opacity: '0.5'};
if (events.length > 0) {
const eventStyle = events[0].style;
const eventName = events[0].description || events[0].name;
if (eventStyle)
Object.assign(params.style, eventStyle);
if (eventName)
params.eventName = eventName;
}
this.days.push(params);
return classes;
}
/**
* Moves to next month(s)
*
* @param {Integer} skip - Months to skip at once
*/
moveNext(skip = 1) {
let next = this.defaultDate.getMonth() + skip;
this.defaultDate.setMonth(next);
this.repaint();
this.emit('moveNext');
moveNext() {
this.move(1);
}
/**
* Moves to previous month(s)
*
* @param {Integer} skip - Months to skip at once
*/
movePrevious(skip = 1) {
let previous = this.defaultDate.getMonth() - skip;
this.defaultDate.setMonth(previous);
this.repaint();
this.emit('movePrevious');
movePrevious() {
this.move(-1);
}
/**
* Day selection event
* Moves @direction months backwards/forwards.
*
* @param {Integer} index - Index from days array
* @param {Number} direction Negative to move backwards, positive forwards
*/
select(index) {
if (this.disabled) return;
let day = this.days[index].dated;
move(direction) {
let date = new Date(this.defaultDate.getTime());
date.setMonth(date.getMonth() + direction);
this.defaultDate = date;
this.repaint();
this.emit('move', {$date: date});
}
/*
* Day selection event
*/
select(day) {
if (!this.editable) return;
this.change(day);
this.emit('selection', {
$days: [day],
$type: 'day'
});
this.repaint();
}
/**
/*
* WeekDay selection event
*
* @param {Integer} weekday - weekday index
*/
selectAll(weekday) {
if (this.disabled) return;
selectWeekDay(weekday) {
if (!this.editable) return;
let days = [];
for (let i in this.days) {
const day = this.days[i].dated;
if (day.getDay() === weekday && day.getMonth() == this.defaultDate.getMonth())
for (let day of this.days) {
if (day.getDay() === weekday && day.getMonth() == this.month)
days.push(day);
}
this.field = days[0];
this.emit('selection', {
$days: days,
$type: 'weekday',
$weekday: weekday
});
}
renderStyle(style) {
const normalizedStyle = {};
if (style) {
const properties = Object.keys(style);
properties.forEach(attribute => {
const attrName = attribute.split(/(?=[A-Z])/).
join('-').toLowerCase();
normalizedStyle[attrName] = style[attribute];
});
}
return normalizedStyle;
this.repaint();
}
hasEvents() {
@ -314,24 +163,31 @@ export default class Calendar extends Component {
getClass() {
return '';
}
repeatLast() {
if (!this.formatDay) return;
let days = this.element.querySelectorAll('.days > .day');
for (let i = 0; i < days.length; i++) {
this.formatDay({
$day: this.days[i],
$element: days[i]
});
}
}
}
Calendar.$inject = ['$element', '$scope', 'vnWeekDays'];
Calendar.$inject = ['$element', '$scope'];
ngModule.component('vnCalendar', {
ngModule.vnComponent('vnCalendar', {
template: require('./index.html'),
controller: Calendar,
bindings: {
model: '<',
data: '<?',
defaultDate: '=?',
onSelection: '&?',
onMoveNext: '&?',
onMovePrevious: '&?',
hasEvents: '&?',
getClass: '&?',
formatDay: '&?',
displayControls: '<?',
disabled: '<?',
skip: '<?'
hideYear: '<?',
hideContiguous: '<?'
}
});

View File

@ -2,86 +2,64 @@ describe('Component vnCalendar', () => {
let controller;
let $element;
beforeEach(angular.mock.module('vnCore', $translateProvider => {
$translateProvider.translations('en', {});
}));
let date = new Date();
date.setHours(0, 0, 0, 0);
date.setDate(1);
beforeEach(ngModule('vnCore'));
beforeEach(inject(($compile, $rootScope) => {
$element = $compile(`<vn-calendar></vn-calendar`)($rootScope);
controller = $element.controller('vnCalendar');
controller.defaultDate = new Date();
controller.defaultDate = date;
}));
afterEach(() => {
$element.remove();
});
describe('data() setter', () => {
it(`should set an array of events and convert string dates to string object, then call repaint() method`, () => {
spyOn(controller, 'repaint');
let currentDate = new Date().toString();
controller.data = [
{dated: currentDate, name: 'Event 1'},
{dated: currentDate, name: 'Event 2'},
];
expect(controller.events[0].dated instanceof Object).toBeTruthy();
expect(controller.repaint).toHaveBeenCalledWith();
});
});
describe('moveNext()', () => {
it(`should shift to the next n months, then emit a 'moveNext' event`, () => {
it(`should shift to the next month, then emit a 'move' event`, () => {
spyOn(controller, 'emit');
const currentMonth = controller.defaultDate.getMonth();
let nextMonth = currentMonth + 1;
let nextMonth = new Date(date.getTime());
nextMonth.setMonth(nextMonth.getMonth() + 1);
controller.moveNext(1);
controller.moveNext();
expect(controller.defaultDate.getMonth()).toEqual(nextMonth);
expect(controller.emit).toHaveBeenCalledWith('moveNext');
expect(controller.month).toEqual(nextMonth.getMonth());
expect(controller.emit).toHaveBeenCalledWith('move', {$date: nextMonth});
});
});
describe('movePrevious()', () => {
it(`should shift to the previous n months, then emit a 'movePrevious' event`, () => {
it(`should shift to the previous month, then emit a 'move' event`, () => {
spyOn(controller, 'emit');
const currentMonth = controller.defaultDate.getMonth();
let previousMonth = currentMonth - 1;
let previousMonth = new Date(date.getTime());
previousMonth.setMonth(previousMonth.getMonth() - 1);
controller.movePrevious(1);
controller.movePrevious();
expect(controller.defaultDate.getMonth()).toEqual(previousMonth);
expect(controller.emit).toHaveBeenCalledWith('movePrevious');
expect(controller.month).toEqual(previousMonth.getMonth());
expect(controller.emit).toHaveBeenCalledWith('move', {$date: previousMonth});
});
});
describe('select()', () => {
it(`should return the selected element, then emit a 'selection' event`, () => {
spyOn(controller, 'emit');
const dated = new Date();
const days = [{dated}];
controller.days = days;
controller.select(0);
const day = new Date();
day.setHours(0, 0, 0, 0);
controller.select(day);
let res = {
$days: [dated],
$days: [day],
$type: 'day'
};
expect(controller.field).toEqual(day);
expect(controller.emit).toHaveBeenCalledWith('selection', res);
});
});
describe('renderStyle()', () => {
it(`should normalize CSS attributes`, () => {
const result = controller.renderStyle({
backgroundColor: 'red'
});
expect(result['background-color']).toEqual('red');
});
});
});

View File

@ -1,103 +1,97 @@
@import "variables";
vn-calendar.small {
.events {
display: none
}
}
vn-calendar {
.vn-calendar {
display: block;
.header vn-one {
text-align: center;
padding: 0.2em 0;
height: 1.5em
}
.weekdays {
color: $color-font-secondary;
margin-bottom: 0.5em;
padding: 0.5em 0;
font-weight: bold;
font-size: 0.8em;
}
.weekdays section {
cursor: pointer
}
.weekdays section, .day {
position: relative;
text-align: center;
box-sizing: border-box;
width: 14.28%;
outline: 0;
}
.days {
justify-content: flex-start;
align-items: flex-start;
flex-wrap: wrap;
}
.day {
.content {
position: absolute;
bottom: 0;
right: 0;
left: 0;
top: 0
}
.day-number {
transition: background-color 0.3s;
text-align:center;
float:inline-end;
margin: 0 auto;
border-radius: 50%;
font-size: 0.85em;
width:2.2em;
height: 1.2em;
padding: 0.5em 0;
cursor: pointer;
outline: 0
}
.day-number:hover {
background-color: lighten($color-font-secondary, 20%);
opacity: 0.8
}
}
.day::after {
content: "";
display: block;
padding-top: 100%;
}
.day.primary .day-number {
background-color: $color-main;
color: $color-font-dark;
}
.events {
margin-top: 0.5em;
font-size: 0.6em
}
.events {
color: $color-font-secondary;
& > div {
& > .header {
display: flex;
margin-bottom: 0.5em;
align-items: center;
height: 2.4em;
.event {
margin-bottom: .1em;
& > .title {
flex: 1;
text-align: center;
padding: 0.2em 0;
}
& > .vn-button {
color: inherit;
}
}
& > .weekdays {
display: flex;
color: $color-font-secondary;
margin-bottom: 0.5em;
padding: 0.5em 0;
font-weight: bold;
font-size: 0.8em;
text-align: center;
& > section {
width: 14.28%;
cursor: pointer;
}
}
& > .days {
display: flex;
justify-content: center;
align-items: center;
flex-wrap: wrap;
& > .day {
width: 14.28%;
height: 40px;
display: flex;
justify-content: center;
align-items: center;
&.weekend {
color: $color-font-secondary;
}
&.previous,
&.next {
opacity: .5;
}
&.event .day-number {
background-color: $color-main;
color: $color-font-dark;
}
& > .day-number {
display: flex;
justify-content: center;
align-items: center;
border-radius: 50%;
font-size: 14px;
width: 2.2em;
height: 2.2em;
cursor: pointer;
outline: 0;
transition: background-color 300ms ease-in-out;
&:hover {
background-color: lighten($color-font-secondary, 20%);
opacity: .8
}
}
}
&.hide-contiguous > .day {
&.previous,
&.next {
visibility: hidden;
}
}
}
}
.chip {
background-color: $color-main;
color: $color-font-bg;
display: inline-block;
border-radius: .3em;
padding: 0.3em .8em;
max-width: 5em;
}
.day.gray {
.day-number {
color: $color-font-secondary
}
}
.day.sunday {
.day-number {
color: $color-alert;
font-weight: bold
&.disabled,
&.readonly {
& > div {
& > .weekdays > section {
cursor: initial;
}
& > .days > .day > .day-number {
cursor: initial;
}
}
}
}

View File

@ -1 +0,0 @@
<div></div>

View File

@ -5,12 +5,11 @@ export default function directive() {
return {
restrict: 'E',
transclude: true,
template: require('./card.html'),
link: function($scope, $element, $attrs, $ctrl, $transclude) {
$element.addClass('demo-card-wide vn-shadow bg-panel');
$element[0].classList.add('vn-shadow', 'bg-panel');
$transclude($scope, function(clone) {
angular.element($element[0].querySelector('div')).append(clone);
$element.append(clone);
});
}
};

View File

@ -49,18 +49,19 @@ export default class Check extends Toggle {
onClick(event) {
if (super.onClick(event)) return;
let value;
if (this.tripleState) {
if (this.field == null)
this.field = true;
value = true;
else if (this.field)
this.field = false;
value = false;
else
this.field = null;
value = null;
} else
this.field = !this.field;
value = !this.field;
this.changed();
this.change(value);
}
}

View File

@ -1,15 +1,13 @@
describe('Component vnCheck', () => {
let $element;
let $ctrl;
let controller;
let element;
beforeEach(angular.mock.module('vnCore', $translateProvider => {
$translateProvider.translations('en', {});
}));
beforeEach(ngModule('vnCore'));
beforeEach(inject(($compile, $rootScope) => {
$element = $compile(`<vn-check></vn-check>`)($rootScope);
$ctrl = $element.controller('vnCheck');
controller = $element.controller('vnCheck');
element = $element[0];
}));
@ -19,46 +17,46 @@ describe('Component vnCheck', () => {
describe('field() setter', () => {
it(`should set model value`, () => {
$ctrl.field = true;
controller.field = true;
expect($ctrl.field).toEqual(true);
expect(controller.field).toEqual(true);
});
it(`should uncheck value and change to true when clicked`, () => {
$ctrl.field = false;
controller.field = false;
element.click();
expect($ctrl.field).toEqual(true);
expect(controller.field).toEqual(true);
});
it(`should check value and change to false when clicked`, () => {
$ctrl.field = true;
controller.field = true;
element.click();
expect($ctrl.field).toEqual(false);
expect(controller.field).toEqual(false);
});
it(`should check value and change to false when clicked`, () => {
$ctrl.field = true;
$ctrl.tripleState = true;
controller.field = true;
controller.tripleState = true;
element.click();
expect($ctrl.field).toEqual(false);
expect(controller.field).toEqual(false);
});
it(`should set value to null and change to true when clicked`, () => {
$ctrl.field = null;
$ctrl.tripleState = true;
controller.field = null;
controller.tripleState = true;
element.click();
expect($ctrl.field).toEqual(true);
expect(controller.field).toEqual(true);
});
it(`should cast value to boolean when clicked`, () => {
$ctrl.field = 0;
controller.field = 0;
element.click();
expect($ctrl.field).toEqual(true);
expect(controller.field).toEqual(true);
});
});
});

View File

@ -1,6 +1,6 @@
@import "variables";
vn-check {
.vn-check {
& > .btn {
border-radius: 2px;
transition: background 250ms;
@ -12,8 +12,13 @@ vn-check {
border-width: 0;
}
}
& > vn-icon {
margin-left: 5px;
color: $color-font-secondary;
vertical-align: middle;
}
&.checked > .btn {
border-color: $color-main;
border-color: transparent;
background-color: $color-main;
& > .mark {
@ -35,9 +40,7 @@ vn-check {
height: 2px;
border-bottom: 2px solid #666;
}
& > vn-icon {
margin-left: 5px;
color: $color-font-secondary;
vertical-align: middle;
&.disabled.checked > .btn {
background-color: $color-font-secondary;
}
}

View File

@ -9,7 +9,7 @@ export default class Chip extends Component {
}
Chip.$inject = ['$element', '$scope', '$transclude'];
ngModule.component('vnChip', {
ngModule.vnComponent('vnChip', {
template: require('./index.html'),
controller: Chip,
transclude: true,

View File

@ -6,9 +6,7 @@ describe('Component vnChip', () => {
let $scope;
let controller;
beforeEach(angular.mock.module('vnCore', $translateProvider => {
$translateProvider.translations('en', {});
}));
beforeEach(ngModule('vnCore'));
beforeEach(angular.mock.inject(($componentController, $rootScope) => {
$scope = $rootScope.$new();

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

@ -1,10 +1,10 @@
<root>
<div>
<tpl-body>
<h6 translate>{{::$ctrl.message}}</h6>
<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>
</root>
</div>

View File

@ -1,24 +1,22 @@
import ngModule from '../../module';
import Dialog from '../dialog/dialog';
import Dialog from '../dialog';
import template from './confirm.html';
export default class Confirm extends Dialog {
constructor($element, $scope, $compile) {
super($element);
let cTemplate = $compile(template)($scope)[0];
this.body = cTemplate.querySelector('tpl-body');
this.buttons = cTemplate.querySelector('tpl-buttons');
constructor($element, $, $transclude) {
super($element, $, $transclude);
let $template = angular.element(template);
this.fillSlot('body', $template.find('tpl-body'));
this.fillSlot('buttons', $template.find('tpl-buttons'));
}
}
Confirm.$inject = ['$element', '$scope', '$compile'];
ngModule.component('vnConfirm', {
template: require('../dialog/dialog.html'),
ngModule.vnComponent('vnConfirm', {
controller: Confirm,
transclude: true,
bindings: {
onOpen: '&?',
onResponse: '&',
question: '@',
message: '@?'
},
controller: Confirm
}
});

View File

@ -95,7 +95,7 @@ export default class CrudModel extends ModelProxy {
*/
addFilter(filter, params) {
this.userFilter = mergeFilters(filter, this.userFilter);
Object.assign(this.userParams, params);
this.userParams = Object.assign({}, this.userParams, params);
return this.refresh();
}

View File

@ -1,12 +1,9 @@
import ngModule from '../../module';
import Field from '../field';
import './style.scss';
class DatePicker extends Field {
constructor($element, $scope, $compile, $translate, $filter) {
constructor($element, $scope, $compile) {
super($element, $scope, $compile);
this.$translate = $translate;
this.$filter = $filter;
this.input = $compile(`<input type="date"></input>`)($scope)[0];
this.input.addEventListener('change', () => this.onValueUpdate());
@ -46,7 +43,7 @@ class DatePicker extends Field {
this.input.value = this.$filter('date')(value, 'yyyy-MM-dd');
}
}
DatePicker.$inject = ['$element', '$scope', '$compile', '$translate', '$filter'];
DatePicker.$inject = ['$element', '$scope', '$compile'];
ngModule.vnComponent('vnDatePicker', {
controller: DatePicker,

View File

@ -3,9 +3,7 @@ describe('Component vnDatePicker', () => {
let $element;
let $ctrl;
beforeEach(angular.mock.module('vnCore', $translateProvider => {
$translateProvider.translations('en', {});
}));
beforeEach(ngModule('vnCore'));
beforeEach(angular.mock.inject(($compile, $rootScope, _$filter_) => {
$filter = _$filter_;

View File

@ -1,7 +0,0 @@
@import "variables";
.flatpickr-months .flatpickr-month,
.flatpickr-weekdays,
span.flatpickr-weekday {
background-color: $color-main;
}

View File

@ -0,0 +1,9 @@
<h6>Debug info</h6>
<ul>
<li>
{{$ctrl.env}}
</li>
<li>
<span ng-class="{alert: $root.$$watchersCount > 500}">{{$root.$$watchersCount}}</span> watchers
</li>
</ul>

View File

@ -0,0 +1,27 @@
import ngModule from '../../module';
import './style.scss';
/**
* Floating box displaying debugging information.
* Enabled only in development environment.
*/
export default class Controller {
constructor($element, $) {
this.env = process.env.NODE_ENV || 'development';
if (this.env == 'development')
this.interval = setInterval(() => $.$digest(), 2000);
else
$element[0].style.display = 'none';
}
$onDestroy() {
clearInterval(this.interval);
}
}
Controller.$inject = ['$element', '$scope'];
ngModule.component('vnDebugInfo', {
template: require('./index.html'),
controller: Controller
});

View File

@ -0,0 +1,44 @@
@import "variables";
vn-debug-info {
position: fixed;
bottom: 1em;
left: 1em;
padding: 1em;
min-width: 8em;
background-color: #3f51b5;
color: $color-font-dark;
border-radius: 4px;
z-index: 999;
box-shadow: $shadow;
transition: opacity 400ms ease-in-out;
&:hover {
opacity: .5;
}
& > h6 {
font-weight: normal;
color: rgba(255, 255, 255, .5);
font-size: 1em;
}
ul {
list-style-type: none;
padding: 0;
margin: 0;
& > li {
margin-top: .2em;
font-size: .95em;
& > span {
padding: .05em .2em;
border-radius: 4px;
transition: background-color 200ms ease-in-out;
&.alert {
background-color: $color-alert;
}
}
}
}
}

View File

@ -1,17 +0,0 @@
<div ng-mousedown="$ctrl.onDialogMouseDown($event)">
<button
class="close"
ng-click="$ctrl.hide()"
translate-attr="{title: 'Close'}">
<vn-icon icon="clear"></vn-icon>
</button>
<form>
<div
class="body">
</div>
<div
class="buttons"
ng-click="$ctrl.onButtonClick($event)">
</div>
</form>
</div>

View File

@ -1,126 +0,0 @@
import ngModule from '../../module';
import Component from '../../lib/component';
import './style.scss';
/**
* Dialog component.
*
* @property {HTMLElement} body The dialog HTML body
* @property {HTMLElement} buttons The dialog HTML buttons
*/
export default class Dialog extends Component {
constructor($element, $scope, $transclude) {
super($element, $scope);
this.shown = false;
this.$element.addClass('vn-dialog');
this.element.addEventListener('mousedown',
e => this.onBackgroundMouseDown(e));
if ($transclude) {
$transclude($scope.$parent, tClone => {
this.body = tClone[0];
}, null, 'body');
$transclude($scope.$parent, tClone => {
this.buttons = tClone[0];
}, null, 'buttons');
}
}
set body(value) {
this.element.querySelector('.body').appendChild(value);
}
set buttons(value) {
this.element.querySelector('.buttons').appendChild(value);
}
/**
* Displays the dialog to the user.
*/
show() {
if (this.shown) return;
this.shown = true;
this.keyDownHandler = e => this.onkeyDown(e);
this.document.addEventListener('keydown', this.keyDownHandler);
this.element.style.display = 'flex';
this.transitionTimeout = setTimeout(() => this.$element.addClass('shown'), 30);
this.emit('open');
}
/**
* Hides the dialog calling the response handler.
*/
hide() {
this.fireResponse();
this.realHide();
this.emit('close');
}
/**
* Calls the response handler.
*
* @param {String} response The response code
* @return {Boolean} %true if response was canceled, %false otherwise
*/
fireResponse(response) {
let cancel = false;
if (this.onResponse)
cancel = this.onResponse({response: response});
return cancel;
}
realHide() {
if (!this.shown) return;
this.element.style.display = 'none';
this.document.removeEventListener('keydown', this.keyDownHandler);
this.lastEvent = null;
this.shown = false;
this.transitionTimeout = setTimeout(() => this.$element.removeClass('shown'), 30);
}
onButtonClick(event) {
let buttons = this.element.querySelector('.buttons');
let tplButtons = buttons.querySelector('tpl-buttons');
let node = event.target;
while (node.parentNode != tplButtons) {
if (node == buttons) return;
node = node.parentNode;
}
let response = node.getAttribute('response');
let cancel = this.fireResponse(response);
if (cancel !== false) this.realHide();
}
onDialogMouseDown(event) {
this.lastEvent = event;
}
onBackgroundMouseDown(event) {
if (event != this.lastEvent)
this.hide();
}
onkeyDown(event) {
if (event.keyCode == 27) // Esc
this.hide();
}
$onDestroy() {
clearTimeout(this.transitionTimeout);
}
}
Dialog.$inject = ['$element', '$scope', '$transclude'];
ngModule.component('vnDialog', {
template: require('./dialog.html'),
transclude: {
body: 'tplBody',
buttons: '?tplButtons'
},
bindings: {
onResponse: '&?'
},
controller: Dialog
});

View File

@ -1,75 +0,0 @@
describe('Component vnDialog', () => {
let $element;
let controller;
beforeEach(angular.mock.module('vnCore', $translateProvider => {
$translateProvider.translations('en', {});
}));
beforeEach(angular.mock.inject($componentController => {
$element = angular.element('<vn-dialog></vn-dialog>');
controller = $componentController('vnDialog', {$element, $transclude: null});
controller.emit = jasmine.createSpy('emit');
}));
describe('show()', () => {
it(`should do nothing if controller.shown is defined`, () => {
controller.element = {style: {display: 'none'}};
controller.shown = true;
controller.show();
expect(controller.element.style.display).toEqual('none');
expect(controller.emit).not.toHaveBeenCalledWith('open');
});
it(`should set shown on the controller, set style.display on the element and emit onOpen() event`, () => {
controller.show();
expect(controller.element.style.display).toEqual('flex');
expect(controller.shown).toBeTruthy();
expect(controller.emit).toHaveBeenCalledWith('open');
});
});
describe('hide()', () => {
describe('fireResponse()', () => {
it(`should call onResponse() if it's defined in the controller`, () => {
controller.onResponse = () => {};
spyOn(controller, 'onResponse');
controller.hide();
expect(controller.onResponse).toHaveBeenCalledWith(jasmine.any(Object));
});
it(`should call onResponse() with a response`, () => {
let responseRes;
controller.onResponse = response => {
responseRes = response;
return false;
};
let responseRet = controller.fireResponse('answer');
expect(responseRes).toEqual({response: 'answer'});
expect(responseRet).toEqual(false);
});
});
describe('realHide()', () => {
it(`should do nothing if controller.shown is not defined`, () => {
controller.element = {style: {display: 'not none'}};
controller.hide();
expect(controller.element.style.display).toEqual('not none');
});
it(`should set lastEvent, shown and element.style.display to their expected values`, () => {
controller.shown = true;
controller.hide();
expect(controller.lastEvent).toBeFalsy();
expect(controller.shown).toBeFalsy();
expect(controller.element.style.display).toEqual('none');
});
});
});
});

View File

@ -0,0 +1,22 @@
<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'}"
icon="clear"
class="flat close">
</vn-button>
<form>
<div
class="body"
ng-transclude="body">
</div>
<div
class="buttons"
ng-click="$ctrl.onButtonClick($event)"
ng-transclude="buttons">
</div>
</form>

View File

@ -0,0 +1,136 @@
import ngModule from '../../module';
import Popup from '../popup';
import template from './index.html';
import './style.scss';
/**
* 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 {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) {
super($element, $, $transclude);
this.fillDefaultSlot(template);
}
/**
* 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
*/
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} The response handler return
*/
respond(response) {
if (!this.shown)
return this.$q.resolve();
let handlerArgs = {
$response: response,
$data: this.data
};
let cancellers = [];
if (this.onResponse)
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) {
let buttons = this.popup.querySelector('.buttons');
let tplButtons = buttons.querySelector('tpl-buttons');
let node = event.target;
while (node.parentNode != tplButtons) {
if (node == buttons) return;
node = node.parentNode;
}
this.respond(node.getAttribute('response'));
}
}
ngModule.vnComponent('vnDialog', {
controller: Dialog,
transclude: {
body: 'tplBody',
buttons: '?tplButtons'
},
bindings: {
onResponse: '&?',
onAccept: '&?'
}
});

View File

@ -0,0 +1,106 @@
describe('Component vnDialog', () => {
let $element;
let $scope;
let controller;
beforeEach(ngModule('vnCore'));
beforeEach(angular.mock.inject(($rootScope, $compile) => {
$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()', () => {
it(`should do nothing if it's already hidden`, () => {
controller.onResponse = () => {};
spyOn(controller, 'onResponse');
controller.hide();
expect(controller.onResponse).not.toHaveBeenCalledWith();
});
});
describe('respond()', () => {
it(`should do nothing if dialog is already hidden`, () => {
controller.onResponse = () => {};
spyOn(controller, 'onResponse');
controller.respond();
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,55 +1,29 @@
@import "effects";
.vn-dialog {
display: none;
justify-content: center;
align-items: center;
z-index: 20;
position: fixed;
left: 0;
top: 0;
height: 100%;
width: 100%;
background-color: rgba(0, 0, 0, .6);
opacity: 0;
transition: opacity 300ms ease-in-out;
padding: 3em;
box-sizing: border-box;
.vn-dialog > .window {
position: relative;
&.shown {
opacity: 1;
& > .close {
@extend %clickable;
text-transform: uppercase;
background-color: transparent;
border: none;
border-radius: .1em;
position: absolute;
top: 0;
right: 0;
padding: .3em;
color: #666;
}
& > div {
position: relative;
box-shadow: 0 0 .4em $color-shadow;
background-color: $color-bg-panel;
border-radius: .2em;
overflow: auto;
padding: 2em;
box-sizing: border-box;
max-height: 100%;
& > form {
padding: $spacing-lg;
tpl-body {
& > .body > tpl-body {
display: block;
min-width: 20em;
min-width: 16em;
}
& > button.close {
@extend %clickable;
text-transform: uppercase;
background-color: transparent;
border: none;
border-radius: .1em;
position: absolute;
top: 0;
right: 0;
padding: .3em;
& > vn-icon {
display: block;
color: #666;
}
}
& > form > .buttons {
& > .buttons > tpl-buttons {
display: block;
margin-top: 1.5em;
text-align: right;
@ -70,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;
}
}
}

View File

@ -1,31 +0,0 @@
<vn-popover
vn-id="popover"
on-open="$ctrl.onOpen()"
on-close="$ctrl.onClose()"
on-close-start="$ctrl.emit('closeStart')">
<div class="vn-drop-down">
<div ng-show="$ctrl.showFilter" class="filter">
<vn-textfield
vn-id="input"
ng-model="$ctrl.search"
class="dense search"
ng-blur="$ctrl.onFocusOut()"
placeholder="{{::'Search' | translate}}">
</vn-textfield>
</div>
<div vn-id="list" class="list" tabindex="-1">
<ul
vn-id="ul"
class="dropdown"
ng-click="$ctrl.onContainerClick($event)">
</ul>
<div
ng-if="$ctrl.statusText"
ng-click="$ctrl.onLoadMoreClick($event)"
class="status"
translate>
{{$ctrl.statusText}}
</div>
</div>
</div>
</vn-popover>

View File

@ -0,0 +1,21 @@
<div ng-show="$ctrl.showFilter" class="filter">
<vn-textfield
ng-model="$ctrl.search"
class="dense search"
ng-blur="$ctrl.onFocusOut()"
placeholder="{{::'Search' | translate}}">
</vn-textfield>
</div>
<div class="list" tabindex="-1">
<ul
class="dropdown"
ng-click="$ctrl.onContainerClick($event)">
</ul>
<div
ng-if="$ctrl.statusText"
ng-click="$ctrl.onLoadMoreClick($event)"
class="status"
translate>
{{$ctrl.statusText}}
</div>
</div>

View File

@ -1,6 +1,7 @@
import './style.scss';
import ngModule from '../../module';
import Component from '../../lib/component';
import Popover from '../popover';
import template from './index.html';
import ArrayModel from '../array-model/array-model';
import CrudModel from '../crud-model/crud-model';
import {mergeWhere} from 'vn-loopback/util/filter';
@ -9,37 +10,17 @@ import {mergeWhere} from 'vn-loopback/util/filter';
* @event select Thrown when model item is selected
* @event change Thrown when model data is ready
*/
export default class DropDown extends Component {
constructor($element, $scope, $transclude, $timeout, $translate, $http, $q, $filter) {
super($element, $scope);
this.$transclude = $transclude;
this.$timeout = $timeout;
this.$translate = $translate;
this.$http = $http;
this.$q = $q;
this.$filter = $filter;
export default class DropDown extends Popover {
constructor($element, $, $transclude) {
super($element, $, $transclude);
this.valueField = 'id';
this.showField = 'name';
this._search = undefined;
this._activeOption = -1;
this.showLoadMore = true;
this.showFilter = true;
this.docKeyDownHandler = e => this.onDocKeyDown(e);
}
$postLink() {
super.$postLink();
this.$.list.addEventListener('scroll', e => this.onScroll(e));
}
get shown() {
return this.$.popover && this.$.popover.shown;
}
set shown(value) {
this.$.popover.shown = value;
this.searchDelay = 300;
this.fillDefaultSlot(template);
}
get search() {
@ -67,7 +48,7 @@ export default class DropDown extends Component {
this.searchTimeout = this.$timeout(() => {
this.refreshModel();
this.searchTimeout = null;
}, 350);
}, value != null ? this.searchDelay : 0);
} else
this.refreshModel();
}
@ -106,16 +87,37 @@ export default class DropDown extends Component {
*/
show(parent, search) {
this._activeOption = -1;
this.$.popover.show(parent || this.parent);
super.show(parent);
this.list = this.popup.querySelector('.list');
this.ul = this.popup.querySelector('ul');
this.docKeyDownHandler = e => this.onDocKeyDown(e);
this.document.addEventListener('keydown', this.docKeyDownHandler);
this.listScrollHandler = e => this.onScroll(e);
this.list.addEventListener('scroll', this.listScrollHandler);
this.list.scrollTop = 0;
this.search = search;
this.buildList();
let input = this.popup.querySelector('input');
setTimeout(() => input.focus());
}
/**
* Hides the drop-down.
*/
hide() {
this.$.popover.hide();
onClose() {
this.document.removeEventListener('keydown', this.docKeyDownHandler);
this.docKeyDownHandler = null;
this.list.removeEventListener('scroll', this.listScrollHandler);
this.listScrollHandler = null;
this.list = null;
this.ul = null;
this.destroyList();
super.onClose();
}
/**
@ -126,7 +128,7 @@ export default class DropDown extends Component {
moveToOption(option) {
this.activateOption(option);
let list = this.$.list;
let list = this.list;
let li = this.activeLi;
if (!li) return;
@ -153,7 +155,7 @@ export default class DropDown extends Component {
let data = this.modelData;
if (option >= 0 && data && option < data.length) {
this.activeLi = this.$.ul.children[option];
this.activeLi = this.ul.children[option];
this.activeLi.className = 'active';
}
}
@ -187,19 +189,7 @@ export default class DropDown extends Component {
}
if (!this.multiple)
this.$.popover.hide();
}
onOpen() {
this.document.addEventListener('keydown', this.docKeyDownHandler);
this.$.list.scrollTop = 0;
setTimeout(() => this.$.input.focus());
this.emit('open');
}
onClose() {
this.document.removeEventListener('keydown', this.docKeyDownHandler);
this.emit('close');
this.hide();
}
onClearClick() {
@ -207,7 +197,7 @@ export default class DropDown extends Component {
}
onScroll() {
let list = this.$.list;
let list = this.list;
let shouldLoad =
list.scrollTop + list.clientHeight >= (list.scrollHeight - 40)
&& !this.model.isLoading;
@ -218,17 +208,13 @@ export default class DropDown extends Component {
onLoadMoreClick(event) {
if (event.defaultPrevented) return;
event.preventDefault();
this.model.loadMore();
}
onContainerClick(event) {
if (event.defaultPrevented) return;
let index = getPosition(this.$.ul, event);
if (index != -1) {
event.preventDefault();
this.selectOption(index);
}
let index = getPosition(this.ul, event);
if (index != -1) this.selectOption(index);
}
onDocKeyDown(event) {
@ -238,23 +224,23 @@ export default class DropDown extends Component {
let option = this.activeOption;
let nOpts = data ? data.length - 1 : 0;
switch (event.keyCode) {
case 9: // Tab
switch (event.key) {
case 'Tab':
this.selectOption(option);
return;
case 13: // Enter
case 'Enter':
this.selectOption(option);
break;
case 38: // Up
case 'ArrowUp':
this.moveToOption(option <= 0 ? nOpts : option - 1);
break;
case 40: // Down
case 'ArrowDown':
this.moveToOption(option >= nOpts ? 0 : option + 1);
break;
case 35: // End
case 'End':
this.moveToOption(nOpts);
break;
case 36: // Start
case 'Home':
this.moveToOption(0);
break;
default:
@ -311,13 +297,14 @@ export default class DropDown extends Component {
}
}
this.$.ul.appendChild(fragment);
this.ul.appendChild(fragment);
this.activateOption(this._activeOption);
this.$.$applyAsync(() => this.$.popover.relocate());
this.$.$applyAsync(() => this.relocate());
}
destroyList() {
this.$.ul.innerHTML = '';
if (this.ul)
this.ul.innerHTML = '';
if (this.scopes) {
for (let scope of this.scopes)
@ -340,10 +327,6 @@ export default class DropDown extends Component {
return fields;
}
$onDestroy() {
this.destroyList();
}
// Model related code
onDataChange() {
@ -432,7 +415,6 @@ export default class DropDown extends Component {
return {[this.showField]: scope.$search};
}
}
DropDown.$inject = ['$element', '$scope', '$transclude', '$timeout', '$translate', '$http', '$q', '$filter'];
/**
* Gets the position of an event element relative to a parent.
@ -459,9 +441,11 @@ function getPosition(parent, event) {
return -1;
}
ngModule.component('vnDropDown', {
template: require('./drop-down.html'),
ngModule.vnComponent('vnDropDown', {
controller: DropDown,
transclude: {
tplItem: '?tplItem'
},
bindings: {
field: '=?',
selection: '=?',
@ -478,9 +462,7 @@ ngModule.component('vnDropDown', {
where: '<?',
order: '@?',
limit: '<?',
searchFunction: '&?'
},
transclude: {
tplItem: '?tplItem'
searchFunction: '&?',
searchDelay: '<?'
}
});

View File

@ -2,9 +2,7 @@ describe('Component vnDropDown', () => {
let $element;
let controller;
beforeEach(angular.mock.module('vnCore', $translateProvider => {
$translateProvider.translations('en', {});
}));
beforeEach(ngModule('vnCore'));
beforeEach(inject(($compile, $rootScope, $document) => {
$element = $compile(`<vn-drop-down></vn-drop-down>`)($rootScope);

View File

@ -1,7 +1,7 @@
@import "effects";
@import "variables";
.vn-drop-down {
.vn-drop-down > .window > .content {
display: flex;
flex-direction: column;
height: inherit;

View File

@ -19,7 +19,7 @@
ng-click="$ctrl.onClear($event)">
</vn-icon>
<vn-icon
ng-if="::$ctrl.info"
ng-if="::$ctrl.info != null"
icon="info_outline"
vn-tooltip="{{::$ctrl.info}}">
</vn-icon>

View File

@ -3,15 +3,13 @@ import FormInput from '../form-input';
import './style.scss';
export default class Field extends FormInput {
constructor($element, $scope, $compile) {
constructor($element, $scope) {
super($element, $scope);
this.$compile = $compile;
this.prefix = null;
this.suffix = null;
this.control = this.element.querySelector('.control');
this.classList.add('vn-field');
this.element.addEventListener('click', e => this.onClick(e));
this.container = this.element.querySelector('.container');
@ -25,9 +23,7 @@ export default class Field extends FormInput {
this.input.addEventListener('focus', () => this.onFocus(true));
this.input.addEventListener('blur', () => this.onFocus(false));
this.input.addEventListener('change', e => {
this.emit('change', {event: e});
});
this.input.addEventListener('change', () => this.onChange());
}
set field(value) {
@ -153,13 +149,8 @@ export default class Field extends FormInput {
fix.innerText = text || '';
}
refreshTabIndex() {
this.input.tabIndex = this.disabled ? -1 : this.tabIndex;
}
onClick() {
// if (event.defaultPrevented) return;
// event.preventDefault();
if (this.input !== document.activeElement)
this.focus();
@ -182,14 +173,6 @@ export default class Field extends FormInput {
this.input.dispatchEvent(new Event('change'));
}
focus() {
this.input.focus();
}
select() {
this.input.select();
}
buildInput(type) {
let template = `<input type="${type}" ng-model="$ctrl.field"></input>`;
this.input = this.$compile(template)(this.$)[0];
@ -207,8 +190,12 @@ export default class Field extends FormInput {
this.inputError = error;
this.refreshHint();
}
onChange() {
this.emit('change', {value: this.field});
}
}
Field.$inject = ['$element', '$scope', '$compile'];
Field.$inject = ['$element', '$scope'];
ngModule.vnComponent('vnField', {
template: require('./index.html'),

View File

@ -35,7 +35,7 @@
& > .fix {
padding-top: 24px;
line-height: 24px;
font-size: $font-size;
font-size: 1rem;
opacity: 0;
transition: opacity 200ms ease-in-out;
@ -58,7 +58,7 @@
border: none;
font-family: Arial, sans-serif;
display: block;
font-size: $font-size;
font-size: 1rem;
width: 100%;
background: 0;
color: inherit;

View File

@ -12,6 +12,7 @@ export default class FormInput extends Component {
constructor($element, $scope) {
super($element, $scope);
this.classList = this.element.classList;
this.classList.add(...this.constructor.$classNames);
}
$onInit() {
@ -49,8 +50,9 @@ export default class FormInput extends Component {
set disabled(value) {
this._disabled = boolTag(value);
this.input.disabled = this._disabled;
this.classList.toggle('disabled', this._disabled);
if (this.input)
this.input.disabled = this._disabled;
this.refreshTabIndex();
}
@ -60,8 +62,9 @@ export default class FormInput extends Component {
set readonly(value) {
this._readonly = boolTag(value);
this.input.readOnly = this._readonly;
this.classList.toggle('readonly', this._readonly);
if (this.input)
this.input.readOnly = this._readonly;
}
get readonly() {
@ -77,16 +80,36 @@ export default class FormInput extends Component {
return this._tabIndex;
}
get inputEl() {
return this.input || this.element;
}
get editable() {
return !(this.readonly || this.disabled);
}
select() {
this.input.select();
if (this.inputEl.select)
this.inputEl.select();
}
focus() {
this.input.focus();
this.inputEl.focus();
}
initTabIndex() {
if (!this.element.hasAttribute('tabindex'))
this.element.tabIndex = 0;
}
refreshTabIndex() {
this.element.tabIndex = this.disabled ? -1 : this.tabIndex;
this.inputEl.tabIndex = this.disabled ? -1 : this.tabIndex;
}
change(value) {
this.field = value;
this.element.dispatchEvent(new Event('change'));
this.emit('change', {value: this.field});
}
}

View File

@ -1,6 +1,6 @@
@import "effects";
vn-icon-button {
.vn-icon-button {
@extend %clickable-light;
color: $color-main;

View File

@ -2,8 +2,8 @@ import ngModule from '../../module';
import ButtonMenu from '../button-menu';
export default class IconMenu extends ButtonMenu {
constructor($element, $scope) {
super($element, $scope);
constructor($element, $scope, $transclude) {
super($element, $scope, $transclude);
this.element.classList.add('flat');
}
}

View File

@ -3,20 +3,16 @@ import './crud-model/crud-model';
import './watcher/watcher';
import './textfield/textfield';
import './icon/icon';
import './dialog/dialog';
import './confirm/confirm';
import './title/title';
import './subtitle/subtitle';
import './spinner/spinner';
import './snackbar/snackbar';
import './tooltip/tooltip';
import './popover/popover';
import './drop-down/drop-down';
import './menu/menu';
import './multi-check/multi-check';
import './card/card';
import './step-control/step-control';
import './label-value/label-value';
import './pagination/pagination';
import './searchbar/searchbar';
import './scroll-up/scroll-up';
@ -28,15 +24,22 @@ import './check';
import './chip';
import './data-viewer';
import './date-picker';
import './drop-down';
import './debug-info';
import './dialog';
import './field';
import './float-button';
import './icon-menu';
import './icon-button';
import './input-number';
import './label-value';
import './range';
import './input-time';
import './input-file';
import './label';
import './list';
import './popover';
import './popup';
import './radio';
import './submit';
import './table';
@ -44,3 +47,4 @@ import './td-editable';
import './textarea';
import './th';
import './treeview';
import './wday-picker';

View File

@ -9,13 +9,12 @@
<section
class="value"
ng-click="$ctrl.openFileSelector()"
translate>
{{$ctrl.value}}
tabindex="0">
</section>
<input
type="file"
ng-model="$ctrl.files"
accept="{{$ctrl.accept}}">
accept="{{$ctrl.accept}}"
style="display: none;">
</input>
</div>
<div class="fix suffix"></div>
@ -36,7 +35,7 @@
ng-click="$ctrl.openFileSelector()">
</vn-icon>
<vn-icon
ng-if="::$ctrl.info"
ng-if="::$ctrl.info != null"
icon="info_outline"
vn-tooltip="{{::$ctrl.info}}">
</vn-icon>

View File

@ -1,107 +1,82 @@
import ngModule from '../../module';
import FormInput from '../form-input';
import Field from '../field';
import './style.scss';
export default class InputFile extends FormInput {
constructor($element, $scope) {
super($element, $scope);
/**
* Input file selector.
*
* @property {String} accept List of valid file types
*/
export default class InputFile extends Field {
constructor($element, $) {
super($element, $);
this._multiple = false;
this._value = 'Select a file';
this.input = this.element.querySelector('input');
this.registerEvents();
}
/**
/*
* Registers all event emitters
*/
registerEvents() {
this.input.addEventListener('change', event => {
const target = event.target;
const fileNames = Array.from(target.files).map(file => {
return file.name;
});
const names = fileNames.join(', ');
const label = this.element.querySelector('.value');
label.innerHTML = names;
this.files = target.files;
this.input.addEventListener('change', () => {
const files = this.input.files;
const fileList = Array
.from(files)
.map(file => file.name)
.join(', ');
this.emit('change', {files: target.files, event});
const label = this.element.querySelector('.value');
label.innerHTML = fileList;
this.field = files.length ? files : null;
});
}
get value() {
return this._value;
get field() {
return super.field;
}
set value(value) {
this._value = value;
set field(value) {
if (!value) this.input.value = '';
super.field = value;
}
/**
* Gets current value
* @property {FileList} files Selected files list
*/
get files() {
return this._files;
return this.input.files;
}
/**
* Sets input value
*
* @param {Number} value - Value
*/
set files(value) {
this._files = value;
this.hasValue = !(value === null || value === undefined || value === '');
if (this.hasValue)
this.element.classList.add('not-empty');
else
this.element.classList.remove('not-empty');
this.input.files = value;
}
/**
* Gets if multiple file selection
* @property {Boolean} multiple Whether to allow multiple file selection
*/
get multiple() {
return this._multiple;
return this.input.multiple;
}
/**
* Sets multiple file selection
*
* @param {Boolean} value - True if is multiple
*/
set multiple(value) {
this._multiple = value;
if (value)
this.input.multiple = true;
else
this.input.multiple = false;
this.input.multiple = value;
}
/**
* Returns a list of valid file types
*/
get accept() {
return this._accept;
}
/**
* Sets a list of valid file types
*
* @param {String} value - Valid file types
*/
set accept(value) {
this._accept = value;
}
/**
/*
* Fires file selection explorer event
*/
openFileSelector() {
this.input.click();
}
onChange() {
this.emit('change', {
value: this.field,
$files: this.files
});
}
}
ngModule.vnComponent('vnInputFile', {
@ -110,6 +85,6 @@ ngModule.vnComponent('vnInputFile', {
bindings: {
multiple: '<?',
accept: '@?',
files: '=model'
files: '=?'
}
});

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