[UPDT] PMS: Assignees list is updated

This commit is contained in:
Horilla
2025-10-28 10:01:49 +05:30
parent 1dc11c8da0
commit cfb335821f
3 changed files with 157 additions and 46 deletions

View File

@@ -68,7 +68,7 @@
<span class="oh-badge oh-badge--secondary oh-badge--small oh-badge--round ms-2 mr-2" id="" data-category-id="1" title="{{own_objectives.paginator.count}} objectives" onclick="event.stopPropagation()">{{own_objectives.paginator.count}}</span>
</li>
<!-- normal user can't view all objective -->
{% if perms.pms.view_objective or manager %}
{% if perms.pms.view_objective or manager or reporting_manager %}
<li class="oh-tabs__tab" onclick="switchTab(event)" data-target="#all_objective">
{% trans "All Objective" %}
<div style="align-items:center;display:flex">
@@ -132,9 +132,11 @@
<div data-cell-index="2" data-cell-title='{% trans "Key Results" %}'
class="oh-sticky-table__th"
>{% trans "Key Results" %}</div>
<div data-cell-index="3" data-cell-title='{% trans "Assignees" %}'
class="oh-sticky-table__th"
>{% trans "Assignees" %}</div>
{% if perms.pms.view_objective or manager or reporting_manager %}
<div data-cell-index="3" data-cell-title='{% trans "Assignees" %}'
class="oh-sticky-table__th"
>{% trans "Assignees" %}</div>
{% endif %}
<div data-cell-index="4" data-cell-title='{% trans "Duration" %}'
class="oh-sticky-table__th"
>{% trans "Duration" %}</div>
@@ -228,35 +230,76 @@
{% endfor %}
<span class="count-span">{{objective.key_result_id.all|length}} {% trans "Key results" %}</span>
</div>
<div data-cell-index="3" class="oh-sticky-table__td">
{% for emp_objective in objective.employee_objective.all %}
<div id="assigneesContainer{{emp_objective.id}}">
<span class="oh-user-panel oh-collapse-panel" data-type="user" >
<div class="oh-profile oh-profile--md">
<div class="oh-profile__avatar mr-1">
<img
src="https://ui-avatars.com/api/?name={{emp_objective.employee_id.get_full_name}}&background=random"
class="oh-profile__image"
alt="Baby C."
/>
{% if perms.pms.view_objective or manager or reporting_manager %}
<div data-cell-index="3" class="oh-sticky-table__td">
{% for emp_objective in objective.employee_objective.all %}
{% if request.user.employee_get not in objective.managers.all and reporting_manager %}
{% if emp_objective.employee_id in subordinates %}
<div id="assigneesContainer{{ emp_objective.id }}">
<span class="oh-user-panel oh-collapse-panel" data-type="user">
<div class="oh-profile oh-profile--md">
<div class="oh-profile__avatar mr-1">
<img
src="https://ui-avatars.com/api/?name={{ emp_objective.employee_id.get_full_name }}&background=random"
class="oh-profile__image"
alt="{{ emp_objective.employee_id.get_full_name }}"
/>
</div>
<span class="oh-profile__name oh-text--dark" title="{{ emp_objective.employee_id }}">
{{ emp_objective.employee_id|truncatechars:15 }}
</span>
</div>
<a
hx-confirm="{% trans 'Are you sure you want to remove this assignee?' %}"
hx-post="{% url 'assignees-remove' objective.id emp_objective.employee_id.id %}"
title="{% trans 'Remove' %}"
hx-swap="delete"
hx-target="#assigneesContainer{{ emp_objective.id }}"
onclick="event.stopPropagation()"
class="oh-user-panel__remove"
>
<ion-icon name="close-outline"></ion-icon>
</a>
</span>
</div>
<span class="oh-profile__name oh-text--dark" title="{{emp_objective.employee_id}}"
>{{emp_objective.employee_id|truncatechars:15}}</span
>
{% endif %}
{% else %}
<div id="assigneesContainer{{ emp_objective.id }}">
<span class="oh-user-panel oh-collapse-panel" data-type="user">
<div class="oh-profile oh-profile--md">
<div class="oh-profile__avatar mr-1">
<img
src="https://ui-avatars.com/api/?name={{ emp_objective.employee_id.get_full_name }}&background=random"
class="oh-profile__image"
alt="{{ emp_objective.employee_id.get_full_name }}"
/>
</div>
<span class="oh-profile__name oh-text--dark" title="{{ emp_objective.employee_id }}">
{{ emp_objective.employee_id|truncatechars:15 }}
</span>
</div>
<a
hx-confirm="{% trans 'Are you sure you want to remove this assignee?' %}"
hx-post="{% url 'assignees-remove' objective.id emp_objective.employee_id.id %}"
title="{% trans 'Remove' %}"
hx-swap="delete"
hx-target="#assigneesContainer{{ emp_objective.id }}"
onclick="event.stopPropagation()"
class="oh-user-panel__remove"
>
<ion-icon name="close-outline"></ion-icon>
</a>
</span>
</div>
<a
hx-confirm="{% trans 'Are you sure want to remove this assignee?' %}"
hx-post="{% url 'assignees-remove' objective.id emp_objective.employee_id.id %}"
title="{% trans "Remove" %}" hx-swap="delete" hx-target="#assigneesContainer{{emp_objective.id}}"
onclick="event.stopPropagation()" class="oh-user-panel__remove"
>
<ion-icon name="close-outline"></ion-icon>
</a>
</span>
</div>
{% endfor %}
<span class="count-span">{{ objective.employee_objective.all|length}} {% trans "Assignees" %}</span>
</div>
{% endif %}
{% endfor %}
<span class="count-span">
{{ objective|assignees_count:request }} {% trans "Assignees" %}
</span>
</div>
{% endif %}
<div data-cell-index="4" class="oh-sticky-table__td ">
{{objective.duration}} {{objective.get_duration_unit_display}}
</div>
@@ -471,7 +514,7 @@
<img
src="https://ui-avatars.com/api/?name={{manager.get_full_name}}&background=random"
class="oh-profile__image"
alt="Baby C."
alt="{{manager.get_full_name}}"
/>
</div>
<span class="oh-profile__name oh-text--dark" title="{{manager}}"

View File

@@ -16,6 +16,7 @@ Filters:
from django.template.defaultfilters import register
from base.methods import filtersubordinatesemployeemodel
from employee.models import Employee, EmployeeWorkInformation
from pms.models import AnonymousFeedback, EmployeeObjective, Feedback, Objective
@@ -124,3 +125,29 @@ def is_anonymous_feedback_owner(user, feedback):
if str(user.id) == feedback.anonymous_feedback_id:
return True
return False
@register.filter(name="assignees_count")
def assignees_count(objective, request):
"""
Args:
objective: The objective for which to retrieve assignees.
user: The user requesting the assignees.
Returns:
int: The count of assignees for the given objective.
"""
if (
request.user.has_perm("pms.view_objective")
or objective.managers.filter(id=request.user.employee_get.id).exists()
):
return objective.employee_objective.count()
sub_employees = filtersubordinatesemployeemodel(
request,
queryset=Employee.objects.filter(is_active=True),
)
if sub_employees.exists():
subordinate_objectives = objective.employee_objective.filter(
employee_id__in=sub_employees
)
return subordinate_objectives.count()

View File

@@ -592,7 +592,7 @@ def objective_filter_pagination(request, objective_own):
employee = request.user.employee_get
manager = False
reporting_manager = False
sub_employees = filtersubordinatesemployeemodel(
request,
queryset=Employee.objects.filter(is_active=True),
@@ -609,10 +609,10 @@ def objective_filter_pagination(request, objective_own):
if request.user.has_perm("pms.view_objective"):
objectives = Objective.objects.all()
manager = True
elif Objective.objects.filter(managers=employee).exists() or is_reportingmanager(
request
):
elif Objective.objects.filter(managers=employee).exists():
manager = True
if is_reportingmanager(request):
reporting_manager = True
objectives = ActualObjectiveFilter(
request.GET or initial_data, queryset=objectives
).qs
@@ -637,6 +637,8 @@ def objective_filter_pagination(request, objective_own):
"filter_dict": data_dict,
"gp_fields": ObjectiveReGroup.fields,
"field": field,
"reporting_manager": reporting_manager,
"subordinates": sub_employees,
}
return context
@@ -731,33 +733,54 @@ def objective_history(emp_obj_id):
@login_required
def objective_detailed_view(request, obj_id, **kwargs):
"""
this function is used to update the key result of objectives
args:
obj_id(int) : pimarykey of EmployeeObjective
return:
objects to objective_detailed_view
View to display and update key results of an objective.
Args:
request: The HTTP request object.
obj_id (int): Primary key of the Objective.
Returns:
Rendered template or redirect if no permission.
"""
objective = Objective.objects.get(id=obj_id)
try:
objective = Objective.objects.get(id=obj_id)
except Objective.DoesNotExist:
messages.error(request, _("Objective not found."))
return redirect("objective-list-view")
emp_objectives = EmployeeObjective.objects.filter(
objective_id=objective, archive=False
)
user_employee = request.user.employee_get
# Determine if the user is a reporting manager of any employee in this objective
subordinates = filtersubordinatesemployeemodel(
request,
queryset=Employee.objects.filter(is_active=True),
)
is_reporting_manager = emp_objectives.filter(employee_id__in=subordinates).exists()
# Permission check
if not (
request.user.employee_get in objective.managers.all()
user_employee in objective.managers.all()
or request.user.has_perm("pms.view_employeeobjective")
or emp_objectives.filter(employee_id=request.user.employee_get).exists()
or emp_objectives.filter(employee_id=user_employee).exists()
or is_reporting_manager
):
messages.info(request, _("You dont have permission."))
messages.info(request, _("You don't have permission."))
return redirect("objective-list-view")
previous_data = request.GET.urlencode()
data_dict = parse_qs(previous_data)
now = datetime.datetime.now()
context = {
"objective": objective,
"emp_objectives": emp_objectives,
"pd": previous_data,
"filter_dict": data_dict,
"objective": objective,
"key_result_form": KeyResultForm,
"objective_key_result_status": EmployeeKeyResult.STATUS_CHOICES,
"comment_form": ObjectiveCommentForm,
@@ -853,6 +876,23 @@ def emp_objective_search(request, obj_id):
"""
objective = Objective.objects.get(id=obj_id)
emp_objectives = objective.employee_objective.all()
# Limit objectives if user is a reporting manager but not a manager or assignee
user_employee = request.user.employee_get
# Determine if the user is a reporting manager of any employee in this objective
subordinates = filtersubordinatesemployeemodel(
request,
queryset=Employee.objects.filter(is_active=True),
)
is_reporting_manager = emp_objectives.filter(employee_id__in=subordinates).exists()
if (
not (
user_employee in objective.managers.all()
or request.user.has_perm("pms.view_employeeobjective")
or emp_objectives.filter(employee_id=user_employee).exists()
)
and is_reporting_manager
):
emp_objectives = emp_objectives.filter(employee_id__in=subordinates)
search_val = request.GET.get("search")
if search_val is None:
search_val = ""
@@ -870,6 +910,7 @@ def emp_objective_search(request, obj_id):
"filter_dict": data_dict,
"pg": previous_data,
"objective": objective,
"is_reporting_manager": is_reporting_manager,
}
template = "okr/emp_objective/emp_objective_list.html"
if request.GET.get("field") != "" and request.GET.get("field") is not None: