diff --git a/base/views.py b/base/views.py index f9857bd90..df7ca997e 100644 --- a/base/views.py +++ b/base/views.py @@ -804,6 +804,8 @@ def object_delete(request, id, **kwargs): _("This {} is already in use for {}.").format(instance, model_names_str), ), if redirect_path: + previous_data = request.GET.urlencode() + redirect_path = redirect_path + "?" + previous_data return redirect(redirect_path) else: return HttpResponseRedirect(request.META.get("HTTP_REFERER", "/")) diff --git a/pms/filters.py b/pms/filters.py index 0e5785a39..3288b7384 100644 --- a/pms/filters.py +++ b/pms/filters.py @@ -9,7 +9,7 @@ import datetime import django_filters from django import forms from django_filters import DateFilter -from pms.models import EmployeeKeyResult, EmployeeObjective, Feedback, Objective +from pms.models import EmployeeKeyResult, EmployeeObjective, Feedback, KeyResult, Objective from base.methods import reload_queryset from base.filters import FilterSet @@ -226,6 +226,34 @@ class KeyResultFilter(CustomFilterSet): model = EmployeeKeyResult fields = "__all__" +class ActualKeyResultFilter(FilterSet): + """ + Filter through KeyResult model + """ + + search = django_filters.CharFilter(method="search_method") + + class Meta: + model = KeyResult + fields = [ + "progress_type", + "target_value", + "duration", + 'company_id' + ] + + def search_method(self, queryset, _, value: str): + """ + This method is used to search employees and objective + """ + values = value.split(" ") + empty = queryset.model.objects.none() + for split in values: + empty = empty | (queryset.filter(title__icontains=split) + ) + + return empty.distinct() + class ObjectiveReGroup: """ diff --git a/pms/templates/okr/key_result/kr_card.html b/pms/templates/okr/key_result/kr_card.html new file mode 100644 index 000000000..b50d74f3a --- /dev/null +++ b/pms/templates/okr/key_result/kr_card.html @@ -0,0 +1,140 @@ +{% load i18n %} {% load yes_no %} {% load static %} +{% include 'filter_tags.html' %} +{% if messages %} +
+ {% for message in messages %} +
+
+ {{ message }} +
+
+ {% endfor %} +
+{% endif %} +{% if krs %} +
+ {% for kr in krs %} +
+
+
+ Username +
+
+
+ {{kr}} +
+
+ {% trans "Target Value" %} + + {{kr.target_value}} {{kr.progress_type}} + +
+
+ {% trans "Duration" %} + {{kr.duration}}{% trans " Days" %} +
+
+ +
+
+
+ + +
+
+
+ {% endfor %} +
+ +
+ + {% trans "Page" %} {{ krs.number }} {% trans "of" %} {{ krs.paginator.num_pages }}. + + +
+{% else %} + +
+ +
+ {% trans "No search result found!" %} +
+
+ +{% endif %} + diff --git a/pms/templates/okr/key_result/kr_filter.html b/pms/templates/okr/key_result/kr_filter.html new file mode 100644 index 000000000..1dc86c4c8 --- /dev/null +++ b/pms/templates/okr/key_result/kr_filter.html @@ -0,0 +1,66 @@ +{% load static %} +{% load i18n %} + + + +
+
+
{% trans "Key Result" %}
+
+
+
+
+ + {{ f.form.progress_type }} +
+
+
+
+ + {{ f.form.target_value }} +
+
+
+
+
+
+ + {{ f.form.duration }} +
+
+
+
+ + {{ f.form.company_id }} +
+
+
+
+
+
+ + + diff --git a/pms/templates/okr/key_result/kr_list.html b/pms/templates/okr/key_result/kr_list.html new file mode 100644 index 000000000..c02b698ea --- /dev/null +++ b/pms/templates/okr/key_result/kr_list.html @@ -0,0 +1,219 @@ +{% load i18n %} {% load yes_no %} {% load static %} +{% include 'filter_tags.html' %} +{% if messages %} +
+ {% for message in messages %} +
+
+ {{ message }} +
+
+ {% endfor %} +
+{% endif %} +{% if krs %} + + {% comment %}
+ {% trans "Select All" %} +
+ + {% endcomment %} + + +
+
+
+ +
+
    +
+
+
+
+
+ +
+ +
+
+
+
+
+
+ +
+
+
+ {% trans "Key Results" %} +
+
{% trans "Progress Type" %}
+
{% trans "Target Value" %}
+
{% trans "Duration" %}
+
{% trans "Descrption" %}
+ {% comment %}
{% trans "Is Active" %}
{% endcomment %} + +
{% trans "Actions" %}
+
+
+ {% for kr in krs %} +
+
+
+
+ +
+
+
+ {{kr.title}} +
+
+ {{kr.get_progress_type_display}} +
+
+ {{kr.target_value}} +
+
+ {{kr.duration}}{% trans " Days" %} +
+
+ {{kr.description}} +
+ {% comment %}
+ {{kr.target_value}} +
{% endcomment %} + +
+ +
+
+
+ {% endfor %} +
+
+ + + +
+ + {% trans "Page" %} {{ krs.number }} {% trans "of" %} {{ krs.paginator.num_pages }}. + + +
+ +
+{% else %} + +
+ +
+ {% trans "No search result found!" %} +
+
+ +{% endif %} + + \ No newline at end of file diff --git a/pms/templates/okr/key_result/kr_nav.html b/pms/templates/okr/key_result/kr_nav.html new file mode 100644 index 000000000..fb5998381 --- /dev/null +++ b/pms/templates/okr/key_result/kr_nav.html @@ -0,0 +1,126 @@ +{% load i18n %} +
+
+

{% trans "Key Results" %}

+ + + +
+
+
+
+ + +
+
+ +
+ + +
+ {% comment %}
+
+ + +
+
{% endcomment %} + +
+
+
+
\ No newline at end of file diff --git a/pms/templates/okr/key_result/real_kr_form.html b/pms/templates/okr/key_result/real_kr_form.html new file mode 100644 index 000000000..08563870d --- /dev/null +++ b/pms/templates/okr/key_result/real_kr_form.html @@ -0,0 +1,38 @@ +{% load static i18n%} +{% load i18n %} + + +
+ {% if form.instance %} +

+ {% trans "Update Key result" %} +

+ {% else %} +

+ {% trans "Create Key result" %} +

+ {% endif %} + + +
+
+ {% if form.instance %} +
+ {% else %} + + {% endif %} + + {% csrf_token %} + {{form.as_p}} +
+
diff --git a/pms/templates/okr/key_result/view_kr.html b/pms/templates/okr/key_result/view_kr.html new file mode 100644 index 000000000..d4fa5fa0f --- /dev/null +++ b/pms/templates/okr/key_result/view_kr.html @@ -0,0 +1,27 @@ +{% extends 'index.html' %} {% block content %} {% load i18n %} {% load yes_no %} {% load static %} + +{% include "okr/key_result/kr_nav.html" %} + +
+ +
+ {% if krs %} + {% if request.GET.view == 'list' %} + {% include 'okr/key_result/kr_list.html' %} + {% else %} + {% include 'okr/key_result/kr_card.html' %} + {% endif %} + {% else %} +
+
+
+ Page not found. 404. +
{% trans "There are currently no key results to consider." %}
+
+
+
+ {% endif %} +
+
+{% endblock content %} + \ No newline at end of file diff --git a/pms/urls.py b/pms/urls.py index 54ae6e519..01903eeba 100644 --- a/pms/urls.py +++ b/pms/urls.py @@ -1,4 +1,6 @@ from django.urls import path + +from base.views import object_delete from . import views from . import models @@ -14,8 +16,18 @@ urlpatterns = [ path("add-assignees/", views.add_assignees, name="add-assignees"), # key results + path("view-key-result/", views.view_key_result, name="view-key-result"), + path("filter-key-result/", views.filter_key_result, name="filter-key-result"), + path("create-key-result/", views.kr_create_or_update, name="create-key-result"), + path("update-key-result/", views.kr_create_or_update, name="update-key-result"), + path( + "delete-key-result//", + object_delete, + name="delete-key-result", + kwargs={"model": models.KeyResult, "redirect_path": "/pms/filter-key-result/"}, + ), path("key-result-creation", views.key_result_create, name="key-result-creation"), - path( + path( "key-reult-remove//", views.key_result_remove, name="key-result-remove", diff --git a/pms/views.py b/pms/views.py index 2597631f1..8d9061dbe 100644 --- a/pms/views.py +++ b/pms/views.py @@ -16,9 +16,11 @@ from horilla.decorators import manager_can_enter, permission_required from horilla.decorators import login_required, hx_request_required from notifications.signals import notify from base.methods import get_key_instances, get_pagination, sortby +from base.views import paginator_qry from base.models import Department, JobPosition from employee.models import Employee, EmployeeWorkInformation from pms.filters import ( + ActualKeyResultFilter, ActualObjectiveFilter, KeyResultFilter, ObjectiveFilter, @@ -231,6 +233,51 @@ def objective_update(request, obj_id): return render(request, "okr/objective_creation.html", context) # key result +@login_required +@permission_required("pms.view_keyresult") +def view_key_result(request): + """ + This method is used render template to view all the key result instances + """ + krs=KeyResult.objects.all() + krs_filter = ActualKeyResultFilter(request.GET) + krs = paginator_qry(krs, request.GET.get("page")) + krs_ids = json.dumps([instance.id for instance in krs.object_list]) + context={ + 'krs':krs, + "f": krs_filter, + "krs_ids": krs_ids, + } + return render(request, "okr/key_result/view_kr.html", context) + + +@login_required +@permission_required("payroll.view_key_result") +def filter_key_result(request): + """ + Filter and retrieve a list of key results based on the provided query parameters. + """ + query_string = request.GET.urlencode() + krs = ActualKeyResultFilter(request.GET).qs + template = "okr/key_result/kr_card.html" + if request.GET.get("view") == "list": + template = "okr/key_result/kr_list.html" + krs = sortby(request, krs, "sortby") + krs = paginator_qry(krs, request.GET.get("page")) + allowance_ids = json.dumps([instance.id for instance in krs.object_list]) + data_dict = parse_qs(query_string) + get_key_instances(KeyResult, data_dict) + return render( + request, + template, + { + "krs": krs, + "pd": query_string, + "filter_dict": data_dict, + "krs_ids": allowance_ids, + }, + ) + @login_required def key_result_create(request): """ @@ -242,17 +289,47 @@ def key_result_create(request): form = KRForm(request.POST) if form.is_valid(): instance = form.save() - obj_data = request.POST.get("dyanamic_create") - obj_data = obj_data.replace("create_new_key_result", str(instance.id)) messages.success( request, _("Key result %(key_result)s created successfully") % {"key_result": instance}, ) - # Redirect to the desired URL with encoded query parameters - redirect_url = f'/pms/objective-creation?{obj_data}' - form = KRForm() + + if request.POST.get('dynamic_create'): + obj_data = request.POST.get("dyanamic_create") + obj_data = obj_data.replace("create_new_key_result", str(instance.id)) + + # Redirect to the desired URL with encoded query parameters + redirect_url = f'/pms/objective-creation?{obj_data}' + form = KRForm() return render(request,'okr/key_result/key_result_form.html',{'k_form':form,'redirect_url':redirect_url}) +@login_required +@permission_required("payroll.add_key_result") +def kr_create_or_update(request,kr_id=None): + form=KRForm() + kr = False + if kr_id is not None: + kr=KeyResult.objects.filter(id=kr_id).first() + form=KRForm(instance=kr) + if request.method == "POST": + if kr: + form = KRForm(request.POST, instance=kr) + if form.is_valid(): + instance = form.save() + messages.success( + request, + _("Key result %(key_result)s updated successfully") % {"key_result": instance}, + ) + else: + form = KRForm(request.POST) + if form.is_valid(): + instance = form.save() + messages.success( + request, + _("Key result %(key_result)s created successfully") % {"key_result": instance}, + ) + return HttpResponse("") + return render(request,'okr/key_result/real_kr_form.html',{'form':form}) @login_required def add_assignees(request, obj_id): diff --git a/templates/sidebar.html b/templates/sidebar.html index addaf630d..07dd35278 100755 --- a/templates/sidebar.html +++ b/templates/sidebar.html @@ -707,6 +707,15 @@ > {% if perms.pms.view_period or request.user|is_reportingmanager %} +
  • + {% trans "Key Results" %} +
  • + {% endif %} + {% if perms.pms.view_period or request.user|is_reportingmanager %}