todos: create demo data, add some css

This commit is contained in:
muahahahh 2021-01-10 21:10:39 +01:00
parent a49c50f91e
commit 2eeda5315e
101 changed files with 1057 additions and 1375 deletions

Binary file not shown.

View File

@ -2,22 +2,23 @@
const monthsStrings = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'] const monthsStrings = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']
var today = new Date() var today = new Date()
function addCalendar(monthsAhead = 1, currentMonth = new Date().getMonth() + 1, currentYear= new Date().getFullYear(), weekStart=1){ function addCalendar(monthsAhead , currentMonth , currentYear, weekStart, buttonEventListener){
var calendarContainer = document.createElement('div') var calendarContainer = document.createElement('div')
calendarContainer.id = 'calendar_container' calendarContainer.id = 'calendar_container'
var monthsBlock = document.createElement('div') var monthsBlock = document.createElement('div')
monthsBlock.id = 'months_block' monthsBlock.id = 'months_block'
renderCalendarFor(calendarContainer, monthsBlock, currentYear, currentMonth, monthsAhead, weekStart) renderCalendarFor(calendarContainer, monthsBlock, currentYear, currentMonth, monthsAhead, weekStart)
calendarContainer.appendChild(createButtonBack(calendarContainer, monthsBlock, monthsAhead, weekStart)) calendarContainer.appendChild(createButtonBack(calendarContainer, monthsBlock, monthsAhead, weekStart))
calendarContainer.appendChild(monthsBlock) calendarContainer.appendChild(monthsBlock)
calendarContainer.appendChild(createButtonForwards(calendarContainer, monthsBlock, monthsAhead, weekStart)) calendarContainer.appendChild(createButtonForwards(calendarContainer, monthsBlock, monthsAhead, weekStart))
calendarContainer.appendChild(createDateSelector(calendarContainer, monthsBlock, monthsAhead, weekStart)) calendarContainer.appendChild(createDateSelector(calendarContainer, monthsBlock, monthsAhead, weekStart))
var buttons = calendarContainer.getElementsByClassName('calendar_button')
for (var i = 0; i < buttons.length; i++){
buttons[i].addEventListener('click', buttonEventListener)
}
var element = calendarContainer.getElementsByTagName('button')[0]
element.addEventListener('click', buttonEventListener)
return calendarContainer return calendarContainer
} }
@ -26,7 +27,6 @@ function createButtonBack(calendarContainer, monthsBlock, monthsAhead, weekStart
buttonBack.addEventListener('click', function(){ buttonBack.addEventListener('click', function(){
var currentMonth = parseInt(calendarContainer.getAttribute('month_shown')) var currentMonth = parseInt(calendarContainer.getAttribute('month_shown'))
var currentYear = parseInt(calendarContainer.getAttribute('year_shown')) var currentYear = parseInt(calendarContainer.getAttribute('year_shown'))
if (currentMonth == 1){ if (currentMonth == 1){
currentMonth = 12 currentMonth = 12
currentYear = currentYear - 1 currentYear = currentYear - 1
@ -43,7 +43,6 @@ function createButtonForwards(calendarContainer, monthsBlock, monthsAhead, weekS
buttonForwards.addEventListener('click', function(){ buttonForwards.addEventListener('click', function(){
var currentMonth = parseInt(calendarContainer.getAttribute('month_shown')) var currentMonth = parseInt(calendarContainer.getAttribute('month_shown'))
var currentYear = parseInt(calendarContainer.getAttribute('year_shown')) var currentYear = parseInt(calendarContainer.getAttribute('year_shown'))
if (currentMonth == 12){ if (currentMonth == 12){
currentMonth = 1 currentMonth = 1
currentYear = currentYear + 1 currentYear = currentYear + 1
@ -58,7 +57,6 @@ function createButtonForwards(calendarContainer, monthsBlock, monthsAhead, weekS
function createDateSelector(calendarContainer, monthsBlock, monthsAhead, weekStart){ function createDateSelector(calendarContainer, monthsBlock, monthsAhead, weekStart){
var dateSelector = createDateSelectionHTML() var dateSelector = createDateSelectionHTML()
var buttonGoToDate = dateSelector.querySelector('#button_load_selected_months') var buttonGoToDate = dateSelector.querySelector('#button_load_selected_months')
buttonGoToDate.addEventListener('click', function(){ buttonGoToDate.addEventListener('click', function(){
var currentYear = parseInt(dateSelector.querySelector('#year_selector').value) var currentYear = parseInt(dateSelector.querySelector('#year_selector').value)
@ -71,7 +69,6 @@ function createDateSelector(calendarContainer, monthsBlock, monthsAhead, weekSta
function renderCalendarFor(calendarContainer, monthsBlock, year, month, nMonths, weekStart){ function renderCalendarFor(calendarContainer, monthsBlock, year, month, nMonths, weekStart){
monthsBlock.innerHTML = '' monthsBlock.innerHTML = ''
calendarContainer.setAttribute('month_shown', month.toString()) calendarContainer.setAttribute('month_shown', month.toString())
calendarContainer.setAttribute('year_shown', year.toString()) calendarContainer.setAttribute('year_shown', year.toString())
@ -81,12 +78,9 @@ function renderCalendarFor(calendarContainer, monthsBlock, year, month, nMonths,
if (monthToCreate == 13){ if (monthToCreate == 13){
monthToCreate = 1; monthToCreate = 1;
year = year + 1; year = year + 1;
// console.log(monthToCreate, month, year, nMonths)
} }
var monthContainer = document.createElement('div') var monthContainer = document.createElement('div')
monthContainer.className = 'month_container' monthContainer.className = 'month_container'
monthContainer.appendChild(renderMonth(year, monthToCreate, weekStart)) monthContainer.appendChild(renderMonth(year, monthToCreate, weekStart))
monthsBlock.appendChild(monthContainer) monthsBlock.appendChild(monthContainer)
} }
@ -100,16 +94,13 @@ function renderMonth(year, month, weekStart = 0, daysOfWeekNumeric){
daysOfWeek.push(daysOfWeek.shift()) daysOfWeek.push(daysOfWeek.shift())
daysOfWeekNumeric.push(daysOfWeekNumeric.shift()) daysOfWeekNumeric.push(daysOfWeekNumeric.shift())
} }
var table = document.createElement('table') var table = document.createElement('table')
var monthString = monthsStrings[month - 1] var monthString = monthsStrings[month - 1]
createHeaders(table, year, monthString, daysOfWeek) createHeaders(table, year, monthString, daysOfWeek)
createDates(table, year, month, daysOfWeekNumeric) createDates(table, year, month, daysOfWeekNumeric)
return table return table
} }
function createHeaders(table, year, month, daysOfWeek){ function createHeaders(table, year, month, daysOfWeek){
let monthHeaderRow = document.createElement('tr') let monthHeaderRow = document.createElement('tr')
let monthHeader = document.createElement('th') let monthHeader = document.createElement('th')
@ -118,7 +109,6 @@ function createHeaders(table, year, month, daysOfWeek){
monthHeader.colSpan = 7 monthHeader.colSpan = 7
monthHeaderRow.appendChild(monthHeader) monthHeaderRow.appendChild(monthHeader)
table.appendChild(monthHeaderRow) table.appendChild(monthHeaderRow)
let header = document.createElement('tr') let header = document.createElement('tr')
for (var i = 0; i < daysOfWeek.length; i++){ for (var i = 0; i < daysOfWeek.length; i++){
var headerDay = document.createElement('th') var headerDay = document.createElement('th')
@ -133,7 +123,6 @@ function createHeaders(table, year, month, daysOfWeek){
function createDates(table, year, month, daysOfWeekNumeric){ function createDates(table, year, month, daysOfWeekNumeric){
var weekEnd = daysOfWeekNumeric[daysOfWeekNumeric.length - 1] var weekEnd = daysOfWeekNumeric[daysOfWeekNumeric.length - 1]
var daysOfMonth = daysArray(year, month, daysOfWeekNumeric) var daysOfMonth = daysArray(year, month, daysOfWeekNumeric)
var row = document.createElement('tr') var row = document.createElement('tr')
for (var i = 0; i < daysOfMonth.length; i++){ for (var i = 0; i < daysOfMonth.length; i++){
@ -143,11 +132,9 @@ function createDates(table, year, month, daysOfWeekNumeric){
var dateString = new Date(date.getTime() - (date.getTimezoneOffset() * 60000 )) var dateString = new Date(date.getTime() - (date.getTimezoneOffset() * 60000 ))
.toISOString() .toISOString()
.split("T")[0]; .split("T")[0];
var dateContainer = document.createElement('div') var dateContainer = document.createElement('div')
dateContainer.innerText = dayNr dateContainer.innerText = dayNr
dateContainer.className = 'days_of_month' dateContainer.className = 'days_of_month'
if (month - 1 == date.getMonth()){ if (month - 1 == date.getMonth()){
dateContainer.classList.add('days_of_month_current') dateContainer.classList.add('days_of_month_current')
dateContainer.id = 'date_' + dateString dateContainer.id = 'date_' + dateString
@ -158,50 +145,36 @@ function createDates(table, year, month, daysOfWeekNumeric){
} else { } else {
dateContainer.classList.add('days_of_month_not_current') dateContainer.classList.add('days_of_month_not_current')
} }
dateContainer.setAttribute('date', dateString) dateContainer.setAttribute('date', dateString)
cell.appendChild(dateContainer) cell.appendChild(dateContainer)
row.appendChild(cell) row.appendChild(cell)
if (date.getDay() == weekEnd) { if (date.getDay() == weekEnd) {
table.appendChild(row) table.appendChild(row)
var row = document.createElement('tr') var row = document.createElement('tr')
} }
} }
table.appendChild(row) table.appendChild(row)
} }
function daysArray(year, month, daysOfWeekNumeric) { function daysArray(year, month, daysOfWeekNumeric) {
month = month - 1 month = month - 1
var arr = [] var arr = []
var daysInCurrentMonth = daysInMonth(year, month + 1) var daysInCurrentMonth = daysInMonth(year, month + 1)
var firstDayOfMonth = new Date(year, month, 1).getDay() var firstDayOfMonth = new Date(year, month, 1).getDay()
var blankDaysStart = daysOfWeekNumeric.indexOf(firstDayOfMonth) * -1 var blankDaysStart = daysOfWeekNumeric.indexOf(firstDayOfMonth) * -1
for (var i = blankDaysStart + 1; i < 1; i++){ for (var i = blankDaysStart + 1; i < 1; i++){
var date = new Date(year, month, i) var date = new Date(year, month, i)
arr.push(date) arr.push(date)
} }
for (var i = 1; i < daysInCurrentMonth + 1; i++){ for (var i = 1; i < daysInCurrentMonth + 1; i++){
var date = new Date(year, month, i) var date = new Date(year, month, i)
arr.push(date) arr.push(date)
} }
var daysToFill = arr.length var daysToFill = arr.length
for (var i = 1; i < 42 - daysToFill + 1; i++){ for (var i = 1; i < 42 - daysToFill + 1; i++){
var date = new Date(year, month + 1, i) var date = new Date(year, month + 1, i)
arr.push(date) arr.push(date)
} }
return arr return arr
} }
@ -209,27 +182,21 @@ function daysInMonth (year, month) {
return new Date(year, month, 0).getDate(); return new Date(year, month, 0).getDate();
} }
function createDateSelectionHTML(){ function createDateSelectionHTML(){
var container = document.createElement('div') var container = document.createElement('div')
container.id = 'date_selector' container.id = 'date_selector'
var goButton = document.createElement('button') var goButton = document.createElement('button')
goButton.innerText = 'Go' goButton.innerText = 'Go'
goButton.id = 'button_load_selected_months' goButton.id = 'button_load_selected_months'
var label = document.createElement('label') var label = document.createElement('label')
label.setAttribute('for', 'years') label.setAttribute('for', 'years')
label.innerText = 'Go to: ' label.innerText = 'Go to: '
var selectYear = document.createElement('select') var selectYear = document.createElement('select')
selectYear.name='years' selectYear.name='years'
selectYear.id = 'year_selector' selectYear.id = 'year_selector'
var spanBegin = 1990
spanBegin = 1990 var spanEnd = 2030
spanEnd = 2030 var yearsSpan = spanEnd - spanBegin
yearsSpan = spanEnd - spanBegin
for (var i = 0; i < yearsSpan; i++){ for (var i = 0; i < yearsSpan; i++){
var option = document.createElement('option') var option = document.createElement('option')
option.value = spanBegin + i option.value = spanBegin + i
@ -237,7 +204,6 @@ function createDateSelectionHTML(){
selectYear.appendChild(option) selectYear.appendChild(option)
} }
selectYear.value = today.getFullYear() selectYear.value = today.getFullYear()
var selectMonth = document.createElement('select') var selectMonth = document.createElement('select')
selectMonth.name='months' selectMonth.name='months'
selectMonth.id = 'month_selector' selectMonth.id = 'month_selector'
@ -249,7 +215,6 @@ function createDateSelectionHTML(){
} }
selectMonth.value = today.getMonth() selectMonth.value = today.getMonth()
container.appendChild(label) container.appendChild(label)
container.appendChild(selectYear) container.appendChild(selectYear)
container.appendChild(selectMonth) container.appendChild(selectMonth)
@ -264,4 +229,7 @@ function createButton(id, className, innerText){
button.className = className button.className = className
button.innerText = innerText button.innerText = innerText
return button return button
} }
export { addCalendar }

View File

@ -0,0 +1,14 @@
const urls = {
'show_schedule': {
'show': '/employee_module/show_employee_plan_api',
'update': '/employee_module/update_plan_api'
}
,
'show_timelog': {
'show': '/employee_module/show_employee_timelog_api',
'update': '/employee_module/update_timelog_api',
}
}
export { urls }

View File

@ -0,0 +1,30 @@
import { addCalendar } from './calendar.js';
import { appendLegend, formatCalendarContainerSize, formatCalendarSize} from "./calendar_extended.js";
import { fetchDays } from './calendar_ajax_employee_module_requests.js'
window.addEventListener('load', renderWhole)
function renderWhole(){
var parent = document.getElementById('calendar_box')
parent.innerHTML = ''
parent.appendChild(addCalendar(3, new Date().getMonth() + 1, new Date().getFullYear(), 1, fetchDays))
appendLegend()
formatCalendarContainerSize(document.getElementById('calendar_container'))
formatCalendarSize()
console.log('hoba')
fetchDays()
}
export { renderWhole }

View File

@ -0,0 +1,68 @@
import {addClassToWorkingDays, searchedDateRange} from "./calendar_extended.js";
import {csrftoken} from "../../../static/js/csrf_token.js";
import {detailedRecordsMainBlock, formatTableSize} from "./calendar_employee_module_to_table.js";
import { urls } from './calendar_ajax_employee_module_config.js'
function fetchDays(){
var host = 'http://' + window.location.host;
var fetch_url = host + urls[window.location.pathname.substring(window.location.pathname.lastIndexOf('/') + 1)]['show']
var range = searchedDateRange()
var startDate = range['min']
var endDate = range['max']
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,
"start_date": startDate,
"end_date" : endDate
}),
}).then((response) => {
return response.json();
}).then((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(detailedRecordsMainBlock(data))
parent.appendChild(listContainer)
formatTableSize()
});
}
function updateCheckedRecords(recordsArray, action){
var host = 'http://' + window.location.host;
var fetch_url = host + urls[window.location.pathname.substring(window.location.pathname.lastIndexOf('/') + 1)]['update']
fetch(fetch_url,
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRFToken': csrftoken
},
body: JSON.stringify({
'action': action,
'records': recordsArray,
}),
}).then((response) => {
return response.json();
}).then((data) => {
fetchDays()
})
}
export { fetchDays, updateCheckedRecords }

View File

@ -0,0 +1,68 @@
import { updateCheckedRecords } from './calendar_ajax_employee_module_requests.js'
function detailedRecordsMainBlock(data){
var container = document.createElement('div')
var buttonsContainer = document.createElement('div')
buttonsContainer.id = 'buttons_container'
container.appendChild(detailedCalendarRecordsTable(data))
return container
}
function detailedCalendarRecordsTable(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.className = 'database_row'
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
textInput.className = tagName
cell.appendChild(textInput)
}
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 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
}
export { detailedRecordsMainBlock, formatTableSize }

View File

@ -0,0 +1,91 @@
function appendLegend(){
var calendar = document.getElementById('calendar_container')
var container = document.createElement('div')
container.id = 'legend_container'
var activityTypes = ['work', 'vacation', 'sickness', 'parental_leave']
for(var i = 0; i < activityTypes.length; i++){
var legendElementContainer = document.createElement('div')
legendElementContainer.className = 'legend_element_container'
var legendDivText = document.createElement('div')
legendDivText.innerText = activityTypes[i]
legendDivText.className = 'legend_label'
var legendDivBox = document.createElement('div')
legendDivBox.classList.add('legend_cube')
legendDivBox.classList.add('days_of_month_' + activityTypes[i])
legendElementContainer.appendChild(legendDivText)
legendElementContainer.appendChild(legendDivBox)
container.appendChild(legendElementContainer)
}
calendar.appendChild(container)
}
function formatCalendarContainerSize(calendarContainer){
var monthsBlock = calendarContainer.querySelector('#months_block')
var calendarButton = calendarContainer.querySelector('#calendar_button_back')
var dateSelector = calendarContainer.querySelector('#date_selector')
var legendSelector = calendarContainer.querySelector('#legend_container')
var widthMonths = monthsBlock.offsetWidth
var heightMonths = monthsBlock.offsetHeight
var heightDateSelector = dateSelector.offsetHeight
var heightLegend = legendSelector.offsetHeight
var widthCalendarButton = calendarButton.offsetWidth * 2
var widthTotal = widthMonths + widthCalendarButton
var heightTotal = heightMonths + heightDateSelector + heightLegend
calendarContainer.setAttribute('style','height:' + heightTotal +'px; width:' + widthTotal + 'px');
}
function formatCalendarSize(){
var calendarBox = document.getElementById('calendar_box')
var calendar = document.getElementById('calendar_container')
calendarBox.setAttribute('style', 'width:' + calendar.offsetWidth + 'px')
}
function cleanCalendarClasses(){
var classesToKeep = ['days_of_month', 'days_of_month_current', 'days_of_month_today']
var days = document.getElementsByClassName('days_of_month_current')
for (var i = 0; i < days.length; i++){
var classList = days[i].classList
for (var j = 0; j < classList.length; j++){
if (!classesToKeep.includes(classList[j])){
days[i].classList.remove(classList[j])
console.log('removed ' + classList[j])
}
}
}
}
function addClassToWorkingDays(data){
cleanCalendarClasses()
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 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
}
export { appendLegend, formatCalendarContainerSize, formatCalendarSize, addClassToWorkingDays, searchedDateRange }

View File

@ -0,0 +1,62 @@
import {csrftoken} from "../../../static/js/csrf_token.js";
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)
}
}

View File

@ -1,4 +1,4 @@
const csrftoken = getCookie('csrftoken'); import {csrftoken} from "../../../static/js/csrf_token.js";
window.addEventListener('load', function(){ window.addEventListener('load', function(){
fetchSearchEmployeeData() fetchSearchEmployeeData()

View File

@ -1,201 +0,0 @@
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))
appendLegend()
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 legendSelector = calendarContainer.querySelector('#legend_container')
var widthMonths = monthsBlock.offsetWidth
var heightMonths = monthsBlock.offsetHeight
var heightDateSelector = dateSelector.offsetHeight
var heightLegend = legendSelector.offsetHeight
var widthCalendarButton = calendarButton.offsetWidth * 2
var widthTotal = widthMonths + widthCalendarButton
var heightTotal = heightMonths + heightDateSelector + heightLegend
calendarContainer.setAttribute('style','height:' + heightTotal +'px; width:' + widthTotal + 'px');
}
function formatTableSize(){
var calendarBox = document.getElementById('calendar_box')
var calendar = document.getElementById('calendar_container')
var tableDiv = document.getElementById('list_container')
var width = calendar.offsetWidth
calendarBox.setAttribute('style', 'width:' + calendar.offsetWidth + 'px')
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;
}
function appendLegend(){
var calendar = document.getElementById('calendar_container')
var container = document.createElement('div')
container.id = 'legend_container'
var activityTypes = ['work', 'vacation', 'sickness', 'parental_leave']
for(var i = 0; i < activityTypes.length; i++){
var legendElementContainer = document.createElement('div')
legendElementContainer.className = 'legend_element_container'
var legendDivText = document.createElement('div')
legendDivText.innerText = activityTypes[i]
legendDivText.className = 'legend_label'
var legendDivBox = document.createElement('div')
legendDivBox.classList.add('legend_cube')
legendDivBox.classList.add('days_of_month_' + activityTypes[i])
legendElementContainer.appendChild(legendDivText)
legendElementContainer.appendChild(legendDivBox)
container.appendChild(legendElementContainer)
}
calendar.appendChild(container)
}

View File

@ -1,201 +0,0 @@
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))
appendLegend()
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_timelog_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 legendSelector = calendarContainer.querySelector('#legend_container')
var widthMonths = monthsBlock.offsetWidth
var heightMonths = monthsBlock.offsetHeight
var heightDateSelector = dateSelector.offsetHeight
var heightLegend = legendSelector.offsetHeight
var widthCalendarButton = calendarButton.offsetWidth * 2
var widthTotal = widthMonths + widthCalendarButton
var heightTotal = heightMonths + heightDateSelector + heightLegend
calendarContainer.setAttribute('style','height:' + heightTotal +'px; width:' + widthTotal + 'px');
}
function formatTableSize(){
var calendarBox = document.getElementById('calendar_box')
var calendar = document.getElementById('calendar_container')
var tableDiv = document.getElementById('list_container')
var width = calendar.offsetWidth
calendarBox.setAttribute('style', 'width:' + calendar.offsetWidth + 'px')
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;
}
function appendLegend(){
var calendar = document.getElementById('calendar_container')
var container = document.createElement('div')
container.id = 'legend_container'
var activityTypes = ['work', 'vacation', 'sickness', 'parental_leave']
for(var i = 0; i < activityTypes.length; i++){
var legendElementContainer = document.createElement('div')
legendElementContainer.className = 'legend_element_container'
var legendDivText = document.createElement('div')
legendDivText.innerText = activityTypes[i]
legendDivText.className = 'legend_label'
var legendDivBox = document.createElement('div')
legendDivBox.classList.add('legend_cube')
legendDivBox.classList.add('days_of_month_' + activityTypes[i])
legendElementContainer.appendChild(legendDivText)
legendElementContainer.appendChild(legendDivBox)
container.appendChild(legendElementContainer)
}
calendar.appendChild(container)
}

View File

@ -8,7 +8,6 @@
{% block core_content %} {% block core_content %}
<script src="{% static '/js/csrf_token.js' %}"></script>
<div id="sidebar"> <div id="sidebar">
@ -37,6 +36,14 @@
</div> </div>
</a> </a>
{% if request.user.is_superuser or MANAGER_FLAG %}
<a href="{% url 'hr_module:homepage' %}">
<div class="sidebar_item">Go to administration site
</div>
</a>
{% endif %}
</div> </div>
<div id="hr_module_main_container"> <div id="hr_module_main_container">

View File

@ -10,6 +10,6 @@
</div> </div>
<script src="{% static '/js/employee_module_show_employee_data.js' %}"></script> <script type="module" src="{% static '/js/employee_module_show_employee_data.js' %}"></script>
{% endblock %} {% endblock %}

View File

@ -7,13 +7,13 @@
<link rel="stylesheet" href="{% static '/css/calendar_local.css' %}"> <link rel="stylesheet" href="{% static '/css/calendar_local.css' %}">
<link rel="stylesheet" href="{% static '/css/employee_module_show_schedule.css' %}"> <link rel="stylesheet" href="{% static '/css/employee_module_show_schedule.css' %}">
<div> <div hidden>
<div id="username" username="{{ user }}"></div> <div id="username_input" username="{{ user }}"></div>
<button type="button" id="load_schedule_button">Load Schedule</button>
</div> </div>
<div id="calendar_box"></div> <div id="calendar_box"></div>
<script src="{% static '/js/calendar.js' %}"></script> <script type="module" src="{% static '/js/calendar_ajax_employee_module_main.js' %}"></script>
<script src="{% static '/js/employee_module_show_schedule.js' %}"></script>
{% endblock %} {% endblock %}

View File

@ -7,13 +7,12 @@
<link rel="stylesheet" href="{% static '/css/calendar_local.css' %}"> <link rel="stylesheet" href="{% static '/css/calendar_local.css' %}">
<link rel="stylesheet" href="{% static '/css/employee_module_show_schedule.css' %}"> <link rel="stylesheet" href="{% static '/css/employee_module_show_schedule.css' %}">
<div> <div hidden>
<div id="username" username="{{ user }}"></div> <div id="username_input" username="{{ user }}"></div>
<button type="button" id="load_schedule_button">Load Schedule</button>
</div> </div>
<div id="calendar_box"></div> <div id="calendar_box"></div>
<script src="{% static '/js/calendar.js' %}"></script> <script type="module" src="{% static '/js/calendar_ajax_employee_module_main.js' %}"></script>
<script src="{% static '/js/employee_module_show_timelog.js' %}"></script>
{% endblock %} {% endblock %}

View File

@ -6,9 +6,6 @@ from django.contrib.auth import views as auth_views
app_name = 'employee_module' app_name = 'employee_module'
urlpatterns = [ 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('home', views.homepage, name='homepage'),
path('time_tracking', views.time_tracking, name='time_tracking'), path('time_tracking', views.time_tracking, name='time_tracking'),
path('show_schedule', views.show_schedule, name='show_schedule'), path('show_schedule', views.show_schedule, name='show_schedule'),

View File

@ -5,11 +5,11 @@ from hr_module.models import Employee, Plan, TimeLog
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.http import HttpResponse, JsonResponse, Http404 from django.http import HttpResponse, JsonResponse, Http404
import datetime import datetime
from django.urls import reverse from django.urls import reverse, reverse_lazy
from django.http import HttpResponse, HttpResponseRedirect from django.http import HttpResponse, HttpResponseRedirect
login_url = '/hr_module/login' login_url = reverse_lazy('login')
# Create your views here. # Create your views here.
@login_required(login_url=login_url) @login_required(login_url=login_url)
def homepage(request): def homepage(request):

Binary file not shown.

View File

@ -1,5 +1,10 @@
from django.conf import settings from django.contrib.auth.models import User
def report_download_path(request): def manager_flag(request):
return {'IMPORT_REPORT_STORAGE': settings.IMPORT_REPORT_STORAGE} if request.user.is_authenticated:
session_user = User.objects.select_related('employee').get(username=request.user.username)
manager_flag = session_user.employee.manager_flag
else:
manager_flag = None
return {'MANAGER_FLAG': manager_flag}

View File

@ -88,4 +88,4 @@ def create_planning_operation_report(dict_, current_user):
filename = current_user + '_' + datetime.datetime.now().isoformat() + '.xlsx' filename = current_user + '_' + datetime.datetime.now().isoformat() + '.xlsx'
path_temp = settings.IMPORT_REPORT_STORAGE + filename path_temp = settings.IMPORT_REPORT_STORAGE + filename
df.to_excel(path_temp, index=False) df.to_excel(path_temp, index=False)
return filename return filename

47
hr_module/sql_queries.py Normal file
View File

@ -0,0 +1,47 @@
export_query_body = '''select d.username,
d.first_name,
d.last_name,
d.manager_username,
d.department,
c.month,
c.activity_type,
c.time_should,
c.time_is,
c.overtime as difference_hours
from (select *
from auth_user a
inner join hr_module_employee b on a.username = b.username) d
left join (
select plan.username_id,
plan.month,
plan.activity_type,
plan.time_should,
log.time_is,
log.time_is - plan.time_should as overtime
from (
select username_id,
activity_type,
strftime('%Y-%m') as month,
sum(strftime('%s', end_time) - strftime('%s', begin_time)) / 3600 as time_should
from hr_module_plan
group by username_id, activity_type, strftime('%Y-%m')
) plan
left join (
select username_id,
activity_type,
strftime('%Y-%m') as month,
sum(strftime('%s', end_time) - strftime('%s', begin_time)) / 3600 as time_is
from hr_module_timelog
group by username_id, activity_type, strftime('%Y-%m')
) log on log.username_id = plan.username_id and log.activity_type = plan.activity_type and
log.month = plan.month
) c on c.username_id = d.username
where c.month in {} '''
export_queries = {'username': export_query_body + "and d.username = '{}'",
'department': export_query_body + "and d.department = '{}'",
'manager': export_query_body + "and d.manager_username = '{}'"}

View File

@ -5,7 +5,7 @@ input[readonly] {
} }
table#detailed_plan_records { table#detailed_plan_records {
margin-top: 15px; margin-top: 10px;
width: 100%; width: 100%;
font-size: 15px; font-size: 15px;
vertical-align:middle; vertical-align:middle;
@ -42,4 +42,21 @@ div#detailed_plan_records input {
.begin_time, .end_time { .begin_time, .end_time {
display: block; display: block;
}
#list_container {
margin-top: 20px;
}
#buttons_container {
margin-left: 2px;
}
#buttons_container button {
width: 157px;
margin-right: 10px;
}
#checkox_select_button {
margin-right: 0px;
} }

View File

@ -5,6 +5,7 @@ input[readonly] {
} }
table#detailed_plan_records { table#detailed_plan_records {
margin-top: 10px;
width: 100%; width: 100%;
font-size: 15px; font-size: 15px;
vertical-align:middle; vertical-align:middle;
@ -41,4 +42,22 @@ div#detailed_plan_records input {
.begin_time, .end_time { .begin_time, .end_time {
display: block; display: block;
}
#list_container {
margin-top: 20px;
}
#buttons_container {
margin-left: 2px;
}
#buttons_container button {
width: 157px;
margin-right: 10px;
}
#checkox_select_button {
margin-right: 0px;
} }

View File

@ -2,22 +2,23 @@
const monthsStrings = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'] const monthsStrings = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']
var today = new Date() var today = new Date()
function addCalendar(monthsAhead = 1, currentMonth = new Date().getMonth() + 1, currentYear= new Date().getFullYear(), weekStart=1){ function addCalendar(monthsAhead , currentMonth , currentYear, weekStart, buttonEventListener){
var calendarContainer = document.createElement('div') var calendarContainer = document.createElement('div')
calendarContainer.id = 'calendar_container' calendarContainer.id = 'calendar_container'
var monthsBlock = document.createElement('div') var monthsBlock = document.createElement('div')
monthsBlock.id = 'months_block' monthsBlock.id = 'months_block'
renderCalendarFor(calendarContainer, monthsBlock, currentYear, currentMonth, monthsAhead, weekStart) renderCalendarFor(calendarContainer, monthsBlock, currentYear, currentMonth, monthsAhead, weekStart)
calendarContainer.appendChild(createButtonBack(calendarContainer, monthsBlock, monthsAhead, weekStart)) calendarContainer.appendChild(createButtonBack(calendarContainer, monthsBlock, monthsAhead, weekStart))
calendarContainer.appendChild(monthsBlock) calendarContainer.appendChild(monthsBlock)
calendarContainer.appendChild(createButtonForwards(calendarContainer, monthsBlock, monthsAhead, weekStart)) calendarContainer.appendChild(createButtonForwards(calendarContainer, monthsBlock, monthsAhead, weekStart))
calendarContainer.appendChild(createDateSelector(calendarContainer, monthsBlock, monthsAhead, weekStart)) calendarContainer.appendChild(createDateSelector(calendarContainer, monthsBlock, monthsAhead, weekStart))
var buttons = calendarContainer.getElementsByClassName('calendar_button')
for (var i = 0; i < buttons.length; i++){
buttons[i].addEventListener('click', buttonEventListener)
}
var element = calendarContainer.getElementsByTagName('button')[0]
element.addEventListener('click', buttonEventListener)
return calendarContainer return calendarContainer
} }
@ -26,7 +27,6 @@ function createButtonBack(calendarContainer, monthsBlock, monthsAhead, weekStart
buttonBack.addEventListener('click', function(){ buttonBack.addEventListener('click', function(){
var currentMonth = parseInt(calendarContainer.getAttribute('month_shown')) var currentMonth = parseInt(calendarContainer.getAttribute('month_shown'))
var currentYear = parseInt(calendarContainer.getAttribute('year_shown')) var currentYear = parseInt(calendarContainer.getAttribute('year_shown'))
if (currentMonth == 1){ if (currentMonth == 1){
currentMonth = 12 currentMonth = 12
currentYear = currentYear - 1 currentYear = currentYear - 1
@ -43,7 +43,6 @@ function createButtonForwards(calendarContainer, monthsBlock, monthsAhead, weekS
buttonForwards.addEventListener('click', function(){ buttonForwards.addEventListener('click', function(){
var currentMonth = parseInt(calendarContainer.getAttribute('month_shown')) var currentMonth = parseInt(calendarContainer.getAttribute('month_shown'))
var currentYear = parseInt(calendarContainer.getAttribute('year_shown')) var currentYear = parseInt(calendarContainer.getAttribute('year_shown'))
if (currentMonth == 12){ if (currentMonth == 12){
currentMonth = 1 currentMonth = 1
currentYear = currentYear + 1 currentYear = currentYear + 1
@ -58,7 +57,6 @@ function createButtonForwards(calendarContainer, monthsBlock, monthsAhead, weekS
function createDateSelector(calendarContainer, monthsBlock, monthsAhead, weekStart){ function createDateSelector(calendarContainer, monthsBlock, monthsAhead, weekStart){
var dateSelector = createDateSelectionHTML() var dateSelector = createDateSelectionHTML()
var buttonGoToDate = dateSelector.querySelector('#button_load_selected_months') var buttonGoToDate = dateSelector.querySelector('#button_load_selected_months')
buttonGoToDate.addEventListener('click', function(){ buttonGoToDate.addEventListener('click', function(){
var currentYear = parseInt(dateSelector.querySelector('#year_selector').value) var currentYear = parseInt(dateSelector.querySelector('#year_selector').value)
@ -71,7 +69,6 @@ function createDateSelector(calendarContainer, monthsBlock, monthsAhead, weekSta
function renderCalendarFor(calendarContainer, monthsBlock, year, month, nMonths, weekStart){ function renderCalendarFor(calendarContainer, monthsBlock, year, month, nMonths, weekStart){
monthsBlock.innerHTML = '' monthsBlock.innerHTML = ''
calendarContainer.setAttribute('month_shown', month.toString()) calendarContainer.setAttribute('month_shown', month.toString())
calendarContainer.setAttribute('year_shown', year.toString()) calendarContainer.setAttribute('year_shown', year.toString())
@ -81,12 +78,9 @@ function renderCalendarFor(calendarContainer, monthsBlock, year, month, nMonths,
if (monthToCreate == 13){ if (monthToCreate == 13){
monthToCreate = 1; monthToCreate = 1;
year = year + 1; year = year + 1;
// console.log(monthToCreate, month, year, nMonths)
} }
var monthContainer = document.createElement('div') var monthContainer = document.createElement('div')
monthContainer.className = 'month_container' monthContainer.className = 'month_container'
monthContainer.appendChild(renderMonth(year, monthToCreate, weekStart)) monthContainer.appendChild(renderMonth(year, monthToCreate, weekStart))
monthsBlock.appendChild(monthContainer) monthsBlock.appendChild(monthContainer)
} }
@ -100,16 +94,13 @@ function renderMonth(year, month, weekStart = 0, daysOfWeekNumeric){
daysOfWeek.push(daysOfWeek.shift()) daysOfWeek.push(daysOfWeek.shift())
daysOfWeekNumeric.push(daysOfWeekNumeric.shift()) daysOfWeekNumeric.push(daysOfWeekNumeric.shift())
} }
var table = document.createElement('table') var table = document.createElement('table')
var monthString = monthsStrings[month - 1] var monthString = monthsStrings[month - 1]
createHeaders(table, year, monthString, daysOfWeek) createHeaders(table, year, monthString, daysOfWeek)
createDates(table, year, month, daysOfWeekNumeric) createDates(table, year, month, daysOfWeekNumeric)
return table return table
} }
function createHeaders(table, year, month, daysOfWeek){ function createHeaders(table, year, month, daysOfWeek){
let monthHeaderRow = document.createElement('tr') let monthHeaderRow = document.createElement('tr')
let monthHeader = document.createElement('th') let monthHeader = document.createElement('th')
@ -118,7 +109,6 @@ function createHeaders(table, year, month, daysOfWeek){
monthHeader.colSpan = 7 monthHeader.colSpan = 7
monthHeaderRow.appendChild(monthHeader) monthHeaderRow.appendChild(monthHeader)
table.appendChild(monthHeaderRow) table.appendChild(monthHeaderRow)
let header = document.createElement('tr') let header = document.createElement('tr')
for (var i = 0; i < daysOfWeek.length; i++){ for (var i = 0; i < daysOfWeek.length; i++){
var headerDay = document.createElement('th') var headerDay = document.createElement('th')
@ -133,7 +123,6 @@ function createHeaders(table, year, month, daysOfWeek){
function createDates(table, year, month, daysOfWeekNumeric){ function createDates(table, year, month, daysOfWeekNumeric){
var weekEnd = daysOfWeekNumeric[daysOfWeekNumeric.length - 1] var weekEnd = daysOfWeekNumeric[daysOfWeekNumeric.length - 1]
var daysOfMonth = daysArray(year, month, daysOfWeekNumeric) var daysOfMonth = daysArray(year, month, daysOfWeekNumeric)
var row = document.createElement('tr') var row = document.createElement('tr')
for (var i = 0; i < daysOfMonth.length; i++){ for (var i = 0; i < daysOfMonth.length; i++){
@ -143,11 +132,9 @@ function createDates(table, year, month, daysOfWeekNumeric){
var dateString = new Date(date.getTime() - (date.getTimezoneOffset() * 60000 )) var dateString = new Date(date.getTime() - (date.getTimezoneOffset() * 60000 ))
.toISOString() .toISOString()
.split("T")[0]; .split("T")[0];
var dateContainer = document.createElement('div') var dateContainer = document.createElement('div')
dateContainer.innerText = dayNr dateContainer.innerText = dayNr
dateContainer.className = 'days_of_month' dateContainer.className = 'days_of_month'
if (month - 1 == date.getMonth()){ if (month - 1 == date.getMonth()){
dateContainer.classList.add('days_of_month_current') dateContainer.classList.add('days_of_month_current')
dateContainer.id = 'date_' + dateString dateContainer.id = 'date_' + dateString
@ -158,50 +145,36 @@ function createDates(table, year, month, daysOfWeekNumeric){
} else { } else {
dateContainer.classList.add('days_of_month_not_current') dateContainer.classList.add('days_of_month_not_current')
} }
dateContainer.setAttribute('date', dateString) dateContainer.setAttribute('date', dateString)
cell.appendChild(dateContainer) cell.appendChild(dateContainer)
row.appendChild(cell) row.appendChild(cell)
if (date.getDay() == weekEnd) { if (date.getDay() == weekEnd) {
table.appendChild(row) table.appendChild(row)
var row = document.createElement('tr') var row = document.createElement('tr')
} }
} }
table.appendChild(row) table.appendChild(row)
} }
function daysArray(year, month, daysOfWeekNumeric) { function daysArray(year, month, daysOfWeekNumeric) {
month = month - 1 month = month - 1
var arr = [] var arr = []
var daysInCurrentMonth = daysInMonth(year, month + 1) var daysInCurrentMonth = daysInMonth(year, month + 1)
var firstDayOfMonth = new Date(year, month, 1).getDay() var firstDayOfMonth = new Date(year, month, 1).getDay()
var blankDaysStart = daysOfWeekNumeric.indexOf(firstDayOfMonth) * -1 var blankDaysStart = daysOfWeekNumeric.indexOf(firstDayOfMonth) * -1
for (var i = blankDaysStart + 1; i < 1; i++){ for (var i = blankDaysStart + 1; i < 1; i++){
var date = new Date(year, month, i) var date = new Date(year, month, i)
arr.push(date) arr.push(date)
} }
for (var i = 1; i < daysInCurrentMonth + 1; i++){ for (var i = 1; i < daysInCurrentMonth + 1; i++){
var date = new Date(year, month, i) var date = new Date(year, month, i)
arr.push(date) arr.push(date)
} }
var daysToFill = arr.length var daysToFill = arr.length
for (var i = 1; i < 42 - daysToFill + 1; i++){ for (var i = 1; i < 42 - daysToFill + 1; i++){
var date = new Date(year, month + 1, i) var date = new Date(year, month + 1, i)
arr.push(date) arr.push(date)
} }
return arr return arr
} }
@ -209,27 +182,21 @@ function daysInMonth (year, month) {
return new Date(year, month, 0).getDate(); return new Date(year, month, 0).getDate();
} }
function createDateSelectionHTML(){ function createDateSelectionHTML(){
var container = document.createElement('div') var container = document.createElement('div')
container.id = 'date_selector' container.id = 'date_selector'
var goButton = document.createElement('button') var goButton = document.createElement('button')
goButton.innerText = 'Go' goButton.innerText = 'Go'
goButton.id = 'button_load_selected_months' goButton.id = 'button_load_selected_months'
var label = document.createElement('label') var label = document.createElement('label')
label.setAttribute('for', 'years') label.setAttribute('for', 'years')
label.innerText = 'Go to: ' label.innerText = 'Go to: '
var selectYear = document.createElement('select') var selectYear = document.createElement('select')
selectYear.name='years' selectYear.name='years'
selectYear.id = 'year_selector' selectYear.id = 'year_selector'
var spanBegin = 1990
spanBegin = 1990 var spanEnd = 2030
spanEnd = 2030 var yearsSpan = spanEnd - spanBegin
yearsSpan = spanEnd - spanBegin
for (var i = 0; i < yearsSpan; i++){ for (var i = 0; i < yearsSpan; i++){
var option = document.createElement('option') var option = document.createElement('option')
option.value = spanBegin + i option.value = spanBegin + i
@ -237,7 +204,6 @@ function createDateSelectionHTML(){
selectYear.appendChild(option) selectYear.appendChild(option)
} }
selectYear.value = today.getFullYear() selectYear.value = today.getFullYear()
var selectMonth = document.createElement('select') var selectMonth = document.createElement('select')
selectMonth.name='months' selectMonth.name='months'
selectMonth.id = 'month_selector' selectMonth.id = 'month_selector'
@ -249,7 +215,6 @@ function createDateSelectionHTML(){
} }
selectMonth.value = today.getMonth() selectMonth.value = today.getMonth()
container.appendChild(label) container.appendChild(label)
container.appendChild(selectYear) container.appendChild(selectYear)
container.appendChild(selectMonth) container.appendChild(selectMonth)
@ -264,4 +229,7 @@ function createButton(id, className, innerText){
button.className = className button.className = className
button.innerText = innerText button.innerText = innerText
return button return button
} }
export { addCalendar }

View File

@ -0,0 +1,14 @@
const urls = {
'show_schedule': {
'show': '/hr_module/show_employee_plan_api',
'update': '/hr_module/update_plan_api'
}
,
'show_timelog': {
'show': '/hr_module/show_employee_timelog_api',
'update': '/hr_module/update_timelog_api',
}
}
export { urls }

View File

@ -0,0 +1,31 @@
import { addCalendar } from './calendar.js';
import { appendLegend, formatCalendarContainerSize, formatCalendarSize} from "./calendar_extended.js";
import { fetchDays } from './calendar_ajax_hr_module_requests.js'
window.addEventListener('load', renderWhole)
function renderWhole(){
var parent = document.getElementById('calendar_box')
parent.innerHTML = ''
parent.appendChild(addCalendar(3, new Date().getMonth() + 1, new Date().getFullYear(), 1, fetchDays))
appendLegend()
formatCalendarContainerSize(document.getElementById('calendar_container'))
formatCalendarSize()
document.getElementById('load_schedule_button').addEventListener('click', function(){
fetchDays()
})
}
export { renderWhole }

View File

@ -0,0 +1,68 @@
import {addClassToWorkingDays, searchedDateRange} from "./calendar_extended.js";
import {csrftoken} from "../../../static/js/csrf_token.js";
import {detailedRecordsMainBlock, formatTableSize} from "./calendar_to_table.js";
import { urls } from './calendar_ajax_hr_module_config.js'
function fetchDays(){
var host = 'http://' + window.location.host;
var fetch_url = host + urls[window.location.pathname.substring(window.location.pathname.lastIndexOf('/') + 1)]['show']
var range = searchedDateRange()
var startDate = range['min']
var endDate = range['max']
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,
"start_date": startDate,
"end_date" : endDate
}),
}).then((response) => {
return response.json();
}).then((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(detailedRecordsMainBlock(data))
parent.appendChild(listContainer)
formatTableSize()
});
}
function updateCheckedRecords(recordsArray, action){
var host = 'http://' + window.location.host;
var fetch_url = host + urls[window.location.pathname.substring(window.location.pathname.lastIndexOf('/') + 1)]['update']
fetch(fetch_url,
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRFToken': csrftoken
},
body: JSON.stringify({
'action': action,
'records': recordsArray,
}),
}).then((response) => {
return response.json();
}).then((data) => {
fetchDays()
})
}
export { fetchDays, updateCheckedRecords }

View File

@ -0,0 +1,91 @@
function appendLegend(){
var calendar = document.getElementById('calendar_container')
var container = document.createElement('div')
container.id = 'legend_container'
var activityTypes = ['work', 'vacation', 'sickness', 'parental_leave']
for(var i = 0; i < activityTypes.length; i++){
var legendElementContainer = document.createElement('div')
legendElementContainer.className = 'legend_element_container'
var legendDivText = document.createElement('div')
legendDivText.innerText = activityTypes[i]
legendDivText.className = 'legend_label'
var legendDivBox = document.createElement('div')
legendDivBox.classList.add('legend_cube')
legendDivBox.classList.add('days_of_month_' + activityTypes[i])
legendElementContainer.appendChild(legendDivText)
legendElementContainer.appendChild(legendDivBox)
container.appendChild(legendElementContainer)
}
calendar.appendChild(container)
}
function formatCalendarContainerSize(calendarContainer){
var monthsBlock = calendarContainer.querySelector('#months_block')
var calendarButton = calendarContainer.querySelector('#calendar_button_back')
var dateSelector = calendarContainer.querySelector('#date_selector')
var legendSelector = calendarContainer.querySelector('#legend_container')
var widthMonths = monthsBlock.offsetWidth
var heightMonths = monthsBlock.offsetHeight
var heightDateSelector = dateSelector.offsetHeight
var heightLegend = legendSelector.offsetHeight
var widthCalendarButton = calendarButton.offsetWidth * 2
var widthTotal = widthMonths + widthCalendarButton
var heightTotal = heightMonths + heightDateSelector + heightLegend
calendarContainer.setAttribute('style','height:' + heightTotal +'px; width:' + widthTotal + 'px');
}
function formatCalendarSize(){
var calendarBox = document.getElementById('calendar_box')
var calendar = document.getElementById('calendar_container')
calendarBox.setAttribute('style', 'width:' + calendar.offsetWidth + 'px')
}
function cleanCalendarClasses(){
var classesToKeep = ['days_of_month', 'days_of_month_current', 'days_of_month_today']
var days = document.getElementsByClassName('days_of_month_current')
for (var i = 0; i < days.length; i++){
var classList = days[i].classList
for (var j = 0; j < classList.length; j++){
if (!classesToKeep.includes(classList[j])){
days[i].classList.remove(classList[j])
console.log('removed ' + classList[j])
}
}
}
}
function addClassToWorkingDays(data){
cleanCalendarClasses()
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 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
}
export { appendLegend, formatCalendarContainerSize, formatCalendarSize, addClassToWorkingDays, searchedDateRange }

View File

@ -0,0 +1,179 @@
import { updateCheckedRecords } from './calendar_ajax_hr_module_requests.js'
function detailedRecordsMainBlock(data){
var container = document.createElement('div')
var buttonsContainer = document.createElement('div')
buttonsContainer.id = 'buttons_container'
buttonsContainer.appendChild(addButton('Edit', 'edit', eventListenerEdit))
buttonsContainer.appendChild(addButton('Save', 'save', eventListenerUpdate))
buttonsContainer.appendChild(addButton('Delete', 'delete', eventListenerUpdate))
buttonsContainer.appendChild(addButton('Cancel', 'cancel'))
buttonsContainer.appendChild(addButton('Select all/none', 'checkbox_select', eventListenerSelectAll))
container.appendChild(buttonsContainer)
container.appendChild(detailedCalendarRecordsTable(data))
return container
}
function addButton(innText, name, eventListener=null){
var button = document.createElement('button')
button.innerHTML = innText
button.name = name
button.className = 'change_button'
button.id = name + '_button'
if (eventListener !== null) {
button.addEventListener('click', eventListener)
}
return button
}
function detailedCalendarRecordsTable(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.className = 'database_row'
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)
var cell = row.insertCell(4)
var checkboxContainer = document.createElement('checkbox')
checkboxContainer.className = 'copy_over_checkbox_cell'
checkboxContainer.style.display = 'none'
var checkbox = document.createElement('input')
checkbox.type = 'checkbox'
checkbox.checked = false
checkboxContainer.appendChild(checkbox)
cell.appendChild(checkboxContainer)
}
return table
}
function eventListenerSelectAll(){
var elements = document.getElementsByTagName('input')
for (var i = 0; i < elements.length; i++){
if (elements[i].type == 'checkbox' && elements[i].checked == true){
elements[i].checked = false
} else if (elements[i].type == 'checkbox' && elements[i].checked == false){
elements[i].checked = true
}
}
}
function eventListenerEdit(){
unhideCheckboxes()
unlockRecordsForEditing()
}
function eventListenerUpdate(e){
var action = e.target.name
var data = getCheckedRecords()
updateCheckedRecords(data, action)
}
function appendCell(tableRow, tag, tagName, tagText, cellIndex){
var cell = tableRow.insertCell(cellIndex)
var textInput = document.createElement(tag)
textInput.innerText = tagText
textInput.name = tagName
textInput.className = tagName
cell.appendChild(textInput)
}
function unhideCheckboxes(){
var checkboxes = document.getElementsByClassName('copy_over_checkbox_cell')
for (var i = 0; i < checkboxes.length; i++){
checkboxes[i].style.display = 'initial'
checkboxes[i].firstChild.checked = true
}
var header_copy_over = document.getElementById('header_copy_over')
header_copy_over.style.display = 'table-cell'
}
function unlockRecordsForEditing(){
var rows = document.getElementsByClassName('database_row')
for (var j = 0; j < rows.length; j++) {
var children = rows[j].getElementsByTagName('div')
for (var i = 0; i < children.length; i++) {
if (['begin_time', 'end_time'].includes(children[i].className)) {
var value = children[i].innerText
var name = children[i].className
var input = document.createElement('input')
input.name = name
input.value = value
input.type = 'time'
children[i].innerHTML = ''
children[i].appendChild(input)
}
}
}
}
function getCheckedRecords(){
var checkboxes = document.getElementsByClassName('copy_over_checkbox_cell')
var outputArray = []
for (var i = 0; i < checkboxes.length; i++) {
if (checkboxes[i].firstChild.checked == true) {
console.log('checked', i)
var jsonChecked = {}
var row = checkboxes[i].parentNode.parentNode
var id = row.id.split('_')
id = id[id.length-1]
var username = row.getAttribute('database_username')
var beginTime = row.querySelectorAll('input[name="begin_time"]')[0].value
var endTime = row.querySelectorAll('input[name="end_time"]')[0].value
jsonChecked['id'] = parseInt(id)
jsonChecked['username'] = username
jsonChecked['begin_time'] = beginTime
jsonChecked['end_time'] = endTime
outputArray.push(jsonChecked)
}
}
return outputArray
}
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 createDetailedHeaders(){
var table = document.createElement('table')
let headerRow = document.createElement('tr')
let columns = ['Date', 'Start time', 'End time', 'Activity type', 'Copy over']
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)
if (i == columns.length -1){
headerCell.style.display = 'none'
headerCell.id = 'header_copy_over'
}
headerRow.appendChild(headerCell)
}
table.appendChild(headerRow)
table.id = 'detailed_plan_records'
return table
}
export { detailedRecordsMainBlock, getCheckedRecords, formatTableSize }

View File

@ -1,17 +0,0 @@
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;
}

View File

@ -1,4 +1,4 @@
const csrftoken = getCookie('csrftoken'); import {csrftoken} from "../../../static/js/csrf_token.js";
var searchEmployeeButton = document.getElementById('load_employee_data_button') var searchEmployeeButton = document.getElementById('load_employee_data_button')
searchEmployeeButton.addEventListener('click', function(){ searchEmployeeButton.addEventListener('click', function(){

View File

@ -1,5 +1,5 @@
const csrftoken = getCookie('csrftoken');
import { csrftoken } from '../../../static/js/csrf_token.js'
window.addEventListener('load', function (){ window.addEventListener('load', function (){
fetchSearchOptions() fetchSearchOptions()
@ -48,10 +48,10 @@ function appendFoundFilterOptions(data){
var caption = data[i]['caption']; var caption = data[i]['caption'];
var value = data[i]['column_value']; var value = data[i]['column_value'];
innerHTML = '<option value="' + value + '">' + caption + '</option>' var innerhtml = '<option value="' + value + '">' + caption + '</option>'
var wrapper = document.createElement('div'); var wrapper = document.createElement('div');
wrapper.innerHTML = innerHTML; wrapper.innerHTML = innerhtml;
var htmlNode = wrapper.firstChild; var htmlNode = wrapper.firstChild;
parent.appendChild(htmlNode); parent.appendChild(htmlNode);
@ -204,7 +204,7 @@ function buildPlanJson(){
var upperBoundary = document.getElementById('planning_upper_boundary').value var upperBoundary = document.getElementById('planning_upper_boundary').value
for (var i = 0; i < employees.length; i++) { for (var i = 0; i < employees.length; i++) {
var planJson = {} var planJson = {}
row = employees[0] var row = employees[0]
var username = row.getAttribute('data-username') var username = row.getAttribute('data-username')
var startTime = row.getElementsByClassName('schedule_time_input')[0].value var startTime = row.getElementsByClassName('schedule_time_input')[0].value
var activityType = row.getElementsByClassName('activity_type')[0].value var activityType = row.getElementsByClassName('activity_type')[0].value
@ -212,7 +212,7 @@ function buildPlanJson(){
var days = row.getElementsByClassName('working_days') var days = row.getElementsByClassName('working_days')
var daysOfWeek = {} var daysOfWeek = {}
for (var k = 0; k < days.length; k++){ for (var k = 0; k < days.length; k++){
day = days[k] var day = days[k]
daysOfWeek[day.value] = day.checked daysOfWeek[day.value] = day.checked
} }
planJson['username'] = username planJson['username'] = username
@ -250,14 +250,3 @@ function postPlanToDb(){
} }
function showPopup(){
document.getElementById("popup_content").addEventListener("click", function(e) {
e.stopPropagation();
});
let popup = document.getElementById("login_popup");
if (window.getComputedStyle(popup).getPropertyValue('display') === 'none'){
popup.style.display ='flex';
} else {
popup.style.display ='none';
}
}

View File

@ -0,0 +1,59 @@
import { csrftoken } from '../../../static/js/csrf_token.js'
window.addEventListener('load', function (){
fetchSearchOptions()
var filterType = document.getElementById('schedule_filter_category')
filterType.addEventListener('change', fetchSearchOptions)
var fetchEmployeesButton = document.getElementById('load_employees');
fetchEmployeesButton.addEventListener('click', fetchEmployees);
var submitToDb = document.getElementById('run_planning');
submitToDb.addEventListener('click', postPlanToDb);
})
function fetchSearchOptions() {
var host = 'http://' + window.location.host;
var fetch_url = host + '/hr_module/search_api'
var searched_field = document.getElementById('schedule_filter_category').value
var searched_string = document.getElementById('searched_string').value
fetch(fetch_url,
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRFToken': csrftoken
},
body: JSON.stringify({
"searched_field": searched_field,
"searched_string": searched_string
}),
}).then((response) => {
return response.json();
}).then((data) => {
appendFoundFilterOptions(data);
});
}
function appendFoundFilterOptions(data){
var parent = document.getElementById('schedule_filter_search');
parent.innerHTML = '';
for (var i = 0; i < data.length; i++) {
var caption = data[i]['caption'];
var value = data[i]['column_value'];
var innerhtml = '<option value="' + value + '">' + caption + '</option>'
var wrapper = document.createElement('div');
wrapper.innerHTML = innerhtml;
var htmlNode = wrapper.firstChild;
parent.appendChild(htmlNode);
}
}

View File

@ -1,377 +0,0 @@
const csrftoken = getCookie('csrftoken');
window.addEventListener('load', function(){
var parent = document.getElementById('calendar_box')
parent.appendChild(addCalendar(monthsAhead=3))
appendLegend()
formatCalendarContainerSize(document.getElementById('calendar_container'))
formatCalendarSize()
document.getElementById('load_schedule_button').addEventListener('click', function(){
fetchDays()
})
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 + '/hr_module/show_employee_plan_api'
var range = searchedDateRange()
var startDate = range['min']
var endDate = range['max']
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,
"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)
var cell = row.insertCell(4)
var buttonContainer = document.createElement('div')
buttonContainer.className = 'buttons_cell'
var button = document.createElement('button')
button.innerText = 'Edit'
button.value = index
button.addEventListener('click', unlockRecordsForEditing)
buttonContainer.appendChild(button)
cell.appendChild(buttonContainer)
var cell = row.insertCell(5)
var checkboxContainer = document.createElement('checkbox')
checkboxContainer.className = 'copy_over_checkbox_cell'
checkboxContainer.style.display = 'none'
var checkbox = document.createElement('input')
checkbox.type = 'checkbox'
checkbox.checked = false
checkboxContainer.appendChild(checkbox)
cell.appendChild(checkboxContainer)
}
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 unlockRecordsForEditing(event){
var databaseId = event.target.value
var parent = event.target.parentElement
var row = document.getElementById('database_id_' + databaseId.toString())
var children = row.getElementsByTagName('div')
for (var i = 0; i < children.length; i++){
console.log(children[i].className )
if (['begin_time', 'end_time'].includes(children[i].className)) {
var value = children[i].innerText
var name = children[i].className
var input = document.createElement('input')
input.name = name
input.value = value
input.type = 'time'
children[i].innerHTML = ''
children[i].appendChild(input)
}
}
removeEditButtons(databaseId)
parent.appendChild(addSaveButton(databaseId))
parent.appendChild(addDeleteButton(databaseId))
parent.appendChild(addCancelButton(databaseId))
unhideCheckboxes(databaseId)
}
function getCheckedRecords(event){
var id = event.target.value
var row = document.getElementById('database_id_' + id)
var username = row.getAttribute('database_username')
var children = row.getElementsByTagName('input')
var copyValues = {'username': username}
for (var i = 0; i < children.length; i++) {
var fieldName = children[i].name
var fieldvalue = children[i].value
if (fieldName != '') {
copyValues[fieldName] = fieldvalue
}
}
var checkboxes = document.getElementsByClassName('copy_over_checkbox_cell')
var outputArray = []
for (var i = 0; i < checkboxes.length; i++) {
if (checkboxes[i].firstChild.checked == true) {
console.log('checked', i)
var jsonChecked = {}
var row = checkboxes[i].parentNode.parentNode
var id = row.id.split('_')
id = id[id.length-1]
jsonChecked['id'] = parseInt(id)
var jsonConcat = Object.assign(jsonChecked, copyValues)
outputArray.push(jsonConcat)
}
}
console.log(outputArray)
return outputArray
}
function updateCheckedRecords(recordsArray, action){
var host = 'http://' + window.location.host;
var fetch_url = host + '/hr_module/update_plan_api'
fetch(fetch_url,
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRFToken': csrftoken
},
body: JSON.stringify({
'action': action,
'records': recordsArray,
}),
}).then((response) => {
return response.json();
}).then((data) => {
console.log(data);
parent.innerHTML = ''
parent.appendChild(addCalendar(3))
formatCalendarContainerSize(document.getElementById('calendar_container'))
})
}
function unhideCheckboxes(databaseId){
var checkboxes = document.getElementsByClassName('copy_over_checkbox_cell')
for (var i = 0; i < checkboxes.length; i++){
checkboxes[i].style.display = 'initial'
if (checkboxes[i].parentNode.parentNode.id == 'database_id_' + databaseId.toString()){
checkboxes[i].firstChild.checked = 'true'
}
}
var header_copy_over = document.getElementById('header_copy_over')
header_copy_over.style.display = 'table-cell'
}
function removeEditButtons(id){
var elements = document.getElementsByClassName('buttons_cell')
for (var i = 0; i < elements.length; i++){
elements[i].innerHTML = ''
}
}
function addSaveButton(databaseId){
var button = document.createElement('button')
button.innerHTML = 'Save'
button.name = 'save'
button.value = databaseId
button.addEventListener('click', function(event){
var checkedRecords = getCheckedRecords(event)
updateCheckedRecords(checkedRecords, 'update')
fetchDays()
})
return button
}
function addDeleteButton(databaseId){
var button = document.createElement('button')
button.innerHTML = 'Delete'
button.name = 'delete'
button.value = databaseId
button.addEventListener('click', function(event){
var checkedRecords = getCheckedRecords(event)
updateCheckedRecords(checkedRecords, 'delete')
fetchDays()
})
return button
}
function addCancelButton(databaseId){
var button = document.createElement('button')
button.innerHTML = 'Cancel'
button.name = 'cancel'
button.value = databaseId
button.addEventListener('click', fetchDays)
return button
}
function createDetailedHeaders(){
var table = document.createElement('table')
let headerRow = document.createElement('tr')
let columns = ['Date', 'Start time', 'End time', 'Activity type', 'Action', 'Copy over']
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)
if (i == columns.length -1){
headerCell.style.display = 'none'
headerCell.id = 'header_copy_over'
}
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 legendSelector = calendarContainer.querySelector('#legend_container')
var widthMonths = monthsBlock.offsetWidth
var heightMonths = monthsBlock.offsetHeight
var heightDateSelector = dateSelector.offsetHeight
var heightLegend = legendSelector.offsetHeight
var widthCalendarButton = calendarButton.offsetWidth * 2
var widthTotal = widthMonths + widthCalendarButton
var heightTotal = heightMonths + heightDateSelector + heightLegend
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 formatCalendarSize(){
var calendarBox = document.getElementById('calendar_box')
var calendar = document.getElementById('calendar_container')
calendarBox.setAttribute('style', 'width:' + calendar.offsetWidth + '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;
}
function appendLegend(){
var calendar = document.getElementById('calendar_container')
var container = document.createElement('div')
container.id = 'legend_container'
var activityTypes = ['work', 'vacation', 'sickness', 'parental_leave']
for(var i = 0; i < activityTypes.length; i++){
var legendElementContainer = document.createElement('div')
legendElementContainer.className = 'legend_element_container'
var legendDivText = document.createElement('div')
legendDivText.innerText = activityTypes[i]
legendDivText.className = 'legend_label'
var legendDivBox = document.createElement('div')
legendDivBox.classList.add('legend_cube')
legendDivBox.classList.add('days_of_month_' + activityTypes[i])
legendElementContainer.appendChild(legendDivText)
legendElementContainer.appendChild(legendDivBox)
container.appendChild(legendElementContainer)
}
calendar.appendChild(container)
}

View File

@ -1,378 +0,0 @@
const csrftoken = getCookie('csrftoken');
window.addEventListener('load', function(){
var parent = document.getElementById('calendar_box')
parent.appendChild(addCalendar(monthsAhead=3))
appendLegend()
formatCalendarContainerSize(document.getElementById('calendar_container'))
formatCalendarSize()
document.getElementById('load_schedule_button').addEventListener('click', function(){
fetchDays()
})
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 + '/hr_module/show_employee_timelog_api'
var range = searchedDateRange()
var startDate = range['min']
var endDate = range['max']
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,
"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)
var cell = row.insertCell(4)
var buttonContainer = document.createElement('div')
buttonContainer.className = 'buttons_cell'
var button = document.createElement('button')
button.innerText = 'Edit'
button.value = index
button.addEventListener('click', unlockRecordsForEditing)
buttonContainer.appendChild(button)
cell.appendChild(buttonContainer)
var cell = row.insertCell(5)
var checkboxContainer = document.createElement('checkbox')
checkboxContainer.className = 'copy_over_checkbox_cell'
checkboxContainer.style.display = 'none'
var checkbox = document.createElement('input')
checkbox.type = 'checkbox'
checkbox.checked = false
checkboxContainer.appendChild(checkbox)
cell.appendChild(checkboxContainer)
}
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 unlockRecordsForEditing(event){
var databaseId = event.target.value
var parent = event.target.parentElement
var row = document.getElementById('database_id_' + databaseId.toString())
var children = row.getElementsByTagName('div')
for (var i = 0; i < children.length; i++){
console.log(children[i].className )
if (['begin_time', 'end_time'].includes(children[i].className)) {
var value = children[i].innerText
var name = children[i].className
var input = document.createElement('input')
input.name = name
input.value = value
input.type = 'time'
children[i].innerHTML = ''
children[i].appendChild(input)
}
}
removeEditButtons(databaseId)
parent.appendChild(addSaveButton(databaseId))
parent.appendChild(addDeleteButton(databaseId))
parent.appendChild(addCancelButton(databaseId))
unhideCheckboxes(databaseId)
}
function getCheckedRecords(event){
var id = event.target.value
var row = document.getElementById('database_id_' + id)
var username = row.getAttribute('database_username')
var children = row.getElementsByTagName('input')
var copyValues = {'username': username}
for (var i = 0; i < children.length; i++) {
var fieldName = children[i].name
var fieldvalue = children[i].value
if (fieldName != '') {
copyValues[fieldName] = fieldvalue
}
}
var checkboxes = document.getElementsByClassName('copy_over_checkbox_cell')
var outputArray = []
for (var i = 0; i < checkboxes.length; i++) {
if (checkboxes[i].firstChild.checked == true) {
console.log('checked', i)
var jsonChecked = {}
var row = checkboxes[i].parentNode.parentNode
var id = row.id.split('_')
id = id[id.length-1]
jsonChecked['id'] = parseInt(id)
var jsonConcat = Object.assign(jsonChecked, copyValues)
outputArray.push(jsonConcat)
}
}
console.log(outputArray)
return outputArray
}
function updateCheckedRecords(recordsArray, action){
var host = 'http://' + window.location.host;
var fetch_url = host + '/hr_module/update_timelog_api'
fetch(fetch_url,
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRFToken': csrftoken
},
body: JSON.stringify({
'action': action,
'records': recordsArray,
}),
}).then((response) => {
return response.json();
}).then((data) => {
console.log(data);
parent.innerHTML = ''
parent.appendChild(addCalendar(3))
formatCalendarContainerSize(document.getElementById('calendar_container'))
})
}
function unhideCheckboxes(databaseId){
var checkboxes = document.getElementsByClassName('copy_over_checkbox_cell')
for (var i = 0; i < checkboxes.length; i++){
checkboxes[i].style.display = 'initial'
if (checkboxes[i].parentNode.parentNode.id == 'database_id_' + databaseId.toString()){
checkboxes[i].firstChild.checked = 'true'
}
}
var header_copy_over = document.getElementById('header_copy_over')
header_copy_over.style.display = 'table-cell'
}
function removeEditButtons(id){
var elements = document.getElementsByClassName('buttons_cell')
for (var i = 0; i < elements.length; i++){
elements[i].innerHTML = ''
}
}
function addSaveButton(databaseId){
var button = document.createElement('button')
button.innerHTML = 'Save'
button.name = 'save'
button.value = databaseId
button.addEventListener('click', function(event){
var checkedRecords = getCheckedRecords(event)
updateCheckedRecords(checkedRecords, 'update')
fetchDays()
})
return button
}
function addDeleteButton(databaseId){
var button = document.createElement('button')
button.innerHTML = 'Delete'
button.name = 'delete'
button.value = databaseId
button.addEventListener('click', function(event){
var checkedRecords = getCheckedRecords(event)
updateCheckedRecords(checkedRecords, 'delete')
fetchDays()
})
return button
}
function addCancelButton(databaseId){
var button = document.createElement('button')
button.innerHTML = 'Cancel'
button.name = 'cancel'
button.value = databaseId
button.addEventListener('click', fetchDays)
return button
}
function createDetailedHeaders(){
var table = document.createElement('table')
let headerRow = document.createElement('tr')
let columns = ['Date', 'Start time', 'End time', 'Activity type', 'Action', 'Copy over']
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)
if (i == columns.length -1){
headerCell.style.display = 'none'
headerCell.id = 'header_copy_over'
}
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 legendSelector = calendarContainer.querySelector('#legend_container')
var widthMonths = monthsBlock.offsetWidth
var heightMonths = monthsBlock.offsetHeight
var heightDateSelector = dateSelector.offsetHeight
var heightLegend = legendSelector.offsetHeight
var widthCalendarButton = calendarButton.offsetWidth * 2
var widthTotal = widthMonths + widthCalendarButton
var heightTotal = heightMonths + heightDateSelector + heightLegend
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 formatCalendarSize(){
var calendarBox = document.getElementById('calendar_box')
var calendar = document.getElementById('calendar_container')
calendarBox.setAttribute('style', 'width:' + calendar.offsetWidth + '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;
}
function appendLegend(){
var calendar = document.getElementById('calendar_container')
var container = document.createElement('div')
container.id = 'legend_container'
var activityTypes = ['work', 'vacation', 'sickness', 'parental_leave']
for(var i = 0; i < activityTypes.length; i++){
var legendElementContainer = document.createElement('div')
legendElementContainer.className = 'legend_element_container'
var legendDivText = document.createElement('div')
legendDivText.innerText = activityTypes[i]
legendDivText.className = 'legend_label'
var legendDivBox = document.createElement('div')
legendDivBox.classList.add('legend_cube')
legendDivBox.classList.add('days_of_month_' + activityTypes[i])
legendElementContainer.appendChild(legendDivText)
legendElementContainer.appendChild(legendDivBox)
container.appendChild(legendElementContainer)
}
calendar.appendChild(container)
}

View File

@ -8,7 +8,6 @@
{% block core_content %} {% block core_content %}
<script src="{% static '/js/csrf_token.js' %}"></script>
<div id="sidebar"> <div id="sidebar">
@ -51,7 +50,7 @@
</a> </a>
<a href="{% url 'hr_module:create_schedule' %}"> <a href="{% url 'hr_module:export' %}">
<div class="sidebar_item" >Export data <div class="sidebar_item" >Export data
</div> </div>
</a> </a>

View File

@ -15,6 +15,6 @@
</div> </div>
<script src="{% static '/js/hr_module_change_employee_data.js' %}"></script> <script type="module" src="{% static '/js/hr_module_change_employee_data.js' %}"></script>
{% endblock %} {% endblock %}

View File

@ -56,6 +56,6 @@
</div> </div>
<script src="{% static '/js/hr_module_create_schedule.js' %}"></script> <script type="module" src="{% static '/js/hr_module_create_schedule.js' %}"></script>
{% endblock %} {% endblock %}

View File

@ -0,0 +1,48 @@
{% extends 'hr_module_base.html' %}
{% load static %}
{% block action_panel %}
<link rel="stylesheet" href="{% static '/css/hr_module_create_schedule.css' %}">
<form method="POST">
{% csrf_token %}
<div class="search_row">
<div class="search_element">Select filter type:
<select name="category" id="schedule_filter_category">
<option value="username">Person</option>
<option value="manager">Manager</option>
<option value="department">Department</option>
</select>
</div>
<div class="search_element">
<input name="searched_string" list="schedule_filter_search" id="searched_string" autocomplete="off" >
<datalist id="schedule_filter_search">
</datalist>
</div>
</div>
<div class="search_row">
<div class="search_element">
<input name="date_start" type="date" id="date_start" autocomplete="off" >
</div>
<div class="search_element">
<input name="date_end" type="date" id="date_end" autocomplete="off" >
</div>
</div>
<div class="search_row">
<div class="search_element">
<button type="submit" id="download_report">Download report</button>
</div>
</div>
</form>
<script type="module" src="{% static '/js/hr_module_export.js' %}"></script>
{% endblock %}

View File

@ -1,16 +0,0 @@
{% extends 'base.html' %}
{% load static %}
{% block core_content %}
<h4>Please login</h4>
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Submit">
</form>
{% endblock %}

View File

@ -1,16 +0,0 @@
{% extends 'base.html' %}
{% load static %}
{% block core_content %}
<h4>Please change your password</h4>
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Submit">
</form>
{% endblock %}

View File

@ -14,8 +14,7 @@
</div> </div>
<div id="calendar_box"></div> <div id="calendar_box"></div>
<script src="{% static '/js/calendar.js' %}"></script>
<script src="{% static '/js/hr_module_show_schedule.js' %}"></script>
<script type="module" src="{% static '/js/../../static/js/calendar_ajax_hr_module_main.js' %}"></script>
{% endblock %} {% endblock %}

View File

@ -14,8 +14,6 @@
</div> </div>
<div id="calendar_box"></div> <div id="calendar_box"></div>
<script src="{% static '/js/calendar.js' %}"></script> <script type="module" src="{% static '/js/../../static/js/calendar_ajax_hr_module_main.js' %}"></script>
<script src="{% static '/js/hr_module_show_timelog.js' %}"></script>
{% endblock %} {% endblock %}

View File

@ -6,22 +6,21 @@ from django.contrib.auth import views as auth_views
app_name = 'hr_module' app_name = 'hr_module'
urlpatterns = [ 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('home', views.homepage, name='homepage'),
path('create_schedule', views.create_schedule, name='create_schedule'), path('create_schedule', views.create_schedule, name='create_schedule'),
path('create_employees', views.create_employees, name='create_employees'), path('create_employees', views.create_employees, name='create_employees'),
path('search_api', views.search_users_api, name='search_users_api'), path('search_api', views.search_users_api, name='search_users_api'),
path('loademployees', views.load_employees_api, name='load_employees'), path('loademployees', views.load_employees_api, name='load_employees'),
path('new_plan_api', views.new_plan_api, name='new_plan_api'), path('new_plan_api', views.new_plan_api, name='new_plan_api'),
path('manage_schedule', views.manage_schedule, name='manage_schedule'), path('show_schedule', views.manage_schedule, name='manage_schedule'),
path('show_employee_plan_api', views.show_employee_plan_api, name='show_employee_plan_api'), path('show_employee_plan_api', views.show_employee_plan_api, name='show_employee_plan_api'),
path('update_plan_api', views.update_plan_api, name='update_plan_api'), path('update_plan_api', views.update_plan_api, name='update_plan_api'),
path('manage_timelog', views.manage_timelog, name='manage_timelog'), path('show_timelog', views.manage_timelog, name='manage_timelog'),
path('show_employee_timelog_api', views.show_employee_timelog_api, name='show_employee_timelog_api'), path('show_employee_timelog_api', views.show_employee_timelog_api, name='show_employee_timelog_api'),
path('update_timelog_api', views.update_timelog_api, name='update_timelog_api'), path('update_timelog_api', views.update_timelog_api, name='update_timelog_api'),
path('change_employee_data', views.change_employee_data, name='change_employee_data'), 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'), path('change_employee_data_api', views.change_employee_data_api, name='change_employee_data_api'),
path('plan_creation_log', views.plan_creation_log, name='plan_creation_log'), path('plan_creation_log', views.plan_creation_log, name='plan_creation_log'),
path('export', views.export, name='export'),
] ]

View File

@ -5,18 +5,20 @@ from hr_module.handling_functions.data_import_functions import read_and_parse_ex
from hr_module.handling_functions.misc import dictfetchall from hr_module.handling_functions.misc import dictfetchall
from hr_module.handling_functions.insert_to_plan import UpdatePlan from hr_module.handling_functions.insert_to_plan import UpdatePlan
from hr_module.handling_functions.monthly_planning_functions import create_planning_operation_report from hr_module.handling_functions.monthly_planning_functions import create_planning_operation_report
from hr_module.sql_queries import export_queries
import pandas as pd import pandas as pd
import json import json
from .models import Employee, PlanCreationLog, Plan, TimeLog from .models import Employee, PlanCreationLog, Plan, TimeLog
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.http import HttpResponse, JsonResponse, Http404, HttpResponseRedirect from django.http import HttpResponse, JsonResponse, HttpResponseRedirect
from django.db import connection from django.db import connection
import datetime import datetime
from django.urls import reverse from django.urls import reverse, reverse_lazy
from django.conf import settings from django.conf import settings
import csv
login_url = '/hr_module/login' login_url = reverse_lazy('login')
# Create your views here. # Create your views here.
@login_required(login_url=login_url) @login_required(login_url=login_url)
def create_schedule(request): def create_schedule(request):
@ -84,7 +86,6 @@ def change_employee_data_api(request):
response_dict = dict(record_user, **record_employee) response_dict = dict(record_user, **record_employee)
for i in ['_state', 'password']: for i in ['_state', 'password']:
response_dict.pop(i) response_dict.pop(i)
print(response_dict)
return JsonResponse(response_dict, safe=False) return JsonResponse(response_dict, safe=False)
else: else:
return JsonResponse({'error': 'not_authenticated'}) return JsonResponse({'error': 'not_authenticated'})
@ -98,7 +99,6 @@ def create_employees(request):
if request.method == 'POST': if request.method == 'POST':
if 'import_preview' in request.POST: if 'import_preview' in request.POST:
fileform = UploadFileForm(request.POST, request.FILES) fileform = UploadFileForm(request.POST, request.FILES)
print(fileform.is_valid())
if fileform.is_valid(): if fileform.is_valid():
uploaded_file = request.FILES['file'] uploaded_file = request.FILES['file']
df_dict = read_and_parse_excel(uploaded_file) df_dict = read_and_parse_excel(uploaded_file)
@ -123,7 +123,6 @@ def create_employees(request):
df_dict.pop(i, None) df_dict.pop(i, None)
df = pd.DataFrame(df_dict, index=[0]) df = pd.DataFrame(df_dict, index=[0])
insert_excel(df) insert_excel(df)
print('done')
template = 'hr_module_import_success.html' template = 'hr_module_import_success.html'
return render(request, template) return render(request, template)
@ -156,7 +155,6 @@ def search_users_api(request):
body = json.loads(request.body) body = json.loads(request.body)
searched_field = body['searched_field'] searched_field = body['searched_field']
searched_string = body['searched_string'] searched_string = body['searched_string']
print(searched_field, searched_string)
cursor = connection.cursor() cursor = connection.cursor()
@ -175,7 +173,6 @@ def search_users_api(request):
) )
response = dictfetchall(cursor) response = dictfetchall(cursor)
print(response)
return JsonResponse(response, safe=False) return JsonResponse(response, safe=False)
@ -184,12 +181,10 @@ def load_employees_api(request):
body = json.loads(request.body) body = json.loads(request.body)
searched_field = body['searched_field'] searched_field = body['searched_field']
searched_string = body['searched_string'] searched_string = body['searched_string']
print(searched_field, searched_string)
cursor = connection.cursor() cursor = connection.cursor()
if searched_field == 'department': if searched_field == 'department':
print('Deparment executed')
cursor.execute('select auth.first_name || %s || auth.last_name as name, auth.username as username, ' cursor.execute('select auth.first_name || %s || auth.last_name as name, auth.username as username, '
'empl.manager_username as manager_name, tm.daily_hours, ' 'empl.manager_username as manager_name, tm.daily_hours, '
'tm.mon, tm.tue, tm.wed, tm.thu, tm.fri, tm.sat, tm.fri ' 'tm.mon, tm.tue, tm.wed, tm.thu, tm.fri, tm.sat, tm.fri '
@ -198,7 +193,6 @@ def load_employees_api(request):
'where department = %s', [' ', searched_string]) 'where department = %s', [' ', searched_string])
elif searched_field == 'manager': elif searched_field == 'manager':
print('Manager executed')
cursor.execute('select auth.first_name || %s || auth.last_name as name, auth.username as username, ' cursor.execute('select auth.first_name || %s || auth.last_name as name, auth.username as username, '
'empl.manager_username as manager_name, tm.daily_hours, ' 'empl.manager_username as manager_name, tm.daily_hours, '
'tm.mon, tm.tue, tm.wed, tm.thu, tm.fri, tm.sat, tm.fri ' 'tm.mon, tm.tue, tm.wed, tm.thu, tm.fri, tm.sat, tm.fri '
@ -207,7 +201,6 @@ def load_employees_api(request):
'where manager_username = %s', [' ', searched_string]) 'where manager_username = %s', [' ', searched_string])
elif searched_field == 'username': elif searched_field == 'username':
print('Username executed')
cursor.execute('select auth.first_name || %s || auth.last_name as name, auth.username as username, ' cursor.execute('select auth.first_name || %s || auth.last_name as name, auth.username as username, '
'empl.manager_username as manager_name, tm.daily_hours, ' 'empl.manager_username as manager_name, tm.daily_hours, '
'tm.mon, tm.tue, tm.wed, tm.thu, tm.fri, tm.sat, tm.sun ' 'tm.mon, tm.tue, tm.wed, tm.thu, tm.fri, tm.sat, tm.sun '
@ -217,7 +210,6 @@ def load_employees_api(request):
'where empl.username = %s ', [' ', searched_string]) 'where empl.username = %s ', [' ', searched_string])
response = dictfetchall(cursor) response = dictfetchall(cursor)
print(response)
return JsonResponse(response, safe=False) return JsonResponse(response, safe=False)
@ -266,7 +258,6 @@ def show_employee_plan_api(request):
def update_plan_api(request): def update_plan_api(request):
if request.method == 'POST': if request.method == 'POST':
body = json.loads(request.body) body = json.loads(request.body)
print(body)
if body['action'] == 'delete': if body['action'] == 'delete':
for i in body['records']: for i in body['records']:
record_id = i['id'] record_id = i['id']
@ -315,7 +306,6 @@ def show_employee_timelog_api(request):
def update_timelog_api(request): def update_timelog_api(request):
if request.method == 'POST': if request.method == 'POST':
body = json.loads(request.body) body = json.loads(request.body)
print(body)
if body['action'] == 'delete': if body['action'] == 'delete':
for i in body['records']: for i in body['records']:
record_id = i['id'] record_id = i['id']
@ -339,6 +329,9 @@ def update_timelog_api(request):
def plan_creation_log(request): def plan_creation_log(request):
session_user = User.objects.select_related('employee').get(username=request.user.username) session_user = User.objects.select_related('employee').get(username=request.user.username)
session_user_manager_flag = session_user.employee.manager_flag session_user_manager_flag = session_user.employee.manager_flag
if not session_user_manager_flag and not request.user.is_superuser:
return HttpResponseRedirect(reverse('employee_module:homepage'))
if request.user.is_superuser: if request.user.is_superuser:
creation_log = PlanCreationLog.objects.all().order_by('-creation_date') creation_log = PlanCreationLog.objects.all().order_by('-creation_date')
elif session_user_manager_flag: elif session_user_manager_flag:
@ -348,4 +341,50 @@ def plan_creation_log(request):
'path': settings.IMPORT_REPORT_STORAGE} 'path': settings.IMPORT_REPORT_STORAGE}
template_name = 'hr_module_creation_log.html' template_name = 'hr_module_creation_log.html'
return render(request, context=context, template_name=template_name) return render(request, context=context, template_name=template_name)
@login_required(login_url=login_url)
def export(request):
session_user = User.objects.select_related('employee').get(username=request.user.username)
if not session_user.employee.manager_flag and not request.user.is_superuser:
return HttpResponseRedirect(reverse('employee_module:homepage'))
if request.method == 'POST':
category = request.POST.get('category')
searched_string = request.POST.get('searched_string')
date_start = request.POST.get('date_start')
date_end = request.POST.get('date_end')
months = months_list(date_start, date_end)
query = export_queries[category]
cursor = connection.cursor()
cursor.execute(query.format(months, searched_string))
response = HttpResponse(content_type='text/csv')
response['Content-Disposition'] = 'attachment; filename="time_report.csv"'
resp = dictfetchall(cursor)
writer = csv.writer(response)
writer.writerow([k for k in resp[0].keys()])
for row in resp:
writer.writerow([v for v in row.values()])
return response
template = 'hr_module_export.html'
return render(request, template)
def months_list(start_date, end_date):
start_date = datetime.datetime.strptime(start_date, '%Y-%m-%d').date()
end_date = datetime.datetime.strptime(end_date, '%Y-%m-%d').date()
tmp = end_date
list_ = []
while tmp >= start_date:
list_.append(tmp.strftime('%Y-%m'))
tmp = tmp.replace(day=1) - datetime.timedelta(days=1)
start_date_str = start_date.strftime('%Y-%m')
if not start_date_str in list_:
list_.append(start_date_str)
return tuple(list_)

View File

@ -6,8 +6,11 @@ html, body {
} }
.navbar { .navbar {
height: 50px; height: 50px;
background-color: #D3D3D3; background-color: #202831;
width: 100%; width: 100%;
border-bottom: #7F8B94 thin solid;
color: #7F8B94;
} }
.main_container { .main_container {
background-color: whitesmoke; background-color: whitesmoke;
@ -25,6 +28,7 @@ html, body {
text-align:center; text-align:center;
margin-top: 15px; margin-top: 15px;
margin-right: 15px; margin-right: 15px;
text-decoration: none;
} }
#calendar_box, #list_container { #calendar_box, #list_container {

View File

@ -14,4 +14,8 @@ function getCookie(name) {
} }
} }
return cookieValue; return cookieValue;
} }
const csrftoken = getCookie('csrftoken');
export { csrftoken }

View File

@ -15,7 +15,7 @@
{% if user.is_authenticated %} {% if user.is_authenticated %}
<div class="navbar_item"> <div class="navbar_item">
<a href="{% url 'hr_module:logout' %}">Log out</a> <a href="{% url 'logout' %}">Log out</a>
</div> </div>
<div class="navbar_item">You are logged in as: {{ user }} </div> <div class="navbar_item">You are logged in as: {{ user }} </div>

View File

@ -12,6 +12,7 @@ https://docs.djangoproject.com/en/3.1/ref/settings/
from pathlib import Path from pathlib import Path
import os import os
from django.urls import reverse_lazy
# Build paths inside the project like this: BASE_DIR / 'subdir'. # Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent BASE_DIR = Path(__file__).resolve().parent.parent
@ -66,7 +67,7 @@ TEMPLATES = [
'APP_DIRS': True, 'APP_DIRS': True,
'OPTIONS': { 'OPTIONS': {
'context_processors': [ 'context_processors': [
'hr_module.context_processors.report_download_path', 'hr_module.context_processors.manager_flag',
'django.template.context_processors.media', 'django.template.context_processors.media',
'django.template.context_processors.debug', 'django.template.context_processors.debug',
'django.template.context_processors.request', 'django.template.context_processors.request',
@ -138,11 +139,11 @@ STATICFILES_DIRS = [
LOGOUT_REDIRECT_URL = '/hr_module/login' LOGOUT_REDIRECT_URL = reverse_lazy('login')
LOGIN_REDIRECT_URL = '/hr_module/home' LOGIN_REDIRECT_URL = reverse_lazy('hr_module:homepage')
MEDIA_ROOT = os.path.join(BASE_DIR, 'media') MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/' MEDIA_URL = '/media/'
TMP_FILE_STORAGE = os.path.join(MEDIA_URL, 'temp/') TMP_FILE_STORAGE = os.path.join(MEDIA_ROOT, 'temp/')
IMPORT_REPORT_STORAGE = os.path.join(BASE_DIR, 'import_reports') IMPORT_REPORT_STORAGE = os.path.join(MEDIA_ROOT, 'import_reports/')

Some files were not shown because too many files have changed in this diff Show More