Merge pull request 'feat: refs #6235 Added device in clockIn' (!1977) from 6235-addDeviceWorkerTimeControl into dev

Reviewed-on: #1977
This commit is contained in:
Guillermo Bonet 2024-02-01 06:45:33 +00:00
commit 50b7f4350e
12 changed files with 48 additions and 47 deletions

View File

@ -2,21 +2,23 @@ DELIMITER $$
CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`workerTimeControl_clockIn`(
vWorkerFk INT,
vTimed DATETIME,
vDirection VARCHAR(10)
vDirection VARCHAR(10),
vDevice VARCHAR(255)
)
BEGIN
/**
* Verifica si el empleado puede fichar
* @param vWorkerFk Identificador del trabajador
* @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')
* @return Si todo es correcto, retorna el número de id la tabla workerTimeControl.
* Si hay algún problema, devuelve el mesaje 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
*/
* Verifica si el empleado puede fichar
* @param vWorkerFk Identificador del trabajador
* @param vTimed Balor 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 vDevice Dispositivo en el que se ha fichado
* @return Si todo es correcto, retorna el número de id la tabla workerTimeControl.
* Si hay algún problema, devuelve el mesaje 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 vLastOut DATETIME;
DECLARE vNextIn DATETIME;
@ -269,16 +271,16 @@ BEGIN
GROUP BY breakCounter
HAVING hasError
LIMIT 1;
IF vIsError THEN
SET vErrorCode = 'BREAK_WEEK';
CALL util.throw(vErrorCode);
END IF;
END IF;
-- SE PERMITE FICHAR
INSERT INTO workerTimeControl(userFk, timed, direction, `manual`)
VALUES(vWorkerFk, vTimed, vDirection, vIsManual);
-- Se permite fichar
INSERT INTO workerTimeControl(userFk, timed, direction, device, `manual`)
VALUES(vWorkerFk, vTimed, vDirection, vDevice, vIsManual);
SELECT LAST_INSERT_ID() id;

View File

@ -0,0 +1 @@
ALTER TABLE vn.workerTimeControl ADD device varchar(255) DEFAULT NULL NULL COMMENT 'Dispositivo en el que se ha fichado' AFTER `order`;

View File

@ -0,0 +1 @@
ALTER TABLE vn.workerTimeControl CHANGE direction direction enum('in','out','middle') CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_ci DEFAULT 'middle' NULL AFTER timed;

View File

@ -333,7 +333,7 @@
"It was not able to remove the next expeditions:": "No se pudo eliminar las siguientes expediciones: {{expeditions}}",
"This claim has been updated": "La reclamación con Id: {{claimId}}, ha sido actualizada",
"This user does not have an assigned tablet": "Este usuario no tiene tablet asignada",
"Incorrect pin": "Pin incorrecto.",
"Incorrect pin": "Pin incorrecto",
"You already have the mailAlias": "Ya tienes este alias de correo",
"The alias cant be modified": "Este alias de correo no puede ser modificado",
"No tickets to invoice": "No hay tickets para facturar"

View File

@ -1,6 +1,6 @@
import './index';
fdescribe('component vnRoleCard', () => {
describe('component vnRoleCard', () => {
let controller;
let $httpBackend;

View File

@ -1,6 +1,6 @@
import './index';
fdescribe('component vnRoleDescriptor', () => {
describe('component vnRoleDescriptor', () => {
let controller;
let $httpBackend;

View File

@ -46,6 +46,6 @@ module.exports = Self => {
if (!isSubordinate || (isHimself && !isTeamBoss))
throw new UserError(`You don't have enough privileges`);
return Self.clockIn(workerId, args.timed, args.direction, myOptions);
return Self.clockIn(workerId, args.timed, args.direction, null, myOptions);
};
};

View File

@ -18,7 +18,10 @@ module.exports = Self => {
arg: 'direction',
type: 'string'
},
{
arg: 'device',
type: 'string'
},
],
http: {
path: `/clockIn`,
@ -30,13 +33,19 @@ module.exports = Self => {
}
});
Self.clockIn = async(workerFk, timed, direction, options) => {
Self.clockIn = async(workerFk, timed, direction, device, options) => {
const myOptions = {};
if (typeof options == 'object')
Object.assign(myOptions, options);
const query = 'CALL vn.workerTimeControl_clockIn(?, ?, ?)';
const [[response]] = await Self.rawSql(query, [workerFk, timed, direction], myOptions);
const query = 'CALL vn.workerTimeControl_clockIn(?, ?, ?, ?)';
const [[response]] = await Self.rawSql(query, [
workerFk,
timed,
direction,
(device || null)],
myOptions);
if (response && response.error)
throw new UserError(response.error);

View File

@ -1,7 +1,7 @@
const UserError = require('vn-loopback/util/user-error');
module.exports = Self => {
Self.remoteMethodCtx('login', {
Self.remoteMethod('login', {
description: 'Consult the user\'s information and the buttons that must be activated after logging in',
accessType: 'READ',
accepts: [
@ -21,15 +21,14 @@ module.exports = Self => {
}
});
Self.login = async(ctx, pin, options) => {
Self.login = async(pin, options) => {
const myOptions = {};
const $t = ctx.req.__;
if (typeof options == 'object')
Object.assign(myOptions, options);
const query = `CALL vn.workerTimeControl_login(?)`;
const [[user]] = await Self.rawSql(query, [pin], myOptions);
if (!user) throw new UserError($t('Incorrect pin'));
if (!user) throw new UserError('Incorrect pin');
return user;
};
};

View File

@ -30,7 +30,7 @@ describe('workerTimeControl clockIn()', () => {
try {
const options = {transaction: tx};
await models.WorkerTimeControl.clockIn(workerId, inTime, 'in', options);
await models.WorkerTimeControl.clockIn(workerId, inTime, 'in', 'test', options);
const isClockIn = await models.WorkerTimeControl.findOne({
where: {
userFk: workerId

View File

@ -3,29 +3,15 @@ const LoopBackContext = require('loopback-context');
const UserError = require('vn-loopback/util/user-error');
describe('workerTimeControl login()', () => {
let ctx;
beforeAll(async() => {
ctx = {
accessToken: {userId: 9},
req: {
headers: {origin: 'http://localhost'},
__: key => key
}
};
spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({
active: ctx
});
});
it('should correctly login', async() => {
const response = await models.WorkerTimeControl.login(ctx, 9);
const response = await models.WorkerTimeControl.login(9);
expect(response.name).toBe('developer');
});
it('should throw UserError if pin is not provided', async() => {
try {
await models.WorkerTimeControl.login(ctx);
await models.WorkerTimeControl.login();
} catch (error) {
expect(error).toBeInstanceOf(UserError);
expect(error.message).toBe('Incorrect pin');

View File

@ -14,13 +14,16 @@
"timed": {
"type": "date"
},
"direction": {
"type": "string"
},
"manual": {
"type": "boolean"
},
"order": {
"type": "number"
},
"direction": {
"device": {
"type": "string"
},
"isSendMail": {