diff --git a/attendance/views.py b/attendance/views.py index 7f2ea55ca..727cd2df8 100644 --- a/attendance/views.py +++ b/attendance/views.py @@ -1167,6 +1167,10 @@ def validate_bulk_attendance(request): request.user.employee_get, recipient=attendance.employee_id.employee_user_id, verb=f"Your attendance for the date {attendance.attendance_date} is validated", + verb_ar=f"تم التحقق من حضورك في تاريخ {attendance.attendance_date}", + verb_de=f"Ihre Anwesenheit für das Datum {attendance.attendance_date} wurde bestätigt", + verb_es=f"Se ha validado su asistencia para la fecha {attendance.attendance_date}", + verb_fr=f"Votre présence pour la date {attendance.attendance_date} est validée", redirect="/attendance/view-my-attendance", icon="checkmark", ) @@ -1192,6 +1196,10 @@ def validate_this_attendance(request, obj_id): request.user.employee_get, recipient=attendance.employee_id.employee_user_id, verb=f"Your attendance for the date {attendance.attendance_date} is validated", + verb_ar=f"تم تحقيق حضورك في تاريخ {attendance.attendance_date}", + verb_de=f"Deine Anwesenheit für das Datum {attendance.attendance_date} ist bestätigt.", + verb_es=f"Se valida tu asistencia para la fecha {attendance.attendance_date}.", + verb_fr=f"Votre présence pour la date {attendance.attendance_date} est validée.", redirect="/attendance/view-my-attendance", icon="checkmark", ) @@ -1221,6 +1229,10 @@ def revalidate_this_attendance(request, obj_id): ), verb=f"{attendance.employee_id} requested revalidation for \ {attendance.attendance_date} attendance", + verb_ar=f"{attendance.employee_id} طلب إعادة التحقق من حضور تاريخ {attendance.attendance_date}", + verb_de=f"{attendance.employee_id} beantragte eine Neubewertung der Teilnahme am {attendance.attendance_date}", + verb_es=f"{attendance.employee_id} solicitó la validación nuevamente para la asistencia del {attendance.attendance_date}", + verb_fr=f"{attendance.employee_id} a demandé une revalidation pour la présence du {attendance.attendance_date}", redirect="/attendance/view-my-attendance", icon="refresh", ) @@ -1244,6 +1256,10 @@ def approve_overtime(request, obj_id): request.user.employee_get, recipient=attendance.employee_id.employee_user_id, verb=f"Your {attendance.attendance_date}'s attendance overtime approved.", + verb_ar=f"تمت الموافقة على إضافة ساعات العمل الإضافية لتاريخ {attendance.attendance_date}.", + verb_de=f"Die Überstunden für den {attendance.attendance_date} wurden genehmigt.", + verb_es=f"Se ha aprobado el tiempo extra de asistencia para el {attendance.attendance_date}.", + verb_fr=f"Les heures supplémentaires pour la date {attendance.attendance_date} ont été approuvées.", redirect="/attendance/attendance-overtime-view", icon="checkmark", ) @@ -1267,6 +1283,10 @@ def approve_bulk_overtime(request): request.user.employee_get, recipient=attendance.employee_id.employee_user_id, verb=f"Overtime approved for {attendance.attendance_date}'s attendance", + verb_ar=f"تمت الموافقة على العمل الإضافي لحضور تاريخ {attendance.attendance_date}", + verb_de=f"Überstunden für die Anwesenheit am {attendance.attendance_date} genehmigt", + verb_es=f"Horas extra aprobadas para la asistencia del {attendance.attendance_date}", + verb_fr=f"Heures supplémentaires approuvées pour la présence du {attendance.attendance_date}", redirect="/attendance/attendance-overtime-view", icon="checkmark", ) @@ -1427,9 +1447,9 @@ def dashboard_attendance(request): JsonResponse: returns data set as json """ labels = [ - "On Time", - "Late Come", - "On Break", + _("On Time"), + _("Late Come"), + _("On Break"), ] data_set = [] departments = Department.objects.all() diff --git a/base/scheduler.py b/base/scheduler.py index 4987299f1..ebe9f3196 100644 --- a/base/scheduler.py +++ b/base/scheduler.py @@ -4,11 +4,12 @@ import calendar from notifications.signals import notify -def update_rotating_work_type_assign(rotating_work_type,new_date): +def update_rotating_work_type_assign(rotating_work_type, new_date): """ Here will update the employee work information details and send notification """ from django.contrib.auth.models import User + employee = rotating_work_type.employee_id employee_work_info = employee.employee_work_info work_type1 = rotating_work_type.rotating_work_type_id.work_type1 @@ -26,19 +27,30 @@ def update_rotating_work_type_assign(rotating_work_type,new_date): bot = User.objects.filter(username="Horilla Bot").first() if bot is not None: employee = rotating_work_type.employee_id - notify.send(bot,recipient=employee.employee_user_id,verb="Your Work Type has been changed.",icon="infinite",redirect="/employee/employee-profile") + notify.send( + bot, + recipient=employee.employee_user_id, + verb="Your Work Type has been changed.", + verb_ar="لقد تغير نوع عملك.", + verb_de="Ihre Art der Arbeit hat sich geändert.", + verb_es="Su tipo de trabajo ha sido cambiado.", + verb_fr="Votre type de travail a été modifié.", + icon="infinite", + redirect="/employee/employee-profile", + ) return + def work_type_rotate_after(rotating_work_work_type): """ This method for rotate work type based on after day """ - date_today = datetime.now() + date_today = datetime.now() switch_date = rotating_work_work_type.next_change_date - if switch_date.strftime('%Y-%m-%d') == date_today.strftime('%Y-%m-%d'): + if switch_date.strftime("%Y-%m-%d") == date_today.strftime("%Y-%m-%d"): # calculate the next work type switch date new_date = date_today + timedelta(days=rotating_work_work_type.rotate_after_day) - update_rotating_work_type_assign(rotating_work_work_type,new_date) + update_rotating_work_type_assign(rotating_work_work_type, new_date) return @@ -46,36 +58,38 @@ def work_type_rotate_weekend(rotating_work_type): """ This method for rotate work type based on weekend """ - date_today = datetime.now() + date_today = datetime.now() switch_date = rotating_work_type.next_change_date - if switch_date.strftime('%Y-%m-%d') == date_today.strftime('%Y-%m-%d'): + if switch_date.strftime("%Y-%m-%d") == date_today.strftime("%Y-%m-%d"): # calculate the next work type switch date - day = datetime.now().strftime('%A').lower() + day = datetime.now().strftime("%A").lower() switch_day = rotating_work_type.rotate_every_weekend if day == switch_day: new_date = date_today + timedelta(days=7) - update_rotating_work_type_assign(rotating_work_type,new_date) + update_rotating_work_type_assign(rotating_work_type, new_date) return + def work_type_rotate_every(rotating_work_type): - """ + """ This method for rotate work type based on every month """ date_today = datetime.now() switch_date = rotating_work_type.next_change_date day_date = rotating_work_type.rotate_every - if switch_date.strftime('%Y-%m-%d') == date_today.strftime('%Y-%m-%d'): + if switch_date.strftime("%Y-%m-%d") == date_today.strftime("%Y-%m-%d"): # calculate the next work type switch date - if day_date == switch_date.strftime('%d').lstrip('0'): + if day_date == switch_date.strftime("%d").lstrip("0"): new_date = date_today.replace(month=date_today.month + 1) update_rotating_work_type_assign(rotating_work_type, new_date) - elif day_date == 'last': - year = date_today.strftime('%Y') - month = date_today.strftime('%m') + elif day_date == "last": + year = date_today.strftime("%Y") + month = date_today.strftime("%m") last_day = calendar.monthrange(int(year), int(month) + 1)[1] new_date = datetime(int(year), int(month) + 1, last_day) update_rotating_work_type_assign(rotating_work_type, new_date) - return + return + def rotate_work_type(): """ @@ -83,24 +97,25 @@ def rotate_work_type(): and redirect to the chunk method to execute. """ from base.models import RotatingWorkTypeAssign + rotating_work_types = RotatingWorkTypeAssign.objects.filter(is_active=True) for rotating_work_type in rotating_work_types: based_on = rotating_work_type.based_on - if based_on =='after': + if based_on == "after": work_type_rotate_after(rotating_work_type) - elif based_on == 'weekly': + elif based_on == "weekly": work_type_rotate_weekend(rotating_work_type) - elif based_on == 'monthly': + elif based_on == "monthly": work_type_rotate_every(rotating_work_type) return - -def update_rotating_shift_assign(rotating_shift,new_date): +def update_rotating_shift_assign(rotating_shift, new_date): """ - Here will update the employee work information and send notification + Here will update the employee work information and send notification """ from django.contrib.auth.models import User + employee = rotating_shift.employee_id employee_work_info = employee.employee_work_info shift1 = rotating_shift.rotating_shift_id.shift1 @@ -115,59 +130,72 @@ def update_rotating_shift_assign(rotating_shift,new_date): rotating_shift.current_shift = new rotating_shift.next_shift = next rotating_shift.save() - bot = User.objects.filter(username='Horilla Bot').first() + bot = User.objects.filter(username="Horilla Bot").first() if bot is not None: employee = rotating_shift.employee_id - notify.send(bot,recipient=employee.employee_user_id,verb="Your shift has been changed.",icon="infinite",redirect="/employee/employee-profile") + notify.send( + bot, + recipient=employee.employee_user_id, + verb="Your shift has been changed.", + verb_ar="تم تغيير التحول الخاص بك.", + verb_de="Ihre Schicht wurde geändert.", + verb_es="Tu turno ha sido cambiado.", + verb_fr="Votre quart de travail a été modifié.", + icon="infinite", + redirect="/employee/employee-profile", + ) return + def shift_rotate_after_day(rotating_shift): """ This method for rotate shift based on after day """ - date_today = datetime.now() + date_today = datetime.now() switch_date = rotating_shift.next_change_date - if switch_date.strftime('%Y-%m-%d') == date_today.strftime('%Y-%m-%d'): + if switch_date.strftime("%Y-%m-%d") == date_today.strftime("%Y-%m-%d"): # calculate the next work type switch date new_date = date_today + timedelta(days=rotating_shift.rotate_after_day) - update_rotating_shift_assign(rotating_shift,new_date) + update_rotating_shift_assign(rotating_shift, new_date) return + def shift_rotate_weekend(rotating_shift): """ This method for rotate shift based on weekend """ - date_today = datetime.now() - switch_date = rotating_shift.next_change_date - if switch_date.strftime('%Y-%m-%d') == date_today.strftime('%Y-%m-%d'): + date_today = datetime.now() + switch_date = rotating_shift.next_change_date + if switch_date.strftime("%Y-%m-%d") == date_today.strftime("%Y-%m-%d"): # calculate the next work type switch date - day = datetime.now().strftime('%A').lower() + day = datetime.now().strftime("%A").lower() switch_day = rotating_shift.rotate_every_weekend if day == switch_day: new_date = date_today + timedelta(days=7) - update_rotating_shift_assign(rotating_shift,new_date) + update_rotating_shift_assign(rotating_shift, new_date) return + def shift_rotate_every(rotating_shift): - """ + """ This method for rotate shift based on every month """ date_today = datetime.now() switch_date = rotating_shift.next_change_date day_date = rotating_shift.rotate_every - if switch_date.strftime('%Y-%m-%d') == date_today.strftime('%Y-%m-%d'): + if switch_date.strftime("%Y-%m-%d") == date_today.strftime("%Y-%m-%d"): # calculate the next work type switch date - if day_date == switch_date.strftime('%d').lstrip('0'): + if day_date == switch_date.strftime("%d").lstrip("0"): new_date = date_today.replace(month=date_today.month + 1) update_rotating_shift_assign(rotating_shift, new_date) - elif day_date == 'last': - year = date_today.strftime('%Y') - month = date_today.strftime('%m') + elif day_date == "last": + year = date_today.strftime("%Y") + month = date_today.strftime("%m") last_day = calendar.monthrange(int(year), int(month) + 1)[1] new_date = datetime(int(year), int(month) + 1, last_day) update_rotating_shift_assign(rotating_shift, new_date) - return - + return + def rotate_shift(): """ @@ -175,21 +203,21 @@ def rotate_shift(): and redirect to the chunk method to execute. """ from base.models import RotatingShiftAssign + rotating_shifts = RotatingShiftAssign.objects.filter(is_active=True) for rotating_shift in rotating_shifts: based_on = rotating_shift.based_on # after day condition - if based_on =='after': + if based_on == "after": shift_rotate_after_day(rotating_shift) # weekly condition - elif based_on == 'weekly': + elif based_on == "weekly": shift_rotate_weekend(rotating_shift) # monthly condition - elif based_on == 'monthly': + elif based_on == "monthly": shift_rotate_every(rotating_shift) - + return - def switch_shift(): @@ -199,8 +227,10 @@ def switch_shift(): from base.models import ShiftRequest from django.contrib.auth.models import User - today =date.today() - shift_requests = ShiftRequest.objects.filter(canceled=False,approved=True,requested_date__exact=today,shift_changed=False) + today = date.today() + shift_requests = ShiftRequest.objects.filter( + canceled=False, approved=True, requested_date__exact=today, shift_changed=False + ) for request in shift_requests: work_info = request.employee_id.employee_work_info # updating requested shift to the employee work information. @@ -209,12 +239,23 @@ def switch_shift(): request.approved = True request.shift_changed = True request.save() - bot = User.objects.filter(username='Horilla Bot').first() + bot = User.objects.filter(username="Horilla Bot").first() if bot is not None: employee = request.employee_id - notify.send(bot,recipient=employee.employee_user_id,verb="Shift Changes notification",icon="refresh",redirect="/employee/employee-profile") + notify.send( + bot, + recipient=employee.employee_user_id, + verb="Shift Changes notification", + verb_ar="التحول تغيير الإخطار", + verb_de="Benachrichtigung über Schichtänderungen", + verb_es="Notificación de cambios de turno", + verb_fr="Notification des changements de quart de travail", + icon="refresh", + redirect="/employee/employee-profile", + ) return + def undo_shift(): """ This method undo previous employees shift information regards to the shift request @@ -222,9 +263,15 @@ def undo_shift(): from base.models import ShiftRequest from django.contrib.auth.models import User - today =date.today() + today = date.today() # here will get all the active shift requests - shift_requests = ShiftRequest.objects.filter(canceled=False,approved=True,requested_till__lt=today,is_active=True,shift_changed=True) + shift_requests = ShiftRequest.objects.filter( + canceled=False, + approved=True, + requested_till__lt=today, + is_active=True, + shift_changed=True, + ) for request in shift_requests: work_info = request.employee_id.employee_work_info work_info.shift_id = request.previous_shift_id @@ -232,22 +279,37 @@ def undo_shift(): # making the instance in-active request.is_active = False request.save() - bot = User.objects.filter(username='Horilla Bot').first() + bot = User.objects.filter(username="Horilla Bot").first() if bot is not None: employee = request.employee_id - notify.send(bot,recipient=employee.employee_user_id,verb="Shift changes notification, Requested date expired.",icon="refresh",redirect="/employee/employee-profile") + notify.send( + bot, + recipient=employee.employee_user_id, + verb="Shift changes notification, Requested date expired.", + verb_ar="التحول يغير الإخطار ، التاريخ المطلوب انتهت صلاحيته.", + verb_de="Benachrichtigung über Schichtänderungen, gewünschtes Datum abgelaufen.", + verb_es="Notificación de cambios de turno, Fecha solicitada vencida.", + verb_fr="Notification de changement d'équipe, la date demandée a expiré.", + icon="refresh", + redirect="/employee/employee-profile", + ) return - def switch_work_type(): """ This method change employees work type information regards to the work type request """ from django.contrib.auth.models import User from base.models import WorkTypeRequest - today =date.today() - work_type_requests = WorkTypeRequest.objects.filter(canceled=False,approved=True,requested_date__exact=today,work_type_changed=False) + + today = date.today() + work_type_requests = WorkTypeRequest.objects.filter( + canceled=False, + approved=True, + requested_date__exact=today, + work_type_changed=False, + ) for request in work_type_requests: work_info = request.employee_id.employee_work_info # updating requested work type to the employee work information. @@ -256,12 +318,23 @@ def switch_work_type(): request.approved = True request.work_type_changed = True request.save() - bot = User.objects.filter(username='Horilla Bot').first() + bot = User.objects.filter(username="Horilla Bot").first() if bot is not None: employee = request.employee_id - notify.send(bot,recipient=employee.employee_user_id,verb="Work Type Changes notification",icon="swap-horizontal",redirect="/employee/employee-profile") + notify.send( + bot, + recipient=employee.employee_user_id, + verb="Work Type Changes notification", + verb_ar="إخطار تغييرات نوع العمل", + verb_de="Benachrichtigung über Änderungen des Arbeitstyps", + verb_es="Notificación de cambios de tipo de trabajo", + verb_fr="Notification de changement de type de travail", + icon="swap-horizontal", + redirect="/employee/employee-profile", + ) return + def undo_work_type(): """ This method undo previous employees work type information regards to the work type request @@ -269,9 +342,15 @@ def undo_work_type(): from base.models import WorkTypeRequest from django.contrib.auth.models import User - today =date.today() + today = date.today() # here will get all the active work type requests - work_type_requests = WorkTypeRequest.objects.filter(canceled=False,approved=True,requested_till__lt=today,is_active=True,work_type_changed=True) + work_type_requests = WorkTypeRequest.objects.filter( + canceled=False, + approved=True, + requested_till__lt=today, + is_active=True, + work_type_changed=True, + ) for request in work_type_requests: work_info = request.employee_id.employee_work_info # updating employee work information's work type to previous work type @@ -280,18 +359,28 @@ def undo_work_type(): # making the instance is in-active request.is_active = False request.save() - bot = User.objects.filter(username='Horilla Bot').first() + bot = User.objects.filter(username="Horilla Bot").first() if bot is not None: employee = request.employee_id - notify.send(bot,recipient=employee.employee_user_id,verb="Work type changes notification, Requested date expired.",icon="swap-horizontal",redirect="/employee/employee-profile") + notify.send( + bot, + recipient=employee.employee_user_id, + verb="Work type changes notification, Requested date expired.", + verb_ar="إعلام بتغيير نوع العمل ، انتهاء صلاحية التاريخ المطلوب.", + verb_de="Benachrichtigung über Änderungen des Arbeitstyps, angefordertes Datum abgelaufen.", + verb_es="Notificación de cambios de tipo de trabajo, fecha solicitada vencida.", + verb_fr="Notification de changement de type de travail, la date demandée a expiré.", + icon="swap-horizontal", + redirect="/employee/employee-profile", + ) return scheduler = BackgroundScheduler() -scheduler.add_job(rotate_shift, 'interval', seconds=10) -scheduler.add_job(rotate_work_type, 'interval', seconds=10) -scheduler.add_job(switch_shift, 'interval', seconds=10) -scheduler.add_job(undo_shift, 'interval', seconds=10) -scheduler.add_job(switch_work_type, 'interval', seconds=10) -scheduler.add_job(undo_work_type, 'interval', seconds=10) -scheduler.start() +scheduler.add_job(rotate_shift, "interval", seconds=10) +scheduler.add_job(rotate_work_type, "interval", seconds=10) +scheduler.add_job(switch_shift, "interval", seconds=10) +scheduler.add_job(undo_shift, "interval", seconds=10) +scheduler.add_job(switch_work_type, "interval", seconds=10) +scheduler.add_job(undo_work_type, "interval", seconds=10) +scheduler.start() diff --git a/base/translator.py b/base/translator.py index d0e5ab7ec..7e8dcd1ba 100644 --- a/base/translator.py +++ b/base/translator.py @@ -58,6 +58,37 @@ _("September"), _("October"), _("November"), _("December"), +_("One time date"), +_("Is condition based"), +_("Is taxable"), +_("Is fixed"), +_("Value"), +_("If choice"), +_("Is tax"), +_("If amount"), +_("If condition"), +_("Employer rate"), +_("Contract name"), +_("Contract start date"), +_("Contract end date"), +_("Wage type"), +_("Calculate daily leave amount"), +_("Deduction for one leave amount"), +_("Deduct leave from basic pay"), +_("Job role"), +_("Work type"), +_("Pay frequency"), +_("Filing status"), +_("Contract status"), +_("Contract document"), +_("Is tax"), +_("Update compensation"), +_("Is pretax"), +_("DASHBOARD"), +_("SHIFT REQUESTS"), +_("WORK TYPE REQUESTS"), +_("ATTENDANCE"), +_("ASSET"), _(), _(), _(), @@ -66,23 +97,3 @@ _(), _(), _(), _(), -_(), -_(), -_(), -_(), -_(), -_(), -_(), -_(), -_(), -_(), -_(), -_(), -_(), -_(), -_(), -_(), -_(), -_(), -_(), -_(), \ No newline at end of file diff --git a/base/views.py b/base/views.py index ccd1cd740..8a3f65cdf 100644 --- a/base/views.py +++ b/base/views.py @@ -1,45 +1,100 @@ +""" +views.py + +This module is used to map url pattens with django views or methods +""" +import uuid +import json +from notifications.models import Notification from django.shortcuts import render, redirect -from django.contrib import messages -from django.contrib.auth import authenticate, login, logout -from horilla.decorators import permission_required, login_required, manager_can_enter -from django.contrib.auth.models import Group, User, Permission -from base.forms import CompanyForm, DepartmentForm, JobPositionForm, JobRoleForm, EmployeeShiftForm, EmployeeShiftScheduleForm, EmployeeTypeForm, WorkTypeForm, UserGroupForm, RotatingShiftForm, RotatingShiftAssign, RotatingWorkTypeForm, RotatingWorkTypeAssignForm, RotatingShiftAssignForm, ShiftRequestForm, WorkTypeRequestForm, RotatingShiftAssignUpdateForm, RotatingWorkTypeAssignUpdateForm, EmployeeShiftScheduleUpdateForm, AssignUserGroup, AssignPermission, ResetPasswordForm -from base.models import Company, JobPosition, JobRole, Department, WorkType, EmployeeShift, EmployeeShiftDay, EmployeeShiftSchedule, EmployeeType, RotatingWorkType, RotatingWorkTypeAssign, RotatingShiftAssign, RotatingShift, ShiftRequest, WorkTypeRequest -from employee.models import Employee from django.http import HttpResponse, HttpResponseRedirect, JsonResponse -from datetime import datetime from django.views.decorators.http import require_http_methods -from base.filters import ShiftRequestFilter, WorkTypeRequestFilter, RotatingShiftAssignFilters, RotatingWorkTypeAssignFilter from django.core.paginator import Paginator from django.core.mail import send_mail -import uuid -from horilla.settings import EMAIL_HOST_USER -import json -from base.methods import choosesubordinates, filtersubordinates, sortby -from notifications.signals import notify from django.utils.translation import gettext as _ +from django.contrib import messages +from django.contrib.auth import authenticate, login, logout +from django.contrib.auth.models import Group, User, Permission +from notifications.signals import notify +from horilla.decorators import permission_required, login_required, manager_can_enter +from horilla.settings import EMAIL_HOST_USER +from employee.models import Employee +from base.forms import ( + CompanyForm, + DepartmentForm, + JobPositionForm, + JobRoleForm, + EmployeeShiftForm, + EmployeeShiftScheduleForm, + EmployeeTypeForm, + WorkTypeForm, + UserGroupForm, + RotatingShiftForm, + RotatingShiftAssign, + RotatingWorkTypeForm, + RotatingWorkTypeAssignForm, + RotatingShiftAssignForm, + ShiftRequestForm, + WorkTypeRequestForm, + RotatingShiftAssignUpdateForm, + RotatingWorkTypeAssignUpdateForm, + EmployeeShiftScheduleUpdateForm, + AssignUserGroup, + AssignPermission, + ResetPasswordForm, +) +from base.models import ( + Company, + JobPosition, + JobRole, + Department, + WorkType, + EmployeeShift, + EmployeeShiftDay, + EmployeeShiftSchedule, + EmployeeType, + RotatingWorkType, + RotatingWorkTypeAssign, + RotatingShift, + ShiftRequest, + WorkTypeRequest, +) +from base.filters import ( + ShiftRequestFilter, + WorkTypeRequestFilter, + RotatingShiftAssignFilters, + RotatingWorkTypeAssignFilter, +) +from base.methods import choosesubordinates, filtersubordinates, sortby - -def custom404(request,exception): - - return render(request,'404.html') +def custom404(request, exception): + """ + Custom 404 method + """ + return render(request, "404.html") # Create your views here. def is_reportingmanger(request, instance): """ - If the instance have employee id field then you can use this method to know the request user employee is the reporting manager of the instance + If the instance have employee id field then you can use this method to know the request + user employee is the reporting manager of the instance """ manager = request.user.employee_get try: - employee_workinfo_manager = instance.employee_id.employee_work_info.reporting_manager_id + employee_workinfo_manager = ( + instance.employee_id.employee_work_info.reporting_manager_id + ) except Exception: - return HttpResponse('This Employee Dont Have any work information') + return HttpResponse("This Employee Dont Have any work information") return manager == employee_workinfo_manager def paginator_qry(qryset, page_number): + """ + Common paginator method + """ paginator = Paginator(qryset, 50) qryset = paginator.get_page(page_number) return qryset @@ -47,35 +102,35 @@ def paginator_qry(qryset, page_number): def login_user(request): """ - This method is used render login template and authenticate user + This method is used render login template and authenticate user """ - if request.method == 'POST': - username = request.POST['username'] - password = request.POST['password'] + if request.method == "POST": + username = request.POST["username"] + password = request.POST["password"] user = authenticate(request, username=username, password=password) if user is None: - messages.error(request, _('Invalid username or password.')) - return redirect('/login') + messages.error(request, _("Invalid username or password.")) + return redirect("/login") login(request, user) - messages.success(request, _('Login Success')) - return redirect('/') - return render(request, 'login.html') + messages.success(request, _("Login Success")) + return redirect("/") + return render(request, "login.html") def include_employee_instance(request, form): """ This method is used to include the employee instance to the form - Args: + Args: form: django forms instance """ - queryset = form.fields['employee_id'].queryset + queryset = form.fields["employee_id"].queryset employee = Employee.objects.filter(employee_user_id=request.user) if employee.first() is not None: if queryset.filter(id=employee.first().id).first() is None: queryset = queryset | employee - form.fields['employee_id'].queryset = queryset - return (form) + form.fields["employee_id"].queryset = queryset + return form reset_ids = [] @@ -85,9 +140,9 @@ def forgot_password(request): """ This method is used to send the reset password link to the employee email """ - if request.method == 'POST': + if request.method == "POST": id = str(uuid.uuid4()) - username = request.POST['email'] + username = request.POST["email"] user = User.objects.filter(username=username).first() if user is not None: employee = Employee.objects.filter(employee_user_id=user).first() @@ -95,25 +150,31 @@ def forgot_password(request): if employee.email is not None: send_link(employee, request, id, user) else: - messages.error(request, _('No email found.')) + messages.error(request, _("No email found.")) else: - messages.error(request, 'User not found') - return render(request, 'forgot_password.html') + messages.error(request, "User not found") + return render(request, "forgot_password.html") def send_link(employee, request, id, user): """ Here actually the link will send to the employee email """ - recipient = [employee.email,] - subject = 'Link To Rest Your Password!' - url = request.build_absolute_uri('/') + 'reset-password/' + id - message = f'Reset Your Password {url}.' - reset_ids.append({'uuid': id, 'user': user}) + recipient = [ + employee.email, + ] + subject = "Link To Rest Your Password!" + url = request.build_absolute_uri("/") + "reset-password/" + id + message = f"Reset Your Password {url}." + reset_ids.append({"uuid": id, "user": user}) try: - send_mail(subject=subject, message=message, - from_email=EMAIL_HOST_USER, recipient_list=recipient) - response_success = _('Link sended to {recipient}').format(recipient=recipient) + send_mail( + subject=subject, + message=message, + from_email=EMAIL_HOST_USER, + recipient_list=recipient, + ) + response_success = _("Link sended to {recipient}").format(recipient=recipient) messages.success(request, response_success) except Exception as e: messages.error(request, e) @@ -123,19 +184,18 @@ def reset_password(request, uuid): """ This method is used to reset the current password for the employee """ - user = next((item['user'] - for item in reset_ids if item['uuid'] == uuid), None) + user = next((item["user"] for item in reset_ids if item["uuid"] == uuid), None) form = ResetPasswordForm() - if request.method == 'POST': + if request.method == "POST": form = ResetPasswordForm(request.POST) if form.is_valid(): form.save(user=user) - messages.success(request, _('Password reset success')) - reset_ids.remove({'uuid': uuid, 'user': user}) - return redirect('/login') + messages.success(request, _("Password reset success")) + reset_ids.remove({"uuid": uuid, "user": user}) + return redirect("/login") if user is None: - return HttpResponse('Link Expired...') - return render(request, 'reset_password.html', {'form': form}) + return HttpResponse("Link Expired...") + return render(request, "reset_password.html", {"form": form}) def logout_user(request): @@ -144,27 +204,30 @@ def logout_user(request): """ if request.user: logout(request) - return redirect('/login') + return redirect("/login") @login_required def home(request): + """ + This method is used to render index page + """ if len(EmployeeShiftDay.objects.all()) == 0: days = ( - ('monday', 'Monday'), - ('tuesday', 'Tuesday'), - ('wednesday', 'Wednesday'), - ('thursday', 'Thursday'), - ('friday', 'Friday'), - ('saturday', 'Saturday'), - ('sunday', 'Sunday'), + ("monday", "Monday"), + ("tuesday", "Tuesday"), + ("wednesday", "Wednesday"), + ("thursday", "Thursday"), + ("friday", "Friday"), + ("saturday", "Saturday"), + ("sunday", "Sunday"), ) for day in days: shift_day = EmployeeShiftDay() shift_day.day = day[0] shift_day.save() - return render(request, 'index.html') + return render(request, "index.html") @login_required @@ -172,32 +235,32 @@ def common_settings(request): """ This method is used to render setting page template """ - return render(request, 'settings.html') + return render(request, "settings.html") @login_required -@permission_required('add_group') +@permission_required("add_group") def user_group_create(request): """ - This method is used to create user permission group + This method is used to create user permission group """ form = UserGroupForm() groups = Group.objects.all() - if request.method == 'POST': + if request.method == "POST": form = UserGroupForm(request.POST) if form.is_valid(): form.save() form = UserGroupForm() - - messages.success(request, _('User group created.')) + + messages.success(request, _("User group created.")) return redirect(user_group_create) - return render(request, 'base/auth/group.html', {'form': form, 'groups': groups}) + return render(request, "base/auth/group.html", {"form": form, "groups": groups}) @login_required -@permission_required('add_group') +@permission_required("add_group") def group_assign(request): """ This method is used to assign user group to the users. @@ -208,42 +271,50 @@ def group_assign(request): form = AssignUserGroup(request.POST) if form.is_valid(): form.save() - messages.success(request, _('User group assigned.')) + messages.success(request, _("User group assigned.")) return redirect(group_assign) - return render(request, 'base/auth/group_assign.html', {'form': form, 'groups': paginator_qry(groups, request.GET.get('page'))}) + return render( + request, + "base/auth/group_assign.html", + {"form": form, "groups": paginator_qry(groups, request.GET.get("page"))}, + ) @login_required -@permission_required('view_group') +@permission_required("view_group") def group_assign_view(request): """ This method is used to search the user groups """ - search = '' - if request.GET.get('search') is not None: - search = request.GET.get('search') + search = "" + if request.GET.get("search") is not None: + search = request.GET.get("search") groups = Group.objects.filter(name__icontains=search) - previous_data = request.environ['QUERY_STRING'] - return render(request, 'base/auth/group_assign_view.html', {'groups': paginator_qry(groups, request.GET.get('page')), 'pd': previous_data}) + previous_data = request.environ["QUERY_STRING"] + return render( + request, + "base/auth/group_assign_view.html", + {"groups": paginator_qry(groups, request.GET.get("page")), "pd": previous_data}, + ) @login_required -@permission_required('base.view_group') +@permission_required("base.view_group") def user_group_view(request): """ - This method is used to render template for view all groups + This method is used to render template for view all groups """ - search = '' - if request.GET.get('search') is not None: - search = request.GET['search'] + search = "" + if request.GET.get("search") is not None: + search = request.GET["search"] user_group = Group.objects.filter() - return render(request, 'base/auth/group_assign.html', {'data': user_group}) + return render(request, "base/auth/group_assign.html", {"data": user_group}) @login_required -@permission_required('change_group') -@require_http_methods(['POST']) +@permission_required("change_group") +@require_http_methods(["POST"]) def user_group_permission_remove(request, pid, gid): """ This method is used to remove permission from group. @@ -254,12 +325,12 @@ def user_group_permission_remove(request, pid, gid): group = Group.objects.get(id=1) permission = Permission.objects.get(id=2) group.permissions.remove(permission) - return HttpResponseRedirect(request. META. get('HTTP_REFERER', '/')) + return HttpResponseRedirect(request.META.get("HTTP_REFERER", "/")) @login_required -@permission_required('change_group') -@require_http_methods(['POST']) +@permission_required("change_group") +@require_http_methods(["POST"]) def group_remove_user(request, uid, gid): """ This method is used to remove an user from group permission. @@ -270,11 +341,11 @@ def group_remove_user(request, uid, gid): group = Group.objects.get(id=gid) user = User.objects.get(id=uid) group.user_set.remove(user) - return HttpResponseRedirect(request. META. get('HTTP_REFERER', '/')) + return HttpResponseRedirect(request.META.get("HTTP_REFERER", "/")) @login_required -@permission_required('change_group') +@permission_required("change_group") def user_group_update(request, id): """ This method is used to render updating form template for user permission group @@ -283,20 +354,20 @@ def user_group_update(request, id): """ group = Group.objects.get(id=id) form = UserGroupForm(instance=group) - if request.method == 'POST': + if request.method == "POST": form = UserGroupForm(request.POST, instance=group) if form.is_valid(): form.save() - messages.success(request, _('User group updated.')) + messages.success(request, _("User group updated.")) return redirect(user_group_create) groups = Group.objects.all() - return render(request, 'base/auth/group.html', {'form': form, 'groups': groups}) + return render(request, "base/auth/group.html", {"form": form, "groups": groups}) @login_required -@permission_required('base.delete_group') -@require_http_methods(['POST']) +@permission_required("base.delete_group") +@require_http_methods(["POST"]) def user_group_delete(request, id): """ This method is used to delete user group @@ -306,37 +377,38 @@ def user_group_delete(request, id): """ try: user_group = Group.objects.get(id=id).delete() - messages.success(request, _('User group deleted.')) + messages.success(request, _("User group deleted.")) except Exception as e: messages.error(request, e) - messages.error(request, _('You cannot delete this user group.')) - return redirect('/settings/user-group-create') - + messages.error(request, _("You cannot delete this user group.")) + return redirect("/settings/user-group-create") @login_required -@permission_required('base.add_company') +@permission_required("base.add_company") def company_create(request): """ - This method render template and form to create company and save if the form is valid + This method render template and form to create company and save if the form is valid """ form = CompanyForm() companies = Company.objects.all() - if request.method == 'POST': + if request.method == "POST": form = CompanyForm(request.POST, request.FILES) if form.is_valid(): form.save() form = CompanyForm() - - messages.success(request, _('Company has been created successfully!')) + + messages.success(request, _("Company has been created successfully!")) return redirect(company_create) - return render(request, 'base/company/company.html', {'form': form, 'companies': companies}) + return render( + request, "base/company/company.html", {"form": form, "companies": companies} + ) @login_required -@permission_required('base.change_company') +@permission_required("base.change_company") def company_update(request, id): """ This method is used to update company @@ -347,18 +419,20 @@ def company_update(request, id): companies = Company.objects.all() company = Company.objects.get(id=id) form = CompanyForm(instance=company) - if request.method == 'POST': + if request.method == "POST": form = CompanyForm(request.POST, request.FILES, instance=company) if form.is_valid(): form.save() - messages.success(request, _('Company updated')) + messages.success(request, _("Company updated")) return redirect(company_create) - return render(request, 'base/company/company.html', {'form': form, 'companies': companies}) + return render( + request, "base/company/company.html", {"form": form, "companies": companies} + ) @login_required -@permission_required('base.base.delete_company') -@require_http_methods(['POST']) +@permission_required("base.base.delete_company") +@require_http_methods(["POST"]) def company_delete(request, id): """ This method is used to delete company @@ -368,57 +442,62 @@ def company_delete(request, id): """ try: company = Company.objects.get(id=id).delete() - messages.success(request, _('Company deleted.')) + messages.success(request, _("Company deleted.")) except Exception as e: messages.error(request, e) - messages.error(request, _('This company already in use')) + messages.error(request, _("This company already in use")) return redirect(company_create) - @login_required -@permission_required('base.add_department') +@permission_required("base.add_department") def department(request): """ - This method render renders form and template to create department + This method render renders form and template to create department """ form = DepartmentForm() departments = Department.objects.all() - if request.method == 'POST': + if request.method == "POST": form = DepartmentForm(request.POST) if form.is_valid(): form.save() form = DepartmentForm() - messages.success( - request, _('Department has been created successfully!')) - return render(request, 'base/department/department.html', {'form': form, 'departments': departments}) + messages.success(request, _("Department has been created successfully!")) + return render( + request, + "base/department/department.html", + {"form": form, "departments": departments}, + ) @login_required -@permission_required('base.change_department') +@permission_required("base.change_department") def department_update(request, id): """ This method is used to update department args: - id : department instance id + id : department instance id """ department = Department.objects.get(id=id) departments = Department.objects.all() form = DepartmentForm(instance=department) - if request.method == 'POST': - form = DepartmentForm( - request.POST, instance=department) + if request.method == "POST": + form = DepartmentForm(request.POST, instance=department) if form.is_valid(): form.save() - messages.success(request, _('Department updated.')) - return redirect('/settings/department-creation') - return render(request, 'base/department/department.html', {'form': form, 'departments': departments}) + messages.success(request, _("Department updated.")) + return redirect("/settings/department-creation") + return render( + request, + "base/department/department.html", + {"form": form, "departments": departments}, + ) @login_required -@permission_required('base.delete_department') -@require_http_methods(['POST', 'DELETE']) +@permission_required("base.delete_department") +@require_http_methods(["POST", "DELETE"]) def department_delete(request, id): """ This method is used to delete department instance @@ -427,34 +506,37 @@ def department_delete(request, id): """ try: departments = Department.objects.get(id=id).delete() - messages.success(request, _('Department deleted.')) + messages.success(request, _("Department deleted.")) except Exception as e: messages.error(request, e) - messages.error(request, _('Department already in use.')) + messages.error(request, _("Department already in use.")) - return redirect('/settings/department-creation') + return redirect("/settings/department-creation") @login_required -@permission_required('base.add_jobposition') +@permission_required("base.add_jobposition") def job_position(request): """ - This method is used to create job position + This method is used to create job position """ departments = Department.objects.all() form = JobPositionForm() - if request.method == 'POST': + if request.method == "POST": form = JobPositionForm(request.POST) if form.is_valid(): form.save() - messages.success( - request, _('Job Position has been created successfully!')) - return render(request, 'base/job_position/job_position.html', {'form': form, 'departments': departments}) + messages.success(request, _("Job Position has been created successfully!")) + return render( + request, + "base/job_position/job_position.html", + {"form": form, "departments": departments}, + ) @login_required -@permission_required('base.change_jobposition') +@permission_required("base.change_jobposition") def job_position_update(request, id): """ This method is used to update job position @@ -465,56 +547,60 @@ def job_position_update(request, id): job_position = JobPosition.objects.get(id=id) departments = Department.objects.all() form = JobPositionForm(instance=job_position) - if request.method == 'POST': - form = JobPositionForm( - request.POST, instance=job_position) + if request.method == "POST": + form = JobPositionForm(request.POST, instance=job_position) if form.is_valid(): form.save() - messages.success(request, _('Job position updated.')) + messages.success(request, _("Job position updated.")) return redirect("/settings/job-position-creation") - return render(request, 'base/job_position/job_position.html', {'form': form, 'departments': departments}) + return render( + request, + "base/job_position/job_position.html", + {"form": form, "departments": departments}, + ) @login_required -@permission_required('base.delete_jobposition') -@require_http_methods(['POST']) +@permission_required("base.delete_jobposition") +@require_http_methods(["POST"]) def job_position_delete(request, id): """ This method is used to delete job position - args: - id : job position id + args: + id : job position id """ try: job_position = JobPosition.objects.get(id=id).delete() - messages.success(request, _('Job Position Deleted.')) + messages.success(request, _("Job Position Deleted.")) except Exception as e: messages.error(request, e) - messages.error(request, _('This job position already in use.')) - return redirect('/settings/job-position-creation') + messages.error(request, _("This job position already in use.")) + return redirect("/settings/job-position-creation") @login_required -@permission_required('base.add_jobrole') +@permission_required("base.add_jobrole") def job_role_create(request): """ - This method is used to create job role. + This method is used to create job role. """ form = JobRoleForm() jobs = JobPosition.objects.all() - if request.method == 'POST': + if request.method == "POST": form = JobRoleForm(request.POST) if form.is_valid(): form.save() form = JobRoleForm() - - messages.success( - request, _('Job role has been created successfully!')) - return render(request, 'base/job_role/job_role.html', {'form': form, 'job_positions': jobs}) + + messages.success(request, _("Job role has been created successfully!")) + return render( + request, "base/job_role/job_role.html", {"form": form, "job_positions": jobs} + ) @login_required -@permission_required('base.change_jobrole') +@permission_required("base.change_jobrole") def job_role_update(request, id): """ This method is used to update job role instance @@ -527,55 +613,59 @@ def job_role_update(request, id): jobs = JobPosition.objects.all() form = JobRoleForm(instance=job_role) - if request.method == 'POST': + if request.method == "POST": form = JobRoleForm(request.POST, instance=job_role) if form.is_valid(): form.save() - messages.success(request, _('Job role updated.')) - return render(request, 'base/job_role/job_role.html', {'form': form, 'job_positions': jobs}) + messages.success(request, _("Job role updated.")) + return render( + request, "base/job_role/job_role.html", {"form": form, "job_positions": jobs} + ) @login_required -@permission_required('base.delete_jobrole') -@require_http_methods(['POST']) +@permission_required("base.delete_jobrole") +@require_http_methods(["POST"]) def job_role_delete(request, id): """ This method is used to delete job role args: - id : job role instance id + id : job role instance id """ try: job_role = JobRole.objects.get(id=id).delete() - messages.success(request, _('Job Role Deleted.')) + messages.success(request, _("Job Role Deleted.")) except Exception as e: messages.error(request, e) - messages.error(request, _('This job role already in use.')) - return redirect('/settings/job-role-create') - + messages.error(request, _("This job role already in use.")) + return redirect("/settings/job-role-create") @login_required -@permission_required('base.add_worktype') +@permission_required("base.add_worktype") def work_type_create(request): """ - This method is used to create work type + This method is used to create work type """ form = WorkTypeForm() work_types = WorkType.objects.all() - if request.method == 'POST': + if request.method == "POST": form = WorkTypeForm(request.POST) if form.is_valid(): form.save() form = WorkTypeForm() - - messages.success( - request, _('Work Type has been created successfully!')) - return render(request, 'base/work_type/work_type.html', {'form': form, 'work_types': work_types}) + + messages.success(request, _("Work Type has been created successfully!")) + return render( + request, + "base/work_type/work_type.html", + {"form": form, "work_types": work_types}, + ) @login_required -@permission_required('base.change_worktype') +@permission_required("base.change_worktype") def work_type_update(request, id): """ This method is used to update work type instance @@ -587,54 +677,62 @@ def work_type_update(request, id): work_type = WorkType.objects.get(id=id) work_types = WorkType.objects.all() form = WorkTypeForm(instance=work_type) - if request.method == 'POST': + if request.method == "POST": form = WorkTypeForm(request.POST, instance=work_type) if form.is_valid(): form.save() - messages.success(request, _('Work type updated.')) + messages.success(request, _("Work type updated.")) return redirect(work_type_create) - return render(request, 'base/work_type/work_type.html', {'form': form, 'work_types': work_types}) + return render( + request, + "base/work_type/work_type.html", + {"form": form, "work_types": work_types}, + ) @login_required -@permission_required('base.delete_worktype') -@require_http_methods(['POST', 'DELETE']) +@permission_required("base.delete_worktype") +@require_http_methods(["POST", "DELETE"]) def work_type_delete(request, id): """ This method is used to delete work type instance args: - id : work type instance id + id : work type instance id """ try: work_type = WorkType.objects.get(id=id).delete() - messages.success(request, _('Work type deleted.')) + messages.success(request, _("Work type deleted.")) except Exception as e: messages.error(request, e) - messages.error(request, _('This work type already in use.')) - return redirect('/settings/work-type-create') + messages.error(request, _("This work type already in use.")) + return redirect("/settings/work-type-create") @login_required -@permission_required('base.add_rotatingworktype') +@permission_required("base.add_rotatingworktype") def rotating_work_type_create(request): """ - This method is used to create rotating work type . + This method is used to create rotating work type . """ form = RotatingWorkTypeForm() - if request.method == 'POST': + if request.method == "POST": form = RotatingWorkTypeForm(request.POST) if form.is_valid(): form.save() form = RotatingWorkTypeForm() - - messages.success(request, _('Rotating work type created.')) + + messages.success(request, _("Rotating work type created.")) return redirect(rotating_work_type_create) - return render(request, 'base/rotating_work_type/rotating_work_type.html', {'form': form, 'rwork_type': RotatingWorkType.objects.all()}) + return render( + request, + "base/rotating_work_type/rotating_work_type.html", + {"form": form, "rwork_type": RotatingWorkType.objects.all()}, + ) @login_required -@permission_required('base.change_rotatingworktype') +@permission_required("base.change_rotatingworktype") def rotating_work_type_update(request, id): """ This method is used to update rotating work type instance. @@ -645,239 +743,311 @@ def rotating_work_type_update(request, id): rotating_work_type = RotatingWorkType.objects.get(id=id) form = RotatingWorkTypeForm(instance=rotating_work_type) - if request.method == 'POST': + if request.method == "POST": form = RotatingWorkTypeForm(request.POST, instance=rotating_work_type) if form.is_valid(): form.save() - messages.success(request, _('Rotating work type updated.')) + messages.success(request, _("Rotating work type updated.")) return redirect(rotating_work_type_create) - return render(request, 'base/rotating_work_type/rotating_work_type.html', {'form': form, 'rwork_type': RotatingWorkType.objects.all()}) + return render( + request, + "base/rotating_work_type/rotating_work_type.html", + {"form": form, "rwork_type": RotatingWorkType.objects.all()}, + ) @login_required -@permission_required('base.delete_rotatingworktype') -@require_http_methods(['POST', 'DELETE']) +@permission_required("base.delete_rotatingworktype") +@require_http_methods(["POST", "DELETE"]) def rotating_work_type_delete(request, id): """ - This method is used to delete rotating work type + This method is used to delete rotating work type args: id : rotating work type id """ try: rotating_work_type = RotatingWorkType.objects.get(id=id).delete() - messages.success(request, _('Rotating work type deleted.')) + messages.success(request, _("Rotating work type deleted.")) except Exception as e: messages.error(request, e) - messages.error(request, _('This rotating work type already in use.')) - return redirect('/settings/rotating-work-type-create') - + messages.error(request, _("This rotating work type already in use.")) + return redirect("/settings/rotating-work-type-create") @login_required -@manager_can_enter('base.view_rotatingworktypeassign') +@manager_can_enter("base.view_rotatingworktypeassign") def rotating_work_type_assign(request): """ - This method is used to assign rotating work type to employee users + This method is used to assign rotating work type to employee users """ filter = RotatingWorkTypeAssignFilter( - queryset=RotatingWorkTypeAssign.objects.filter(is_active=True)) + queryset=RotatingWorkTypeAssign.objects.filter(is_active=True) + ) rwork_type_assign = filter.qs rwork_type_assign = filtersubordinates( - request, rwork_type_assign, 'base.view_rotatingworktypeassign') + request, rwork_type_assign, "base.view_rotatingworktypeassign" + ) - return render(request, 'base/rotating_work_type/rotating_work_type_assign.html', { - 'f': filter, - 'rwork_type_assign': paginator_qry(rwork_type_assign, request.GET.get('page')), }) + return render( + request, + "base/rotating_work_type/rotating_work_type_assign.html", + { + "f": filter, + "rwork_type_assign": paginator_qry( + rwork_type_assign, request.GET.get("page") + ), + }, + ) @login_required -@manager_can_enter('base.add_rotatingworktypeassign') +@manager_can_enter("base.add_rotatingworktypeassign") def rotating_work_type_assign_add(request): + """ + This method is used to assign rotating work type + """ form = RotatingWorkTypeAssignForm() - form = choosesubordinates(request, form, 'base.add_rotatingworktypeassign') - if request.method == 'POST': + form = choosesubordinates(request, form, "base.add_rotatingworktypeassign") + if request.method == "POST": form = RotatingWorkTypeAssignForm(request.POST) - form = choosesubordinates( - request, form, 'base.add_rotatingworktypeassign') + form = choosesubordinates(request, form, "base.add_rotatingworktypeassign") if form.is_valid(): form.save() - employee_ids = request.POST.getlist('employee_id') - employees = Employee.objects.filter( - id__in=employee_ids).select_related('employee_user_id') + employee_ids = request.POST.getlist("employee_id") + employees = Employee.objects.filter(id__in=employee_ids).select_related( + "employee_user_id" + ) users = [employee.employee_user_id for employee in employees] - notify.send(request.user.employee_get, recipient=users, verb="You are added to rotating work type", - icon="infinite", redirect="/employee/rotating-work-type-assign") + notify.send( + request.user.employee_get, + recipient=users, + verb="You are added to rotating work type", + verb_ar="تمت إضافتك إلى نوع العمل المتناوب", + verb_de="Sie werden zum rotierenden Arbeitstyp hinzugefügt", + verb_es="Se le agrega al tipo de trabajo rotativo", + verb_fr="Vous êtes ajouté au type de travail rotatif", + icon="infinite", + redirect="/employee/rotating-work-type-assign", + ) - messages.success(request, _('Rotating work type assigned.')) + messages.success(request, _("Rotating work type assigned.")) response = render( - request, 'base/rotating_work_type/htmx/rotating_work_type_assign_form.html', {'form': form}) - return HttpResponse(response.content.decode('utf-8') + '') - return render(request, 'base/rotating_work_type/htmx/rotating_work_type_assign_form.html', {'form': form}) + request, + "base/rotating_work_type/htmx/rotating_work_type_assign_form.html", + {"form": form}, + ) + return HttpResponse( + response.content.decode("utf-8") + "" + ) + return render( + request, + "base/rotating_work_type/htmx/rotating_work_type_assign_form.html", + {"form": form}, + ) @login_required -@manager_can_enter('base.view_rotatingworktypeassign') +@manager_can_enter("base.view_rotatingworktypeassign") def rotating_work_type_assign_view(request): """ - This method renders template to view rotating work type objects + This method renders template to view rotating work type objects """ - previous_data = request.environ['QUERY_STRING'] - rwork_type_assign = RotatingWorkTypeAssignFilter( - request.GET).qs - if request.GET.get('is_active') is None: + previous_data = request.environ["QUERY_STRING"] + rwork_type_assign = RotatingWorkTypeAssignFilter(request.GET).qs + if request.GET.get("is_active") is None: rwork_type_assign = rwork_type_assign.filter(is_active=True) rwork_type_assign = filtersubordinates( - request, rwork_type_assign, 'base.view_rotatingworktypeassign') - rwork_type_assign = sortby(request, rwork_type_assign, 'orderby') - return render(request, 'base/rotating_work_type/rotating_work_type_assign_view.html', { - 'rwork_type_assign': paginator_qry(rwork_type_assign, request.GET.get('page')), - 'pd': previous_data, - }) + request, rwork_type_assign, "base.view_rotatingworktypeassign" + ) + rwork_type_assign = sortby(request, rwork_type_assign, "orderby") + return render( + request, + "base/rotating_work_type/rotating_work_type_assign_view.html", + { + "rwork_type_assign": paginator_qry( + rwork_type_assign, request.GET.get("page") + ), + "pd": previous_data, + }, + ) @login_required -@manager_can_enter('base.change_rotatingworktypeassign') +@manager_can_enter("base.change_rotatingworktypeassign") def rotating_work_type_assign_update(request, id): """ - This method is used to update rotating work type instance + This method is used to update rotating work type instance """ rotating_work_type_assign_obj = RotatingWorkTypeAssign.objects.get(id=id) - form = RotatingWorkTypeAssignUpdateForm( - instance=rotating_work_type_assign_obj) - form = choosesubordinates( - request, form, 'base.change_rotatingworktypeassign') - if request.method == 'POST': + form = RotatingWorkTypeAssignUpdateForm(instance=rotating_work_type_assign_obj) + form = choosesubordinates(request, form, "base.change_rotatingworktypeassign") + if request.method == "POST": form = RotatingWorkTypeAssignUpdateForm( - request.POST, instance=rotating_work_type_assign_obj) - form = choosesubordinates( - request, form, 'base.change_rotatingworktypeassign') + request.POST, instance=rotating_work_type_assign_obj + ) + form = choosesubordinates(request, form, "base.change_rotatingworktypeassign") if form.is_valid(): form.save() - messages.success(request, _('Rotating work type assign updated.')) + messages.success(request, _("Rotating work type assign updated.")) response = render( - request, 'base/rotating_work_type/htmx/rotating_work_type_assign_update_form.html', {'update_form': form}) - return HttpResponse(response.content.decode('utf-8') + '') - return render(request, 'base/rotating_work_type/htmx/rotating_work_type_assign_update_form.html', {'update_form': form}) + request, + "base/rotating_work_type/htmx/rotating_work_type_assign_update_form.html", + {"update_form": form}, + ) + return HttpResponse( + response.content.decode("utf-8") + "" + ) + return render( + request, + "base/rotating_work_type/htmx/rotating_work_type_assign_update_form.html", + {"update_form": form}, + ) @login_required -@manager_can_enter('base.change_rotatingworktypeassign') +@manager_can_enter("base.change_rotatingworktypeassign") def rotating_work_type_assign_archive(request, id): """ This method is used to archive or un-archive rotating work type assigns """ rwork_type = RotatingWorkTypeAssign.objects.get(id=id) - employees_rwork_types = RotatingWorkTypeAssign.objects.filter(is_active=True,employee_id=rwork_type.employee_id) + employees_rwork_types = RotatingWorkTypeAssign.objects.filter( + is_active=True, employee_id=rwork_type.employee_id + ) flag = False - if len(employees_rwork_types) < 1 : + if len(employees_rwork_types) < 1: rwork_type.is_active = True flag = True - message = _('un-archived') - if request.GET.get('is_active') == 'False': + message = _("un-archived") + if request.GET.get("is_active") == "False": rwork_type.is_active = False - message = _('archived') - flag = True + message = _("archived") + flag = True rwork_type.save() if flag: - messages.success(request, _('Rotating shift assign is {message}').format(message=message)) + messages.success( + request, _("Rotating shift assign is {message}").format(message=message) + ) else: - messages.error(request,'Already on record is active') - return HttpResponseRedirect(request. META. get('HTTP_REFERER', '/')) + messages.error(request, "Already on record is active") + return HttpResponseRedirect(request.META.get("HTTP_REFERER", "/")) @login_required -@manager_can_enter('base.change_rotatingworktypeassign') +@manager_can_enter("base.change_rotatingworktypeassign") def rotating_work_type_assign_bulk_archive(request): """ This method is used to archive/un-archive bulk rotating work type assigns """ - ids = request.POST['ids'] + ids = request.POST["ids"] ids = json.loads(ids) is_active = True - message = _('un-archived') - if request.GET.get('is_active') == 'False': + message = _("un-archived") + if request.GET.get("is_active") == "False": is_active = False - message = _('archived') + message = _("archived") for id in ids: # check permission right here... rwork_type_assign = RotatingWorkTypeAssign.objects.get(id=id) - employees_rwork_type_assign = RotatingWorkTypeAssign.objects.filter(is_active=True,employee_id=rwork_type_assign.employee_id) + employees_rwork_type_assign = RotatingWorkTypeAssign.objects.filter( + is_active=True, employee_id=rwork_type_assign.employee_id + ) flag = True - if len(employees_rwork_type_assign)<1: - flag=False + if len(employees_rwork_type_assign) < 1: + flag = False rwork_type_assign.is_active = is_active rwork_type_assign.save() if not flag: messages.success( - request, _('Rotating shift for {employee_id} is {message}').format(employee_id=rwork_type_assign.employee_id, message=message)) + request, + _("Rotating shift for {employee_id} is {message}").format( + employee_id=rwork_type_assign.employee_id, message=message + ), + ) else: messages.error( - request, _('Rotating shift for {employee_id} is already exists').format(employee_id=rwork_type_assign.employee_id,) + request, + _("Rotating shift for {employee_id} is already exists").format( + employee_id=rwork_type_assign.employee_id, + ), ) - return JsonResponse({'message': 'Success'}) + return JsonResponse({"message": "Success"}) @login_required -@permission_required('base.delete_rotatingworktypeassign') +@permission_required("base.delete_rotatingworktypeassign") def rotating_work_type_assign_bulk_delete(request): """ This method is used to archive/un-archive bulk rotating work type assigns """ - ids = request.POST['ids'] + ids = request.POST["ids"] ids = json.loads(ids) for id in ids: rwork_type_assign = RotatingWorkTypeAssign.objects.get(id=id) try: rwork_type_assign.delete() - messages.success(request, _('{employee} deleted.').format(employee=rwork_type_assign.employee_id)) + messages.success( + request, + _("{employee} deleted.").format(employee=rwork_type_assign.employee_id), + ) except Exception as e: - messages.error(request, _('You cannot delete {rwork_type_assign}').format(rwork_type_assign=rwork_type_assign)) + messages.error( + request, + _("You cannot delete {rwork_type_assign}").format( + rwork_type_assign=rwork_type_assign + ), + ) messages.error(request, e) - return JsonResponse({'message': 'Success'}) + return JsonResponse({"message": "Success"}) @login_required -@permission_required('base.delete_rotatingworktypeassign') -@require_http_methods(['POST']) +@permission_required("base.delete_rotatingworktypeassign") +@require_http_methods(["POST"]) def rotating_work_type_assign_delete(request, id): """ - This method is used to delete rotating work type + This method is used to delete rotating work type """ try: rotating_work_type_assign_obj = RotatingWorkTypeAssign.objects.get( - id=id).delete() - messages.success(request, _('Rotating work type assign deleted.')) + id=id + ).delete() + messages.success(request, _("Rotating work type assign deleted.")) except Exception as e: messages.error(request, e) - messages.error(request, _('You cannot delete this rotating work type.')) - return redirect('/employee/rotating-work-type-assign') + messages.error(request, _("You cannot delete this rotating work type.")) + return redirect("/employee/rotating-work-type-assign") @login_required -@permission_required('base.add_employeetype') +@permission_required("base.add_employeetype") def employee_type_create(request): """ - This method is used to create employee type + This method is used to create employee type """ form = EmployeeTypeForm() types = EmployeeType.objects.all() - if request.method == 'POST': + if request.method == "POST": form = EmployeeTypeForm(request.POST) if form.is_valid(): form.save() form = EmployeeTypeForm() - messages.success(request, _('Employee type created.')) - return render(request, 'base/employee_type/employee_type.html', {'form': form, 'employee_types': types}) + messages.success(request, _("Employee type created.")) + return render( + request, + "base/employee_type/employee_type.html", + {"form": form, "employee_types": types}, + ) @login_required -@permission_required('base.change_employeetype') +@permission_required("base.change_employeetype") def employee_type_update(request, id): """ This method is used to update employee type instance @@ -889,36 +1059,39 @@ def employee_type_update(request, id): employee_type = EmployeeType.objects.get(id=id) employee_types = EmployeeType.objects.all() form = EmployeeTypeForm(instance=employee_type) - if request.method == 'POST': + if request.method == "POST": form = EmployeeTypeForm(request.POST, instance=employee_type) if form.is_valid(): form.save() - messages.success(request, _('Employee type updated.')) + messages.success(request, _("Employee type updated.")) return redirect(employee_type_create) - return render(request, 'base/employee_type/employee_type.html', {'form': form, 'employee_types': employee_types}) + return render( + request, + "base/employee_type/employee_type.html", + {"form": form, "employee_types": employee_types}, + ) @login_required -@permission_required('base.delete_employeetype') -@require_http_methods(['POST']) +@permission_required("base.delete_employeetype") +@require_http_methods(["POST"]) def employee_type_delete(request, id): """ This method is used to delete employee type args: - id : employee type id + id : employee type id """ try: employee_type = EmployeeType.objects.get(id=id).delete() - messages.success(request, _('Employee type deleted.')) + messages.success(request, _("Employee type deleted.")) except Exception as e: messages.error(request, e) - messages.error(request, _('This Employee type already in use.')) - return redirect('/settings/employee-type-create') - + messages.error(request, _("This Employee type already in use.")) + return redirect("/settings/employee-type-create") @login_required -@permission_required('base.add_employeeshift') +@permission_required("base.add_employeeshift") def employee_shift_create(request): """ This method is used to create employee shift @@ -926,19 +1099,20 @@ def employee_shift_create(request): form = EmployeeShiftForm() shifts = EmployeeShift.objects.all() - if request.method == 'POST': + if request.method == "POST": form = EmployeeShiftForm(request.POST) if form.is_valid(): form.save() form = EmployeeShiftForm() - + messages.success( - request, _('Employee Shift has been created successfully!')) - return render(request, 'base/shift/shift.html', {'form': form, 'shifts': shifts}) + request, _("Employee Shift has been created successfully!") + ) + return render(request, "base/shift/shift.html", {"form": form, "shifts": shifts}) @login_required -@permission_required('base.change_employeeshiftupdate') +@permission_required("base.change_employeeshiftupdate") def employee_shift_update(request, id): """ This method is used to update employee shift instance @@ -949,137 +1123,150 @@ def employee_shift_update(request, id): employee_shift = EmployeeShift.objects.get(id=id) employee_shifts = EmployeeShift.objects.all() form = EmployeeShiftForm(instance=employee_shift) - if request.method == 'POST': - form = EmployeeShiftForm( - request.POST, instance=employee_shift) + if request.method == "POST": + form = EmployeeShiftForm(request.POST, instance=employee_shift) if form.is_valid: form.save() - messages.success(request, _('Shift updated')) + messages.success(request, _("Shift updated")) return redirect(employee_shift_create) - return render(request, 'base/shift/shift.html', {'form': form, 'shifts': employee_shifts}) + return render( + request, "base/shift/shift.html", {"form": form, "shifts": employee_shifts} + ) -@login_required -@permission_required('base.delete_employeeshift') -@require_http_methods(['POST']) +@login_required +@permission_required("base.delete_employeeshift") +@require_http_methods(["POST"]) def employee_shift_delete(request, id): """ This method is used to delete shift args: - id : employee shift instance id + id : employee shift instance id """ try: employee_shift = EmployeeShift.objects.get(id=id).delete() - messages.success(request, _('Employee shift deleted.')) + messages.success(request, _("Employee shift deleted.")) except Exception as e: messages.error(request, e) - messages.error(request, _('This shift already in use.')) - return redirect('/settings/employee-shift-create') - + messages.error(request, _("This shift already in use.")) + return redirect("/settings/employee-shift-create") @login_required -@permission_required('base.add_employeeshiftschedule') +@permission_required("base.add_employeeshiftschedule") def employee_shift_schedule_create(request): """ - This method is used to create schedule for shift + This method is used to create schedule for shift """ form = EmployeeShiftScheduleForm() shifts = EmployeeShift.objects.all() - if request.method == 'POST': + if request.method == "POST": form = EmployeeShiftScheduleForm(request.POST) if form.is_valid(): form.save() form = EmployeeShiftScheduleForm() messages.success( - request, _('Employee Shift Schedule has been created successfully!')) - return render(request, 'base/shift/schedule.html', {'form': form, 'shifts': shifts}) + request, _("Employee Shift Schedule has been created successfully!") + ) + return render(request, "base/shift/schedule.html", {"form": form, "shifts": shifts}) @login_required -@permission_required('base.change_employeeshiftschedule') +@permission_required("base.change_employeeshiftschedule") def employee_shift_schedule_update(request, id): """ - This method is used to update employee shift instance + This method is used to update employee shift instance args: - id : employee shift instance id + id : employee shift instance id """ employee_shift_schedule = EmployeeShiftSchedule.objects.get(id=id) form = EmployeeShiftScheduleUpdateForm(instance=employee_shift_schedule) shifts = EmployeeShift.objects.all() - if request.method == 'POST': + if request.method == "POST": form = EmployeeShiftScheduleUpdateForm( - request.POST, instance=employee_shift_schedule) + request.POST, instance=employee_shift_schedule + ) if form.is_valid(): form.save() - messages.success(request, _('Shift schedule created.')) + messages.success(request, _("Shift schedule created.")) return redirect(employee_shift_schedule_create) - return render(request, 'base/shift/schedule.html', {'form': form, 'shifts': shifts}) + return render(request, "base/shift/schedule.html", {"form": form, "shifts": shifts}) @login_required -@permission_required('base.delete_employeeshiftschedule') -@require_http_methods(['POST']) +@permission_required("base.delete_employeeshiftschedule") +@require_http_methods(["POST"]) def employee_shift_schedule_delete(request, id): """ This method is used to delete employee shift instance args: - id : employee shift instance id + id : employee shift instance id """ try: - employee_shift_schedule = EmployeeShiftSchedule.objects.get( - id=id).delete() - messages.success(request, _('Shift schedule deleted.')) + employee_shift_schedule = EmployeeShiftSchedule.objects.get(id=id).delete() + messages.success(request, _("Shift schedule deleted.")) except Exception as e: messages.error(request, e) - messages.error(request, _('You cannot delete this schedule')) - return redirect('/settings/employee-shift-schedule-create') - + messages.error(request, _("You cannot delete this schedule")) + return redirect("/settings/employee-shift-schedule-create") @login_required -@permission_required('base.add_rotatingshift') +@permission_required("base.add_rotatingshift") def rotating_shift_create(request): """ - This method is used to create rotating shift + This method is used to create rotating shift """ form = RotatingShiftForm() - if request.method == 'POST': + if request.method == "POST": form = RotatingShiftForm(request.POST) if form.is_valid(): form.save() form = RotatingShiftForm() - messages.success(request, _('Rotating shift created.')) - return render(request, 'base/rotating_shift/rotating_shift.html', {'form': form, 'rshifts': RotatingShift.objects.all()}) + messages.success(request, _("Rotating shift created.")) + return render( + request, + "base/rotating_shift/rotating_shift.html", + {"form": form, "rshifts": RotatingShift.objects.all()}, + ) @login_required -@permission_required('base.change_rotatingshift') +@permission_required("base.change_rotatingshift") def rotating_shift_update(request, id): """ This method is used to update rotating shift instance args: - id : rotating shift instance id + id : rotating shift instance id """ rotating_shift = RotatingShift.objects.get(id=id) form = RotatingShiftForm(instance=rotating_shift) - if request.method == 'POST': + if request.method == "POST": form = RotatingShiftForm(request.POST, instance=rotating_shift) if form.is_valid(): form.save() form = RotatingShiftForm() - messages.success(request, _('Rotating shift updated.')) - return redirect(rotating_shift_create) - return render(request, 'base/rotating_shift/rotating_shift.html', {'form': form, 'rshifts': paginator_qry(RotatingShift.objects.all(), request.GET.get('page'))}) + messages.success(request, _("Rotating shift updated.")) + return redirect(rotating_shift_create) + return render( + request, + "base/rotating_shift/rotating_shift.html", + { + "form": form, + "rshifts": paginator_qry( + RotatingShift.objects.all(), request.GET.get("page") + ), + }, + ) @login_required -@permission_required('base.delete_rotatingshift') -@require_http_methods(['POST']) +@permission_required("base.delete_rotatingshift") +@require_http_methods(["POST"]) def rotating_shift_delete(request, id): """ This method is used to delete rotating shift @@ -1089,81 +1276,113 @@ def rotating_shift_delete(request, id): """ try: rotating_shift = RotatingShift.objects.get(id=id).delete() - messages.success(request, _('Rotating shift deleted.')) + messages.success(request, _("Rotating shift deleted.")) except Exception as e: messages.error(request, e) - messages.error(request, _('You cannot delete this rotating shift')) + messages.error(request, _("You cannot delete this rotating shift")) return redirect(rotating_shift_create) @login_required -@manager_can_enter('base.view_rotatingshiftassign') +@manager_can_enter("base.view_rotatingshiftassign") def rotating_shift_assign(request): """ - This method is used to assign rotating shift + This method is used to assign rotating shift """ form = RotatingShiftAssignForm() - form = choosesubordinates(request, form, 'base.add_rotatingshiftassign') + form = choosesubordinates(request, form, "base.add_rotatingshiftassign") filter = RotatingShiftAssignFilters( - queryset=RotatingShiftAssign.objects.filter(is_active=True)) + queryset=RotatingShiftAssign.objects.filter(is_active=True) + ) rshift_assign = filter.qs rshift_assign = filtersubordinates( - request, rshift_assign, 'base.view_rotatingshiftassign') + request, rshift_assign, "base.view_rotatingshiftassign" + ) - return render(request, 'base/rotating_shift/rotating_shift_assign.html', { - 'form': form, - 'f': filter, - 'rshift_assign': paginator_qry(rshift_assign, request.GET.get('page')), - }) + return render( + request, + "base/rotating_shift/rotating_shift_assign.html", + { + "form": form, + "f": filter, + "rshift_assign": paginator_qry(rshift_assign, request.GET.get("page")), + }, + ) @login_required -@manager_can_enter('base.add_rotatingshiftassign') +@manager_can_enter("base.add_rotatingshiftassign") def rotating_shift_assign_add(request): + """ + This method is used to add rotating shift assign + """ form = RotatingShiftAssignForm() - form = choosesubordinates(request, form, 'base.add_rotatingshiftassign') - if request.method == 'POST': + form = choosesubordinates(request, form, "base.add_rotatingshiftassign") + if request.method == "POST": form = RotatingShiftAssignForm(request.POST) - form = choosesubordinates( - request, form, 'base.add_rotatingshiftassign') + form = choosesubordinates(request, form, "base.add_rotatingshiftassign") if form.is_valid(): form.save() - employee_ids = request.POST.getlist('employee_id') - employees = Employee.objects.filter( - id__in=employee_ids).select_related('employee_user_id') + employee_ids = request.POST.getlist("employee_id") + employees = Employee.objects.filter(id__in=employee_ids).select_related( + "employee_user_id" + ) users = [employee.employee_user_id for employee in employees] - notify.send(request.user.employee_get, recipient=users, verb="You are added to rotating shift", - icon="infinite", redirect="/employee/rotating-shift-assign") + notify.send( + request.user.employee_get, + recipient=users, + verb="You are added to rotating shift", + verb_ar="تمت إضافتك إلى وردية الدورية", + verb_de="Sie werden der rotierenden Arbeitsschicht hinzugefügt", + verb_es="Estás agregado a turno rotativo", + verb_fr="Vous êtes ajouté au quart de travail rotatif", + icon="infinite", + redirect="/employee/rotating-shift-assign", + ) - messages.success(request, _('Rotating shift assigned.')) + messages.success(request, _("Rotating shift assigned.")) response = render( - request, 'base/rotating_shift/htmx/rotating_shift_assign_form.html', {'form': form}) - return HttpResponse(response.content.decode('utf-8') + '') - return render(request, 'base/rotating_shift/htmx/rotating_shift_assign_form.html', {'form': form}) + request, + "base/rotating_shift/htmx/rotating_shift_assign_form.html", + {"form": form}, + ) + return HttpResponse( + response.content.decode("utf-8") + "" + ) + return render( + request, + "base/rotating_shift/htmx/rotating_shift_assign_form.html", + {"form": form}, + ) @login_required -@manager_can_enter('base.view_rotatingshiftassign') +@manager_can_enter("base.view_rotatingshiftassign") def rotating_shift_assign_view(request): """ - This method renders all instance of rotating shift assign to a template + This method renders all instance of rotating shift assign to a template """ - previous_data = request.environ['QUERY_STRING'] + previous_data = request.environ["QUERY_STRING"] rshift_assign = RotatingShiftAssignFilters(request.GET).qs - if request.GET.get('is_active') is None: + if request.GET.get("is_active") is None: rshift_assign = rshift_assign.filter(is_active=True) rshift_assign = filtersubordinates( - request, rshift_assign, 'base.view_rotatingshiftassign') - rshift_assign = sortby(request, rshift_assign, 'orderby') - return render(request, 'base/rotating_shift/rotating_shift_assign_view.html', { - 'rshift_assign': paginator_qry(rshift_assign, request.GET.get('page')), - 'pd': previous_data - }) + request, rshift_assign, "base.view_rotatingshiftassign" + ) + rshift_assign = sortby(request, rshift_assign, "orderby") + return render( + request, + "base/rotating_shift/rotating_shift_assign_view.html", + { + "rshift_assign": paginator_qry(rshift_assign, request.GET.get("page")), + "pd": previous_data, + }, + ) @login_required -@manager_can_enter('base.change_rotatingshiftassign') +@manager_can_enter("base.change_rotatingshiftassign") def rotating_shift_assign_update(request, id): """ This method is used to update rotating shift assign instance @@ -1173,63 +1392,82 @@ def rotating_shift_assign_update(request, id): """ rotating_shift_assign_obj = RotatingShiftAssign.objects.get(id=id) form = RotatingShiftAssignUpdateForm(instance=rotating_shift_assign_obj) - form = choosesubordinates(request, form, 'base.change_rotatingshiftassign') - if request.method == 'POST': + form = choosesubordinates(request, form, "base.change_rotatingshiftassign") + if request.method == "POST": form = RotatingShiftAssignUpdateForm( - request.POST, instance=rotating_shift_assign_obj) - form = choosesubordinates( - request, form, 'base.change_rotatingshiftassign') + request.POST, instance=rotating_shift_assign_obj + ) + form = choosesubordinates(request, form, "base.change_rotatingshiftassign") if form.is_valid(): form.save() - messages.success(request, _('Rotating shift assign updated.')) + messages.success(request, _("Rotating shift assign updated.")) response = render( - request, 'base/rotating_shift/htmx/rotating_shift_assign_update_form.html', {'update_form': form, }) - return HttpResponse(response.content.decode('utf-8') + '') - return render(request, 'base/rotating_shift/htmx/rotating_shift_assign_update_form.html', {'update_form': form, }) + request, + "base/rotating_shift/htmx/rotating_shift_assign_update_form.html", + { + "update_form": form, + }, + ) + return HttpResponse( + response.content.decode("utf-8") + "" + ) + return render( + request, + "base/rotating_shift/htmx/rotating_shift_assign_update_form.html", + { + "update_form": form, + }, + ) @login_required -@manager_can_enter('base.change_rotatingshiftassign') +@manager_can_enter("base.change_rotatingshiftassign") def rotating_shift_assign_archive(request, id): """ This method is used to archive and unarchive rotating shift assign records """ rshift = RotatingShiftAssign.objects.get(id=id) - employees_rshift_assign = RotatingShiftAssign.objects.filter(is_active=True,employee_id=rshift.employee_id) + employees_rshift_assign = RotatingShiftAssign.objects.filter( + is_active=True, employee_id=rshift.employee_id + ) flag = False if len(employees_rshift_assign) < 1: rshift.is_active = True flag = True - message = _('un-archived') - if request.GET.get('is_active') == 'False': + message = _("un-archived") + if request.GET.get("is_active") == "False": rshift.is_active = False flag = True - message = _('archived') + message = _("archived") rshift.save() if flag: - messages.success(request, _('Rotating shift assign is {message}').format(message=message)) + messages.success( + request, _("Rotating shift assign is {message}").format(message=message) + ) else: - messages.error(request,'Already on record is active') - return HttpResponseRedirect(request. META. get('HTTP_REFERER', '/')) + messages.error(request, "Already on record is active") + return HttpResponseRedirect(request.META.get("HTTP_REFERER", "/")) @login_required -@manager_can_enter('base.change_rotatingshiftassign') +@manager_can_enter("base.change_rotatingshiftassign") def rotating_shift_assign_bulk_archive(request): """ This method is used to archive/un-archive bulk rotating shift assigns """ - ids = request.POST['ids'] + ids = request.POST["ids"] ids = json.loads(ids) is_active = True - message =_('un-archived') - if request.GET.get('is_active') == 'False': + message = _("un-archived") + if request.GET.get("is_active") == "False": is_active = False - message =_('archived') + message = _("archived") for id in ids: # check permission right here... rshift_assign = RotatingShiftAssign.objects.get(id=id) - employees_rshift_assign = RotatingShiftAssign.objects.filter(is_active=True,employee_id=rshift_assign.employee_id) + employees_rshift_assign = RotatingShiftAssign.objects.filter( + is_active=True, employee_id=rshift_assign.employee_id + ) flag = True if len(employees_rshift_assign) < 1: flag = False @@ -1237,36 +1475,53 @@ def rotating_shift_assign_bulk_archive(request): rshift_assign.save() if not flag: messages.success( - request, _('Rotating shift for {employee} is {message}').format(employee=rshift_assign.employee_id,message=message)) + request, + _("Rotating shift for {employee} is {message}").format( + employee=rshift_assign.employee_id, message=message + ), + ) else: messages.error( - request, _('Rotating shift for {employee} is already exists').format(employee=rshift_assign.employee_id) + request, + _("Rotating shift for {employee} is already exists").format( + employee=rshift_assign.employee_id + ), ) - return JsonResponse({'message': 'Success'}) + return JsonResponse({"message": "Success"}) @login_required -@permission_required('base.delete_rotatingshiftassign') +@permission_required("base.delete_rotatingshiftassign") def rotating_shift_assign_bulk_delete(request): """ This method is used to bulk delete for rotating shift assign """ - ids = request.POST['ids'] + ids = request.POST["ids"] ids = json.loads(ids) for id in ids: rshift_assign = RotatingShiftAssign.objects.get(id=id) try: rshift_assign.delete() - messages.success(request, _('{employee} assign deleted.').format(employee =rshift_assign.employee_id)) + messages.success( + request, + _("{employee} assign deleted.").format( + employee=rshift_assign.employee_id + ), + ) except Exception as e: - messages.error(request, _('You cannot delete {rshift_assign}').format(rshift_assign=rshift_assign)) + messages.error( + request, + _("You cannot delete {rshift_assign}").format( + rshift_assign=rshift_assign + ), + ) messages.error(request, e) - return JsonResponse({'message': 'Success'}) + return JsonResponse({"message": "Success"}) @login_required -@permission_required('base.delete_rotatingshiftassign') -@require_http_methods(['POST']) +@permission_required("base.delete_rotatingshiftassign") +@require_http_methods(["POST"]) def rotating_shift_assign_delete(request, id): """ This method is used to delete rotating shift assign instance @@ -1274,18 +1529,16 @@ def rotating_shift_assign_delete(request, id): id : rotating shift assign instance id """ try: - rotating_shift_assign_obj = RotatingShiftAssign.objects.get( - id=id).delete() - messages.success(request, _('Rotating shift assign deleted.')) + rotating_shift_assign_obj = RotatingShiftAssign.objects.get(id=id).delete() + messages.success(request, _("Rotating shift assign deleted.")) except Exception as e: messages.error(request, e) - messages.error( - request, _('You cannot delete this rotating shift assign.')) - return redirect('/employee/rotating-shift-assign') + messages.error(request, _("You cannot delete this rotating shift assign.")) + return redirect("/employee/rotating-shift-assign") @login_required -@permission_required('add_permission') +@permission_required("add_permission") def employee_permission_assign(request): """ This method is used to assign permissions to employee user @@ -1294,68 +1547,92 @@ def employee_permission_assign(request): employees = Employee.objects.all() permissions = Permission.objects.all() form = AssignPermission() - if request.method == 'POST': + if request.method == "POST": form = AssignPermission(request.POST) if form.is_valid(): form.save() - messages.success(request, _('Employee permission assigned.')) + messages.success(request, _("Employee permission assigned.")) return redirect(employee_permission_assign) - return render(request, 'base/auth/permission.html', { - 'employees': paginator_qry(employees, request.GET.get('page')), - 'form': form - }) - - -@login_required -@permission_required('view_permissions') -def employee_permission_search(request, codename=None, uid=None): - """ - This method renders template to view all instances of user permissions - """ - - search = '' - if request.GET.get('search') is not None: - search = request.GET.get('search') - employees = Employee.objects.filter(employee_first_name__icontains=search) | Employee.objects.filter( - employee_last_name__icontains=search) - previous_data = request.environ['QUERY_STRING'] - return render(request, 'base/auth/permission_view.html', { - 'employees': paginator_qry(employees, request.GET.get('page')), - 'pd': previous_data} + return render( + request, + "base/auth/permission.html", + {"employees": paginator_qry(employees, request.GET.get("page")), "form": form}, ) @login_required -@require_http_methods(['POST']) +@permission_required("view_permissions") +def employee_permission_search(request, codename=None, uid=None): + """ + This method renders template to view all instances of user permissions + """ + + search = "" + if request.GET.get("search") is not None: + search = request.GET.get("search") + employees = Employee.objects.filter( + employee_first_name__icontains=search + ) | Employee.objects.filter(employee_last_name__icontains=search) + previous_data = request.environ["QUERY_STRING"] + return render( + request, + "base/auth/permission_view.html", + { + "employees": paginator_qry(employees, request.GET.get("page")), + "pd": previous_data, + }, + ) + + +@login_required +@require_http_methods(["POST"]) def remove_permission(request, codename, uid): """ This method is used to remove user permission. """ user = User.objects.get(id=uid) - permission_codename = codename.split('.')[1] + permission_codename = codename.split(".")[1] permission = Permission.objects.filter(codename=permission_codename) user.user_permissions.remove(*permission) employees = Employee.objects.all() - page = request.GET.get('page') - return render(request, 'base/auth/permission_view.html', {'employees': paginator_qry(employees, page), 'pd': f'&page={page}'}) + page = request.GET.get("page") + return render( + request, + "base/auth/permission_view.html", + {"employees": paginator_qry(employees, page), "pd": f"&page={page}"}, + ) @login_required def work_type_request_view(request): """ - This method renders template to view all work type requests + This method renders template to view all work type requests """ employee = Employee.objects.filter(employee_user_id=request.user).first() work_type_requests = filtersubordinates( - request, WorkTypeRequest.objects.all(), 'base.add_worktyperequest') + request, WorkTypeRequest.objects.all(), "base.add_worktyperequest" + ) work_type_requests = work_type_requests | WorkTypeRequest.objects.filter( - employee_id=employee) + employee_id=employee + ) f = WorkTypeRequestFilter() form = WorkTypeRequestForm() - form = choosesubordinates(request, form, 'base.add_worktypereqeust',) + form = choosesubordinates( + request, + form, + "base.add_worktypereqeust", + ) form = include_employee_instance(request, form) - return render(request, 'work_type_request/work_type_request_view.html', {'data': paginator_qry(work_type_requests, request.GET.get('page')), 'f': f, 'form': form}) + return render( + request, + "work_type_request/work_type_request_view.html", + { + "data": paginator_qry(work_type_requests, request.GET.get("page")), + "f": f, + "form": form, + }, + ) @login_required @@ -1364,43 +1641,76 @@ def work_type_request_search(request): This method is used to search work type request. """ employee = Employee.objects.filter(employee_user_id=request.user).first() - previous_data = request.environ['QUERY_STRING'] + previous_data = request.environ["QUERY_STRING"] f = WorkTypeRequestFilter(request.GET) - work_typ_requests = filtersubordinates(request, f.qs, 'base.add_worktyperequest') - if set(WorkTypeRequest.objects.filter(employee_id = employee)).issubset(set(f.qs)): - work_typ_requests = work_typ_requests | WorkTypeRequest.objects.filter(employee_id = employee) - work_typ_requests = sortby(request, work_typ_requests, 'orderby') - return render(request, 'work_type_request/htmx/requests.html', {'data': paginator_qry(work_typ_requests, request.GET.get('page')), 'pd': previous_data}) + work_typ_requests = filtersubordinates(request, f.qs, "base.add_worktyperequest") + if set(WorkTypeRequest.objects.filter(employee_id=employee)).issubset(set(f.qs)): + work_typ_requests = work_typ_requests | WorkTypeRequest.objects.filter( + employee_id=employee + ) + work_typ_requests = sortby(request, work_typ_requests, "orderby") + return render( + request, + "work_type_request/htmx/requests.html", + { + "data": paginator_qry(work_typ_requests, request.GET.get("page")), + "pd": previous_data, + }, + ) @login_required def work_type_request(request): """ - This method is used to create request for work type . + This method is used to create request for work type . """ form = WorkTypeRequestForm() - 'canceled' - form = choosesubordinates(request, form, 'base.add_worktyperequest',) + "canceled" + form = choosesubordinates( + request, + form, + "base.add_worktyperequest", + ) form = include_employee_instance(request, form) f = WorkTypeRequestFilter() - if request.method == 'POST': + if request.method == "POST": form = WorkTypeRequestForm(request.POST) - form = choosesubordinates(request, form, 'base.add_worktyperequest',) + form = choosesubordinates( + request, + form, + "base.add_worktyperequest", + ) form = include_employee_instance(request, form) response = render( - request, 'work_type_request/request_form.html', {'form': form, 'f': f}) + request, "work_type_request/request_form.html", {"form": form, "f": f} + ) if form.is_valid(): instance = form.save() try: - notify.send(instance.employee_id, recipient=instance.employee_id.employee_work_info.reporting_manager_id.employee_user_id, - verb=f"You have new work type request to validate for {instance.employee_id}", icon="information", redirect="/shift-requests/shift-request-view") - except Exception as e: + notify.send( + instance.employee_id, + recipient=( + instance.employee_id.employee_work_info.reporting_manager_id.employee_user_id + ), + verb=f"You have new work type request to validate for {instance.employee_id}", + verb_ar=f"لديك طلب نوع وظيفة جديد للتحقق من {instance.employee_id}", + verb_de=f"Sie haben eine neue Arbeitstypanfrage zur Validierung für {instance.employee_id}", + verb_es=f"Tiene una nueva solicitud de tipo de trabajo para validar para {instance.employee_id}", + verb_fr=f"Vous avez une nouvelle demande de type de travail à valider pour {instance.employee_id}", + icon="information", + redirect="/shift-requests/shift-request-view", + ) + except Exception as error: pass - messages.success(request, _('Work type request added.')) - return HttpResponse(response.content.decode('utf-8') + '') + messages.success(request, _("Work type request added.")) + return HttpResponse( + response.content.decode("utf-8") + "" + ) - return render(request, 'work_type_request/request_form.html', {'form': form, 'f': f}) + return render( + request, "work_type_request/request_form.html", {"form": form, "f": f} + ) @login_required @@ -1412,88 +1722,146 @@ def work_type_request_cancel(request, id): """ work_type_request = WorkTypeRequest.objects.get(id=id) - if is_reportingmanger(request, work_type_request) or request.user.has_perm('base.cancel_worktyperequest') or work_type_request.employee_id == request.user.employee_get and work_type_request.approved == False: + if ( + is_reportingmanger(request, work_type_request) + or request.user.has_perm("base.cancel_worktyperequest") + or work_type_request.employee_id == request.user.employee_get + and work_type_request.approved == False + ): work_type_request.canceled = True work_type_request.approved = False - work_type_request.employee_id.employee_work_info.work_type_id = work_type_request.previous_work_type_id + work_type_request.employee_id.employee_work_info.work_type_id = ( + work_type_request.previous_work_type_id + ) work_type_request.employee_id.employee_work_info.save() work_type_request.save() - messages.success(request, _('Work type request has been canceled.')) - notify.send(request.user.employee_get, recipient=work_type_request.employee_id.employee_user_id, - verb='Your work type request has been canceled.', redirect='/', icon='close') - return HttpResponseRedirect(request. META. get('HTTP_REFERER', '/')) - return HttpResponse('You dont have permission') + messages.success(request, _("Work type request has been canceled.")) + notify.send( + request.user.employee_get, + recipient=work_type_request.employee_id.employee_user_id, + verb="Your work type request has been canceled.", + verb_ar="تم إلغاء طلب نوع وظيفتك", + verb_de="Ihre Arbeitstypanfrage wurde storniert", + verb_es="Su solicitud de tipo de trabajo ha sido cancelada", + verb_fr="Votre demande de type de travail a été annulée", + redirect="/", + icon="close", + ) + return HttpResponseRedirect(request.META.get("HTTP_REFERER", "/")) + return HttpResponse("You dont have permission") @login_required -@manager_can_enter('base.change_worktyperequest') +@manager_can_enter("base.change_worktyperequest") def work_type_request_bulk_cancel(request): """ This method is used to cancel a bunch work type request """ - ids = request.POST['ids'] + ids = request.POST["ids"] ids = json.loads(ids) for id in ids: work_type_request = WorkTypeRequest.objects.get(id=id) - if is_reportingmanger(request, work_type_request) or request.user.has_perm('base.cancel_worktyperequest') or work_type_request.employee_id == request.user.employee_get and work_type_request.approved == False: + if ( + is_reportingmanger(request, work_type_request) + or request.user.has_perm("base.cancel_worktyperequest") + or work_type_request.employee_id == request.user.employee_get + and work_type_request.approved == False + ): work_type_request.canceled = True work_type_request.approved = False - work_type_request.employee_id.employee_work_info.work_type_id = work_type_request.previous_work_type_id + work_type_request.employee_id.employee_work_info.work_type_id = ( + work_type_request.previous_work_type_id + ) work_type_request.employee_id.employee_work_info.save() work_type_request.save() - messages.success(request, _('Work type request has been canceled.')) - notify.send(request.user.employee_get, recipient=work_type_request.employee_id.employee_user_id, - verb='Your work type request has been canceled.', redirect='/', icon='close') - return HttpResponseRedirect(request. META. get('HTTP_REFERER', '/')) + messages.success(request, _("Work type request has been canceled.")) + notify.send( + request.user.employee_get, + recipient=work_type_request.employee_id.employee_user_id, + verb="Your work type request has been canceled.", + verb_ar="تم إلغاء طلب نوع وظيفتك.", + verb_de="Ihre Arbeitstypanfrage wurde storniert.", + verb_es="Su solicitud de tipo de trabajo ha sido cancelada.", + verb_fr="Votre demande de type de travail a été annulée.", + redirect="/", + icon="close", + ) + return HttpResponseRedirect(request.META.get("HTTP_REFERER", "/")) @login_required def work_type_request_approve(request, id): """ - This method is used to approve requested work type + This method is used to approve requested work type """ work_type_request = WorkTypeRequest.objects.get(id=id) - if is_reportingmanger(request, work_type_request) or request.user.has_perm('approve_worktyperequest') or request.user.has_perm('change_worktyperequest') and not work_type_request.approved: - + if ( + is_reportingmanger(request, work_type_request) + or request.user.has_perm("approve_worktyperequest") + or request.user.has_perm("change_worktyperequest") + and not work_type_request.approved + ): """ - Here the request will be approved, can send mail right here + Here the request will be approved, can send mail right here """ work_type_request.approved = True work_type_request.canceled = False work_type_request.save() - messages.success(request, _('Work type request has been approved.')) - notify.send(request.user.employee_get, recipient=work_type_request.employee_id.employee_user_id, - verb='Your work type request has been approved.', redirect='/', icon='checkmark') + messages.success(request, _("Work type request has been approved.")) + notify.send( + request.user.employee_get, + recipient=work_type_request.employee_id.employee_user_id, + verb="Your work type request has been approved.", + verb_ar="تمت الموافقة على طلب نوع وظيفتك.", + verb_de="Ihre Arbeitstypanfrage wurde genehmigt.", + verb_es="Su solicitud de tipo de trabajo ha sido aprobada.", + verb_fr="Votre demande de type de travail a été approuvée.", + redirect="/", + icon="checkmark", + ) - return HttpResponseRedirect(request. META. get('HTTP_REFERER', '/')) - return HttpResponse('You Do nt Have Permission') + return HttpResponseRedirect(request.META.get("HTTP_REFERER", "/")) + return HttpResponse("You Do nt Have Permission") @login_required def work_type_request_bulk_approve(request): """ - This method is used to approve bulk of requested work type + This method is used to approve bulk of requested work type """ - ids = request.POST['ids'] + ids = request.POST["ids"] ids = json.loads(ids) for id in ids: work_type_request = WorkTypeRequest.objects.get(id=id) - if is_reportingmanger(request, work_type_request) or request.user.has_perm('approve_worktyperequest') or request.user.has_perm('change_worktyperequest') and not work_type_request.approved: - - """ - Here the request will be approved, can send mail right here - """ + if ( + is_reportingmanger(request, work_type_request) + or request.user.has_perm("approve_worktyperequest") + or request.user.has_perm("change_worktyperequest") + and not work_type_request.approved + ): + # """ + # Here the request will be approved, can send mail right here + # """ work_type_request.approved = True work_type_request.canceled = False employee_work_info = work_type_request.employee_id.employee_work_info employee_work_info.work_type_id = work_type_request.work_type_id employee_work_info.save() work_type_request.save() - messages.success(request, _('Work type request has been approved.')) - notify.send(request.user.employee_get, recipient=work_type_request.employee_id.employee_user_id, - verb='Your work type request has been approved.', redirect='/', icon='checkmark') - return HttpResponseRedirect(request. META. get('HTTP_REFERER', '/')) + messages.success(request, _("Work type request has been approved.")) + notify.send( + request.user.employee_get, + recipient=work_type_request.employee_id.employee_user_id, + verb="Your work type request has been approved.", + verb_ar="تمت الموافقة على طلب نوع وظيفتك.", + verb_de="Ihre Arbeitstypanfrage wurde genehmigt.", + verb_es="Su solicitud de tipo de trabajo ha sido aprobada.", + verb_fr="Votre demande de type de travail a été approuvée.", + redirect="/", + icon="checkmark", + ) + return HttpResponseRedirect(request.META.get("HTTP_REFERER", "/")) @login_required @@ -1506,29 +1874,36 @@ def work_type_request_update(request, id): """ work_type_request = WorkTypeRequest.objects.get(id=id) form = WorkTypeRequestForm(instance=work_type_request) - form = choosesubordinates(request, form, 'base.change_worktyperequest') + form = choosesubordinates(request, form, "base.change_worktyperequest") form = include_employee_instance(request, form) - if request.method == 'POST': + if request.method == "POST": response = render( - request, 'work_type_request/request_update_form.html', {'form': form, }) + request, + "work_type_request/request_update_form.html", + { + "form": form, + }, + ) form = WorkTypeRequestForm(request.POST, instance=work_type_request) - form = choosesubordinates(request, form, 'base.change_worktyperequest') + form = choosesubordinates(request, form, "base.change_worktyperequest") form = include_employee_instance(request, form) if form.is_valid(): form.save() - messages.success(request, _('Request Updated Successfully')) - return HttpResponse(response.content.decode('utf-8') + '') + messages.success(request, _("Request Updated Successfully")) + return HttpResponse( + response.content.decode("utf-8") + "" + ) - return render(request, 'work_type_request/request_update_form.html', {'form': form}) + return render(request, "work_type_request/request_update_form.html", {"form": form}) @login_required -@permission_required('base.delete_worktyperequest') -@require_http_methods(['POST']) +@permission_required("base.delete_worktyperequest") +@require_http_methods(["POST"]) def work_type_request_delete(request, id): """ This method is used to delete work type request - args: + args: id : work type request instance id """ @@ -1536,83 +1911,138 @@ def work_type_request_delete(request, id): work_type_request = WorkTypeRequest.objects.get(id=id) employee = work_type_request.employee_id.employee_user_id work_type_request.delete() - messages.success(request, _('Work type request deleted.')) - notify.send(request.user.employee_get, recipient=employee, - verb='Your work type request has been deleted.', redirect='/', icon='trash') + messages.success(request, _("Work type request deleted.")) + notify.send( + request.user.employee_get, + recipient=employee, + verb="Your work type request has been deleted.", + verb_ar="تم حذف طلب نوع وظيفتك.", + verb_de="Ihre Arbeitstypanfrage wurde gelöscht.", + verb_es="Su solicitud de tipo de trabajo ha sido eliminada.", + verb_fr="Votre demande de type de travail a été supprimée.", + redirect="/", + icon="trash", + ) except Exception as e: messages.error(request, e) - messages.error(request, _('You cannot delete this work type request.')) - return HttpResponseRedirect(request. META. get('HTTP_REFERER', '/')) + messages.error(request, _("You cannot delete this work type request.")) + return HttpResponseRedirect(request.META.get("HTTP_REFERER", "/")) @login_required -@permission_required('base.delete_worktyperequest') -@require_http_methods(['POST']) +@permission_required("base.delete_worktyperequest") +@require_http_methods(["POST"]) def work_type_request_bulk_delete(request): """ This method is used to delete work type request - args: + args: id : work type request instance id """ - ids = request.POST['ids'] + ids = request.POST["ids"] ids = json.loads(ids) for id in ids: try: work_type_request = WorkTypeRequest.objects.get(id=id) user = work_type_request.employee_id.employee_user_id work_type_request.delete() - messages.success(request,_('Work type request deleted.')) - notify.send(request.user.employee_get, recipient=user, - verb='Your work type request has been deleted.', redirect='/', icon='trash') + messages.success(request, _("Work type request deleted.")) + notify.send( + request.user.employee_get, + recipient=user, + verb="Your work type request has been deleted.", + verb_ar="تم حذف طلب نوع وظيفتك.", + verb_de="Ihre Arbeitstypanfrage wurde gelöscht.", + verb_es="Su solicitud de tipo de trabajo ha sido eliminada.", + verb_fr="Votre demande de type de travail a été supprimée.", + redirect="/", + icon="trash", + ) except Exception as e: messages.error(request, e) messages.error( - request, _('You cannot delete {employee} work type request for the date {date}.').format(employee=work_type_request.employee_id,date=work_type_request.requested_date)) - return HttpResponseRedirect(request. META. get('HTTP_REFERER', '/')) + request, + _( + "You cannot delete {employee} work type request for the date {date}." + ).format( + employee=work_type_request.employee_id, + date=work_type_request.requested_date, + ), + ) + return HttpResponseRedirect(request.META.get("HTTP_REFERER", "/")) @login_required def shift_request(request): """ - This method is used to create shift request + This method is used to create shift request """ form = ShiftRequestForm() - form = choosesubordinates(request, form, 'base.add_shiftrequest',) + form = choosesubordinates( + request, + form, + "base.add_shiftrequest", + ) f = ShiftRequestFilter() - if request.method == 'POST': + if request.method == "POST": form = ShiftRequestForm(request.POST) - form = choosesubordinates(request, form, 'base.add_shiftrequest') + form = choosesubordinates(request, form, "base.add_shiftrequest") form = include_employee_instance(request, form) response = render( - request, 'shift_request/request_form.html', {'form': form, 'f': f}) + request, "shift_request/request_form.html", {"form": form, "f": f} + ) if form.is_valid(): instance = form.save() try: - notify.send(instance.employee_id, recipient=instance.employee_id.employee_work_info.reporting_manager_id.employee_user_id, - verb=f"You have new shift request to approve for {instance.employee_id}", icon="information", redirect="/shift-requests/shift-request-view") + notify.send( + instance.employee_id, + recipient=( + instance.employee_id.employee_work_info.reporting_manager_id.employee_user_id + ), + verb=f"You have new shift request to approve for {instance.employee_id}", + verb_ar=f"لديك طلب وردية جديد للموافقة عليه لـ {instance.employee_id}", + verb_de=f"Sie müssen eine neue Schichtanfrage für {instance.employee_id} genehmigen", + verb_es=f"Tiene una nueva solicitud de turno para aprobar para {instance.employee_id}", + verb_fr=f"Vous avez une nouvelle demande de quart de travail à approuver pour {instance.employee_id}", + icon="information", + redirect="/shift-requests/shift-request-view", + ) except Exception as e: pass - messages.success(request, _('Request Added')) - return HttpResponse(response.content.decode('utf-8') + '') - return render(request, 'shift_request/request_form.html', {'form': form, 'f': f}) + messages.success(request, _("Request Added")) + return HttpResponse( + response.content.decode("utf-8") + "" + ) + return render(request, "shift_request/request_form.html", {"form": form, "f": f}) @login_required def shift_request_view(request): """ - This method renders all shift request instances to a template + This method renders all shift request instances to a template """ employee = Employee.objects.filter(employee_user_id=request.user).first() shift_requests = filtersubordinates( - request, ShiftRequest.objects.all(), 'base.add_shiftrequest') - shift_requests = shift_requests | ShiftRequest.objects.filter( - employee_id=employee) + request, ShiftRequest.objects.all(), "base.add_shiftrequest" + ) + shift_requests = shift_requests | ShiftRequest.objects.filter(employee_id=employee) f = ShiftRequestFilter() form = ShiftRequestForm() - form = choosesubordinates(request, form, 'base.add_shiftrequest',) + form = choosesubordinates( + request, + form, + "base.add_shiftrequest", + ) form = include_employee_instance(request, form) - return render(request, 'shift_request/shift_request_view.html', {'data': paginator_qry(shift_requests, request.GET.get('page')), 'f': f, 'form': form}) + return render( + request, + "shift_request/shift_request_view.html", + { + "data": paginator_qry(shift_requests, request.GET.get("page")), + "f": f, + "form": form, + }, + ) @login_required @@ -1621,13 +2051,22 @@ def shift_request_search(request): This method is used search shift request by employee and also used to filter shift request. """ employee = Employee.objects.filter(employee_user_id=request.user).first() - previous_data = request.environ['QUERY_STRING'] + previous_data = request.environ["QUERY_STRING"] f = ShiftRequestFilter(request.GET) - shift_requests = filtersubordinates(request, f.qs, 'base.add_shiftrequest') - if set(ShiftRequest.objects.filter(employee_id = employee)).issubset(set(f.qs)): - shift_requests = shift_requests | ShiftRequest.objects.filter(employee_id = employee) - shift_requests = sortby(request, shift_requests, 'orderby') - return render(request, 'shift_request/htmx/requests.html', {'data': paginator_qry(shift_requests, request.GET.get('page')), 'pd': previous_data}) + shift_requests = filtersubordinates(request, f.qs, "base.add_shiftrequest") + if set(ShiftRequest.objects.filter(employee_id=employee)).issubset(set(f.qs)): + shift_requests = shift_requests | ShiftRequest.objects.filter( + employee_id=employee + ) + shift_requests = sortby(request, shift_requests, "orderby") + return render( + request, + "shift_request/htmx/requests.html", + { + "data": paginator_qry(shift_requests, request.GET.get("page")), + "pd": previous_data, + }, + ) @login_required @@ -1635,24 +2074,31 @@ def shift_request_update(request, id): """ This method is used to update shift request instance args: - id : shift request instance id + id : shift request instance id """ shift_request = ShiftRequest.objects.get(id=id) form = ShiftRequestForm(instance=shift_request) - form = choosesubordinates(request, form, 'base.change_shiftrequest') + form = choosesubordinates(request, form, "base.change_shiftrequest") form = include_employee_instance(request, form) - if request.method == 'POST': + if request.method == "POST": response = render( - request, 'shift_request/request_update_form.html', {'form': form, }) + request, + "shift_request/request_update_form.html", + { + "form": form, + }, + ) form = ShiftRequestForm(request.POST, instance=shift_request) - form = choosesubordinates(request, form, 'base.change_shiftrequest') + form = choosesubordinates(request, form, "base.change_shiftrequest") form = include_employee_instance(request, form) if form.is_valid(): form.save() - messages.success(request, _('Request Updated Successfully')) - return HttpResponse(response.content.decode('utf-8') + '') + messages.success(request, _("Request Updated Successfully")) + return HttpResponse( + response.content.decode("utf-8") + "" + ) - return render(request, 'shift_request/request_update_form.html', {'form': form}) + return render(request, "shift_request/request_update_form.html", {"form": form}) @login_required @@ -1665,84 +2111,134 @@ def shift_request_cancel(request, id): """ shift_request = ShiftRequest.objects.get(id=id) - if is_reportingmanger(request, shift_request) or request.user.has_perm('base.cancel_shiftrequest') or shift_request.employee_id == request.user.employee_get and shift_request.approved == False: + if ( + is_reportingmanger(request, shift_request) + or request.user.has_perm("base.cancel_shiftrequest") + or shift_request.employee_id == request.user.employee_get + and shift_request.approved == False + ): shift_request.canceled = True shift_request.approved = False - shift_request.employee_id.employee_work_info.shift_id = shift_request.previous_shift_id + shift_request.employee_id.employee_work_info.shift_id = ( + shift_request.previous_shift_id + ) shift_request.employee_id.employee_work_info.save() shift_request.save() - messages.success(request, _('Shift request canceled')) - notify.send(request.user.employee_get, recipient=shift_request.employee_id.employee_user_id, - verb='Your shift request has been canceled.', redirect='/', icon='close') + messages.success(request, _("Shift request canceled")) + notify.send( + request.user.employee_get, + recipient=shift_request.employee_id.employee_user_id, + verb="Your shift request has been canceled.", + verb_ar="تم إلغاء طلبك للوردية.", + verb_de="Ihr Schichtantrag wurde storniert.", + verb_es="Se ha cancelado su solicitud de turno.", + verb_fr="Votre demande de quart a été annulée.", + redirect="/", + icon="close", + ) - return HttpResponseRedirect(request. META. get('HTTP_REFERER', '/')) - return HttpResponse('You cant cancel the request') + return HttpResponseRedirect(request.META.get("HTTP_REFERER", "/")) + return HttpResponse("You cant cancel the request") @login_required -@manager_can_enter('base.change_shiftrequest') -@require_http_methods(['POST']) +@manager_can_enter("base.change_shiftrequest") +@require_http_methods(["POST"]) def shift_request_bulk_cancel(request): """ - This method is used to cancel a bunch of shift request. + This method is used to cancel a bunch of shift request. """ - ids = request.POST['ids'] + ids = request.POST["ids"] ids = json.loads(ids) for id in ids: shift_request = ShiftRequest.objects.get(id=id) - if is_reportingmanger(request, shift_request) or request.user.has_perm('base.cancel_shiftrequest') or shift_request.employee_id == request.user.employee_get and shift_request.approved == False: + if ( + is_reportingmanger(request, shift_request) + or request.user.has_perm("base.cancel_shiftrequest") + or shift_request.employee_id == request.user.employee_get + and shift_request.approved == False + ): shift_request.canceled = True shift_request.approved = False - shift_request.employee_id.employee_work_info.shift_id = shift_request.previous_shift_id + shift_request.employee_id.employee_work_info.shift_id = ( + shift_request.previous_shift_id + ) shift_request.employee_id.employee_work_info.save() shift_request.save() - messages.success(request, _('Shift request canceled')) - notify.send(request.user.employee_get, recipient=shift_request.employee_id.employee_user_id, - verb='Your shift request has been canceled.', redirect='/', icon='close') - return HttpResponseRedirect(request. META. get('HTTP_REFERER', '/')) + messages.success(request, _("Shift request canceled")) + notify.send( + request.user.employee_get, + recipient=shift_request.employee_id.employee_user_id, + verb="Your shift request has been canceled.", + verb_ar="تم إلغاء طلبك للوردية.", + verb_de="Ihr Schichtantrag wurde storniert.", + verb_es="Se ha cancelado su solicitud de turno.", + verb_fr="Votre demande de quart a été annulée.", + redirect="/", + icon="close", + ) + return HttpResponseRedirect(request.META.get("HTTP_REFERER", "/")) @login_required -@manager_can_enter('base.change_shiftrequest') +@manager_can_enter("base.change_shiftrequest") def shift_request_approve(request, id): """ This method is used to approve shift request - args: - id : shift request instance id + args: + id : shift request instance id """ shift_request = ShiftRequest.objects.get(id=id) - if is_reportingmanger(request, shift_request) or request.user.has_perm('approve_shiftrequest') or request.user.has_perm('change_shiftrequest') and not shift_request.approved: - + if ( + is_reportingmanger(request, shift_request) + or request.user.has_perm("approve_shiftrequest") + or request.user.has_perm("change_shiftrequest") + and not shift_request.approved + ): """ - here the request will be approved, can send mail right here + here the request will be approved, can send mail right here """ shift_request.approved = True shift_request.canceled = False shift_request.save() - messages.success(request, _('Shift has been approved.')) - notify.send(request.user.employee_get, recipient=shift_request.employee_id.employee_user_id, - verb='Your shift request has been approved.', redirect='/', icon='checkmark') - return HttpResponseRedirect(request. META. get('HTTP_REFERER', '/')) - return HttpResponse('You Dont Have Permission') + messages.success(request, _("Shift has been approved.")) + notify.send( + request.user.employee_get, + recipient=shift_request.employee_id.employee_user_id, + verb="Your shift request has been approved.", + verb_ar="تمت الموافقة على طلبك للوردية.", + verb_de="Ihr Schichtantrag wurde genehmigt.", + verb_es="Se ha aprobado su solicitud de turno.", + verb_fr="Votre demande de quart a été approuvée.", + redirect="/", + icon="checkmark", + ) + return HttpResponseRedirect(request.META.get("HTTP_REFERER", "/")) + return HttpResponse("You Dont Have Permission") @login_required -@require_http_methods(['POST']) -@manager_can_enter('base.change_shiftrequest') +@require_http_methods(["POST"]) +@manager_can_enter("base.change_shiftrequest") def shift_request_bulk_approve(request): """ - This method is used to approve a bunch of shift request + This method is used to approve a bunch of shift request """ - ids = request.POST['ids'] + ids = request.POST["ids"] ids = json.loads(ids) for id in ids: shift_request = ShiftRequest.objects.get(id=id) - if is_reportingmanger(request, shift_request) or request.user.has_perm('approve_shiftrequest') or request.user.has_perm('change_shiftrequest') and not shift_request.approved: + if ( + is_reportingmanger(request, shift_request) + or request.user.has_perm("approve_shiftrequest") + or request.user.has_perm("change_shiftrequest") + and not shift_request.approved + ): """ - here the request will be approved, can send mail right here + here the request will be approved, can send mail right here """ shift_request.approved = True shift_request.canceled = False @@ -1750,15 +2246,24 @@ def shift_request_bulk_approve(request): employee_work_info.shift_id = shift_request.shift_id employee_work_info.save() shift_request.save() - messages.success(request, _('Shift has been approved.')) - notify.send(request.user.employee_get, recipient=shift_request.employee_id.employee_user_id, - verb='Your shift request has been approved.', redirect='/', icon='checkmark') - return HttpResponseRedirect(request. META. get('HTTP_REFERER', '/')) + messages.success(request, _("Shift has been approved.")) + notify.send( + request.user.employee_get, + recipient=shift_request.employee_id.employee_user_id, + verb="Your shift request has been approved.", + verb_ar="تمت الموافقة على طلبك للوردية.", + verb_de="Ihr Schichtantrag wurde genehmigt.", + verb_es="Se ha aprobado su solicitud de turno.", + verb_fr="Votre demande de quart a été approuvée.", + redirect="/", + icon="checkmark", + ) + return HttpResponseRedirect(request.META.get("HTTP_REFERER", "/")) @login_required -@permission_required('delete_shiftrequest') -@require_http_methods(['POST']) +@permission_required("delete_shiftrequest") +@require_http_methods(["POST"]) def shift_request_delete(request, id): """ This method is used to delete shift request instance @@ -1770,19 +2275,28 @@ def shift_request_delete(request, id): shift_request = ShiftRequest.objects.get(id=id) user = shift_request.employee_id.employee_user_id shift_request.delete() - messages.success(request, _('Shift request deleted.')) - notify.send(request.user.employee_get, recipient=user, - verb='Your shift request has been deleted.', redirect='/', icon='trash') + messages.success(request, _("Shift request deleted.")) + notify.send( + request.user.employee_get, + recipient=user, + verb="Your shift request has been deleted.", + verb_ar="تم حذف طلب الوردية الخاص بك.", + verb_de="Ihr Schichtantrag wurde gelöscht.", + verb_es="Se ha eliminado su solicitud de turno.", + verb_fr="Votre demande de quart a été supprimée.", + redirect="/", + icon="trash", + ) except Exception as e: messages.error(request, e) - messages.error(request, _('You cannot delete this shift request.')) - return HttpResponseRedirect(request. META. get('HTTP_REFERER', '/')) + messages.error(request, _("You cannot delete this shift request.")) + return HttpResponseRedirect(request.META.get("HTTP_REFERER", "/")) @login_required -@permission_required('delete_shiftrequest') -@require_http_methods(['POST']) +@permission_required("delete_shiftrequest") +@require_http_methods(["POST"]) def shift_request_bulk_delete(request): """ This method is used to delete shift request instance @@ -1790,7 +2304,7 @@ def shift_request_bulk_delete(request): id : shift request instance id """ - ids = request.POST['ids'] + ids = request.POST["ids"] ids = json.loads(ids) for id in ids: @@ -1798,58 +2312,106 @@ def shift_request_bulk_delete(request): shift_request = ShiftRequest.objects.get(id=id) user = shift_request.employee_id.employee_user_id shift_request.delete() - messages.success(request, _('Shift request deleted.')) - notify.send(request.user.employee_get, recipient=user, - verb='Your shift request has been deleted.', redirect='/', icon='trash') - except Exception as e: - messages.error(request, e) + messages.success(request, _("Shift request deleted.")) + notify.send( + request.user.employee_get, + recipient=user, + verb="Your shift request has been deleted.", + verb_ar="تم حذف طلب الوردية الخاص بك.", + verb_de="Ihr Schichtantrag wurde gelöscht.", + verb_es="Se ha eliminado su solicitud de turno.", + verb_fr="Votre demande de quart a été supprimée.", + redirect="/", + icon="trash", + ) + except Exception as error: + messages.error(request, error) messages.error( - request, _('You cannot delete {employee} shift request for the date {date}.').format(employee=shift_request.employee_id,date=shift_request.requested_date)) + request, + _( + "You cannot delete {employee} shift request for the date {date}." + ).format( + employee=shift_request.employee_id, + date=shift_request.requested_date, + ), + ) - return HttpResponseRedirect(request. META. get('HTTP_REFERER', '/')) + return HttpResponseRedirect(request.META.get("HTTP_REFERER", "/")) @login_required def notifications(request): - notifications = request.user.notifications.unread() - return render(request, 'notification/notification_items.html', {'notifications': notifications}) + """ + This method will render notification items + """ + all_notifications = request.user.notifications.unread() + return render( + request, + "notification/notification_items.html", + {"notifications": all_notifications}, + ) @login_required def clear_notification(request): + """ + This method is used to clear notification + """ try: request.user.notifications.read().delete() - messages.success(request, _('Unread notifications removed.')) + messages.success(request, _("Unread notifications removed.")) except Exception as e: messages.error(request, e) notifications = request.user.notifications.unread() - return render(request, 'notification/notification_items.html', {'notifications': notifications}) + return render( + request, + "notification/notification_items.html", + {"notifications": notifications}, + ) @login_required def delete_notification(request, id): + """ + This method is used to delete notification + """ try: notification = request.user.notifications.get(id=id).delete() - messages.success(request, _('Notification deleted.')) + messages.success(request, _("Notification deleted.")) except Exception as e: messages.error(request, e) notifications = request.user.notifications.all() - return render(request, 'notification/all_notifications.html', {'notifications': notifications}) + return render( + request, "notification/all_notifications.html", {"notifications": notifications} + ) @login_required def read_notifications(request): + """ + This method is to mark as read the notification + """ try: request.user.notifications.all().mark_all_as_read() - messages.info(request, _('Notifications marked as read')) + messages.info(request, _("Notifications marked as read")) except Exception as e: messages.error(request, e) notifications = request.user.notifications.unread() - return render(request, 'notification/notification_items.html', {'notifications': notifications}) + return render( + request, + "notification/notification_items.html", + {"notifications": notifications}, + ) @login_required def all_notifications(request): - notifications = request.user.notifications.all() - return render(request, 'notification/all_notifications.html', {'notifications': notifications}) + """ + This method to render all notifications to template + """ + return render( + request, + "notification/all_notifications.html", + {"notifications": request.user.notifications.all()}, + ) diff --git a/employee/views.py b/employee/views.py index eb5a6eecb..056bef0b7 100755 --- a/employee/views.py +++ b/employee/views.py @@ -242,9 +242,6 @@ def employee_view_update(request, obj_id): if request.POST: if request.POST.get("employee_first_name") is not None: form = EmployeeForm(request.POST, instance=employee) - print("----------") - print(request.POST) - print("----------") if form.is_valid(): form.save() messages.success( @@ -265,6 +262,10 @@ def employee_view_update(request, obj_id): request.user.employee_get, recipient=instance.employee_id.employee_user_id, verb="Your work details has been updated.", + verb_ar="تم تحديث تفاصيل عملك.", + verb_de="Ihre Arbeitsdetails wurden aktualisiert.", + verb_es="Se han actualizado los detalles de su trabajo.", + verb_fr="Vos informations professionnelles ont été mises à jour.", redirect="/employee/employee-profile", icon="briefcase", ) @@ -411,7 +412,7 @@ def employee_update_personal_info(request, obj_id=None): form = EmployeeForm(request.POST, instance=employee) if form.is_valid(): form.save() - if id is None: + if obj_id is None: messages.success(request, _("New Employee Added.")) form = EmployeeForm(request.POST, instance=form.instance) work_form = EmployeeWorkInformationForm( @@ -438,7 +439,7 @@ def employee_update_personal_info(request, obj_id=None): """ ) - if id is None: + if obj_id is None: return render( request, "employee/create_form/form_view.html", @@ -563,7 +564,7 @@ def employee_card(request): """ previous_data = request.environ["QUERY_STRING"] search = request.GET.get("search") - if isinstance(search,type(None)): + if isinstance(search, type(None)): search = "" employees = filtersubordinatesemployeemodel( request, Employee.objects.all(), "employee.view_employee" @@ -602,7 +603,7 @@ def employee_list(request): """ previous_data = request.environ["QUERY_STRING"] search = request.GET.get("search") - if isinstance(search,type(None)): + if isinstance(search, type(None)): search = "" if request.GET.get("is_active") is None: filter_obj = EmployeeFilter( @@ -1140,7 +1141,7 @@ def work_info_import(request): employee_type_obj.employee_type = employee_type employee_type_obj.save() manager_fname, manager_lname = "", "" - if isinstance(reporting_manager,str) and " " in reporting_manager: + if isinstance(reporting_manager, str) and " " in reporting_manager: manager_fname, manager_lname = reporting_manager.split(" ", 1) reporting_manager_obj = Employee.objects.filter( employee_first_name=manager_fname, @@ -1360,8 +1361,8 @@ def dashboard_employee(request): Active and in-active employee dashboard """ labels = [ - "Active", - "In-Active", + _("Active"), + _("In-Active"), ] employees = Employee.objects.all() employees = filtersubordinates(request, employees, "employee.view_employee") @@ -1386,7 +1387,7 @@ def dashboard_employee_gender(request): """ This method is used to filter out gender vise employees """ - labels = [" Male", "Female", "Others"] + labels = [_("Male"), _("Female"), _("Others")] employees = Employee.objects.all() employees = filtersubordinates(request, employees, "employee.view_employee") diff --git a/horilla/settings.py b/horilla/settings.py index 443bdf13a..4549845e0 100755 --- a/horilla/settings.py +++ b/horilla/settings.py @@ -55,6 +55,8 @@ INSTALLED_APPS = [ 'onboarding', 'asset', 'attendance', + 'payroll', + 'widget_tweaks', "django_apscheduler", @@ -184,8 +186,8 @@ LOGIN_URL = '/login' EMAIL_USE_TLS = True EMAIL_HOST = 'smtp.gmail.com' EMAIL_PORT = 587 -EMAIL_HOST_USER = '' -EMAIL_HOST_PASSWORD = '' +EMAIL_HOST_USER = 'samplemail13456@gmail.com' +EMAIL_HOST_PASSWORD = 'ysfkxwmjxmbmfkrr' SIMPLE_HISTORY_REVERT_DISABLED=True @@ -199,17 +201,17 @@ DJANGO_NOTIFICATIONS_CONFIG = { X_FRAME_OPTIONS = 'SAMEORIGIN' +LANGUAGE_CODE = 'en-us' + LANGUAGES = ( ('en', 'English (US)'), ('de', 'Deutsche'), - ('es','Spanish'), + ('es','Español'), ('fr','France'), ('ar', 'عربى'), ) -LANGUAGE_CODE = 'en-us' - LOCALE_PATHS = [ join(BASE_DIR, 'horilla', 'locale'), ] diff --git a/leave/models.py b/leave/models.py index 90a4ede9b..c9209bc75 100644 --- a/leave/models.py +++ b/leave/models.py @@ -97,6 +97,7 @@ class Holiday(models.Model): start_date = models.DateField() end_date = models.DateField(null=True, blank=True) recurring = models.BooleanField(default=False) + objects = models.Manager() def __str__(self): return self.name @@ -109,6 +110,7 @@ class CompanyLeave(models.Model): based_on_week = models.CharField( max_length=100, choices=WEEKS, blank=True, null=True) based_on_week_day = models.CharField(max_length=100, choices=WEEK_DAYS) + objects = models.Manager() class Meta: unique_together = ('based_on_week', 'based_on_week_day') diff --git a/leave/views.py b/leave/views.py index 6c747f654..c05605505 100644 --- a/leave/views.py +++ b/leave/views.py @@ -207,6 +207,10 @@ def leave_request_creation(request): request.user.employee_get, recipient=leave_request.employee_id.employee_work_info.reporting_manager_id.employee_user_id, verb=f"New leave request created for {leave_request.employee_id}.", + verb_ar=f"تم إنشاء طلب إجازة جديد لـ {leave_request.employee_id}.", + verb_de=f"Neuer Urlaubsantrag für {leave_request.employee_id} erstellt.", + verb_es=f"Nueva solicitud de permiso creada para {leave_request.employee_id}.", + verb_fr=f"Nouvelle demande de congé créée pour {leave_request.employee_id}.", icon="people-circle", redirect="/leave/request-view", ) @@ -309,6 +313,10 @@ def leave_request_update(request, id): request.user.employee_get, recipient=leave_request.employee_id.employee_work_info.reporting_manager_id.employee_user_id, verb=f"Leave request updated for {leave_request.employee_id}.", + verb_ar=f"تم تحديث طلب الإجازة لـ {leave_request.employee_id}.", + verb_de=f"Urlaubsantrag für {leave_request.employee_id} aktualisiert.", + verb_es=f"Solicitud de permiso actualizada para {leave_request.employee_id}.", + verb_fr=f"Demande de congé mise à jour pour {leave_request.employee_id}.", icon="people-circle", redirect="/leave/request-view", ) @@ -380,6 +388,10 @@ def leave_request_approve(request, id): request.user.employee_get, recipient=leave_request.employee_id.employee_user_id, verb="Your Leave request has been approved", + verb_ar="تمت الموافقة على طلب الإجازة الخاص بك.", + verb_de="Ihr Urlaubsantrag wurde genehmigt.", + verb_es="Se ha aprobado su solicitud de permiso.", + verb_fr="Votre demande de congé a été approuvée.", icon="people-circle", redirect="/leave/user-request-view", ) @@ -421,6 +433,10 @@ def leave_request_cancel(request, id): request.user.employee_get, recipient=leave_request.employee_id.employee_user_id, verb="Your Leave request has been cancelled", + verb_ar="تم إلغاء طلب الإجازة الخاص بك.", + verb_de="Ihr Urlaubsantrag wurde storniert.", + verb_es="Se ha cancelado su solicitud de permiso.", + verb_fr="Votre demande de congé a été annulée.", icon="people-circle", redirect="/leave/user-request-view", ) @@ -481,6 +497,10 @@ def leave_assign_one(request, id): request.user.employee_get, recipient=employee.employee_user_id, verb="New leave type is assigned to you", + verb_ar="تم تعيين نوع إجازة جديد لك.", + verb_de="Ihnen wurde ein neuer Urlaubstyp zugewiesen.", + verb_es="Se le ha asignado un nuevo tipo de permiso.", + verb_fr="Un nouveau type de congé vous a été attribué.", icon="people-circle", redirect="/leave/user-leave", ) @@ -594,6 +614,10 @@ def leave_assign(request): request.user.employee_get, recipient=employee.employee_user_id, verb="New leave type is assigned to you", + verb_ar="تم تعيين نوع إجازة جديد لك.", + verb_de="Ihnen wurde ein neuer Urlaubstyp zugewiesen.", + verb_es="Se te ha asignado un nuevo tipo de permiso.", + verb_fr="Un nouveau type de congé vous a été attribué.", icon="people-circle", redirect="/leave/user-leave", ) @@ -638,6 +662,10 @@ def available_leave_update(request, id): request.user.employee_get, recipient=available_leave.employee_id.employee_user_id, verb=f"Your {available_leave.leave_type_id} leave type updated.", + verb_ar=f"تم تحديث نوع إجازتك {available_leave.leave_type_id}.", + verb_de=f"Ihr Urlaubstyp {available_leave.leave_type_id} wurde aktualisiert.", + verb_es=f"Se ha actualizado su tipo de permiso {available_leave.leave_type_id}.", + verb_fr=f"Votre type de congé {available_leave.leave_type_id} a été mis à jour.", icon="people-circle", redirect="/leave/user-leave", ) @@ -1050,6 +1078,10 @@ def user_leave_request(request, id): request.user.employee_get, recipient=leave_request.employee_id.employee_work_info.reporting_manager_id.employee_user_id, verb="You have a new leave request to validate.", + verb_ar="لديك طلب إجازة جديد يحتاج إلى التحقق منه.", + verb_de="Sie haben eine neue Urlaubsanfrage zur Validierung.", + verb_es="Tiene una nueva solicitud de permiso para validar.", + verb_fr="Vous avez une nouvelle demande de congé à valider.", icon="people-circle", redirect="/leave/user-request-view", ) diff --git a/onboarding/views.py b/onboarding/views.py index eddf37a06..f3801a7fe 100644 --- a/onboarding/views.py +++ b/onboarding/views.py @@ -94,6 +94,10 @@ def stage_save(form, recruitment, request, rec_id): request.user.employee_get, recipient=users, verb="You are chosen as onboarding stage manager", + verb_ar="لقد تم اختيارك كمدير مرحلة التدريب.", + verb_de="Sie wurden als Onboarding-Stage-Manager ausgewählt.", + verb_es="Ha sido seleccionado/a como responsable de etapa de incorporación.", + verb_fr="Vous avez été choisi(e) en tant que responsable de l'étape d'intégration.", icon="people-circle", redirect="/onboarding/onboarding-view", ) @@ -133,6 +137,10 @@ def stage_update(request, stage_id, recruitment_id): request.user.employee_get, recipient=users, verb="You are chosen as onboarding stage manager", + verb_ar="لقد تم اختيارك كمدير مرحلة التدريب.", + verb_de="Sie wurden als Onboarding-Stage-Manager ausgewählt.", + verb_es="Ha sido seleccionado/a como responsable de etapa de incorporación.", + verb_fr="Vous avez été choisi(e) en tant que responsable de l'étape d'intégration.", icon="people-circle", redirect="/onboarding/onboarding-view", ) @@ -207,7 +215,11 @@ def task_creation(request, obj_id): notify.send( request.user.employee_get, recipient=users, - verb="You are chosen as onboarding task manager", + verb="You are chosen as an onboarding task manager", + verb_ar="لقد تم اختيارك كمدير مهام التدريب.", + verb_de="Sie wurden als Onboarding-Aufgabenmanager ausgewählt.", + verb_es="Ha sido seleccionado/a como responsable de tareas de incorporación.", + verb_fr="Vous avez été choisi(e) en tant que responsable des tâches d'intégration.", icon="people-circle", redirect="/onboarding/onboarding-view", ) @@ -246,7 +258,11 @@ def task_update(request, task_id, recruitment_id): notify.send( request.user.employee_get, recipient=users, - verb="You are chosen as onboarding task manager", + verb="You are chosen as an onboarding task manager", + verb_ar="لقد تم اختيارك كمدير مهام التدريب.", + verb_de="Sie wurden als Onboarding-Aufgabenmanager ausgewählt.", + verb_es="Ha sido seleccionado/a como responsable de tareas de incorporación.", + verb_fr="Vous avez été choisi(e) en tant que responsable des tâches d'intégration.", icon="people-circle", redirect="/onboarding/onboarding-view", ) @@ -740,6 +756,10 @@ def candidate_task_update(request, obj_id): recipient=users, verb=f"The task {candidate_task.onboarding_task_id} of\ {candidate_task.candidate_id} was updated to {candidate_task.status}.", + verb_ar=f"تم تحديث المهمة {candidate_task.onboarding_task_id} للمرشح {candidate_task.candidate_id} إلى {candidate_task.status}.", + verb_de=f"Die Aufgabe {candidate_task.onboarding_task_id} des Kandidaten {candidate_task.candidate_id} wurde auf {candidate_task.status} aktualisiert.", + verb_es=f"La tarea {candidate_task.onboarding_task_id} del candidato {candidate_task.candidate_id} se ha actualizado a {candidate_task.status}.", + verb_fr=f"La tâche {candidate_task.onboarding_task_id} du candidat {candidate_task.candidate_id} a été mise à jour à {candidate_task.status}.", icon="people-circle", redirect="/onboarding/onboarding-view", ) @@ -787,6 +807,10 @@ def candidate_stage_update(request, candidate_id, recruitment_id): recipient=users, verb=f"The stage of {candidate_stage.candidate_id} \ was updated to {candidate_stage.onboarding_stage_id}.", + verb_ar=f"تم تحديث مرحلة المرشح {candidate_stage.candidate_id} إلى {candidate_stage.onboarding_stage_id}.", + verb_de=f"Die Phase des Kandidaten {candidate_stage.candidate_id} wurde auf {candidate_stage.onboarding_stage_id} aktualisiert.", + verb_es=f"La etapa del candidato {candidate_stage.candidate_id} se ha actualizado a {candidate_stage.onboarding_stage_id}.", + verb_fr=f"L'étape du candidat {candidate_stage.candidate_id} a été mise à jour à {candidate_stage.onboarding_stage_id}.", icon="people-circle", redirect="/onboarding/onboarding-view", ) diff --git a/pms/models.py b/pms/models.py index c3d93c206..e1370a633 100644 --- a/pms/models.py +++ b/pms/models.py @@ -22,13 +22,13 @@ class EmployeeObjective(models.Model): """ this is a EmployObjective model used for creating Employee objectives """ - STATUS_CHOICES = [ + STATUS_CHOICES = ( ('On Track', _('On Track')), ('Behind', _('Behind')), ('Closed', _('Closed')), ('At Risk', _('At Risk')), ('Not Started', _('Not Started')), - ] + ) objective = models.CharField(null=False, blank=False, max_length=100) objective_description = models.TextField(blank=False, null=False) created_at = models.DateField(auto_now_add=True) @@ -134,11 +134,11 @@ class QuestionOptions(models.Model): class Feedback(models.Model): """feedback model for creating feedback """ STATUS_CHOICES = ( - ('On Track', 'On Track'), - ('Behind', 'Behind' ), - ('Closed', 'Closed' ), - ('At Risk', 'At Risk' ), - ('Not Started', 'Not Started') + ('On Track', _('On Track')), + ('Behind', _('Behind') ), + ('Closed', _('Closed') ), + ('At Risk', _('At Risk') ), + ('Not Started', _('Not Started')) ) review_cycle = models.CharField(max_length=100, null=False, blank=False) manager_id = models.ForeignKey(Employee, related_name='feedback_manager', on_delete=models.DO_NOTHING, null=True, blank=False) diff --git a/pms/templates/feedback/feedback_list.html b/pms/templates/feedback/feedback_list.html index 4b7d371aa..5fcc38055 100644 --- a/pms/templates/feedback/feedback_list.html +++ b/pms/templates/feedback/feedback_list.html @@ -54,7 +54,11 @@
- @@ -161,7 +165,11 @@ - @@ -271,7 +279,11 @@ - diff --git a/pms/templates/okr/objective_list.html b/pms/templates/okr/objective_list.html index 31e4ca8e4..68a1b1dd0 100644 --- a/pms/templates/okr/objective_list.html +++ b/pms/templates/okr/objective_list.html @@ -42,7 +42,7 @@ {% if own_objective.archive %} {% csrf_token %} - +
{% else %}
@@ -144,7 +144,7 @@ {% if all_objective.archive %} {% csrf_token %} - +
{% else %}
diff --git a/pms/views.py b/pms/views.py index 7f8ad5eef..eddb11d80 100644 --- a/pms/views.py +++ b/pms/views.py @@ -1,7 +1,18 @@ import datetime from django.http import HttpResponse from django.shortcuts import get_object_or_404, render, redirect -from pms.models import EmployeeKeyResult, EmployeeObjective, Comment, Feedback, QuestionTemplate, Question, Answer, Period, QuestionOptions, KeyresultFeedback +from pms.models import ( + EmployeeKeyResult, + EmployeeObjective, + Comment, + Feedback, + QuestionTemplate, + Question, + Answer, + Period, + QuestionOptions, + KeyresultFeedback, +) from base.models import Department, JobPosition from employee.models import Employee, EmployeeWorkInformation from horilla.decorators import manager_can_enter @@ -10,10 +21,18 @@ import json from itertools import tee from django.core.paginator import Paginator from pms.filters import ObjectiveFilter, FeedbackFilter -from .forms import QuestionForm, ObjectiveForm, KeyResultForm, FeedbackForm, ObjectiveCommentForm, PeriodForm, QuestionTemplateForm +from .forms import ( + QuestionForm, + ObjectiveForm, + KeyResultForm, + FeedbackForm, + ObjectiveCommentForm, + PeriodForm, + QuestionTemplateForm, +) from django.forms import modelformset_factory from django.contrib import messages -from horilla.decorators import login_required,hx_request_required +from horilla.decorators import login_required, hx_request_required from django.urls import reverse from django.db.utils import IntegrityError from django.db.models import Q @@ -22,15 +41,15 @@ from notifications.signals import notify @login_required -@manager_can_enter(perm='pms.add_employeeobjective') +@manager_can_enter(perm="pms.add_employeeobjective") def objective_creation(request): """ This view is for objective creation , and returns a objective form. Returns: GET: - objective form, period, department, job position, employee, department + objective form, period, department, job position, employee, department POST: - Objective created, and returnes to key result creation function + Objective created, and returnes to key result creation function """ employees = Employee.objects.all() @@ -40,35 +59,47 @@ def objective_creation(request): employee = request.user.employee_get objective_form = ObjectiveForm(employee=employee) context = { - 'employee': employees, - 'department': departments, - 'job_position': job_positions, - 'period': periods, - 'objective_form':objective_form, + "employee": employees, + "department": departments, + "job_position": job_positions, + "period": periods, + "objective_form": objective_form, } - if request.method == 'POST': - objective_type = request.POST.get('objective_type') - if objective_type == 'individual': - # if the objective is for a individual + if request.method == "POST": + objective_type = request.POST.get("objective_type") + if objective_type == "individual": + # if the objective is for a individual form_objectives = ObjectiveForm(request.POST) if form_objectives.is_valid(): objective = form_objectives.save() obj_id = objective.id - obj_type = 'individual' - messages.success(request,_("Objective created")) - notify.send(request.user.employee_get, recipient=objective.employee_id.employee_user_id, verb='You got an OKR!.',redirect=f'/pms/objective-detailed-view/{obj_id}',icon='list-circle') + obj_type = "individual" + messages.success(request, _("Objective created")) + notify.send( + request.user.employee_get, + recipient=objective.employee_id.employee_user_id, + verb="You got an OKR!.", + verb_ar="لقد حققت هدفًا ونتيجة رئيسية!", + verb_de="Du hast ein Ziel-Key-Ergebnis erreicht!", + verb_es="¡Has logrado un Resultado Clave de Objetivo!", + verb_fr="Vous avez atteint un Résultat Clé d'Objectif !", + redirect=f"/pms/objective-detailed-view/{obj_id}", + icon="list-circle", + ) return redirect(key_result_creation, obj_id, obj_type) else: - context['objective_form'] = form_objectives - elif objective_type == 'job_position' or objective_type == 'department': - # if the objective is based on particular job position or department + context["objective_form"] = form_objectives + elif objective_type == "job_position" or objective_type == "department": + # if the objective is based on particular job position or department form_objectives = ObjectiveForm(request.POST) - obj_type = 'multiple' + obj_type = "multiple" if form_objectives.is_valid(): objective_type = form_objectives.cleaned_data[objective_type] # to get all employee workinformation - employee_work_informations = objective_type.employeeworkinformation_set.all() + employee_work_informations = ( + objective_type.employeeworkinformation_set.all() + ) # getting all the employees in the job position or department and assigning then the objective to them objective_ids = [] for employee in employee_work_informations: @@ -76,22 +107,32 @@ def objective_creation(request): form = form_objectives.save(commit=False) form.employee_id = employee.employee_id form.save() - notify.send(request.user.employee_get, recipient=form.employee_id.employee_user_id, verb='You got an OKR!.',redirect=f'/pms/objective-detailed-view/{form.id}',icon='list-circle') + notify.send( + request.user.employee_get, + recipient=form.employee_id.employee_user_id, + verb="You got an OKR!.", + verb_ar="لقد حققت هدفًا ونتيجة رئيسية!", + verb_de="Du hast ein Ziel-Key-Ergebnis erreicht!", + verb_es="¡Has logrado un Resultado Clave de Objetivo!", + verb_fr="Vous avez atteint un Résultat Clé d'Objectif !", + redirect=f"/pms/objective-detailed-view/{form.id}", + icon="list-circle", + ) objective_ids.append(form.id) obj_id = str(objective_ids) - messages.success(request,_("Objectives created")) + messages.success(request, _("Objectives created")) return redirect(key_result_creation, obj_id, obj_type) else: - context['objective_form'] = form_objectives - elif objective_type == 'none': + context["objective_form"] = form_objectives + elif objective_type == "none": form_objectives = ObjectiveForm(request.POST) - context['objective_form'] = form_objectives - return render(request, 'okr/objective_creation.html', context=context) + context["objective_form"] = form_objectives + return render(request, "okr/objective_creation.html", context=context) @login_required @hx_request_required -@manager_can_enter(perm='pms.change_employeeobjective') +@manager_can_enter(perm="pms.change_employeeobjective") def objective_update(request, id): """ This view takes one arguments, id , and returns a HttpResponse object.,using htmx @@ -102,23 +143,39 @@ def objective_update(request, id): """ instance = EmployeeObjective.objects.get(id=id) objective_form = ObjectiveForm(instance=instance) - context={'objective_form':objective_form} - if request.method == 'POST': + context = {"objective_form": objective_form} + if request.method == "POST": objective_form = ObjectiveForm(request.POST, instance=instance) if objective_form.is_valid(): objective_form.save() - if not instance.employee_id.id == int(request.POST.get('employee_id')): - notify.send(request.user.employee_get, recipient=instance.employee_id.employee_user_id, verb='You got an OKR!.',redirect=f'/pms/objective-detailed-view/{instance.id}',icon='eye-outline') - messages.info(request, _('Objective %(objective)s Updated') % {'objective': instance.objective}) - response = render(request,'okr/objective_update.html',context) - return HttpResponse(response.content.decode('utf-8') +'') + if not instance.employee_id.id == int(request.POST.get("employee_id")): + notify.send( + request.user.employee_get, + recipient=instance.employee_id.employee_user_id, + verb="You got an OKR!.", + verb_ar="لقد حققت هدفًا ونتيجة رئيسية!", + verb_de="Du hast ein Ziel-Key-Ergebnis erreicht!", + verb_es="¡Has logrado un Resultado Clave de Objetivo!", + verb_fr="Vous avez atteint un Résultat Clé d'Objectif !", + redirect=f"/pms/objective-detailed-view/{instance.id}", + icon="eye-outline", + ) + messages.info( + request, + _("Objective %(objective)s Updated") + % {"objective": instance.objective}, + ) + response = render(request, "okr/objective_update.html", context) + return HttpResponse( + response.content.decode("utf-8") + "" + ) else: - context['objective_form']=objective_form - return render(request,'okr/objective_update.html',context) + context["objective_form"] = objective_form + return render(request, "okr/objective_update.html", context) @login_required -@manager_can_enter(perm='pms.delete_employeeobjective') +@manager_can_enter(perm="pms.delete_employeeobjective") def objective_delete(request, id): """ This view takes one arguments, id and returns redirecting to a view. @@ -129,7 +186,10 @@ def objective_delete(request, id): """ objective = EmployeeObjective.objects.get(id=id) objective.delete() - messages.success(request,_('Objective %(objective)s deleted') % {'objective':objective.objective}) + messages.success( + request, + _("Objective %(objective)s deleted") % {"objective": objective.objective}, + ) return redirect(objective_list_view) @@ -142,23 +202,27 @@ def objecitve_filter_pagination(request, objective_own, objective_all): Returns: All the filtered and paginated object will return. """ - previous_data = request.environ['QUERY_STRING'] - initial_data = {'archive': False} # set initial value of archive filter to False - objective_filter_own = ObjectiveFilter(request.GET or initial_data, queryset=objective_own) - objective_filter_all = ObjectiveFilter(request.GET or initial_data, queryset=objective_all) + previous_data = request.environ["QUERY_STRING"] + initial_data = {"archive": False} # set initial value of archive filter to False + objective_filter_own = ObjectiveFilter( + request.GET or initial_data, queryset=objective_own + ) + objective_filter_all = ObjectiveFilter( + request.GET or initial_data, queryset=objective_all + ) objective_paginator_own = Paginator(objective_filter_own.qs, 50) objective_paginator_all = Paginator(objective_filter_all.qs, 50) - page_number = request.GET.get('page') + page_number = request.GET.get("page") objectives_own = objective_paginator_own.get_page(page_number) objectives_all = objective_paginator_all.get_page(page_number) - now =datetime.datetime.now() + now = datetime.datetime.now() context = { - 'superuser': 'true', - 'own_objectives': objectives_own, - 'all_objectives': objectives_all, - 'objective_filer_form': objective_filter_own.form, - 'pg': previous_data, - 'current_date':now + "superuser": "true", + "own_objectives": objectives_own, + "all_objectives": objectives_all, + "objective_filer_form": objective_filter_own.form, + "pg": previous_data, + "current_date": now, } return context @@ -172,29 +236,49 @@ def objective_list_view(request): """ user = request.user employee = Employee.objects.filter(employee_user_id=user).first() - is_manager = Employee.objects.filter(employee_work_info__reporting_manager_id=employee) - - if request.user.has_perm('pms.view_employeeobjective'): - objective_own = EmployeeObjective.objects.filter(employee_id = employee).exclude(status='Closed')| EmployeeObjective.objects.filter(emp_obj_id__employee_id = employee).exclude(status='Closed') + is_manager = Employee.objects.filter( + employee_work_info__reporting_manager_id=employee + ) + + if request.user.has_perm("pms.view_employeeobjective"): + objective_own = EmployeeObjective.objects.filter(employee_id=employee).exclude( + status="Closed" + ) | EmployeeObjective.objects.filter(emp_obj_id__employee_id=employee).exclude( + status="Closed" + ) objective_own = objective_own.distinct() - objective_all = EmployeeObjective.objects.all().exclude(status='Closed') + objective_all = EmployeeObjective.objects.all().exclude(status="Closed") context = objecitve_filter_pagination(request, objective_own, objective_all) elif is_manager: # if user is a manager employees_ids = [employee.id for employee in is_manager] - objective_own = EmployeeObjective.objects.filter(employee_id = employee).exclude(status='Closed') | EmployeeObjective.objects.filter(emp_obj_id__employee_id = employee).exclude(status='Closed') + objective_own = EmployeeObjective.objects.filter(employee_id=employee).exclude( + status="Closed" + ) | EmployeeObjective.objects.filter(emp_obj_id__employee_id=employee).exclude( + status="Closed" + ) objective_own = objective_own.distinct() - objective_all = EmployeeObjective.objects.filter(employee_id__in=employees_ids).exclude(status='Closed') | EmployeeObjective.objects.filter(emp_obj_id__employee_id__in = employees_ids).exclude(status='Closed') + objective_all = EmployeeObjective.objects.filter( + employee_id__in=employees_ids + ).exclude(status="Closed") | EmployeeObjective.objects.filter( + emp_obj_id__employee_id__in=employees_ids + ).exclude( + status="Closed" + ) objective_all = objective_all.distinct() context = objecitve_filter_pagination(request, objective_own, objective_all) else: # for normal user - objective_own = EmployeeObjective.objects.filter(employee_id = employee).exclude(status='Closed') | EmployeeObjective.objects.filter(emp_obj_id__employee_id = employee).exclude(status='Closed') + objective_own = EmployeeObjective.objects.filter(employee_id=employee).exclude( + status="Closed" + ) | EmployeeObjective.objects.filter(emp_obj_id__employee_id=employee).exclude( + status="Closed" + ) objective_own = objective_own.distinct() objective_all = EmployeeObjective.objects.none() context = objecitve_filter_pagination(request, objective_own, objective_all) - return render(request, 'okr/objective_list_view.html', context) + return render(request, "okr/objective_list_view.html", context) @login_required @@ -205,34 +289,46 @@ def objective_list_search(request): Returns: All the filtered and searched object will based on userlevel. """ - objective_owner = request.GET.get('search') + objective_owner = request.GET.get("search") if objective_owner is None: objective_owner = "" user = request.user employee = Employee.objects.filter(employee_user_id=user).first() - is_manager = Employee.objects.filter(employee_work_info__reporting_manager_id=employee) + is_manager = Employee.objects.filter( + employee_work_info__reporting_manager_id=employee + ) - if request.user.has_perm('pms.view_employeeobjective'): + if request.user.has_perm("pms.view_employeeobjective"): # based on permission - objective_own = EmployeeObjective.objects.filter(employee_id=request.user.employee_get).filter(employee_id__employee_first_name__icontains=objective_owner) - objective_all = EmployeeObjective.objects.filter(employee_id__employee_first_name__icontains=objective_owner) + objective_own = EmployeeObjective.objects.filter( + employee_id=request.user.employee_get + ).filter(employee_id__employee_first_name__icontains=objective_owner) + objective_all = EmployeeObjective.objects.filter( + employee_id__employee_first_name__icontains=objective_owner + ) context = objecitve_filter_pagination(request, objective_own, objective_all) elif is_manager: # if user is a manager employees_ids = [employee.id for employee in is_manager] - objective_own = EmployeeObjective.objects.filter(employee_id=employee).filter(employee_id__employee_first_name__icontains=objective_owner) - objective_all = EmployeeObjective.objects.filter(employee_id__in=employees_ids).filter(employee_id__employee_first_name__icontains=objective_owner) + objective_own = EmployeeObjective.objects.filter(employee_id=employee).filter( + employee_id__employee_first_name__icontains=objective_owner + ) + objective_all = EmployeeObjective.objects.filter( + employee_id__in=employees_ids + ).filter(employee_id__employee_first_name__icontains=objective_owner) context = objecitve_filter_pagination(request, objective_own, objective_all) else: # for normal user - objective_own = EmployeeObjective.objects.filter(employee_id=employee).filter(employee_id__employee_first_name__icontains=objective_owner) + objective_own = EmployeeObjective.objects.filter(employee_id=employee).filter( + employee_id__employee_first_name__icontains=objective_owner + ) objective_all = EmployeeObjective.objects.none() context = objecitve_filter_pagination(request, objective_own, objective_all) - return render(request, 'okr/objective_list.html', context) + return render(request, "okr/objective_list.html", context) def objective_history(emp_obj_id): @@ -243,32 +339,41 @@ def objective_history(emp_obj_id): Returns: All the history of EmployeeObjective. """ + def pair_history(iterable): - """this function return two history pair """ + """this function return two history pair""" a, b = tee(iterable) next(b, None) return zip(a, b) + changed_key_results = [] def key_result_history(key_result): - """ key result history """ - key_result_iterator = key_result.history.all().order_by('history_date').iterator() + """key result history""" + key_result_iterator = ( + key_result.history.all().order_by("history_date").iterator() + ) for record_pair in pair_history(key_result_iterator): old_record, new_record = record_pair delta = new_record.diff_against(old_record) history_user_id = delta.new_record.history_user history_change_date = delta.new_record.history_date employee = Employee.objects.filter(employee_user_id=history_user_id).first() - changed_key_results.append({ - 'delta': delta, - 'changed_user': employee, - 'changed_date': history_change_date - }) + changed_key_results.append( + { + "delta": delta, + "changed_user": employee, + "changed_date": history_change_date, + } + ) + obj_objective = EmployeeObjective.objects.get(id=emp_obj_id) - all_key_results = EmployeeKeyResult.objects.filter(employee_objective_id=obj_objective) + all_key_results = EmployeeKeyResult.objects.filter( + employee_objective_id=obj_objective + ) for key_result in all_key_results: - # loop each key result and generate it's history + # loop each key result and generate it's history key_result_history(key_result) changed_key_results.reverse() return changed_key_results @@ -290,7 +395,11 @@ def objective_detailed_view(request, emp_obj_id): key_results_all = objective.emp_obj_id.all() # progress of objective calculation - completed_key_result = [obj.current_value for obj in key_results_all if obj.current_value == obj.target_value] + completed_key_result = [ + obj.current_value + for obj in key_results_all + if obj.current_value == obj.target_value + ] total_kr = key_results_all.count() try: progress = int((len(completed_key_result) / total_kr) * 100) @@ -301,18 +410,18 @@ def objective_detailed_view(request, emp_obj_id): history = objective_history(emp_obj_id) now = datetime.datetime.now() context = { - 'employee_key_results': key_results, - 'employee_objective': objective, - 'comments': comments, - 'historys': history, - 'progress': progress, - 'objective_form': objective_form, - 'key_result_form': KeyResultForm, - 'objective_key_result_status': EmployeeKeyResult.STATUS_CHOICES, - 'comment_form': ObjectiveCommentForm, - 'current_date':now + "employee_key_results": key_results, + "employee_objective": objective, + "comments": comments, + "historys": history, + "progress": progress, + "objective_form": objective_form, + "key_result_form": KeyResultForm, + "objective_key_result_status": EmployeeKeyResult.STATUS_CHOICES, + "comment_form": ObjectiveCommentForm, + "current_date": now, } - return render(request, 'okr/objective_detailed_view.html', context) + return render(request, "okr/objective_detailed_view.html", context) @login_required @@ -333,7 +442,7 @@ def objective_detailed_view_activity(request, id): "historys": history, "comments": comments, } - return render(request, 'okr/objective_detailed_view_activity.html', context) + return render(request, "okr/objective_detailed_view_activity.html", context) @login_required @@ -370,12 +479,16 @@ def objective_detailed_view_objective_status(request, id): """ objective = EmployeeObjective.objects.get(id=id) - status = request.POST.get('objective_status') + status = request.POST.get("objective_status") objective.status = status objective.save() - messages.info(request,_('Objective %(objective)s status updated') % {'objective':objective.objective}) + messages.info( + request, + _("Objective %(objective)s status updated") + % {"objective": objective.objective}, + ) return redirect(objective_detailed_view_activity, id) - + @login_required @hx_request_required @@ -389,11 +502,11 @@ def objective_detailed_view_key_result_status(request, obj_id, kr_id): All the filtered and searched object will based on userlevel. """ - status = request.POST.get('key_result_status') + status = request.POST.get("key_result_status") employee_key_result = EmployeeKeyResult.objects.get(id=kr_id) employee_key_result.status = status employee_key_result.save() - messages.info(request, _('Status has been updated')) + messages.info(request, _("Status has been updated")) return redirect(objective_detailed_view_activity, id=obj_id) @@ -407,20 +520,24 @@ def objective_detailed_view_current_value(request, kr_id): Returns: All the history of EmployeeObjective. """ - if request.method == 'POST': - current_value = request.POST.get('current_value') + if request.method == "POST": + current_value = request.POST.get("current_value") employee_key_result = EmployeeKeyResult.objects.get(id=kr_id) target_value = employee_key_result.target_value objective_id = employee_key_result.employee_objective_id.id if int(current_value) <= target_value: employee_key_result.current_value = current_value employee_key_result.save() - messages.info(request,_('Current value of %(employee_key_result)s updated') % {'employee_key_result':employee_key_result}) - return redirect(objective_detailed_view_activity, objective_id ) - elif int(current_value) > target_value: - messages.warning(request,_('Current value is greater than target value')) + messages.info( + request, + _("Current value of %(employee_key_result)s updated") + % {"employee_key_result": employee_key_result}, + ) return redirect(objective_detailed_view_activity, objective_id) - messages.error(request,_('Error occurred during current value updation')) + elif int(current_value) > target_value: + messages.warning(request, _("Current value is greater than target value")) + return redirect(objective_detailed_view_activity, objective_id) + messages.error(request, _("Error occurred during current value updation")) return redirect(objective_detailed_view_activity, objective_id) @@ -435,58 +552,64 @@ def objective_archive(request, id): """ objective = EmployeeObjective.objects.get(id=id) if objective.archive == True: - objective.archive = False + objective.archive = False objective.save() - messages.info(request,_('Objective un-archived successfully!.')) + messages.info(request, _("Objective un-archived successfully!.")) elif objective.archive == False: objective.archive = True objective.save() - messages.info(request,_('Objective archived successfully!.')) + messages.info(request, _("Objective archived successfully!.")) return redirect(f"/pms/objective-list-view?{request.environ['QUERY_STRING']}") @login_required -@manager_can_enter(perm='pms.add_employeekeyresult') +@manager_can_enter(perm="pms.add_employeekeyresult") def key_result_creation(request, obj_id, obj_type): """ - This view is used to create key result, + This view is used to create key result, Args: id (int): Primarykey of EmployeeObjective. obj_type (str): type of objecitve Returns: if errorr occure it will return errorr message . """ - + employee = request.user.employee_get key_result_form = KeyResultForm(employee=employee) - context = {'key_result_form': key_result_form, - 'objective_id': obj_id, - 'objective_type':obj_type} - if obj_type == 'multiple': + context = { + "key_result_form": key_result_form, + "objective_id": obj_id, + "objective_type": obj_type, + } + if obj_type == "multiple": # for job position or department the context should have all the related object ids - value = context.pop('objective_id') - context['objective_ids'] = value - if request.method == 'POST': - if obj_type == 'individual': + value = context.pop("objective_id") + context["objective_ids"] = value + if request.method == "POST": + if obj_type == "individual": employee_objective_id = EmployeeObjective.objects.get(id=int(obj_id)) - form_key_result = KeyResultForm(request.POST, initial={'employee_objective_id': employee_objective_id}) + form_key_result = KeyResultForm( + request.POST, initial={"employee_objective_id": employee_objective_id} + ) if form_key_result.is_valid(): form = form_key_result.save(commit=False) form.start_value = form.current_value form.employee_objective_id = employee_objective_id form.save() - messages.success(request,_("Key result created")) - return redirect(objective_detailed_view, obj_id) + messages.success(request, _("Key result created")) + return redirect(objective_detailed_view, obj_id) else: - context['key_result_form'] = form_key_result + context["key_result_form"] = form_key_result - elif obj_type == 'multiple': + elif obj_type == "multiple": # If the objective is for job postion or department # The id will be list of objective id objective_ids = json.loads(obj_id) for objective_id in objective_ids: objective = EmployeeObjective.objects.filter(id=objective_id).first() - form_key_result = KeyResultForm(request.POST, initial={'employee_objective_id': objective}) + form_key_result = KeyResultForm( + request.POST, initial={"employee_objective_id": objective} + ) if form_key_result.is_valid(): form = form_key_result.save(commit=False) form.start_value = form.current_value @@ -494,16 +617,18 @@ def key_result_creation(request, obj_id, obj_type): form.employee_objective_id = objective form.save() else: - context['key_result_form'] = form_key_result - return render(request, 'okr/key_result/key_result_creation.html', context) - messages.success(request,_("Key results created")) + context["key_result_form"] = form_key_result + return render( + request, "okr/key_result/key_result_creation.html", context + ) + messages.success(request, _("Key results created")) return redirect(objective_list_view) - return render(request, 'okr/key_result/key_result_creation.html', context) + return render(request, "okr/key_result/key_result_creation.html", context) @login_required @hx_request_required -@manager_can_enter(perm='pms.add_employeekeyresult') +@manager_can_enter(perm="pms.add_employeekeyresult") def key_result_creation_htmx(request, id): """ This view is used to create key result in objective detailed view, using htmx @@ -513,27 +638,30 @@ def key_result_creation_htmx(request, id): Returns: if errorr occure it will return errorr message . """ - context = {'key_result_form': KeyResultForm(), - 'objecitve_id': id} + context = {"key_result_form": KeyResultForm(), "objecitve_id": id} objective = EmployeeObjective.objects.get(id=id) - if request.method == 'POST': - initial_data = {'employee_objective_id': objective } - form_key_result = KeyResultForm(request.POST,initial=initial_data) + if request.method == "POST": + initial_data = {"employee_objective_id": objective} + form_key_result = KeyResultForm(request.POST, initial=initial_data) if form_key_result.is_valid(): form = form_key_result.save(commit=False) form.start_value = form.current_value form.employee_objective_id = objective form.save() - messages.success(request,_("Key result created")) - response = render(request,'okr/key_result/key_result_creation_htmx.html',context) - return HttpResponse(response.content.decode('utf-8') +'') - context['key_result_form'] = form_key_result - return render(request,'okr/key_result/key_result_creation_htmx.html',context) + messages.success(request, _("Key result created")) + response = render( + request, "okr/key_result/key_result_creation_htmx.html", context + ) + return HttpResponse( + response.content.decode("utf-8") + "" + ) + context["key_result_form"] = form_key_result + return render(request, "okr/key_result/key_result_creation_htmx.html", context) @login_required @hx_request_required -@manager_can_enter(perm='pms.update_employeekeyresult') +@manager_can_enter(perm="pms.update_employeekeyresult") def key_result_update(request, id): """ This view is used to update key result, using htmx @@ -545,52 +673,96 @@ def key_result_update(request, id): key_result = EmployeeKeyResult.objects.get(id=id) key_result_form = KeyResultForm(instance=key_result) - context = {'key_result_form':key_result_form, - "key_result_id":key_result.id} - if request.method == 'POST': - key_result_form = KeyResultForm(request.POST,instance=key_result) - key_result_form.initial['employee_objective_id']= key_result.employee_objective_id # adding intial objective value to the form + context = {"key_result_form": key_result_form, "key_result_id": key_result.id} + if request.method == "POST": + key_result_form = KeyResultForm(request.POST, instance=key_result) + key_result_form.initial[ + "employee_objective_id" + ] = ( + key_result.employee_objective_id + ) # adding intial objective value to the form if key_result_form.is_valid(): key_result_form.save() - messages.info(request,_("Key result updated")) - response = render(request,'okr/key_result/key_result_update.html',context) - return HttpResponse(response.content.decode('utf-8') +'') + messages.info(request, _("Key result updated")) + response = render(request, "okr/key_result/key_result_update.html", context) + return HttpResponse( + response.content.decode("utf-8") + "" + ) else: - context['key_result_form']=key_result_form - return render(request,'okr/key_result/key_result_update.html',context) + context["key_result_form"] = key_result_form + return render(request, "okr/key_result/key_result_update.html", context) # feedback section def send_feedback_notifications(request, form): - # Send notification to employee if form.employee_id: employee = form.employee_id - notify.send(request.user.employee_get, recipient=employee.employee_user_id, verb='You have received feedback!', redirect=f'/pms/feedback-detailed-view/{form.id}', icon='chatbox-ellipses') + notify.send( + request.user.employee_get, + recipient=employee.employee_user_id, + verb="You have received feedback!", + verb_ar="لقد تلقيت ملاحظات!", + verb_de="Sie haben Feedback erhalten!", + verb_es="¡Has recibido retroalimentación!", + verb_fr="Vous avez reçu des commentaires !", + redirect=f"/pms/feedback-detailed-view/{form.id}", + icon="chatbox-ellipses", + ) # Send notification to manager if form.manager_id: manager = form.manager_id - notify.send(request.user.employee_get, recipient=manager.employee_user_id, verb='You have been assigned as a manager in a feedback!', redirect=f'/pms/feedback-detailed-view/{form.id}', icon='chatbox-ellipses') + notify.send( + request.user.employee_get, + recipient=manager.employee_user_id, + verb="You have been assigned as a manager in a feedback!", + verb_ar="لقد تم تعيينك كمدير في ملاحظة!", + verb_de="Sie wurden als Manager in einem Feedback zugewiesen!", + verb_es="¡Has sido asignado como manager en un feedback!", + verb_fr="Vous avez été désigné comme manager dans un commentaire !", + redirect=f"/pms/feedback-detailed-view/{form.id}", + icon="chatbox-ellipses", + ) # Send notification to subordinates if form.subordinate_id: subordinates = form.subordinate_id.all() for subordinate in subordinates: - notify.send(request.user.employee_get, recipient=subordinate.employee_user_id, verb='You have been assigned as a subordinate in a feedback!', redirect=f'/pms/feedback-detailed-view/{form.id}', icon='chatbox-ellipses') + notify.send( + request.user.employee_get, + recipient=subordinate.employee_user_id, + verb="You have been assigned as a subordinate in a feedback!", + verb_ar="لقد تم تعيينك كمرؤوس في ملاحظة!", + verb_de="Sie wurden als Untergebener in einem Feedback zugewiesen!", + verb_es="¡Has sido asignado como subordinado en un feedback!", + verb_fr="Vous avez été désigné comme subordonné dans un commentaire !", + redirect=f"/pms/feedback-detailed-view/{form.id}", + icon="chatbox-ellipses", + ) # Send notification to colleagues if form.colleague_id: colleagues = form.colleague_id.all() for colleague in colleagues: - notify.send(request.user.employee_get, recipient=colleague.employee_user_id, verb='You have been assigned as a colleague in a feedback!', redirect=f'/pms/feedback-detailed-view/{form.id}', icon='chatbox-ellipses') + notify.send( + request.user.employee_get, + recipient=colleague.employee_user_id, + verb="You have been assigned as a colleague in a feedback!", + verb_ar="لقد تم تعيينك كزميل في ملاحظة!", + verb_de="Sie wurden als Kollege in einem Feedback zugewiesen!", + verb_es="¡Has sido asignado como colega en un feedback!", + verb_fr="Vous avez été désigné comme collègue dans un commentaire !", + redirect=f"/pms/feedback-detailed-view/{form.id}", + icon="chatbox-ellipses", + ) @login_required -@manager_can_enter(perm='pms.add_feedback') +@manager_can_enter(perm="pms.add_feedback") def feedback_creation(request): """ - This view is used to create feedback object. + This view is used to create feedback object. Returns: it will return feedback creation html. """ @@ -600,89 +772,106 @@ def feedback_creation(request): context = { "feedback_form": form, } - if request.method == 'POST': + if request.method == "POST": form = FeedbackForm(request.POST) if form.is_valid(): - if key_result_ids := request.POST.getlist('employee_key_results_id'): + if key_result_ids := request.POST.getlist("employee_key_results_id"): for key_result_id in key_result_ids: key_result = EmployeeKeyResult.objects.get(id=key_result_id) feedback_form = form.save() feedback_form.employee_key_results_id.add(key_result) instance = form.save() - messages.success(request,_('Feedback created successfully.')) - send_feedback_notifications(request,form = instance) + messages.success(request, _("Feedback created successfully.")) + send_feedback_notifications(request, form=instance) return redirect(feedback_list_view) else: - context['feedback_form'] = form - return render(request, 'feedback/feedback_creation.html', context) + context["feedback_form"] = form + return render(request, "feedback/feedback_creation.html", context) @login_required -@manager_can_enter(perm='pms.add_feedback') +@manager_can_enter(perm="pms.add_feedback") def feedback_creation_ajax(request): """ - This view is used to create feedback object. + This view is used to create feedback object. Returns: it will return feedback creation html. """ - # this ajax request is used to get the Key result and manager of the choosen employee - is_ajax = request.headers.get('X-Requested-With') == 'XMLHttpRequest' + # this ajax request is used to get the Key result and manager of the choosen employee + is_ajax = request.headers.get("X-Requested-With") == "XMLHttpRequest" if is_ajax: - if request.method == 'POST': - employee_id = request.POST.get('employee_id') - key_results = EmployeeKeyResult.objects.filter(employee_id=employee_id).values() - employee_work_info = EmployeeWorkInformation.objects.filter(employee_id__id = employee_id).first() + if request.method == "POST": + employee_id = request.POST.get("employee_id") + key_results = EmployeeKeyResult.objects.filter( + employee_id=employee_id + ).values() + employee_work_info = EmployeeWorkInformation.objects.filter( + employee_id__id=employee_id + ).first() reporting_manager_id = employee_work_info.reporting_manager_id if reporting_manager_id: reporting_manager = { "id": reporting_manager_id.id or None, - "employee_first_name": reporting_manager_id.employee_first_name or None, - "employee_last_name": reporting_manager_id.employee_last_name or None, - } + "employee_first_name": reporting_manager_id.employee_first_name + or None, + "employee_last_name": reporting_manager_id.employee_last_name + or None, + } else: - reporting_manager = None - return JsonResponse({'key_results': list(key_results),'reporting_manager':reporting_manager}) - return JsonResponse({'status': 'Invalid request'}, status=400) + reporting_manager = None + return JsonResponse( + { + "key_results": list(key_results), + "reporting_manager": reporting_manager, + } + ) + return JsonResponse({"status": "Invalid request"}, status=400) @login_required @hx_request_required -@manager_can_enter(perm='pms.change_feedback') +@manager_can_enter(perm="pms.change_feedback") def feedback_update(request, id): """ - This view is used to update the feedback. + This view is used to update the feedback. Args: id(int) : primarykey of the feedback. Returns: it will redirect to feedback_detailed_view. """ - + feedback = Feedback.objects.get(id=id) form = FeedbackForm(instance=feedback) feedback_started = Answer.objects.filter(feedback_id=feedback) - context = {'feedback_form': form} + context = {"feedback_form": form} if feedback_started: - messages.error(request,'Ongoing feedback is not editable!.') - response = render(request,'feedback/feedback_update.html',context) - return HttpResponse(response.content.decode('utf-8') +'') + messages.error(request, "Ongoing feedback is not editable!.") + response = render(request, "feedback/feedback_update.html", context) + return HttpResponse( + response.content.decode("utf-8") + "" + ) - if request.method =='POST': + if request.method == "POST": form = FeedbackForm(request.POST, instance=feedback) if form.is_valid(): form = form.save() - messages.info(request,'Feedback updated successfully!.') - send_feedback_notifications(request,form) - response = render(request,'feedback/feedback_update.html',context) - return HttpResponse(response.content.decode('utf-8') +'') + messages.info(request, "Feedback updated successfully!.") + send_feedback_notifications(request, form) + response = render(request, "feedback/feedback_update.html", context) + return HttpResponse( + response.content.decode("utf-8") + "" + ) else: - context['feedback_form'] = form - return render(request, 'feedback/feedback_update.html', context) + context["feedback_form"] = form + return render(request, "feedback/feedback_update.html", context) @login_required -def filter_pagination_feedback(request, self_feedback, requested_feedback, all_feedback): +def filter_pagination_feedback( + request, self_feedback, requested_feedback, all_feedback +): """ - This view is used to filter or search the feedback object , + This view is used to filter or search the feedback object , Args: self_feedback (queryset): self feedback filtered queryset. @@ -693,30 +882,36 @@ def filter_pagination_feedback(request, self_feedback, requested_feedback, all_f it will return the filtered and searched object. """ - previous_data = request.environ['QUERY_STRING'] - initial_data = {'archive': False} # set initial value of archive filter to False - feedback_filter_own = FeedbackFilter(request.GET or initial_data, queryset=self_feedback) - feedback_filter_requested = FeedbackFilter(request.GET or initial_data, queryset=requested_feedback) - feedback_filter_all = FeedbackFilter(request.GET or initial_data, queryset=all_feedback) + previous_data = request.environ["QUERY_STRING"] + initial_data = {"archive": False} # set initial value of archive filter to False + feedback_filter_own = FeedbackFilter( + request.GET or initial_data, queryset=self_feedback + ) + feedback_filter_requested = FeedbackFilter( + request.GET or initial_data, queryset=requested_feedback + ) + feedback_filter_all = FeedbackFilter( + request.GET or initial_data, queryset=all_feedback + ) feedback_paginator_own = Paginator(feedback_filter_own.qs, 50) feedback_paginator_requested = Paginator(feedback_filter_requested.qs, 50) feedback_paginator_all = Paginator(feedback_filter_all.qs, 50) - page_number = request.GET.get('page') + page_number = request.GET.get("page") feedbacks_own = feedback_paginator_own.get_page(page_number) feedbacks_requested = feedback_paginator_requested.get_page(page_number) feedbacks_all = feedback_paginator_all.get_page(page_number) - now =datetime.datetime.now() + now = datetime.datetime.now() context = { - 'superuser': 'true', - 'self_feedback': feedbacks_own, - 'requested_feedback': feedbacks_requested, - 'all_feedbacks': feedbacks_all, - 'feedback_filter_form': feedback_filter_own.form, - 'pg': previous_data, - 'current_date':now, + "superuser": "true", + "self_feedback": feedbacks_own, + "requested_feedback": feedbacks_requested, + "all_feedbacks": feedbacks_all, + "feedback_filter_form": feedback_filter_own.form, + "pg": previous_data, + "current_date": now, } return context @@ -725,76 +920,106 @@ def filter_pagination_feedback(request, self_feedback, requested_feedback, all_f @hx_request_required def feedback_list_search(request): """ - This view is used to filter or search the feedback object , + This view is used to filter or search the feedback object , Args: Returns: it will return the filtered and searched object. """ - feedback = request.GET.get('search') # if the search is none the filter will works + feedback = request.GET.get("search") # if the search is none the filter will works if feedback is None: feedback = "" employee_id = Employee.objects.get(employee_user_id=request.user) - self_feedback = Feedback.objects.filter(employee_id=employee_id).filter(review_cycle__icontains=feedback) + self_feedback = Feedback.objects.filter(employee_id=employee_id).filter( + review_cycle__icontains=feedback + ) requested_feedback_ids = [] - requested_feedback_ids.extend([i.id for i in Feedback.objects.filter(manager_id=employee_id)]) - requested_feedback_ids.extend([i.id for i in Feedback.objects.filter(colleague_id=employee_id)]) - requested_feedback_ids.extend( [i.id for i in Feedback.objects.filter(subordinate_id=employee_id)]) + requested_feedback_ids.extend( + [i.id for i in Feedback.objects.filter(manager_id=employee_id)] + ) + requested_feedback_ids.extend( + [i.id for i in Feedback.objects.filter(colleague_id=employee_id)] + ) + requested_feedback_ids.extend( + [i.id for i in Feedback.objects.filter(subordinate_id=employee_id)] + ) - requested_feedback = Feedback.objects.filter(pk__in=requested_feedback_ids).filter(review_cycle__icontains=feedback) + requested_feedback = Feedback.objects.filter(pk__in=requested_feedback_ids).filter( + review_cycle__icontains=feedback + ) all_feedback = Feedback.objects.all().filter(review_cycle__icontains=feedback) reporting_manager_to = employee_id.reporting_manager.all() - if request.user.has_perm('pms.view_feedback'): + if request.user.has_perm("pms.view_feedback"): context = filter_pagination_feedback( - request, self_feedback, requested_feedback, all_feedback) + request, self_feedback, requested_feedback, all_feedback + ) elif reporting_manager_to: employees_id = [i.id for i in reporting_manager_to] - all_feedback = Feedback.objects.filter( - employee_id__in=employees_id).filter(review_cycle__icontains=feedback) + all_feedback = Feedback.objects.filter(employee_id__in=employees_id).filter( + review_cycle__icontains=feedback + ) context = filter_pagination_feedback( - request, self_feedback, requested_feedback, all_feedback) + request, self_feedback, requested_feedback, all_feedback + ) else: all_feedback = Feedback.objects.none() context = filter_pagination_feedback( - request, self_feedback, requested_feedback, all_feedback) + request, self_feedback, requested_feedback, all_feedback + ) - return render(request, 'feedback/feedback_list.html', context) + return render(request, "feedback/feedback_list.html", context) @login_required def feedback_list_view(request): """ - This view is used to filter or search the feedback object , + This view is used to filter or search the feedback object , Args: Returns: it will return the filtered and searched object. """ user = request.user employee = Employee.objects.filter(employee_user_id=user).first() - feedback_requested_ids = Feedback.objects.filter(Q(manager_id=employee) | Q(colleague_id=employee) | Q(subordinate_id=employee)).values_list('id', flat=True) - feedback_own = Feedback.objects.filter(employee_id=employee).exclude(status='Closed').filter(archive=False) - feedback_requested = Feedback.objects.filter(pk__in=feedback_requested_ids).filter(archive=False) - feedback_all = Feedback.objects.all().exclude(status='Closed').filter(archive=False) - employees = Employee.objects.filter(employee_work_info__reporting_manager_id = employee) # checking the user is reporting manager or not + feedback_requested_ids = Feedback.objects.filter( + Q(manager_id=employee) | Q(colleague_id=employee) | Q(subordinate_id=employee) + ).values_list("id", flat=True) + feedback_own = ( + Feedback.objects.filter(employee_id=employee) + .exclude(status="Closed") + .filter(archive=False) + ) + feedback_requested = Feedback.objects.filter(pk__in=feedback_requested_ids).filter( + archive=False + ) + feedback_all = Feedback.objects.all().exclude(status="Closed").filter(archive=False) + employees = Employee.objects.filter( + employee_work_info__reporting_manager_id=employee + ) # checking the user is reporting manager or not - if request.user.has_perm('pms.view_feedback'): - context = filter_pagination_feedback(request, feedback_own, feedback_requested, feedback_all) + if request.user.has_perm("pms.view_feedback"): + context = filter_pagination_feedback( + request, feedback_own, feedback_requested, feedback_all + ) elif employees: - # based on the reporting manager - feedback_all = Feedback.objects.filter(employee_id__in =employees) - context = filter_pagination_feedback(request, feedback_own, feedback_requested, feedback_all) + # based on the reporting manager + feedback_all = Feedback.objects.filter(employee_id__in=employees) + context = filter_pagination_feedback( + request, feedback_own, feedback_requested, feedback_all + ) else: feedback_all = Feedback.objects.none() - context = filter_pagination_feedback(request, feedback_own, feedback_requested, feedback_all) + context = filter_pagination_feedback( + request, feedback_own, feedback_requested, feedback_all + ) - return render(request, 'feedback/feedback_list_view.html', context) + return render(request, "feedback/feedback_list_view.html", context) @login_required def feedback_detailed_view(request, id): """ - This view is used to for detailed view of feedback, + This view is used to for detailed view of feedback, Args: id(int) : primarykey of the feedback Returns: @@ -803,17 +1028,16 @@ def feedback_detailed_view(request, id): feedback = Feedback.objects.get(id=id) current_date = datetime.datetime.now() context = { - 'feedback': feedback, - 'feedback_status': Feedback.STATUS_CHOICES, - 'current_date':current_date, - + "feedback": feedback, + "feedback_status": Feedback.STATUS_CHOICES, + "current_date": current_date, } - return render(request, 'feedback/feedback_detailed_view.html', context) + return render(request, "feedback/feedback_detailed_view.html", context) -def feedback_detailed_view_answer(request,id,emp_id): +def feedback_detailed_view_answer(request, id, emp_id): """ - This view is used show answer , + This view is used show answer , Args: id(int) : primarykey of the feedback. emp_id(int) : primarykey of the Employee. @@ -822,17 +1046,17 @@ def feedback_detailed_view_answer(request,id,emp_id): """ employee = Employee.objects.filter(id=emp_id).first() feedback = Feedback.objects.filter(id=id).first() - answers = Answer.objects.filter(employee_id = employee, feedback_id = feedback) + answers = Answer.objects.filter(employee_id=employee, feedback_id=feedback) context = { - 'answers': answers, + "answers": answers, } - return render(request, 'feedback/feedback_detailed_view_answer.html', context) + return render(request, "feedback/feedback_detailed_view_answer.html", context) @login_required def feedback_answer_get(request, id): """ - This view is used to render the feedback questions , + This view is used to render the feedback questions , Args: id(int) : primarykey of the feedback. Returns: @@ -846,37 +1070,44 @@ def feedback_answer_get(request, id): question_template = feedback.question_template_id questions = question_template.question.all() options = QuestionOptions.objects.all() - feedback_employees = [feedback.employee_id] +[feedback.manager_id] + list(feedback.colleague_id.all()) + list(feedback.subordinate_id.all()) + feedback_employees = ( + [feedback.employee_id] + + [feedback.manager_id] + + list(feedback.colleague_id.all()) + + list(feedback.subordinate_id.all()) + ) if not employee in feedback_employees: - messages.info(request, _('You are not allowed to answer')) + messages.info(request, _("You are not allowed to answer")) return redirect(feedback_list_view) - + # Employee does not have an answer object for employee in feedback_employees: - has_answer = Answer.objects.filter(employee_id=employee, feedback_id=feedback).exists() + has_answer = Answer.objects.filter( + employee_id=employee, feedback_id=feedback + ).exists() has_answer = has_answer and has_answer if has_answer: - feedback.status = 'Closed' + feedback.status = "Closed" feedback.save() # Check if the feedback has already been answered if answer: - messages.info(request, _('Feedback already answered')) + messages.info(request, _("Feedback already answered")) return redirect(feedback_list_view) - + context = { - 'questions': questions, - 'options': options, - 'feedback': feedback, + "questions": questions, + "options": options, + "feedback": feedback, } - - return render(request, 'feedback/answer/feedback_answer.html', context) - + + return render(request, "feedback/answer/feedback_answer.html", context) + @login_required def feedback_answer_post(request, id): """ - This view is used to create feedback answer , + This view is used to create feedback answer , Args: id(int) : primarykey of the feedback. Returns: @@ -888,26 +1119,40 @@ def feedback_answer_post(request, id): feedback = Feedback.objects.get(id=id) question_template = feedback.question_template_id questions = question_template.question.all() - - if request.method == 'POST': + + if request.method == "POST": for question in questions: - if request.POST.get(f'answer{question.id}'): - answer = request.POST.get(f'answer{question.id}') - Answer.objects.get_or_create(answer={'answer': answer}, question_id=question, feedback_id=feedback, employee_id=employee) - feedback.status = 'On Track' + if request.POST.get(f"answer{question.id}"): + answer = request.POST.get(f"answer{question.id}") + Answer.objects.get_or_create( + answer={"answer": answer}, + question_id=question, + feedback_id=feedback, + employee_id=employee, + ) + feedback.status = "On Track" feedback.save() for key_result in feedback.employee_key_results_id.all(): - if request.POST.get(f'key_result{key_result.id}'): - answer = request.POST.get(f'key_result{key_result.id}') - KeyresultFeedback.objects.get_or_create(answer={'answer': answer}, key_result_id=key_result, feedback_id=feedback, employee_id=request.user.employee_get) - messages.success(request,_('Feedback %(review_cycle)s has been answered successfully!.') % {'review_cycle':feedback.review_cycle}) + if request.POST.get(f"key_result{key_result.id}"): + answer = request.POST.get(f"key_result{key_result.id}") + KeyresultFeedback.objects.get_or_create( + answer={"answer": answer}, + key_result_id=key_result, + feedback_id=feedback, + employee_id=request.user.employee_get, + ) + messages.success( + request, + _("Feedback %(review_cycle)s has been answered successfully!.") + % {"review_cycle": feedback.review_cycle}, + ) return redirect(feedback_list_view) @login_required def feedback_answer_view(request, id): """ - This view is used to view the feedback for employee. + This view is used to view the feedback for employee. Args: id(int) : primarykey of the feedback. Returns: @@ -918,25 +1163,27 @@ def feedback_answer_view(request, id): employee = Employee.objects.filter(employee_user_id=user).first() feedback = Feedback.objects.get(id=id) answers = Answer.objects.filter(feedback_id=feedback, employee_id=employee) - key_result_feedback = KeyresultFeedback.objects.filter(feedback_id=feedback, employee_id=employee) - + key_result_feedback = KeyresultFeedback.objects.filter( + feedback_id=feedback, employee_id=employee + ) + if not answers: - messages.info(request, _('Feedback is not answered yet')) + messages.info(request, _("Feedback is not answered yet")) return redirect(feedback_list_view) - + context = { - 'answers': answers, - 'feedback_id': feedback, - 'key_result_feedback': key_result_feedback, + "answers": answers, + "feedback_id": feedback, + "key_result_feedback": key_result_feedback, } - return render(request, 'feedback/answer/feedback_answer_view.html', context) + return render(request, "feedback/answer/feedback_answer_view.html", context) @login_required -@manager_can_enter(perm='pms.delete_feedback') +@manager_can_enter(perm="pms.delete_feedback") def feedback_delete(request, id): """ - This view is used to delete the feedback. + This view is used to delete the feedback. Args: id(int) : primarykey of the feedback. Returns: @@ -944,14 +1191,22 @@ def feedback_delete(request, id): """ feedback = Feedback.objects.filter(id=id).first() - answered = Answer.objects.filter(feedback_id =feedback).first() - if feedback.status == 'Closed' or feedback.status == 'Not Started' and not answered: + answered = Answer.objects.filter(feedback_id=feedback).first() + if feedback.status == "Closed" or feedback.status == "Not Started" and not answered: feedback.delete() - messages.success(request,_('Feedback %(review_cycle)s deleted successfully!') % {'review_cycle':feedback.review_cycle}) + messages.success( + request, + _("Feedback %(review_cycle)s deleted successfully!") + % {"review_cycle": feedback.review_cycle}, + ) return redirect(feedback_list_view) else: - messages.warning(request,_('Feedback %(review_cycle)s is ongoing you you can archive it!') % {'review_cycle':feedback.review_cycle}) - return redirect(feedback_detailed_view,feedback.id) + messages.warning( + request, + _("Feedback %(review_cycle)s is ongoing you you can archive it!") + % {"review_cycle": feedback.review_cycle}, + ) + return redirect(feedback_detailed_view, feedback.id) @login_required @@ -964,105 +1219,118 @@ def feedback_detailed_view_status(request, id): Returns: message to the view """ - status = request.POST.get('feedback_status') - feedback = get_object_or_404(Feedback,id=id) - answer = Answer.objects.filter(feedback_id = feedback) - if status == 'Not Started' and answer: - messages.warning(request,_('Feedback is already started')) - return render(request,'messages.html') + status = request.POST.get("feedback_status") + feedback = get_object_or_404(Feedback, id=id) + answer = Answer.objects.filter(feedback_id=feedback) + if status == "Not Started" and answer: + messages.warning(request, _("Feedback is already started")) + return render(request, "messages.html") feedback.status = status feedback.save() if (feedback.status) == status: - messages.info(request,_('Feedback status updated to %(status)s') % {'status':_(status)}) - return render(request,'messages.html') - messages.info(request,_('Error occurred during status update to %(status)s') % {'status':_(status)}) - return render(request,'message.html') + messages.info( + request, _("Feedback status updated to %(status)s") % {"status": _(status)} + ) + return render(request, "messages.html") + messages.info( + request, + _("Error occurred during status update to %(status)s") % {"status": _(status)}, + ) + return render(request, "message.html") @login_required def feedback_archive(request, id): """ - this function is used to archive the feedback for employee - args: - id(int): primarykey of feedback + this function is used to archive the feedback for employee + args: + id(int): primarykey of feedback """ - + feedback = Feedback.objects.get(id=id) if feedback.archive == True: - feedback.archive = False + feedback.archive = False feedback.save() - messages.info(request,_('Feedback un-archived successfully!.')) + messages.info(request, _("Feedback un-archived successfully!.")) elif feedback.archive == False: feedback.archive = True feedback.save() - messages.info(request,_('Feedback archived successfully!.')) + messages.info(request, _("Feedback archived successfully!.")) return redirect(feedback_list_view) @login_required def feedback_status(request): - """this function is used to un-archive the feedback - args: - id(int): primarykey of feedback - emp_id(int): primarykey of feedback + """this function is used to un-archive the feedback + args: + id(int): primarykey of feedback + emp_id(int): primarykey of feedback """ - - is_ajax = request.headers.get('X-Requested-With') == 'XMLHttpRequest' + + is_ajax = request.headers.get("X-Requested-With") == "XMLHttpRequest" if is_ajax: - if request.method == 'POST': - employee_id = request.POST.get('employee_id') - feedback_id = request.POST.get('feedback_id') + if request.method == "POST": + employee_id = request.POST.get("employee_id") + feedback_id = request.POST.get("feedback_id") feedback = Feedback.objects.get(id=feedback_id) employee = Employee.objects.filter(id=employee_id).first() - answer = Answer.objects.filter(employee_id=employee,feedback_id = feedback) - status = _('Completed') if answer else _('Not-completed') - return JsonResponse({'status': status}) - return JsonResponse({'status': 'Invalid request'}, status=400) - + answer = Answer.objects.filter(employee_id=employee, feedback_id=feedback) + status = _("Completed") if answer else _("Not-completed") + return JsonResponse({"status": status}) + return JsonResponse({"status": "Invalid request"}, status=400) + @login_required -@manager_can_enter(perm='pms.add_question') +@manager_can_enter(perm="pms.add_question") def question_creation(request, id): """ - This view is used to create question object. + This view is used to create question object. Args: id(int) : primarykey of the question template. Returns: it will redirect to question_template_detailed_view. """ - if request.method == 'POST': + if request.method == "POST": form = QuestionForm(request.POST) question_template = QuestionTemplate.objects.get(id=id) - feedback_ongoing = Feedback.objects.filter(question_template_id=question_template).first() + feedback_ongoing = Feedback.objects.filter( + question_template_id=question_template + ).first() if feedback_ongoing: - messages.info(request,_('Question template is used in feedback.')) + messages.info(request, _("Question template is used in feedback.")) return redirect(question_template_detailed_view, id) if form.is_valid(): obj_question = form.save(commit=False) obj_question.template_id = question_template obj_question.save() - if obj_question.question_type == '4': + if obj_question.question_type == "4": # checking the question type is multichoice - option_a = request.POST.get('option_a') - option_b = request.POST.get('option_b') - option_c = request.POST.get('option_c') - option_d = request.POST.get('option_d') - QuestionOptions(question_id=obj_question, option_a=option_a, - option_b=option_b, option_c=option_c, option_d=option_d).save() - messages.success(request,_('Question created successfully.')) + option_a = request.POST.get("option_a") + option_b = request.POST.get("option_b") + option_c = request.POST.get("option_c") + option_d = request.POST.get("option_d") + QuestionOptions( + question_id=obj_question, + option_a=option_a, + option_b=option_b, + option_c=option_c, + option_d=option_d, + ).save() + messages.success(request, _("Question created successfully.")) return redirect(question_template_detailed_view, id) - messages.success(request,_('Question created successfully.')) + messages.success(request, _("Question created successfully.")) return redirect(question_template_detailed_view, id) else: - messages.error(request,_('Error occurred during question creation!')) + messages.error(request, _("Error occurred during question creation!")) return redirect(question_template_detailed_view, id) + @login_required def question_view(request, id): """ - This view is used to view question object. + This view is used to view question object. Args: id(int) : primarykey of the question template. Returns: @@ -1074,26 +1342,30 @@ def question_view(request, id): questions = question_template.question.all() formset = question_formset(queryset=questions) options = [] - question_types = ['text', 'ratings', 'boolean', 'Multi-choices', 'likert'] + question_types = ["text", "ratings", "boolean", "Multi-choices", "likert"] for question in questions: question_options = QuestionOptions.objects.filter(question_id=question) options.extend(question_options) context = { - 'question_template': question_template, - 'questions': questions, - 'question_options': options, - 'question_types': question_types, - 'formset': formset + "question_template": question_template, + "questions": questions, + "question_options": options, + "question_types": question_types, + "formset": formset, } - return render(request, 'feedback/question_template/question_template_detailed_view.html', context) + return render( + request, + "feedback/question_template/question_template_detailed_view.html", + context, + ) @login_required -@manager_can_enter(perm='pms.change_question') +@manager_can_enter(perm="pms.change_question") def question_update(request, temp_id, q_id): """ - This view is used to update question object. + This view is used to update question object. Args: id (int): primarykey of question temp_id (int): primarykey of question_template @@ -1101,136 +1373,160 @@ def question_update(request, temp_id, q_id): it will redirect to question_template_detailed_view. """ - if request.method == 'POST': + if request.method == "POST": question = Question.objects.get(id=q_id) form = QuestionForm(request.POST, instance=question) if form.is_valid(): - question_type = form.cleaned_data['question_type'] - if question_type == '4': + question_type = form.cleaned_data["question_type"] + if question_type == "4": # if question is Multi-choices - option_a = form.cleaned_data['option_a'] - option_b = form.cleaned_data['option_b'] - option_c = form.cleaned_data['option_c'] - option_d = form.cleaned_data['option_d'] - options, created = QuestionOptions.objects.get_or_create(question_id=question) + option_a = form.cleaned_data["option_a"] + option_b = form.cleaned_data["option_b"] + option_c = form.cleaned_data["option_c"] + option_d = form.cleaned_data["option_d"] + options, created = QuestionOptions.objects.get_or_create( + question_id=question + ) options.option_a = option_a options.option_b = option_b options.option_c = option_c options.option_d = option_d options.save() form.save() - messages.info(request,_('Question updated successfully.')) + messages.info(request, _("Question updated successfully.")) return redirect(question_template_detailed_view, temp_id) else: form.save() question_options = QuestionOptions.objects.filter(question_id=question) if question_options: question_options.delete() - messages.info(request,_('Question updated successfully.')) + messages.info(request, _("Question updated successfully.")) return redirect(question_template_detailed_view, temp_id) else: - # Form submission had errors - messages.error(request, '\n'.join([f'{field}: {error}' for field, errors in form.errors.items() for error in errors])) + # Form submission had errors + messages.error( + request, + "\n".join( + [ + f"{field}: {error}" + for field, errors in form.errors.items() + for error in errors + ] + ), + ) return redirect(question_template_detailed_view, temp_id) @login_required -@manager_can_enter(perm='pms.delete_question') +@manager_can_enter(perm="pms.delete_question") def question_delete(request, id): """ - This view is used to delete question object. + This view is used to delete question object. Args: id (int): primarykey of question Returns: it will redirect to question_template_detailed_view. """ - + try: # Code that may trigger the FOREIGN KEY constraint failed error question = Question.objects.filter(id=id).first() temp_id = question.template_id.id QuestionOptions.objects.filter(question_id=question).delete() question.delete() - messages.success(request, _('Question deleted successfully!')) + messages.success(request, _("Question deleted successfully!")) return redirect(question_template_detailed_view, temp_id) - + except IntegrityError: # Code to handle the FOREIGN KEY constraint failed error - messages.error(request, _('Failed to delete question: Question template is in use.')) + messages.error( + request, _("Failed to delete question: Question template is in use.") + ) return redirect(question_template_detailed_view, temp_id) @login_required -@manager_can_enter(perm='pms.add_questiontemplate') +@manager_can_enter(perm="pms.add_questiontemplate") def question_template_creation(request): """ - This view is used to create question template object. + This view is used to create question template object. Args: Returns: it will redirect to question_template_detailed_view. """ - if request.method == 'POST': + if request.method == "POST": form = QuestionTemplateForm(request.POST) if form.is_valid(): instance = form.save() return redirect(question_template_detailed_view, instance.id) else: - messages.error(request, '\n'.join([f'{field}: {error}' for field, errors in form.errors.items() for error in errors])) + messages.error( + request, + "\n".join( + [ + f"{field}: {error}" + for field, errors in form.errors.items() + for error in errors + ] + ), + ) return redirect(question_template_view) @login_required -@manager_can_enter(perm='pms.view_questiontemplate') +@manager_can_enter(perm="pms.view_questiontemplate") def question_template_view(request): """ - This view is used to view question template object. + This view is used to view question template object. Returns: it will redirect to question_template_detailed_view. """ question_templates = QuestionTemplate.objects.all() - context = { - 'form': QuestionTemplateForm, - 'question_templates': question_templates - } - return render(request, 'feedback/question_template/question_template_view.html', context) + context = {"form": QuestionTemplateForm, "question_templates": question_templates} + return render( + request, "feedback/question_template/question_template_view.html", context + ) @login_required -@manager_can_enter(perm='pms.view_questiontemplate') +@manager_can_enter(perm="pms.view_questiontemplate") def question_template_detailed_view(request, id): """ - This view is used to view question template object. + This view is used to view question template object. Args: id (int): primarykey of question template temp_id (int): primarykey of question_template Returns: it will redirect to question_template_detailed_view. """ - + question_template = QuestionTemplate.objects.get(id=id) questions = question_template.question.all() - question_types = ['text', 'ratings', 'boolean', 'multi-choices', 'likert'] + question_types = ["text", "ratings", "boolean", "multi-choices", "likert"] options = QuestionOptions.objects.filter(question_id__in=questions) - + # passing individual form question_form_list = [QuestionForm(instance=question) for question in questions] context = { - 'question_template': question_template, - 'questions': questions, - 'question_options': options, - 'question_types': question_types, - 'form': QuestionForm, - 'form_list': question_form_list, - + "question_template": question_template, + "questions": questions, + "question_options": options, + "question_types": question_types, + "form": QuestionForm, + "form_list": question_form_list, } - return render(request, 'feedback/question_template/question_template_detailed_view.html', context) + return render( + request, + "feedback/question_template/question_template_detailed_view.html", + context, + ) @login_required -@manager_can_enter(perm='pms.change_questiontemplate') +@manager_can_enter(perm="pms.change_questiontemplate") def question_template_update(request, id): """ - This view is used to update question template object. + This view is used to update question template object. Args: id (int): primarykey of question template Returns: @@ -1238,25 +1534,25 @@ def question_template_update(request, id): """ question_template = QuestionTemplate.objects.filter(id=id).first() - question_update_form =QuestionTemplateForm(instance=question_template) - context = { - 'question_update_form': question_update_form - } - if request.method == 'POST': - form = QuestionTemplateForm(request.POST,instance=question_template) + question_update_form = QuestionTemplateForm(instance=question_template) + context = {"question_update_form": question_update_form} + if request.method == "POST": + form = QuestionTemplateForm(request.POST, instance=question_template) if form.is_valid(): form.save() - messages.info(request,_('Question template updated')) + messages.info(request, _("Question template updated")) return redirect(question_template_view) - context['question_update_form'] =form - return render(request, 'feedback/question_template/question_template_update.html', context) + context["question_update_form"] = form + return render( + request, "feedback/question_template/question_template_update.html", context + ) @login_required -@manager_can_enter(perm='pms.delete_questiontemplate') +@manager_can_enter(perm="pms.delete_questiontemplate") def question_template_delete(request, id): """ - This view is used to delete question template object. + This view is used to delete question template object. Args: id (int): primarykey of question template Returns: @@ -1265,80 +1561,85 @@ def question_template_delete(request, id): question_template = QuestionTemplate.objects.get(id=id) if Feedback.objects.filter(question_template_id=question_template): - messages.info(request, _('This template is using in a feedback')) + messages.info(request, _("This template is using in a feedback")) return redirect(question_template_view) question_template.delete() return redirect(question_template_view) @login_required -@manager_can_enter(perm='pms.view_period') +@manager_can_enter(perm="pms.view_period") def period_view(request): """ - This view is used to view period objects. + This view is used to view period objects. Returns: it will return to period_view. """ periods = Period.objects.all() context = { - 'periods': periods, + "periods": periods, } - return render(request, 'period/period_view.html', context) + return render(request, "period/period_view.html", context) @login_required -@manager_can_enter(perm='pms.add_period') +@manager_can_enter(perm="pms.add_period") @hx_request_required def period_create(request): """ - This view is used to create period objects. + This view is used to create period objects. Returns: it will redirect to period_view. """ - context ={'form':PeriodForm()} - if request.method == 'POST': + context = {"form": PeriodForm()} + if request.method == "POST": form = PeriodForm(request.POST) if form.is_valid(): form.save() - messages.success(request, _('Period creation was Successful ')) - response = render(request,'period/period_create.html',context) - return HttpResponse(response.content.decode('utf-8') +'') + messages.success(request, _("Period creation was Successful ")) + response = render(request, "period/period_create.html", context) + return HttpResponse( + response.content.decode("utf-8") + "" + ) else: - context['form']=form - return render(request,'period/period_create.html',context) + context["form"] = form + return render(request, "period/period_create.html", context) @login_required -@manager_can_enter(perm='pms.change_period') +@manager_can_enter(perm="pms.change_period") def period_update(request, id): """ - This view is used to update period objects. + This view is used to update period objects. Args: id (int): primarykey of period Returns: it will redirect to period_view. """ - + period = Period.objects.filter(id=id).first() - form = PeriodForm(instance = period) - context ={'form': form} - if request.method == 'POST': - form = PeriodForm(request.POST,instance=period) + form = PeriodForm(instance=period) + context = {"form": form} + if request.method == "POST": + form = PeriodForm(request.POST, instance=period) if form.is_valid(): form.save() - messages.info(request, _('Period updated Successfully. ')) - response = render(request,'period/period_update.html',context) - return HttpResponse(response.content.decode('utf-8') +'') + messages.info(request, _("Period updated Successfully. ")) + response = render(request, "period/period_update.html", context) + return HttpResponse( + response.content.decode("utf-8") + "" + ) else: - context['form']=form - return render(request, 'period/period_update.html', context) + context["form"] = form + return render(request, "period/period_update.html", context) + @login_required -@manager_can_enter(perm='pms.delete_period') +@manager_can_enter(perm="pms.delete_period") def period_delete(request, id): """ - This view is used to delete period objects. + This view is used to delete period objects. Args: id (int): primarykey of period Returns: @@ -1347,108 +1648,129 @@ def period_delete(request, id): obj_period = Period.objects.get(id=id) obj_period.delete() - messages.info(request,_('Period deleted successfully.')) + messages.info(request, _("Period deleted successfully.")) return redirect(period_view) @login_required def period_change(request): """this function is used to detect the period change and return the start and end date of that period""" - is_ajax = request.headers.get('X-Requested-With') == 'XMLHttpRequest' + is_ajax = request.headers.get("X-Requested-With") == "XMLHttpRequest" if is_ajax: - if request.method == 'POST': + if request.method == "POST": data = json.load(request) period_obj = Period.objects.get(id=data) start_date = period_obj.start_date end_date = period_obj.end_date - return JsonResponse({'start_date': start_date, 'end_date': end_date}) - return JsonResponse({'failed': 'failed'}) + return JsonResponse({"start_date": start_date, "end_date": end_date}) + return JsonResponse({"failed": "failed"}) return HttpResponse(status=204) + @login_required def dashboard_view(request): """ - This view is used to view dashboard. + This view is used to view dashboard. Returns: it will redirect to dashboard. """ user = request.user employee = Employee.objects.filter(employee_user_id=user).first() - is_manager = Employee.objects.filter(employee_work_info__reporting_manager_id=employee) + is_manager = Employee.objects.filter( + employee_work_info__reporting_manager_id=employee + ) - if user.has_perm('pms.view_employeeobjective') and user.has_perm('pms.view_feedback'): + if user.has_perm("pms.view_employeeobjective") and user.has_perm( + "pms.view_feedback" + ): count_objective = EmployeeObjective.objects.all().count() count_key_result = EmployeeKeyResult.objects.all().count() count_feedback = Feedback.objects.all().count() - okr_at_risk = EmployeeObjective.objects.filter(status ='At Risk') - if is_manager : + okr_at_risk = EmployeeObjective.objects.filter(status="At Risk") + if is_manager: employees_ids = [employee.id for employee in is_manager] - count_objective = EmployeeObjective.objects.filter(employee_id__in=employees_ids).count() - count_key_result = EmployeeObjective.objects.filter(emp_obj_id__employee_id__in = employees_ids).count() - count_feedback = Feedback.objects.filter(employee_id__in =employees_ids).count() - okr_at_risk = EmployeeObjective.objects.filter(employee_id__in=employees_ids).filter(status ='At Risk') + count_objective = EmployeeObjective.objects.filter( + employee_id__in=employees_ids + ).count() + count_key_result = EmployeeObjective.objects.filter( + emp_obj_id__employee_id__in=employees_ids + ).count() + count_feedback = Feedback.objects.filter(employee_id__in=employees_ids).count() + okr_at_risk = EmployeeObjective.objects.filter( + employee_id__in=employees_ids + ).filter(status="At Risk") else: - count_objective = EmployeeObjective.objects.filter(employee_id = employee).count() - count_key_result = EmployeeKeyResult.objects.filter(employee_id = employee).count() - count_feedback = Feedback.objects.filter(employee_id = employee).count() - okr_at_risk = EmployeeObjective.objects.filter(employee_id = employee).filter(status ='At Risk') + count_objective = EmployeeObjective.objects.filter(employee_id=employee).count() + count_key_result = EmployeeKeyResult.objects.filter( + employee_id=employee + ).count() + count_feedback = Feedback.objects.filter(employee_id=employee).count() + okr_at_risk = EmployeeObjective.objects.filter(employee_id=employee).filter( + status="At Risk" + ) context = { - 'count_objective':count_objective, - 'count_key_result':count_key_result, - 'count_feedback':count_feedback, - 'okr_at_risk':okr_at_risk - } - return render(request,'dashboard/pms_dashboard.html',context) + "count_objective": count_objective, + "count_key_result": count_key_result, + "count_feedback": count_feedback, + "okr_at_risk": okr_at_risk, + } + return render(request, "dashboard/pms_dashboard.html", context) @login_required def dashboard_objective_status(request): """objective dashboard data""" - is_ajax = request.headers.get('X-Requested-With') == 'XMLHttpRequest' - if is_ajax and request.method == 'GET': + is_ajax = request.headers.get("X-Requested-With") == "XMLHttpRequest" + if is_ajax and request.method == "GET": objective_status = EmployeeObjective.STATUS_CHOICES data = {} for status in objective_status: objectives = EmployeeObjective.objects.filter(status=status[0]) - objectives_count = filtersubordinates(request,queryset=objectives,perm='pms.view_employeeobjective').count() + objectives_count = filtersubordinates( + request, queryset=objectives, perm="pms.view_employeeobjective" + ).count() # if not objectives_count: - data.setdefault('objective_label', []).append(status[0]) - data.setdefault('objective_value', []).append(objectives_count) + data.setdefault("objective_label", []).append(status[1]) + data.setdefault("objective_value", []).append(objectives_count) return JsonResponse(data) @login_required def dashboard_key_result_status(request): """key result dashboard data""" - is_ajax = request.headers.get('X-Requested-With') == 'XMLHttpRequest' - if is_ajax and request.method == 'GET': + is_ajax = request.headers.get("X-Requested-With") == "XMLHttpRequest" + if is_ajax and request.method == "GET": key_result_status = EmployeeKeyResult.STATUS_CHOICES data = {} for i in key_result_status: key_results = EmployeeKeyResult.objects.filter(status=i[0]) - key_results_count = filtersubordinates(request,queryset=key_results,perm='pms.view_employeekeyresult').count() - data.setdefault('key_result_label', []).append(i[0]) - data.setdefault('key_result_value', []).append(key_results_count) + key_results_count = filtersubordinates( + request, queryset=key_results, perm="pms.view_employeekeyresult" + ).count() + data.setdefault("key_result_label", []).append(i[1]) + data.setdefault("key_result_value", []).append(key_results_count) return JsonResponse(data) @login_required def dashboard_feedback_status(request): """feedback dashboard data""" - is_ajax = request.headers.get('X-Requested-With') == 'XMLHttpRequest' - if is_ajax and request.method == 'GET': + is_ajax = request.headers.get("X-Requested-With") == "XMLHttpRequest" + if is_ajax and request.method == "GET": feedback_status = Feedback.STATUS_CHOICES data = {} for i in feedback_status: feedbacks = Feedback.objects.filter(status=i[0]) - feedback_count = filtersubordinates(request,queryset=feedbacks,perm='pms.view_feedback').count() - data.setdefault('feedback_label', []).append(i[0]) - data.setdefault('feedback_value', []).append(feedback_count) + feedback_count = filtersubordinates( + request, queryset=feedbacks, perm="pms.view_feedback" + ).count() + data.setdefault("feedback_label", []).append(i[1]) + data.setdefault("feedback_value", []).append(feedback_count) return JsonResponse(data) - -def filtersubordinates(request,queryset,perm=None): + +def filtersubordinates(request, queryset, perm=None): """ This method is used to filter out subordinates queryset element. """ @@ -1457,9 +1779,10 @@ def filtersubordinates(request,queryset,perm=None): return queryset manager = Employee.objects.filter(employee_user_id=user).first() if manager: - queryset = queryset.filter(employee_id__employee_work_info__reporting_manager_id=manager) | queryset.filter(employee_id = manager) + queryset = queryset.filter( + employee_id__employee_work_info__reporting_manager_id=manager + ) | queryset.filter(employee_id=manager) return queryset else: - queryset = queryset.filter(employee_id=user.employee_get) + queryset = queryset.filter(employee_id=user.employee_get) return queryset - diff --git a/recruitment/views.py b/recruitment/views.py index 848dd3f4b..007bbf67f 100644 --- a/recruitment/views.py +++ b/recruitment/views.py @@ -131,6 +131,10 @@ def recruitment(request): request.user.employee_get, recipient=users, verb="You are chosen as one of recruitment manager", + verb_ar="لقد تم اختيارك كواحد من مديري التوظيف.", + verb_de="Sie wurden als einer der Einstellungsmanager ausgewählt.", + verb_es="Has sido elegido como uno de los gerentes de contratación.", + verb_fr="Vous avez été choisi comme l'un des responsables du recrutement.", icon="people-circle", redirect="/recruitment/pipeline", ) @@ -164,6 +168,10 @@ def remove_recruitment_manager(request, mid, rid): request.user.employee_get, recipient=manager.employee_user_id, verb=f"You are removed from recruitment manager from {recruitment_obj}", + verb_ar=f"تمت إزالتك من دور مدير التوظيف لـ {recruitment_obj}.", + verb_de=f"Sie wurden aus der Rolle des Einstellungsmanagers für {recruitment_obj} entfernt.", + verb_es=f"Has sido removido del rol de gerente de contratación para {recruitment_obj}.", + verb_fr=f"Vous avez été retiré du rôle de responsable du recrutement pour {recruitment_obj}.", icon="person-remove", redirect="", ) @@ -248,6 +256,10 @@ def recruitment_update(request, rec_id): request.user.employee_get, recipient=users, verb=f"{recruitment_obj} is updated, You are chosen as one of managers", + verb_ar=f"{recruitment_obj} تم تحديثه. تم اختيارك كواحد من المديرين.", + verb_de=f"{recruitment_obj} wurde aktualisiert. Du wurdest als einer der Manager ausgewählt.", + verb_es=f"{recruitment_obj} se ha actualizado. Has sido elegido como uno de los gerentes.", + verb_fr=f"{recruitment_obj} a été mis à jour. Vous avez été choisi comme l'un des responsables.", icon="people-circle", redirect="/recruitment/pipeline", ) @@ -326,6 +338,10 @@ def recruitment_pipeline(request): recipient=users, verb=f"""You are chosen as recruitment manager for the recruitment {recruitment_obj}""", + verb_ar=f"تم اختيارك كمدير توظيف للتوظيف {recruitment_obj}.", + verb_de=f"Sie wurden als Recruitment Manager für das Recruitment {recruitment_obj} ausgewählt.", + verb_es=f"Has sido elegido como gerente de contratación para el reclutamiento {recruitment_obj}.", + verb_fr=f"Vous avez été choisi en tant que responsable du recrutement pour le recrutement {recruitment_obj}.", icon="people-circle", redirect="/recruitment/pipeline", ) @@ -347,6 +363,10 @@ def recruitment_pipeline(request): request.user.employee_get, recipient=users, verb=f"New candidate arrived on stage {candidate_obj.stage_id.stage}", + verb_ar=f"وصل مرشح جديد إلى المرحلة {candidate_obj.stage_id.stage}.", + verb_de=f"Neuer Kandidat ist auf Stufe {candidate_obj.stage_id.stage} angekommen.", + verb_es=f"Nuevo candidato llegó a la etapa {candidate_obj.stage_id.stage}.", + verb_fr=f"Nouveau candidat arrivé à l'étape {candidate_obj.stage_id.stage}.", icon="person-add", redirect="/recruitment/pipeline", ) @@ -369,9 +389,12 @@ def recruitment_pipeline(request): notify.send( request.user.employee_get, recipient=users, - verb=f"""You are chosen as a stage manager on the stage - {stage_obj.stage} in recruitment {stage_obj.recruitment_id}", - icon="people-circle""", + verb=f"You are chosen as a stage manager on the stage {stage_obj.stage} in recruitment {stage_obj.recruitment_id}", + verb_ar=f"لقد تم اختيارك كمدير مرحلة في المرحلة {stage_obj.stage} في عملية التوظيف {stage_obj.recruitment_id}.", + verb_de=f"Sie wurden als Bühnenleiter für die Stufe {stage_obj.stage} in der Rekrutierung {stage_obj.recruitment_id} ausgewählt.", + verb_es=f"Has sido elegido como gerente de etapa en la etapa {stage_obj.stage} del reclutamiento {stage_obj.recruitment_id}.", + verb_fr=f"Vous avez été choisi en tant que responsable d'étape pour l'étape {stage_obj.stage} dans le recrutement {stage_obj.recruitment_id}.", + icon="people-circle" "", redirect="/recruitment/pipeline", ) return HttpResponseRedirect(request.META.get("HTTP_REFERER", "/")) @@ -439,6 +462,10 @@ def stage_update_pipeline(request, stage_id): recipient=users, verb=f"{stage_obj.stage} stage in recruitment {stage_obj.recruitment_id}\ is updated, You are chosen as one of managers", + verb_ar=f"تم تحديث المرحلة {stage_obj.stage} في التوظيف {stage_obj.recruitment_id}. تم اختيارك كواحد من المديرين.", + verb_de=f"Die Stufe {stage_obj.stage} im Recruitment {stage_obj.recruitment_id} wurde aktualisiert. Du wurdest als einer der Manager ausgewählt.", + verb_es=f"La etapa {stage_obj.stage} en el reclutamiento {stage_obj.recruitment_id} se ha actualizado. Has sido elegido como uno de los gerentes.", + verb_fr=f"L'étape {stage_obj.stage} dans le recrutement {stage_obj.recruitment_id} a été mise à jour. Vous avez été choisi comme l'un des responsables.", icon="people-circle", redirect="/recruitment/pipeline", ) @@ -469,6 +496,10 @@ def recruitment_update_pipeline(request, rec_id): request.user.employee_get, recipient=users, verb=f"{recruitment_obj} is updated, You are chosen as one of managers", + verb_ar=f"{recruitment_obj} تم تحديثه. تم اختيارك كواحد من المديرين.", + verb_de=f"{recruitment_obj} wurde aktualisiert. Du wurdest als einer der Manager ausgewählt.", + verb_es=f"{recruitment_obj} se ha actualizado. Has sido elegido como uno de los gerentes.", + verb_fr=f"{recruitment_obj} a été mis à jour. Vous avez été choisi comme l'un des responsables.", icon="people-circle", redirect="/recruitment/pipeline", ) @@ -548,6 +579,10 @@ def candidate_stage_update(request, cand_id): request.user.employee_get, recipient=users, verb=f"New candidate arrived on stage {stage_obj.stage}", + verb_ar=f"وصل مرشح جديد إلى المرحلة {stage_obj.stage}.", + verb_de=f"Neuer Kandidat ist auf Stufe {stage_obj.stage} angekommen.", + verb_es=f"Nuevo candidato llegó a la etapa {stage_obj.stage}.", + verb_fr=f"Nouveau candidat arrivé à l'étape {stage_obj.stage}.", icon="person-add", redirect="/recruitment/pipeline", ) @@ -716,6 +751,10 @@ def stage(request): recipient=users, verb=f"Stage {stage_obj} is updated on recruitment\ {stage_obj.recruitment_id}, You are chosen as one of managers", + verb_ar=f"تم تحديث المرحلة {stage_obj} في التوظيف {stage_obj.recruitment_id}. تم اختيارك كواحد من المديرين.", + verb_de=f"Stufe {stage_obj} im Recruitment {stage_obj.recruitment_id} wurde aktualisiert. Du wurdest als einer der Manager ausgewählt.", + verb_es=f"La etapa {stage_obj} en el reclutamiento {stage_obj.recruitment_id} se ha actualizado. Has sido elegido como uno de los gerentes.", + verb_fr=f"L'étape {stage_obj} dans le recrutement {stage_obj.recruitment_id} a été mise à jour. Vous avez été choisi comme l'un des responsables.", icon="people-circle", redirect="/recruitment/pipeline", ) @@ -778,6 +817,10 @@ def remove_stage_manager(request, mid, sid): request.user.employee_get, recipient=manager.employee_user_id, verb=f"You are removed from stage managers from stage {stage_obj}", + verb_ar=f"لقد تمت إزالتك من دور مدير المرحلة للمرحلة {stage_obj}.", + verb_de=f"Sie wurden aus der Rolle des Bühnenleiters für die Stufe {stage_obj} entfernt.", + verb_es=f"Has sido removido del rol de gerente de etapa para la etapa {stage_obj}.", + verb_fr=f"Vous avez été retiré du rôle de responsable d'étape pour l'étape {stage_obj}.", icon="person-remove", redirect="", ) @@ -883,9 +926,8 @@ def candidate(request): recruitment_id=candidate_obj.recruitment_id, stage_type="initial" ).first() # when creating new candidate from onboarding view - if request.GET.get("onboarding") =="True": - print("hitting here...") - candidate_obj.hired= True + if request.GET.get("onboarding") == "True": + candidate_obj.hired = True path = "/onboarding/candidates-view" candidate_obj.save() messages.success(request, _("Candidate added.")) @@ -1175,8 +1217,10 @@ def application_form(request): candidate_obj.stage_id = stages.order_by("sequence").first() candidate_obj.save() messages.success(request, _("Application saved.")) - return render(request,"candidate/success.html") - form.fields["job_position_id"].queryset = form.instance.recruitment_id.open_positions.all() + return render(request, "candidate/success.html") + form.fields[ + "job_position_id" + ].queryset = form.instance.recruitment_id.open_positions.all() return render(request, "candidate/application_form.html", {"form": form}) @@ -1296,4 +1340,4 @@ def get_open_position(request): queryset = recruitment_obj.open_positions.all() job_info = serializers.serialize("json", queryset) rec_info = serializers.serialize("json", [recruitment_obj]) - return JsonResponse({"openPositions": job_info,"recruitmentInfo":rec_info}) + return JsonResponse({"openPositions": job_info, "recruitmentInfo": rec_info}) diff --git a/static/images/ui/ar.png b/static/images/ui/ar.png new file mode 100644 index 000000000..aa4643253 Binary files /dev/null and b/static/images/ui/ar.png differ diff --git a/static/images/ui/de.png b/static/images/ui/de.png new file mode 100644 index 000000000..557087fdf Binary files /dev/null and b/static/images/ui/de.png differ diff --git a/static/images/ui/en.png b/static/images/ui/en.png new file mode 100644 index 000000000..47cb0c934 Binary files /dev/null and b/static/images/ui/en.png differ diff --git a/static/images/ui/es.png b/static/images/ui/es.png new file mode 100644 index 000000000..f29ff1577 Binary files /dev/null and b/static/images/ui/es.png differ diff --git a/static/images/ui/fr.png b/static/images/ui/fr.png new file mode 100644 index 000000000..f008d6a9e Binary files /dev/null and b/static/images/ui/fr.png differ diff --git a/static/images/ui/us.png b/static/images/ui/us.png new file mode 100644 index 000000000..47cb0c934 Binary files /dev/null and b/static/images/ui/us.png differ diff --git a/templates/dashboard.html b/templates/dashboard.html index 3db5d32cb..5c9adf16c 100755 --- a/templates/dashboard.html +++ b/templates/dashboard.html @@ -1,6 +1,7 @@ {% load static %} {% load basefilters %} {% load recruitmentfilters %} +{% load i18n %}