From a8af8b78ef4b1b57809023a77055ebccb3971f20 Mon Sep 17 00:00:00 2001 From: Horilla Date: Fri, 14 Jun 2024 10:48:36 +0530 Subject: [PATCH 01/16] [FIX] BASE: Employee filter badge count wrong indication --- horilla_views/templates/generic/group_by.html | 2 +- horilla_views/templates/generic/horilla_card.html | 2 +- horilla_views/templates/generic/horilla_list.html | 2 +- horilla_views/templates/generic/horilla_nav.html | 4 ++-- templates/sidebar.html | 3 ++- 5 files changed, 7 insertions(+), 6 deletions(-) diff --git a/horilla_views/templates/generic/group_by.html b/horilla_views/templates/generic/group_by.html index ef763b7ea..84ec53d15 100644 --- a/horilla_views/templates/generic/group_by.html +++ b/horilla_views/templates/generic/group_by.html @@ -10,7 +10,7 @@ reloadSelectedCount($('#count_{{view_id|safe}}')); " style="cursor: pointer;"> - {% trans "Select All" %}{{select_all_path}} + {% trans "Select All" %} {{queryset.paginator.count}}
{% for action in actions %}
  • - {{action.action}} + {{instance|getattribute:action.action|default:action.action}}
  • {% endfor %} diff --git a/horilla_views/templates/generic/horilla_list.html b/horilla_views/templates/generic/horilla_list.html index 76b5e0541..8becf9257 100644 --- a/horilla_views/templates/generic/horilla_list.html +++ b/horilla_views/templates/generic/horilla_list.html @@ -14,7 +14,7 @@ reloadSelectedCount($('#count_{{view_id|safe}}')); " style="cursor: pointer;"> - {% trans "Select All" %}{{select_all_path}} + {% trans "Select All" %} {{queryset.paginator.count}}
    {{nav_title}} @@ -214,7 +214,7 @@

    {{nav_title}}

    - \ No newline at end of file + From 102413d202e2f256eb1b363e075c5922ce20ca1f Mon Sep 17 00:00:00 2001 From: Horilla Date: Fri, 14 Jun 2024 14:47:23 +0530 Subject: [PATCH 04/16] [FIX] ONBOARDING: Fixed closed recruitments also showing on the initial load on onboarding view --- onboarding/views.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/onboarding/views.py b/onboarding/views.py index 84e4f1dc4..6f3ec239f 100644 --- a/onboarding/views.py +++ b/onboarding/views.py @@ -810,6 +810,8 @@ def onboarding_view(request): ) recruitments = recruitments.filter(is_active=True).distinct() status = request.GET.get("closed") + if not status: + recruitments = recruitments.filter(closed=False) onboarding_stages = OnboardingStage.objects.all() choices = CandidateTask.choice From 820b6d080655f3a45512e841ef3f1c90d65da2af Mon Sep 17 00:00:00 2001 From: Horilla Date: Fri, 14 Jun 2024 14:47:35 +0530 Subject: [PATCH 05/16] [FIX] ASSET: Fixed permission in sidebar --- asset/sidebar.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/asset/sidebar.py b/asset/sidebar.py index 44296aa09..b8f6e22c1 100644 --- a/asset/sidebar.py +++ b/asset/sidebar.py @@ -12,12 +12,12 @@ { "menu": trans("Dashboard"), "redirect": reverse("asset-dashboard"), - "accessability": "asset.sidebar.dashboard_accessability", + "accessibility": "asset.sidebar.dashboard_accessibility", }, { "menu": trans("Asset View"), "redirect": reverse("asset-category-view"), - "accessability": "asset.sidebar.dashboard_accessability", + "accessibility": "asset.sidebar.dashboard_accessibility", }, { "menu": trans("Request and Allocation"), @@ -30,5 +30,5 @@ ] -def dashboard_accessability(request, submenu, user_perms, *args, **kwargs): +def dashboard_accessibility(request, submenu, user_perms, *args, **kwargs): return request.user.has_perm("asset.view_assetcategory") From a5a51ba027e671d50c223ea7a010e0dc849aa6ba Mon Sep 17 00:00:00 2001 From: Horilla Date: Fri, 14 Jun 2024 14:47:54 +0530 Subject: [PATCH 06/16] [FIX] ATTENDANCE: Fixed permission in sidebar --- attendance/sidebar.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/attendance/sidebar.py b/attendance/sidebar.py index d9ba2945c..8b31ca505 100644 --- a/attendance/sidebar.py +++ b/attendance/sidebar.py @@ -18,6 +18,7 @@ { "menu": trans("Dashboard"), "redirect": reverse("attendance-dashboard"), + "accessibility": "attendance.sidebar.dashboard_accessibility", }, { "menu": trans("Attendances"), @@ -68,3 +69,9 @@ def work_record_accessibility(request, submenu, user_perms, *args, **kwargs): return request.user.has_perm("attendance.view_attendance") or is_reportingmanager( request.user ) + + +def dashboard_accessibility(request, submenu, user_perms, *args, **kwargs): + return request.user.has_perm("attendance.view_attendance") or is_reportingmanager( + request.user + ) From 043772cc5fdd26cac49b3ae069256d8ce08722f7 Mon Sep 17 00:00:00 2001 From: Horilla Date: Fri, 14 Jun 2024 14:48:12 +0530 Subject: [PATCH 07/16] [FIX] ATTENDANCE: Fixed permissions and filtersubordinate in attendance dashboard --- .../attendance/dashboard/overtime_table.html | 2 +- .../attendance/dashboard/to_validate_table.html | 6 +++--- attendance/views/dashboard.py | 17 +++++++++++++++++ 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/attendance/templates/attendance/dashboard/overtime_table.html b/attendance/templates/attendance/dashboard/overtime_table.html index 3dde1005d..3e79f8789 100644 --- a/attendance/templates/attendance/dashboard/overtime_table.html +++ b/attendance/templates/attendance/dashboard/overtime_table.html @@ -26,7 +26,7 @@ > {% trans "Overtime" %}
    -
    +
    {% trans "Actions" %}
    {% for attendance in overtime_attendances %} diff --git a/attendance/templates/attendance/dashboard/to_validate_table.html b/attendance/templates/attendance/dashboard/to_validate_table.html index bc0b504bd..18fc51933 100644 --- a/attendance/templates/attendance/dashboard/to_validate_table.html +++ b/attendance/templates/attendance/dashboard/to_validate_table.html @@ -1,4 +1,4 @@ -{% load i18n %} +{% load i18n static basefilters %}
    @@ -62,7 +62,7 @@ > {% trans "Pending Hour" %}
    -
    +
    {% trans "Actions" %}
    {% for attendance in validate_attendances %} @@ -111,7 +111,7 @@
    {{attendance.hours_pending}}
    - {% if perms.attendance.change_attendance %} + {% if perms.attendance.change_attendance or request.user|is_reportingmanager %} Date: Fri, 14 Jun 2024 14:48:25 +0530 Subject: [PATCH 08/16] [FIX] RECRUITMENT: Fixed permission in sidebar --- recruitment/sidebar.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/recruitment/sidebar.py b/recruitment/sidebar.py index e0415ddaf..9c8c1f51d 100644 --- a/recruitment/sidebar.py +++ b/recruitment/sidebar.py @@ -127,3 +127,7 @@ def skill_zone_accessibility( return is_stagemanager(request.user) or request.user.has_perm( "recruitment.view_skillzone" ) + + +def dashboard_accessibility(request, submenu, user_perms, *args, **kwargs): + return is_stagemanager(request.user) or "recruitment" in user_perms From 780a2622463c976d6db637029afbf995bd396e01 Mon Sep 17 00:00:00 2001 From: Horilla Date: Fri, 14 Jun 2024 14:49:22 +0530 Subject: [PATCH 09/16] [UPDT] BREADCRUMBS: Saved filters to the breadcrumbs url --- horilla_crumbs/context_processors.py | 29 ++++++++++++++++++- .../generic/reload_select_field.html | 1 - static/index/saveFilters.js | 4 +++ 3 files changed, 32 insertions(+), 2 deletions(-) diff --git a/horilla_crumbs/context_processors.py b/horilla_crumbs/context_processors.py index 2c3daec95..7ef57c367 100644 --- a/horilla_crumbs/context_processors.py +++ b/horilla_crumbs/context_processors.py @@ -140,6 +140,19 @@ def breadcrumbs(request): try: user_breadcrumb = user_breadcrumbs[user_id] + qs = request.META.get("QUERY_STRING", "") + pairs = qs.split("&") + filtered_pairs = [pair for pair in pairs if "=" in pair and pair.split("=")[1]] + filtered_query_string = "&".join(filtered_pairs) + emp_query_string = None + + for item in user_breadcrumb: + if item["name"] in ["employee-view", "candidate-view"]: + items = item["url"].split("?", 1) + if len(items) > 1: + emp_query_string = items[1] + break + parts = _split_path(request) path = base_url @@ -216,14 +229,28 @@ def breadcrumbs(request): pass key = "HTTP_HX_REQUEST" + names = [d["name"] for d in user_breadcrumb] if ( new_dict not in user_breadcrumb - and new_dict["name"] not in remove_urls + and new_dict["name"] not in remove_urls + names and key not in request.META.keys() and not new_dict["name"].isdigit() ): + if new_dict["name"] in ["employee-view", "candidate-view"]: + new_dict["url"] = f'{new_dict["url"]}?{emp_query_string}' + user_breadcrumb.append(new_dict) + try: + prev_url = user_breadcrumb[-1] + prev_url["url"] = prev_url["url"].split("?")[0] + if filtered_query_string: + prev_url["url"] = f'{prev_url["url"]}?{filtered_query_string}' + else: + prev_url["url"] = f'{prev_url["url"]}' + except: + pass + user_breadcrumbs[user_id] = user_breadcrumb except Exception as e: diff --git a/horilla_views/templates/generic/reload_select_field.html b/horilla_views/templates/generic/reload_select_field.html index b423c5700..e7170b829 100644 --- a/horilla_views/templates/generic/reload_select_field.html +++ b/horilla_views/templates/generic/reload_select_field.html @@ -10,4 +10,3 @@ } }); - diff --git a/static/index/saveFilters.js b/static/index/saveFilters.js index 427abf74c..c4bdeab4e 100644 --- a/static/index/saveFilters.js +++ b/static/index/saveFilters.js @@ -56,4 +56,8 @@ $(document).ready(function () { }; localStorage.setItem("savedFilters", JSON.stringify(filterDetails)); }); + + var url = window.location.href; + var newUrl = url.split('?')[0]; + history.replaceState(null, '', newUrl); }); From 55abe529a70f11decf8a6815a60f744454fb445b Mon Sep 17 00:00:00 2001 From: Horilla Date: Sat, 15 Jun 2024 14:06:05 +0530 Subject: [PATCH 10/16] [FIX] ASSET: Fixed date formatter not showing in asset history --- asset/templates/asset_history/asset_history_list.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/asset/templates/asset_history/asset_history_list.html b/asset/templates/asset_history/asset_history_list.html index a6390ce49..c11df63df 100644 --- a/asset/templates/asset_history/asset_history_list.html +++ b/asset/templates/asset_history/asset_history_list.html @@ -22,7 +22,7 @@
    {% trans "Asset" %}
    {% trans "Employee" %}
    {% trans "Assigned Date" %}
    -
    {% trans "Returned Date" %}
    +
    {% trans "Returned Date" %}
    {% trans "Return Status" %}
    @@ -44,8 +44,8 @@
    {{asset_assignement.assigned_to_employee_id}}
    -
    {{asset_assignement.assigned_date}}
    -
    {{asset_assignement.return_date}}
    +
    {{asset_assignement.assigned_date}}
    +
    {{asset_assignement.return_date}}
    {{asset_assignement.return_status}}
    {% endfor %} From 20bc0a6c243bd50efc3a1865eb5b27e053973281 Mon Sep 17 00:00:00 2001 From: Horilla Date: Sat, 15 Jun 2024 14:06:37 +0530 Subject: [PATCH 11/16] [FIX] BASE: Fixed date changer to add to non date items --- attendance/static/attendance/actions.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/attendance/static/attendance/actions.js b/attendance/static/attendance/actions.js index 806c36016..0e7c7aafa 100644 --- a/attendance/static/attendance/actions.js +++ b/attendance/static/attendance/actions.js @@ -1721,10 +1721,12 @@ $(".requested-attendance-row").change(function () { // Iterate through all elements with the 'dateformat_changer' class and format their content $(".dateformat_changer").each(function (index, element) { - var currentDate = $(element).text(); + var currentDate = $(element).text().trim(); // Checking currentDate value is a date or None value. if (/[\.,\-\/]/.test(currentDate)) { var formattedDate = dateFormatter.getFormattedDate(currentDate); + } else if (currentDate) { + var formattedDate = currentDate; } else { var formattedDate = "None"; } @@ -1741,11 +1743,13 @@ var formattedDate = dateFormatter.getFormattedDate(currentDate); // Iterate through all elements with the 'timeformat_changer' class and format their content $(".timeformat_changer").each(function (index, element) { - var currentTime = $(element).text(); + var currentTime = $(element).text().trim(); // Checking currentTime value is a valid time. if (/[\.:]/.test(currentTime)) { var formattedTime = timeFormatter.getFormattedTime(currentTime); + } else if (currentTime) { + var formattedTime = currentTime; } else { var formattedTime = "None"; } From b55a5ca8498d6aa2fce17b3b95a7949a2a895b35 Mon Sep 17 00:00:00 2001 From: Horilla Date: Sat, 15 Jun 2024 14:07:15 +0530 Subject: [PATCH 12/16] [ADD] HORILLA VIEWS: Accessibility method dynamic mapping to the HCV and HLV --- horilla_views/cbv_methods.py | 17 +++++++-- horilla_views/generic/cbv/views.py | 35 ++++++++++++++++++- horilla_views/templates/generic/group_by.html | 32 +++++++++-------- .../templates/generic/horilla_card.html | 2 ++ .../templates/generic/horilla_list.html | 32 +++++++++-------- .../generic/reload_select_field.html | 1 + .../templatetags/generic_template_filters.py | 17 +++++++++ 7 files changed, 105 insertions(+), 31 deletions(-) diff --git a/horilla_views/cbv_methods.py b/horilla_views/cbv_methods.py index acaaeb0c6..d96d471d1 100644 --- a/horilla_views/cbv_methods.py +++ b/horilla_views/cbv_methods.py @@ -2,6 +2,7 @@ horilla/cbv_methods.py """ +import types import uuid from urllib.parse import urlencode from venv import logger @@ -236,6 +237,14 @@ def sortby( ) reverse = cache[request.session.session_key].reverse none_ids = [] + none_queryset = [] + model = queryset.model + model_attr = getattribute(model, sort_key) + is_method = isinstance(model_attr, types.FunctionType) + if not is_method: + none_queryset = queryset.filter(**{f"{sort_key}__isnull": True}) + none_ids = list(none_queryset.values_list("id", flat=True)) + queryset = queryset.exclude(id__in=none_ids) def _sortby(object): result = getattribute(object, attr=sort_key) @@ -258,10 +267,14 @@ def _sortby(object): except TypeError: none_queryset = list(queryset.filter(id__in=none_ids)) queryset = sorted(queryset.exclude(id__in=none_ids), key=_sortby, reverse=order) - queryset = queryset + none_queryset cache[request.session.session_key].reverse = order - order = "asc" if not order else "desc" + if order: + order = "asc" + queryset = list(queryset) + list(none_queryset) + else: + queryset = list(none_queryset) + list(queryset) + order = "desc" setattr(request, "sort_order", order) setattr(request, "sort_key", sort_key) return queryset diff --git a/horilla_views/generic/cbv/views.py b/horilla_views/generic/cbv/views.py index 6cf64d9f0..614da8b65 100644 --- a/horilla_views/generic/cbv/views.py +++ b/horilla_views/generic/cbv/views.py @@ -52,6 +52,23 @@ class HorillaListView(ListView): bulk_select_option: bool = True action_method: str = """""" + """ + eg: + def accessibility( + request, instance: object = None, user_perms: PermWrapper = [], *args, **kwargs + )->bool: + # True if accessible to the action else False + return True + + actions = [ + { + "action": "Edit", + "accessibility": "path_to_your.accessibility", # path to your accessibility method + "attrs": '''{instance_attributes_called_like_this}''', + }, + etc.. + ] + """ actions: list = [] option_method: str = "" @@ -392,7 +409,23 @@ class HorillaCardView(ListView): search_url: str = "" details: dict = {} - + """ + eg: + def accessibility( + request, instance: object = None, user_perms: PermWrapper = [], *args, **kwargs + )->bool: + # True if accessible to the action else False + return True + + actions = [ + { + "action": "Edit", + "accessibility": "path_to_your.accessibility", # path to your accessibility method + "attrs": '''{instance_attributes_called_like_this}''', + }, + etc.. + ] + """ actions: list = [] card_attrs: str = """""" diff --git a/horilla_views/templates/generic/group_by.html b/horilla_views/templates/generic/group_by.html index 84ec53d15..ef40937a7 100644 --- a/horilla_views/templates/generic/group_by.html +++ b/horilla_views/templates/generic/group_by.html @@ -199,13 +199,15 @@ {% if not option_method %}
    {% for option in options %} - - - + {% if option.accessibility|accessibility:instance %} + + + + {% endif %} {% endfor %}
    {% else %} {{instance|getattribute:option_method|safe}} {% endif %} @@ -215,13 +217,15 @@ {% if not action_method %}
    {% for action in actions %} - - - + {% if action.accessibility|accessibility:instance %} + + + + {% endif %} {% endfor %}
    {% else %} {{instance|getattribute:action_method|safe}} {% endif %} diff --git a/horilla_views/templates/generic/horilla_card.html b/horilla_views/templates/generic/horilla_card.html index 2c232c7c9..65e934009 100644 --- a/horilla_views/templates/generic/horilla_card.html +++ b/horilla_views/templates/generic/horilla_card.html @@ -48,9 +48,11 @@ > diff --git a/horilla_views/templates/generic/horilla_list.html b/horilla_views/templates/generic/horilla_list.html index 8becf9257..c03e6bc90 100644 --- a/horilla_views/templates/generic/horilla_list.html +++ b/horilla_views/templates/generic/horilla_list.html @@ -218,13 +218,15 @@ {% if not option_method %}
    {% for option in options %} - - - + {% if option.accessibility|accessibility:instance %} + + + + {% endif %} {% endfor %}
    {% else %} {{instance|getattribute:option_method|safe}} {% endif %} @@ -234,13 +236,15 @@ {% if not action_method %}
    {% for action in actions %} - - - + {% if action.accessibility|accessibility:instance %} + + + + {% endif %} {% endfor %}
    {% else %} {{instance|getattribute:action_method|safe}} {% endif %} diff --git a/horilla_views/templates/generic/reload_select_field.html b/horilla_views/templates/generic/reload_select_field.html index e7170b829..b423c5700 100644 --- a/horilla_views/templates/generic/reload_select_field.html +++ b/horilla_views/templates/generic/reload_select_field.html @@ -10,3 +10,4 @@ } }); + diff --git a/horilla_views/templatetags/generic_template_filters.py b/horilla_views/templatetags/generic_template_filters.py index 2fd04b8a4..78fbd6342 100644 --- a/horilla_views/templatetags/generic_template_filters.py +++ b/horilla_views/templatetags/generic_template_filters.py @@ -10,8 +10,12 @@ from django import template from django.conf import settings +from django.contrib.auth.context_processors import PermWrapper from django.template.defaultfilters import register +from base.thread_local_middleware import _thread_locals +from horilla.config import import_method + register = template.Library() @@ -60,3 +64,16 @@ def format(string: str, instance: object): formatted_string = string.format(**format_context) return formatted_string + + +@register.filter("accessibility") +def accessibility(method: str, instance=None): + if method: + request = getattr(_thread_locals, "request") + method = import_method(method) + return method( + request, + instance, + PermWrapper(request.user), + ) + return True From 7ac3a3f4d9a602b69823437be8af7ec29e717f86 Mon Sep 17 00:00:00 2001 From: Horilla Date: Sat, 15 Jun 2024 14:07:52 +0530 Subject: [PATCH 13/16] [FIX] HORILLA VIEWS: Search not working --- horilla/filters.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/horilla/filters.py b/horilla/filters.py index c1b8e2b68..65feee164 100755 --- a/horilla/filters.py +++ b/horilla/filters.py @@ -116,7 +116,7 @@ def search_in(self, queryset, name, value): """ Search in generic method for filter field """ - search = value.lower() + search = self.data.get("search", "") search_field = self.data.get("search_field") if not search_field: search_field = self.filters[name].field_name From 2fcedda1b6d516a59e618af9c53cf07c617321b3 Mon Sep 17 00:00:00 2001 From: Horilla Date: Sat, 15 Jun 2024 14:08:12 +0530 Subject: [PATCH 14/16] [UPDT] BASE: Export error handling --- base/methods.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/base/methods.py b/base/methods.py index 4fa687581..3e7a8a340 100644 --- a/base/methods.py +++ b/base/methods.py @@ -560,7 +560,8 @@ def export_data(request, model, form_class, filter_class, file_name): for format_name, format_string in date_formats.items(): if format_name == date_format: value = start_date.strftime(format_string) - + if isinstance(value, datetime): + value = str(value) data_export[verbose_name].append(value) data_frame = pd.DataFrame(data=data_export) From 992f160260ec09b246397b4777b212912c7b4229 Mon Sep 17 00:00:00 2001 From: Horilla Date: Sat, 15 Jun 2024 19:19:55 +0530 Subject: [PATCH 15/16] [UPDT] TEMPLATES: New page for employee work info complete table view --- templates/dashboard.html | 76 ++++++------------------ templates/work_info_complete.html | 97 +++++++++++++++++++++++++++++++ 2 files changed, 114 insertions(+), 59 deletions(-) create mode 100644 templates/work_info_complete.html diff --git a/templates/dashboard.html b/templates/dashboard.html index 71bae931f..96b21c99f 100755 --- a/templates/dashboard.html +++ b/templates/dashboard.html @@ -838,56 +838,29 @@
    {% trans "No Announcements to show." %}
    hx-trigger="load"> +
    - {% if request.user.employee_get.employee_user_id.is_superuser %} -
    - -
    - {% trans "Employee Work Information" %} -
    - - - - -
    - - - - - - - - - - {% for employee_info in employees_with_pending %} - - - - - {% endfor %} - -
    {% trans "Employee" %}{% trans "Progress" %}
    - - {{ employee_info.employee.employee_id }} - - -
    -
    -
    -
    {{ employee_info.completed_field_count }}% {% trans "Completed" %}
    -
    -
    -
    +
    + {% trans "Employee Work Information" %} +
    + + - {% endif %} + + {% if request.user.employee_get.employee_user_id.is_superuser or request.user|is_reportingmanager %} +
    +
    + {% endif %}
    +