From 6eaf317b5e83cad6d1e349933e51e2b3d6595da6 Mon Sep 17 00:00:00 2001 From: Joan Sanchez Date: Fri, 22 Mar 2019 08:28:57 +0100 Subject: [PATCH] added worker calendar #1147 --- db/install/changes/01-ACL.sql | 2 + db/install/changes/absenceType.sql | 12 ++ db/install/changes/holiday.sql | 16 ++ db/install/changes/holidayDetail.sql | 13 ++ db/install/changes/holidayType.sql | 14 ++ db/install/changes/workCenterHoliday.sql | 11 ++ db/install/changes/workerCalendar.sql | 16 ++ db/install/changes/workerLabour.sql | 18 ++ front/core/components/calendar/index.html | 8 +- front/core/components/calendar/index.js | 19 ++- front/core/components/calendar/style.scss | 2 + front/salix/styles/misc.scss | 1 + modules/agency/back/model-config.json | 13 -- .../back/models/labour-holiday-legend.json | 18 -- .../back/models/labour-holiday-type.json | 21 --- modules/agency/back/models/labour-holiday.js | 3 - modules/agency/front/calendar/index.js | 4 +- modules/ticket/front/volume/index.js | 1 - modules/ticket/front/volume/style.scss | 0 .../back/methods/holiday}/getByWarehouse.js | 20 ++- .../back/methods/worker-calendar/absences.js | 155 ++++++++++++++++++ modules/worker/back/model-config.json | 24 +++ modules/worker/back/models/absence-type.json | 29 ++++ .../worker/back/models/holiday-detail.json | 26 +++ modules/worker/back/models/holiday-type.json | 29 ++++ modules/worker/back/models/holiday.js | 3 + .../back/models/holiday.json} | 26 +-- .../back/models/work-center-holiday.json | 34 ++++ .../back/models/work-center.json | 17 +- modules/worker/back/models/worker-calendar.js | 3 + .../worker/back/models/worker-calendar.json | 35 ++++ modules/worker/back/models/worker-labour.json | 43 +++++ modules/worker/front/calendar/index.html | 22 +++ modules/worker/front/calendar/index.js | 113 +++++++++++++ modules/worker/front/calendar/locale/es.yml | 5 + modules/worker/front/calendar/style.scss | 23 +++ modules/worker/front/index.js | 1 + modules/worker/front/locale/es.yml | 3 +- modules/worker/front/routes.json | 15 +- 39 files changed, 726 insertions(+), 92 deletions(-) create mode 100644 db/install/changes/absenceType.sql create mode 100644 db/install/changes/holiday.sql create mode 100644 db/install/changes/holidayDetail.sql create mode 100644 db/install/changes/holidayType.sql create mode 100644 db/install/changes/workCenterHoliday.sql create mode 100644 db/install/changes/workerCalendar.sql create mode 100644 db/install/changes/workerLabour.sql delete mode 100644 modules/agency/back/models/labour-holiday-legend.json delete mode 100644 modules/agency/back/models/labour-holiday-type.json delete mode 100644 modules/agency/back/models/labour-holiday.js delete mode 100644 modules/ticket/front/volume/style.scss rename modules/{agency/back/methods/labour-holiday => worker/back/methods/holiday}/getByWarehouse.js (62%) create mode 100644 modules/worker/back/methods/worker-calendar/absences.js create mode 100644 modules/worker/back/models/absence-type.json create mode 100644 modules/worker/back/models/holiday-detail.json create mode 100644 modules/worker/back/models/holiday-type.json create mode 100644 modules/worker/back/models/holiday.js rename modules/{agency/back/models/labour-holiday.json => worker/back/models/holiday.json} (50%) create mode 100644 modules/worker/back/models/work-center-holiday.json rename modules/{agency => worker}/back/models/work-center.json (52%) create mode 100644 modules/worker/back/models/worker-calendar.js create mode 100644 modules/worker/back/models/worker-calendar.json create mode 100644 modules/worker/back/models/worker-labour.json create mode 100644 modules/worker/front/calendar/index.html create mode 100644 modules/worker/front/calendar/index.js create mode 100644 modules/worker/front/calendar/locale/es.yml create mode 100644 modules/worker/front/calendar/style.scss diff --git a/db/install/changes/01-ACL.sql b/db/install/changes/01-ACL.sql index e5bfe3bd1..0fd715d7f 100644 --- a/db/install/changes/01-ACL.sql +++ b/db/install/changes/01-ACL.sql @@ -2,3 +2,5 @@ INSERT INTO `salix`.`ACL` (`id`,`model`, `property`, `accessType`, `permission`, INSERT INTO `salix`.`ACL` (`id`,`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) VALUES (152, 'Department','*','WRITE','ALLOW','ROLE','hr'); INSERT INTO `salix`.`ACL` (`id`,`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) VALUES (153, 'Route','*','READ','ALLOW','ROLE','employee'); INSERT INTO `salix`.`ACL` (`id`,`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) VALUES (154, 'Route','*','WRITE','ALLOW','ROLE','delivery'); +INSERT INTO `salix`.`ACL` (`id`,`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) VALUES (155, 'WorkerCalendar','*','READ','ALLOW','ROLE','hr'); +INSERT INTO `salix`.`ACL` (`id`,`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) VALUES (156, 'WorkerLabour','*','READ','ALLOW','ROLE','hr'); diff --git a/db/install/changes/absenceType.sql b/db/install/changes/absenceType.sql new file mode 100644 index 000000000..31047c95e --- /dev/null +++ b/db/install/changes/absenceType.sql @@ -0,0 +1,12 @@ +DROP VIEW IF EXISTS `vn`.`absenceType`; +CREATE + ALGORITHM = UNDEFINED + DEFINER = `root`@`%` + SQL SECURITY DEFINER +VIEW `vn`.`absenceType` AS + SELECT + `cs`.`calendar_state_id` AS `id`, + `cs`.`type` AS `name`, + `cs`.`rgb` AS `rgb` + FROM + `postgresql`.`calendar_state` `cs` \ No newline at end of file diff --git a/db/install/changes/holiday.sql b/db/install/changes/holiday.sql new file mode 100644 index 000000000..cf1e21387 --- /dev/null +++ b/db/install/changes/holiday.sql @@ -0,0 +1,16 @@ + +DROP VIEW IF EXISTS `vn`.`labourHoliday`; +DROP VIEW IF EXISTS `vn`.`holiday`; +CREATE + OR REPLACE ALGORITHM = UNDEFINED + DEFINER = `root`@`%` + SQL SECURITY DEFINER +VIEW `vn`.`holiday` AS + SELECT + `cl`.`calendar_labour_legend_id` AS `holidayDetailFk`, + `cl`.`calendar_free_id` AS `holidayTypeFk`, + `cl`.`workcenter_id` AS `workCenterFk`, + `cl`.`day` AS `dated` + FROM + `postgresql`.`calendar_labour` `cl`; + diff --git a/db/install/changes/holidayDetail.sql b/db/install/changes/holidayDetail.sql new file mode 100644 index 000000000..3697c91e1 --- /dev/null +++ b/db/install/changes/holidayDetail.sql @@ -0,0 +1,13 @@ +DROP VIEW IF EXISTS `vn`.`labourHolidayLegend`; +DROP VIEW IF EXISTS `vn`.`holidayDetail`; + +CREATE + OR REPLACE ALGORITHM = UNDEFINED + DEFINER = `root`@`%` + SQL SECURITY DEFINER +VIEW `vn`.`holidayDetail` AS + SELECT + `cll`.`calendar_labour_legend_id` AS `id`, + `cll`.`descripcion` AS `description` + FROM + `postgresql`.`calendar_labour_legend` `cll`; \ No newline at end of file diff --git a/db/install/changes/holidayType.sql b/db/install/changes/holidayType.sql new file mode 100644 index 000000000..e67eba4b4 --- /dev/null +++ b/db/install/changes/holidayType.sql @@ -0,0 +1,14 @@ +DROP VIEW IF EXISTS `vn`.`labourHolidayType`; +DROP VIEW IF EXISTS `vn`.`holidayType`; + +CREATE + OR REPLACE ALGORITHM = UNDEFINED + DEFINER = `root`@`%` + SQL SECURITY DEFINER +VIEW `vn`.`holidayType` AS + SELECT + `cf`.`calendar_free_id` AS `id`, + `cf`.`type` AS `name`, + `cf`.`rgb` AS `rgb` + FROM + `postgresql`.`calendar_free` `cf`; \ No newline at end of file diff --git a/db/install/changes/workCenterHoliday.sql b/db/install/changes/workCenterHoliday.sql new file mode 100644 index 000000000..bfcef4248 --- /dev/null +++ b/db/install/changes/workCenterHoliday.sql @@ -0,0 +1,11 @@ +DROP VIEW IF EXISTS `vn`.`workCenterHoliday`; +CREATE + ALGORITHM = UNDEFINED + DEFINER = `root`@`%` + SQL SECURITY DEFINER +VIEW `vn`.`workCenterHoliday` AS + SELECT + `wh`.`workcenter_id` AS `workCenterFk`, + `wh`.`day` AS `days`, + `wh`.`year` AS `year` + FROM `vn2008`.`workcenter_holiday` `wh` \ No newline at end of file diff --git a/db/install/changes/workerCalendar.sql b/db/install/changes/workerCalendar.sql new file mode 100644 index 000000000..bf9199a9a --- /dev/null +++ b/db/install/changes/workerCalendar.sql @@ -0,0 +1,16 @@ +DROP VIEW IF EXISTS `vn`.`workerCalendar`; +CREATE + ALGORITHM = UNDEFINED + DEFINER = `root`@`%` + SQL SECURITY DEFINER +VIEW `vn`.`workerCalendar` AS + SELECT + `ce`.`business_id` AS `businessFk`, + `p`.`id_trabajador` AS `workerFk`, + `ce`.`calendar_state_id` AS `absenceTypeFk`, + `ce`.`date` AS `dated` + FROM + (((`postgresql`.`person` `p` + JOIN `postgresql`.`profile` `pr` ON ((`pr`.`person_id` = `p`.`person_id`))) + JOIN `postgresql`.`business` `b` ON ((`b`.`client_id` = `pr`.`profile_id`))) + JOIN `postgresql`.`calendar_employee` `ce` ON ((`ce`.`business_id` = `b`.`business_id`))) \ No newline at end of file diff --git a/db/install/changes/workerLabour.sql b/db/install/changes/workerLabour.sql new file mode 100644 index 000000000..c31a04de4 --- /dev/null +++ b/db/install/changes/workerLabour.sql @@ -0,0 +1,18 @@ +DROP VIEW IF EXISTS `vn`.`workerLabour`; +CREATE + ALGORITHM = UNDEFINED + DEFINER = `root`@`%` + SQL SECURITY DEFINER +VIEW `vn`.`workerLabour` AS + SELECT + `b`.`business_id` AS `businessFk`, + `p`.`id_trabajador` AS `workerFk`, + `bl`.`workcenter_id` AS `workCenterFk`, + `b`.`date_start` AS `started`, + `b`.`date_end` AS `ended`, + `d`.`id` AS `departmentFk` + FROM `postgresql`.`person` `p` + JOIN `postgresql`.`profile` `pr` ON `pr`.`person_id` = `p`.`person_id` + JOIN `postgresql`.`business` `b` ON `b`.`client_id` = `pr`.`profile_id` + JOIN `postgresql`.`business_labour` `bl` ON `b`.`business_id` = `bl`.`business_id` + JOIN `vn`.`department` `d` ON `d`.`id` = `bl`.`department_id` \ No newline at end of file diff --git a/front/core/components/calendar/index.html b/front/core/components/calendar/index.html index 25af81815..5e3d34f49 100644 --- a/front/core/components/calendar/index.html +++ b/front/core/components/calendar/index.html @@ -75,9 +75,11 @@ -
- +
+ {{::day.date | date: 'd'}} {{::day.date | date: 'd'}} diff --git a/front/core/components/calendar/index.js b/front/core/components/calendar/index.js index e26e6890a..9ccb856ee 100644 --- a/front/core/components/calendar/index.js +++ b/front/core/components/calendar/index.js @@ -115,7 +115,7 @@ export default class Calendar extends Component { } } - addDay(date, day, color = '') { + addDay(date, day, className = '', style) { const newDate = new Date( date.getFullYear(), date.getMonth(), day); @@ -125,29 +125,32 @@ export default class Calendar extends Component { }); if (newDate.getMonth() === this.currentMonth.getMonth() && newDate.getDay() == 0) - color = 'red'; + className = 'red'; - if (event) - color = event.color; + if (event) { + className = event.className; + style = event.style; + } - this.days.push({date: newDate, color, event}); + + this.days.push({date: newDate, className, style, event}); } /** * Adds a new calendar event * * @param {Date} date - Day to add event - * @param {String} color - [green, blue, orange, red] + * @param {String} className - [green, blue, orange, red] * @param {String} title - Tooltip description * @param {Boolean} isRemovable - True if is removable by users */ - addEvent(date, color, title = '', isRemovable = true) { + addEvent(date, className, title = '', isRemovable = true) { const event = this.events.findIndex(event => { return event.date >= date && event.date <= date; }); if (event == -1) - this.events.push({date, color, title, isRemovable}); + this.events.push({date, className, title, isRemovable}); this.repaint(); } diff --git a/front/core/components/calendar/style.scss b/front/core/components/calendar/style.scss index 0e20fabf2..69749023b 100644 --- a/front/core/components/calendar/style.scss +++ b/front/core/components/calendar/style.scss @@ -2,6 +2,7 @@ vn-calendar { display: block; + max-width: 250px; .header vn-one { text-align: center; @@ -26,6 +27,7 @@ vn-calendar { padding: 0.1em; width: 14.2857143%; line-height: 1.5em; + outline: 0; span { transition: background-color 0.3s; diff --git a/front/salix/styles/misc.scss b/front/salix/styles/misc.scss index c73cd6959..8b8bb0b4f 100644 --- a/front/salix/styles/misc.scss +++ b/front/salix/styles/misc.scss @@ -40,6 +40,7 @@ a, .link { align-items: center; padding: 18px; margin-bottom: 10px; + max-width: 10em; } .form { height: 100%; diff --git a/modules/agency/back/model-config.json b/modules/agency/back/model-config.json index d910a1602..9019ac246 100644 --- a/modules/agency/back/model-config.json +++ b/modules/agency/back/model-config.json @@ -19,18 +19,5 @@ }, "ZoneIncluded": { "dataSource": "vn" - }, - "LabourHoliday": { - "dataSource": "vn" - }, - "LabourHolidayLegend": { - "dataSource": "vn" - }, - "LabourHolidayType": { - "dataSource": "vn" } } - - - - diff --git a/modules/agency/back/models/labour-holiday-legend.json b/modules/agency/back/models/labour-holiday-legend.json deleted file mode 100644 index a2650ddd7..000000000 --- a/modules/agency/back/models/labour-holiday-legend.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "name": "LabourHolidayLegend", - "base": "VnModel", - "options": { - "mysql": { - "table": "labourHolidayLegend" - } - }, - "properties": { - "id": { - "id": true, - "type": "Number" - }, - "description": { - "type": "String" - } - } -} \ No newline at end of file diff --git a/modules/agency/back/models/labour-holiday-type.json b/modules/agency/back/models/labour-holiday-type.json deleted file mode 100644 index ea4272723..000000000 --- a/modules/agency/back/models/labour-holiday-type.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "name": "LabourHolidayType", - "base": "VnModel", - "options": { - "mysql": { - "table": "labourHolidayType" - } - }, - "properties": { - "id": { - "id": true, - "type": "Number" - }, - "name": { - "type": "String" - }, - "rgb": { - "type": "String" - } - } -} \ No newline at end of file diff --git a/modules/agency/back/models/labour-holiday.js b/modules/agency/back/models/labour-holiday.js deleted file mode 100644 index 629e11a91..000000000 --- a/modules/agency/back/models/labour-holiday.js +++ /dev/null @@ -1,3 +0,0 @@ -module.exports = Self => { - require('../methods/labour-holiday/getByWarehouse')(Self); -}; diff --git a/modules/agency/front/calendar/index.js b/modules/agency/front/calendar/index.js index 4e84c73eb..20d91f994 100644 --- a/modules/agency/front/calendar/index.js +++ b/modules/agency/front/calendar/index.js @@ -35,7 +35,7 @@ class Controller { res.data.forEach(holiday => { events.push({ date: holiday.dated, - color: 'red', + className: 'red', title: holiday.description || holiday.name, isRemovable: false }); @@ -61,7 +61,7 @@ class Controller { events.push({ date: date, - color: 'green-circle', + className: 'green-circle', title: 'Has delivery', isRemovable: true }); diff --git a/modules/ticket/front/volume/index.js b/modules/ticket/front/volume/index.js index cbdb91559..89fd924a5 100644 --- a/modules/ticket/front/volume/index.js +++ b/modules/ticket/front/volume/index.js @@ -1,5 +1,4 @@ import ngModule from '../module'; -import './style.scss'; class Controller { constructor($scope, $http, $stateParams) { diff --git a/modules/ticket/front/volume/style.scss b/modules/ticket/front/volume/style.scss deleted file mode 100644 index e69de29bb..000000000 diff --git a/modules/agency/back/methods/labour-holiday/getByWarehouse.js b/modules/worker/back/methods/holiday/getByWarehouse.js similarity index 62% rename from modules/agency/back/methods/labour-holiday/getByWarehouse.js rename to modules/worker/back/methods/holiday/getByWarehouse.js index 23282305a..3ebb5f5b2 100644 --- a/modules/agency/back/methods/labour-holiday/getByWarehouse.js +++ b/modules/worker/back/methods/holiday/getByWarehouse.js @@ -17,19 +17,25 @@ module.exports = Self => { } }); - Self.getByWarehouse = warehouseFk => { + Self.getByWarehouse = async warehouseFk => { let beginningYear = new Date(); beginningYear.setMonth(0); beginningYear.setDate(1); beginningYear.setHours(0, 0, 0, 0); - return Self.rawSql( + let holidays = await Self.rawSql( `SELECT lh.dated, lhl.description, lht.name, w.id - FROM vn.labourHoliday lh + FROM vn.holiday lh JOIN vn.workCenter w ON w.id = lh.workcenterFk - LEFT JOIN vn.labourHolidayLegend lhl ON lhl.id = lh.labourHolidayLegendFk - LEFT JOIN vn.labourHolidayType lht ON lht.id = lh.labourHolidayTypeFk - WHERE w.warehouseFk = ? AND lh.dated >= ?`, [warehouseFk, beginningYear] - ); + LEFT JOIN vn.holidayDetail lhl ON lhl.id = lh.holidayDetailFk + LEFT JOIN vn.holidayType lht ON lht.id = lh.holidayTypeFk + WHERE w.warehouseFk = ? AND lh.dated >= ?`, [warehouseFk, beginningYear]); + + return holidays.map(holiday => { + holiday.dated = new Date(holiday.dated); + holiday.dated.setHours(0, 0, 0, 0); + + return holiday; + }); }; }; diff --git a/modules/worker/back/methods/worker-calendar/absences.js b/modules/worker/back/methods/worker-calendar/absences.js new file mode 100644 index 000000000..9b9479ca1 --- /dev/null +++ b/modules/worker/back/methods/worker-calendar/absences.js @@ -0,0 +1,155 @@ + +const ParameterizedSQL = require('loopback-connector').ParameterizedSQL; +const UserError = require('vn-loopback/util/user-error'); + +module.exports = Self => { + Self.remoteMethodCtx('absences', { + description: 'Returns an array of absences from an specified worker', + accessType: '', + accepts: [{ + arg: 'workerFk', + type: 'Number', + required: true, + }, + { + arg: 'started', + type: 'Date', + required: true, + }, + { + arg: 'ended', + type: 'Date', + required: true, + }], + returns: [{ + arg: 'calendar' + }, + { + arg: 'absences' + }, + { + arg: 'holidays' + }], + http: { + path: `/absences`, + verb: 'GET' + } + }); + + Self.absences = async(ctx, workerFk, started, ended) => { + const models = Self.app.models; + const conn = Self.dataSource.connector; + const myUserId = ctx.req.accessToken.userId; + const myWorker = await models.Worker.findOne({where: {userFk: myUserId}}); + const calendar = {totalHolidays: 0, holidaysEnjoyed: 0}; + const holidays = []; + const stmts = []; + + // Get subordinates + stmts.push(new ParameterizedSQL('CALL vn.subordinateGetList(?)', [myWorker.id])); + let subordinatesIndex = stmts.push('SELECT * FROM tmp.subordinate') - 1; + let sql = ParameterizedSQL.join(stmts, ';'); + let result = await conn.executeStmt(sql); + + const subordinates = result[subordinatesIndex]; + const isSubordinate = subordinates.find(subordinate => { + return subordinate.workerFk === workerFk; + }); + const isHr = await models.Account.hasRole(myUserId, 'hr'); + + if (!isHr && workerFk !== myWorker.id && !isSubordinate) + throw new UserError(`You don't have enough privileges`); + + + // Get absences of year + let absences = await Self.find({ + include: { + relation: 'absenceType' + }, + where: { + workerFk: workerFk, + dated: {between: [started, ended]} + } + }); + + absences.forEach(absence => { + if (absence.absenceType().id === 1) + calendar.holidaysEnjoyed++; + + absence.dated = new Date(absence.dated); + absence.dated.setHours(0, 0, 0, 0); + }); + + // Get active contracts on current year + const year = started.getFullYear(); + const contracts = await models.WorkerLabour.find({ + include: [{ + relation: 'holidays', + scope: { + where: {year} + } + }, + { + relation: 'workCenter', + scope: { + include: { + relation: 'holidays', + scope: { + include: [{ + relation: 'detail' + }, + { + relation: 'type' + }], + where: { + dated: {between: [started, ended]} + } + } + } + } + }], + where: { + and: [ + {workerFk: workerFk}, + {or: [{ + ended: {gte: [started]} + }, {ended: null}]} + ], + + } + }); + + // Get number of total holidays + contracts.forEach(contract => { + let totalHolidays = contract.holidays().days; + + if (contract.started && contract.ended) + totalHolidays = getHolidaysByContract(contract); + + calendar.totalHolidays += totalHolidays; + + + let holidayList = contract.workCenter().holidays(); + for (let day of holidayList) { + day.dated = new Date(day.dated); + day.dated.setHours(0, 0, 0, 0); + + holidays.push(day); + } + }); + + return [calendar, absences, holidays]; + }; + + function getHolidaysByContract(contract) { + const dayTimestamp = 1000 * 60 * 60 * 24; + const endedTime = contract.ended.getTime(); + const startedTime = contract.started.getTime(); + const contractDays = Math.floor((endedTime - startedTime) / dayTimestamp); + + if (contractDays < 365) + return Math.floor(contract.holidays().days * (contractDays + 1) / 365); + + return contract.holidays().days; + } +}; diff --git a/modules/worker/back/model-config.json b/modules/worker/back/model-config.json index 19c496d04..fae2fcc20 100644 --- a/modules/worker/back/model-config.json +++ b/modules/worker/back/model-config.json @@ -1,10 +1,31 @@ { + "AbsenceType": { + "dataSource": "vn" + }, "Department": { "dataSource": "vn" + }, + "Holiday": { + "dataSource": "vn" + }, + "HolidayDetail": { + "dataSource": "vn" + }, + "HolidayType": { + "dataSource": "vn" + }, + "WorkCenter": { + "dataSource": "vn" + }, + "WorkCenterHoliday": { + "dataSource": "vn" }, "Worker": { "dataSource": "vn" }, + "WorkerLabour": { + "dataSource": "vn" + }, "WorkerMana": { "dataSource": "vn" }, @@ -19,5 +40,8 @@ }, "WorkerDepartment": { "dataSource": "vn" + }, + "WorkerCalendar": { + "dataSource": "vn" } } diff --git a/modules/worker/back/models/absence-type.json b/modules/worker/back/models/absence-type.json new file mode 100644 index 000000000..578a7b21a --- /dev/null +++ b/modules/worker/back/models/absence-type.json @@ -0,0 +1,29 @@ +{ + "name": "AbsenceType", + "base": "VnModel", + "options": { + "mysql": { + "table": "absenceType" + } + }, + "properties": { + "id": { + "id": true, + "type": "Number" + }, + "name": { + "type": "String" + }, + "rgb": { + "type": "String" + } + }, + "acls": [ + { + "accessType": "READ", + "principalType": "ROLE", + "principalId": "$everyone", + "permission": "ALLOW" + } + ] +} \ No newline at end of file diff --git a/modules/worker/back/models/holiday-detail.json b/modules/worker/back/models/holiday-detail.json new file mode 100644 index 000000000..86874a02e --- /dev/null +++ b/modules/worker/back/models/holiday-detail.json @@ -0,0 +1,26 @@ +{ + "name": "HolidayDetail", + "base": "VnModel", + "options": { + "mysql": { + "table": "holidayDetail" + } + }, + "properties": { + "id": { + "id": true, + "type": "Number" + }, + "description": { + "type": "String" + } + }, + "acls": [ + { + "accessType": "READ", + "principalType": "ROLE", + "principalId": "$everyone", + "permission": "ALLOW" + } + ] +} \ No newline at end of file diff --git a/modules/worker/back/models/holiday-type.json b/modules/worker/back/models/holiday-type.json new file mode 100644 index 000000000..6e40a62c7 --- /dev/null +++ b/modules/worker/back/models/holiday-type.json @@ -0,0 +1,29 @@ +{ + "name": "HolidayType", + "base": "VnModel", + "options": { + "mysql": { + "table": "holidayType" + } + }, + "properties": { + "id": { + "id": true, + "type": "Number" + }, + "name": { + "type": "String" + }, + "rgb": { + "type": "String" + } + }, + "acls": [ + { + "accessType": "READ", + "principalType": "ROLE", + "principalId": "$everyone", + "permission": "ALLOW" + } + ] +} \ No newline at end of file diff --git a/modules/worker/back/models/holiday.js b/modules/worker/back/models/holiday.js new file mode 100644 index 000000000..107452dd5 --- /dev/null +++ b/modules/worker/back/models/holiday.js @@ -0,0 +1,3 @@ +module.exports = Self => { + require('../methods/holiday/getByWarehouse')(Self); +}; diff --git a/modules/agency/back/models/labour-holiday.json b/modules/worker/back/models/holiday.json similarity index 50% rename from modules/agency/back/models/labour-holiday.json rename to modules/worker/back/models/holiday.json index a15b22675..678910f0a 100644 --- a/modules/agency/back/models/labour-holiday.json +++ b/modules/worker/back/models/holiday.json @@ -1,17 +1,17 @@ { - "name": "LabourHoliday", + "name": "Holiday", "base": "VnModel", "options": { "mysql": { - "table": "labourHoliday" + "table": "holiday" } }, "properties": { - "labourHolidayLegendFk": { + "holidayDetailFk": { "id": true, "type": "Number" }, - "labourHolidayTypeFk": { + "holidayTypeFk": { "id": true, "type": "Number" }, @@ -20,20 +20,26 @@ } }, "relations": { - "legend": { + "detail": { "type": "belongsTo", - "model": "LabourHolidayLegend", - "foreignKey": "labourHolidayLegendFk" + "model": "HolidayDetail", + "foreignKey": "holidayDetailFk" }, "type": { "type": "belongsTo", - "model": "LabourHolidayType", - "foreignKey": "labourHolidayTypeFk" + "model": "HolidayType", + "foreignKey": "holidayTypeFk" }, "workCenter": { "type": "belongsTo", "model": "WorkCenter", "foreignKey": "workCenterFk" } - } + }, + "acls": [{ + "accessType": "READ", + "principalType": "ROLE", + "principalId": "$everyone", + "permission": "ALLOW" + }] } \ No newline at end of file diff --git a/modules/worker/back/models/work-center-holiday.json b/modules/worker/back/models/work-center-holiday.json new file mode 100644 index 000000000..eddfd7af1 --- /dev/null +++ b/modules/worker/back/models/work-center-holiday.json @@ -0,0 +1,34 @@ +{ + "name": "WorkCenterHoliday", + "base": "VnModel", + "options": { + "mysql": { + "table": "workCenterHoliday" + } + }, + "properties": { + "workCenterFk": { + "id": true, + "type": "Number" + }, + "days": { + "type": "Number" + }, + "year": { + "type": "Number" + } + }, + "relations": { + "workCenter": { + "type": "belongsTo", + "model": "WorkCenter", + "foreignKey": "workCenterFk" + } + }, + "acls": [{ + "accessType": "READ", + "principalType": "ROLE", + "principalId": "$everyone", + "permission": "ALLOW" + }] +} \ No newline at end of file diff --git a/modules/agency/back/models/work-center.json b/modules/worker/back/models/work-center.json similarity index 52% rename from modules/agency/back/models/work-center.json rename to modules/worker/back/models/work-center.json index 44096bda7..03a335022 100644 --- a/modules/agency/back/models/work-center.json +++ b/modules/worker/back/models/work-center.json @@ -3,7 +3,7 @@ "base": "VnModel", "options": { "mysql": { - "table": "work-center" + "table": "workCenter" } }, "properties": { @@ -20,6 +20,17 @@ "type": "belongsTo", "model": "Warehouse", "foreignKey": "warehouseFk" - } - } + }, + "holidays": { + "type": "hasMany", + "model": "Holiday", + "foreignKey": "workCenterFk" + } + }, + "acls": [{ + "accessType": "READ", + "principalType": "ROLE", + "principalId": "$everyone", + "permission": "ALLOW" + }] } \ No newline at end of file diff --git a/modules/worker/back/models/worker-calendar.js b/modules/worker/back/models/worker-calendar.js new file mode 100644 index 000000000..ea603af41 --- /dev/null +++ b/modules/worker/back/models/worker-calendar.js @@ -0,0 +1,3 @@ +module.exports = Self => { + require('../methods/worker-calendar/absences')(Self); +}; diff --git a/modules/worker/back/models/worker-calendar.json b/modules/worker/back/models/worker-calendar.json new file mode 100644 index 000000000..569d4d1ba --- /dev/null +++ b/modules/worker/back/models/worker-calendar.json @@ -0,0 +1,35 @@ +{ + "name": "WorkerCalendar", + "base": "VnModel", + "options": { + "mysql": { + "table": "workerCalendar" + } + }, + "properties": { + "businessFk": { + "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", + "foreignKey": "absenceTypeFk" + } + } +} diff --git a/modules/worker/back/models/worker-labour.json b/modules/worker/back/models/worker-labour.json new file mode 100644 index 000000000..eae28cf89 --- /dev/null +++ b/modules/worker/back/models/worker-labour.json @@ -0,0 +1,43 @@ +{ + "name": "WorkerLabour", + "base": "VnModel", + "options": { + "mysql": { + "table": "workerLabour" + } + }, + "properties": { + "businessFk": { + "id": true, + "type": "Number" + }, + "started": { + "type": "Date" + }, + "ended": { + "type": "Date" + } + }, + "relations": { + "worker": { + "type": "belongsTo", + "model": "Worker", + "foreignKey": "workerFk" + }, + "department": { + "type": "belongsTo", + "model": "Department", + "foreignKey": "departmentFk" + }, + "workCenter": { + "type": "belongsTo", + "model": "WorkCenter", + "foreignKey": "workCenterFk" + }, + "holidays": { + "type": "belongsTo", + "model": "WorkCenterHoliday", + "foreignKey": "workCenterFk" + } + } +} diff --git a/modules/worker/front/calendar/index.html b/modules/worker/front/calendar/index.html new file mode 100644 index 000000000..bef551523 --- /dev/null +++ b/modules/worker/front/calendar/index.html @@ -0,0 +1,22 @@ + + + + +
Holidays
+ + {{'Used' | translate}} {{$ctrl.calendar.holidaysEnjoyed}} + {{'of' | translate}} {{$ctrl.calendar.totalHolidays}} {{'days' | translate}} + +
+
+ +
+ + +
+
+
+
diff --git a/modules/worker/front/calendar/index.js b/modules/worker/front/calendar/index.js new file mode 100644 index 000000000..e871de1cc --- /dev/null +++ b/modules/worker/front/calendar/index.js @@ -0,0 +1,113 @@ +import ngModule from '../module'; +import './style.scss'; + +class Controller { + constructor($scope, $http) { + this.$scope = $scope; + this.$http = $http; + this.months = this.monthsOfYear(); + this.events = []; + this.eventMap = {}; + } + + get worker() { + return this._worker; + } + + set worker(value) { + this._worker = value; + + if (!value) return; + + let params = {params: { + workerFk: this.worker.id, + started: this.started, + ended: this.ended + }}; + + let query = `/worker/api/WorkerCalendars/absences`; + this.$http.get(query, params).then(res => { + if (!res.data) return; + + this.setHolidays(res.data); + this.setWorkerCalendar(res.data); + + this.calendar = res.data.calendar; + }); + } + + setHolidays(data) { + const holidays = data.holidays; + const events = []; + + holidays.forEach(holiday => { + events.push({ + date: holiday.dated, + className: 'red', + title: holiday.detail.description || holiday.type.name, + isRemovable: false + }); + }); + this.events = this.events.concat(events); + } + + setWorkerCalendar(data) { + const absences = data.absences; + const events = []; + absences.forEach(absence => { + const absenceType = absence.absenceType; + events.push({ + date: absence.dated, + title: absenceType.name, + style: { + background: absenceType.rgb + } + }); + }); + this.events = this.events.concat(events); + } + + get started() { + const started = new Date(); + started.setHours(0, 0, 0, 0); + started.setMonth(0); + started.setDate(1); + + return started; + } + + get ended() { + const monthIndex = 11; + const ended = new Date(); + ended.setHours(0, 0, 0, 0); + ended.setMonth(monthIndex + 1); + // Last day of previous month (January) + ended.setDate(0); + + return ended; + } + + monthsOfYear() { + let months = new Array(12); + + for (let i = 0; i < months.length; i++) { + const currentDate = new Date(); + currentDate.setMonth(i); + currentDate.setDate(1); + + months[i] = currentDate; + } + + return months; + } +} + +Controller.$inject = ['$scope', '$http']; + +ngModule.component('vnWorkerCalendar', { + template: require('./index.html'), + controller: Controller, + bindings: { + worker: '<' + } +}); diff --git a/modules/worker/front/calendar/locale/es.yml b/modules/worker/front/calendar/locale/es.yml new file mode 100644 index 000000000..82939ce91 --- /dev/null +++ b/modules/worker/front/calendar/locale/es.yml @@ -0,0 +1,5 @@ +Calendar: Calendario +Holidays: Vacaciones +Used: Utilizados +of: de +days: días \ No newline at end of file diff --git a/modules/worker/front/calendar/style.scss b/modules/worker/front/calendar/style.scss new file mode 100644 index 000000000..70503336a --- /dev/null +++ b/modules/worker/front/calendar/style.scss @@ -0,0 +1,23 @@ +@import "variables"; + +.calendar-list { + align-items: flex-start; + flex-wrap: wrap; + justify-content: center; + + .calendar { + box-sizing: border-box; + padding: $pad-medium; + overflow: hidden; + width: 20em + } +} + +vn-horizontal.header { + justify-content: flex-end; + margin-bottom: 0.5em; + + .totalBox { + max-width: 15em + } +} \ No newline at end of file diff --git a/modules/worker/front/index.js b/modules/worker/front/index.js index 512e712c2..308de70fe 100644 --- a/modules/worker/front/index.js +++ b/modules/worker/front/index.js @@ -9,3 +9,4 @@ import './search-panel'; import './basic-data'; import './pbx'; import './department'; +import './calendar'; diff --git a/modules/worker/front/locale/es.yml b/modules/worker/front/locale/es.yml index a7a47d654..a4b13d34d 100644 --- a/modules/worker/front/locale/es.yml +++ b/modules/worker/front/locale/es.yml @@ -13,4 +13,5 @@ View worker: Ver trabajador Worker id: Id trabajador Fiscal Identifier: NIF User name: Usuario -Departments: Departamentos \ No newline at end of file +Departments: Departamentos +Calendar: Calendario \ No newline at end of file diff --git a/modules/worker/front/routes.json b/modules/worker/front/routes.json index 73b503058..8b2fe193d 100644 --- a/modules/worker/front/routes.json +++ b/modules/worker/front/routes.json @@ -5,7 +5,8 @@ "validations" : true, "menu": [ {"state": "worker.card.basicData", "icon": "settings"}, - {"state": "worker.card.pbx", "icon": ""} + {"state": "worker.card.pbx", "icon": "icon-pbx"}, + {"state": "worker.card.calendar", "icon": "icon-calendar"} ], "routes": [ { @@ -43,7 +44,8 @@ "worker": "$ctrl.worker" }, "acl": ["developer"] - }, { + }, + { "url": "/pbx", "state": "worker.card.pbx", "component": "vn-worker-pbx", @@ -53,6 +55,15 @@ }, "acl": ["hr"] }, + { + "url": "/calendar", + "state": "worker.card.calendar", + "component": "vn-worker-calendar", + "description": "Calendar", + "params": { + "worker": "$ctrl.worker" + } + }, { "url" : "/department", "state": "worker.department",