diff --git a/db/changes/10200-normality/00-workerCalendar.sql b/db/changes/10200-normality/00-workerCalendar.sql new file mode 100644 index 000000000..04b30394f --- /dev/null +++ b/db/changes/10200-normality/00-workerCalendar.sql @@ -0,0 +1,11 @@ +USE `vn`; +CREATE + OR REPLACE ALGORITHM = UNDEFINED + DEFINER = `root`@`%` + SQL SECURITY DEFINER +VIEW `workerCalendar2` AS + SELECT + `ce`.`business_id` AS `businessFk`, + `ce`.`calendar_state_id` AS `absenceTypeFk`, + `ce`.`date` AS `dated` + FROM `postgresql`.`calendar_employee` `ce`; diff --git a/modules/worker/back/methods/worker/createAbsences.js b/modules/worker/back/methods/worker/createAbsences.js new file mode 100644 index 000000000..e744d4796 --- /dev/null +++ b/modules/worker/back/methods/worker/createAbsences.js @@ -0,0 +1,101 @@ +const UserError = require('vn-loopback/util/user-error'); + +module.exports = Self => { + Self.remoteMethodCtx('createAbsences', { + description: 'Returns an array of absences from an specified worker', + accepts: [{ + arg: 'id', + type: 'Number', + description: 'The worker id', + http: {source: 'path'} + }, + { + arg: 'absenceTypeId', + type: 'Number', + required: true + }, + { + arg: 'dated', + type: 'Date', + required: false + }, + { + arg: 'started', + type: 'Date', + required: false + }, + { + arg: 'ended', + type: 'Date', + required: false + }, + { + arg: 'type', + type: 'String', + required: true + }], + returns: 'Object', + http: { + path: `/:id/createAbsences`, + verb: 'POST' + } + }); + + Self.createAbsences = async(ctx, id, absenceTypeId, dated, started, ended, type) => { + const models = Self.app.models; + const isSubordinate = await models.Worker.isSubordinate(ctx, id); + + if (!isSubordinate) + throw new UserError(`You don't have enough privileges`); + + const absences = []; + + if (type == 'day') { + const contracts = await models.WorkerLabour.find({ + where: { + and: [ + {workerFk: id}, + {or: [{ + ended: {gte: [yearStarted]} + }, {ended: null}]} + ] + } + }); + + absences.push({ + businessFk: 106, + absenceTypeFk: absenceTypeId, + dated: dated + }); + } else if (type == 'range') + console.log(true); + + return models.WorkerCalendar.create(absences); + }; +}; + +/* include: [{ + relation: 'holidays', + scope: { + where: {year} + } +}, +{ + relation: 'workCenter', + scope: { + include: { + relation: 'holidays', + scope: { + include: [{ + relation: 'detail' + }, + { + relation: 'type' + }], + where: { + dated: {between: [yearStarted, yearEnded]} + } + } + } + } +}], */ diff --git a/modules/worker/back/models/worker-calendar.json b/modules/worker/back/models/worker-calendar.json index 569d4d1ba..109b93c77 100644 --- a/modules/worker/back/models/worker-calendar.json +++ b/modules/worker/back/models/worker-calendar.json @@ -3,7 +3,7 @@ "base": "VnModel", "options": { "mysql": { - "table": "workerCalendar" + "table": "workerCalendar2" } }, "properties": { @@ -11,21 +11,12 @@ "id": 1, "type": "Number" }, - "workerFk": { - "id": 2, - "type": "Number" - }, "dated": { "id": 3, "type": "Date" } }, "relations": { - "worker": { - "type": "belongsTo", - "model": "Worker", - "foreignKey": "workerFk" - }, "absenceType": { "type": "belongsTo", "model": "AbsenceType", diff --git a/modules/worker/back/models/worker.js b/modules/worker/back/models/worker.js index 692c8c735..5f97c3e10 100644 --- a/modules/worker/back/models/worker.js +++ b/modules/worker/back/models/worker.js @@ -4,4 +4,5 @@ module.exports = Self => { require('../methods/worker/isSubordinate')(Self); require('../methods/worker/getWorkedHours')(Self); require('../methods/worker/uploadFile')(Self); + require('../methods/worker/createAbsences')(Self); }; diff --git a/modules/worker/front/calendar/index.html b/modules/worker/front/calendar/index.html index 08b3f469c..859da81b5 100644 --- a/modules/worker/front/calendar/index.html +++ b/modules/worker/front/calendar/index.html @@ -12,7 +12,8 @@ format-day="$ctrl.formatDay($day, $element)" display-controls="false" hide-contiguous="true" - hide-year="true"> + hide-year="true" + on-selection="$ctrl.onSelection($days, $type, $weekday)"> @@ -26,12 +27,74 @@
- + + {{absenceType.name}}
- \ No newline at end of file + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/modules/worker/front/calendar/index.js b/modules/worker/front/calendar/index.js index 6b849d19f..0a7f591db 100644 --- a/modules/worker/front/calendar/index.js +++ b/modules/worker/front/calendar/index.js @@ -43,15 +43,8 @@ class Controller extends Section { set worker(value) { this._worker = value; - if (!value) return; - let params = { - workerFk: this.worker.id, - started: this.started, - ended: this.ended - }; - this.$http.get(`WorkerCalendars/absences`, {params}) - .then(res => this.onData(res.data)); + if (value) this.refresh(); } onData(data) { @@ -102,6 +95,86 @@ class Controller extends Section { dayNumber.style.backgroundColor = event.color; dayNumber.style.color = 'rgba(0, 0, 0, 0.7)'; } + + pick(absenceType) { + if (absenceType == this.absenceType) + absenceType = null; + + this.absenceType = absenceType; + } + + onSelection($days, $type, $weekday) { + if (!this.absenceType) + return this.vnApp.showMessage(this.$t('Choose an absence type')); + + let $events = []; + for (let day of $days) { + const stamp = day.getTime(); + $events = $events.concat(this.events[stamp] || []); + } + + if ($events.length) + this.edit($events[0]); + else + this.create($type, $days, $weekday); + } + + create(type, days, weekday) { + this.isNew = true; + this.selected = { + type: 'day', + dated: days[0] + }; + + this.$.dialog.show(); + } + + edit() { + this.isNew = false; + } + + onAbsenceResponse(response) { + switch (response) { + case 'accept': { + const selected = this.selected; + const params = Object.assign(selected, { + absenceTypeId: this.absenceType.id + }); + + /* const selected = { + businessFk: 106, + absenceTypeFk: this.absenceType.id, + dated: $days[0] + }; */ + + let req; + if (this.isNew) { + const path = `Workers/${this.$params.id}/createAbsences`; + req = this.$http.post(path, params); + } else + req = this.$http.put(`${this.path}/${selected.id}`, selected); + + return req.then(() => { + this.selected = null; + this.isNew = null; + this.refresh(); + }); + } + case 'delete': + return this.onDelete(this.selected.id) + .then(response => response == 'accept'); + } + } + + refresh() { + const params = { + workerFk: this.worker.id, + started: this.started, + ended: this.ended + }; + this.$http.get(`WorkerCalendars/absences`, {params}) + .then(res => this.onData(res.data)); + } } ngModule.component('vnWorkerCalendar', { diff --git a/modules/worker/front/calendar/style.scss b/modules/worker/front/calendar/style.scss index 9b3fc749b..1c22fdfb0 100644 --- a/modules/worker/front/calendar/style.scss +++ b/modules/worker/front/calendar/style.scss @@ -16,4 +16,17 @@ vn-worker-calendar { max-width: 288px; } } + + vn-chip.selectable { + cursor: pointer + } + + vn-chip.selectable:hover { + opacity: 0.8 + } + + vn-chip vn-avatar { + text-align: center; + color: white + } }