Merge
This commit is contained in:
commit
e147f318cb
|
@ -9,7 +9,7 @@ Salix is also the scientific name of a beautifull tree! :)
|
|||
Required applications.
|
||||
|
||||
* Visual Studio Code
|
||||
* Node.js = 8.15.0
|
||||
* Node.js = 10.15.3 LTS
|
||||
* Docker
|
||||
|
||||
In Visual Studio Code we use the ESLint extension. Open Visual Studio Code, press Ctrl+P and paste the following command.
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
[client]
|
||||
enable_cleartext_plugin = ON
|
||||
host = localhost
|
||||
port = 3306
|
||||
user = root
|
||||
password = password
|
||||
ssl-mode = DISABLED
|
||||
enable_cleartext_plugin = ON
|
|
@ -60,6 +60,7 @@ echo "[INFO] Config file: $INI_FILE"
|
|||
echo "[INFO] Applying changes"
|
||||
|
||||
# Import changes
|
||||
|
||||
for file in $DIR/install/changes/*.sql; do
|
||||
echo "[INFO] -> $file"
|
||||
mysql --defaults-file="$INI_FILE" < $file
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
export MYSQL_PWD=root
|
||||
|
||||
# Dump structure
|
||||
echo "[INFO] -> Imported ./dump/truncateAll.sql"
|
||||
mysql -u root -f < ./dump/truncateAll.sql
|
||||
echo "[INFO] -> Imported ./dump/structure.sql"
|
||||
mysql -u root -f < ./dump/structure.sql
|
||||
echo "[INFO] -> Imported ./dump/mysqlPlugins.sql"
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
INSERT INTO `salix`.`ACL` (`id`,`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) VALUES (149, 'Sip', '*', 'WRITE', 'ALLOW', 'ROLE', 'hr');
|
||||
INSERT INTO `salix`.`ACL` (`id`,`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) VALUES (150, 'Sip', '*', 'READ', 'ALLOW', 'ROLE', 'employee');
|
||||
INSERT INTO `salix`.`ACL` (`id`,`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) VALUES (151, 'Department','*','READ','ALLOW','ROLE','employee');
|
||||
INSERT INTO `salix`.`ACL` (`id`,`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) VALUES (152, 'Department','*','WRITE','ALLOW','ROLE','hr');
|
|
@ -1,10 +1,7 @@
|
|||
USE `hedera`;
|
||||
DROP procedure IF EXISTS `orderGetTotal`;
|
||||
|
||||
DROP procedure IF EXISTS `hedera`.`orderGetTotal`;
|
||||
DELIMITER $$
|
||||
USE `hedera`$$
|
||||
|
||||
CREATE DEFINER=`root`@`%` PROCEDURE `orderGetTotal`()
|
||||
CREATE DEFINER=`root`@`%` PROCEDURE `hedera`.`orderGetTotal`()
|
||||
BEGIN
|
||||
/**
|
||||
* Calcula el total con IVA para un conjunto de orders.
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
USE `vn`;
|
||||
DROP procedure IF EXISTS `ticketCalculateSale`;
|
||||
|
||||
DELIMITER $$
|
||||
USE `vn`$$
|
||||
CREATE DEFINER=`root`@`%` PROCEDURE `ticketCalculateSale`(IN vSale BIGINT)
|
||||
proc: BEGIN
|
||||
|
||||
/*
|
||||
Este procedimiento bioniza una linea de movimiento
|
||||
*/
|
||||
DECLARE vShipped DATE;
|
||||
DECLARE vWarehouse SMALLINT;
|
||||
DECLARE vAgencyMode INT;
|
||||
DECLARE vAddress INT;
|
||||
DECLARE vTicket BIGINT;
|
||||
DECLARE vItem BIGINT;
|
||||
DECLARE vLanded DATE;
|
||||
DECLARE vTicketFree BOOLEAN DEFAULT TRUE;
|
||||
|
||||
SELECT FALSE
|
||||
INTO vTicketFree
|
||||
FROM vn.ticket t
|
||||
JOIN vn.sale s ON s.ticketFk = t.id
|
||||
LEFT JOIN vn.ticketState ts ON ts.ticketFk = t.id
|
||||
WHERE s.id = vSale
|
||||
AND (t.refFk != "" OR (ts.alertLevel > 0 AND s.price != 0))
|
||||
LIMIT 1;
|
||||
|
||||
SELECT ticketFk, itemFk
|
||||
INTO vTicket, vItem
|
||||
FROM sale
|
||||
WHERE id = vSale;
|
||||
|
||||
SELECT t.warehouseFk, DATE(t.shipped), t.addressFk, t.agencyModeFk, t.landed
|
||||
INTO vWarehouse, vShipped, vAddress, vAgencyMode, vLanded
|
||||
FROM agencyMode a
|
||||
JOIN ticket t ON t.agencyModeFk = a.id
|
||||
WHERE t.id = vTicket;
|
||||
|
||||
DROP TEMPORARY TABLE IF EXISTS tmp.agencyHourGetShipped;
|
||||
CREATE TEMPORARY TABLE tmp.agencyHourGetShipped ENGINE = MEMORY
|
||||
SELECT vWarehouse warehouseFk, vShipped shipped, vLanded landed;
|
||||
|
||||
CALL buyUltimate (vWarehouse, vShipped); -- rellena la tabla tmp.buyUltimate con la ultima compra
|
||||
|
||||
DELETE FROM tmp.buyUltimate WHERE itemFk != vItem;
|
||||
|
||||
DROP TEMPORARY TABLE IF EXISTS tmp.ticketLot;
|
||||
CREATE TEMPORARY TABLE tmp.ticketLot
|
||||
SELECT vWarehouse warehouseFk, NULL available, vItem itemFk, buyFk
|
||||
FROM tmp.buyUltimate
|
||||
WHERE itemFk = vItem;
|
||||
|
||||
CALL ticketComponentCalculate(vAddress, vAgencyMode);
|
||||
|
||||
DROP TEMPORARY TABLE IF EXISTS tmp.sale;
|
||||
CREATE TEMPORARY TABLE tmp.sale
|
||||
(PRIMARY KEY (saleFk)) ENGINE = MEMORY
|
||||
SELECT vSale saleFk,vWarehouse warehouseFk;
|
||||
|
||||
CALL ticketComponentUpdateSale(IF(vTicketFree,1,6)); -- si el ticket esta facturado, respeta los precios
|
||||
|
||||
-- Log
|
||||
INSERT INTO vn.ticketLog (originFk, userFk, `action`, description)
|
||||
VALUES (vTicket, account.userGetId(), 'update', CONCAT('Bionizo linea id ', vSale));
|
||||
|
||||
-- Limpieza
|
||||
DROP TEMPORARY TABLE tmp.buyUltimate;
|
||||
END$$
|
||||
|
||||
DELIMITER ;
|
|
@ -0,0 +1,23 @@
|
|||
/* Ejecutar en prod * /
|
||||
|
||||
/* USE `vn2008`;
|
||||
|
||||
ALTER TABLE vn2008.department ADD `depth` int DEFAULT 0 NOT NULL;
|
||||
ALTER TABLE vn2008.department ADD sons int DEFAULT 0 NOT NULL;
|
||||
|
||||
USE `vn`;
|
||||
|
||||
CREATE
|
||||
OR REPLACE
|
||||
VIEW `vn`.`department` AS select
|
||||
`b`.`department_id` AS `id`,
|
||||
`b`.`name` AS `name`,
|
||||
`b`.`father_id` AS `fatherFk`,
|
||||
`b`.`production` AS `isProduction`,
|
||||
`b`.`lft` AS `lft`,
|
||||
`b`.`rgt` AS `rgt`,
|
||||
`b`.`isSelected` AS `isSelected`,
|
||||
`b`.`depth` AS `depth`,
|
||||
`b`.`sons` AS `sons`
|
||||
from
|
||||
`vn2008`.`department` `b`; */
|
|
@ -0,0 +1,165 @@
|
|||
USE `vn`;
|
||||
DROP procedure IF EXISTS `ticketGetProblems`;
|
||||
|
||||
DELIMITER $$
|
||||
USE `vn`$$
|
||||
CREATE DEFINER=`root`@`%` PROCEDURE `ticketGetProblems`()
|
||||
BEGIN
|
||||
/**
|
||||
* Obtiene los problemas de uno o varios tickets
|
||||
*
|
||||
* @table tmp.ticketGetProblems(ticketFk, clientFk, warehouseFk, shipped)
|
||||
* @return tmp.ticketProblems
|
||||
*/
|
||||
DECLARE vWarehouse INT;
|
||||
DECLARE vDate DATE;
|
||||
DECLARE vAvailableCache INT;
|
||||
DECLARE vVisibleCache INT;
|
||||
DECLARE vDone INT DEFAULT 0;
|
||||
|
||||
DECLARE vCursor CURSOR FOR
|
||||
SELECT DISTINCT tt.warehouseFk, date(tt.shipped)
|
||||
FROM tmp.ticketGetProblems tt
|
||||
WHERE DATE(tt.shipped) BETWEEN CURDATE()
|
||||
AND TIMESTAMPADD(DAY, 1.9, CURDATE());
|
||||
|
||||
DECLARE CONTINUE HANDLER FOR NOT FOUND SET vDone = 1;
|
||||
|
||||
DROP TEMPORARY TABLE IF EXISTS tmp.ticketProblems;
|
||||
CREATE TEMPORARY TABLE tmp.ticketProblems (
|
||||
ticketFk INT(11) PRIMARY KEY,
|
||||
isFreezed INTEGER(1) DEFAULT 0,
|
||||
risk DECIMAL(10,2) DEFAULT 0,
|
||||
hasTicketRequest INTEGER(1) DEFAULT 0,
|
||||
isAvailable INTEGER(1) DEFAULT 1
|
||||
) ENGINE = MEMORY;
|
||||
|
||||
DROP TEMPORARY TABLE IF EXISTS tmp.ticketList;
|
||||
CREATE TEMPORARY TABLE tmp.ticketList
|
||||
(PRIMARY KEY (ticketFk))
|
||||
ENGINE = MEMORY
|
||||
SELECT tp.ticketFk, c.id clientFk
|
||||
FROM tmp.ticketGetProblems tp
|
||||
JOIN vn.client c ON c.id = tp.clientFk;
|
||||
|
||||
-- Inserta tickets de clientes congelados
|
||||
INSERT INTO tmp.ticketProblems(ticketFk, isFreezed)
|
||||
SELECT DISTINCT tl.ticketFk, 1
|
||||
FROM tmp.ticketList tl
|
||||
JOIN vn.client c ON c.id = tl.clientFk
|
||||
WHERE c.isFreezed;
|
||||
|
||||
DELETE tl FROM tmp.ticketList tl
|
||||
JOIN tmp.ticketProblems tp ON tl.ticketFk = tp.ticketFk;
|
||||
|
||||
DROP TEMPORARY TABLE IF EXISTS tmp.clientGetDebt;
|
||||
CREATE TEMPORARY TABLE tmp.clientGetDebt
|
||||
(PRIMARY KEY (clientFk))
|
||||
ENGINE = MEMORY
|
||||
SELECT DISTINCT clientFk
|
||||
FROM tmp.ticketList;
|
||||
|
||||
CALL clientGetDebt(CURDATE());
|
||||
|
||||
-- Inserta tickets de clientes con riesgo
|
||||
INSERT INTO tmp.ticketProblems(ticketFk, risk)
|
||||
SELECT DISTINCT tl.ticketFk, r.risk
|
||||
FROM tmp.ticketList tl
|
||||
JOIN vn.ticket t ON t.id = tl.ticketFk
|
||||
JOIN vn.agencyMode a ON t.agencyModeFk = a.id
|
||||
JOIN tmp.risk r ON r.clientFk = t.clientFk
|
||||
JOIN vn.client c ON c.id = t.clientFk
|
||||
WHERE r.risk > c.credit + 10
|
||||
AND a.deliveryMethodFk != 3
|
||||
ON DUPLICATE KEY UPDATE
|
||||
risk = r.risk;
|
||||
|
||||
DELETE tl FROM tmp.ticketList tl
|
||||
JOIN tmp.ticketProblems tp ON tl.ticketFk = tp.ticketFk;
|
||||
|
||||
-- Inserta tickets que tengan codigos 100
|
||||
INSERT INTO tmp.ticketProblems(ticketFk, hasTicketRequest)
|
||||
SELECT DISTINCT tl.ticketFk, 1
|
||||
FROM tmp.ticketList tl
|
||||
JOIN vn.ticketRequest tr ON tr.ticketFk = tl.ticketFk
|
||||
WHERE tr.isOK IS NULL
|
||||
ON DUPLICATE KEY UPDATE
|
||||
hasTicketRequest = 1;
|
||||
|
||||
DELETE tl FROM tmp.ticketList tl
|
||||
JOIN tmp.ticketProblems tp ON tl.ticketFk = tp.ticketFk;
|
||||
|
||||
OPEN vCursor;
|
||||
|
||||
WHILE NOT vDone
|
||||
DO
|
||||
FETCH vCursor INTO vWarehouse, vDate;
|
||||
|
||||
CALL cache.visible_refresh(vVisibleCache, FALSE, vWarehouse);
|
||||
CALL cache.available_refresh(vAvailableCache, FALSE, vWarehouse, vDate);
|
||||
|
||||
-- Inserta tickets con articulos que no tegan disponible
|
||||
INSERT INTO tmp.ticketProblems(ticketFk, isAvailable)
|
||||
SELECT tl.ticketFk, 0
|
||||
FROM tmp.ticketList tl
|
||||
JOIN vn.ticket t ON t.id = tl.ticketFk
|
||||
LEFT JOIN vn.sale s ON s.ticketFk = t.id
|
||||
JOIN vn.item i ON i.id = s.itemFk
|
||||
JOIN vn.itemType it on it.id = i.typeFk
|
||||
LEFT JOIN cache.visible v ON i.id = v.item_id
|
||||
AND v.calc_id = vVisibleCache
|
||||
LEFT JOIN cache.available av ON av.item_id = i.id
|
||||
AND av.calc_id = vAvailableCache
|
||||
WHERE date(t.shipped) = vDate
|
||||
AND categoryFk != 6
|
||||
AND s.quantity > IFNULL(v.visible, 0)
|
||||
AND IFNULL(av.available, 0) < 0
|
||||
AND s.isPicked = FALSE
|
||||
AND NOT i.generic
|
||||
AND vWarehouse = t.warehouseFk
|
||||
GROUP BY tl.ticketFk
|
||||
ON DUPLICATE KEY UPDATE
|
||||
isAvailable = 0;
|
||||
|
||||
|
||||
DELETE tl FROM tmp.ticketList tl
|
||||
JOIN tmp.ticketProblems tp ON tl.ticketFk = tp.ticketFk;
|
||||
|
||||
|
||||
INSERT INTO tmp.ticketProblems(ticketFk, isAvailable)
|
||||
SELECT tl.ticketFk, 0
|
||||
FROM tmp.ticketList tl
|
||||
JOIN vn.ticket t ON t.id = tl.ticketFk
|
||||
LEFT JOIN vn.sale s ON s.ticketFk = t.id
|
||||
JOIN vn.item i ON i.id = s.itemFk
|
||||
JOIN vn.itemType it on it.id = i.typeFk
|
||||
LEFT JOIN cache.visible v ON i.id = v.item_id AND v.calc_id = vVisibleCache
|
||||
LEFT JOIN cache.available av ON av.item_id = i.id AND av.calc_id = vAvailableCache
|
||||
WHERE IFNULL(av.available, 0) >= 0
|
||||
AND s.quantity > IFNULL(v.visible, 0)
|
||||
AND s.isPicked = FALSE
|
||||
AND s.reserved = FALSE
|
||||
AND it.categoryFk != 6
|
||||
AND date(t.shipped) = vDate
|
||||
AND NOT i.generic
|
||||
AND CURDATE() = vDate
|
||||
AND t.warehouseFk = vWarehouse
|
||||
GROUP BY tl.ticketFk
|
||||
ON DUPLICATE KEY UPDATE
|
||||
isAvailable = 0;
|
||||
|
||||
DELETE tl FROM tmp.ticketList tl
|
||||
JOIN tmp.ticketProblems tp ON tl.ticketFk = tp.ticketFk;
|
||||
|
||||
END WHILE;
|
||||
|
||||
CLOSE vCursor;
|
||||
|
||||
SELECT * FROM tmp.ticketProblems;
|
||||
|
||||
DROP TEMPORARY TABLE
|
||||
tmp.clientGetDebt,
|
||||
tmp.ticketList;
|
||||
END$$
|
||||
|
||||
DELIMITER ;
|
|
@ -0,0 +1,86 @@
|
|||
/* Ejecutar en prod * /
|
||||
|
||||
/* DROP PROCEDURE IF EXISTS nst.NodeAdd;
|
||||
|
||||
DELIMITER $$
|
||||
$$
|
||||
CREATE DEFINER=`root`@`%` PROCEDURE `nst`.`nodeAdd`(IN `vScheme` VARCHAR(45), IN `vTable` VARCHAR(45), IN `vParentFk` INT, IN `vChild` VARCHAR(100))
|
||||
BEGIN
|
||||
DECLARE vSql TEXT;
|
||||
DECLARE vTableClone VARCHAR(45);
|
||||
|
||||
SET vTableClone = CONCAT(vTable, 'Clone');
|
||||
|
||||
CALL util.exec(CONCAT('DROP TEMPORARY TABLE IF EXISTS tmp.', vTableClone));
|
||||
CALL util.exec(CONCAT(
|
||||
'CREATE TEMPORARY TABLE tmp.', vTableClone,
|
||||
' ENGINE = MEMORY'
|
||||
' SELECT * FROM ', vScheme, '.', vTable
|
||||
));
|
||||
|
||||
-- Check parent childs
|
||||
SET vSql = sql_printf('
|
||||
SELECT COUNT(c.id) INTO @childs
|
||||
FROM %t.%t p
|
||||
LEFT JOIN %t.%t c ON c.lft BETWEEN p.lft AND p.rgt AND c.id != %v
|
||||
WHERE p.id = %v',
|
||||
vScheme, vTable, 'tmp', vTableClone, vParentFk, vParentFk);
|
||||
SET @qrySql := vSql;
|
||||
|
||||
PREPARE stmt FROM @qrySql;
|
||||
EXECUTE stmt;
|
||||
DEALLOCATE PREPARE stmt;
|
||||
|
||||
-- Select left from last child
|
||||
IF @childs = 0 THEN
|
||||
SET vSql = sql_printf('SELECT lft INTO @vLeft FROM %t.%t WHERE id = %v', vScheme, vTable, vParentFk);
|
||||
SET @qrySql := vSql;
|
||||
ELSE
|
||||
SET vSql = sql_printf('
|
||||
SELECT c.rgt INTO @vLeft
|
||||
FROM %t.%t p
|
||||
JOIN %t.%t c ON c.lft BETWEEN p.lft AND p.rgt
|
||||
WHERE p.id = %v
|
||||
ORDER BY c.lft
|
||||
DESC LIMIT 1',
|
||||
vScheme, vTable, 'tmp', vTableClone, vParentFk);
|
||||
SET @qrySql := vSql;
|
||||
END IF;
|
||||
|
||||
PREPARE stmt FROM @qrySql;
|
||||
EXECUTE stmt;
|
||||
DEALLOCATE PREPARE stmt;
|
||||
|
||||
-- Update right
|
||||
SET vSql = sql_printf('UPDATE %t.%t SET rgt = rgt + 2 WHERE rgt > %v ORDER BY rgt DESC', vScheme, vTable, @vLeft);
|
||||
SET @qrySql := vSql;
|
||||
|
||||
PREPARE stmt FROM @qrySql;
|
||||
EXECUTE stmt;
|
||||
DEALLOCATE PREPARE stmt;
|
||||
|
||||
SET vSql = sql_printf('UPDATE %t.%t SET lft = lft + 2 WHERE lft > %v ORDER BY lft DESC', vScheme, vTable, @vLeft);
|
||||
SET @qrySql := vSql;
|
||||
|
||||
PREPARE stmt FROM @qrySql;
|
||||
EXECUTE stmt;
|
||||
DEALLOCATE PREPARE stmt;
|
||||
|
||||
-- Escape character
|
||||
SET vChild = REPLACE(vChild, "'", "\\'");
|
||||
|
||||
-- Add child
|
||||
SET vSql = sql_printf('INSERT INTO %t.%t (name, lft, rgt) VALUES (%v, %v, %v)', vScheme, vTable, vChild, @vLeft + 1, @vLeft + 2);
|
||||
SET @qrySql := vSql;
|
||||
|
||||
PREPARE stmt FROM @qrySql;
|
||||
EXECUTE stmt;
|
||||
DEALLOCATE PREPARE stmt;
|
||||
|
||||
SELECT id, name, lft, rgt, depth, sons FROM vn.department
|
||||
WHERE id = LAST_INSERT_ID();
|
||||
|
||||
CALL util.exec(CONCAT('DROP TEMPORARY TABLE tmp.', vTableClone));
|
||||
END$$
|
||||
DELIMITER ;
|
||||
*/
|
|
@ -0,0 +1,21 @@
|
|||
DROP procedure IF EXISTS `hedera`.`basketGetTax`;
|
||||
DELIMITER $$
|
||||
CREATE DEFINER=`root`@`%` PROCEDURE `hedera`.`basketGetTax`()
|
||||
READS SQL DATA
|
||||
BEGIN
|
||||
/**
|
||||
* Returns the taxes for the current client basket.
|
||||
*
|
||||
* @treturn tmp.orderTax
|
||||
*/
|
||||
DROP TEMPORARY TABLE IF EXISTS tmp.order;
|
||||
CREATE TEMPORARY TABLE tmp.order
|
||||
ENGINE = MEMORY
|
||||
SELECT myBasketGetId() orderFk;
|
||||
|
||||
CALL orderGetTax();
|
||||
|
||||
DROP TEMPORARY TABLE IF EXISTS tmp.order;
|
||||
END$$
|
||||
|
||||
DELIMITER ;
|
|
@ -0,0 +1,31 @@
|
|||
/* Ejecutar en prod * /
|
||||
|
||||
/* DROP PROCEDURE IF EXISTS nst.nodeRecalc;
|
||||
|
||||
DELIMITER $$
|
||||
$$
|
||||
CREATE DEFINER=`root`@`%` PROCEDURE `nst`.`nodeRecalc`(IN `vScheme` VARCHAR(45), IN `vTable` VARCHAR(45))
|
||||
BEGIN
|
||||
CALL util.exec (sql_printf (
|
||||
'UPDATE %t.%t d
|
||||
JOIN (SELECT
|
||||
node.id,
|
||||
COUNT(parent.id) - 1 as depth,
|
||||
cast((node.rgt - node.lft - 1) / 2 as DECIMAL) as sons
|
||||
FROM
|
||||
%t.%t AS node,
|
||||
%t.%t AS parent
|
||||
WHERE node.lft BETWEEN parent.lft AND parent.rgt
|
||||
GROUP BY node.id
|
||||
ORDER BY node.lft) n ON n.id = d.id
|
||||
SET d.`depth` = n.depth, d.sons = n.sons',
|
||||
vScheme,
|
||||
vTable,
|
||||
vScheme,
|
||||
vTable,
|
||||
vScheme,
|
||||
vTable
|
||||
));
|
||||
END$$
|
||||
DELIMITER ;
|
||||
*/
|
|
@ -0,0 +1 @@
|
|||
ALTER TABLE vn.itemLog MODIFY COLUMN userFk int(10) unsigned NULL;
|
|
@ -0,0 +1,4 @@
|
|||
USE `vn`;
|
||||
|
||||
CREATE UNIQUE INDEX zoneGeo_lft_IDX USING BTREE ON vn.zoneGeo (lft);
|
||||
CREATE UNIQUE INDEX zoneGeo_rgt_IDX USING BTREE ON vn.zoneGeo (rgt);
|
|
@ -0,0 +1,16 @@
|
|||
ALTER TABLE `vn`.`itemLog`
|
||||
CHANGE COLUMN `id` `id` INT(11) NOT NULL AUTO_INCREMENT ,
|
||||
ADD PRIMARY KEY (`id`);
|
||||
|
||||
|
||||
ALTER TABLE `vn`.`itemLog`
|
||||
DROP FOREIGN KEY `itemLogUserFk`;
|
||||
ALTER TABLE `vn`.`itemLog`
|
||||
CHANGE COLUMN `id` `id` INT(11) NOT NULL AUTO_INCREMENT ,
|
||||
CHANGE COLUMN `userFk` `userFk` INT(10) UNSIGNED NULL DEFAULT NULL ;
|
||||
ALTER TABLE `vn`.`itemLog`
|
||||
ADD CONSTRAINT `itemLogUserFk`
|
||||
FOREIGN KEY (`userFk`)
|
||||
REFERENCES `account`.`user` (`id`)
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE CASCADE;
|
|
@ -1,3 +1,3 @@
|
|||
/* Añadir a producción cuando se suba salix */
|
||||
|
||||
DROP TRIGGER vn2008.ClientesAfterInsert;
|
||||
DROP TRIGGER IF EXISTS vn2008.ClientesAfterInsert;
|
||||
|
|
|
@ -12,7 +12,8 @@ BEGIN
|
|||
UPDATE Consignatarios SET predeterminada = FALSE
|
||||
WHERE Id_cliente = NEW.Id_cliente;
|
||||
|
||||
|
||||
UPDATE Consignatarios SET predeterminada = TRUE
|
||||
WHERE Id_consigna = NEW.default_address;
|
||||
END IF;
|
||||
END$$
|
||||
DELIMITER ;
|
||||
|
|
|
@ -191,18 +191,23 @@ INSERT INTO `vn`.`contactChannel`(`id`, `name`)
|
|||
|
||||
INSERT INTO `vn`.`client`(`id`,`name`,`fi`,`socialName`,`contact`,`street`,`city`,`postcode`,`phone`,`mobile`,`fax`,`isRelevant`,`email`,`iban`,`dueDay`,`accountingAccount`,`isEqualizated`,`provinceFk`,`hasToInvoice`,`credit`,`countryFk`,`isActive`,`gestdocFk`,`quality`,`payMethodFk`,`created`,`isToBeMailed`,`contactChannelFk`,`hasSepaVnl`,`hasCoreVnl`,`hasCoreVnh`,`riskCalculated`,`clientTypeFk`,`mailAddress`,`cplusTerIdNifFk`,`hasToInvoiceByAddress`,`isTaxDataChecked`,`isFreezed`,`creditInsurance`,`isCreatedAsServed`,`hasInvoiceSimplified`,`salesPersonFk`,`isVies`,`eypbc`)
|
||||
VALUES
|
||||
(101, 'Bruce Wayne', '84612325V', 'Batman', 'Alfred', '1007 Mountain Drive, Gotham', 'Silla', 46460, 1111111111, 222222222, 333333333, 1, 'BruceWayne@verdnatura.es', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1,NULL, 10, 5,CURDATE(), 1, 5, 1, 1, 1,'0000-00-00', 1, NULL, 1, 1, 1, 1, NULL, 0, 0, 18, 0, 1),
|
||||
(102, 'Petter Parker', '87945234L', 'Spider-Man', 'Aunt May', '20 Ingram Street', 'Silla', 46460, 1111111111, 222222222, 333333333, 1, 'PetterParker@verdnatura.es', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1,NULL, 10, 5,CURDATE(), 1, 5, 1, 1, 1,'0000-00-00', 1, NULL, 1, 1, 0, 1, NULL, 0, 0, 18, 0, 1),
|
||||
(103, 'Clark Kent', '06815934E', 'Super-Man', 'lois lane', '344 Clinton Street', 'Silla', 46460, 1111111111, 222222222, 333333333, 1, 'ClarkKent@verdnatura.es', NULL, 0, 1234567890, 0, 1, 1, 0, 1, 1,NULL, 10, 5,CURDATE(), 1, 5, 1, 1, 1,'0000-00-00', 1, NULL, 1, 1, 1, 0, NULL, 0, 0, 18, 0, 1),
|
||||
(104, 'Tony Stark', '06089160W', 'Iron-Man', 'Pepper Potts', '10880 Malibu Point', 'Silla', 46460, 1111111111, 222222222, 333333333, 1, 'TonyStark@verdnatura.es', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1,NULL, 10, 5,CURDATE(), 1, 5, 1, 1, 1,'0000-00-00', 1, NULL, 1, 1, 1, 0, NULL, 0, 0, 18, 0, 1),
|
||||
(105, 'Max Eisenhardt', '39182496H', 'Magneto', 'Rogue', 'Unknown Whereabouts', 'Silla', 46460, 1111111111, 222222222, 333333333, 1, 'MaxEisenhardt@verdnatura.es', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1,NULL, 10, 5,CURDATE(), 1, 5, 1, 1, 1,'0000-00-00', 1, NULL, 1, 1, 1, 0, NULL, 0, 0, NULL, 0, 1),
|
||||
(106, 'DavidCharlesHaller', '53136686Q', 'Legion', 'Charles Xavier', 'Evil hideout', 'Silla', 46460, 1111111111, 222222222, 333333333, 1, 'DavidCharlesHaller@verdnatura.es', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 0,NULL, 10, 5,CURDATE(), 1, 5, 1, 1, 1,'0000-00-00', 1, NULL, 1, 1, 1, 0, NULL, 0, 0, 19, 0, 1),
|
||||
(107, 'Hank Pym', '09854837G', 'Ant-Man', 'Hawk', 'Anthill', 'Silla', 46460, 1111111111, 222222222, 333333333, 1, 'HankPym@verdnatura.es', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1,NULL, 10, 5,CURDATE(), 1, 5, 1, 1, 1,'0000-00-00', 1, NULL, 1, 1, 0, 0, NULL, 0, 0, 19, 0, 1),
|
||||
(108, 'Charles Xavier', '22641921P', 'Professor X', 'Beast', '3800 Victory Pkwy, Cincinnati, OH 45207, USA', 'Silla', 46460, 1111111111, 222222222, 333333333, 1, 'CharlesXavier@verdnatura.es', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1,NULL, 10, 5,CURDATE(), 1, 5, 1, 1, 1,'0000-00-00', 1, NULL, 1, 1, 1, 1, NULL, 0, 0, 19, 0, 1),
|
||||
(109, 'Bruce Banner', '16104829E', 'Hulk', 'Black widow', 'Somewhere in New York', 'Silla', 46460, 1111111111, 222222222, 333333333, 1, 'BruceBanner@verdnatura.es', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1,NULL, 10, 5,CURDATE(), 1, 5, 1, 1, 1,'0000-00-00', 1, NULL, 1, 1, 0, 1, NULL, 0, 0, 19, 0, 1),
|
||||
(110, 'Jessica Jones', '58282869H', 'Jessica Jones', 'Luke Cage', 'NYCC 2015 Poster', 'Silla', 46460, 1111111111, 222222222, 333333333, 1, 'JessicaJones@verdnatura.es', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1,NULL, 10, 5,CURDATE(), 1, 5, 1, 1, 1,'0000-00-00', 1, NULL, 1, 1, 0, 1, NULL, 0, 0, NULL, 0, 1),
|
||||
(200, 'Missing', NULL, 'Missing man', 'Anton', 'The space', 'Silla', 46460, 1111111111, 222222222, 333333333, 1, NULL, NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1,NULL, 10, 5,CURDATE(), 1, 5, 1, 1, 1,'0000-00-00', 4, NULL, 1, 0, 1, 0, NULL, 1, 0, NULL, 0, 1),
|
||||
(400, 'Trash', NULL, 'Garbage man', 'Unknown name', 'New York city', 'Silla', 46460, 1111111111, 222222222, 333333333, 1, NULL, NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1,NULL, 10, 5,CURDATE(), 1, 5, 1, 1, 1,'0000-00-00', 4, NULL, 1, 0, 1, 0, NULL, 1, 0, NULL, 0, 1);
|
||||
(101, 'Bruce Wayne', '84612325V', 'Batman', 'Alfred', '1007 Mountain Drive, Gotham', 'Silla', 46460, 1111111111, 222222222, 333333333, 1, 'BruceWayne@verdnatura.es', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1,NULL, 10, 5,CURDATE(), 1, 5, 1, 1, 1,'0000-00-00', 1, NULL, 1, 1, 1, 1, NULL, 0, 0, 18, 0, 1),
|
||||
(102, 'Petter Parker', '87945234L', 'Spider-Man', 'Aunt May', '20 Ingram Street', 'Silla', 46460, 1111111111, 222222222, 333333333, 1, 'PetterParker@verdnatura.es', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1,NULL, 10, 5,CURDATE(), 1, 5, 1, 1, 1,'0000-00-00', 1, NULL, 1, 1, 0, 1, NULL, 0, 0, 18, 0, 1),
|
||||
(103, 'Clark Kent', '06815934E', 'Super-Man', 'lois lane', '344 Clinton Street', 'Silla', 46460, 1111111111, 222222222, 333333333, 1, 'ClarkKent@verdnatura.es', NULL, 0, 1234567890, 0, 1, 1, 0, 1, 1,NULL, 10, 5,CURDATE(), 1, 5, 1, 1, 1,'0000-00-00', 1, NULL, 1, 1, 1, 0, NULL, 0, 0, 18, 0, 1),
|
||||
(104, 'Tony Stark', '06089160W', 'Iron-Man', 'Pepper Potts', '10880 Malibu Point', 'Silla', 46460, 1111111111, 222222222, 333333333, 1, 'TonyStark@verdnatura.es', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1,NULL, 10, 5,CURDATE(), 1, 5, 1, 1, 1,'0000-00-00', 1, NULL, 1, 1, 1, 0, NULL, 0, 0, 18, 0, 1),
|
||||
(105, 'Max Eisenhardt', '39182496H', 'Magneto', 'Rogue', 'Unknown Whereabouts', 'Silla', 46460, 1111111111, 222222222, 333333333, 1, 'MaxEisenhardt@verdnatura.es', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1,NULL, 10, 5,CURDATE(), 1, 5, 1, 1, 1,'0000-00-00', 1, NULL, 1, 1, 1, 0, NULL, 0, 0, NULL, 0, 1),
|
||||
(106, 'DavidCharlesHaller', '53136686Q', 'Legion', 'Charles Xavier', 'Evil hideout', 'Silla', 46460, 1111111111, 222222222, 333333333, 1, 'DavidCharlesHaller@verdnatura.es', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 0,NULL, 10, 5,CURDATE(), 1, 5, 1, 1, 1,'0000-00-00', 1, NULL, 1, 1, 1, 0, NULL, 0, 0, 19, 0, 1),
|
||||
(107, 'Hank Pym', '09854837G', 'Ant-Man', 'Hawk', 'Anthill', 'Silla', 46460, 1111111111, 222222222, 333333333, 1, 'HankPym@verdnatura.es', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1,NULL, 10, 5,CURDATE(), 1, 5, 1, 1, 1,'0000-00-00', 1, NULL, 1, 1, 0, 0, NULL, 0, 0, 19, 0, 1),
|
||||
(108, 'Charles Xavier', '22641921P', 'Professor X', 'Beast', '3800 Victory Pkwy, Cincinnati, OH 45207, USA', 'Silla', 46460, 1111111111, 222222222, 333333333, 1, 'CharlesXavier@verdnatura.es', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1,NULL, 10, 5,CURDATE(), 1, 5, 1, 1, 1,'0000-00-00', 1, NULL, 1, 1, 1, 1, NULL, 0, 0, 19, 0, 1),
|
||||
(109, 'Bruce Banner', '16104829E', 'Hulk', 'Black widow', 'Somewhere in New York', 'Silla', 46460, 1111111111, 222222222, 333333333, 1, 'BruceBanner@verdnatura.es', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1,NULL, 10, 5,CURDATE(), 1, 5, 1, 1, 1,'0000-00-00', 1, NULL, 1, 1, 0, 1, NULL, 0, 0, 19, 0, 1),
|
||||
(110, 'Jessica Jones', '58282869H', 'Jessica Jones', 'Luke Cage', 'NYCC 2015 Poster', 'Silla', 46460, 1111111111, 222222222, 333333333, 1, 'JessicaJones@verdnatura.es', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1,NULL, 10, 5,CURDATE(), 1, 5, 1, 1, 1,'0000-00-00', 1, NULL, 1, 1, 0, 1, NULL, 0, 0, NULL, 0, 1),
|
||||
(200, 'Missing', NULL, 'Missing man', 'Anton', 'The space', 'Silla', 46460, 1111111111, 222222222, 333333333, 1, NULL, NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1,NULL, 10, 5,CURDATE(), 1, 5, 1, 1, 1,'0000-00-00', 4, NULL, 1, 0, 1, 0, NULL, 1, 0, NULL, 0, 1),
|
||||
(400, 'Trash', NULL, 'Garbage man', 'Unknown name', 'New York city', 'Silla', 46460, 1111111111, 222222222, 333333333, 1, NULL, NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1,NULL, 10, 5,CURDATE(), 1, 5, 1, 1, 1,'0000-00-00', 4, NULL, 1, 0, 1, 0, NULL, 1, 0, NULL, 0, 1);
|
||||
|
||||
INSERT INTO `vn`.`client`(`id`, `name`, `fi`, `socialName`, `contact`, `street`, `city`, `postcode`, `phone`, `isRelevant`, `email`, `iban`,`dueDay`,`accountingAccount`, `isEqualizated`, `provinceFk`, `hasToInvoice`, `credit`, `countryFk`, `isActive`, `gestdocFk`, `quality`, `payMethodFk`,`created`, `isTaxDataChecked`)
|
||||
SELECT id, name, CONCAT(RPAD(CONCAT(id,9),8,id),'A'), CONCAT(name, 'Social'), CONCAT(name, 'Contact'), CONCAT(name, 'Street'), 'SILLA', 46460, 623111111, 1, CONCAT(name,'@verdnatura.es'), NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1,NULL, 10, 5, CURDATE(), 1
|
||||
FROM `account`.`role` `r`
|
||||
WHERE `r`.`hasLogin` = 1;
|
||||
|
||||
INSERT INTO `vn`.`clientManaCache`(`clientFk`, `mana`, `dated`)
|
||||
VALUES
|
||||
|
@ -258,6 +263,11 @@ INSERT INTO `vn`.`address`(`id`, `nickname`, `street`, `city`, `postalCode`, `pr
|
|||
(131, 'Missing', 'The space', 'Silla', 46460, 1, 1111111111, 222222222, 1, 200, 2, NULL, NULL, 0, 0),
|
||||
(132, 'Trash', 'New York city', 'Silla', 46460, 1, 1111111111, 222222222, 1, 400, 2, NULL, NULL, 0, 0);
|
||||
|
||||
INSERT INTO `vn`.`address`( `nickname`, `street`, `city`, `postalCode`, `provinceFk`, `isActive`, `clientFk`, `agencyModeFk`, `isDefaultAddress`)
|
||||
SELECT name, CONCAT(name, 'Street'), 'SILLA', 46460, 1, 1, id, 2, 1
|
||||
FROM `account`.`role` `r`
|
||||
WHERE `r`.`hasLogin` = 1;
|
||||
|
||||
UPDATE `vn`.`client` SET defaultAddressFk = 1 WHERE id = 101;
|
||||
UPDATE `vn`.`client` SET defaultAddressFk = 2 WHERE id = 102;
|
||||
UPDATE `vn`.`client` SET defaultAddressFk = 3 WHERE id = 103;
|
||||
|
@ -271,6 +281,11 @@ UPDATE `vn`.`client` SET defaultAddressFk = 10 WHERE id = 110;
|
|||
UPDATE `vn`.`client` SET defaultAddressFk = 11 WHERE id = 200;
|
||||
UPDATE `vn`.`client` SET defaultAddressFk = 12 WHERE id = 400;
|
||||
|
||||
UPDATE `vn`.`client` `c`
|
||||
JOIN `vn`.`address` `a` ON `a`.`clientFk` = `c`.`id`
|
||||
SET `c`.`defaultAddressFk` = `a`.`id`
|
||||
WHERE `defaultAddressFk` IS NULL;
|
||||
|
||||
INSERT INTO `vn`.`clientCredit`(`id`, `clientFk`, `workerFk`, `amount`, `created`)
|
||||
VALUES
|
||||
(1 , 101, 5, 300, DATE_ADD(CURDATE(), INTERVAL -1 MONTH)),
|
||||
|
|
|
@ -1,37 +0,0 @@
|
|||
DROP PROCEDURE IF EXISTS mysql.truncateAll;
|
||||
DELIMITER $$
|
||||
CREATE PROCEDURE mysql.truncateAll()
|
||||
BEGIN
|
||||
DECLARE vSchema VARCHAR(255);
|
||||
DECLARE vTable VARCHAR(255);
|
||||
DECLARE vDone BOOL;
|
||||
|
||||
DECLARE cTables CURSOR FOR
|
||||
SELECT `TABLE_SCHEMA`, `TABLE_NAME`
|
||||
FROM `information_schema`.`TABLES`
|
||||
WHERE `TABLE_TYPE` = 'BASE TABLE'
|
||||
AND `TABLE_SCHEMA` NOT IN ('information_schema', 'mysql', 'performance_schema');
|
||||
|
||||
DECLARE CONTINUE HANDLER FOR NOT FOUND SET vDone = TRUE;
|
||||
|
||||
SET FOREIGN_KEY_CHECKS = FALSE;
|
||||
OPEN cTables;
|
||||
|
||||
l: LOOP
|
||||
SET vDone = FALSE;
|
||||
FETCH cTables INTO vSchema, vTable;
|
||||
|
||||
IF vDone THEN
|
||||
LEAVE l;
|
||||
END IF;
|
||||
|
||||
SET @stmt = CONCAT('TRUNCATE TABLE `', vSchema, '`.`', vTable, '`');
|
||||
PREPARE stmt FROM @stmt;
|
||||
EXECUTE stmt;
|
||||
DEALLOCATE PREPARE stmt;
|
||||
END LOOP;
|
||||
|
||||
CLOSE cTables;
|
||||
SET FOREIGN_KEY_CHECKS = TRUE;
|
||||
END$$
|
||||
DELIMITER ;
|
|
@ -87,6 +87,7 @@ export default {
|
|||
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="Code"] input',
|
||||
acceptBankEntityButton: 'vn-client-billing-data > vn-dialog button[response="ACCEPT"]',
|
||||
saveButton: `${components.vnSubmit}`
|
||||
},
|
||||
|
@ -171,7 +172,8 @@ export default {
|
|||
firstPaymentConfirmed: 'vn-client-web-payment vn-tr:nth-child(1) vn-icon[icon="check"][aria-hidden="false"]'
|
||||
},
|
||||
itemsIndex: {
|
||||
goBackToModuleIndexButton: `vn-ticket-descriptor a[href="#!/ticket/index"]`,
|
||||
searchIcon: `vn-item-index vn-searchbar vn-icon[icon="search"]`,
|
||||
goBackToModuleIndexButton: `vn-item-descriptor a[href="#!/item/index"]`,
|
||||
createItemButton: `${components.vnFloatButton}`,
|
||||
searchResult: `vn-item-index a.vn-tr`,
|
||||
searchResultPreviewButton: `vn-item-index .buttons > [icon="desktop_windows"]`,
|
||||
|
@ -179,7 +181,23 @@ export default {
|
|||
acceptClonationAlertButton: `vn-item-index [vn-id="clone"] [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-item-index [vn-id="preview"] button.close',
|
||||
fieldsToShowButton: 'vn-item-index vn-table > div.ng-scope > div > vn-icon-button[icon="menu"]',
|
||||
fieldsToShowForm: 'vn-item-index > div > vn-card > div > vn-table > div.ng-scope > div > vn-dialog > div > 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 > md-checkbox',
|
||||
stemsCheckbox: 'vn-item-index vn-dialog form vn-horizontal:nth-child(3) > vn-check > md-checkbox',
|
||||
sizeCheckbox: 'vn-item-index vn-dialog form vn-horizontal:nth-child(4) > vn-check > md-checkbox',
|
||||
nicheCheckbox: 'vn-item-index vn-dialog form vn-horizontal:nth-child(5) > vn-check > md-checkbox',
|
||||
typeCheckbox: 'vn-item-index vn-dialog form vn-horizontal:nth-child(6) > vn-check > md-checkbox',
|
||||
categoryCheckbox: 'vn-item-index vn-dialog form vn-horizontal:nth-child(7) > vn-check > md-checkbox',
|
||||
intrastadCheckbox: 'vn-item-index vn-dialog form vn-horizontal:nth-child(8) > vn-check > md-checkbox',
|
||||
originCheckbox: 'vn-item-index vn-dialog form vn-horizontal:nth-child(9) > vn-check > md-checkbox',
|
||||
buyerCheckbox: 'vn-item-index vn-dialog form vn-horizontal:nth-child(10) > vn-check > md-checkbox',
|
||||
destinyCheckbox: 'vn-item-index vn-dialog form vn-horizontal:nth-child(11) > vn-check > md-checkbox',
|
||||
taxClassCheckbox: 'vn-item-index vn-dialog form vn-horizontal:nth-child(12) > vn-check > md-checkbox',
|
||||
saveFieldsButton: 'vn-item-index vn-dialog vn-horizontal:nth-child(16) > vn-button > button'
|
||||
},
|
||||
itemCreateView: {
|
||||
temporalName: `${components.vnTextfield}[name="provisionalName"]`,
|
||||
|
@ -195,7 +213,9 @@ export default {
|
|||
regularizeQuantityInput: `vn-item-descriptor > vn-dialog > div > form > div.body > tpl-body > div > vn-textfield > div > div > div.infix > input`,
|
||||
regularizeWarehouseAutocomplete: 'vn-item-descriptor vn-dialog vn-autocomplete[field="$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-item-descriptor > vn-dialog > div > form > div.buttons > tpl-buttons > button`,
|
||||
inactiveIcon: 'vn-item-descriptor vn-icon[icon="icon-unavailable"]',
|
||||
navigateBackToIndex: 'vn-item-descriptor vn-icon[icon="chevron_left"]'
|
||||
},
|
||||
itemBasicData: {
|
||||
basicDataButton: `vn-left-menu a[ui-sref="item.card.data"]`,
|
||||
|
@ -325,7 +345,7 @@ export default {
|
|||
packagesButton: `vn-left-menu a[ui-sref="ticket.card.package.index"]`,
|
||||
firstPackageAutocomplete: `vn-autocomplete[label="Package"]`,
|
||||
firstQuantityInput: `vn-textfield[label="Quantity"] input`,
|
||||
firstRemovePackageButton: `vn-icon[vn-tooltip="Remove package"]`,
|
||||
firstRemovePackageButton: `vn-icon-button[vn-tooltip="Remove package"]`,
|
||||
addPackageButton: `vn-icon-button[vn-tooltip="Add package"]`,
|
||||
clearPackageAutocompleteButton: `vn-autocomplete[label="Package"] > div > div > div > vn-icon > i`,
|
||||
savePackagesButton: `${components.vnSubmit}`
|
||||
|
@ -425,7 +445,7 @@ export default {
|
|||
addServiceButton: 'vn-ticket-service > form > vn-card > div > vn-one:nth-child(3) > vn-icon-button > button > vn-icon',
|
||||
firstDescriptionInput: 'vn-ticket-service vn-textfield[label="Description"] input',
|
||||
firstQuantityInput: 'vn-ticket-service vn-textfield[label="Quantity"] input',
|
||||
firstPriceInput: 'vn-ticket-service vn-textfield[label="Price"] input',
|
||||
firstPriceInput: 'vn-ticket-service vn-input-number[label="Price"] input',
|
||||
firstVatTypeAutocomplete: 'vn-ticket-service vn-autocomplete[label="Tax class"]',
|
||||
fistDeleteServiceButton: 'vn-ticket-card > vn-main-block > div.content-block.ng-scope > vn-ticket-service > form > vn-card > div > vn-one:nth-child(1) > vn-horizontal:nth-child(1) > vn-auto > vn-icon-button[icon="delete"]',
|
||||
serviceLine: 'vn-ticket-service > form > vn-card > div > vn-one:nth-child(2) > vn-horizontal',
|
||||
|
@ -515,4 +535,9 @@ export default {
|
|||
confirmOrder: 'vn-order-line > vn-vertical > vn-button-bar > vn-button > button',
|
||||
confirmButton: 'vn-order-line > vn-confirm button[response="ACCEPT"]',
|
||||
},
|
||||
workerPbx: {
|
||||
extensionInput: 'vn-worker-pbx vn-textfield[model="$ctrl.worker.sip.extension"] input',
|
||||
passwordInput: 'vn-worker-pbx vn-textfield[model="$ctrl.worker.sip.secret"] input',
|
||||
saveButton: 'vn-worker-pbx vn-submit[label="Save"] input'
|
||||
}
|
||||
};
|
||||
|
|
|
@ -44,6 +44,7 @@ describe('Client Edit pay method path', () => {
|
|||
const newcode = await nightmare
|
||||
.waitToClick(selectors.clientPayMethod.newBankEntityButton)
|
||||
.write(selectors.clientPayMethod.newBankEntityName, 'Gotham City Bank')
|
||||
.write(selectors.clientPayMethod.newBankEntityCode, 9999)
|
||||
.write(selectors.clientPayMethod.newBankEntityBIC, 'GTHMCT')
|
||||
.waitToClick(selectors.clientPayMethod.acceptBankEntityButton)
|
||||
.waitToGetProperty(`${selectors.clientPayMethod.swiftBicAutocomplete} input`, 'value');
|
||||
|
|
|
@ -0,0 +1,88 @@
|
|||
import selectors from '../../helpers/selectors.js';
|
||||
import createNightmare from '../../helpers/nightmare';
|
||||
|
||||
describe('Item index path', () => {
|
||||
const nightmare = createNightmare();
|
||||
|
||||
beforeAll(() => {
|
||||
nightmare
|
||||
.loginAndModule('salesPerson', 'item')
|
||||
.waitToClick(selectors.itemsIndex.searchIcon);
|
||||
});
|
||||
|
||||
it('should click on the fields to show button to open the list of columns to show', async() => {
|
||||
const visible = await nightmare
|
||||
.waitToClick(selectors.itemsIndex.fieldsToShowButton)
|
||||
.isVisible(selectors.itemsIndex.fieldsToShowForm);
|
||||
|
||||
expect(visible).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should unmark all checkboxes except the first and the last ones', async() => {
|
||||
const result = await nightmare
|
||||
.waitToClick(selectors.itemsIndex.idCheckbox)
|
||||
.waitToClick(selectors.itemsIndex.stemsCheckbox)
|
||||
.waitToClick(selectors.itemsIndex.sizeCheckbox)
|
||||
.waitToClick(selectors.itemsIndex.nicheCheckbox)
|
||||
.waitToClick(selectors.itemsIndex.typeCheckbox)
|
||||
.waitToClick(selectors.itemsIndex.categoryCheckbox)
|
||||
.waitToClick(selectors.itemsIndex.intrastadCheckbox)
|
||||
.waitToClick(selectors.itemsIndex.originCheckbox)
|
||||
.waitToClick(selectors.itemsIndex.buyerCheckbox)
|
||||
.waitToClick(selectors.itemsIndex.destinyCheckbox)
|
||||
// .waitToClick(selectors.itemsIndex.taxClassCheckbox)
|
||||
.waitToClick(selectors.itemsIndex.saveFieldsButton)
|
||||
.waitForLastSnackbar();
|
||||
|
||||
expect(result).toEqual('Data saved!');
|
||||
});
|
||||
|
||||
it('should navigate forth and back to see the images column is still visible', async() => {
|
||||
const imageVisible = await nightmare
|
||||
.waitToClick(selectors.itemsIndex.searchResult)
|
||||
.waitToClick(selectors.itemsIndex.goBackToModuleIndexButton)
|
||||
.waitToClick(selectors.itemsIndex.searchIcon)
|
||||
.wait(selectors.itemsIndex.searchResult)
|
||||
.isVisible(selectors.itemsIndex.firstItemImage);
|
||||
|
||||
expect(imageVisible).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should check the ids column is not visible', async() => {
|
||||
const idVisible = await nightmare
|
||||
.isVisible(selectors.itemsIndex.firstItemId);
|
||||
|
||||
expect(idVisible).toBeFalsy();
|
||||
});
|
||||
|
||||
it('should mark all unchecked boxes to leave the index as it was', async() => {
|
||||
const result = await nightmare
|
||||
.waitToClick(selectors.itemsIndex.fieldsToShowButton)
|
||||
.waitToClick(selectors.itemsIndex.idCheckbox)
|
||||
.waitToClick(selectors.itemsIndex.stemsCheckbox)
|
||||
.waitToClick(selectors.itemsIndex.sizeCheckbox)
|
||||
.waitToClick(selectors.itemsIndex.nicheCheckbox)
|
||||
.waitToClick(selectors.itemsIndex.typeCheckbox)
|
||||
.waitToClick(selectors.itemsIndex.categoryCheckbox)
|
||||
.waitToClick(selectors.itemsIndex.intrastadCheckbox)
|
||||
.waitToClick(selectors.itemsIndex.originCheckbox)
|
||||
.waitToClick(selectors.itemsIndex.buyerCheckbox)
|
||||
.waitToClick(selectors.itemsIndex.destinyCheckbox)
|
||||
// .waitToClick(selectors.itemsIndex.taxClassCheckbox)
|
||||
.waitToClick(selectors.itemsIndex.saveFieldsButton)
|
||||
.waitForLastSnackbar();
|
||||
|
||||
expect(result).toEqual('Data saved!');
|
||||
});
|
||||
|
||||
it('should now navigate forth and back to see the ids column is now visible', async() => {
|
||||
const idVisible = await nightmare
|
||||
.waitToClick(selectors.itemsIndex.searchResult)
|
||||
.waitToClick(selectors.itemsIndex.goBackToModuleIndexButton)
|
||||
.waitToClick(selectors.itemsIndex.searchIcon)
|
||||
.wait(selectors.itemsIndex.searchResult)
|
||||
.isVisible(selectors.itemsIndex.firstItemId);
|
||||
|
||||
expect(idVisible).toBeTruthy();
|
||||
});
|
||||
});
|
|
@ -0,0 +1,48 @@
|
|||
import selectors from '../../helpers/selectors.js';
|
||||
import createNightmare from '../../helpers/nightmare';
|
||||
|
||||
describe('Item regularize path', () => {
|
||||
const nightmare = createNightmare();
|
||||
beforeAll(() => {
|
||||
nightmare
|
||||
.loginAndModule('developer', 'item')
|
||||
.accessToSearchResult(1)
|
||||
.accessToSection('item.card.data');
|
||||
});
|
||||
|
||||
it('should check the descriptor inactive icon is dark as the item is active', async() => {
|
||||
let darkIcon = await nightmare
|
||||
.wait(selectors.itemDescriptor.inactiveIcon)
|
||||
.waitForClassNotPresent(selectors.itemDescriptor.inactiveIcon, 'bright')
|
||||
.isVisible(selectors.itemDescriptor.inactiveIcon);
|
||||
|
||||
expect(darkIcon).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should set the item to inactive', async() => {
|
||||
let result = await nightmare
|
||||
.waitToClick(selectors.itemBasicData.isActiveCheckbox)
|
||||
.waitToClick(selectors.itemBasicData.submitBasicDataButton)
|
||||
.waitForLastSnackbar();
|
||||
|
||||
expect(result).toEqual('Data saved!');
|
||||
});
|
||||
|
||||
it('should reload the section and check the inactive icon is bright', async() => {
|
||||
let brightIcon = await nightmare
|
||||
.reloadSection('item.card.data')
|
||||
.waitForClassPresent(selectors.itemDescriptor.inactiveIcon, 'bright')
|
||||
.isVisible(selectors.itemDescriptor.inactiveIcon);
|
||||
|
||||
expect(brightIcon).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should set the item back to active', async() => {
|
||||
let result = await nightmare
|
||||
.waitToClick(selectors.itemBasicData.isActiveCheckbox)
|
||||
.waitToClick(selectors.itemBasicData.submitBasicDataButton)
|
||||
.waitForLastSnackbar();
|
||||
|
||||
expect(result).toEqual('Data saved!');
|
||||
});
|
||||
});
|
|
@ -7,7 +7,7 @@ describe('Ticket services path', () => {
|
|||
beforeAll(() => {
|
||||
nightmare
|
||||
.loginAndModule('employee', 'ticket')
|
||||
.accessToSearchResult('id:1')
|
||||
.accessToSearchResult('1')
|
||||
.accessToSection('ticket.card.service');
|
||||
});
|
||||
|
||||
|
@ -24,7 +24,7 @@ describe('Ticket services path', () => {
|
|||
.waitForLastSnackbar();
|
||||
|
||||
expect(result).toEqual('Data saved!');
|
||||
});
|
||||
}, 15000);
|
||||
|
||||
it('should confirm the service description was edited correctly', async() => {
|
||||
const result = await nightmare
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
import selectors from '../../helpers/selectors.js';
|
||||
import createNightmare from '../../helpers/nightmare';
|
||||
|
||||
describe('pbx path', () => {
|
||||
const nightmare = createNightmare();
|
||||
|
||||
beforeAll(() => {
|
||||
nightmare
|
||||
.loginAndModule('hr', 'worker')
|
||||
.accessToSearchResult('employee')
|
||||
.accessToSection('worker.card.pbx');
|
||||
});
|
||||
|
||||
it('should receive an error when the extension exceeds 4 characters', async() => {
|
||||
const result = await nightmare
|
||||
.write(selectors.workerPbx.extensionInput, 55555)
|
||||
|
||||
.waitToClick(selectors.workerPbx.saveButton)
|
||||
.waitForLastSnackbar();
|
||||
|
||||
expect(result).toEqual('EXTENSION_INVALID_FORMAT');
|
||||
});
|
||||
|
||||
it('should sucessfully save the changes', async() => {
|
||||
const result = await nightmare
|
||||
.clearInput(selectors.workerPbx.extensionInput)
|
||||
.write(selectors.workerPbx.extensionInput, 4444)
|
||||
.clearInput(selectors.workerPbx.passwordInput)
|
||||
.write(selectors.workerPbx.passwordInput, 666666)
|
||||
.waitToClick(selectors.workerPbx.saveButton)
|
||||
.waitForLastSnackbar();
|
||||
|
||||
expect(result).toEqual('Data saved!');
|
||||
});
|
||||
});
|
|
@ -6,7 +6,7 @@
|
|||
<input
|
||||
class="mdl-textfield__input"
|
||||
type="time"
|
||||
ng-model="$ctrl.value"
|
||||
ng-model="$ctrl.model"
|
||||
vn-validation="{{$ctrl.rule}}"
|
||||
ng-disabled="$ctrl.disabled"
|
||||
ng-readonly="$ctrl.readonly"
|
||||
|
|
|
@ -3,11 +3,19 @@ import Textfield from '../textfield/textfield';
|
|||
import './style.scss';
|
||||
|
||||
export default class InputTime extends Textfield {
|
||||
|
||||
get value() {
|
||||
return this._value;
|
||||
}
|
||||
|
||||
get model() {
|
||||
return this._model;
|
||||
}
|
||||
|
||||
|
||||
set model(value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
set value(value) {
|
||||
if (!value) return;
|
||||
|
||||
|
@ -15,7 +23,15 @@ export default class InputTime extends Textfield {
|
|||
newDate.setSeconds(0);
|
||||
newDate.setMilliseconds(0);
|
||||
|
||||
this._value = newDate;
|
||||
this._model = newDate;
|
||||
this.hasValue = this._model !== null;
|
||||
|
||||
let date = new Date(value);
|
||||
date.setSeconds(0);
|
||||
date.setMilliseconds(0);
|
||||
let offset = date.getTimezoneOffset() * 60000;
|
||||
date.setTime(date.getTime() - offset);
|
||||
this._value = date;
|
||||
|
||||
this.hasValue = this._value !== null;
|
||||
|
||||
|
|
|
@ -1,25 +1,54 @@
|
|||
<ul ng-if="$ctrl.items">
|
||||
<ul ng-if="::$ctrl.items">
|
||||
<li ng-repeat="item in $ctrl.items"
|
||||
ng-class="{
|
||||
'expanded': item.active,
|
||||
'collapsed': !item.active,
|
||||
'included': item.isIncluded == 1,
|
||||
'excluded': item.isIncluded == 0
|
||||
'included': item.selected == 1,
|
||||
'excluded': item.selected == 0
|
||||
}">
|
||||
<vn-horizontal>
|
||||
<vn-auto class="actions">
|
||||
<vn-icon icon="keyboard_arrow_down"
|
||||
ng-show="item.sons > 0"
|
||||
ng-click="$ctrl.toggle(item, $event)" >
|
||||
<vn-icon icon="keyboard_arrow_down" title="{{'Toggle' | translate}}"
|
||||
ng-click="$ctrl.toggle(item, $event)">
|
||||
</vn-icon>
|
||||
</vn-auto>
|
||||
<div class="description">
|
||||
<vn-check vn-auto field="item.isIncluded"
|
||||
on-change="$ctrl.select(item, value)" triple-state="true">
|
||||
<vn-one class="description">
|
||||
<vn-check vn-auto vn-acl="{{$ctrl.aclRole}}"
|
||||
ng-if="$ctrl.selectable"
|
||||
field="item.selected"
|
||||
disabled="$ctrl.disabled"
|
||||
on-change="$ctrl.select(item, value)"
|
||||
triple-state="true">
|
||||
</vn-check>
|
||||
{{::item.name}}
|
||||
</vn-one>
|
||||
<vn-auto>
|
||||
<vn-icon-button icon="{{icon.icon}}"
|
||||
ng-repeat="icon in $ctrl.icons"
|
||||
ng-click="$ctrl.onClick(icon, item, $ctrl.parent, $parent.$index)"
|
||||
vn-acl="{{$ctrl.aclRole}}" vn-acl-action="remove">
|
||||
</vn-icon-button>
|
||||
</vn-auto>
|
||||
</vn-horizontal>
|
||||
<vn-treeview-child items="item.childs" parent="item"
|
||||
selectable="$ctrl.selectable"
|
||||
disabled="$ctrl.disabled"
|
||||
editable="$ctrl.editable"
|
||||
icons="$ctrl.icons"
|
||||
acl-role="$ctrl.aclRole">
|
||||
</vn-treeview-child>
|
||||
</li>
|
||||
<li ng-if="$ctrl.isInsertable && $ctrl.editable"
|
||||
ng-click="$ctrl.onCreate($ctrl.parent)"
|
||||
vn-acl="{{$ctrl.aclRole}}"
|
||||
vn-acl-action="remove">
|
||||
<vn-horizontal>
|
||||
<vn-auto>
|
||||
<vn-icon-button icon="add_circle"></vn-icon-button>
|
||||
</vn-auto>
|
||||
<div class="description" translate>
|
||||
Create new one
|
||||
</div>
|
||||
</vn-horizontal>
|
||||
<vn-treeview-child items="item.childs"></vn-treeview-child>
|
||||
</li>
|
||||
</ul>
|
|
@ -4,6 +4,7 @@ import Component from '../../lib/component';
|
|||
class Controller extends Component {
|
||||
constructor($element, $scope) {
|
||||
super($element, $scope);
|
||||
this.$scope = $scope;
|
||||
}
|
||||
|
||||
toggle(item) {
|
||||
|
@ -13,13 +14,33 @@ class Controller extends Component {
|
|||
select(item, value) {
|
||||
this.treeview.onSelection(item, value);
|
||||
}
|
||||
|
||||
onClick(icon, item, parent, index) {
|
||||
let parentScope = this.$scope.$parent.$parent;
|
||||
let parentController = parentScope.$ctrl;
|
||||
icon.callback.call(parentController, item, parent, index);
|
||||
}
|
||||
|
||||
onCreate(parent) {
|
||||
this.treeview.onCreate(parent);
|
||||
}
|
||||
|
||||
get isInsertable() {
|
||||
return Array.isArray(this.parent) || this.parent.childs;
|
||||
}
|
||||
}
|
||||
|
||||
ngModule.component('vnTreeviewChild', {
|
||||
template: require('./child.html'),
|
||||
controller: Controller,
|
||||
bindings: {
|
||||
items: '<'
|
||||
items: '<',
|
||||
parent: '<',
|
||||
icons: '<?',
|
||||
disabled: '<?',
|
||||
selectable: '<?',
|
||||
editable: '<?',
|
||||
aclRole: '<?',
|
||||
},
|
||||
require: {
|
||||
treeview: '^vnTreeview'
|
||||
|
|
|
@ -1 +1,9 @@
|
|||
<vn-treeview-child items="$ctrl.data"></vn-treeview-child>
|
||||
<vn-treeview-child
|
||||
items="$ctrl.data"
|
||||
parent="$ctrl.data"
|
||||
selectable="$ctrl.selectable"
|
||||
editable="$ctrl.editable"
|
||||
disabled="$ctrl.disabled"
|
||||
icons="$ctrl.icons"
|
||||
acl-role="$ctrl.aclRole">
|
||||
</vn-treeview-child>
|
||||
|
|
|
@ -23,10 +23,19 @@ export default class Treeview extends Component {
|
|||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Emits selection event
|
||||
* @param {Object} item - Selected item
|
||||
* @param {Boolean} value - Changed value
|
||||
*/
|
||||
onSelection(item, value) {
|
||||
this.emit('selection', {item, value});
|
||||
}
|
||||
|
||||
onCreate(parent) {
|
||||
this.emit('create', {parent});
|
||||
}
|
||||
|
||||
onToggle(item) {
|
||||
if (item.active)
|
||||
item.childs = undefined;
|
||||
|
@ -45,12 +54,12 @@ export default class Treeview extends Component {
|
|||
}
|
||||
|
||||
item.childs = newData.sort((a, b) => {
|
||||
if (b.isIncluded !== a.isIncluded) {
|
||||
if (a.isIncluded == null)
|
||||
if (b.selected !== a.selected) {
|
||||
if (a.selected == null)
|
||||
return 1;
|
||||
if (b.isIncluded == null)
|
||||
if (b.selected == null)
|
||||
return -1;
|
||||
return b.isIncluded - a.isIncluded;
|
||||
return b.selected - a.selected;
|
||||
}
|
||||
|
||||
return a.name.localeCompare(b.name);
|
||||
|
@ -68,6 +77,11 @@ ngModule.component('vnTreeview', {
|
|||
template: require('./index.html'),
|
||||
controller: Treeview,
|
||||
bindings: {
|
||||
model: '<'
|
||||
model: '<',
|
||||
icons: '<?',
|
||||
disabled: '<?',
|
||||
selectable: '<?',
|
||||
editable: '<?',
|
||||
aclRole: '@?'
|
||||
}
|
||||
});
|
||||
|
|
|
@ -21,7 +21,7 @@ vn-treeview {
|
|||
}
|
||||
|
||||
li ul {
|
||||
padding: 0 1.8em;
|
||||
padding-left: 1.8em;
|
||||
}
|
||||
|
||||
li > vn-horizontal {
|
||||
|
@ -62,4 +62,8 @@ vn-treeview {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
vn-icon-button {
|
||||
padding: 0
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,7 +36,7 @@ function vnAcl(aclService, $timeout) {
|
|||
return conditions;
|
||||
}
|
||||
|
||||
function permissionElement($element, action) {
|
||||
function permissionElement($scope, $element, action) {
|
||||
if (!aclService.hasAny(acls)) {
|
||||
if (action === 'disabled') {
|
||||
let input = $element[0];
|
||||
|
@ -72,9 +72,13 @@ function vnAcl(aclService, $timeout) {
|
|||
priority: -1,
|
||||
link: function($scope, $element, $attrs) {
|
||||
acls = $attrs.vnAcl.split(',').map(i => i.trim());
|
||||
|
||||
if (acls[0] == '') return;
|
||||
|
||||
let action = $attrs.vnAclAction || 'disabled';
|
||||
let conditions = getDynamicConditions($attrs);
|
||||
permissionElement($element, action);
|
||||
|
||||
permissionElement($scope, $element, action);
|
||||
|
||||
if (Object.keys(conditions).length) {
|
||||
let watchConditions = $scope.$watch(() => {
|
||||
|
@ -82,7 +86,7 @@ function vnAcl(aclService, $timeout) {
|
|||
let hasPermission = $scope.$eval($attrs[attrName]);
|
||||
if (!hasPermission) {
|
||||
updateAcls(conditions[attrName].role, hasPermission);
|
||||
permissionElement($element, action);
|
||||
permissionElement($scope, $element, action);
|
||||
delete conditions[attrName];
|
||||
}
|
||||
});
|
||||
|
|
|
@ -40,3 +40,5 @@ December: Diciembre
|
|||
Has delivery: Hay reparto
|
||||
Loading: Cargando
|
||||
Fields to show: Campos a mostrar
|
||||
Create new one: Crear nuevo
|
||||
Toggle: Desplegar/Plegar
|
|
@ -1,9 +1,3 @@
|
|||
<vn-crud-model
|
||||
url="/api/Banks"
|
||||
vn-id="banks"
|
||||
data="banksData"
|
||||
order="bank">
|
||||
</vn-crud-model>
|
||||
<vn-crud-model
|
||||
url="/api/Warehouses"
|
||||
vn-id="warehouses"
|
||||
|
@ -33,11 +27,12 @@
|
|||
label="Local bank"
|
||||
id="localBank"
|
||||
field="$ctrl.localBankFk"
|
||||
data="banksData"
|
||||
url="/api/Banks"
|
||||
select-fields="['id','bank']"
|
||||
show-field="bank"
|
||||
order="id"
|
||||
value-field="id">
|
||||
value-field="id"
|
||||
search-function="{or: [{id: $search}, {bank: {like: '%'+ $search +'%'}}]}">
|
||||
<tpl-item>{{id}}: {{bank}}</tpl-item>
|
||||
</vn-autocomplete>
|
||||
<vn-autocomplete
|
||||
|
|
|
@ -31,6 +31,13 @@ class Controller {
|
|||
}
|
||||
}
|
||||
|
||||
$onInit() {
|
||||
if (window.localStorage.localBankFk && window.localStorage.localBankFk !== 'null')
|
||||
window.localStorage.defaultBankFk = window.localStorage.localBankFk;
|
||||
else
|
||||
localStorage.removeItem('defaultBankFk');
|
||||
}
|
||||
|
||||
set lang(value) {
|
||||
this._lang = value;
|
||||
this.$translate.use(value);
|
||||
|
@ -105,7 +112,6 @@ class Controller {
|
|||
}
|
||||
|
||||
show(event) {
|
||||
this.$scope.banks.refresh();
|
||||
this.$scope.warehouses.refresh();
|
||||
this.$scope.companies.refresh();
|
||||
this.$scope.popover.parent = event.target;
|
||||
|
@ -139,11 +145,8 @@ class Controller {
|
|||
});
|
||||
}
|
||||
|
||||
$onInit() {
|
||||
if (window.localStorage.localBankFk && window.localStorage.localBankFk !== 'null')
|
||||
window.localStorage.defaultBankFk = window.localStorage.localBankFk;
|
||||
else
|
||||
localStorage.removeItem('defaultBankFk');
|
||||
searchLocalBank(a, b) {
|
||||
return angular.equals(a.id, b.id);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -163,7 +163,7 @@ module.exports = function(Self) {
|
|||
// Sets the changedModelValue to save and the instances changed in case its an updateAll
|
||||
let changedModelValue = definition.settings.log.changedModelValue;
|
||||
let where;
|
||||
if (changedModelValue && (!ctx.instance || !ctx.instance[changedModelValue])) {
|
||||
if (changedModelValue && (!ctx.instance || !ctx.instance[changedModelValue]) && ctx.where) {
|
||||
changedModelId = [];
|
||||
where = [];
|
||||
let changedInstances = await ctx.Model.app.models[definition.name].find({where: ctx.where, fields: ['id', changedModelValue]}, options);
|
||||
|
|
|
@ -128,44 +128,33 @@ module.exports = function(Self) {
|
|||
return replaceErrFunc(err);
|
||||
}
|
||||
|
||||
function rewriteMethod(methodName) {
|
||||
const realMethod = this[methodName];
|
||||
return async(data, options, cb) => {
|
||||
if (options instanceof Function) {
|
||||
cb = options;
|
||||
options = null;
|
||||
}
|
||||
|
||||
try {
|
||||
await realMethod.call(this, data, options);
|
||||
if (cb) cb();
|
||||
} catch (err) {
|
||||
let myErr = replaceErr(err, replaceErrFunc);
|
||||
if (cb)
|
||||
cb(myErr);
|
||||
else
|
||||
throw myErr;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
this.once('attached', () => {
|
||||
let realUpsert = this.upsert;
|
||||
this.upsert = async(data, options, cb) => {
|
||||
if (options instanceof Function) {
|
||||
cb = options;
|
||||
options = null;
|
||||
}
|
||||
|
||||
try {
|
||||
await realUpsert.call(this, data, options);
|
||||
if (cb) cb();
|
||||
} catch (err) {
|
||||
let myErr = replaceErr(err, replaceErrFunc);
|
||||
if (cb)
|
||||
cb(myErr);
|
||||
else
|
||||
throw myErr;
|
||||
}
|
||||
};
|
||||
|
||||
let realCreate = this.create;
|
||||
this.create = async(data, options, cb) => {
|
||||
if (options instanceof Function) {
|
||||
cb = options;
|
||||
options = null;
|
||||
}
|
||||
|
||||
try {
|
||||
await realCreate.call(this, data, options);
|
||||
if (cb) cb();
|
||||
} catch (err) {
|
||||
let myErr = replaceErr(err, replaceErrFunc);
|
||||
if (cb)
|
||||
cb(myErr);
|
||||
else
|
||||
throw myErr;
|
||||
}
|
||||
};
|
||||
this.remove =
|
||||
this.deleteAll =
|
||||
this.destroyAll = rewriteMethod.call(this, 'remove');
|
||||
this.upsert = rewriteMethod.call(this, 'upsert');
|
||||
this.create = rewriteMethod.call(this, 'create');
|
||||
});
|
||||
},
|
||||
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
"Package cannot be blank": "Package cannot be blank",
|
||||
"The new quantity should be smaller than the old one": "The new quantity should be smaller than the old one",
|
||||
"The sales of this ticket can't be modified": "The sales of this ticket can't be modified",
|
||||
"Cannot check VIES and Equalization Tax": "Cannot check VIES and Equalization Tax",
|
||||
"Cannot check Equalization Tax in this NIF/CIF": "Cannot check Equalization Tax in this NIF/CIF",
|
||||
"You can't create an order for a frozen client": "You can't create an order for a frozen client",
|
||||
"This address doesn't exist": "This address doesn't exist",
|
||||
|
@ -39,5 +38,6 @@
|
|||
"You can't create a ticket for a frozen client": "You can't create a ticket for a frozen client",
|
||||
"can't be blank": "can't be blank",
|
||||
"Street cannot be empty": "Street cannot be empty",
|
||||
"City cannot be empty": "City cannot be empty"
|
||||
"City cannot be empty": "City cannot be empty",
|
||||
"EXTENSION_INVALID_FORMAT": "EXTENSION_INVALID_FORMAT"
|
||||
}
|
|
@ -59,7 +59,6 @@
|
|||
"You can't create an order for a client that doesn't has tax data verified": "You can't create an order for a client that doesn't has tax data verified",
|
||||
"You must delete the claim id %d first": "Antes debes borrar la reclamacion %d",
|
||||
"You don't have enough privileges": "No tienes suficientes permisos",
|
||||
"Cannot check VIES and Equalization Tax": "No puedes marcar VIES y RE al mismo",
|
||||
"Cannot check Equalization Tax in this NIF/CIF": "No se puede marcar RE en este NIF/CIF",
|
||||
"You can't make changes on the basic data of an confirmed order or with rows": "No puedes cambiar los datos basicos de una orden con artículos",
|
||||
"INVALID_USER_NAME": "El nombre de usuario solo debe contener letras minúsculas o, a partir del segundo carácter, números o subguiones, no esta permitido el uso de la letra ñ",
|
||||
|
@ -71,6 +70,8 @@
|
|||
"You can't create a ticket for a client that has a debt": "No puedes crear un ticket para un client con deuda",
|
||||
"NO SE PUEDE DESACTIVAR EL CONSIGNAT": "NO SE PUEDE DESACTIVAR EL CONSIGNAT",
|
||||
"Error. El NIF/CIF está repetido": "Error. El NIF/CIF está repetido",
|
||||
"Street cannot be empty": "Street cannot be empty",
|
||||
"City cannot be empty": "City cannot be empty"
|
||||
"Street cannot be empty": "Dirección no puede estar en blanco",
|
||||
"City cannot be empty": "Cuidad no puede estar en blanco",
|
||||
"Code cannot be blank": "Código no puede estar en blanco",
|
||||
"You cannot remove this department": "No puedes eliminar este departamento"
|
||||
}
|
|
@ -73,7 +73,7 @@ module.exports = Self => {
|
|||
zg.rgt,
|
||||
zg.depth,
|
||||
zg.sons,
|
||||
IF(ch.id = zg.id, isIncluded, null) isIncluded
|
||||
IF(ch.id = zg.id, isIncluded, null) selected
|
||||
FROM zoneGeo zg
|
||||
JOIN tmp.checkedChilds ch
|
||||
ON zg.lft <= ch.lft AND zg.rgt >= ch.rgt
|
||||
|
@ -86,7 +86,7 @@ module.exports = Self => {
|
|||
child.rgt,
|
||||
child.depth,
|
||||
child.sons,
|
||||
zi.isIncluded
|
||||
zi.isIncluded AS selected
|
||||
FROM zoneGeo parent
|
||||
JOIN zoneGeo child ON child.lft > parent.lft
|
||||
AND child.rgt < parent.rgt
|
||||
|
@ -122,9 +122,11 @@ module.exports = Self => {
|
|||
|
||||
function nestLeaves(elements) {
|
||||
elements.forEach(element => {
|
||||
element.childs = Object.assign([], getLeaves(element));
|
||||
|
||||
nestLeaves(element.childs);
|
||||
let childs = Object.assign([], getLeaves(element));
|
||||
if (childs.length > 0) {
|
||||
element.childs = childs;
|
||||
nestLeaves(element.childs);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -142,12 +144,12 @@ module.exports = Self => {
|
|||
|
||||
function sortNodes(nodes) {
|
||||
return nodes.sort((a, b) => {
|
||||
if (b.isIncluded !== a.isIncluded) {
|
||||
if (a.isIncluded == null)
|
||||
if (b.selected !== a.selected) {
|
||||
if (a.selected == null)
|
||||
return 1;
|
||||
if (b.isIncluded == null)
|
||||
if (b.selected == null)
|
||||
return -1;
|
||||
return b.isIncluded - a.isIncluded;
|
||||
return b.selected - a.selected;
|
||||
}
|
||||
|
||||
return a.name.localeCompare(b.name);
|
||||
|
|
|
@ -30,6 +30,10 @@
|
|||
"bonus": {
|
||||
"type": "Number",
|
||||
"required": true
|
||||
},
|
||||
"isVolumetric": {
|
||||
"type": "Boolean",
|
||||
"required": true
|
||||
}
|
||||
},
|
||||
"relations": {
|
||||
|
|
|
@ -62,6 +62,9 @@
|
|||
display-controls="false">
|
||||
</vn-input-number>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal>
|
||||
<vn-check field="$ctrl.zone.isVolumetric" label="Volumetric"></vn-check>
|
||||
</vn-horizontal>
|
||||
</vn-card>
|
||||
<vn-button-bar>
|
||||
<vn-submit label="Save"></vn-submit>
|
||||
|
|
|
@ -64,6 +64,9 @@
|
|||
display-controls="false">
|
||||
</vn-input-number>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal>
|
||||
<vn-check field="$ctrl.zone.isVolumetric" label="Volumetric"></vn-check>
|
||||
</vn-horizontal>
|
||||
</vn-card>
|
||||
<vn-button-bar>
|
||||
<vn-submit label="Create"></vn-submit>
|
||||
|
|
|
@ -6,8 +6,8 @@ export default class Controller {
|
|||
this.$state = $state;
|
||||
this.zone = {
|
||||
travelingDays: 0,
|
||||
price: 0.50,
|
||||
bonus: 0.50,
|
||||
price: 0.20,
|
||||
bonus: 0.20,
|
||||
hour: new Date()
|
||||
};
|
||||
}
|
||||
|
|
|
@ -7,3 +7,4 @@ Delete zone: Eliminar zona
|
|||
Are you sure you want to delete this zone?: ¿Estás seguro de querer eliminar esta zona?
|
||||
Zones: Zonas
|
||||
New zone: Nueva zona
|
||||
Volumetric: Volumétrico
|
|
@ -12,7 +12,7 @@
|
|||
on-search="$ctrl.onSearch()"
|
||||
vn-focus>
|
||||
</vn-searchbar>
|
||||
<vn-treeview vn-id="treeview" model="model"
|
||||
<vn-treeview vn-id="treeview" model="model" selectable="true" acl-role="deliveryBoss"
|
||||
on-selection="$ctrl.onSelection(item, value)">
|
||||
</vn-treeview>
|
||||
</vn-card>
|
||||
|
|
|
@ -29,22 +29,23 @@ module.exports = Self => {
|
|||
}
|
||||
});
|
||||
|
||||
Self.isValidClient = async function(id) {
|
||||
Self.isValidClient = async id => {
|
||||
let query =
|
||||
`SELECT r.name
|
||||
FROM salix.Account A
|
||||
JOIN vn.client C ON A.id = C.id
|
||||
JOIN salix.RoleMapping rm ON rm.principalId = A.id
|
||||
FROM salix.Account a
|
||||
JOIN vn.client c ON a.id = c.id
|
||||
JOIN salix.RoleMapping rm ON rm.principalId = a.id
|
||||
JOIN salix.Role r ON r.id = rm.roleId
|
||||
WHERE A.id = ? AND C.isActive AND C.isTaxDataChecked`;
|
||||
WHERE a.id = ? AND c.isActive AND c.isTaxDataChecked`;
|
||||
|
||||
let roleNames = await Self.rawSql(query, [id]);
|
||||
if (!roleNames.length) return false;
|
||||
|
||||
roleNames.forEach(role => {
|
||||
if (role.name === 'employee')
|
||||
return false;
|
||||
let isEmployee = roleNames.findIndex(role => {
|
||||
return role.name === 'employee';
|
||||
});
|
||||
|
||||
if (!roleNames.length || isEmployee > -1 ) return false;
|
||||
|
||||
return true;
|
||||
};
|
||||
};
|
||||
|
|
|
@ -1,57 +1,45 @@
|
|||
const app = require('vn-loopback/server/server');
|
||||
|
||||
describe('Client isValidClient', () => {
|
||||
it('should call the isValidClient() method with a client id and receive true', done => {
|
||||
it('should call the isValidClient() method with a client id and receive true', async() => {
|
||||
let id = 101;
|
||||
app.models.Client.isValidClient(id)
|
||||
.then(result => {
|
||||
expect(result).toBeTruthy();
|
||||
done();
|
||||
});
|
||||
let result = await app.models.Client.isValidClient(id);
|
||||
|
||||
expect(result).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should call the isValidClient() method with a employee id and receive false', done => {
|
||||
it('should call the isValidClient() method with an employee id to receive false', async() => {
|
||||
let id = 1;
|
||||
app.models.Client.isValidClient(id)
|
||||
.then(result => {
|
||||
expect(result).toBeFalsy();
|
||||
done();
|
||||
});
|
||||
let result = await app.models.Client.isValidClient(id);
|
||||
|
||||
expect(result).toBeFalsy();
|
||||
});
|
||||
|
||||
it('should call the isValidClient() method with a unexistant id and receive false', done => {
|
||||
it('should call the isValidClient() method with an unexistant id and receive false', async() => {
|
||||
let id = 999999;
|
||||
app.models.Client.isValidClient(id)
|
||||
.then(result => {
|
||||
expect(result).toBeFalsy();
|
||||
done();
|
||||
});
|
||||
let result = await app.models.Client.isValidClient(id);
|
||||
|
||||
expect(result).toBeFalsy();
|
||||
});
|
||||
|
||||
it('should call the isValidClient() method with a invalid id and receive false', done => {
|
||||
it('should call the isValidClient() method with an invalid id and receive false', async() => {
|
||||
let id = 'Pepinillos';
|
||||
app.models.Client.isValidClient(id)
|
||||
.then(result => {
|
||||
expect(result).toBeFalsy();
|
||||
done();
|
||||
});
|
||||
let result = await app.models.Client.isValidClient(id);
|
||||
|
||||
expect(result).toBeFalsy();
|
||||
});
|
||||
|
||||
it('should call the isValidClient() method with a customer id which isnt active and return false', done => {
|
||||
it('should call the isValidClient() method with a customer id which isnt active and return false', async() => {
|
||||
let id = '106';
|
||||
app.models.Client.isValidClient(id)
|
||||
.then(result => {
|
||||
expect(result).toBeFalsy();
|
||||
done();
|
||||
});
|
||||
let result = await app.models.Client.isValidClient(id);
|
||||
|
||||
expect(result).toBeFalsy();
|
||||
});
|
||||
|
||||
it('should call the isValidClient() method with a customer id which his data isnt verified and return false', done => {
|
||||
it('should call the isValidClient() method with a customer id which his data isnt verified and return false', async() => {
|
||||
let id = '110';
|
||||
app.models.Client.isValidClient(id)
|
||||
.then(result => {
|
||||
expect(result).toBeFalsy();
|
||||
done();
|
||||
});
|
||||
let result = await app.models.Client.isValidClient(id);
|
||||
|
||||
expect(result).toBeFalsy();
|
||||
});
|
||||
});
|
||||
|
|
|
@ -73,6 +73,7 @@ module.exports = Self => {
|
|||
Self.validateAsync('fi', tinIsValid, {
|
||||
message: 'Invalid TIN'
|
||||
});
|
||||
|
||||
let validateTin = require('../validations/validateTin');
|
||||
async function tinIsValid(err, done) {
|
||||
if (!this.isTaxDataChecked)
|
||||
|
@ -85,7 +86,7 @@ module.exports = Self => {
|
|||
let country = await Self.app.models.Country.findOne(filter);
|
||||
let code = country ? country.code.toLowerCase() : null;
|
||||
|
||||
if (!validateTin(this.fi, code))
|
||||
if (!this.fi || !validateTin(this.fi, code))
|
||||
err();
|
||||
done();
|
||||
}
|
||||
|
|
|
@ -111,6 +111,12 @@
|
|||
show-field="country">
|
||||
</vn-autocomplete>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal>
|
||||
<vn-textfield vn-one
|
||||
label="Code"
|
||||
model="$ctrl.newBankEntity.id">
|
||||
</vn-textfield>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal>
|
||||
<vn-textfield vn-one
|
||||
label="Swift / BIC"
|
||||
|
|
|
@ -49,6 +49,7 @@ export default class Controller {
|
|||
|
||||
onBankEntityOpen() {
|
||||
this.newBankEntity.name = '';
|
||||
this.newBankEntity.id = '';
|
||||
this.newBankEntity.bic = '';
|
||||
this.$scope.$apply();
|
||||
}
|
||||
|
@ -58,6 +59,8 @@ export default class Controller {
|
|||
try {
|
||||
if (!this.newBankEntity.name)
|
||||
throw new Error(`Name can't be empty`);
|
||||
if (!this.newBankEntity.id)
|
||||
throw new Error(`Code can't be empty`);
|
||||
if (!this.newBankEntity.bic)
|
||||
throw new Error(`Swift / BIC can't be empty`);
|
||||
|
||||
|
|
|
@ -51,7 +51,8 @@ describe('Client', () => {
|
|||
controller.newBankEntity = {
|
||||
name: '',
|
||||
bic: 'ES123',
|
||||
countryFk: 1
|
||||
countryFk: 1,
|
||||
id: 999
|
||||
};
|
||||
controller.onBankEntityResponse('ACCEPT');
|
||||
|
||||
|
@ -62,18 +63,32 @@ describe('Client', () => {
|
|||
controller.newBankEntity = {
|
||||
name: 'My new bank entity',
|
||||
bic: '',
|
||||
countryFk: 1
|
||||
countryFk: 1,
|
||||
id: 999
|
||||
};
|
||||
controller.onBankEntityResponse('ACCEPT');
|
||||
|
||||
expect(vnApp.showError).toHaveBeenCalledWith(`Swift / BIC can't be empty`);
|
||||
});
|
||||
|
||||
it(`should throw an error if id property is empty`, () => {
|
||||
controller.newBankEntity = {
|
||||
name: 'My new bank entity',
|
||||
bic: 'ES123',
|
||||
countryFk: 1,
|
||||
id: null
|
||||
};
|
||||
controller.onBankEntityResponse('ACCEPT');
|
||||
|
||||
expect(vnApp.showError).toHaveBeenCalledWith(`Code can't be empty`);
|
||||
});
|
||||
|
||||
it('should request to create a new bank entity', () => {
|
||||
let newBankEntity = {
|
||||
name: 'My new bank entity',
|
||||
bic: 'ES123',
|
||||
countryFk: 1
|
||||
countryFk: 1,
|
||||
id: 999
|
||||
};
|
||||
controller.newBankEntity = newBankEntity;
|
||||
$httpBackend.when('POST', '/client/api/BankEntities').respond('done');
|
||||
|
|
|
@ -16,3 +16,4 @@ Save: Guardar
|
|||
New bank entity: Nueva entidad bancaria
|
||||
Name can't be empty: El nombre no puede quedar vacío
|
||||
Swift / BIC can't be empty: El Swift / BIC no puede quedar vacío
|
||||
Code: Código
|
|
@ -89,12 +89,12 @@ module.exports = Self => {
|
|||
}
|
||||
});
|
||||
|
||||
filter = mergeFilters(ctx.args.filter, {where});
|
||||
/* case 'hasVisible':
|
||||
return value ? {'v.visible': {gt: 0}} : {'v.visible': {or: [{lte: 0}, {neq: null}]}}; */
|
||||
|
||||
filter = mergeFilters(ctx.args.filter, {where});
|
||||
let stmts = [];
|
||||
let stmt;
|
||||
if (ctx.args.hasVisible === true)
|
||||
stmts.push('CALL cache.visible_refresh(@visibleCalc, true, 1)');
|
||||
|
||||
stmt = new ParameterizedSQL(
|
||||
`SELECT i.id, i.image, i.name, i.description,
|
||||
|
@ -106,7 +106,7 @@ module.exports = Self => {
|
|||
intr.description AS intrastat, i.stems,
|
||||
ori.code AS origin, t.name AS type,
|
||||
ic.name AS category, i.density,
|
||||
b.grouping, b.packing, itn.code AS niche
|
||||
b.grouping, b.packing, itn.code AS niche, @visibleCalc
|
||||
FROM item i
|
||||
LEFT JOIN itemType t ON t.id = i.typeFk
|
||||
LEFT JOIN itemCategory ic ON ic.id = t.categoryFk
|
||||
|
@ -120,13 +120,18 @@ module.exports = Self => {
|
|||
LEFT JOIN itemPlacement itn ON itn.itemFk = i.id AND itn.warehouseFk = t.warehouseFk`
|
||||
);
|
||||
|
||||
if (ctx.args.hasVisible === true) {
|
||||
/* if (ctx.args.hasVisible !== undefined) {
|
||||
stmts.push('CALL cache.visible_refresh(@visibleCalc, false, 1)');
|
||||
stmts.push('CALL cache.visible_refresh(@visibleCalc, false, 44)');
|
||||
let joinAvailable = new ParameterizedSQL(
|
||||
`JOIN cache.visible v
|
||||
ON v.item_id = i.id AND v.calc_id = @visibleCalc`
|
||||
`LEFT JOIN cache.visible v
|
||||
ON v.item_id = i.id`
|
||||
);
|
||||
stmt.merge(joinAvailable);
|
||||
}
|
||||
} */
|
||||
/* where v.visible > 0
|
||||
where v.visible <= 0 OR v.visible IS NULL
|
||||
*/
|
||||
|
||||
if (ctx.args.tags) {
|
||||
let i = 1;
|
||||
|
@ -150,7 +155,12 @@ module.exports = Self => {
|
|||
}
|
||||
}
|
||||
|
||||
stmt.merge(conn.makeSuffix(filter));
|
||||
stmt.merge(conn.makeWhere(filter.where));
|
||||
|
||||
/* if (ctx.args.hasVisible !== undefined)
|
||||
stmt.merge(`GROUP BY i.id`);
|
||||
*/
|
||||
stmt.merge(conn.makePagination(filter));
|
||||
let itemsIndex = stmts.push(stmt) - 1;
|
||||
|
||||
let sql = ParameterizedSQL.join(stmts, ';');
|
||||
|
|
|
@ -4,7 +4,12 @@ describe('item new()', () => {
|
|||
let item;
|
||||
|
||||
afterAll(async done => {
|
||||
await app.models.Item.destroyById(item.id);
|
||||
let sql = 'DELETE FROM vn.itemLog WHERE originFk = ?';
|
||||
await app.models.Item.rawSql(sql, [item.id]);
|
||||
|
||||
sql = 'DELETE FROM vn.item WHERE id = ?';
|
||||
await app.models.Item.rawSql(sql, [item.id]);
|
||||
|
||||
|
||||
done();
|
||||
});
|
||||
|
|
|
@ -27,7 +27,7 @@ module.exports = Self => {
|
|||
if (!tax.taxClassFk)
|
||||
throw new UserError('Tax class cannot be blank');
|
||||
|
||||
promises.push(Self.app.models.ItemTaxCountry.updateAll(
|
||||
promises.push(Self.app.models.ItemTaxCountry.update(
|
||||
{id: tax.id},
|
||||
{taxClassFk: tax.taxClassFk}
|
||||
));
|
||||
|
|
|
@ -1,6 +1,11 @@
|
|||
{
|
||||
"name": "ItemBarcode",
|
||||
"base": "VnModel",
|
||||
"base": "Loggable",
|
||||
"log": {
|
||||
"model": "ItemLog",
|
||||
"relation": "item",
|
||||
"changedModelValue": "code"
|
||||
},
|
||||
"options": {
|
||||
"mysql": {
|
||||
"table": "itemBarcode"
|
||||
|
|
|
@ -1,6 +1,11 @@
|
|||
{
|
||||
"name": "ItemBotanical",
|
||||
"base": "VnModel",
|
||||
"base": "Loggable",
|
||||
"log": {
|
||||
"model": "ItemLog",
|
||||
"relation": "item",
|
||||
"changedModelValue": "botanical"
|
||||
},
|
||||
"options": {
|
||||
"mysql": {
|
||||
"table": "itemBotanical"
|
||||
|
|
|
@ -2,44 +2,54 @@
|
|||
"name": "ItemLog",
|
||||
"base": "VnModel",
|
||||
"options": {
|
||||
"mysql": {
|
||||
"table": "itemLog"
|
||||
}
|
||||
"mysql": {
|
||||
"table": "itemLog"
|
||||
}
|
||||
},
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "Number",
|
||||
"id": true,
|
||||
"description": "Identifier"
|
||||
"type": "Number",
|
||||
"forceId": false
|
||||
},
|
||||
"originFk": {
|
||||
"type": "Number",
|
||||
"required": true
|
||||
},
|
||||
"userFk": {
|
||||
"type": "Number"
|
||||
},
|
||||
"action": {
|
||||
"type": "String",
|
||||
"required": true
|
||||
},
|
||||
"changedModel": {
|
||||
"type": "String"
|
||||
},
|
||||
"oldInstance": {
|
||||
"type": "Object"
|
||||
},
|
||||
"newInstance": {
|
||||
"type": "Object"
|
||||
},
|
||||
"creationDate": {
|
||||
"type": "Date"
|
||||
},
|
||||
"description": {
|
||||
"changedModelId": {
|
||||
"type": "Number"
|
||||
},
|
||||
"changedModelValue": {
|
||||
"type": "String"
|
||||
},
|
||||
"action": {
|
||||
"description": {
|
||||
"type": "String"
|
||||
}
|
||||
},
|
||||
"relations": {
|
||||
"item": {
|
||||
"type": "belongsTo",
|
||||
"model": "Item",
|
||||
"foreignKey": "originFk"
|
||||
},
|
||||
"user": {
|
||||
"type": "belongsTo",
|
||||
"model": "Account",
|
||||
"foreignKey": "userFk"
|
||||
}
|
||||
},
|
||||
"acls": [
|
||||
{
|
||||
"accessType": "READ",
|
||||
"principalType": "ROLE",
|
||||
"principalId": "$everyone",
|
||||
"permission": "ALLOW"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,11 @@
|
|||
{
|
||||
"name": "ItemNiche",
|
||||
"base": "VnModel",
|
||||
"base": "Loggable",
|
||||
"log": {
|
||||
"model": "ItemLog",
|
||||
"relation": "item",
|
||||
"changedModelValue": "code"
|
||||
},
|
||||
"options": {
|
||||
"mysql": {
|
||||
"table": "itemPlacement"
|
||||
|
|
|
@ -1,6 +1,11 @@
|
|||
{
|
||||
"name": "ItemTag",
|
||||
"base": "VnModel",
|
||||
"base": "Loggable",
|
||||
"log": {
|
||||
"model": "ItemLog",
|
||||
"relation": "item",
|
||||
"changedModelValue": "value"
|
||||
},
|
||||
"options": {
|
||||
"mysql": {
|
||||
"table": "itemTag"
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
{
|
||||
"name": "Item",
|
||||
"base": "VnModel",
|
||||
"base": "Loggable",
|
||||
"log": {
|
||||
"model":"ItemLog"
|
||||
},
|
||||
"options": {
|
||||
"mysql": {
|
||||
"table": "item"
|
||||
|
|
|
@ -1,33 +0,0 @@
|
|||
<vn-crud-model
|
||||
vn-id="model"
|
||||
url="/item/api/ItemLogs"
|
||||
filter="::$ctrl.filter"
|
||||
link="{originFk: $ctrl.$stateParams.id}"
|
||||
limit="20"
|
||||
data="logs" auto-load="false">
|
||||
</vn-crud-model>
|
||||
<vn-vertical>
|
||||
<vn-card pad-large>
|
||||
<vn-vertical>
|
||||
<vn-table model="model">
|
||||
<vn-thead>
|
||||
<vn-tr>
|
||||
<vn-th field="description">Description</vn-th>
|
||||
<vn-th field="action">Action</vn-th>
|
||||
<vn-th field="userFk">Changed by</vn-th>
|
||||
<vn-th field="creationDate" default-order="DESC">Date</vn-th>
|
||||
</vn-tr>
|
||||
</vn-thead>
|
||||
<vn-tbody>
|
||||
<vn-tr ng-repeat="itemLog in logs">
|
||||
<vn-td>{{::itemLog.description}}</vn-td>
|
||||
<vn-td>{{::itemLog.action}}</vn-td>
|
||||
<vn-td>{{::itemLog.user.name}}</vn-td>
|
||||
<vn-td>{{::itemLog.creationDate | dateTime:'dd/MM/yyyy HH:mm'}}</vn-td>
|
||||
</vn-tr>
|
||||
</vn-tbody>
|
||||
</vn-table>
|
||||
</vn-vertical>
|
||||
<vn-pagination model="model"></vn-pagination>
|
||||
</vn-card>
|
||||
</vn-vertical>
|
|
@ -1,25 +0,0 @@
|
|||
import ngModule from '../module';
|
||||
|
||||
class Controller {
|
||||
constructor($stateParams) {
|
||||
this.$stateParams = $stateParams;
|
||||
this.filter = {
|
||||
include: [{
|
||||
relation: "item"
|
||||
},
|
||||
{
|
||||
relation: "user",
|
||||
scope: {
|
||||
fields: ["name"]
|
||||
}
|
||||
}]
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
Controller.$inject = ['$stateParams'];
|
||||
|
||||
ngModule.component('vnItemHistory', {
|
||||
template: require('./index.html'),
|
||||
controller: Controller
|
||||
});
|
|
@ -11,7 +11,7 @@ import './data';
|
|||
import './fetched-tags';
|
||||
import './tags';
|
||||
import './tax';
|
||||
// import './history';
|
||||
import './log';
|
||||
import './last-entries';
|
||||
import './niche';
|
||||
import './botanical';
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
<vn-crud-model
|
||||
vn-id="model"
|
||||
url="/api/ItemLogs"
|
||||
link="{originFk: $ctrl.$stateParams.id}"
|
||||
filter="$ctrl.filter"
|
||||
limit="20"
|
||||
data="$ctrl.logs" auto-load="false">
|
||||
</vn-crud-model>
|
||||
<vn-log model="model"></vn-log>
|
|
@ -0,0 +1,53 @@
|
|||
import ngModule from '../module';
|
||||
|
||||
class Controller {
|
||||
constructor($scope, $stateParams) {
|
||||
this.$scope = $scope;
|
||||
this.$stateParams = $stateParams;
|
||||
this.filter = {
|
||||
include: [{
|
||||
relation: 'user',
|
||||
scope: {
|
||||
fields: ['name'],
|
||||
},
|
||||
}],
|
||||
};
|
||||
}
|
||||
|
||||
get logs() {
|
||||
return this._logs;
|
||||
}
|
||||
|
||||
set logs(value) {
|
||||
this._logs = value;
|
||||
|
||||
if (this.logs) {
|
||||
this.logs.forEach(log => {
|
||||
log.oldProperties = this.getInstance(log.oldInstance);
|
||||
log.newProperties = this.getInstance(log.newInstance);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
getInstance(instance) {
|
||||
let validDate = /^(-?(?:[1-9][0-9]*)?[0-9]{4})-(1[0-2]|0[1-9])-(3[01]|0[1-9]|[12][0-9])T(2[0-3]|[01][0-9]):([0-5][0-9]):([0-5][0-9])(.[0-9]+)?(Z)?$/;
|
||||
const properties = [];
|
||||
if (typeof instance == 'object' && instance != null) {
|
||||
Object.keys(instance).forEach(property => {
|
||||
if (validDate.test(instance[property]))
|
||||
instance[property] = new Date(instance[property]).toLocaleString('es-ES');
|
||||
|
||||
properties.push({key: property, value: instance[property]});
|
||||
});
|
||||
return properties;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
Controller.$inject = ['$scope', '$stateParams'];
|
||||
|
||||
ngModule.component('vnItemLog', {
|
||||
template: require('./index.html'),
|
||||
controller: Controller,
|
||||
});
|
|
@ -12,7 +12,8 @@
|
|||
{"state": "item.card.botanical", "icon": "local_florist"},
|
||||
{"state": "item.card.itemBarcode", "icon": "icon-barcode"},
|
||||
{"state": "item.card.diary", "icon": "icon-transaction"},
|
||||
{"state": "item.card.last-entries", "icon": "icon-regentry"}
|
||||
{"state": "item.card.last-entries", "icon": "icon-regentry"},
|
||||
{"state": "item.card.log", "icon": "history"}
|
||||
],
|
||||
"keybindings": [
|
||||
{"key": "a", "state": "item.index"}
|
||||
|
@ -116,6 +117,11 @@
|
|||
"item": "$ctrl.item"
|
||||
},
|
||||
"acl": ["employee"]
|
||||
}, {
|
||||
"url" : "/log",
|
||||
"state": "item.card.log",
|
||||
"component": "vn-item-log",
|
||||
"description": "Log"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -42,11 +42,6 @@
|
|||
</vn-autocomplete>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal>
|
||||
<vn-check
|
||||
vn-one
|
||||
label="With visible"
|
||||
field="filter.hasVisible">
|
||||
</vn-check>
|
||||
<vn-check
|
||||
vn-one
|
||||
label="Active"
|
||||
|
|
|
@ -15,6 +15,11 @@ class Controller {
|
|||
icon: 'icon-ticket',
|
||||
state: `ticket.index({q: '{"orderFk": ${value.id}}'})`,
|
||||
tooltip: 'Order ticket list'
|
||||
},
|
||||
btnTwo: {
|
||||
icon: 'person',
|
||||
state: `client.card.summary({id: ${value.clientFk}})`,
|
||||
tooltip: 'Client card'
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ module.exports = Self => {
|
|||
http: {source: 'query'}
|
||||
}],
|
||||
returns: {
|
||||
type: ["Object"],
|
||||
type: ['Object'],
|
||||
root: true
|
||||
},
|
||||
http: {
|
||||
|
@ -28,7 +28,8 @@ module.exports = Self => {
|
|||
`SELECT name, itemFk, packagingFk
|
||||
FROM (SELECT i.name, i.id itemFk, p.id packagingFk
|
||||
FROM item i
|
||||
JOIN packaging p ON i.id = p.itemFk) p`
|
||||
JOIN packaging p ON i.id = p.itemFk
|
||||
WHERE i.name <> '') p`
|
||||
);
|
||||
|
||||
stmt.merge(conn.makeSuffix(filter));
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
let UserError = require('vn-loopback/util/user-error');
|
||||
|
||||
module.exports = Self => {
|
||||
Self.remoteMethod('updateDiscount', {
|
||||
Self.remoteMethodCtx('updateDiscount', {
|
||||
description: 'Changes the discount of a sale',
|
||||
accessType: '',
|
||||
accepts: [{
|
||||
|
@ -21,16 +21,12 @@ module.exports = Self => {
|
|||
}
|
||||
});
|
||||
|
||||
Self.updateDiscount = async params => {
|
||||
Self.updateDiscount = async(ctx, params) => {
|
||||
if (isNaN(params.editLines[0].discount))
|
||||
throw new UserError(`The value should be a number`);
|
||||
|
||||
let model = Self.app.models;
|
||||
let thisTicketIsEditable = await model.Ticket.isEditable(params.editLines[0].ticketFk);
|
||||
|
||||
if (!thisTicketIsEditable)
|
||||
throw new UserError(`The sales of this ticket can't be modified`);
|
||||
|
||||
let ticket = await model.Ticket.find({
|
||||
where: {
|
||||
id: params.editLines[0].ticketFk
|
||||
|
@ -41,9 +37,16 @@ module.exports = Self => {
|
|||
fields: ['salesPersonFk']
|
||||
}
|
||||
}],
|
||||
fields: ['id', 'clientFk']
|
||||
fields: ['id', 'clientFk', 'refFk']
|
||||
});
|
||||
|
||||
let userId = ctx.req.accessToken.userId;
|
||||
let isSalesAssistant = await Self.app.models.Account.hasRole(userId, 'salesAssistant');
|
||||
|
||||
if ((!thisTicketIsEditable && !isSalesAssistant) || (ticket.refFk && isSalesAssistant))
|
||||
throw new UserError(`The sales of this ticket can't be modified`);
|
||||
|
||||
|
||||
let componentToUse;
|
||||
let usesMana = await model.WorkerMana.findOne({where: {workerFk: ticket[0].client().salesPersonFk}, fields: 'amount'});
|
||||
|
||||
|
|
|
@ -23,23 +23,28 @@ module.exports = Self => {
|
|||
}
|
||||
});
|
||||
|
||||
Self.changeState = async(ctx, data) => {
|
||||
Self.changeState = async(ctx, params) => {
|
||||
let userId = ctx.req.accessToken.userId;
|
||||
let $ = Self.app.models;
|
||||
|
||||
if (!data.stateFk)
|
||||
if (!params.stateFk && !params.code)
|
||||
throw new UserError('State cannot be blank');
|
||||
|
||||
if (params.code) {
|
||||
let state = await $.State.findOne({where: {code: params.code}, fields: ['id']});
|
||||
params.stateFk = state.id;
|
||||
}
|
||||
|
||||
let isProduction = await $.Account.hasRole(userId, 'production');
|
||||
let isSalesPerson = await $.Account.hasRole(userId, 'salesPerson');
|
||||
|
||||
let ticket = await $.TicketState.findById(
|
||||
data.ticketFk,
|
||||
params.ticketFk,
|
||||
{fields: ['stateFk']}
|
||||
);
|
||||
|
||||
let oldState = await $.State.findById(ticket.stateFk);
|
||||
let newState = await $.State.findById(data.stateFk);
|
||||
let newState = await $.State.findById(params.stateFk);
|
||||
|
||||
let isAllowed = isProduction || isSalesPerson
|
||||
&& oldState.isEditable()
|
||||
|
@ -50,9 +55,9 @@ module.exports = Self => {
|
|||
|
||||
if (newState.code != 'PICKER_DESIGNED') {
|
||||
let worker = await $.Worker.findOne({where: {userFk: userId}});
|
||||
data.workerFk = worker.id;
|
||||
params.workerFk = worker.id;
|
||||
}
|
||||
|
||||
return await $.TicketTracking.create(data);
|
||||
return await $.TicketTracking.create(params);
|
||||
};
|
||||
};
|
||||
|
|
|
@ -220,12 +220,12 @@ module.exports = Self => {
|
|||
SELECT
|
||||
f.*,
|
||||
tt.total,
|
||||
tp.problem
|
||||
tp.*
|
||||
FROM tmp.filter f
|
||||
LEFT JOIN tmp.ticketProblems tp ON tp.ticketFk = f.id
|
||||
LEFT JOIN tmp.ticketTotal tt ON tt.ticketFk = f.id`);
|
||||
stmt.merge(conn.makeOrderBy(filter.order));
|
||||
let ticketsIndex = stmts.push(stmt) - 1;
|
||||
let ticketsIndex = stmts.push(stmt);
|
||||
|
||||
stmts.push(
|
||||
`DROP TEMPORARY TABLE
|
||||
|
|
|
@ -2,7 +2,7 @@ const app = require('vn-loopback/server/server');
|
|||
|
||||
describe('ticket filter()', () => {
|
||||
it('should call the filter method', async() => {
|
||||
let ctx = {req: {accessToken: {userId: 9}}};
|
||||
let ctx = {req: {accessToken: {userId: 9}}, args: {}};
|
||||
|
||||
let filter = {order: 'shipped DESC'};
|
||||
let result = await app.models.Ticket.filter(ctx, filter);
|
||||
|
|
|
@ -11,7 +11,7 @@ class Controller {
|
|||
{callback: this.showAddTurnDialog, name: 'Add turn', show: true},
|
||||
{callback: this.showAddStowaway, name: 'Add stowaway', show: () => this.isTicketModule()},
|
||||
{callback: this.showRemoveStowaway, name: 'Remove stowaway', show: () => this.shouldShowRemoveStowaway()},
|
||||
/* {callback: this.showDeliveryNote, name: 'Show Delivery Note', show: true}, */
|
||||
{callback: this.showDeliveryNote, name: 'Show Delivery Note', show: true},
|
||||
{callback: this.showDeleteTicketDialog, name: 'Delete ticket', show: true},
|
||||
/* callback: this.showChangeShipped, name: 'Change shipped hour', show: true} */
|
||||
];
|
||||
|
@ -57,7 +57,8 @@ class Controller {
|
|||
}
|
||||
|
||||
goToTicket(ticketID) {
|
||||
this.$state.go('ticket.card.sale', {id: ticketID});
|
||||
let url = this.$state.href('ticket.card.sale', {id: ticketID}, {absolute: true});
|
||||
window.open(url, '_blank');
|
||||
}
|
||||
|
||||
onMoreOpen() {
|
||||
|
|
|
@ -52,10 +52,28 @@
|
|||
ui-sref="ticket.card.summary({id: {{::ticket.id}}})">
|
||||
<vn-td shrink>
|
||||
<vn-icon
|
||||
ng-show="ticket.problem"
|
||||
ng-show="ticket.hasTicketRequest"
|
||||
class="bright"
|
||||
vn-tooltip="{{ticket.problem}}"
|
||||
icon="warning">
|
||||
vn-tooltip="{{ticket.hasTicketRequest}}"
|
||||
icon="icon-100">
|
||||
</vn-icon>
|
||||
<vn-icon
|
||||
ng-show="ticket.isAvailable === 0"
|
||||
class="bright"
|
||||
vn-tooltip="{{ticket.isAvailable}}"
|
||||
icon="icon-unavailable">
|
||||
</vn-icon>
|
||||
<vn-icon
|
||||
ng-show="ticket.isFreezed"
|
||||
class="bright"
|
||||
vn-tooltip="Client frozen"
|
||||
icon="icon-frozen">
|
||||
</vn-icon>
|
||||
<vn-icon
|
||||
ng-show="ticket.risk"
|
||||
class="bright"
|
||||
vn-tooltip="Risk : {{ticket.risk}}"
|
||||
icon="icon-risk">
|
||||
</vn-icon>
|
||||
</vn-td>
|
||||
<vn-td number>{{::ticket.id}}</vn-td>
|
||||
|
|
|
@ -35,12 +35,12 @@
|
|||
rule="ticketObservation.description">
|
||||
</vn-textfield>
|
||||
<vn-auto pad-medium-top>
|
||||
<vn-icon
|
||||
<vn-icon-button
|
||||
pointer
|
||||
vn-tooltip="Remove note"
|
||||
icon="delete"
|
||||
ng-click="model.remove($index)">
|
||||
</vn-icon>
|
||||
</vn-icon-button>
|
||||
</vn-auto>
|
||||
</vn-horizontal>
|
||||
</vn-one>
|
||||
|
|
|
@ -39,12 +39,12 @@
|
|||
ng-readonly="true">
|
||||
</vn-textfield>
|
||||
<vn-auto pad-medium-top>
|
||||
<vn-icon
|
||||
<vn-icon-button
|
||||
pointer
|
||||
vn-tooltip="Remove package"
|
||||
icon="delete"
|
||||
ng-click="model.remove($index)">
|
||||
</vn-icon>
|
||||
</vn-icon-button>
|
||||
</vn-one>
|
||||
</vn-horizontal>
|
||||
</vn-one>
|
||||
|
|
|
@ -27,12 +27,13 @@
|
|||
model="service.quantity"
|
||||
rule="TicketService.quantity">
|
||||
</vn-textfield>
|
||||
<vn-textfield
|
||||
<vn-input-number
|
||||
vn-one
|
||||
step="1"
|
||||
label="Price"
|
||||
model="service.price"
|
||||
rule="TicketService.price">
|
||||
</vn-textfield>
|
||||
display-controls="false">
|
||||
</vn-input-number>
|
||||
<vn-autocomplete vn-one
|
||||
url="/api/TaxClasses"
|
||||
label="Tax class"
|
||||
|
|
|
@ -17,12 +17,7 @@ class Controller {
|
|||
set ticket(value) {
|
||||
this._ticket = value;
|
||||
|
||||
if (!value) return;
|
||||
|
||||
this.$http.get(`/ticket/api/Tickets/${this.ticket.id}/summary`).then(res => {
|
||||
if (res && res.data)
|
||||
this.summary = res.data;
|
||||
});
|
||||
if (value) this.getSummary();
|
||||
}
|
||||
|
||||
get formattedAddress() {
|
||||
|
@ -34,6 +29,13 @@ class Controller {
|
|||
return `${address.street} - ${address.city} ${province}`;
|
||||
}
|
||||
|
||||
getSummary() {
|
||||
this.$http.get(`/ticket/api/Tickets/${this.ticket.id}/summary`).then(res => {
|
||||
if (res && res.data)
|
||||
this.summary = res.data;
|
||||
});
|
||||
}
|
||||
|
||||
showDescriptor(event, itemFk) {
|
||||
this.quicklinks = {
|
||||
btnThree: {
|
||||
|
@ -64,25 +66,22 @@ class Controller {
|
|||
}
|
||||
|
||||
setOkState() {
|
||||
let filter = {where: {code: 'OK'}, fields: ['id']};
|
||||
let json = encodeURIComponent(JSON.stringify(filter));
|
||||
this.$http.get(`/ticket/api/States?filter=${json}`).then(res => {
|
||||
this.changeTicketState(res.data[0].id);
|
||||
});
|
||||
}
|
||||
|
||||
changeTicketState(value) {
|
||||
let params;
|
||||
let params = {};
|
||||
|
||||
if (this.$state.params.id)
|
||||
params = {ticketFk: this.$state.params.id, stateFk: value};
|
||||
params = {ticketFk: this.$state.params.id};
|
||||
|
||||
if (!this.$state.params.id)
|
||||
params = {ticketFk: this.ticket.id, stateFk: value};
|
||||
params = {ticketFk: this.ticket.id};
|
||||
|
||||
params.code = 'OK';
|
||||
|
||||
this.$http.post(`/ticket/api/TicketTrackings/changeState`, params).then(() => {
|
||||
this.vnApp.showSuccess(this.$translate.instant('Data saved!'));
|
||||
if (this.card) this.card.reload();
|
||||
if (this.card)
|
||||
this.card.reload();
|
||||
else
|
||||
this.getSummary();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,87 @@
|
|||
|
||||
const ParameterizedSQL = require('loopback-connector').ParameterizedSQL;
|
||||
|
||||
module.exports = Self => {
|
||||
Self.remoteMethod('getLeaves', {
|
||||
description: 'Returns the first shipped and landed possible for params',
|
||||
accessType: '',
|
||||
accepts: [{
|
||||
arg: 'parentFk',
|
||||
type: 'Number',
|
||||
default: 1,
|
||||
required: false,
|
||||
},
|
||||
{
|
||||
arg: 'filter',
|
||||
type: 'Object',
|
||||
description: 'Filter defining where, order, offset, and limit - must be a JSON-encoded string',
|
||||
http: {source: 'query'}
|
||||
}],
|
||||
returns: {
|
||||
type: ['object'],
|
||||
root: true
|
||||
},
|
||||
http: {
|
||||
path: `/getLeaves`,
|
||||
verb: 'GET'
|
||||
}
|
||||
});
|
||||
|
||||
Self.getLeaves = async(parentFk = 1, filter) => {
|
||||
let conn = Self.dataSource.connector;
|
||||
let stmt = new ParameterizedSQL(
|
||||
`SELECT
|
||||
child.id,
|
||||
child.name,
|
||||
child.lft,
|
||||
child.rgt,
|
||||
child.depth,
|
||||
child.sons
|
||||
FROM department parent
|
||||
JOIN department child ON child.lft > parent.lft
|
||||
AND child.rgt < parent.rgt
|
||||
AND child.depth = parent.depth + 1
|
||||
WHERE parent.id = ?`, [parentFk]);
|
||||
|
||||
// Get nodes from depth greather than Origin
|
||||
stmt.merge(conn.makeSuffix(filter));
|
||||
|
||||
const nodes = await Self.rawStmt(stmt);
|
||||
|
||||
if (nodes.length == 0)
|
||||
return nodes;
|
||||
|
||||
// Get parent nodes
|
||||
const minorDepth = nodes.reduce((a, b) => {
|
||||
return b < a ? b : a;
|
||||
}).depth;
|
||||
|
||||
const parentNodes = nodes.filter(element => {
|
||||
return element.depth === minorDepth;
|
||||
});
|
||||
const leaves = Object.assign([], parentNodes);
|
||||
|
||||
nestLeaves(leaves);
|
||||
|
||||
function nestLeaves(elements) {
|
||||
elements.forEach(element => {
|
||||
let childs = Object.assign([], getLeaves(element));
|
||||
if (childs.length > 0) {
|
||||
element.childs = childs;
|
||||
nestLeaves(element.childs);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function getLeaves(parent) {
|
||||
let elements = nodes.filter(element => {
|
||||
return element.lft > parent.lft && element.rgt < parent.rgt
|
||||
&& element.depth === parent.depth + 1;
|
||||
});
|
||||
|
||||
return elements;
|
||||
}
|
||||
|
||||
return leaves;
|
||||
};
|
||||
};
|
|
@ -0,0 +1,43 @@
|
|||
|
||||
const ParameterizedSQL = require('loopback-connector').ParameterizedSQL;
|
||||
|
||||
module.exports = Self => {
|
||||
Self.remoteMethod('nodeAdd', {
|
||||
description: 'Returns the first shipped and landed possible for params',
|
||||
accessType: '',
|
||||
accepts: [{
|
||||
arg: 'parentFk',
|
||||
type: 'Number',
|
||||
required: false,
|
||||
},
|
||||
{
|
||||
arg: 'name',
|
||||
type: 'String',
|
||||
required: true,
|
||||
}],
|
||||
returns: {
|
||||
type: 'object',
|
||||
root: true
|
||||
},
|
||||
http: {
|
||||
path: `/nodeAdd`,
|
||||
verb: 'POST'
|
||||
}
|
||||
});
|
||||
|
||||
Self.nodeAdd = async(parentFk = 1, name) => {
|
||||
let stmts = [];
|
||||
let conn = Self.dataSource.connector;
|
||||
let nodeIndex = stmts.push(new ParameterizedSQL(
|
||||
`CALL nst.NodeAdd('vn', 'department', ?, ?)`, [parentFk, name])) - 1;
|
||||
|
||||
stmts.push(`CALL nst.nodeRecalc('vn', 'department')`);
|
||||
|
||||
|
||||
let sql = ParameterizedSQL.join(stmts, ';');
|
||||
let result = await conn.executeStmt(sql);
|
||||
let [node] = result[nodeIndex];
|
||||
|
||||
return node;
|
||||
};
|
||||
};
|
|
@ -0,0 +1,29 @@
|
|||
|
||||
const ParameterizedSQL = require('loopback-connector').ParameterizedSQL;
|
||||
|
||||
module.exports = Self => {
|
||||
Self.remoteMethod('nodeDelete', {
|
||||
description: 'Returns the first shipped and landed possible for params',
|
||||
accessType: '',
|
||||
accepts: [{
|
||||
arg: 'parentFk',
|
||||
type: 'Number',
|
||||
required: false,
|
||||
}],
|
||||
returns: {
|
||||
type: ['object'],
|
||||
root: true
|
||||
},
|
||||
http: {
|
||||
path: `/nodeDelete`,
|
||||
verb: 'POST'
|
||||
}
|
||||
});
|
||||
|
||||
Self.nodeDelete = async parentFk => {
|
||||
let stmt = new ParameterizedSQL(
|
||||
`CALL nst.nodeDelete('vn', 'department', ?)`, [parentFk]);
|
||||
|
||||
return await Self.rawStmt(stmt);
|
||||
};
|
||||
};
|
|
@ -80,7 +80,8 @@ module.exports = Self => {
|
|||
? {'w.id': value}
|
||||
: {or: [
|
||||
{'w.firstName': {like: `%${value}%`}},
|
||||
{'w.name': {like: `%${value}%`}}
|
||||
{'w.name': {like: `%${value}%`}},
|
||||
{'u.name': {like: `%${value}%`}}
|
||||
]};
|
||||
case 'id':
|
||||
return {'w.id': value};
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
const UserError = require('vn-loopback/util/user-error');
|
||||
|
||||
module.exports = Self => {
|
||||
require('../methods/department/getLeaves')(Self);
|
||||
require('../methods/department/nodeAdd')(Self);
|
||||
require('../methods/department/nodeDelete')(Self);
|
||||
|
||||
Self.rewriteDbError(function(err) {
|
||||
if (err.code === 'ER_ROW_IS_REFERENCED_2')
|
||||
return new UserError(`You cannot remove this department`);
|
||||
return err;
|
||||
});
|
||||
|
||||
Self.rewriteDbError(function(err) {
|
||||
if (err.code === 'ER_DUP_ENTRY')
|
||||
return new UserError(`The department name can't be repeated`);
|
||||
return err;
|
||||
});
|
||||
};
|
|
@ -22,7 +22,9 @@ class Controller {
|
|||
},
|
||||
{
|
||||
relation: 'sip',
|
||||
scope: {fields: ['extension']}
|
||||
scope: {
|
||||
fields: ['extension', 'secret']
|
||||
}
|
||||
}, {
|
||||
relation: 'department',
|
||||
scope: {
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
<vn-crud-model
|
||||
vn-id="model"
|
||||
url="/worker/api/departments/getLeaves"
|
||||
params="::$ctrl.params"
|
||||
auto-load="false">
|
||||
</vn-crud-model>
|
||||
|
||||
<form name="form">
|
||||
<div margin-medium>
|
||||
<vn-card margin-medium-v pad-medium>
|
||||
<vn-treeview vn-id="treeview" model="model"
|
||||
on-selection="$ctrl.onSelection(item, value)"
|
||||
on-create="$ctrl.onCreate(parent)"
|
||||
icons="$ctrl.icons" editable="true" acl-role="hr">
|
||||
</vn-treeview>
|
||||
</vn-card>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<vn-confirm
|
||||
vn-id="deleteNode"
|
||||
on-response="$ctrl.onRemoveResponse(response)"
|
||||
question="Delete department"
|
||||
message="Are you sure you want to delete it?">
|
||||
</vn-confirm>
|
||||
|
||||
<!-- Create department dialog -->
|
||||
<vn-dialog
|
||||
vn-id="createNode"
|
||||
on-open="$ctrl.onCreateDialogOpen()"
|
||||
on-response="$ctrl.onCreateResponse(response)">
|
||||
<tpl-body>
|
||||
<h5 pad-small-v translate>New department</h5>
|
||||
<vn-horizontal>
|
||||
<vn-textfield vn-one
|
||||
label="Name"
|
||||
model="$ctrl.newNode.name">
|
||||
</vn-textfield>
|
||||
</vn-horizontal>
|
||||
</tpl-body>
|
||||
<tpl-buttons>
|
||||
<input type="button" response="CANCEL" translate-attr="{value: 'Cancel'}"/>
|
||||
<button response="ACCEPT" translate>Create</button>
|
||||
</tpl-buttons>
|
||||
</vn-dialog>
|
|
@ -0,0 +1,78 @@
|
|||
import ngModule from '../module';
|
||||
|
||||
class Controller {
|
||||
constructor($scope, $http, vnApp, $translate) {
|
||||
this.$scope = $scope;
|
||||
this.$http = $http;
|
||||
this.vnApp = vnApp;
|
||||
this.$translate = $translate;
|
||||
this.params = {parentFk: 1};
|
||||
this.icons = [{icon: 'delete', tooltip: 'Delete', callback: this.onDelete}];
|
||||
this.newNode = {
|
||||
name: ''
|
||||
};
|
||||
}
|
||||
|
||||
onCreate(parent) {
|
||||
if (parent instanceof Object)
|
||||
this.newNode.parentFk = parent.id;
|
||||
|
||||
this.selectedNode = {parent};
|
||||
this.$scope.createNode.show();
|
||||
}
|
||||
|
||||
onDelete(item, parent, index) {
|
||||
this.selectedNode = {id: item.id, parent, index};
|
||||
this.$scope.deleteNode.show();
|
||||
}
|
||||
|
||||
onCreateDialogOpen() {
|
||||
this.newNode.name = '';
|
||||
}
|
||||
|
||||
onCreateResponse(response) {
|
||||
if (response == 'ACCEPT') {
|
||||
try {
|
||||
if (!this.newNode.name)
|
||||
throw new Error(`Name can't be empty`);
|
||||
|
||||
this.$http.post(`/worker/api/Departments/nodeAdd`, this.newNode).then(response => {
|
||||
if (response.data) {
|
||||
let parent = this.selectedNode.parent;
|
||||
if ((parent instanceof Object) && !(parent instanceof Array)) {
|
||||
const childs = parent.childs;
|
||||
childs.push(response.data);
|
||||
} else if ((parent instanceof Object) && (parent instanceof Array))
|
||||
parent.push(response.data);
|
||||
}
|
||||
});
|
||||
} catch (e) {
|
||||
this.vnApp.showError(this.$translate.instant(e.message));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
onRemoveResponse(response) {
|
||||
if (response === 'ACCEPT') {
|
||||
const path = `/worker/api/Departments/nodeDelete`;
|
||||
this.$http.post(path, {parentFk: this.selectedNode.id}).then(() => {
|
||||
let parent = this.selectedNode.parent;
|
||||
|
||||
if ((parent instanceof Object) && !(parent instanceof Array)) {
|
||||
const childs = parent.childs;
|
||||
childs.splice(this.selectedNode.index, 1);
|
||||
} else if ((parent instanceof Object) && (parent instanceof Array))
|
||||
parent.splice(this.selectedNode.index, 1);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Controller.$inject = ['$scope', '$http', 'vnApp', '$translate'];
|
||||
|
||||
ngModule.component('vnWorkerDepartment', {
|
||||
template: require('./index.html'),
|
||||
controller: Controller
|
||||
});
|
|
@ -0,0 +1,3 @@
|
|||
New department: Nuevo departamento
|
||||
Delete department: Eliminar departamento
|
||||
Are you sure you want to delete it?: ¿Seguro que quieres eliminarlo?
|
|
@ -7,3 +7,5 @@ import './descriptor';
|
|||
import './descriptor-popover';
|
||||
import './search-panel';
|
||||
import './basic-data';
|
||||
import './pbx';
|
||||
import './department';
|
||||
|
|
|
@ -8,17 +8,30 @@
|
|||
<div class="content-block">
|
||||
<div class="vn-list">
|
||||
<vn-card pad-medium-h>
|
||||
<vn-searchbar
|
||||
panel="vn-worker-search-panel"
|
||||
on-search="$ctrl.onSearch($params)"
|
||||
vn-focus>
|
||||
</vn-searchbar>
|
||||
<vn-horizontal>
|
||||
<vn-searchbar
|
||||
style="width: 100%"
|
||||
panel="vn-worker-search-panel"
|
||||
on-search="$ctrl.onSearch($params)"
|
||||
vn-focus>
|
||||
</vn-searchbar>
|
||||
<vn-icon-menu
|
||||
vn-id="more-button"
|
||||
icon="more_vert"
|
||||
show-filter="false"
|
||||
value-field="callback"
|
||||
translate-fields="['name']"
|
||||
data="$ctrl.moreOptions"
|
||||
on-change="$ctrl.onMoreChange(value)">
|
||||
</vn-icon-menu>
|
||||
</vn-horizontal>
|
||||
</vn-card>
|
||||
<vn-card margin-medium-v>
|
||||
<a ng-repeat="worker in workers track by worker.id"
|
||||
<a
|
||||
ng-repeat="worker in workers track by worker.id"
|
||||
ui-sref="worker.card.summary({id: worker.id})"
|
||||
translate-attr="{title: 'View worker'}"
|
||||
class="vn-list-item">
|
||||
class="vn-list-item searchResult">
|
||||
<vn-horizontal>
|
||||
<vn-one>
|
||||
<h6>{{::worker.nickname}}</h6>
|
||||
|
|
|
@ -1,11 +1,16 @@
|
|||
import ngModule from '../module';
|
||||
import './style.scss';
|
||||
|
||||
export default class Controller {
|
||||
constructor($) {
|
||||
constructor($, $state) {
|
||||
this.$state = $state;
|
||||
Object.assign(this, {
|
||||
$,
|
||||
selectedWorker: null,
|
||||
});
|
||||
this.moreOptions = [
|
||||
{callback: () => this.$state.go('worker.department'), name: 'Departments'}
|
||||
];
|
||||
}
|
||||
|
||||
onSearch(params) {
|
||||
|
@ -22,9 +27,13 @@ export default class Controller {
|
|||
this.$.preview.show();
|
||||
event.stopImmediatePropagation();
|
||||
}
|
||||
|
||||
onMoreChange(callback) {
|
||||
callback.call(this);
|
||||
}
|
||||
}
|
||||
|
||||
Controller.$inject = ['$scope'];
|
||||
Controller.$inject = ['$scope', '$state'];
|
||||
|
||||
ngModule.component('vnWorkerIndex', {
|
||||
template: require('./index.html'),
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
@import "variables";
|
||||
|
||||
vn-worker-index vn-icon-menu {
|
||||
padding-top: 30px;
|
||||
padding-left: 10px;
|
||||
color: $color-main;
|
||||
|
||||
li {
|
||||
color: initial;
|
||||
}
|
||||
}
|
|
@ -8,7 +8,9 @@ User id: Id de usuario
|
|||
Role: Rol
|
||||
Extension: Extensión
|
||||
Go to client: Ir al cliente
|
||||
Private Branch Exchange: Centralita
|
||||
View worker: Ver trabajador
|
||||
Worker id: Id trabajador
|
||||
Fiscal Identifier: NIF
|
||||
User name: Usuario
|
||||
Departments: Departamentos
|
|
@ -0,0 +1,28 @@
|
|||
<mg-ajax path="/api/Sips/{{patch.params.id}}" options="vnPatch"></mg-ajax>
|
||||
<vn-watcher
|
||||
vn-id="watcher"
|
||||
data="$ctrl.worker.sip"
|
||||
form="form"
|
||||
save="patch">
|
||||
</vn-watcher>
|
||||
<form name="form" ng-submit="watcher.submit()" compact>
|
||||
<vn-card pad-large>
|
||||
<vn-vertical>
|
||||
<vn-horizontal>
|
||||
<vn-textfield
|
||||
vn-one
|
||||
label="Extension"
|
||||
model="$ctrl.worker.sip.extension">
|
||||
</vn-textfield>
|
||||
<vn-textfield
|
||||
vn-one
|
||||
label="Password"
|
||||
model="$ctrl.worker.sip.secret">
|
||||
</vn-textfield>
|
||||
</vn-horizontal>
|
||||
</vn-vertical>
|
||||
</vn-card>
|
||||
<vn-button-bar>
|
||||
<vn-submit label="Save"></vn-submit>
|
||||
</vn-button-bar>
|
||||
</form>
|
|
@ -0,0 +1,8 @@
|
|||
import ngModule from '../module';
|
||||
|
||||
ngModule.component('vnWorkerPbx', {
|
||||
template: require('./index.html'),
|
||||
bindings: {
|
||||
worker: '<'
|
||||
}
|
||||
});
|
|
@ -4,7 +4,8 @@
|
|||
"icon" : "icon-worker",
|
||||
"validations" : true,
|
||||
"menu": [
|
||||
{"state": "worker.card.basicData", "icon": "settings"}
|
||||
{"state": "worker.card.basicData", "icon": "settings"},
|
||||
{"state": "worker.card.pbx", "icon": ""}
|
||||
],
|
||||
"routes": [
|
||||
{
|
||||
|
@ -32,7 +33,8 @@
|
|||
"component": "vn-worker-card",
|
||||
"abstract": true,
|
||||
"description": "Detail"
|
||||
}, {
|
||||
},
|
||||
{
|
||||
"url": "/basic-data",
|
||||
"state": "worker.card.basicData",
|
||||
"component": "vn-worker-basic-data",
|
||||
|
@ -41,6 +43,21 @@
|
|||
"worker": "$ctrl.worker"
|
||||
},
|
||||
"acl": ["developer"]
|
||||
}, {
|
||||
"url": "/pbx",
|
||||
"state": "worker.card.pbx",
|
||||
"component": "vn-worker-pbx",
|
||||
"description": "Private Branch Exchange",
|
||||
"params": {
|
||||
"worker": "$ctrl.worker"
|
||||
},
|
||||
"acl": ["hr"]
|
||||
},
|
||||
{
|
||||
"url" : "/department",
|
||||
"state": "worker.department",
|
||||
"component": "vn-worker-department",
|
||||
"description": "Departments"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -2735,15 +2735,6 @@
|
|||
"integrity": "sha1-FopHAXVran9RoSzgyXv6KMCE7WM=",
|
||||
"dev": true
|
||||
},
|
||||
"combine-lists": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/combine-lists/-/combine-lists-1.0.1.tgz",
|
||||
"integrity": "sha1-RYwH4J4NkA/Ci3Cj/sLazR0st/Y=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"lodash": "^4.5.0"
|
||||
}
|
||||
},
|
||||
"combined-stream": {
|
||||
"version": "1.0.7",
|
||||
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.7.tgz",
|
||||
|
@ -2886,6 +2877,18 @@
|
|||
"xdg-basedir": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"connect": {
|
||||
"version": "3.6.6",
|
||||
"resolved": "https://registry.npmjs.org/connect/-/connect-3.6.6.tgz",
|
||||
"integrity": "sha1-Ce/2xVr3I24TcTWnJXSFi2eG9SQ=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"debug": "2.6.9",
|
||||
"finalhandler": "1.1.0",
|
||||
"parseurl": "~1.3.2",
|
||||
"utils-merge": "1.0.1"
|
||||
}
|
||||
},
|
||||
"connect-history-api-fallback": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-1.5.0.tgz",
|
||||
|
@ -3287,9 +3290,9 @@
|
|||
"integrity": "sha1-bYCcnNDPe7iVLYD8hPoT1H3bEwg="
|
||||
},
|
||||
"date-format": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/date-format/-/date-format-1.2.0.tgz",
|
||||
"integrity": "sha1-YV6CjiM90aubua4JUODOzPpuytg=",
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/date-format/-/date-format-2.0.0.tgz",
|
||||
"integrity": "sha512-M6UqVvZVgFYqZL1SfHsRGIQSz3ZL+qgbsV5Lp1Vj61LZVYuEwcMXYay7DRDtYs2HQQBK5hQtQ0fD9aEJ89V0LA==",
|
||||
"dev": true
|
||||
},
|
||||
"date-now": {
|
||||
|
@ -4442,40 +4445,6 @@
|
|||
"integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=",
|
||||
"dev": true
|
||||
},
|
||||
"expand-braces": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/expand-braces/-/expand-braces-0.1.2.tgz",
|
||||
"integrity": "sha1-SIsdHSRRyz06axks/AMPRMWFX+o=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"array-slice": "^0.2.3",
|
||||
"array-unique": "^0.2.1",
|
||||
"braces": "^0.1.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"array-slice": {
|
||||
"version": "0.2.3",
|
||||
"resolved": "https://registry.npmjs.org/array-slice/-/array-slice-0.2.3.tgz",
|
||||
"integrity": "sha1-3Tz7gO15c6dRF82sabC5nshhhvU=",
|
||||
"dev": true
|
||||
},
|
||||
"array-unique": {
|
||||
"version": "0.2.1",
|
||||
"resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz",
|
||||
"integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=",
|
||||
"dev": true
|
||||
},
|
||||
"braces": {
|
||||
"version": "0.1.5",
|
||||
"resolved": "https://registry.npmjs.org/braces/-/braces-0.1.5.tgz",
|
||||
"integrity": "sha1-wIVxEIUpHYt1/ddOqw+FlygHEeY=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"expand-range": "^0.1.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"expand-brackets": {
|
||||
"version": "2.1.4",
|
||||
"resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz",
|
||||
|
@ -4511,30 +4480,6 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"expand-range": {
|
||||
"version": "0.1.1",
|
||||
"resolved": "http://registry.npmjs.org/expand-range/-/expand-range-0.1.1.tgz",
|
||||
"integrity": "sha1-TLjtoJk8pW+k9B/ELzy7TMrf8EQ=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-number": "^0.1.1",
|
||||
"repeat-string": "^0.2.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"is-number": {
|
||||
"version": "0.1.1",
|
||||
"resolved": "https://registry.npmjs.org/is-number/-/is-number-0.1.1.tgz",
|
||||
"integrity": "sha1-aaevEWlj1HIG7JvZtIoUIW8eOAY=",
|
||||
"dev": true
|
||||
},
|
||||
"repeat-string": {
|
||||
"version": "0.2.2",
|
||||
"resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-0.2.2.tgz",
|
||||
"integrity": "sha1-x6jTI2BoNiBZp+RlH8aITosftK4=",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"expand-tilde": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz",
|
||||
|
@ -4932,6 +4877,29 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"finalhandler": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.0.tgz",
|
||||
"integrity": "sha1-zgtoVbRYU+eRsvzGgARtiCU91/U=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"debug": "2.6.9",
|
||||
"encodeurl": "~1.0.1",
|
||||
"escape-html": "~1.0.3",
|
||||
"on-finished": "~2.3.0",
|
||||
"parseurl": "~1.3.2",
|
||||
"statuses": "~1.3.1",
|
||||
"unpipe": "~1.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"statuses": {
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz",
|
||||
"integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4=",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"find-cache-dir": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-1.0.0.tgz",
|
||||
|
@ -7729,28 +7697,27 @@
|
|||
"dev": true
|
||||
},
|
||||
"karma": {
|
||||
"version": "3.1.4",
|
||||
"resolved": "https://registry.npmjs.org/karma/-/karma-3.1.4.tgz",
|
||||
"integrity": "sha512-31Vo8Qr5glN+dZEVIpnPCxEGleqE0EY6CtC2X9TagRV3rRQ3SNrvfhddICkJgUK3AgqpeKSZau03QumTGhGoSw==",
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/karma/-/karma-4.0.1.tgz",
|
||||
"integrity": "sha512-ind+4s03BqIXas7ZmraV3/kc5+mnqwCd+VDX1FndS6jxbt03kQKX2vXrWxNLuCjVYmhMwOZosAEKMM0a2q7w7A==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"bluebird": "^3.3.0",
|
||||
"body-parser": "^1.16.1",
|
||||
"braces": "^2.3.2",
|
||||
"chokidar": "^2.0.3",
|
||||
"colors": "^1.1.0",
|
||||
"combine-lists": "^1.0.0",
|
||||
"connect": "^3.6.0",
|
||||
"core-js": "^2.2.0",
|
||||
"di": "^0.0.1",
|
||||
"dom-serialize": "^2.2.0",
|
||||
"expand-braces": "^0.1.1",
|
||||
"flatted": "^2.0.0",
|
||||
"glob": "^7.1.1",
|
||||
"graceful-fs": "^4.1.2",
|
||||
"http-proxy": "^1.13.0",
|
||||
"isbinaryfile": "^3.0.0",
|
||||
"lodash": "^4.17.5",
|
||||
"log4js": "^3.0.0",
|
||||
"lodash": "^4.17.11",
|
||||
"log4js": "^4.0.0",
|
||||
"mime": "^2.3.1",
|
||||
"minimatch": "^3.0.2",
|
||||
"optimist": "^0.6.1",
|
||||
|
@ -7764,33 +7731,6 @@
|
|||
"useragent": "2.3.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"connect": {
|
||||
"version": "3.6.6",
|
||||
"resolved": "https://registry.npmjs.org/connect/-/connect-3.6.6.tgz",
|
||||
"integrity": "sha1-Ce/2xVr3I24TcTWnJXSFi2eG9SQ=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"debug": "2.6.9",
|
||||
"finalhandler": "1.1.0",
|
||||
"parseurl": "~1.3.2",
|
||||
"utils-merge": "1.0.1"
|
||||
}
|
||||
},
|
||||
"finalhandler": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.0.tgz",
|
||||
"integrity": "sha1-zgtoVbRYU+eRsvzGgARtiCU91/U=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"debug": "2.6.9",
|
||||
"encodeurl": "~1.0.1",
|
||||
"escape-html": "~1.0.3",
|
||||
"on-finished": "~2.3.0",
|
||||
"parseurl": "~1.3.2",
|
||||
"statuses": "~1.3.1",
|
||||
"unpipe": "~1.0.0"
|
||||
}
|
||||
},
|
||||
"glob": {
|
||||
"version": "7.1.3",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz",
|
||||
|
@ -7805,12 +7745,6 @@
|
|||
"path-is-absolute": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"lodash": {
|
||||
"version": "4.17.11",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz",
|
||||
"integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==",
|
||||
"dev": true
|
||||
},
|
||||
"mime": {
|
||||
"version": "2.4.0",
|
||||
"resolved": "https://registry.npmjs.org/mime/-/mime-2.4.0.tgz",
|
||||
|
@ -7822,18 +7756,6 @@
|
|||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
|
||||
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
|
||||
"dev": true
|
||||
},
|
||||
"statuses": {
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz",
|
||||
"integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4=",
|
||||
"dev": true
|
||||
},
|
||||
"utils-merge": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
|
||||
"integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -8259,24 +8181,18 @@
|
|||
}
|
||||
},
|
||||
"log4js": {
|
||||
"version": "3.0.6",
|
||||
"resolved": "https://registry.npmjs.org/log4js/-/log4js-3.0.6.tgz",
|
||||
"integrity": "sha512-ezXZk6oPJCWL483zj64pNkMuY/NcRX5MPiB0zE6tjZM137aeusrOnW1ecxgF9cmwMWkBMhjteQxBPoZBh9FDxQ==",
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/log4js/-/log4js-4.0.2.tgz",
|
||||
"integrity": "sha512-KE7HjiieVDPPdveA3bJZSuu0n8chMkFl8mIoisBFxwEJ9FmXe4YzNuiqSwYUiR1K8q8/5/8Yd6AClENY1RA9ww==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"circular-json": "^0.5.5",
|
||||
"date-format": "^1.2.0",
|
||||
"date-format": "^2.0.0",
|
||||
"debug": "^3.1.0",
|
||||
"flatted": "^2.0.0",
|
||||
"rfdc": "^1.1.2",
|
||||
"streamroller": "0.7.0"
|
||||
"streamroller": "^1.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"circular-json": {
|
||||
"version": "0.5.9",
|
||||
"resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.5.9.tgz",
|
||||
"integrity": "sha512-4ivwqHpIFJZBuhN3g/pEcdbnGUywkBblloGbkglyloVjjR3uT6tieI89MVOfbP2tHX5sgb01FuLgAOzebNlJNQ==",
|
||||
"dev": true
|
||||
},
|
||||
"debug": {
|
||||
"version": "3.2.6",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
|
||||
|
@ -12918,7 +12834,6 @@
|
|||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.2.tgz",
|
||||
"integrity": "sha512-UHYyq1MO8GsefGEt7EprS8UrXsm1TxEvFUX1IMTuSLU2Rh7fTIdFtl8xD7JiEYiWU2dl+NYAjCTksTehQUxPag==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"lodash": "^4.17.11"
|
||||
}
|
||||
|
@ -12927,7 +12842,6 @@
|
|||
"version": "1.0.7",
|
||||
"resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.7.tgz",
|
||||
"integrity": "sha512-rIMnbBdgNViL37nZ1b3L/VfPOpSi0TqVDQPAvO6U14lMzOLrt5nilxCQqtDKhZeDiW0/hkCXGoQjhgJd/tCh6w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"request-promise-core": "1.1.2",
|
||||
"stealthy-require": "^1.1.1",
|
||||
|
@ -14070,8 +13984,7 @@
|
|||
"stealthy-require": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz",
|
||||
"integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=",
|
||||
"dev": true
|
||||
"integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks="
|
||||
},
|
||||
"stream-browserify": {
|
||||
"version": "2.0.2",
|
||||
|
@ -14164,17 +14077,27 @@
|
|||
"dev": true
|
||||
},
|
||||
"streamroller": {
|
||||
"version": "0.7.0",
|
||||
"resolved": "https://registry.npmjs.org/streamroller/-/streamroller-0.7.0.tgz",
|
||||
"integrity": "sha512-WREzfy0r0zUqp3lGO096wRuUp7ho1X6uo/7DJfTlEi0Iv/4gT7YHqXDjKC2ioVGBZtE8QzsQD9nx1nIuoZ57jQ==",
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/streamroller/-/streamroller-1.0.3.tgz",
|
||||
"integrity": "sha512-P7z9NwP51EltdZ81otaGAN3ob+/F88USJE546joNq7bqRNTe6jc74fTBDyynxP4qpIfKlt/CesEYicuMzI0yJg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"date-format": "^1.2.0",
|
||||
"async": "^2.6.1",
|
||||
"date-format": "^2.0.0",
|
||||
"debug": "^3.1.0",
|
||||
"mkdirp": "^0.5.1",
|
||||
"readable-stream": "^2.3.0"
|
||||
"fs-extra": "^7.0.0",
|
||||
"lodash": "^4.17.10"
|
||||
},
|
||||
"dependencies": {
|
||||
"async": {
|
||||
"version": "2.6.2",
|
||||
"resolved": "https://registry.npmjs.org/async/-/async-2.6.2.tgz",
|
||||
"integrity": "sha512-H1qVYh1MYhEEFLsP97cVKqCGo7KfCyTt6uEWqsTBr9SO84oK9Uwbyd/yCW+6rKJLHksBNUVWZDAjfS+Ccx0Bbg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"lodash": "^4.17.11"
|
||||
}
|
||||
},
|
||||
"debug": {
|
||||
"version": "3.2.6",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
|
||||
|
@ -14184,6 +14107,17 @@
|
|||
"ms": "^2.1.1"
|
||||
}
|
||||
},
|
||||
"fs-extra": {
|
||||
"version": "7.0.1",
|
||||
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz",
|
||||
"integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"graceful-fs": "^4.1.2",
|
||||
"jsonfile": "^4.0.0",
|
||||
"universalify": "^0.1.0"
|
||||
}
|
||||
},
|
||||
"ms": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
|
||||
|
@ -15532,6 +15466,12 @@
|
|||
"integrity": "sha1-ihagXURWV6Oupe7MWxKk+lN5dyw=",
|
||||
"dev": true
|
||||
},
|
||||
"utils-merge": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
|
||||
"integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=",
|
||||
"dev": true
|
||||
},
|
||||
"uuid": {
|
||||
"version": "3.3.2",
|
||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz",
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue