diff --git a/offboarding/admin.py b/offboarding/admin.py
index ff57014eb..8a10c2734 100644
--- a/offboarding/admin.py
+++ b/offboarding/admin.py
@@ -4,10 +4,17 @@ from offboarding.models import (
OffboardingNote,
OffboardingTask,
EmployeeTask,
+ ResignationLetter,
)
# Register your models here.
admin.site.register(
- [OffboardingStageMultipleFile, OffboardingNote, OffboardingTask, EmployeeTask]
+ [
+ OffboardingStageMultipleFile,
+ ResignationLetter,
+ OffboardingNote,
+ OffboardingTask,
+ EmployeeTask,
+ ]
)
diff --git a/offboarding/filters.py b/offboarding/filters.py
new file mode 100644
index 000000000..90e370ac4
--- /dev/null
+++ b/offboarding/filters.py
@@ -0,0 +1,32 @@
+"""
+offboarding/filters.py
+
+This module is used to register django_filters
+"""
+import django_filters
+from django import forms
+from base.filters import FilterSet
+from offboarding.models import ResignationLetter
+
+
+class LetterFilter(FilterSet):
+ """
+ LetterFilter class
+ """
+
+ search = django_filters.CharFilter(field_name="title", lookup_expr="icontains")
+ planned_to_leave_on = django_filters.DateFilter(
+ field_name="planned_to_leave_on",
+ widget=forms.DateInput(attrs={"type": "date"}),
+ )
+
+ class Meta:
+ model = ResignationLetter
+ fields = [
+ "status",
+ "employee_id",
+ "planned_to_leave_on",
+ "employee_id__employee_work_info__department_id",
+ "employee_id__employee_work_info__job_position_id",
+ "employee_id__employee_work_info__reporting_manager_id",
+ ]
diff --git a/offboarding/forms.py b/offboarding/forms.py
index 0e662fd6b..a129eb48f 100644
--- a/offboarding/forms.py
+++ b/offboarding/forms.py
@@ -4,11 +4,14 @@ offboarding/forms.py
This module is used to register forms for offboarding app
"""
+import contextlib
from typing import Any
from django import forms
from django.template.loader import render_to_string
from base.forms import ModelForm
+from base import thread_local_middleware
from employee.forms import MultipleFileField
+from notifications.signals import notify
from offboarding.models import (
EmployeeTask,
Offboarding,
@@ -17,6 +20,7 @@ from offboarding.models import (
OffboardingStage,
OffboardingStageMultipleFile,
OffboardingTask,
+ ResignationLetter,
)
@@ -89,8 +93,15 @@ class OffboardingEmployeeForm(ModelForm):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
if self.instance.pk:
- self.initial["notice_period_starts"] = self.instance.notice_period_starts.strftime("%Y-%m-%d")
- self.initial["notice_period_ends"] = self.instance.notice_period_ends.strftime("%Y-%m-%d")
+ if self.instance.notice_period_starts:
+ self.initial[
+ "notice_period_starts"
+ ] = self.instance.notice_period_starts.strftime("%Y-%m-%d")
+ if self.instance.notice_period_ends:
+ self.initial[
+ "notice_period_ends"
+ ] = self.instance.notice_period_ends.strftime("%Y-%m-%d")
+
class StageSelectForm(ModelForm):
"""
@@ -180,7 +191,13 @@ class TaskForm(ModelForm):
super().__init__(*args, **kwargs)
self.fields["stage_id"].empty_label = "All Stages in Offboarding"
self.fields["managers"].empty_label = None
- queryset = OffboardingEmployee.objects.filter(stage_id__offboarding_id=OffboardingStage.objects.filter(id=self.initial.get("stage_id")).first().offboarding_id)
+ queryset = OffboardingEmployee.objects.filter(
+ stage_id__offboarding_id=OffboardingStage.objects.filter(
+ id=self.initial.get("stage_id")
+ )
+ .first()
+ .offboarding_id
+ )
self.fields["tasks_to"].queryset = queryset
def as_p(self):
@@ -200,3 +217,69 @@ class TaskForm(ModelForm):
employee_id=employee,
task_id=self.instance,
)
+
+
+class ResignationLetterForm(ModelForm):
+ """
+ Resignation Letter
+ """
+
+ description = forms.CharField(
+ widget=forms.Textarea(attrs={"data-summernote": "", "style": "display:none;"}),
+ label="Description",
+ )
+ verbose_name = "Resignation Letter"
+
+ class Meta:
+ model = ResignationLetter
+ fields = "__all__"
+
+ def as_p(self):
+ """
+ Render the form fields as HTML table rows with Bootstrap styling.
+ """
+ context = {"form": self}
+ table_html = render_to_string("common_form.html", context)
+ return table_html
+
+ def __init__(self, *args, **kwargs):
+ super().__init__(*args, **kwargs)
+ self.fields["planned_to_leave_on"].widget = forms.DateInput(
+ attrs={"type": "date", "class": "oh-input w-100"}
+ )
+ exclude = []
+ if self.instance.pk:
+ exclude.append("employee_id")
+ self.verbose_name = (
+ self.instance.employee_id.get_full_name() + " Resignation Letter"
+ )
+
+ request = getattr(thread_local_middleware._thread_locals, "request", None)
+
+ if request and not request.user.has_perm("offboarding.add_offboardingemployee"):
+ exclude = exclude + [
+ "employee_id",
+ "status",
+ "is_active",
+ ]
+ self.instance.employee_id = request.user.employee_get
+ for field in exclude:
+ del self.fields[field]
+
+ def save(self, commit: bool = ...) -> Any:
+ instance = super().save(commit)
+ request = getattr(thread_local_middleware._thread_locals, "request", None)
+ if request and not request.user.has_perm("offboarding.add_offboardingemployee"):
+ with contextlib.suppress(Exception):
+ notify.send(
+ request.user.employee_get,
+ recipient=self.instance.employee_id.get_reporting_manager().employee_user_id,
+ verb=f"{self.instance.employee_id.get_full_name()} requested for resignation.",
+ verb_ar=f"",
+ verb_de=f"",
+ verb_es=f"",
+ verb_fr=f"",
+ redirect="#",
+ icon="information",
+ )
+ return instance
diff --git a/offboarding/models.py b/offboarding/models.py
index ccd9245a3..04ca6933f 100644
--- a/offboarding/models.py
+++ b/offboarding/models.py
@@ -1,9 +1,9 @@
-from collections.abc import Iterable
-from typing import Any
+from datetime import date
from django.db import models
from django.db.models.signals import post_save
from django.dispatch import receiver
from base import thread_local_middleware
+from base.models import Company
from employee.models import Employee
from horilla_audit.models import HorillaAuditInfo, HorillaAuditLog
from notifications.signals import notify
@@ -25,7 +25,10 @@ class Offboarding(models.Model):
created_at = models.DateTimeField(auto_now_add=True)
status = models.CharField(max_length=10, default="ongoing", choices=statuses)
is_active = models.BooleanField(default=True)
-
+ company_id = models.ForeignKey(
+ Company, on_delete=models.CASCADE, null=True, editable=False
+ )
+
def __str__(self):
return self.title
@@ -91,18 +94,91 @@ class OffboardingEmployee(models.Model):
Employee, on_delete=models.CASCADE, verbose_name="Employee"
)
stage_id = models.ForeignKey(
- OffboardingStage, on_delete=models.PROTECT, verbose_name="Stage"
+ OffboardingStage, on_delete=models.PROTECT, verbose_name="Stage", null=True
)
- notice_period = models.IntegerField()
- unit = models.CharField(max_length=10, choices=units)
- notice_period_starts = models.DateField()
- notice_period_ends = models.DateField()
+ notice_period = models.IntegerField(null=True)
+ unit = models.CharField(max_length=10, choices=units, null=True)
+ notice_period_starts = models.DateField(null=True)
+ notice_period_ends = models.DateField(null=True)
created_at = models.DateTimeField(auto_now_add=True)
def __str__(self) -> str:
return self.employee_id.get_full_name()
+class ResignationLetter(models.Model):
+ """
+ Resignation Request Employee model
+ """
+
+ statuses = [
+ ("requested", "Requested"),
+ ("approved", "Approved"),
+ ("rejected", "Rejected"),
+ ]
+ employee_id = models.ForeignKey(
+ Employee, on_delete=models.CASCADE, verbose_name="Employee"
+ )
+ title = models.CharField(max_length=30, null=True)
+ description = models.TextField(
+ null=True,
+ )
+ planned_to_leave_on = models.DateField()
+ status = models.CharField(max_length=10, choices=statuses, default="requested")
+ offboarding_employee_id = models.ForeignKey(
+ OffboardingEmployee, on_delete=models.CASCADE, editable=False, null=True
+ )
+ created_at = models.DateTimeField(auto_now_add=True)
+ is_active = models.BooleanField(default=True)
+
+ def save(self, *args, **kwargs):
+ super().save(*args, **kwargs)
+ if self.status == "approved":
+ pass
+
+ return
+
+ def to_offboarding_employee(
+ self, offboarding, notice_period_starts, notice_period_ends
+ ):
+ """
+ This method is used to convert/add employee to offboarding
+ """
+ offboarding_employee = OffboardingEmployee.objects.filter(
+ employee_id=self.employee_id
+ ).first()
+ offboarding_employee = (
+ offboarding_employee if offboarding_employee else OffboardingEmployee()
+ )
+ offboarding_employee.employee_id = self.employee_id
+ offboarding_employee.stage_id = (
+ OffboardingStage.objects.order_by("created_at")
+ .filter(offboarding_id=offboarding)
+ .first()
+ )
+ offboarding_employee.notice_period_starts = notice_period_starts
+ offboarding_employee.notice_period_ends = notice_period_ends
+ if (
+ notice_period_starts
+ and notice_period_ends
+ and not isinstance(notice_period_starts, str)
+ and not isinstance(notice_period_ends, str)
+ ):
+ diffs = date(
+ day=notice_period_ends.day,
+ month=notice_period_ends.month,
+ year=notice_period_ends.year,
+ ) - date(
+ day=notice_period_starts.day,
+ month=notice_period_starts.month,
+ year=notice_period_starts.year,
+ )
+ diffs = diffs.days
+ offboarding_employee.notice_period = diffs if diffs > 0 else None
+ offboarding_employee.unit = "day" if diffs > 0 else None
+ offboarding_employee.save()
+
+
class OffboardingTask(models.Model):
"""
OffboardingTask model
@@ -146,6 +222,7 @@ class EmployeeTask(models.Model):
)
status = models.CharField(max_length=10, choices=statuses, default="todo")
task_id = models.ForeignKey(OffboardingTask, on_delete=models.CASCADE)
+ description = models.TextField(null=True, editable=False)
history = HorillaAuditLog(
related_name="history_set",
bases=[
@@ -156,7 +233,7 @@ class EmployeeTask(models.Model):
class Meta:
unique_together = ["employee_id", "task_id"]
-
+
def save(self, *args, **kwargs):
super().save(*args, **kwargs)
request = getattr(_thread_locals, "request", None)
@@ -218,3 +295,10 @@ class OffboardingNote(models.Model):
if self.employee_id:
self.stage_id = self.employee_id.stage_id
return super().save(*args, **kwargs)
+
+
+class OffboardingGeneralSetting(models.Model):
+ """
+ OffboardingGeneralSettings
+ """
+ resignation_request = models.BooleanField(default=True)
\ No newline at end of file
diff --git a/offboarding/templates/offboarding/resignation/filter.html b/offboarding/templates/offboarding/resignation/filter.html
new file mode 100644
index 000000000..2fc15f0ea
--- /dev/null
+++ b/offboarding/templates/offboarding/resignation/filter.html
@@ -0,0 +1,55 @@
+{% load i18n %}
+
+
+
+ {% trans "Filter" %}
+
+
+
+
+
\ No newline at end of file
diff --git a/offboarding/templates/offboarding/resignation/form.html b/offboarding/templates/offboarding/resignation/form.html
new file mode 100644
index 000000000..d05124f46
--- /dev/null
+++ b/offboarding/templates/offboarding/resignation/form.html
@@ -0,0 +1,7 @@
+
+
\ No newline at end of file
diff --git a/offboarding/templates/offboarding/resignation/nav.html b/offboarding/templates/offboarding/resignation/nav.html
new file mode 100644
index 000000000..c3602bdb3
--- /dev/null
+++ b/offboarding/templates/offboarding/resignation/nav.html
@@ -0,0 +1,35 @@
+{% load i18n %}
+
+
+
{% trans 'Resignations' %}
+
+
+
+
+
diff --git a/offboarding/templates/offboarding/resignation/request_cards.html b/offboarding/templates/offboarding/resignation/request_cards.html
new file mode 100644
index 000000000..0e2b22125
--- /dev/null
+++ b/offboarding/templates/offboarding/resignation/request_cards.html
@@ -0,0 +1,188 @@
+{% load i18n %}
+{% include 'filter_tags.html' %}
+{% if perms.offboarding.view_resignationletter %}
+
+
+
+ {% trans 'Rejected' %}
+
+
+
+ {% trans 'Requested' %}
+
+
+
+ {% trans 'Approved' %}
+
+
+{% endif %}
+
+
+ {% for record in letters %}
+
+
+
+
{{ record.status|capfirst }}
+
+
+ {% if perms.offboarding.change_resignationletter %}
+
+ {% endif %}
+
+
+
+
+
+
+
+
+
+ {{ record.employee_id.get_full_name }}
+
+ {{ record.employee_id.get_department }} / {{ record.employee_id.get_job_position }}
+
+
+
+
{{ record.title }}
+
{{ record.description|safe }}
+
+
+ {% endfor %}
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/offboarding/templates/offboarding/resignation/requests_view.html b/offboarding/templates/offboarding/resignation/requests_view.html
new file mode 100644
index 000000000..577f002f3
--- /dev/null
+++ b/offboarding/templates/offboarding/resignation/requests_view.html
@@ -0,0 +1,18 @@
+{% extends "index.html" %}
+{% block content %}
+
+{% include "offboarding/resignation/nav.html" %}
+
+ {% include "offboarding/resignation/request_cards.html" %}
+
+{% endblock content %}
\ No newline at end of file
diff --git a/offboarding/templates/offboarding/settings/settings.html b/offboarding/templates/offboarding/settings/settings.html
new file mode 100644
index 000000000..b85f53b10
--- /dev/null
+++ b/offboarding/templates/offboarding/settings/settings.html
@@ -0,0 +1,13 @@
+{% load i18n %}
+{% csrf_token %}
+
+{% trans 'By enabling this normal users can request for their resignation' %}
+
+
diff --git a/offboarding/urls.py b/offboarding/urls.py
index 0ff95a75e..a410aadf3 100644
--- a/offboarding/urls.py
+++ b/offboarding/urls.py
@@ -28,7 +28,33 @@ urlpatterns = [
path("offboarding-add-task", views.add_task, name="offboarding-add-task"),
path("update-task-status", views.update_task_status, name="update-task-status"),
path("offboarding-assign-task", views.task_assign, name="offboarding-assign-task"),
- path("delete-offboarding-employee",views.delete_employee,name="delete-offboarding-employee"),
- path("delete-offboarding-task",views.delete_task,name="delete-offboarding-task"),
- path("offboarding-individual-view//",views.offboarding_individual_view,name="offboarding-individual-view"),
+ path(
+ "delete-offboarding-employee",
+ views.delete_employee,
+ name="delete-offboarding-employee",
+ ),
+ path("delete-offboarding-task", views.delete_task, name="delete-offboarding-task"),
+ path(
+ "offboarding-individual-view//",
+ views.offboarding_individual_view,
+ name="offboarding-individual-view",
+ ),
+ path("requests-view", views.request_view, name="resignation-request-view"),
+ path(
+ "create-resignation-request",
+ views.create_resignation_request,
+ name="create-resignation-request",
+ ),
+ path(
+ "search-resignation-request",
+ views.search_resignation_request,
+ name="search-resignation-request",
+ ),
+ path(
+ "delete-resignation-request",
+ views.delete_resignation_request,
+ name="delete-resignation-request",
+ ),
+ path("update-letter-status", views.update_status, name="update-letter-status"),
+ path("enable-resignation-request", views.enable_resignation_request, name="enable-resignation-request"),
]
diff --git a/offboarding/views.py b/offboarding/views.py
index c3de79d20..8c07c42fe 100644
--- a/offboarding/views.py
+++ b/offboarding/views.py
@@ -1,19 +1,24 @@
+import datetime
+from urllib.parse import parse_qs
from django.http import HttpResponse, JsonResponse
from django.shortcuts import redirect, render
from django.contrib import messages
from django.contrib.auth.models import User
from employee.models import Employee
from horilla.decorators import login_required, permission_required
+from base.views import paginator_qry
from offboarding.decorators import (
any_manager_can_enter,
offboarding_manager_can_enter,
offboarding_or_stage_manager_can_enter,
)
+from offboarding.filters import LetterFilter
from offboarding.forms import (
NoteForm,
OffboardingEmployeeForm,
OffboardingForm,
OffboardingStageForm,
+ ResignationLetterForm,
StageSelectForm,
TaskForm,
)
@@ -21,10 +26,12 @@ from offboarding.models import (
EmployeeTask,
Offboarding,
OffboardingEmployee,
+ OffboardingGeneralSetting,
OffboardingNote,
OffboardingStage,
OffboardingStageMultipleFile,
OffboardingTask,
+ ResignationLetter,
)
from notifications.signals import notify
from django.utils.translation import gettext_lazy as _
@@ -161,12 +168,14 @@ def delete_employee(request):
This method is used to delete the offboarding employee
"""
employee_ids = request.GET.getlist("employee_ids")
- instances = OffboardingEmployee.objects.filter(id__in=employee_ids)
+ instances = OffboardingEmployee.objects.filter(id__in=employee_ids)
OffboardingEmployee.objects.filter(id__in=employee_ids).delete()
messages.success(request, _("Offboarding employee deleted"))
notify.send(
request.user.employee_get,
- recipient=User.objects.filter(id__in=instances.values_list("employee_id__employee_user_id",flat=True)),
+ recipient=User.objects.filter(
+ id__in=instances.values_list("employee_id__employee_user_id", flat=True)
+ ),
verb=f"You have been removed from the offboarding",
verb_ar=f"",
verb_de=f"",
@@ -215,7 +224,9 @@ def change_stage(request):
)
notify.send(
request.user.employee_get,
- recipient=User.objects.filter(id__in=employees.values_list("employee_id__employee_user_id",flat=True)),
+ recipient=User.objects.filter(
+ id__in=employees.values_list("employee_id__employee_user_id", flat=True)
+ ),
verb=f"Offboarding stage has been changed",
verb_ar=f"",
verb_de=f"",
@@ -227,12 +238,18 @@ def change_stage(request):
return render(
request,
"offboarding/stage/offboarding_body.html",
- {"offboarding": stage.offboarding_id, "stage_forms": stage_forms,"response_message":_("stage changed successfully.")},
+ {
+ "offboarding": stage.offboarding_id,
+ "stage_forms": stage_forms,
+ "response_message": _("stage changed successfully."),
+ },
)
@login_required
-@any_manager_can_enter("offboarding.view_offboardingnote",offboarding_employee_can_enter=True)
+@any_manager_can_enter(
+ "offboarding.view_offboardingnote", offboarding_employee_can_enter=True
+)
def view_notes(request):
"""
This method is used to render all the notes of the employee
@@ -329,21 +346,31 @@ def add_task(request):
instance=instance,
)
if request.method == "POST":
- form = TaskForm(request.POST, instance=instance,initial={
- "stage_id": stage_id,
- })
+ form = TaskForm(
+ request.POST,
+ instance=instance,
+ initial={
+ "stage_id": stage_id,
+ },
+ )
if form.is_valid():
form.save()
messages.success(request, "Task Added")
return HttpResponse("")
- return render(request, "offboarding/task/form.html", {"form": form,})
+ return render(
+ request,
+ "offboarding/task/form.html",
+ {
+ "form": form,
+ },
+ )
@login_required
@any_manager_can_enter(
"offboarding.change_employeetask", offboarding_employee_can_enter=True
)
-def update_task_status(request,*args, **kwargs):
+def update_task_status(request, *args, **kwargs):
"""
This method is used to update the assigned tasks status
"""
@@ -357,7 +384,11 @@ def update_task_status(request,*args, **kwargs):
employee_task.update(status=status)
notify.send(
request.user.employee_get,
- recipient=User.objects.filter(id__in=employee_task.values_list("task_id__managers__employee_user_id",flat=True)),
+ recipient=User.objects.filter(
+ id__in=employee_task.values_list(
+ "task_id__managers__employee_user_id", flat=True
+ )
+ ),
verb=f"Offboarding Task status has been updated",
verb_ar=f"",
verb_de=f"",
@@ -374,7 +405,11 @@ def update_task_status(request,*args, **kwargs):
return render(
request,
"offboarding/stage/offboarding_body.html",
- {"offboarding": stage.offboarding_id, "stage_forms": stage_forms,"response_message": _("Task status changed successfully.")},
+ {
+ "offboarding": stage.offboarding_id,
+ "stage_forms": stage_forms,
+ "response_message": _("Task status changed successfully."),
+ },
)
@@ -414,8 +449,9 @@ def delete_task(request):
messages.success(request, "Task deleted")
return redirect(pipeline)
+
@login_required
-def offboarding_individual_view(request,emp_id):
+def offboarding_individual_view(request, emp_id):
"""
This method is used to get the individual view of the offboarding employees
parameters:
@@ -424,13 +460,153 @@ def offboarding_individual_view(request,emp_id):
employee = OffboardingEmployee.objects.get(id=emp_id)
tasks = EmployeeTask.objects.filter(employee_id=emp_id)
stage_forms = {}
- offboarding_stages = OffboardingStage.objects.filter(offboarding_id = employee.stage_id.offboarding_id)
- stage_forms[str(employee.stage_id.offboarding_id.id)] = StageSelectForm(offboarding=employee.stage_id.offboarding_id)
+ offboarding_stages = OffboardingStage.objects.filter(
+ offboarding_id=employee.stage_id.offboarding_id
+ )
+ stage_forms[str(employee.stage_id.offboarding_id.id)] = StageSelectForm(
+ offboarding=employee.stage_id.offboarding_id
+ )
context = {
- 'employee':employee,
- "tasks":tasks,
+ "employee": employee,
+ "tasks": tasks,
"choices": EmployeeTask.statuses,
- "offboarding_stages":offboarding_stages,
- "stage_forms":stage_forms
+ "offboarding_stages": offboarding_stages,
+ "stage_forms": stage_forms,
}
- return render(request, 'offboarding/pipeline/individual_view.html', context)
\ No newline at end of file
+ return render(request, "offboarding/pipeline/individual_view.html", context)
+
+
+@login_required
+@permission_required("offboarding.view_resignationletter")
+def request_view(request):
+ """
+ This method is used to view the resignation request
+ """
+ defatul_filter = {"status": "requested"}
+ filter_instance = LetterFilter(defatul_filter)
+ offboardings = Offboarding.objects.all()
+
+ return render(
+ request,
+ "offboarding/resignation/requests_view.html",
+ {
+ "letters": paginator_qry(filter_instance.qs, request.GET.get("page")),
+ "f": filter_instance,
+ "filter_dict": {"status": ["Requested"]},
+ "offboardings": offboardings,
+ },
+ )
+
+
+@login_required
+def search_resignation_request(request):
+ """
+ This method is used to search/filter the letter
+ """
+ if request.user.has_perm("offboarding.view_resignationletter"):
+ letters = LetterFilter(request.GET).qs
+ else:
+ letters = ResignationLetter.objects.filter(
+ employee_id__employee_user_id=request.user
+ )
+ data_dict = parse_qs(request.GET.urlencode())
+ return render(
+ request,
+ "offboarding/resignation/request_cards.html",
+ {
+ "letters": paginator_qry(letters, request.GET.get("page")),
+ "filter_dict": data_dict,
+ "pd": request.GET.urlencode(),
+ },
+ )
+
+
+@login_required
+@permission_required("offboarding.delete_resignationletter")
+def delete_resignation_request(request):
+ """
+ This method is used to delete resignation letter instance
+ """
+ ids = request.GET.getlist("letter_ids")
+ ResignationLetter.objects.filter(id__in=ids).delete()
+ messages.success(request, "Resignation letter deleted")
+ return redirect(request_view)
+
+
+def create_resignation_request(request):
+ """
+ This method is used to render form to create resignation requests
+ """
+ instance_id = eval(str(request.GET.get("instance_id")))
+ instance = None
+ if instance_id:
+ instance = ResignationLetter.objects.get(id=instance_id)
+ form = ResignationLetterForm(instance=instance)
+ if request.method == "POST":
+ form = ResignationLetterForm(request.POST, instance=instance)
+ if form.is_valid():
+ form.save()
+ messages.success(request, "Resingation letter saved")
+ return HttpResponse("")
+ return render(request, "offboarding/resignation/form.html", {"form": form})
+
+
+@login_required
+@permission_required("offboarding.change_resignationletter")
+def update_status(request):
+ """
+ This method is used to update the status of resignation letter
+ """
+ ids = request.GET.getlist("letter_ids")
+ status = request.GET["status"]
+ offboarding_id = request.GET.get("offboarding_id")
+ if offboarding_id:
+ offboarding = Offboarding.objects.get(id=offboarding_id)
+ notice_period_starts = request.GET.get("notice_period_starts")
+ notice_period_ends = request.GET.get("notice_period_ends")
+ if (notice_period_starts and notice_period_ends) is not None:
+ notice_period_starts = datetime.datetime.strptime(
+ notice_period_starts, "%Y-%m-%d"
+ ).date()
+ notice_period_ends = datetime.datetime.strptime(
+ notice_period_ends, "%Y-%m-%d"
+ ).date()
+
+ letters = ResignationLetter.objects.filter(id__in=ids)
+ # if use update method instead of save then save method will not trigger
+ if status in ["approved", "rejected"]:
+ for letter in letters:
+ letter.status = status
+ letter.save()
+ if status == "approved":
+ letter.to_offboarding_employee(
+ offboarding, notice_period_starts, notice_period_ends
+ )
+ messages.success(
+ request, f"Resingation request has been {letter.get_status_display()}"
+ )
+ notify.send(
+ request.user.employee_get,
+ recipient=letter.employee_id.employee_user_id,
+ verb=f"Resingation request has been {letter.get_status_display()}",
+ verb_ar=f"",
+ verb_de=f"",
+ verb_es=f"",
+ verb_fr=f"",
+ redirect="#",
+ icon="information",
+ )
+ return redirect(request_view)
+
+
+@login_required
+@permission_required("offboarding.offboardinggeneralsetting")
+def enable_resignation_request(request):
+ """
+ Enable disable resignation letter feature
+ """
+ resignation_request_feature = OffboardingGeneralSetting.objects.first()
+ resignation_request_feature = resignation_request_feature if resignation_request_feature else OffboardingGeneralSetting()
+ resignation_request_feature.resignation_request = "resignation_request" in request.GET.keys()
+ resignation_request_feature.save()
+ return HttpResponse("Success")