680 lines
24 KiB
Python
680 lines
24 KiB
Python
"""
|
|
This page is handling the cbv methods of shift request page.
|
|
"""
|
|
|
|
import contextlib
|
|
from typing import Any
|
|
|
|
from django import forms
|
|
from django.contrib import messages
|
|
from django.db.models import Q
|
|
from django.http import HttpResponse
|
|
from django.shortcuts import render
|
|
from django.urls import reverse, reverse_lazy
|
|
from django.utils.decorators import method_decorator
|
|
from django.utils.translation import gettext_lazy as _
|
|
|
|
from base.filters import ShiftRequestFilter
|
|
from base.forms import (
|
|
EmployeeShiftForm,
|
|
ShiftAllocationForm,
|
|
ShiftRequestColumnForm,
|
|
ShiftRequestForm,
|
|
)
|
|
from base.methods import choosesubordinates, filtersubordinates, is_reportingmanager
|
|
from base.models import EmployeeShift, ShiftRequest
|
|
from base.views import include_employee_instance
|
|
from employee.models import Employee
|
|
from horilla_views.cbv_methods import login_required, permission_required
|
|
from horilla_views.generic.cbv.views import (
|
|
HorillaDetailedView,
|
|
HorillaFormView,
|
|
HorillaListView,
|
|
HorillaNavView,
|
|
HorillaTabView,
|
|
TemplateView,
|
|
)
|
|
from notifications.signals import notify
|
|
|
|
|
|
@method_decorator(login_required, name="dispatch")
|
|
class ShiftRequestView(TemplateView):
|
|
"""
|
|
Shift request page
|
|
"""
|
|
|
|
template_name = "cbv/shift_request/shift_request.html"
|
|
|
|
|
|
@method_decorator(login_required, name="dispatch")
|
|
class ShiftList(HorillaListView):
|
|
"""
|
|
List view
|
|
"""
|
|
|
|
model = ShiftRequest
|
|
filter_class = ShiftRequestFilter
|
|
|
|
row_status_class = (
|
|
"approved-{approved} canceled-{canceled} requested-{approved}-{canceled}"
|
|
)
|
|
records_per_page = 5
|
|
|
|
row_status_indications = [
|
|
(
|
|
"canceled--dot",
|
|
_("Canceled"),
|
|
"""
|
|
onclick="
|
|
$('#applyFilter').closest('form').find('[name=canceled]').val('true');
|
|
$('[name=approved]').val('unknown').change();
|
|
$('[name=requested]').val('unknown').change();
|
|
$('#applyFilter').click();
|
|
"
|
|
""",
|
|
),
|
|
(
|
|
"approved--dot",
|
|
_("Approved"),
|
|
"""
|
|
onclick="
|
|
$('#applyFilter').closest('form').find('[name=approved]').val('true');
|
|
$('[name=canceled]').val('unknown').change();
|
|
$('[name=requested]').val('unknown').change();
|
|
$('#applyFilter').click();
|
|
"
|
|
""",
|
|
),
|
|
(
|
|
"requested--dot",
|
|
_("Requested"),
|
|
"""
|
|
onclick="
|
|
$('#applyFilter').closest('form').find('[name=requested]').val('true');
|
|
$('[name=approved]').val('unknown').change();
|
|
$('[name=canceled]').val('unknown').change();
|
|
$('#applyFilter').click();
|
|
"
|
|
""",
|
|
),
|
|
]
|
|
|
|
|
|
@method_decorator(login_required, name="dispatch")
|
|
class ShiftRequestList(ShiftList):
|
|
"""
|
|
List view for shift requests
|
|
"""
|
|
|
|
selected_instances_key_id = "shiftselectedInstances"
|
|
template_name = "cbv/shift_request/extended_shift.html"
|
|
|
|
def __init__(self, **kwargs: Any) -> None:
|
|
super().__init__(**kwargs)
|
|
self.search_url = reverse("list-shift-request")
|
|
self.view_id = "shift-container"
|
|
# self.filter_keys_to_remove = ["deleted"]
|
|
if self.request.user.has_perm(
|
|
"base.change_shiftrequest"
|
|
) or is_reportingmanager(self.request):
|
|
self.action_method = "confirmations"
|
|
else:
|
|
self.action_method = None
|
|
|
|
def get_queryset(self):
|
|
queryset = super().get_queryset()
|
|
data = queryset
|
|
|
|
employee = self.request.user.employee_get
|
|
queryset = filtersubordinates(
|
|
self.request,
|
|
queryset.filter(reallocate_to__isnull=True),
|
|
"base.view_shiftrequest",
|
|
)
|
|
queryset = queryset | data.filter(employee_id=employee)
|
|
queryset = queryset.filter(employee_id__is_active=True)
|
|
|
|
return queryset
|
|
|
|
columns = [
|
|
(_("Employee"), "employee_id", "employee_id__get_avatar"),
|
|
(_("Requested Shift"), "shift_id"),
|
|
(_("Previous/Current Shift"), "previous_shift_id"),
|
|
(_("Requested Date"), "requested_date"),
|
|
(_("Requested Till"), "requested_till"),
|
|
(_("Description"), "description"),
|
|
(_("Comment"), "comment"),
|
|
]
|
|
|
|
header_attrs = {
|
|
"option": """ style="width:190px !important;" """,
|
|
"description": """ style="width:300px !important;" """,
|
|
}
|
|
|
|
option_method = "shift_actions"
|
|
|
|
sortby_mapping = [
|
|
("Employee", "employee_id__get_full_name"),
|
|
("Requested Shift", "shift_id__employee_shift"),
|
|
("Previous/Current Shift", "previous_shift_id__employee_shift"),
|
|
("Requested Date", "requested_date"),
|
|
("Requested Till", "requested_till"),
|
|
]
|
|
|
|
row_attrs = """
|
|
hx-get='{shift_details}?instance_ids={ordered_ids}'
|
|
hx-target="#genericModalBody"
|
|
data-target="#genericModal"
|
|
data-toggle="oh-modal-toggle"
|
|
"""
|
|
|
|
|
|
@method_decorator(login_required, name="dispatch")
|
|
class AllocatedShift(ShiftList):
|
|
"""
|
|
Allocated tab class
|
|
"""
|
|
|
|
selected_instances_key_id = "allocatedselectedInstances"
|
|
|
|
def __init__(self, **kwargs: Any) -> None:
|
|
super().__init__(**kwargs)
|
|
self.search_url = reverse("allocated-shift-view")
|
|
|
|
columns = [
|
|
(_("Employee"), "employee_id", "employee_id__get_avatar"),
|
|
(_("Allocated Employee"), "reallocate_to"),
|
|
(_("User Availability"), "user_availability"),
|
|
(_("Requested Shift"), "shift_id"),
|
|
(_("Previous/Current Shift"), "previous_shift_id"),
|
|
(_("Requested Date"), "requested_date"),
|
|
(_("Requested Till"), "requested_till"),
|
|
(_("Description"), "description"),
|
|
(_("Comment"), "comment"),
|
|
]
|
|
|
|
action_method = "allocated_confirm_action_col"
|
|
option_method = "allocate_confirmations"
|
|
|
|
def get_queryset(self):
|
|
queryset = super().get_queryset()
|
|
b = queryset
|
|
employee = self.request.user.employee_get
|
|
queryset = filtersubordinates(
|
|
self.request,
|
|
queryset.filter(reallocate_to__isnull=False),
|
|
"base.view_shiftrequest",
|
|
)
|
|
allocated_requests = b.filter(reallocate_to__isnull=False)
|
|
if not self.request.user.has_perm("base.view_shiftrequest"):
|
|
allocated_requests = allocated_requests.filter(
|
|
Q(reallocate_to=employee) | Q(employee_id=employee)
|
|
)
|
|
queryset = queryset | allocated_requests
|
|
|
|
return queryset
|
|
|
|
row_attrs = """
|
|
hx-get='{allocate_shift_details}?instance_ids={ordered_ids}'
|
|
hx-target="#genericModalBody"
|
|
data-target="#genericModal"
|
|
data-toggle="oh-modal-toggle"
|
|
"""
|
|
sortby_mapping = [
|
|
("Employee", "employee_id__get_full_name"),
|
|
("Allocated Employee", "reallocate_to__get_full_name"),
|
|
("Requested Shift", "shift_id__employee_shift"),
|
|
("Previous/Current Shift", "previous_shift_id__employee_shift"),
|
|
("Requested Date", "requested_date"),
|
|
("Requested Till", "requested_till"),
|
|
]
|
|
|
|
|
|
@method_decorator(login_required, name="dispatch")
|
|
class ShitRequestNav(HorillaNavView):
|
|
"""
|
|
Nav bar
|
|
"""
|
|
|
|
def __init__(self, **kwargs: Any) -> None:
|
|
super().__init__(**kwargs)
|
|
self.search_url = reverse("shift-request-tab")
|
|
self.create_attrs = f"""
|
|
hx-get="{reverse_lazy('shift-request')}"
|
|
data-toggle="oh-modal-toggle"
|
|
data-target="#genericModal"
|
|
hx-target="#genericModalBody"
|
|
|
|
"""
|
|
self.actions = []
|
|
if self.request.user.has_perm(
|
|
"base.change_shiftrequest"
|
|
) or is_reportingmanager(self.request):
|
|
self.actions.append(
|
|
{
|
|
"action": _("Approve Requests"),
|
|
"attrs": """
|
|
onclick="
|
|
shiftRequestApprove();
|
|
"
|
|
style="cursor: pointer;"
|
|
""",
|
|
}
|
|
)
|
|
self.actions.append(
|
|
{
|
|
"action": _("Reject Requests"),
|
|
"attrs": """
|
|
onclick="
|
|
shiftRequestReject();
|
|
"
|
|
style="cursor: pointer;"
|
|
""",
|
|
}
|
|
)
|
|
if self.request.user.has_perm(
|
|
"base.delete_shiftrequest"
|
|
) or is_reportingmanager(self.request):
|
|
self.actions.append(
|
|
{
|
|
"action": _("Delete"),
|
|
"attrs": """
|
|
onclick="
|
|
shiftRequestDelete();
|
|
"
|
|
data-action ="delete"
|
|
style="cursor: pointer; color:red !important"
|
|
""",
|
|
}
|
|
)
|
|
|
|
if self.request.user.has_perm("base.view_shiftrequest") or is_reportingmanager(
|
|
self.request
|
|
):
|
|
self.actions.insert(
|
|
0,
|
|
{
|
|
"action": _("Export"),
|
|
"attrs": f"""
|
|
data-toggle="oh-modal-toggle"
|
|
data-target="#genericModal"
|
|
hx-get="{reverse('shift-export')}"
|
|
hx-target="#genericModalBody"
|
|
style="cursor: pointer;"
|
|
""",
|
|
},
|
|
)
|
|
|
|
nav_title = _("Shift Requests")
|
|
filter_body_template = "cbv/shift_request/filter.html"
|
|
filter_instance = ShiftRequestFilter()
|
|
filter_form_context_name = "form"
|
|
search_swap_target = "#listContainer"
|
|
|
|
group_by_fields = [
|
|
("employee_id", _("Employee")),
|
|
("shift_id", _("Requested Shift")),
|
|
("previous_shift_id", _("Current Shift")),
|
|
("requested_date", _("Requested Date")),
|
|
]
|
|
|
|
|
|
@method_decorator(login_required, name="dispatch")
|
|
class ShiftRequestTab(HorillaTabView):
|
|
"""
|
|
Tab View
|
|
"""
|
|
|
|
def __init__(self, **kwargs: Any) -> None:
|
|
super().__init__(**kwargs)
|
|
self.view_id = "shift-tab"
|
|
self.tabs = [
|
|
{
|
|
"title": _("Shift Requests"),
|
|
"url": f"{reverse('list-shift-request')}",
|
|
},
|
|
{
|
|
"title": _("Allocated Shift Requests"),
|
|
"url": f"{reverse('allocated-shift-view')}",
|
|
},
|
|
]
|
|
|
|
|
|
@method_decorator(login_required, name="dispatch")
|
|
class ExportView(TemplateView):
|
|
"""
|
|
For candidate export
|
|
"""
|
|
|
|
template_name = "cbv/shift_request/export_shift.html"
|
|
|
|
def get_context_data(self, **kwargs: Any):
|
|
context = super().get_context_data(**kwargs)
|
|
shift_requests = ShiftRequest.objects.all()
|
|
export_fields = ShiftRequestColumnForm
|
|
export_filter = ShiftRequestFilter(queryset=shift_requests)
|
|
context["export_fields"] = export_fields
|
|
context["export_filter"] = export_filter
|
|
return context
|
|
|
|
|
|
@method_decorator(login_required, name="dispatch")
|
|
class ShiftRequestDetailview(HorillaDetailedView):
|
|
"""
|
|
Detail View
|
|
"""
|
|
|
|
model = ShiftRequest
|
|
|
|
title = _("Details")
|
|
|
|
header = {
|
|
"title": "employee_id__get_full_name",
|
|
"subtitle": "details_subtitle",
|
|
"avatar": "employee_id__get_avatar",
|
|
}
|
|
|
|
body = [
|
|
(_("Requested Shift"), "shift_id"),
|
|
(_("Previous Shift"), "previous_shift_id"),
|
|
(_("Requested Date"), "requested_date"),
|
|
(_("Requested Till"), "requested_till"),
|
|
(_("Is permenent shift"), "is_permanent"),
|
|
(_("Description"), "description"),
|
|
]
|
|
|
|
cols = {
|
|
"description": 12,
|
|
}
|
|
|
|
def __init__(self, **kwargs: Any) -> None:
|
|
super().__init__(**kwargs)
|
|
self.action_method = "confirmations"
|
|
|
|
def get_context_data(self, **kwargs):
|
|
context = super().get_context_data(**kwargs)
|
|
if (
|
|
self.request.user.employee_get == self.instance.employee_id
|
|
and not self.request.GET.get("dashboard")
|
|
):
|
|
context["action_method"] = "detail_actions"
|
|
|
|
return context
|
|
|
|
|
|
@method_decorator(login_required, name="dispatch")
|
|
class AllocatedShiftDetailView(ShiftRequestDetailview):
|
|
"""
|
|
Allocated detail View
|
|
"""
|
|
|
|
body = [
|
|
(_("Allocated Employee"), "reallocate_to"),
|
|
(_("User Availability"), "user_availability"),
|
|
(_("Requested Shift"), "shift_id"),
|
|
(_("Previous Shift"), "previous_shift_id"),
|
|
(_("Requested Date"), "requested_date"),
|
|
(_("Requested Till"), "requested_till"),
|
|
(_("Description"), "description"),
|
|
]
|
|
|
|
|
|
class ShiftTypeFormView(HorillaFormView):
|
|
"""
|
|
form view
|
|
"""
|
|
|
|
model = EmployeeShift
|
|
form_class = EmployeeShiftForm
|
|
new_display_title = "Create Shift"
|
|
is_dynamic_create_view = True
|
|
|
|
def form_valid(self, form: EmployeeShiftForm) -> HttpResponse:
|
|
if form.is_valid():
|
|
form.save()
|
|
message = _("Shift Created")
|
|
messages.success(self.request, message)
|
|
return self.HttpResponse("<script>window.location.reload():</script>")
|
|
return super().form_valid(form)
|
|
|
|
|
|
@method_decorator(login_required, name="dispatch")
|
|
@method_decorator(permission_required(perm="base.add_employeeshift"), name="dispatch")
|
|
class ShiftTypeCreateFormView(ShiftTypeFormView):
|
|
|
|
is_dynamic_create_view = False
|
|
|
|
def get_context_data(self, **kwargs):
|
|
context = super().get_context_data(**kwargs)
|
|
# form = self.form_class()
|
|
if self.form.instance.pk:
|
|
self.form_class(instance=self.form.instance)
|
|
self.form_class.verbose_name = _("Update Shift")
|
|
context["form"] = self.form
|
|
return context
|
|
|
|
def form_valid(self, form: EmployeeShiftForm) -> HttpResponse:
|
|
if form.is_valid():
|
|
if self.form.instance.pk:
|
|
message = _("Shift Updated")
|
|
else:
|
|
message = _("Shift Created")
|
|
form.save()
|
|
messages.success(self.request, message)
|
|
return self.HttpResponse()
|
|
|
|
|
|
@method_decorator(login_required, name="dispatch")
|
|
class ShiftRequestFormView(HorillaFormView):
|
|
"""
|
|
Form View
|
|
"""
|
|
|
|
model = ShiftRequest
|
|
form_class = ShiftRequestForm
|
|
new_display_title = _("Create Shift Request")
|
|
template_name = "cbv/shift_request/shift_request_form.html"
|
|
dynamic_create_fields = [("shift_id", ShiftTypeFormView)]
|
|
|
|
def get_context_data(self, **kwargs):
|
|
context = super().get_context_data(**kwargs)
|
|
employee = self.request.user.employee_get.id
|
|
if self.form.instance.pk:
|
|
self.form_class(instance=self.form.instance)
|
|
self.form = choosesubordinates(
|
|
self.request,
|
|
self.form,
|
|
"base.add_shiftrequest",
|
|
)
|
|
self.form = include_employee_instance(self.request, self.form)
|
|
if self.form.instance.pk:
|
|
self.form_class.verbose_name = _("Update Request")
|
|
if self.request.GET.get("emp_id"):
|
|
employee = self.request.GET.get("emp_id")
|
|
self.form.fields["employee_id"].queryset = Employee.objects.filter(
|
|
id=employee
|
|
)
|
|
self.form.fields["employee_id"].initial = employee
|
|
context["form"] = self.form
|
|
return context
|
|
|
|
def form_invalid(self, form: Any) -> HttpResponse:
|
|
if self.form.instance.pk:
|
|
self.form_class.verbose_name = _("Update Request")
|
|
if not form.is_valid():
|
|
errors = form.errors.as_data()
|
|
return render(
|
|
self.request, self.template_name, {"form": form, "errors": errors}
|
|
)
|
|
return super().form_invalid(form)
|
|
|
|
def form_valid(self, form: ShiftRequestForm) -> HttpResponse:
|
|
if form.is_valid():
|
|
if form.instance.pk:
|
|
message = _("Shift request updated Successfully")
|
|
form.save()
|
|
else:
|
|
instance = form.save()
|
|
message = _("Shift request added Successfully")
|
|
with contextlib.suppress(Exception):
|
|
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=reverse("shift-request-view") + f"?id={instance.id}",
|
|
)
|
|
messages.success(self.request, message)
|
|
return self.HttpResponse()
|
|
return super().form_valid(form)
|
|
|
|
|
|
@method_decorator(login_required, name="dispatch")
|
|
class ShiftRequestFormDuplicate(HorillaFormView):
|
|
"""
|
|
Duplicate form view
|
|
"""
|
|
|
|
model = ShiftRequest
|
|
form_class = ShiftRequestForm
|
|
template_name = "cbv/shift_request/shift_request_form.html"
|
|
|
|
def get_context_data(self, **kwargs):
|
|
context = super().get_context_data(**kwargs)
|
|
original_object = ShiftRequest.objects.get(id=self.kwargs["pk"])
|
|
self.form = self.form_class(instance=original_object)
|
|
for field_name, field in self.form.fields.items():
|
|
if isinstance(field, forms.CharField):
|
|
if field.initial:
|
|
initial_value = field.initial
|
|
else:
|
|
initial_value = f"{self.form.initial.get(field_name, '')} (copy)"
|
|
self.form.initial[field_name] = initial_value
|
|
self.form.fields[field_name].initial = initial_value
|
|
self.form = choosesubordinates(
|
|
self.request,
|
|
self.form,
|
|
"base.add_shiftrequest",
|
|
)
|
|
self.form = include_employee_instance(self.request, self.form)
|
|
if self.request.GET.get("emp_id"):
|
|
employee = self.request.GET.get("emp_id")
|
|
self.form.fields["employee_id"].queryset = Employee.objects.filter(
|
|
id=employee
|
|
)
|
|
context["form"] = self.form
|
|
self.form_class.verbose_name = _("Duplicate")
|
|
return context
|
|
|
|
def form_invalid(self, form: Any) -> HttpResponse:
|
|
# form = self.form_class(self.request.POST)
|
|
self.form_class.verbose_name = _("Duplicate")
|
|
if not form.is_valid():
|
|
errors = form.errors.as_data()
|
|
return render(
|
|
self.request, self.template_name, {"form": form, "errors": errors}
|
|
)
|
|
return super().form_invalid(form)
|
|
|
|
def form_valid(self, form: ShiftRequestForm) -> HttpResponse:
|
|
form = self.form_class(self.request.POST)
|
|
if form.is_valid():
|
|
form.save()
|
|
message = _("Shift request added Successfully")
|
|
messages.success(self.request, message)
|
|
return self.HttpResponse("<script>window.location.reload();</script>")
|
|
return super().form_valid(form)
|
|
|
|
|
|
@method_decorator(login_required, name="dispatch")
|
|
class ShiftAllocationFormView(HorillaFormView):
|
|
"""
|
|
Form View
|
|
"""
|
|
|
|
model = ShiftRequest
|
|
form_class = ShiftAllocationForm
|
|
new_display_title = _("Shift Request")
|
|
|
|
def get_context_data(self, **kwargs):
|
|
context = super().get_context_data(**kwargs)
|
|
if self.form.instance.pk:
|
|
self.form_class(instance=self.form.instance)
|
|
self.form = choosesubordinates(
|
|
self.request,
|
|
self.form,
|
|
"base.add_shiftrequest",
|
|
)
|
|
self.form = include_employee_instance(self.request, self.form)
|
|
if self.form.instance.pk:
|
|
self.form_class.verbose_name = _("Update Request")
|
|
if self.request.GET.get("emp_id"):
|
|
employee = self.request.GET.get("emp_id")
|
|
self.form.fields["employee_id"].initial = employee
|
|
self.form.fields["employee_id"].queryset = Employee.objects.filter(
|
|
id=employee
|
|
)
|
|
context["form"] = self.form
|
|
return context
|
|
|
|
def form_invalid(self, form: Any) -> HttpResponse:
|
|
|
|
# form = self.form_class(self.request.POST)
|
|
if self.form.instance.pk:
|
|
self.form_class.verbose_name = _("Update Request")
|
|
if not form.is_valid():
|
|
errors = form.errors.as_data()
|
|
return render(
|
|
self.request, self.template_name, {"form": form, "errors": errors}
|
|
)
|
|
return super().form_invalid(form)
|
|
|
|
def form_valid(self, form: ShiftRequestForm) -> HttpResponse:
|
|
if form.is_valid():
|
|
if form.instance.pk:
|
|
message = _("Shift request updated Successfully")
|
|
form.save()
|
|
else:
|
|
instance = form.save()
|
|
message = _("Shift request added Successfully")
|
|
reallocate_emp = form.cleaned_data["reallocate_to"]
|
|
with contextlib.suppress(Exception):
|
|
notify.send(
|
|
form.instance.employee_id,
|
|
recipient=(
|
|
form.instance.employee_id.employee_work_info.reporting_manager_id.employee_user_id
|
|
),
|
|
verb=f"You have a new shift reallocation request to approve for {instance.employee_id}.",
|
|
verb_ar=f"لديك طلب تخصيص جديد للورديات يتعين عليك الموافقة عليه لـ {instance.employee_id}.",
|
|
verb_de=f"Sie haben eine neue Anfrage zur Verschiebung der Schichtzuteilung zur Genehmigung für {instance.employee_id}.",
|
|
verb_es=f"Tienes una nueva solicitud de reasignación de turnos para aprobar para {instance.employee_id}.",
|
|
verb_fr=f"Vous avez une nouvelle demande de réaffectation de shift à approuver pour {instance.employee_id}.",
|
|
icon="information",
|
|
redirect=reverse("shift-request-view") + f"?id={instance.id}",
|
|
)
|
|
|
|
notify.send(
|
|
instance.employee_id,
|
|
recipient=(reallocate_emp.employee_user_id),
|
|
verb=f"You have a new shift reallocation request from {instance.employee_id}.",
|
|
verb_ar=f"لديك طلب تخصيص جديد للورديات من {instance.employee_id}.",
|
|
verb_de=f"Sie haben eine neue Anfrage zur Verschiebung der Schichtzuteilung von {instance.employee_id}.",
|
|
verb_es=f"Tienes una nueva solicitud de reasignación de turnos de {instance.employee_id}.",
|
|
verb_fr=f"Vous avez une nouvelle demande de réaffectation de shift de {instance.employee_id}.",
|
|
icon="information",
|
|
redirect=reverse("shift-request-view") + f"?id={instance.id}",
|
|
)
|
|
messages.success(self.request, message)
|
|
return self.HttpResponse("<script>window.location.reload();</script>")
|
|
return super().form_valid(form)
|