m-leave Module
Complete leave management: types, balances, applications, orders, credits.
DocTypes
Section titled “DocTypes”LeaveType
Section titled “LeaveType”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"LeaveBalance
Section titled “LeaveBalance”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")]LeaveApplication
Section titled “LeaveApplication”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"LeaveOrder
Section titled “LeaveOrder”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"Holiday
Section titled “Holiday”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"LeaveClubRule
Section titled “LeaveClubRule”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")]LeaveCreditProcess
Section titled “LeaveCreditProcess”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"Services
Section titled “Services”LeaveCreditService
Section titled “LeaveCreditService”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(...)API Endpoints
Section titled “API Endpoints”| 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 |