Merge pull request '#6878 hotfix fix add manual entries' (!2074) from 6878-hotfix-addManualTimeEntries into master
gitea/salix/pipeline/head This commit looks good
Details
gitea/salix/pipeline/head This commit looks good
Details
Reviewed-on: #2074 Reviewed-by: Carlos Andrés <carlosap@verdnatura.es> Reviewed-by: Alex Moreno <alexm@verdnatura.es>
This commit is contained in:
commit
775764c2a9
|
@ -75,7 +75,7 @@ BEGIN
|
||||||
|
|
||||||
SET vDated = DATE(vTimed);
|
SET vDated = DATE(vTimed);
|
||||||
|
|
||||||
SELECT IF(pc.name = 'Conductor +3500kg',
|
SELECT IF(pc.code = 'driveCE',
|
||||||
wc.dayBreakDriver,
|
wc.dayBreakDriver,
|
||||||
wc.dayBreak),
|
wc.dayBreak),
|
||||||
wc.shortWeekBreak,
|
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', () => {
|
describe('as Role errors', () => {
|
||||||
it('should add if the current user is team boss and the target user is himself', async() => {
|
it('should add if the current user is team boss and the target user is himself', async() => {
|
||||||
activeCtx.accessToken.userId = teamBossId;
|
activeCtx.accessToken.userId = teamBossId;
|
||||||
|
@ -110,16 +135,22 @@ describe('workerTimeControl clockIn()', () => {
|
||||||
todayAtOne.setHours(1, 0, 0, 0);
|
todayAtOne.setHours(1, 0, 0, 0);
|
||||||
|
|
||||||
ctx.args = {timed: todayAtOne, direction: 'in'};
|
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();
|
todayAtTwo.setHours(2, 0, 0, 0);
|
||||||
|
ctx.args = {timed: todayAtTwo, direction: 'middle'};
|
||||||
ctx.args = {direction: 'out'};
|
const middleTime = await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options);
|
||||||
const updatedTimeEntry = await models.WorkerTimeControl.updateTimeEntry(
|
|
||||||
ctx, createdTimeEntry.id, 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();
|
await tx.rollback();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
await tx.rollback();
|
await tx.rollback();
|
||||||
|
|
|
@ -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 currentUserId = ctx.req.accessToken.userId;
|
||||||
const models = Self.app.models;
|
const models = Self.app.models;
|
||||||
const args = ctx.args;
|
|
||||||
|
|
||||||
const myOptions = {};
|
const myOptions = {};
|
||||||
|
let tx;
|
||||||
|
|
||||||
if (typeof options == 'object')
|
if (typeof options == 'object')
|
||||||
Object.assign(myOptions, options);
|
Object.assign(myOptions, options);
|
||||||
|
|
||||||
const targetTimeEntry = await Self.findById(id, null, myOptions);
|
if (!myOptions.transaction) {
|
||||||
const isSubordinate = await models.Worker.isSubordinate(ctx, targetTimeEntry.userFk, myOptions);
|
tx = await Self.beginTransaction({});
|
||||||
const isTeamBoss = await models.ACL.checkAccessAcl(ctx, 'Worker', 'isTeamBoss', 'WRITE');
|
myOptions.transaction = tx;
|
||||||
const isHimself = currentUserId == targetTimeEntry.userFk;
|
}
|
||||||
|
|
||||||
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)
|
const notAllowed = isSubordinate === false || (isSubordinate && isHimself && !isTeamBoss);
|
||||||
throw new UserError(`You don't have enough privileges`);
|
if (notAllowed) throw new UserError(`You don't have enough privileges`);
|
||||||
|
|
||||||
const timeEntryUpdated = await targetTimeEntry.updateAttributes({
|
await models.WorkerTimeControl.deleteById(id, myOptions);
|
||||||
direction: args.direction
|
const timeEntryUpdatedId = await Self.clockIn(userFk, timed, direction, null, myOptions);
|
||||||
}, 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;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -415,11 +415,13 @@ class Controller extends Section {
|
||||||
throw new Error(`The entry type can't be empty`);
|
throw new Error(`The entry type can't be empty`);
|
||||||
|
|
||||||
const query = `WorkerTimeControls/${entry.id}/updateTimeEntry`;
|
const query = `WorkerTimeControls/${entry.id}/updateTimeEntry`;
|
||||||
this.$http.post(query, {direction: entry.direction})
|
if (entry.direction !== entry.$orgRow.direction) {
|
||||||
.then(() => this.vnApp.showSuccess(this.$t('Data saved!')))
|
this.$http.post(query, {direction: entry.direction})
|
||||||
.then(() => this.$.editEntry.hide())
|
.then(() => this.vnApp.showSuccess(this.$t('Data saved!')))
|
||||||
.then(() => this.fetchHours())
|
.then(() => this.$.editEntry.hide())
|
||||||
.then(() => this.getMailStates(this.date));
|
.then(() => this.fetchHours())
|
||||||
|
.then(() => this.getMailStates(this.date));
|
||||||
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
this.vnApp.showError(this.$t(e.message));
|
this.vnApp.showError(this.$t(e.message));
|
||||||
}
|
}
|
||||||
|
|
|
@ -130,7 +130,7 @@ describe('Component vnWorkerTimeControl', () => {
|
||||||
controller.$.model = {applyFilter: jest.fn().mockReturnValue(Promise.resolve())};
|
controller.$.model = {applyFilter: jest.fn().mockReturnValue(Promise.resolve())};
|
||||||
controller.date = today;
|
controller.date = today;
|
||||||
controller.fetchHours = jest.fn();
|
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 = {
|
controller.$.editEntry = {
|
||||||
hide: () => {}
|
hide: () => {}
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue