added links
This commit is contained in:
parent
6d51486266
commit
08523f6204
BIN
db.sqlite3
BIN
db.sqlite3
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
hr_module/handling_functions/__pycache__/misc.cpython-38.pyc
Normal file
BIN
hr_module/handling_functions/__pycache__/misc.cpython-38.pyc
Normal file
Binary file not shown.
8
hr_module/handling_functions/misc.py
Normal file
8
hr_module/handling_functions/misc.py
Normal file
@ -0,0 +1,8 @@
|
||||
|
||||
def dictfetchall(cursor):
|
||||
"Return all rows from a cursor as a dict"
|
||||
columns = [col[0] for col in cursor.description]
|
||||
return [
|
||||
dict(zip(columns, row))
|
||||
for row in cursor.fetchall()
|
||||
]
|
@ -1,7 +1,4 @@
|
||||
|
||||
html, body {
|
||||
font-family: sans-serif;
|
||||
}
|
||||
|
||||
div.month_container table,
|
||||
div.month_container th,
|
||||
|
25
hr_module/static/css/hr_module_change_employee_data.css
Normal file
25
hr_module/static/css/hr_module_change_employee_data.css
Normal file
@ -0,0 +1,25 @@
|
||||
|
||||
#search_results {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
div#search_results label {
|
||||
text-transform: capitalize;
|
||||
clear: both;
|
||||
width: 200px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.field_container {
|
||||
width: 400px;
|
||||
margin-top: 10px;
|
||||
display: flex;
|
||||
height: 30px;
|
||||
border: thin;
|
||||
border-bottom: 1px solid lightgray;
|
||||
}
|
||||
|
||||
.database_field {
|
||||
text-align: center;
|
||||
}
|
||||
|
1
hr_module/static/css/hr_module_import.css
vendored
1
hr_module/static/css/hr_module_import.css
vendored
@ -25,7 +25,6 @@ table, th, td {
|
||||
}
|
||||
|
||||
|
||||
|
||||
.form_element, .import_text {
|
||||
height: 30px;
|
||||
}
|
||||
|
@ -1,21 +1,35 @@
|
||||
|
||||
input {
|
||||
border: solid thin black;
|
||||
}
|
||||
|
||||
input[readonly] {
|
||||
color: black;
|
||||
background-color: lightgray;
|
||||
}
|
||||
|
||||
table {
|
||||
table#detailed_plan_records {
|
||||
width: 100%;
|
||||
font-size: 15px;
|
||||
vertical-align:middle;
|
||||
font-weight: lighter;
|
||||
}
|
||||
|
||||
input {
|
||||
width: 100%;
|
||||
display: block;
|
||||
table#detailed_plan_records th {
|
||||
height: 25px;
|
||||
font-weight: lighter;
|
||||
padding: 0px;
|
||||
}
|
||||
|
||||
table#detailed_plan_records td {
|
||||
text-align: center;
|
||||
padding: 0px;
|
||||
}
|
||||
|
||||
tr:nth-child(even) {
|
||||
background-color: #6DDCBD;
|
||||
}
|
||||
|
||||
div#detailed_plan_records input {
|
||||
width: 97%;
|
||||
display: block;
|
||||
border: solid thin black;
|
||||
}
|
||||
|
||||
.detailed_plan_records {
|
||||
@ -24,3 +38,7 @@ input {
|
||||
border-width: thin;
|
||||
font-weight: lighter;
|
||||
}
|
||||
|
||||
.begin_time, .end_time {
|
||||
display: block;
|
||||
}
|
17
hr_module/static/js/csrf_token.js
Normal file
17
hr_module/static/js/csrf_token.js
Normal file
@ -0,0 +1,17 @@
|
||||
const csrftoken = getCookie('csrftoken');
|
||||
|
||||
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;
|
||||
}
|
61
hr_module/static/js/hr_module_change_employee_data.js
Normal file
61
hr_module/static/js/hr_module_change_employee_data.js
Normal file
@ -0,0 +1,61 @@
|
||||
|
||||
var searchEmployeeButton = document.getElementById('load_employee_data_button')
|
||||
searchEmployeeButton.addEventListener('click', function(){
|
||||
fetchSearchEmployeeData()
|
||||
})
|
||||
|
||||
function fetchSearchEmployeeData() {
|
||||
var host = 'http://' + window.location.host;
|
||||
var fetch_url = host + '/hr_module/change_employee_data_api'
|
||||
var username = document.getElementById('username_input').value
|
||||
|
||||
fetch(fetch_url,
|
||||
{
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'X-CSRFToken': csrftoken
|
||||
},
|
||||
body: JSON.stringify({
|
||||
"username": username
|
||||
}),
|
||||
}).then((response) => {
|
||||
return response.json();
|
||||
}).then((data) => {
|
||||
console.log(data);
|
||||
loadValuesIntoPage(data)
|
||||
});
|
||||
}
|
||||
|
||||
function loadValuesIntoPage(data){
|
||||
var order = ['username', 'first_name', 'last_name', 'email', 'department', 'manager_username', 'time_model_id', 'manager_flag', 'is_active', 'is_staff', 'is_superuser']
|
||||
|
||||
var informationContainer = document.getElementById('search_results')
|
||||
|
||||
for (var i = 0; i < order.length; i++){
|
||||
var field = order[i]
|
||||
var value = data[field]
|
||||
|
||||
var fieldContainer = document.createElement('div')
|
||||
fieldContainer.className = 'field_container'
|
||||
|
||||
if (typeof(value) === 'boolean'){
|
||||
var httpfield = document.createElement('input')
|
||||
httpfield.type = 'checkbox'
|
||||
httpfield.checked = value
|
||||
httpfield.setAttribute('disabled', 'disabled')
|
||||
} else {
|
||||
var httpfield = document.createElement('div')
|
||||
httpfield.innerHTML = value
|
||||
}
|
||||
var label = document.createElement('label')
|
||||
label.setAttribute('for', field)
|
||||
label.innerText = field.replace('_', ' ')
|
||||
httpfield.id = field
|
||||
httpfield.className = 'database_field'
|
||||
|
||||
fieldContainer.appendChild(label)
|
||||
fieldContainer.appendChild(httpfield)
|
||||
informationContainer.appendChild(fieldContainer)
|
||||
}
|
||||
}
|
@ -1,4 +1,3 @@
|
||||
const csrftoken = getCookie('csrftoken');
|
||||
|
||||
var searchInput = document.getElementById('searched_string');
|
||||
searchInput.addEventListener("click", fetchSearchOptions);
|
||||
@ -11,7 +10,7 @@ submitToDb.addEventListener('click', postPlanToDb);
|
||||
|
||||
function fetchSearchOptions() {
|
||||
var host = 'http://' + window.location.host;
|
||||
var fetch_url = host + '/hr_module/search'
|
||||
var fetch_url = host + '/hr_module/search_api'
|
||||
|
||||
var searched_field = document.getElementById('schedule_filter_category').value
|
||||
var searched_string = document.getElementById('searched_string').value
|
||||
@ -235,24 +234,6 @@ function postPlanToDb(){
|
||||
}
|
||||
|
||||
|
||||
|
||||
function getCookie(name) {
|
||||
let cookieValue = null;
|
||||
if (document.cookie && document.cookie !== '') {
|
||||
let cookies = document.cookie.split(';');
|
||||
for (let i = 0; i < cookies.length; i++) {
|
||||
let cookie = cookies[i].trim();
|
||||
|
||||
if (cookie.substring(0, name.length + 1) === (name + '=')) {
|
||||
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return cookieValue;
|
||||
}
|
||||
|
||||
|
||||
function showPopup(){
|
||||
document.getElementById("popup_content").addEventListener("click", function(e) {
|
||||
e.stopPropagation();
|
@ -1,4 +1,3 @@
|
||||
const csrftoken = getCookie('csrftoken');
|
||||
|
||||
var parent = document.getElementById('calendar_box')
|
||||
document.onload = parent.appendChild(addCalendar(monthsAhead=3))
|
||||
@ -86,34 +85,26 @@ function createDetailedCalendarRecords(data){
|
||||
row.setAttribute('database_username', username)
|
||||
|
||||
var cell = row.insertCell(0)
|
||||
var dateInput = document.createElement('input')
|
||||
dateInput.type = 'date'
|
||||
dateInput.readOnly = true
|
||||
dateInput.value = processedDate
|
||||
var dateInput = document.createElement('div')
|
||||
dateInput.innerText = processedDate
|
||||
dateInput.name = 'date'
|
||||
cell.appendChild(dateInput)
|
||||
|
||||
var cell = row.insertCell(1)
|
||||
var timeInput = document.createElement('input')
|
||||
timeInput.type = 'time'
|
||||
timeInput.readOnly = true
|
||||
timeInput.value = processedBeginTime
|
||||
timeInput.name = 'begin_time'
|
||||
var timeInput = document.createElement('div')
|
||||
timeInput.innerText = processedBeginTime
|
||||
timeInput.className = 'begin_time'
|
||||
cell.appendChild(timeInput)
|
||||
|
||||
var cell = row.insertCell(2)
|
||||
var timeInput = document.createElement('input')
|
||||
timeInput.type = 'time'
|
||||
timeInput.readOnly = true
|
||||
timeInput.value = processedEndTime
|
||||
timeInput.name = 'end_time'
|
||||
var timeInput = document.createElement('div')
|
||||
timeInput.innerText = processedEndTime
|
||||
timeInput.className = 'end_time'
|
||||
cell.appendChild(timeInput)
|
||||
|
||||
var cell = row.insertCell(3)
|
||||
var textInput = document.createElement('input')
|
||||
textInput.type = 'text'
|
||||
textInput.readOnly = true
|
||||
textInput.value = processedActivityType
|
||||
var textInput = document.createElement('div')
|
||||
textInput.innerText = processedActivityType
|
||||
textInput.name = 'activity_type'
|
||||
cell.appendChild(textInput)
|
||||
|
||||
@ -144,10 +135,18 @@ function unlockRecordsForEditing(event){
|
||||
var databaseId = event.target.value
|
||||
var parent = event.target.parentElement
|
||||
var row = document.getElementById('database_id_' + databaseId.toString())
|
||||
var children = row.getElementsByTagName('input')
|
||||
var children = row.getElementsByTagName('div')
|
||||
for (var i = 0; i < children.length; i++){
|
||||
if (children[i].getAttribute('type') == 'time') {
|
||||
children[i].readOnly = false;
|
||||
console.log(children[i].className )
|
||||
if (['begin_time', 'end_time'].includes(children[i].className)) {
|
||||
var value = children[i].innerText
|
||||
var name = children[i].className
|
||||
var input = document.createElement('input')
|
||||
input.name = name
|
||||
input.value = value
|
||||
input.type = 'time'
|
||||
children[i].innerHTML = ''
|
||||
children[i].appendChild(input)
|
||||
}
|
||||
}
|
||||
|
||||
@ -229,6 +228,8 @@ function unhideCheckboxes(databaseId){
|
||||
checkboxes[i].firstChild.checked = 'true'
|
||||
}
|
||||
}
|
||||
var header_copy_over = document.getElementById('header_copy_over')
|
||||
header_copy_over.style.display = 'table-cell'
|
||||
}
|
||||
|
||||
function removeEditButtons(id){
|
||||
@ -277,13 +278,19 @@ function addCancelButton(databaseId){
|
||||
function createDetailedHeaders(){
|
||||
var table = document.createElement('table')
|
||||
let headerRow = document.createElement('tr')
|
||||
let columns = ['Date', 'Start time', 'End time', 'Activity type', '', '']
|
||||
let columns = ['Date', 'Start time', 'End time', 'Activity type', 'Action', 'Copy over']
|
||||
for (let i = 0; i < columns.length; i++){
|
||||
var headerCell = document.createElement('th')
|
||||
var headerText = document.createElement('div')
|
||||
headerText.innerText = columns[i]
|
||||
headerCell.appendChild(headerText)
|
||||
if (i == columns.length -1){
|
||||
headerCell.style.display = 'none'
|
||||
headerCell.id = 'header_copy_over'
|
||||
}
|
||||
|
||||
headerRow.appendChild(headerCell)
|
||||
|
||||
}
|
||||
table.appendChild(headerRow)
|
||||
table.id = 'detailed_plan_records'
|
||||
|
@ -1,42 +0,0 @@
|
||||
var container = document.createElement('div')
|
||||
container.id = 'calendar_container'
|
||||
|
||||
var monthsBlock = document.createElement('div')
|
||||
monthsBlock.id = 'months_block'
|
||||
|
||||
renderCalendarFor(monthsBlock, currentYear, currentMonth, monthsAhead, 1)
|
||||
|
||||
var buttonBack = createButton('calendar_button_back', 'calendar_button', '<')
|
||||
buttonBack.addEventListener('click', function(){
|
||||
if (currentMonth == 1){
|
||||
currentMonth = 11
|
||||
currentYear = currentYear - 1
|
||||
}
|
||||
renderCalendarFor(monthsBlock, currentYear, currentMonth, monthsAhead, 1)
|
||||
})
|
||||
|
||||
|
||||
container.appendChild(buttonBack)
|
||||
container.appendChild(monthsBlock)
|
||||
|
||||
var buttonForward = createButton('calendar_button_forwards', 'calendar_button', '>')
|
||||
buttonForward.addEventListener('click', function(){
|
||||
if (currentMonth == 12){
|
||||
currentMonth = 0
|
||||
currentYear = currentYear + 1
|
||||
}
|
||||
renderCalendarFor(monthsBlock, currentYear, currentMonth, monthsAhead, 1)
|
||||
})
|
||||
|
||||
container.appendChild(buttonForward)
|
||||
|
||||
|
||||
|
||||
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(container, monthsAhead, currentMonth + 1, currentYear)
|
||||
})
|
||||
|
||||
formatCalendarContainerSize()
|
@ -10,17 +10,31 @@
|
||||
{% block core_content %}
|
||||
|
||||
<div class="sidebar">
|
||||
|
||||
<a href="{% url 'hr_module:create_schedule' %}">
|
||||
<div class="sidebar_item">Create schedule
|
||||
</div>
|
||||
</a>
|
||||
|
||||
<div class="sidebar_item">Manage Employees
|
||||
<a href="{% url 'hr_module:manage_schedule' %}">
|
||||
<div class="sidebar_item">Manage employee schedule
|
||||
</div>
|
||||
</a>
|
||||
|
||||
<div class="sidebar_item">Import Data
|
||||
<a href="{% url 'hr_module:change_employee_data' %}">
|
||||
<div class="sidebar_item">Manage employee data
|
||||
</div>
|
||||
</a>
|
||||
|
||||
<a href="{% url 'hr_module:create_employees' %}">
|
||||
<div class="sidebar_item">Create new employees
|
||||
</div>
|
||||
</a>
|
||||
|
||||
<a href="{% url 'hr_module:create_schedule' %}">
|
||||
<div class="sidebar_item">Export Data
|
||||
</div>
|
||||
</a>
|
||||
|
||||
</div>
|
||||
|
||||
@ -29,4 +43,6 @@
|
||||
{% endblock %}
|
||||
</div>
|
||||
|
||||
<script src="{% static '/js/csrf_token.js' %}"></script>
|
||||
|
||||
{% endblock %}
|
20
hr_module/templates/hr_module_change_employee_data.html
Normal file
20
hr_module/templates/hr_module_change_employee_data.html
Normal file
@ -0,0 +1,20 @@
|
||||
{% extends 'hr_module_base.html' %}
|
||||
|
||||
{% load static %}
|
||||
|
||||
{% block action_panel %}
|
||||
|
||||
<link rel="stylesheet" href="{% static '/css/hr_module_change_employee_data.css' %}">
|
||||
|
||||
<div>
|
||||
<label for="username_input">Person username: </label>
|
||||
<input id="username_input" type="text" value="kowalskija">
|
||||
<button type="button" id="load_employee_data_button">Search</button>
|
||||
</div>
|
||||
<div id="search_results">
|
||||
|
||||
</div>
|
||||
|
||||
<script src="{% static '/js/hr_module_change_employee_data.js' %}"></script>
|
||||
|
||||
{% endblock %}
|
@ -3,7 +3,7 @@
|
||||
{% load static %}
|
||||
|
||||
{% block action_panel %}
|
||||
<link rel="stylesheet" href="{% static '/css/hr_module_schedule.css' %}">
|
||||
<link rel="stylesheet" href="{% static '/css/hr_module_create_schedule.css' %}">
|
||||
|
||||
<div class="scheduleSearchRow">
|
||||
<div class="search_element">Select filter type:
|
||||
@ -54,8 +54,8 @@
|
||||
|
||||
<div class="popup" id="plan_log_popup">
|
||||
|
||||
</div>s
|
||||
</div>
|
||||
|
||||
<script src="{% static '/js/hr_module_schedule.js' %}"></script>
|
||||
<script src="{% static '/js/hr_module_create_schedule.js' %}"></script>
|
||||
|
||||
{% endblock %}
|
@ -5,12 +5,14 @@ from . import views
|
||||
app_name = 'hr_module'
|
||||
|
||||
urlpatterns = [
|
||||
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('create_schedule', views.create_schedule, name='create_schedule'),
|
||||
path('create_employees', views.create_employees, name='create_employees'),
|
||||
path('search_api', views.search_users_api, name='search_users_api'),
|
||||
path('loeademployees', views.load_employees_api, name='load_employees'),
|
||||
path('new_plan_api', views.new_plan_api, name='new_plan_api'),
|
||||
path('show_schedule', views.show_employee_plan, name='employee_schedule'),
|
||||
path('manage_schedule', views.manage_schedule, name='manage_schedule'),
|
||||
path('show_employee_plan_api', views.show_employee_plan_api, name='show_employee_plan_api'),
|
||||
path('update_plan_api', views.update_plan_api, name='update_plan_api'),
|
||||
path('change_employee_data', views.change_employee_data, name='change_employee_data'),
|
||||
path('change_employee_data_api', views.change_employee_data_api, name='change_employee_data_api'),
|
||||
]
|
@ -2,9 +2,11 @@ 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, create_planning_operation_report
|
||||
from hr_module.handling_functions.misc import dictfetchall
|
||||
import pandas as pd
|
||||
import json
|
||||
from .models import Employee, PlanCreationLog, Plan
|
||||
from django.contrib.auth.models import User
|
||||
from django.http import HttpResponse, JsonResponse, Http404
|
||||
from django.db import connection
|
||||
import datetime
|
||||
@ -12,11 +14,31 @@ import datetime
|
||||
|
||||
# Create your views here.
|
||||
def create_schedule(request):
|
||||
template_name = 'hr_module_schedule.html'
|
||||
template_name = 'hr_module_create_schedule.html'
|
||||
return render(request, template_name)
|
||||
|
||||
def change_employee_data(request):
|
||||
template_name = 'hr_module_change_employee_data.html'
|
||||
return render(request, template_name)
|
||||
|
||||
def hr_import(request):
|
||||
def change_employee_data_api(request):
|
||||
|
||||
if request.method == 'POST':
|
||||
body = json.loads(request.body)
|
||||
username = body['username']
|
||||
|
||||
empl = User.objects.select_related('employee').get(username=username)
|
||||
|
||||
record_employee = empl.employee.__dict__
|
||||
record_user = empl.__dict__
|
||||
response_dict = dict(record_user, **record_employee)
|
||||
for i in ['_state', 'password']:
|
||||
response_dict.pop(i)
|
||||
print(response_dict)
|
||||
return JsonResponse(response_dict, safe=False)
|
||||
|
||||
|
||||
def create_employees(request):
|
||||
if request.method == 'POST':
|
||||
if 'import_preview' in request.POST:
|
||||
fileform = UploadFileForm(request.POST, request.FILES)
|
||||
@ -73,14 +95,6 @@ def hr_import(request):
|
||||
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)
|
||||
@ -168,13 +182,12 @@ def new_plan_api(request):
|
||||
return JsonResponse(log)
|
||||
|
||||
|
||||
def show_employee_plan(request):
|
||||
def manage_schedule(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']
|
||||
|
Loading…
Reference in New Issue
Block a user