feat: refs #6235 Added device in clockIn #1977
|
@ -2,20 +2,22 @@ DELIMITER $$
|
||||||
CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`workerTimeControl_clockIn`(
|
CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`workerTimeControl_clockIn`(
|
||||||
vWorkerFk INT,
|
vWorkerFk INT,
|
||||||
vTimed DATETIME,
|
vTimed DATETIME,
|
||||||
vDirection VARCHAR(10)
|
vDirection VARCHAR(10),
|
||||||
|
vDevice VARCHAR(255)
|
||||||
)
|
)
|
||||||
BEGIN
|
BEGIN
|
||||||
/**
|
/**
|
||||||
* Verifica si el empleado puede fichar
|
* Verifica si el empleado puede fichar
|
||||||
* @param vWorkerFk Identificador del trabajador
|
* @param vWorkerFk Identificador del trabajador
|
||||||
* @param vTimed valor de la fichada, IF vTimed IS NULL vTimed = NOW
|
* @param vTimed Balor de la fichada, IF vTimed IS NULL vTimed = NOW
|
||||||
* @param vDirection solo se pueden pasa los valores del campo
|
* @param vDirection Solo se pueden pasa los valores del campo
|
||||||
* workerTimeControl.direction ENUM('in', 'out', 'middle')
|
* workerTimeControl.direction ENUM('in', 'out', 'middle')
|
||||||
* @return Si todo es correcto, retorna el número de id la tabla workerTimeControl.
|
* @param vDevice Dispositivo en el que se ha fichado
|
||||||
* Si hay algún problema, devuelve el mesaje que se debe mostrar al usuario
|
* @return Si todo es correcto, retorna el número de id la tabla workerTimeControl.
|
||||||
* Solo retorna el primer problema, en caso de no ocurrir ningún error se añadirá
|
* Si hay algún problema, devuelve el mesaje que se debe mostrar al usuario
|
||||||
* fichada a la tabla vn.workerTimeControl
|
* 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;
|
||||||
|
@ -276,9 +278,9 @@ BEGIN
|
||||||
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, device, `manual`)
|
||||||
VALUES(vWorkerFk, vTimed, vDirection, vIsManual);
|
VALUES(vWorkerFk, vTimed, vDirection, vDevice, vIsManual);
|
||||||
|
|
||||||
SELECT LAST_INSERT_ID() id;
|
SELECT LAST_INSERT_ID() id;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
ALTER TABLE vn.workerTimeControl ADD device varchar(255) DEFAULT NULL NULL COMMENT 'Dispositivo en el que se ha fichado' AFTER `order`;
|
|
@ -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;
|
|
@ -333,7 +333,7 @@
|
||||||
"It was not able to remove the next expeditions:": "No se pudo eliminar las siguientes expediciones: {{expeditions}}",
|
"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 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",
|
"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",
|
"You already have the mailAlias": "Ya tienes este alias de correo",
|
||||||
"The alias cant be modified": "Este alias de correo no puede ser modificado",
|
"The alias cant be modified": "Este alias de correo no puede ser modificado",
|
||||||
"No tickets to invoice": "No hay tickets para facturar"
|
"No tickets to invoice": "No hay tickets para facturar"
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import './index';
|
import './index';
|
||||||
|
|
||||||
fdescribe('component vnRoleCard', () => {
|
describe('component vnRoleCard', () => {
|
||||||
let controller;
|
let controller;
|
||||||
let $httpBackend;
|
let $httpBackend;
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import './index';
|
import './index';
|
||||||
|
|
||||||
fdescribe('component vnRoleDescriptor', () => {
|
describe('component vnRoleDescriptor', () => {
|
||||||
let controller;
|
let controller;
|
||||||
let $httpBackend;
|
let $httpBackend;
|
||||||
|
|
||||||
|
|
|
@ -46,6 +46,6 @@ module.exports = Self => {
|
||||||
if (!isSubordinate || (isHimself && !isTeamBoss))
|
if (!isSubordinate || (isHimself && !isTeamBoss))
|
||||||
throw new UserError(`You don't have enough privileges`);
|
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);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -18,7 +18,10 @@ module.exports = Self => {
|
||||||
arg: 'direction',
|
arg: 'direction',
|
||||||
type: 'string'
|
type: 'string'
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
arg: 'device',
|
||||||
|
type: 'string'
|
||||||
|
},
|
||||||
],
|
],
|
||||||
http: {
|
http: {
|
||||||
path: `/clockIn`,
|
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 = {};
|
const myOptions = {};
|
||||||
if (typeof options == 'object')
|
if (typeof options == 'object')
|
||||||
Object.assign(myOptions, options);
|
Object.assign(myOptions, options);
|
||||||
|
|
||||||
const query = 'CALL vn.workerTimeControl_clockIn(?, ?, ?)';
|
const query = 'CALL vn.workerTimeControl_clockIn(?, ?, ?, ?)';
|
||||||
const [[response]] = await Self.rawSql(query, [workerFk, timed, direction], myOptions);
|
const [[response]] = await Self.rawSql(query, [
|
||||||
|
workerFk,
|
||||||
|
timed,
|
||||||
|
direction,
|
||||||
|
(device || null)],
|
||||||
|
myOptions);
|
||||||
|
|
||||||
if (response && response.error)
|
if (response && response.error)
|
||||||
throw new UserError(response.error);
|
throw new UserError(response.error);
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
const UserError = require('vn-loopback/util/user-error');
|
const UserError = require('vn-loopback/util/user-error');
|
||||||
|
|
||||||
module.exports = Self => {
|
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',
|
description: 'Consult the user\'s information and the buttons that must be activated after logging in',
|
||||||
accessType: 'READ',
|
accessType: 'READ',
|
||||||
accepts: [
|
accepts: [
|
||||||
|
@ -21,15 +21,14 @@ module.exports = Self => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Self.login = async(ctx, pin, options) => {
|
Self.login = async(pin, options) => {
|
||||||
const myOptions = {};
|
const myOptions = {};
|
||||||
const $t = ctx.req.__;
|
|
||||||
if (typeof options == 'object')
|
if (typeof options == 'object')
|
||||||
Object.assign(myOptions, options);
|
Object.assign(myOptions, options);
|
||||||
|
|
||||||
const query = `CALL vn.workerTimeControl_login(?)`;
|
const query = `CALL vn.workerTimeControl_login(?)`;
|
||||||
const [[user]] = await Self.rawSql(query, [pin], myOptions);
|
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;
|
return user;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -30,7 +30,7 @@ describe('workerTimeControl clockIn()', () => {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const options = {transaction: tx};
|
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({
|
const isClockIn = await models.WorkerTimeControl.findOne({
|
||||||
where: {
|
where: {
|
||||||
userFk: workerId
|
userFk: workerId
|
||||||
|
|
|
@ -3,29 +3,15 @@ const LoopBackContext = require('loopback-context');
|
||||||
const UserError = require('vn-loopback/util/user-error');
|
const UserError = require('vn-loopback/util/user-error');
|
||||||
|
|
||||||
describe('workerTimeControl login()', () => {
|
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() => {
|
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');
|
expect(response.name).toBe('developer');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should throw UserError if pin is not provided', async() => {
|
it('should throw UserError if pin is not provided', async() => {
|
||||||
try {
|
try {
|
||||||
await models.WorkerTimeControl.login(ctx);
|
await models.WorkerTimeControl.login();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
expect(error).toBeInstanceOf(UserError);
|
expect(error).toBeInstanceOf(UserError);
|
||||||
expect(error.message).toBe('Incorrect pin');
|
expect(error.message).toBe('Incorrect pin');
|
||||||
|
|
|
@ -14,13 +14,16 @@
|
||||||
"timed": {
|
"timed": {
|
||||||
"type": "date"
|
"type": "date"
|
||||||
},
|
},
|
||||||
|
"direction": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
"manual": {
|
"manual": {
|
||||||
"type": "boolean"
|
"type": "boolean"
|
||||||
},
|
},
|
||||||
"order": {
|
"order": {
|
||||||
"type": "number"
|
"type": "number"
|
||||||
},
|
},
|
||||||
"direction": {
|
"device": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"isSendMail": {
|
"isSendMail": {
|
||||||
|
|
Loading…
Reference in New Issue