#6878 hotfix add manual time entries #2073
|
@ -75,7 +75,7 @@ BEGIN
|
|||
|
||||
SET vDated = DATE(vTimed);
|
||||
|
||||
SELECT IF(pc.name = 'Conductor +3500kg',
|
||||
SELECT IF(pc.code = 'driverCE',
|
||||
wc.dayBreakDriver,
|
||||
wc.dayBreak),
|
||||
wc.shortWeekBreak,
|
||||
|
|
|
@ -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';
|
|
@ -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,21 @@ 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();
|
||||
|
||||
expect(createdTimeEntry.id).toBeDefined();
|
||||
|
||||
ctx.args = {direction: 'out'};
|
||||
const updatedTimeEntry = await models.WorkerTimeControl.updateTimeEntry(
|
||||
ctx, createdTimeEntry.id, options
|
||||
const todayAtTwo = Date.vnNew();
|
||||
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();
|
||||
|
|
|
@ -26,32 +26,40 @@ 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);
|
||||
|
||||
await models.WorkerTimeControl.resendWeeklyHourEmail(ctx, targetTimeEntry.userFk, targetTimeEntry.timed, myOptions);
|
||||
const timeEntryUpdatedId = await Self.clockIn(userFk, timed, direction, null, myOptions);
|
||||
|
||||
return timeEntryUpdated;
|
||||
await models.WorkerTimeControl.resendWeeklyHourEmail(ctx, userFk, timed, myOptions);
|
||||
|
||||
if (tx) await tx.commit();
|
||||
return timeEntryUpdatedId;
|
||||
} catch (e) {
|
||||
if (tx) await tx.rollback();
|
||||
throw e;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
|
|
@ -415,11 +415,14 @@ 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));
|
||||
}
|
||||
|
|
|
@ -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: () => {}
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue