test(worker_time-control): new backTest and e2e using workerTimeControl_clockIn
gitea/salix/pipeline/head There was a failure building this commit Details

This commit is contained in:
Alex Moreno 2022-06-23 14:07:53 +02:00
parent f7d64e89ab
commit 4d4e09fb9f
8 changed files with 831 additions and 659 deletions

View File

@ -1973,7 +1973,8 @@ INSERT INTO `postgresql`.`calendar_employee` (`business_id`, `calendar_state_id`
(1107, 1, IF(MONTH(util.VN_CURDATE()) = 12 AND DAY(util.VN_CURDATE()) > 10, DATE_ADD(util.VN_CURDATE(), INTERVAL -20 DAY), DATE_ADD(util.VN_CURDATE(), INTERVAL 20 DAY))), (1107, 1, IF(MONTH(util.VN_CURDATE()) = 12 AND DAY(util.VN_CURDATE()) > 10, DATE_ADD(util.VN_CURDATE(), INTERVAL -20 DAY), DATE_ADD(util.VN_CURDATE(), INTERVAL 20 DAY))),
(1107, 2, IF(MONTH(util.VN_CURDATE()) >= 1 AND DAY(util.VN_CURDATE()) > 20, DATE_ADD(util.VN_CURDATE(), INTERVAL -13 DAY), DATE_ADD(util.VN_CURDATE(), INTERVAL 8 DAY))), (1107, 2, IF(MONTH(util.VN_CURDATE()) >= 1 AND DAY(util.VN_CURDATE()) > 20, DATE_ADD(util.VN_CURDATE(), INTERVAL -13 DAY), DATE_ADD(util.VN_CURDATE(), INTERVAL 8 DAY))),
(1107, 1, IF(MONTH(util.VN_CURDATE()) >= 1 AND DAY(util.VN_CURDATE()) > 20, DATE_ADD(util.VN_CURDATE(), INTERVAL -14 DAY), DATE_ADD(util.VN_CURDATE(), INTERVAL 9 DAY))), (1107, 1, IF(MONTH(util.VN_CURDATE()) >= 1 AND DAY(util.VN_CURDATE()) > 20, DATE_ADD(util.VN_CURDATE(), INTERVAL -14 DAY), DATE_ADD(util.VN_CURDATE(), INTERVAL 9 DAY))),
(1107, 2, IF(MONTH(util.VN_CURDATE()) >= 1 AND DAY(util.VN_CURDATE()) > 20, DATE_ADD(util.VN_CURDATE(), INTERVAL -15 DAY), DATE_ADD(util.VN_CURDATE(), INTERVAL 7 DAY))); (1107, 2, IF(MONTH(util.VN_CURDATE()) >= 1 AND DAY(util.VN_CURDATE()) > 20, DATE_ADD(util.VN_CURDATE(), INTERVAL -15 DAY), DATE_ADD(util.VN_CURDATE(), INTERVAL 7 DAY))),
(1107, 2, DATE_ADD(util.VN_CURDATE(), INTERVAL - 16 DAY));
INSERT INTO `vn`.`smsConfig` (`id`, `uri`, `title`, `apiKey`) INSERT INTO `vn`.`smsConfig` (`id`, `uri`, `title`, `apiKey`)
VALUES VALUES
@ -2612,3 +2613,7 @@ INSERT INTO `vn`.`sectorCollection` (`userFk`, `sectorFk`)
INSERT INTO `vn`.`sectorCollectionSaleGroup` (`sectorCollectionFk`, `saleGroupFk`) INSERT INTO `vn`.`sectorCollectionSaleGroup` (`sectorCollectionFk`, `saleGroupFk`)
VALUES VALUES
(1, 1); (1, 1);
INSERT INTO `vn`.`workerTimeControlConfig`
(id, dayBreak, dayBreakDriver, shortWeekBreak, longWeekBreak, weekScope, mailPass, mailHost, mailSuccessFolder, mailErrorFolder, mailUser, minHoursToBreak, breakHours, hoursCompleteWeek, startNightlyHours, endNightlyHours, maxTimePerDay, breakTime, timeToBreakTime, dayMaxTime, shortWeekDays, longWeekDays)
VALUES(1, 43200, 32400, 129600, 259200, 604800, 'q8UAYfSnyKyS1APc', 'imap.verdnatura.es', 'Leidos.exito', 'Leidos.error', 'timeControl', 5.33, 0.33, 40, '22:00:00', '06:00:00', 57600, 1200, 18000, 57600, 6, 13);

View File

@ -43565,8 +43565,10 @@ CREATE TABLE `workerTimeControlConfig` (
`breakTime` int(11) DEFAULT NULL COMMENT 'Tiempo de descanso expresado en segundos', `breakTime` int(11) DEFAULT NULL COMMENT 'Tiempo de descanso expresado en segundos',
`timeToBreakTime` int(11) DEFAULT NULL COMMENT 'Tiempo mínimo que se debe trabajar para añadir descanso, expresado en segundos', `timeToBreakTime` int(11) DEFAULT NULL COMMENT 'Tiempo mínimo que se debe trabajar para añadir descanso, expresado en segundos',
`dayMaxTime` int(11) DEFAULT NULL COMMENT 'Tiempo máximo desde la entrada hasta la salida, expresado en segundos', `dayMaxTime` int(11) DEFAULT NULL COMMENT 'Tiempo máximo desde la entrada hasta la salida, expresado en segundos',
`shortWeekDays` int(11) DEFAULT NULL COMMENT 'Días a tener en cuenta para calcular el descanso corto',
`longWeekDays` int(11) DEFAULT NULL COMMENT 'Días a tener en cuenta para calcular el descanso largo',
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='All values in seconds'; ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='All values in seconds';
/*!40101 SET character_set_client = @saved_cs_client */; /*!40101 SET character_set_client = @saved_cs_client */;
-- --
@ -89169,15 +89171,21 @@ DELIMITER ;
/*!50003 SET @saved_sql_mode = @@sql_mode */ ; /*!50003 SET @saved_sql_mode = @@sql_mode */ ;
/*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ; /*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ;
DELIMITER ;; DELIMITER ;;
CREATE DEFINER=`root`@`localhost` PROCEDURE `workerTimeControl_clockIn`(vWorker INT, vTimed DATETIME, vDirection VARCHAR(10)) CREATE DEFINER=`root`@`localhost` PROCEDURE `vn`.`workerTimeControl_clockIn`(
vWorker INT,
vTimed DATETIME,
vDirection VARCHAR(10))
BEGIN BEGIN
/** /**
* Verifica si el empleado puede fichar * Verifica si el empleado puede fichar
* @param vWorker Identificador del trabajador * @param vWorker Identificador del trabajador
* @param vTimed valor de la fichada, IF vTimed IS NULL vTimed = util.VN_NOW() * @param vTimed valor de la fichada, IF vTimed IS NULL vTimed = NOW()
* @param vDirection solo se pueden pasa los valores del campo workerTimeControl.direction ENUM('in', 'out', 'middle') * @param vDirection solo se pueden pasa los valores del campo
* @return Si todo es correcto, retorna el número de id la tabla workerTimeControl. Si hay algún problema, devuelve el mesaje a que se debe mostrar al usuario * workerTimeControl.direction ENUM('in', 'out', 'middle')
* Solo retorna el primer problema, en caso de no ocurrir ningún error se añadirá fichada a la tabla vn.workerTimeControl * @return Si todo es correcto, retorna el número de id la tabla workerTimeControl.
* Si hay algún problema, devuelve el mesaje a que se debe mostrar al usuario
* Solo retorna el primer problema, en caso de no ocurrir ningún error se añadirá
* fichada a la tabla vn.workerTimeControl
*/ */
DECLARE vLastIn DATETIME; DECLARE vLastIn DATETIME;
DECLARE vLastOut DATETIME; DECLARE vLastOut DATETIME;
@ -89197,42 +89205,39 @@ BEGIN
DECLARE vDated DATE; DECLARE vDated DATE;
DECLARE vIsAllowedToWork VARCHAR(50); DECLARE vIsAllowedToWork VARCHAR(50);
DECLARE vDepartmentFk INT; DECLARE vDepartmentFk INT;
DECLARE vTimedLoop INT; DECLARE vTimedLoop BIGINT;
DECLARE vTimedLoopPrevious INT; DECLARE vTimedLoopPrevious BIGINT;
DECLARE vHasBreakWeek BOOLEAN DEFAULT FALSE; DECLARE vHasBreakWeek BOOLEAN DEFAULT FALSE;
DECLARE vManual BOOLEAN DEFAULT TRUE; DECLARE vManual BOOLEAN DEFAULT TRUE;
DECLARE vDone INT DEFAULT FALSE; DECLARE vDone INT DEFAULT FALSE;
DECLARE vCursor CURSOR FOR DECLARE vCursor CURSOR FOR
SELECT UNIX_TIMESTAMP(util.VN_NOW() - INTERVAL vGap SECOND) SELECT UNIX_TIMESTAMP(vTimed) timed
UNION
SELECT UNIX_TIMESTAMP(util.VN_NOW())
UNION
(SELECT UNIX_TIMESTAMP(timed)
FROM workerTimeControl
WHERE timed BETWEEN (vTimed - INTERVAL vGap SECOND) AND vTimed AND
userFk = vWorker AND
direction IN ('in', 'out')
ORDER BY timed ASC);
DECLARE vCursor2 CURSOR FOR
SELECT UNIX_TIMESTAMP(util.VN_NOW() - INTERVAL vGap SECOND)
UNION
SELECT UNIX_TIMESTAMP(util.VN_NOW())
UNION UNION
SELECT UNIX_TIMESTAMP(timed) SELECT UNIX_TIMESTAMP(timed)
FROM workerTimeControl FROM workerTimeControl
WHERE timed BETWEEN vTimed AND (vTimed - INTERVAL vGap SECOND) AND WHERE timed BETWEEN (vTimed - INTERVAL vGap SECOND) AND vTimed
userFk = vWorker AND AND userFk = vWorker
direction IN ('in', 'out') AND direction IN ('in', 'out')
ORDER BY timed ASC; ORDER BY timed ASC;
DECLARE vCursor2 CURSOR FOR
SELECT UNIX_TIMESTAMP(vTimed) timed
UNION
SELECT UNIX_TIMESTAMP(timed)
FROM workerTimeControl
WHERE timed BETWEEN vTimed AND (vTimed + INTERVAL vGap SECOND)
AND userFk = vWorker
AND direction IN ('in', 'out')
ORDER BY timed ASC;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET vDone = TRUE; DECLARE CONTINUE HANDLER FOR NOT FOUND SET vDone = TRUE;
DECLARE EXIT HANDLER FOR SQLSTATE '45000' DECLARE EXIT HANDLER FOR SQLSTATE '45000'
BEGIN BEGIN
SELECT CONCAT(u.name, '@verdnatura.es'), CONCAT(w.firstName, ' ', w.lastName) SELECT CONCAT(u.name, '@verdnatura.es'),
CONCAT(w.firstName, ' ', w.lastName)
INTO vMailTo, vUserName INTO vMailTo, vUserName
FROM account.user u FROM account.user u
JOIN worker w ON w.bossFk = u.id JOIN worker w ON w.bossFk = u.id
@ -89248,7 +89253,8 @@ BEGIN
WHEN 'ODD_WORKERTIMECONTROL' THEN WHEN 'ODD_WORKERTIMECONTROL' THEN
SELECT 'Fichadas impares' INTO vErrorMessage; SELECT 'Fichadas impares' INTO vErrorMessage;
WHEN 'BREAK_DAY' THEN WHEN 'BREAK_DAY' THEN
SELECT CONCAT('Descanso diario ', FORMAT(vDayBreak/3600, 0) , 'h.') INTO vErrorMessage; SELECT CONCAT('Descanso diario ', FORMAT(vDayBreak/3600, 0), 'h.')
INTO vErrorMessage;
WHEN 'BREAK_WEEK' THEN WHEN 'BREAK_WEEK' THEN
SELECT CONCAT('Descanso semanal ', SELECT CONCAT('Descanso semanal ',
FORMAT(vShortWeekBreak / 3600,0) ,'h. / ', FORMAT(vShortWeekBreak / 3600,0) ,'h. / ',
@ -89260,29 +89266,35 @@ BEGIN
END CASE; END CASE;
SELECT vErrorMessage `error`; SELECT vErrorMessage `error`;
SELECT CONCAT(vUserName, ' no ha podido fichar por el siguiente problema: ', vErrorMessage) INTO vErrorMessage; SELECT CONCAT(vUserName,
' no ha podido fichar por el siguiente problema: ',
vErrorMessage)
INTO vErrorMessage;
CALL mail_insert( vMailTo, vMailTo, 'Error al fichar', vErrorMessage); CALL mail_insert( vMailTo, vMailTo, 'Error al fichar', vErrorMessage);
END; END;
IF (vTimed IS NULL) THEN IF (vTimed IS NULL) THEN
SET vTimed = util.VN_NOW(); SET vTimed = NOW();
SET vManual = FALSE; SET vManual = FALSE;
END IF; END IF;
SET vDated = DATE(vTimed); SET vDated = DATE(vTimed);
SELECT IF(pc.category_name = 'Conductor +3500kg', wc.dayBreakDriver, wc.dayBreak), SELECT IF(pc.category_name = 'Conductor +3500kg',
wc.shortWeekBreak, wc.dayBreakDriver,
wc.longWeekBreak, wc.dayBreak),
wc.weekScope wc.shortWeekBreak,
wc.longWeekBreak,
wc.weekScope
INTO vDayBreak, INTO vDayBreak,
vShortWeekBreak, vShortWeekBreak,
vLongWeekBreak, vLongWeekBreak,
vWeekScope vWeekScope
FROM workerLabour w FROM workerLabour w
JOIN postgresql.business_labour bl ON bl.business_id = w.businessFk JOIN postgresql.business_labour bl ON bl.business_id = w.businessFk
JOIN postgresql.professional_category pc ON pc.professional_category_id = bl.professional_category_id JOIN postgresql.professional_category pc
ON pc.professional_category_id = bl.professional_category_id
JOIN workerTimeControlConfig wc ON TRUE JOIN workerTimeControlConfig wc ON TRUE
WHERE w.workerFk = vWorker WHERE w.workerFk = vWorker
AND vDated BETWEEN w.started AND IFNULL(w.ended, vDated); AND vDated BETWEEN w.started AND IFNULL(w.ended, vDated);
@ -89326,7 +89338,7 @@ BEGIN
LIMIT 1; LIMIT 1;
-- FICHADAS A FUTURO -- FICHADAS A FUTURO
IF vTimed > DATE_ADD(util.VN_NOW(), INTERVAL 60 SECOND) THEN IF vTimed > DATE_ADD(NOW(), INTERVAL 60 SECOND) THEN
SET vErrorCode = 'IS_NOT_ALLOWED_FUTURE'; SET vErrorCode = 'IS_NOT_ALLOWED_FUTURE';
CALL util.throw(vErrorCode); CALL util.throw(vErrorCode);
END IF; END IF;
@ -89349,10 +89361,18 @@ BEGIN
END IF; END IF;
-- DIRECCION CORRECTA -- DIRECCION CORRECTA
CALL vn.workerTimeControl_direction(vWorker, vTimed); CALL workerTimeControl_direction(vWorker, vTimed);
IF (SELECT IF(IF(option1 IN ('inMiddle', 'outMiddle'), 'middle', option1) <> vDirection IF (SELECT
AND IF(option2 IN ('inMiddle', 'outMiddle'), 'middle', IFNULL(option2, '')) <> vDirection, TRUE , FALSE) IF(IF(option1 IN ('inMiddle', 'outMiddle'),
FROM tmp.workerTimeControlDirection) THEN 'middle',
option1) <> vDirection
AND IF(option2 IN ('inMiddle', 'outMiddle'),
'middle',
IFNULL(option2, '')) <> vDirection,
TRUE ,
FALSE)
FROM tmp.workerTimeControlDirection
) THEN
SET vIsError = TRUE; SET vIsError = TRUE;
END IF; END IF;
@ -89363,7 +89383,9 @@ BEGIN
END IF; END IF;
-- FICHADAS IMPARES -- FICHADAS IMPARES
IF (SELECT IF(vDirection = 'in', MOD(COUNT(*), 2) , IF (vDirection = 'out', NOT MOD(COUNT(*), 2), FALSE)) IF (SELECT IF(vDirection = 'in',
MOD(COUNT(*), 2) ,
IF (vDirection = 'out', NOT MOD(COUNT(*), 2), FALSE))
FROM workerTimeControl FROM workerTimeControl
WHERE userFk = vWorker WHERE userFk = vWorker
AND timed BETWEEN vLastIn AND vTimed AND timed BETWEEN vLastIn AND vTimed
@ -89402,7 +89424,7 @@ BEGIN
IF vDone THEN IF vDone THEN
LEAVE l; LEAVE l;
END IF; END IF;
IF vShortWeekBreak - (vTimedLoop - vTimedLoopPrevious) < 0 THEN IF vShortWeekBreak - (vTimedLoop - vTimedLoopPrevious) <= 0 THEN
SET vHasBreakWeek = TRUE; SET vHasBreakWeek = TRUE;
LEAVE l; LEAVE l;
END IF; END IF;
@ -89412,7 +89434,7 @@ BEGIN
-- VERIFICA DESCANSO LARGO EN LA ÚLTIMAS 2 SEMANAS -- VERIFICA DESCANSO LARGO EN LA ÚLTIMAS 2 SEMANAS
IF NOT vHasBreakWeek THEN IF NOT vHasBreakWeek THEN
SET vGap = vWeekScope * 2; SET vGap = vWeekScope * 2;
SET vTimedLoopPrevious = UNIX_TIMESTAMP((vTimed - INTERVAL vGap SECOND)); SET vTimedLoopPrevious = UNIX_TIMESTAMP(vTimed - INTERVAL vGap SECOND);
SET vDone = FALSE; SET vDone = FALSE;
OPEN vCursor; OPEN vCursor;
l:LOOP l:LOOP
@ -89420,7 +89442,7 @@ BEGIN
IF vDone THEN IF vDone THEN
LEAVE l; LEAVE l;
END IF; END IF;
IF vLongWeekBreak - (vTimedLoop - vTimedLoopPrevious) < 0 THEN IF vLongWeekBreak - (vTimedLoop - vTimedLoopPrevious) <= 0 THEN
SET vHasBreakWeek = TRUE; SET vHasBreakWeek = TRUE;
LEAVE l; LEAVE l;
END IF; END IF;
@ -89434,37 +89456,37 @@ BEGIN
SET vGap = vWeekScope; SET vGap = vWeekScope;
SET vTimedLoopPrevious = vTimed; SET vTimedLoopPrevious = vTimed;
SET vDone = FALSE; SET vDone = FALSE;
OPEN vCursor; OPEN vCursor2;
l:LOOP l:LOOP
FETCH vCursor INTO vTimedLoop; FETCH vCursor2 INTO vTimedLoop;
IF vDone THEN IF vDone THEN
LEAVE l; LEAVE l;
END IF; END IF;
IF vShortWeekBreak - (vTimedLoop - vTimedLoopPrevious) < 0 THEN IF vShortWeekBreak - (vTimedLoop - vTimedLoopPrevious) <= 0 THEN
SET vHasBreakWeek = TRUE; SET vHasBreakWeek = TRUE;
LEAVE l; LEAVE l;
END IF; END IF;
SET vTimedLoopPrevious = vTimedLoop; SET vTimedLoopPrevious = vTimedLoop;
END LOOP l; END LOOP l;
CLOSE vCursor; CLOSE vCursor2;
-- VERIFICA DESCANSO LARGO EN LAS PRÓXIMAS 2 SEMANAS -- VERIFICA DESCANSO LARGO EN LAS PRÓXIMAS 2 SEMANAS
IF NOT vHasBreakWeek THEN IF NOT vHasBreakWeek THEN
SET vGap = vWeekScope * 2; SET vGap = vWeekScope * 2;
SET vTimedLoopPrevious = vTimed; SET vTimedLoopPrevious = vTimed;
SET vDone = FALSE; SET vDone = FALSE;
OPEN vCursor; OPEN vCursor2;
l:LOOP l:LOOP
FETCH vCursor INTO vTimedLoop; FETCH vCursor2 INTO vTimedLoop;
IF vDone THEN IF vDone THEN
LEAVE l; LEAVE l;
END IF; END IF;
IF vShortWeekBreak - (vTimedLoop - vTimedLoopPrevious) < 0 THEN IF vShortWeekBreak - (vTimedLoop - vTimedLoopPrevious) <= 0 THEN
SET vHasBreakWeek = TRUE; SET vHasBreakWeek = TRUE;
LEAVE l; LEAVE l;
END IF; END IF;
SET vTimedLoopPrevious = vTimedLoop; SET vTimedLoopPrevious = vTimedLoop;
END LOOP l; END LOOP l;
CLOSE vCursor; CLOSE vCursor2;
END IF; END IF;
END IF; END IF;
IF NOT vHasBreakWeek THEN IF NOT vHasBreakWeek THEN
@ -89472,7 +89494,7 @@ BEGIN
CALL util.throw(vErrorCode); CALL util.throw(vErrorCode);
END IF; END IF;
END IF; END IF;
-- SE PERMITE FICHAR -- SE PERMITE FICHAR
INSERT INTO workerTimeControl(userFk, timed, direction, manual) INSERT INTO workerTimeControl(userFk, timed, direction, manual)
VALUES(vWorker, vTimed, vDirection, vManual); VALUES(vWorker, vTimed, vDirection, vManual);
@ -97138,7 +97160,7 @@ USE `vn`;
/*!50001 SET collation_connection = utf8mb4_unicode_ci */; /*!50001 SET collation_connection = utf8mb4_unicode_ci */;
/*!50001 CREATE ALGORITHM=UNDEFINED */ /*!50001 CREATE ALGORITHM=UNDEFINED */
/*!50013 DEFINER=`root`@`localhost` SQL SECURITY DEFINER */ /*!50013 DEFINER=`root`@`localhost` SQL SECURITY DEFINER */
/*!50001 VIEW `workerLabour` AS select `b`.`business_id` AS `businessFk`,`p`.`id_trabajador` AS `workerFk`,`bl`.`workcenter_id` AS `workCenterFk`,`b`.`date_start` AS `started`,`b`.`date_end` AS `ended`,`d`.`id` AS `departmentFk`,`b`.`payedHolidays` AS `payedHolidays` from ((((`postgresql`.`person` `p` join `postgresql`.`profile` `pr` on(`pr`.`person_id` = `p`.`person_id`)) join `postgresql`.`business` `b` on(`b`.`client_id` = `pr`.`profile_id`)) join `postgresql`.`business_labour` `bl` on(`b`.`business_id` = `bl`.`business_id`)) join `vn`.`department` `d` on(`d`.`id` = `bl`.`department_id`)) order by `b`.`date_start` desc */; /*!50001 VIEW `workerLabour` AS select `b`.`business_id` AS `businessFk`,`p`.`id_trabajador` AS `workerFk`,`bl`.`workcenter_id` AS `workCenterFk`,`b`.`date_start` AS `started`,`b`.`date_end` AS `ended`,`d`.`id` AS `departmentFk`,`b`.`payedHolidays` AS `payedHolidays` from ((((`postgresql`.`person` `p` join `postgresql`.`profile` `pr` on(`pr`.`person_id` = `p`.`person_id`)) join `postgresql`.`business` `b` on(`b`.`client_id` = `pr`.`profile_id`)) join `postgresql`.`business_labour` `bl` on(`b`.`business_id` = `bl`.`business_id`)) join `vn`.`department` `d` on(`d`.`id` = `bl`.`department_id`)) */;
/*!50001 SET character_set_client = @saved_cs_client */; /*!50001 SET character_set_client = @saved_cs_client */;
/*!50001 SET character_set_results = @saved_cs_results */; /*!50001 SET character_set_results = @saved_cs_results */;
/*!50001 SET collation_connection = @saved_col_connection */; /*!50001 SET collation_connection = @saved_col_connection */;

View File

@ -905,52 +905,16 @@ export default {
dialogTimeInput: '.vn-dialog.shown vn-input-time[ng-model="$ctrl.newTimeEntry.timed"]', dialogTimeInput: '.vn-dialog.shown vn-input-time[ng-model="$ctrl.newTimeEntry.timed"]',
dialogTimeDirection: '.vn-dialog.shown vn-autocomplete[ng-model="$ctrl.newTimeEntry.direction"]', dialogTimeDirection: '.vn-dialog.shown vn-autocomplete[ng-model="$ctrl.newTimeEntry.direction"]',
mondayAddTimeButton: 'vn-worker-time-control vn-table > div > vn-tfoot > vn-tr:nth-child(2) > vn-td:nth-child(1) > vn-icon-button', mondayAddTimeButton: 'vn-worker-time-control vn-table > div > vn-tfoot > vn-tr:nth-child(2) > vn-td:nth-child(1) > vn-icon-button',
tuesdayAddTimeButton: 'vn-worker-time-control vn-table > div > vn-tfoot > vn-tr:nth-child(2) > vn-td:nth-child(2) > vn-icon-button',
wednesdayAddTimeButton: 'vn-worker-time-control vn-table > div > vn-tfoot > vn-tr:nth-child(2) > vn-td:nth-child(3) > vn-icon-button',
thursdayAddTimeButton: 'vn-worker-time-control vn-table > div > vn-tfoot > vn-tr:nth-child(2) > vn-td:nth-child(4) > vn-icon-button',
fridayAddTimeButton: 'vn-worker-time-control vn-table > div > vn-tfoot > vn-tr:nth-child(2) > vn-td:nth-child(5) > vn-icon-button',
saturdayAddTimeButton: 'vn-worker-time-control vn-table > div > vn-tfoot > vn-tr:nth-child(2) > vn-td:nth-child(6) > vn-icon-button',
sundayAddTimeButton: 'vn-worker-time-control vn-table > div > vn-tfoot > vn-tr:nth-child(2) > vn-td:nth-child(7) > vn-icon-button',
firstEntryOfMonday: 'vn-worker-time-control vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(1) > section:nth-child(1) > vn-chip > div:nth-child(2)', firstEntryOfMonday: 'vn-worker-time-control vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(1) > section:nth-child(1) > vn-chip > div:nth-child(2)',
firstEntryOfTuesday: 'vn-worker-time-control vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(2) > section:nth-child(1) > vn-chip > div:nth-child(2)', firstEntryOfMondayDelete: 'vn-worker-time-control vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(1) > section:nth-child(1) > vn-chip > vn-icon[icon="cancel"]',
firstEntryOfWednesday: 'vn-worker-time-control vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(3) > section:nth-child(1) > vn-chip > div:nth-child(2)',
firstEntryOfThursday: 'vn-worker-time-control vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(4) > section:nth-child(1) > vn-chip > div:nth-child(2)',
firstEntryOfFriday: 'vn-worker-time-control vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(5) > section:nth-child(1) > vn-chip > div:nth-child(2)',
firstEntryOfSaturday: 'vn-worker-time-control vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(6) > section:nth-child(1) > vn-chip > div:nth-child(2)',
firstEntryOfSunday: 'vn-worker-time-control vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(7) > section:nth-child(1) > vn-chip > div:nth-child(2)',
secondEntryOfMonday: 'vn-worker-time-control vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(1) > section:nth-child(2) > vn-chip > div:nth-child(2)', secondEntryOfMonday: 'vn-worker-time-control vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(1) > section:nth-child(2) > vn-chip > div:nth-child(2)',
secondEntryOfTuesday: 'vn-worker-time-control vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(2) > section:nth-child(2) > vn-chip > div:nth-child(2)',
secondEntryOfWednesday: 'vn-worker-time-control vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(3) > section:nth-child(2) > vn-chip > div:nth-child(2)',
secondEntryOfThursday: 'vn-worker-time-control vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(4) > section:nth-child(2) > vn-chip > div:nth-child(2)',
secondEntryOfFriday: 'vn-worker-time-control vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(5) > section:nth-child(2) > vn-chip > div:nth-child(2)',
secondEntryOfSaturday: 'vn-worker-time-control vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(6) > section:nth-child(2) > vn-chip > div:nth-child(2)',
secondEntryOfSunday: 'vn-worker-time-control vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(7) > section:nth-child(2) > vn-chip > div:nth-child(2)',
thirdEntryOfMonday: 'vn-worker-time-control vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(1) > section:nth-child(3) > vn-chip > div:nth-child(2)',
thirdEntryOfMondayDelete: 'vn-worker-time-control vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(1) > section:nth-child(3) > vn-chip > vn-icon[icon="cancel"]',
thirdEntryOfTuesday: 'vn-worker-time-control vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(2) > section:nth-child(3) > vn-chip > div:nth-child(2)',
thirdEntryOfWednesday: 'vn-worker-time-control vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(3) > section:nth-child(3) > vn-chip > div:nth-child(2)',
thirdEntryOfThursday: 'vn-worker-time-control vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(4) > section:nth-child(3) > vn-chip > div:nth-child(2)',
thirdEntryOfFriday: 'vn-worker-time-control vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(5) > section:nth-child(3) > vn-chip > div:nth-child(2)',
thirdEntryOfSaturday: 'vn-worker-time-control vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(6) > section:nth-child(3) > vn-chip > div:nth-child(2)',
thirdEntryOfSunday: 'vn-worker-time-control vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(7) > section:nth-child(3) > vn-chip > div:nth-child(2)',
fourthEntryOfMonday: 'vn-worker-time-control vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(1) > section:nth-child(4) > vn-chip > div:nth-child(2)',
fourthEntryOfTuesday: 'vn-worker-time-control vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(2) > section:nth-child(4) > vn-chip > div:nth-child(2)',
fourthEntryOfWednesday: 'vn-worker-time-control vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(3) > section:nth-child(4) > vn-chip > div:nth-child(2)',
fourthEntryOfThursday: 'vn-worker-time-control vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(4) > section:nth-child(4) > vn-chip > div:nth-child(2)',
fourthEntryOfFriday: 'vn-worker-time-control vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(5) > section:nth-child(4) > vn-chip > div:nth-child(2)',
fourthEntryOfSaturday: 'vn-worker-time-control vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(6) > section:nth-child(4) > vn-chip > div:nth-child(2)',
fourthEntryOfSunday: 'vn-worker-time-control vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(7) > section:nth-child(4) > vn-chip > div:nth-child(2)',
mondayWorkedHours: 'vn-worker-time-control vn-table > div > vn-tfoot > vn-tr:nth-child(1) > vn-td:nth-child(1)', mondayWorkedHours: 'vn-worker-time-control vn-table > div > vn-tfoot > vn-tr:nth-child(1) > vn-td:nth-child(1)',
tuesdayWorkedHours: 'vn-worker-time-control vn-table > div > vn-tfoot > vn-tr:nth-child(1) > vn-td:nth-child(2)',
wednesdayWorkedHours: 'vn-worker-time-control vn-table > div > vn-tfoot > vn-tr:nth-child(1) > vn-td:nth-child(3)',
thursdayWorkedHours: 'vn-worker-time-control vn-table > div > vn-tfoot > vn-tr:nth-child(1) > vn-td:nth-child(4)',
fridayWorkedHours: 'vn-worker-time-control vn-table > div > vn-tfoot > vn-tr:nth-child(1) > vn-td:nth-child(5)',
saturdayWorkedHours: 'vn-worker-time-control vn-table > div > vn-tfoot > vn-tr:nth-child(1) > vn-td:nth-child(6)',
sundayWorkedHours: 'vn-worker-time-control vn-table > div > vn-tfoot > vn-tr:nth-child(1) > vn-td:nth-child(7)',
weekWorkedHours: 'vn-worker-time-control vn-side-menu vn-label-value > section > span', weekWorkedHours: 'vn-worker-time-control vn-side-menu vn-label-value > section > span',
nextMonthButton: 'vn-worker-time-control vn-side-menu vn-calendar vn-button[icon=keyboard_arrow_right]', nextMonthButton: 'vn-worker-time-control vn-side-menu vn-calendar vn-button[icon=keyboard_arrow_right]',
previousMonthButton: 'vn-worker-time-control vn-side-menu vn-calendar vn-button[icon=keyboard_arrow_left]', previousMonthButton: 'vn-worker-time-control vn-side-menu vn-calendar vn-button[icon=keyboard_arrow_left]',
nameOfMonth: 'vn-worker-time-control vn-side-menu vn-calendar div > .title',
secondWeekDay: 'vn-worker-time-control vn-side-menu vn-calendar .day:nth-child(8) > .day-number', secondWeekDay: 'vn-worker-time-control vn-side-menu vn-calendar .day:nth-child(8) > .day-number',
thrirdWeekDay: 'vn-worker-time-control vn-side-menu vn-calendar .day:nth-child(15) > .day-number',
navigateBackToIndex: 'vn-worker-descriptor [name="goToModuleIndex"]' navigateBackToIndex: 'vn-worker-descriptor [name="goToModuleIndex"]'
}, },
workerCalendar: { workerCalendar: {

View File

@ -1,3 +1,4 @@
/* eslint max-len: ["error", { "code": 150 }]*/
import selectors from '../../helpers/selectors.js'; import selectors from '../../helpers/selectors.js';
import getBrowser from '../../helpers/puppeteer'; import getBrowser from '../../helpers/puppeteer';
@ -10,414 +11,105 @@ describe('Worker time control path', () => {
await page.loginAndModule('salesBoss', 'worker'); await page.loginAndModule('salesBoss', 'worker');
await page.accessToSearchResult('HankPym'); await page.accessToSearchResult('HankPym');
await page.accessToSection('worker.card.timeControl'); await page.accessToSection('worker.card.timeControl');
await page.waitToClick(selectors.workerTimeControl.previousMonthButton);
await page.waitToClick(selectors.workerTimeControl.secondWeekDay);
}); });
afterAll(async() => { afterAll(async() => {
await browser.close(); await browser.close();
}); });
describe('as salesBoss', () => { const heightAm = '08:00';
describe('on Monday', () => { const fourPm = '16:00';
it('should scan in Hank Pym', async() => { const hankPymId = 1107;
const scanTime = '07:00';
await page.waitToClick(selectors.workerTimeControl.mondayAddTimeButton); it('should go to the next month', async() => {
await page.pickTime(selectors.workerTimeControl.dialogTimeInput, scanTime); const date = new Date();
await page.autocompleteSearch(selectors.workerTimeControl.dialogTimeDirection, 'in'); date.setMonth(date.getMonth() + 1);
await page.respondToDialog('accept'); const month = date.toLocaleString('default', {month: 'long'});
const result = await page.waitToGetProperty(selectors.workerTimeControl.firstEntryOfMonday, 'innerText');
expect(result).toEqual(scanTime); await page.waitToClick(selectors.workerTimeControl.nextMonthButton);
}); const result = await page.waitToGetProperty(selectors.workerTimeControl.nameOfMonth, 'innerText');
it(`should scan out Hank Pym for break`, async() => { expect(result).toContain(month);
const scanTime = '10:00';
await page.waitToClick(selectors.workerTimeControl.mondayAddTimeButton);
await page.pickTime(selectors.workerTimeControl.dialogTimeInput, scanTime);
await page.autocompleteSearch(selectors.workerTimeControl.dialogTimeDirection, 'intermediate');
await page.respondToDialog('accept');
const result = await page.waitToGetProperty(selectors.workerTimeControl.secondEntryOfMonday, 'innerText');
expect(result).toEqual(scanTime);
});
it(`should scan in Hank Pym for a wrong hour and forget to scan in from the break`, async() => {
const scanTime = '18:00';
await page.waitToClick(selectors.workerTimeControl.mondayAddTimeButton);
await page.pickTime(selectors.workerTimeControl.dialogTimeInput, scanTime);
await page.autocompleteSearch(selectors.workerTimeControl.dialogTimeDirection, 'intermediate');
await page.respondToDialog('accept');
const result = await page.waitToGetProperty(selectors.workerTimeControl.thirdEntryOfMonday, 'innerText');
expect(result).toEqual(scanTime);
});
it(`should delete the wrong entry for Hank Pym`, async() => {
const wrongScanTime = '18:00';
await page.waitForTextInElement(selectors.workerTimeControl.thirdEntryOfMonday, wrongScanTime);
await page.waitToClick(selectors.workerTimeControl.thirdEntryOfMondayDelete);
await page.respondToDialog('accept');
const message = await page.waitForSnackbar();
expect(message.text).toContain('Entry removed');
});
it(`should scan out Hank Pym to leave early`, async() => {
const scanTime = '14:00';
await page.waitToClick(selectors.workerTimeControl.mondayAddTimeButton);
await page.pickTime(selectors.workerTimeControl.dialogTimeInput, scanTime);
await page.autocompleteSearch(selectors.workerTimeControl.dialogTimeDirection, 'out');
await page.respondToDialog('accept');
const result = await page.waitToGetProperty(selectors.workerTimeControl.thirdEntryOfMonday, 'innerText');
expect(result).toEqual(scanTime);
});
it(`should add the break's scan in for Hank Pym and be in the right order`, async() => {
const scanTime = '10:20';
await page.waitToClick(selectors.workerTimeControl.mondayAddTimeButton);
await page.pickTime(selectors.workerTimeControl.dialogTimeInput, scanTime);
await page.autocompleteSearch(selectors.workerTimeControl.dialogTimeDirection, 'intermediate');
await page.respondToDialog('accept');
const result = await page.waitToGetProperty(selectors.workerTimeControl.fourthEntryOfMonday, 'innerText');
expect(result).toEqual('14:00');
});
it(`should the third entry be the scan in from break`, async() => {
const scanTime = '10:20';
const result = await page
.waitToGetProperty(selectors.workerTimeControl.thirdEntryOfMonday, 'innerText');
expect(result).toEqual(scanTime);
});
it(`should check Hank Pym worked 6:40 hours`, async() => {
await page.waitForTextInElement(selectors.workerTimeControl.mondayWorkedHours, '06:40 h.');
});
});
describe('on Tuesday', () => {
it('should happily scan in Hank Pym', async() => {
const scanTime = '08:00';
await page.waitToClick(selectors.workerTimeControl.tuesdayAddTimeButton);
await page.pickTime(selectors.workerTimeControl.dialogTimeInput, scanTime);
await page.autocompleteSearch(selectors.workerTimeControl.dialogTimeDirection, 'in');
await page.respondToDialog('accept');
const result = await page.waitToGetProperty(selectors.workerTimeControl.firstEntryOfTuesday, 'innerText');
expect(result).toEqual(scanTime);
});
it(`should happily scan out Hank Pym for break`, async() => {
const scanTime = '10:00';
await page.waitToClick(selectors.workerTimeControl.tuesdayAddTimeButton);
await page.pickTime(selectors.workerTimeControl.dialogTimeInput, scanTime);
await page.autocompleteSearch(selectors.workerTimeControl.dialogTimeDirection, 'intermediate');
await page.respondToDialog('accept');
const result = await page.waitToGetProperty(selectors.workerTimeControl.secondEntryOfTuesday, 'innerText');
expect(result).toEqual(scanTime);
});
it(`should happily scan in Hank Pym from the break`, async() => {
const scanTime = '10:20';
await page.waitToClick(selectors.workerTimeControl.tuesdayAddTimeButton);
await page.pickTime(selectors.workerTimeControl.dialogTimeInput, scanTime);
await page.autocompleteSearch(selectors.workerTimeControl.dialogTimeDirection, 'intermediate');
await page.respondToDialog('accept');
const result = await page.waitToGetProperty(selectors.workerTimeControl.thirdEntryOfTuesday, 'innerText');
expect(result).toEqual(scanTime);
});
it(`should happily scan out Hank Pym for the day`, async() => {
const scanTime = '16:00';
await page.waitToClick(selectors.workerTimeControl.tuesdayAddTimeButton);
await page.pickTime(selectors.workerTimeControl.dialogTimeInput, scanTime);
await page.autocompleteSearch(selectors.workerTimeControl.dialogTimeDirection, 'out');
await page.respondToDialog('accept');
const result = await page.waitToGetProperty(selectors.workerTimeControl.fourthEntryOfTuesday, 'innerText');
expect(result).toEqual(scanTime);
});
it(`should check Hank Pym worked 7:40 hours`, async() => {
await page.waitForTextInElement(selectors.workerTimeControl.tuesdayWorkedHours, '07:40 h.');
});
});
describe('on Wednesday', () => {
it('should cheerfully scan in Hank Pym', async() => {
const scanTime = '09:00';
await page.waitToClick(selectors.workerTimeControl.wednesdayAddTimeButton);
await page.pickTime(selectors.workerTimeControl.dialogTimeInput, scanTime);
await page.autocompleteSearch(selectors.workerTimeControl.dialogTimeDirection, 'in');
await page.respondToDialog('accept');
const result = await page.waitToGetProperty(selectors.workerTimeControl.firstEntryOfWednesday, 'innerText');
expect(result).toEqual(scanTime);
});
it(`should cheerfully scan out Hank Pym for break`, async() => {
const scanTime = '10:00';
await page.waitToClick(selectors.workerTimeControl.wednesdayAddTimeButton);
await page.pickTime(selectors.workerTimeControl.dialogTimeInput, scanTime);
await page.autocompleteSearch(selectors.workerTimeControl.dialogTimeDirection, 'intermediate');
await page.respondToDialog('accept');
const result = await page.waitToGetProperty(selectors.workerTimeControl.secondEntryOfWednesday, 'innerText');
expect(result).toEqual(scanTime);
});
it(`should cheerfully scan in Hank Pym from the break`, async() => {
const scanTime = '10:20';
await page.waitToClick(selectors.workerTimeControl.wednesdayAddTimeButton);
await page.pickTime(selectors.workerTimeControl.dialogTimeInput, scanTime);
await page.autocompleteSearch(selectors.workerTimeControl.dialogTimeDirection, 'intermediate');
await page.respondToDialog('accept');
const result = await page.waitToGetProperty(selectors.workerTimeControl.thirdEntryOfWednesday, 'innerText');
expect(result).toEqual(scanTime);
});
it(`should cheerfully scan out Hank Pym for the day`, async() => {
const scanTime = '17:00';
await page.waitToClick(selectors.workerTimeControl.wednesdayAddTimeButton);
await page.pickTime(selectors.workerTimeControl.dialogTimeInput, scanTime);
await page.autocompleteSearch(selectors.workerTimeControl.dialogTimeDirection, 'out');
await page.respondToDialog('accept');
const result = await page.waitToGetProperty(selectors.workerTimeControl.fourthEntryOfWednesday, 'innerText');
expect(result).toEqual(scanTime);
});
it(`should check Hank Pym worked 7:40 cheerfull hours`, async() => {
await page.waitForTextInElement(selectors.workerTimeControl.wednesdayWorkedHours, '07:40 h.');
});
});
describe('on Thursday', () => {
it('should joyfully scan in Hank Pym', async() => {
const scanTime = '09:59';
await page.waitToClick(selectors.workerTimeControl.thursdayAddTimeButton);
await page.pickTime(selectors.workerTimeControl.dialogTimeInput, scanTime);
await page.autocompleteSearch(selectors.workerTimeControl.dialogTimeDirection, 'in');
await page.respondToDialog('accept');
const result = await page.waitToGetProperty(selectors.workerTimeControl.firstEntryOfThursday, 'innerText');
expect(result).toEqual(scanTime);
});
it(`should joyfully scan out Hank Pym for break`, async() => {
const scanTime = '10:00';
await page.waitToClick(selectors.workerTimeControl.thursdayAddTimeButton);
await page.pickTime(selectors.workerTimeControl.dialogTimeInput, scanTime);
await page.autocompleteSearch(selectors.workerTimeControl.dialogTimeDirection, 'intermediate');
await page.respondToDialog('accept');
const result = await page.waitToGetProperty(selectors.workerTimeControl.secondEntryOfThursday, 'innerText');
expect(result).toEqual(scanTime);
});
it(`should joyfully scan in Hank Pym from the break`, async() => {
const scanTime = '10:20';
await page.waitToClick(selectors.workerTimeControl.thursdayAddTimeButton);
await page.pickTime(selectors.workerTimeControl.dialogTimeInput, scanTime);
await page.autocompleteSearch(selectors.workerTimeControl.dialogTimeDirection, 'intermediate');
await page.respondToDialog('accept');
const result = await page.waitToGetProperty(selectors.workerTimeControl.thirdEntryOfThursday, 'innerText');
expect(result).toEqual(scanTime);
});
it(`should joyfully scan out Hank Pym for the day`, async() => {
const scanTime = '17:59';
await page.waitToClick(selectors.workerTimeControl.thursdayAddTimeButton);
await page.pickTime(selectors.workerTimeControl.dialogTimeInput, scanTime);
await page.autocompleteSearch(selectors.workerTimeControl.dialogTimeDirection, 'out');
await page.respondToDialog('accept');
const result = await page.waitToGetProperty(selectors.workerTimeControl.fourthEntryOfThursday, 'innerText');
expect(result).toEqual(scanTime);
});
it(`should check Hank Pym worked 7:40 joyfull hours`, async() => {
await page.waitForTextInElement(selectors.workerTimeControl.thursdayWorkedHours, '07:40 h.');
});
});
describe('on Friday', () => {
it('should smilingly scan in Hank Pym', async() => {
const scanTime = '07:30';
await page.waitToClick(selectors.workerTimeControl.fridayAddTimeButton);
await page.pickTime(selectors.workerTimeControl.dialogTimeInput, scanTime);
await page.autocompleteSearch(selectors.workerTimeControl.dialogTimeDirection, 'in');
await page.respondToDialog('accept');
const result = await page.waitToGetProperty(selectors.workerTimeControl.firstEntryOfFriday, 'innerText');
expect(result).toEqual(scanTime);
});
it(`should smilingly scan out Hank Pym for break`, async() => {
const scanTime = '10:00';
await page.waitToClick(selectors.workerTimeControl.fridayAddTimeButton);
await page.pickTime(selectors.workerTimeControl.dialogTimeInput, scanTime);
await page.autocompleteSearch(selectors.workerTimeControl.dialogTimeDirection, 'intermediate');
await page.respondToDialog('accept');
const result = await page.waitToGetProperty(selectors.workerTimeControl.secondEntryOfFriday, 'innerText');
expect(result).toEqual(scanTime);
});
it(`should smilingly scan in Hank Pym from the break`, async() => {
const scanTime = '10:20';
await page.waitToClick(selectors.workerTimeControl.fridayAddTimeButton);
await page.pickTime(selectors.workerTimeControl.dialogTimeInput, scanTime);
await page.autocompleteSearch(selectors.workerTimeControl.dialogTimeDirection, 'intermediate');
await page.respondToDialog('accept');
const result = await page.waitToGetProperty(selectors.workerTimeControl.thirdEntryOfFriday, 'innerText');
expect(result).toEqual(scanTime);
});
it(`should smilingly scan out Hank Pym for the day`, async() => {
const scanTime = '15:30';
await page.waitToClick(selectors.workerTimeControl.fridayAddTimeButton);
await page.pickTime(selectors.workerTimeControl.dialogTimeInput, scanTime);
await page.autocompleteSearch(selectors.workerTimeControl.dialogTimeDirection, 'out');
await page.respondToDialog('accept');
const result = await page.waitToGetProperty(selectors.workerTimeControl.fourthEntryOfFriday, 'innerText');
expect(result).toEqual(scanTime);
});
it(`should check Hank Pym worked 7:40 hours with a smile on his face`, async() => {
await page.waitForTextInElement(selectors.workerTimeControl.fridayWorkedHours, '07:40 h.');
});
});
}); });
describe('as HHRR', () => { it('should go to current month', async() => {
describe('on Saturday', () => { const date = new Date();
it('should log in as hr and pick the worker module', async() => { const month = date.toLocaleString('default', {month: 'long'});
await page.loginAndModule('hr', 'worker');
});
it('should search for a worker and access to its summary', async() => { await page.waitToClick(selectors.workerTimeControl.previousMonthButton);
await page.accessToSearchResult('HankPym'); const result = await page.waitToGetProperty(selectors.workerTimeControl.nameOfMonth, 'innerText');
await page.waitForState('worker.card.summary');
});
it('should access to the time control section', async() => { expect(result).toContain(month);
await page.accessToSection('worker.card.timeControl');
await page.waitForState('worker.card.timeControl');
await page.waitToClick(selectors.workerTimeControl.previousMonthButton);
await page.waitToClick(selectors.workerTimeControl.secondWeekDay);
});
it('should lovingly scan in Hank Pym', async() => {
const scanTime = '06:00';
await page.waitForTimeout(1000); // without this timeout the dialog doesn't pop up
await page.waitToClick(selectors.workerTimeControl.saturdayAddTimeButton);
await page.pickTime(selectors.workerTimeControl.dialogTimeInput, scanTime);
await page.autocompleteSearch(selectors.workerTimeControl.dialogTimeDirection, 'in');
await page.respondToDialog('accept');
const result = await page.waitToGetProperty(selectors.workerTimeControl.firstEntryOfSaturday, 'innerText');
expect(result).toEqual(scanTime);
});
it(`should lovingly scan out Hank Pym for the day with no break to leave a bit early`, async() => {
const scanTime = '13:40';
await page.waitToClick(selectors.workerTimeControl.saturdayAddTimeButton);
await page.pickTime(selectors.workerTimeControl.dialogTimeInput, scanTime);
await page.autocompleteSearch(selectors.workerTimeControl.dialogTimeDirection, 'out');
await page.respondToDialog('accept');
const result = await page.waitToGetProperty(selectors.workerTimeControl.secondEntryOfSaturday, 'innerText');
expect(result).toEqual(scanTime);
});
it(`should check Hank Pym worked 7:40 hours with all his will`, async() => {
await page.waitForTextInElement(selectors.workerTimeControl.saturdayWorkedHours, '07:40 h.');
});
});
describe('on Sunday', () => {
it('should gladly scan in Hank Pym', async() => {
const scanTime = '05:00';
await page.waitToClick(selectors.workerTimeControl.sundayAddTimeButton);
await page.pickTime(selectors.workerTimeControl.dialogTimeInput, scanTime);
await page.autocompleteSearch(selectors.workerTimeControl.dialogTimeDirection, 'in');
await page.respondToDialog('accept');
const result = await page.waitToGetProperty(selectors.workerTimeControl.firstEntryOfSunday, 'innerText');
expect(result).toEqual(scanTime);
});
it(`should gladly scan out Hank Pym for the day with no break to leave a bit early`, async() => {
const scanTime = '12:40';
await page.waitToClick(selectors.workerTimeControl.sundayAddTimeButton);
await page.pickTime(selectors.workerTimeControl.dialogTimeInput, scanTime);
await page.autocompleteSearch(selectors.workerTimeControl.dialogTimeDirection, 'out');
await page.respondToDialog('accept');
const result = await page.waitToGetProperty(selectors.workerTimeControl.secondEntryOfSunday, 'innerText');
expect(result).toEqual(scanTime);
});
it(`should check Hank Pym worked 7:40 glad hours`, async() => {
await page.waitForTextInElement(selectors.workerTimeControl.sundayWorkedHours, '07:40 h.');
});
it(`should check Hank Pym doesn't have hours set on the next months second week`, async() => {
await page.waitToClick(selectors.workerTimeControl.nextMonthButton);
await page.waitToClick(selectors.workerTimeControl.secondWeekDay);
await page.waitForTextInElement(selectors.workerTimeControl.weekWorkedHours, '00:00 h.');
});
it(`should check he didn't scan in this week yet`, async() => {
await page.waitToClick(selectors.workerTimeControl.navigateBackToIndex);
await page.accessToSearchResult('salesBoss');
await page.accessToSection('worker.card.timeControl');
const wholeWeekHours = await page
.waitToGetProperty(selectors.workerTimeControl.weekWorkedHours, 'innerText');
expect(wholeWeekHours).toEqual('00:00 h.');
});
});
}); });
describe('after all this amazing week', () => { it('should go 1 month in the past', async() => {
it('should log in Hank', async() => { const date = new Date();
await page.loginAndModule('HankPym', 'worker'); date.setMonth(date.getMonth() - 1);
await page.accessToSearchResult('HankPym'); const timestamp = Math.round(date.getTime() / 1000);
await page.accessToSection('worker.card.timeControl'); const month = date.toLocaleString('default', {month: 'long'});
await page.waitToClick(selectors.workerTimeControl.previousMonthButton);
await page.waitToClick(selectors.workerTimeControl.secondWeekDay);
});
it('should check his weekly hours are alright', async() => { await page.loginAndModule('salesBoss', 'worker');
await page.waitForTextInElement(selectors.workerTimeControl.weekWorkedHours, '52:40 h.'); await page.goto(`http://localhost:5000/#!/worker/${hankPymId}/time-control?timestamp=${timestamp}`);
}); await page.waitToClick(selectors.workerTimeControl.secondWeekDay);
const result = await page.waitToGetProperty(selectors.workerTimeControl.nameOfMonth, 'innerText');
expect(result).toContain(month);
});
it(`should return error when insert 'out' of first entry`, async() => {
await page.waitToClick(selectors.workerTimeControl.mondayAddTimeButton);
await page.pickTime(selectors.workerTimeControl.dialogTimeInput, heightAm);
await page.autocompleteSearch(selectors.workerTimeControl.dialogTimeDirection, 'out');
await page.respondToDialog('accept');
const message = await page.waitForSnackbar();
expect(message.text).toBeDefined();
});
it(`should insert 'in' monday`, async() => {
await page.waitToClick(selectors.workerTimeControl.mondayAddTimeButton);
await page.pickTime(selectors.workerTimeControl.dialogTimeInput, heightAm);
await page.autocompleteSearch(selectors.workerTimeControl.dialogTimeDirection, 'in');
await page.respondToDialog('accept');
const result = await page.waitToGetProperty(selectors.workerTimeControl.firstEntryOfMonday, 'innerText');
expect(result).toEqual(heightAm);
});
it(`should insert 'out' monday`, async() => {
await page.waitToClick(selectors.workerTimeControl.mondayAddTimeButton);
await page.pickTime(selectors.workerTimeControl.dialogTimeInput, fourPm);
await page.autocompleteSearch(selectors.workerTimeControl.dialogTimeDirection, 'out');
await page.respondToDialog('accept');
const result = await page.waitToGetProperty(selectors.workerTimeControl.secondEntryOfMonday, 'innerText');
expect(result).toEqual(fourPm);
});
it(`should check Hank Pym worked 8:20 hours`, async() => {
await page.waitForTextInElement(selectors.workerTimeControl.mondayWorkedHours, '08:20 h.');
await page.waitForTextInElement(selectors.workerTimeControl.weekWorkedHours, '08:20 h.');
});
it('should remove first entry of monday', async() => {
await page.waitForTextInElement(selectors.workerTimeControl.firstEntryOfMonday, heightAm);
await page.waitForTextInElement(selectors.workerTimeControl.secondEntryOfMonday, fourPm);
await page.waitToClick(selectors.workerTimeControl.firstEntryOfMondayDelete);
await page.respondToDialog('accept');
const message = await page.waitForSnackbar();
expect(message.text).toContain('Entry removed');
});
it(`should be the 'out' the first entry of monday`, async() => {
const result = await page.waitToGetProperty(selectors.workerTimeControl.firstEntryOfMonday, 'innerText');
expect(result).toEqual(fourPm);
});
it('should change week of month', async() => {
await page.waitToClick(selectors.workerTimeControl.thrirdWeekDay);
await page.waitForTextInElement(selectors.workerTimeControl.mondayWorkedHours, '00:00 h.');
}); });
}); });

View File

@ -124,5 +124,13 @@
"isWithoutNegatives": "isWithoutNegatives", "isWithoutNegatives": "isWithoutNegatives",
"routeFk": "routeFk", "routeFk": "routeFk",
"Not enough privileges to edit a client with verified data": "Not enough privileges to edit a client with verified data", "Not enough privileges to edit a client with verified data": "Not enough privileges to edit a client with verified data",
"Can't change the password of another worker": "Can't change the password of another worker" "Can't change the password of another worker": "Can't change the password of another worker",
"No hay un contrato en vigor": "No hay un contrato en vigor",
"No está permitido trabajar": "Holaholahola",
"Dirección incorrecta": "Dirección incorrecta",
"No se permite fichar a futuro": "No se permite fichar a futuro",
"Descanso diario 12h.": "Descanso diario 12h.",
"Fichadas impares": "Fichadas impares",
"Descanso diario 9h.": "Descanso diario 9h.",
"Descanso semanal 36h. / 72h.": "Descanso semanal 36h. / 72h."
} }

View File

@ -227,5 +227,12 @@
"This ticket is already a refund": "Este ticket ya es un abono", "This ticket is already a refund": "Este ticket ya es un abono",
"isWithoutNegatives": "isWithoutNegatives", "isWithoutNegatives": "isWithoutNegatives",
"routeFk": "routeFk", "routeFk": "routeFk",
"Can't change the password of another worker": "No se puede cambiar la contraseña de otro trabajador" "Can't change the password of another worker": "No se puede cambiar la contraseña de otro trabajador",
"No hay un contrato en vigor": "No hay un contrato en vigor",
"No se permite fichar a futuro": "No se permite fichar a futuro",
"No está permitido trabajar": "No está permitido trabajar",
"Fichadas impares": "Fichadas impares",
"Descanso diario 12h.": "Descanso diario 12h.",
"Descanso semanal 36h. / 72h.": "Descanso semanal 36h. / 72h.",
"Dirección incorrecta": "Dirección incorrecta"
} }

View File

@ -46,30 +46,11 @@ module.exports = Self => {
if (isSubordinate === false || (isSubordinate && isHimself && !isTeamBoss)) if (isSubordinate === false || (isSubordinate && isHimself && !isTeamBoss))
throw new UserError(`You don't have enough privileges`); throw new UserError(`You don't have enough privileges`);
const minTime = new Date(args.timed); query = `CALL vn.workerTimeControl_clockIn(?,?,?)`;
minTime.setHours(0, 0, 0, 0); const [response] = await Self.rawSql(query, [workerId, args.timed, args.direction], myOptions);
if (response[0] && response[0].error)
throw new UserError(response[0].error);
query = `SELECT * FROM vn.workerLabour WHERE workerFk = ? AND (ended >= ? OR ended IS NULL);`; return response;
const [workerLabour] = await Self.rawSql(query, [workerId, minTime]);
const absence = await models.Calendar.findOne({
where: {
businessFk: workerLabour.businessFk,
dated: minTime
}
});
if (absence) {
const absenceType = await models.AbsenceType.findById(absence.dayOffTypeFk, null, myOptions);
const isNotHalfAbsence = absenceType.code != 'halfHoliday'
&& absenceType.code != 'halfPaidLeave'
&& absenceType.code != 'halfFurlough';
if (isNotHalfAbsence)
throw new UserError(`The worker has a marked absence that day`);
}
return models.WorkerTimeControl.create({
userFk: workerId,
direction: args.direction,
timed: args.timed,
manual: true
}, myOptions);
}; };
}; };

View File

@ -1,6 +1,6 @@
const app = require('vn-loopback/server/server'); /* eslint max-len: ["error", { "code": 150 }]*/
const models = require('vn-loopback/server/server').models;
const LoopBackContext = require('loopback-context'); const LoopBackContext = require('loopback-context');
const models = app.models;
describe('workerTimeControl add/delete timeEntry()', () => { describe('workerTimeControl add/delete timeEntry()', () => {
const HHRRId = 37; const HHRRId = 37;
@ -8,6 +8,14 @@ describe('workerTimeControl add/delete timeEntry()', () => {
const employeeId = 1; const employeeId = 1;
const salesPersonId = 1106; const salesPersonId = 1106;
const salesBossId = 19; const salesBossId = 19;
const hankPymId = 1107;
const jessicaJonesId = 1110;
const monday = 1;
const tuesday = 2;
const thursday = 4;
const friday = 5;
const saturday = 6;
const sunday = 7;
const activeCtx = { const activeCtx = {
accessToken: {userId: 50}, accessToken: {userId: 50},
}; };
@ -19,190 +27,675 @@ describe('workerTimeControl add/delete timeEntry()', () => {
}); });
}); });
it('should fail to add a time entry if the target user is not a subordinate', async() => { describe('as Role errors', () => {
activeCtx.accessToken.userId = employeeId; it('should fail to add a time entry if the target user is not a subordinate', async() => {
const workerId = 2; activeCtx.accessToken.userId = employeeId;
const workerId = 2;
let error; let error;
try { try {
ctx.args = {timed: new Date(), direction: 'in'}; ctx.args = {timed: new Date(), direction: 'in'};
await models.WorkerTimeControl.addTimeEntry(ctx, workerId); await models.WorkerTimeControl.addTimeEntry(ctx, workerId);
} catch (e) { } catch (e) {
error = e; error = e;
} }
expect(error).toBeDefined(); expect(error).toBeDefined();
expect(error.statusCode).toBe(400); expect(error.statusCode).toBe(400);
expect(error.message).toBe(`You don't have enough privileges`); expect(error.message).toBe(`You don't have enough privileges`);
});
it('should fail to add if the current and the target user are the same and is not team boss', async() => {
activeCtx.accessToken.userId = employeeId;
const workerId = employeeId;
let error;
try {
ctx.args = {timed: new Date(), direction: 'in'};
await models.WorkerTimeControl.addTimeEntry(ctx, workerId);
} catch (e) {
error = e;
}
expect(error).toBeDefined();
expect(error.statusCode).toBe(400);
expect(error.message).toBe(`You don't have enough privileges`);
});
it('should add if the current user is team boss and the target user is a himself', async() => {
activeCtx.accessToken.userId = teamBossId;
const workerId = teamBossId;
const tx = await models.WorkerTimeControl.beginTransaction({});
try {
const options = {transaction: tx};
const todayAtOne = new Date();
todayAtOne.setHours(1, 0, 0, 0);
ctx.args = {timed: todayAtOne, direction: 'in'};
const [createdTimeEntry] = await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options);
expect(createdTimeEntry.id).toBeDefined();
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
});
it('should try but fail to delete his own time entry', async() => {
activeCtx.accessToken.userId = salesBossId;
const workerId = salesBossId;
let error;
const tx = await models.WorkerTimeControl.beginTransaction({});
try {
const options = {transaction: tx};
const todayAtOne = new Date();
todayAtOne.setHours(1, 0, 0, 0);
ctx.args = {timed: todayAtOne, direction: 'in'};
const [createdTimeEntry] = await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options);
activeCtx.accessToken.userId = salesPersonId;
await models.WorkerTimeControl.deleteTimeEntry(ctx, createdTimeEntry.id, options);
await tx.rollback();
} catch (e) {
error = e;
await tx.rollback();
}
expect(error).toBeDefined();
expect(error.statusCode).toBe(400);
expect(error.message).toBe(`You don't have enough privileges`);
});
it('should delete the created time entry for the team boss as himself', async() => {
activeCtx.accessToken.userId = teamBossId;
const workerId = teamBossId;
const tx = await models.WorkerTimeControl.beginTransaction({});
try {
const options = {transaction: tx};
const todayAtOne = new Date();
todayAtOne.setHours(1, 0, 0, 0);
ctx.args = {timed: todayAtOne, direction: 'in'};
const [createdTimeEntry] = await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options);
expect(createdTimeEntry.id).toBeDefined();
await models.WorkerTimeControl.deleteTimeEntry(ctx, createdTimeEntry.id, options);
const deletedTimeEntry = await models.WorkerTimeControl.findById(createdTimeEntry.id, null, options);
expect(deletedTimeEntry).toBeNull();
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
});
it('should delete the created time entry for the team boss as HHRR', async() => {
activeCtx.accessToken.userId = HHRRId;
const workerId = teamBossId;
const tx = await models.WorkerTimeControl.beginTransaction({});
try {
const options = {transaction: tx};
const todayAtOne = new Date();
todayAtOne.setHours(1, 0, 0, 0);
ctx.args = {timed: todayAtOne, direction: 'in'};
const [createdTimeEntry] = await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options);
expect(createdTimeEntry.id).toBeDefined();
await models.WorkerTimeControl.deleteTimeEntry(ctx, createdTimeEntry.id, options);
const deletedTimeEntry = await models.WorkerTimeControl.findById(createdTimeEntry.id, null, options);
expect(deletedTimeEntry).toBeNull();
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
});
it('should edit the created time entry for the team boss as HHRR', async() => {
activeCtx.accessToken.userId = HHRRId;
const workerId = teamBossId;
const tx = await models.WorkerTimeControl.beginTransaction({});
try {
const options = {transaction: tx};
const todayAtOne = new Date();
todayAtOne.setHours(1, 0, 0, 0);
ctx.args = {timed: todayAtOne, direction: 'in'};
const [createdTimeEntry] = await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options);
expect(createdTimeEntry.id).toBeDefined();
ctx.args = {direction: 'out'};
const updatedTimeEntry = await models.WorkerTimeControl.updateTimeEntry(ctx, createdTimeEntry.id, options);
expect(updatedTimeEntry.direction).toEqual('out');
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
});
}); });
it('should fail to add if the current and the target user are the same and is not team boss', async() => { describe('as WorkerTimeControl_clockIn calls', () => {
activeCtx.accessToken.userId = employeeId; it('should fail to add a time entry if the target user has absent that day', async() => {
const workerId = employeeId; activeCtx.accessToken.userId = salesBossId;
let error; const workerId = hankPymId;
const date = new Date();
date.setDate(date.getDate() - 16);
date.setHours(8, 0, 0);
let error;
try { const tx = await models.WorkerTimeControl.beginTransaction({});
ctx.args = {timed: new Date(), direction: 'in'};
await models.WorkerTimeControl.addTimeEntry(ctx, workerId);
} catch (e) {
error = e;
}
expect(error).toBeDefined();
expect(error.statusCode).toBe(400);
expect(error.message).toBe(`You don't have enough privileges`);
});
it('should add if the current user is team boss and the target user is a himself', async() => {
activeCtx.accessToken.userId = teamBossId;
const workerId = teamBossId;
const tx = await models.WorkerTimeControl.beginTransaction({});
try {
const options = {transaction: tx}; const options = {transaction: tx};
try {
ctx.args = {timed: date, direction: 'in'};
await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options);
const todayAtSix = new Date(); await tx.rollback();
todayAtSix.setHours(18, 30, 0, 0); } catch (e) {
await tx.rollback();
error = e;
}
ctx.args = {timed: todayAtSix, direction: 'in'}; expect(error.message).toBe(`No está permitido trabajar`);
const createdTimeEntry = await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options); });
expect(createdTimeEntry.id).toBeDefined(); it('should fail to add a time entry if worker no have business', async() => {
activeCtx.accessToken.userId = salesBossId;
const workerId = hankPymId;
const date = new Date();
date.setFullYear(date.getFullYear() - 2);
let error;
await tx.rollback(); const tx = await models.WorkerTimeControl.beginTransaction({});
} catch (e) { try {
await tx.rollback(); const options = {transaction: tx};
throw e; ctx.args = {timed: date, direction: 'in'};
} await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options);
});
it('should fail to add a time entry if the target user has absent that day', async() => { await tx.rollback();
activeCtx.accessToken.userId = salesBossId; } catch (e) {
const workerId = salesPersonId; await tx.rollback();
let error; error = e;
}
const calendar = await app.models.Calendar.findById(3); expect(error.message).toBe(`No hay un contrato en vigor`);
});
try { describe('as direction errors', () => {
ctx.args = {timed: new Date(calendar.dated), direction: 'in'}; it('should return error when set in with in', async() => {
await models.WorkerTimeControl.addTimeEntry(ctx, workerId); activeCtx.accessToken.userId = salesBossId;
} catch (e) { const workerId = hankPymId;
error = e;
}
expect(error.message).toBe(`The worker has a marked absence that day`); let date = new Date();
}); date.setDate(date.getDate() - 21);
date = weekDay(date, monday);
let error;
it('should try but fail to delete his own time entry', async() => { const tx = await models.WorkerTimeControl.beginTransaction({});
activeCtx.accessToken.userId = salesBossId; const options = {transaction: tx};
const workerId = salesBossId; date.setHours(8, 0, 0);
ctx.args = {timed: date, direction: 'in'};
await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options);
let error; try {
const tx = await models.WorkerTimeControl.beginTransaction({}); date.setHours(10, 0, 0);
try { ctx.args = {timed: date, direction: 'in'};
const options = {transaction: tx}; await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options);
const todayAtSeven = new Date(); await tx.rollback();
todayAtSeven.setHours(19, 30, 0, 0); } catch (e) {
await tx.rollback();
error = e;
}
ctx.args = {timed: todayAtSeven, direction: 'in'}; expect(error.message).toBe(`Dirección incorrecta`);
const createdTimeEntry = await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options); });
activeCtx.accessToken.userId = salesPersonId; it('should return error when set in with in, middle', async() => {
await models.WorkerTimeControl.deleteTimeEntry(ctx, createdTimeEntry.id, options); activeCtx.accessToken.userId = salesBossId;
const workerId = hankPymId;
await tx.rollback(); let date = new Date();
} catch (e) { date.setDate(date.getDate() - 21);
error = e; date = weekDay(date, monday);
await tx.rollback(); let error;
}
expect(error).toBeDefined(); const tx = await models.WorkerTimeControl.beginTransaction({});
expect(error.statusCode).toBe(400); const options = {transaction: tx};
expect(error.message).toBe(`You don't have enough privileges`);
});
it('should delete the created time entry for the team boss as himself', async() => { date.setHours(8, 0, 0);
activeCtx.accessToken.userId = teamBossId; ctx.args = {timed: date, direction: 'in'};
const workerId = teamBossId; await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options);
date.setHours(9, 0, 0);
ctx.args = {timed: date, direction: 'middle'};
await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options);
const tx = await models.WorkerTimeControl.beginTransaction({}); try {
try { date.setHours(10, 0, 0);
const options = {transaction: tx}; ctx.args = {timed: date, direction: 'in'};
await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options);
const todayAtFive = new Date(); await tx.rollback();
todayAtFive.setHours(17, 30, 0, 0); } catch (e) {
await tx.rollback();
error = e;
}
ctx.args = {timed: todayAtFive, direction: 'in'}; expect(error.message).toBe(`Dirección incorrecta`);
const createdTimeEntry = await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options); });
expect(createdTimeEntry.id).toBeDefined(); it('should return error when set out with in, middle', async() => {
activeCtx.accessToken.userId = salesBossId;
const workerId = hankPymId;
await models.WorkerTimeControl.deleteTimeEntry(ctx, createdTimeEntry.id, options); let date = new Date();
date.setDate(date.getDate() - 21);
date = weekDay(date, monday);
let error;
const deletedTimeEntry = await models.WorkerTimeControl.findById(createdTimeEntry.id, null, options); const tx = await models.WorkerTimeControl.beginTransaction({});
const options = {transaction: tx};
expect(deletedTimeEntry).toBeNull(); date.setHours(8, 0, 0);
await tx.rollback(); ctx.args = {timed: date, direction: 'in'};
} catch (e) { await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options);
await tx.rollback(); date.setHours(9, 0, 0);
throw e; ctx.args = {timed: date, direction: 'middle'};
} await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options);
});
it('should delete the created time entry for the team boss as HHRR', async() => { try {
activeCtx.accessToken.userId = HHRRId; date.setHours(10, 0, 0);
const workerId = teamBossId; ctx.args = {timed: date, direction: 'out'};
await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options);
const tx = await models.WorkerTimeControl.beginTransaction({}); await tx.rollback();
try { } catch (e) {
const options = {transaction: tx}; await tx.rollback();
error = e;
}
const todayAtFive = new Date(); expect(error.message).toBe(`Dirección incorrecta`);
todayAtFive.setHours(17, 30, 0, 0); });
ctx.args = {timed: todayAtFive, direction: 'in'}; it('should return error when set middle with in, out', async() => {
const createdTimeEntry = await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options); activeCtx.accessToken.userId = salesBossId;
const workerId = hankPymId;
expect(createdTimeEntry.id).toBeDefined(); let date = new Date();
date.setDate(date.getDate() - 21);
date = weekDay(date, monday);
let error;
await models.WorkerTimeControl.deleteTimeEntry(ctx, createdTimeEntry.id, options); const tx = await models.WorkerTimeControl.beginTransaction({});
const options = {transaction: tx};
const deletedTimeEntry = await models.WorkerTimeControl.findById(createdTimeEntry.id, null, options); date.setHours(8, 0, 0);
ctx.args = {timed: date, direction: 'in'};
await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options);
date.setHours(9, 0, 0);
ctx.args = {timed: date, direction: 'out'};
await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options);
expect(deletedTimeEntry).toBeNull(); try {
await tx.rollback(); date.setHours(10, 0, 0);
} catch (e) { ctx.args = {timed: date, direction: 'middle'};
await tx.rollback(); await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options);
throw e;
}
});
it('should edit the created time entry for the team boss as HHRR', async() => { await tx.rollback();
activeCtx.accessToken.userId = HHRRId; } catch (e) {
const workerId = teamBossId; await tx.rollback();
error = e;
}
const tx = await models.WorkerTimeControl.beginTransaction({}); expect(error.message).toBe(`Dirección incorrecta`);
try { });
const options = {transaction: tx};
const todayAtFive = new Date(); it('should return error when set out with in, out', async() => {
todayAtFive.setHours(17, 30, 0, 0); activeCtx.accessToken.userId = salesBossId;
const workerId = hankPymId;
ctx.args = {timed: todayAtFive, direction: 'in'}; let date = new Date();
const createdTimeEntry = await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options); date.setDate(date.getDate() - 21);
date = weekDay(date, monday);
let error;
expect(createdTimeEntry.id).toBeDefined(); const tx = await models.WorkerTimeControl.beginTransaction({});
const options = {transaction: tx};
ctx.args = {direction: 'out'}; date.setHours(8, 0, 0);
const updatedTimeEntry = await models.WorkerTimeControl.updateTimeEntry(ctx, createdTimeEntry.id, options); ctx.args = {timed: date, direction: 'in'};
await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options);
date.setHours(9, 0, 0);
ctx.args = {timed: date, direction: 'out'};
await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options);
expect(updatedTimeEntry.direction).toEqual('out'); try {
await tx.rollback(); date.setHours(10, 0, 0);
} catch (e) { ctx.args = {timed: date, direction: 'out'};
await tx.rollback(); await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options);
throw e;
} await tx.rollback();
} catch (e) {
await tx.rollback();
error = e;
}
expect(error.message).toBe(`Dirección incorrecta`);
});
});
describe('as break 12h', () => {
it('should return error when not fulfilled 12H break', async() => {
activeCtx.accessToken.userId = salesBossId;
const workerId = hankPymId;
let date = new Date();
date.setDate(date.getDate() - 21);
date = weekDay(date, monday);
let error;
const tx = await models.WorkerTimeControl.beginTransaction({});
const options = {transaction: tx};
date.setHours(8, 0, 0);
ctx.args = {timed: date, direction: 'in'};
await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options);
date.setHours(16, 0, 0);
ctx.args = {timed: date, direction: 'out'};
await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options);
try {
date = weekDay(date, tuesday);
date.setHours(4, 0, 0);
ctx.args = {timed: date, direction: 'in'};
await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options);
await tx.rollback();
} catch (e) {
await tx.rollback();
error = e;
}
expect(error.message).toBe(`Descanso diario 12h.`);
});
it('should not fail when fulfilled 12H break', async() => {
activeCtx.accessToken.userId = salesBossId;
const workerId = hankPymId;
let date = new Date();
date.setDate(date.getDate() - 21);
date = weekDay(date, monday);
let error;
const tx = await models.WorkerTimeControl.beginTransaction({});
const options = {transaction: tx};
date.setHours(8, 0, 0);
ctx.args = {timed: date, direction: 'in'};
await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options);
date.setHours(16, 0, 0);
ctx.args = {timed: date, direction: 'out'};
await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options);
try {
date = weekDay(date, tuesday);
date.setHours(4, 1, 0);
ctx.args = {timed: date, direction: 'in'};
await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options);
await tx.rollback();
} catch (e) {
await tx.rollback();
error = e;
}
expect(error).not.toBeDefined;
});
});
describe('as break 9h for conductors of 3500kg', () => {
it('should return error when not fulfilled 9H break', async() => {
activeCtx.accessToken.userId = salesBossId;
const workerId = jessicaJonesId;
let date = new Date();
date.setDate(date.getDate() - 21);
date = weekDay(date, monday);
let error;
const tx = await models.WorkerTimeControl.beginTransaction({});
const options = {transaction: tx};
date.setHours(8, 0, 0);
ctx.args = {timed: date, direction: 'in'};
await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options);
date.setHours(16, 0, 0);
ctx.args = {timed: date, direction: 'out'};
await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options);
try {
date = weekDay(date, tuesday);
date.setHours(1, 0, 0);
ctx.args = {timed: date, direction: 'in'};
await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options);
await tx.rollback();
} catch (e) {
await tx.rollback();
error = e;
}
expect(error.message).toBe(`Descanso diario 9h.`);
});
it('should not fail when fulfilled 9H break', async() => {
activeCtx.accessToken.userId = salesBossId;
const workerId = jessicaJonesId;
let date = new Date();
date.setDate(date.getDate() - 21);
date = weekDay(date, monday);
let error;
const tx = await models.WorkerTimeControl.beginTransaction({});
const options = {transaction: tx};
date.setHours(8, 0, 0);
ctx.args = {timed: date, direction: 'in'};
await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options);
date.setHours(16, 0, 0);
ctx.args = {timed: date, direction: 'out'};
await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options);
try {
date = weekDay(date, tuesday);
date.setHours(1, 1, 0);
ctx.args = {timed: date, direction: 'in'};
await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options);
await tx.rollback();
} catch (e) {
await tx.rollback();
error = e;
}
expect(error).not.toBeDefined;
});
});
describe('as short break', () => {
it('should return error when not fulfilled 36H week break', async() => {
activeCtx.accessToken.userId = salesBossId;
const workerId = hankPymId;
let date = new Date();
date.setMonth(date.getMonth() - 2);
date.setDate(1);
let error;
const tx = await models.WorkerTimeControl.beginTransaction({});
const options = {transaction: tx};
await populateWeek(date, monday, sunday, ctx, workerId, options);
date = nextWeek(date);
await populateWeek(date, monday, thursday, ctx, workerId, options);
date = weekDay(date, friday);
date.setHours(6, 59, 0);
ctx.args = {timed: date, direction: 'in'};
await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options);
try {
date.setHours(7, 1, 0);
ctx.args = {timed: date, direction: 'out'};
await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options);
await tx.rollback();
} catch (e) {
await tx.rollback();
error = e;
}
expect(error.message).toBe(`Descanso semanal 36h. / 72h.`);
});
it('should return error when not fulfilled 36H week break again', async() => {
activeCtx.accessToken.userId = salesBossId;
const workerId = hankPymId;
let date = new Date();
date.setMonth(date.getMonth() - 2);
date.setDate(1);
let error;
const tx = await models.WorkerTimeControl.beginTransaction({});
const options = {transaction: tx};
await populateWeek(date, monday, sunday, ctx, workerId, options);
date = nextWeek(date);
await populateWeek(date, monday, thursday, ctx, workerId, options);
try {
date = weekDay(date, saturday);
date.setHours(3, 59, 0);
ctx.args = {timed: date, direction: 'in'};
await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options);
await tx.rollback();
} catch (e) {
await tx.rollback();
error = e;
}
expect(error.message).toBe(`Descanso semanal 36h. / 72h.`);
});
});
describe('as long break', () => {
it('should return error when not fulfilled 72H week break', async() => {
activeCtx.accessToken.userId = salesBossId;
const workerId = hankPymId;
let date = new Date();
date.setMonth(date.getMonth() - 2);
date.setDate(1);
let error;
const tx = await models.WorkerTimeControl.beginTransaction({});
const options = {transaction: tx};
await populateWeek(date, monday, sunday, ctx, workerId, options);
date = nextWeek(date);
await populateWeek(date, monday, thursday, ctx, workerId, options);
date = nextWeek(date);
await populateWeek(date, monday, friday, ctx, workerId, options);
date = nextWeek(date);
await populateWeek(date, monday, saturday, ctx, workerId, options);
date = nextWeek(date);
await populateWeek(date, monday, saturday, ctx, workerId, options);
date = lastWeek(date);
try {
date = weekDay(date, sunday);
date.setHours(8, 0, 0);
ctx.args = {timed: date, direction: 'in'};
await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options);
await tx.rollback();
} catch (e) {
await tx.rollback();
error = e;
}
expect(error.message).toBe(`Descanso semanal 36h. / 72h.`);
});
});
}); });
}); });
function weekDay(date, dayToSet) {
const currentDay = date.getDay();
const distance = dayToSet - currentDay;
date.setDate(date.getDate() + distance);
return date;
}
function nextWeek(date) {
const sunday = 7;
const currentDay = date.getDay();
let newDate = date;
if (currentDay != 0)
newDate = weekDay(date, sunday);
newDate.setDate(newDate.getDate() + 1);
return newDate;
}
function lastWeek(date) {
const monday = 1;
newDate = weekDay(date, monday);
newDate.setDate(newDate.getDate() - 1);
return newDate;
}
async function populateWeek(date, dayStart, dayEnd, ctx, workerId, options) {
const dateStart = new Date(weekDay(date, dayStart));
const dateEnd = new Date(dateStart);
dateEnd.setDate(dateStart.getDate() + dayEnd);
for (let i = dayStart; i <= dayEnd; i++) {
dateStart.setHours(8, 0, 0);
ctx.args = {timed: dateStart, direction: 'in'};
await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options);
dateStart.setHours(16, 0, 0);
ctx.args = {timed: dateStart, direction: 'out'};
await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options);
dateStart.setDate(dateStart.getDate() + 1);
}
}