337 lines
16 KiB
JavaScript
337 lines
16 KiB
JavaScript
|
const ParameterizedSQL = require('loopback-connector').ParameterizedSQL;
|
||
|
|
||
|
module.exports = Self => {
|
||
|
Self.remoteMethodCtx('sendMail', {
|
||
|
description: `Send an email with the hours booked to the employees who telecommuting.
|
||
|
It also inserts booked hours in cases where the employee is telecommuting`,
|
||
|
accessType: 'WRITE',
|
||
|
accepts: [{
|
||
|
arg: 'workerId',
|
||
|
type: 'number',
|
||
|
description: 'The worker id'
|
||
|
},
|
||
|
{
|
||
|
arg: 'week',
|
||
|
type: 'number',
|
||
|
required: true
|
||
|
},
|
||
|
{
|
||
|
arg: 'year',
|
||
|
type: 'number',
|
||
|
required: true
|
||
|
}],
|
||
|
returns: [{
|
||
|
type: 'Object',
|
||
|
root: true
|
||
|
}],
|
||
|
http: {
|
||
|
path: `/sendMail`,
|
||
|
verb: 'POST'
|
||
|
}
|
||
|
});
|
||
|
|
||
|
Self.sendMail = async(ctx, options) => {
|
||
|
const models = Self.app.models;
|
||
|
const args = ctx.args;
|
||
|
const myOptions = {};
|
||
|
const conn = Self.dataSource.connector;
|
||
|
|
||
|
if (typeof options == 'object')
|
||
|
Object.assign(myOptions, options);
|
||
|
|
||
|
const stmts = [];
|
||
|
let stmt;
|
||
|
|
||
|
stmts.push('DROP TEMPORARY TABLE IF EXISTS tmp.timeControlCalculate');
|
||
|
stmts.push('DROP TEMPORARY TABLE IF EXISTS tmp.timeBusinessCalculate');
|
||
|
stmts.push('DROP TEMPORARY TABLE IF EXISTS tmp.timeControlCalculate1');
|
||
|
stmts.push('DROP TEMPORARY TABLE IF EXISTS tmp.timeBusinessCalculate1');
|
||
|
stmts.push('DROP TEMPORARY TABLE IF EXISTS tmp.error');
|
||
|
|
||
|
const today = new Date();
|
||
|
|
||
|
const started = new Date(today.setDate(today.getDate() - today.getDay()));
|
||
|
started.setHours(0, 0, 0, 0);
|
||
|
|
||
|
const ended = new Date(today.setDate(today.getDate() - today.getDay() + 6));
|
||
|
ended.setHours(23, 59, 59, 999);
|
||
|
|
||
|
if (args.workerId) {
|
||
|
await models.WorkerTimeControl.destroyAll({
|
||
|
userFk: args.workerId,
|
||
|
timed: {between: [started, ended]},
|
||
|
isSendMail: true
|
||
|
}, myOptions);
|
||
|
|
||
|
const where = {
|
||
|
workerFk: args.workerId,
|
||
|
year: args.year,
|
||
|
week: args.week
|
||
|
};
|
||
|
await models.WorkerTimeControlMail.updateAll(where, {
|
||
|
updated: new Date(), state: 'SENDED'
|
||
|
}, myOptions);
|
||
|
|
||
|
stmt = new ParameterizedSQL(`CALL vn.timeControl_calculateAll(?, ?)`, [args.workerId, started, ended]);
|
||
|
stmts.push(stmt);
|
||
|
|
||
|
stmt = new ParameterizedSQL(`CALL vn.timeBusiness_calculateAll(?, ?)`, [args.workerId, started, ended]);
|
||
|
stmts.push(stmt);
|
||
|
} else { // args.workerId IS NULL
|
||
|
await models.WorkerTimeControl.destroyAll({
|
||
|
timed: {between: [started, ended]},
|
||
|
isSendMail: true
|
||
|
}, myOptions);
|
||
|
|
||
|
const where = {
|
||
|
year: args.year,
|
||
|
week: args.week
|
||
|
};
|
||
|
await models.WorkerTimeControlMail.updateAll(where, {
|
||
|
updated: new Date(), state: 'SENDED'
|
||
|
}, myOptions);
|
||
|
|
||
|
stmt = new ParameterizedSQL(`CALL vn.timeControl_calculateAll(?, ?)`, [started, ended]);
|
||
|
stmts.push(stmt);
|
||
|
|
||
|
stmt = new ParameterizedSQL(`CALL vn.timeBusiness_calculateAll(?, ?)`, [started, ended]);
|
||
|
stmts.push(stmt);
|
||
|
}
|
||
|
|
||
|
stmts.push(`CREATE TEMPORARY TABLE tmp.timeControlCalculate1
|
||
|
SELECT * FROM tmp.timeControlCalculate`);
|
||
|
|
||
|
stmts.push(`CREATE TEMPORARY TABLE tmp.timeBusinessCalculate1
|
||
|
SELECT * FROM tmp.timeBusinessCalculate`);
|
||
|
|
||
|
const index = stmts.push(`SELECT CONCAT(u.name, '@verdnatura.es'), -- vReceiver
|
||
|
u.id workerFk, -- vWorkerFk
|
||
|
tb.dated, -- vDated
|
||
|
tb.timeWorkDecimal, -- vTimeWorkDecimal
|
||
|
tb.timeWorkSexagesimal timeWorkSexagesimal, -- vTimeWorkSexagesimal
|
||
|
tb.timeTable, -- vTimeTable
|
||
|
tc.timeWorkDecimal timeWorkedDecimal, -- vTimeWorkedDecimal
|
||
|
tc.timeWorkSexagesimal timeWorkedSexagesimal, -- vTimeWorkedSexagesimal
|
||
|
tb.type, -- vAbsenceType
|
||
|
tb.businessFk, -- vBusinessFk
|
||
|
tb.permissionRate, -- vPermissionRate
|
||
|
d.isTeleworking -- vIsTeleworking
|
||
|
FROM tmp.timeBusinessCalculate tb
|
||
|
JOIN user u ON u.id = tb.userFk
|
||
|
JOIN department d ON d.id = tb.departmentFk
|
||
|
JOIN business b ON b.id = tb.businessFk
|
||
|
LEFT JOIN tmp.timeControlCalculate tc ON tc.userFk = tb.userFk AND tc.dated = tb.dated
|
||
|
LEFT JOIN worker w ON w.id = u.id
|
||
|
LEFT JOIN user u2 ON u2.id = w.bossFk
|
||
|
JOIN (SELECT tb.userFk,
|
||
|
SUM(IF(tb.type IS NULL,
|
||
|
IF(tc.timeWorkDecimal > 0, FALSE, IF(tb.timeWorkDecimal > 0, TRUE, FALSE)),
|
||
|
TRUE))isTeleworkingWeek
|
||
|
FROM tmp.timeBusinessCalculate1 tb
|
||
|
LEFT JOIN tmp.timeControlCalculate1 tc ON tc.userFk = tb.userFk AND tc.dated = tb.dated
|
||
|
GROUP BY tb.userFk
|
||
|
HAVING isTeleworkingWeek > 0
|
||
|
)sub ON sub.userFk = u.id
|
||
|
WHERE d.hasToRefill
|
||
|
-- AND IFNULL(vWorkerFk, u.id) = u.id
|
||
|
AND b.companyCodeFk = 'VNL'
|
||
|
AND w.businessFk
|
||
|
ORDER BY u.id, tb.dated`) - 1;
|
||
|
|
||
|
const sql = ParameterizedSQL.join(stmts, ';');
|
||
|
const days = await conn.executeStmt(sql, myOptions);
|
||
|
|
||
|
for (let day of days[index]) {
|
||
|
const weekDay = day.dated.getDay() + 1;
|
||
|
const journeys = await models.Journey.find({
|
||
|
where: {
|
||
|
business_id: day.businessFk,
|
||
|
day_id: weekDay
|
||
|
}
|
||
|
}, myOptions);
|
||
|
console.log('journeys: ', journeys);
|
||
|
|
||
|
for (let journey of journeys) {
|
||
|
// const minStart = journeys.reduce(function(prev, curr) {
|
||
|
// return curr.start < prev.start ? curr : prev;
|
||
|
// });
|
||
|
// if (journey == minStart) {
|
||
|
// const [startHours, startMinutes, startSeconds] = journey.start.split(':');
|
||
|
// await models.WorkerTimeControl.create({
|
||
|
// userFk: day.workerFk,
|
||
|
// timed: day.dated.setHours(startHours, startMinutes, startSeconds),
|
||
|
// manual: true,
|
||
|
// isSendMail: true
|
||
|
// }, myOptions);
|
||
|
|
||
|
// const [hoursWork, minutesWork, secondsWork] = day.timeWorkSexagesimal.split(':');
|
||
|
// await models.WorkerTimeControl.create({
|
||
|
// userFk: day.workerFk,
|
||
|
// timed: day.dated.setHours(
|
||
|
// parseInt(startHours) + parseInt(hoursWork),
|
||
|
// parseInt(startMinutes) + parseInt(minutesWork),
|
||
|
// parseInt(startSeconds) + parseInt(secondsWork)
|
||
|
// ),
|
||
|
// manual: true,
|
||
|
// isSendMail: true
|
||
|
// }, myOptions);
|
||
|
// }
|
||
|
}
|
||
|
|
||
|
if (day.timeWorkDecimal > 0 && day.timeWorkedDecimal == null && (day.permissionRate ? day.permissionRate : true)) {
|
||
|
if (day.timeTable == null) {
|
||
|
await models.WorkerTimeControl.create({
|
||
|
userFk: day.workerFk,
|
||
|
timed: day.dated.setHours(8),
|
||
|
manual: true,
|
||
|
direction: 'in',
|
||
|
isSendMail: true
|
||
|
}, myOptions);
|
||
|
|
||
|
if (day.timeWorkDecimal >= 5) {
|
||
|
await models.WorkerTimeControl.create({
|
||
|
userFk: day.workerFk,
|
||
|
timed: day.dated.setHours(9),
|
||
|
manual: true,
|
||
|
direction: 'middle',
|
||
|
isSendMail: true
|
||
|
}, myOptions);
|
||
|
|
||
|
await models.WorkerTimeControl.create({
|
||
|
userFk: day.workerFk,
|
||
|
timed: day.dated.setHours(9, 20),
|
||
|
manual: true,
|
||
|
direction: 'middle',
|
||
|
isSendMail: true
|
||
|
}, myOptions);
|
||
|
}
|
||
|
|
||
|
const [hoursWork, minutesWork, secondsWork] = day.timeWorkSexagesimal.split(':');
|
||
|
await models.WorkerTimeControl.create({
|
||
|
userFk: day.workerFk,
|
||
|
timed: day.dated.setHours(8 + parseInt(hoursWork), minutesWork, secondsWork),
|
||
|
manual: true,
|
||
|
direction: 'out',
|
||
|
isSendMail: true
|
||
|
}, myOptions);
|
||
|
} else {
|
||
|
const weekDay = day.dated.getDay() + 1;
|
||
|
const journeys = await models.Journey.find({
|
||
|
where: {
|
||
|
business_id: day.businessFk,
|
||
|
day_id: weekDay
|
||
|
}
|
||
|
}, myOptions);
|
||
|
console.log('journeys: ', journeys);
|
||
|
|
||
|
let timeTableDecimalInSeconds = 0;
|
||
|
|
||
|
for (let journey of journeys) {
|
||
|
const start = new Date();
|
||
|
const [startHours, startMinutes, startSeconds] = journey.start.split(':');
|
||
|
start.setHours(startHours, startMinutes, startSeconds);
|
||
|
|
||
|
const end = new Date();
|
||
|
const [endHours, endMinutes, endSeconds] = journey.end.split(':');
|
||
|
end.setHours(endHours, endMinutes, endSeconds);
|
||
|
|
||
|
const result = (end - start) / 1000;
|
||
|
timeTableDecimalInSeconds += result;
|
||
|
}
|
||
|
|
||
|
for (let journey of journeys) {
|
||
|
const timeTableDecimal = timeTableDecimalInSeconds / 3600;
|
||
|
if (day.timeWorkDecimal == timeTableDecimal) {
|
||
|
const [startHours, startMinutes, startSeconds] = journey.start.split(':');
|
||
|
await models.WorkerTimeControl.create({
|
||
|
userFk: day.workerFk,
|
||
|
timed: day.dated.setHours(startHours, startMinutes, startSeconds),
|
||
|
manual: true,
|
||
|
isSendMail: true
|
||
|
}, myOptions);
|
||
|
|
||
|
const [endHours, endMinutes, endSeconds] = journey.end.split(':');
|
||
|
await models.WorkerTimeControl.create({
|
||
|
userFk: day.workerFk,
|
||
|
timed: day.dated.setHours(endHours, endMinutes, endSeconds),
|
||
|
manual: true,
|
||
|
isSendMail: true
|
||
|
}, myOptions);
|
||
|
} else {
|
||
|
const minStart = journeys.reduce(function(prev, curr) {
|
||
|
return curr.start < prev.start ? curr : prev;
|
||
|
});
|
||
|
if (journey == minStart) {
|
||
|
const [startHours, startMinutes, startSeconds] = journey.start.split(':');
|
||
|
await models.WorkerTimeControl.create({
|
||
|
userFk: day.workerFk,
|
||
|
timed: day.dated.setHours(startHours, startMinutes, startSeconds),
|
||
|
manual: true,
|
||
|
isSendMail: true
|
||
|
}, myOptions);
|
||
|
|
||
|
const [hoursWork, minutesWork, secondsWork] = day.timeWorkSexagesimal.split(':');
|
||
|
await models.WorkerTimeControl.create({
|
||
|
userFk: day.workerFk,
|
||
|
timed: day.dated.setHours(
|
||
|
parseInt(startHours) + parseInt(hoursWork),
|
||
|
parseInt(startMinutes) + parseInt(minutesWork),
|
||
|
parseInt(startSeconds) + parseInt(secondsWork)
|
||
|
),
|
||
|
manual: true,
|
||
|
isSendMail: true
|
||
|
}, myOptions);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (day.timeWorkDecimal >= 5) {
|
||
|
const minStart = journeys.reduce(function(prev, curr) {
|
||
|
return curr.start < prev.start ? curr : prev;
|
||
|
});
|
||
|
if (journey == minStart) {
|
||
|
const [startHours, startMinutes, startSeconds] = journey.start.split(':');
|
||
|
await models.WorkerTimeControl.create({
|
||
|
userFk: day.workerFk,
|
||
|
timed: day.dated.setHours(parseInt(startHours) + 1, startMinutes, startSeconds),
|
||
|
manual: true,
|
||
|
isSendMail: true
|
||
|
}, myOptions);
|
||
|
|
||
|
await models.WorkerTimeControl.create({
|
||
|
userFk: day.workerFk,
|
||
|
timed: day.dated.setHours(parseInt(startHours) + 1, parseInt(startMinutes) + 20, startSeconds),
|
||
|
manual: true,
|
||
|
isSendMail: true
|
||
|
}, myOptions);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
const firstWorkerTimeControl = await models.WorkerTimeControl.findOne({
|
||
|
where: {
|
||
|
userFk: day.workerFk,
|
||
|
timed: {between: [day.dated, day.dated.setHours(23, 59, 59, 999)]}
|
||
|
},
|
||
|
order: 'timed ASC',
|
||
|
limit: 1
|
||
|
}, myOptions);
|
||
|
|
||
|
if (firstWorkerTimeControl) firstWorkerTimeControl.updateAttribute('direction', 'in', myOptions);
|
||
|
|
||
|
const lastWorkerTimeControl = await models.WorkerTimeControl.findOne({
|
||
|
where: {
|
||
|
userFk: day.workerFk,
|
||
|
timed: {between: [day.dated, day.dated.setHours(23, 59, 59, 999)]}
|
||
|
},
|
||
|
order: 'timed DESC',
|
||
|
limit: 1
|
||
|
}, myOptions);
|
||
|
|
||
|
if (lastWorkerTimeControl) lastWorkerTimeControl.updateAttribute('direction', 'out', myOptions);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return true;
|
||
|
};
|
||
|
};
|