Payroll Formula System

Payroll Formula System

The payroll formula engine provides flexible arithmetic expressions for calculating pay element amounts. Instead of using fixed amounts or simple percentages, you can write formulas that reference built-in payroll variables.

Where Formulas Are Used

Formulas are used when a Pay Element has its Amount Type set to Formula (type 3). They can be defined at three levels:

LevelWherePriority
Employee Salary OverrideManage Employees salary tabHighest (1st)
Salary StructureSalary Structure element lineMid (2nd)
Pay Element DefaultPay Elements formula fieldLowest (3rd)

The system checks from highest to lowest priority and uses the first non-empty formula it finds.

Formula Syntax

Formulas are plain arithmetic expressions. They support:

  • Numbers: integers and decimals (100, 0.15, 1500.50)
  • Variables: named tokens that resolve to numeric values (BASIC, GROSS)
  • Operators: + (add), - (subtract), * (multiply), / (divide), % (modulo)
  • Parentheses: ( ) for grouping and controlling order of operations

Not supported: conditional logic (if/else), functions (round, max, min), string operations, or custom variables.

Available Variables

These variables are automatically set for each employee when a payslip is calculated:

VariableTypeDescriptionHow Calculated
BASICfloatBase salary for the periodFrom employee salary or structure
GROSSfloatCumulative earnings so farBasic + all prior earnings (recalculated after each component)
DAYS_WORKEDfloatDays actually workedFrom attendance records
WORKING_DAYSfloatTotal working days in periodCalendar days minus weekends and holidays
DAYS_IN_MONTHfloatSame as WORKING_DAYSAlias for backwards compatibility
OVERTIME_HOURSfloatTotal overtime hoursFrom attendance records
UNPAID_LEAVE_DAYSfloatDays of unpaid absenceFrom attendance records
HOURLY_RATEfloatHourly pay rateBASIC / WORKING_DAYS / 8

All variable names are case-insensitive -- basic, Basic, and BASIC are all equivalent.

Cascading GROSS Calculation

The GROSS variable is special -- it is recalculated after each salary component is processed. Components are processed in Display Order sequence.

Processing example:

StepComponentFormulaAmountGROSS After
1Basic Salary(fixed)5,0005,000
2HRABASIC * 0.105005,500
3TransportBASIC * 0.084005,900
4Performance BonusGROSS * 0.05295 (5% of 5,900)6,195

This means the Display Order of pay elements affects formula results when they reference GROSS.

Common Formula Patterns

Percentage of Basic Salary

BASIC * 0.10

10% of basic salary. Useful for allowances like HRA, Dearness Allowance, etc.

Overtime Pay

HOURLY_RATE * OVERTIME_HOURS * 1.5

1.5x overtime rate. Change 1.5 to 2.0 for double-time.

Absence Deduction

(BASIC / WORKING_DAYS) * UNPAID_LEAVE_DAYS

Deducts proportionally for each day of unpaid absence.

Pro-Rata Salary (Attendance Based by Formula)

(BASIC / WORKING_DAYS) * DAYS_WORKED

Pay proportional to actual days worked. Useful for new joiners mid-month.

Percentage of Gross (Cascading)

GROSS * 0.10

10% of cumulative gross. Amount depends on which components were processed before this one.

Fixed Amount Plus Variable

500 + (BASIC * 0.05)

A 500 fixed component plus 5% of basic.

Complex Deduction

(BASIC * 0.08) + (OVERTIME_HOURS * HOURLY_RATE * 0.02)

8% of basic plus 2% of overtime earnings.

Error Handling

SituationResult
Empty formulaReturns 0.00
Invalid characters (letters other than variables, special symbols)Returns 0.00
Division by zeroReturns 0.00
Unbalanced parenthesesReturns 0.00
Undefined variable nameLeft as text, causes invalid expression, returns 0.00
NaN or Infinity resultReturns 0.00

Formulas fail silently -- they do not show error messages. Always verify results via Payslip Entry preview.

Security

The formula engine uses a strict whitelist approach:

  • Only digits, decimal points, operators (+ - * / %), parentheses, and spaces are allowed in the final expression
  • All variable names are replaced with their numeric values before evaluation
  • Any unrecognized characters cause the formula to return 0.00
  • This prevents code injection or unauthorized operations

Audit Trail

Every payslip records the exact formula text that was used for each line item in the formula_used column of the payslip details table. This means:

  • You can audit which formula was active when a payslip was generated
  • If you change a formula later, existing payslips retain their historical formula record
  • Useful for compliance and payroll dispute resolution

Tips

  • Test first: Create a payslip preview for one employee before running batch payroll to verify formula results
  • Order matters: Component Display Order affects the GROSS variable -- ensure earnings appear before deductions that reference GROSS
  • Keep it simple: Complex formulas are harder to audit; prefer multiple simple elements over one complex formula
  • Use overrides wisely: Use salary structure overrides for grade-level differences, employee overrides only for truly individual cases
  • Parentheses: When in doubt, add parentheses. (BASIC / WORKING_DAYS) * UNPAID_LEAVE_DAYS is clearer than BASIC / WORKING_DAYS * UNPAID_LEAVE_DAYS

See Also