Calendar changes
gitea/salix/pipeline/head This commit looks good Details

This commit is contained in:
Joan Sánchez 2020-07-08 15:05:56 +02:00
parent dd8e03dd0f
commit 01b32d2b89
11 changed files with 213 additions and 212 deletions

View File

@ -0,0 +1,5 @@
ALTER TABLE `postgresql`.`calendar_employee`
ADD COLUMN `id` INT NULL AUTO_INCREMENT FIRST,
ADD UNIQUE INDEX `id_UNIQUE` (`id` ASC) VISIBLE,
ADD INDEX `id_index` (`id` ASC) VISIBLE;
;

View File

@ -5,6 +5,7 @@ CREATE
SQL SECURITY DEFINER
VIEW `workerCalendar2` AS
SELECT
`ce`.`id` AS `id`,
`ce`.`business_id` AS `businessFk`,
`ce`.`calendar_state_id` AS `absenceTypeFk`,
`ce`.`date` AS `dated`

View File

@ -135,7 +135,7 @@ export default class Calendar extends FormInput {
$days: [day],
$type: 'day'
});
this.repaint();
// this.repaint();
}
/*

View File

@ -0,0 +1,56 @@
const UserError = require('vn-loopback/util/user-error');
module.exports = Self => {
Self.remoteMethodCtx('createAbsence', {
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
}],
returns: {
type: 'Object',
root: true
},
http: {
path: `/:id/createAbsence`,
verb: 'POST'
}
});
Self.createAbsence = async(ctx, id, absenceTypeId, dated) => {
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 labour = await models.WorkerLabour.findOne({
where: {
and: [
{workerFk: id},
{or: [{
ended: {gte: [dated]}
}, {ended: null}]}
]
}
});
return models.WorkerCalendar.create({
businessFk: labour.businessFk,
absenceTypeFk: absenceTypeId,
dated: dated
});
};
};

View File

@ -1,101 +0,0 @@
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]}
}
}
}
}
}], */

View File

@ -0,0 +1,35 @@
const UserError = require('vn-loopback/util/user-error');
module.exports = Self => {
Self.remoteMethodCtx('deleteAbsence', {
description: 'Returns an array of absences from an specified worker',
accepts: [{
arg: 'id',
type: 'Number',
description: 'The worker id',
http: {source: 'path'}
},
{
arg: 'absenceId',
type: 'Number',
required: true
}],
returns: 'Object',
http: {
path: `/:id/deleteAbsence`,
verb: 'DELETE'
}
});
Self.deleteAbsence = async(ctx, id, absenceId) => {
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 absence = await models.WorkerCalendar.findById(absenceId);
return absence.destroy();
};
};

View File

@ -0,0 +1,40 @@
const UserError = require('vn-loopback/util/user-error');
module.exports = Self => {
Self.remoteMethodCtx('updateAbsence', {
description: 'Returns an array of absences from an specified worker',
accepts: [{
arg: 'id',
type: 'Number',
description: 'The worker id',
http: {source: 'path'}
},
{
arg: 'absenceId',
type: 'Number',
required: true
},
{
arg: 'absenceTypeId',
type: 'Number',
required: true
}],
returns: 'Object',
http: {
path: `/:id/updateAbsence`,
verb: 'PATCH'
}
});
Self.updateAbsence = async(ctx, id, absenceId, absenceTypeId) => {
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 absence = await models.WorkerCalendar.findById(absenceId);
return absence.updateAttribute('absenceTypeFk', absenceTypeId);
};
};

View File

@ -7,12 +7,14 @@
}
},
"properties": {
"id": {
"id": true,
"type": "Number"
},
"businessFk": {
"id": 1,
"type": "Number"
},
"dated": {
"id": 3,
"type": "Date"
}
},

View File

@ -4,5 +4,7 @@ module.exports = Self => {
require('../methods/worker/isSubordinate')(Self);
require('../methods/worker/getWorkedHours')(Self);
require('../methods/worker/uploadFile')(Self);
require('../methods/worker/createAbsences')(Self);
require('../methods/worker/createAbsence')(Self);
require('../methods/worker/deleteAbsence')(Self);
require('../methods/worker/updateAbsence')(Self);
};

View File

@ -13,7 +13,7 @@
display-controls="false"
hide-contiguous="true"
hide-year="true"
on-selection="$ctrl.onSelection($days, $type, $weekday)">
on-selection="$ctrl.onSelection($days)">
</vn-calendar>
</vn-card>
</div>
@ -38,61 +38,6 @@
</div>
</div>
</vn-side-menu>
<vn-dialog
vn-id="dialog"
on-response="$ctrl.onAbsenceResponse($response)"
message="{{$ctrl.isNew ? 'Add absence' : 'Edit absence'}}">
<tpl-body>
<vn-vertical>
<vn-vertical class="vn-pb-md">
<vn-radio
ng-model="$ctrl.selected.type"
label="One day"
val="day">
</vn-radio>
<vn-radio
ng-model="$ctrl.selected.type"
label="Range of dates"
val="range">
</vn-radio>
</vn-vertical>
<vn-date-picker
ng-if="$ctrl.selected.type == 'day'"
label="Day"
ng-model="$ctrl.selected.dated">
</vn-date-picker>
<vn-horizontal
ng-if="$ctrl.selected.type == 'range'">
<vn-date-picker
label="From"
ng-model="$ctrl.selected.started">
</vn-date-picker>
<vn-date-picker
label="To"
ng-model="$ctrl.selected.ended">
</vn-date-picker>
</vn-horizontal>
</vn-vertical>
</tpl-body>
<tpl-buttons>
<input
type="button"
response="cancel"
translate-attr="{value: 'Cancel'}">
</input>
<input
type="button"
ng-if="!$ctrl.isNew"
response="delete"
translate-attr="{value: 'Delete'}">
</input>
<button response="accept">
<span ng-if="$ctrl.isNew" translate>Add</span>
<span ng-if="!$ctrl.isNew" translate>Save</span>
</button>
</tpl-buttons>
</vn-dialog>
<vn-confirm
vn-id="confirm"
message="This item will be deleted"

View File

@ -72,7 +72,9 @@ class Controller extends Section {
let type = absence.absenceType;
addEvent(absence.dated, {
name: type.name,
color: type.rgb
color: type.rgb,
type: type.code,
absenceId: absence.id
});
});
}
@ -103,67 +105,81 @@ class Controller extends Section {
this.absenceType = absenceType;
}
onSelection($days, $type, $weekday) {
onSelection($days) {
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] || []);
}
const day = $days[0];
const stamp = day.getTime();
const event = this.events[stamp];
if ($events.length)
this.edit($events[0]);
else
this.create($type, $days, $weekday);
if (event) {
if (event.type == this.absenceType.code)
this.delete(day, event);
else
this.edit(event);
} else
this.create(day);
}
create(type, days, weekday) {
this.isNew = true;
this.selected = {
type: 'day',
dated: days[0]
create(dated) {
const absenceType = this.absenceType;
const params = {
dated: dated,
absenceTypeId: absenceType.id
};
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;
const path = `Workers/${this.$params.id}/createAbsence`;
this.$http.post(path, params).then(res => {
this.responseHandler(() => {
const newEvent = res.data;
this.events[dated.getTime()] = {
name: absenceType.name,
color: absenceType.rgb,
type: absenceType.code,
absenceId: newEvent.id
};
this.refresh();
});
});
}
edit(event) {
const absenceType = this.absenceType;
const params = {
absenceId: event.absenceId,
absenceTypeId: absenceType.id
};
const path = `Workers/${this.$params.id}/updateAbsence`;
this.$http.patch(path, params).then(
this.responseHandler(() => {
event.color = absenceType.rgb;
event.name = absenceType.name;
event.code = absenceType.code;
this.refresh();
})
);
}
delete(day, event) {
const params = {absenceId: event.absenceId};
const path = `Workers/${this.$params.id}/deleteAbsence`;
this.$http.delete(path, {params}).then(
this.responseHandler(() => {
delete this.events[day.getTime()];
this.refresh();
})
);
}
responseHandler(cb) {
if (this.repaintCanceller) {
clearTimeout(this.repaintCanceller);
this.repaintCanceller = null;
}
case 'delete':
return this.onDelete(this.selected.id)
.then(response => response == 'accept');
}
this.repaintCanceller = setTimeout(
() => cb(), 650);
}
refresh() {