🌴 How Leave Application Works

A complete guide — from an employee requesting a day off, to a manager approving it, to the balance being updated automatically.

🌍 The Big Picture

Imagine you work at a company and you want to take a week off. Here is what happens, from start to finish:

  1. You open the ESS Portal (your personal employee page) and click "Apply for Leave".
  2. You pick the type of leave, the dates, and the reason. You click Submit.
  3. Your manager sees a notification. They look at your request and click Approve (or Reject).
  4. You get a notification. Your leave balance is automatically reduced.
  5. On your leave dates, the attendance system marks you as "On Leave" — not absent.
  6. When payroll runs that month, paid leave is treated as if you worked those days — no salary cut.
Employee Submits leave via ESS portal System Checks ✓ No overlap ✓ Balance ok? ✓ Valid dates Manager / HR Reviews & decides Approve or Reject Balance Updated Days deducted Attendance marked Payroll notified

The leave journey: employee submits → system validates → manager decides → balance updates automatically.

📋 Types of Leave

Not all leave is the same. HRSanad supports many different leave types. Each one has its own rules — how many days you get, whether you need to submit a document, whether you get paid during it, and whether the company allows you to take more than your balance.

🏖️
Annual Leave
30 days/year
UAE minimum
🤒
Sick Leave
Requires medical
certificate
👶
Maternity Leave
Female employees
only
🚨
Emergency Leave
Short notice
allowed
🕌
Hajj Leave
Once in a career
(Muslim employees)
📅
Unpaid Leave
No salary
during leave

What HR configures for each leave type

SettingWhat it meansExample
unitIs the leave counted in days or hours?Annual = days, Short break = hours
is_paidDoes the employee get full salary during this leave?Annual Leave = paid; Unpaid Leave = not paid
requires_approvalDoes someone need to approve it, or is it automatic?Annual = must be approved; Emergency = sometimes auto-approved
requires_documentMust the employee upload a supporting document?Sick leave = medical certificate required
min_notice_daysHow many days in advance must the request be submitted?Annual Leave = 7 days notice
max_consecutive_daysMaximum days allowed in a single stretch without special approval30 days; beyond that needs HR Director approval
accrual_methodHow the balance builds up over timemonthly = 2.5 days credited each month; annual = all 30 days credited on Jan 1
carry_forward_maxHow many unused days the employee can keep into next year15 days max carry forward
negative_balanceCan the employee take leave even if their balance is zero?true = allowed (balance goes negative); false = hard block
gender_restrictedApplies to a specific gender onlyMaternity leave = female only; Paternity leave = male only

⚖️ Leave Balance — How It Builds Up

Your leave balance is not just one number. It is calculated from five parts that add up together:

Ahmed's Annual Leave Balance — 2026 Annual Leave (AL)
Opening Balance
5
days carried forward from 2025
Accrued
+20
8 months × 2.5 days credited
Taken
−10
approved leave used
Adjusted
+2
manual HR correction
Closing Balance
17
available to take now
Formula:   Closing Balance = Opening + Accrued − Taken − Encashed + Adjusted

How the balance grows — Monthly Accrual

For leave types with accrual_method = "monthly", HRSanad credits a portion of your annual entitlement on the last day of every month. A cron job runs automatically at 20:05 UTC each day and credits the right amount to every active employee.

Example: Annual Leave entitlement = 30 days/year

Monthly credit = 30 ÷ 12 = 2.5 days per month

This means by mid-year (after 6 months) the employee has accrued 15 days — even if they haven't taken any leave yet.

Jan
2.5
Feb
5.0
Mar
7.5
Apr
10.0
May
2.5
Jun
5.0
Jul
7.5
Aug
10.0
Sep
12.5
Oct
15.0
Nov
17.5
Dec
20.0

Running balance over the year. The red May column shows where 7.5 days were taken, resetting the available balance back to 2.5 days after that month's accrual.

Entitlements — seniority-based rates

Employees who have worked longer may get more leave. HRSanad supports entitlement bands by years of service:

Years of ServiceDays Entitled / YearMonthly Credit
0 – 2 years21 days1.75 days
2 – 5 years25 days2.08 days
5+ years30 days2.5 days
💡 UAE minimum UAE Labour Law (Article 29) sets a minimum of 30 calendar days annual leave per year for employees who have completed one full year of service. HRSanad enforces this and will not allow you to set an entitlement below this for active employees.

📱 How an Employee Applies for Leave

Employees apply through the ESS Portal (Employee Self-Service). This is a separate, secure web portal where each employee can only see their own data.

  1. Log into the ESS Portal

    The employee visits the ESS portal and logs in using their work email address or their mobile number (the system detects which format was entered). After successful login they see their personal dashboard.

  2. Check your leave balance first

    On the Leave section, the employee sees their current balance for each leave type — how many days they have available right now. This prevents them submitting a request they cannot take.

    API: GET /v1/ess/leave-balance

  3. Click "Apply for Leave" and fill the form
    • Leave Type — pick from the list (Annual, Sick, Emergency…)
    • From Date / To Date — the dates you want off
    • Reason — a short explanation (optional for annual, mandatory for some types)
    • Supporting Document — required for types like Sick Leave
  4. System runs instant checks before submitting

    Before saving the request, the system automatically verifies:

    • Do you have enough balance? (If negative_balance = false and balance is insufficient → blocked with an error)
    • Do you already have another approved or pending leave that overlaps these dates? (Overlap → blocked)
    • Is the advance notice requirement met? (e.g., annual leave requires 7 days notice)

    If any check fails, the employee sees a clear error and the request is not saved.

  5. Request is saved as "Submitted"

    If all checks pass, the request is saved with status . The balance is not deducted yet — it is only deducted when the manager approves it. This is important: a submitted request is a pending request, not a confirmed leave.

    API: POST /v1/ess/leave-requests

  6. Employee can track the status

    From the ESS portal, the employee can see all their requests and their current statuses. They can also cancel a request (while it's still submitted or even after it's approved, before the leave starts).

    API: GET /v1/ess/leave-requests

✅ The Approval Workflow

Once a request is submitted, the approval workflow begins. The manager or HR team is responsible for reviewing and making a decision.

Who can approve leave?

HR Admin

Full access — can approve, reject, cancel, or adjust any employee's leave. Can also override business rules.

Line Manager

Can approve or reject requests for employees who report to them directly.

HR Officer

Can approve or reject leave requests. Similar to HR Admin but without payroll access.

Sysadmin

Full system access including all leave operations. Used for setup and emergency corrections.

The full status machine

Every leave request moves through a series of statuses. The diagram below shows every possible path:

SUBMITTED Awaiting decision APPROVED Balance deducted REJECTED No balance change CANCELLED Balance restored if approved RESUMED Unused days returned Approve Reject Employee cancels (while pending) Employee or HR cancels Returns early Approve path Reject path Cancel path Early return path

Every possible path a leave request can take. Solid lines = normal flow. Dashed lines = exception paths.

What happens at each status transition

From → ToWho can do itWhat happens automatically
draft / new → Employee (via ESS) System validates dates, overlap, and balance. Request saved. Balance NOT deducted yet.
approved HR Admin, HR Officer, Line Manager, Sysadmin Days deducted from balance immediately. taken += days_requested. approved_by and approved_at recorded.
rejected HR Admin, HR Officer, Line Manager, Sysadmin Rejection reason stored. No balance change (balance was never deducted on submit). Employee notified.
cancelled Employee, HR Admin Request cancelled before approval. No balance change (was never deducted).
approvedcancelled Employee, HR Admin Days restored to balance. taken -= days_requested. Useful if plans change before the leave starts.
approvedresumed HR Admin (on behalf of employee) Employee returned early. Unused days calculated and credited back. taken -= days_resumed. actual_return_date recorded.
⚠️ Critical rule: Only SUBMITTED requests can be approved or rejected Once a request is approved, rejected, or cancelled — you cannot approve or reject it again. The system enforces this strictly. This prevents accidental double-deductions or contradictory decisions.

↩️ Returning Early — The "Resumed" Status

Life happens. Sometimes an employee is approved for 10 days of leave but comes back after 6. HRSanad handles this cleanly with the Resume action.

Example — Ahmed's Early Return

  1. Ahmed applies for leave: 1 April – 10 April (10 days). Approved. Balance reduced by 10.
  2. Ahmed comes back on 6 April unexpectedly (family matter resolved).
  3. HR opens the request and clicks Resume, entering the actual return date: 6 April.
  4. The system calculates: days actually taken = 5 (1st to 5th April). Days unused = 10 − 5 = 5 days.
  5. 5 days are automatically credited back to Ahmed's balance.
days_actually_taken = calendar_days(start_date → actual_return_date) - 1
days_resumed        = max(0, days_requested - days_actually_taken)
new_taken_balance   = old_taken - days_resumed

🛡️ Business Rules & Guardrails

The system enforces these rules automatically — HR does not need to check them manually.

🚫 Overlapping Leaves — Hard Block

You cannot have two leave requests that cover the same dates (unless the earlier one is already rejected or cancelled). The system checks:

existing leave with status NOT IN
  ('rejected', 'cancelled')
AND dates overlap with new request
→ BLOCKED (error returned)

⚠️ Insufficient Balance — Configurable

If a leave type has negative_balance = false, the request is blocked when balance would go below zero. If negative_balance = true, the employee can take more than they have (the balance goes negative — an advance on future accrual).

📅 Day Calculation

Leave days are counted as calendar days (including weekends). If you apply for Monday–Friday (5 days), the system counts 5 days, not 5 working days. Holiday exclusion is handled at the entitlement setup level.

days = floor((end_date - start_date)
             / 86400000) + 1

🔔 Min Notice Days

If a leave type requires advance notice (e.g., annual leave requires 7 days notice), the system rejects requests submitted too close to the start date. Sick leave and emergency leave typically have zero notice requirement.

🚨 Rule: BR-LVE-001 Days calculation for leave excludes weekends AND public holidays when computing working-day impact (relevant for attendance and payroll). The raw days requested figure is calendar days; the actual working-day impact on attendance uses the TNA calendar.
🚨 Rule: BR-LVE-002 If allow_negative_balance = false for the leave type, insufficient balance is a hard error. The request is rejected immediately and not saved. The employee must wait for more days to accrue.
🚨 Rule: BR-LVE-003 Overlapping leaves are always a hard error. There is no override. Two requests cannot cover the same date.

🔗 How Leave Connects to Attendance & Payroll

Approved Leave status = "approved" TNA / Attendance Day marked "on_leave" (not "absent") Leave Balance taken += days_requested Payroll Engine Paid leave = full salary Unpaid = salary deducted

One approval triggers two automatic updates: attendance is marked and balance is reduced.

Attendance Impact

When a leave request is approved, the TNA (Time & Attendance) module marks those dates as on_leave — not as absent. This matters because:

  • Absent days → salary deduction (pro-rated)
  • On-leave days (paid) → no salary deduction
  • On-leave days (unpaid) → salary deducted for those days

Payroll Impact

When payroll is calculated for the month:

  • The engine reads the attendance data, which already contains the on_leave markers
  • For paid leave (is_paid = true): the employee gets full salary for those days
  • For unpaid leave (is_paid = false): those days are treated like absent days — salary is pro-rated

🖥️ The HR Admin View

HR managers have a separate admin console that shows all leave requests across the company. They can filter, search, approve, and reject from one screen.

Leave Requests Page — what HR sees

ColumnMeaning
EmployeeName and employee code
Leave TypeAnnual, Sick, Emergency, etc.
From / ToRequested dates
DaysNumber of calendar days requested
ReasonEmployee's note
StatusColour-coded badge — yellow = submitted, green = approved, red = rejected, grey = cancelled, blue = resumed
ActionsApprove / Reject buttons (only visible for "submitted" requests)

Filters available to HR

Leave Types Management

HR Admin can create, edit, and deactivate leave types from the Leave Types page. Key actions:

📆 End of Year — Carry Forward & Encashment

At the end of each calendar year, unused leave days need to be resolved. HRSanad supports two mechanisms:

🔁 Carry Forward

Unused days are moved to the next year's opening balance — up to the carry_forward_max limit set on the leave type.

Example: Employee has 8 days unused. Leave type allows carry forward of max 5 days → only 5 days move to next year. The remaining 3 days are forfeited.

💵 Encashment

Some companies allow employees to be paid cash for unused leave days instead of carrying them forward (or at final settlement).

When days are encashed, the balance records encashed += days, reducing the closing balance. The encashed amount is typically calculated as: basic_salary / 30 × days_encashed

💡 Carry forward expiry Carried-forward days can have an expiry date. If carry_forward_expiry_months is set to 3, any carried-forward days that are not taken within 3 months of the new year are automatically forfeited. This encourages employees to use their leave rather than hoard it.

🎬 Full Walkthrough — A Real Example

Scenario: Sara is an active employee. She joined 3 years ago. It's August 2026. She wants 5 days annual leave from 15–19 September.

  1. Sara checks her balance

    Sara logs into ESS. Her annual leave balance shows: 12.5 days available (8 months × 2.5 days accrued, minus 7.5 days she already took in March).

  2. Sara submits the request

    She selects: Leave Type = Annual, From = 15 Sep, To = 19 Sep, Reason = "Family holiday". She clicks Submit.

    The system checks: No overlap with existing leaves ✓ | Balance 12.5 ≥ 5 ✓ | 28 days advance notice given ✓

    Request saved: status = . Sara's available balance still shows 12.5 (not yet deducted).

  3. Manager receives the request

    Sara's line manager logs into the admin console. He sees Sara's request in yellow. He checks the team calendar — no other team member is off those dates. He clicks Approve.

  4. Balance deducted automatically

    The system deducts 5 days: taken += 5. Sara's balance drops from 12.5 to 7.5 days. Status changes to approved. Sara gets a notification.

  5. Leave dates arrive

    On 15–19 September, the TNA system marks Sara as on_leave (not absent) for all 5 days. She does not need to clock in.

  6. Payroll at end of September

    When payroll is calculated, the engine sees Sara had 5 days on_leave (paid). Annual leave is is_paid = true, so those 5 days count as full working days — no salary deduction. Sara receives her full September salary.

  7. October accrual

    At end of September, the cron job credits another 2.5 days. Sara's balance is now 10.0 days again.

🔌 API Quick Reference

Employee (ESS) endpoints

ActionMethodEndpoint
Check leave balanceGET/v1/ess/leave-balance
List active leave typesGET/v1/ess/leave-types
View my requestsGET/v1/ess/leave-requests
Submit a new requestPOST/v1/ess/leave-requests
Cancel my requestPOST/v1/ess/leave-requests/:id/cancel

HR Admin endpoints

ActionMethodEndpoint
List all requests (with filters)GET/v1/leave/requests
Get a single requestGET/v1/leave/requests/:id
Approve or Reject requestPOST/v1/leave/requests/:id/action
Cancel any requestPOST/v1/leave/requests/:id/cancel
Resume (early return)POST/v1/leave/requests/:id/resume
List leave typesGET/v1/leave/types
Create leave typePOST/v1/leave/types
Update leave typePATCH/v1/leave/types/:id
List entitlementsGET/v1/leave/entitlements
Create entitlementPOST/v1/leave/entitlements
View balancesGET/v1/leave/balances
Manual balance adjustmentPOST/v1/leave/balances/adjust
Trigger monthly accrualPOST/v1/leave/accrue
🔑 Access control ESS endpoints: any authenticated employee (own data only). HR admin endpoints: hr_admin, hr_officer, sysadmin. Line managers additionally have access to action (approve/reject) requests for their direct reports.

📌 Status Reference Card

StatusMeaningBalance ImpactWho Can Act Next
Waiting for a decision. Leave not yet confirmed. None — balance unchanged HR/Manager: Approve or Reject
Employee: Cancel
approved Confirmed. Employee is authorised to take this leave. Deducted: taken += days HR/Employee: Cancel
HR: Resume (if returns early)
rejected Denied. Employee cannot take this leave. None — balance unchanged Terminal state. Employee must submit a new request.
cancelled Withdrawn — either by employee or HR. If was approved: Restored taken −= days
If was submitted: no change
Terminal state.
resumed Employee came back before the end date. Partially restored: taken −= unused_days Terminal state.
HRSanad HRMS — How Leave Application Works Last updated: April 2026  |  Owner: Waheed Rahuman Kamaludeen