3928-worker.time-control_sendMail #1129

Merged
joan merged 26 commits from 3928-worker.time-control_sendMail into dev 2022-11-11 07:30:09 +00:00
7 changed files with 365 additions and 222 deletions
Showing only changes of commit 57564325e1 - Show all commits

View File

@ -30,33 +30,24 @@ module.exports = Self => {
Self.sendMail = async(ctx, options) => { Self.sendMail = async(ctx, options) => {
const models = Self.app.models; const models = Self.app.models;
const $t = ctx.req.__; // $translate
const args = ctx.args;
const myOptions = {};
const conn = Self.dataSource.connector; const conn = Self.dataSource.connector;
const args = ctx.args;
const $t = ctx.req.__; // $translate
let tx;
const myOptions = {};
if (typeof options == 'object') if (typeof options == 'object')
Object.assign(myOptions, options); Object.assign(myOptions, options);
if (!myOptions.transaction) {
tx = await Self.beginTransaction({});
myOptions.transaction = tx;
}
const stmts = []; const stmts = [];
let stmt; let stmt;
function getStartDateOfWeekNumber(week, year) { try {
const simple = new Date(year, 0, 1 + (week - 1) * 7);
const dow = simple.getDay();
const weekStart = simple;
if (dow <= 4)
weekStart.setDate(simple.getDate() - simple.getDay() + 1);
else
weekStart.setDate(simple.getDate() + 8 - simple.getDay());
return weekStart;
}
function getTime(timeString) {
const [hours, minutes, seconds] = timeString.split(':');
return [parseInt(hours), parseInt(minutes), parseInt(seconds)];
}
if (!args.week || !args.year) { if (!args.week || !args.year) {
const from = new Date(); const from = new Date();
const to = new Date(); const to = new Date();
@ -182,6 +173,7 @@ module.exports = Self => {
let previousReceiver = days[index][0].receiver; let previousReceiver = days[index][0].receiver;
for (let day of days[index]) { for (let day of days[index]) {
workerFk = day.workerFk;
if (day.timeWorkDecimal > 0 && day.timeWorkedDecimal == null if (day.timeWorkDecimal > 0 && day.timeWorkedDecimal == null
&& (day.permissionRate ? day.permissionRate : true)) { && (day.permissionRate ? day.permissionRate : true)) {
if (day.timeTable == null) { if (day.timeTable == null) {
@ -280,7 +272,9 @@ module.exports = Self => {
await models.WorkerTimeControl.create({ await models.WorkerTimeControl.create({
userFk: day.workerFk, userFk: day.workerFk,
timed: timed.setHours( timed: timed.setHours(
startHours + hoursWork, startMinutes + minutesWork, startSeconds + secondsWork startHours + hoursWork,
startMinutes + minutesWork,
startSeconds + secondsWork
), ),
manual: true, manual: true,
isSendMail: true isSendMail: true
@ -311,48 +305,82 @@ module.exports = Self => {
} }
} }
} }
const timed = new Date(day.dated); const timed = new Date(day.dated);
const firstWorkerTimeControl = await models.WorkerTimeControl.findOne({ const firstWorkerTimeControl = await models.WorkerTimeControl.findOne({
where: { where: {
userFk: day.workerFk, userFk: day.workerFk,
timed: {between: [timed.setHours(0, 0, 0, 0), timed.setHours(23, 59, 59, 999)]} timed: {between: [timed.setHours(0, 0, 0, 0), timed.setHours(23, 59, 59, 999)]}
}, },
order: 'timed ASC', order: 'timed ASC'
limit: 1
}, myOptions); }, myOptions);
if (firstWorkerTimeControl) firstWorkerTimeControl.updateAttribute('direction', 'in', myOptions); if (firstWorkerTimeControl)
firstWorkerTimeControl.updateAttribute('direction', 'in', myOptions);
const lastWorkerTimeControl = await models.WorkerTimeControl.findOne({ const lastWorkerTimeControl = await models.WorkerTimeControl.findOne({
where: { where: {
userFk: day.workerFk, userFk: day.workerFk,
timed: {between: [timed.setHours(0, 0, 0, 0), timed.setHours(23, 59, 59, 999)]} timed: {between: [timed.setHours(0, 0, 0, 0), timed.setHours(23, 59, 59, 999)]}
}, },
order: 'timed DESC', order: 'timed DESC'
limit: 1
}, myOptions); }, myOptions);
if (lastWorkerTimeControl) lastWorkerTimeControl.updateAttribute('direction', 'out', myOptions); if (lastWorkerTimeControl)
lastWorkerTimeControl.updateAttribute('direction', 'out', myOptions);
} }
} }
const origin = ctx.req.headers.origin;
const lastDay = days[index][days[index].length - 1]; const lastDay = days[index][days[index].length - 1];
if (day.workerFk != previousWorkerFk || day == lastDay) { if (day.workerFk != previousWorkerFk || day == lastDay) {
const salix = await models.Url.findOne({
where: {
appName: 'salix',
environment: process.env.NODE_ENV || 'dev'
}
}, myOptions);
const timestamp = started.getTime() / 1000;
await models.Mail.create({ await models.Mail.create({
receiver: previousReceiver, receiver: previousReceiver,
subject: $t('Record of hours week', { subject: $t('Record of hours week', {
week: args.week, week: args.week,
year: args.year year: args.year
}), }),
body: `${origin}/#!/worker/${previousWorkerFk}/time-control?timestamp=` body: `${salix.url}worker/${previousWorkerFk}/time-control?timestamp=${timestamp}`
}); }, myOptions);
await models.WorkerTimeControlMail.create({
workerFk: previousWorkerFk,
week: args.week,
year: args.year
}, myOptions);
previousWorkerFk = day.workerFk; previousWorkerFk = day.workerFk;
previousReceiver = day.receiver; previousReceiver = day.receiver;
} }
} }
if (tx) await tx.commit();
} catch (e) {
if (tx) await tx.rollback();
throw e;
}
return true; return true;
}; };
function getStartDateOfWeekNumber(week, year) {
const simple = new Date(year, 0, 1 + (week - 1) * 7);
const dow = simple.getDay();
const weekStart = simple;
if (dow <= 4)
weekStart.setDate(simple.getDate() - simple.getDay() + 1);
else
weekStart.setDate(simple.getDate() + 8 - simple.getDay());
return weekStart;
}
function getTime(timeString) {
const [hours, minutes, seconds] = timeString.split(':');
return [parseInt(hours), parseInt(minutes), parseInt(seconds)];
}
}; };

View File

@ -0,0 +1,61 @@
module.exports = Self => {
Self.remoteMethodCtx('updateWorkerTimeControlMail', {
description: 'Updates the state of WorkerTimeControlMail',
accessType: 'WRITE',
accepts: [{
arg: 'workerId',
type: 'number',
required: true
},
{
arg: 'year',
type: 'number',
required: true
},
{
arg: 'week',
type: 'number',
required: true
},
{
arg: 'state',
type: 'string',
required: true
},
{
arg: 'emailResponse',
type: 'string'
}],
returns: {
type: 'boolean',
root: true
},
http: {
path: `/updateWorkerTimeControlMail`,
verb: 'POST'
}
});
Self.updateWorkerTimeControlMail = async(ctx, options) => {
const models = Self.app.models;
const args = ctx.args;
const myOptions = {};
if (typeof options == 'object')
Object.assign(myOptions, options);
const workerTimeControlMail = await models.WorkerTimeControlMail.findOne({
where: {
workerFk: args.workerId,
year: args.year,
week: args.week
}
}, myOptions);
return workerTimeControlMail.updateAttributes({
state: args.state,
emailResponse: args.emailResponse || null
}, myOptions);
};
};

View File

@ -9,8 +9,7 @@
"properties": { "properties": {
"id": { "id": {
"id": true, "id": true,
"type": "number", "type": "number"
"required": true
}, },
"workerFk": { "workerFk": {
"type": "number" "type": "number"

View File

@ -6,6 +6,7 @@ module.exports = Self => {
require('../methods/worker-time-control/deleteTimeEntry')(Self); require('../methods/worker-time-control/deleteTimeEntry')(Self);
require('../methods/worker-time-control/updateTimeEntry')(Self); require('../methods/worker-time-control/updateTimeEntry')(Self);
require('../methods/worker-time-control/sendMail')(Self); require('../methods/worker-time-control/sendMail')(Self);
require('../methods/worker-time-control/updateWorkerTimeControlMail')(Self);
Self.rewriteDbError(function(err) { Self.rewriteDbError(function(err) {
if (err.code === 'ER_DUP_ENTRY') if (err.code === 'ER_DUP_ENTRY')

View File

@ -81,11 +81,11 @@
<vn-button-bar class="vn-pa-xs vn-w-lg"> <vn-button-bar class="vn-pa-xs vn-w-lg">
<vn-button <vn-button
label="Satisfied" label="Satisfied"
ng-click="$ctrl.onNextClick()"> ng-click="$ctrl.isSatisfied()">
</vn-button> </vn-button>
<vn-button <vn-button
label="Not satisfied" label="Not satisfied"
ng-click="$ctrl.onNextClick()"> ng-click="reason.show()">
</vn-button> </vn-button>
</vn-button-bar> </vn-button-bar>
@ -161,3 +161,20 @@
</vn-icon-button> </vn-icon-button>
</vn-horizontal> </vn-horizontal>
</vn-popover> </vn-popover>
<vn-dialog
vn-id="reason"
on-accept="$ctrl.isUnsatisfied()">
<tpl-body>
<vn-textarea
label="Reason"
ng-model="$ctrl.reason"
required="true"
rows="3">
</vn-textarea>
</tpl-body>
<tpl-buttons>
<input type="button" response="cancel" translate-attr="{value: 'Cancel'}"/>
<button response="accept" translate>Save</button>
</tpl-buttons>
</vn-dialog>

View File

@ -294,6 +294,42 @@ class Controller extends Section {
this.$.editEntry.show($event); this.$.editEntry.show($event);
} }
getWeekNumber(currentDate) {
const startDate = new Date(currentDate.getFullYear(), 0, 1);
let days = Math.floor((currentDate - startDate) /
(24 * 60 * 60 * 1000));
return Math.ceil(days / 7);
}
isSatisfied() {
const weekNumber = this.getWeekNumber(this.date);
const params = {
workerId: this.worker.id,
year: this.date.getFullYear(),
week: weekNumber,
state: 'CONFIRMED'
};
const query = `WorkerTimeControls/updateWorkerTimeControlMail`;
this.$http.post(query, params).then(() => {
this.vnApp.showSuccess(this.$t('Data saved!'));
});
}
isUnsatisfied() {
const weekNumber = this.getWeekNumber(this.date);
const params = {
workerId: this.worker.id,
year: this.date.getFullYear(),
week: weekNumber,
state: 'REVISE',
emailResponse: this.reason
};
const query = `WorkerTimeControls/updateWorkerTimeControlMail`;
this.$http.post(query, params).then(() => {
this.vnApp.showSuccess(this.$t('Data saved!'));
});
}
save() { save() {
try { try {
const entry = this.selectedRow; const entry = this.selectedRow;

View File

@ -13,3 +13,4 @@ Entry removed: Fichada borrada
The entry type can't be empty: El tipo de fichada no puede quedar vacía The entry type can't be empty: El tipo de fichada no puede quedar vacía
Satisfied: Conforme Satisfied: Conforme
Not satisfied: No conforme Not satisfied: No conforme
Reason: Motivo