From 2f1a11c9156e47fa70b59df79c202a7ef91bcd4b Mon Sep 17 00:00:00 2001 From: Horilla Date: Fri, 28 Feb 2025 18:56:52 +0530 Subject: [PATCH] [UPDT] LEAVE: Changed signals to signals.py --- leave/admin.py | 4 - leave/apps.py | 3 +- leave/models.py | 191 ++++++++++++++++++++++------------------------- leave/signals.py | 156 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 249 insertions(+), 105 deletions(-) create mode 100644 leave/signals.py diff --git a/leave/admin.py b/leave/admin.py index 8cfebe8e1..a6a5bee23 100644 --- a/leave/admin.py +++ b/leave/admin.py @@ -9,8 +9,6 @@ from .models import ( AvailableLeave, - CompanyLeave, - Holiday, LeaveAllocationRequest, LeaveallocationrequestComment, LeaveGeneralSetting, @@ -25,8 +23,6 @@ admin.site.register(LeaveType) admin.site.register(LeaveRequest) admin.site.register(AvailableLeave) -admin.site.register(Holiday) -admin.site.register(CompanyLeave) admin.site.register(LeaveAllocationRequest, SimpleHistoryAdmin) admin.site.register(LeaveRequestConditionApproval) admin.site.register(LeaverequestComment) diff --git a/leave/apps.py b/leave/apps.py index 06c80af9f..efc07dad6 100644 --- a/leave/apps.py +++ b/leave/apps.py @@ -1,4 +1,4 @@ -from django.apps import AppConfig +from django.apps import AppConfig, apps class LeaveConfig(AppConfig): @@ -10,6 +10,7 @@ def ready(self): from horilla.horilla_settings import APPS from horilla.urls import urlpatterns + from leave import signals APPS.append("leave") urlpatterns.append( diff --git a/leave/models.py b/leave/models.py index 67fa0e593..f62b10d65 100644 --- a/leave/models.py +++ b/leave/models.py @@ -2,24 +2,19 @@ import logging import math import operator -import threading from datetime import date, datetime, timedelta from dateutil.relativedelta import relativedelta from django.apps import apps -from django.conf import settings from django.contrib import messages from django.core.exceptions import ValidationError from django.core.files.storage import default_storage from django.db import models -from django.db.models import Q -from django.db.models.signals import post_save, pre_save -from django.dispatch import receiver +from django.db.models import Q, Sum from django.utils import timezone from django.utils.translation import gettext_lazy as _ from base.horilla_company_manager import HorillaCompanyManager -from base.methods import get_date_range from base.models import ( Company, CompanyLeaves, @@ -31,12 +26,10 @@ ) from employee.models import Employee, EmployeeWorkInformation from horilla import horilla_middlewares -from horilla.methods import get_horilla_model_class from horilla.models import HorillaModel from horilla_audit.methods import get_diff from horilla_audit.models import HorillaAuditInfo, HorillaAuditLog from leave.methods import calculate_requested_days -from leave.threading import LeaveClashThread logger = logging.getLogger(__name__) @@ -341,9 +334,6 @@ def __str__(self): return f"{dict(WEEK_DAYS).get(self.based_on_week_day)} | {dict(WEEKS).get(self.based_on_week)}" -from django.db.models import Sum - - class AvailableLeave(HorillaModel): employee_id = models.ForeignKey( Employee, @@ -1242,93 +1232,94 @@ class OverrideLeaveRequests(LeaveRequest): Class to override Attendance model save method """ + pass # Additional fields and methods specific to AnotherModel - @receiver(pre_save, sender=LeaveRequest) - def leaverequest_pre_save(sender, instance, **_kwargs): - """ - Overriding LeaveRequest model save method - """ - WorkRecords = get_horilla_model_class( - app_label="attendance", model="workrecords" - ) - if ( - instance.start_date == instance.end_date - and instance.end_date_breakdown != instance.start_date_breakdown - ): - instance.end_date_breakdown = instance.start_date_breakdown - super(LeaveRequest, instance).save() - - period_dates = get_date_range(instance.start_date, instance.end_date) - if instance.status == "approved": - for date in period_dates: - try: - work_entry = ( - WorkRecords.objects.filter( - date=date, - employee_id=instance.employee_id, - ) - if WorkRecords.objects.filter( - date=date, - employee_id=instance.employee_id, - ).exists() - else WorkRecords() - ) - work_entry.employee_id = instance.employee_id - work_entry.is_leave_record = True - work_entry.day_percentage = ( - 0.50 - if instance.start_date == date - and instance.start_date_breakdown == "first_half" - or instance.end_date == date - and instance.end_date_breakdown == "second_half" - else 0.00 - ) - status = ( - "CONF" - if instance.start_date == date - and instance.start_date_breakdown == "first_half" - or instance.end_date == date - and instance.end_date_breakdown == "second_half" - else "ABS" - ) - work_entry.work_record_type = status - work_entry.date = date - work_entry.message = ( - "Absent" - if status == "ABS" - else _("Half day Attendance need to validate") - ) - work_entry.save() - except: - pass - - else: - for date in period_dates: - WorkRecords.objects.filter( - is_leave_record=True, - date=date, - employee_id=instance.employee_id, - ).delete() - - -@receiver(post_save, sender=LeaveRequest) -def update_available(sender, instance, **kwargs): - """ - post save method to update the available leaves - """ - - _sender = sender - - def update_leaves(): - try: - if instance.leave_type_id: - available_leaves = instance.employee_id.available_leave.filter( - leave_type_id=instance.leave_type_id - ) - for assigned in available_leaves: - assigned.save() - except Exception as e: - pass - - thread = threading.Thread(target=update_leaves) - thread.start() + # @receiver(pre_save, sender=LeaveRequest) + # def leaverequest_pre_save(sender, instance, **_kwargs): + # """ + # Overriding LeaveRequest model save method + # """ + # WorkRecords = get_horilla_model_class( + # app_label="attendance", model="workrecords" + # ) + # if ( + # instance.start_date == instance.end_date + # and instance.end_date_breakdown != instance.start_date_breakdown + # ): + # instance.end_date_breakdown = instance.start_date_breakdown + # super(LeaveRequest, instance).save() + + # period_dates = get_date_range(instance.start_date, instance.end_date) + # if instance.status == "approved": + # for date in period_dates: + # try: + # work_entry = ( + # WorkRecords.objects.filter( + # date=date, + # employee_id=instance.employee_id, + # ) + # if WorkRecords.objects.filter( + # date=date, + # employee_id=instance.employee_id, + # ).exists() + # else WorkRecords() + # ) + # work_entry.employee_id = instance.employee_id + # work_entry.is_leave_record = True + # work_entry.day_percentage = ( + # 0.50 + # if instance.start_date == date + # and instance.start_date_breakdown == "first_half" + # or instance.end_date == date + # and instance.end_date_breakdown == "second_half" + # else 0.00 + # ) + # status = ( + # "CONF" + # if instance.start_date == date + # and instance.start_date_breakdown == "first_half" + # or instance.end_date == date + # and instance.end_date_breakdown == "second_half" + # else "ABS" + # ) + # work_entry.work_record_type = status + # work_entry.date = date + # work_entry.message = ( + # "Absent" + # if status == "ABS" + # else _("Half day Attendance need to validate") + # ) + # work_entry.save() + # except: + # pass + + # else: + # for date in period_dates: + # WorkRecords.objects.filter( + # is_leave_record=True, + # date=date, + # employee_id=instance.employee_id, + # ).delete() + + +# @receiver(post_save, sender=LeaveRequest) +# def update_available(sender, instance, **kwargs): +# """ +# post save method to update the available leaves +# """ + +# _sender = sender + +# def update_leaves(): +# try: +# if instance.leave_type_id: +# available_leaves = instance.employee_id.available_leave.filter( +# leave_type_id=instance.leave_type_id +# ) +# for assigned in available_leaves: +# assigned.save() +# except Exception as e: +# pass + +# thread = threading.Thread(target=update_leaves) +# thread.start() diff --git a/leave/signals.py b/leave/signals.py new file mode 100644 index 000000000..c8d13ee40 --- /dev/null +++ b/leave/signals.py @@ -0,0 +1,156 @@ +# leave/signals.py + +import threading + +from django.apps import apps +from django.db.models.signals import post_migrate, pre_save, post_save, pre_delete +from django.dispatch import receiver +from django.utils.translation import gettext_lazy as _ + +from horilla.methods import get_horilla_model_class +from leave.models import LeaveRequest + + +if apps.is_installed("attendance"): + + @receiver(pre_save, sender=LeaveRequest) + def leaverequest_pre_save(sender, instance, **_kwargs): + """ + Overriding LeaveRequest model save method + """ + WorkRecords = get_horilla_model_class( + app_label="attendance", model="workrecords" + ) + if ( + instance.start_date == instance.end_date + and instance.end_date_breakdown != instance.start_date_breakdown + ): + instance.end_date_breakdown = instance.start_date_breakdown + super(LeaveRequest, instance).save() + + period_dates = instance.requested_dates() + if instance.status == "approved": + for date in period_dates: + try: + work_entry = ( + WorkRecords.objects.filter( + date=date, + employee_id=instance.employee_id, + ).first() + if WorkRecords.objects.filter( + date=date, + employee_id=instance.employee_id, + ).exists() + else WorkRecords() + ) + work_entry.employee_id = instance.employee_id + work_entry.is_leave_record = True + work_entry.leave_request_id = instance + work_entry.day_percentage = ( + 0.50 + if instance.start_date == date + and instance.start_date_breakdown == "first_half" + or instance.end_date == date + and instance.end_date_breakdown == "second_half" + else 0.00 + ) + status = ( + "CONF" + if instance.start_date == date + and instance.start_date_breakdown == "first_half" + or instance.end_date == date + and instance.end_date_breakdown == "second_half" + else "ABS" + ) + work_entry.work_record_type = status + work_entry.date = date + work_entry.message = ( + "Leave" + if status == "ABS" + else _("Half day Attendance need to validate") + ) + work_entry.save() + + except Exception as e: + print(e) + + else: + for date in period_dates: + WorkRecords.objects.filter( + is_leave_record=True, + date=date, + employee_id=instance.employee_id, + ).delete() + + @receiver(pre_delete, sender=LeaveRequest) + def leaverequest_pre_delete(sender, instance, **kwargs): + from attendance.models import WorkRecords + + work_records = WorkRecords.objects.filter(leave_request_id=instance).delete() + + +@receiver(post_save, sender=LeaveRequest) +def update_available(sender, instance, **kwargs): + """ + post save method to update the available leaves + """ + + _sender = sender + + def update_leaves(): + try: + if instance.leave_type_id: + available_leaves = instance.employee_id.available_leave.filter( + leave_type_id=instance.leave_type_id + ) + for assigned in available_leaves: + assigned.save() + except Exception as e: + pass + + thread = threading.Thread(target=update_leaves) + thread.start() + + +@receiver(post_migrate) +def add_missing_leave_to_workrecords(sender, **kwargs): + if sender.label not in ["attendance", "leave"]: + return + + if not apps.is_installed("attendance"): + return + try: + from attendance.models import WorkRecords + from leave.models import LeaveRequest + + work_records = WorkRecords.objects.filter( + is_leave_record=True, leave_request_id__isnull=True + ) + if not work_records.exists(): + return + + leave_requests = LeaveRequest.objects.all() + date_leave_map = {} + + for leave in leave_requests: + for date in leave.requested_dates(): + key = (leave.employee_id, date) + date_leave_map[key] = leave + + records_to_update = [] + for record in work_records: + leave_request = date_leave_map.get((record.employee_id, record.date)) + if leave_request: + record.leave_request_id = leave_request + records_to_update.append(record) + + if records_to_update: + WorkRecords.objects.bulk_update( + records_to_update, ["leave_request_id"], batch_size=500 + ) + print( + f"Successfully updated {len(records_to_update)} work records with leave information" + ) + + except Exception as e: + print(f"Error in leave/work records sync: {e}")