Overtime
Overtime management in ERPNext v15
- Author: aliraxa29
- Repository: https://github.com/aliraxa29/overtime
- GitHub stars: 6
- Forks: 5
- License: MIT
- Category: Other
- Maintenance: Minimally Maintained
- Frappe versions: develop, v15
Install Overtime
bench get-app https://github.com/aliraxa29/overtime
Tags
- erpnext
- frappe
- overtime
- overtime-calculation
- overtime-tracking
- version-15
Add the Frappe Gems badge to your README
Maintain Overtime? Paste this into your README:
[](https://frappegems.com/gems/apps/aliraxa29/overtime)
About Overtime
# Overtime Management for HRMS v15
[](https://github.com/aliraxa29/overtime/actions/workflows/ci.yml)
[](https://opensource.org/licenses/MIT)
[](https://www.python.org/downloads/)
[](https://frappeframework.com/)
[](CONTRIBUTING.md)
A Frappe/HRMS v15 app that **automatically calculates overtime hours** from Employee Checkin records. Supports overnight shifts, Ramadan schedules with religion-based rules, configurable rounding, rate multipliers, and an approval workflow.
---
## Table of Contents
- [Features](#features)
- [Installation](#installation)
- [Configuration](#configuration)
- [Overtime Settings](#overtime-settings)
- [Overtime Shift Rules](#overtime-shift-rules)
- [Custom Fields](#custom-fields)
- [How It Works](#how-it-works)
- [Calculation Flow](#calculation-flow)
- [Overnight Shift Handling](#overnight-shift-handling)
- [Ramadan Mode](#ramadan-mode)
- [Shift Rule Matching (Scoring)](#shift-rule-matching-scoring)
- [Shift Schedule Reference](#shift-schedule-reference)
- [DocTypes](#doctypes)
- [Extending / Customization](#extending--customization)
- [Troubleshooting](#troubleshooting)
- [License](#license)
---
## Features
| Feature | Description |
|---|---|
| **Auto-calculation** | Overtime calculated on Attendance submit via `doc_events` hook |
| **Overnight shifts** | Full support for shifts crossing midnight (e.g. 23:30 → 07:30) |
| **Ramadan mode** | Date-range activation with religion-based shift schedules |
| **Shift rule scoring** | Weighted matching: period → religion category → shift type → department |
| **Food/Suhoor breaks** | Configurable break deductions per shift rule |
| **Grace period** | Late arrival / early departure tolerance (per shift rule) |
| **Rounding** | Round Up, Round Down, or Round to Nearest (configurable interval) |
| **Rate multipliers** | Separate rates for normal days vs holidays |
| **Min/Max caps** | Minimum minutes threshold, maximum hours per day |
| **Approval workflow** | Optional manager approval before overtime is finalized |
| **Bulk operations** | Recalculate / bulk-submit overtime via API |
| **Daily scheduler** | Fallback daily job to catch missed attendance events |
| **Attendance sync** | Overtime hours and entry link written back to Attendance record |
---
## Installation
### Prerequisites
- Frappe v15
- HRMS v15 (installed and configured with Shift Types and Employee Checkin)
- Python 3.10+
### Install
```bash
cd $PATH_TO_YOUR_BENCH
# Get the app
bench get-app $URL_OF_THIS_REPO --branch develop
# Install on your site
bench --site your-site.local install-app overtime
# Run migrations
bench --site your-site.local migrate
```
The `after_install` hook automatically:
1. Creates custom fields on Employee and Attendance
2. Creates default Overtime Settings
3. Creates 7 default Overtime Shift Rules
---
## Configuration
### Overtime Settings
Navigate to **Overtime Settings** (single DocType) to configure global behavior.
| Field | Type | Description |
|---|---|---|
| `enabled` | Check | Master switch — disables all overtime processing when off |
| `overtime_based_on` | Select | `Shift Hours` (scheduled vs actual) or `Fixed Hours` (fixed daily threshold) |
| `minimum_overtime_minutes` | Int | Minimum minutes before overtime counts (e.g. 15 = ignore <15min) |
| `max_overtime_hours_per_day` | Float | Daily cap (e.g. 4.0) |
| `overtime_rounding` | Select | `No Rounding`, `Round Up`, `Round Down`, `Round to Nearest` |
| `rounding_interval_minutes` | Int | Interval for rounding (e.g. 15 = round to 15-min blocks) |
| `default_overtime_rate_multiplier` | Float | Normal-day rate (e.g. 1.5x) |
| `holiday_overtime_rate_multiplier` | Float | Holiday rate (e.g. 2.0x) |
| `require_approval` | Check | If enabled, entries are created as Draft for manager approval |
| `auto_create_overtime_entry` | Check | Auto-create Overtime Entry on Attendance submit |
| `ramadan_mode_enabled` | Check | Enable Ramadan period shift rules |
| `ramadan_start_date` | Date | Ramadan period start |
| `ramadan_end_date` | Date | Ramadan period end |
### Overtime Shift Rules
Navigate to **Overtime Shift Rule** list to manage shift definitions.
Each rule defines:
| Field | Description |
|---|---|
| `shift_name` | Display name (e.g. "Morning", "Night") |
| `applicable_period` | `Standard` or `Ramadan` |
| `employee_category` | `All`, `Muslim`, or `Non-Muslim` |
| `check_in_time` / `check_out_time` | Scheduled shift start/end times |
| `is_overnight_shift` | Check if shift crosses midnight |
| `allow_late_early_exception` | Enable grace period |
| `late_early_grace_minutes` | Grace minutes for late arrival / early departure |
| `has_food_break` | Deduct a food/suhoor break from working hours |
| `food_break_duration_minutes` | Break length in minutes |
| `food_break_type` | `Regular Break` or `Suhoor Break` |
| `food_break_included_in_shift` | If checked, break is deducted from scheduled hours |
| `shift_type` | Optional — link to HRMS Shift Type for matching |
| `department` | Optional — restrict rule to a department |
| `overtime_eligible` | Allow overtime calculation for this rule |
### Custom Fields
Created automatically by `after_install`:
| DocType | Field | Type | Description |
|---|---|---|---|
| Employee | `religion_category` | Select | Muslim / Non-Muslim |
| Attendance | `overtime_hours` | Float | Auto-filled overtime hours |
| Attendance | `overtime_entry` | Link | Link to Overtime Entry |
---
## How It Works
### Calculation Flow
1. **Trigger**: `Attendance.on_submit` fires `hooks_handler.on_attendance_submit()`
2. **Settings check**: Load Overtime Settings; skip if disabled or auto-create is off
3. **Rule matching**: `get_applicable_shift_rule()` finds the best-scoring rule for this attendance
4. **Checkin retrieval**: Get Employee Checkin records linked to this Attendance (with fallback search)
5. **Duration calc**: Compute actual working hours from first-IN to last-OUT checkin timestamps
6. **Scheduled hours**: Calculate from shift rule's check_in/check_out times (handles overnight)
7. **Net overtime**: `actual_hours - scheduled_hours - food_break + grace_adjustment`
8. **Rounding**: Apply configured rounding method
9. **Caps**: Enforce `minimum_overtime_minutes` and `max_overtime_hours_per_day`
10. **Rate**: Apply `default_overtime_rate_multiplier` or `holiday_overtime_rate_multiplier`
11. **Create entry**: Insert Overtime Entry with all calculated fields
### Overnight Shift Handling
**HRMS behavior** (critical to understand):
When a Shift Type has `start_time > end_time` (e.g. 23:30 → 07:30), HRMS treats it as an overnight shift:
- The `get_shift_timings()` function in HRMS detects `start_time > end_time` and enters the overnight branch
- A checkin at **23:30 on Jan 15** gets `shift_start = Jan 15 23:30` and `shift_end = Jan 16 07:30`
- A checkout at **07:30 on Jan 16** gets the **same** `shift_start = Jan 15 23:30` and `shift_end = Jan 16 07:30`
- HRMS groups checkins by `(employee, shift_start)` and creates ONE Attendance record
- The Attendance date is **Jan 15** (the `shift_start.date()`)
**Our app handles this by:**
- Using `is_overnight_shift` flag on shift rules to correctly calculate scheduled hours across midnight
- The `_get_checkin_logs()` function searches by `shift_start` date for fallback matching
- Duration is always calculated from full datetime timestamps (not time-only), so midnight crossing is automatic
**Known HRMS edge case**: If `last_sync_of_checkin` on the Shift Type is set to a value less than the shift duration, overnight OUT checkins may be skipped. Ensure `last_sync_of_checkin` ≥ shift duration.
### Ramadan Mode
When `ramadan_mode_enabled = 1` and today falls within `[ramadan_start_date, ramadan_end_date]`:
1. Shift rules with `applicable_period = "Ramadan"` get +100 priority in scoring
2. Muslim employees match rules with `employee_category = "Muslim"`
3. Non-Muslim employees match rules with `employee_category = "Non-Muslim"`
4. Rules with `employee_category = "All"` serve as fallback
Outside the Ramadan date range, only `Standard` period rules are considered.
### Shift Rule Matching (Scoring)
When multiple shift rules exist, the system picks the best match using a weighted score:
| Criterion | Points | Description |
|---|---|---|
| **Period match** | +100 | Ramadan rule during Ramadan period |
| **Category match** | +50 | Exact religion category match (Muslim/Non-Muslim) |
| **Shift type match** | +30 | Rule's `shift_type` matches Attendance's shift |
| **Department match** | +25 | Rule's `department` matches Employee's department |
| **Fallback** | +10 | Rules with `employee_category = "All"` |
The highest-scoring enabled rule wins. Ties are broken by the DB ordering.
---
## Shift Schedule Reference
### Standard Period (All Employees)
| Shift | Check-in | Check-out | Overnight | Scheduled | Food Break | Grace |
|---|---|---|---|---|---|---|
| Morning | 07:30 | 15:30 | No | 8h (7.5h net) | 30min | 15min |
| Evening | 15:30 | 23:30 | No | 8h (7.5h net) | 30min | 15min |
| Night | 23:30 | 07:30 | **Yes** | 8h (7.5h net) | 30min | 15min |
### Ramadan Period — Muslim Employees
| Shift | Check-in | Check-out | Overnight | Scheduled | Food Break | Grace |
|---|---|---|---|---|---|---|
| Factory Morning | 07:00 | 13:00 | No | 6h | None (fasting) | None |
| Admin Morning | 09:00 | 15:00 | No | 6h | None (fasting) | None |
| Factory Night | 00:00 | 19:30 | No | 19.5h (18.5h net) | 60min Suhoor | None |
### Ramadan Period — Non-Muslim Employees
| Shift | Check-in | Check-out | Overnight | Scheduled | Food Break | Grace |
|---|---|---|---|---|---|---|
| Factory Evening | 16:00 | 00:00 | **Yes** | 8h (7.5h net) | 30min | None |
---
## DocTypes
### Overtime Settings (Single)
Global configuration for overtime processing. One record per site.
### Overtime Shift Rule
Defines shift schedules with check-in/out times, breaks, grace periods, and category/period qualifiers. Named as `{shift_name}-{employee_category}-{applicable_period}`.
### Overtime Entry (Submittable)
Individual overtime records linked to Employee + Attendance. Named as `OT-{employee}-.####`.
**Fields**: employee, attendance, attendance_date, shift, overtime_hours, rate_multiplier, payable_overtime_hours, status (Draft/Approved/Rejected), and complete shift/checkin details.
---
## Extending / Customization
### Adding New Shift Rules
1. Go to **Overtime Shift Rule** → New
2. Fill in shift name, times, period, category
3. Set `overtime_eligible = 1`
4. Save — the rule will be matched automatically by the scoring engine
### Custom Rate Logic
Override `_get_rate_multiplier()` in `utils.py` if you need per-employee or per-department rates.
### Custom Hooks
The app hooks into `Attendance.on_submit` and `Attendance.on_cancel`. If you need to add custom logic, extend `hooks_handler.py` or add your own `doc_events` in a separate app.
### Adding Department-Specific Rules
Set the `department` field on a shift rule to restrict it. Department match adds +25 to the scoring, giving it priority over generic rules.
---
## Troubleshooting
| Problem | Solution |
|---|---|
| No overtime calculated | Check **Overtime Settings** → `enabled` and `auto_create_overtime_entry` are checked |
| Wrong shift rule applied | Check scoring: verify `applicable_period`, `employee_category`, `shift_type`, `department` on rules |
| Overnight shift gives 0 hours | Ensure `is_overnight_shift` is checked on the rule; verify HRMS Shift Type has `start_time > end_time` |
| Checkins not found | Ensure Employee Checkins have `attendance` linked, or `shift_start` set for fall
Related Other apps for Frappe & ERPNext
- Erpnext — Free and Open Source Enterprise Resource Planning (ERP)
- Helpdesk — Modern, Streamlined, Free and Open Source Customer Service Software
- Print Designer — Visual print designer for Frappe / ERPNext
- Ctr — CTR模型代码和学习笔记总结
- Whitelabel — Whitelabel ERPNext
- Fossunited — fossunited.org
- Helm — Helm Chart Repository for Frappe/ERPNext
- Frappe Attachments S3 — A frappe app to upload file attachments in doctypes to s3.