todos: create demo data, add some css
This commit is contained in:
parent
a49c50f91e
commit
2eeda5315e
BIN
db.sqlite3
BIN
db.sqlite3
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -2,22 +2,23 @@
|
||||
const monthsStrings = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']
|
||||
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')
|
||||
calendarContainer.id = 'calendar_container'
|
||||
|
||||
|
||||
var monthsBlock = document.createElement('div')
|
||||
monthsBlock.id = 'months_block'
|
||||
|
||||
renderCalendarFor(calendarContainer, monthsBlock, currentYear, currentMonth, monthsAhead, weekStart)
|
||||
|
||||
calendarContainer.appendChild(createButtonBack(calendarContainer, monthsBlock, monthsAhead, weekStart))
|
||||
calendarContainer.appendChild(monthsBlock)
|
||||
calendarContainer.appendChild(createButtonForwards(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
|
||||
}
|
||||
|
||||
@ -26,7 +27,6 @@ function createButtonBack(calendarContainer, monthsBlock, monthsAhead, weekStart
|
||||
buttonBack.addEventListener('click', function(){
|
||||
var currentMonth = parseInt(calendarContainer.getAttribute('month_shown'))
|
||||
var currentYear = parseInt(calendarContainer.getAttribute('year_shown'))
|
||||
|
||||
if (currentMonth == 1){
|
||||
currentMonth = 12
|
||||
currentYear = currentYear - 1
|
||||
@ -43,7 +43,6 @@ function createButtonForwards(calendarContainer, monthsBlock, monthsAhead, weekS
|
||||
buttonForwards.addEventListener('click', function(){
|
||||
var currentMonth = parseInt(calendarContainer.getAttribute('month_shown'))
|
||||
var currentYear = parseInt(calendarContainer.getAttribute('year_shown'))
|
||||
|
||||
if (currentMonth == 12){
|
||||
currentMonth = 1
|
||||
currentYear = currentYear + 1
|
||||
@ -58,7 +57,6 @@ function createButtonForwards(calendarContainer, monthsBlock, monthsAhead, weekS
|
||||
|
||||
function createDateSelector(calendarContainer, monthsBlock, monthsAhead, weekStart){
|
||||
var dateSelector = createDateSelectionHTML()
|
||||
|
||||
var buttonGoToDate = dateSelector.querySelector('#button_load_selected_months')
|
||||
buttonGoToDate.addEventListener('click', function(){
|
||||
var currentYear = parseInt(dateSelector.querySelector('#year_selector').value)
|
||||
@ -71,7 +69,6 @@ function createDateSelector(calendarContainer, monthsBlock, monthsAhead, weekSta
|
||||
|
||||
|
||||
function renderCalendarFor(calendarContainer, monthsBlock, year, month, nMonths, weekStart){
|
||||
|
||||
monthsBlock.innerHTML = ''
|
||||
calendarContainer.setAttribute('month_shown', month.toString())
|
||||
calendarContainer.setAttribute('year_shown', year.toString())
|
||||
@ -81,12 +78,9 @@ function renderCalendarFor(calendarContainer, monthsBlock, year, month, nMonths,
|
||||
if (monthToCreate == 13){
|
||||
monthToCreate = 1;
|
||||
year = year + 1;
|
||||
// console.log(monthToCreate, month, year, nMonths)
|
||||
}
|
||||
|
||||
var monthContainer = document.createElement('div')
|
||||
monthContainer.className = 'month_container'
|
||||
|
||||
monthContainer.appendChild(renderMonth(year, monthToCreate, weekStart))
|
||||
monthsBlock.appendChild(monthContainer)
|
||||
}
|
||||
@ -100,16 +94,13 @@ function renderMonth(year, month, weekStart = 0, daysOfWeekNumeric){
|
||||
daysOfWeek.push(daysOfWeek.shift())
|
||||
daysOfWeekNumeric.push(daysOfWeekNumeric.shift())
|
||||
}
|
||||
|
||||
var table = document.createElement('table')
|
||||
var monthString = monthsStrings[month - 1]
|
||||
createHeaders(table, year, monthString, daysOfWeek)
|
||||
createDates(table, year, month, daysOfWeekNumeric)
|
||||
|
||||
return table
|
||||
}
|
||||
|
||||
|
||||
function createHeaders(table, year, month, daysOfWeek){
|
||||
let monthHeaderRow = document.createElement('tr')
|
||||
let monthHeader = document.createElement('th')
|
||||
@ -118,7 +109,6 @@ function createHeaders(table, year, month, daysOfWeek){
|
||||
monthHeader.colSpan = 7
|
||||
monthHeaderRow.appendChild(monthHeader)
|
||||
table.appendChild(monthHeaderRow)
|
||||
|
||||
let header = document.createElement('tr')
|
||||
for (var i = 0; i < daysOfWeek.length; i++){
|
||||
var headerDay = document.createElement('th')
|
||||
@ -133,7 +123,6 @@ function createHeaders(table, year, month, daysOfWeek){
|
||||
|
||||
function createDates(table, year, month, daysOfWeekNumeric){
|
||||
var weekEnd = daysOfWeekNumeric[daysOfWeekNumeric.length - 1]
|
||||
|
||||
var daysOfMonth = daysArray(year, month, daysOfWeekNumeric)
|
||||
var row = document.createElement('tr')
|
||||
for (var i = 0; i < daysOfMonth.length; i++){
|
||||
@ -143,11 +132,9 @@ function createDates(table, year, month, daysOfWeekNumeric){
|
||||
var dateString = new Date(date.getTime() - (date.getTimezoneOffset() * 60000 ))
|
||||
.toISOString()
|
||||
.split("T")[0];
|
||||
|
||||
var dateContainer = document.createElement('div')
|
||||
dateContainer.innerText = dayNr
|
||||
dateContainer.className = 'days_of_month'
|
||||
|
||||
if (month - 1 == date.getMonth()){
|
||||
dateContainer.classList.add('days_of_month_current')
|
||||
dateContainer.id = 'date_' + dateString
|
||||
@ -158,50 +145,36 @@ function createDates(table, year, month, daysOfWeekNumeric){
|
||||
} else {
|
||||
dateContainer.classList.add('days_of_month_not_current')
|
||||
}
|
||||
|
||||
|
||||
dateContainer.setAttribute('date', dateString)
|
||||
|
||||
cell.appendChild(dateContainer)
|
||||
|
||||
row.appendChild(cell)
|
||||
|
||||
|
||||
if (date.getDay() == weekEnd) {
|
||||
table.appendChild(row)
|
||||
var row = document.createElement('tr')
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
table.appendChild(row)
|
||||
}
|
||||
|
||||
function daysArray(year, month, daysOfWeekNumeric) {
|
||||
month = month - 1
|
||||
|
||||
var arr = []
|
||||
var daysInCurrentMonth = daysInMonth(year, month + 1)
|
||||
|
||||
var firstDayOfMonth = new Date(year, month, 1).getDay()
|
||||
var blankDaysStart = daysOfWeekNumeric.indexOf(firstDayOfMonth) * -1
|
||||
|
||||
for (var i = blankDaysStart + 1; i < 1; i++){
|
||||
var date = new Date(year, month, i)
|
||||
arr.push(date)
|
||||
}
|
||||
|
||||
for (var i = 1; i < daysInCurrentMonth + 1; i++){
|
||||
var date = new Date(year, month, i)
|
||||
arr.push(date)
|
||||
}
|
||||
|
||||
var daysToFill = arr.length
|
||||
for (var i = 1; i < 42 - daysToFill + 1; i++){
|
||||
var date = new Date(year, month + 1, i)
|
||||
arr.push(date)
|
||||
}
|
||||
|
||||
return arr
|
||||
}
|
||||
|
||||
@ -209,27 +182,21 @@ function daysInMonth (year, month) {
|
||||
return new Date(year, month, 0).getDate();
|
||||
}
|
||||
|
||||
|
||||
function createDateSelectionHTML(){
|
||||
|
||||
var container = document.createElement('div')
|
||||
container.id = 'date_selector'
|
||||
|
||||
var goButton = document.createElement('button')
|
||||
goButton.innerText = 'Go'
|
||||
goButton.id = 'button_load_selected_months'
|
||||
|
||||
var label = document.createElement('label')
|
||||
label.setAttribute('for', 'years')
|
||||
label.innerText = 'Go to: '
|
||||
|
||||
var selectYear = document.createElement('select')
|
||||
selectYear.name='years'
|
||||
selectYear.id = 'year_selector'
|
||||
|
||||
spanBegin = 1990
|
||||
spanEnd = 2030
|
||||
yearsSpan = spanEnd - spanBegin
|
||||
var spanBegin = 1990
|
||||
var spanEnd = 2030
|
||||
var yearsSpan = spanEnd - spanBegin
|
||||
for (var i = 0; i < yearsSpan; i++){
|
||||
var option = document.createElement('option')
|
||||
option.value = spanBegin + i
|
||||
@ -237,7 +204,6 @@ function createDateSelectionHTML(){
|
||||
selectYear.appendChild(option)
|
||||
}
|
||||
selectYear.value = today.getFullYear()
|
||||
|
||||
var selectMonth = document.createElement('select')
|
||||
selectMonth.name='months'
|
||||
selectMonth.id = 'month_selector'
|
||||
@ -249,7 +215,6 @@ function createDateSelectionHTML(){
|
||||
}
|
||||
|
||||
selectMonth.value = today.getMonth()
|
||||
|
||||
container.appendChild(label)
|
||||
container.appendChild(selectYear)
|
||||
container.appendChild(selectMonth)
|
||||
@ -265,3 +230,6 @@ function createButton(id, className, innerText){
|
||||
button.innerText = innerText
|
||||
return button
|
||||
}
|
||||
|
||||
|
||||
export { addCalendar }
|
@ -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 }
|
@ -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 }
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -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 }
|
@ -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 }
|
91
employee_module/static/js/calendar_extended.js
Normal file
91
employee_module/static/js/calendar_extended.js
Normal 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 }
|
@ -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)
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
const csrftoken = getCookie('csrftoken');
|
||||
import {csrftoken} from "../../../static/js/csrf_token.js";
|
||||
|
||||
window.addEventListener('load', function(){
|
||||
fetchSearchEmployeeData()
|
||||
|
@ -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)
|
||||
}
|
@ -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)
|
||||
}
|
@ -8,7 +8,6 @@
|
||||
|
||||
|
||||
{% block core_content %}
|
||||
<script src="{% static '/js/csrf_token.js' %}"></script>
|
||||
|
||||
<div id="sidebar">
|
||||
|
||||
@ -37,6 +36,14 @@
|
||||
</div>
|
||||
</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 id="hr_module_main_container">
|
||||
|
@ -10,6 +10,6 @@
|
||||
|
||||
</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 %}
|
||||
|
@ -7,13 +7,13 @@
|
||||
<link rel="stylesheet" href="{% static '/css/calendar_local.css' %}">
|
||||
<link rel="stylesheet" href="{% static '/css/employee_module_show_schedule.css' %}">
|
||||
|
||||
<div>
|
||||
<div id="username" username="{{ user }}"></div>
|
||||
<div hidden>
|
||||
<div id="username_input" username="{{ user }}"></div>
|
||||
<button type="button" id="load_schedule_button">Load Schedule</button>
|
||||
</div>
|
||||
<div id="calendar_box"></div>
|
||||
|
||||
<script src="{% static '/js/calendar.js' %}"></script>
|
||||
<script src="{% static '/js/employee_module_show_schedule.js' %}"></script>
|
||||
<script type="module" src="{% static '/js/calendar_ajax_employee_module_main.js' %}"></script>
|
||||
|
||||
|
||||
{% endblock %}
|
||||
|
@ -7,13 +7,12 @@
|
||||
<link rel="stylesheet" href="{% static '/css/calendar_local.css' %}">
|
||||
<link rel="stylesheet" href="{% static '/css/employee_module_show_schedule.css' %}">
|
||||
|
||||
<div>
|
||||
<div id="username" username="{{ user }}"></div>
|
||||
<div hidden>
|
||||
<div id="username_input" username="{{ user }}"></div>
|
||||
<button type="button" id="load_schedule_button">Load Schedule</button>
|
||||
</div>
|
||||
<div id="calendar_box"></div>
|
||||
|
||||
<script src="{% static '/js/calendar.js' %}"></script>
|
||||
<script src="{% static '/js/employee_module_show_timelog.js' %}"></script>
|
||||
|
||||
<script type="module" src="{% static '/js/calendar_ajax_employee_module_main.js' %}"></script>
|
||||
|
||||
{% endblock %}
|
||||
|
@ -6,9 +6,6 @@ from django.contrib.auth import views as auth_views
|
||||
app_name = 'employee_module'
|
||||
|
||||
urlpatterns = [
|
||||
path('login', auth_views.LoginView.as_view(template_name='hr_module_login.html'), name='login'),
|
||||
path('logout', auth_views.LogoutView.as_view(), name='logout'),
|
||||
path('change_password', auth_views.PasswordChangeView.as_view(template_name='hr_module_password_change.html'), name='change_password'),
|
||||
path('home', views.homepage, name='homepage'),
|
||||
path('time_tracking', views.time_tracking, name='time_tracking'),
|
||||
path('show_schedule', views.show_schedule, name='show_schedule'),
|
||||
|
@ -5,11 +5,11 @@ from hr_module.models import Employee, Plan, TimeLog
|
||||
from django.contrib.auth.models import User
|
||||
from django.http import HttpResponse, JsonResponse, Http404
|
||||
import datetime
|
||||
from django.urls import reverse
|
||||
from django.urls import reverse, reverse_lazy
|
||||
from django.http import HttpResponse, HttpResponseRedirect
|
||||
|
||||
|
||||
login_url = '/hr_module/login'
|
||||
login_url = reverse_lazy('login')
|
||||
# Create your views here.
|
||||
@login_required(login_url=login_url)
|
||||
def homepage(request):
|
||||
|
Binary file not shown.
BIN
hr_module/__pycache__/sql_queries.cpython-38.pyc
Normal file
BIN
hr_module/__pycache__/sql_queries.cpython-38.pyc
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1,5 +1,10 @@
|
||||
|
||||
from django.conf import settings
|
||||
from django.contrib.auth.models import User
|
||||
|
||||
def report_download_path(request):
|
||||
return {'IMPORT_REPORT_STORAGE': settings.IMPORT_REPORT_STORAGE}
|
||||
def manager_flag(request):
|
||||
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}
|
Binary file not shown.
47
hr_module/sql_queries.py
Normal file
47
hr_module/sql_queries.py
Normal 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 = '{}'"}
|
@ -5,7 +5,7 @@ input[readonly] {
|
||||
}
|
||||
|
||||
table#detailed_plan_records {
|
||||
margin-top: 15px;
|
||||
margin-top: 10px;
|
||||
width: 100%;
|
||||
font-size: 15px;
|
||||
vertical-align:middle;
|
||||
@ -43,3 +43,20 @@ div#detailed_plan_records input {
|
||||
.begin_time, .end_time {
|
||||
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;
|
||||
}
|
@ -5,6 +5,7 @@ input[readonly] {
|
||||
}
|
||||
|
||||
table#detailed_plan_records {
|
||||
margin-top: 10px;
|
||||
width: 100%;
|
||||
font-size: 15px;
|
||||
vertical-align:middle;
|
||||
@ -42,3 +43,21 @@ div#detailed_plan_records input {
|
||||
.begin_time, .end_time {
|
||||
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;
|
||||
}
|
@ -2,22 +2,23 @@
|
||||
const monthsStrings = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']
|
||||
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')
|
||||
calendarContainer.id = 'calendar_container'
|
||||
|
||||
|
||||
var monthsBlock = document.createElement('div')
|
||||
monthsBlock.id = 'months_block'
|
||||
|
||||
renderCalendarFor(calendarContainer, monthsBlock, currentYear, currentMonth, monthsAhead, weekStart)
|
||||
|
||||
calendarContainer.appendChild(createButtonBack(calendarContainer, monthsBlock, monthsAhead, weekStart))
|
||||
calendarContainer.appendChild(monthsBlock)
|
||||
calendarContainer.appendChild(createButtonForwards(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
|
||||
}
|
||||
|
||||
@ -26,7 +27,6 @@ function createButtonBack(calendarContainer, monthsBlock, monthsAhead, weekStart
|
||||
buttonBack.addEventListener('click', function(){
|
||||
var currentMonth = parseInt(calendarContainer.getAttribute('month_shown'))
|
||||
var currentYear = parseInt(calendarContainer.getAttribute('year_shown'))
|
||||
|
||||
if (currentMonth == 1){
|
||||
currentMonth = 12
|
||||
currentYear = currentYear - 1
|
||||
@ -43,7 +43,6 @@ function createButtonForwards(calendarContainer, monthsBlock, monthsAhead, weekS
|
||||
buttonForwards.addEventListener('click', function(){
|
||||
var currentMonth = parseInt(calendarContainer.getAttribute('month_shown'))
|
||||
var currentYear = parseInt(calendarContainer.getAttribute('year_shown'))
|
||||
|
||||
if (currentMonth == 12){
|
||||
currentMonth = 1
|
||||
currentYear = currentYear + 1
|
||||
@ -58,7 +57,6 @@ function createButtonForwards(calendarContainer, monthsBlock, monthsAhead, weekS
|
||||
|
||||
function createDateSelector(calendarContainer, monthsBlock, monthsAhead, weekStart){
|
||||
var dateSelector = createDateSelectionHTML()
|
||||
|
||||
var buttonGoToDate = dateSelector.querySelector('#button_load_selected_months')
|
||||
buttonGoToDate.addEventListener('click', function(){
|
||||
var currentYear = parseInt(dateSelector.querySelector('#year_selector').value)
|
||||
@ -71,7 +69,6 @@ function createDateSelector(calendarContainer, monthsBlock, monthsAhead, weekSta
|
||||
|
||||
|
||||
function renderCalendarFor(calendarContainer, monthsBlock, year, month, nMonths, weekStart){
|
||||
|
||||
monthsBlock.innerHTML = ''
|
||||
calendarContainer.setAttribute('month_shown', month.toString())
|
||||
calendarContainer.setAttribute('year_shown', year.toString())
|
||||
@ -81,12 +78,9 @@ function renderCalendarFor(calendarContainer, monthsBlock, year, month, nMonths,
|
||||
if (monthToCreate == 13){
|
||||
monthToCreate = 1;
|
||||
year = year + 1;
|
||||
// console.log(monthToCreate, month, year, nMonths)
|
||||
}
|
||||
|
||||
var monthContainer = document.createElement('div')
|
||||
monthContainer.className = 'month_container'
|
||||
|
||||
monthContainer.appendChild(renderMonth(year, monthToCreate, weekStart))
|
||||
monthsBlock.appendChild(monthContainer)
|
||||
}
|
||||
@ -100,16 +94,13 @@ function renderMonth(year, month, weekStart = 0, daysOfWeekNumeric){
|
||||
daysOfWeek.push(daysOfWeek.shift())
|
||||
daysOfWeekNumeric.push(daysOfWeekNumeric.shift())
|
||||
}
|
||||
|
||||
var table = document.createElement('table')
|
||||
var monthString = monthsStrings[month - 1]
|
||||
createHeaders(table, year, monthString, daysOfWeek)
|
||||
createDates(table, year, month, daysOfWeekNumeric)
|
||||
|
||||
return table
|
||||
}
|
||||
|
||||
|
||||
function createHeaders(table, year, month, daysOfWeek){
|
||||
let monthHeaderRow = document.createElement('tr')
|
||||
let monthHeader = document.createElement('th')
|
||||
@ -118,7 +109,6 @@ function createHeaders(table, year, month, daysOfWeek){
|
||||
monthHeader.colSpan = 7
|
||||
monthHeaderRow.appendChild(monthHeader)
|
||||
table.appendChild(monthHeaderRow)
|
||||
|
||||
let header = document.createElement('tr')
|
||||
for (var i = 0; i < daysOfWeek.length; i++){
|
||||
var headerDay = document.createElement('th')
|
||||
@ -133,7 +123,6 @@ function createHeaders(table, year, month, daysOfWeek){
|
||||
|
||||
function createDates(table, year, month, daysOfWeekNumeric){
|
||||
var weekEnd = daysOfWeekNumeric[daysOfWeekNumeric.length - 1]
|
||||
|
||||
var daysOfMonth = daysArray(year, month, daysOfWeekNumeric)
|
||||
var row = document.createElement('tr')
|
||||
for (var i = 0; i < daysOfMonth.length; i++){
|
||||
@ -143,11 +132,9 @@ function createDates(table, year, month, daysOfWeekNumeric){
|
||||
var dateString = new Date(date.getTime() - (date.getTimezoneOffset() * 60000 ))
|
||||
.toISOString()
|
||||
.split("T")[0];
|
||||
|
||||
var dateContainer = document.createElement('div')
|
||||
dateContainer.innerText = dayNr
|
||||
dateContainer.className = 'days_of_month'
|
||||
|
||||
if (month - 1 == date.getMonth()){
|
||||
dateContainer.classList.add('days_of_month_current')
|
||||
dateContainer.id = 'date_' + dateString
|
||||
@ -158,50 +145,36 @@ function createDates(table, year, month, daysOfWeekNumeric){
|
||||
} else {
|
||||
dateContainer.classList.add('days_of_month_not_current')
|
||||
}
|
||||
|
||||
|
||||
dateContainer.setAttribute('date', dateString)
|
||||
|
||||
cell.appendChild(dateContainer)
|
||||
|
||||
row.appendChild(cell)
|
||||
|
||||
|
||||
if (date.getDay() == weekEnd) {
|
||||
table.appendChild(row)
|
||||
var row = document.createElement('tr')
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
table.appendChild(row)
|
||||
}
|
||||
|
||||
function daysArray(year, month, daysOfWeekNumeric) {
|
||||
month = month - 1
|
||||
|
||||
var arr = []
|
||||
var daysInCurrentMonth = daysInMonth(year, month + 1)
|
||||
|
||||
var firstDayOfMonth = new Date(year, month, 1).getDay()
|
||||
var blankDaysStart = daysOfWeekNumeric.indexOf(firstDayOfMonth) * -1
|
||||
|
||||
for (var i = blankDaysStart + 1; i < 1; i++){
|
||||
var date = new Date(year, month, i)
|
||||
arr.push(date)
|
||||
}
|
||||
|
||||
for (var i = 1; i < daysInCurrentMonth + 1; i++){
|
||||
var date = new Date(year, month, i)
|
||||
arr.push(date)
|
||||
}
|
||||
|
||||
var daysToFill = arr.length
|
||||
for (var i = 1; i < 42 - daysToFill + 1; i++){
|
||||
var date = new Date(year, month + 1, i)
|
||||
arr.push(date)
|
||||
}
|
||||
|
||||
return arr
|
||||
}
|
||||
|
||||
@ -209,27 +182,21 @@ function daysInMonth (year, month) {
|
||||
return new Date(year, month, 0).getDate();
|
||||
}
|
||||
|
||||
|
||||
function createDateSelectionHTML(){
|
||||
|
||||
var container = document.createElement('div')
|
||||
container.id = 'date_selector'
|
||||
|
||||
var goButton = document.createElement('button')
|
||||
goButton.innerText = 'Go'
|
||||
goButton.id = 'button_load_selected_months'
|
||||
|
||||
var label = document.createElement('label')
|
||||
label.setAttribute('for', 'years')
|
||||
label.innerText = 'Go to: '
|
||||
|
||||
var selectYear = document.createElement('select')
|
||||
selectYear.name='years'
|
||||
selectYear.id = 'year_selector'
|
||||
|
||||
spanBegin = 1990
|
||||
spanEnd = 2030
|
||||
yearsSpan = spanEnd - spanBegin
|
||||
var spanBegin = 1990
|
||||
var spanEnd = 2030
|
||||
var yearsSpan = spanEnd - spanBegin
|
||||
for (var i = 0; i < yearsSpan; i++){
|
||||
var option = document.createElement('option')
|
||||
option.value = spanBegin + i
|
||||
@ -237,7 +204,6 @@ function createDateSelectionHTML(){
|
||||
selectYear.appendChild(option)
|
||||
}
|
||||
selectYear.value = today.getFullYear()
|
||||
|
||||
var selectMonth = document.createElement('select')
|
||||
selectMonth.name='months'
|
||||
selectMonth.id = 'month_selector'
|
||||
@ -249,7 +215,6 @@ function createDateSelectionHTML(){
|
||||
}
|
||||
|
||||
selectMonth.value = today.getMonth()
|
||||
|
||||
container.appendChild(label)
|
||||
container.appendChild(selectYear)
|
||||
container.appendChild(selectMonth)
|
||||
@ -265,3 +230,6 @@ function createButton(id, className, innerText){
|
||||
button.innerText = innerText
|
||||
return button
|
||||
}
|
||||
|
||||
|
||||
export { addCalendar }
|
14
hr_module/static/js/calendar_ajax_hr_module_config.js
Normal file
14
hr_module/static/js/calendar_ajax_hr_module_config.js
Normal 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 }
|
31
hr_module/static/js/calendar_ajax_hr_module_main.js
Normal file
31
hr_module/static/js/calendar_ajax_hr_module_main.js
Normal 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 }
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
68
hr_module/static/js/calendar_ajax_hr_module_requests.js
Normal file
68
hr_module/static/js/calendar_ajax_hr_module_requests.js
Normal 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 }
|
91
hr_module/static/js/calendar_extended.js
Normal file
91
hr_module/static/js/calendar_extended.js
Normal 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 }
|
179
hr_module/static/js/calendar_to_table.js
Normal file
179
hr_module/static/js/calendar_to_table.js
Normal 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 }
|
@ -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;
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
const csrftoken = getCookie('csrftoken');
|
||||
import {csrftoken} from "../../../static/js/csrf_token.js";
|
||||
|
||||
var searchEmployeeButton = document.getElementById('load_employee_data_button')
|
||||
searchEmployeeButton.addEventListener('click', function(){
|
||||
|
@ -1,5 +1,5 @@
|
||||
const csrftoken = getCookie('csrftoken');
|
||||
|
||||
import { csrftoken } from '../../../static/js/csrf_token.js'
|
||||
|
||||
window.addEventListener('load', function (){
|
||||
fetchSearchOptions()
|
||||
@ -48,10 +48,10 @@ function appendFoundFilterOptions(data){
|
||||
var caption = data[i]['caption'];
|
||||
var value = data[i]['column_value'];
|
||||
|
||||
innerHTML = '<option value="' + value + '">' + caption + '</option>'
|
||||
var innerhtml = '<option value="' + value + '">' + caption + '</option>'
|
||||
|
||||
var wrapper = document.createElement('div');
|
||||
wrapper.innerHTML = innerHTML;
|
||||
wrapper.innerHTML = innerhtml;
|
||||
var htmlNode = wrapper.firstChild;
|
||||
|
||||
parent.appendChild(htmlNode);
|
||||
@ -204,7 +204,7 @@ function buildPlanJson(){
|
||||
var upperBoundary = document.getElementById('planning_upper_boundary').value
|
||||
for (var i = 0; i < employees.length; i++) {
|
||||
var planJson = {}
|
||||
row = employees[0]
|
||||
var row = employees[0]
|
||||
var username = row.getAttribute('data-username')
|
||||
var startTime = row.getElementsByClassName('schedule_time_input')[0].value
|
||||
var activityType = row.getElementsByClassName('activity_type')[0].value
|
||||
@ -212,7 +212,7 @@ function buildPlanJson(){
|
||||
var days = row.getElementsByClassName('working_days')
|
||||
var daysOfWeek = {}
|
||||
for (var k = 0; k < days.length; k++){
|
||||
day = days[k]
|
||||
var day = days[k]
|
||||
daysOfWeek[day.value] = day.checked
|
||||
}
|
||||
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';
|
||||
}
|
||||
}
|
59
hr_module/static/js/hr_module_export.js
Normal file
59
hr_module/static/js/hr_module_export.js
Normal 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);
|
||||
}
|
||||
}
|
@ -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)
|
||||
}
|
@ -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)
|
||||
}
|
@ -8,7 +8,6 @@
|
||||
|
||||
|
||||
{% block core_content %}
|
||||
<script src="{% static '/js/csrf_token.js' %}"></script>
|
||||
|
||||
<div id="sidebar">
|
||||
|
||||
@ -51,7 +50,7 @@
|
||||
</a>
|
||||
|
||||
|
||||
<a href="{% url 'hr_module:create_schedule' %}">
|
||||
<a href="{% url 'hr_module:export' %}">
|
||||
<div class="sidebar_item" >Export data
|
||||
</div>
|
||||
</a>
|
||||
|
@ -15,6 +15,6 @@
|
||||
|
||||
</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 %}
|
||||
|
@ -56,6 +56,6 @@
|
||||
|
||||
</div>
|
||||
|
||||
<script src="{% static '/js/hr_module_create_schedule.js' %}"></script>
|
||||
<script type="module" src="{% static '/js/hr_module_create_schedule.js' %}"></script>
|
||||
|
||||
{% endblock %}
|
||||
|
48
hr_module/templates/hr_module_export.html
Normal file
48
hr_module/templates/hr_module_export.html
Normal 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 %}
|
@ -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 %}
|
@ -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 %}
|
@ -14,8 +14,7 @@
|
||||
</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 %}
|
||||
|
@ -14,8 +14,6 @@
|
||||
</div>
|
||||
<div id="calendar_box"></div>
|
||||
|
||||
<script src="{% static '/js/calendar.js' %}"></script>
|
||||
<script src="{% static '/js/hr_module_show_timelog.js' %}"></script>
|
||||
|
||||
<script type="module" src="{% static '/js/../../static/js/calendar_ajax_hr_module_main.js' %}"></script>
|
||||
|
||||
{% endblock %}
|
||||
|
@ -6,22 +6,21 @@ from django.contrib.auth import views as auth_views
|
||||
app_name = 'hr_module'
|
||||
|
||||
urlpatterns = [
|
||||
path('login', auth_views.LoginView.as_view(template_name='hr_module_login.html'), name='login'),
|
||||
path('logout', auth_views.LogoutView.as_view(), name='logout'),
|
||||
path('change_password', auth_views.PasswordChangeView.as_view(template_name='hr_module_password_change.html'), name='change_password'),
|
||||
path('home', views.homepage, name='homepage'),
|
||||
path('create_schedule', views.create_schedule, name='create_schedule'),
|
||||
path('create_employees', views.create_employees, name='create_employees'),
|
||||
path('search_api', views.search_users_api, name='search_users_api'),
|
||||
path('loademployees', views.load_employees_api, name='load_employees'),
|
||||
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('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('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_api', views.change_employee_data_api, name='change_employee_data_api'),
|
||||
path('plan_creation_log', views.plan_creation_log, name='plan_creation_log'),
|
||||
path('export', views.export, name='export'),
|
||||
|
||||
]
|
@ -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.insert_to_plan import UpdatePlan
|
||||
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 json
|
||||
from .models import Employee, PlanCreationLog, Plan, TimeLog
|
||||
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
|
||||
import datetime
|
||||
from django.urls import reverse
|
||||
from django.urls import reverse, reverse_lazy
|
||||
from django.conf import settings
|
||||
import csv
|
||||
|
||||
|
||||
login_url = '/hr_module/login'
|
||||
login_url = reverse_lazy('login')
|
||||
# Create your views here.
|
||||
@login_required(login_url=login_url)
|
||||
def create_schedule(request):
|
||||
@ -84,7 +86,6 @@ def change_employee_data_api(request):
|
||||
response_dict = dict(record_user, **record_employee)
|
||||
for i in ['_state', 'password']:
|
||||
response_dict.pop(i)
|
||||
print(response_dict)
|
||||
return JsonResponse(response_dict, safe=False)
|
||||
else:
|
||||
return JsonResponse({'error': 'not_authenticated'})
|
||||
@ -98,7 +99,6 @@ def create_employees(request):
|
||||
if request.method == 'POST':
|
||||
if 'import_preview' in request.POST:
|
||||
fileform = UploadFileForm(request.POST, request.FILES)
|
||||
print(fileform.is_valid())
|
||||
if fileform.is_valid():
|
||||
uploaded_file = request.FILES['file']
|
||||
df_dict = read_and_parse_excel(uploaded_file)
|
||||
@ -123,7 +123,6 @@ def create_employees(request):
|
||||
df_dict.pop(i, None)
|
||||
df = pd.DataFrame(df_dict, index=[0])
|
||||
insert_excel(df)
|
||||
print('done')
|
||||
template = 'hr_module_import_success.html'
|
||||
return render(request, template)
|
||||
|
||||
@ -156,7 +155,6 @@ def search_users_api(request):
|
||||
body = json.loads(request.body)
|
||||
searched_field = body['searched_field']
|
||||
searched_string = body['searched_string']
|
||||
print(searched_field, searched_string)
|
||||
cursor = connection.cursor()
|
||||
|
||||
|
||||
@ -175,7 +173,6 @@ def search_users_api(request):
|
||||
)
|
||||
|
||||
response = dictfetchall(cursor)
|
||||
print(response)
|
||||
return JsonResponse(response, safe=False)
|
||||
|
||||
|
||||
@ -184,12 +181,10 @@ def load_employees_api(request):
|
||||
body = json.loads(request.body)
|
||||
searched_field = body['searched_field']
|
||||
searched_string = body['searched_string']
|
||||
print(searched_field, searched_string)
|
||||
cursor = connection.cursor()
|
||||
|
||||
|
||||
if searched_field == 'department':
|
||||
print('Deparment executed')
|
||||
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, '
|
||||
'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])
|
||||
|
||||
elif searched_field == 'manager':
|
||||
print('Manager executed')
|
||||
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, '
|
||||
'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])
|
||||
|
||||
elif searched_field == 'username':
|
||||
print('Username executed')
|
||||
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, '
|
||||
'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])
|
||||
|
||||
response = dictfetchall(cursor)
|
||||
print(response)
|
||||
return JsonResponse(response, safe=False)
|
||||
|
||||
|
||||
@ -266,7 +258,6 @@ def show_employee_plan_api(request):
|
||||
def update_plan_api(request):
|
||||
if request.method == 'POST':
|
||||
body = json.loads(request.body)
|
||||
print(body)
|
||||
if body['action'] == 'delete':
|
||||
for i in body['records']:
|
||||
record_id = i['id']
|
||||
@ -315,7 +306,6 @@ def show_employee_timelog_api(request):
|
||||
def update_timelog_api(request):
|
||||
if request.method == 'POST':
|
||||
body = json.loads(request.body)
|
||||
print(body)
|
||||
if body['action'] == 'delete':
|
||||
for i in body['records']:
|
||||
record_id = i['id']
|
||||
@ -339,6 +329,9 @@ def update_timelog_api(request):
|
||||
def plan_creation_log(request):
|
||||
session_user = User.objects.select_related('employee').get(username=request.user.username)
|
||||
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:
|
||||
creation_log = PlanCreationLog.objects.all().order_by('-creation_date')
|
||||
elif session_user_manager_flag:
|
||||
@ -349,3 +342,49 @@ def plan_creation_log(request):
|
||||
|
||||
template_name = 'hr_module_creation_log.html'
|
||||
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_)
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -6,8 +6,11 @@ html, body {
|
||||
}
|
||||
.navbar {
|
||||
height: 50px;
|
||||
background-color: #D3D3D3;
|
||||
background-color: #202831;
|
||||
width: 100%;
|
||||
border-bottom: #7F8B94 thin solid;
|
||||
color: #7F8B94;
|
||||
|
||||
}
|
||||
.main_container {
|
||||
background-color: whitesmoke;
|
||||
@ -25,6 +28,7 @@ html, body {
|
||||
text-align:center;
|
||||
margin-top: 15px;
|
||||
margin-right: 15px;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
#calendar_box, #list_container {
|
||||
|
@ -15,3 +15,7 @@ function getCookie(name) {
|
||||
}
|
||||
return cookieValue;
|
||||
}
|
||||
|
||||
const csrftoken = getCookie('csrftoken');
|
||||
|
||||
export { csrftoken }
|
@ -15,7 +15,7 @@
|
||||
|
||||
{% if user.is_authenticated %}
|
||||
<div class="navbar_item">
|
||||
<a href="{% url 'hr_module:logout' %}">Log out</a>
|
||||
<a href="{% url 'logout' %}">Log out</a>
|
||||
</div>
|
||||
<div class="navbar_item">You are logged in as: {{ user }} </div>
|
||||
|
||||
|
Binary file not shown.
Binary file not shown.
@ -12,6 +12,7 @@ https://docs.djangoproject.com/en/3.1/ref/settings/
|
||||
|
||||
from pathlib import Path
|
||||
import os
|
||||
from django.urls import reverse_lazy
|
||||
|
||||
# Build paths inside the project like this: BASE_DIR / 'subdir'.
|
||||
BASE_DIR = Path(__file__).resolve().parent.parent
|
||||
@ -66,7 +67,7 @@ TEMPLATES = [
|
||||
'APP_DIRS': True,
|
||||
'OPTIONS': {
|
||||
'context_processors': [
|
||||
'hr_module.context_processors.report_download_path',
|
||||
'hr_module.context_processors.manager_flag',
|
||||
'django.template.context_processors.media',
|
||||
'django.template.context_processors.debug',
|
||||
'django.template.context_processors.request',
|
||||
@ -138,11 +139,11 @@ STATICFILES_DIRS = [
|
||||
|
||||
|
||||
|
||||
LOGOUT_REDIRECT_URL = '/hr_module/login'
|
||||
LOGIN_REDIRECT_URL = '/hr_module/home'
|
||||
LOGOUT_REDIRECT_URL = reverse_lazy('login')
|
||||
LOGIN_REDIRECT_URL = reverse_lazy('hr_module:homepage')
|
||||
|
||||
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
|
||||
MEDIA_URL = '/media/'
|
||||
|
||||
TMP_FILE_STORAGE = os.path.join(MEDIA_URL, 'temp/')
|
||||
IMPORT_REPORT_STORAGE = os.path.join(BASE_DIR, 'import_reports')
|
||||
TMP_FILE_STORAGE = os.path.join(MEDIA_ROOT, 'temp/')
|
||||
IMPORT_REPORT_STORAGE = os.path.join(MEDIA_ROOT, 'import_reports/')
|
||||
|
@ -17,11 +17,17 @@ from django.contrib import admin
|
||||
from django.urls import path, include
|
||||
from django.conf import settings
|
||||
from django.conf.urls.static import static
|
||||
from django.contrib.auth import views as auth_views
|
||||
|
||||
urlpatterns = [
|
||||
path('admin/', admin.site.urls),
|
||||
path('hr_module/', include('hr_module.urls')),
|
||||
path('employee_module/', include('employee_module.urls')),
|
||||
|
||||
path('login', auth_views.LoginView.as_view(template_name='login.html'), name='login'),
|
||||
path('logout', auth_views.LogoutView.as_view(), name='logout'),
|
||||
path('change_password', auth_views.PasswordChangeView.as_view(template_name='change_password.html'),
|
||||
name='change_password'),
|
||||
]
|
||||
|
||||
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
|
||||
|
Loading…
Reference in New Issue
Block a user