2022-06-23 12:07:53 +00:00
|
|
|
/* eslint max-len: ["error", { "code": 150 }]*/
|
|
|
|
const models = require('vn-loopback/server/server').models;
|
2020-10-08 14:00:19 +00:00
|
|
|
const LoopBackContext = require('loopback-context');
|
|
|
|
|
2021-02-02 09:12:37 +00:00
|
|
|
describe('workerTimeControl add/delete timeEntry()', () => {
|
2020-10-08 14:00:19 +00:00
|
|
|
const employeeId = 1;
|
2021-02-02 09:07:13 +00:00
|
|
|
const salesBossId = 19;
|
2022-06-23 12:07:53 +00:00
|
|
|
const hankPymId = 1107;
|
|
|
|
const monday = 1;
|
2022-04-05 05:46:49 +00:00
|
|
|
const activeCtx = {
|
2020-10-08 14:00:19 +00:00
|
|
|
accessToken: {userId: 50},
|
|
|
|
};
|
2022-04-05 05:46:49 +00:00
|
|
|
const ctx = {req: activeCtx};
|
2022-04-01 11:55:45 +00:00
|
|
|
|
2020-10-08 14:00:19 +00:00
|
|
|
beforeAll(() => {
|
|
|
|
spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({
|
|
|
|
active: activeCtx
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2022-06-23 12:07:53 +00:00
|
|
|
describe('as Role errors', () => {
|
|
|
|
it('should fail to add a time entry if the target user is not a subordinate', async() => {
|
|
|
|
activeCtx.accessToken.userId = employeeId;
|
|
|
|
const workerId = 2;
|
2021-06-17 13:09:04 +00:00
|
|
|
|
2022-06-23 12:07:53 +00:00
|
|
|
let error;
|
2019-11-18 10:00:09 +00:00
|
|
|
|
2022-06-23 12:07:53 +00:00
|
|
|
try {
|
2023-01-16 14:18:24 +00:00
|
|
|
ctx.args = {timed: Date.vnNew(), direction: 'in'};
|
2022-06-23 12:07:53 +00:00
|
|
|
await models.WorkerTimeControl.addTimeEntry(ctx, workerId);
|
|
|
|
} catch (e) {
|
|
|
|
error = e;
|
|
|
|
}
|
2019-11-18 10:00:09 +00:00
|
|
|
|
2022-06-23 12:07:53 +00:00
|
|
|
expect(error).toBeDefined();
|
|
|
|
expect(error.statusCode).toBe(400);
|
|
|
|
expect(error.message).toBe(`You don't have enough privileges`);
|
|
|
|
});
|
2019-11-18 10:00:09 +00:00
|
|
|
|
2022-06-23 12:07:53 +00:00
|
|
|
it('should fail to add if the current and the target user are the same and is not team boss', async() => {
|
|
|
|
activeCtx.accessToken.userId = employeeId;
|
|
|
|
const workerId = employeeId;
|
|
|
|
let error;
|
|
|
|
|
|
|
|
try {
|
2023-01-16 14:18:24 +00:00
|
|
|
ctx.args = {timed: Date.vnNew(), direction: 'in'};
|
2022-06-23 12:07:53 +00:00
|
|
|
await models.WorkerTimeControl.addTimeEntry(ctx, workerId);
|
|
|
|
} catch (e) {
|
|
|
|
error = e;
|
|
|
|
}
|
|
|
|
|
|
|
|
expect(error).toBeDefined();
|
|
|
|
expect(error.statusCode).toBe(400);
|
|
|
|
expect(error.message).toBe(`You don't have enough privileges`);
|
|
|
|
});
|
2021-06-17 13:09:04 +00:00
|
|
|
});
|
|
|
|
|
2022-06-28 10:10:37 +00:00
|
|
|
describe('WorkerTimeControl_clockIn calls', () => {
|
2023-12-22 09:44:21 +00:00
|
|
|
beforeEach(() => activeCtx.accessToken.userId = salesBossId);
|
2022-06-23 12:07:53 +00:00
|
|
|
|
2023-10-23 12:51:09 +00:00
|
|
|
describe('WorkerTimeControl_calculate calls', () => {
|
|
|
|
let dated = Date.vnNew();
|
|
|
|
dated.setDate(dated.getDate() - 7);
|
|
|
|
dated = new Date(weekDay(dated, monday));
|
|
|
|
const end = new Date(dated);
|
|
|
|
end.setDate(end.getDate() + 1);
|
|
|
|
|
|
|
|
it(`should return today's worked 8 hours without break`, async() => {
|
|
|
|
const tx = await models.WorkerTimeControl.beginTransaction({});
|
|
|
|
const options = {transaction: tx};
|
|
|
|
|
|
|
|
try {
|
|
|
|
await populateWeek(dated, monday, monday, ctx, hankPymId, options);
|
|
|
|
const start = new Date(dated - 1);
|
|
|
|
start.setHours(0, 0, 0);
|
|
|
|
await models.WorkerTimeControl.rawSql('CALL vn.timeControl_calculateByUser(?, ?, ?)', [
|
|
|
|
hankPymId,
|
|
|
|
start,
|
|
|
|
end
|
|
|
|
], options);
|
|
|
|
|
|
|
|
let [timeControlCalculateTable] = await models.WorkerTimeControl.rawSql('SELECT * FROM tmp.timeControlCalculate', null, options);
|
|
|
|
|
|
|
|
expect(timeControlCalculateTable.timeWorkSeconds).toEqual(28800);
|
|
|
|
await tx.rollback();
|
|
|
|
} catch (e) {
|
|
|
|
await tx.rollback();
|
|
|
|
throw e;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
it(`should return today's worked hours with 15min break and work time consecutive less than 5h`, async() => {
|
|
|
|
const tx = await models.WorkerTimeControl.beginTransaction({});
|
|
|
|
const options = {transaction: tx};
|
|
|
|
|
|
|
|
try {
|
|
|
|
await populateWeek(dated, monday, monday, ctx, hankPymId, options);
|
|
|
|
dated.setHours(14, 59, 0);
|
|
|
|
await addTimeEntry(ctx, dated, 'middle', hankPymId, options);
|
|
|
|
dated.setHours(15, 14, 0);
|
|
|
|
await addTimeEntry(ctx, dated, 'middle', hankPymId, options);
|
|
|
|
|
|
|
|
const start = new Date(dated - 1);
|
|
|
|
start.setHours(0, 0, 0);
|
|
|
|
await models.WorkerTimeControl.rawSql('CALL vn.timeControl_calculateByUser(?, ?, ?)', [
|
|
|
|
hankPymId,
|
|
|
|
start,
|
|
|
|
end
|
|
|
|
], options);
|
|
|
|
|
|
|
|
let [timeControlCalculateTable] = await models.WorkerTimeControl.rawSql('SELECT * FROM tmp.timeControlCalculate', null, options);
|
|
|
|
|
|
|
|
expect(timeControlCalculateTable.timeWorkSeconds).toEqual(28800);
|
|
|
|
await tx.rollback();
|
|
|
|
} catch (e) {
|
|
|
|
await tx.rollback();
|
|
|
|
throw e;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
it(`should return today's worked hours with 15min break and work time consecutive greater than 5h`, async() => {
|
|
|
|
const tx = await models.WorkerTimeControl.beginTransaction({});
|
|
|
|
const options = {transaction: tx};
|
|
|
|
|
|
|
|
try {
|
|
|
|
await populateWeek(dated, monday, monday, ctx, hankPymId, options);
|
|
|
|
dated.setHours(15, 0, 0);
|
|
|
|
await addTimeEntry(ctx, dated, 'middle', hankPymId, options);
|
|
|
|
dated.setHours(15, 15, 0);
|
|
|
|
await addTimeEntry(ctx, dated, 'middle', hankPymId, options);
|
|
|
|
|
|
|
|
const start = new Date(dated - 1);
|
|
|
|
start.setHours(0, 0, 0);
|
|
|
|
await models.WorkerTimeControl.rawSql('CALL vn.timeControl_calculateByUser(?, ?, ?)', [
|
|
|
|
hankPymId,
|
|
|
|
start,
|
|
|
|
end
|
|
|
|
], options);
|
|
|
|
|
|
|
|
let [timeControlCalculateTable] = await models.WorkerTimeControl.rawSql('SELECT * FROM tmp.timeControlCalculate', null, options);
|
|
|
|
|
|
|
|
expect(timeControlCalculateTable.timeWorkSeconds).toEqual(28800);
|
|
|
|
await tx.rollback();
|
|
|
|
} catch (e) {
|
|
|
|
await tx.rollback();
|
|
|
|
throw e;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
it(`should return today's worked hours with 25min break and work time consecutive less than 5h`, async() => {
|
|
|
|
const tx = await models.WorkerTimeControl.beginTransaction({});
|
|
|
|
const options = {transaction: tx};
|
|
|
|
|
|
|
|
try {
|
|
|
|
await populateWeek(dated, monday, monday, ctx, hankPymId, options);
|
|
|
|
dated.setHours(14, 59, 0);
|
|
|
|
await addTimeEntry(ctx, dated, 'middle', hankPymId, options);
|
|
|
|
dated.setHours(15, 24, 0);
|
|
|
|
await addTimeEntry(ctx, dated, 'middle', hankPymId, options);
|
|
|
|
|
|
|
|
const start = new Date(dated - 1);
|
|
|
|
start.setHours(0, 0, 0);
|
|
|
|
await models.WorkerTimeControl.rawSql('CALL vn.timeControl_calculateByUser(?, ?, ?)', [
|
|
|
|
hankPymId,
|
|
|
|
start,
|
|
|
|
end
|
|
|
|
], options);
|
|
|
|
|
|
|
|
let [timeControlCalculateTable] = await models.WorkerTimeControl.rawSql('SELECT * FROM tmp.timeControlCalculate', null, options);
|
|
|
|
|
|
|
|
expect(timeControlCalculateTable.timeWorkSeconds).toEqual(28500);
|
|
|
|
await tx.rollback();
|
|
|
|
} catch (e) {
|
|
|
|
await tx.rollback();
|
|
|
|
throw e;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
it(`should return today's worked hours with 25min break and work time consecutive greater than 5h`, async() => {
|
|
|
|
const tx = await models.WorkerTimeControl.beginTransaction({});
|
|
|
|
const options = {transaction: tx};
|
|
|
|
|
|
|
|
try {
|
|
|
|
await populateWeek(dated, monday, monday, ctx, hankPymId, options);
|
|
|
|
dated.setHours(15, 0, 0);
|
|
|
|
await addTimeEntry(ctx, dated, 'middle', hankPymId, options);
|
|
|
|
dated.setHours(15, 25, 0);
|
|
|
|
await addTimeEntry(ctx, dated, 'middle', hankPymId, options);
|
|
|
|
|
|
|
|
const start = new Date(dated - 1);
|
|
|
|
start.setHours(0, 0, 0);
|
|
|
|
await models.WorkerTimeControl.rawSql('CALL vn.timeControl_calculateByUser(?, ?, ?)', [
|
|
|
|
hankPymId,
|
|
|
|
start,
|
|
|
|
end
|
|
|
|
], options);
|
|
|
|
|
|
|
|
let [timeControlCalculateTable] = await models.WorkerTimeControl.rawSql('SELECT * FROM tmp.timeControlCalculate', null, options);
|
|
|
|
|
|
|
|
expect(timeControlCalculateTable.timeWorkSeconds).toEqual(28500);
|
|
|
|
await tx.rollback();
|
|
|
|
} catch (e) {
|
|
|
|
await tx.rollback();
|
|
|
|
throw e;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
it(`should return today's worked hours with 60min break and work time consecutive less than 5h`, async() => {
|
|
|
|
const tx = await models.WorkerTimeControl.beginTransaction({});
|
|
|
|
const options = {transaction: tx};
|
|
|
|
|
|
|
|
try {
|
|
|
|
await populateWeek(dated, monday, monday, ctx, hankPymId, options);
|
|
|
|
dated.setHours(14, 59, 0);
|
|
|
|
await addTimeEntry(ctx, dated, 'middle', hankPymId, options);
|
|
|
|
dated.setHours(15, 59, 0);
|
|
|
|
await addTimeEntry(ctx, dated, 'middle', hankPymId, options);
|
|
|
|
|
|
|
|
const start = new Date(dated - 1);
|
|
|
|
start.setHours(0, 0, 0);
|
|
|
|
await models.WorkerTimeControl.rawSql('CALL vn.timeControl_calculateByUser(?, ?, ?)', [
|
|
|
|
hankPymId,
|
|
|
|
start,
|
|
|
|
end
|
|
|
|
], options);
|
|
|
|
|
|
|
|
let [timeControlCalculateTable] = await models.WorkerTimeControl.rawSql('SELECT * FROM tmp.timeControlCalculate', null, options);
|
|
|
|
|
|
|
|
expect(timeControlCalculateTable.timeWorkSeconds).toEqual(25200);
|
|
|
|
await tx.rollback();
|
|
|
|
} catch (e) {
|
|
|
|
await tx.rollback();
|
|
|
|
throw e;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
it(`should return today's worked hours with 60min break and work time consecutive greater than 5h`, async() => {
|
|
|
|
const tx = await models.WorkerTimeControl.beginTransaction({});
|
|
|
|
const options = {transaction: tx};
|
|
|
|
|
|
|
|
try {
|
|
|
|
await populateWeek(dated, monday, monday, ctx, hankPymId, options);
|
|
|
|
dated.setHours(15, 0, 0);
|
|
|
|
await addTimeEntry(ctx, dated, 'middle', hankPymId, options);
|
|
|
|
dated.setHours(16, 0, 0);
|
|
|
|
await addTimeEntry(ctx, dated, 'middle', hankPymId, options);
|
|
|
|
|
|
|
|
const start = new Date(dated - 1);
|
|
|
|
start.setHours(0, 0, 0);
|
|
|
|
await models.WorkerTimeControl.rawSql('CALL vn.timeControl_calculateByUser(?, ?, ?)', [
|
|
|
|
hankPymId,
|
|
|
|
start,
|
|
|
|
end
|
|
|
|
], options);
|
|
|
|
|
|
|
|
let [timeControlCalculateTable] = await models.WorkerTimeControl.rawSql('SELECT * FROM tmp.timeControlCalculate', null, options);
|
|
|
|
|
|
|
|
expect(timeControlCalculateTable.timeWorkSeconds).toEqual(26400);
|
|
|
|
await tx.rollback();
|
|
|
|
} catch (e) {
|
|
|
|
await tx.rollback();
|
|
|
|
throw e;
|
|
|
|
}
|
2022-06-23 12:07:53 +00:00
|
|
|
});
|
|
|
|
});
|
2019-11-18 10:00:09 +00:00
|
|
|
});
|
|
|
|
});
|
2022-06-23 12:07:53 +00:00
|
|
|
|
2023-10-23 12:51:09 +00:00
|
|
|
async function addTimeEntry(ctx, dated, direction, userId, option) {
|
|
|
|
ctx.args = {timed: dated, direction};
|
|
|
|
await models.WorkerTimeControl.addTimeEntry(ctx, userId, option);
|
|
|
|
}
|
|
|
|
|
2022-06-23 12:07:53 +00:00
|
|
|
function weekDay(date, dayToSet) {
|
|
|
|
const currentDay = date.getDay();
|
|
|
|
const distance = dayToSet - currentDay;
|
|
|
|
|
|
|
|
date.setDate(date.getDate() + distance);
|
|
|
|
return date;
|
|
|
|
}
|
|
|
|
|
|
|
|
async function populateWeek(date, dayStart, dayEnd, ctx, workerId, options) {
|
|
|
|
const dateStart = new Date(weekDay(date, dayStart));
|
|
|
|
const dateEnd = new Date(dateStart);
|
|
|
|
dateEnd.setDate(dateStart.getDate() + dayEnd);
|
|
|
|
|
|
|
|
for (let i = dayStart; i <= dayEnd; i++) {
|
2023-10-23 12:51:09 +00:00
|
|
|
dateStart.setHours(10, 0, 0);
|
2022-06-23 12:07:53 +00:00
|
|
|
ctx.args = {timed: dateStart, direction: 'in'};
|
|
|
|
await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options);
|
2023-10-23 12:51:09 +00:00
|
|
|
dateStart.setHours(18, 0, 0);
|
2022-06-23 12:07:53 +00:00
|
|
|
ctx.args = {timed: dateStart, direction: 'out'};
|
|
|
|
await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options);
|
|
|
|
dateStart.setDate(dateStart.getDate() + 1);
|
|
|
|
}
|
|
|
|
}
|