403Webshell
Server IP : 65.108.144.40  /  Your IP : 216.73.217.165
Web Server : Apache/2.4.52 (Ubuntu)
System : Linux ubuntu-8gb-hel1-1 5.15.0-173-generic #183-Ubuntu SMP Fri Mar 6 13:29:34 UTC 2026 x86_64
User : dev ( 1000)
PHP Version : 8.2.30
Disable Function : NONE
MySQL : OFF  |  cURL : ON  |  WGET : ON  |  Perl : ON  |  Python : ON  |  Sudo : ON  |  Pkexec : ON
Directory :  /var/www/erp/leave/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : /var/www/erp/leave/scheduler.py
import calendar
import contextlib
import datetime as dt
import sys
from datetime import datetime, timedelta
from urllib import request

from apscheduler.schedulers.background import BackgroundScheduler
from apscheduler.triggers.cron import CronTrigger
from dateutil.relativedelta import relativedelta
from django.urls import reverse
from notifications.signals import notify
from django.db.models import Q
import logging
logger = logging.getLogger(__name__)
logger = logging.getLogger('django')

today = datetime.now()


def leave_reset():
    from leave.models import LeaveType

    today_date = today.date()
    leave_types = LeaveType.objects.filter(reset=True)
    # Looping through filtered leave types with reset is true
    for leave_type in leave_types:
        # Looping through all available leaves
        available_leaves = leave_type.employee_available_leave.all()

        for available_leave in available_leaves:
            reset_date = available_leave.reset_date
            expired_date = available_leave.expired_date
            if reset_date == today_date:
                available_leave.update_carryforward()
                # new_reset_date = available_leave.set_reset_date(assigned_date=today_date,available_leave = available_leave)
                new_reset_date = available_leave.set_reset_date(
                    assigned_date=today_date, available_leave=available_leave
                )
                available_leave.reset_date = new_reset_date
                available_leave.save()
            if expired_date and expired_date <= today_date:
                new_expired_date = available_leave.set_expired_date(
                    available_leave=available_leave, assigned_date=today_date
                )
                available_leave.expired_date = new_expired_date
                available_leave.save()

        if (
            leave_type.carryforward_expire_date
            and leave_type.carryforward_expire_date <= today_date
        ):
            leave_type.carryforward_expire_date = leave_type.set_expired_date(
                today_date
            )
            leave_type.save()

# Custom auto leave approve method
def auto_approve_leave_requests():

    from leave.models import AvailableLeave, LeaveRequest
    today_date = today.date()

    # Query for pending leave requests
    leave_requests = LeaveRequest.objects.filter(status="requested")
    logger.info("Auto approve function executed (line 66)")
    logger.info(f"""{leave_requests}""")
    for leave_request in leave_requests:
        employee_id = leave_request.employee_id
        leave_type_id = leave_request.leave_type_id
        available_leave = AvailableLeave.objects.get(
            leave_type_id=leave_type_id, employee_id=employee_id
        )

        total_available_leave = available_leave.available_days + available_leave.carryforward_days
    
        # if (not (total_available_leave >= leave_request.requested_days)) and leave_request.status != "approved":
        #     leave_request.status = "rejected"
        #     super(AvailableLeave, available_leave).save()
        #     leave_request.save()
        #     logger.info(f"""Rejected leave for {employee_id}, {leave_type_id}""")
            
        if total_available_leave >= leave_request.requested_days and today_date - timedelta(days=1) >= leave_request.start_date and leave_request.status != "approved":
            # Approve the leave request
            leave_request.status = "approved"
            if leave_request.requested_days > available_leave.available_days:
                leave = leave_request.requested_days - available_leave.available_days
                leave_request.approved_available_days = available_leave.available_days
                available_leave.available_days = 0
                available_leave.carryforward_days -= leave
                leave_request.approved_carryforward_days = leave
            else:
                available_leave.available_days -= leave_request.requested_days
                leave_request.approved_available_days = leave_request.requested_days
            

            super(AvailableLeave, available_leave).save()
            leave_request.save()
            logger.info(f"""Approved leave for {employee_id}, {leave_type_id}""")

# Method to delete unwanted leave type
def delete_leave_type_on_tag_change(employee_id,leave_type):
    from leave.models import AvailableLeave
    # Check if the employee has the 'Leave Type' available and is assigned to them
    available_leave = AvailableLeave.objects.filter(
        leave_type_id=leave_type,
        employee_id=employee_id
    ).exists()
    if available_leave:
        # Delete the leave type record for the employee if it exists
        AvailableLeave.objects.filter(
            leave_type_id=leave_type,
            employee_id=employee_id
        ).delete()

# custom function for update leave for employee
def update_leave_for_employee(employee_info, leave_type, reset_interval, reset_date_field):
    """
    Generalized function to update the available leave for an employee.
    """
    from leave.models import AvailableLeave
    from leave.models import LeaveType
    employee_id = employee_info.employee_id
    joining_date = employee_info.date_joining
    tag_is_intern_or_trainee = employee_info.tags.filter(title__in=["Intern", "Trainee"]).exists()
    tag_is_full_time = employee_info.tags.filter(title="Full Time").exists()
    tag_is_probation = employee_info.tags.filter(title="Probation").exists()
    casual_type_id = LeaveType.objects.get(name="Casual Leave")
    earn_type_id = LeaveType.objects.get(name="Earn Leave")
    today = datetime.now()
    current_date = today.date()
    # Get the available leave for the employee
    is_leave_type =  AvailableLeave.objects.filter(
            leave_type_id=leave_type, employee_id=employee_id
        ).exists()
    if is_leave_type:
        available_leave = AvailableLeave.objects.get(
            leave_type_id=leave_type, employee_id=employee_id
        )

        if available_leave:
            next_reset = getattr(available_leave, reset_date_field, None)
            total_leave_taken = available_leave.leave_taken()
            logger.info("Executed update leave function at 143 line")
            logger.info(f"""Name {employee_id}""")
            try:
                logger.info(f"""{current_date} >= {next_reset} : {current_date >= next_reset}""")
            except Exception:
                logger.info(f"""{current_date} >= {next_reset}""")
            logger.info(f"""tag_is_intern_or_trainee : {tag_is_intern_or_trainee}""")

            if next_reset is None and available_leave.assigned_date is not None:
                if joining_date == current_date or ((joining_date + timedelta(days=1)) == current_date):
                    setattr(available_leave, reset_date_field, joining_date + reset_interval)

                elif tag_is_full_time and available_leave.leave_type_id == earn_type_id:
                    if (joining_date + relativedelta(month=3)).year < current_date.year:
                        next_reset = current_date.replace(year=current_date.year,month=1,day=1) + timedelta(days=45)
                    else:
                        next_reset = available_leave.assigned_date + timedelta(days=45)
                    setattr(available_leave, reset_date_field, next_reset)

                elif tag_is_full_time and available_leave.leave_type_id == casual_type_id:
                    next_reset = current_date.replace(year=current_date.year+1,month=1,day=1)
                    setattr(available_leave, reset_date_field, next_reset)

                else:
                    next_reset = joining_date.replace(year=current_date.year, month=current_date.month)
                    setattr(available_leave, reset_date_field, next_reset)
                available_leave.save()
                

            # Check if it's time to increment leave days
            elif current_date >= next_reset:
                logger.info("Inside the current_date >= next_reset condition at 171 line")
                if tag_is_full_time:
                    if available_leave.leave_type_id == earn_type_id:
                        logger.info("Executed earn leave condition at 174 line")
                        available_leave.available_days += 1.0
                        condition_date = datetime(current_date.year,1,1) + timedelta(days=45)*8
                        if current_date == condition_date.date():
                            resetting_date = current_date.replace(year=current_date.year + 1, month=2, day=15)
                            setattr(available_leave, reset_date_field, resetting_date)
                        else:
                            setattr(available_leave, reset_date_field, next_reset + reset_interval)
                        available_leave.save()
                    elif available_leave.leave_type_id == casual_type_id:
                        available_leave.available_days = 6.0
                        setattr(available_leave, reset_date_field, next_reset + reset_interval)
                        available_leave.save()

                elif tag_is_intern_or_trainee:
                    logger.info("Executed intern leave condition at 189 line")
                    next_reset = joining_date.replace(year=current_date.year, month=current_date.month + 1)
                    available_leave.available_days = 1.0
                    setattr(available_leave, reset_date_field, next_reset)
                    available_leave.save()
                
                elif tag_is_probation and ((total_leave_taken + available_leave.available_days + available_leave.carryforward_days) < 3.0) and not (next_reset >= joining_date + relativedelta(months=3)):
                    logger.info("Executed Probation leave condition at 196 line(Jan-June)")
                    available_leave.available_days += 1.0
                    next_reset = joining_date.replace(year=current_date.year, month=current_date.month + 1)
                    setattr(available_leave, reset_date_field, next_reset)
                    available_leave.save()

                elif tag_is_probation and (next_reset == joining_date + relativedelta(months=3)) and joining_date.month <= 6:
                    logger.info("Executed Probation leave condition at 203 line(Jan-June applied)")
                    available_leave.available_days += 3.0
                    resetting_date = current_date.replace(year=current_date.year + 1, month=1, day=1)
                    setattr(available_leave, reset_date_field, resetting_date)
                    available_leave.save()
                
                elif tag_is_probation and (next_reset >= joining_date + relativedelta(months=3)) and joining_date.month > 6:
                    logger.info("Executed Probation leave condition at 210 line(July-Dec)")
                    if (joining_date + relativedelta(month=3)).year == joining_date.year:
                        resetting_date = current_date.replace(year=current_date.year + 1, month=1, day=1)
                        setattr(available_leave, reset_date_field, resetting_date)
                        available_leave.save()
                    elif (joining_date + relativedelta(month=3)).year > joining_date.year:
                        available_leave.available_days += ((12 - current_date.month) * 0.5)
                        if available_leave.available_days > 6:
                            available_leave.available_days = 6
                        resetting_date = current_date.replace(year=current_date.year + 1, month=1, day=1)
                        setattr(available_leave, reset_date_field, resetting_date)
                        available_leave.save()

                available_leave.save()

            elif current_date == current_date.replace(year=current_date.year,month=1,day=1) and tag_is_full_time:
                if available_leave.leave_type_id == earn_type_id:
                    resetting_date = current_date.replace(year=current_date.year, month=2, day=15)
                    setattr(available_leave, reset_date_field, resetting_date)      
                    if available_leave.available_days > 5.0:
                        available_leave.available_days = 5.0
                    available_leave.save()
    
    elif not is_leave_type:
        available_leave = AvailableLeave(
                    leave_type_id=leave_type,
                    employee_id=employee_id,
                    available_days=leave_type.total_days,
                )
        if tag_is_intern_or_trainee or tag_is_probation:
            next_reset = joining_date.replace(year=current_date.year, month=current_date.month + 1)
            setattr(available_leave, reset_date_field, next_reset)
            if tag_is_probation:
                available_leave.available_days = 1
            available_leave.save()
        elif tag_is_full_time and available_leave.leave_type_id == earn_type_id:
            next_reset = available_leave.assigned_date + timedelta(days=45)
            setattr(available_leave, reset_date_field, next_reset)
            available_leave.save()
        elif tag_is_full_time and available_leave.leave_type_id == casual_type_id:
            available_leave.available_days = ((12 - available_leave.assigned_date.month) * 0.5)
            next_reset = current_date.replace(year=current_date.year + 1,month=1,day=1)
            setattr(available_leave, reset_date_field, next_reset)
            available_leave.save()

# custom 45 days leave increment by 1 for full time employee
def increment_earned_leave():
    """
    This function finds all full-time employees with Full Time tag and increments their available Earn leave
    by 1 for every 45 days.
    """
    from base.models import EmployeeType
    from employee.models import EmployeeWorkInformation
    from leave.models import LeaveType
    
    # Get the Full Time Employee Type
    full_time_type_id = EmployeeType.objects.get(employee_type="Full Time")
    leave_type_id = LeaveType.objects.get(name="Earn Leave")
    logger.info("Earned function executed")
    
    # Get all employees who are full time and have a joining date
    employees = EmployeeWorkInformation.objects.filter(employee_type_id=full_time_type_id, date_joining__isnull=False)
    for employee_info in employees:
        emp_tag = employee_info.tags.filter(title="Full Time").exists()
        if emp_tag:
            update_leave_for_employee(
                employee_info, leave_type_id, timedelta(days=45), "next_earn_leave_reset_date"
            )

def fulltime_casual_leave():
    """
    This function finds all full-time employees with Full Time tag and increments their available casual leave
    by 6 for every year.
    """
    from base.models import EmployeeType
    from employee.models import EmployeeWorkInformation
    from leave.models import LeaveType
    
    # Get the Full Time Employee Type
    full_time_type_id = EmployeeType.objects.get(employee_type="Full Time")
    leave_type_id = LeaveType.objects.get(name="Casual Leave")
    leave_type_id2 = LeaveType.objects.get(name="Intern Casual Leave")
    logger.info("Full-time Casual function executed")
    
    # Get all employees who are full time and have a joining date
    employees = EmployeeWorkInformation.objects.filter(employee_type_id=full_time_type_id, date_joining__isnull=False)
    for employee_info in employees:
        emp_tag = employee_info.tags.filter(title="Full Time").exists()
        if emp_tag:
            delete_leave_type_on_tag_change(employee_info.employee_id,leave_type_id2)
            update_leave_for_employee(
                employee_info, leave_type_id, relativedelta(years=1), "reset_date"
            )

#  custom Probation period days leave increment by 0.5 for full time employee who have probation tag
def probation_casual_leave():
    """
    This function finds all Full Time employees with Probation tag and increments their available casual leave
    by 1 for probation period and than add 3 after their probation period if they lie in (Jan-June) range else only 3 for probation period.
    """
    from base.models import EmployeeType
    from employee.models import EmployeeWorkInformation
    from leave.models import LeaveType
    
    # Get the Full Time Employee Type
    full_time_type_id = EmployeeType.objects.get(employee_type="Full Time")
    leave_type_id = LeaveType.objects.get(name="Casual Leave")
    leave_type_id2 = LeaveType.objects.get(name="Intern Casual Leave")
    leave_type_id3 = LeaveType.objects.get(name="Earn Leave")
    logger.info("Probation function executed")
    
    # Get all employees who are full time and have a joining date    
    employees = EmployeeWorkInformation.objects.filter(employee_type_id=full_time_type_id, date_joining__isnull=False)
    for employee_info in employees:
        emp_tag = employee_info.tags.filter(title="Probation").exists()
        if emp_tag:
            delete_leave_type_on_tag_change(employee_info.employee_id,leave_type_id2)
            delete_leave_type_on_tag_change(employee_info.employee_id,leave_type_id3)
            update_leave_for_employee(
                employee_info, leave_type_id, relativedelta(months=1), "reset_date"
            )

# Custom Intern Casual Leaves Flow Method (same for Trainee)
def intern_casual_leave():
    """
    This function will find all Intern & Trainee employees with tag and increments their available Inter Casual leave
    by 1 from the date of joining + reset their old balance to 0.
    """
    from base.models import EmployeeType
    from employee.models import EmployeeWorkInformation
    from leave.models import LeaveType
    
    # Get the Full Time Employee Type
    intern_type_id = EmployeeType.objects.get(employee_type="Intern")
    trainee_type_id = EmployeeType.objects.get(employee_type="Trainee")
    leave_type_id = LeaveType.objects.get(name="Intern Casual Leave")
    logger.info("Intern function executed")

    # Get all employees who are Intern and Trainee 
    employees = EmployeeWorkInformation.objects.filter( Q(employee_type_id=intern_type_id) | Q(employee_type_id=trainee_type_id),
                                                        date_joining__isnull=False )

    for employee_info in employees:
        emp_tag = employee_info.tags.filter(title="Intern").exists() or employee_info.tags.filter(title="Trainee").exists()
        if emp_tag:
            update_leave_for_employee(
                employee_info, leave_type_id, relativedelta(months=1), "reset_date"
            )

if not any(
    cmd in sys.argv
    for cmd in ["makemigrations", "migrate", "compilemessages", "flush", "shell"]
):
    """
    Initializes and starts background tasks using APScheduler when the server is running.
    """
    scheduler = BackgroundScheduler()
    scheduler.add_job(leave_reset, "interval", seconds=20, max_instances=1)

    scheduler.add_job(probation_casual_leave, "interval", hours=5, max_instances=6)
    scheduler.add_job(intern_casual_leave, "interval", hours=4, max_instances=6) 
    scheduler.add_job(auto_approve_leave_requests, "interval", hours=3, max_instances=1)
    scheduler.add_job(increment_earned_leave, "interval", hours=7, max_instances=6)
    scheduler.add_job(fulltime_casual_leave, "interval", hours=11, max_instances=6)

    scheduler.start()

Youez - 2016 - github.com/yon3zu
LinuXploit