Skip to content
People · Leave management module

A leave management system with rules your managers don't have to remember

Leave looks simple until three people from the same team book the same week in December and the approvals all went through because each manager only saw one request. A leave management system should know your rules before anyone clicks approve. Tell erpfly what they are, and it builds them into ERPNext or Odoo.

ERPNext v16

Works with ERPNext v15 and v16, and Odoo 17, 18 and 19.

Features

What your leave management module can do

Accruals that match the policy document

Monthly or yearly earning, pro-rated for joiners, with carry-forward caps and expiry dates that follow the handbook word for word.

Team cover limits

A maximum number of people away per department or team during the periods you choose, checked when the request is made, not when it's too late.

Approvals that go to the right person

Requests route to the line manager, then to HR for long or unusual leave, with delegation when the manager is away themselves.

Balances people can check themselves

Staff see what they've earned, taken and have left from the portal or their phone, which removes most of the emails HR gets.

Payroll that knows about unpaid days

Leave without pay and encashment feed the salary slip automatically, so HR doesn't reconcile leave and payroll by hand.

The output

What actually gets generated

Real files in a real repository. Here’s the typical output when someone asks for leave management.

ERPNext / Frappe app

  • Leave Type and Leave Policy fixtures for each employee group
  • Department Leave Cover DocType with date ranges
  • doc_events validation on Leave Application
  • Leave Policy Assignment import for existing staff
  • Team leave calendar Script Report

Odoo addon

  • hr.leave inheritance with a team cover constraint
  • hr.leave.accrual.plan data matching your policy
  • Cover rule model linked to hr.department
  • Opening balances loaded as hr.leave.allocation records
  • Inherited calendar and list views on hr.leave
leave_cover/leave_application.py
import frappe
from frappe import _

def check_team_cover(doc, method=None):
    """Leave Application.validate. Keeps enough people working in busy periods."""
    if doc.status in ("Rejected", "Cancelled") or not doc.department:
        return
    rule = frappe.db.get_value(
        "Department Leave Cover",
        {"department": doc.department, "from_date": ["<=", doc.to_date], "to_date": [">=", doc.from_date]},
        ["max_away", "from_date", "to_date"],
        as_dict=True,
    )
    if not rule:
        return
    others = frappe.get_all(
        "Leave Application",
        filters={
            "department": doc.department,
            "employee": ["!=", doc.employee],
            "docstatus": ["<", 2],
            "status": ["in", ["Open", "Approved"]],
            "from_date": ["<=", doc.to_date],
            "to_date": [">=", doc.from_date],
        },
        pluck="employee",
    )
    away = len(set(others))
    if away >= rule.max_away:
        frappe.throw(
            _("{0} people from {1} already have leave overlapping these dates. The limit between {2} and {3} is {4}.")
            .format(away, doc.department, rule.from_date, rule.to_date, rule.max_away),
            title=_("Team cover limit reached"),
        )
Trimmed excerpt. The full module includes tests, fixtures and a README.

How it works

From a paragraph to a pull request

The long version
  1. 01

    Describe it

    In your own words. Paste the spreadsheet or a photo of the paper form if that's easier.

  2. 02

    Answer a couple of questions

    It asks only what it can't work out from your setup, like who's allowed to override.

  3. 03

    Try it on a sandbox

    A copy of your site with the module installed. Break it, then ask for changes.

  4. 04

    Merge when it's right

    Code lands as a pull request with tests. Your developer, or ours, reviews it first.

Leave balances are a trust problem

Ask five employees how much leave they have left and you’ll get five confident answers. Ask HR and you’ll get a spreadsheet with a tab called “FINAL v3” and a note about someone’s carry-forward from 2023.

Leave isn’t hard to calculate. The trouble is that employees don’t believe the balance HR gives them, so every request becomes a negotiation. A leave management system fixes that only if the rules inside it are the same ones in the employee handbook, applied the same way to everyone.

What a leave management system in ERPNext or Odoo covers already

More than most people expect, and we’d rather you used it than paid for code you don’t need.

In Frappe HR (the HR app that runs alongside ERPNext), Leave Types define whether leave is paid, carried forward or encashable. A Leave Policy bundles entitlements, and a Leave Policy Assignment gives them to an employee for a leave period. Earned leave accrues monthly through a scheduled job. Holiday Lists keep public holidays out of the day count, and a Leave Block List closes specific dates for a department or company, with named people allowed through. Balances are tracked through Leave Ledger Entries, so there’s a history behind every number.

Odoo’s Time Off app is part of Community. It has leave types, allocations, accrual plans with carry-forward rules, and a team calendar managers actually look at.

What neither does out of the box is reason about headcount. A Leave Block List says “not on these days”. It can’t say “no more than two people at once”.

Worked example: holding the line in peak season

Picture a customer support team of 60 agents split across four departments. November to early January is their busiest period, and everyone wants the same fortnight off.

The policy they already have on paper:

  • Agents earn 1.5 days a month, 18 days a year. Up to 10 unused days carry into the next year. The rest expire.
  • From 15 November to 10 January, no more than 2 people from the same department may be away on any overlapping dates.
  • Requests over 5 consecutive days go to HR after the team lead approves.

Accrual and carry-forward are standard configuration, so erpfly generates a Leave Type and a Leave Policy as fixtures rather than code. The cover rule needs code, and that’s the function on this page, hooked to Leave Application through doc_events.

Now watch it work. In the Billing department, Hana has approved leave from 22 to 31 December. Tariq applied for 24 to 28 December, still open. On 3 November, Luis applies for 27 December to 2 January. Two people already overlap his dates, the limit is 2, so his application won’t save and the message tells him why. He picks 3 to 9 January instead, when the rest of Billing is back at work. No manager had to be the bad guy.

Open requests count toward the limit on purpose. Otherwise two people apply on the same morning, both look fine, and the manager approves both before lunch.

Leave rules we’d argue with

Different accrual maths for every employee. If you have 14 leave policies for 60 people, the handbook is the thing to fix. Group them.

Hard blocks with no escape hatch. Family emergencies don’t check the cover calendar. Give HR a role that can override with a reason.

Negative balances by default. Letting people borrow future leave sounds kind until someone resigns owing eight days. Allow it per case, not for everyone.

Syncing leave into three calendars. Pushing approved leave to one shared calendar is useful. Two-way sync with personal calendars fills personal calendars with duplicate events that pile up for months.

Where leave fits in HR

Approved leave should stop someone being marked absent in attendance management, and unpaid days need to reach the salary slip in HR and payroll. If you’re on ERPNext and wondering whether a rule like this belongs in a Server Script or a proper app, see Server Scripts vs a custom app. For wider changes to your setup, start with ERPNext customization or Odoo customization.

Guides and terms for leave management

Leave management module questions

Something missing? Email hello@erpfly.com and a person will answer.

Doesn't ERPNext already have leave management?

It does, and it's decent. Frappe HR includes Leave Type, Leave Policy, Leave Allocation, Leave Application, earned leave accrual, Holiday Lists and Leave Block Lists. We configure those first and generate code only for rules they can't express, like headcount-based cover limits.

Is Odoo's Time Off app free?

Time Off (hr.leave, allocations and accrual plans) is part of Odoo Community. If you want unpaid leave to flow into payslips automatically, that needs Payroll, which is Enterprise.

How do we bring over leave balances from spreadsheets?

We generate an import that creates one opening allocation per employee and leave type, dated at go-live. Before that, send balances to every employee and give them a week to object. It's far easier to fix a number before it's in the system than after.

Can the rules differ by country or site?

Yes. Leave policies can be assigned per employee group, so a team in one country can have different entitlements and public holidays from another. You tell us the rules. Confirming they match local labour law is a job for your HR lead or adviser.

Will custom leave rules break when we upgrade?

They live in your own app or addon and hook into standard documents, so an upgrade won't overwrite them. Leave validation has changed between major versions before, so test on a staging copy before upgrading production.

How long does this take?

Rules like the example on this page take minutes to generate. Cleaning up opening balances usually takes longer, often a couple of weeks if they haven't been checked in a while.

Your next module is one paragraph away

Write it the way you’d explain it to a new hire. We’ll turn it into an app you can read, test and install.

ERPNext v16

Create your account

Free to start. No card needed.

By signing up you agree to our terms and privacy policy.