From 842b57520a6020f73c0b9fcb656c7bd37702db9e Mon Sep 17 00:00:00 2001 From: muahahahh Date: Tue, 5 Jan 2021 00:33:09 +0100 Subject: [PATCH] started adding employee functionality --- db.sqlite3 | Bin 176128 -> 176128 bytes .../__pycache__/__init__.cpython-38.pyc | Bin 0 -> 155 bytes .../__pycache__/admin.cpython-38.pyc | Bin 0 -> 196 bytes .../__pycache__/apps.cpython-38.pyc | Bin 0 -> 392 bytes .../__pycache__/models.cpython-38.pyc | Bin 0 -> 193 bytes .../__pycache__/urls.cpython-38.pyc | Bin 0 -> 776 bytes .../__pycache__/views.cpython-38.pyc | Bin 0 -> 2568 bytes .../handling_functions}/__init__.py | 0 .../data_import_functions.py | 62 ++++ employee_module/handling_functions/misc.py | 8 + .../monthly_planning_functions.py | 85 ++++++ .../__pycache__/__init__.cpython-38.pyc | Bin 0 -> 166 bytes employee_module/static/css/calendar.css | 108 +++++++ employee_module/static/css/calendar_local.css | 5 + .../static/css/hr_import_validation.css | 23 ++ employee_module/static/css/hr_module_base.css | 30 ++ .../css/hr_module_change_employee_data.css | 25 ++ .../static/css/hr_module_create_schedule.css | 38 +++ .../static/css/hr_module_import.css | 94 ++++++ .../static/css/hr_module_show_schedule.css | 44 +++ employee_module/static/js/calendar.js | 267 ++++++++++++++++++ employee_module/static/js/csrf_token.js | 17 ++ .../employee_module_change_employee_data.js | 62 ++++ .../js/employee_module_show_schedule.js | 173 ++++++++++++ .../templates/employee_module_base.html | 39 +++ .../employee_module_change_employee_data.html | 20 ++ .../templates/employee_module_home.html | 9 + .../templates/employee_module_login.html | 16 ++ .../employee_module_password_change.html | 16 ++ .../employee_module_show_schedule.html | 19 ++ employee_module/urls.py | 17 ++ employee_module/views.py | 63 ++++- hr_module/__pycache__/urls.cpython-38.pyc | Bin 716 -> 1023 bytes hr_module/__pycache__/views.cpython-38.pyc | Bin 7964 -> 8213 bytes .../data_import_functions.cpython-38.pyc | Bin 1751 -> 1825 bytes .../data_import_functions.py | 3 +- .../static/js/hr_module_create_schedule.js | 2 +- hr_module/templates/hr_module_home.html | 9 + hr_module/templates/hr_module_login.html | 16 ++ .../templates/hr_module_password_change.html | 16 ++ hr_module/urls.py | 5 + hr_module/views.py | 19 +- .../admin_2021-01-04T23:08:43.146410.xlsx | Bin 0 -> 5355 bytes manager_module/admin.py | 3 - manager_module/apps.py | 5 - manager_module/migrations/__init__.py | 0 manager_module/models.py | 3 - manager_module/tests.py | 3 - manager_module/views.py | 3 - static/css/base.css | 13 +- templates/base.html | 11 + timefall/__pycache__/settings.cpython-38.pyc | Bin 2610 -> 2766 bytes timefall/__pycache__/urls.cpython-38.pyc | Bin 986 -> 1040 bytes timefall/settings.py | 7 +- timefall/urls.py | 1 + 55 files changed, 1332 insertions(+), 27 deletions(-) create mode 100644 employee_module/__pycache__/__init__.cpython-38.pyc create mode 100644 employee_module/__pycache__/admin.cpython-38.pyc create mode 100644 employee_module/__pycache__/apps.cpython-38.pyc create mode 100644 employee_module/__pycache__/models.cpython-38.pyc create mode 100644 employee_module/__pycache__/urls.cpython-38.pyc create mode 100644 employee_module/__pycache__/views.cpython-38.pyc rename {manager_module => employee_module/handling_functions}/__init__.py (100%) create mode 100644 employee_module/handling_functions/data_import_functions.py create mode 100644 employee_module/handling_functions/misc.py create mode 100644 employee_module/handling_functions/monthly_planning_functions.py create mode 100644 employee_module/migrations/__pycache__/__init__.cpython-38.pyc create mode 100644 employee_module/static/css/calendar.css create mode 100644 employee_module/static/css/calendar_local.css create mode 100644 employee_module/static/css/hr_import_validation.css create mode 100644 employee_module/static/css/hr_module_base.css create mode 100644 employee_module/static/css/hr_module_change_employee_data.css create mode 100644 employee_module/static/css/hr_module_create_schedule.css create mode 100644 employee_module/static/css/hr_module_import.css create mode 100644 employee_module/static/css/hr_module_show_schedule.css create mode 100644 employee_module/static/js/calendar.js create mode 100644 employee_module/static/js/csrf_token.js create mode 100644 employee_module/static/js/employee_module_change_employee_data.js create mode 100644 employee_module/static/js/employee_module_show_schedule.js create mode 100644 employee_module/templates/employee_module_base.html create mode 100644 employee_module/templates/employee_module_change_employee_data.html create mode 100644 employee_module/templates/employee_module_home.html create mode 100644 employee_module/templates/employee_module_login.html create mode 100644 employee_module/templates/employee_module_password_change.html create mode 100644 employee_module/templates/employee_module_show_schedule.html create mode 100644 employee_module/urls.py create mode 100644 hr_module/templates/hr_module_home.html create mode 100644 hr_module/templates/hr_module_login.html create mode 100644 hr_module/templates/hr_module_password_change.html create mode 100644 import_reports/admin_2021-01-04T23:08:43.146410.xlsx delete mode 100644 manager_module/admin.py delete mode 100644 manager_module/apps.py delete mode 100644 manager_module/migrations/__init__.py delete mode 100644 manager_module/models.py delete mode 100644 manager_module/tests.py delete mode 100644 manager_module/views.py diff --git a/db.sqlite3 b/db.sqlite3 index 801844be4a7f4811c366233cfdbfb080e6d1acd9..74a63cc8850f6300ebd12641c2d0a642ac0accbc 100644 GIT binary patch delta 2750 zcmb_eT}<0n6t?5=lMr&#vX&wUkQUe&3fPI0*hrOX0wF*lgz}ee5|}t7juSgL&aWy3 z+D)svm#)!DwLWZ`+Np2rpj+PBO55YKYA^lSrm5PbYHcUA)wI1-lV+EM20FFcgl*k> zkI%XHeCN-{%XhWQceSS*;in%oIpL>Y%vbbusKH0O0n!PF#JQ-zBqD*iScK+VYV}A9 zOedt!Tp}J2@%8t6l4za&7*tvF0IIzSqWW94R$ad4LB4gqBahDO)?M=#YH}+bcrCQj zNmUygY}Fc5eQbea7AF@N>{u8OerebZuE} z&?351kp6b|+!ot$NkM%nSc2^-2TxTA|9%tKn{g7}E! z@FW6$FNrT;p`$Dog=l07v=`NgPcjfxh*zZ4bFl#t@H78{Re8NnW2v=d}r_3@Ql$`|8$M=2uV zAyAeVe3NcxUzQx07@1DZhN#rwk}GIF%*`biJoVE#rm@n;hg}vdZ zUy}NgBE`lqpT{?h4sgRBN5C(Pr$;h&U%98SUaP&=N_OL@9Y-Bn`D=lIGY}{M zWvl!)@y6}q@{dLle9?&V)4}&pPswY=IX`b`vYH#V9fLYvrd8hBllL0B&YV^oDnSnf zdcZC488`vvflE%WyLsWk2~R%=S0TMU*~Chh8ipxO^>R^L^o>eWkv3Wci* zcLdcNt#x2cPMz}*xCGA28T$lW1vlhF-vhbwIM-;9dYERSEMF<3(Unf#-V(JhwnR-? z50v|Obr~tQ#40WLO;-Oi1b&q(QYqQrW#ZYjUcdYe*sn%3aE&r3dezE8s|*@ts8)um Fe*iFp7A^n) delta 1514 zcmah}O>7%Q6rP!N+}N@A*>MsViXEFKr6u*>+HsozQrwh43xx(s0VycnjlCQHZm>5l zjgV?laRQ=7dsqnx6e@%wAt1y7BM!tWqT*CQLP10vQsu%0B`E?90f||+38|q%TD{qM z^WOKq`DWgfSIy;B^QC?G%FI23_{zueroaIP-fRWt5FRg#=H$d=HaR+xmA(18##T9=V^89sv?w6it#Wz`cupa$cX%252>7ONtO5+?})9Rxw0 z&N$sqA}4BgI(^M1ucN5&1tlR$N=Qi-6^{O?AEccZ=!g*0rU!OAj?h4FJy1*)ippr7 z&n1PBAWFNYqBJ0iqJK=zaX~KV3vs?+^q*yf$k#enyR(O4*>7TP*QCYu(!2B3FVe;? zodUU3=i08P?Qo^FO9_!u6iTWqbC;VuTgP_Xw}UN-b$)c9`1G~DMp^bi^j6aOp(tgl7+KAi)una{|4*569+mU1&$ zK9?GsQg|QBcyUHP$7hQfKFuHAHBF`Yo`tf(){NN|#I8VF#p`*UB{;1P+XfE4vY#}a zy7){?&i5*%mx9T$WGbp05mQ2n7c-m?DTZ=NsdO}_uDrE)RvDC@@6SYDERG!yJr{dK zp5T4yoHATEKXg769rPWO9zK&kaXfu8Ci~KZ(am zenJ?k2&z!6*vs$3p)TeW{y!3gHcJ#Os)ufDpzgxk#wyMf>nNU$54t%m!nkJj)DtQxmHR^7OU z+q}&ft|Pb(Us8IX1Ab^Gc6Xj z0p5d)5QiZMP;ojyyI&@*eN9G}-DNV3r<826z|-#D{_`3%K_>TNMtfBsh&CsaAjZ`n zWpdC{fB#?(!5l15$!@?Bd`m%9$c>m7C*~8mRNiP|TzDI;sj(Xj|L%s}a?);Skkee> m#~Ok^;SXBy7x)?0Xvu5f_8J%yHtMEHHwN7>x*-f>GW`wUVy#U8 diff --git a/employee_module/__pycache__/__init__.cpython-38.pyc b/employee_module/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..95892743d4a8008889bfc551bec6462dbd935806 GIT binary patch literal 155 zcmWIL<>g`kg5L*r#e?X_AOaaM0yz#qT+9L_QW%06G#UL?G8BP?5yUSC{fzwFRQ-a) zveX>?fXd{I#G>4QqWrAXg`kg5L*r#oGhv#~=SiVz0(JS z{gmts2UgmSUZ!!INLeb2Qnq6`(3DT4d^#vIC~=5yP$jgigYUU0oJHZ)Ga9jK@vgmv|jZhfkEs@%9)=&OR(DSvDGY(zqv O%=;%?g`eo=O!zN4%U=or literal 0 HcmV?d00001 diff --git a/employee_module/__pycache__/models.cpython-38.pyc b/employee_module/__pycache__/models.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6e4019c511ab1e5f3000ad1d26db608027e03c11 GIT binary patch literal 193 zcmWIL<>g`kg5L*r#ajaD#~=(C&v_Te5rXmQ^UtF45c*-kzhe&IC4A~T7>X$7sKGhL zh>oboM~#VIRQW&&LeYfCcrW4(XUq9stqs!2@;*?DR|c7160QH)79GNTL050l=IRkDM;mPXj_C3c4^4-X0(RV#P%q;k|St>LDIL&m2>Pxt7Y|JOOCoUk+sFpqmXo6FV{?8 z+vdE7&Y1~Oz1u{B231>%EX$~`e#rTypCqFRo{?& zW*yf2zRhfFvX0y_p6$*cP&PX$YPQ!Z(^bPh63(+r8-_>Btj2A3HsS3+ys&!J4VXEG PIr6;J_!7VJ9~`*FnY2ie=2c5trAg|r)X)5UNxT?&_sOd!vsy|8E2b$K>j4wuuFa3x(0R}HTr z*V1$0xtYE5;d$N+F9=6m;H^Ez+r0C_+GXK8bItCin-Tw6QsS`8WGxOwHDaZy=geCfwFRJdYe8wxW! z`1bDD+xNMBz{a(Tac7TB?aCepfkuPPW!!(#u;YFT=gSzcb+OYPP-N$V~)o^ zkeK7~H^ugCq?`k+12`iZ5r2%^YZjssx!hf|5Q&U?uW(#d8`t)O%HjTjJ#}W3YbaOM zE4y+kcNg1>YK)uXR%P=VBHL4Kq&k&HyW2Jo_Ux&z7Ak+gdw?Z>T2qTvjn{dDFl=z! z+<LzKK1dK2-bPEeA>|jom6NyJ3@^wy`6{{RdAnfSt^Cq*7Rg_EWeOr^vw4ibwA1jWMlp5d(7d%u1pR{kj zQ9H$hM{?(+sm=`p)lwh;>&tI8k(5Kg|AH_U1-ciPhy)IwBO~mdC}NisvOEf5lPsI) zoqOH=XQHNfHD>}N?7u*5(}WhfbX 0: + for day in plan: + planned_time_start = day.begin_time + planned_time_end = day.end_time + + if planned_time_start <= end_time and planned_time_end >= start_time: + return True + else: + return False + else: + return False + + +def create_planning_operation_report(dict_, current_user): + df = pd.DataFrame(dict_) + filename = current_user + '_' + datetime.datetime.now().isoformat() + '.xlsx' + path_temp = settings.IMPORT_REPORT_STORAGE + filename + df.to_excel(path_temp, index=False) + return filename \ No newline at end of file diff --git a/employee_module/migrations/__pycache__/__init__.cpython-38.pyc b/employee_module/migrations/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6d96e3b493802d88bd874a68fb4d5aa4a6cec790 GIT binary patch literal 166 zcmWIL<>g`kg5L*r#e?X_AOaaM0yz#qT+9L_QW%06G#UL?G8BP?5yUTV{fzwFRQ-a) zveX>?fXd{I#G>4QqWrAX') + buttonForwards.addEventListener('click', function(){ + var currentMonth = parseInt(calendarContainer.getAttribute('month_shown')) + var currentYear = parseInt(calendarContainer.getAttribute('year_shown')) + + if (currentMonth == 12){ + currentMonth = 1 + currentYear = currentYear + 1 + } else { + currentMonth = currentMonth + 1 + } + console.log(currentYear, currentMonth, monthsAhead) + renderCalendarFor(calendarContainer,monthsBlock, currentYear, currentMonth, monthsAhead, weekStart) + }) + return buttonForwards +} + +function createDateSelector(calendarContainer, monthsBlock, monthsAhead, weekStart){ + var dateSelector = createDateSelectionHTML() + + var buttonGoToDate = dateSelector.querySelector('#button_load_selected_months') + buttonGoToDate.addEventListener('click', function(){ + var currentYear = parseInt(dateSelector.querySelector('#year_selector').value) + var currentMonth = parseInt(dateSelector.querySelector('#month_selector').value) + 1 + console.log(currentMonth, currentYear) + renderCalendarFor(calendarContainer,monthsBlock, currentYear, currentMonth, monthsAhead, weekStart) + }) + return dateSelector +} + + +function renderCalendarFor(calendarContainer, monthsBlock, year, month, nMonths, weekStart){ + + monthsBlock.innerHTML = '' + calendarContainer.setAttribute('month_shown', month.toString()) + calendarContainer.setAttribute('year_shown', year.toString()) + var monthToCreate = month - 1 + for (var i = 0; i < nMonths; i++){ + monthToCreate = monthToCreate + 1 + if (monthToCreate == 13){ + monthToCreate = 1; + year = year + 1; + // console.log(monthToCreate, month, year, nMonths) + } + + var monthContainer = document.createElement('div') + monthContainer.className = 'month_container' + + monthContainer.appendChild(renderMonth(year, monthToCreate, weekStart)) + monthsBlock.appendChild(monthContainer) + } +} + + +function renderMonth(year, month, weekStart = 0, daysOfWeekNumeric){ + var daysOfWeek = ['sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat'] + var daysOfWeekNumeric = [0, 1, 2, 3, 4, 5, 6] + for (var i = 0; i < weekStart; i++){ + daysOfWeek.push(daysOfWeek.shift()) + daysOfWeekNumeric.push(daysOfWeekNumeric.shift()) + } + + var table = document.createElement('table') + var monthString = monthsStrings[month - 1] + createHeaders(table, year, monthString, daysOfWeek) + createDates(table, year, month, daysOfWeekNumeric) + + return table +} + + +function createHeaders(table, year, month, daysOfWeek){ + let monthHeaderRow = document.createElement('tr') + let monthHeader = document.createElement('th') + monthHeader.innerText = month + ' ' + year + monthHeader.className = "month_header" + monthHeader.colSpan = 7 + monthHeaderRow.appendChild(monthHeader) + table.appendChild(monthHeaderRow) + + let header = document.createElement('tr') + for (var i = 0; i < daysOfWeek.length; i++){ + var headerDay = document.createElement('th') + var headerText = document.createElement('div') + headerText.innerText = daysOfWeek[i] + headerText.className = 'weekday_header' + headerDay.appendChild(headerText) + header.appendChild(headerDay) + table.appendChild(header) + } +} + +function createDates(table, year, month, daysOfWeekNumeric){ + var weekEnd = daysOfWeekNumeric[daysOfWeekNumeric.length - 1] + + var daysOfMonth = daysArray(year, month, daysOfWeekNumeric) + var row = document.createElement('tr') + for (var i = 0; i < daysOfMonth.length; i++){ + var date = daysOfMonth[i] + var dayNr = date.getDate() + var cell = document.createElement('td') + var dateString = new Date(date.getTime() - (date.getTimezoneOffset() * 60000 )) + .toISOString() + .split("T")[0]; + + var dateContainer = document.createElement('div') + dateContainer.innerText = dayNr + dateContainer.className = 'days_of_month' + + if (month - 1 == date.getMonth()){ + dateContainer.classList.add('days_of_month_current') + dateContainer.id = 'date_' + dateString + today.setHours(0, 0, 0, 0) + if(today.getTime()==date.getTime()){ + dateContainer.classList.add('days_of_month_today') + } + } else { + dateContainer.classList.add('days_of_month_not_current') + } + + + dateContainer.setAttribute('date', dateString) + + cell.appendChild(dateContainer) + + row.appendChild(cell) + + + if (date.getDay() == weekEnd) { + table.appendChild(row) + var row = document.createElement('tr') + + } + + } + table.appendChild(row) +} + +function daysArray(year, month, daysOfWeekNumeric) { + month = month - 1 + + var arr = [] + var daysInCurrentMonth = daysInMonth(year, month + 1) + + var firstDayOfMonth = new Date(year, month, 1).getDay() + var blankDaysStart = daysOfWeekNumeric.indexOf(firstDayOfMonth) * -1 + + for (var i = blankDaysStart + 1; i < 1; i++){ + var date = new Date(year, month, i) + arr.push(date) + } + + for (var i = 1; i < daysInCurrentMonth + 1; i++){ + var date = new Date(year, month, i) + arr.push(date) + } + + var daysToFill = arr.length + for (var i = 1; i < 42 - daysToFill + 1; i++){ + var date = new Date(year, month + 1, i) + arr.push(date) + } + + return arr +} + +function daysInMonth (year, month) { + return new Date(year, month, 0).getDate(); +} + + +function createDateSelectionHTML(){ + + var container = document.createElement('div') + container.id = 'date_selector' + + var goButton = document.createElement('button') + goButton.innerText = 'Go' + goButton.id = 'button_load_selected_months' + + var label = document.createElement('label') + label.setAttribute('for', 'years') + label.innerText = 'Go to: ' + + var selectYear = document.createElement('select') + selectYear.name='years' + selectYear.id = 'year_selector' + + spanBegin = 1990 + spanEnd = 2030 + yearsSpan = spanEnd - spanBegin + for (var i = 0; i < yearsSpan; i++){ + var option = document.createElement('option') + option.value = spanBegin + i + option.innerText = option.value + selectYear.appendChild(option) + } + selectYear.value = today.getFullYear() + + var selectMonth = document.createElement('select') + selectMonth.name='months' + selectMonth.id = 'month_selector' + for (var i = 0; i < 12; i++){ + var option = document.createElement('option') + option.value = i; + option.innerText = monthsStrings[i] + selectMonth.appendChild(option) + } + + selectMonth.value = today.getMonth() + + container.appendChild(label) + container.appendChild(selectYear) + container.appendChild(selectMonth) + container.appendChild(goButton) + return container +} + + +function createButton(id, className, innerText){ + var button = document.createElement('div') + button.id = id + button.className = className + button.innerText = innerText + return button +} \ No newline at end of file diff --git a/employee_module/static/js/csrf_token.js b/employee_module/static/js/csrf_token.js new file mode 100644 index 0000000..e32f7e3 --- /dev/null +++ b/employee_module/static/js/csrf_token.js @@ -0,0 +1,17 @@ + + +function getCookie(name) { + let cookieValue = null; + if (document.cookie && document.cookie !== '') { + let cookies = document.cookie.split(';'); + for (let i = 0; i < cookies.length; i++) { + let cookie = cookies[i].trim(); + + if (cookie.substring(0, name.length + 1) === (name + '=')) { + cookieValue = decodeURIComponent(cookie.substring(name.length + 1)); + break; + } + } + } + return cookieValue; +} \ No newline at end of file diff --git a/employee_module/static/js/employee_module_change_employee_data.js b/employee_module/static/js/employee_module_change_employee_data.js new file mode 100644 index 0000000..6d3156f --- /dev/null +++ b/employee_module/static/js/employee_module_change_employee_data.js @@ -0,0 +1,62 @@ +const csrftoken = getCookie('csrftoken'); + +var searchEmployeeButton = document.getElementById('load_employee_data_button') +searchEmployeeButton.addEventListener('click', function(){ + fetchSearchEmployeeData() +}) + +function fetchSearchEmployeeData() { + var host = 'http://' + window.location.host; + var fetch_url = host + '/hr_module/change_employee_data_api' + var username = document.getElementById('username_input').value + + fetch(fetch_url, + { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'X-CSRFToken': csrftoken + }, + body: JSON.stringify({ + "username": username + }), + }).then((response) => { + return response.json(); + }).then((data) => { + console.log(data); + loadValuesIntoPage(data) + }); +} + +function loadValuesIntoPage(data){ + var order = ['username', 'first_name', 'last_name', 'email', 'department', 'manager_username', 'time_model_id', 'manager_flag', 'is_active', 'is_staff', 'is_superuser'] + + var informationContainer = document.getElementById('search_results') + + for (var i = 0; i < order.length; i++){ + var field = order[i] + var value = data[field] + + var fieldContainer = document.createElement('div') + fieldContainer.className = 'field_container' + + if (typeof(value) === 'boolean'){ + var httpfield = document.createElement('input') + httpfield.type = 'checkbox' + httpfield.checked = value + httpfield.setAttribute('disabled', 'disabled') + } else { + var httpfield = document.createElement('div') + httpfield.innerHTML = value + } + var label = document.createElement('label') + label.setAttribute('for', field) + label.innerText = field.replace('_', ' ') + httpfield.id = field + httpfield.className = 'database_field' + + fieldContainer.appendChild(label) + fieldContainer.appendChild(httpfield) + informationContainer.appendChild(fieldContainer) + } +} \ No newline at end of file diff --git a/employee_module/static/js/employee_module_show_schedule.js b/employee_module/static/js/employee_module_show_schedule.js new file mode 100644 index 0000000..d76afe0 --- /dev/null +++ b/employee_module/static/js/employee_module_show_schedule.js @@ -0,0 +1,173 @@ + +const csrftoken = getCookie('csrftoken'); + + +// document.onload = parent.appendChild(addCalendar(monthsAhead=3)) + +window.addEventListener('load', function(){ + var parent = document.getElementById('calendar_box') + parent.appendChild(addCalendar(monthsAhead=3)) + fetchDays() + formatCalendarContainerSize(document.getElementById('calendar_container')) + document.getElementById('calendar_button_back').addEventListener('click', function(){ + fetchDays() + }) + document.getElementById('calendar_button_forwards').addEventListener('click', function(){ + fetchDays() + }) + document.getElementById('button_load_selected_months').addEventListener('click', function(){ + fetchDays() + }) + +}) + + + +function fetchDays(){ + var host = 'http://' + window.location.host; + var fetch_url = host + '/employee_module/show_employee_plan_api' + + var range = searchedDateRange() + var startDate = range['min'] + var endDate = range['max'] + + fetch(fetch_url, + { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'X-CSRFToken': csrftoken + }, + body: JSON.stringify({ + "start_date": startDate, + "end_date" : endDate + }), + }).then((response) => { + return response.json(); + }).then((data) => { + console.log(data); + addClassToWorkingDays(data); + + var parent = document.getElementById('hr_module_main_container') + + var listContainer = document.getElementById('list_container') + if (listContainer == null){ + var listContainer = document.createElement('div') + listContainer.id = 'list_container' + } else { + listContainer.innerHTML = '' + } + listContainer.appendChild(createDetailedCalendarRecords(data)) + parent.appendChild(listContainer) + formatTableSize() + }); +} + +function addClassToWorkingDays(data){ + for (var i = 0; i < data.length; i++){ + var processedDate = data[i]['date'] + var processedActivityType = data[i]['activity_type'] + var nodeToChange = document.getElementById('date_' + processedDate) + nodeToChange.classList.add('days_of_month_' + processedActivityType) + } +} + +function createDetailedCalendarRecords(data){ + var table = createDetailedHeaders() + + for (var i = 0; i < data.length; i++){ + var index = data[i]['id'] + var username = data[i]['username_id'] + + var row = table.insertRow(-1) + row.id = 'database_id_' + index.toString() + row.setAttribute('database_username', username) + + appendCell(row, 'div', 'date', data[i]['date'], 0) + appendCell(row, 'div', 'begin_time', data[i]['begin_time'], 1) + appendCell(row, 'div', 'end_time', data[i]['end_time'], 2) + appendCell(row, 'div', 'activity_type', data[i]['activity_type'], 3) + } + return table +} + +function appendCell(tableRow, tag, tagName, tagText, cellIndex){ + var cell = tableRow.insertCell(cellIndex) + var textInput = document.createElement(tag) + textInput.innerText = tagText + textInput.name = tagName + cell.appendChild(textInput) +} + +function createDetailedHeaders(){ + var table = document.createElement('table') + let headerRow = document.createElement('tr') + let columns = ['Date', 'Start time', 'End time', 'Activity type'] + for (let i = 0; i < columns.length; i++){ + var headerCell = document.createElement('th') + var headerText = document.createElement('div') + headerText.innerText = columns[i] + headerCell.appendChild(headerText) + headerRow.appendChild(headerCell) + + } + table.appendChild(headerRow) + table.id = 'detailed_plan_records' + return table +} + +function formatCalendarContainerSize(calendarContainer){ + + var monthsBlock = calendarContainer.querySelector('#months_block') + var calendarButton = calendarContainer.querySelector('#calendar_button_back') + var dateSelector = calendarContainer.querySelector('#date_selector') + + var widthMonths = monthsBlock.offsetWidth + var heightMonths = monthsBlock.offsetHeight + var heightDateSelector = dateSelector.offsetHeight + var widthCalendarButton = calendarButton.offsetWidth * 2 + + var widthTotal = widthMonths + widthCalendarButton + var heightTotal = heightMonths + heightDateSelector + + calendarContainer.setAttribute('style','height:' + heightTotal +'px; width:' + widthTotal + 'px'); +} + +function formatTableSize(){ + var calendar = document.getElementById('calendar_container') + var tableDiv = document.getElementById('list_container') + var width = calendar.offsetWidth + tableDiv.setAttribute('style', 'width:' + width + 'px') +} + +function searchedDateRange(){ + var dates = document.getElementsByClassName('days_of_month_current') + + var datesArray = [] + for (var i = 0; i < dates.length; i++){ + var dateAttr = new Date(dates[i].getAttribute('date')) + datesArray.push(dateAttr) + } + var minDate = new Date(Math.min.apply(null, datesArray)) + var maxDate = new Date(Math.max.apply(null, datesArray)) + var out = {'min' : minDate, + 'max': maxDate} + console.log(out) + return out +} + +function getCookie(name) { + let cookieValue = null; + if (document.cookie && document.cookie !== '') { + let cookies = document.cookie.split(';'); + for (let i = 0; i < cookies.length; i++) { + let cookie = cookies[i].trim(); + + if (cookie.substring(0, name.length + 1) === (name + '=')) { + cookieValue = decodeURIComponent(cookie.substring(name.length + 1)); + break; + } + } + } + return cookieValue; +} diff --git a/employee_module/templates/employee_module_base.html b/employee_module/templates/employee_module_base.html new file mode 100644 index 0000000..3ca6abe --- /dev/null +++ b/employee_module/templates/employee_module_base.html @@ -0,0 +1,39 @@ +{% extends 'base.html' %} +{% load static %} + +{% block stylesheet_hr_module_base %} + +{% endblock %} + + + +{% block core_content %} + + + + +
+{% block action_panel %} +{% endblock %} +
+ + + +{% endblock %} \ No newline at end of file diff --git a/employee_module/templates/employee_module_change_employee_data.html b/employee_module/templates/employee_module_change_employee_data.html new file mode 100644 index 0000000..31d4a1c --- /dev/null +++ b/employee_module/templates/employee_module_change_employee_data.html @@ -0,0 +1,20 @@ +{% extends 'employee_module_base.html' %} + +{% load static %} + +{% block action_panel %} + + + +
+ + + +
+
+ +
+ + + +{% endblock %} diff --git a/employee_module/templates/employee_module_home.html b/employee_module/templates/employee_module_home.html new file mode 100644 index 0000000..0a47868 --- /dev/null +++ b/employee_module/templates/employee_module_home.html @@ -0,0 +1,9 @@ +{% extends 'employee_module_base.html' %} + +{% load static %} + +{% block action_panel %} + +

Welcome to Timefall - time tracking application, employee section

+ +{% endblock %} \ No newline at end of file diff --git a/employee_module/templates/employee_module_login.html b/employee_module/templates/employee_module_login.html new file mode 100644 index 0000000..3e88a5f --- /dev/null +++ b/employee_module/templates/employee_module_login.html @@ -0,0 +1,16 @@ +{% extends 'base.html' %} +{% load static %} + +{% block core_content %} + + +

Please login

+ +
+ {% csrf_token %} + {{ form.as_p }} + + +
+ +{% endblock %} \ No newline at end of file diff --git a/employee_module/templates/employee_module_password_change.html b/employee_module/templates/employee_module_password_change.html new file mode 100644 index 0000000..04c6fd0 --- /dev/null +++ b/employee_module/templates/employee_module_password_change.html @@ -0,0 +1,16 @@ +{% extends 'base.html' %} +{% load static %} + +{% block core_content %} + + +

Please change your password

+ +
+ {% csrf_token %} + {{ form.as_p }} + + +
+ +{% endblock %} \ No newline at end of file diff --git a/employee_module/templates/employee_module_show_schedule.html b/employee_module/templates/employee_module_show_schedule.html new file mode 100644 index 0000000..db4e148 --- /dev/null +++ b/employee_module/templates/employee_module_show_schedule.html @@ -0,0 +1,19 @@ +{% extends 'employee_module_base.html' %} + +{% load static %} + +{% block action_panel %} + + + + +
+
+
+
+ + + + + +{% endblock %} diff --git a/employee_module/urls.py b/employee_module/urls.py new file mode 100644 index 0000000..982a7be --- /dev/null +++ b/employee_module/urls.py @@ -0,0 +1,17 @@ + +from django.urls import path +from . import views +from django.contrib.auth import views as auth_views + +app_name = 'employee_module' + +urlpatterns = [ + path('login', auth_views.LoginView.as_view(template_name='hr_module_login.html'), name='login'), + path('logout', auth_views.LogoutView.as_view(), name='logout'), + path('change_password', auth_views.PasswordChangeView.as_view(template_name='hr_module_password_change.html'), name='change_password'), + path('home', views.homepage, name='homepage'), + path('show_schedule', views.manage_schedule, name='show_schedule'), + path('show_employee_plan_api', views.show_employee_plan_api, name='show_employee_plan_api'), + path('change_employee_data', views.change_employee_data, name='change_employee_data'), + path('change_employee_data_api', views.change_employee_data_api, name='change_employee_data_api'), +] \ No newline at end of file diff --git a/employee_module/views.py b/employee_module/views.py index ef8db10..a80c2e2 100644 --- a/employee_module/views.py +++ b/employee_module/views.py @@ -1,5 +1,66 @@ from django.shortcuts import render -from django.http import HttpResponse +from django.contrib.auth.decorators import login_required +from hr_module.handling_functions.data_import_functions import read_and_parse_excel, insert_excel +from hr_module.handling_functions.monthly_planning_functions import insert_into_plan, create_planning_operation_report +from hr_module.handling_functions.misc import dictfetchall +import pandas as pd +import json +from hr_module.models import Employee, PlanCreationLog, Plan +from django.contrib.auth.models import User +from django.http import HttpResponse, JsonResponse, Http404 +from django.db import connection +import datetime + +login_url = '/hr_module/login' # Create your views here. +@login_required(login_url=login_url) +def homepage(request): + template_name = 'employee_module_home.html' + return render(request, template_name) + +@login_required(login_url=login_url) +def change_employee_data(request): + template_name = 'employee_module_change_employee_data.html' + return render(request, template_name) + +def change_employee_data_api(request): + if request.method == 'POST': + if request.user.is_authenticated: + username = request.user.username + empl = User.objects.select_related('employee').get(username=username) + record_employee = empl.employee.__dict__ + record_user = empl.__dict__ + response_dict = dict(record_user, **record_employee) + for i in ['_state', 'password']: + response_dict.pop(i) + print(response_dict) + return JsonResponse(response_dict, safe=False) + else: + return JsonResponse({'error': 'not_authenticated'}) + + +@login_required(login_url=login_url) +def manage_schedule(request): + template = 'employee_module_show_schedule.html' + return render(request, template) + + +def show_employee_plan_api(request): + if request.method == 'POST': + body = json.loads(request.body) + username = request.user.username + start_date = body['start_date'].split('T')[0] + end_date = body['end_date'].split('T')[0] + + start_date = datetime.datetime.strptime(start_date, '%Y-%m-%d') + end_date = datetime.datetime.strptime(end_date, '%Y-%m-%d') + + print(username, start_date, end_date) + + user_obj = Employee.objects.get(pk=username) + + query_result = Plan.objects.filter(username=user_obj, date__range= [start_date, end_date]) + response = list(query_result.values()) + return JsonResponse(response, safe=False) diff --git a/hr_module/__pycache__/urls.cpython-38.pyc b/hr_module/__pycache__/urls.cpython-38.pyc index 424aa277a3fdf82284d4ce9a757267700d568745..9d71915481b9e68f31c4a2f5bcad444c9d9f3726 100644 GIT binary patch literal 1023 zcmZvbyN=U96o$vSY#b-C6X&`hZH0u=#NAd1A<-ff2?3HDYseYmM80Xp*(m!46#EWP z@=DWEZ3`V0=Qy*;BCW0bp6{PCw{s>Rdp(EY^ZDDK=w*|!Uj&aIAK?xDlx;Bv46KBu zR%lraYEVyVX+5lCn_;_w?IyMx;f1iEDVp2X)`kmc-64T}S4X#vZu`6agF)Lk4mu9T zb*ebWxLr}-cA#g-Me2fU$V2LZXQ+?l!oZM^?xO4dOx4)4s0Lh1gCot(D4_=LEEp6SMD{XLcKugTKLu) O^@-(M6U%+-{rwM588u7* delta 383 zcmZY5KT88K6aes~x&QxL4}=z6rBDPnM`v*pms^g|7pmoY7joCZ$qyhM*;aX>KMUq8zSM#!7S-$)SW*xP6FxR~8rg(WE1 zf~{?^!PzmCi*mp<@=z}LMghu$&?rLr5E;d&0AiyA6+&W^q9RC*GE@v1IMd$?$H)Z6 zdU6#MDNL@&{GdOh$A{@s3EqjaUET=TR$@*EtLB^jgYGZ0A%r!rSIx;*RjnG~qXwcZ zJ$PKo64wdkAeE<+kExhc4Tn-}WYydW(Ux4^D*a#mDa&Un#cBxgG|9V8sJeY3D%X4S Te#b73rdUQa8d)r%|Jv6NF%?*L diff --git a/hr_module/__pycache__/views.cpython-38.pyc b/hr_module/__pycache__/views.cpython-38.pyc index 758c979667c84f1ca4c7b0273d473e0d83f8edb4..2c04ddba852968501751a2e401885ce3c6e15d8d 100644 GIT binary patch delta 2302 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 bNO+?FS@G+dLO!D5->9}js{rP-sFwd9e9q(L diff --git a/hr_module/handling_functions/__pycache__/data_import_functions.cpython-38.pyc b/hr_module/handling_functions/__pycache__/data_import_functions.cpython-38.pyc index 03703216a824ca075a103a1a7a5713e203e01233..e5945fb38fbe1e91c1c4d5f84125f8acc13ffadd 100644 GIT binary patch delta 476 zcmZ9IzfZzI6vz8YTaMBq3KAnB4kRZ02!qiKzOwT=L$#ckkWzeeS;O=Zt-1+omGcYxLuer*;Vrr?q-bp;|vV zAPxbATGXJ)2{d;*_Q1RF-J!?Wb%^xsaUVeE-*5mK zUR4nYe^QH(eg9B(*v*J}ICD#47w6IUsOtq(Tu0`+{>`c1FNzAAk%0;8!ZLs*{+lSl zEnn5jMr2U!9(YqLLy{lQ{GIkvSd)T@(=c#Sy^c`ov4~-gxAb;`V3t4V)dFgw$1$SN zWtaVmhH?_7`KP{FUjVau0rN4M1C=FEQ#b`y1dPQujP1sbNGpK43|4Fm#Unh11(C*S zdhP{hVMDNVP!%V*#m7dz6Bqvr5%x|R-YDuex*qHL$YyMqmE9%jr2hP;7SKp*5YkcK R-;>Hr7717&%~H)AA%Ef_ZDard delta 423 zcmZ8d%}T>S5YD8VpT?xcsx4GSupmTxQF@Z%K~YbhiWDLeLN;O{{c*N}f*?pAz_L#u zdh{X%4?c)OU%&_OL7Ua3n$XJ+{BV%(uF#Fw5T%|rkMU0O8F*d3*I^9-BB-o$o zTUV631R4}bn=KE`TB$}?A5h8iow3=Yog#rt^3g0dw<#Go#1WAZx$Z33_8$~JRWelcome to Timefall - time tracking application + +{% endblock %} \ No newline at end of file diff --git a/hr_module/templates/hr_module_login.html b/hr_module/templates/hr_module_login.html new file mode 100644 index 0000000..3e88a5f --- /dev/null +++ b/hr_module/templates/hr_module_login.html @@ -0,0 +1,16 @@ +{% extends 'base.html' %} +{% load static %} + +{% block core_content %} + + +

Please login

+ +
+ {% csrf_token %} + {{ form.as_p }} + + +
+ +{% endblock %} \ No newline at end of file diff --git a/hr_module/templates/hr_module_password_change.html b/hr_module/templates/hr_module_password_change.html new file mode 100644 index 0000000..04c6fd0 --- /dev/null +++ b/hr_module/templates/hr_module_password_change.html @@ -0,0 +1,16 @@ +{% extends 'base.html' %} +{% load static %} + +{% block core_content %} + + +

Please change your password

+ +
+ {% csrf_token %} + {{ form.as_p }} + + +
+ +{% endblock %} \ No newline at end of file diff --git a/hr_module/urls.py b/hr_module/urls.py index 6ee02de..a0ef145 100644 --- a/hr_module/urls.py +++ b/hr_module/urls.py @@ -1,10 +1,15 @@ from django.urls import path from . import views +from django.contrib.auth import views as auth_views app_name = 'hr_module' urlpatterns = [ + path('login', auth_views.LoginView.as_view(template_name='hr_module_login.html'), name='login'), + path('logout', auth_views.LogoutView.as_view(), name='logout'), + path('change_password', auth_views.PasswordChangeView.as_view(template_name='hr_module_password_change.html'), name='change_password'), + path('home', views.homepage, name='homepage'), path('create_schedule', views.create_schedule, name='create_schedule'), path('create_employees', views.create_employees, name='create_employees'), path('search_api', views.search_users_api, name='search_users_api'), diff --git a/hr_module/views.py b/hr_module/views.py index 22f0848..cf466e5 100644 --- a/hr_module/views.py +++ b/hr_module/views.py @@ -1,4 +1,5 @@ from django.shortcuts import render, redirect +from django.contrib.auth.decorators import login_required from .forms import UploadFileForm, NewUserForm from hr_module.handling_functions.data_import_functions import read_and_parse_excel, insert_excel from hr_module.handling_functions.monthly_planning_functions import insert_into_plan, create_planning_operation_report @@ -12,11 +13,19 @@ from django.db import connection import datetime +login_url = '/hr_module/login' # Create your views here. +@login_required(login_url=login_url) def create_schedule(request): template_name = 'hr_module_create_schedule.html' return render(request, template_name) +@login_required(login_url=login_url) +def homepage(request): + template_name = 'hr_module_home.html' + return render(request, template_name) + +@login_required(login_url=login_url) def change_employee_data(request): template_name = 'hr_module_change_employee_data.html' return render(request, template_name) @@ -62,7 +71,7 @@ def change_employee_data_api(request): else: return JsonResponse({'error': 'not_authenticated'}) - +@login_required(login_url=login_url) def create_employees(request): if request.method == 'POST': if 'import_preview' in request.POST: @@ -75,7 +84,7 @@ def create_employees(request): request.session['df_path'] = df_dict['df_path'] df_html = df_dict['df_html'] context = {'df_html': df_html} - template = 'hr_import_validation.html' + template = 'hr_module_import_validation.html' return render(request, template, context) if 'import_insert' in request.POST: @@ -202,11 +211,11 @@ def new_plan_api(request): report_location = create_planning_operation_report(log, user) print(user) user_obj = Employee.objects.get(pk=user) - plan_creation_log = PlanCreationLog(username=user_obj, report_location=report_location) - plan_creation_log.save() + # plan_creation_log = PlanCreationLog(username=user_obj, report_location=report_location) + # plan_creation_log.save() return JsonResponse(log) - +@login_required(login_url=login_url) def manage_schedule(request): template = 'hr_module_show_schedule.html' return render(request, template) diff --git a/import_reports/admin_2021-01-04T23:08:43.146410.xlsx b/import_reports/admin_2021-01-04T23:08:43.146410.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..d344ccb34718b09349c69da38e6247432f6b5731 GIT binary patch literal 5355 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 of&T~VZ`!#@rGM
diff --git a/timefall/__pycache__/settings.cpython-38.pyc b/timefall/__pycache__/settings.cpython-38.pyc index c9307bf9a431c98a621ee5a4c63c6435ae5b578a..062ba0fad44fdf120847653fab5c1f14fbe14d8d 100644 GIT binary patch delta 475 zcmY*WyG{Z@6y4b!!fRPpp6VjL<)w>@@6JStG4YY0#AISZOwMLOK?ue|8Vd_+q%xt< z(pLV#!om-*_6xMJGLC4B&dojdoHKLpE#^M(6jbsak4xa^y8TwjDorIqBF)soIUJV6 zTyVk#H)MFAzzfxKFgJSOgC79|5klCqGa0?igFe%aeof%0X@Vufh6n}_#UO?(S|S*3 zQ;RSKBg~6YjPZBlnt%yY{bm;=EFjjFN`&Ib#jiJtv2J1?Sa8*ixTV*TenU9MWC<3Z#8BtezE3jG{*CRm?fh;bmt9@YWmk3!`P{~{kDKdT|GYb)9^-#fkG1xko5?Fq gsVozRq}r)OMUn9MppI_+;@|O3<<_IKNEMNiPZ~sa$p8QV delta 330 zcmYLFyG{a85WO$5u-ya(OaI&l@e)Zd6&QCg;zG|(k~|6?5l8;vfSyAjbiSi+v_)TZ^T#q_C&5rf@VfHZ!F& zM{%TZ1~X`KZ7kTyBvU1jnp=>QUzwU3pPQdjnv<$uB?1$fEX%xJfCp#_3qKE|05cCG H5dH-KS#BG$ delta 85 zcmbQhaf@9$l$V!_0SK-g-W9LK%)sy%#6bqEK#l_t7duSUw&qG_isDFN4`$Hh*jTfZ WX>u&{Vm^>|7JeQ^0cIXXo__#(RSt6i diff --git a/timefall/settings.py b/timefall/settings.py index 01422e0..d09979c 100644 --- a/timefall/settings.py +++ b/timefall/settings.py @@ -27,6 +27,7 @@ SECRET_KEY = 'tx#+u3u-r1$n_4r(!6vvcb@1f5!z21^74w(zesiz$&59&72$kq' DEBUG = True ALLOWED_HOSTS = ['192.168.101.128', + '192.168.101.129', '127.0.0.1',] @@ -34,6 +35,7 @@ ALLOWED_HOSTS = ['192.168.101.128', INSTALLED_APPS = [ 'hr_module.apps.HrModuleConfig', + 'employee_module.apps.EmployeeModuleConfig', 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', @@ -132,4 +134,7 @@ STATICFILES_DIRS = [ TMP_FILE_STORAGE = os.path.join(BASE_DIR, 'temp/') -IMPORT_REPORT_STORAGE = os.path.join(BASE_DIR, 'import_reports/') \ No newline at end of file +IMPORT_REPORT_STORAGE = os.path.join(BASE_DIR, 'import_reports/') + +LOGOUT_REDIRECT_URL = '/hr_module/login' +LOGIN_REDIRECT_URL = '/hr_module/home' \ No newline at end of file diff --git a/timefall/urls.py b/timefall/urls.py index 4e9b82b..34ee850 100644 --- a/timefall/urls.py +++ b/timefall/urls.py @@ -19,4 +19,5 @@ from django.urls import path, include urlpatterns = [ path('admin/', admin.site.urls), path('hr_module/', include('hr_module.urls')), + path('employee_module/', include('employee_module.urls')), ]