var TimeManagementEasyCalendar = (function ($) { 'use strict'; var me = { isInitialized: false, selector: { easyCalendar: '#easycalendar', easyCalendarLegend: '#easycalendar-legend', calendarattributes: '#calendarattributes' }, storage: { days: [], dataEndpoint: '', monthNames: [ 'Januar', 'Februar', 'März', 'April', 'Mai', 'Juni', 'Juli', 'August', 'September', 'Oktober', 'November', 'Dezember'], statusMapping: { 'unpaid': 'Unbezahlt', 'absent': 'Fehltag', 'away': 'Abwesend', 'vacation': 'Urlaub', 'request-vacation': 'Urlaubsantrag', 'remove-vacation': 'Stornoantrag Urlaub', 'sick': 'Krank', 'request-sick': 'Krankheitsantrag', 'remove-sick': 'Stornoantrag Krankheit' } }, init: function () { if (me.isInitialized === true) { return; } me.registerMonthNames(); me.drawCalendar(); me.drawLegend(); }, drawLegend: function () { for (let statusClass in me.storage.statusMapping) { let statusTxt = me.storage.statusMapping[statusClass]; let html = 'm' + statusTxt + ''; $(me.selector.easyCalendarLegend).append(html); } }, registerMonthNames: function () { if ($(me.selector.calendarattributes).length !== 0) { try { let calendarattributes = JSON.parse($(me.selector.calendarattributes).html()); me.storage.monthNames = calendarattributes.monthNames; } catch (e) { //do nothing, fallback from storage } } }, drawCalendar: function () { me.storage.dataEndpoint = $(me.selector.easyCalendar).data('endpoint'); $.ajax({ url: me.storage.dataEndpoint, type: 'POST', dataType: 'json', success: function (data) { if (data.error) { me.storage.$dialog.find(me.selector.msg).text(data.error); } else { let formattedData = []; if (data.is_expanded === true) { formattedData = me.buildCalendarDataExpanded(data.holidays, data.calendar_data, data.calendar_year); } else { formattedData = me.buildCalendarDataSummed(data.holidays, data.calendar_data, data.calendar_year); } let html = ''; for (let i = 0; i < formattedData.length; i++) { html += '
' + formattedData[i].txt + '
'; } $(me.selector.easyCalendar).append(html); } }, beforeSend: function () {} }); }, buildCalendarDataExpanded: function (holidays, vacations, year) { let dayAmount = 31; let monthAmount = 12; let currentMonth = new Date().getMonth() + 1; let allDays = me.buildCalendarFirstLine(year, dayAmount); for (let month = 1; month <= monthAmount; month++) { let daysInMonth = me.daysInMonth(year, month); let monthName = me.storage.monthNames[month - 1]; allDays.push({ txt: monthName, class: (currentMonth === month ? 'month today' : 'month'), title: '', year: year, month: month, day: 0 }); // first line with month for (let day = 1; day <= dayAmount; day++) { let classAndTitle = me.findClassAndTitle(daysInMonth, holidays, year, month, day); let htmlClass = classAndTitle.htmlClass; let title = classAndTitle.title; allDays.push({ txt: '', class: htmlClass, title: title, year: year, month: month, day: day }); } // month info by employee if (vacations) { for (let employeeName in vacations) { if (vacations.hasOwnProperty(employeeName)) { let employeeVacation = vacations[employeeName]; allDays.push({ txt: employeeName, class: 'employee-name', title: '', year: year, month: month, day: 0 }); for (let day = 1; day <= dayAmount; day++) { let classAndTitle = me.findClassAndTitle(daysInMonth, holidays, year, month, day); let htmlClass = classAndTitle.htmlClass; let title = classAndTitle.title; let date = me.buildDateString(year, month, day); if (date in employeeVacation) { let type = employeeVacation[date]; htmlClass += ' ' + type; title = me.mapTypeToName(type) + ': ' + employeeName; } allDays.push({ txt: '', class: htmlClass, title: title, year: year, month: month, day: day }); } } } } } return allDays; }, mapTypeToName: function (type) { if (type.search('half')) { type = type.replace('half', '').trim(); } if (type in me.storage.statusMapping) { return me.storage.statusMapping[type]; } return ''; }, buildCalendarFirstLine: function (year, dayAmount) { let allDays = []; let currentDay = new Date().getDate(); //first line with day-numbers for (let day = 0; day <= dayAmount; day++) { if (day === 0) { allDays.push({ txt: '', class: 'top', title: '', year: year, month: 0, day: 0 }); } else { allDays.push({ txt: day, class: (day === currentDay ? 'top today' : 'top'), title: '', year: year, month: 0, day: 0 }); } } return allDays; }, buildCalendarDataSummed: function (holidays, vacations, year) { let dayAmount = 31; let monthAmount = 12; let summedVacations = me.sumVacations(vacations); let allDays = me.buildCalendarFirstLine(year, dayAmount); let currentMonth = new Date().getMonth() + 1; for (let month = 1; month <= monthAmount; month++) { let daysInMonth = me.daysInMonth(year, month); let monthName = me.storage.monthNames[month - 1]; allDays.push({ txt: monthName, class: (currentMonth === month ? 'month today' : 'month'), title: '', year: year, month: month, day: 0 }); for (let day = 1; day <= dayAmount; day++) { let classAndTitle = me.findClassAndTitle(daysInMonth, holidays, year, month, day); let htmlClass = classAndTitle.htmlClass; let title = classAndTitle.title; let date = me.buildDateString(year, month, day); if (summedVacations.hasOwnProperty(date)) { let txt = ''; let typeAddress = summedVacations[date]; let countTypes = 0; for (let type in typeAddress) { countTypes++; } for (let type in typeAddress) { if (typeAddress.hasOwnProperty(type)) { let addresses = typeAddress[type]; txt += '
' + (addresses.length === 1 ? '' : addresses.length) + '
'; } } allDays.push({ txt: txt, class: htmlClass, title: title, year: year, month: month, day: day }); } else { allDays.push({ txt: '', class: htmlClass, title: title, year: year, month: month, day: day }); } } } return allDays; }, sumVacations: function (vacations) { let summedVacation = {}; for (let employeeName in vacations) { if (vacations.hasOwnProperty(employeeName)) { let employeeVacation = vacations[employeeName]; for (let date in employeeVacation) { if (employeeVacation.hasOwnProperty(date)) { let type = employeeVacation[date]; if (summedVacation.hasOwnProperty(date)) { let typeAddress = summedVacation[date]; if (typeAddress.hasOwnProperty(type)) { let addresses = typeAddress[type]; addresses.push(employeeName); typeAddress[type] = addresses; summedVacation[date] = typeAddress; } else { let typeAddress = summedVacation[date]; typeAddress[type] = [employeeName]; summedVacation[date] = typeAddress; } } else { let typeAddress = {}; typeAddress[type] = [employeeName]; summedVacation[date] = typeAddress; } } } } } return summedVacation; }, buildDateString: function (year, month, day) { return year + '-' + (month < 10 ? '0' + month : month) + '-' + (day < 10 ? '0' + day : day); }, findClassAndTitle: function (daysInMonth, holidays, year, month, day) { let date = me.buildDateString(year, month, day); let htmlClass = 'standard'; let title = ''; //always counting to 31, therefore some days dont exist if (day > daysInMonth) { htmlClass = 'noday'; } if (me.isSaturday(date) || me.isSunday(date)) { htmlClass = me.getWeekDayName(date); } else { htmlClass += ' ' + me.getWeekDayName(date); } // is a holiday if (date in holidays) { htmlClass = 'holiday'; title = holidays[date]; } return { htmlClass: htmlClass, title: title }; }, daysInMonth: function (year, month) { return new Date(year, month, 0).getDate(); }, isSaturday: function (dateString) { let day = new Date(dateString).getDay(); return (day === 6); }, isSunday: function (dateString) { let day = new Date(dateString).getDay(); return (day === 0); }, getWeekDayName: function (dateString) { let weekdays = ['sunday', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday']; let day = new Date(dateString).getDay(); return weekdays[day]; } }; return { init: me.init }; })(jQuery); $(document).ready(function () { TimeManagementEasyCalendar.init(); });