Files
ihrm/offboarding/models.py

351 lines
11 KiB
Python
Raw Normal View History

from collections.abc import Iterable
from datetime import date, timedelta
[IMP] Remove inter module dependency (#274) This commit introduces significant changes to the architecture of the Horilla HRMS system by decoupling interdependent modules. The following modifications were made: 1. **Module Independence**: Each module has been refactored to eliminate reliance on other modules, promoting a more modular and maintainable codebase. 2. **Refactored Imports and Dependencies**: Adjusted import statements and dependency injections to support independent module operation. 3. **Compatibility and Functionality**: Ensured that all modules are compatible with existing systems and maintain their intended functionality both independently and when integrated with other modules. These changes enhance the modularity, maintainability, and scalability of the Horilla HRMS, allowing developers to work on individual modules without affecting the entire system. Future development and deployment will be more efficient and less prone to issues arising from tightly coupled code. **NOTE** For existing Horilla users, if you face any issues during the migrations, please run the following command and try again the migrations. - `python3 manage.py makemigrations` - `python3 manage.py migrate base` - `python3 manage.py migrate` * [IMP] ASSET: Asset module dependency removal from other Horilla apps * [IMP] ATTENDANCE: Attendance module dependency removal from other Horilla apps * [IMP] BASE: Base module dependency removal from other Horilla apps * [IMP] EMPLOYEE: Employee module dependency removal from other Horilla apps * [IMP] HELPDESK: Helpdesk module dependency removal from other Horilla apps * [IMP] HORILLA AUDIT: Horilla Audit module dependency removal from other Horilla apps * [IMP] HORILLA CRUMBS: Horilla Crumbs module dependency removal from other Horilla apps * [IMP] HORILLA AUTOMATIONS: Horilla Automations module dependency removal from other Horilla apps * [IMP] HORILLA VIEWS: Horilla Views module dependency removal from other Horilla apps * [IMP] LEAVE: Leave module dependency removal from other Horilla apps * [IMP] OFFBOARDING: Offboarding module dependency removal from other Horilla apps * [IMP] ONBOARDING: Onboarding module dependency removal from other Horilla apps * [IMP] PMS: PMS module dependency removal from other Horilla apps * [IMP] PAYROLL: Payroll module dependency removal from other Horilla apps * [IMP] RECRUITMENT: Recruitment module dependency removal from other Horilla apps * [IMP] HORILLA: Dependency removal updates * [IMP] TEMPLATES: Dependency removal updates * [IMP] STATIC: Dependency removal updates * [IMP] HORILLA DOCUMENTS: Horilla Documents module dependency removal from other Horilla apps * [ADD] HORILLA: methods.py * [UPDT] HORILLA: Settings.py * [FIX] EMPLOYEE: About tab issue * Update horilla_settings.py * Remove dummy db init password
2024-08-05 14:22:44 +05:30
from django.apps import apps
from django.contrib.auth.models import User
from django.db import models
from django.db.models.signals import post_save
from django.dispatch import receiver
from django.utils.translation import gettext_lazy as _
2024-02-26 20:17:39 +05:30
from base.horilla_company_manager import HorillaCompanyManager
2024-01-25 15:59:15 +05:30
from base.models import Company
from employee.models import Employee
from horilla import horilla_middlewares
from horilla.horilla_middlewares import _thread_locals
[IMP] Remove inter module dependency (#274) This commit introduces significant changes to the architecture of the Horilla HRMS system by decoupling interdependent modules. The following modifications were made: 1. **Module Independence**: Each module has been refactored to eliminate reliance on other modules, promoting a more modular and maintainable codebase. 2. **Refactored Imports and Dependencies**: Adjusted import statements and dependency injections to support independent module operation. 3. **Compatibility and Functionality**: Ensured that all modules are compatible with existing systems and maintain their intended functionality both independently and when integrated with other modules. These changes enhance the modularity, maintainability, and scalability of the Horilla HRMS, allowing developers to work on individual modules without affecting the entire system. Future development and deployment will be more efficient and less prone to issues arising from tightly coupled code. **NOTE** For existing Horilla users, if you face any issues during the migrations, please run the following command and try again the migrations. - `python3 manage.py makemigrations` - `python3 manage.py migrate base` - `python3 manage.py migrate` * [IMP] ASSET: Asset module dependency removal from other Horilla apps * [IMP] ATTENDANCE: Attendance module dependency removal from other Horilla apps * [IMP] BASE: Base module dependency removal from other Horilla apps * [IMP] EMPLOYEE: Employee module dependency removal from other Horilla apps * [IMP] HELPDESK: Helpdesk module dependency removal from other Horilla apps * [IMP] HORILLA AUDIT: Horilla Audit module dependency removal from other Horilla apps * [IMP] HORILLA CRUMBS: Horilla Crumbs module dependency removal from other Horilla apps * [IMP] HORILLA AUTOMATIONS: Horilla Automations module dependency removal from other Horilla apps * [IMP] HORILLA VIEWS: Horilla Views module dependency removal from other Horilla apps * [IMP] LEAVE: Leave module dependency removal from other Horilla apps * [IMP] OFFBOARDING: Offboarding module dependency removal from other Horilla apps * [IMP] ONBOARDING: Onboarding module dependency removal from other Horilla apps * [IMP] PMS: PMS module dependency removal from other Horilla apps * [IMP] PAYROLL: Payroll module dependency removal from other Horilla apps * [IMP] RECRUITMENT: Recruitment module dependency removal from other Horilla apps * [IMP] HORILLA: Dependency removal updates * [IMP] TEMPLATES: Dependency removal updates * [IMP] STATIC: Dependency removal updates * [IMP] HORILLA DOCUMENTS: Horilla Documents module dependency removal from other Horilla apps * [ADD] HORILLA: methods.py * [UPDT] HORILLA: Settings.py * [FIX] EMPLOYEE: About tab issue * Update horilla_settings.py * Remove dummy db init password
2024-08-05 14:22:44 +05:30
from horilla.methods import get_horilla_model_class
from horilla.models import HorillaModel
from horilla_audit.models import HorillaAuditInfo, HorillaAuditLog
from notifications.signals import notify
# Create your models here.
class Offboarding(HorillaModel):
"""
Offboarding model
"""
statuses = [("ongoing", _("Ongoing")), ("completed", _("Completed"))]
title = models.CharField(max_length=20)
description = models.TextField(max_length=255)
managers = models.ManyToManyField(Employee)
status = models.CharField(max_length=10, default="ongoing", choices=statuses)
2024-01-25 15:59:15 +05:30
company_id = models.ForeignKey(
Company,
on_delete=models.CASCADE,
null=True,
verbose_name="Company",
2024-01-25 15:59:15 +05:30
)
objects = HorillaCompanyManager("company_id")
2024-01-25 15:59:15 +05:30
def __str__(self):
return self.title
def save(self, *args, **kwargs):
is_new = not self.pk
super().save(*args, **kwargs)
if is_new:
stages = [
("Exit interview", "interview"),
("Work Handover", "handover"),
("FNF", "fnf"),
("Farewell", "other"),
("Archived", "archived"),
]
for stage in stages:
new = OffboardingStage()
new.offboarding_id = self
new.title = stage[0]
new.type = stage[1]
new.save()
return
class OffboardingStage(HorillaModel):
"""
Offboarding model
"""
types = [
("notice_period", _("Notice period")),
("fnf", _("FnF Settlement")),
("other", _("Other")),
("interview", _("Interview")),
("handover", _("Work handover")),
("archived", _("Archived")),
]
title = models.CharField(max_length=20)
type = models.CharField(max_length=13, choices=types)
offboarding_id = models.ForeignKey(Offboarding, on_delete=models.CASCADE)
managers = models.ManyToManyField(Employee)
sequence = models.IntegerField(default=0, editable=False)
def __str__(self) -> str:
return str(self.title)
def is_archived_stage(self):
"""
This method is to check the stage is archived or not
"""
return self.type == "archived"
@receiver(post_save, sender=Offboarding)
def create_initial_stage(sender, instance, created, **kwargs):
"""
This is post save method, used to create initial stage for the recruitment
"""
if created:
initial_stage = OffboardingStage()
initial_stage.title = "Notice Period"
initial_stage.offboarding_id = instance
initial_stage.type = "notice_period"
initial_stage.save()
class OffboardingStageMultipleFile(HorillaModel):
"""
OffboardingStageMultipleFile
"""
attachment = models.FileField(upload_to="offboarding/attachments")
class OffboardingEmployee(HorillaModel):
"""
OffboardingEmployee model / Employee on stage
"""
UNIT = [("day", "days"), ("month", "Month")]
employee_id = models.OneToOneField(
Employee, on_delete=models.CASCADE, verbose_name="Employee"
)
stage_id = models.ForeignKey(
OffboardingStage, on_delete=models.CASCADE, verbose_name="Stage", null=True
)
2024-01-25 15:59:15 +05:30
notice_period = models.IntegerField(null=True)
unit = models.CharField(max_length=10, choices=UNIT, default="month", null=True)
2024-01-25 15:59:15 +05:30
notice_period_starts = models.DateField(null=True)
notice_period_ends = models.DateField(null=True, blank=True)
2024-02-26 20:17:39 +05:30
objects = HorillaCompanyManager(
related_company_field="employee_id__employee_work_info__company_id"
)
def __str__(self) -> str:
return self.employee_id.get_full_name()
class ResignationLetter(HorillaModel):
2024-01-25 15:59:15 +05:30
"""
Resignation Request Employee model
"""
statuses = [
("requested", _("Requested")),
("approved", _("Approved")),
("rejected", _("Rejected")),
2024-01-25 15:59:15 +05:30
]
employee_id = models.ForeignKey(
Employee, on_delete=models.CASCADE, verbose_name="Employee"
)
title = models.CharField(max_length=100, null=True)
description = models.TextField(null=True, max_length=255)
2024-01-25 15:59:15 +05:30
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
)
2024-02-26 20:17:39 +05:30
objects = HorillaCompanyManager(
related_company_field="employee_id__employee_work_info__company_id"
)
2024-01-25 15:59:15 +05:30
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()
)
default_notice_end = (
get_horilla_model_class(
app_label="payroll", model="payrollgeneralsetting"
).objects.first()
[IMP] Remove inter module dependency (#274) This commit introduces significant changes to the architecture of the Horilla HRMS system by decoupling interdependent modules. The following modifications were made: 1. **Module Independence**: Each module has been refactored to eliminate reliance on other modules, promoting a more modular and maintainable codebase. 2. **Refactored Imports and Dependencies**: Adjusted import statements and dependency injections to support independent module operation. 3. **Compatibility and Functionality**: Ensured that all modules are compatible with existing systems and maintain their intended functionality both independently and when integrated with other modules. These changes enhance the modularity, maintainability, and scalability of the Horilla HRMS, allowing developers to work on individual modules without affecting the entire system. Future development and deployment will be more efficient and less prone to issues arising from tightly coupled code. **NOTE** For existing Horilla users, if you face any issues during the migrations, please run the following command and try again the migrations. - `python3 manage.py makemigrations` - `python3 manage.py migrate base` - `python3 manage.py migrate` * [IMP] ASSET: Asset module dependency removal from other Horilla apps * [IMP] ATTENDANCE: Attendance module dependency removal from other Horilla apps * [IMP] BASE: Base module dependency removal from other Horilla apps * [IMP] EMPLOYEE: Employee module dependency removal from other Horilla apps * [IMP] HELPDESK: Helpdesk module dependency removal from other Horilla apps * [IMP] HORILLA AUDIT: Horilla Audit module dependency removal from other Horilla apps * [IMP] HORILLA CRUMBS: Horilla Crumbs module dependency removal from other Horilla apps * [IMP] HORILLA AUTOMATIONS: Horilla Automations module dependency removal from other Horilla apps * [IMP] HORILLA VIEWS: Horilla Views module dependency removal from other Horilla apps * [IMP] LEAVE: Leave module dependency removal from other Horilla apps * [IMP] OFFBOARDING: Offboarding module dependency removal from other Horilla apps * [IMP] ONBOARDING: Onboarding module dependency removal from other Horilla apps * [IMP] PMS: PMS module dependency removal from other Horilla apps * [IMP] PAYROLL: Payroll module dependency removal from other Horilla apps * [IMP] RECRUITMENT: Recruitment module dependency removal from other Horilla apps * [IMP] HORILLA: Dependency removal updates * [IMP] TEMPLATES: Dependency removal updates * [IMP] STATIC: Dependency removal updates * [IMP] HORILLA DOCUMENTS: Horilla Documents module dependency removal from other Horilla apps * [ADD] HORILLA: methods.py * [UPDT] HORILLA: Settings.py * [FIX] EMPLOYEE: About tab issue * Update horilla_settings.py * Remove dummy db init password
2024-08-05 14:22:44 +05:30
if apps.is_installed("payroll")
else None
)
try:
if not notice_period_ends:
notice_period_ends = (
notice_period_starts + timedelta(default_notice_end.notice_period)
if default_notice_end
else notice_period_ends
)
except:
notice_period_ends = notice_period_ends
2024-01-25 15:59:15 +05:30
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
2024-01-25 15:59:15 +05:30
offboarding_employee.save()
class OffboardingTask(HorillaModel):
"""
OffboardingTask model
"""
title = models.CharField(max_length=30)
managers = models.ManyToManyField(Employee)
stage_id = models.ForeignKey(
OffboardingStage,
on_delete=models.PROTECT,
verbose_name="Stage",
null=True,
blank=True,
)
class Meta:
unique_together = ["title", "stage_id"]
def __str__(self) -> str:
return self.title
class EmployeeTask(HorillaModel):
"""
EmployeeTask model
"""
statuses = [
("todo", _("Todo")),
("in_progress", _("In progress")),
("stuck", _("Stuck")),
("completed", _("Completed")),
]
employee_id = models.ForeignKey(
OffboardingEmployee,
on_delete=models.CASCADE,
verbose_name="Employee",
null=True,
)
status = models.CharField(max_length=20, choices=statuses, default="todo")
task_id = models.ForeignKey(OffboardingTask, on_delete=models.CASCADE)
description = models.TextField(null=True, editable=False, max_length=255)
history = HorillaAuditLog(
related_name="history_set",
bases=[
HorillaAuditInfo,
],
)
class Meta:
unique_together = ["employee_id", "task_id"]
2024-01-25 15:59:15 +05:30
def save(self, *args, **kwargs):
super().save(*args, **kwargs)
request = getattr(_thread_locals, "request", None)
notify.send(
request.user.employee_get,
recipient=self.employee_id.employee_id.employee_user_id,
verb=f'Offboarding task "{self.task_id.title}" has been assigned',
verb_ar=f"",
verb_de=f"",
verb_es=f"",
verb_fr=f"",
redirect="offboarding/offboarding-pipeline",
icon="information",
)
class ExitReason(HorillaModel):
"""
ExitReason model
"""
title = models.CharField(max_length=50)
description = models.TextField(max_length=255)
offboarding_employee_id = models.ForeignKey(
OffboardingEmployee, on_delete=models.CASCADE
)
attachments = models.ManyToManyField(OffboardingStageMultipleFile)
class OffboardingNote(HorillaModel):
"""
OffboardingNote
"""
attachments = models.ManyToManyField(
OffboardingStageMultipleFile, blank=True, editable=False
)
description = models.TextField(null=True, blank=True, max_length=255)
note_by = models.ForeignKey(
Employee, on_delete=models.SET_NULL, null=True, editable=False
)
employee_id = models.ForeignKey(
OffboardingEmployee, on_delete=models.CASCADE, null=True, editable=False
)
stage_id = models.ForeignKey(
OffboardingStage, on_delete=models.PROTECT, null=True, editable=False
)
class Meta:
ordering = ["-created_at"]
def save(self, *args, **kwargs):
request = getattr(horilla_middlewares._thread_locals, "request", None)
if request:
updated_by = request.user.employee_get
self.note_by = updated_by
if self.employee_id:
self.stage_id = self.employee_id.stage_id
return super().save(*args, **kwargs)
2024-01-25 15:59:15 +05:30
class OffboardingGeneralSetting(HorillaModel):
2024-01-25 15:59:15 +05:30
"""
OffboardingGeneralSettings
"""
resignation_request = models.BooleanField(default=False)
company_id = models.ForeignKey(Company, on_delete=models.CASCADE, null=True)