---
title: Staff report (HR)
order: 6
updated: 2026-07-12
---

# Staff report (HR)

The *HR* tab on the dashboard turns the work your team already does — entering enquiries, sending quotes, recording deliveries, marking attendance — into a per-employee picture of quality, speed, and discipline. Nothing extra to fill in: every number is computed from data your staff already create, and everything reacts to the *From* / *To* date range at the top of the dashboard.

It is deliberately a *soft* view of your team. The headline "productivity index" grades data-entry quality and clerical speed, and the tab always shows the raw numbers next to it so you read the score in context rather than treating it as a hard grade. Attendance, throughput, and money-out figures are shown for reference and are **not** part of the grade.

## Open the HR report

The HR tab lives inside the main dashboard, not on a separate page.

1. Open the *Dashboard*.
2. In the tab strip under the firm header, pick *HR* (the people icon).
3. The *Team leaderboard* opens by default. Click any employee row to drill into their scorecard; use *Team* (top-left, the ← chevron) to come back.

### Who can see it

The tab only appears if you hold the *HR Report (detailed)* permission (`dashboard.hrReport`), and that permission itself depends on *Dashboard* view access (`dashboard.view`). Both endpoints behind the tab — the data call and the PDF — re-check **both** permissions on every request, so the tab can't be reached by anyone who lacks them even if the request is forged. This is owner / HR data.

- No dashboard access at all → you land on a plain "HELLO" greeting page instead of the dashboard.
- Dashboard access but no *HR Report (detailed)* → the *HR* tab is simply not in the strip.

### The date range

Both views obey the shared *From* / *To* pickers in the dashboard header. The picker defaults to the current calendar month. Notes on how the window is applied:

- *From* is taken at the **start** of that day (`00:00:00`) and *To* at the **end** of that day (`23:59:59.999`).
- If you pick a *From* later than the current *To*, the *To* snaps to match (and vice-versa) — the range can never invert.
- The server rejects a range whose ends aren't positive numbers, where start is after end, or that spans **more than 3 years** (`366 × 3` days). An invalid range returns an error instead of a report.
- Results are cached in your browser per `employee + date-range` for the session, so flipping back to a range you already viewed is instant. There is no firm-wide "Updated …" snapshot here (unlike the [Sales report](/docs/reports/sales-report)) — each new range is calculated live.

## Team leaderboard

The default view: firm-level KPIs, a band-distribution donut, and a ranked table of every active employee. It is what the PDF prints when no employee is selected.

An employee is "active" for the period — and therefore appears — only if they have **some** signal in the window: at least one enquiry created, one delivery recorded, one quote sent, or any attendance day marked (present, half-day, absent, or on-leave). Staff who have been deleted from the firm are always excluded, even if they created records during the period.

### Firm overview KPIs

Four tiles summarising the whole team for the selected range.

#### Scored staff

The number of employees who had **enough activity to earn a productivity index** (at least one pillar met its minimum sample size — see [The productivity index](#the-productivity-index)). Someone can appear on the leaderboard with an index of `—` and still not be counted here.

#### Avg index

The mean productivity index (`0`–`100`) across staff who have one. Employees whose index is `—` are left out of the average, so it never invents a number.

#### Avg quick-fix

The average *quick-fix rate* across staff — the share of enquiries re-edited within minutes of first save (the "typed it wrong, corrected it twice" churn). Shown as a percentage; higher is worse.

#### Avg attendance

The average present-day rate across staff, where half-days count as `0.5`. Shown as a percentage. Context only — attendance is not graded.

### Productivity bands

A donut showing how the team spreads across the four bands — *Excellent*, *Good*, *Fair*, *Needs attention*. Slices are coloured green → indigo → amber → red in that order, and a slice only renders when at least one employee falls in it. The centre reads *Staff*. Employees whose index is `—` (too little data to score) are in the leaderboard but appear in **no** band slice.

### The leaderboard table

Every active employee, ranked by productivity index (highest first; an `—` index sorts to the bottom). The on-screen table shows up to the **top 50**; the PDF prints the top 30. Click a row's *Employee*, *Index*, or *Band* cell to open that person's scorecard.

Columns:

- *Employee* — the person's full name (first + last). Clickable — drills in.
- *Index* — the `0`–`100` productivity index, rounded. `—` when there isn't enough data in any pillar.
- *Band* — a coloured chip: *Excellent*, *Good*, *Fair*, or *Needs attention* (or `—`).
- *Quality* — the quality pillar sub-score (`0`–`100`), or `—`.
- *Quote* — the quote-speed pillar sub-score (`0`–`100`), or `—`.
- *Enquiries* — count of enquiries this person created in the window.
- *Deliveries* — count of deliveries this person recorded in the window.
- *Quotes* — count of quotations this person sent in the window.
- *Att %* — attendance rate for the window, or `—` if no working days were marked.

> The on-screen leaderboard shows the *Quality* and *Quote* sub-scores but not the *Delivery speed* sub-score — open the employee's scorecard to see all three pillars. (The PDF leaderboard does include a *Deliv* sub-score column.)

## Employee scorecard

Click any leaderboard row (or generate the PDF with an employee selected) to open the full scorecard. The toolbar shows a coloured band chip, the person's name, their *Index /100*, and their role; *Team* returns to the leaderboard.

If the employee you open had **no** activity in the window, the card still renders with every metric at `—` / `0` rather than erroring.

### Productivity pillars

Three tiles — the same pillars that make up the index — each a `0`–`100` sub-score:

- *Quality* — how clean their fresh data entry was. `100` = clean first entry, no quick re-fixes and no senior clean-ups. `—` until they created at least `3` enquiries in the window.
- *Delivery speed* — how quickly a completed delivery is recorded after its delivery date. `≤ 1 day` = `100`. `—` until at least `2` deliveries (with a delivery date) fall in the window.
- *Quote speed* — how quickly an enquiry is turned into a sent quote. `—` until at least `2` quotes (with a computable turnaround) fall in the window.

The block subtitle also restates the raw counts: *N enquiries · N deliveries · N quotes*.

### Raw metrics

The un-graded numbers behind the pillars, so you can sanity-check the score:

- *Avg edit churn* — average number of post-creation edit versions per enquiry they created. Higher means a sloppier first entry. `—` with no enquiries.
- *Quick-fix rate* — share of their enquiries re-edited within **30 minutes** of first save (typo churn). Percentage.
- *Senior-fix rate* — share of their enquiries a **different** user had to come back and correct. Percentage. A stronger "sloppy first entry" signal than quick-fix.
- *Avg delivery lag* — average days between a delivery's picked delivery date and when it was actually uploaded into the system. Shown as `N.N d`.
- *Avg quote turnaround* — average days from an enquiry's creation to the quote being sent. Shown as `N.N d`.
- *Expenses ₹* — the employee's **approved or paid** expense vouchers whose voucher date falls in the window. Context for the HR money-out view.
- *Advance o/s ₹* — their currently **open** (unsettled) advances. This is a *live* outstanding figure — it is **not** filtered by the date range, so it reflects what they owe right now regardless of the period you're viewing.

### Attendance

Four tiles built from the employee's marked attendance days in the window (holidays and weekends are not counted as working days and are ignored):

- *Attendance* — the present-day rate: `(present + 0.5 × half-days) ÷ (present + half-days + absent)`, as a percentage. `—` if no working days were marked. Approved leave is **not** in the denominator, so being on approved leave never lowers the rate.
- *Present* — days marked present.
- *Absent* — days marked absent.
- *On leave* — days on approved leave (shown for context; excluded from the rate).

See [Marking attendance](/docs/human-resources/marking-attendance) and [Attendance](/docs/human-resources/attendance) for how these days are recorded.

### Recent activity tables

Three breakdown tables, each showing the **25 most recent** matching records for that employee (newest first).

#### Recent enquiries

Enquiries this person created, with the quality signals per row:

- *Customer* — the enquiry's customer name (`—` if unresolved).
- *Created* — the date the enquiry was created (`dd/mm/yy`).
- *Edits* — how many post-creation edit-log versions the enquiry has.
- *Quick-fix* — `Yes` if it was re-edited within 30 minutes of first save, else `—`.
- *Senior-fix* — `Yes` if a different user corrected it, else `—`.
- *Capture lag* — days between the enquiry's own date and when it was entered (`N.N d`; `—` when the enquiry carries no date).

#### Recent deliveries

Deliveries this person recorded, focused on recording lag:

- *Customer* — resolved from the delivery's sales order (`—` if the delivery has no resolvable order).
- *Delivered on* — the delivery date they picked (`—` if none).
- *Uploaded on* — when the delivery was actually saved into the system.
- *Recording lag* — days between *Delivered on* and *Uploaded on* (`N.N d`).
- *Items* — number of product lines on the delivery.

Right-click a row (where the delivery resolves to an order) for *Open sales order*, which deep-links to that [sales order](/docs/enquiry-bank/orders).

#### Recent quotes

Quotations this person sent, focused on turnaround:

- *Customer* — the enquiry's customer name.
- *Sent on* — the date the quotation was sent (`dd/mm/yy`).
- *Turnaround* — days from the enquiry's creation to this send (`N.N d`).

## The productivity index

The index is a single `0`–`100` soft score per employee. It is deliberately *not* an A–D letter grade: it grades people, from noisier signals than the [vendor scorecard](/docs/reports/vendor-scorecard), so the wording is gentle and the raw numbers always sit beside it.

### Bands

The index rounds into four soft bands:

| Band | Index |
|---|---|
| *Excellent* | `75`–`100` |
| *Good* | `55`–`74` |
| *Fair* | `40`–`54` |
| *Needs attention* | `0`–`39` |

An employee with no scoreable pillar shows band `—` (not *Needs attention*).

### How the index is blended

Three pillars, each a `0`–`100` sub-score, combined with fixed weights:

| Pillar | Weight | What it measures |
|---|---|---|
| *Quality* | `40%` | How clean their data entry is — quick re-fixes and senior clean-ups on the enquiries they created. |
| *Delivery speed* | `30%` | How quickly a completed delivery is **recorded** after its delivery date. |
| *Quote speed* | `30%` | How quickly an enquiry is turned into a **sent quote**. |

The index is a weighted average of whichever pillars the employee has. If a pillar is `—` (insufficient data), it drops out and the remaining weights **re-balance** — the index is computed only over the pillars that have a number, and never invents one. If **no** pillar qualifies, the index (and band) is `—`.

The index is non-zero-sum by design: a uniformly strong team can all score well. It is not a forced ranking curve.

### Quality pillar

Built from two creation-anchored signals on the enquiries a person **created** — both drawn from the tamper-proof enquiry edit log (every edit is a versioned snapshot stamped with who edited it and when, which a "lazy worker" can't quietly undo):

- *Quick-fix rate* — the fraction of their enquiries re-edited within **30 minutes** of first save. A genuine price revision days later is deliberately **not** counted — only the rapid churn near first entry.
- *Senior-fix rate* — the fraction a *different* user had to come back and correct.

The score is `100 × (1 − defect)`, where `defect = min(1, quickFixRate + 0.5 × seniorFixRate)`. So a senior clean-up hurts, but at half the weight of a quick-fix. Requires at least `3` enquiries created in the window; below that the pillar is `—`.

### Delivery speed pillar

A soft curve on the *average delivery recording lag* (days between the picked delivery date and the upload). Anything at or under a `1`-day grace scores `100`; the score then falls linearly to `0` over the next `7` days — so an average lag of `8` days or more scores `0`. Requires at least `2` deliveries (with a delivery date) in the window.

### Quote speed pillar

The same soft-curve shape on the *average quote turnaround* (enquiry creation → quote sent). A `1`-day grace scores `100`, falling linearly to `0` over the next `14` days — so an average turnaround of `15` days or more scores `0`. Requires at least `2` quotes (with a computable turnaround) in the window.

> **Why soft curves, not hard cutoffs?** These are *clerical* speeds — recording a delivery you already made, turning an enquiry into a quote — where item complexity barely matters, so a normal day or two costs nothing. Unlike supplier lead times they aren't normalised per item. (A refinement for genuinely complex enquiries with longer legitimate quote turnaround is noted for a future version.)

## Where the numbers come from

Everything is gathered firm-wide for the period and attributed to the employee stamped on each record — so you can't inflate someone else's numbers, and a forged payload can't slip a fake user in (the drill-down user is validated to exist and not be deleted, or the request is rejected).

- **Enquiries created / quality / capture lag** — enquiries whose creation date is in the window, attributed to their *createdBy*. Edit signals come from the edit-log versions of exactly those enquiries.
- **Quotes / turnaround** — enquiries whose offer-send date is in the window; each send is attributed to the user who **sent** that offer (not necessarily the enquiry's creator). Turnaround is measured from the enquiry's creation to the send.
- **Deliveries / recording lag** — deliveries whose upload date is in the window, attributed to *deliveredBy*.
- **Attendance** — attendance records dated in the window, grouped by user and status.
- **Expenses** — expense vouchers dated in the window with status *approved* or *paid*.
- **Advances** — all *open* advances for the user, regardless of date.

## Print report

*Print report* (top-right of the tab) generates a one-click PDF of the current view — the team leaderboard when no employee is selected, or the single-employee scorecard with its breakdown tables when one is. The PDF:

- Carries your firm name and logo in the header and the exact *From → To* period.
- Reflects **live** figures at the moment you export (there is no cached snapshot behind it).
- Prints the top 30 employees on the leaderboard view.
- Carries a footer and a faint background trace naming who printed it, with their user ID — this is confidential HR data, and the trace makes leaks attributable.

If generation fails, an error line appears under the toolbar and nothing downloads.

## Common questions

### Where's the "View employee" picker to jump to a person?

There isn't one anymore. You reach an employee's scorecard by **clicking their row** in the leaderboard, and return with *Team* (the ← chevron, top-left). If someone isn't on the leaderboard for the chosen range, widen the *From* / *To* window until they have activity in it.

### Why is someone's index (or a pillar) showing `—`?

They don't have enough data for that pillar in the window. *Quality* needs at least `3` enquiries created, *Delivery speed* at least `2` deliveries with a date, and *Quote speed* at least `2` quotes with a turnaround. The index is computed from whichever pillars qualify; if none do, the whole index is `—`. Widen the date range and it may fill in.

### Is the index a performance grade I can act on directly?

Treat it as a *soft signal*, not a verdict. It only measures data-entry quality and clerical speed, and it's built from noisy human signals. Always read it next to the raw metrics (edit churn, quick-fix / senior-fix rates, lags) and the throughput and attendance context — none of which are graded.

### Does being on leave hurt someone's attendance %?

No. Approved leave is excluded from the attendance denominator entirely — only present, half-day, and absent days count. Holidays and weekends aren't working days and are ignored too. See [Applying leave](/docs/human-resources/applying-leave).

### Can a "quick-fix" be a legitimate later edit?

No — only edits within **30 minutes** of first save count as quick-fix churn. A genuine revision hours or days later is treated as normal work and never dents the quality score. A *senior-fix* is different: it flags that a **different** person had to correct the entry, which is a stronger signal regardless of timing.

### Why does the outstanding advance figure ignore my date range?

Advances are a *live* balance of what the employee currently owes, so *Advance o/s ₹* always shows the present open total — it isn't scoped to the *From* / *To* window like the other numbers. Approved expenses (*Expenses ₹*) *are* scoped to the window. See [Log an expense](/docs/human-resources/log-expense).

### A former employee's work isn't showing up — why?

Deleted staff are excluded from the leaderboard, the scorecard, and the firm KPIs, even for periods when they were active. Only current employees are scored.

### How is the quote credited when one person creates the enquiry and another sends the quote?

The quote count and turnaround go to whoever **sent** the offer; the enquiry-creation quality and capture-lag go to whoever **created** the enquiry. They can be different people. See [Generate a quotation](/docs/enquiry-bank/generate-quotation).
