started adding employee functionality

This commit is contained in:
muahahahh 2021-01-05 00:33:09 +01:00
parent 1aee89b425
commit 842b57520a
55 changed files with 1332 additions and 27 deletions

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.

View File

@ -0,0 +1,62 @@
import pandas as pd
from django.conf import settings
import datetime
from sqlalchemy import create_engine
from django.contrib.auth.hashers import make_password
def create_connection(db_file, type=1):
""" create a database connection to the SQLite database
specified by the db_file
:param db_file: database file
:return: Connection object or None
"""
conn = None
try:
path = 'sqlite:///' + str(db_file)
if type == 1:
return create_engine(path)
else:
return create_engine(path).connect()
except Exception as e:
print(e)
return None
def read_and_parse_excel(file):
df = pd.read_excel(file)
path_temp = settings.TMP_FILE_STORAGE + file.name.split('.')[0] + '.csv'
df.to_csv(path_temp)
html = df.to_html(index=False, na_rep='')
return {'df_html': html, 'df_path': path_temp}
def insert_excel(df):
conn = create_connection(settings.DATABASES['default']['NAME'])
df['date_joined'] = datetime.date.today()
df['password'] = make_password('start')
df_to_user_model = df[['username',
'first_name',
'last_name',
'email',
'is_staff',
'is_active',
'date_joined',
'is_superuser',
'password']]
df_to_user_model.to_sql(name='auth_user',
con=conn,
if_exists='append', index=False)
df_to_employee = df[['username',
'department',
'manager_username',
'time_model_id',
'manager_flag']]
df_to_employee.to_sql(name='hr_module_employee',
con=conn,
if_exists='append', index=False)

View File

@ -0,0 +1,8 @@
def dictfetchall(cursor):
"Return all rows from a cursor as a dict"
columns = [col[0] for col in cursor.description]
return [
dict(zip(columns, row))
for row in cursor.fetchall()
]

View File

@ -0,0 +1,85 @@
from django.conf import settings
import pandas as pd
from ..models import Employee, Plan
import datetime
def time_timedelta(time, timedelta):
start = datetime.datetime(2020, 1, 1, time.hour, time.minute)
end = start + timedelta
return end.time()
def insert_into_plan(user, start_date, end_date, start_time, daily_hours, activity_type, timemodel):
start_date = datetime.datetime.strptime(start_date, '%Y-%m-%d')
end_date = datetime.datetime.strptime(end_date, '%Y-%m-%d')
start_time = datetime.datetime.strptime(start_time, '%H:%M').time()
username = Employee.objects.get(username=user)
daily_hours = int(daily_hours * 60)
end_time = time_timedelta(start_time, datetime.timedelta(minutes=daily_hours))
timemodel_pattern = {0: timemodel['mon'],
1: timemodel['tue'],
2: timemodel['wed'],
3: timemodel['thu'],
4: timemodel['fri'],
5: timemodel['sat'],
6: timemodel['sun']}
days = (end_date - start_date).days
log = []
for day in range(days + 1):
date_to_add = start_date + datetime.timedelta(days=day)
overlap = check_conflicting_records(username, date_to_add, start_time, end_time)
print(overlap)
if timemodel_pattern[date_to_add.weekday()] and not overlap:
print(date_to_add, start_time, end_time, overlap)
plan = Plan(username=username,
date=date_to_add,
begin_time=start_time,
end_time=end_time,
activity_type=activity_type)
plan.save()
log.append({'username': username.pk,
'date': date_to_add,
'begin_time': start_time,
'end_time': end_time,
'activity_type': activity_type,
'status': 'imported'})
else:
log.append({'username': username.pk,
'date': date_to_add,
'begin_time': start_time,
'end_time': end_time,
'activity_type': activity_type,
'status': 'failed due to conflicting overlap'})
return log
def check_conflicting_records(username, date, start_time, end_time):
plan = Plan.objects.filter(username=username, date=date)
if len(plan) > 0:
for day in plan:
planned_time_start = day.begin_time
planned_time_end = day.end_time
if planned_time_start <= end_time and planned_time_end >= start_time:
return True
else:
return False
else:
return False
def create_planning_operation_report(dict_, current_user):
df = pd.DataFrame(dict_)
filename = current_user + '_' + datetime.datetime.now().isoformat() + '.xlsx'
path_temp = settings.IMPORT_REPORT_STORAGE + filename
df.to_excel(path_temp, index=False)
return filename

View File

@ -0,0 +1,108 @@
div.month_container table,
div.month_container th,
div.month_container td {
text-align: center;
border-collapse: collapse;
border-width: thin;
font-weight: lighter;
}
th {
background-color: darkred;
color: white;
border: solid 1px white;
border-width: thin;
}
#calendar_container {
height: 257px;
}
#months_block {
float: left;
}
.month_container {
float: left;
margin: 10px;
}
.calendar_button:hover {
background-color: white;
cursor: pointer;
}
.calendar_button {
float: left;
margin-top: 10px;
margin-bottom: 10px;
height: 271px;
width: 30px;
background-color: lightgray;
display: flex;
align-items: center;
justify-content: center;
}
#date_selector {
clear: both;
display: flex;
align-items: center;
justify-content: center;
}
#year_selector, #month_selector {
margin-right: 5px;
margin-left: 5px;
height: 25px;
}
#button_load_selected_months{
height: 25px;
margin-left: 5px;
width: 50px;
}
.days_of_month {
font-size: 15px;
width: 32px;
height: 32px;
margin: auto;
vertical-align:middle;
display: table-cell;
}
.days_of_month_current {
background-color: #ab9898;
color: white;
}
.days_of_month_not_current {
background-color: #dbd7d7;
color: white;
}
.days_of_month_today{
background-color: darkred;
}
.month_header {
font-size: 15px;
height: 28px;
margin: auto;
vertical-align:middle;
display: table-cell;
}
.weekday_header {
font-size: 15px;
height: 32px;
text-transform: capitalize;
display: flex;
justify-content: center;
align-items: center;
}

View File

@ -0,0 +1,5 @@
.days_of_month_work {
background-color: darkslateblue;
}

View File

@ -0,0 +1,23 @@
.import_table {
float:left;
overflow: auto;
}
table, th, td {
border: 1px solid lightgray;
padding: 5px;
width: auto;
text-align: center;
border-collapse: collapse;
border-width: thin;
}
table tr:nth-child(even){
background-color: #f2f2f2;
}
tr:hover {
}

View File

@ -0,0 +1,30 @@
#hr_module_main_container {
padding: 1%;
float: left;
width: 80%;
height: 100%;
background-color: whitesmoke;
}
.sidebar {
background-color: #8b0000;
width: 18%;
height: 100%;
float: left;
}
.sidebar_item {
background-color: navajowhite;
margin-right: 6px;
margin-left: 6px;
margin-top: 6px;
padding: 10px;
font-size: 20px;
}
.sidebar_item:hover {
background-color: white;
cursor: pointer;
}

View File

@ -0,0 +1,25 @@
#search_results {
margin-top: 20px;
}
div#search_results label {
text-transform: capitalize;
clear: both;
width: 200px;
margin-right: 10px;
}
.field_container {
width: 400px;
margin-top: 10px;
display: flex;
height: 30px;
border: thin;
border-bottom: 1px solid lightgray;
}
.database_field {
text-align: center;
}

View File

@ -0,0 +1,38 @@
.scheduleSearchRow {
height: 35px;
}
.search_element {
float: left;
width: 20%;
}
#schedule_filter_category {
margin-right: 10px;
}
.day_of_week_checkbox {
float: left;
height: 36px;
padding: 4px;
}
input, label{
display: block;
}
table, th, td {
border: 1px solid lightgray;
padding: 5px;
width: auto;
text-align: center;
border-collapse: collapse;
border-width: thin;
}
.date_select_row {
margin-top: 10px;
margin-bottom: 10px;
}

View File

@ -0,0 +1,94 @@
label {
width: 40%;
display:inline-block;
}
table {
margin-top: 10px;
}
table, th, td {
border: 1px solid lightgray;
padding: 5px;
width: auto;
text-align: center;
border-collapse: collapse;
border-width: thin;
}
.import_container {
float: left;
width: 40%;
height: 70%;
}
.form_element, .import_text {
height: 30px;
}
.separator {
position: relative;
float: left;
width: 10%;
height: 70%;
}
.separatorline {
position: absolute;
left: 49%;
top: 0;
bottom: 0;
width: 1px;
background: black;
z-index: 1;
}
.wordwrapper {
text-align: center;
height: 12px;
position: absolute;
left: 0;
right: 0;
top: 50%;
margin-top: -12px;
z-index: 2;
}
.word {
color: #cccccc;
text-transform: uppercase;
letter-spacing: 1px;
padding: 3px;
font: bold 12px;
background-color: whitesmoke;
}
.import_execute {
padding: 5px;
width: 30%;
text-align: center;
margin: 10px;
}
#import_filepicker {
padding: 5px;
width: 90%;
text-align: center;
margin: 10px;
}

View File

@ -0,0 +1,44 @@
input[readonly] {
color: black;
background-color: lightgray;
}
table#detailed_plan_records {
width: 100%;
font-size: 15px;
vertical-align:middle;
font-weight: lighter;
}
table#detailed_plan_records th {
height: 25px;
font-weight: lighter;
padding: 0px;
}
table#detailed_plan_records td {
text-align: center;
padding: 0px;
}
tr:nth-child(even) {
background-color: #6DDCBD;
}
div#detailed_plan_records input {
width: 97%;
display: block;
border: solid thin black;
}
.detailed_plan_records {
text-align: center;
border-collapse: collapse;
border-width: thin;
font-weight: lighter;
}
.begin_time, .end_time {
display: block;
}

View File

@ -0,0 +1,267 @@
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){
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))
return calendarContainer
}
function createButtonBack(calendarContainer, monthsBlock, monthsAhead, weekStart){
var buttonBack = createButton('calendar_button_back', 'calendar_button', '<')
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
} else {
currentMonth = currentMonth - 1
}
renderCalendarFor(calendarContainer, monthsBlock, currentYear, currentMonth, monthsAhead, weekStart)
})
return buttonBack
}
function createButtonForwards(calendarContainer, monthsBlock, monthsAhead, weekStart){
var buttonForwards = createButton('calendar_button_forwards', 'calendar_button', '>')
buttonForwards.addEventListener('click', function(){
var currentMonth = parseInt(calendarContainer.getAttribute('month_shown'))
var currentYear = parseInt(calendarContainer.getAttribute('year_shown'))
if (currentMonth == 12){
currentMonth = 1
currentYear = currentYear + 1
} else {
currentMonth = currentMonth + 1
}
console.log(currentYear, currentMonth, monthsAhead)
renderCalendarFor(calendarContainer,monthsBlock, currentYear, currentMonth, monthsAhead, weekStart)
})
return buttonForwards
}
function createDateSelector(calendarContainer, monthsBlock, monthsAhead, weekStart){
var dateSelector = createDateSelectionHTML()
var buttonGoToDate = dateSelector.querySelector('#button_load_selected_months')
buttonGoToDate.addEventListener('click', function(){
var currentYear = parseInt(dateSelector.querySelector('#year_selector').value)
var currentMonth = parseInt(dateSelector.querySelector('#month_selector').value) + 1
console.log(currentMonth, currentYear)
renderCalendarFor(calendarContainer,monthsBlock, currentYear, currentMonth, monthsAhead, weekStart)
})
return dateSelector
}
function renderCalendarFor(calendarContainer, monthsBlock, year, month, nMonths, weekStart){
monthsBlock.innerHTML = ''
calendarContainer.setAttribute('month_shown', month.toString())
calendarContainer.setAttribute('year_shown', year.toString())
var monthToCreate = month - 1
for (var i = 0; i < nMonths; i++){
monthToCreate = monthToCreate + 1
if (monthToCreate == 13){
monthToCreate = 1;
year = year + 1;
// console.log(monthToCreate, month, year, nMonths)
}
var monthContainer = document.createElement('div')
monthContainer.className = 'month_container'
monthContainer.appendChild(renderMonth(year, monthToCreate, weekStart))
monthsBlock.appendChild(monthContainer)
}
}
function renderMonth(year, month, weekStart = 0, daysOfWeekNumeric){
var daysOfWeek = ['sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat']
var daysOfWeekNumeric = [0, 1, 2, 3, 4, 5, 6]
for (var i = 0; i < weekStart; i++){
daysOfWeek.push(daysOfWeek.shift())
daysOfWeekNumeric.push(daysOfWeekNumeric.shift())
}
var table = document.createElement('table')
var monthString = monthsStrings[month - 1]
createHeaders(table, year, monthString, daysOfWeek)
createDates(table, year, month, daysOfWeekNumeric)
return table
}
function createHeaders(table, year, month, daysOfWeek){
let monthHeaderRow = document.createElement('tr')
let monthHeader = document.createElement('th')
monthHeader.innerText = month + ' ' + year
monthHeader.className = "month_header"
monthHeader.colSpan = 7
monthHeaderRow.appendChild(monthHeader)
table.appendChild(monthHeaderRow)
let header = document.createElement('tr')
for (var i = 0; i < daysOfWeek.length; i++){
var headerDay = document.createElement('th')
var headerText = document.createElement('div')
headerText.innerText = daysOfWeek[i]
headerText.className = 'weekday_header'
headerDay.appendChild(headerText)
header.appendChild(headerDay)
table.appendChild(header)
}
}
function createDates(table, year, month, daysOfWeekNumeric){
var weekEnd = daysOfWeekNumeric[daysOfWeekNumeric.length - 1]
var daysOfMonth = daysArray(year, month, daysOfWeekNumeric)
var row = document.createElement('tr')
for (var i = 0; i < daysOfMonth.length; i++){
var date = daysOfMonth[i]
var dayNr = date.getDate()
var cell = document.createElement('td')
var dateString = new Date(date.getTime() - (date.getTimezoneOffset() * 60000 ))
.toISOString()
.split("T")[0];
var dateContainer = document.createElement('div')
dateContainer.innerText = dayNr
dateContainer.className = 'days_of_month'
if (month - 1 == date.getMonth()){
dateContainer.classList.add('days_of_month_current')
dateContainer.id = 'date_' + dateString
today.setHours(0, 0, 0, 0)
if(today.getTime()==date.getTime()){
dateContainer.classList.add('days_of_month_today')
}
} else {
dateContainer.classList.add('days_of_month_not_current')
}
dateContainer.setAttribute('date', dateString)
cell.appendChild(dateContainer)
row.appendChild(cell)
if (date.getDay() == weekEnd) {
table.appendChild(row)
var row = document.createElement('tr')
}
}
table.appendChild(row)
}
function daysArray(year, month, daysOfWeekNumeric) {
month = month - 1
var arr = []
var daysInCurrentMonth = daysInMonth(year, month + 1)
var firstDayOfMonth = new Date(year, month, 1).getDay()
var blankDaysStart = daysOfWeekNumeric.indexOf(firstDayOfMonth) * -1
for (var i = blankDaysStart + 1; i < 1; i++){
var date = new Date(year, month, i)
arr.push(date)
}
for (var i = 1; i < daysInCurrentMonth + 1; i++){
var date = new Date(year, month, i)
arr.push(date)
}
var daysToFill = arr.length
for (var i = 1; i < 42 - daysToFill + 1; i++){
var date = new Date(year, month + 1, i)
arr.push(date)
}
return arr
}
function daysInMonth (year, month) {
return new Date(year, month, 0).getDate();
}
function createDateSelectionHTML(){
var container = document.createElement('div')
container.id = 'date_selector'
var goButton = document.createElement('button')
goButton.innerText = 'Go'
goButton.id = 'button_load_selected_months'
var label = document.createElement('label')
label.setAttribute('for', 'years')
label.innerText = 'Go to: '
var selectYear = document.createElement('select')
selectYear.name='years'
selectYear.id = 'year_selector'
spanBegin = 1990
spanEnd = 2030
yearsSpan = spanEnd - spanBegin
for (var i = 0; i < yearsSpan; i++){
var option = document.createElement('option')
option.value = spanBegin + i
option.innerText = option.value
selectYear.appendChild(option)
}
selectYear.value = today.getFullYear()
var selectMonth = document.createElement('select')
selectMonth.name='months'
selectMonth.id = 'month_selector'
for (var i = 0; i < 12; i++){
var option = document.createElement('option')
option.value = i;
option.innerText = monthsStrings[i]
selectMonth.appendChild(option)
}
selectMonth.value = today.getMonth()
container.appendChild(label)
container.appendChild(selectYear)
container.appendChild(selectMonth)
container.appendChild(goButton)
return container
}
function createButton(id, className, innerText){
var button = document.createElement('div')
button.id = id
button.className = className
button.innerText = innerText
return button
}

View File

@ -0,0 +1,17 @@
function getCookie(name) {
let cookieValue = null;
if (document.cookie && document.cookie !== '') {
let cookies = document.cookie.split(';');
for (let i = 0; i < cookies.length; i++) {
let cookie = cookies[i].trim();
if (cookie.substring(0, name.length + 1) === (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}

View File

@ -0,0 +1,62 @@
const csrftoken = getCookie('csrftoken');
var searchEmployeeButton = document.getElementById('load_employee_data_button')
searchEmployeeButton.addEventListener('click', function(){
fetchSearchEmployeeData()
})
function fetchSearchEmployeeData() {
var host = 'http://' + window.location.host;
var fetch_url = host + '/hr_module/change_employee_data_api'
var username = document.getElementById('username_input').value
fetch(fetch_url,
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRFToken': csrftoken
},
body: JSON.stringify({
"username": username
}),
}).then((response) => {
return response.json();
}).then((data) => {
console.log(data);
loadValuesIntoPage(data)
});
}
function loadValuesIntoPage(data){
var order = ['username', 'first_name', 'last_name', 'email', 'department', 'manager_username', 'time_model_id', 'manager_flag', 'is_active', 'is_staff', 'is_superuser']
var informationContainer = document.getElementById('search_results')
for (var i = 0; i < order.length; i++){
var field = order[i]
var value = data[field]
var fieldContainer = document.createElement('div')
fieldContainer.className = 'field_container'
if (typeof(value) === 'boolean'){
var httpfield = document.createElement('input')
httpfield.type = 'checkbox'
httpfield.checked = value
httpfield.setAttribute('disabled', 'disabled')
} else {
var httpfield = document.createElement('div')
httpfield.innerHTML = value
}
var label = document.createElement('label')
label.setAttribute('for', field)
label.innerText = field.replace('_', ' ')
httpfield.id = field
httpfield.className = 'database_field'
fieldContainer.appendChild(label)
fieldContainer.appendChild(httpfield)
informationContainer.appendChild(fieldContainer)
}
}

View File

@ -0,0 +1,173 @@
const csrftoken = getCookie('csrftoken');
// document.onload = parent.appendChild(addCalendar(monthsAhead=3))
window.addEventListener('load', function(){
var parent = document.getElementById('calendar_box')
parent.appendChild(addCalendar(monthsAhead=3))
fetchDays()
formatCalendarContainerSize(document.getElementById('calendar_container'))
document.getElementById('calendar_button_back').addEventListener('click', function(){
fetchDays()
})
document.getElementById('calendar_button_forwards').addEventListener('click', function(){
fetchDays()
})
document.getElementById('button_load_selected_months').addEventListener('click', function(){
fetchDays()
})
})
function fetchDays(){
var host = 'http://' + window.location.host;
var fetch_url = host + '/employee_module/show_employee_plan_api'
var range = searchedDateRange()
var startDate = range['min']
var endDate = range['max']
fetch(fetch_url,
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRFToken': csrftoken
},
body: JSON.stringify({
"start_date": startDate,
"end_date" : endDate
}),
}).then((response) => {
return response.json();
}).then((data) => {
console.log(data);
addClassToWorkingDays(data);
var parent = document.getElementById('hr_module_main_container')
var listContainer = document.getElementById('list_container')
if (listContainer == null){
var listContainer = document.createElement('div')
listContainer.id = 'list_container'
} else {
listContainer.innerHTML = ''
}
listContainer.appendChild(createDetailedCalendarRecords(data))
parent.appendChild(listContainer)
formatTableSize()
});
}
function addClassToWorkingDays(data){
for (var i = 0; i < data.length; i++){
var processedDate = data[i]['date']
var processedActivityType = data[i]['activity_type']
var nodeToChange = document.getElementById('date_' + processedDate)
nodeToChange.classList.add('days_of_month_' + processedActivityType)
}
}
function createDetailedCalendarRecords(data){
var table = createDetailedHeaders()
for (var i = 0; i < data.length; i++){
var index = data[i]['id']
var username = data[i]['username_id']
var row = table.insertRow(-1)
row.id = 'database_id_' + index.toString()
row.setAttribute('database_username', username)
appendCell(row, 'div', 'date', data[i]['date'], 0)
appendCell(row, 'div', 'begin_time', data[i]['begin_time'], 1)
appendCell(row, 'div', 'end_time', data[i]['end_time'], 2)
appendCell(row, 'div', 'activity_type', data[i]['activity_type'], 3)
}
return table
}
function appendCell(tableRow, tag, tagName, tagText, cellIndex){
var cell = tableRow.insertCell(cellIndex)
var textInput = document.createElement(tag)
textInput.innerText = tagText
textInput.name = tagName
cell.appendChild(textInput)
}
function createDetailedHeaders(){
var table = document.createElement('table')
let headerRow = document.createElement('tr')
let columns = ['Date', 'Start time', 'End time', 'Activity type']
for (let i = 0; i < columns.length; i++){
var headerCell = document.createElement('th')
var headerText = document.createElement('div')
headerText.innerText = columns[i]
headerCell.appendChild(headerText)
headerRow.appendChild(headerCell)
}
table.appendChild(headerRow)
table.id = 'detailed_plan_records'
return table
}
function formatCalendarContainerSize(calendarContainer){
var monthsBlock = calendarContainer.querySelector('#months_block')
var calendarButton = calendarContainer.querySelector('#calendar_button_back')
var dateSelector = calendarContainer.querySelector('#date_selector')
var widthMonths = monthsBlock.offsetWidth
var heightMonths = monthsBlock.offsetHeight
var heightDateSelector = dateSelector.offsetHeight
var widthCalendarButton = calendarButton.offsetWidth * 2
var widthTotal = widthMonths + widthCalendarButton
var heightTotal = heightMonths + heightDateSelector
calendarContainer.setAttribute('style','height:' + heightTotal +'px; width:' + widthTotal + 'px');
}
function formatTableSize(){
var calendar = document.getElementById('calendar_container')
var tableDiv = document.getElementById('list_container')
var width = calendar.offsetWidth
tableDiv.setAttribute('style', 'width:' + width + 'px')
}
function searchedDateRange(){
var dates = document.getElementsByClassName('days_of_month_current')
var datesArray = []
for (var i = 0; i < dates.length; i++){
var dateAttr = new Date(dates[i].getAttribute('date'))
datesArray.push(dateAttr)
}
var minDate = new Date(Math.min.apply(null, datesArray))
var maxDate = new Date(Math.max.apply(null, datesArray))
var out = {'min' : minDate,
'max': maxDate}
console.log(out)
return out
}
function getCookie(name) {
let cookieValue = null;
if (document.cookie && document.cookie !== '') {
let cookies = document.cookie.split(';');
for (let i = 0; i < cookies.length; i++) {
let cookie = cookies[i].trim();
if (cookie.substring(0, name.length + 1) === (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}

View File

@ -0,0 +1,39 @@
{% extends 'base.html' %}
{% load static %}
{% block stylesheet_hr_module_base %}
<link rel="stylesheet" href="{% static '/css/hr_module_base.css' %}">
{% endblock %}
{% block core_content %}
<script src="{% static '/js/csrf_token.js' %}"></script>
<div class="sidebar">
<a href="{% url 'employee_module:show_schedule' %}">
<div class="sidebar_item">Show schedule
</div>
</a>
<a href="{% url 'hr_module:change_employee_data' %}">
<div class="sidebar_item">Show time tracking history
</div>
</a>
<a href="{% url 'hr_module:create_employees' %}">
<div class="sidebar_item">Show your data
</div>
</a>
</div>
<div id="hr_module_main_container">
{% block action_panel %}
{% endblock %}
</div>
{% endblock %}

View File

@ -0,0 +1,20 @@
{% extends 'employee_module_base.html' %}
{% load static %}
{% block action_panel %}
<link rel="stylesheet" href="{% static '/css/hr_module_change_employee_data.css' %}">
<div>
<label for="username_input">Person username: </label>
<input id="username_input" type="text" value="kowalskija">
<button type="button" id="load_employee_data_button">Search</button>
</div>
<div id="search_results">
</div>
<script src="{% static '/js/hr_module_change_employee_data.js' %}"></script>
{% endblock %}

View File

@ -0,0 +1,9 @@
{% extends 'employee_module_base.html' %}
{% load static %}
{% block action_panel %}
<h2>Welcome to Timefall - time tracking application, employee section </h2>
{% endblock %}

View File

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

View File

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

View File

@ -0,0 +1,19 @@
{% extends 'employee_module_base.html' %}
{% load static %}
{% block action_panel %}
<link rel="stylesheet" href="{% static '/css/calendar.css' %}">
<link rel="stylesheet" href="{% static '/css/calendar_local.css' %}">
<link rel="stylesheet" href="{% static '/css/hr_module_show_schedule.css' %}">
<div>
<div id="username" username="{{ user }}"></div>
</div>
<div id="calendar_box"></div>
<script src="{% static '/js/calendar.js' %}"></script>
<script src="{% static '/js/employee_module_show_schedule.js' %}"></script>
{% endblock %}

17
employee_module/urls.py Normal file
View File

@ -0,0 +1,17 @@
from django.urls import path
from . import views
from django.contrib.auth import views as auth_views
app_name = 'employee_module'
urlpatterns = [
path('login', auth_views.LoginView.as_view(template_name='hr_module_login.html'), name='login'),
path('logout', auth_views.LogoutView.as_view(), name='logout'),
path('change_password', auth_views.PasswordChangeView.as_view(template_name='hr_module_password_change.html'), name='change_password'),
path('home', views.homepage, name='homepage'),
path('show_schedule', views.manage_schedule, name='show_schedule'),
path('show_employee_plan_api', views.show_employee_plan_api, name='show_employee_plan_api'),
path('change_employee_data', views.change_employee_data, name='change_employee_data'),
path('change_employee_data_api', views.change_employee_data_api, name='change_employee_data_api'),
]

View File

@ -1,5 +1,66 @@
from django.shortcuts import render
from django.http import HttpResponse
from django.contrib.auth.decorators import login_required
from hr_module.handling_functions.data_import_functions import read_and_parse_excel, insert_excel
from hr_module.handling_functions.monthly_planning_functions import insert_into_plan, create_planning_operation_report
from hr_module.handling_functions.misc import dictfetchall
import pandas as pd
import json
from hr_module.models import Employee, PlanCreationLog, Plan
from django.contrib.auth.models import User
from django.http import HttpResponse, JsonResponse, Http404
from django.db import connection
import datetime
login_url = '/hr_module/login'
# Create your views here.
@login_required(login_url=login_url)
def homepage(request):
template_name = 'employee_module_home.html'
return render(request, template_name)
@login_required(login_url=login_url)
def change_employee_data(request):
template_name = 'employee_module_change_employee_data.html'
return render(request, template_name)
def change_employee_data_api(request):
if request.method == 'POST':
if request.user.is_authenticated:
username = request.user.username
empl = User.objects.select_related('employee').get(username=username)
record_employee = empl.employee.__dict__
record_user = empl.__dict__
response_dict = dict(record_user, **record_employee)
for i in ['_state', 'password']:
response_dict.pop(i)
print(response_dict)
return JsonResponse(response_dict, safe=False)
else:
return JsonResponse({'error': 'not_authenticated'})
@login_required(login_url=login_url)
def manage_schedule(request):
template = 'employee_module_show_schedule.html'
return render(request, template)
def show_employee_plan_api(request):
if request.method == 'POST':
body = json.loads(request.body)
username = request.user.username
start_date = body['start_date'].split('T')[0]
end_date = body['end_date'].split('T')[0]
start_date = datetime.datetime.strptime(start_date, '%Y-%m-%d')
end_date = datetime.datetime.strptime(end_date, '%Y-%m-%d')
print(username, start_date, end_date)
user_obj = Employee.objects.get(pk=username)
query_result = Plan.objects.filter(username=user_obj, date__range= [start_date, end_date])
response = list(query_result.values())
return JsonResponse(response, safe=False)

View File

@ -3,6 +3,7 @@ import pandas as pd
from django.conf import settings
import datetime
from sqlalchemy import create_engine
from django.contrib.auth.hashers import make_password
def create_connection(db_file, type=1):
""" create a database connection to the SQLite database
@ -34,7 +35,7 @@ def read_and_parse_excel(file):
def insert_excel(df):
conn = create_connection(settings.DATABASES['default']['NAME'])
df['date_joined'] = datetime.date.today()
df['password'] = 'start'
df['password'] = make_password('start')
df_to_user_model = df[['username',
'first_name',

View File

@ -214,7 +214,7 @@ function buildPlanJson(){
function postPlanToDb(){
var host = 'http://' + window.location.host;
var fetch_url = host + '/hr_module/plan_api'
var fetch_url = host + '/hr_module/new_plan_api'
var json = buildPlanJson()
fetch(fetch_url,

View File

@ -0,0 +1,9 @@
{% extends 'hr_module_base.html' %}
{% load static %}
{% block action_panel %}
<h2>Welcome to Timefall - time tracking application</h2>
{% endblock %}

View File

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

View File

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

View File

@ -1,10 +1,15 @@
from django.urls import path
from . import views
from django.contrib.auth import views as auth_views
app_name = 'hr_module'
urlpatterns = [
path('login', auth_views.LoginView.as_view(template_name='hr_module_login.html'), name='login'),
path('logout', auth_views.LogoutView.as_view(), name='logout'),
path('change_password', auth_views.PasswordChangeView.as_view(template_name='hr_module_password_change.html'), name='change_password'),
path('home', views.homepage, name='homepage'),
path('create_schedule', views.create_schedule, name='create_schedule'),
path('create_employees', views.create_employees, name='create_employees'),
path('search_api', views.search_users_api, name='search_users_api'),

View File

@ -1,4 +1,5 @@
from django.shortcuts import render, redirect
from django.contrib.auth.decorators import login_required
from .forms import UploadFileForm, NewUserForm
from hr_module.handling_functions.data_import_functions import read_and_parse_excel, insert_excel
from hr_module.handling_functions.monthly_planning_functions import insert_into_plan, create_planning_operation_report
@ -12,11 +13,19 @@ from django.db import connection
import datetime
login_url = '/hr_module/login'
# Create your views here.
@login_required(login_url=login_url)
def create_schedule(request):
template_name = 'hr_module_create_schedule.html'
return render(request, template_name)
@login_required(login_url=login_url)
def homepage(request):
template_name = 'hr_module_home.html'
return render(request, template_name)
@login_required(login_url=login_url)
def change_employee_data(request):
template_name = 'hr_module_change_employee_data.html'
return render(request, template_name)
@ -62,7 +71,7 @@ def change_employee_data_api(request):
else:
return JsonResponse({'error': 'not_authenticated'})
@login_required(login_url=login_url)
def create_employees(request):
if request.method == 'POST':
if 'import_preview' in request.POST:
@ -75,7 +84,7 @@ def create_employees(request):
request.session['df_path'] = df_dict['df_path']
df_html = df_dict['df_html']
context = {'df_html': df_html}
template = 'hr_import_validation.html'
template = 'hr_module_import_validation.html'
return render(request, template, context)
if 'import_insert' in request.POST:
@ -202,11 +211,11 @@ def new_plan_api(request):
report_location = create_planning_operation_report(log, user)
print(user)
user_obj = Employee.objects.get(pk=user)
plan_creation_log = PlanCreationLog(username=user_obj, report_location=report_location)
plan_creation_log.save()
# plan_creation_log = PlanCreationLog(username=user_obj, report_location=report_location)
# plan_creation_log.save()
return JsonResponse(log)
@login_required(login_url=login_url)
def manage_schedule(request):
template = 'hr_module_show_schedule.html'
return render(request, template)

Binary file not shown.

View File

@ -1,3 +0,0 @@
from django.contrib import admin
# Register your models here.

View File

@ -1,5 +0,0 @@
from django.apps import AppConfig
class ManagerModuleConfig(AppConfig):
name = 'manager_module'

View File

@ -1,3 +0,0 @@
from django.db import models
# Create your models here.

View File

@ -1,3 +0,0 @@
from django.test import TestCase
# Create your tests here.

View File

@ -1,3 +0,0 @@
from django.shortcuts import render
# Create your views here.

View File

@ -13,4 +13,15 @@ html, body {
background-color: whitesmoke;
width: 100%;
height: 100%;
}
}
.navbar_item {
float: right;
height: 35px;
width: auto;
display: block;
vertical-align:middle;
text-align:center;
margin-top: 15px;
margin-right: 15px;
}

View File

@ -12,6 +12,17 @@
<body>
<div class="navbar">
{% if user.is_authenticated %}
<div class="navbar_item">
<a href="{% url 'hr_module:logout' %}">Log out</a>
</div>
<div class="navbar_item">You are logged in as: {{ user }} </div>
{% else %}
{% endif %}
</div>
<div class="main_container">

View File

@ -27,6 +27,7 @@ SECRET_KEY = 'tx#+u3u-r1$n_4r(!6vvcb@1f5!z21^74w(zesiz$&59&72$kq'
DEBUG = True
ALLOWED_HOSTS = ['192.168.101.128',
'192.168.101.129',
'127.0.0.1',]
@ -34,6 +35,7 @@ ALLOWED_HOSTS = ['192.168.101.128',
INSTALLED_APPS = [
'hr_module.apps.HrModuleConfig',
'employee_module.apps.EmployeeModuleConfig',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
@ -132,4 +134,7 @@ STATICFILES_DIRS = [
TMP_FILE_STORAGE = os.path.join(BASE_DIR, 'temp/')
IMPORT_REPORT_STORAGE = os.path.join(BASE_DIR, 'import_reports/')
IMPORT_REPORT_STORAGE = os.path.join(BASE_DIR, 'import_reports/')
LOGOUT_REDIRECT_URL = '/hr_module/login'
LOGIN_REDIRECT_URL = '/hr_module/home'

View File

@ -19,4 +19,5 @@ from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('hr_module/', include('hr_module.urls')),
path('employee_module/', include('employee_module.urls')),
]