> ## Documentation Index
> Fetch the complete documentation index at: https://docs.hitaji360.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Salary structures

> A salary structure is a reusable pay template. It gathers the salary components that make up a complete pay package — basic pay, allowances, deductions…

A salary structure is a reusable pay template. It gathers the [salary components](/hr/user/payroll/salary-components) that make up a complete pay package — basic pay, allowances, deductions and the statutory items — and decides, for each one, whether it is a flat amount or a formula. You build a structure once (say "Teaching Staff 2026" or "Management"), then **assign** it to each employee from a date, plugging in that person's base pay. The structure plus the assignment is what a payroll run uses to compute every payslip.

This page covers building a structure in the builder, the formula editor and its code picker, how statutory items appear as read-only pills, the draft → submitted lifecycle, and assigning a structure to an employee.

**You'll find this at:** `/settings/erp/finance/payroll-structures` (list) — the old `/payroll/setup/structures` redirects here. Create at `/payroll/setup/structures/new`, edit at `/payroll/setup/structures/:id`.

> 📷 *Screenshot: the Salary Structure Builder with earnings and deductions sections and the formula editor — to be added.*

> **Multi-business:** a structure belongs to the selected business. Confirm the business switcher first.

***

## The structure lifecycle (docstatus)

Like most posting documents in Hitaji 360, a structure carries a **docstatus**:

| Status            | Meaning                        | What you can do                                     |
| ----------------- | ------------------------------ | --------------------------------------------------- |
| **Draft** (0)     | Being built; not yet usable    | Edit everything — add/remove lines, change formulas |
| **Submitted** (1) | Finalised; available to assign | Read-only. Cancel it to make changes                |
| **Cancelled** (2) | Retired                        | Read-only                                           |

You can only **assign** a structure that is **Submitted** and active. A draft can't be assigned, and a submitted structure is locked — you must **Cancel** it (and build a new version) to change the lines.

***

## Building a structure

From the list, choose **New** (or open an existing draft). The builder has:

### Header

* **Name** — e.g. "Teaching Staff 2026"
* **Frequency** — `Monthly`, `Bimonthly`, `Weekly`, `Daily`, or `Hourly`
* **Currency** — ISO code (e.g. `UGX`)
* **Attendance-based payment days** — optional; derive paid days from attendance rather than the calendar

### Earnings and deductions

Add component lines into the **Earnings** and **Deductions** sections. For each line you pick a component, then choose how its value is set:

* **Fixed amount** — type a number, or
* **Formula** — write an expression (see below).

A line cannot have **both** an amount and a formula — the builder makes you choose one. (A per-line value overrides the component's own default.)

> 📷 *Screenshot: adding an earning line and choosing fixed-amount vs formula — to be added.*

### The formula editor and code picker

When a line is formula-driven, the editor offers a **code picker** so you don't have to memorise variables. The built-in codes are:

| Code                 | Meaning                                      |
| -------------------- | -------------------------------------------- |
| `base`               | The employee's basic pay (set at assignment) |
| `gross`              | Gross pay accumulated so far                 |
| `payment_days`       | Days paid in this period                     |
| `total_working_days` | Working days in the period                   |

The picker also lists **every non-statutory component's abbreviation** so you can reference, say, `BASIC * 0.4` or `HRA + TRANSPORT`. Statutory components are deliberately **excluded** from the picker — you can't build a formula on top of PAYE/NSSF/LST because those are computed last.

Formulas support arithmetic, comparisons, `&&`/`||`/`!`, the ternary `cond ? a : b`, and `min`, `max`, `abs`, `round`, `floor`, `ceil`.

### Statutory items appear as read-only "auto-calculated" pills

When you add a statutory component (PAYE, NSSF, LST) to a structure, it shows as a read-only pill labelled **"Auto-calculated at run time"** — there is no amount box and no formula box. The builder strips any value off the line, and the backend rejects any inline amount or formula on a statutory line. The statutory engine supplies the figure during the run using the income-tax slabs and configured rates. This is intentional and keeps statutory maths consistent for every employee.

> ⚠️ **Watch out — double pro-ration:** if a line both *depends on payment days* **and** uses a formula that references another already-prorated component, the system blocks it, because the amount would be prorated twice and underpay the employee. Keep the formula referencing the full-value component and let pro-ration apply once.

### Saving and submitting

Save keeps the structure as a **Draft**. When the lines are right, **Submit** moves it to Submitted so it can be assigned. To revise a submitted structure, **Cancel** it and build a fresh version.

***

## Assigning a structure to an employee

A structure does nothing until it is assigned to an employee's contract. Assignment is where the per-employee numbers live — most importantly the **base** pay. You assign from the employee's **Compensation** card (see [Employee profile](/hr/user/employees/employee-profile) and [Employment records & contracts](/hr/user/employees/employment-and-contracts)), which opens the Salary Structure Assignment modal.

| Field                        | Required    | Notes                                                                                                                            |
| ---------------------------- | ----------- | -------------------------------------------------------------------------------------------------------------------------------- |
| **Salary structure**         | Yes         | Only Submitted, active structures are listed                                                                                     |
| **Effective from**           | Yes         | The date the assignment takes effect (defaults to today)                                                                         |
| **Base**                     | Conditional | Required only if the structure's formulas reference `base`. If no line uses `base`, the field is hidden and base is treated as 0 |
| **Hourly rate**              | Conditional | Shown instead of Base when the structure frequency is `Hourly`                                                                   |
| **Currency**                 | Yes         | Defaults from the structure                                                                                                      |
| **Income-tax slab**          | No          | Leave blank to use the business's default effective slab; set it to override PAYE bands for this person                          |
| **Taxable earnings to date** | No          | Year-to-date taxable pay from a previous employer (mid-year hires)                                                               |
| **Tax deducted to date**     | No          | Year-to-date tax already withheld elsewhere                                                                                      |
| **Cost centres**             | No          | Split the cost across cost centres (percentages must total 100)                                                                  |

Submitting the assignment **automatically closes any earlier overlapping assignment** for that contract (it stamps an end date), so an employee always has exactly one active assignment on any given date. The active assignment as of the run date is what determines whether the employee appears in a run and how their pay is computed.

***

## Permissions

| Action                                      | Permission       |
| ------------------------------------------- | ---------------- |
| View structures and assignments             | `payroll:read`   |
| Create / edit / submit / cancel a structure | `payroll:config` |
| Create / submit / cancel an assignment      | `payroll:write`  |

***

## Behind the scenes — how a slip is computed

During a run, for each employee the engine:

1. loads the active **assignment** (giving `base`, currency, any tax-slab override),
2. evaluates each **earning** line (formula or fixed amount), accumulating `gross`,
3. evaluates each **deduction** line,
4. then asks the **statutory engine** for PAYE / NSSF / LST (which ignore any structure value), and
5. produces the payslip: gross − total deductions = net pay, plus employer contributions.

Each component's GL mapping drives where its amount posts. The full debit/credit posting is on [Running payroll → Behind the scenes](/hr/user/payroll/running-payroll).

***

## Related

* [Salary components](/hr/user/payroll/salary-components) — the building blocks
* [Income-tax slabs](/hr/user/payroll/income-tax-slabs) — the PAYE bands a slab override points at
* [Running payroll](/hr/user/payroll/running-payroll) — where structures are turned into payslips
* [Employment records & contracts](/hr/user/employees/employment-and-contracts) — where assignments attach
* [Payroll overview](/hr/user/payroll/overview) — the whole chain
