added calendar
This commit is contained in:
parent
49d88f8d6b
commit
f7ea46d9f5
BIN
db.sqlite3
BIN
db.sqlite3
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -4,7 +4,7 @@ from django.conf import settings
|
||||
import datetime
|
||||
from sqlalchemy import create_engine
|
||||
|
||||
def create_connection(db_file):
|
||||
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
|
||||
@ -13,11 +13,13 @@ def create_connection(db_file):
|
||||
conn = None
|
||||
try:
|
||||
path = 'sqlite:///' + str(db_file)
|
||||
engine = create_engine(path)
|
||||
conn = engine.connect()
|
||||
if type == 1:
|
||||
return create_engine(path)
|
||||
else:
|
||||
return create_engine(path).connect()
|
||||
except Exception as e:
|
||||
print(e)
|
||||
return conn
|
||||
return None
|
||||
|
||||
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
|
||||
from sqlalchemy.orm import sessionmaker
|
||||
from sqlalchemy import create_engine
|
||||
|
||||
from django.conf import settings
|
||||
from ..models import Employee, TimeModel, Plan
|
||||
import pandas as pd
|
||||
from ..models import Employee, Plan
|
||||
import datetime
|
||||
|
||||
|
||||
@ -31,8 +31,7 @@ def insert_into_plan(user, start_date, end_date, start_time, daily_hours, activi
|
||||
6: timemodel['sun']}
|
||||
|
||||
days = (end_date - start_date).days
|
||||
overlaps = []
|
||||
inserted = []
|
||||
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)
|
||||
@ -45,20 +44,21 @@ def insert_into_plan(user, start_date, end_date, start_time, daily_hours, activi
|
||||
end_time=end_time,
|
||||
activity_type=activity_type)
|
||||
plan.save()
|
||||
inserted.append({'username': username.pk,
|
||||
log.append({'username': username.pk,
|
||||
'date': date_to_add,
|
||||
'begin_time': start_time,
|
||||
'end_time': end_time,
|
||||
'activity_type': activity_type})
|
||||
'activity_type': activity_type,
|
||||
'status': 'imported'})
|
||||
else:
|
||||
|
||||
overlaps.append({'username': username.pk,
|
||||
log.append({'username': username.pk,
|
||||
'date': date_to_add,
|
||||
'begin_time': start_time,
|
||||
'end_time': end_time,
|
||||
'activity_type': activity_type})
|
||||
return {'overlaps': overlaps,
|
||||
'inserted': inserted}
|
||||
'activity_type': activity_type,
|
||||
'status': 'failed due to conflicting overlap'})
|
||||
return log
|
||||
|
||||
|
||||
def check_conflicting_records(username, date, start_time, end_time):
|
||||
@ -74,4 +74,12 @@ def check_conflicting_records(username, date, start_time, end_time):
|
||||
else:
|
||||
return False
|
||||
else:
|
||||
return False
|
||||
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
|
76
hr_module/migrations/0001_initial.py
Normal file
76
hr_module/migrations/0001_initial.py
Normal file
@ -0,0 +1,76 @@
|
||||
# Generated by Django 3.1.3 on 2020-12-22 19:18
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
('auth', '0012_alter_user_first_name_max_length'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Employee',
|
||||
fields=[
|
||||
('username', models.OneToOneField(db_column='username', on_delete=django.db.models.deletion.CASCADE, primary_key=True, serialize=False, to='auth.user', to_field='username')),
|
||||
('department', models.CharField(max_length=200)),
|
||||
('manager_username', models.CharField(max_length=200)),
|
||||
('manager_flag', models.BooleanField()),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='TimeModel',
|
||||
fields=[
|
||||
('time_model_id', models.IntegerField(primary_key=True, serialize=False)),
|
||||
('daily_hours', models.DecimalField(decimal_places=2, max_digits=4)),
|
||||
('weekly_days', models.IntegerField()),
|
||||
('mon', models.BooleanField()),
|
||||
('tue', models.BooleanField()),
|
||||
('wed', models.BooleanField()),
|
||||
('thu', models.BooleanField()),
|
||||
('fri', models.BooleanField()),
|
||||
('sat', models.BooleanField()),
|
||||
('sun', models.BooleanField()),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='TimeLog',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('date', models.DateField()),
|
||||
('begin_time', models.TimeField()),
|
||||
('end_time', models.TimeField()),
|
||||
('activity_type', models.CharField(max_length=100)),
|
||||
('username', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='hr_module.employee')),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='PlanCreationLog',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('report_location', models.CharField(max_length=500)),
|
||||
('creation_date', models.DateTimeField(auto_now_add=True)),
|
||||
('username', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='hr_module.employee')),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Plan',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('date', models.DateField()),
|
||||
('begin_time', models.TimeField()),
|
||||
('end_time', models.TimeField()),
|
||||
('activity_type', models.CharField(max_length=100)),
|
||||
('username', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='hr_module.employee')),
|
||||
],
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='employee',
|
||||
name='time_model',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='hr_module.timemodel'),
|
||||
),
|
||||
]
|
0
hr_module/migrations/__init__.py
Normal file
0
hr_module/migrations/__init__.py
Normal file
BIN
hr_module/migrations/__pycache__/0001_initial.cpython-38.pyc
Normal file
BIN
hr_module/migrations/__pycache__/0001_initial.cpython-38.pyc
Normal file
Binary file not shown.
BIN
hr_module/migrations/__pycache__/__init__.cpython-38.pyc
Normal file
BIN
hr_module/migrations/__pycache__/__init__.cpython-38.pyc
Normal file
Binary file not shown.
@ -48,3 +48,9 @@ class TimeLog(models.Model):
|
||||
begin_time = models.TimeField()
|
||||
end_time = models.TimeField()
|
||||
activity_type = models.CharField(max_length=100)
|
||||
|
||||
|
||||
class PlanCreationLog(models.Model):
|
||||
username = models.ForeignKey(Employee, on_delete=models.PROTECT)
|
||||
report_location = models.CharField(max_length=500)
|
||||
creation_date = models.DateTimeField(auto_now_add=True)
|
110
hr_module/static/css/calendar.css
Normal file
110
hr_module/static/css/calendar.css
Normal file
@ -0,0 +1,110 @@
|
||||
|
||||
html, body {
|
||||
font-family: sans-serif;
|
||||
}
|
||||
|
||||
table, th, 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;
|
||||
|
||||
}
|
5
hr_module/static/css/calendar_local.css
Normal file
5
hr_module/static/css/calendar_local.css
Normal file
@ -0,0 +1,5 @@
|
||||
|
||||
|
||||
.days_of_month_work {
|
||||
background-color: darkslateblue;
|
||||
}
|
264
hr_module/static/js/calendar.js
Normal file
264
hr_module/static/js/calendar.js
Normal file
@ -0,0 +1,264 @@
|
||||
|
||||
const monthsStrings = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']
|
||||
var today = new Date()
|
||||
|
||||
function addCalendar(parent, monthsAhead = 1, currentMonth = new Date().getMonth() + 1, currentYear= new Date().getFullYear()){
|
||||
parent.innerHTML = ''
|
||||
|
||||
var calendar = renderCalendarFor(currentYear, currentMonth, monthsAhead, 1)
|
||||
|
||||
var container = document.createElement('div')
|
||||
container.id = 'calendar_container'
|
||||
|
||||
var buttonBack = createButton('calendar_button_back', 'calendar_button', '<')
|
||||
buttonBack.addEventListener('click', function(){
|
||||
if (currentMonth == 1){
|
||||
currentMonth = 11
|
||||
currentYear = currentYear - 1
|
||||
}
|
||||
addCalendar(parent, monthsAhead, currentMonth - 1, currentYear)
|
||||
})
|
||||
container.appendChild(buttonBack)
|
||||
container.appendChild(calendar)
|
||||
|
||||
var buttonForward = createButton('calendar_button_forwards', 'calendar_button', '>')
|
||||
buttonForward.addEventListener('click', function(){
|
||||
if (currentMonth == 12){
|
||||
currentMonth = 0
|
||||
currentYear = currentYear + 1
|
||||
}
|
||||
addCalendar(parent, monthsAhead, currentMonth + 1, currentYear)
|
||||
})
|
||||
|
||||
container.appendChild(buttonForward)
|
||||
container.appendChild(createDateSelection())
|
||||
|
||||
parent.appendChild(container)
|
||||
|
||||
var buttonGoToDate = document.getElementById('button_load_selected_months')
|
||||
buttonGoToDate.addEventListener('click', function(){
|
||||
var currentYear = parseInt(document.getElementById('year_selector').value)
|
||||
var currentMonth = parseInt(document.getElementById('month_selector').value)
|
||||
addCalendar(parent, monthsAhead, currentMonth + 1, currentYear)
|
||||
})
|
||||
|
||||
formatContainerSize()
|
||||
|
||||
}
|
||||
|
||||
|
||||
function formatContainerSize(){
|
||||
|
||||
var container = document.getElementById('calendar_container')
|
||||
|
||||
var monthsBlock = document.getElementById('months_block')
|
||||
var calendarButton = document.getElementById('calendar_button_back')
|
||||
var dateSelector = document.getElementById('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
|
||||
|
||||
container.setAttribute('style','height:' + heightTotal +'px; width:' + widthTotal + 'px');
|
||||
|
||||
}
|
||||
|
||||
|
||||
function createDateSelection(){
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
function renderCalendarFor(year, month, nMonths, weekStart){
|
||||
var parent = document.createElement('div')
|
||||
parent.id = 'months_block'
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
var monthContainer = document.createElement('div')
|
||||
monthContainer.className = 'month_container'
|
||||
|
||||
monthContainer.appendChild(renderMonth(year, monthToCreate, weekStart))
|
||||
parent.appendChild(monthContainer)
|
||||
}
|
||||
return parent
|
||||
}
|
||||
|
||||
|
||||
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'
|
||||
dateContainer.id = 'date_' + dateString
|
||||
|
||||
if (month - 1 == date.getMonth()){
|
||||
dateContainer.classList.add('days_of_month_current')
|
||||
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();
|
||||
}
|
@ -43,7 +43,7 @@ function appendFoundFilterOptions(data){
|
||||
for (var i = 0; i < data.length; i++) {
|
||||
|
||||
var caption = data[i]['caption'];
|
||||
var value = data[i]['value'];
|
||||
var value = data[i]['column_value'];
|
||||
console.log(caption)
|
||||
console.log(value)
|
||||
|
||||
@ -228,7 +228,7 @@ function postPlanToDb(){
|
||||
json
|
||||
}),
|
||||
}).then((response) => {
|
||||
return true;
|
||||
return response;
|
||||
}).then((data) => {
|
||||
console.log(data);
|
||||
});
|
||||
@ -250,4 +250,17 @@ function getCookie(name) {
|
||||
}
|
||||
}
|
||||
return cookieValue;
|
||||
}
|
||||
|
||||
|
||||
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';
|
||||
}
|
||||
}
|
89
hr_module/static/js/hr_module_show_schedule.js
Normal file
89
hr_module/static/js/hr_module_show_schedule.js
Normal file
@ -0,0 +1,89 @@
|
||||
const csrftoken = getCookie('csrftoken');
|
||||
|
||||
var parent = document.getElementById('calendar_box')
|
||||
document.onload = addCalendar(parent, 3)
|
||||
|
||||
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);
|
||||
adjustCalendar(data);
|
||||
});
|
||||
}
|
||||
|
||||
function adjustCalendar(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 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}
|
||||
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;
|
||||
}
|
11
hr_module/templates/hr_module_import_success.html
Normal file
11
hr_module/templates/hr_module_import_success.html
Normal file
@ -0,0 +1,11 @@
|
||||
{% extends 'hr_module_base.html' %}
|
||||
|
||||
{% load static %}
|
||||
|
||||
{% block action_panel %}
|
||||
<link rel="stylesheet" href="{% static '/css/hr_import_validation.css' %}">
|
||||
<div class="import_instructions">Data has been imported successfully
|
||||
</div>
|
||||
|
||||
|
||||
{% endblock %}
|
@ -52,6 +52,10 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="popup" id="plan_log_popup">
|
||||
|
||||
</div>s
|
||||
|
||||
<script src="{% static '/js/hr_module_schedule.js' %}"></script>
|
||||
|
||||
{% endblock %}
|
||||
|
20
hr_module/templates/hr_module_show_schedule.html
Normal file
20
hr_module/templates/hr_module_show_schedule.html
Normal file
@ -0,0 +1,20 @@
|
||||
{% extends 'hr_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' %}">
|
||||
|
||||
<div>
|
||||
<label for="username_input">Person username: </label>
|
||||
<input id="username_input" type="text">
|
||||
<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/hr_module_show_schedule.js' %}"></script>
|
||||
|
||||
|
||||
{% endblock %}
|
@ -5,10 +5,11 @@ from . import views
|
||||
app_name = 'hr_module'
|
||||
|
||||
urlpatterns = [
|
||||
path('', views.index, name='index'),
|
||||
path('create_schedule', views.create_schedule, name='schedule'),
|
||||
path('import_data', views.hr_import, name='import_data'),
|
||||
path('search', views.search_users_api, name='search_users_api'),
|
||||
path('loeademployees', views.load_employees_api, name='load_employees'),
|
||||
path('plan_api', views.plan_api, name='plan_api'),
|
||||
|
||||
path('new_plan_api', views.new_plan_api, name='new_plan_api'),
|
||||
path('show_schedule', views.show_employee_plan, name='employee_schedule'),
|
||||
path('show_employee_plan_api', views.show_employee_plan_api, name='show_employee_plan_api')
|
||||
]
|
@ -1,18 +1,18 @@
|
||||
from django.shortcuts import render, redirect
|
||||
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
|
||||
from hr_module.handling_functions.monthly_planning_functions import insert_into_plan, create_planning_operation_report
|
||||
import pandas as pd
|
||||
import json
|
||||
from .models import Employee
|
||||
from django.core import serializers
|
||||
from .models import Employee, PlanCreationLog, Plan
|
||||
from django.http import HttpResponse, JsonResponse, Http404
|
||||
from django.db import connection
|
||||
import datetime
|
||||
|
||||
|
||||
# Create your views here.
|
||||
def index(request):
|
||||
def create_schedule(request):
|
||||
template_name = 'hr_module_schedule.html'
|
||||
|
||||
return render(request, template_name)
|
||||
|
||||
|
||||
@ -35,17 +35,19 @@ def hr_import(request):
|
||||
df = pd.read_csv(request.session['df_path'])
|
||||
insert_excel(df)
|
||||
del request.session['df_path']
|
||||
return redirect('import_data')
|
||||
template = 'hr_module_import_success.html'
|
||||
return render(request, template)
|
||||
|
||||
|
||||
if 'import_single' in request.POST:
|
||||
df_dict = {k: v[0] for k, v in dict(request.POST).items()}
|
||||
for i in ('csrfmiddlewaretoken','import_single'):
|
||||
for i in ('csrfmiddlewaretoken', 'import_single'):
|
||||
df_dict.pop(i, None)
|
||||
df = pd.DataFrame(df_dict, index=[0])
|
||||
insert_excel(df)
|
||||
print('done')
|
||||
return redirect('import_data')
|
||||
template = 'hr_module_import_success.html'
|
||||
return render(request, template)
|
||||
|
||||
else:
|
||||
columns_user = ['first_name',
|
||||
@ -89,15 +91,16 @@ def search_users_api(request):
|
||||
|
||||
|
||||
if searched_field == 'department':
|
||||
cursor.execute('select department as caption, department as value from hr_module_employee '
|
||||
cursor.execute('select department as caption, department as column_value from hr_module_employee '
|
||||
'group by department')
|
||||
|
||||
elif searched_field == 'manager':
|
||||
cursor.execute('select auth.first_name || %s || auth.last_name as caption, empl.manager_username as value '
|
||||
cursor.execute('select auth.first_name || %s || auth.last_name as caption, empl.manager_username as column_value '
|
||||
'from hr_module_employee empl inner join auth_user auth on auth.username = empl.manager_username '
|
||||
'group by auth.first_name || %s || auth.last_name, empl.manager_username', [' ', ' ']
|
||||
)
|
||||
elif searched_field == 'username':
|
||||
cursor.execute('select auth.first_name || %s || auth.last_name as caption, empl.username as value from hr_module_employee empl '
|
||||
cursor.execute('select auth.first_name || %s || auth.last_name as caption, empl.username as column_value from hr_module_employee empl '
|
||||
'inner join auth_user auth on empl.username = auth.username ', [' ',]
|
||||
)
|
||||
|
||||
@ -148,11 +151,43 @@ def load_employees_api(request):
|
||||
return JsonResponse(response, safe=False)
|
||||
|
||||
|
||||
def plan_api(request):
|
||||
def new_plan_api(request):
|
||||
if request.method == 'POST':
|
||||
user = request.user.username
|
||||
body = json.loads(request.body)['json']
|
||||
log = []
|
||||
for item in body:
|
||||
insert_result = insert_into_plan(item['username'], item['date_start'], item['date_end'], item['start_time'], item['daily_hours'], item['activity_type'], item['timemodel_pattern'])
|
||||
print(insert_result)
|
||||
response = ''
|
||||
return JsonResponse(response, safe=False)
|
||||
log = log + insert_result
|
||||
|
||||
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()
|
||||
return JsonResponse(log)
|
||||
|
||||
|
||||
def show_employee_plan(request):
|
||||
template = 'hr_module_show_schedule.html'
|
||||
return render(request, template)
|
||||
|
||||
|
||||
def show_employee_plan_api(request):
|
||||
|
||||
if request.method == 'POST':
|
||||
body = json.loads(request.body)
|
||||
username = body['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)
|
BIN
import_reports/admin_2020-12-22T19:08:15.299016.xlsx
Normal file
BIN
import_reports/admin_2020-12-22T19:08:15.299016.xlsx
Normal file
Binary file not shown.
BIN
import_reports/admin_2020-12-22T19:09:05.123287.xlsx
Normal file
BIN
import_reports/admin_2020-12-22T19:09:05.123287.xlsx
Normal file
Binary file not shown.
BIN
import_reports/admin_2020-12-22T19:09:28.658828.xlsx
Normal file
BIN
import_reports/admin_2020-12-22T19:09:28.658828.xlsx
Normal file
Binary file not shown.
BIN
import_reports/admin_2020-12-22T19:11:49.978261.xlsx
Normal file
BIN
import_reports/admin_2020-12-22T19:11:49.978261.xlsx
Normal file
Binary file not shown.
BIN
import_reports/admin_2020-12-22T19:13:02.417671.xlsx
Normal file
BIN
import_reports/admin_2020-12-22T19:13:02.417671.xlsx
Normal file
Binary file not shown.
BIN
import_reports/admin_2020-12-22T19:14:59.952208.xlsx
Normal file
BIN
import_reports/admin_2020-12-22T19:14:59.952208.xlsx
Normal file
Binary file not shown.
BIN
import_reports/admin_2020-12-22T19:17:30.188295.xlsx
Normal file
BIN
import_reports/admin_2020-12-22T19:17:30.188295.xlsx
Normal file
Binary file not shown.
BIN
import_reports/admin_2020-12-26T16:46:57.200845.xlsx
Normal file
BIN
import_reports/admin_2020-12-26T16:46:57.200845.xlsx
Normal file
Binary file not shown.
BIN
import_reports/admin_2020-12-26T16:48:14.407064.xlsx
Normal file
BIN
import_reports/admin_2020-12-26T16:48:14.407064.xlsx
Normal file
Binary file not shown.
BIN
import_reports/admin_2020-12-26T16:49:58.769368.xlsx
Normal file
BIN
import_reports/admin_2020-12-26T16:49:58.769368.xlsx
Normal file
Binary file not shown.
BIN
temp/admin2020-12-22T18:09:47.063879.xlsx
Normal file
BIN
temp/admin2020-12-22T18:09:47.063879.xlsx
Normal file
Binary file not shown.
@ -1,6 +1,6 @@
|
||||
,first_name,last_name,username,email,is_staff,is_active,is_superuser,department,manager_username,time_model_id,manager_flag
|
||||
0,Jan,Kowalski,kowalskija,kowalskija@company.com,0,1,0,test department,hitlerad,1,0
|
||||
1,Janina,Kowalska,kowalskaja,kowalskaja@company.com,0,1,0,test department,hitlerad,2,0
|
||||
2,Tadeusz,Tadeuszowicz,tadeuszowiczta,tadeuszowiczta@company.com,0,1,0,dfdfdv,hitlerad,3,0
|
||||
3,Aleksander,Lukaszenko,lukaszenkoal,lukaszenkoal@company.com,0,1,0,fsdfgfg,hitlerad,4,0
|
||||
4,Adolf,Hitler,hitlerad,hitlerad@company.com,0,1,0,fg,hitlerad,5,0
|
||||
1,Janina,Kowalska,kowalskaja,kowalskaja@company.com,0,1,0,test department,test department0,1,0
|
||||
2,Tadeusz,Tadeuszowicz,tadeuszowiczta,tadeuszowiczta@company.com,0,1,0,dfdfdv,dfdfdv0,1,0
|
||||
3,Aleksander,Lukaszenko,lukaszenkoal,lukaszenkoal@company.com,0,1,0,fsdfgfg,hitlerad,1,0
|
||||
4,Adolf,Hitler,hitlerad,hitlerad@company.com,0,1,0,fg,hitlerad,1,0
|
||||
|
|
Binary file not shown.
@ -131,4 +131,5 @@ STATICFILES_DIRS = [
|
||||
]
|
||||
|
||||
|
||||
TMP_FILE_STORAGE = os.path.join(BASE_DIR, 'temp/')
|
||||
TMP_FILE_STORAGE = os.path.join(BASE_DIR, 'temp/')
|
||||
IMPORT_REPORT_STORAGE = os.path.join(BASE_DIR, 'import_reports/')
|
Loading…
Reference in New Issue
Block a user