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; }; };