---
title: Approvals
order: 5
updated: 2026-07-12
---

# Approvals

Approvals are where a manager, HR, or owner acts on the things employees submit — leave applications, travel claims, and expense vouchers. There are two separate queues in two different screens, each on its own *Approvals* tab:

- **Leave approvals** live under *Human Resources → Attendance → Approvals*.
- **Expense approvals** (travel + vouchers) live under *Human Resources → Expenses → Approvals*.

Both queues only show what *you* are allowed to act on. Routing follows your firm's reporting hierarchy (who reports to whom) plus the approval permissions on your account — there is no separate "assign approvers" setting under [HR settings](/docs/human-resources/hr-settings). Every action is re-checked on the server, so what the buttons let you do is exactly what the backend will allow.

## Open the leave approvals queue

1. Open *Human Resources* in the sidebar and click *Attendance*.
2. Open the *Approvals* tab. The tab shows a small count badge of how many leaves are waiting on you.
3. Pending leave applications appear in a list titled *Pending Leave Approvals*.

The *Approvals* tab only appears at all if you are a firm administrator, hold *Approve Any User's Leave* (`attendence.approveAllUsersLeave`), or hold *Approve Junior Leave* (`attendence.approveLeave`) **and** have at least one person reporting to you. If none of those apply, the tab is hidden.

The list is loaded from pending leaves in your scope and then narrowed to only the rows you can actually approve — so someone else's pending leave that isn't yours to decide never clutters your queue. When there is nothing waiting, the tab shows an *All caught up* empty state.

## The pending-leave list

Each row shows:

- *Applicant* — the employee's name and `@username`.
- *Leave Type* — the type name, its short code, and a `· Unpaid` tag when the type is unpaid.
- *Dates* — a single date, or `from → to` for a multi-day leave.
- *Days* — the total leave days; a half-day shows a `(½)` marker.
- *Applied* — the date the application was submitted (`dd/mm/yy`).
- *Status* — a status pill; everything in this queue is `pending`.
- *View* — opens the leave detail.

Click *View* on any row to open the *Leave Application* detail modal, where the decision is made.

## Review a leave application

The *Leave Application* modal shows the full request: the status pill, a *Backdated* warning chip when the leave's start date is today or earlier, and then the applicant, leave type (name, code, paid/unpaid), dates, duration (including *Morning off* / *Evening off* for a half-day), the employee's reason, and the applied-on date. If the leave was already rejected or cancelled, the reason for that is shown too.

The action buttons at the bottom depend on your permissions for that specific leave — the buttons you don't have rights for simply don't render.

### Approve

Click *Approve*. This confirms the leave immediately (there is no second confirmation prompt). A *Leave approved* toast appears and the row leaves your queue.

Approving does real work behind the scenes — see [What approving a leave does](#what-approving-a-leave-does).

### Reject

Click *Reject*. A *Reject leave application* prompt opens asking for a *Reason for rejection*. The reason is **required** — the *Reject* button stays disabled until you type something, and the server independently rejects the request if the reason is missing. The applicant sees this note on their own leave detail. On success you get a *Leave rejected* toast.

### Cancel a leave

*Cancel Leave* appears when you have the right to withdraw a leave that is already `pending` or `approved` (it is not a rejection — it undoes a leave). A confirmation dialog opens first:

- For a future-dated leave, it simply asks you to confirm.
- For a **backdated** leave (start date today or earlier), the dialog warns that cancelling will **remove the on-leave attendance entries** for the past days — those days fall back to present/absent. See [Marking attendance](/docs/human-resources/marking-attendance).

Confirm to get a *Leave cancelled* toast. Cancelling also restores any comp-off days the leave had consumed.

### Edit

*Edit* appears only on a leave you own that is still `pending` (an approver editing someone else's leave is not offered here — reject it and let them re-apply). It reopens the *Apply for Leave* form pre-filled. See [Applying for leave](/docs/human-resources/applying-leave).

## What approving a leave does

Approving is not just a status flip. When you approve, the app:

- **Writes attendance records** for every working day in the leave range, marked `on_leave` (or `half_day` for a half-day application). Non-working days and holidays in the range are skipped automatically — a leave that spans a weekend or a firm holiday does not "spend" those days as leave.
- **Notifies the applicant** that their leave was approved.
- **Consumes comp-off balance** when the leave type is a comp-off type (code `COMP`/`COMPOFF`). If the employee doesn't have enough comp-off days banked, the server refuses the approval with an *Insufficient comp-off balance* message telling you how many were available versus needed. Fix the balance or reject instead.

Because these records are written at approval time, the working-day pattern and holidays configured in [HR settings](/docs/human-resources/hr-settings) determine exactly which days are consumed.

## Who can approve or cancel leave

Leave approval is a two-tier model, both re-enforced server-side:

- *Approve Junior Leave* (`attendence.approveLeave`) — approve or reject leaves of people **below you** in the reporting hierarchy (direct and indirect reports). Trying to act on someone who is not your junior is refused with a `403`.
- *Approve Any User's Leave* (`attendence.approveAllUsersLeave`) — approve or reject **any** user's leave firm-wide, regardless of hierarchy. This is the elevated HR grant.

Cancellation is split by whether the leave has started:

- *Cancel Junior's Future Leave* (`attendence.cancelApprovedLeave`) / *Cancel Any User's Future Leave* (`attendence.cancelAllUsersApprovedLeave`) — for leaves whose start date is still in the future.
- *Cancel Junior's Backdated Leave* (`attendence.cancelBackDateLeave`) / *Cancel Any User's Backdated Leave* (`attendence.cancelAllUsersBackDateLeave`) — for leaves whose start date is today or in the past.

The "Junior" variants require the target to be inside your reporting subtree; the "Any User" variants are firm-wide. Separately, you can always cancel **your own** still-`pending` leave, at any date, as an escape hatch. Firm administrators bypass all of these checks. A leave can only be cancelled while it is `pending` or `approved`; a rejected or already-cancelled leave cannot be cancelled again.

## Open the expense approvals queue

1. Open *Human Resources* in the sidebar and click *Expenses*.
2. Open the *Approvals* tab (the tab also carries a pending-count badge). Its header reads *Pending Approvals*.

This tab appears only when you have people reporting to you **and** are either a firm administrator or hold *Approve Expense* (`expense.approveExpense`). If you have nobody under you, the tab is hidden entirely — there is nothing for you to approve. See [Logging expenses](/docs/human-resources/log-expense) for how employees create these entries.

## The pending-expense list

Two things sit above the list:

- An *employee filter* dropdown — only shown if you can view others' expenses (*View All Expenses*, `expense.viewAllExpenses`, or admin). *All Employees* shows everyone in your team; pick a name to narrow to one person.
- Three filter buttons — *All*, *Travel*, and *Vouchers* — each showing a live count of pending items of that kind.

**Scope matters:** the expense queue is limited to your **downline** — yourself plus everyone under you in the reporting hierarchy. There is deliberately no firm-wide view here; even an administrator only sees their own subtree, and you can never see a peer's or an unrelated person's claims. *View All Expenses* widens you from "just me" to "my whole team" and unlocks the employee filter.

Travel rows show *Date*, *Employee*, *Route* (the chain of stops), *KM* (total distance), and *Cost ₹* (the calculated reimbursement). Voucher rows show *Date*, *Employee*, *Title*, *Category*, and *Amount ₹*. Each row has a *View* button that opens the review modal.

## Review a travel claim

*View* on a travel row opens the *Travel Entry* modal. It lays out:

- **Employee** — name and `@username`.
- **Trip Details** — the date of travel and the number of stops.
- **Cost Breakdown** — total kilometres, the *Rate/km* that applied (shown only when the mode of transport is own vehicle and a petrol rate applied), and the *Reimbursable* total in ₹.
- **Route** — a timeline of every stop with its arrival/departure times, any remark, and the distance to the next stop.
- **Rejection Reason** and **Notes** cards appear only when those fields are set.

If you can approve and the entry is still `pending`, a menu (the `⋮` button, top-right) offers:

- *Approve* — "Approve and credit to employee ledger." Applies immediately and shows a *Travel entry approved* toast. The approved amount then appears as a debit on the employee's expense ledger.
- *Reject* — opens the *Reject Travel Entry* prompt for a required reason (which the employee will see), then shows *Travel entry rejected*.

The petrol rate on a travel claim is frozen at the time it was logged, so the figure you approve is exactly what the employee saw — see [Logging expenses](/docs/human-resources/log-expense).

## Review a voucher

*View* on a voucher row opens a modal titled with the voucher's own title (vouchers cover non-travel spend — office supplies, courier, refreshments, and so on). It shows:

- **Voucher Details** — date, category, and invoice number.
- **Employee** — name and `@username`.
- **Amount** — the claimed amount in ₹.
- **Description** and **Rejection Reason** cards when present.
- **Attachments** — any receipts uploaded with the voucher. Click *View* on a file to open it; the file streams down on demand rather than being embedded in the page.

The `⋮` menu (shown when you can approve a `pending` voucher) offers:

- *Approve* — "Approve and add to employee ledger." Shows a *Voucher approved* toast, notifies the employee, and posts the amount to their ledger.
- *Reject* — opens the *Reject Voucher* prompt for a required reason, then shows *Voucher rejected*.

## Who can approve expenses

A single permission governs both travel and voucher decisions:

- *Approve Expense* (`expense.approveExpense`, or firm administrator) — approve or reject pending travel entries and vouchers. This is what the backend checks on every approve/reject call.

Both actions also require the entry to still be `pending`; the server refuses to approve or reject anything already approved, rejected, or paid. Rejection always requires a reason.

## Common questions

### Why do I see no pending approvals?

Either there genuinely are none, or nobody whose applications are in flight falls within your approval scope. Leave approvers only see leaves of their juniors (or everyone, with *Approve Any User's Leave*); expense approvers only see their own downline. The queues also hide entirely if you have nobody reporting to you and lack the firm-wide grants.

### Can I bulk-approve?

No. Approvals are processed one at a time. This is deliberate so a rejection can always carry a specific reason and each amount or leave range gets a real look.

### Do I have to give a reason when rejecting?

Yes. Every rejection — leave, travel, or voucher — requires a *Reason for rejection*. The *Reject* button is disabled until you type one, and the server independently rejects the call if the reason is empty. The employee sees the reason on their own copy of the record.

### What if I approved a leave by mistake?

Use *Cancel Leave* on the leave detail, provided you have a cancellation permission for that leave (or are an administrator). Cancelling an already-started (backdated) leave removes the on-leave attendance entries it created and restores any comp-off it consumed. See [Who can approve or cancel leave](#who-can-approve-or-cancel-leave).

### Why did approving a week-long leave only mark a few days?

Approval writes leave attendance only for **working days**, and skips holidays. Weekends and firm holidays inside the range are not counted as leave. The working-day pattern and holiday list come from [HR settings](/docs/human-resources/hr-settings).

### An employee's claim isn't in my expense queue — why?

The expense queue only covers your reporting downline. If the person doesn't report to you (directly or indirectly), their travel and vouchers won't appear, even with *View All Expenses* — that permission widens you to your whole team, not the entire firm. Ask whoever the person reports to, or a firm administrator.

### Where does an approved expense end up?

Approved travel and vouchers post to the employee's reimbursement ledger as a debit, ready to be paid. See [Logging expenses](/docs/human-resources/log-expense) for the ledger and *Pay Balance* flow.
