diff --git a/db/routines/vn/procedures/workerTimeControl_clockIn.sql b/db/routines/vn/procedures/workerTimeControl_clockIn.sql index 23739a515..77a628d10 100644 --- a/db/routines/vn/procedures/workerTimeControl_clockIn.sql +++ b/db/routines/vn/procedures/workerTimeControl_clockIn.sql @@ -75,7 +75,7 @@ BEGIN SET vDated = DATE(vTimed); - SELECT IF(pc.name = 'Conductor +3500kg', + SELECT IF(pc.code = 'driveCE', wc.dayBreakDriver, wc.dayBreak), wc.shortWeekBreak, diff --git a/db/versions/10903-pinkIvy/00-professionalCategoryAddCode.sql b/db/versions/10903-pinkIvy/00-professionalCategoryAddCode.sql new file mode 100644 index 000000000..7caa42f32 --- /dev/null +++ b/db/versions/10903-pinkIvy/00-professionalCategoryAddCode.sql @@ -0,0 +1,6 @@ +ALTER TABLE vn.professionalCategory DROP COLUMN IF EXISTS code; +ALTER TABLE IF EXISTS vn.professionalCategory ADD COLUMN code VARCHAR(25) DEFAULT NULL; + +UPDATE vn.professionalCategory + SET code = 'driverCE' + WHERE name = 'Conductor C + E'; \ No newline at end of file diff --git a/modules/worker/back/methods/worker-time-control/specs/clockIn.spec.js b/modules/worker/back/methods/worker-time-control/specs/clockIn.spec.js index ff4cac7b7..0ee439941 100644 --- a/modules/worker/back/methods/worker-time-control/specs/clockIn.spec.js +++ b/modules/worker/back/methods/worker-time-control/specs/clockIn.spec.js @@ -46,6 +46,31 @@ describe('workerTimeControl clockIn()', () => { } }); + it('should throw an error trying to change a middle hour to out not resting 12h', async() => { + activeCtx.accessToken.userId = HHRRId; + const workerId = teamBossId; + + const tx = await models.WorkerTimeControl.beginTransaction({}); + try { + const options = {transaction: tx}; + + const entryTime = "2000-12-25T11:00:00.000Z"; + ctx.args = {timed: entryTime, direction: 'in'}; + await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options); + + const middleTime ="2000-12-26T11:00:00.000Z"; + ctx.args = {timed: middleTime, direction: 'middle'}; + const middleEntryTime = await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options); + + const direction = 'out'; + await models.WorkerTimeControl.updateTimeEntry(ctx, middleEntryTime.id, direction, options); + await tx.rollback(); + } catch (e) { + expect(e.message).toBe('Superado el tiempo máximo entre entrada y salida'); + await tx.rollback(); + } + }); + describe('as Role errors', () => { it('should add if the current user is team boss and the target user is himself', async() => { activeCtx.accessToken.userId = teamBossId; @@ -110,16 +135,22 @@ describe('workerTimeControl clockIn()', () => { todayAtOne.setHours(1, 0, 0, 0); ctx.args = {timed: todayAtOne, direction: 'in'}; - const createdTimeEntry = await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options); + const entryTime = await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options); + expect(entryTime.id).toBeDefined(); + const todayAtTwo = Date.vnNew(); - expect(createdTimeEntry.id).toBeDefined(); - - ctx.args = {direction: 'out'}; - const updatedTimeEntry = await models.WorkerTimeControl.updateTimeEntry( - ctx, createdTimeEntry.id, options + todayAtTwo.setHours(2, 0, 0, 0); + ctx.args = {timed: todayAtTwo, direction: 'middle'}; + const middleTime = await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options); + + const direction = 'out'; + const {id:outTimeEntryId} = await models.WorkerTimeControl.updateTimeEntry( + ctx, middleTime.id, direction, options ); - expect(updatedTimeEntry.direction).toEqual('out'); + const {direction: updatedDirection} = await models.WorkerTimeControl.findById(outTimeEntryId,{fields:['direction']},options); + expect(updatedDirection).toEqual('out'); + await tx.rollback(); } catch (e) { await tx.rollback(); diff --git a/modules/worker/back/methods/worker-time-control/updateTimeEntry.js b/modules/worker/back/methods/worker-time-control/updateTimeEntry.js index e9d35f880..7e4455447 100644 --- a/modules/worker/back/methods/worker-time-control/updateTimeEntry.js +++ b/modules/worker/back/methods/worker-time-control/updateTimeEntry.js @@ -26,32 +26,39 @@ module.exports = Self => { } }); - Self.updateTimeEntry = async(ctx, id, options) => { + Self.updateTimeEntry = async(ctx, timeEntryId, direction, options) => { const currentUserId = ctx.req.accessToken.userId; const models = Self.app.models; - const args = ctx.args; - const myOptions = {}; + let tx; if (typeof options == 'object') Object.assign(myOptions, options); - const targetTimeEntry = await Self.findById(id, null, myOptions); - const isSubordinate = await models.Worker.isSubordinate(ctx, targetTimeEntry.userFk, myOptions); - const isTeamBoss = await models.ACL.checkAccessAcl(ctx, 'Worker', 'isTeamBoss', 'WRITE'); - const isHimself = currentUserId == targetTimeEntry.userFk; + if (!myOptions.transaction) { + tx = await Self.beginTransaction({}); + myOptions.transaction = tx; + } - const notAllowed = isSubordinate === false || (isSubordinate && isHimself && !isTeamBoss); + try { + const {id, userFk, timed} = await Self.findById(timeEntryId, null, myOptions); + const isSubordinate = await models.Worker.isSubordinate(ctx, userFk, myOptions); + const isTeamBoss = await models.ACL.checkAccessAcl(ctx, 'Worker', 'isTeamBoss', 'WRITE'); + const isHimself = currentUserId == userFk; - if (notAllowed) - throw new UserError(`You don't have enough privileges`); + const notAllowed = isSubordinate === false || (isSubordinate && isHimself && !isTeamBoss); + if (notAllowed) throw new UserError(`You don't have enough privileges`); - const timeEntryUpdated = await targetTimeEntry.updateAttributes({ - direction: args.direction - }, myOptions); + await models.WorkerTimeControl.deleteById(id, myOptions); + const timeEntryUpdatedId = await Self.clockIn(userFk, timed, direction, null, myOptions); - await models.WorkerTimeControl.resendWeeklyHourEmail(ctx, targetTimeEntry.userFk, targetTimeEntry.timed, myOptions); + await models.WorkerTimeControl.resendWeeklyHourEmail(ctx, userFk, timed, myOptions); - return timeEntryUpdated; + if (tx) await tx.commit(); + return timeEntryUpdatedId; + } catch (e) { + if (tx) await tx.rollback(); + throw e; + } }; }; diff --git a/modules/worker/front/time-control/index.js b/modules/worker/front/time-control/index.js index f6a6ed535..094e200a4 100644 --- a/modules/worker/front/time-control/index.js +++ b/modules/worker/front/time-control/index.js @@ -415,11 +415,13 @@ class Controller extends Section { throw new Error(`The entry type can't be empty`); const query = `WorkerTimeControls/${entry.id}/updateTimeEntry`; - this.$http.post(query, {direction: entry.direction}) - .then(() => this.vnApp.showSuccess(this.$t('Data saved!'))) - .then(() => this.$.editEntry.hide()) - .then(() => this.fetchHours()) - .then(() => this.getMailStates(this.date)); + if (entry.direction !== entry.$orgRow.direction) { + this.$http.post(query, {direction: entry.direction}) + .then(() => this.vnApp.showSuccess(this.$t('Data saved!'))) + .then(() => this.$.editEntry.hide()) + .then(() => this.fetchHours()) + .then(() => this.getMailStates(this.date)); + } } catch (e) { this.vnApp.showError(this.$t(e.message)); } diff --git a/modules/worker/front/time-control/index.spec.js b/modules/worker/front/time-control/index.spec.js index 10e8aba0d..8610da46e 100644 --- a/modules/worker/front/time-control/index.spec.js +++ b/modules/worker/front/time-control/index.spec.js @@ -130,7 +130,7 @@ describe('Component vnWorkerTimeControl', () => { controller.$.model = {applyFilter: jest.fn().mockReturnValue(Promise.resolve())}; controller.date = today; controller.fetchHours = jest.fn(); - controller.selectedRow = {id: 1, timed: Date.vnNew(), direction: 'in'}; + controller.selectedRow = {id: 1, timed: Date.vnNew(), direction: 'in', $orgRow: {direction: null}}; controller.$.editEntry = { hide: () => {} };