This commit is contained in:
Juan Ferrer 2019-03-12 15:02:05 +01:00
commit 1c8edefd36
280 changed files with 5458 additions and 3789 deletions

View File

@ -1,3 +1,4 @@
node_modules node_modules
print/node_modules
front/node_modules front/node_modules
services services

View File

@ -1,4 +1,5 @@
FROM debian:stretch-slim FROM debian:stretch-slim
ENV TZ Europe/Madrid
ARG DEBIAN_FRONTEND=noninteractive ARG DEBIAN_FRONTEND=noninteractive
RUN apt-get update \ RUN apt-get update \
@ -21,6 +22,7 @@ COPY package.json package-lock.json ./
COPY loopback/package.json loopback/ COPY loopback/package.json loopback/
COPY print/package.json print/ COPY print/package.json print/
RUN npm install --only=prod RUN npm install --only=prod
RUN npm --prefix ./print install --only=prod ./print
COPY loopback loopback COPY loopback loopback
COPY back back COPY back back

View File

@ -26,7 +26,7 @@ module.exports = Self => {
}); });
Self.send = async(ctx, data, transaction) => { Self.send = async(ctx, data, transaction) => {
const userId = ctx.req.accessToken.userId; const userId = ctx.options && ctx.options.accessToken.userId || ctx.req && ctx.req.accessToken.userId;
const models = Self.app.models; const models = Self.app.models;
const sender = await models.Account.findById(userId, transaction); const sender = await models.Account.findById(userId, transaction);
const recipient = await models.Account.findById(data.recipientFk, transaction); const recipient = await models.Account.findById(data.recipientFk, transaction);

View File

@ -1,72 +1,74 @@
{ {
"name": "Account", "name": "Account",
"base": "VnModel", "base": "VnModel",
"options": { "options": {
"mysql": { "mysql": {
"table": "account.user" "table": "account.user"
} }
}, },
"properties": { "properties": {
"id": { "id": {
"type": "number", "type": "number",
"required": true "required": true
}, },
"name": { "name": {
"type": "string", "type": "string",
"required": true "required": true
}, },
"roleFk": { "roleFk": {
"type": "number", "type": "number",
"mysql": { "mysql": {
"columnName": "role" "columnName": "role"
} }
}, },
"nickname": { "nickname": {
"type": "string" "type": "string"
}, },
"password": { "password": {
"type": "string", "type": "string",
"required": true "required": true
}, },
"active": { "active": {
"type": "boolean" "type": "boolean"
}, },
"email": { "email": {
"type": "string" "type": "string"
}, },
"created": { "created": {
"type": "date" "type": "date"
}, },
"updated": { "updated": {
"type": "date" "type": "date"
} }
}, },
"relations": { "relations": {
"role": { "role": {
"type": "belongsTo", "type": "belongsTo",
"model": "Role", "model": "Role",
"foreignKey": "roleFk" "foreignKey": "roleFk"
} }
}, },
"acls": [ "acls": [
{ {
"property": "login", "property": "login",
"accessType": "EXECUTE", "accessType": "EXECUTE",
"principalType": "ROLE", "principalType": "ROLE",
"principalId": "$everyone", "principalId": "$everyone",
"permission": "ALLOW" "permission": "ALLOW"
}, { },
"property": "logout", {
"accessType": "EXECUTE", "property": "logout",
"principalType": "ROLE", "accessType": "EXECUTE",
"principalId": "$authenticated", "principalType": "ROLE",
"permission": "ALLOW" "principalId": "$authenticated",
}, { "permission": "ALLOW"
"property": "validateToken", },
"accessType": "EXECUTE", {
"principalType": "ROLE", "property": "validateToken",
"principalId": "$authenticated", "accessType": "EXECUTE",
"permission": "ALLOW" "principalType": "ROLE",
} "principalId": "$authenticated",
] "permission": "ALLOW"
}
]
} }

2
db/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
config.production.ini
config.test.ini

7
db/config.ini Normal file
View File

@ -0,0 +1,7 @@
[client]
host = localhost
port = 3306
user = root
password = password
ssl-mode = DISABLED
enable_cleartext_plugin = ON

View File

@ -1,5 +1,4 @@
#!/bin/bash #!/bin/bash
#IMPORTANT Any changes in this file are to applyed to mirror file export-data.cmd
echo "USE \`account\`;" > install/dump/dumpedFixtures.sql echo "USE \`account\`;" > install/dump/dumpedFixtures.sql
mysqldump --defaults-file=connect.ini --no-create-info account role roleRole roleInherit >> install/dump/dumpedFixtures.sql mysqldump --defaults-file=connect.ini --no-create-info account role roleRole roleInherit >> install/dump/dumpedFixtures.sql
echo "USE \`salix\`;" >> install/dump/dumpedFixtures.sql echo "USE \`salix\`;" >> install/dump/dumpedFixtures.sql

42
db/import-changes.sh Executable file
View File

@ -0,0 +1,42 @@
#!/bin/bash
ENV=$1
if [ "$ENV" == "production" ]; then
echo ""
echo " ( ( ) ( ( ) ) "
echo " )\ ))\ ) ( /( )\ ) ( * ))\ ) ( /( ( /( "
echo "(()/(()/( )\()|()/( ( )\ ) /(()/( )\()) )\())"
echo " /(_))(_)|(_)\ /(_)) )\ (((_) ( )(_))(_)|(_)\ ((_)\ "
echo "(_))(_)) ((_|_))_ _ ((_))\___(_(_()|_)) ((_) _((_)"
echo "| _ \ _ \ / _ \| \| | | ((/ __|_ _|_ _| / _ \| \| |"
echo "| _/ /| (_) | |) | |_| || (__ | | | | | (_) | . |"
echo "|_| |_|_\ \___/|___/ \___/ \___| |_| |___| \___/|_|\_|"
echo ""
read -p "Are you sure? (Default: no) [yes|no]: " ANSWER
if [ "$ANSWER" != "yes" ]; then
echo "Aborting"
exit;
fi
fi
if [ -z "$ENV" ]; then
ENV="test"
fi
INI_FILE="config.$ENV.ini"
if [ ! -f "$INI_FILE" ]; then
echo "File $INI_FILE doesn't exists"
exit 1
fi
echo "[INFO] Config file: $INI_FILE"
echo "[INFO] Importing changes."
# Import changes
for file in install/changes/*.sql; do
echo "[INFO] -> Applying $file"
mysql --defaults-file="$INI_FILE" < $file
done

View File

@ -2,15 +2,13 @@
export MYSQL_PWD=root export MYSQL_PWD=root
# Dump structure # Dump structure
echo "[INFO] -> Imported ./dump/truncateAll.sql"
mysql -u root -f < ./dump/truncateAll.sql
echo "[INFO] -> Imported ./dump/structure.sql" echo "[INFO] -> Imported ./dump/structure.sql"
mysql -u root -f < ./dump/structure.sql mysql -u root -f < ./dump/structure.sql
echo "[INFO] -> Imported ./dump/mysqlPlugins.sql" echo "[INFO] -> Imported ./dump/mysqlPlugins.sql"
mysql -u root -f < ./dump/mysqlPlugins.sql mysql -u root -f < ./dump/mysqlPlugins.sql
# Import changes # Import changes
for file in changes/*/*.sql; do for file in changes/*.sql; do
echo "[INFO] -> Imported ./$file" echo "[INFO] -> Imported ./$file"
mysql -u root -fc < $file mysql -u root -fc < $file
done done

View File

@ -0,0 +1,2 @@
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');

View File

@ -0,0 +1,29 @@
USE `hedera`;
DROP procedure IF EXISTS `orderGetTotal`;
DELIMITER $$
USE `hedera`$$
CREATE DEFINER=`root`@`%` PROCEDURE `orderGetTotal`()
BEGIN
/**
* Calcula el total con IVA para un conjunto de orders.
*
* @table tmp.order(orderFk) Identificadores de las ordenes a calcular
* @return tmp.orderTotal Total para cada order
*/
CALL orderGetTax;
DROP TEMPORARY TABLE IF EXISTS tmp.orderTotal;
CREATE TEMPORARY TABLE tmp.orderTotal
(INDEX (orderFk))
ENGINE = MEMORY
SELECT o.orderFk, IFNULL(SUM(ot.taxableBase + ot.tax), 0.0) AS total
FROM tmp.order o
LEFT JOIN tmp.orderAmount ot ON o.orderFk = ot.orderFk
GROUP BY orderFk;
DROP TEMPORARY TABLE IF EXISTS tmp.orderTax;
END$$
DELIMITER ;

View File

@ -0,0 +1,36 @@
DROP PROCEDURE IF EXISTS vn.ticketGetVisibleAvailable;
DELIMITER $$
$$
CREATE DEFINER=`root`@`%` PROCEDURE `vn`.`ticketGetVisibleAvailable`(
vTicket INT)
BEGIN
DECLARE vVisibleCalc INT;
DECLARE vAvailableCalc INT;
DECLARE vShipped DATE;
DECLARE vWarehouse TINYINT;
DECLARE vAlertLevel INT;
SELECT t.warehouseFk, t.shipped, ts.alertLevel INTO vWarehouse, vShipped, vAlertLevel
FROM ticket t
LEFT JOIN ticketState ts ON ts.ticketFk = vTicket
WHERE t.id = vTicket;
IF vAlertLevel IS NULL OR vAlertLevel = 0 THEN
IF vShipped >= CURDATE() THEN
CALL cache.available_refresh(vAvailableCalc, FALSE, vWarehouse, vShipped);
END IF;
IF vShipped = CURDATE() THEN
CALL cache.visible_refresh(vVisibleCalc, FALSE, vWarehouse);
END IF;
END IF;
SELECT s.id, s.itemFk, s.quantity, s.concept, s.price, s.reserved, s.discount, v.visible, av.available, it.image
FROM sale s
LEFT JOIN cache.visible v ON v.item_id = s.itemFk AND v.calc_id = vVisibleCalc
LEFT JOIN cache.available av ON av.item_id = s.itemFk AND av.calc_id = vAvailableCalc
LEFT JOIN item it ON it.id = s.itemFk
WHERE s.ticketFk = vTicket
ORDER BY s.concept;
END$$
DELIMITER ;

View File

@ -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 ;

View File

@ -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, 'Code 100'
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 ;

View File

@ -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 ;

View File

@ -0,0 +1,36 @@
USE `hedera`;
DROP FUNCTION IF EXISTS `orderGetTotal`;
DELIMITER $$
USE `hedera`$$
CREATE DEFINER=`root`@`%` FUNCTION `orderGetTotal`(vOrder INT) RETURNS decimal(10,2)
READS SQL DATA
DETERMINISTIC
BEGIN
/**
* Obtiene el total de un pedido con el IVA y el recargo de
* equivalencia incluidos.
*
* @param vOrder El identificador del pedido
* @return El total del pedido
*/
DECLARE vTotal DECIMAL(10,2);
DROP TEMPORARY TABLE IF EXISTS tmp.order;
CREATE TEMPORARY TABLE tmp.order
ENGINE = MEMORY
SELECT vOrder orderFk;
CALL orderGetTotal;
SELECT total INTO vTotal FROM tmp.orderTotal;
DROP TEMPORARY TABLE
tmp.order,
tmp.orderTotal;
RETURN vTotal;
END$$
DELIMITER ;

View File

@ -0,0 +1,65 @@
USE `hedera`;
DROP procedure IF EXISTS `orderGetTax`;
DELIMITER $$
USE `hedera`$$
CREATE DEFINER=`root`@`%` PROCEDURE `orderGetTax`()
READS SQL DATA
BEGIN
/**
* Calcula el IVA, y el recargo de equivalencia de un pedido
* desglosados por tipos.
*
* @param vOrder El identificador del pedido
* @treturn tmp.orderTax Bases imponibles, IVA y recargo de equivalencia
*/
DROP TEMPORARY TABLE IF EXISTS tmp.addressCompany;
CREATE TEMPORARY TABLE tmp.addressCompany
(INDEX (addressFk, companyFk))
ENGINE = MEMORY
SELECT DISTINCT o.address_id addressFk, o.company_id companyFk
FROM tmp.order tmpOrder
JOIN hedera.order o ON o.id = tmpOrder.orderFk;
CALL vn.addressTaxArea ();
-- Calcula el IVA y el recargo desglosado.
DROP TEMPORARY TABLE IF EXISTS tmp.orderTax;
CREATE TEMPORARY TABLE tmp.orderTax
(INDEX (orderFk))
ENGINE = MEMORY
SELECT o.id orderFk,
tc.code,
SUM(m.amount * m.price) taxableBase,
pgc.rate
FROM tmp.order tmpOrder
JOIN `order` o ON o.id = tmpOrder.orderFk
JOIN orderRow m ON m.orderFk = o.id
JOIN vn.item i ON i.id = m.itemFk
JOIN vn.client c ON c.id = o.customer_id
JOIN vn.supplier s ON s.id = o.company_id
JOIN tmp.addressTaxArea ata
ON ata.addressFk = o.address_id AND ata.companyFk = o.company_id
JOIN vn.itemTaxCountry itc
ON itc.itemFk = i.id AND itc.countryFk = s.countryFk
JOIN vn.bookingPlanner bp
ON bp.countryFk = s.countryFk
AND bp.taxAreaFk = ata.areaFk
AND bp.taxClassFk = itc.taxClassFk
JOIN vn.pgc ON pgc.code = bp.pgcFk
JOIN vn.taxClass tc ON tc.id = bp.taxClassFk
GROUP BY tmpOrder.orderFk, pgc.code,pgc.rate
HAVING taxableBase != 0;
DROP TEMPORARY TABLE IF EXISTS tmp.orderAmount;
CREATE TEMPORARY TABLE tmp.orderAmount
(INDEX (orderFk))
ENGINE = MEMORY
SELECT orderFk, taxableBase, SUM(CAST(taxableBase * rate / 100 AS DECIMAL(10, 2))) tax,code
FROM tmp.orderTax
GROUP BY orderFk, code;
END$$
DELIMITER ;

View File

@ -0,0 +1,34 @@
/* Añadir a producción cuando se suba salix */
DROP TRIGGER IF EXISTS vn2008.ConsignatariosAfterUpdate;
USE vn2008;
DELIMITER $$
$$
CREATE DEFINER=`root`@`%` TRIGGER `vn2008`.`ConsignatariosAfterUpdate` AFTER UPDATE ON `Consignatarios` FOR EACH ROW
BEGIN
-- Recargos de equivalencia distintos implican facturacion por consignatario
IF NEW.isEqualizated != OLD.isEqualizated THEN
IF
(SELECT COUNT(*) FROM
(
SELECT DISTINCT (isEqualizated = FALSE) as Equ
FROM Consignatarios
WHERE Id_Cliente = NEW.Id_Cliente
) t1
) > 1
THEN
UPDATE Clientes
SET invoiceByAddress = TRUE
WHERE Id_Cliente = NEW.Id_Cliente;
END IF;
END IF;
END$$
DELIMITER ;
USE vn;

View File

@ -0,0 +1,27 @@
/* Añadir a producción cuando se suba salix */
DROP TRIGGER IF EXISTS vn2008.ConsignatariosBeforeInsert;
USE vn2008;
DELIMITER $$
$$
CREATE DEFINER=`root`@`%` TRIGGER `vn2008`.`ConsignatariosBeforeInsert`
BEFORE INSERT ON `vn2008`.`Consignatarios`
FOR EACH ROW
BEGIN
DECLARE vIsEqualizated BOOLEAN;
CALL pbx.phoneIsValid (NEW.telefono);
CALL pbx.phoneIsValid (NEW.movil);
IF NEW.isEqualizated IS NULL THEN
SELECT RE
INTO vIsEqualizated
FROM Clientes
WHERE Id_Cliente = NEW.Id_Cliente;
SET NEW.isEqualizated = vIsEqualizated;
END IF;
END$$
DELIMITER ;
USE vn;

View File

@ -0,0 +1,16 @@
/* Añadir a producción cuando se suba salix */
DROP TRIGGER IF EXISTS vn2008.ConsignatariosBeforeUpdate;
USE vn2008;
DELIMITER $$
$$
CREATE DEFINER=`root`@`%` TRIGGER `vn2008`.`ConsignatariosBeforeUpdate`
BEFORE UPDATE ON `vn2008`.`Consignatarios`
FOR EACH ROW
BEGIN
CALL pbx.phoneIsValid (NEW.telefono);
CALL pbx.phoneIsValid (NEW.movil);
END$$
DELIMITER ;
USE vn;

View File

@ -0,0 +1,3 @@
/* Añadir a producción cuando se suba salix */
DROP TRIGGER vn2008.ClientesAfterInsert;

View File

@ -0,0 +1,20 @@
/* Añadir a producción cuando se suba salix */
DROP TRIGGER IF EXISTS vn2008.ClientesAfterUpdate;
USE vn2008;
DELIMITER $$
$$
CREATE DEFINER=`root`@`%` TRIGGER `vn2008`.`ClientesAfterUpdate`
AFTER UPDATE ON `Clientes`
FOR EACH ROW
BEGIN
IF NEW.default_address AND (NEW.default_address != OLD.default_address) THEN
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 ;
USE vn;

View File

@ -0,0 +1,9 @@
/* Script de migración consignatarios.
Añadir a producción cuando se suba salix */
/* USE vn;
UPDATE vn.client c
JOIN vn.address a ON a.clientFk = c.id AND a.isDefaultAddress
SET c.defaultAddressFk = a.id
WHERE c.defaultAddressFk IS NULL */

File diff suppressed because one or more lines are too long

View File

@ -1,3 +1,5 @@
ALTER TABLE `vn`.`itemTaxCountry` AUTO_INCREMENT = 1; ALTER TABLE `vn`.`itemTaxCountry` AUTO_INCREMENT = 1;
ALTER TABLE `vn2008`.`Consignatarios` AUTO_INCREMENT = 1; ALTER TABLE `vn2008`.`Consignatarios` AUTO_INCREMENT = 1;
@ -8,7 +10,7 @@ INSERT INTO `account`.`user`(`id`,`name`, `nickname`, `password`,`role`,`active`
SELECT id, name, CONCAT(name, 'Nick'),MD5('nightmare'), id, 1, CONCAT(name, '@verdnatura.es') SELECT id, name, CONCAT(name, 'Nick'),MD5('nightmare'), id, 1, CONCAT(name, '@verdnatura.es')
FROM `account`.`role`; FROM `account`.`role`;
INSERT INTO `vn`.`worker`(`id`,`workerCode`, `firstName`, `name`, `userFk`) INSERT INTO `vn2008`.`Trabajadores`(`Id_Trabajador`,`CodigoTrabajador`, `Nombre`, `Apellidos`, `user_id`)
SELECT id,UPPER(LPAD(role, 3, '0')), name, name, id SELECT id,UPPER(LPAD(role, 3, '0')), name, name, id
FROM `vn`.`user`; FROM `vn`.`user`;
@ -29,7 +31,7 @@ INSERT INTO `account`.`user`(`id`,`name`,`password`,`role`,`active`,`email`,`lan
(111, 'Missing', 'ac754a330530832ba1bf7687f577da91', 2 , 0, NULL, 'es'), (111, 'Missing', 'ac754a330530832ba1bf7687f577da91', 2 , 0, NULL, 'es'),
(112, 'Trash', 'ac754a330530832ba1bf7687f577da91', 2 , 0, NULL, 'es'); (112, 'Trash', 'ac754a330530832ba1bf7687f577da91', 2 , 0, NULL, 'es');
INSERT INTO `vn`.`worker`(`workerCode`, `id`, `firstName`, `name`, `userFk`) INSERT INTO `vn2008`.`Trabajadores`(`CodigoTrabajador`, `Id_Trabajador`, `Nombre`, `Apellidos`, `user_id`)
VALUES VALUES
('LGN', 106, 'David Charles', 'Haller', 106), ('LGN', 106, 'David Charles', 'Haller', 106),
('ANT', 107, 'Hank' , 'Pym' , 107), ('ANT', 107, 'Hank' , 'Pym' , 107),
@ -189,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`) 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 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), (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), (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), (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), (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), (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), (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), (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), (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), (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), (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), (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); (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`) INSERT INTO `vn`.`clientManaCache`(`clientFk`, `mana`, `dated`)
VALUES VALUES
@ -209,38 +216,75 @@ INSERT INTO `vn`.`clientManaCache`(`clientFk`, `mana`, `dated`)
( 103, 0, DATE_ADD(CURDATE(), INTERVAL -1 MONTH)), ( 103, 0, DATE_ADD(CURDATE(), INTERVAL -1 MONTH)),
( 104, -30, DATE_ADD(CURDATE(), INTERVAL -1 MONTH)); ( 104, -30, DATE_ADD(CURDATE(), INTERVAL -1 MONTH));
INSERT INTO `vn`.`address`(`id`, `nickname`, `street`, `city`, `postalCode`, `provinceFk`, `phone`, `mobile`, `isActive`, `isDefaultAddress`, `clientFk`, `agencyModeFk`, `longitude`, `latitude`, `isEqualizated`) INSERT INTO `vn`.`address`(`id`, `nickname`, `street`, `city`, `postalCode`, `provinceFk`, `phone`, `mobile`, `isActive`, `clientFk`, `agencyModeFk`, `longitude`, `latitude`, `isEqualizated`, `isDefaultAddress`)
VALUES VALUES
(101, 'address 01', 'Somewhere in Thailand', 'Silla', 46460, 1, 1111111111, 222222222, 1, 0, 109, 2, NULL, NULL, 0), (1, 'Bruce Wayne', '1007 Mountain Drive, Gotham', 'Silla', 46460, 1, 1111111111, 222222222, 1, 101, 2, NULL, NULL, 0, 1),
(102, 'address 02', 'Somewhere in Poland', 'Silla', 46460, 1, 3333333333, 444444444, 1, 0, 109, 2, NULL, NULL, 0), (2, 'Petter Parker', '20 Ingram Street', 'Silla', 46460, 1, 1111111111, 222222222, 1, 102, 2, NULL, NULL, 0, 1),
(103, 'address 03', 'Somewhere in Japan', 'Silla', 46460, 1, 3333333333, 444444444, 1, 0, 109, 2, NULL, NULL, 0), (3, 'Clark Kent', '344 Clinton Street', 'Silla', 46460, 1, 1111111111, 222222222, 1, 103, 2, NULL, NULL, 0, 1),
(104, 'address 04', 'Somewhere in Spain', 'Silla', 46460, 1, 3333333333, 444444444, 1, 0, 109, 2, NULL, NULL, 0), (4, 'Tony Stark', '10880 Malibu Point', 'Silla', 46460, 1, 1111111111, 222222222, 1, 104, 2, NULL, NULL, 0, 1),
(105, 'address 05', 'Somewhere in Potugal', 'Silla', 46460, 1, 5555555555, 666666666, 1, 0, 109, 2, NULL, NULL, 0), (5, 'Max Eisenhardt', 'Unknown Whereabouts', 'Silla', 46460, 1, 1111111111, 222222222, 1, 105, 2, NULL, NULL, 0, 1),
(106, 'address 06', 'Somewhere in UK', 'Silla', 46460, 1, 5555555555, 666666666, 1, 0, 109, 2, NULL, NULL, 0), (6, 'DavidCharlesHaller', 'Evil hideout', 'Silla', 46460, 1, 1111111111, 222222222, 1, 106, 2, NULL, NULL, 0, 1),
(107, 'address 07', 'Somewhere in Valencia', 'Silla', 46460, 1, 5555555555, 666666666, 1, 0, 109, 2, NULL, NULL, 0), (7, 'Hank Pym', 'Anthill', 'Silla', 46460, 1, 1111111111, 222222222, 1, 107, 2, NULL, NULL, 0, 1),
(108, 'address 08', 'Somewhere in Silla', 'Silla', 46460, 1, 5555555555, 666666666, 1, 0, 109, 2, NULL, NULL, 0), (8, 'Charles Xavier', '3800 Victory Pkwy, Cincinnati, OH 45207, USA', 'Silla', 46460, 1, 1111111111, 222222222, 1, 108, 2, NULL, NULL, 0, 1),
(109, 'address 09', 'Somewhere in London', 'Silla', 46460, 1, 1111111111, 222222222, 1, 0, 109, 2, NULL, NULL, 0), (9, 'Bruce Banner', 'Somewhere in New York', 'Silla', 46460, 1, 1111111111, 222222222, 1, 109, 2, NULL, NULL, 0, 1),
(110, 'address 10', 'Somewhere in Algemesi', 'Silla', 46460, 1, 1111111111, 222222222, 1, 0, 109, 2, NULL, NULL, 0), (10, 'Jessica Jones', 'NYCC 2015 Poster', 'Silla', 46460, 1, 1111111111, 222222222, 1, 110, 2, NULL, NULL, 0, 1),
(111, 'address 11', 'Somewhere in Carlet', 'Silla', 46460, 1, 1111111111, 222222222, 1, 0, 109, 2, NULL, NULL, 0), (11, 'Missing', 'The space', 'Silla', 46460, 1, 1111111111, 222222222, 1, 200, 2, NULL, NULL, 0, 1),
(112, 'address 12', 'Somewhere in Campanar', 'Silla', 46460, 1, 1111111111, 222222222, 1, 0, 109, 2, NULL, NULL, 0), (12, 'Trash', 'New York city', 'Silla', 46460, 1, 1111111111, 222222222, 1, 400, 2, NULL, NULL, 0, 1),
(113, 'address 13', 'Somewhere in Malilla', 'Silla', 46460, 1, 1111111111, 222222222, 1, 0, 109, 2, NULL, NULL, 0), (101, 'address 01', 'Somewhere in Thailand', 'Silla', 46460, 1, 1111111111, 222222222, 1, 109, 2, NULL, NULL, 0, 0),
(114, 'address 14', 'Somewhere in France', 'Silla', 46460, 1, 1111111111, 222222222, 1, 0, 109, 2, NULL, NULL, 0), (102, 'address 02', 'Somewhere in Poland', 'Silla', 46460, 1, 3333333333, 444444444, 1, 109, 2, NULL, NULL, 0, 0),
(115, 'address 15', 'Somewhere in Birmingham', 'Silla', 46460, 1, 1111111111, 222222222, 1, 0, 109, 2, NULL, NULL, 0), (103, 'address 03', 'Somewhere in Japan', 'Silla', 46460, 1, 3333333333, 444444444, 1, 109, 2, NULL, NULL, 0, 0),
(116, 'address 16', 'Somewhere in Scotland', 'Silla', 46460, 1, 1111111111, 222222222, 1, 0, 109, 2, NULL, NULL, 0), (104, 'address 04', 'Somewhere in Spain', 'Silla', 46460, 1, 3333333333, 444444444, 1, 109, 2, NULL, NULL, 0, 0),
(117, 'address 17', 'Somewhere in nowhere', 'Silla', 46460, 1, 1111111111, 222222222, 1, 0, 109, 2, NULL, NULL, 0), (105, 'address 05', 'Somewhere in Potugal', 'Silla', 46460, 1, 5555555555, 666666666, 1, 109, 2, NULL, NULL, 0, 0),
(118, 'address 18', 'Somewhere over the rainbow', 'Silla', 46460, 1, 1111111111, 222222222, 1, 0, 109, 2, NULL, NULL, 0), (106, 'address 06', 'Somewhere in UK', 'Silla', 46460, 1, 5555555555, 666666666, 1, 109, 2, NULL, NULL, 0, 0),
(119, 'address 19', 'Somewhere in Alberic', 'Silla', 46460, 1, 1111111111, 222222222, 1, 0, 109, 2, NULL, NULL, 0), (107, 'address 07', 'Somewhere in Valencia', 'Silla', 46460, 1, 5555555555, 666666666, 1, 109, 2, NULL, NULL, 0, 0),
(120, 'address 20', 'Somewhere in Montortal', 'Silla', 46460, 1, 1111111111, 222222222, 1, 0, 109, 2, NULL, NULL, 0), (108, 'address 08', 'Somewhere in Silla', 'Silla', 46460, 1, 5555555555, 666666666, 1, 109, 2, NULL, NULL, 0, 0),
(121, 'address 21', 'the bat cave', 'Silla', 46460, 1, 1111111111, 222222222, 1, 0, 101, 2, NULL, NULL, 0), (109, 'address 09', 'Somewhere in London', 'Silla', 46460, 1, 1111111111, 222222222, 1, 109, 2, NULL, NULL, 0, 0),
(122, 'address 22', 'NY roofs', 'Silla', 46460, 1, 1111111111, 222222222, 1, 0, 102, 2, NULL, NULL, 0), (110, 'address 10', 'Somewhere in Algemesi', 'Silla', 46460, 1, 1111111111, 222222222, 1, 109, 2, NULL, NULL, 0, 0),
(123, 'address 23', 'The phone box', 'Silla', 46460, 1, 1111111111, 222222222, 1, 0, 103, 2, NULL, NULL, 0), (111, 'address 11', 'Somewhere in Carlet', 'Silla', 46460, 1, 1111111111, 222222222, 1, 109, 2, NULL, NULL, 0, 0),
(124, 'address 24', 'Stark tower', 'Silla', 46460, 1, 1111111111, 222222222, 1, 0, 104, 2, NULL, NULL, 0), (112, 'address 12', 'Somewhere in Campanar', 'Silla', 46460, 1, 1111111111, 222222222, 1, 109, 2, NULL, NULL, 0, 0),
(125, 'address 25', 'The plastic cell', 'Silla', 46460, 1, 1111111111, 222222222, 1, 0, 105, 2, NULL, NULL, 0), (113, 'address 13', 'Somewhere in Malilla', 'Silla', 46460, 1, 1111111111, 222222222, 1, 109, 2, NULL, NULL, 0, 0),
(126, 'address 26', 'Many places', 'Silla', 46460, 1, 1111111111, 222222222, 1, 0, 106, 2, NULL, NULL, 0), (114, 'address 14', 'Somewhere in France', 'Silla', 46460, 1, 1111111111, 222222222, 1, 109, 2, NULL, NULL, 0, 0),
(127, 'address 27', 'Your pocket', 'Silla', 46460, 1, 1111111111, 222222222, 1, 0, 107, 2, NULL, NULL, 0), (115, 'address 15', 'Somewhere in Birmingham', 'Silla', 46460, 1, 1111111111, 222222222, 1, 109, 2, NULL, NULL, 0, 0),
(128, 'address 28', 'Cerebro', 'Silla', 46460, 1, 1111111111, 222222222, 1, 0, 108, 2, NULL, NULL, 0), (116, 'address 16', 'Somewhere in Scotland', 'Silla', 46460, 1, 1111111111, 222222222, 1, 109, 2, NULL, NULL, 0, 0),
(129, 'address 29', 'Luke Cages Bar', 'Silla', 46460, 1, 1111111111, 222222222, 1, 0, 110, 2, NULL, NULL, 0), (117, 'address 17', 'Somewhere in nowhere', 'Silla', 46460, 1, 1111111111, 222222222, 1, 109, 2, NULL, NULL, 0, 0),
(130, 'address 30', 'Non valid address', 'Silla', 46460, 1, 1111111111, 222222222, 0, 0, 101, 2, NULL, NULL, 0); (118, 'address 18', 'Somewhere over the rainbow', 'Silla', 46460, 1, 1111111111, 222222222, 1, 109, 2, NULL, NULL, 0, 0),
(119, 'address 19', 'Somewhere in Alberic', 'Silla', 46460, 1, 1111111111, 222222222, 1, 109, 2, NULL, NULL, 0, 0),
(120, 'address 20', 'Somewhere in Montortal', 'Silla', 46460, 1, 1111111111, 222222222, 1, 109, 2, NULL, NULL, 0, 0),
(121, 'address 21', 'the bat cave', 'Silla', 46460, 1, 1111111111, 222222222, 1, 101, 2, NULL, NULL, 0, 0),
(122, 'address 22', 'NY roofs', 'Silla', 46460, 1, 1111111111, 222222222, 1, 102, 2, NULL, NULL, 0, 0),
(123, 'address 23', 'The phone box', 'Silla', 46460, 1, 1111111111, 222222222, 1, 103, 2, NULL, NULL, 0, 0),
(124, 'address 24', 'Stark tower', 'Silla', 46460, 1, 1111111111, 222222222, 1, 104, 2, NULL, NULL, 0, 0),
(125, 'address 25', 'The plastic cell', 'Silla', 46460, 1, 1111111111, 222222222, 1, 105, 2, NULL, NULL, 0, 0),
(126, 'address 26', 'Many places', 'Silla', 46460, 1, 1111111111, 222222222, 1, 106, 2, NULL, NULL, 0, 0),
(127, 'address 27', 'Your pocket', 'Silla', 46460, 1, 1111111111, 222222222, 1, 107, 2, NULL, NULL, 0, 0),
(128, 'address 28', 'Cerebro', 'Silla', 46460, 1, 1111111111, 222222222, 1, 108, 2, NULL, NULL, 0, 0),
(129, 'address 29', 'Luke Cages Bar', 'Silla', 46460, 1, 1111111111, 222222222, 1, 110, 2, NULL, NULL, 0, 0),
(130, 'address 30', 'Non valid address', 'Silla', 46460, 1, 1111111111, 222222222, 0, 101, 2, NULL, NULL, 0, 0),
(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;
UPDATE `vn`.`client` SET defaultAddressFk = 4 WHERE id = 104;
UPDATE `vn`.`client` SET defaultAddressFk = 5 WHERE id = 105;
UPDATE `vn`.`client` SET defaultAddressFk = 6 WHERE id = 106;
UPDATE `vn`.`client` SET defaultAddressFk = 7 WHERE id = 107;
UPDATE `vn`.`client` SET defaultAddressFk = 8 WHERE id = 108;
UPDATE `vn`.`client` SET defaultAddressFk = 9 WHERE id = 109;
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`) INSERT INTO `vn`.`clientCredit`(`id`, `clientFk`, `workerFk`, `amount`, `created`)
VALUES VALUES
@ -267,15 +311,15 @@ INSERT INTO `vn`.`clientCreditLimit`(`id`, `maxAmount`, `roleFk`)
INSERT INTO `vn`.`clientObservation`(`id`, `clientFk`, `workerFk`, `text`, `created`) INSERT INTO `vn`.`clientObservation`(`id`, `clientFk`, `workerFk`, `text`, `created`)
VALUES VALUES
(1, 101, 1, 'Madness, as you know, is like gravity, all it takes is a little push', CURDATE()), (1, 101, 1, 'Madness, as you know, is like gravity, all it takes is a little push', CURDATE()),
(2, 102, 1, 'With great power, comes great responsibility', CURDATE()), (2, 102, 1, 'With great power, comes great responsibility', CURDATE()),
(3, 103, 3, 'this is a job for Super-Man!', CURDATE()), (3, 103, 3, 'this is a job for Super-Man!', CURDATE()),
(4, 104, 3, 'yes... I am Iron-Man', CURDATE()), (4, 104, 3, 'yes... I am Iron-Man', CURDATE()),
(5, 105, 5, 'They do understand. Our mutant powers make us superior', CURDATE()), (5, 105, 5, 'They do understand. Our mutant powers make us superior', CURDATE()),
(6, 106, 5, 'My name is Legion, for we are many!', CURDATE()), (6, 106, 5, 'My name is Legion, for we are many!', CURDATE()),
(7, 107, 9, 'I think our first move should be calling the Avengers..', CURDATE()), (7, 107, 9, 'I think our first move should be calling the Avengers..', CURDATE()),
(8, 108, 9, 'Just because someone stumbles and loses their path, does not mean they are lost forever.', CURDATE()), (8, 108, 9, 'Just because someone stumbles and loses their path, does not mean they are lost forever.', CURDATE()),
(9, 109, 20, 'HULK SMASH! ...', CURDATE()), (9, 109, 20, 'HULK SMASH! ...', CURDATE()),
(10, 110, 20, 'They say everyone is born a hero. But if you let it, life will push you over the line until you are the villain.', CURDATE()); (10, 110, 20, 'They say everyone is born a hero. But if you let it, life will push you over the line until you are the villain.', CURDATE());
INSERT INTO `vn`.`observationType`(`id`,`description`) INSERT INTO `vn`.`observationType`(`id`,`description`)
@ -593,11 +637,11 @@ INSERT INTO `vn`.`saleComponent`(`saleFk`, `componentFk`, `value`)
(5, 29, -18.72), (5, 29, -18.72),
(5, 39, 0.02), (5, 39, 0.02),
(6, 23, 6.5), (6, 23, 6.5),
(7, 15, 0.29), (7, 15, 0.2899),
(7, 28, 5.6), (7, 28, 5.6),
(7, 29, -4.6), (7, 29, -4.6),
(7, 39, 0.01), (7, 39, 0.01),
(8, 15, 0.044), (8, 15, 0.0435),
(8, 21, -0.004), (8, 21, -0.004),
(8, 28, 20.72), (8, 28, 20.72),
(8, 29, -19.72), (8, 29, -19.72),
@ -624,7 +668,7 @@ INSERT INTO `vn`.`saleComponent`(`saleFk`, `componentFk`, `value`)
(12, 29, -19.72), (12, 29, -19.72),
(12, 37, 2), (12, 37, 2),
(12, 39, 0.01), (12, 39, 0.01),
(13, 15, 0.29), (13, 15, 0.2899),
(13, 28, 5.6), (13, 28, 5.6),
(13, 29, -4.6), (13, 29, -4.6),
(13, 39, 0.01), (13, 39, 0.01),
@ -793,14 +837,14 @@ INSERT INTO `vn`.`travel`(`id`,`shipped`, `landed`, `warehouseInFk`, `warehouseO
(1, DATE_ADD(CURDATE(), INTERVAL -2 MONTH), DATE_ADD(CURDATE(), INTERVAL -2 MONTH), 1, 2, 1, 100.00, 1000), (1, DATE_ADD(CURDATE(), INTERVAL -2 MONTH), DATE_ADD(CURDATE(), INTERVAL -2 MONTH), 1, 2, 1, 100.00, 1000),
(2, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 1, 2, 1, 150, 2000), (2, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 1, 2, 1, 150, 2000),
(3, CURDATE(), CURDATE(), 1, 2, 1, 0.00, 0.00), (3, CURDATE(), CURDATE(), 1, 2, 1, 0.00, 0.00),
(4, DATE_ADD(CURDATE(), INTERVAL -30 DAY), DATE_ADD(CURDATE(), INTERVAL -30 DAY), 1, 2, 1, 50.00, 500); (4, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 1, 2, 1, 50.00, 500);
INSERT INTO `vn`.`entry`(`id`, `supplierFk`, `created`, `travelFk`, `companyFk`,`ref`) INSERT INTO `vn`.`entry`(`id`, `supplierFk`, `created`, `travelFk`, `companyFk`,`ref`)
VALUES VALUES
( 1, 1, DATE_ADD(CURDATE(), INTERVAL -30 DAY), 1, 442, 'Movimiento 1'), ( 1, 1, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 1, 442, 'Movimiento 1'),
( 2, 2, DATE_ADD(CURDATE(), INTERVAL -30 DAY), 2, 442, 'Movimiento 2'), ( 2, 2, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 2, 442, 'Movimiento 2'),
( 3, 1, DATE_ADD(CURDATE(), INTERVAL -30 DAY), 3, 442, 'Movimiento 3'), ( 3, 1, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 3, 442, 'Movimiento 3'),
( 4, 2, DATE_ADD(CURDATE(), INTERVAL -30 DAY), 4, 69, 'Movimiento 4'); ( 4, 2, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 4, 69, 'Movimiento 4');
INSERT INTO `vn`.`agencyProvince`(`provinceFk`, `agencyFk`, `zone`, `warehouseFk`) INSERT INTO `vn`.`agencyProvince`(`provinceFk`, `agencyFk`, `zone`, `warehouseFk`)
VALUES VALUES
@ -927,7 +971,7 @@ INSERT INTO `hedera`.`orderRowComponent`(`rowFk`, `componentFk`, `price`)
(5, 29, -18.72), (5, 29, -18.72),
(5, 39, 0.02), (5, 39, 0.02),
(6, 23, 6.5), (6, 23, 6.5),
(7, 15, 0.29), (7, 15, 0.2899),
(7, 28, 5.6), (7, 28, 5.6),
(7, 29, -4.6), (7, 29, -4.6),
(7, 39, 0.01), (7, 39, 0.01),
@ -1061,10 +1105,10 @@ INSERT INTO `vn`.`userConfig` (`userFk`, `warehouseFk`, `companyFk`)
INSERT INTO `vn`.`receipt`(`id`, `invoiceFk`, `amountPaid`, `amountUnpaid`, `payed`, `workerFk`, `bankFk`, `clientFk`, `created`, `companyFk`, `isConciliate`) INSERT INTO `vn`.`receipt`(`id`, `invoiceFk`, `amountPaid`, `amountUnpaid`, `payed`, `workerFk`, `bankFk`, `clientFk`, `created`, `companyFk`, `isConciliate`)
VALUES VALUES
(1, 'Cobro web', 100.50, 0.00, CURDATE(), 9, 1, 101, CURDATE(), 442, 1), (1, 'Cobro web', 100.50, 0.00, CURDATE(), 9, 1, 101, CURDATE(), 442, 1),
(2, 'Cobro web', 200.50, 0.00, DATE_ADD(CURDATE(), INTERVAL -5 DAY), 9, 1, 101, DATE_ADD(CURDATE(), INTERVAL -5 DAY), 442, 1), (2, 'Cobro web', 200.50, 0.00, DATE_ADD(CURDATE(), INTERVAL -5 DAY), 9, 1, 101, DATE_ADD(CURDATE(), INTERVAL -5 DAY), 442, 1),
(3, 'Cobro en efectivo', 300.00, 100.00, DATE_ADD(CURDATE(), INTERVAL -10 DAY), 9, 1, 102, DATE_ADD(CURDATE(), INTERVAL -10 DAY), 442, 0), (3, 'Cobro en efectivo', 300.00, 100.00, DATE_ADD(CURDATE(), INTERVAL -10 DAY), 9, 1, 102, DATE_ADD(CURDATE(), INTERVAL -10 DAY), 442, 0),
(4, 'Cobro en efectivo', -400.00, -50.00, DATE_ADD(CURDATE(), INTERVAL -15 DAY), 9, 1, 103, DATE_ADD(CURDATE(), INTERVAL -15 DAY), 442, 0); (4, 'Cobro en efectivo', -400.00, -50.00, DATE_ADD(CURDATE(), INTERVAL -15 DAY), 9, 1, 103, DATE_ADD(CURDATE(), INTERVAL -15 DAY), 442, 0);
INSERT INTO `vn2008`.`workerTeam`(`id`, `team`, `user`) INSERT INTO `vn2008`.`workerTeam`(`id`, `team`, `user`)
VALUES VALUES
@ -1126,5 +1170,3 @@ INSERT INTO `postgresql`.`business_labour`(`business_id`, `notes`, `department_i
VALUES VALUES
(1, NULL, 22, 4, 0, 1, 1, 1, 1), (1, NULL, 22, 4, 0, 1, 1, 1, 1),
(2, 'From las friday worker ownes the company 1 hour', 23, 1, 0, 1, 0, 1, 1); (2, 'From las friday worker ownes the company 1 hour', 23, 1, 0, 1, 0, 1, 1);

View File

@ -18,11 +18,11 @@ let jasmine = new Jasmine();
let SpecReporter = require('jasmine-spec-reporter').SpecReporter; let SpecReporter = require('jasmine-spec-reporter').SpecReporter;
let serviceSpecs = [ let serviceSpecs = [
'./db/tests/**/*[sS]pec.js' './tests/**/*[sS]pec.js'
]; ];
jasmine.loadConfig({ jasmine.loadConfig({
spec_dir: 'services', spec_dir: 'db',
spec_files: serviceSpecs, spec_files: serviceSpecs,
helpers: [] helpers: []
}); });

View File

@ -183,6 +183,7 @@ describe('ticket ticketCreateWithUser()', () => {
params.landed, params.landed,
params.userId params.userId
]); ]);
stmts.push(stmt); stmts.push(stmt);
let ticketAddressIndex = stmts.push(`SELECT addressFk FROM vn.ticket WHERE id = @newTicketId`) - 1; let ticketAddressIndex = stmts.push(`SELECT addressFk FROM vn.ticket WHERE id = @newTicketId`) - 1;
@ -191,12 +192,9 @@ describe('ticket ticketCreateWithUser()', () => {
params.clientFk, params.clientFk,
]); ]);
let clientDefaultAddressIndex = stmts.push(stmt) - 1; let clientDefaultAddressIndex = stmts.push(stmt) - 1;
stmts.push('ROLLBACK'); stmts.push('ROLLBACK');
let sql = ParameterizedSQL.join(stmts, ';'); let sql = ParameterizedSQL.join(stmts, ';');
let result = await app.models.Ticket.rawStmt(sql); let result = await app.models.Ticket.rawStmt(sql);
let ticketAddress = result[ticketAddressIndex][0]; let ticketAddress = result[ticketAddressIndex][0];
let clientDefaultAddress = result[clientDefaultAddressIndex][0]; let clientDefaultAddress = result[clientDefaultAddressIndex][0];

View File

@ -160,6 +160,16 @@ let actions = {
.catch(done); .catch(done);
}, },
waitToFocus: function(selector, done) {
this.wait(selector)
.evaluate_now(selector => {
let element = document.querySelector(selector);
element.focus();
}, done, selector)
.then(done)
.catch(done);
},
isVisible: function(selector, done) { isVisible: function(selector, done) {
this.wait(selector) this.wait(selector)
.evaluate_now(elementSelector => { .evaluate_now(elementSelector => {
@ -351,6 +361,7 @@ let actions = {
accessToSearchResult: function(searchValue, done) { accessToSearchResult: function(searchValue, done) {
this.write(`vn-searchbar input`, searchValue) this.write(`vn-searchbar input`, searchValue)
.click(`vn-searchbar vn-icon[icon="search"]`) .click(`vn-searchbar vn-icon[icon="search"]`)
.wait(100)
.waitForNumberOfElements('.searchResult', 1) .waitForNumberOfElements('.searchResult', 1)
.evaluate(() => { .evaluate(() => {
return document.querySelector('ui-view vn-card vn-table') != null; return document.querySelector('ui-view vn-card vn-table') != null;

View File

@ -31,6 +31,8 @@ export default {
name: `${components.vnTextfield}[name="name"]`, name: `${components.vnTextfield}[name="name"]`,
taxNumber: `${components.vnTextfield}[name="fi"]`, taxNumber: `${components.vnTextfield}[name="fi"]`,
socialName: `${components.vnTextfield}[name="socialName"]`, socialName: `${components.vnTextfield}[name="socialName"]`,
street: `${components.vnTextfield}[name="street"]`,
city: `${components.vnTextfield}[name="city"]`,
userName: `${components.vnTextfield}[name="userName"]`, userName: `${components.vnTextfield}[name="userName"]`,
email: `${components.vnTextfield}[name="email"]`, email: `${components.vnTextfield}[name="email"]`,
salesPersonAutocomplete: `vn-autocomplete[field="$ctrl.client.salesPersonFk"]`, salesPersonAutocomplete: `vn-autocomplete[field="$ctrl.client.salesPersonFk"]`,
@ -85,6 +87,7 @@ export default {
newBankEntityButton: 'vn-client-billing-data vn-icon-button[vn-tooltip="New bank entity"] > button', 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', 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', 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"]', acceptBankEntityButton: 'vn-client-billing-data > vn-dialog button[response="ACCEPT"]',
saveButton: `${components.vnSubmit}` saveButton: `${components.vnSubmit}`
}, },
@ -149,6 +152,7 @@ export default {
}, },
clientLog: { clientLog: {
logButton: `vn-left-menu a[ui-sref="client.card.log"]`, logButton: `vn-left-menu a[ui-sref="client.card.log"]`,
lastModificationDate: 'vn-client-log > vn-log vn-table vn-tbody > vn-tr > vn-td:nth-child(1)',
lastModificationPreviousValue: 'vn-client-log vn-table vn-td.before', lastModificationPreviousValue: 'vn-client-log vn-table vn-td.before',
lastModificationCurrentValue: 'vn-client-log vn-table vn-td.after' lastModificationCurrentValue: 'vn-client-log vn-table vn-td.after'
@ -165,10 +169,11 @@ export default {
}, },
webPayment: { webPayment: {
confirmFirstPaymentButton: 'vn-client-web-payment vn-tr:nth-child(1) vn-icon-button[icon="done_all"]', confirmFirstPaymentButton: 'vn-client-web-payment vn-tr:nth-child(1) vn-icon-button[icon="done_all"]',
firstPaymentConfirmed: 'vn-client-web-payment vn-tr:nth-child(1) vn-icon[icon="check"]' firstPaymentConfirmed: 'vn-client-web-payment vn-tr:nth-child(1) vn-icon[icon="check"][aria-hidden="false"]'
}, },
itemsIndex: { 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}`, createItemButton: `${components.vnFloatButton}`,
searchResult: `vn-item-index a.vn-tr`, searchResult: `vn-item-index a.vn-tr`,
searchResultPreviewButton: `vn-item-index .buttons > [icon="desktop_windows"]`, searchResultPreviewButton: `vn-item-index .buttons > [icon="desktop_windows"]`,
@ -176,7 +181,23 @@ export default {
acceptClonationAlertButton: `vn-item-index [vn-id="clone"] [response="ACCEPT"]`, acceptClonationAlertButton: `vn-item-index [vn-id="clone"] [response="ACCEPT"]`,
searchItemInput: `vn-searchbar vn-textfield input`, searchItemInput: `vn-searchbar vn-textfield input`,
searchButton: `vn-searchbar vn-icon[icon="search"]`, 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: { itemCreateView: {
temporalName: `${components.vnTextfield}[name="provisionalName"]`, temporalName: `${components.vnTextfield}[name="provisionalName"]`,
@ -192,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`, 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"]', regularizeWarehouseAutocomplete: 'vn-item-descriptor vn-dialog vn-autocomplete[field="$ctrl.warehouseFk"]',
editButton: 'vn-item-card vn-item-descriptor vn-float-button[icon="edit"]', 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: { itemBasicData: {
basicDataButton: `vn-left-menu a[ui-sref="item.card.data"]`, basicDataButton: `vn-left-menu a[ui-sref="item.card.data"]`,
@ -322,7 +345,7 @@ export default {
packagesButton: `vn-left-menu a[ui-sref="ticket.card.package.index"]`, packagesButton: `vn-left-menu a[ui-sref="ticket.card.package.index"]`,
firstPackageAutocomplete: `vn-autocomplete[label="Package"]`, firstPackageAutocomplete: `vn-autocomplete[label="Package"]`,
firstQuantityInput: `vn-textfield[label="Quantity"] input`, 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"]`, addPackageButton: `vn-icon-button[vn-tooltip="Add package"]`,
clearPackageAutocompleteButton: `vn-autocomplete[label="Package"] > div > div > div > vn-icon > i`, clearPackageAutocompleteButton: `vn-autocomplete[label="Package"] > div > div > div > vn-icon > i`,
savePackagesButton: `${components.vnSubmit}` savePackagesButton: `${components.vnSubmit}`
@ -339,12 +362,13 @@ export default {
firstSaleThumbnailImage: 'vn-ticket-sale:nth-child(1) vn-tr:nth-child(1) vn-td:nth-child(3) > img', firstSaleThumbnailImage: 'vn-ticket-sale:nth-child(1) vn-tr:nth-child(1) vn-td:nth-child(3) > img',
firstSaleZoomedImage: 'body > div > div > img', firstSaleZoomedImage: 'body > div > div > img',
firstSaleQuantity: `vn-textfield[model="sale.quantity"]:nth-child(1) input`, firstSaleQuantity: `vn-textfield[model="sale.quantity"]:nth-child(1) input`,
firstSaleQuantityCell: `vn-ticket-sale vn-tr:nth-child(1) > vn-td-editable`,
firstSaleQuantityClearInput: `vn-textfield[model="sale.quantity"] div.suffix > i`, firstSaleQuantityClearInput: `vn-textfield[model="sale.quantity"] div.suffix > i`,
firstSaleID: 'vn-ticket-sale:nth-child(1) vn-td:nth-child(4) > span', firstSaleID: 'vn-ticket-sale:nth-child(1) vn-td:nth-child(4) > span',
firstSalePrice: 'vn-ticket-sale:nth-child(1) vn-tr:nth-child(1) > vn-td:nth-child(7) > span', firstSalePrice: 'vn-ticket-sale:nth-child(1) vn-tr:nth-child(1) > vn-td:nth-child(7) > span',
firstSalePriceInput: 'vn-ticket-sale:nth-child(1) > vn-vertical > vn-popover.edit.dialog-summary.ng-isolate-scope.vn-popover.shown > div > div.content > div > vn-textfield', firstSalePriceInput: 'vn-ticket-sale:nth-child(1) vn-popover.edit.dialog-summary.ng-isolate-scope.vn-popover.shown vn-textfield input',
firstSaleDiscount: 'vn-ticket-sale:nth-child(1) vn-td:nth-child(8) > span', firstSaleDiscount: 'vn-ticket-sale:nth-child(1) vn-td:nth-child(8) > span',
firstSaleDiscountInput: 'vn-ticket-sale:nth-child(1) vn-ticket-sale-edit-discount > div > vn-textfield > div > div > div.infix > input.ng-not-empty', firstSaleDiscountInput: 'vn-ticket-sale:nth-child(1) vn-ticket-sale-edit-discount vn-textfield input',
firstSaleImport: 'vn-ticket-sale:nth-child(1) vn-td:nth-child(9)', firstSaleImport: 'vn-ticket-sale:nth-child(1) vn-td:nth-child(9)',
firstSaleReservedIcon: 'vn-ticket-sale vn-tr:nth-child(1) > vn-td:nth-child(2) > vn-icon:nth-child(3)', firstSaleReservedIcon: 'vn-ticket-sale vn-tr:nth-child(1) > vn-td:nth-child(2) > vn-icon:nth-child(3)',
firstSaleColour: `vn-ticket-sale vn-tr:nth-child(1) vn-td:nth-child(6) section:nth-child(1)`, firstSaleColour: `vn-ticket-sale vn-tr:nth-child(1) vn-td:nth-child(6) section:nth-child(1)`,
@ -421,7 +445,7 @@ export default {
addServiceButton: 'vn-ticket-service > form > vn-card > div > vn-one:nth-child(3) > vn-icon-button > button > vn-icon', 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', firstDescriptionInput: 'vn-ticket-service vn-textfield[label="Description"] input',
firstQuantityInput: 'vn-ticket-service vn-textfield[label="Quantity"] 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"]', 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"]', 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', serviceLine: 'vn-ticket-service > form > vn-card > div > vn-one:nth-child(2) > vn-horizontal',
@ -468,6 +492,17 @@ export default {
secondClaimRedeliveryAutocomplete: 'vn-claim-development vn-horizontal:nth-child(2) vn-autocomplete[field="claimDevelopment.claimRedeliveryFk"]', secondClaimRedeliveryAutocomplete: 'vn-claim-development vn-horizontal:nth-child(2) vn-autocomplete[field="claimDevelopment.claimRedeliveryFk"]',
saveDevelopmentButton: `${components.vnSubmit}` saveDevelopmentButton: `${components.vnSubmit}`
}, },
claimAction: {
importClaimButton: 'vn-claim-action vn-button[label="Import claim"]',
importTicketButton: 'vn-claim-action vn-button[label="Import ticket"]',
secondImportableTicket: 'vn-claim-action > vn-vertical > vn-popover > div > div.content > div > vn-table > div > vn-tbody > vn-tr:nth-child(2)',
firstLineDestination: 'vn-claim-action vn-tr:nth-child(1) vn-autocomplete[field="saleClaimed.claimDestinationFk"]',
thirdLineDestination: 'vn-claim-action vn-tr:nth-child(3) vn-autocomplete[field="saleClaimed.claimDestinationFk"]',
firstDeleteLine: 'vn-claim-action vn-tr:nth-child(1) vn-icon-button[icon="delete"]',
secondDeleteLine: 'vn-claim-action vn-tr:nth-child(2) vn-icon-button[icon="delete"]',
thirdDeleteLine: 'vn-claim-action vn-tr:nth-child(3) vn-icon-button[icon="delete"]'
},
ordersIndex: { ordersIndex: {
searchResult: `vn-order-index vn-card > div > vn-table > div > vn-tbody > a.vn-tr`, searchResult: `vn-order-index vn-card > div > vn-table > div > vn-tbody > a.vn-tr`,
searchResultDate: `vn-order-index vn-table vn-tbody > a:nth-child(1) > vn-td:nth-child(4)`, searchResultDate: `vn-order-index vn-table vn-tbody > a:nth-child(1) > vn-td:nth-child(4)`,
@ -500,4 +535,9 @@ export default {
confirmOrder: 'vn-order-line > vn-vertical > vn-button-bar > vn-button > button', confirmOrder: 'vn-order-line > vn-vertical > vn-button-bar > vn-button > button',
confirmButton: 'vn-order-line > vn-confirm button[response="ACCEPT"]', 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'
}
}; };

View File

@ -0,0 +1,63 @@
import selectors from '../../helpers/selectors.js';
import createNightmare from '../../helpers/nightmare';
describe('Claim edit basic data path', () => {
const nightmare = createNightmare();
beforeAll(() => {
nightmare
.loginAndModule('administrative', 'claim')
.accessToSearchResult('4')
.accessToSection('claim.card.action');
});
it('should import the claim', async() => {
const result = await nightmare
.waitToClick(selectors.claimAction.importClaimButton)
.waitForLastSnackbar();
expect(result).toEqual('Data saved!');
});
it('should import the eighth ticket', async() => {
const result = await nightmare
.waitToClick(selectors.claimAction.importTicketButton)
.waitToClick(selectors.claimAction.secondImportableTicket)
.waitForLastSnackbar();
expect(result).toEqual('Data saved!');
});
it('should edit the fourth line destination field', async() => {
const result = await nightmare
.autocompleteSearch(selectors.claimAction.thirdLineDestination, 'Bueno')
.waitForLastSnackbar();
expect(result).toEqual('Data saved!');
});
it('should delete two first lines', async() => {
const result = await nightmare
.waitToClick(selectors.claimAction.secondDeleteLine)
.waitToClick(selectors.claimAction.firstDeleteLine)
.waitForLastSnackbar();
expect(result).toEqual('Data saved!');
});
it('should refresh the view to check the remaining line is the expected one', async() => {
const result = await nightmare
.reloadSection('claim.card.action')
.waitToGetProperty(`${selectors.claimAction.firstLineDestination} input`, 'value');
expect(result).toEqual('Bueno');
});
it('should delete the current first line', async() => {
const result = await nightmare
.waitToClick(selectors.claimAction.firstDeleteLine)
.waitForLastSnackbar();
expect(result).toEqual('Data saved!');
});
});

View File

@ -52,6 +52,8 @@ describe('Client create path', () => {
const result = await nightmare const result = await nightmare
.write(selectors.createClientView.name, 'Carol Danvers') .write(selectors.createClientView.name, 'Carol Danvers')
.write(selectors.createClientView.socialName, 'AVG tax') .write(selectors.createClientView.socialName, 'AVG tax')
.write(selectors.createClientView.street, 'Many places')
.write(selectors.createClientView.city, 'Silla')
.clearInput(selectors.createClientView.email) .clearInput(selectors.createClientView.email)
.write(selectors.createClientView.email, 'incorrect email format') .write(selectors.createClientView.email, 'incorrect email format')
.waitToClick(selectors.createClientView.createButton) .waitToClick(selectors.createClientView.createButton)

View File

@ -58,7 +58,7 @@ describe('Client Edit fiscalData path', () => {
.accessToSection('client.card.fiscalData'); .accessToSection('client.card.fiscalData');
}); });
it('should receive an error if VIES and EQtax are being ticked together', async() => { it('should edit the fiscal data', async() => {
const result = await nightmare const result = await nightmare
.wait(selectors.clientFiscalData.socialNameInput) .wait(selectors.clientFiscalData.socialNameInput)
.clearInput(selectors.clientFiscalData.socialNameInput) .clearInput(selectors.clientFiscalData.socialNameInput)
@ -84,9 +84,17 @@ describe('Client Edit fiscalData path', () => {
.waitToClick(selectors.clientFiscalData.saveButton) .waitToClick(selectors.clientFiscalData.saveButton)
.waitForLastSnackbar(); .waitForLastSnackbar();
expect(result).toEqual('Cannot check VIES and Equalization Tax'); expect(result).toEqual('Data saved!');
}, 15000); }, 15000);
it('should propagate the Equalization tax', async() => {
const result = await nightmare
.waitToClick(selectors.clientFiscalData.acceptPropagationButton)
.waitForLastSnackbar();
expect(result).toEqual('Equivalent tax spreaded');
});
it('should receive an error if the fiscal id contains A or B at the beginning', async() => { it('should receive an error if the fiscal id contains A or B at the beginning', async() => {
const result = await nightmare const result = await nightmare
.waitToClick(selectors.clientFiscalData.viesCheckbox) .waitToClick(selectors.clientFiscalData.viesCheckbox)
@ -108,14 +116,6 @@ describe('Client Edit fiscalData path', () => {
expect(result).toEqual('Data saved!'); expect(result).toEqual('Data saved!');
}); });
it('should propagate the Equalization tax', async() => {
const result = await nightmare
.waitToClick(selectors.clientFiscalData.acceptPropagationButton)
.waitForLastSnackbar();
expect(result).toEqual('Equivalent tax spreaded');
});
// confirm all addresses have now EQtax checked step 1 // confirm all addresses have now EQtax checked step 1
it(`should click on the addresses button to access to the client's addresses`, async() => { it(`should click on the addresses button to access to the client's addresses`, async() => {
const url = await nightmare const url = await nightmare

View File

@ -44,6 +44,7 @@ describe('Client Edit pay method path', () => {
const newcode = await nightmare const newcode = await nightmare
.waitToClick(selectors.clientPayMethod.newBankEntityButton) .waitToClick(selectors.clientPayMethod.newBankEntityButton)
.write(selectors.clientPayMethod.newBankEntityName, 'Gotham City Bank') .write(selectors.clientPayMethod.newBankEntityName, 'Gotham City Bank')
.write(selectors.clientPayMethod.newBankEntityCode, 9999)
.write(selectors.clientPayMethod.newBankEntityBIC, 'GTHMCT') .write(selectors.clientPayMethod.newBankEntityBIC, 'GTHMCT')
.waitToClick(selectors.clientPayMethod.acceptBankEntityButton) .waitToClick(selectors.clientPayMethod.acceptBankEntityButton)
.waitToGetProperty(`${selectors.clientPayMethod.swiftBicAutocomplete} input`, 'value'); .waitToGetProperty(`${selectors.clientPayMethod.swiftBicAutocomplete} input`, 'value');

View File

@ -4,6 +4,8 @@ import createNightmare from '../../helpers/nightmare';
describe('Client log path', () => { describe('Client log path', () => {
const nightmare = createNightmare(); const nightmare = createNightmare();
let date;
beforeAll(() => { beforeAll(() => {
nightmare nightmare
.loginAndModule('employee', 'client') .loginAndModule('employee', 'client')
@ -17,6 +19,7 @@ describe('Client log path', () => {
.write(selectors.clientBasicData.nameInput, 'this is a test') .write(selectors.clientBasicData.nameInput, 'this is a test')
.waitToClick(selectors.clientBasicData.saveButton) .waitToClick(selectors.clientBasicData.saveButton)
.waitForLastSnackbar(); .waitForLastSnackbar();
date = new Date();
expect(result).toEqual('Data saved!'); expect(result).toEqual('Data saved!');
}); });
@ -38,9 +41,33 @@ describe('Client log path', () => {
}); });
it('should check the current value of the last logged change', async() => { it('should check the current value of the last logged change', async() => {
let lastModificationDate = await nightmare
.waitToGetProperty(selectors.clientLog.lastModificationDate, 'innerText');
let lastModificationPreviousValue = await nightmare
.waitToGetProperty(selectors.clientLog.lastModificationPreviousValue, 'innerText');
let lastModificationCurrentValue = await nightmare let lastModificationCurrentValue = await nightmare
.waitToGetProperty(selectors.clientLog.lastModificationCurrentValue, 'innerText'); .waitToGetProperty(selectors.clientLog.lastModificationCurrentValue, 'innerText');
expect(lastModificationCurrentValue).toContain('this is a test'); let month = date.getMonth() + 1;
let day = date.getDate();
let year = date.getFullYear();
let hours = date.getHours();
let minutes = date.getMinutes();
if (month.toString().length < 2) month = '0' + month;
if (day.toString().length < 2) day = `0${day}`;
if (hours.toString().length < 2) hours = '0' + hours;
if (minutes.toString().length < 2) minutes = `0${minutes}`;
let today = [day, month, year].join('/');
let time = [hours, minutes].join(':');
let now = [today, time].join(' ');
expect(lastModificationDate).toContain(now);
expect(lastModificationPreviousValue).toEqual('name: DavidCharlesHaller');
expect(lastModificationCurrentValue).toEqual('name: this is a test');
}); });
}); });

View File

@ -1,15 +1,14 @@
import selectors from '../../helpers/selectors.js'; import selectors from '../../helpers/selectors.js';
import createNightmare from '../../helpers/nightmare'; import createNightmare from '../../helpers/nightmare';
// #860 E2E client/client/src/web-payment/index.js missing fixtures for another client describe('Client web Payment', () => {
xdescribe('Client web Payment', () => {
const nightmare = createNightmare(); const nightmare = createNightmare();
describe('as employee', () => { describe('as employee', () => {
beforeAll(() => { beforeAll(() => {
nightmare nightmare
.loginAndModule('employee', 'client') .loginAndModule('employee', 'client')
.accessToSearchResult('Bruce Wayne') .accessToSearchResult('Tony Stark')
.accessToSection('client.card.webPayment'); .accessToSection('client.card.webPayment');
}); });
@ -25,13 +24,14 @@ xdescribe('Client web Payment', () => {
beforeAll(() => { beforeAll(() => {
nightmare nightmare
.loginAndModule('administrative', 'client') .loginAndModule('administrative', 'client')
.accessToSearchResult('Bruce Wayne') .accessToSearchResult('Tony Stark')
.accessToSection('client.card.webPayment'); .accessToSection('client.card.webPayment');
}); });
it('should be able to confirm payments', async() => { it('should be able to confirm payments', async() => {
let exists = await nightmare let exists = await nightmare
.waitToClick(selectors.webPayment.confirmFirstPaymentButton) .waitToClick(selectors.webPayment.confirmFirstPaymentButton)
.wait(selectors.webPayment.firstPaymentConfirmed)
.exists(selectors.webPayment.firstPaymentConfirmed); .exists(selectors.webPayment.firstPaymentConfirmed);
expect(exists).toBeTruthy(); expect(exists).toBeTruthy();

View File

@ -7,7 +7,7 @@ describe('Item Create botanical path', () => {
beforeAll(() => { beforeAll(() => {
nightmare nightmare
.loginAndModule('buyer', 'item') .loginAndModule('buyer', 'item')
.accessToSearchResult('Object5 Weapon 50') .accessToSearchResult('Object5 Weapon 50 hasVisible:false')
.accessToSection('item.card.botanical'); .accessToSection('item.card.botanical');
}); });

View File

@ -95,7 +95,7 @@ describe('Item Create/Clone path', () => {
it(`should search for the item Infinity Gauntlet`, async() => { it(`should search for the item Infinity Gauntlet`, async() => {
const result = await nightmare const result = await nightmare
.write(selectors.itemsIndex.searchItemInput, 'Infinity Gauntlet') .write(selectors.itemsIndex.searchItemInput, 'Infinity Gauntlet hasVisible:false')
.waitToClick(selectors.itemsIndex.searchButton) .waitToClick(selectors.itemsIndex.searchButton)
.waitForNumberOfElements(selectors.itemsIndex.searchResult, 1) .waitForNumberOfElements(selectors.itemsIndex.searchResult, 1)
.countElement(selectors.itemsIndex.searchResult); .countElement(selectors.itemsIndex.searchResult);
@ -117,7 +117,7 @@ describe('Item Create/Clone path', () => {
it('should search for the item Infinity Gauntlet and find two', async() => { it('should search for the item Infinity Gauntlet and find two', async() => {
const result = await nightmare const result = await nightmare
.waitToClick(selectors.itemTags.goToItemIndexButton) .waitToClick(selectors.itemTags.goToItemIndexButton)
.write(selectors.itemsIndex.searchItemInput, 'Infinity Gauntlet') .write(selectors.itemsIndex.searchItemInput, 'Infinity Gauntlet hasVisible:false')
.waitToClick(selectors.itemsIndex.searchButton) .waitToClick(selectors.itemsIndex.searchButton)
.waitForNumberOfElements(selectors.itemsIndex.searchResult, 2) .waitForNumberOfElements(selectors.itemsIndex.searchResult, 2)
.countElement(selectors.itemsIndex.searchResult); .countElement(selectors.itemsIndex.searchResult);

View File

@ -1,7 +1,8 @@
import selectors from '../../helpers/selectors.js'; import selectors from '../../helpers/selectors.js';
import createNightmare from '../../helpers/nightmare'; import createNightmare from '../../helpers/nightmare';
describe('Item regularize path', () => { // #1186 repearar e2e ticket.sale, item.regularize.
xdescribe('Item regularize path', () => {
const nightmare = createNightmare(); const nightmare = createNightmare();
beforeAll(() => { beforeAll(() => {
nightmare nightmare
@ -176,7 +177,7 @@ describe('Item regularize path', () => {
it('should search for the ticket with id 23 once again', async() => { it('should search for the ticket with id 23 once again', async() => {
const result = await nightmare const result = await nightmare
.write(selectors.ticketsIndex.searchTicketInput, 'id:23') .write(selectors.ticketsIndex.searchTicketInput, 'id:24')
.waitToClick(selectors.ticketsIndex.searchButton) .waitToClick(selectors.ticketsIndex.searchButton)
.waitForNumberOfElements(selectors.ticketsIndex.searchResult, 1) .waitForNumberOfElements(selectors.ticketsIndex.searchResult, 1)
.countElement(selectors.ticketsIndex.searchResult); .countElement(selectors.ticketsIndex.searchResult);
@ -186,7 +187,7 @@ describe('Item regularize path', () => {
it(`should now click on the search result to access to the ticket summary`, async() => { it(`should now click on the search result to access to the ticket summary`, async() => {
const url = await nightmare const url = await nightmare
.waitForTextInElement(selectors.ticketsIndex.searchResult, '23') .waitForTextInElement(selectors.ticketsIndex.searchResult, '24')
.waitToClick(selectors.ticketsIndex.searchResult) .waitToClick(selectors.ticketsIndex.searchResult)
.waitForURL('/summary') .waitForURL('/summary')
.parsedUrl(); .parsedUrl();

View File

@ -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();
});
});

View File

@ -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!');
});
});

View File

@ -15,21 +15,21 @@ describe('Ticket List sale path', () => {
const value = await nightmare const value = await nightmare
.waitToGetProperty(selectors.ticketSales.firstSaleColour, 'innerText'); .waitToGetProperty(selectors.ticketSales.firstSaleColour, 'innerText');
expect(value).toContain('Red'); expect(value).toContain('Yellow');
}); });
it('should confirm the first ticket sale contains the lenght', async() => { it('should confirm the first ticket sale contains the lenght', async() => {
const value = await nightmare const value = await nightmare
.waitToGetProperty(selectors.ticketSales.firstSaleText, 'innerText'); .waitToGetProperty(selectors.ticketSales.firstSaleText, 'innerText');
expect(value).toContain('3'); expect(value).toContain('5');
}); });
it('should confirm the first ticket sale contains the price', async() => { it('should confirm the first ticket sale contains the price', async() => {
const value = await nightmare const value = await nightmare
.waitToGetProperty(selectors.ticketSales.firstSalePrice, 'innerText'); .waitToGetProperty(selectors.ticketSales.firstSalePrice, 'innerText');
expect(value).toContain('1.30'); expect(value).toContain('2.30');
}); });
it('should confirm the first ticket sale contains the discount', async() => { it('should confirm the first ticket sale contains the discount', async() => {
@ -43,7 +43,7 @@ describe('Ticket List sale path', () => {
const value = await nightmare const value = await nightmare
.waitToGetProperty(selectors.ticketSales.firstSaleImport, 'innerText'); .waitToGetProperty(selectors.ticketSales.firstSaleImport, 'innerText');
expect(value).toContain('19.50'); expect(value).toContain('23');
}); });
it('should navigate to the catalog by pressing the new item button', async() => { it('should navigate to the catalog by pressing the new item button', async() => {

View File

@ -1,7 +1,7 @@
import selectors from '../../helpers/selectors.js'; import selectors from '../../helpers/selectors.js';
import createNightmare from '../../helpers/nightmare'; import createNightmare from '../../helpers/nightmare';
// #1152 refactor ticket.sale, update price no funciona correctamente. // #1186 repearar e2e ticket.sale, item.regularize.
xdescribe('Ticket Edit sale path', () => { xdescribe('Ticket Edit sale path', () => {
const nightmare = createNightmare(); const nightmare = createNightmare();
@ -138,7 +138,7 @@ xdescribe('Ticket Edit sale path', () => {
it('should try to add a higher quantity value and then receive an error', async() => { it('should try to add a higher quantity value and then receive an error', async() => {
const result = await nightmare const result = await nightmare
.waitToClick(selectors.ticketSales.firstSaleQuantityClearInput) .waitToFocus(selectors.ticketSales.firstSaleQuantityCell)
.write(selectors.ticketSales.firstSaleQuantity, '9\u000d') .write(selectors.ticketSales.firstSaleQuantity, '9\u000d')
.waitForLastSnackbar(); .waitForLastSnackbar();
@ -147,7 +147,7 @@ xdescribe('Ticket Edit sale path', () => {
it('should remove 1 from quantity', async() => { it('should remove 1 from quantity', async() => {
const result = await nightmare const result = await nightmare
.waitToClick(selectors.ticketSales.firstSaleQuantityClearInput) .waitToFocus(selectors.ticketSales.firstSaleQuantityCell)
.write(selectors.ticketSales.firstSaleQuantity, '4\u000d') .write(selectors.ticketSales.firstSaleQuantity, '4\u000d')
.waitForLastSnackbar(); .waitForLastSnackbar();
@ -180,7 +180,6 @@ xdescribe('Ticket Edit sale path', () => {
it('should update the discount', async() => { it('should update the discount', async() => {
const result = await nightmare const result = await nightmare
.waitToClick(selectors.ticketSales.firstSaleDiscount) .waitToClick(selectors.ticketSales.firstSaleDiscount)
.wait('vn-textfield[label="Discount"] > div[class="container selected"]') // a function selects the text after it's loaded
.write(selectors.ticketSales.firstSaleDiscountInput, '50\u000d') .write(selectors.ticketSales.firstSaleDiscountInput, '50\u000d')
// .write('body', '\u000d') // simulates enter // .write('body', '\u000d') // simulates enter
.waitForLastSnackbar(); .waitForLastSnackbar();
@ -467,7 +466,7 @@ xdescribe('Ticket Edit sale path', () => {
.waitToClick(selectors.ticketSales.moreMenuButton) .waitToClick(selectors.ticketSales.moreMenuButton)
.waitToClick(selectors.ticketSales.moreMenuUpdateDiscount) .waitToClick(selectors.ticketSales.moreMenuUpdateDiscount)
.write(selectors.ticketSales.moreMenuUpdateDiscountInput, 100) .write(selectors.ticketSales.moreMenuUpdateDiscountInput, 100)
.write('body', '\u000d') // simulates enter .write('body', '\u000d')
.waitForTextInElement(selectors.ticketSales.totalImport, '0.00') .waitForTextInElement(selectors.ticketSales.totalImport, '0.00')
.waitToGetProperty(selectors.ticketSales.totalImport, 'innerText'); .waitToGetProperty(selectors.ticketSales.totalImport, 'innerText');
@ -597,16 +596,16 @@ xdescribe('Ticket Edit sale path', () => {
describe('when state is preparation and loged as salesPerson', () => { describe('when state is preparation and loged as salesPerson', () => {
it(`shouldnt be able to edit the sale price`, async() => { it(`shouldnt be able to edit the sale price`, async() => {
const result = await nightmare const result = await nightmare
.waitToClick(selectors.ticketSales.firstSalePrice) .waitToClick(selectors.ticketSales.firstSaleID)
.exists(selectors.ticketSales.firstSalePriceInput); .exists(selectors.ticketSales.firstSalePrice);
expect(result).toBeFalsy(); expect(result).toBeFalsy();
}); });
it(`shouldnt be able to edit the sale discount`, async() => { it(`shouldnt be able to edit the sale discount`, async() => {
const result = await nightmare const result = await nightmare
.waitToClick(selectors.ticketSales.firstSaleDiscount) .waitToClick(selectors.ticketSales.firstSaleID)
.exists(selectors.ticketSales.firstSaleDiscountInput); .exists(selectors.ticketSales.firstSaleDiscount);
expect(result).toBeFalsy(); expect(result).toBeFalsy();
}); });

View File

@ -7,7 +7,7 @@ describe('Ticket services path', () => {
beforeAll(() => { beforeAll(() => {
nightmare nightmare
.loginAndModule('employee', 'ticket') .loginAndModule('employee', 'ticket')
.accessToSearchResult('id:1') .accessToSearchResult('1')
.accessToSection('ticket.card.service'); .accessToSection('ticket.card.service');
}); });
@ -24,7 +24,7 @@ describe('Ticket services path', () => {
.waitForLastSnackbar(); .waitForLastSnackbar();
expect(result).toEqual('Data saved!'); expect(result).toEqual('Data saved!');
}); }, 15000);
it('should confirm the service description was edited correctly', async() => { it('should confirm the service description was edited correctly', async() => {
const result = await nightmare const result = await nightmare

View File

@ -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!');
});
});

View File

@ -1,5 +1,6 @@
FROM debian:stretch-slim FROM debian:stretch-slim
EXPOSE 80 EXPOSE 80
ENV TZ Europe/Madrid
ARG DEBIAN_FRONTEND=noninteractive ARG DEBIAN_FRONTEND=noninteractive
RUN apt-get update \ RUN apt-get update \

View File

@ -15,9 +15,8 @@ export default class Button extends Input {
} }
$onInit() { $onInit() {
if (!this.type) { if (!this.type)
this.type = 'button'; this.type = 'button';
}
} }
} }
Button.$inject = ['$element']; Button.$inject = ['$element'];

View File

@ -10,8 +10,8 @@
</vn-auto> </vn-auto>
<vn-one> <vn-one>
<strong> <strong>
<span translate>{{$ctrl.defaultDate | date: 'MMMM'}}</span> <span translate>{{$ctrl.defaultDate | dateTime: 'MMMM'}}</span>
<span>{{$ctrl.defaultDate | date: 'yyyy'}}</span> <span>{{$ctrl.defaultDate | dateTime: 'yyyy'}}</span>
</strong> </strong>
</vn-one> </vn-one>
<vn-auto> <vn-auto>
@ -19,7 +19,7 @@
icon="keyboard_arrow_right" icon="keyboard_arrow_right"
class="pointer" class="pointer"
ng-click="$ctrl.moveNext($ctrl.skip)" ng-click="$ctrl.moveNext($ctrl.skip)"
ng-show="$ctrl.displayControls" ng-show="$ctrl.displayControls">
</vn-icon> </vn-icon>
</vn-auto> </vn-auto>
</vn-horizontal> </vn-horizontal>

View File

@ -71,8 +71,6 @@ export default class Calendar extends Component {
date.getFullYear(), date.getFullYear(),
date.getMonth(), 1); date.getMonth(), 1);
this.applyOffset(newDate);
return newDate; return newDate;
} }
@ -87,15 +85,9 @@ export default class Calendar extends Component {
date.getFullYear(), date.getFullYear(),
date.getMonth() + 1, 0); date.getMonth() + 1, 0);
this.applyOffset(newDate);
return newDate; return newDate;
} }
applyOffset(date) {
date.setTime(date.getTime() - date.getTimezoneOffset() * 60000);
}
repaint() { repaint() {
const firstWeekday = this.firstDay(this.currentMonth).getDay(); const firstWeekday = this.firstDay(this.currentMonth).getDay();
const previousLastDay = this.lastDay(this.previousMonth).getDate(); const previousLastDay = this.lastDay(this.previousMonth).getDate();
@ -124,27 +116,14 @@ export default class Calendar extends Component {
} }
addDay(date, day, color = '') { addDay(date, day, color = '') {
const curDate = new Date();
curDate.setHours(0, 0, 0, 0);
this.applyOffset(curDate);
const newDate = new Date( const newDate = new Date(
date.getFullYear(), date.getFullYear(),
date.getMonth(), day); date.getMonth(), day);
this.applyOffset(newDate);
let event = this.events.find(event => { let event = this.events.find(event => {
return event.date >= newDate && event.date <= newDate; return event.date >= newDate && event.date <= newDate;
}); });
/* if (curDate >= newDate && curDate <= newDate)
color = 'orange'; */
/* if (newDate.getMonth() === this.currentMonth.getMonth() && newDate.getDay() == 6)
color = 'light-blue'; */
if (newDate.getMonth() === this.currentMonth.getMonth() && newDate.getDay() == 0) if (newDate.getMonth() === this.currentMonth.getMonth() && newDate.getDay() == 0)
color = 'red'; color = 'red';

View File

@ -28,14 +28,8 @@ class DatePicker extends Component {
onValueUpdate() { onValueUpdate() {
if (this.vp.selectedDates.length) { if (this.vp.selectedDates.length) {
let date = this.vp.selectedDates[0]; let date = this.vp.selectedDates[0];
let offset = date.getTimezoneOffset() * 60000;
if (!this.isLocale && !this._iniOptions.enableTime) { date.setTime(date.getTime() - offset);
let now = new Date();
let offset = now.getTimezoneOffset() * 60000;
date.setHours(0, 0, 0, 0);
date.setTime(date.getTime() - offset);
}
this._model = date; this._model = date;
} else } else
this.model = null; this.model = null;
@ -67,8 +61,16 @@ class DatePicker extends Component {
set model(value) { set model(value) {
this._model = value; this._model = value;
this.dateValue = value ? new Date(value) : null; this.dateValue = value;
this.vp.setDate(this.dateValue); let date;
if (value && this.iniOptions.enableTime) {
date = new Date(value);
let offset = date.getTimezoneOffset() * 60000;
date.setTime(date.getTime() + offset);
} else
date = value;
this.vp.setDate(date);
this.mdlUpdate(); this.mdlUpdate();
} }
@ -84,6 +86,7 @@ class DatePicker extends Component {
$onDestroy() { $onDestroy() {
this.vp.destroy(); this.vp.destroy();
this.dateValue = undefined;
} }
} }
DatePicker.$inject = ['$element', '$scope', '$translate', '$attrs']; DatePicker.$inject = ['$element', '$scope', '$translate', '$attrs'];
@ -91,12 +94,12 @@ DatePicker.$inject = ['$element', '$scope', '$translate', '$attrs'];
ngModule.component('vnDatePicker', { ngModule.component('vnDatePicker', {
template: require('./date-picker.html'), template: require('./date-picker.html'),
bindings: { bindings: {
iniOptions: '<?',
model: '=', model: '=',
label: '@?', label: '@?',
name: '@?', name: '@?',
disabled: '<?', disabled: '<?',
rule: '<?', rule: '<?',
iniOptions: '<?',
isLocale: '<?' isLocale: '<?'
}, },
controller: DatePicker controller: DatePicker

View File

@ -3,6 +3,7 @@
<div class="textField"> <div class="textField">
<div class="leftIcons"> <div class="leftIcons">
<vn-icon-button <vn-icon-button
ng-if="$ctrl.displayControls"
icon="remove" icon="remove"
ng-click="$ctrl.remove()" ng-click="$ctrl.remove()"
tabindex="-1" tabindex="-1"
@ -13,7 +14,7 @@
<input <input
class="mdl-textfield__input" class="mdl-textfield__input"
type="number" type="number"
name="{{$ctrl.name}}" name="{{::$ctrl.name}}"
ng-model="$ctrl.value" ng-model="$ctrl.value"
ng-disabled="$ctrl.disabled" ng-disabled="$ctrl.disabled"
ng-readonly="$ctrl.readonly" ng-readonly="$ctrl.readonly"
@ -26,14 +27,15 @@
<div class="selected underline"></div> <div class="selected underline"></div>
<div class="suffix"> <div class="suffix">
<vn-icon-button <vn-icon-button
ng-if="$ctrl.displayControls"
icon="add" icon="add"
ng-click="$ctrl.add()" ng-click="$ctrl.add()"
tabindex="-1" tabindex="-1"
translate-attr="{title: 'Add'}"> translate-attr="{title: 'Add'}">
</vn-icon-button> </vn-icon-button>
<i class="material-icons" <i class="material-icons"
ng-if="$ctrl.hasInfo" ng-if="::$ctrl.hasInfo"
vn-tooltip="{{$ctrl.info}}"> vn-tooltip="{{::$ctrl.info}}">
info_outline info_outline
</i> </i>
</div> </div>

View File

@ -3,10 +3,9 @@ import Textfield from '../textfield/textfield';
import './style.scss'; import './style.scss';
export default class InputNumber extends Textfield { export default class InputNumber extends Textfield {
constructor($element, $scope, $attrs, vnTemplate, $transclude) { constructor($element, $scope, $attrs, vnTemplate, $transclude) {
super($element, $scope, $attrs, vnTemplate, $transclude); super($element, $scope, $attrs, vnTemplate, $transclude);
this.displayControls = true;
this.input.addEventListener('change', () => { this.input.addEventListener('change', () => {
this.validateValue(); this.validateValue();
}); });
@ -56,30 +55,30 @@ export default class InputNumber extends Textfield {
if ((this.validate() !== undefined && !this.validate()) || if ((this.validate() !== undefined && !this.validate()) ||
(this.max && this.value > this.max) || (this.max && this.value > this.max) ||
(this.min && this.value < this.min) || (this.min && this.value < this.min) ||
(this.step && this.value % this.step != 0)) { (this.displayControls && (this.step && this.value % this.step != 0)))
this.$element[0].querySelector('.infix').classList.add('invalid', 'validated'); this.$element[0].querySelector('.infix').classList.add('invalid', 'validated');
}
if (this.onChange) if (this.onChange)
this.onChange(); this.onChange();
} }
add() { add() {
if (this.step && this.value % this.step != 0) { if (this.step && this.value % this.step != 0)
this.value += (this.step - this.value % this.step); this.value += (this.step - this.value % this.step);
} else { else
this.value += this.step; this.value += this.step;
}
this.validateValue(); this.validateValue();
} }
remove() { remove() {
if (this.step && this.value % this.step != 0) { if (this.step && this.value % this.step != 0)
this.value -= (this.step + this.value % this.step); this.value -= (this.step + this.value % this.step);
} else { else
this.value -= this.step; this.value -= this.step;
}
this.validateValue(); this.validateValue();
} }
} }
@ -95,6 +94,7 @@ ngModule.component('vnInputNumber', {
min: '<?', min: '<?',
max: '<?', max: '<?',
step: '<?', step: '<?',
displayControls: '<?',
rule: '@?', rule: '@?',
value: '=model', value: '=model',
validate: '&', validate: '&',

View File

@ -17,7 +17,7 @@
<vn-tbody> <vn-tbody>
<vn-tr ng-repeat="log in $ctrl.model.data"> <vn-tr ng-repeat="log in $ctrl.model.data">
<vn-td> <vn-td>
{{::log.creationDate | date:'dd/MM/yyyy HH:mm'}} {{::log.creationDate | dateTime:'dd/MM/yyyy HH:mm'}}
<div class="changes"> <div class="changes">
<div> <div>
<span translate class="label">Changed by</span><span class="label">: </span> <span translate class="label">Changed by</span><span class="label">: </span>

View File

@ -0,0 +1,84 @@
import './searchbar.js';
describe('Component vnSearchbar', () => {
let controller;
let $element;
let $state;
beforeEach(ngModule('vnCore'));
beforeEach(angular.mock.inject(($componentController, _$state_) => {
$state = _$state_;
$element = angular.element(`<div></div>`);
controller = $componentController('vnSearchbar', {$element, $state});
controller.panel = 'vn-client-search-panel';
}));
describe('$postLink()', () => {
it(`should not call onStateChange() if filter is defined`, () => {
spyOn(controller, 'onStateChange');
controller.filter = {};
controller.$postLink();
expect(controller.onStateChange).not.toHaveBeenCalledWith();
});
it(`should call onStateChange() if filter is null`, () => {
spyOn(controller, 'onStateChange');
controller.filter = null;
controller.$postLink();
expect(controller.onStateChange).toHaveBeenCalledWith();
});
});
describe('filter() setter', () => {
it(`should call $state.go()`, () => {
controller._filter = {};
spyOn(controller.$state, 'go');
controller.filter = {expected: 'filter'};
expect(controller._filter).toEqual(controller.filter);
expect(controller.$state.go).toHaveBeenCalledWith('.', Object({q: '{"expected":"filter"}'}));
});
});
describe('openPanel()', () => {
it(`should do nothing if the event is prevented`, () => {
let event = {
defaultPrevented: true,
preventDefault: jasmine.createSpy('preventDefault')
};
controller.openPanel(event);
expect(event.preventDefault).not.toHaveBeenCalledWith();
});
});
describe('getObjectFromString()', () => {
it(`should return a formated object based on the string received for basic search`, () => {
let result = controller.getObjectFromString('Bruce Wayne');
expect(result).toEqual({search: 'Bruce Wayne'});
});
it(`should return a formated object based on the string received for advanced search`, () => {
let result = controller.getObjectFromString('id:101 name:(Bruce Wayne)');
expect(result).toEqual({id: '101', name: 'Bruce Wayne'});
});
it(`should format the object grouping any unmatched part of the instring of the string to the search property`, () => {
let string = 'I am the search id:101 name:(Bruce Wayne) concatenated value';
let result = controller.getObjectFromString(string);
expect(result).toEqual({
id: '101',
name: 'Bruce Wayne',
search: 'I am the search concatenated value'
});
});
});
});

View File

@ -11,7 +11,8 @@ export default class Controller extends Component {
element.tabIndex = 0; element.tabIndex = 0;
element.addEventListener('focus', () => { element.addEventListener('focus', () => {
if (this.field) return; if (this.field || this.disabled) return;
$transclude((tClone, tScope) => { $transclude((tClone, tScope) => {
this.field = tClone; this.field = tClone;
this.tScope = tScope; this.tScope = tScope;
@ -26,7 +27,8 @@ export default class Controller extends Component {
}); });
element.addEventListener('focusout', event => { element.addEventListener('focusout', event => {
this.destroyTimer(); if (!this.field || this.disabled) return;
// this.destroyTimer();
this.lastEvent = event; this.lastEvent = event;
let target = event.relatedTarget; let target = event.relatedTarget;
while (target && target != element) while (target && target != element)
@ -57,6 +59,9 @@ Controller.$inject = ['$element', '$scope', '$transclude', '$timeout'];
ngModule.component('vnTdEditable', { ngModule.component('vnTdEditable', {
template: require('./index.html'), template: require('./index.html'),
controller: Controller, controller: Controller,
bindings: {
disabled: '<?'
},
transclude: { transclude: {
text: 'text', text: 'text',
field: '?field' field: '?field'

View File

@ -1,10 +1,24 @@
@import "variables"; @import "variables";
vn-td-editable { vn-td-editable {
cursor: pointer; text {
cursor: pointer;
display: block
}
outline: none; outline: none;
position: relative; position: relative;
&:not([disabled="true"]) {
cursor: initial;
text:hover::after {
font-family: 'salixfont';
float: right;
content: '\e900';
display: block
}
}
&.selected > .text { &.selected > .text {
visibility: hidden; visibility: hidden;
} }

View File

@ -18,18 +18,15 @@ export default class Textfield extends Input {
if (!this.oldValue) if (!this.oldValue)
this.saveOldValue(); this.saveOldValue();
}); });
this.input.addEventListener('keyup', e => { this.input.addEventListener('keyup', e => {
if (e.key == 'Escape') { if (e.defaultPrevented || e.key != 'Escape')
this.value = this.oldValue; return;
this.cancelled = true;
e.stopPropagation();
}
if (e.key == 'Escape' || e.key == 'Enter')
this.input.blur();
});
this.input.addEventListener('blur', () => { this.value = this.oldValue;
this.cancelled = true;
e.preventDefault();
});
this.input.addEventListener('change', e => {
if (this.onChange && !this.cancelled && (this.oldValue != this.value)) { if (this.onChange && !this.cancelled && (this.oldValue != this.value)) {
this.onChange(); this.onChange();
this.saveOldValue(); this.saveOldValue();

View File

@ -49,13 +49,26 @@ export function directive($http, $compile, vnApp, $translate) {
} }
}); });
let rule = selectors.join(', ') + '{display: none;}';
if ($scope.css)
document.head.removeChild($scope.css);
$scope.css = document.createElement('style'); if ($scope.css || document.querySelector('style[id="uvc"]')) {
document.head.appendChild($scope.css); let child = document.querySelector('style[id="uvc"]');
$scope.css.appendChild(document.createTextNode(rule)); child.parentNode.removeChild(child);
}
if (selectors.length) {
let rule = selectors.join(', ') + '{display: none;}';
$scope.css = document.createElement('style');
$scope.css.setAttribute('id', 'uvc');
document.head.appendChild($scope.css);
$scope.css.appendChild(document.createTextNode(rule));
}
$scope.$on('$destroy', () => {
if ($scope.css && document.querySelector('style[id="uvc"]')) {
let child = document.querySelector('style[id="uvc"]');
child.parentNode.removeChild(child);
}
});
} }
function saveConfiguration(tableConfiguration) { function saveConfiguration(tableConfiguration) {

View File

@ -9,7 +9,12 @@ dateTime.$inject = ['$filter'];
export default function dateTime($filter) { export default function dateTime($filter) {
return function(input, format) { return function(input, format) {
let value = typeof input === 'string' ? new Date(input) : input; let value;
if (input) {
value = new Date(input);
let offset = value.getTimezoneOffset() * 60000;
value.setTime(value.getTime() + offset);
}
return $filter('date')(value, format); return $filter('date')(value, format);
}; };

View File

@ -23,8 +23,8 @@
-moz-osx-font-smoothing: grayscale; -moz-osx-font-smoothing: grayscale;
} }
.icon-pets:before { .icon-unavailable:before {
content: "\e94e"; content: "\e94f";
} }
.icon-100:before { .icon-100:before {
content: "\e940"; content: "\e940";
@ -134,12 +134,12 @@
.icon-info:before { .icon-info:before {
content: "\e949"; content: "\e949";
} }
.icon-invoices1:before {
content: "\e94a";
}
.icon-invoices:before { .icon-invoices:before {
content: "\e91c"; content: "\e91c";
} }
.icon-invoices1:before {
content: "\e94a";
}
.icon-item:before { .icon-item:before {
content: "\e941"; content: "\e941";
} }
@ -191,6 +191,9 @@
.icon-person:before { .icon-person:before {
content: "\e929"; content: "\e929";
} }
.icon-pets:before {
content: "\e94e";
}
.icon-photo:before { .icon-photo:before {
content: "\e92a"; content: "\e92a";
} }

Binary file not shown.

View File

@ -86,4 +86,5 @@
<glyph unicode="&#xe94c;" glyph-name="revision" d="M358.4 140.8h-102.4v102.4h81.067c0 0 0 4.267 0 4.267 0 34.133 8.533 68.267 21.333 98.133h-102.4v102.4h170.667c51.2 51.2 123.733 85.333 200.533 102.4h-371.2v102.4h512v-93.867c76.8-8.533 149.333-34.133 204.8-72.533v268.8c0 55.467-46.933 102.4-102.4 102.4h-213.333c-21.333 59.733-76.8 102.4-145.067 102.4s-123.733-42.667-145.067-102.4h-213.333c-55.467 0-102.4-46.933-102.4-102.4v-716.8c0-55.467 46.933-102.4 102.4-102.4h546.133c-157.867 8.533-290.133 89.6-341.333 204.8zM512 857.6c29.867 0 51.2-21.333 51.2-51.2s-21.333-51.2-51.2-51.2-51.2 21.333-51.2 51.2c0 29.867 21.333 51.2 51.2 51.2zM721.067 452.267c-136.533 0-251.733-85.333-302.933-204.8 46.933-119.467 162.133-204.8 302.933-204.8s251.733 85.333 302.933 204.8c-46.933 119.467-162.133 204.8-302.933 204.8zM721.067 110.933c-76.8 0-136.533 59.733-136.533 136.533s64 136.533 136.533 136.533 136.533-64 136.533-136.533-59.733-136.533-136.533-136.533zM721.067 328.533c-46.933 0-81.067-38.4-81.067-81.067s38.4-81.067 81.067-81.067c46.933 0 81.067 38.4 81.067 81.067s-34.133 81.067-81.067 81.067z" /> <glyph unicode="&#xe94c;" glyph-name="revision" d="M358.4 140.8h-102.4v102.4h81.067c0 0 0 4.267 0 4.267 0 34.133 8.533 68.267 21.333 98.133h-102.4v102.4h170.667c51.2 51.2 123.733 85.333 200.533 102.4h-371.2v102.4h512v-93.867c76.8-8.533 149.333-34.133 204.8-72.533v268.8c0 55.467-46.933 102.4-102.4 102.4h-213.333c-21.333 59.733-76.8 102.4-145.067 102.4s-123.733-42.667-145.067-102.4h-213.333c-55.467 0-102.4-46.933-102.4-102.4v-716.8c0-55.467 46.933-102.4 102.4-102.4h546.133c-157.867 8.533-290.133 89.6-341.333 204.8zM512 857.6c29.867 0 51.2-21.333 51.2-51.2s-21.333-51.2-51.2-51.2-51.2 21.333-51.2 51.2c0 29.867 21.333 51.2 51.2 51.2zM721.067 452.267c-136.533 0-251.733-85.333-302.933-204.8 46.933-119.467 162.133-204.8 302.933-204.8s251.733 85.333 302.933 204.8c-46.933 119.467-162.133 204.8-302.933 204.8zM721.067 110.933c-76.8 0-136.533 59.733-136.533 136.533s64 136.533 136.533 136.533 136.533-64 136.533-136.533-59.733-136.533-136.533-136.533zM721.067 328.533c-46.933 0-81.067-38.4-81.067-81.067s38.4-81.067 81.067-81.067c46.933 0 81.067 38.4 81.067 81.067s-34.133 81.067-81.067 81.067z" />
<glyph unicode="&#xe94d;" glyph-name="services" d="M951.467 217.6c0 8.533 0 21.333 0 29.867s0 21.333-4.267 29.867l64 51.2c4.267 4.267 8.533 12.8 4.267 21.333l-64 106.667c-4.267 8.533-12.8 8.533-17.067 8.533l-76.8-29.867c-17.067 12.8-34.133 21.333-51.2 29.867l-12.8 81.067c0 8.533-8.533 12.8-17.067 12.8h-123.733c-8.533 0-12.8-4.267-17.067-12.8l-12.8-81.067c-17.067-8.533-38.4-17.067-51.2-29.867l-76.8 29.867c-8.533 4.267-17.067 0-17.067-8.533l-64-106.667c-4.267-8.533-4.267-17.067 4.267-21.333l64-51.2c0-8.533-4.267-21.333-4.267-29.867s0-21.333 4.267-29.867l-55.467-51.2c-4.267-4.267-8.533-12.8-4.267-21.333l64-106.667c4.267-8.533 12.8-8.533 17.067-8.533l76.8 29.867c17.067-12.8 34.133-21.333 51.2-29.867l12.8-81.067c0-8.533 8.533-12.8 17.067-12.8h123.733c8.533 0 12.8 4.267 17.067 12.8l12.8 81.067c17.067 8.533 38.4 17.067 51.2 29.867l76.8-29.867c8.533-4.267 17.067 0 17.067 8.533l64 106.667c4.267 8.533 4.267 17.067-4.267 21.333 0 0-68.267 51.2-68.267 51.2zM721.067 132.267c-64 0-115.2 51.2-115.2 115.2s51.2 115.2 115.2 115.2 115.2-51.2 115.2-115.2c0-64-51.2-115.2-115.2-115.2zM345.6 174.933h-89.6v102.4h81.067c4.267 34.133 8.533 68.267 21.333 102.4h-102.4v102.4h162.133c34.133 42.667 72.533 76.8 119.467 102.4h-281.6v102.4h520.533v-59.733c51.2-8.533 102.4-25.6 145.067-51.2v281.6c0 55.467-46.933 102.4-102.4 102.4h-622.933c-55.467 0-102.4-46.933-102.4-102.4v-819.2c0-55.467 46.933-102.4 102.4-102.4h302.933c-81.067 55.467-136.533 140.8-153.6 238.933z" /> <glyph unicode="&#xe94d;" glyph-name="services" d="M951.467 217.6c0 8.533 0 21.333 0 29.867s0 21.333-4.267 29.867l64 51.2c4.267 4.267 8.533 12.8 4.267 21.333l-64 106.667c-4.267 8.533-12.8 8.533-17.067 8.533l-76.8-29.867c-17.067 12.8-34.133 21.333-51.2 29.867l-12.8 81.067c0 8.533-8.533 12.8-17.067 12.8h-123.733c-8.533 0-12.8-4.267-17.067-12.8l-12.8-81.067c-17.067-8.533-38.4-17.067-51.2-29.867l-76.8 29.867c-8.533 4.267-17.067 0-17.067-8.533l-64-106.667c-4.267-8.533-4.267-17.067 4.267-21.333l64-51.2c0-8.533-4.267-21.333-4.267-29.867s0-21.333 4.267-29.867l-55.467-51.2c-4.267-4.267-8.533-12.8-4.267-21.333l64-106.667c4.267-8.533 12.8-8.533 17.067-8.533l76.8 29.867c17.067-12.8 34.133-21.333 51.2-29.867l12.8-81.067c0-8.533 8.533-12.8 17.067-12.8h123.733c8.533 0 12.8 4.267 17.067 12.8l12.8 81.067c17.067 8.533 38.4 17.067 51.2 29.867l76.8-29.867c8.533-4.267 17.067 0 17.067 8.533l64 106.667c4.267 8.533 4.267 17.067-4.267 21.333 0 0-68.267 51.2-68.267 51.2zM721.067 132.267c-64 0-115.2 51.2-115.2 115.2s51.2 115.2 115.2 115.2 115.2-51.2 115.2-115.2c0-64-51.2-115.2-115.2-115.2zM345.6 174.933h-89.6v102.4h81.067c4.267 34.133 8.533 68.267 21.333 102.4h-102.4v102.4h162.133c34.133 42.667 72.533 76.8 119.467 102.4h-281.6v102.4h520.533v-59.733c51.2-8.533 102.4-25.6 145.067-51.2v281.6c0 55.467-46.933 102.4-102.4 102.4h-622.933c-55.467 0-102.4-46.933-102.4-102.4v-819.2c0-55.467 46.933-102.4 102.4-102.4h302.933c-81.067 55.467-136.533 140.8-153.6 238.933z" />
<glyph unicode="&#xe94e;" glyph-name="pets" d="M1024 571.733c-4.267 46.933-25.6 81.067-55.467 110.933-34.133 29.867-72.533 42.667-110.933 38.4 0 0-4.267 0-4.267 0 0 8.533 0 17.067-4.267 29.867-8.533 51.2-29.867 98.133-68.267 128-25.6 21.333-51.2 34.133-72.533 38.4-29.867 4.267-59.733 0-76.8-4.267-42.667-8.533-81.067-34.133-110.933-72.533-21.333 25.6-42.667 46.933-68.267 64-64 38.4-140.8 29.867-196.267-21.333-25.6-21.333-42.667-46.933-51.2-81.067-12.8-29.867-17.067-59.733-17.067-93.867-8.533 0-17.067 0-25.6 0-42.667 0-81.067-17.067-110.933-46.933-29.867-34.133-42.667-76.8-46.933-98.133-4.267-12.8-4.267-25.6-4.267-42.667 4.267-55.467 25.6-110.933 59.733-157.867 29.867-38.4 68.267-64 110.933-76.8-4.267-12.8-8.533-21.333-8.533-34.133 0-4.267-4.267-8.533-4.267-17.067-12.8-42.667-25.6-98.133 4.267-162.133 29.867-59.733 89.6-102.4 157.867-106.667 4.267 0 12.8 0 17.067 0 46.933 0 85.333 17.067 119.467 29.867 4.267 0 8.533 4.267 12.8 4.267 17.067 4.267 34.133 12.8 51.2 12.8 8.533 0 17.067-4.267 34.133-12.8s42.667-21.333 68.267-25.6c29.867-4.267 64-4.267 93.867 0 38.4 8.533 68.267 21.333 89.6 38.4 59.733 46.933 68.267 128 51.2 187.733-8.533 25.6-21.333 55.467-34.133 85.333 29.867 4.267 55.467 12.8 76.8 29.867 81.067 51.2 110.933 128 119.467 187.733 4.267 12.8 4.267 51.2 4.267 68.267zM541.867 674.133c4.267 42.667 21.333 81.067 42.667 115.2 34.133 42.667 93.867 68.267 136.533 25.6 0 0 0 0 0 0 21.333-21.333 34.133-51.2 34.133-81.067 4.267-38.4 0-72.533-17.067-106.667-17.067-38.4-38.4-68.267-76.8-89.6-46.933-25.6-102.4-8.533-119.467 42.667-4.267 29.867-4.267 68.267 0 93.867zM277.333 776.533c8.533 17.067 17.067 34.133 34.133 46.933 29.867 29.867 64 34.133 102.4 8.533 51.2-29.867 81.067-85.333 85.333-145.067 4.267-51.2-12.8-115.2-64-145.067-17.067-4.267-34.133-8.533-51.2-4.267-21.333 4.267-38.4 17.067-51.2 29.867-55.467 46.933-76.8 140.8-55.467 209.067zM123.733 413.867c-34.133 46.933-55.467 110.933-34.133 170.667 12.8 25.6 34.133 42.667 64 46.933 25.6 4.267 51.2-8.533 72.533-25.6 8.533-4.267 12.8-12.8 17.067-17.067 17.067-21.333 29.867-46.933 34.133-72.533 8.533-29.867 12.8-59.733 8.533-85.333-4.267-34.133-29.867-64-64-68.267-38.4-4.267-76.8 21.333-98.133 51.2zM755.2 76.8c-29.867-25.6-81.067-29.867-115.2-21.333-42.667 8.533-72.533 38.4-115.2 42.667-29.867 0-55.467-8.533-85.333-17.067-38.4-12.8-76.8-34.133-115.2-29.867-25.6 0-55.467 12.8-72.533 34.133-42.667 42.667-29.867 110.933-8.533 162.133 17.067 55.467 55.467 102.4 98.133 140.8 17.067 17.067 38.4 34.133 64 42.667 25.6 12.8 55.467 17.067 85.333 17.067 34.133 0 68.267 0 98.133-12.8s55.467-29.867 72.533-55.467c21.333-25.6 42.667-51.2 59.733-81.067 17.067-25.6 34.133-55.467 46.933-85.333 17.067-34.133 21.333-76.8 4.267-110.933 0-12.8-8.533-21.333-17.067-25.6zM942.933 516.267c-8.533-55.467-34.133-106.667-81.067-136.533-17.067-12.8-38.4-17.067-64-17.067-42.667 0-72.533 34.133-81.067 72.533-17.067 76.8 59.733 200.533 140.8 204.8 21.333 0 38.4-4.267 51.2-21.333 21.333-17.067 29.867-42.667 34.133-68.267 0 4.267 4.267-8.533 0-34.133z" /> <glyph unicode="&#xe94e;" glyph-name="pets" d="M1024 571.733c-4.267 46.933-25.6 81.067-55.467 110.933-34.133 29.867-72.533 42.667-110.933 38.4 0 0-4.267 0-4.267 0 0 8.533 0 17.067-4.267 29.867-8.533 51.2-29.867 98.133-68.267 128-25.6 21.333-51.2 34.133-72.533 38.4-29.867 4.267-59.733 0-76.8-4.267-42.667-8.533-81.067-34.133-110.933-72.533-21.333 25.6-42.667 46.933-68.267 64-64 38.4-140.8 29.867-196.267-21.333-25.6-21.333-42.667-46.933-51.2-81.067-12.8-29.867-17.067-59.733-17.067-93.867-8.533 0-17.067 0-25.6 0-42.667 0-81.067-17.067-110.933-46.933-29.867-34.133-42.667-76.8-46.933-98.133-4.267-12.8-4.267-25.6-4.267-42.667 4.267-55.467 25.6-110.933 59.733-157.867 29.867-38.4 68.267-64 110.933-76.8-4.267-12.8-8.533-21.333-8.533-34.133 0-4.267-4.267-8.533-4.267-17.067-12.8-42.667-25.6-98.133 4.267-162.133 29.867-59.733 89.6-102.4 157.867-106.667 4.267 0 12.8 0 17.067 0 46.933 0 85.333 17.067 119.467 29.867 4.267 0 8.533 4.267 12.8 4.267 17.067 4.267 34.133 12.8 51.2 12.8 8.533 0 17.067-4.267 34.133-12.8s42.667-21.333 68.267-25.6c29.867-4.267 64-4.267 93.867 0 38.4 8.533 68.267 21.333 89.6 38.4 59.733 46.933 68.267 128 51.2 187.733-8.533 25.6-21.333 55.467-34.133 85.333 29.867 4.267 55.467 12.8 76.8 29.867 81.067 51.2 110.933 128 119.467 187.733 4.267 12.8 4.267 51.2 4.267 68.267zM541.867 674.133c4.267 42.667 21.333 81.067 42.667 115.2 34.133 42.667 93.867 68.267 136.533 25.6 0 0 0 0 0 0 21.333-21.333 34.133-51.2 34.133-81.067 4.267-38.4 0-72.533-17.067-106.667-17.067-38.4-38.4-68.267-76.8-89.6-46.933-25.6-102.4-8.533-119.467 42.667-4.267 29.867-4.267 68.267 0 93.867zM277.333 776.533c8.533 17.067 17.067 34.133 34.133 46.933 29.867 29.867 64 34.133 102.4 8.533 51.2-29.867 81.067-85.333 85.333-145.067 4.267-51.2-12.8-115.2-64-145.067-17.067-4.267-34.133-8.533-51.2-4.267-21.333 4.267-38.4 17.067-51.2 29.867-55.467 46.933-76.8 140.8-55.467 209.067zM123.733 413.867c-34.133 46.933-55.467 110.933-34.133 170.667 12.8 25.6 34.133 42.667 64 46.933 25.6 4.267 51.2-8.533 72.533-25.6 8.533-4.267 12.8-12.8 17.067-17.067 17.067-21.333 29.867-46.933 34.133-72.533 8.533-29.867 12.8-59.733 8.533-85.333-4.267-34.133-29.867-64-64-68.267-38.4-4.267-76.8 21.333-98.133 51.2zM755.2 76.8c-29.867-25.6-81.067-29.867-115.2-21.333-42.667 8.533-72.533 38.4-115.2 42.667-29.867 0-55.467-8.533-85.333-17.067-38.4-12.8-76.8-34.133-115.2-29.867-25.6 0-55.467 12.8-72.533 34.133-42.667 42.667-29.867 110.933-8.533 162.133 17.067 55.467 55.467 102.4 98.133 140.8 17.067 17.067 38.4 34.133 64 42.667 25.6 12.8 55.467 17.067 85.333 17.067 34.133 0 68.267 0 98.133-12.8s55.467-29.867 72.533-55.467c21.333-25.6 42.667-51.2 59.733-81.067 17.067-25.6 34.133-55.467 46.933-85.333 17.067-34.133 21.333-76.8 4.267-110.933 0-12.8-8.533-21.333-17.067-25.6zM942.933 516.267c-8.533-55.467-34.133-106.667-81.067-136.533-17.067-12.8-38.4-17.067-64-17.067-42.667 0-72.533 34.133-81.067 72.533-17.067 76.8 59.733 200.533 140.8 204.8 21.333 0 38.4-4.267 51.2-21.333 21.333-17.067 29.867-42.667 34.133-68.267 0 4.267 4.267-8.533 0-34.133z" />
<glyph unicode="&#xe94f;" glyph-name="unavailable" d="M469.333 524.8v366.933h-136.533v-499.2zM290.133 345.6v546.133h-42.667v-588.8zM776.533 832v59.733h-42.667v-102.4zM644.267 699.733v192h-89.6c0 0 0-145.067 0-277.333l89.6 85.333zM866.133 682.667v-42.667c34.133-17.067 64-42.667 89.6-68.267v200.533l-89.6-89.6zM776.533 593.067l-64-64c8.533 0 17.067 4.267 25.6 4.267 85.333 0 149.333-68.267 149.333-149.333 0-85.333-68.267-149.333-149.333-149.333s-149.333 68.267-149.333 149.333c0 8.533 0 17.067 0 25.6l-68.267-68.267c8.533-38.4 21.333-72.533 46.933-102.4l-12.8-12.8h-25.6l-166.4-170.667 51.2-51.2 166.4 170.667v25.6l8.533 12.8c38.4-34.133 89.6-51.2 145.067-51.2 123.733 0 217.6 98.133 217.6 217.6 0 106.667-76.8 192-174.933 213.333zM157.867 213.333v678.4h-89.6v-733.867h29.867zM460.8 273.067l-119.467-115.2h21.333l102.4 102.4c-4.267 4.267-4.267 8.533-4.267 12.8zM964.267 960l59.733-59.733-964.267-964.267-59.733 59.733 964.267 964.267z" />
</font></defs></svg> </font></defs></svg>

Before

Width:  |  Height:  |  Size: 75 KiB

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

Binary file not shown.

View File

@ -17,6 +17,11 @@ describe('Component vnLeftMenu', () => {
]; ];
})); }));
it(`should set items in the controller for the left menu`, () => {
expect(controller.items.length).toEqual(3);
expect(controller.items[2].state).toEqual('client.card.summary');
});
describe('depth() setter', () => { describe('depth() setter', () => {
it(`should set depth property and call activateItem()`, () => { it(`should set depth property and call activateItem()`, () => {
spyOn(controller, 'activateItem'); spyOn(controller, 'activateItem');

View File

@ -1,9 +1,3 @@
<vn-crud-model
url="/api/Banks"
vn-id="banks"
data="banksData"
order="bank">
</vn-crud-model>
<vn-crud-model <vn-crud-model
url="/api/Warehouses" url="/api/Warehouses"
vn-id="warehouses" vn-id="warehouses"
@ -33,11 +27,12 @@
label="Local bank" label="Local bank"
id="localBank" id="localBank"
field="$ctrl.localBankFk" field="$ctrl.localBankFk"
data="banksData" url="/api/Banks"
select-fields="['id','bank']" select-fields="['id','bank']"
show-field="bank" show-field="bank"
order="id" order="id"
value-field="id"> value-field="id"
search-function="{or: [{id: $search}, {bank: {like: '%'+ $search +'%'}}]}">
<tpl-item>{{id}}: {{bank}}</tpl-item> <tpl-item>{{id}}: {{bank}}</tpl-item>
</vn-autocomplete> </vn-autocomplete>
<vn-autocomplete <vn-autocomplete

View File

@ -31,6 +31,13 @@ class Controller {
} }
} }
$onInit() {
if (window.localStorage.localBankFk && window.localStorage.localBankFk !== 'null')
window.localStorage.defaultBankFk = window.localStorage.localBankFk;
else
localStorage.removeItem('defaultBankFk');
}
set lang(value) { set lang(value) {
this._lang = value; this._lang = value;
this.$translate.use(value); this.$translate.use(value);
@ -105,7 +112,6 @@ class Controller {
} }
show(event) { show(event) {
this.$scope.banks.refresh();
this.$scope.warehouses.refresh(); this.$scope.warehouses.refresh();
this.$scope.companies.refresh(); this.$scope.companies.refresh();
this.$scope.popover.parent = event.target; this.$scope.popover.parent = event.target;
@ -139,11 +145,8 @@ class Controller {
}); });
} }
$onInit() { searchLocalBank(a, b) {
if (window.localStorage.localBankFk && window.localStorage.localBankFk !== 'null') return angular.equals(a.id, b.id);
window.localStorage.defaultBankFk = window.localStorage.localBankFk;
else
localStorage.removeItem('defaultBankFk');
} }
} }

View File

@ -355,7 +355,7 @@ async function docker() {
let d = new Date(); let d = new Date();
let pad = v => v < 10 ? '0' + v : v; let pad = v => v < 10 ? '0' + v : v;
let stamp = `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}`; let stamp = `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}`;
await execP(`docker build --build-arg STAMP=${stamp} -t salix-db ./services/db`); await execP(`docker build --build-arg STAMP=${stamp} -t salix-db ./db`);
let dockerArgs = `--name ${containerId} -p 3306:${dbConf.port}`; let dockerArgs = `--name ${containerId} -p 3306:${dbConf.port}`;

View File

@ -8,7 +8,7 @@ describe('Model crud()', () => {
expect(ItemBarcode.crud).toBeDefined(); expect(ItemBarcode.crud).toBeDefined();
}); });
it('should create a new instance', async () => { it('should create a new instance', async() => {
let data = {code: '500', itemFk: '1'}; let data = {code: '500', itemFk: '1'};
let creates = [data]; let creates = [data];
@ -20,7 +20,7 @@ describe('Model crud()', () => {
expect(instance.code).toEqual('500'); expect(instance.code).toEqual('500');
}); });
it('should update the instance', async () => { it('should update the instance', async() => {
let updates = [{ let updates = [{
where: {id: insertId}, where: {id: insertId},
data: {code: '501', itemFk: 1} data: {code: '501', itemFk: 1}
@ -32,7 +32,7 @@ describe('Model crud()', () => {
expect(instance.code).toEqual('501'); expect(instance.code).toEqual('501');
}); });
it('should delete the created instance', async () => { it('should delete the created instance', async() => {
let deletes = [insertId]; let deletes = [insertId];
await ItemBarcode.crud(deletes); await ItemBarcode.crud(deletes);
let instance = await ItemBarcode.findById(insertId); let instance = await ItemBarcode.findById(insertId);

View File

@ -12,6 +12,10 @@ module.exports = function(Self) {
}); });
Self.observe('before save', async function(ctx) { Self.observe('before save', async function(ctx) {
let options = {};
if (ctx.options && ctx.options.transaction)
options.transaction = ctx.options.transaction;
let oldInstance; let oldInstance;
let oldInstanceFk; let oldInstanceFk;
let newInstance; let newInstance;
@ -22,7 +26,7 @@ module.exports = function(Self) {
oldInstance = await fkToValue(oldInstanceFk, ctx); oldInstance = await fkToValue(oldInstanceFk, ctx);
if (ctx.where && !ctx.currentInstance) { if (ctx.where && !ctx.currentInstance) {
let fields = Object.keys(ctx.data); let fields = Object.keys(ctx.data);
ctx.oldInstances = await ctx.Model.app.models[ctx.Model.definition.name].find({where: ctx.where, fields: fields}); ctx.oldInstances = await ctx.Model.app.models[ctx.Model.definition.name].find({where: ctx.where, fields: fields}, options);
} }
} }
if (ctx.isNewInstance) if (ctx.isNewInstance)
@ -33,10 +37,14 @@ module.exports = function(Self) {
}); });
Self.observe('before delete', async function(ctx) { Self.observe('before delete', async function(ctx) {
let options = {};
if (ctx.options && ctx.options.transaction)
options.transaction = ctx.options.transaction;
if (ctx.where) { if (ctx.where) {
let affectedModel = ctx.Model.definition.name; let affectedModel = ctx.Model.definition.name;
let definition = ctx.Model.definition; let definition = ctx.Model.definition;
let deletedInstances = await ctx.Model.app.models[affectedModel].find({where: ctx.where}); let deletedInstances = await ctx.Model.app.models[affectedModel].find({where: ctx.where}, options);
let relation = definition.settings.log.relation; let relation = definition.settings.log.relation;
if (relation) { if (relation) {
@ -61,6 +69,10 @@ module.exports = function(Self) {
}); });
async function logDeletedInstances(ctx, loopBackContext) { async function logDeletedInstances(ctx, loopBackContext) {
let options = {};
if (ctx.options && ctx.options.transaction)
options.transaction = ctx.options.transaction;
ctx.hookState.oldInstance.forEach(async instance => { ctx.hookState.oldInstance.forEach(async instance => {
let userFk; let userFk;
if (loopBackContext) if (loopBackContext)
@ -80,16 +92,16 @@ module.exports = function(Self) {
newInstance: {} newInstance: {}
}; };
let transaction = {};
if (ctx.options && ctx.options.transaction)
transaction = ctx.options.transaction;
let logModel = definition.settings.log.model; let logModel = definition.settings.log.model;
await ctx.Model.app.models[logModel].create(logRecord, transaction); await ctx.Model.app.models[logModel].create(logRecord, options);
}); });
} }
async function fkToValue(instance, ctx) { async function fkToValue(instance, ctx) {
let options = {};
if (ctx.options && ctx.options.transaction)
options.transaction = ctx.options.transaction;
let cleanInstance = JSON.parse(JSON.stringify(instance)); let cleanInstance = JSON.parse(JSON.stringify(instance));
let result = {}; let result = {};
for (let key in cleanInstance) { for (let key in cleanInstance) {
@ -98,8 +110,11 @@ module.exports = function(Self) {
for (let key1 in ctx.Model.relations) { for (let key1 in ctx.Model.relations) {
let val1 = ctx.Model.relations[key1]; let val1 = ctx.Model.relations[key1];
if (val1.keyFrom == key && key != 'id') { if (val1.keyFrom == key && key != 'id') {
let recordSet = await val1.modelTo.findById(val); let recordSet = await ctx.Model.app.models[val1.modelTo.modelName].findById(val, options);
val = recordSet.name; // FIXME preparar todos los modelos con campo name let definition = val1.modelTo.definition;
let changedModelValue = definition.settings.log && definition.settings.log.changedModelValue;
val = (changedModelValue && recordSet && recordSet[changedModelValue]) || (recordSet && recordSet.id) || val; // FIXME preparar todos los modelos con campo name
break; break;
} }
} }
@ -109,6 +124,10 @@ module.exports = function(Self) {
} }
async function logInModel(ctx, loopBackContext) { async function logInModel(ctx, loopBackContext) {
let options = {};
if (ctx.options && ctx.options.transaction)
options.transaction = ctx.options.transaction;
let definition = ctx.Model.definition; let definition = ctx.Model.definition;
let primaryKey; let primaryKey;
for (let property in definition.properties) { for (let property in definition.properties) {
@ -143,10 +162,11 @@ module.exports = function(Self) {
// Sets the changedModelValue to save and the instances changed in case its an updateAll // Sets the changedModelValue to save and the instances changed in case its an updateAll
let changedModelValue = definition.settings.log.changedModelValue; let changedModelValue = definition.settings.log.changedModelValue;
let where;
if (changedModelValue && (!ctx.instance || !ctx.instance[changedModelValue])) { if (changedModelValue && (!ctx.instance || !ctx.instance[changedModelValue])) {
var where = [];
changedModelId = []; changedModelId = [];
let changedInstances = await ctx.Model.app.models[definition.name].find({where: ctx.where, fields: ['id', changedModelValue]}); where = [];
let changedInstances = await ctx.Model.app.models[definition.name].find({where: ctx.where, fields: ['id', changedModelValue]}, options);
changedInstances.forEach(element => { changedInstances.forEach(element => {
where.push(element[changedModelValue]); where.push(element[changedModelValue]);
changedModelId.push(element.id); changedModelId.push(element.id);
@ -185,11 +205,7 @@ module.exports = function(Self) {
let logModel = definition.settings.log.model; let logModel = definition.settings.log.model;
let transaction = {}; await ctx.Model.app.models[logModel].create(logsToSave, options);
if (ctx.options && ctx.options.transaction)
transaction = ctx.options.transaction;
await ctx.Model.app.models[logModel].create(logsToSave, transaction);
} }
// this function retuns all the instances changed in case this is an updateAll // this function retuns all the instances changed in case this is an updateAll

View File

@ -18,7 +18,6 @@
"Package cannot be blank": "Package cannot be blank", "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 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", "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", "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", "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", "This address doesn't exist": "This address doesn't exist",
@ -37,5 +36,7 @@
"Barcode must be unique": "Barcode must be unique", "Barcode must be unique": "Barcode must be unique",
"You don't have enough privileges to do that": "You don't have enough privileges to do that", "You don't have enough privileges to do that": "You don't have enough privileges to do that",
"You can't create a ticket for a frozen client": "You can't create a ticket for a frozen client", "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" "can't be blank": "can't be blank",
"Street cannot be empty": "Street cannot be empty",
"City cannot be empty": "City cannot be empty"
} }

View File

@ -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 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 must delete the claim id %d first": "Antes debes borrar la reclamacion %d",
"You don't have enough privileges": "No tienes suficientes permisos", "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", "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", "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 ñ", "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 ñ",
@ -68,5 +67,10 @@
"Tag value cannot be blank": "El valor del tag no puede quedar en blanco", "Tag value cannot be blank": "El valor del tag no puede quedar en blanco",
"ORDER_EMPTY": "Cesta vacía", "ORDER_EMPTY": "Cesta vacía",
"You don't have enough privileges to do that": "No tienes permisos para cambiar esto", "You don't have enough privileges to do that": "No tienes permisos para cambiar esto",
"You can't create a ticket for a client that has a debt": "No puedes crear un ticket para un client con deuda" "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": "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"
} }

View File

@ -1,4 +1,3 @@
const mysql = require('mysql'); const mysql = require('mysql');
const ParameterizedSQL = require('loopback-connector').ParameterizedSQL; const ParameterizedSQL = require('loopback-connector').ParameterizedSQL;
const MySQL = require('loopback-connector-mysql').MySQL; const MySQL = require('loopback-connector-mysql').MySQL;
@ -23,6 +22,19 @@ class VnMySQL extends MySQL {
return v < 10 ? '0' + v : v; return v < 10 ? '0' + v : v;
} }
} }
fromColumnValue(prop, val) {
if (val == null || !prop || prop.type !== Date)
return MySQL.prototype.fromColumnValue.call(this, prop, val);
let date = new Date(val);
return date;
}
isIsoDate(dateString) {
let isoRegexp = /^(-?(?:[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)?$/g;
return isoRegexp.test(dateString);
}
/** /**
* Promisified version of execute(). * Promisified version of execute().
@ -230,11 +242,12 @@ exports.initialize = function initialize(dataSource, callback) {
dataSource.EnumFactory = EnumFactory; dataSource.EnumFactory = EnumFactory;
if (callback) if (callback) {
if (dataSource.settings.lazyConnect) { if (dataSource.settings.lazyConnect) {
process.nextTick(function() { process.nextTick(function() {
callback(); callback();
}); });
} else } else
dataSource.connector.connect(callback); dataSource.connector.connect(callback);
}
}; };

View File

@ -1,10 +1,10 @@
{ {
"db": { "db": {
"connector": "memory" "connector": "memory",
"timezone": "local"
}, },
"vn": { "vn": {
"connector": "vn-mysql", "connector": "vn-mysql",
"timezone": "CET",
"database": "vn", "database": "vn",
"debug": false, "debug": false,
"host": "localhost", "host": "localhost",

View File

@ -37,7 +37,8 @@
min="0" min="0"
step="1" step="1"
label="Traveling days" label="Traveling days"
field="$ctrl.zone.travelingDays"> field="$ctrl.zone.travelingDays"
display-controls="false">
</vn-input-number> </vn-input-number>
<vn-input-time <vn-input-time
vn-two vn-two
@ -50,13 +51,15 @@
label="Price" label="Price"
field="$ctrl.zone.price" field="$ctrl.zone.price"
min="0.00" min="0.00"
step="0.50"> step="0.10"
display-controls="false">
</vn-input-number> </vn-input-number>
<vn-input-number vn-one <vn-input-number vn-one
label="Bonus" label="Bonus"
field="$ctrl.zone.bonus" field="$ctrl.zone.bonus"
min="0.00" min="0.00"
step="0.50"> step="0.10"
display-controls="false">
</vn-input-number> </vn-input-number>
</vn-horizontal> </vn-horizontal>
</vn-card> </vn-card>

View File

@ -17,7 +17,9 @@ class Controller {
this.ndMonth = this.$scope.ndMonth; this.ndMonth = this.$scope.ndMonth;
} }
get zone() { // Disabled until implementation
// of holidays by node
/* get zone() {
return this._zone; return this._zone;
} }
@ -41,7 +43,7 @@ class Controller {
this.events = this.events.concat(events); this.events = this.events.concat(events);
}); });
} } */
get data() { get data() {
return this._data; return this._data;
@ -54,8 +56,11 @@ class Controller {
const events = []; const events = [];
value.forEach(event => { value.forEach(event => {
let date = new Date(event.delivered);
date.setHours(0, 0, 0, 0);
events.push({ events.push({
date: event.delivered, date: date,
color: 'green-circle', color: 'green-circle',
title: 'Has delivery', title: 'Has delivery',
isRemovable: true isRemovable: true
@ -114,10 +119,7 @@ class Controller {
if (event && !event.isRemovable) if (event && !event.isRemovable)
return false; return false;
// FIXME - Date offset dates.push(day.date);
let date = new Date(day.date);
date.setHours(0, 0, 0, 0);
dates.push(date);
this.stMonth.removeEvent(day.date); this.stMonth.removeEvent(day.date);
this.stMonth.repaint(); this.stMonth.repaint();

View File

@ -39,7 +39,8 @@
value="$ctrl.zone.travelingDays" value="$ctrl.zone.travelingDays"
step="1" step="1"
label="Traveling days" label="Traveling days"
field="$ctrl.zone.travelingDays"> field="$ctrl.zone.travelingDays"
display-controls="false">
</vn-input-number> </vn-input-number>
<vn-input-time <vn-input-time
vn-two vn-two
@ -52,13 +53,15 @@
label="Price" label="Price"
field="$ctrl.zone.price" field="$ctrl.zone.price"
min="0.00" min="0.00"
step="0.50"> step="0.10"
display-controls="false">
</vn-input-number> </vn-input-number>
<vn-input-number vn-one <vn-input-number vn-one
label="Bonus" label="Bonus"
field="$ctrl.zone.bonus" field="$ctrl.zone.bonus"
min="0.00" min="0.00"
step="0.50"> step="0.10"
display-controls="false">
</vn-input-number> </vn-input-number>
</vn-horizontal> </vn-horizontal>
</vn-card> </vn-card>

View File

@ -31,7 +31,7 @@
value="{{$ctrl.zone.agencyMode.name}}"> value="{{$ctrl.zone.agencyMode.name}}">
</vn-label-value> </vn-label-value>
<vn-label-value label="Estimated hour (ETD)" <vn-label-value label="Estimated hour (ETD)"
value="{{$ctrl.zone.hour | date: 'HH:mm'}}"> value="{{$ctrl.zone.hour | dateTime: 'HH:mm'}}">
</vn-label-value> </vn-label-value>
<vn-label-value label="Traveling days" <vn-label-value label="Traveling days"
value="{{$ctrl.zone.travelingDays}}"> value="{{$ctrl.zone.travelingDays}}">

View File

@ -36,7 +36,7 @@
<vn-td>{{::zone.name}}</vn-td> <vn-td>{{::zone.name}}</vn-td>
<vn-td>{{::zone.agencyMode.name}}</vn-td> <vn-td>{{::zone.agencyMode.name}}</vn-td>
<vn-td>{{::zone.warehouse.name}}</vn-td> <vn-td>{{::zone.warehouse.name}}</vn-td>
<vn-td>{{::zone.hour | date: 'HH:mm'}}</vn-td> <vn-td>{{::zone.hour | dateTime: 'HH:mm'}}</vn-td>
<vn-td number>{{::zone.price | currency: 'EUR':2}}</vn-td> <vn-td number>{{::zone.price | currency: 'EUR':2}}</vn-td>
<vn-td> <vn-td>
<vn-icon-button <vn-icon-button

View File

@ -23,12 +23,13 @@ class Controller {
} }
onSelection(item, isIncluded) { onSelection(item, isIncluded) {
item.isIncluded = isIncluded; let node = Object.assign({}, item);
const path = '/agency/api/ZoneIncludeds/toggleIsIncluded'; node.isIncluded = isIncluded;
const params = {zoneFk: this.zone.id, item}; node.childs = []; // Data too large
this.$http.post(path, params).then(() => {
}); const path = '/agency/api/ZoneIncludeds/toggleIsIncluded';
const params = {zoneFk: this.zone.id, item: node};
this.$http.post(path, params);
} }
} }

View File

@ -18,7 +18,7 @@
</vn-one> </vn-one>
<vn-one> <vn-one>
<vn-label-value label="Estimated hour (ETD)" <vn-label-value label="Estimated hour (ETD)"
value="{{::$ctrl.summary.hour | date: 'HH:mm'}}"> value="{{::$ctrl.summary.hour | dateTime: 'HH:mm'}}">
</vn-label-value> </vn-label-value>
<vn-label-value label="Traveling days" <vn-label-value label="Traveling days"
value="{{::$ctrl.summary.travelingDays}}"> value="{{::$ctrl.summary.travelingDays}}">

View File

@ -6,7 +6,7 @@ xdescribe('claimBeginning', () => {
let refundTicketSales; let refundTicketSales;
let salesInsertedInClaimEnd; let salesInsertedInClaimEnd;
afterAll(async () => { afterAll(async() => {
let promises = []; let promises = [];
promises.push(app.models.Ticket.destroyById(ticket.id)); promises.push(app.models.Ticket.destroyById(ticket.id));
@ -16,7 +16,7 @@ xdescribe('claimBeginning', () => {
}); });
describe('importToNewRefundTicket()', () => { describe('importToNewRefundTicket()', () => {
it('should create a new ticket with negative sales, save an observation, update the state and insert the negative sales into claimEnd', async () => { it('should create a new ticket with negative sales, save an observation, update the state and insert the negative sales into claimEnd', async() => {
let ctxOfSalesAssistant = {req: {accessToken: {userId: 21}}}; let ctxOfSalesAssistant = {req: {accessToken: {userId: 21}}};
let claimId = 1; let claimId = 1;
ticket = await app.models.ClaimBeginning.importToNewRefundTicket(ctxOfSalesAssistant, claimId); ticket = await app.models.ClaimBeginning.importToNewRefundTicket(ctxOfSalesAssistant, claimId);

View File

@ -3,13 +3,15 @@ const app = require('vn-loopback/server/server');
describe('Claim importTicketSales()', () => { describe('Claim importTicketSales()', () => {
let claimEnds; let claimEnds;
afterAll(async () => { afterAll(async done => {
claimEnds.forEach(async line => { claimEnds.forEach(async line => {
await line.destroy(); await line.destroy();
}); });
done();
}); });
it('should import sales to a claim actions from an specific ticket', async () => { it('should import sales to a claim actions from an specific ticket', async() => {
let ctx = {req: {accessToken: {userId: 5}}}; let ctx = {req: {accessToken: {userId: 5}}};
claimEnds = await app.models.ClaimEnd.importTicketSales(ctx, { claimEnds = await app.models.ClaimEnd.importTicketSales(ctx, {
claimFk: 1, claimFk: 1,

View File

@ -17,7 +17,7 @@ module.exports = Self => {
} }
}); });
Self.regularizeClaim = async (ctx, params) => { Self.regularizeClaim = async(ctx, params) => {
const userId = ctx.req.accessToken.userId; const userId = ctx.req.accessToken.userId;
const models = Self.app.models; const models = Self.app.models;
const resolvedState = 3; const resolvedState = 3;

View File

@ -4,8 +4,10 @@ describe('Claim Create', () => {
let newDate = new Date(); let newDate = new Date();
let createdClaimFk; let createdClaimFk;
afterAll(async () => { afterAll(async done => {
await app.models.Claim.destroyById(createdClaimFk); await app.models.Claim.destroyById(createdClaimFk);
done();
}); });
let newClaim = { let newClaim = {
@ -23,7 +25,7 @@ describe('Claim Create', () => {
let params = {claim: newClaim, sales: newSale}; let params = {claim: newClaim, sales: newSale};
it('should create a new claim', async () => { it('should create a new claim', async() => {
let claim = await app.models.Claim.createFromSales(params); let claim = await app.models.Claim.createFromSales(params);
expect(claim.ticketFk).toEqual(newClaim.ticketFk); expect(claim.ticketFk).toEqual(newClaim.ticketFk);
@ -39,7 +41,7 @@ describe('Claim Create', () => {
createdClaimFk = claim.id; createdClaimFk = claim.id;
}); });
it('should not be able to create a claim if exists that sale', async () => { it('should not be able to create a claim if exists that sale', async() => {
let error; let error;
await app.models.Claim.createFromSales(params) await app.models.Claim.createFromSales(params)

View File

@ -9,7 +9,7 @@ xdescribe('regularizeClaim()', () => {
let claimEnds = []; let claimEnds = [];
let trashTicket; let trashTicket;
afterAll(async () => { afterAll(async done => {
let claim = await app.models.Claim.findById(claimFk); let claim = await app.models.Claim.findById(claimFk);
await claim.updateAttributes({claimStateFk: pendentState}); await claim.updateAttributes({claimStateFk: pendentState});
await app.models.Ticket.destroyById(trashTicket.id); await app.models.Ticket.destroyById(trashTicket.id);
@ -17,9 +17,11 @@ xdescribe('regularizeClaim()', () => {
claimEnds.forEach(async line => { claimEnds.forEach(async line => {
await line.destroy(); await line.destroy();
}); });
done();
}); });
it('should change claim state to resolved', async () => { it('should change claim state to resolved', async() => {
let ctx = {req: {accessToken: {userId: 18}}}; let ctx = {req: {accessToken: {userId: 18}}};
let params = {claimFk: claimFk}; let params = {claimFk: claimFk};

View File

@ -14,12 +14,16 @@ describe('Update Claim', () => {
observation: 'observation' observation: 'observation'
}; };
beforeAll(async() => { beforeAll(async done => {
newInstance = await app.models.Claim.create(original); newInstance = await app.models.Claim.create(original);
done();
}); });
afterAll(async() => { afterAll(async done => {
await app.models.Claim.destroyById(newInstance.id); await app.models.Claim.destroyById(newInstance.id);
done();
}); });
it('should throw error if isSaleAssistant is false and try to modify a forbidden field', async() => { it('should throw error if isSaleAssistant is false and try to modify a forbidden field', async() => {

View File

@ -177,7 +177,7 @@
ng-repeat="ticket in lastTickets" ng-repeat="ticket in lastTickets"
ng-click="$ctrl.importTicketLines(ticket.id)"> ng-click="$ctrl.importTicketLines(ticket.id)">
<vn-td number>{{::ticket.id}}</vn-td> <vn-td number>{{::ticket.id}}</vn-td>
<vn-td>{{::ticket.shipped | date: 'dd/MM/yyyy'}}</vn-td> <vn-td>{{::ticket.shipped | dateTime: 'dd/MM/yyyy'}}</vn-td>
<vn-td>{{::ticket.agencyMode.name}}</vn-td> <vn-td>{{::ticket.agencyMode.name}}</vn-td>
<vn-td>{{::ticket.warehouse.name}}</vn-td> <vn-td>{{::ticket.warehouse.name}}</vn-td>
</vn-tr> </vn-tr>

View File

@ -41,7 +41,7 @@
{{::claim.client.name}} {{::claim.client.name}}
</span> </span>
</vn-td> </vn-td>
<vn-td center>{{::claim.created | date:'dd/MM/yyyy'}}</vn-td> <vn-td center>{{::claim.created | dateTime:'dd/MM/yyyy'}}</vn-td>
<vn-td expand> <vn-td expand>
<span <span
class="link" class="link"

View File

@ -0,0 +1,42 @@
module.exports = function(Self) {
Self.remoteMethod('createDefaultAddress', {
description: 'Creates both client and its web account',
accepts: {
arg: 'data',
type: 'object',
http: {source: 'body'}
},
returns: {
root: true,
type: 'Object'
},
http: {
verb: 'post',
path: '/createDefaultAddress'
}
});
Self.createDefaultAddress = async data => {
const Address = Self.app.models.Address;
const Client = Self.app.models.Client;
const transaction = await Address.beginTransaction({});
try {
let address = data.address;
let newAddress = await Address.create(address, {transaction});
let client = await Client.findById(address.clientFk, {transaction});
if (data.isDefaultAddress) {
await client.updateAttributes({
defaultAddressFk: newAddress.id
}, {transaction});
}
await transaction.commit();
return newAddress;
} catch (e) {
await transaction.rollback();
throw e;
}
};
};

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