[UPDT] PMS: User permission updated
This commit is contained in:
70
pms/methods.py
Normal file
70
pms/methods.py
Normal file
@@ -0,0 +1,70 @@
|
||||
from pyexpat.errors import messages
|
||||
|
||||
from django.http import HttpResponse
|
||||
from employee.models import EmployeeWorkInformation
|
||||
from pms.models import EmployeeObjective, Objective
|
||||
from django.contrib import messages
|
||||
from django.shortcuts import render
|
||||
|
||||
decorator_with_arguments = (
|
||||
lambda decorator: lambda *args, **kwargs: lambda func: decorator(
|
||||
func, *args, **kwargs
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
@decorator_with_arguments
|
||||
def pms_manager_can_enter(function, perm):
|
||||
"""
|
||||
This method is used to check permission to employee for enter to the function if the employee
|
||||
do not have permission also checks, has reporting manager or manager of respective objective.
|
||||
"""
|
||||
|
||||
def _function(request, *args, **kwargs):
|
||||
user = request.user
|
||||
employee = user.employee_get
|
||||
is_manager = EmployeeWorkInformation.objects.filter(
|
||||
reporting_manager_id=employee
|
||||
).exists()
|
||||
is_objective_manager = Objective.objects.filter(managers=employee).exists()
|
||||
if user.has_perm(perm) or is_manager or is_objective_manager:
|
||||
return function(request, *args, **kwargs)
|
||||
else:
|
||||
messages.info(request, "You dont have permission.")
|
||||
previous_url = request.META.get("HTTP_REFERER", "/")
|
||||
script = f'<script>window.location.href = "{previous_url}"</script>'
|
||||
key = "HTTP_HX_REQUEST"
|
||||
if key in request.META.keys():
|
||||
return render(request, "decorator_404.html")
|
||||
return HttpResponse(script)
|
||||
|
||||
return _function
|
||||
|
||||
|
||||
@decorator_with_arguments
|
||||
def pms_owner_and_manager_can_enter(function, perm):
|
||||
"""
|
||||
This method is used to check permission to employee for enter to the function if the employee
|
||||
do not have permission also checks, has reporting manager or manager of respective objective.
|
||||
"""
|
||||
|
||||
def _function(request, *args, **kwargs):
|
||||
user = request.user
|
||||
employee = user.employee_get
|
||||
is_manager = EmployeeWorkInformation.objects.filter(
|
||||
reporting_manager_id=employee
|
||||
).exists()
|
||||
is_objective_owner = EmployeeObjective.objects.filter(employee_id=employee).exists()
|
||||
is_objective_manager = Objective.objects.filter(managers=employee).exists()
|
||||
if user.has_perm(perm) or is_manager or is_objective_manager or is_objective_owner:
|
||||
return function(request, *args, **kwargs)
|
||||
else:
|
||||
messages.info(request, "You dont have permission.")
|
||||
previous_url = request.META.get("HTTP_REFERER", "/")
|
||||
script = f'<script>window.location.href = "{previous_url}"</script>'
|
||||
key = "HTTP_HX_REQUEST"
|
||||
if key in request.META.keys():
|
||||
return render(request, "decorator_404.html")
|
||||
return HttpResponse(script)
|
||||
|
||||
return _function
|
||||
@@ -63,14 +63,20 @@
|
||||
</a>
|
||||
<div class="oh-timeoff-modal__stat">
|
||||
<span class="oh-timeoff-modal__stat-title me-3">{% trans "Status" %}</span>
|
||||
<select name="status" id="{{instance.id}}" class="oh-table__editable-input p-3"
|
||||
hx-trigger="change" hx-post="{% url 'change-employee-objective-status' instance.id %}" hx-target="#objectDetailsModalTarget"
|
||||
>
|
||||
{% for status in objective_key_result_status %}
|
||||
<option value="{{status.0}}" {% if status.0 == instance.status %} selected {% endif %}>
|
||||
<span class="oh-dot oh-dot--small oh-dot--warning">{{status.1}}</span></option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
{% if perms.pms.change_employeeobjective or instance|is_manager:request.user %}
|
||||
|
||||
<select name="status" id="{{instance.id}}" class="oh-table__editable-input p-3"
|
||||
hx-trigger="change" hx-post="{% url 'change-employee-objective-status' instance.id %}" hx-target="#objectDetailsModalTarget"
|
||||
>
|
||||
{% for status in objective_key_result_status %}
|
||||
<option value="{{status.0}}" {% if status.0 == instance.status %} selected {% endif %}>
|
||||
<span class="oh-dot oh-dot--small oh-dot--warning">{{status.1}}</span></option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
{% else %}
|
||||
<span class="oh-timeoff-modal__stat-count">{{instance.get_status_display}}</span>
|
||||
{% endif %}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="" style="padding-top: 5px;">
|
||||
@@ -111,62 +117,64 @@
|
||||
<span class="oh-timeoff-modal__stat-count dateformat_changer">{{instance.end_date}}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="oh-modal__button-container text-center mt-3">
|
||||
<div class="oh-btn-group">
|
||||
|
||||
<a class="oh-btn oh-btn--info" hx-get='{% url "update-employee-objective" instance.id %}' hx-target="#objectDetailsModalTarget" data-toggle="oh-modal-toggle" data-target="#objectDetailsModal" style="width: 50%;">
|
||||
<ion-icon name="create-outline">
|
||||
</ion-icon>{% trans "Edit" %}
|
||||
</a>
|
||||
{% if instance.archive %}
|
||||
<form class="oh-btn oh-btn--primary" style="width: 50%;" onsubmit="return confirm('Do you want to Unarchive this Employee objective?')" action='{% url "archive-employee-objective" instance.id %}'>
|
||||
<input type="hidden" name="archive" value="False" id="">
|
||||
<button style="background: none;
|
||||
color: inherit;
|
||||
border: none;
|
||||
padding: 0;
|
||||
font: inherit;
|
||||
cursor: pointer;
|
||||
outline: inherit;">
|
||||
<ion-icon name="archive-outline"></ion-icon>
|
||||
{% trans "Unarchive" %}
|
||||
</button>
|
||||
</form>
|
||||
{% else %}
|
||||
<form class="oh-btn oh-btn--primary" style="width: 50%;" onsubmit="return confirm('Do you want to archive this Employee objective?')" action='{% url "archive-employee-objective" instance.id %}'>
|
||||
<input type="hidden" name="archive" value="False" id="">
|
||||
<button style="background: none;
|
||||
color: inherit;
|
||||
border: none;
|
||||
padding: 0;
|
||||
font: inherit;
|
||||
cursor: pointer;
|
||||
outline: inherit;">
|
||||
<ion-icon name="archive-outline"></ion-icon>
|
||||
{% trans "Archive" %}
|
||||
</button>
|
||||
</form>
|
||||
{% endif %}
|
||||
<form class="oh-btn oh-btn--secondary" method="post" style="width: 50%;" onsubmit="return confirm('Do you Want to delete this employee objective?')" action='{% url "delete-employee-objective" instance.id %}'>
|
||||
{% csrf_token %}
|
||||
<button style="background: none;
|
||||
color: inherit;
|
||||
border: none;
|
||||
padding: 0;
|
||||
font: inherit;
|
||||
cursor: pointer;
|
||||
outline: inherit;">
|
||||
<ion-icon name="trash-outline">
|
||||
</ion-icon>{% trans "Delete" %}
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% if perms.pms.change_employeeobjective or perms.pms.delete_employeeobjective or instance|is_manager:request.user %}
|
||||
<div class="oh-modal__button-container text-center mt-3">
|
||||
<div class="oh-btn-group">
|
||||
{% if perms.pms.change_employeeobjective or instance|is_manager:request.user %}
|
||||
<a class="oh-btn oh-btn--info" hx-get='{% url "update-employee-objective" instance.id %}' hx-target="#objectDetailsModalTarget" data-toggle="oh-modal-toggle" data-target="#objectDetailsModal" style="width: 50%;">
|
||||
<ion-icon name="create-outline">
|
||||
</ion-icon>{% trans "Edit" %}
|
||||
</a>
|
||||
{% endif %}
|
||||
{% if perms.pms.delete_employeeobjective or instance|is_manager:request.user %}
|
||||
|
||||
{% comment %} <script>
|
||||
function empObjStatusUpdate(element){
|
||||
alert('ssssssssssss')
|
||||
}
|
||||
</script> {% endcomment %}
|
||||
{% if instance.archive %}
|
||||
<form class="oh-btn oh-btn--primary" style="width: 50%;" onsubmit="return confirm('Do you want to Unarchive this Employee objective?')" action='{% url "archive-employee-objective" instance.id %}'>
|
||||
<input type="hidden" name="archive" value="False" id="">
|
||||
<input type="hidden" name="single_view" value="True">
|
||||
<button style="background: none;
|
||||
color: inherit;
|
||||
border: none;
|
||||
padding: 0;
|
||||
font: inherit;
|
||||
cursor: pointer;
|
||||
outline: inherit;">
|
||||
<ion-icon name="archive-outline"></ion-icon>
|
||||
{% trans "Unarchive" %}
|
||||
</button>
|
||||
</form>
|
||||
{% else %}
|
||||
<form class="oh-btn oh-btn--primary" style="width: 50%;" onsubmit="return confirm('Do you want to archive this Employee objective?')" action='{% url "archive-employee-objective" instance.id %}'>
|
||||
<input type="hidden" name="archive" value="False" id="">
|
||||
<input type="hidden" name="single_view" value="True">
|
||||
<button style="background: none;
|
||||
color: inherit;
|
||||
border: none;
|
||||
padding: 0;
|
||||
font: inherit;
|
||||
cursor: pointer;
|
||||
outline: inherit;">
|
||||
<ion-icon name="archive-outline"></ion-icon>
|
||||
{% trans "Archive" %}
|
||||
</button>
|
||||
</form>
|
||||
{% endif %}
|
||||
<form class="oh-btn oh-btn--secondary" method="post" style="width: 50%;" onsubmit="return confirm('Do you Want to delete this employee objective?')" action='{% url "delete-employee-objective" instance.id %}'>
|
||||
{% csrf_token %}
|
||||
<button style="background: none;
|
||||
color: inherit;
|
||||
border: none;
|
||||
padding: 0;
|
||||
font: inherit;
|
||||
cursor: pointer;
|
||||
outline: inherit;">
|
||||
<ion-icon name="trash-outline">
|
||||
</ion-icon>{% trans "Delete" %}
|
||||
</button>
|
||||
</form>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
@@ -31,7 +31,7 @@
|
||||
<div class="oh-sticky-table__th">{% trans "Start Date" %}</div>
|
||||
<div class="oh-sticky-table__th">{% trans "End Date" %}</div>
|
||||
<div class="oh-sticky-table__th">{% trans "Status" %}</div>
|
||||
{% if perms.pms.change_employeeobjective or emp_objective|is_manager:request.user %}
|
||||
{% if perms.pms.change_employeeobjective %}
|
||||
<div class="oh-sticky-table__th oh-sticky-table__right">{% trans "Actions" %}</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
@@ -92,21 +92,25 @@
|
||||
<div class="oh-sticky-table__td">{{kr.start_date}}</div>
|
||||
<div class="oh-sticky-table__td">{{kr.end_date}}</div>
|
||||
<div class="oh-sticky-table__td">
|
||||
<select
|
||||
id="keyResultStatus" name="key_result_status"
|
||||
hx-post="{% url 'employee-keyresult-update-status' kr.id %}"
|
||||
hx-trigger="change" class="oh-table__editable-input w-100"
|
||||
hx-target="#krData{{kr.employee_objective_id.id}}">
|
||||
{% for value,label in key_result_status %}
|
||||
{% if kr.status != value %}
|
||||
<option value="{{value}}">{{label}}</option>
|
||||
{% else %}
|
||||
<option value="{{value}}" selected>{{label}}</option>
|
||||
{% endif%}
|
||||
{% endfor %}
|
||||
</select>
|
||||
{% if perms.pms.change_employeeobjective or kr.employee_objective_id|is_manager:request.user %}
|
||||
<select
|
||||
id="keyResultStatus" name="key_result_status"
|
||||
hx-post="{% url 'employee-keyresult-update-status' kr.id %}"
|
||||
hx-trigger="change" class="oh-table__editable-input w-100"
|
||||
hx-target="#krData{{kr.employee_objective_id.id}}">
|
||||
{% for value,label in key_result_status %}
|
||||
{% if kr.status != value %}
|
||||
<option value="{{value}}">{{label}}</option>
|
||||
{% else %}
|
||||
<option value="{{value}}" selected>{{label}}</option>
|
||||
{% endif%}
|
||||
{% endfor %}
|
||||
</select>
|
||||
{% else %}
|
||||
{{kr.get_status_display}}
|
||||
{% endif %}
|
||||
</div>
|
||||
{% if perms.pms.change_employeeobjective or emp_objective|is_manager:request.user %}
|
||||
{% if perms.pms.change_employeeobjective or kr.employee_objective_id|is_manager:request.user %}
|
||||
<div class="oh-sticky-table__td oh-sticky-table__right" onclick="event.stopPropagation()">
|
||||
<div class="oh-btn-group">
|
||||
<button
|
||||
@@ -121,7 +125,7 @@
|
||||
</button>
|
||||
<form
|
||||
action='{% url "delete-employee-keyresult" kr.id %}'
|
||||
class="w-1002"
|
||||
class="w-50"
|
||||
onsubmit="return confirm('{% trans 'Are you sure you want to delete this Key result?' %}');"
|
||||
method='post' onclick="event.stopPropagation()" >
|
||||
{% csrf_token %}
|
||||
|
||||
47
pms/views.py
47
pms/views.py
@@ -18,6 +18,7 @@ from django.forms import modelformset_factory
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from django.shortcuts import get_object_or_404, render, redirect
|
||||
from django.http import HttpResponse, HttpResponseRedirect, JsonResponse
|
||||
from attendance.methods.group_by import group_by_queryset
|
||||
from horilla.decorators import manager_can_enter, permission_required
|
||||
from horilla.decorators import login_required, hx_request_required
|
||||
from notifications.signals import notify
|
||||
@@ -33,6 +34,7 @@ from pms.filters import (
|
||||
FeedbackFilter,
|
||||
ObjectiveReGroup,
|
||||
)
|
||||
from pms.methods import pms_manager_can_enter, pms_owner_and_manager_can_enter
|
||||
from pms.models import (
|
||||
AnonymousFeedback,
|
||||
EmployeeKeyResult,
|
||||
@@ -393,10 +395,11 @@ def add_assignees(request, obj_id):
|
||||
if request.method == "POST":
|
||||
form = AddAssigneesForm(request.POST, instance=objective)
|
||||
if form.is_valid():
|
||||
objective = form.save()
|
||||
objective = form.save(commit=False)
|
||||
assignees = form.cleaned_data["assignees"]
|
||||
start_date = form.cleaned_data["start_date"]
|
||||
for emp in assignees:
|
||||
objective.assignees.add(emp)
|
||||
if not EmployeeObjective.objects.filter(
|
||||
employee_id=emp, objective_id=objective
|
||||
).exists():
|
||||
@@ -428,6 +431,7 @@ def add_assignees(request, obj_id):
|
||||
verb_fr="Vous avez atteint un Résultat Clé d'Objectif !",
|
||||
redirect=f"/pms/objective-detailed-view/{objective.id}",
|
||||
)
|
||||
objective.save()
|
||||
messages.info(
|
||||
request,
|
||||
_("Objective %(objective)s Updated") % {"objective": objective},
|
||||
@@ -643,6 +647,23 @@ def objective_list_search(request):
|
||||
template = "okr/group_by.html"
|
||||
return render(request, template, context)
|
||||
|
||||
@login_required
|
||||
# @hx_request_required
|
||||
def objective_dashboard_view(request):
|
||||
"""
|
||||
This view is used to to search objective, returns searched and filtered objects.
|
||||
Returns:
|
||||
All the filtered and searched object will based on userlevel.
|
||||
"""
|
||||
emp_objectives = EmployeeObjectiveFilter(request.GET).qs
|
||||
return render(
|
||||
request,
|
||||
"okr/emp_objective/emp_objective_dashboard_view.html",
|
||||
{
|
||||
'emp_objectives':emp_objectives
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
def objective_history(emp_obj_id):
|
||||
"""
|
||||
@@ -987,7 +1008,7 @@ def objective_archive(request, id):
|
||||
|
||||
|
||||
@login_required
|
||||
@manager_can_enter(perm="pms.view_employeeobjective")
|
||||
@pms_owner_and_manager_can_enter(perm="pms.view_employeeobjective")
|
||||
def view_employee_objective(request, emp_obj_id):
|
||||
"""
|
||||
This function is used to render individual view of the employee objective
|
||||
@@ -1039,7 +1060,7 @@ def archive_employee_objective(request, emp_obj_id):
|
||||
"""
|
||||
emp_objective = EmployeeObjective.objects.get(id=emp_obj_id)
|
||||
obj_id = emp_objective.objective_id.id
|
||||
single_view = request.GET.get("single_view")
|
||||
single_view = eval(request.GET.get("single_view"))
|
||||
if emp_objective.archive:
|
||||
emp_objective.archive = False
|
||||
emp_objective.save()
|
||||
@@ -1051,7 +1072,7 @@ def archive_employee_objective(request, emp_obj_id):
|
||||
if single_view:
|
||||
return redirect(f"/pms/objective-detailed-view/{obj_id}")
|
||||
else:
|
||||
return redirect(objective_list_view)
|
||||
return redirect(f"/pms/emp-objective-search/{obj_id}")
|
||||
|
||||
|
||||
|
||||
@@ -1133,13 +1154,15 @@ def key_result_view(request):
|
||||
Returns:
|
||||
if errorr occur it will return errorr message.
|
||||
"""
|
||||
key_results = KeyResultFilter(request.GET).qs
|
||||
krs =KeyResultFilter(request.GET).qs
|
||||
krs= group_by_queryset(
|
||||
krs, 'employee_objective_id__employee_id', request.GET.get("page"), "page"
|
||||
)
|
||||
context = {
|
||||
"current_date": datetime.date.today(),
|
||||
"key_results": key_results,
|
||||
"objective_key_result_status": EmployeeKeyResult.STATUS_CHOICES,
|
||||
"krs": krs,
|
||||
"key_result_status": EmployeeKeyResult.STATUS_CHOICES,
|
||||
}
|
||||
return render(request, "okr/key_result/key_result_view.html", context=context)
|
||||
return render(request, "okr/key_result/kr_dashboard_view.html", context=context)
|
||||
|
||||
|
||||
@login_required
|
||||
@@ -2412,7 +2435,7 @@ def dashboard_objective_status(request):
|
||||
objective_status = EmployeeObjective.STATUS_CHOICES
|
||||
data = {"message": _("No data Found...")}
|
||||
for status in objective_status:
|
||||
objectives = EmployeeObjective.objects.filter(status=status[0])
|
||||
objectives = EmployeeObjective.objects.filter(status=status[0],archive=False)
|
||||
objectives_count = filtersubordinates(
|
||||
request, queryset=objectives, perm="pms.view_employeeobjective"
|
||||
).count()
|
||||
@@ -2948,6 +2971,8 @@ def delete_employee_keyresult(request, kr_id):
|
||||
emp_objective.update_objective_progress()
|
||||
# objective.assignees.remove(employee)
|
||||
messages.success(request, _("Objective deleted successfully!."))
|
||||
if request.GET.get('dashboard'):
|
||||
return redirect(f"/pms/dashboard-view")
|
||||
return redirect(f"/pms/objective-detailed-view/{objective.id}")
|
||||
|
||||
|
||||
@@ -2979,7 +3004,7 @@ def key_result_current_value_update(request):
|
||||
current_value = eval(request.POST.get("current_value"))
|
||||
emp_kr_id = eval(request.POST.get("emp_key_result_id"))
|
||||
emp_kr = EmployeeKeyResult.objects.get(id=emp_kr_id)
|
||||
if current_value < emp_kr.target_value:
|
||||
if current_value <= emp_kr.target_value:
|
||||
emp_kr.current_value = current_value
|
||||
emp_kr.save()
|
||||
emp_kr.employee_objective_id.update_objective_progress()
|
||||
|
||||
Reference in New Issue
Block a user