diff --git a/README.md b/README.md
index a3394cc84..b3cc9fdbe 100644
--- a/README.md
+++ b/README.md
@@ -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.
diff --git a/db/connect.tpl.ini b/db/config.ini
similarity index 100%
rename from db/connect.tpl.ini
rename to db/config.ini
index 2db13e969..cf1f36d7c 100644
--- a/db/connect.tpl.ini
+++ b/db/config.ini
@@ -1,7 +1,7 @@
[client]
-enable_cleartext_plugin = ON
host = localhost
port = 3306
user = root
password = password
ssl-mode = DISABLED
+enable_cleartext_plugin = ON
diff --git a/db/import-changes.sh b/db/import-changes.sh
index d1fb0aca8..de963674f 100755
--- a/db/import-changes.sh
+++ b/db/import-changes.sh
@@ -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
diff --git a/db/install/boot.sh b/db/install/boot.sh
index 02727e089..ebfdae87f 100755
--- a/db/install/boot.sh
+++ b/db/install/boot.sh
@@ -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"
diff --git a/db/install/changes/0-ACL.sql b/db/install/changes/0-ACL.sql
new file mode 100644
index 000000000..a2f3991f1
--- /dev/null
+++ b/db/install/changes/0-ACL.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');
diff --git a/db/install/changes/1-orderGetTotal.sql b/db/install/changes/1-orderGetTotal.sql
index dbbc990f2..9c47db108 100644
--- a/db/install/changes/1-orderGetTotal.sql
+++ b/db/install/changes/1-orderGetTotal.sql
@@ -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.
diff --git a/db/install/changes/11-ticketCalculateSale.sql b/db/install/changes/11-ticketCalculateSale.sql
new file mode 100644
index 000000000..3f0f424da
--- /dev/null
+++ b/db/install/changes/11-ticketCalculateSale.sql
@@ -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 ;
\ No newline at end of file
diff --git a/db/install/changes/12-department.sql b/db/install/changes/12-department.sql
new file mode 100644
index 000000000..4203b059e
--- /dev/null
+++ b/db/install/changes/12-department.sql
@@ -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`; */
\ No newline at end of file
diff --git a/db/install/changes/12-ticketGetProblems.sql b/db/install/changes/12-ticketGetProblems.sql
new file mode 100644
index 000000000..7355517f2
--- /dev/null
+++ b/db/install/changes/12-ticketGetProblems.sql
@@ -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 ;
diff --git a/db/install/changes/13-nodeAdd.sql b/db/install/changes/13-nodeAdd.sql
new file mode 100644
index 000000000..f3f4381f3
--- /dev/null
+++ b/db/install/changes/13-nodeAdd.sql
@@ -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 ;
+ */
\ No newline at end of file
diff --git a/db/install/changes/14-basketGetTax.sql b/db/install/changes/14-basketGetTax.sql
new file mode 100644
index 000000000..f74623275
--- /dev/null
+++ b/db/install/changes/14-basketGetTax.sql
@@ -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 ;
diff --git a/db/install/changes/14-nodeRecalc.sql b/db/install/changes/14-nodeRecalc.sql
new file mode 100644
index 000000000..73f3042c4
--- /dev/null
+++ b/db/install/changes/14-nodeRecalc.sql
@@ -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 ;
+ */
\ No newline at end of file
diff --git a/db/install/changes/15-ticketLog.sql b/db/install/changes/15-ticketLog.sql
new file mode 100644
index 000000000..e4d5c9e98
--- /dev/null
+++ b/db/install/changes/15-ticketLog.sql
@@ -0,0 +1 @@
+ALTER TABLE vn.itemLog MODIFY COLUMN userFk int(10) unsigned NULL;
diff --git a/db/install/changes/15-zoneGeo.sql b/db/install/changes/15-zoneGeo.sql
new file mode 100644
index 000000000..1037fe089
--- /dev/null
+++ b/db/install/changes/15-zoneGeo.sql
@@ -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);
\ No newline at end of file
diff --git a/db/install/changes/16-itemLog.sql b/db/install/changes/16-itemLog.sql
new file mode 100644
index 000000000..f6d028dab
--- /dev/null
+++ b/db/install/changes/16-itemLog.sql
@@ -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;
diff --git a/db/install/changes/7-clientAfterInsert.sql b/db/install/changes/7-clientAfterInsert.sql
index 2c9033b31..b8b51b5c5 100644
--- a/db/install/changes/7-clientAfterInsert.sql
+++ b/db/install/changes/7-clientAfterInsert.sql
@@ -1,3 +1,3 @@
/* Añadir a producción cuando se suba salix */
-DROP TRIGGER vn2008.ClientesAfterInsert;
+DROP TRIGGER IF EXISTS vn2008.ClientesAfterInsert;
diff --git a/db/install/changes/8-clientAfterUpdate.sql b/db/install/changes/8-clientAfterUpdate.sql
index cfbd145da..385db8739 100644
--- a/db/install/changes/8-clientAfterUpdate.sql
+++ b/db/install/changes/8-clientAfterUpdate.sql
@@ -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 ;
diff --git a/db/install/dump/fixtures.sql b/db/install/dump/fixtures.sql
index 2488c231b..ea867559a 100644
--- a/db/install/dump/fixtures.sql
+++ b/db/install/dump/fixtures.sql
@@ -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)),
diff --git a/db/install/dump/truncateAll.sql b/db/install/dump/truncateAll.sql
deleted file mode 100644
index 9135f7860..000000000
--- a/db/install/dump/truncateAll.sql
+++ /dev/null
@@ -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 ;
\ No newline at end of file
diff --git a/e2e/helpers/selectors.js b/e2e/helpers/selectors.js
index a37d63854..330d2f0b0 100644
--- a/e2e/helpers/selectors.js
+++ b/e2e/helpers/selectors.js
@@ -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'
+ }
};
diff --git a/e2e/paths/client-module/04_edit_pay_method.spec.js b/e2e/paths/client-module/04_edit_pay_method.spec.js
index a8b58ca11..c315371e0 100644
--- a/e2e/paths/client-module/04_edit_pay_method.spec.js
+++ b/e2e/paths/client-module/04_edit_pay_method.spec.js
@@ -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');
diff --git a/e2e/paths/item-module/10_item_index.spec.js b/e2e/paths/item-module/10_item_index.spec.js
new file mode 100644
index 000000000..850a9273c
--- /dev/null
+++ b/e2e/paths/item-module/10_item_index.spec.js
@@ -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();
+ });
+});
diff --git a/e2e/paths/item-module/11_inactive.spec.js b/e2e/paths/item-module/11_inactive.spec.js
new file mode 100644
index 000000000..cdc9d7e65
--- /dev/null
+++ b/e2e/paths/item-module/11_inactive.spec.js
@@ -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!');
+ });
+});
diff --git a/e2e/paths/ticket-module/13_create_ticket_services.spec.js b/e2e/paths/ticket-module/13_create_ticket_services.spec.js
index 394b7cd9f..0b1c08463 100644
--- a/e2e/paths/ticket-module/13_create_ticket_services.spec.js
+++ b/e2e/paths/ticket-module/13_create_ticket_services.spec.js
@@ -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
diff --git a/e2e/paths/worker-module/01_pbx.spec.js b/e2e/paths/worker-module/01_pbx.spec.js
new file mode 100644
index 000000000..e7e97f9b1
--- /dev/null
+++ b/e2e/paths/worker-module/01_pbx.spec.js
@@ -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!');
+ });
+});
diff --git a/front/core/components/input-time/index.html b/front/core/components/input-time/index.html
index c189168d3..d4689ecf5 100644
--- a/front/core/components/input-time/index.html
+++ b/front/core/components/input-time/index.html
@@ -6,7 +6,7 @@
+
-
+
-
-
+
+
- {{::item.name}}
+ {{::item.name}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Create new one
-
\ No newline at end of file
diff --git a/front/core/components/treeview/child.js b/front/core/components/treeview/child.js
index b5bdb67e5..ca5b59efb 100644
--- a/front/core/components/treeview/child.js
+++ b/front/core/components/treeview/child.js
@@ -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'
diff --git a/front/core/components/treeview/index.html b/front/core/components/treeview/index.html
index 05c485fef..85a4e4b6b 100644
--- a/front/core/components/treeview/index.html
+++ b/front/core/components/treeview/index.html
@@ -1 +1,9 @@
-
+
+
diff --git a/front/core/components/treeview/index.js b/front/core/components/treeview/index.js
index 0737bf8cb..9f2a0a3fa 100644
--- a/front/core/components/treeview/index.js
+++ b/front/core/components/treeview/index.js
@@ -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: '@?'
}
});
diff --git a/front/core/components/treeview/style.scss b/front/core/components/treeview/style.scss
index 317d85453..ce51fe482 100644
--- a/front/core/components/treeview/style.scss
+++ b/front/core/components/treeview/style.scss
@@ -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
+ }
}
diff --git a/front/core/directives/acl.js b/front/core/directives/acl.js
index 2ff35a87f..46e8c582e 100644
--- a/front/core/directives/acl.js
+++ b/front/core/directives/acl.js
@@ -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];
}
});
diff --git a/front/core/locale/es.yml b/front/core/locale/es.yml
index 2a5af89ce..7c413dd22 100644
--- a/front/core/locale/es.yml
+++ b/front/core/locale/es.yml
@@ -39,4 +39,6 @@ November: Noviembre
December: Diciembre
Has delivery: Hay reparto
Loading: Cargando
-Fields to show: Campos a mostrar
\ No newline at end of file
+Fields to show: Campos a mostrar
+Create new one: Crear nuevo
+Toggle: Desplegar/Plegar
\ No newline at end of file
diff --git a/front/salix/components/user-configuration-popover/index.html b/front/salix/components/user-configuration-popover/index.html
index 3fe9a40a5..7761fcc4c 100644
--- a/front/salix/components/user-configuration-popover/index.html
+++ b/front/salix/components/user-configuration-popover/index.html
@@ -1,9 +1,3 @@
-
-
+ value-field="id"
+ search-function="{or: [{id: $search}, {bank: {like: '%'+ $search +'%'}}]}">
{{id}}: {{bank}}
{
+ 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');
});
},
diff --git a/loopback/locale/en.json b/loopback/locale/en.json
index 84c2bba4c..f18137966 100644
--- a/loopback/locale/en.json
+++ b/loopback/locale/en.json
@@ -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"
}
\ No newline at end of file
diff --git a/loopback/locale/es.json b/loopback/locale/es.json
index 05e100fb7..d4f3733b0 100644
--- a/loopback/locale/es.json
+++ b/loopback/locale/es.json
@@ -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"
}
\ No newline at end of file
diff --git a/modules/agency/back/methods/zone-geo/getLeaves.js b/modules/agency/back/methods/zone-geo/getLeaves.js
index 64bb68318..7209f5268 100644
--- a/modules/agency/back/methods/zone-geo/getLeaves.js
+++ b/modules/agency/back/methods/zone-geo/getLeaves.js
@@ -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);
diff --git a/modules/agency/back/models/zone.json b/modules/agency/back/models/zone.json
index 5c297f766..dae8a2925 100644
--- a/modules/agency/back/models/zone.json
+++ b/modules/agency/back/models/zone.json
@@ -30,6 +30,10 @@
"bonus": {
"type": "Number",
"required": true
+ },
+ "isVolumetric": {
+ "type": "Boolean",
+ "required": true
}
},
"relations": {
diff --git a/modules/agency/front/basic-data/index.html b/modules/agency/front/basic-data/index.html
index 28ec35377..434322d14 100644
--- a/modules/agency/front/basic-data/index.html
+++ b/modules/agency/front/basic-data/index.html
@@ -62,6 +62,9 @@
display-controls="false">
+
+
+
diff --git a/modules/agency/front/create/index.html b/modules/agency/front/create/index.html
index ac6b76efd..124c4e482 100644
--- a/modules/agency/front/create/index.html
+++ b/modules/agency/front/create/index.html
@@ -64,6 +64,9 @@
display-controls="false">
+
+
+
diff --git a/modules/agency/front/create/index.js b/modules/agency/front/create/index.js
index d10db3e3a..4aace46b7 100644
--- a/modules/agency/front/create/index.js
+++ b/modules/agency/front/create/index.js
@@ -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()
};
}
diff --git a/modules/agency/front/locale/es.yml b/modules/agency/front/locale/es.yml
index 17ef3e09a..3e3efd03e 100644
--- a/modules/agency/front/locale/es.yml
+++ b/modules/agency/front/locale/es.yml
@@ -6,4 +6,5 @@ Locations: Localizaciones
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
\ No newline at end of file
+New zone: Nueva zona
+Volumetric: Volumétrico
\ No newline at end of file
diff --git a/modules/agency/front/location/index.html b/modules/agency/front/location/index.html
index 4482ff52e..c33a71e3c 100644
--- a/modules/agency/front/location/index.html
+++ b/modules/agency/front/location/index.html
@@ -12,7 +12,7 @@
on-search="$ctrl.onSearch()"
vn-focus>
-
diff --git a/modules/client/back/methods/client/isValidClient.js b/modules/client/back/methods/client/isValidClient.js
index 583efa299..241121927 100644
--- a/modules/client/back/methods/client/isValidClient.js
+++ b/modules/client/back/methods/client/isValidClient.js
@@ -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;
};
};
diff --git a/modules/client/back/methods/client/specs/isValidClient.spec.js b/modules/client/back/methods/client/specs/isValidClient.spec.js
index f995bb7ab..446392374 100644
--- a/modules/client/back/methods/client/specs/isValidClient.spec.js
+++ b/modules/client/back/methods/client/specs/isValidClient.spec.js
@@ -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();
});
});
diff --git a/modules/client/back/models/client.js b/modules/client/back/models/client.js
index aa5f5cc0b..803e91605 100644
--- a/modules/client/back/models/client.js
+++ b/modules/client/back/models/client.js
@@ -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();
}
diff --git a/modules/client/front/billing-data/index.html b/modules/client/front/billing-data/index.html
index 300919acc..ce4748829 100644
--- a/modules/client/front/billing-data/index.html
+++ b/modules/client/front/billing-data/index.html
@@ -111,6 +111,12 @@
show-field="country">
+
+
+
+
{
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');
diff --git a/modules/client/front/billing-data/locale/es.yml b/modules/client/front/billing-data/locale/es.yml
index 78d970f5c..84de93695 100644
--- a/modules/client/front/billing-data/locale/es.yml
+++ b/modules/client/front/billing-data/locale/es.yml
@@ -15,4 +15,5 @@ Received B2B VNL: Recibido B2B VNL
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
\ No newline at end of file
+Swift / BIC can't be empty: El Swift / BIC no puede quedar vacío
+Code: Código
\ No newline at end of file
diff --git a/modules/item/back/methods/item/filter.js b/modules/item/back/methods/item/filter.js
index 0bea205e3..b71b3de1a 100644
--- a/modules/item/back/methods/item/filter.js
+++ b/modules/item/back/methods/item/filter.js
@@ -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, ';');
diff --git a/modules/item/back/methods/item/specs/new.spec.js b/modules/item/back/methods/item/specs/new.spec.js
index 793120514..007178c97 100644
--- a/modules/item/back/methods/item/specs/new.spec.js
+++ b/modules/item/back/methods/item/specs/new.spec.js
@@ -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();
});
diff --git a/modules/item/back/methods/item/updateTaxes.js b/modules/item/back/methods/item/updateTaxes.js
index bbf4dc0f1..9b7ffd372 100644
--- a/modules/item/back/methods/item/updateTaxes.js
+++ b/modules/item/back/methods/item/updateTaxes.js
@@ -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}
));
diff --git a/modules/item/back/models/item-barcode.json b/modules/item/back/models/item-barcode.json
index 324f23a6c..c2fa166e1 100644
--- a/modules/item/back/models/item-barcode.json
+++ b/modules/item/back/models/item-barcode.json
@@ -1,6 +1,11 @@
{
"name": "ItemBarcode",
- "base": "VnModel",
+ "base": "Loggable",
+ "log": {
+ "model": "ItemLog",
+ "relation": "item",
+ "changedModelValue": "code"
+ },
"options": {
"mysql": {
"table": "itemBarcode"
diff --git a/modules/item/back/models/item-botanical.json b/modules/item/back/models/item-botanical.json
index 655f0d48c..2a1234e36 100644
--- a/modules/item/back/models/item-botanical.json
+++ b/modules/item/back/models/item-botanical.json
@@ -1,6 +1,11 @@
{
"name": "ItemBotanical",
- "base": "VnModel",
+ "base": "Loggable",
+ "log": {
+ "model": "ItemLog",
+ "relation": "item",
+ "changedModelValue": "botanical"
+ },
"options": {
"mysql": {
"table": "itemBotanical"
diff --git a/modules/item/back/models/item-log.json b/modules/item/back/models/item-log.json
index 76fcc4104..b8e6f79a6 100644
--- a/modules/item/back/models/item-log.json
+++ b/modules/item/back/models/item-log.json
@@ -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"
- }
- ]
+ }
+ }
}
diff --git a/modules/item/back/models/item-niche.json b/modules/item/back/models/item-niche.json
index 74fae2faa..aadcab28e 100644
--- a/modules/item/back/models/item-niche.json
+++ b/modules/item/back/models/item-niche.json
@@ -1,6 +1,11 @@
{
"name": "ItemNiche",
- "base": "VnModel",
+ "base": "Loggable",
+ "log": {
+ "model": "ItemLog",
+ "relation": "item",
+ "changedModelValue": "code"
+ },
"options": {
"mysql": {
"table": "itemPlacement"
diff --git a/modules/item/back/models/item-tag.json b/modules/item/back/models/item-tag.json
index 2dae3b174..d68e1a299 100644
--- a/modules/item/back/models/item-tag.json
+++ b/modules/item/back/models/item-tag.json
@@ -1,6 +1,11 @@
{
"name": "ItemTag",
- "base": "VnModel",
+ "base": "Loggable",
+ "log": {
+ "model": "ItemLog",
+ "relation": "item",
+ "changedModelValue": "value"
+ },
"options": {
"mysql": {
"table": "itemTag"
diff --git a/modules/item/back/models/item.json b/modules/item/back/models/item.json
index 1ca2619e7..4496633e8 100644
--- a/modules/item/back/models/item.json
+++ b/modules/item/back/models/item.json
@@ -1,6 +1,9 @@
{
"name": "Item",
- "base": "VnModel",
+ "base": "Loggable",
+ "log": {
+ "model":"ItemLog"
+ },
"options": {
"mysql": {
"table": "item"
diff --git a/modules/item/front/history/index.html b/modules/item/front/history/index.html
deleted file mode 100644
index 83585f2b7..000000000
--- a/modules/item/front/history/index.html
+++ /dev/null
@@ -1,33 +0,0 @@
-
-
-
-
-
-
-
-
- Description
- Action
- Changed by
- Date
-
-
-
-
- {{::itemLog.description}}
- {{::itemLog.action}}
- {{::itemLog.user.name}}
- {{::itemLog.creationDate | dateTime:'dd/MM/yyyy HH:mm'}}
-
-
-
-
-
-
-
diff --git a/modules/item/front/history/index.js b/modules/item/front/history/index.js
deleted file mode 100644
index 910a4f488..000000000
--- a/modules/item/front/history/index.js
+++ /dev/null
@@ -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
-});
diff --git a/modules/item/front/index.js b/modules/item/front/index.js
index aacaffe85..d6b3e5703 100644
--- a/modules/item/front/index.js
+++ b/modules/item/front/index.js
@@ -11,7 +11,7 @@ import './data';
import './fetched-tags';
import './tags';
import './tax';
-// import './history';
+import './log';
import './last-entries';
import './niche';
import './botanical';
diff --git a/modules/item/front/log/index.html b/modules/item/front/log/index.html
new file mode 100644
index 000000000..3734ba056
--- /dev/null
+++ b/modules/item/front/log/index.html
@@ -0,0 +1,9 @@
+
+
+
\ No newline at end of file
diff --git a/modules/item/front/log/index.js b/modules/item/front/log/index.js
new file mode 100644
index 000000000..edb540760
--- /dev/null
+++ b/modules/item/front/log/index.js
@@ -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,
+});
diff --git a/modules/item/front/routes.json b/modules/item/front/routes.json
index 485bd2760..ec90aa2ba 100644
--- a/modules/item/front/routes.json
+++ b/modules/item/front/routes.json
@@ -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"
}
]
}
\ No newline at end of file
diff --git a/modules/item/front/search-panel/index.html b/modules/item/front/search-panel/index.html
index ba512c1d0..a31f79497 100644
--- a/modules/item/front/search-panel/index.html
+++ b/modules/item/front/search-panel/index.html
@@ -42,11 +42,6 @@
-
-
{
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));
diff --git a/modules/ticket/back/methods/sale/updateDiscount.js b/modules/ticket/back/methods/sale/updateDiscount.js
index 1c1db1927..e1793241b 100644
--- a/modules/ticket/back/methods/sale/updateDiscount.js
+++ b/modules/ticket/back/methods/sale/updateDiscount.js
@@ -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'});
diff --git a/modules/ticket/back/methods/ticket-tracking/changeState.js b/modules/ticket/back/methods/ticket-tracking/changeState.js
index e93eb25f3..f70ae93a5 100644
--- a/modules/ticket/back/methods/ticket-tracking/changeState.js
+++ b/modules/ticket/back/methods/ticket-tracking/changeState.js
@@ -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);
};
};
diff --git a/modules/ticket/back/methods/ticket/filter.js b/modules/ticket/back/methods/ticket/filter.js
index f05101d75..259fe5820 100644
--- a/modules/ticket/back/methods/ticket/filter.js
+++ b/modules/ticket/back/methods/ticket/filter.js
@@ -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
diff --git a/modules/ticket/back/methods/ticket/specs/filter.spec.js b/modules/ticket/back/methods/ticket/specs/filter.spec.js
index 5b27bd0dc..648cfe3ba 100644
--- a/modules/ticket/back/methods/ticket/specs/filter.spec.js
+++ b/modules/ticket/back/methods/ticket/specs/filter.spec.js
@@ -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);
diff --git a/modules/ticket/front/descriptor/index.js b/modules/ticket/front/descriptor/index.js
index d18063ef7..fdee19bec 100644
--- a/modules/ticket/front/descriptor/index.js
+++ b/modules/ticket/front/descriptor/index.js
@@ -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() {
diff --git a/modules/ticket/front/index/index.html b/modules/ticket/front/index/index.html
index 700fd9e87..3835ba6b2 100644
--- a/modules/ticket/front/index/index.html
+++ b/modules/ticket/front/index/index.html
@@ -52,10 +52,28 @@
ui-sref="ticket.card.summary({id: {{::ticket.id}}})">
+ vn-tooltip="{{ticket.hasTicketRequest}}"
+ icon="icon-100">
+
+
+
+
+
+
{{::ticket.id}}
diff --git a/modules/ticket/front/note/index.html b/modules/ticket/front/note/index.html
index ce177b4cb..bc808ce8e 100644
--- a/modules/ticket/front/note/index.html
+++ b/modules/ticket/front/note/index.html
@@ -35,12 +35,12 @@
rule="ticketObservation.description">
-
-
+
diff --git a/modules/ticket/front/package/index.html b/modules/ticket/front/package/index.html
index d8a25c11a..5baf0580c 100644
--- a/modules/ticket/front/package/index.html
+++ b/modules/ticket/front/package/index.html
@@ -39,12 +39,12 @@
ng-readonly="true">
-
-
+
diff --git a/modules/ticket/front/services/index.html b/modules/ticket/front/services/index.html
index ba50c4651..83b504021 100644
--- a/modules/ticket/front/services/index.html
+++ b/modules/ticket/front/services/index.html
@@ -27,12 +27,13 @@
model="service.quantity"
rule="TicketService.quantity">
-
-
+ display-controls="false">
+
{
- 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();
});
}
}
diff --git a/modules/worker/back/methods/department/getLeaves.js b/modules/worker/back/methods/department/getLeaves.js
new file mode 100644
index 000000000..a97dc4f1d
--- /dev/null
+++ b/modules/worker/back/methods/department/getLeaves.js
@@ -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;
+ };
+};
diff --git a/modules/worker/back/methods/department/nodeAdd.js b/modules/worker/back/methods/department/nodeAdd.js
new file mode 100644
index 000000000..bbbcd82ef
--- /dev/null
+++ b/modules/worker/back/methods/department/nodeAdd.js
@@ -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;
+ };
+};
diff --git a/modules/worker/back/methods/department/nodeDelete.js b/modules/worker/back/methods/department/nodeDelete.js
new file mode 100644
index 000000000..22cf5312c
--- /dev/null
+++ b/modules/worker/back/methods/department/nodeDelete.js
@@ -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);
+ };
+};
diff --git a/modules/worker/back/methods/worker/filter.js b/modules/worker/back/methods/worker/filter.js
index cd644730a..ff9068d56 100644
--- a/modules/worker/back/methods/worker/filter.js
+++ b/modules/worker/back/methods/worker/filter.js
@@ -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};
diff --git a/modules/worker/back/models/department.js b/modules/worker/back/models/department.js
new file mode 100644
index 000000000..99b470dbb
--- /dev/null
+++ b/modules/worker/back/models/department.js
@@ -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;
+ });
+};
diff --git a/modules/worker/front/card/index.js b/modules/worker/front/card/index.js
index 9b4f6f93f..fe8a57fb9 100644
--- a/modules/worker/front/card/index.js
+++ b/modules/worker/front/card/index.js
@@ -22,7 +22,9 @@ class Controller {
},
{
relation: 'sip',
- scope: {fields: ['extension']}
+ scope: {
+ fields: ['extension', 'secret']
+ }
}, {
relation: 'department',
scope: {
diff --git a/modules/worker/front/department/index.html b/modules/worker/front/department/index.html
new file mode 100644
index 000000000..7cf4bade7
--- /dev/null
+++ b/modules/worker/front/department/index.html
@@ -0,0 +1,45 @@
+
+
+
+
+
+
+
+
+
+
+
+ New department
+
+
+
+
+
+
+
+ Create
+
+
\ No newline at end of file
diff --git a/modules/worker/front/department/index.js b/modules/worker/front/department/index.js
new file mode 100644
index 000000000..99d65a478
--- /dev/null
+++ b/modules/worker/front/department/index.js
@@ -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
+});
diff --git a/modules/worker/front/department/locale/es.yml b/modules/worker/front/department/locale/es.yml
new file mode 100644
index 000000000..c481bf4a9
--- /dev/null
+++ b/modules/worker/front/department/locale/es.yml
@@ -0,0 +1,3 @@
+New department: Nuevo departamento
+Delete department: Eliminar departamento
+Are you sure you want to delete it?: ¿Seguro que quieres eliminarlo?
\ No newline at end of file
diff --git a/modules/worker/front/index.js b/modules/worker/front/index.js
index 79f374f30..512e712c2 100644
--- a/modules/worker/front/index.js
+++ b/modules/worker/front/index.js
@@ -7,3 +7,5 @@ import './descriptor';
import './descriptor-popover';
import './search-panel';
import './basic-data';
+import './pbx';
+import './department';
diff --git a/modules/worker/front/index/index.html b/modules/worker/front/index/index.html
index a6fdc511e..703c82edd 100644
--- a/modules/worker/front/index/index.html
+++ b/modules/worker/front/index/index.html
@@ -8,17 +8,30 @@
-
-
+
+
+
+
+
+
-
+ class="vn-list-item searchResult">
{{::worker.nickname}}
diff --git a/modules/worker/front/index/index.js b/modules/worker/front/index/index.js
index 333edcd4d..e554f9fa0 100644
--- a/modules/worker/front/index/index.js
+++ b/modules/worker/front/index/index.js
@@ -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'),
diff --git a/modules/worker/front/index/style.scss b/modules/worker/front/index/style.scss
new file mode 100644
index 000000000..f6ebf3828
--- /dev/null
+++ b/modules/worker/front/index/style.scss
@@ -0,0 +1,11 @@
+@import "variables";
+
+vn-worker-index vn-icon-menu {
+ padding-top: 30px;
+ padding-left: 10px;
+ color: $color-main;
+
+ li {
+ color: initial;
+ }
+}
\ No newline at end of file
diff --git a/modules/worker/front/locale/es.yml b/modules/worker/front/locale/es.yml
index fec7b0995..a7a47d654 100644
--- a/modules/worker/front/locale/es.yml
+++ b/modules/worker/front/locale/es.yml
@@ -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
\ No newline at end of file
diff --git a/modules/worker/front/pbx/index.html b/modules/worker/front/pbx/index.html
new file mode 100644
index 000000000..ed29e4450
--- /dev/null
+++ b/modules/worker/front/pbx/index.html
@@ -0,0 +1,28 @@
+
+
+
+
diff --git a/modules/worker/front/pbx/index.js b/modules/worker/front/pbx/index.js
new file mode 100644
index 000000000..70dcc9aef
--- /dev/null
+++ b/modules/worker/front/pbx/index.js
@@ -0,0 +1,8 @@
+import ngModule from '../module';
+
+ngModule.component('vnWorkerPbx', {
+ template: require('./index.html'),
+ bindings: {
+ worker: '<'
+ }
+});
diff --git a/modules/worker/front/routes.json b/modules/worker/front/routes.json
index cb2823484..73b503058 100644
--- a/modules/worker/front/routes.json
+++ b/modules/worker/front/routes.json
@@ -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"
}
]
}
\ No newline at end of file
diff --git a/package-lock.json b/package-lock.json
index 8b04fbf96..e774036c7 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -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",
diff --git a/package.json b/package.json
index 13ae9bd7f..a6ca2f697 100644
--- a/package.json
+++ b/package.json
@@ -60,7 +60,7 @@
"jasmine-reporters": "^2.3.2",
"jasmine-spec-reporter": "^4.2.1",
"json-loader": "^0.5.7",
- "karma": "^3.1.4",
+ "karma": "^4.0.1",
"karma-chrome-launcher": "^2.2.0",
"karma-firefox-launcher": "^1.1.0",
"karma-jasmine": "^2.0.1",
diff --git a/print/config/routes.json b/print/config/routes.json
index c8326effa..88365b1d0 100644
--- a/print/config/routes.json
+++ b/print/config/routes.json
@@ -11,7 +11,7 @@
{"type": "report", "name": "rpt-claim-pickup-order"},
{"type": "report", "name": "rpt-letter-debtor"},
{"type": "report", "name": "rpt-sepa-core"},
- {"type": "report", "name": "rpt-informe"},
+ {"type": "report", "name": "rpt-receipt"},
{"type": "static", "name": "email-header"},
{"type": "static", "name": "email-footer"},
{"type": "static", "name": "report-header"},
diff --git a/print/lib/reportEngine.js b/print/lib/reportEngine.js
index dccb18b4a..8c771c449 100644
--- a/print/lib/reportEngine.js
+++ b/print/lib/reportEngine.js
@@ -26,7 +26,8 @@ module.exports = {
const result = await this.preFetch(component, ctx);
const i18n = new VueI18n({
locale: 'es',
- fallbackLocale: 'es'
+ fallbackLocale: 'es',
+ silentTranslationWarn: true
});
const app = new Vue({i18n,
render: h => h(result.component)});
diff --git a/print/package-lock.json b/print/package-lock.json
index 65f4abb6f..2be86cc84 100644
--- a/print/package-lock.json
+++ b/print/package-lock.json
@@ -242,9 +242,9 @@
"integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk="
},
"denque": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/denque/-/denque-1.3.0.tgz",
- "integrity": "sha512-4SRaSj+PqmrS1soW5/Avd7eJIM2JJIqLLmwhRqIGleZM/8KwZq80njbSS2Iqas+6oARkSkLDHEk4mm78q3JlIg=="
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/denque/-/denque-1.4.0.tgz",
+ "integrity": "sha512-gh513ac7aiKrAgjiIBWZG0EASyDF9p4JMWwKA8YU5s9figrL5SRNEMT6FDynsegakuhWd1wVqTvqvqAoDxw7wQ=="
},
"dom-serializer": {
"version": "0.1.0",
@@ -690,9 +690,9 @@
"integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA=="
},
"lru-cache": {
- "version": "4.1.3",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.3.tgz",
- "integrity": "sha512-fFEhvcgzuIoJVUF8fYr5KR0YqxD238zgObTps31YdADwPPAp82a4M8TrckkWyx7ekNlf9aBcVn81cFwwXngrJA==",
+ "version": "4.1.5",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz",
+ "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==",
"requires": {
"pseudomap": "^1.0.2",
"yallist": "^2.1.2"
@@ -743,33 +743,26 @@
"optional": true
},
"mysql2": {
- "version": "1.6.4",
- "resolved": "https://registry.npmjs.org/mysql2/-/mysql2-1.6.4.tgz",
- "integrity": "sha512-ZYbYgK06HKfxU45tYYLfwW5gKt8BslfE7FGyULNrf2K2fh+DuEX+e0QKsd2ObpZkMILefaVn8hsakVsTFqravQ==",
+ "version": "1.6.5",
+ "resolved": "https://registry.npmjs.org/mysql2/-/mysql2-1.6.5.tgz",
+ "integrity": "sha512-zedaOOyb3msuuZcJJnxIX/EGOpmljDG7B+UevRH5lqcv+yhy9eCwkArBz8/AO+/rlY3/oCsOdG8R5oD6k0hNfg==",
"requires": {
- "denque": "1.3.0",
+ "denque": "^1.4.0",
"generate-function": "^2.3.1",
"iconv-lite": "^0.4.24",
"long": "^4.0.0",
- "lru-cache": "4.1.3",
- "named-placeholders": "1.1.1",
- "seq-queue": "0.0.5",
- "sqlstring": "2.3.1"
+ "lru-cache": "^4.1.3",
+ "named-placeholders": "^1.1.2",
+ "seq-queue": "^0.0.5",
+ "sqlstring": "^2.3.1"
}
},
"named-placeholders": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/named-placeholders/-/named-placeholders-1.1.1.tgz",
- "integrity": "sha1-O3oNJiA910s6nfTJz7gnsvuQfmQ=",
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/named-placeholders/-/named-placeholders-1.1.2.tgz",
+ "integrity": "sha512-wiFWqxoLL3PGVReSZpjLVxyJ1bRqe+KKJVbr4hGs1KWfTZTQyezHFBbuKj9hsizHyGV2ne7EMjHdxEGAybD5SA==",
"requires": {
- "lru-cache": "2.5.0"
- },
- "dependencies": {
- "lru-cache": {
- "version": "2.5.0",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.5.0.tgz",
- "integrity": "sha1-2COIrpyWC+y+oMc7uet5tsbOmus="
- }
+ "lru-cache": "^4.1.3"
}
},
"nice-try": {
@@ -1131,19 +1124,19 @@
}
},
"vue": {
- "version": "2.5.22",
- "resolved": "https://registry.npmjs.org/vue/-/vue-2.5.22.tgz",
- "integrity": "sha512-pxY3ZHlXNJMFQbkjEgGVMaMMkSV1ONpz+4qB55kZuJzyJOhn6MSy/YZdzhdnumegNzVTL/Dn3Pp4UrVBYt1j/g=="
+ "version": "2.6.7",
+ "resolved": "https://registry.npmjs.org/vue/-/vue-2.6.7.tgz",
+ "integrity": "sha512-g7ADfQ82QU+j6F/bVDioVQf2ccIMYLuR4E8ev+RsDBlmwRkhGO3HhgF4PF9vpwjdPpxyb1zzLur2nQ2oIMAMEg=="
},
"vue-i18n": {
- "version": "8.7.0",
- "resolved": "https://registry.npmjs.org/vue-i18n/-/vue-i18n-8.7.0.tgz",
- "integrity": "sha512-qey+OyZSUIje0xJW8HZrvpIss1jW8yBBRe+0QlUn7HENU31m/+Med/u4pcwjoeCaErHU9WMscBEhqK5aAvvEEQ=="
+ "version": "8.8.2",
+ "resolved": "https://registry.npmjs.org/vue-i18n/-/vue-i18n-8.8.2.tgz",
+ "integrity": "sha512-P09ZN2S0mX1AmhSR/+wP2owP3izGVx1pSoDFcOXTLya5xvP95dG7kc9LQUnboPgSzK/JKe9FkYmoYdDTKDjPSw=="
},
"vue-server-renderer": {
- "version": "2.5.22",
- "resolved": "https://registry.npmjs.org/vue-server-renderer/-/vue-server-renderer-2.5.22.tgz",
- "integrity": "sha512-PQ0PubA6b2MyZud/gepWeiUuDFSbRfa6h1qYINcbwXRr4Z3yLTHprEQuFnWikdkTkZpeLFYUqZrDxPbDcJ71mA==",
+ "version": "2.6.7",
+ "resolved": "https://registry.npmjs.org/vue-server-renderer/-/vue-server-renderer-2.6.7.tgz",
+ "integrity": "sha512-CVtGR+bE63y4kyIeOcCEF2UNKquSquFQAsTHZ5R1cGM4L4Z0BXgAUEcngTOy8kN+tubt3c1zpRvbrok/bHKeDg==",
"requires": {
"chalk": "^1.1.3",
"hash-sum": "^1.0.2",
diff --git a/print/package.json b/print/package.json
index 8c922b8a9..bb7c32a3e 100755
--- a/print/package.json
+++ b/print/package.json
@@ -16,11 +16,11 @@
"fs-extra": "^7.0.1",
"html-pdf": "^2.2.0",
"juice": "^5.0.1",
- "mysql2": "^1.6.1",
+ "mysql2": "^1.6.5",
"nodemailer": "^4.7.0",
"strftime": "^0.10.0",
- "vue": "^2.5.17",
- "vue-i18n": "^8.3.1",
- "vue-server-renderer": "^2.5.17"
+ "vue": "^2.6.7",
+ "vue-i18n": "^8.8.2",
+ "vue-server-renderer": "^2.6.7"
}
}
diff --git a/print/report/printer-setup/locale.js b/print/report/printer-setup/locale.js
index 34365cca7..2c5783007 100644
--- a/print/report/printer-setup/locale.js
+++ b/print/report/printer-setup/locale.js
@@ -10,8 +10,8 @@ module.exports = {
https://www.youtube.com/watch?v=qhb0kgQF3o8 .
También necesitarás el QLabel, el programa para imprimir las cintas.`,
downloadFrom: `Puedes descargarlo desde este enlace
- http://ww.godexintl.com/es1/download/downloads/Download/2996 `,
+ https://godex.s3-accelerate.amazonaws.com/gGnOPoojkP6vC1lgmrbEqQ.file?v01 `,
},
sections: {
QLabel: {
@@ -21,6 +21,8 @@ module.exports = {
'Abre el programa QLabel',
'Haz clic en el icono de la barra superior con forma de "carpeta"',
'Selecciona el archivo llamado "model.ezp" adjunto en este correo, y haz click en abrir',
+ 'Ve a "File" -> "Save as" y guárdalo en el escritorio con otro nombre',
+ 'Cierra el Qlabel y abre el archivo que acabamos de guardar',
'Haz clic encima del texto con el botón secundario del ratón',
'Elige la primera opción "setup"',
'Cambia el texto para imprimir',
diff --git a/print/report/rpt-delivery-note/assets/css/style.css b/print/report/rpt-delivery-note/assets/css/style.css
index e05617e6e..04474d4c8 100644
--- a/print/report/rpt-delivery-note/assets/css/style.css
+++ b/print/report/rpt-delivery-note/assets/css/style.css
@@ -9,16 +9,11 @@
max-width: 150px
}
-#packagings {
- box-sizing: border-box;
- padding-right: 10px
-}
-
-#taxes {
- box-sizing: border-box;
- padding-left: 10px
-}
-
.description.phytosanitary {
background-color: #e5e5e5
+}
+
+h3 {
+ font-weight: 100;
+ color: #555
}
\ No newline at end of file
diff --git a/print/report/rpt-delivery-note/index.html b/print/report/rpt-delivery-note/index.html
index 65b1866ae..4a994f847 100644
--- a/print/report/rpt-delivery-note/index.html
+++ b/print/report/rpt-delivery-note/index.html
@@ -58,6 +58,9 @@
+
+
+ {{$t('saleLines')}}
+
+
-
- {{$t('packaging')}}
+
+
+ {{$t('services')}}
- Id
{{$t('concept')}}
{{$t('quantity')}}
+ {{$t('vatType')}}
+ {{$t('amount')}}
-
- {{packaging.itemFk}}
- {{packaging.name}}
- {{packaging.quantity}}
+
+ {{service.description}}
+ {{service.quantity}}
+ {{service.taxDescription}}
+ {{service.price | currency('EUR')}}
-
- {{$t('total')}}
- 0
+
+
+ {{$t('total')}} {{serviceTotal | currency('EUR')}}
+
+
+
+
+
+
+
+ {{$t('packagings')}}
+
+
+
+ Id
+ {{$t('concept')}}
+ {{$t('quantity')}}
+
+
+
+
+ {{packaging.itemFk}}
+ {{packaging.name}}
+ {{packaging.quantity}}
+
+
+
+
+
+
+
-
+
{{signature.created | date}}
+
diff --git a/print/report/rpt-delivery-note/index.js b/print/report/rpt-delivery-note/index.js
index 0a1afc7e5..68450252c 100755
--- a/print/report/rpt-delivery-note/index.js
+++ b/print/report/rpt-delivery-note/index.js
@@ -14,11 +14,12 @@ module.exports = {
const [[taxes]] = await this.fetchTaxes(params.ticketFk);
const [sales] = await this.fetchSales(params.ticketFk);
const [packagings] = await this.fetchPackagings(params.ticketFk);
+ const [services] = await this.fetchServices(params.ticketFk);
if (!ticket)
throw new UserException('No ticket data found');
- return {client, ticket, address, sales, taxes, packagings, signature};
+ return {client, ticket, address, sales, taxes, packagings, services, signature};
},
created() {
if (this.client.locale)
@@ -35,6 +36,14 @@ module.exports = {
},
shipped() {
return strftime('%d-%m-%Y', this.ticket.shipped);
+ },
+ serviceTotal() {
+ let total = 0.00;
+ this.services.forEach(service => {
+ total += parseFloat(service.price) * service.quantity;
+ });
+
+ return total;
}
},
filters: {
@@ -169,6 +178,17 @@ module.exports = {
WHERE tp.ticketFk = ?
ORDER BY itemFk`, [ticketFk]);
},
+ fetchServices(ticketFk) {
+ return database.pool.query(
+ `SELECT
+ tc.description taxDescription,
+ ts.description,
+ ts.quantity,
+ ts.price
+ FROM ticketService ts
+ JOIN taxClass tc ON tc.id = ts.taxClassFk
+ WHERE ts.ticketFk = ?`, [ticketFk]);
+ },
fetchSignature(ticketFk) {
return database.pool.query(
`SELECT
diff --git a/print/report/rpt-delivery-note/locale.js b/print/report/rpt-delivery-note/locale.js
index afc54c72c..c637d9977 100644
--- a/print/report/rpt-delivery-note/locale.js
+++ b/print/report/rpt-delivery-note/locale.js
@@ -6,6 +6,7 @@ module.exports = {
clientId: 'Cliente',
deliveryAddress: 'Dirección de entrega',
fiscalData: 'Datos fiscales',
+ saleLines: 'Líneas de pedido',
date: 'Fecha',
reference: 'Ref.',
quantity: 'Cant.',
@@ -18,10 +19,13 @@ module.exports = {
taxBase: 'Base imp.',
tax: 'Tasa',
fee: 'Cuota',
- packaging: 'Cubos y embalajes',
- taxBreakdown: 'Desglose impositivo',
total: 'Total',
subtotal: 'Subtotal',
+ taxBreakdown: 'Desglose impositivo',
+ packagings: 'Cubos y embalajes',
+ services: 'Servicios',
+ vatType: 'Tipo de IVA',
+ digitalSignature: 'Firma digital',
ticket: 'Albarán {0}'
},
},
diff --git a/print/report/rpt-informe/index.js b/print/report/rpt-informe/index.js
deleted file mode 100755
index b5204e8c7..000000000
--- a/print/report/rpt-informe/index.js
+++ /dev/null
@@ -1,33 +0,0 @@
-const strftime = require('strftime');
-
-module.exports = {
- name: 'rpt-informe',
- created() {
- if (this.locale)
- this.$i18n.locale = this.locale;
-
- const embeded = [];
- this.files.map(file => {
- embeded[file] = `file://${__dirname + file}`;
- });
- this.embeded = embeded;
- },
- data() {
- return {
- client: {
- id: 101,
- name: 'Batman'
- },
- files: ['/assets/images/signature.png'],
- };
- },
- methods: {
- /* dated: () => {
- return strftime('%d-%m-%Y', new Date());
- }, */
- },
- components: {
- 'report-header': require('../report-header'),
- 'report-footer': require('../report-footer'),
- },
-};
diff --git a/print/report/rpt-informe/locale.js b/print/report/rpt-informe/locale.js
deleted file mode 100644
index 69f63bce6..000000000
--- a/print/report/rpt-informe/locale.js
+++ /dev/null
@@ -1,10 +0,0 @@
-module.exports = {
- messages: {
- es: {
- title: 'Recibo',
- date: 'Fecha',
- dated: 'En {0}, a {1} de {2} de {3}',
- client: 'Cliente {0}',
- },
- },
-};
diff --git a/print/report/rpt-informe/assets/css/index.js b/print/report/rpt-receipt/assets/css/index.js
similarity index 100%
rename from print/report/rpt-informe/assets/css/index.js
rename to print/report/rpt-receipt/assets/css/index.js
diff --git a/print/report/rpt-informe/assets/css/style.css b/print/report/rpt-receipt/assets/css/style.css
similarity index 81%
rename from print/report/rpt-informe/assets/css/style.css
rename to print/report/rpt-receipt/assets/css/style.css
index 9dd6ff5b8..350925428 100644
--- a/print/report/rpt-informe/assets/css/style.css
+++ b/print/report/rpt-receipt/assets/css/style.css
@@ -3,10 +3,6 @@ p {
margin: 0
}
-.main {
- position: relative;
- height: 100%
-}
.content {
position: absolute;
diff --git a/print/report/rpt-informe/assets/images/signature.png b/print/report/rpt-receipt/assets/images/signature.png
similarity index 100%
rename from print/report/rpt-informe/assets/images/signature.png
rename to print/report/rpt-receipt/assets/images/signature.png
diff --git a/print/report/rpt-informe/index.html b/print/report/rpt-receipt/index.html
similarity index 51%
rename from print/report/rpt-informe/index.html
rename to print/report/rpt-receipt/index.html
index f77c5d2ae..99058dd9c 100644
--- a/print/report/rpt-informe/index.html
+++ b/print/report/rpt-receipt/index.html
@@ -3,20 +3,27 @@
-
+
{{$t('title')}}
- Recibo de LEON LLORENS LUIS ENRIQUE ,
- la cantidad de 259,96 € en concepto de 'entrega a cuenta', quedando pendiente en la cuenta del cliente
- un saldo de 0,00 € .
+ Recibo de {{client.socialName}} ,
+ la cantidad de {{receipt.amountPaid}} € en concepto de 'entrega a cuenta',
+ quedando pendiente en la cuenta del cliente
+ un saldo de {{receipt.amountUnpaid}} € .
- {{$t('dated', ['Silla', '20', 'enero', '2019'])}}
+ {{$t('payed', [
+ 'Silla',
+ receipt.payed.getDate(),
+ $t('months')[receipt.payed.getMonth()],
+ receipt.payed.getFullYear()])
+ }}
+
@@ -24,8 +31,8 @@
diff --git a/print/report/rpt-receipt/index.js b/print/report/rpt-receipt/index.js
new file mode 100755
index 000000000..7a173e6ee
--- /dev/null
+++ b/print/report/rpt-receipt/index.js
@@ -0,0 +1,71 @@
+const strftime = require('strftime');
+const database = require(`${appPath}/lib/database`);
+const UserException = require(`${appPath}/lib/exceptions/userException`);
+
+module.exports = {
+ name: 'rpt-receipt',
+ /* serverPrefetch() {
+ console.log(arguments);
+ return new Promise(accept => {
+ this.client = this.getReceipt();
+ });
+ }, */
+ async asyncData(ctx, params) {
+ Object.assign(this, this.methods);
+
+ const [[client]] = await this.fetchClient(params.receiptFk);
+ const [[receipt]] = await this.fetchReceipt(params.receiptFk);
+
+ if (!receipt)
+ throw new UserException('No receipt data found');
+
+ return {client, receipt};
+ },
+ created() {
+ if (this.client.locale)
+ this.$i18n.locale = this.client.locale;
+
+ const embeded = [];
+ this.files.map(file => {
+ embeded[file] = `file://${__dirname + file}`;
+ });
+ this.embeded = embeded;
+ },
+ data() {
+ return {
+ files: ['/assets/images/signature.png']
+ };
+ },
+ methods: {
+ fetchClient(receiptFk) {
+ return database.pool.query(
+ `SELECT
+ c.id,
+ c.socialName,
+ u.lang locale
+ FROM receipt r
+ JOIN client c ON c.id = r.clientFk
+ JOIN account.user u ON u.id = c.id
+ WHERE r.id = ?`, [receiptFk]);
+ },
+ fetchReceipt(receiptFk) {
+ return database.pool.query(
+ `SELECT
+ r.id,
+ r.amountPaid,
+ r.amountUnpaid,
+ r.payed,
+ r.companyFk
+ FROM receipt r
+ JOIN client c ON c.id = r.clientFk
+ WHERE r.id = ?`, [receiptFk]);
+ }
+ /* dated: () => {
+ return strftime('%d-%m-%Y', new Date());
+ }, */
+ },
+ components: {
+ 'report-header': require('../report-header'),
+ 'report-footer': require('../report-footer'),
+ },
+};
diff --git a/print/report/rpt-receipt/locale.js b/print/report/rpt-receipt/locale.js
new file mode 100644
index 000000000..b8d524274
--- /dev/null
+++ b/print/report/rpt-receipt/locale.js
@@ -0,0 +1,24 @@
+module.exports = {
+ messages: {
+ es: {
+ title: 'Recibo',
+ date: 'Fecha',
+ payed: 'En {0}, a {1} de {2} de {3}',
+ client: 'Cliente {0}',
+ months: [
+ 'Enero',
+ 'Febrero',
+ 'Marzo',
+ 'Abril',
+ 'Mayo',
+ 'Junio',
+ 'Julio',
+ 'Agosto',
+ 'Septiembre',
+ 'Octubre',
+ 'Noviembre',
+ 'Diciembre'
+ ]
+ },
+ },
+};