156 lines
4.7 KiB
JavaScript
156 lines
4.7 KiB
JavaScript
|
|
||
|
const ParameterizedSQL = require('loopback-connector').ParameterizedSQL;
|
||
|
const UserError = require('vn-loopback/util/user-error');
|
||
|
|
||
|
module.exports = Self => {
|
||
|
Self.remoteMethodCtx('absences', {
|
||
|
description: 'Returns an array of absences from an specified worker',
|
||
|
accessType: '',
|
||
|
accepts: [{
|
||
|
arg: 'workerFk',
|
||
|
type: 'Number',
|
||
|
required: true,
|
||
|
},
|
||
|
{
|
||
|
arg: 'started',
|
||
|
type: 'Date',
|
||
|
required: true,
|
||
|
},
|
||
|
{
|
||
|
arg: 'ended',
|
||
|
type: 'Date',
|
||
|
required: true,
|
||
|
}],
|
||
|
returns: [{
|
||
|
arg: 'calendar'
|
||
|
},
|
||
|
{
|
||
|
arg: 'absences'
|
||
|
},
|
||
|
{
|
||
|
arg: 'holidays'
|
||
|
}],
|
||
|
http: {
|
||
|
path: `/absences`,
|
||
|
verb: 'GET'
|
||
|
}
|
||
|
});
|
||
|
|
||
|
Self.absences = async(ctx, workerFk, started, ended) => {
|
||
|
const models = Self.app.models;
|
||
|
const conn = Self.dataSource.connector;
|
||
|
const myUserId = ctx.req.accessToken.userId;
|
||
|
const myWorker = await models.Worker.findOne({where: {userFk: myUserId}});
|
||
|
const calendar = {totalHolidays: 0, holidaysEnjoyed: 0};
|
||
|
const holidays = [];
|
||
|
const stmts = [];
|
||
|
|
||
|
// Get subordinates
|
||
|
stmts.push(new ParameterizedSQL('CALL vn.subordinateGetList(?)', [myWorker.id]));
|
||
|
let subordinatesIndex = stmts.push('SELECT * FROM tmp.subordinate') - 1;
|
||
|
let sql = ParameterizedSQL.join(stmts, ';');
|
||
|
let result = await conn.executeStmt(sql);
|
||
|
|
||
|
const subordinates = result[subordinatesIndex];
|
||
|
const isSubordinate = subordinates.find(subordinate => {
|
||
|
return subordinate.workerFk === workerFk;
|
||
|
});
|
||
|
const isHr = await models.Account.hasRole(myUserId, 'hr');
|
||
|
|
||
|
if (!isHr && workerFk !== myWorker.id && !isSubordinate)
|
||
|
throw new UserError(`You don't have enough privileges`);
|
||
|
|
||
|
|
||
|
// Get absences of year
|
||
|
let absences = await Self.find({
|
||
|
include: {
|
||
|
relation: 'absenceType'
|
||
|
},
|
||
|
where: {
|
||
|
workerFk: workerFk,
|
||
|
dated: {between: [started, ended]}
|
||
|
}
|
||
|
});
|
||
|
|
||
|
absences.forEach(absence => {
|
||
|
if (absence.absenceType().id === 1)
|
||
|
calendar.holidaysEnjoyed++;
|
||
|
|
||
|
absence.dated = new Date(absence.dated);
|
||
|
absence.dated.setHours(0, 0, 0, 0);
|
||
|
});
|
||
|
|
||
|
// Get active contracts on current year
|
||
|
const year = started.getFullYear();
|
||
|
const contracts = await models.WorkerLabour.find({
|
||
|
include: [{
|
||
|
relation: 'holidays',
|
||
|
scope: {
|
||
|
where: {year}
|
||
|
}
|
||
|
},
|
||
|
{
|
||
|
relation: 'workCenter',
|
||
|
scope: {
|
||
|
include: {
|
||
|
relation: 'holidays',
|
||
|
scope: {
|
||
|
include: [{
|
||
|
relation: 'detail'
|
||
|
},
|
||
|
{
|
||
|
relation: 'type'
|
||
|
}],
|
||
|
where: {
|
||
|
dated: {between: [started, ended]}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}],
|
||
|
where: {
|
||
|
and: [
|
||
|
{workerFk: workerFk},
|
||
|
{or: [{
|
||
|
ended: {gte: [started]}
|
||
|
}, {ended: null}]}
|
||
|
],
|
||
|
|
||
|
}
|
||
|
});
|
||
|
|
||
|
// Get number of total holidays
|
||
|
contracts.forEach(contract => {
|
||
|
let totalHolidays = contract.holidays().days;
|
||
|
|
||
|
if (contract.started && contract.ended)
|
||
|
totalHolidays = getHolidaysByContract(contract);
|
||
|
|
||
|
calendar.totalHolidays += totalHolidays;
|
||
|
|
||
|
|
||
|
let holidayList = contract.workCenter().holidays();
|
||
|
for (let day of holidayList) {
|
||
|
day.dated = new Date(day.dated);
|
||
|
day.dated.setHours(0, 0, 0, 0);
|
||
|
|
||
|
holidays.push(day);
|
||
|
}
|
||
|
});
|
||
|
|
||
|
return [calendar, absences, holidays];
|
||
|
};
|
||
|
|
||
|
function getHolidaysByContract(contract) {
|
||
|
const dayTimestamp = 1000 * 60 * 60 * 24;
|
||
|
const endedTime = contract.ended.getTime();
|
||
|
const startedTime = contract.started.getTime();
|
||
|
const contractDays = Math.floor((endedTime - startedTime) / dayTimestamp);
|
||
|
|
||
|
if (contractDays < 365)
|
||
|
return Math.floor(contract.holidays().days * (contractDays + 1) / 365);
|
||
|
|
||
|
return contract.holidays().days;
|
||
|
}
|
||
|
};
|