375 lines
17 KiB
Python
375 lines
17 KiB
Python
from django.apps import apps
|
|
from django.http import JsonResponse
|
|
from django.shortcuts import render
|
|
|
|
if apps.is_installed("pms"):
|
|
|
|
from base.models import Company
|
|
from horilla.decorators import login_required, permission_required
|
|
from pms.filters import EmployeeObjectiveFilter, FeedbackFilter
|
|
from pms.models import EmployeeKeyResult, EmployeeObjective, Feedback, Objective
|
|
from pms.views import objective_filter_pagination
|
|
|
|
@login_required
|
|
@permission_required(perm="pms.view_objective")
|
|
def pms_report(request):
|
|
|
|
company = "all"
|
|
selected_company = request.session.get("selected_company")
|
|
if selected_company != "all":
|
|
company = Company.objects.filter(id=selected_company).first()
|
|
employee = request.user.employee_get
|
|
objective_own = EmployeeObjective.objects.filter(
|
|
employee_id=employee, archive=False
|
|
)
|
|
objective_own = objective_own.distinct()
|
|
|
|
feedback = request.GET.get(
|
|
"search"
|
|
) # if the search is none the filter will works
|
|
if feedback is None:
|
|
feedback = ""
|
|
self_feedback = Feedback.objects.filter(employee_id=employee).filter(
|
|
review_cycle__icontains=feedback
|
|
)
|
|
initial_data = {"archive": False}
|
|
feedback_filter_own = FeedbackFilter(
|
|
request.GET or initial_data, queryset=self_feedback
|
|
)
|
|
|
|
context = objective_filter_pagination(request, objective_own)
|
|
cm = {
|
|
"company": company,
|
|
"feedback_filter_form": feedback_filter_own.form,
|
|
"emp_obj_form": EmployeeObjectiveFilter(),
|
|
}
|
|
context.update(cm)
|
|
|
|
return render(request, "report/pms_report.html", context)
|
|
|
|
@login_required
|
|
@permission_required(perm="pms.view_objective")
|
|
def pms_pivot(request):
|
|
|
|
model_type = request.GET.get("model", "objective")
|
|
if model_type == "objective":
|
|
qs = Objective.objects.all()
|
|
|
|
if managers := request.GET.getlist("managers"):
|
|
qs = qs.filter(managers__id__in=managers)
|
|
if assignees := request.GET.getlist("assignees"):
|
|
qs = qs.filter(assignees__id__in=assignees)
|
|
if duration := request.GET.get("duration"):
|
|
qs = qs.filter(duration=duration)
|
|
if key_result_id := request.GET.get("employee_objective__key_result_id"):
|
|
qs = qs.filter(key_result_id=key_result_id)
|
|
|
|
data = list(
|
|
qs.values(
|
|
"title",
|
|
"managers__employee_first_name",
|
|
"managers__employee_last_name",
|
|
"assignees__employee_first_name",
|
|
"assignees__employee_last_name",
|
|
"key_result_id__title",
|
|
"key_result_id__target_value",
|
|
"duration_unit",
|
|
"duration",
|
|
"company_id__company",
|
|
"key_result_id__progress_type",
|
|
"key_result_id__duration",
|
|
"assignees__employee_work_info__department_id__department",
|
|
"assignees__employee_work_info__job_role_id__job_role",
|
|
"assignees__employee_work_info__job_position_id__job_position",
|
|
)
|
|
)
|
|
DURATION_UNIT = {
|
|
"days": "Days",
|
|
"months": "Months",
|
|
"years": "Years",
|
|
}
|
|
KEY_RESULT_TARGET = {
|
|
"%": "%",
|
|
"#": "Number",
|
|
"Currency": "Currency",
|
|
}
|
|
data_list = [
|
|
{
|
|
"Objective": item["title"],
|
|
"Objective Duration": f'{item["duration"]} {DURATION_UNIT.get(item["duration_unit"])}',
|
|
"Manager": (
|
|
f"{item['managers__employee_first_name']} {item['managers__employee_last_name']}"
|
|
if item["managers__employee_first_name"]
|
|
else "-"
|
|
),
|
|
"Assignees": f"{item['assignees__employee_first_name']} {item['assignees__employee_last_name']}",
|
|
"Assignee Department": (
|
|
item["assignees__employee_work_info__department_id__department"]
|
|
if item[
|
|
"assignees__employee_work_info__department_id__department"
|
|
]
|
|
else "-"
|
|
),
|
|
"Assignee Job Position": (
|
|
item[
|
|
"assignees__employee_work_info__job_position_id__job_position"
|
|
]
|
|
if item[
|
|
"assignees__employee_work_info__job_position_id__job_position"
|
|
]
|
|
else "-"
|
|
),
|
|
"Assignee Job Role": (
|
|
item["assignees__employee_work_info__job_role_id__job_role"]
|
|
if item["assignees__employee_work_info__job_role_id__job_role"]
|
|
else "-"
|
|
),
|
|
"Key Results": item["key_result_id__title"],
|
|
"Key Result Duration": f'{item["key_result_id__duration"]} {"Days"}',
|
|
"Key Result Target": f'{item["key_result_id__target_value"]} {KEY_RESULT_TARGET.get(item["key_result_id__progress_type"])}',
|
|
"Company": item["company_id__company"],
|
|
}
|
|
for item in data
|
|
]
|
|
elif model_type == "feedback":
|
|
|
|
data_list = []
|
|
|
|
PERIOD = {
|
|
"days": "Days",
|
|
"months": "Months",
|
|
"years": "Years",
|
|
}
|
|
|
|
feedbacks = Feedback.objects.select_related(
|
|
"manager_id", "employee_id", "question_template_id"
|
|
).prefetch_related(
|
|
"colleague_id",
|
|
"subordinate_id",
|
|
"question_template_id__question",
|
|
"feedback_answer__question_id", # related_name
|
|
"feedback_answer__employee_id",
|
|
)
|
|
|
|
# ✅ FILTERS added here
|
|
if review_cycle := request.GET.get("review_cycle"):
|
|
feedbacks = feedbacks.filter(review_cycle=review_cycle)
|
|
if status := request.GET.get("status"):
|
|
feedbacks = feedbacks.filter(status=status)
|
|
if employee_id := request.GET.get("employee_id"):
|
|
feedbacks = feedbacks.filter(employee_id=employee_id)
|
|
if manager_id := request.GET.get("manager_id"):
|
|
feedbacks = feedbacks.filter(manager_id=manager_id)
|
|
if colleague_id := request.GET.get("colleague_id"):
|
|
feedbacks = feedbacks.filter(colleague_id=colleague_id)
|
|
if subordinate_id := request.GET.get("subordinate_id"):
|
|
feedbacks = feedbacks.filter(subordinate_id=subordinate_id)
|
|
if start_date := request.GET.get("start_date"):
|
|
feedbacks = feedbacks.filter(created_at__date__gte=start_date)
|
|
if end_date := request.GET.get("end_date"):
|
|
feedbacks = feedbacks.filter(created_at__date__lte=end_date)
|
|
|
|
for feedback in feedbacks:
|
|
manager = (
|
|
f"{feedback.manager_id.employee_first_name} {feedback.manager_id.employee_last_name}"
|
|
if feedback.manager_id
|
|
else ""
|
|
)
|
|
employee = (
|
|
f"{feedback.employee_id.employee_first_name} {feedback.employee_id.employee_last_name}"
|
|
if feedback.employee_id
|
|
else ""
|
|
)
|
|
|
|
answerable_employees = list(feedback.colleague_id.all()) + list(
|
|
feedback.subordinate_id.all()
|
|
)
|
|
answerable_names = (
|
|
", ".join(
|
|
f"{e.employee_first_name} {e.employee_last_name}"
|
|
for e in answerable_employees
|
|
)
|
|
or "-"
|
|
)
|
|
|
|
questions = feedback.question_template_id.question.all()
|
|
|
|
# Fetch ALL answers for this feedback and map them grouped by question
|
|
answers = feedback.feedback_answer.select_related(
|
|
"employee_id", "question_id"
|
|
)
|
|
|
|
for question in questions:
|
|
question_answers = [
|
|
ans for ans in answers if ans.question_id_id == question.id
|
|
]
|
|
|
|
# If no one answered this question, still show the question
|
|
if not question_answers:
|
|
data_list.append(
|
|
{
|
|
"Title": feedback.review_cycle,
|
|
"Manager": manager,
|
|
"Employee": employee,
|
|
"Answerable Employees": answerable_names,
|
|
"Questions": question.question,
|
|
"Answer": "",
|
|
"Answered Employees": "-",
|
|
"Status": feedback.status,
|
|
"Start Date": feedback.start_date,
|
|
"End Date": feedback.end_date,
|
|
"Is Cyclic": (
|
|
"Yes" if feedback.cyclic_feedback else "No"
|
|
),
|
|
"Cycle Period": (
|
|
f"{feedback.cyclic_feedback_days_count} {PERIOD.get(feedback.cyclic_feedback_period)}"
|
|
if feedback.cyclic_feedback_days_count
|
|
else "-"
|
|
),
|
|
}
|
|
)
|
|
else:
|
|
for answer in question_answers:
|
|
answer_value = (
|
|
answer.answer.get("answer") if answer.answer else ""
|
|
)
|
|
answered_by = (
|
|
f"{answer.employee_id.employee_first_name} {answer.employee_id.employee_last_name}"
|
|
if answer.employee_id
|
|
else "-"
|
|
)
|
|
data_list.append(
|
|
{
|
|
"Title": feedback.review_cycle,
|
|
"Manager": manager,
|
|
"Employee": employee,
|
|
"Answerable Employees": answerable_names,
|
|
"Questions": question.question,
|
|
"Answer": answer_value,
|
|
"Answered Employees": answered_by,
|
|
"Status": feedback.status,
|
|
"Start Date": feedback.start_date,
|
|
"End Date": feedback.end_date,
|
|
"Is Cyclic": (
|
|
"Yes" if feedback.cyclic_feedback else "No"
|
|
),
|
|
"Cycle Period": (
|
|
f"{feedback.cyclic_feedback_days_count} {PERIOD.get(feedback.cyclic_feedback_period)}"
|
|
if feedback.cyclic_feedback_days_count
|
|
else "-"
|
|
),
|
|
}
|
|
)
|
|
elif model_type == "employeeobjective":
|
|
|
|
from django.utils.dateparse import parse_date
|
|
|
|
qs = EmployeeKeyResult.objects.all()
|
|
|
|
# Filter section
|
|
if assignees := request.GET.getlist("employee_id"):
|
|
qs = qs.filter(employee_objective_id__employee_id__id__in=assignees)
|
|
if key_result_id := request.GET.get("key_result_id"):
|
|
qs = qs.filter(key_result_id__id=key_result_id)
|
|
if status := request.GET.get("status"):
|
|
qs = qs.filter(status=status)
|
|
|
|
start_date_from = parse_date(request.GET.get("start_date_from", ""))
|
|
start_date_to = parse_date(request.GET.get("start_date_till", ""))
|
|
if start_date_from:
|
|
qs = qs.filter(start_date__gte=start_date_from)
|
|
if start_date_to:
|
|
qs = qs.filter(start_date__lte=start_date_to)
|
|
|
|
end_date_from = parse_date(request.GET.get("end_date_from", ""))
|
|
end_date_to = parse_date(request.GET.get("end_date_till", ""))
|
|
if end_date_from:
|
|
qs = qs.filter(end_date__gte=end_date_from)
|
|
if end_date_to:
|
|
qs = qs.filter(end_date__lte=end_date_to)
|
|
|
|
data = list(
|
|
qs.values(
|
|
"key_result",
|
|
"employee_objective_id__employee_id__employee_first_name",
|
|
"employee_objective_id__employee_id__employee_last_name",
|
|
"employee_objective_id__objective_id__title",
|
|
"employee_objective_id__objective_id__duration_unit",
|
|
"employee_objective_id__objective_id__duration",
|
|
"start_value",
|
|
"current_value",
|
|
"target_value",
|
|
"start_date",
|
|
"end_date",
|
|
"status",
|
|
"progress_type",
|
|
"employee_objective_id__employee_id__employee_work_info__department_id__department",
|
|
"employee_objective_id__employee_id__employee_work_info__job_role_id__job_role",
|
|
"employee_objective_id__employee_id__employee_work_info__job_position_id__job_position",
|
|
)
|
|
)
|
|
DURATION_UNIT = {
|
|
"days": "Days",
|
|
"months": "Months",
|
|
"years": "Years",
|
|
}
|
|
KEY_RESULT_TARGET = {
|
|
"%": "%",
|
|
"#": "Number",
|
|
"Currency": "Currency",
|
|
}
|
|
|
|
data_list = [
|
|
{
|
|
"Employee": f"{item['employee_objective_id__employee_id__employee_first_name']} {item['employee_objective_id__employee_id__employee_last_name']}",
|
|
"Department": (
|
|
item[
|
|
"employee_objective_id__employee_id__employee_work_info__department_id__department"
|
|
]
|
|
if item[
|
|
"employee_objective_id__employee_id__employee_work_info__department_id__department"
|
|
]
|
|
else "-"
|
|
),
|
|
"Job Position": (
|
|
item[
|
|
"employee_objective_id__employee_id__employee_work_info__job_position_id__job_position"
|
|
]
|
|
if item[
|
|
"employee_objective_id__employee_id__employee_work_info__job_position_id__job_position"
|
|
]
|
|
else "-"
|
|
),
|
|
"Job Role": (
|
|
item[
|
|
"employee_objective_id__employee_id__employee_work_info__job_role_id__job_role"
|
|
]
|
|
if item[
|
|
"employee_objective_id__employee_id__employee_work_info__job_role_id__job_role"
|
|
]
|
|
else "-"
|
|
),
|
|
"Employee Keyresult": item["key_result"],
|
|
"Objective": item["employee_objective_id__objective_id__title"],
|
|
"Objective Duration": f'{item["employee_objective_id__objective_id__duration"]} {DURATION_UNIT.get(item["employee_objective_id__objective_id__duration_unit"])}',
|
|
"Keyresult Start Value": f'{item["start_value"]} {KEY_RESULT_TARGET.get(item["progress_type"])}',
|
|
"Keyresult Target Value": f'{item["target_value"]} {KEY_RESULT_TARGET.get(item["progress_type"])}',
|
|
"Keyresult Current Value": (
|
|
f'{item["current_value"]} {KEY_RESULT_TARGET.get(item["progress_type"])}'
|
|
if item["current_value"]
|
|
else "-"
|
|
),
|
|
"Keyresult Start Date": (
|
|
item["start_date"] if item["start_date"] else "-"
|
|
),
|
|
"Keyresult End Date": item["end_date"] if item["end_date"] else "-",
|
|
"status": item["status"],
|
|
}
|
|
for item in data
|
|
]
|
|
|
|
else:
|
|
data_list = []
|
|
|
|
return JsonResponse(data_list, safe=False)
|