Skip to content

m-leave Module

Complete leave management: types, balances, applications, orders, credits.


class LeaveType(BaseDocType):
"""Leave type master with rules."""
code: str = Field(max_length=10, unique=True)
name: str = Field(max_length=100)
# Rules
half_day_allowed: bool = True
balance_maintained: bool = True
is_paid: bool = True
is_encashable: bool = False
# Limits
max_days_at_once: int | None = None
max_days_per_year: int | None = None
max_times_per_year: int | None = None
max_days_in_career: int | None = None
max_times_in_career: int | None = None
accumulation_limit: int | None = None
class Meta:
table_name = "leave_type"
class LeaveBalance(BaseDocType):
"""Current leave balance per employee per type."""
employee: str # FK to Employee
leave_type: str # FK to LeaveType
balance: Decimal = Decimal("0")
last_credit_date: date | None = None
valid_upto: date | None = None
class Meta:
table_name = "leave_balance"
unique_together = [("employee", "leave_type")]
class LeaveApplication(BaseDocType):
"""Employee leave application."""
application_number: str = Field(max_length=50, unique=True)
employee: str # FK to Employee
application_date: date
receipt_date: date | None = None
# Address while on leave
address_on_leave: str | None = None
status: str = "Draft" # Draft, Submitted, Approved, Rejected, Cancelled
prefix_suffix_flag: bool = False # Include weekends/holidays
ltc_requested: bool = False
remarks: str | None = None
# Child: leave periods
items: list["LeaveApplicationItem"] = []
class Meta:
table_name = "leave_application"
class LeaveApplicationItem(BaseDocType):
"""Leave application line item."""
parent: str # FK to LeaveApplication
leave_type: str # FK to LeaveType
from_date: date
to_date: date
from_half: str = "Full" # Full, FirstHalf, SecondHalf
to_half: str = "Full"
leave_period: Decimal # Calculated days
medical_certificate_attached: bool = False
is_encashed: bool = False
encashed_days: int = 0
class Meta:
table_name = "leave_application_item"
class LeaveOrder(BaseDocType):
"""Consolidated leave order from Depot (monthly)."""
order_number: str = Field(max_length=50, unique=True)
depot: str # FK to Depot
order_date: date
# Child: leave entries
entries: list["LeaveOrderEntry"] = []
class Meta:
table_name = "leave_order"
class LeaveOrderEntry(BaseDocType):
"""Line item in leave order."""
parent: str # FK to LeaveOrder
serial_number: int
employee: str # FK to Employee
leave_type: str
from_date: date
to_date: date
leave_period: Decimal
leave_balance: Decimal | None = None
status: str = "Original" # Original, Amended, Cancelled
remarks: str | None = None
class Meta:
table_name = "leave_order_entry"
class Holiday(BaseDocType):
"""General and Restricted holidays."""
holiday_date: date
description: str = Field(max_length=200)
holiday_type: str # General, Restricted
class Meta:
table_name = "holiday"
class LeaveClubRule(BaseDocType):
"""Rules for leave types that cannot be clubbed."""
leave_type_1: str # FK to LeaveType
leave_type_2: str # FK to LeaveType
class Meta:
table_name = "leave_club_rule"
unique_together = [("leave_type_1", "leave_type_2")]
class LeaveCreditProcess(BaseDocType):
"""Record of leave credit process run."""
process_month: str # "2024-01"
run_date: date
leave_type: str # FK to LeaveType
employees_credited: int = 0
employees_excluded: int = 0
remarks: str | None = None
class Meta:
table_name = "leave_credit_process"

class LeaveCreditService:
"""Half-yearly/yearly leave credit process."""
async def run_credit_process(
self,
leave_type: str,
credit_amount: Decimal,
exclude_employees: list[str] = [],
) -> LeaveCreditProcess:
"""Credit leave to all eligible employees."""
employees = await self.get_eligible_employees(exclude_employees)
for emp in employees:
await self.credit_leave(emp.id, leave_type, credit_amount)
return LeaveCreditProcess(...)

Endpoint Method Description
/api/v1/leave-type GET, POST Leave types
/api/v1/leave-balance/{employee} GET Employee balances
/api/v1/leave-application GET, POST Applications
/api/v1/leave-application/{id}/approve POST Approve leave
/api/v1/leave-order GET, POST Depot orders
/api/v1/leave-credit/run POST Run credit process