---
title: Logging expenses
order: 6
updated: 2026-07-12
---

# Logging expenses

The *Expenses* screen is where the firm's money-in-and-out for each employee lives: travel that earns a per-kilometre allowance, vouchers for out-of-pocket spends, the running reimbursement ledger, and the approval queue that gates it all. The page header reads *Expenses* with the subtitle *Travel allowance, vouchers, and reimbursement ledger.*

Everything you submit here goes through an approval step before it counts against a balance, and the backend re-checks every rule the screen hints at — receipt requirements, edit windows, who is allowed to see or approve whose entries — so a forged request can't slip a bad claim onto the ledger.

## Open the screen

1. Open *Human Resources* in the sidebar.
2. Click *Expenses*. The page opens with tabs across the top.

The active tab is stored in the address bar (`?tab=…`), so a deep link from the dashboard or a bookmark lands you on the right tab. If the tab named in the URL isn't one you're allowed to see, you fall back to the first visible tab.

## The tabs

Which tabs appear depends on your permissions and whether anyone reports to you. Tabs you can't use are hidden entirely, not just disabled.

- *Dashboard* — a team-wide spend overview. **Only appears if you have people reporting to you.** See [The Dashboard tab](#the-dashboard-tab).
- *Ledger* — the running list of claims, payments, and advances for a date range. Needs *View own ledger* (`expense.viewOwnLedger`) or *View all ledgers* (`expense.viewAllLedgers`) — or firm-admin. See [Read your ledger](#read-your-ledger).
- *Travel* — log trips that earn a per-kilometre allowance. Needs *Log travel* (`expense.logTravel`) or *View own expenses* (`expense.viewOwnExpenses`).
- *Vouchers* — log non-travel expenses with an optional receipt. Needs *Log voucher* (`expense.logVoucher`) or *View own expenses* (`expense.viewOwnExpenses`).
- *Approvals* — pending travel and vouchers waiting on your decision. **Only appears if you have subordinates *and* the *Approve expense* permission** (`expense.approveExpense`) — or firm-admin. The tab shows a live count badge of pending travel + voucher entries. See [Approvals](#approvals).

See [Who can do what](#who-can-do-what) for the full permission map.

## Log a travel claim

1. Open the *Travel* tab.
2. Click *Log Travel* (top-right, or the *Log Travel* button on the empty state). The *Log Travel* modal opens. The button only shows if you hold *Log travel* or are an admin.
3. Fill the modal (below) and click *Submit for Approval*.

The claim appears in the *Travel* list with a *Pending* status until an approver acts on it. The app logs every trip as an **own-vehicle** trip, so the distance you enter is what gets reimbursed at the firm's petrol rate.

### Date of travel

A date picker, defaulting to today. For a new claim the range is clamped by the firm's edit window (see [The edit window](#the-edit-window)):

- The latest selectable date is **today** — you can't log a future trip.
- The earliest selectable date is `today − (window − 1)` days when a window is set. With no window configured, older dates are allowed.

In *Edit Travel* mode the date is shown read-only with the note *Date cannot be changed after submission.* — you're correcting *what* happened that day, not *when*.

### Stops (the route)

Add your stops one row at a time. Each stop row has:

- *Arrived* — a time field (`HH:MM`). Required on every stop.
- *Location* — free text, required (server limit `200` characters).
- *Departed* — a time field (`HH:MM`). Required on every stop.
- *Remark* — optional free text for that stop.

Rules the modal enforces (and the backend re-checks):

- **At least two stops** are required — a trip needs a start and an end.
- The **first stop can't be removed**; other stops can be removed with the trash button, but you can never drop below two.
- Add more stops with *Add Another Stop*.
- Every stop must have a location, an arrival time, and a departure time before *Submit for Approval* enables.

**Fixed start location.** If your firm has configured a fixed start location under [HR settings → Travel Location](/docs/human-resources/hr-settings), the first stop is **pre-filled and locked** (an info icon on the *Location* header explains why). The backend rejects any travel whose first stop doesn't match the firm's configured start location (case-insensitive), so you can't work around the lock by forging a payload.

### Distance between stops

Between each pair of consecutive stops sits a *km* number field: the distance travelled on that leg.

- Minimum `0`, entered to up to `2` decimal places.
- There is always exactly one distance per leg. The server rejects the claim unless the number of distances equals the number of stops minus one.

### Estimated reimbursement

A summary card shows the *Estimated Reimbursement* — the sum of all leg distances multiplied by the current *Petrol Rate*. It also shows the total kilometres and the `₹ …/km` rate in use. If no petrol rate is configured you'll see *No petrol rate set* and the estimate stays `₹0.00`.

The rate is set firm-wide under [HR settings → Petrol Rate](/docs/human-resources/hr-settings). When you submit, the backend **freezes** the petrol rate that applied on the travel date onto the entry (`appliedPetrolRate`) and stores the calculated cost — so later rate changes never retroactively alter an already-filed claim, and editing an entry re-freezes the rate for its (possibly new) date.

### Notes

An optional free-text *Notes* box for meeting details, client visits, and so on.

### Submitting and editing

Submitting creates the entry with *Pending* status. From the *Travel* list you can *Edit* or *Delete* an entry, subject to these rules (all re-enforced server-side):

- **Edit** is available on a *Pending* entry to its owner (and to admins / holders of *Edit any expense*). A *Rejected* entry can be edited to fix and resubmit.
- **Delete** is available only on a *Pending* entry, and only to the owner or an admin.
- A *Pending* entry can only be edited **while it's still inside the edit window**. Once it ages past the window it's frozen — a reviewer has to reject it before it can be corrected and resubmitted.
- On a *Rejected* entry the **date is locked** (fix the details and resubmit; you can't change the day).
- Editing an *Approved* entry reverts it to *Pending* and is restricted to admins / *Edit any expense*.

## Log a voucher

1. Open the *Vouchers* tab.
2. Click *Add Voucher*. The *Add Voucher* modal opens (the button shows only if you hold *Log voucher* or are an admin).
3. Fill the modal (below) and click *Submit Voucher*.

The voucher appears with a *Pending* status. Submitting a voucher notifies approvers in the firm.

### Category

A grid of category cards. Pick one — the first category is selected automatically for a new voucher. Each card notes whether it needs a receipt: *Receipt required* or *No receipt*.

If no categories exist yet you'll see a prompt to *Ask HR to add them in HR Settings → Expense Categories.* Categories are managed on the [HR settings](/docs/human-resources/hr-settings) screen; the voucher form only reads the active ones. The backend rejects a voucher whose category is missing or inactive.

### Date and amount

- *Date* — defaults to today, clamped to the same edit-window range as a travel claim (no future dates; earliest is `today − (window − 1)`). Locked and read-only in *Edit Voucher* mode.
- *Amount (₹)* — required, must be **greater than zero** (the server rejects zero or negative amounts).

### Title and invoice number

- *Title* — required. Server limit `100` characters.
- *Invoice Number (optional)* — server limit `50` characters. Shown in the voucher list and approval view; leave blank if there's no invoice.

### Attachments and the receipt rule

A drag-and-drop (or click-to-browse) zone. Each file may be up to `50 MB`; oversized files are rejected with a toast. Files that duplicate one you already added (same name and size) are skipped.

Whether an attachment is *required* depends on the chosen category:

- If the category is marked *No receipt*, attachments are optional.
- If the category **requires a receipt**, a receipt is required **only when the amount exceeds the category's no-receipt threshold** (`maxAmountWithoutReceipt`). Below or at that threshold you can submit without a file. Above it, *Submit Voucher* stays disabled until you attach at least one file, and the backend independently blocks the save with *Category '…' requires a receipt for amounts above ₹…*.

In *Edit Voucher* mode, existing attachments are listed with a *View* button (streams the file) and an *X* to remove them; new files can be added at the same time.

### Description

An optional free-text *Description* box for extra context.

### Editing rules

- **Edit** and **Delete** are offered from the voucher's *View* modal (as menu actions) when your permissions allow. Editing is limited to *Pending* or *Rejected* vouchers for the owner (admins / *Edit any expense* can do more).
- A **paid** voucher can never be edited.
- Editing an *Approved* voucher reverts it to *Pending* (re-approval needed) and is restricted to admins / *Edit any expense*.
- The same edit-window and rejected-date-lock rules as travel apply.

## The Travel tab

Beyond the *Log Travel* button, the *Travel* tab is a full trip register:

- **Stat cards** across the top: *Spent this month*, *Distance this month*, *Working days this month*, and *Travel · <financial year>* (total spend + km). The month cards open a spend/distance calendar; the FY card opens a month-by-month breakdown.
- *Analytics* button — a calendar-plus-cards analytics modal for the selected employee and year.
- **Financial-year picker** — filters the list and the FY stat card. The current year is marked *(current)*; an *All* option spans every year.
- **Employee picker** — appears only if you can view others (*View all expenses* `expense.viewAllExpenses` or admin). Choose *All Employees*, yourself *(me)*, or a specific person. When *All Employees* is selected an extra *Employee* column appears in the table.
- **Table** columns: *Date*, *Route* (the chain of stops), *KM*, *Cost ₹*, *Status*, and row actions (*Edit* / *Delete* where permitted, and *View*).

Viewing others is **hierarchy-scoped**: you only ever see the travel of people in your own reporting line — there is no firm-wide view, even for admins.

## The Vouchers tab

- Two summary cards: *Pending Approval* (sum of pending voucher amounts) and *Approved Total* (approved + paid).
- The same **financial-year** and **employee** pickers as the Travel tab (the employee picker again needs *View all expenses* or admin, and is hierarchy-scoped).
- **Table** columns: *Date*, *Title*, *Category*, *Invoice #*, *Amount ₹*, *Status*, and a *View* action. *View* opens the voucher detail, from which edit / delete / approve actions appear based on your permissions and the voucher's status.

## Read your ledger

The *Ledger* tab is the running account for one employee (or your whole team) over a date range — approved travel and vouchers as debits, payments and salary as credits.

### Employee and date range

- **Employee picker** — appears only if you hold *View all ledgers* (`expense.viewAllLedgers`) or are an admin. Options are *All Employees*, yourself *(me)*, and each team member. Defaults to you. As with the other tabs, this is hierarchy-scoped to your downline; even admins don't get a firm-wide roll-up here.
- **From / To date pickers** — the display window, defaulting to the current Indian financial year (`1 Apr` → `31 Mar`). Both are stored in the URL, so a filtered ledger is shareable.

### Filters

The *Filters* button opens the *Ledger Filters* modal:

- *Entry Types* — three toggles: *Travel* (approved trips), *Vouchers* (claimed expenses), *Payments* (paid & received). All three are on by default. *Payments* covers advances, balance payments, and salary earned/paid. At least one type must stay selected (*Apply Filters* disables otherwise).
- *Voucher Categories* — appears only when *Vouchers* is selected and categories exist. Leave everything unchecked to include all categories; check some to narrow to just those.
- *Only entries with attachments* — restricts to travel and voucher rows that carry at least one file.

The button shows a small count of how many non-default filters are active.

### Net balance (Dr / Cr)

A prominent card shows the net balance for the chosen scope and range:

- **`Dr`** (green) — the firm owes this employee (unreimbursed claims outstanding).
- **`Cr`** (red) — the employee owes the firm (an advance is outstanding).
- No suffix — fully settled (within half a paisa of zero).

For *All Employees* the card shows an aggregated figure and hides per-row running balances.

### The ledger table

Columns: *Sr*, *Date*, *Employee* (only in the all-employees view), *Particulars* (with a paperclip icon when the entry has attachments), *Debit ₹*, *Credit ₹*, *Balance ₹* (hidden in the all-employees view), and a per-row *View* action. The list loads 50 rows at a time and pages in older entries as you scroll.

*View* opens the right detail for the row: the travel or voucher approval/detail modal, a payment or advance detail, or — for a salary row — the salary breakdown for that month (see [Attendance & salary](/docs/human-resources/attendance)).

### Export CSV

*Export CSV* downloads the current ledger (respecting the type, category, attachment, and date filters). It requires *Export expense report* (`expense.exportExpenseReport`) or admin, and works on a **single employee only** — pick a specific person first; it's disabled for *All Employees*.

## Record a payment (Pay Balance)

When a balance is outstanding, users with *Record payment* (`expense.recordPayment`) or admin see a *Pay Balance* button on the ledger's net-balance card (hidden in the all-employees view). It opens the *Payment Done On* modal:

- **Suggested amount** — the current net balance is pre-filled (never negative).
- *Date* — defaults to today. **Future dates are rejected** by the server.
- *Amount (₹)* — required, greater than zero. It can be **more** than the balance (recording an advance) or **less** (a partial payment).
- *Message (optional)* — e.g. a cheque number or transfer note (server limit `500` characters).
- *Proof of Payment* — **at least one attachment is required** (max `50 MB` per file). The backend refuses a payment with no valid attachment, so this can't be skipped by forging the request.

*Record Payment* posts the payment; it immediately shifts the employee's ledger balance.

## Approvals

The *Approvals* tab (visible only to reviewers with subordinates and *Approve expense*) lists pending travel and vouchers so you can clear them before they hit the ledger.

- Sub-filter buttons — *All*, *Travel*, *Vouchers* — each showing a count.
- An **employee picker** (needs *View all expenses* or admin) to focus on one person.
- *View* opens the entry's approval modal, where an actions menu offers **Approve** or **Reject**.
- **Reject requires a reason** — a prompt captures it and the employee sees it on their entry. The server refuses a rejection with no reason.
- You **cannot approve your own** travel or voucher — the approve/reject actions are withheld when the entry is yours.
- Only *Pending* entries can be approved or rejected; the server blocks acting on anything already decided.

Approving a travel entry credits it to the employee's ledger; approving a voucher adds it as a debit. Approver routing follows your **reporting structure** (who reports to whom) plus the approval permission — it is not a setting under HR settings. For the step-by-step approve/reject flow (shared with leave approvals) see [Approvals](/docs/human-resources/approvals).

## The Dashboard tab

For anyone with subordinates, the *Dashboard* tab is a spend overview of the team:

- A **financial-year picker**.
- Six KPI cards: *Total*, *Vouchers*, and *Travel*, each for the selected FY and for the current month. Clicking a card deep-links into the *Ledger* tab (All Employees) pre-filtered to that period and type.
- *Travel this month* — distance and petrol per team member, with its own month picker; click a row for that person's travel analytics.
- *Vouchers by category* — this month's vouchers grouped by category, with its own month picker; click a row to open the ledger filtered to that category and month.

## The edit window

The firm's *Expense edit window (days)* setting (on the [HR settings](/docs/human-resources/hr-settings) *General* tab) controls how far back travel and vouchers can be dated and edited:

- **Empty / unset (the default)** — no restriction; any past date is allowed.
- A number `N` — submissions and edits are allowed for `today` and the previous `N − 1` days. A value of `1` means *today only*.
- Future dates are **never** allowed regardless of the setting.

Admins and holders of *Edit any expense* (`expense.editAnyExpense`) bypass the window entirely. When a pending entry ages out of the window it becomes uneditable and must be rejected before it can be corrected and resubmitted.

## Who can do what

All of these live under the *Expense* permission group on a user's account. Dependencies mean the parent permission must also be granted.

- *View own expenses* (`expense.viewOwnExpenses`) — see your own travel and vouchers.
- *Log travel* (`expense.logTravel`) — create travel entries. Needs *View own expenses*.
- *Log voucher* (`expense.logVoucher`) — submit vouchers. Needs *View own expenses*.
- *View all expenses* (`expense.viewAllExpenses`) — see travel and vouchers of others in your reporting line (drives the employee pickers). Needs *View own expenses*.
- *Approve expense* (`expense.approveExpense`) — approve/reject pending entries. Needs *View all expenses*.
- *Edit any expense* (`expense.editAnyExpense`) — bypass the edit window and approval lock; edit any entry regardless of age or status. Needs *View all expenses*. Reserved for finance admins.
- *View own ledger* (`expense.viewOwnLedger`) — see your own reimbursement ledger.
- *View all ledgers* (`expense.viewAllLedgers`) — see any team member's ledger. Needs *View own ledger*.
- *Record payment* (`expense.recordPayment`) — record payments against a balance. Needs *View all ledgers*.
- *Export expense report* (`expense.exportExpenseReport`) — export ledger/travel/voucher data as CSV. Needs *View all ledgers*.

Managing petrol rate, expense categories, and the fixed travel location is done on the [HR settings](/docs/human-resources/hr-settings) screen, not here.

## Common questions

### Why is the petrol rate fixed?

It's set firm-wide under *HR Settings → Petrol Rate* so every travel claim uses the same calculation. When you submit a trip, the rate that applied on that date is frozen onto the entry. Later rate revisions apply only to trips logged on or after their effective date; older entries keep the rate they were filed with. See [HR settings](/docs/human-resources/hr-settings).

### Can I edit a claim after submitting?

Yes, while it's *Pending* (and inside the edit window) or *Rejected*. The travel modal has an *Edit Travel* mode and the voucher modal an *Edit Voucher* mode. In both, the **date cannot be changed** after submission. A pending entry that has aged past the edit window is frozen until a reviewer rejects it; a paid voucher can't be edited at all.

### Why can't I log a trip for last week?

Your firm has set an *Expense edit window* that only allows dates within the last few days (and never future dates). Ask HR to widen the window, or ask an admin (who bypasses it) to log the older entry. See [The edit window](#the-edit-window).

### Do I need to attach a receipt to a voucher?

Only if the category requires one **and** the amount is above that category's no-receipt threshold. Below the threshold, or for *No receipt* categories, attachments are optional. The rule is enforced on the server too, so it can't be bypassed.

### Why can't I see other employees' expenses or ledgers?

You need *View all expenses* (for travel/vouchers) or *View all ledgers* (for the ledger). Even with those, the view is scoped to your own reporting line — there's no firm-wide roll-up, and admins are scoped to their downline too.

### What does Dr / Cr mean on the balance?

`Dr` (debit balance) means the firm owes the employee — unpaid claims are outstanding. `Cr` (credit balance) means the employee owes the firm — an advance is still outstanding. No suffix means the account is settled.

### Where does my receipt file go?

Attached receipts (and payment proofs) are stored against the entry and are visible to your approver and anyone reviewing it. Files stream on demand via the *View* button; there's a `50 MB` per-file limit.

### Why don't I see the Approvals or Dashboard tab?

Both require that people report to you. *Approvals* additionally needs the *Approve expense* permission (or admin); *Dashboard* just needs subordinates. If nobody reports to you, neither tab appears.
