more ajax

This commit is contained in:
s457957 2020-12-20 23:10:49 +01:00
parent 8da99758f2
commit 2c516b24e8
35 changed files with 1000 additions and 119 deletions

View File

@ -22,6 +22,7 @@
<option name="TEMPLATE_FOLDERS">
<list>
<option value="$MODULE_DIR$/templates" />
<option value="$MODULE_DIR$/hr_module/templates" />
</list>
</option>
</component>

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

@ -1,3 +1,9 @@
from django.contrib import admin
# 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)

View File

@ -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()

View File

@ -1,9 +1,8 @@
import pandas as pd
import sqlite3
from django.conf import settings
import datetime
from sqlalchemy import create_engine
def create_connection(db_file):
""" create a database connection to the SQLite database
@ -13,8 +12,10 @@ def create_connection(db_file):
"""
conn = None
try:
conn = sqlite3.connect(db_file)
except Error as e:
path = 'sqlite:///' + str(db_file)
engine = create_engine(path)
conn = engine.connect()
except Exception as e:
print(e)
return conn
@ -28,36 +29,8 @@ def read_and_parse_excel(file):
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):
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['password'] = 'start'

View File

@ -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()

View File

@ -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)

View File

@ -1,17 +1,50 @@
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.
class Employee(models.Model):
person_id = models.IntegerField(blank=False,
null=False,
unique=True)
first_name = models.CharField(max_length=200,
null=False,
blank=False)
last_name = models.CharField(max_length=200,
null=False,
blank=False)
username = models.OneToOneField(User, on_delete=models.CASCADE,
to_field='username',
db_column="username",
primary_key=True)
department = models.CharField(max_length=200,
null=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)

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,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;
}

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,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;
}

View File

@ -1,10 +1,17 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>$Title$</title>
</head>
<body>
$END$
</body>
</html>
{% extends 'hr_module_base.html' %}
{% load static %}
{% block action_panel %}
<link rel="stylesheet" href="{% static '/css/hr_import_validation.css' %}">
<div class="import_instructions">The following data will be imported:
</div>
<div class="import_table">
{{ df_html|safe }}
</div>
<form method="post" enctype="multipart/form-data" >
{% csrf_token %}
<input type="submit" value="Confirm import" name="import_insert">
</form>
{% endblock %}

View File

@ -1,10 +1,32 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>$Title$</title>
</head>
<body>
$END$
</body>
</html>
{% extends 'base.html' %}
{% load static %}
{% block stylesheet_hr_module_base %}
<link rel="stylesheet" href="{% static '/css/hr_module_base.css' %}">
{% endblock %}
{% 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 %}

View File

@ -1,10 +1,94 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>$Title$</title>
</head>
<body>
$END$
</body>
</html>
{% extends 'hr_module_base.html' %}
{% load static %}
{% block action_panel %}
<link rel="stylesheet" href="{% static '/css/hr_module_import.css' %}">
<div class="import_container">
<div class="import_text">
Add employee manually
</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 %}

View File

@ -1,10 +1,57 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>$Title$</title>
</head>
<body>
$END$
</body>
</html>
{% extends 'hr_module_base.html' %}
{% load static %}
{% block action_panel %}
<link rel="stylesheet" href="{% static '/css/hr_module_schedule.css' %}">
<div class="scheduleSearchRow">
<div class="search_element">Select filter type:
<select name="category" id="schedule_filter_category">
<option value="username">Person</option>
<option value="manager">Manager</option>
<option value="department">Department</option>
</select>
</div>
<div class="search_element">
<input 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 %}

View File

@ -2,6 +2,13 @@
from django.urls import path
from . import views
app_name = 'hr_module'
urlpatterns = [
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'),
]

View File

@ -1,6 +1,147 @@
from django.shortcuts import render
from django.http import HttpResponse
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
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.
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))

View File

@ -1,8 +1,16 @@
.top-bar {
height: 150;
background: #C0C0C0;
margin-left: auto;
margin-right: auto;
html, body {
width: 100%;
height: 100%;
font-family: sans-serif;
}
.navbar {
height: 50px;
background-color: #D3D3D3;
width: 100%;
}
.main_container {
background-color: whitesmoke;
width: 100%;
height: 100%;
}

View File

@ -1,23 +1,6 @@
,first_name,last_name,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
1,test,sf,testsf@fff.com,False,True,False,test department,123555,5,0
2,test,fsdc,testfsdc@fff.com,False,True,False,dfdfdv,58347,14,0
3,test,sdvcds,testsdvcds@fff.com,False,True,False,fsdfgfg,21411,11,0
4,test,vsd,testvsd@fff.com,False,True,False,fg,100670,14,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
,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 first_name last_name username email is_staff is_active is_superuser department manager_username time_model_id manager_flag
2 0 test Jan test2 Kowalski kowalskija testtest2@fff.com kowalskija@company.com False 0 True 1 False 0 test department 93099 hitlerad 10 1 0
3 1 test Janina sf Kowalska kowalskaja testsf@fff.com kowalskaja@company.com False 0 True 1 False 0 test department 123555 hitlerad 5 2 0
4 2 test Tadeusz fsdc Tadeuszowicz tadeuszowiczta testfsdc@fff.com tadeuszowiczta@company.com False 0 True 1 False 0 dfdfdv 58347 hitlerad 14 3 0
5 3 test Aleksander sdvcds Lukaszenko lukaszenkoal testsdvcds@fff.com lukaszenkoal@company.com False 0 True 1 False 0 fsdfgfg 21411 hitlerad 11 4 0
6 4 test Adolf vsd Hitler hitlerad testvsd@fff.com hitlerad@company.com False 0 True 1 False 0 fg 100670 hitlerad 14 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

View File

@ -1,10 +1,24 @@
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>$Title$</title>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="{% static '/css/base.css' %}">
{% block stylesheet_hr_module_base %}
{% endblock %}
</head>
<body>
$END$
<div class="navbar">
</div>
<div class="main_container">
{% block core_content %}
{% endblock %}
</div>
</body>
</html>

View File

@ -11,6 +11,7 @@ https://docs.djangoproject.com/en/3.1/ref/settings/
"""
from pathlib import Path
import os
# Build paths inside the project like this: BASE_DIR / 'subdir'.
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!
DEBUG = True
ALLOWED_HOSTS = []
ALLOWED_HOSTS = ['192.168.101.128',
'127.0.0.1',]
# Application definition
INSTALLED_APPS = [
'hr_module.apps.HrModuleConfig',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
@ -54,7 +57,8 @@ ROOT_URLCONF = 'timefall.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [BASE_DIR / 'templates']
'DIRS': [BASE_DIR / 'templates',
BASE_DIR / 'hr_module/templates']
,
'APP_DIRS': True,
'OPTIONS': {
@ -78,6 +82,7 @@ DATABASES = {
'default': {
'ENGINE': 'django.db.backends.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/
STATIC_URL = '/static/'
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'static'),
]
TMP_FILE_STORAGE = os.path.join(BASE_DIR, 'temp/')