Skip to main content
Schoolyi
School librarian arranging books and planning cards in a bright library

Browse docs

Fees & finance

Payroll setup and usage

Pay components, approved salary assignments, the monthly run from draft to paid, statutory exports, and the two-person rules that gate both.

Fees & finance guide for day and boarding schools.

Last updated August 29, 2026

What this covers

The payroll module turns approved salary structures into monthly payslips, recovers staff advances, settles approved reimbursements, produces statutory CSV files, and optionally posts the net payroll cost against a finance budget line. It is operational payroll: it computes and records what each staff member is owed and keeps an auditable trail of who approved what. It does not connect to a bank, so the actual transfer happens outside Schoolyi and is reflected back by marking the run paid.

Do the setup once, before the first run of the year, and then repeat only the monthly part. Two separate approval gates exist and both refuse the same person twice, so plan for at least two people with payroll access - a first run cannot be completed end to end by a single account.

Prerequisites

  • Staff exist as users with userType staff. Generation walks active staff users, so anyone missing from /users is missing from payroll.
  • Pay components defined at /payroll/components. The first create call seeds a default component set if the table is empty, but review it rather than relying on it.
  • Employee IDs and, for provident fund export, a UAN number on the staff employment profile. The PF CSV reads uanNumber and will emit blanks without it.
  • A finance budget at /finance/budgets if you intend to post the payroll expense on finalize. Without a budget id, finalize completes but posts nothing.

Salary assignments come first, and need approving

  1. Create the assignment at /payroll/salary-assignments with monthly CTC, effective dates, component lines, and the PF, ESI, TDS and professional tax flags. It is created with status PENDING and isActive false.
  2. Alternatively seed it from the HR record with POST /api/payroll/salary-assignments/from-hr, which parses the official CTC held at /salary-management (a plain annual amount or a value such as 12 LPA) and builds default component lines.
  3. A second person with role Platform Admin, Principal or Vice Principal approves it. The creator is refused with 403, and an assignment that is not PENDING cannot be decided again.
  4. Approval activates the assignment and closes the previous active one for that staff member, setting its effectiveTo to the new effective-from date. Rejection stores a reason and leaves the assignment inactive.

The monthly run

StageWhereStatus after
Create the run for a year and month/payroll/runsDRAFT
Generate payslips from approved assignmentsRun detail, GenerateGENERATED
Review each payslip lineRun detailGENERATED
Finalize, optionally against a budgetRun detail, FinalizeFINALIZED
Finalize with mark paid, after the bank transferRun detail, FinalizePAID
Download statutory CSV filesRun detail, exportUnchanged

One run exists per calendar month; a second attempt for the same year and month is refused. Generating is repeatable while the run is DRAFT or GENERATED - it deletes draft payslips and recalculates - but is blocked once the run is FINALIZED or PAID, where the guidance is to record a reversal run rather than edit history. Finalizing requires the run to be in GENERATED with at least one payslip.

What generation calculates, and what it ignores

  • Earnings, deductions and employer contributions from the approved assignment lines, plus the PF, ESI, TDS and professional tax flags on that assignment.
  • Advance recovery: for each ACTIVE staff advance with a balance, the monthly recovery amount capped at the remaining balance.
  • Reimbursements: every APPROVED reimbursement not yet attached to a payslip is added to that payslip.
  • Working days default to 26 and paid days are set equal to them, with loss of pay at zero. Payroll does not read attendance, the academic calendar, or approved leave - a deduction for unpaid absence has to be handled as a manual adjustment.
  • Arrears are recorded as zero on generation. There is no automatic back-pay calculation when an assignment is approved with a past effective date.

Finalize, and what crosses into finance

  • The person who created the run cannot finalize it. Finalizing a run created by the same account returns 403.
  • Advance recoveries are written against each advance and the balance reduced; an advance reaching zero is closed with a closed-at timestamp.
  • Attached reimbursements move to PAID and are stamped with the payslip and a paid-at time.
  • With a budget id, one consolidated expense is created for the net payroll total, category ADMINISTRATION, method BANK_TRANSFER, and stored on the run as payrollExpenseId. The budget spent figure is only adjusted when the run is finalized with mark paid.
  • Statutory CSV export accepts format pf, esi, pt or tds and refuses any run that is not FINALIZED or PAID.

Who owns it

CapabilityRolesCan do
Payroll administrationPlatform Admin, Admin, Principal, Vice PrincipalComponents, salary assignments, advances, create and generate runs
Assignment approvalPlatform Admin, Principal, Vice PrincipalApprove or reject a pending assignment created by someone else
Payroll financeThe above, plus Support Staff - Finance and admin user typesRead run totals, finalize with a budget, export statutory CSV
Own payslipAny staff memberDownload their own payslip once the run is finalized

What breaks if you skip or misorder a step

  • Assignments left pending: the run generates with fewer staff than expected and the shortfall only shows in the skipped count, not as an error.
  • Finalizing without a budget id: payslips lock correctly but finance sees no payroll cost, and adding it afterwards is not possible because the expense is only created during finalize.
  • Marking paid before the bank transfer: the budget spent figure moves and the run becomes immutable, so a correction needs a reversal run.
  • Approving a new assignment mid-month before generating: the previous assignment is closed at the new effective date, so the month is computed on the new structure.
  • A single-account setup: neither approval gate can be satisfied, and payroll stalls at PENDING or GENERATED.

Handoff and limits

Payroll hands two things across module boundaries. Finance receives one consolidated expense per finalized run, linked to the chosen budget line, which is what makes payroll visible at /finance/planning and in cash-flow reporting. Staff receive their payslip, which they download themselves from /payroll/payslips/[id] - payslips are not emailed, and a staff member who is not in a payroll finance role cannot open one until the run is finalized or paid.

  • No bank payment file. Statutory CSVs cover PF, ESI, professional tax and TDS reporting only; transfers happen in the bank.
  • No general ledger. /salary-management holds official CTC and pay band records for HR; /payroll executes the monthly run. Neither replaces accounting software.
  • No loss-of-pay integration with attendance or leave, and no automatic arrears.
  • A finalized run is immutable by design. Corrections are a new run, not an edit.

Common questions

Quick answers in plain language.

Why is a staff member missing from the generated payroll run?+

Generation only uses a salary assignment with status APPROVED and isActive true that is effective on the run period end date. A newly created assignment is PENDING until a second approver decides it at /payroll/salary-assignments, and staff without one are counted in the skipped total. Check the assignment status and effective dates, and that the user has userType staff and is active.

Why can I not finalize the payroll run I just generated?+

The person who created the run is refused with 403 - finalizing is a second-person check. The run must also be in GENERATED with at least one payslip; a run already FINALIZED or PAID is immutable and the answer there is a reversal run.

Does payroll deduct pay for unpaid leave or absence?+

No. Generation sets working days to 26, paid days equal to working days, and loss of pay to zero, and it does not read attendance, the academic calendar, or approved leave. Any unpaid-absence deduction has to be applied through the payslip line or a deduction component.

When does payroll show up in the finance budget?+

Only when you pass a budget id at finalize. That creates one consolidated expense for the net total, category ADMINISTRATION, stored on the run as payrollExpenseId. The budget spent figure is adjusted only when the run is finalized with mark paid, so a run finalized without mark paid appears as an approved expense rather than spend.

Related searches

School leaders and IT teams often search for: how to payroll workflows in school management software, best fee management software for K-12 schools, Schoolyi payroll workflows guide, payroll workflows step by step, online fee collection software, school billing software, and fee receipt software schools.