more ajax
This commit is contained in:
parent
8da99758f2
commit
2c516b24e8
@ -22,6 +22,7 @@
|
|||||||
<option name="TEMPLATE_FOLDERS">
|
<option name="TEMPLATE_FOLDERS">
|
||||||
<list>
|
<list>
|
||||||
<option value="$MODULE_DIR$/templates" />
|
<option value="$MODULE_DIR$/templates" />
|
||||||
|
<option value="$MODULE_DIR$/hr_module/templates" />
|
||||||
</list>
|
</list>
|
||||||
</option>
|
</option>
|
||||||
</component>
|
</component>
|
||||||
|
BIN
__pycache__/manage.cpython-38.pyc
Normal file
BIN
__pycache__/manage.cpython-38.pyc
Normal file
Binary file not shown.
BIN
db.sqlite3
BIN
db.sqlite3
Binary file not shown.
BIN
hr_module/__pycache__/admin.cpython-38.pyc
Normal file
BIN
hr_module/__pycache__/admin.cpython-38.pyc
Normal file
Binary file not shown.
BIN
hr_module/__pycache__/apps.cpython-38.pyc
Normal file
BIN
hr_module/__pycache__/apps.cpython-38.pyc
Normal file
Binary file not shown.
BIN
hr_module/__pycache__/forms.cpython-38.pyc
Normal file
BIN
hr_module/__pycache__/forms.cpython-38.pyc
Normal file
Binary file not shown.
BIN
hr_module/__pycache__/models.cpython-38.pyc
Normal file
BIN
hr_module/__pycache__/models.cpython-38.pyc
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1,3 +1,9 @@
|
|||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
|
|
||||||
# Register your models here.
|
# Register your models here.
|
||||||
|
from .models import Employee, TimeModel, Plan, TimeLog
|
||||||
|
|
||||||
|
admin.site.register(Employee)
|
||||||
|
admin.site.register(TimeModel)
|
||||||
|
admin.site.register(Plan)
|
||||||
|
admin.site.register(TimeLog)
|
||||||
|
@ -0,0 +1,19 @@
|
|||||||
|
from django import forms
|
||||||
|
from django.conf import settings
|
||||||
|
|
||||||
|
class UploadFileForm(forms.Form):
|
||||||
|
file = forms.FileField(widget=forms.ClearableFileInput(attrs={'id': 'import_filepicker'}))
|
||||||
|
|
||||||
|
|
||||||
|
class NewUserForm(forms.Form):
|
||||||
|
first_name = forms.CharField(max_length=200)
|
||||||
|
last_name = forms.CharField(max_length=200)
|
||||||
|
username = forms.CharField(max_length=200)
|
||||||
|
email = forms.EmailField(max_length=200)
|
||||||
|
is_staff = forms.BooleanField()
|
||||||
|
is_active = forms.BooleanField()
|
||||||
|
is_superuser = forms.BooleanField()
|
||||||
|
department = forms.CharField(max_length=200)
|
||||||
|
manager_username = forms.CharField(max_length=200)
|
||||||
|
time_model_id = forms.IntegerField()
|
||||||
|
manager_flag = forms.BooleanField()
|
BIN
hr_module/handling_functions/__pycache__/__init__.cpython-38.pyc
Normal file
BIN
hr_module/handling_functions/__pycache__/__init__.cpython-38.pyc
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1,9 +1,8 @@
|
|||||||
|
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
import sqlite3
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
import datetime
|
import datetime
|
||||||
|
from sqlalchemy import create_engine
|
||||||
|
|
||||||
def create_connection(db_file):
|
def create_connection(db_file):
|
||||||
""" create a database connection to the SQLite database
|
""" create a database connection to the SQLite database
|
||||||
@ -13,8 +12,10 @@ def create_connection(db_file):
|
|||||||
"""
|
"""
|
||||||
conn = None
|
conn = None
|
||||||
try:
|
try:
|
||||||
conn = sqlite3.connect(db_file)
|
path = 'sqlite:///' + str(db_file)
|
||||||
except Error as e:
|
engine = create_engine(path)
|
||||||
|
conn = engine.connect()
|
||||||
|
except Exception as e:
|
||||||
print(e)
|
print(e)
|
||||||
return conn
|
return conn
|
||||||
|
|
||||||
@ -28,36 +29,8 @@ def read_and_parse_excel(file):
|
|||||||
return {'df_html': html, 'df_path': path_temp}
|
return {'df_html': html, 'df_path': path_temp}
|
||||||
|
|
||||||
|
|
||||||
def load_existing_users():
|
|
||||||
conn = create_connection(settings.DATABASES['default']['NAME'])
|
|
||||||
cur = conn.cursor()
|
|
||||||
cur.execute('select username from auth_user')
|
|
||||||
usernames = [user[0] for user in cur.fetchall()]
|
|
||||||
return usernames
|
|
||||||
|
|
||||||
|
|
||||||
def generate_username(first_name, last_name, usernames):
|
|
||||||
username = first_name + last_name[:1]
|
|
||||||
i = 1
|
|
||||||
while username + str(i) in usernames:
|
|
||||||
i += 1
|
|
||||||
|
|
||||||
username = username + str(i)
|
|
||||||
return username.lower()
|
|
||||||
|
|
||||||
|
|
||||||
def insert_excel(df):
|
def insert_excel(df):
|
||||||
conn = create_connection(settings.DATABASES['default']['NAME'])
|
conn = create_connection(settings.DATABASES['default']['NAME'])
|
||||||
|
|
||||||
usernames = load_existing_users()
|
|
||||||
print(usernames)
|
|
||||||
for i in range(len(df)):
|
|
||||||
row = df.iloc[i]
|
|
||||||
username = generate_username(row['first_name'], row['last_name'], usernames)
|
|
||||||
df.at[i, 'username'] = username
|
|
||||||
usernames.append(username)
|
|
||||||
|
|
||||||
|
|
||||||
df['date_joined'] = datetime.date.today()
|
df['date_joined'] = datetime.date.today()
|
||||||
df['password'] = 'start'
|
df['password'] = 'start'
|
||||||
|
|
||||||
|
@ -0,0 +1,46 @@
|
|||||||
|
|
||||||
|
from sqlalchemy.orm import sessionmaker
|
||||||
|
from sqlalchemy import create_engine
|
||||||
|
from django.conf import settings
|
||||||
|
from ..models import Employee, TimeModel, 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 main(user, start_date, end_date, start_time, 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')
|
||||||
|
|
||||||
|
username = Employee.objects.get(username=user)
|
||||||
|
|
||||||
|
daily_hours = int(timemodel.daily_hours * 60)
|
||||||
|
time_end = 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
|
||||||
|
for day in range(days):
|
||||||
|
date_to_add = start_date + datetime.timedelta(days=day)
|
||||||
|
if timemodel_pattern[date_to_add.weekday()]:
|
||||||
|
print(start_time, time_end)
|
||||||
|
plan = Plan(username=username,
|
||||||
|
date=date_to_add,
|
||||||
|
begin_time=start_time,
|
||||||
|
end_time=time_end,
|
||||||
|
activity_type=activity_type)
|
||||||
|
plan.save()
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,47 @@
|
|||||||
|
from sqlalchemy.ext.declarative import declarative_base
|
||||||
|
from sqlalchemy import Column, Integer, String, Boolean, Date, Numeric, Time
|
||||||
|
|
||||||
|
|
||||||
|
Base = declarative_base()
|
||||||
|
|
||||||
|
class Employee(Base):
|
||||||
|
__tablename__ = 'hr_module_employee'
|
||||||
|
|
||||||
|
username = Column(String, primary_key=True)
|
||||||
|
department = Column(String)
|
||||||
|
manager_username = Column(String)
|
||||||
|
time_model_id = Column(Integer)
|
||||||
|
manager_flag = Column(Boolean)
|
||||||
|
|
||||||
|
class TimeModel(Base):
|
||||||
|
__tablename__ = 'hr_module_timemodel'
|
||||||
|
|
||||||
|
time_model_id = Column(Integer, primary_key=True)
|
||||||
|
daily_hours = Column(Numeric)
|
||||||
|
weekly_days = Column(Integer)
|
||||||
|
mon = Column(Boolean)
|
||||||
|
tue = Column(Boolean)
|
||||||
|
wed = Column(Boolean)
|
||||||
|
thu = Column(Boolean)
|
||||||
|
fri = Column(Boolean)
|
||||||
|
sat = Column(Boolean)
|
||||||
|
sun = Column(Boolean)
|
||||||
|
|
||||||
|
class Plan(Base):
|
||||||
|
__tablename__ = 'hr_module_plan'
|
||||||
|
username = Column(String, primary_key=True)
|
||||||
|
date = Column(Date)
|
||||||
|
begin_time = Column(Time)
|
||||||
|
end_time = Column(Time)
|
||||||
|
activity_type = Column(String)
|
||||||
|
|
||||||
|
class TimeLog(Base):
|
||||||
|
__tablename__ = 'hr_module_timelog'
|
||||||
|
username = Column(String, primary_key=True)
|
||||||
|
date = Column(Date)
|
||||||
|
begin_time = Column(Time)
|
||||||
|
end_time = Column(Time)
|
||||||
|
activity_type = Column(String)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,17 +1,50 @@
|
|||||||
from django.db import models
|
from django.db import models
|
||||||
|
from django.contrib.auth.models import User
|
||||||
|
|
||||||
|
ACTIVITY_TYPES = [('work', 'Work'),
|
||||||
|
('vacation', 'Vacation'),
|
||||||
|
('sickness', 'Sickness'),
|
||||||
|
('parental_leave', 'Parental leave'),
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
# Create your models here.
|
# Create your models here.
|
||||||
class Employee(models.Model):
|
class Employee(models.Model):
|
||||||
person_id = models.IntegerField(blank=False,
|
username = models.OneToOneField(User, on_delete=models.CASCADE,
|
||||||
null=False,
|
to_field='username',
|
||||||
unique=True)
|
db_column="username",
|
||||||
first_name = models.CharField(max_length=200,
|
primary_key=True)
|
||||||
null=False,
|
|
||||||
blank=False)
|
|
||||||
last_name = models.CharField(max_length=200,
|
|
||||||
null=False,
|
|
||||||
blank=False)
|
|
||||||
department = models.CharField(max_length=200,
|
department = models.CharField(max_length=200,
|
||||||
null=False,
|
null=False,
|
||||||
blank=False)
|
blank=False)
|
||||||
manager_id = models.IntegerField()
|
manager_username = models.CharField(max_length=200)
|
||||||
|
time_model = models.ForeignKey('TimeModel', on_delete=models.PROTECT)
|
||||||
|
manager_flag = models.BooleanField()
|
||||||
|
|
||||||
|
|
||||||
|
class TimeModel(models.Model):
|
||||||
|
time_model_id = models.IntegerField(primary_key=True)
|
||||||
|
daily_hours = models.DecimalField(max_digits=4, decimal_places=2)
|
||||||
|
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()
|
||||||
|
|
||||||
|
class Plan(models.Model):
|
||||||
|
username = models.ForeignKey(Employee, on_delete=models.PROTECT)
|
||||||
|
date = models.DateField()
|
||||||
|
begin_time = models.TimeField()
|
||||||
|
end_time = models.TimeField()
|
||||||
|
activity_type = models.CharField(max_length=100)
|
||||||
|
|
||||||
|
|
||||||
|
class TimeLog(models.Model):
|
||||||
|
username = models.ForeignKey(Employee, on_delete=models.PROTECT)
|
||||||
|
date = models.DateField()
|
||||||
|
begin_time = models.TimeField()
|
||||||
|
end_time = models.TimeField()
|
||||||
|
activity_type = models.CharField(max_length=100)
|
||||||
|
@ -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 {
|
||||||
|
|
||||||
|
}
|
@ -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;
|
||||||
|
}
|
||||||
|
|
95
hr_module/static/css/hr_module_import.css
vendored
95
hr_module/static/css/hr_module_import.css
vendored
@ -0,0 +1,95 @@
|
|||||||
|
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -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;
|
||||||
|
}
|
@ -0,0 +1,244 @@
|
|||||||
|
const csrftoken = getCookie('csrftoken');
|
||||||
|
|
||||||
|
var searchInput = document.getElementById('searched_string');
|
||||||
|
searchInput.addEventListener("click", 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'
|
||||||
|
|
||||||
|
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) => {
|
||||||
|
console.log(data);
|
||||||
|
appendFoundFilterOptions(data);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function appendFoundFilterOptions(data){
|
||||||
|
console.log(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]['value'];
|
||||||
|
console.log(caption)
|
||||||
|
console.log(value)
|
||||||
|
|
||||||
|
innerHTML = '<option value="' + value + '">' + caption + '</option>'
|
||||||
|
|
||||||
|
var wrapper = document.createElement('div');
|
||||||
|
wrapper.innerHTML = innerHTML;
|
||||||
|
var htmlNode = wrapper.firstChild;
|
||||||
|
|
||||||
|
parent.appendChild(htmlNode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function fetchEmployees() {
|
||||||
|
var host = 'http://' + window.location.host;
|
||||||
|
var fetch_url = host + '/hr_module/loeademployees'
|
||||||
|
|
||||||
|
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) => {
|
||||||
|
console.log(data);
|
||||||
|
appendFoundEmployees(data);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function appendFoundEmployees(data){
|
||||||
|
console.log(data)
|
||||||
|
var parentTable = document.getElementById('scheduling_list');
|
||||||
|
parent.innerHTML = '';
|
||||||
|
for (var i = 0; i < data.length; i++) {
|
||||||
|
|
||||||
|
var name = data[i]['name'];
|
||||||
|
var username = data[i]['username'];
|
||||||
|
var manager_name = data[i]['manager_name'];
|
||||||
|
var daily_hours = data[i]['daily_hours'];
|
||||||
|
|
||||||
|
|
||||||
|
var newRow = parentTable.insertRow(-1)
|
||||||
|
newRow.className = 'employee_row'
|
||||||
|
newRow.id = 'employee_row_' + username
|
||||||
|
newRow.setAttribute('data-username', username)
|
||||||
|
addCell(newRow, username, 0)
|
||||||
|
addCell(newRow, name, 1)
|
||||||
|
addCell(newRow, manager_name, 2)
|
||||||
|
addCell(newRow, daily_hours, 3)
|
||||||
|
var cellDays = addCell(newRow, '', 4)
|
||||||
|
workingDays(cellDays, data[i])
|
||||||
|
|
||||||
|
addCell(newRow, addActivityType(), 5)
|
||||||
|
|
||||||
|
addCell(newRow,'<td><input type="time" class="schedule_time_input"></td>', 6)
|
||||||
|
var cellButton = addCell(newRow, addDeleteButton(username),7)
|
||||||
|
cellButton.firstChild.addEventListener('click', function(){
|
||||||
|
deleteRow(username)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function addDeleteButton(username){
|
||||||
|
var cell = document.createElement('td')
|
||||||
|
var submit = document.createElement('button')
|
||||||
|
submit.innerHTML = 'Delete'
|
||||||
|
cell.appendChild(submit)
|
||||||
|
return cell.outerHTML
|
||||||
|
}
|
||||||
|
|
||||||
|
function addActivityType(){
|
||||||
|
var cell = document.createElement('td')
|
||||||
|
var options = {'work': 'Work',
|
||||||
|
'vacation': 'Vacation',
|
||||||
|
'sickness': 'Sickness',
|
||||||
|
'parental_leave': 'Parental leave'}
|
||||||
|
var select = document.createElement('select')
|
||||||
|
select.id = 'activity_type'
|
||||||
|
|
||||||
|
for (const [key, value] of Object.entries(options)) {
|
||||||
|
var option = document.createElement('option');
|
||||||
|
option.value = key;
|
||||||
|
option.text = value;
|
||||||
|
select.appendChild(option)
|
||||||
|
}
|
||||||
|
|
||||||
|
cell.appendChild(select)
|
||||||
|
return cell.outerHTML
|
||||||
|
}
|
||||||
|
|
||||||
|
function addCell(row, innerhtml, index){
|
||||||
|
var cell = row.insertCell(index);
|
||||||
|
cell.innerHTML = innerhtml;
|
||||||
|
return cell
|
||||||
|
}
|
||||||
|
|
||||||
|
function workingDays(parent, data){
|
||||||
|
var days = ['mon',
|
||||||
|
'tue',
|
||||||
|
'wed',
|
||||||
|
'thu',
|
||||||
|
'fri',
|
||||||
|
'sat',
|
||||||
|
'sun',]
|
||||||
|
days.forEach(function (item) {
|
||||||
|
if (data[item] === true) {
|
||||||
|
var tag = '<label for="' + item + '">'+ item + '</label><input class="working_days" type="checkbox" id="' + item + '" value="' + item + '" checked>'
|
||||||
|
|
||||||
|
} else {
|
||||||
|
var tag = '<label for="' + item + '">'+ item + '</label><input class="working_days" type="checkbox" id="' + item + '" value="' + item + '" >'
|
||||||
|
}
|
||||||
|
var wrapper = document.createElement('div');
|
||||||
|
wrapper.className = 'day_of_week_checkbox'
|
||||||
|
wrapper.innerHTML = tag;
|
||||||
|
parent.appendChild(wrapper)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function deleteRow(username){
|
||||||
|
var row = document.getElementById('employee_row_' + username)
|
||||||
|
row.outerHTML = ''
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildPlanJson(){
|
||||||
|
var listJsons = []
|
||||||
|
var employees = document.getElementsByClassName('employee_row')
|
||||||
|
var lowerBoundary = document.getElementById('planning_lower_boundary').value
|
||||||
|
var upperBoundary = document.getElementById('planning_upper_boundary').value
|
||||||
|
for (var i = 0; i < employees.length; i++) {
|
||||||
|
var planJson = {}
|
||||||
|
row = employees[0]
|
||||||
|
var username = row.getAttribute('data-username')
|
||||||
|
var startTime = row.getElementsByClassName('schedule_time_input')[0].value
|
||||||
|
var days = row.getElementsByClassName('working_days')
|
||||||
|
var daysOfWeek = {}
|
||||||
|
for (var k = 0; k < days.length; k++){
|
||||||
|
day = days[k]
|
||||||
|
daysOfWeek[day.value] = day.checked
|
||||||
|
}
|
||||||
|
planJson['username'] = username
|
||||||
|
planJson['start_time'] = startTime
|
||||||
|
planJson['timemodel_pattern'] = daysOfWeek
|
||||||
|
planJson['date_start'] = lowerBoundary
|
||||||
|
planJson['date_end'] = upperBoundary
|
||||||
|
listJsons.push(planJson)
|
||||||
|
}
|
||||||
|
return listJsons
|
||||||
|
}
|
||||||
|
|
||||||
|
function postPlanToDb(){
|
||||||
|
var host = 'http://' + window.location.host;
|
||||||
|
var fetch_url = host + '/hr_module/plan_api'
|
||||||
|
var json = buildPlanJson()
|
||||||
|
|
||||||
|
fetch(fetch_url,
|
||||||
|
{
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'X-CSRFToken': csrftoken
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
json
|
||||||
|
}),
|
||||||
|
}).then((response) => {
|
||||||
|
return true;
|
||||||
|
}).then((data) => {
|
||||||
|
console.log(data);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
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,10 +1,17 @@
|
|||||||
<!DOCTYPE html>
|
{% extends 'hr_module_base.html' %}
|
||||||
<html lang="en">
|
|
||||||
<head>
|
{% load static %}
|
||||||
<meta charset="UTF-8">
|
|
||||||
<title>$Title$</title>
|
{% block action_panel %}
|
||||||
</head>
|
<link rel="stylesheet" href="{% static '/css/hr_import_validation.css' %}">
|
||||||
<body>
|
<div class="import_instructions">The following data will be imported:
|
||||||
$END$
|
</div>
|
||||||
</body>
|
<div class="import_table">
|
||||||
</html>
|
{{ df_html|safe }}
|
||||||
|
</div>
|
||||||
|
<form method="post" enctype="multipart/form-data" >
|
||||||
|
{% csrf_token %}
|
||||||
|
<input type="submit" value="Confirm import" name="import_insert">
|
||||||
|
</form>
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
|
@ -1,10 +1,32 @@
|
|||||||
<!DOCTYPE html>
|
{% extends 'base.html' %}
|
||||||
<html lang="en">
|
{% load static %}
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
{% block stylesheet_hr_module_base %}
|
||||||
<title>$Title$</title>
|
<link rel="stylesheet" href="{% static '/css/hr_module_base.css' %}">
|
||||||
</head>
|
{% endblock %}
|
||||||
<body>
|
|
||||||
$END$
|
|
||||||
</body>
|
|
||||||
</html>
|
{% block core_content %}
|
||||||
|
|
||||||
|
<div class="sidebar">
|
||||||
|
<div class="sidebar_item">Create schedule
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="sidebar_item">Manage Employees
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="sidebar_item">Import Data
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="sidebar_item">Export Data
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="hr_module_main_container">
|
||||||
|
{% block action_panel %}
|
||||||
|
{% endblock %}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% endblock %}
|
@ -1,10 +1,94 @@
|
|||||||
<!DOCTYPE html>
|
{% extends 'hr_module_base.html' %}
|
||||||
<html lang="en">
|
|
||||||
<head>
|
{% load static %}
|
||||||
<meta charset="UTF-8">
|
|
||||||
<title>$Title$</title>
|
{% block action_panel %}
|
||||||
</head>
|
<link rel="stylesheet" href="{% static '/css/hr_module_import.css' %}">
|
||||||
<body>
|
<div class="import_container">
|
||||||
$END$
|
<div class="import_text">
|
||||||
</body>
|
Add employee manually
|
||||||
</html>
|
</div>
|
||||||
|
<form method="post">
|
||||||
|
|
||||||
|
<div class="form_element">
|
||||||
|
<label for="{{ userform.first_name.id_for_label }}">First Name:</label>
|
||||||
|
{{ userform.first_name }}
|
||||||
|
</div>
|
||||||
|
<div class="form_element">
|
||||||
|
<label for="{{ userform.last_name.id_for_label }}">Last Name:</label>
|
||||||
|
{{ userform.last_name }}
|
||||||
|
</div>
|
||||||
|
<div class="form_element">
|
||||||
|
<label for="{{ userform.username.id_for_label }}">Username:</label>
|
||||||
|
{{ userform.username }}
|
||||||
|
</div>
|
||||||
|
<div class="form_element">
|
||||||
|
<label for="{{ userform.email.id_for_label }}">Email:</label>
|
||||||
|
{{ userform.email }}
|
||||||
|
</div>
|
||||||
|
<div class="form_element">
|
||||||
|
<label for="{{ userform.is_staff.id_for_label }}">Is Staff:</label>
|
||||||
|
{{ userform.is_staff }}
|
||||||
|
</div>
|
||||||
|
<div class="form_element">
|
||||||
|
<label for="{{ userform.is_active.id_for_label }}">Is Active:</label>
|
||||||
|
{{ userform.is_active }}
|
||||||
|
</div>
|
||||||
|
<div class="form_element">
|
||||||
|
<label for="{{ userform.is_superuser.id_for_label }}">Is Superser:</label>
|
||||||
|
{{ userform.is_superuser }}
|
||||||
|
</div>
|
||||||
|
<div class="form_element">
|
||||||
|
<label for="{{ userform.manager_flag.id_for_label }}">Is Manager:</label>
|
||||||
|
{{ userform.manager_flag }}
|
||||||
|
</div>
|
||||||
|
<div class="form_element">
|
||||||
|
<label for="{{ userform.department.id_for_label }}">Department:</label>
|
||||||
|
{{ userform.department }}
|
||||||
|
</div>
|
||||||
|
<div class="form_element">
|
||||||
|
<label for="{{ userform.manager_username.id_for_label }}">Manager's username:</label>
|
||||||
|
{{ userform.manager_username }}
|
||||||
|
</div>
|
||||||
|
<div class="form_element">
|
||||||
|
<label for="{{ userform.time_model_id.id_for_label }}">Time model id:</label>
|
||||||
|
{{ userform.time_model_id }}
|
||||||
|
</div>
|
||||||
|
{% csrf_token %}
|
||||||
|
<input class="import_execute" type="submit" value="Submit" name="import_single">
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="separator">
|
||||||
|
<div class="separatorline"></div>
|
||||||
|
<div class="wordwrapper">
|
||||||
|
<div class="word">or</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="import_container">
|
||||||
|
<div class="import_text">
|
||||||
|
Import employees from Excel file
|
||||||
|
</div>
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<th>Column name</th>
|
||||||
|
<th>Data type</th>
|
||||||
|
</tr>
|
||||||
|
{% for item in columns %}
|
||||||
|
<tr>
|
||||||
|
<td>{{ item }}</td>
|
||||||
|
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</table>
|
||||||
|
<form method="post" enctype="multipart/form-data" >
|
||||||
|
{% csrf_token %}
|
||||||
|
<div class="import_input">
|
||||||
|
{{ fileform.file }}
|
||||||
|
</div>
|
||||||
|
<input class="import_execute" type="submit" value="Preview" name="import_preview">
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
|
@ -1,10 +1,57 @@
|
|||||||
<!DOCTYPE html>
|
{% extends 'hr_module_base.html' %}
|
||||||
<html lang="en">
|
|
||||||
<head>
|
{% load static %}
|
||||||
<meta charset="UTF-8">
|
|
||||||
<title>$Title$</title>
|
{% block action_panel %}
|
||||||
</head>
|
<link rel="stylesheet" href="{% static '/css/hr_module_schedule.css' %}">
|
||||||
<body>
|
|
||||||
$END$
|
<div class="scheduleSearchRow">
|
||||||
</body>
|
<div class="search_element">Select filter type:
|
||||||
</html>
|
<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 list="schedule_filter_search" id="searched_string">
|
||||||
|
<datalist id="schedule_filter_search">
|
||||||
|
</datalist>
|
||||||
|
</div>
|
||||||
|
<div class="search_element">
|
||||||
|
<button type="button" id="load_employees">Search</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<table style="width:100%" id="scheduling_list">
|
||||||
|
<tr>
|
||||||
|
<th>Username</th>
|
||||||
|
<th>Name</th>
|
||||||
|
<th>Name of the Manager</th>
|
||||||
|
<th>Daily working hours</th>
|
||||||
|
<th>Default schedule</th>
|
||||||
|
<th>Activity type</th>
|
||||||
|
<th>Start time</th>
|
||||||
|
<th></th>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<div class="date_select_row">
|
||||||
|
<div class="search_element">
|
||||||
|
<input type="date" id="planning_lower_boundary">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="search_element">
|
||||||
|
<input type="date" id="planning_upper_boundary">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="search_element">
|
||||||
|
<button type="button" id="run_planning">Create plan</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script src="{% static '/js/hr_module_schedule.js' %}"></script>
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
|
@ -2,6 +2,13 @@
|
|||||||
from django.urls import path
|
from django.urls import path
|
||||||
from . import views
|
from . import views
|
||||||
|
|
||||||
|
app_name = 'hr_module'
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path('', views.index, name='index'),
|
path('', views.index, name='index'),
|
||||||
|
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'),
|
||||||
|
|
||||||
]
|
]
|
@ -1,6 +1,147 @@
|
|||||||
from django.shortcuts import render
|
from django.shortcuts import render, redirect
|
||||||
from django.http import HttpResponse
|
from .forms import UploadFileForm, NewUserForm
|
||||||
|
from hr_module.handling_functions.data_import_functions import read_and_parse_excel, insert_excel
|
||||||
|
import pandas as pd
|
||||||
|
import json
|
||||||
|
from .models import Employee
|
||||||
|
from django.core import serializers
|
||||||
|
from django.http import HttpResponse, JsonResponse, Http404
|
||||||
|
from django.db import connection
|
||||||
|
|
||||||
# Create your views here.
|
# Create your views here.
|
||||||
def index(request):
|
def index(request):
|
||||||
return HttpResponse("Hello, world. You're at the app index.")
|
template_name = 'hr_module_schedule.html'
|
||||||
|
|
||||||
|
return render(request, template_name)
|
||||||
|
|
||||||
|
|
||||||
|
def hr_import(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)
|
||||||
|
|
||||||
|
request.session['df_path'] = df_dict['df_path']
|
||||||
|
df_html = df_dict['df_html']
|
||||||
|
context = {'df_html': df_html}
|
||||||
|
template = 'hr_import_validation.html'
|
||||||
|
return render(request, template, context)
|
||||||
|
|
||||||
|
if 'import_insert' in request.POST:
|
||||||
|
df = pd.read_csv(request.session['df_path'])
|
||||||
|
insert_excel(df)
|
||||||
|
del request.session['df_path']
|
||||||
|
return redirect('import_data')
|
||||||
|
|
||||||
|
|
||||||
|
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'):
|
||||||
|
df_dict.pop(i, None)
|
||||||
|
df = pd.DataFrame(df_dict, index=[0])
|
||||||
|
insert_excel(df)
|
||||||
|
print('done')
|
||||||
|
return redirect('import_data')
|
||||||
|
|
||||||
|
else:
|
||||||
|
columns_user = ['first_name',
|
||||||
|
'last_name',
|
||||||
|
'username',
|
||||||
|
'email',
|
||||||
|
'is_staff',
|
||||||
|
'is_active',
|
||||||
|
'is_superuser']
|
||||||
|
columns_empl = ['department',
|
||||||
|
'manager_username',
|
||||||
|
'time_model_id',
|
||||||
|
'manager_flag']
|
||||||
|
columns = columns_user + columns_empl
|
||||||
|
|
||||||
|
fileform = UploadFileForm()
|
||||||
|
userform = NewUserForm()
|
||||||
|
context = {'userform': userform,
|
||||||
|
'columns': columns,
|
||||||
|
'fileform': fileform
|
||||||
|
}
|
||||||
|
template = 'hr_module_import.html'
|
||||||
|
return render(request, template, context)
|
||||||
|
|
||||||
|
|
||||||
|
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()
|
||||||
|
]
|
||||||
|
|
||||||
|
def search_users_api(request):
|
||||||
|
if request.method == 'POST':
|
||||||
|
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':
|
||||||
|
cursor.execute('select department as caption, department as 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 '
|
||||||
|
'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 '
|
||||||
|
'inner join auth_user auth on empl.username = auth.username ', [' ',]
|
||||||
|
)
|
||||||
|
|
||||||
|
response = dictfetchall(cursor)
|
||||||
|
print(response)
|
||||||
|
return JsonResponse(response, safe=False)
|
||||||
|
|
||||||
|
|
||||||
|
def load_employees_api(request):
|
||||||
|
if request.method == 'POST':
|
||||||
|
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':
|
||||||
|
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 '
|
||||||
|
'from hr_module_employee empl inner join auth_user auth on auth.username = empl.manager_username '
|
||||||
|
'inner join hr_module_timemodel tm on empl.time_model_id = tm.time_model_id '
|
||||||
|
'where department = %s', [' ', searched_string])
|
||||||
|
elif searched_field == 'manager':
|
||||||
|
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 '
|
||||||
|
'from hr_module_employee empl inner join auth_user auth on auth.username = empl.manager_username '
|
||||||
|
'inner join hr_module_timemodel tm on empl.time_model_id = tm.time_model_id '
|
||||||
|
'where manager_username = %s', [' ', searched_string])
|
||||||
|
|
||||||
|
elif searched_field == 'username':
|
||||||
|
cursor.execute('select auth.first_name || %s || auth.last_name as name, auth.username as username, '
|
||||||
|
'empl.manager_username as manager_name, tm.daily_hours, '
|
||||||
|
'tm.mon, tm.tue, tm.wed, tm.thu, tm.fri, tm.sat, tm.sun '
|
||||||
|
'from hr_module_employee empl inner join auth_user auth on auth.username = empl.manager_username '
|
||||||
|
'inner join hr_module_timemodel tm on empl.time_model_id = tm.time_model_id '
|
||||||
|
'where auth.username = %s ', [' ', searched_string])
|
||||||
|
|
||||||
|
response = dictfetchall(cursor)
|
||||||
|
print(response)
|
||||||
|
return JsonResponse(response, safe=False)
|
||||||
|
|
||||||
|
|
||||||
|
def plan_api(request):
|
||||||
|
|
||||||
|
print(json.loads(request.body))
|
@ -1,8 +1,16 @@
|
|||||||
|
|
||||||
|
html, body {
|
||||||
.top-bar {
|
width: 100%;
|
||||||
height: 150;
|
height: 100%;
|
||||||
background: #C0C0C0;
|
font-family: sans-serif;
|
||||||
margin-left: auto;
|
}
|
||||||
margin-right: auto;
|
.navbar {
|
||||||
|
height: 50px;
|
||||||
|
background-color: #D3D3D3;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.main_container {
|
||||||
|
background-color: whitesmoke;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
}
|
}
|
@ -1,23 +1,6 @@
|
|||||||
,first_name,last_name,email,is_staff,is_active,is_superuser,department,manager_username,time_model_id,manager_flag
|
,first_name,last_name,username,email,is_staff,is_active,is_superuser,department,manager_username,time_model_id,manager_flag
|
||||||
0,test,test2,testtest2@fff.com,False,True,False,test department,93099,10,0
|
0,Jan,Kowalski,kowalskija,kowalskija@company.com,0,1,0,test department,hitlerad,1,0
|
||||||
1,test,sf,testsf@fff.com,False,True,False,test department,123555,5,0
|
1,Janina,Kowalska,kowalskaja,kowalskaja@company.com,0,1,0,test department,hitlerad,2,0
|
||||||
2,test,fsdc,testfsdc@fff.com,False,True,False,dfdfdv,58347,14,0
|
2,Tadeusz,Tadeuszowicz,tadeuszowiczta,tadeuszowiczta@company.com,0,1,0,dfdfdv,hitlerad,3,0
|
||||||
3,test,sdvcds,testsdvcds@fff.com,False,True,False,fsdfgfg,21411,11,0
|
3,Aleksander,Lukaszenko,lukaszenkoal,lukaszenkoal@company.com,0,1,0,fsdfgfg,hitlerad,4,0
|
||||||
4,test,vsd,testvsd@fff.com,False,True,False,fg,100670,14,0
|
4,Adolf,Hitler,hitlerad,hitlerad@company.com,0,1,0,fg,hitlerad,5,0
|
||||||
5,gf,ddsf,gfddsf@fff.com,False,True,False,fsdfgfg,56776,1,1
|
|
||||||
6,fg,bg,fgbg@fff.com,False,True,False,fg,1012,7,1
|
|
||||||
7,gf,gb,gfgb@fff.com,False,True,False,fsdfgfg,24615,6,1
|
|
||||||
8,fg,gb,fggb@fff.com,False,True,False,dfgdfgffgs,131029,10,1
|
|
||||||
9,fg,gf,fggf@fff.com,False,True,False,fsdfgfg,150186,6,1
|
|
||||||
10,gf,bfg,gfbfg@fff.com,False,True,False,sfgdfsgdfg,127720,7,0
|
|
||||||
11,dfg,bvdf,dfgbvdf@fff.com,False,True,False,test department,21584,13,1
|
|
||||||
12,fg,test2,fgtest2@fff.com,False,True,False,test department,106721,6,0
|
|
||||||
13,first_name,bfg,first_namebfg@fff.com,False,True,False,test department,151398,10,0
|
|
||||||
14,dfg,test2,dfgtest2@fff.com,False,True,False,test department,18196,1,0
|
|
||||||
15,gf,gbb,gfgbb@fff.com,False,True,False,fsdfgfg,23266,11,0
|
|
||||||
16,dfg,fd,dfgfd@fff.com,False,True,False,fsdfgfg,109517,15,0
|
|
||||||
17,gf,bsdgbdf,gfbsdgbdf@fff.com,False,True,False,fsdfgfg,56302,13,1
|
|
||||||
18,gf,fd,gffd@fff.com,False,True,False,fsdfgfg,149169,11,1
|
|
||||||
19,dfg,gdf,dfggdf@fff.com,False,True,False,fsdfgfg,83458,3,0
|
|
||||||
20,dfg,gb,dfggb@fff.com,False,True,False,fsdfgfg,12670,6,0
|
|
||||||
21,test,test2,testtest2@fff.com,False,True,False,test department,49135,3,1
|
|
||||||
|
|
@ -1,10 +1,24 @@
|
|||||||
|
{% load static %}
|
||||||
|
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<title>$Title$</title>
|
<title>Title</title>
|
||||||
|
<link rel="stylesheet" href="{% static '/css/base.css' %}">
|
||||||
|
{% block stylesheet_hr_module_base %}
|
||||||
|
{% endblock %}
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
$END$
|
|
||||||
|
<div class="navbar">
|
||||||
|
</div>
|
||||||
|
<div class="main_container">
|
||||||
|
|
||||||
|
{% block core_content %}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
Binary file not shown.
@ -11,6 +11,7 @@ https://docs.djangoproject.com/en/3.1/ref/settings/
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
import os
|
||||||
|
|
||||||
# Build paths inside the project like this: BASE_DIR / 'subdir'.
|
# Build paths inside the project like this: BASE_DIR / 'subdir'.
|
||||||
BASE_DIR = Path(__file__).resolve().parent.parent
|
BASE_DIR = Path(__file__).resolve().parent.parent
|
||||||
@ -25,12 +26,14 @@ SECRET_KEY = 'tx#+u3u-r1$n_4r(!6vvcb@1f5!z21^74w(zesiz$&59&72$kq'
|
|||||||
# SECURITY WARNING: don't run with debug turned on in production!
|
# SECURITY WARNING: don't run with debug turned on in production!
|
||||||
DEBUG = True
|
DEBUG = True
|
||||||
|
|
||||||
ALLOWED_HOSTS = []
|
ALLOWED_HOSTS = ['192.168.101.128',
|
||||||
|
'127.0.0.1',]
|
||||||
|
|
||||||
|
|
||||||
# Application definition
|
# Application definition
|
||||||
|
|
||||||
INSTALLED_APPS = [
|
INSTALLED_APPS = [
|
||||||
|
'hr_module.apps.HrModuleConfig',
|
||||||
'django.contrib.admin',
|
'django.contrib.admin',
|
||||||
'django.contrib.auth',
|
'django.contrib.auth',
|
||||||
'django.contrib.contenttypes',
|
'django.contrib.contenttypes',
|
||||||
@ -54,7 +57,8 @@ ROOT_URLCONF = 'timefall.urls'
|
|||||||
TEMPLATES = [
|
TEMPLATES = [
|
||||||
{
|
{
|
||||||
'BACKEND': 'django.template.backends.django.DjangoTemplates',
|
'BACKEND': 'django.template.backends.django.DjangoTemplates',
|
||||||
'DIRS': [BASE_DIR / 'templates']
|
'DIRS': [BASE_DIR / 'templates',
|
||||||
|
BASE_DIR / 'hr_module/templates']
|
||||||
,
|
,
|
||||||
'APP_DIRS': True,
|
'APP_DIRS': True,
|
||||||
'OPTIONS': {
|
'OPTIONS': {
|
||||||
@ -78,6 +82,7 @@ DATABASES = {
|
|||||||
'default': {
|
'default': {
|
||||||
'ENGINE': 'django.db.backends.sqlite3',
|
'ENGINE': 'django.db.backends.sqlite3',
|
||||||
'NAME': BASE_DIR / 'db.sqlite3',
|
'NAME': BASE_DIR / 'db.sqlite3',
|
||||||
|
'STRING': 'sqlite:///' + str(BASE_DIR / 'db.sqlite3')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -119,3 +124,11 @@ USE_TZ = True
|
|||||||
# https://docs.djangoproject.com/en/3.1/howto/static-files/
|
# https://docs.djangoproject.com/en/3.1/howto/static-files/
|
||||||
|
|
||||||
STATIC_URL = '/static/'
|
STATIC_URL = '/static/'
|
||||||
|
|
||||||
|
STATICFILES_DIRS = [
|
||||||
|
os.path.join(BASE_DIR, 'static'),
|
||||||
|
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
TMP_FILE_STORAGE = os.path.join(BASE_DIR, 'temp/')
|
Loading…
Reference in New Issue
Block a user