salix/modules/worker/back/methods/worker/holidays.js

177 lines
5.4 KiB
JavaScript

const UserError = require('vn-loopback/util/user-error');
module.exports = Self => {
Self.remoteMethodCtx('holidays', {
description: 'Returns the holidays available whitin a contract or a year',
accepts: [{
arg: 'id',
type: 'number',
required: true,
description: 'The worker id',
http: {source: 'path'}
},
{
arg: 'year',
type: 'date',
required: true,
},
{
arg: 'businessFk',
type: 'number',
required: false
}],
returns: [{
type: 'object',
root: true
}],
http: {
path: `/:id/holidays`,
verb: 'GET'
}
});
Self.holidays = async(ctx, id, options) => {
const models = Self.app.models;
const args = ctx.args;
let myOptions = {};
if (typeof options == 'object')
Object.assign(myOptions, options);
const isSubordinate = await models.Worker.isSubordinate(ctx, id, myOptions);
if (!isSubordinate)
throw new UserError(`You don't have enough privileges`);
const started = new Date();
started.setFullYear(args.year);
started.setMonth(0);
started.setDate(1);
started.setHours(0, 0, 0, 0);
const ended = new Date();
ended.setFullYear(args.year);
ended.setMonth(12);
ended.setDate(0);
ended.setHours(23, 59, 59, 59);
const filter = {
include: [{
relation: 'holidays',
scope: {
where: {year: args.year}
}
},
{
relation: 'absences',
scope: {
include: {
relation: 'absenceType',
},
where: {
dated: {between: [started, ended]}
}
}
},
{
relation: 'workCenter',
scope: {
include: {
relation: 'holidays',
scope: {
include: [{
relation: 'detail'
},
{
relation: 'type'
}],
where: {
dated: {between: [started, ended]}
}
}
}
}
}],
where: {
and: [
{workerFk: id},
{
or: [
{started: {between: [started, ended]}},
{ended: {between: [started, ended]}},
{and: [{started: {lt: started}}, {ended: {gt: ended}}]},
{and: [{started: {lt: started}}, {ended: null}]}
]
}
],
}
};
if (args.businessFk)
filter.where.and.push({businessFk: args.businessFk});
const contracts = await models.WorkerLabour.find(filter, myOptions);
let totalHolidays = 0;
let holidaysEnjoyed = 0;
for (let contract of contracts) {
const contractStarted = contract.started;
contractStarted.setHours(0, 0, 0, 0);
const contractEnded = contract.ended;
if (contractEnded)
contractEnded.setHours(23, 59, 59, 59);
let startedTime;
if (contractStarted < started)
startedTime = started.getTime();
else startedTime = contractStarted.getTime();
let endedTime;
if (!contractEnded || (contractEnded && contractEnded > ended))
endedTime = ended.getTime();
else endedTime = contractEnded.getTime();
const dayTimestamp = 1000 * 60 * 60 * 24;
// Get number of worked days between dates
let workedDays = Math.floor((endedTime - startedTime) / dayTimestamp);
workedDays += 1; // 1 day inclusion
// Calculates absences
let entitlementRate = 0;
for (let absence of contract.absences()) {
const absenceType = absence.absenceType();
const isHoliday = absenceType.code === 'holiday';
const isHalfHoliday = absenceType.code === 'halfHoliday';
if (isHoliday) holidaysEnjoyed += 1;
if (isHalfHoliday) holidaysEnjoyed += 0.5;
entitlementRate += absenceType.holidayEntitlementRate;
}
workedDays -= entitlementRate;
// Max holidays for the selected year
const maxHolidays = contract.holidays() && contract.holidays().days;
if (workedDays < daysInYear())
totalHolidays += Math.round(2 * maxHolidays * (workedDays) / daysInYear()) / 2;
else totalHolidays = maxHolidays;
}
function daysInYear() {
const year = started.getFullYear();
return isLeapYear(year) ? 366 : 365;
}
return {totalHolidays, holidaysEnjoyed};
};
function isLeapYear(year) {
return year % 400 === 0 || (year % 100 !== 0 && year % 4 === 0);
}
};