# Calculation Logic

## Scope

This document describes the formulas implemented by the approved 2025 calculator and preserved by the modular edition. It explains software behavior rather than independently replacing or reinterpreting the approved payroll rules.

All currency outputs are rounded to two decimal places at the component level, matching the legacy JavaScript implementation.

## Shared rate calculations

Let:

- `M` = monthly rate
- `D` = daily rate
- `H` = hourly rate

```text
D = round(M / 21.75)
H = round(D / 8)
Basic pay for one half = round(M / 2)
```

The hourly rate is calculated from the already rounded daily rate, as in the original pages.

## Earnings components

Each component is rounded to two decimal places before totals are calculated.

| Component | Implemented calculation |
|---|---:|
| Basic pay | `M / 2` |
| Ordinary day night differential | `H x hours x 0.10` |
| Ordinary day overtime | `H x hours x 0.25` |
| Rest-day work | `H x hours x 1.30` |
| Rest-day night differential | `H x hours x 0.13` |
| Rest-day overtime | `H x hours x 1.69` |
| Regular-holiday work | `H x hours x 1.00` |
| Regular-holiday night differential | `H x hours x 0.26` |
| Special-holiday work | `H x hours x 0.30` |
| Special-holiday night differential | `H x hours x 0.13` |

The half-period gross taxable income is the rounded sum of basic pay and all nine premium components.

## Optional deductions

The calculator accepts four optional deductions:

- Cash advance
- HMO
- Eyeglass
- Other deductions

```text
Total optional deductions = cash advance + HMO + eyeglass + other
Gross income after optional deductions = half gross taxable income - total optional deductions
```

## H1 statutory deductions

### SSS

The original implementation uses a bracket table beginning at PHP 250.00 for monthly rates up to PHP 5,250.00. The employee contribution then increases by PHP 25.00 for each subsequent PHP 500 salary band, reaching PHP 1,725.00 for monthly rates up to PHP 34,749.99 and PHP 1,750.00 above that amount up to PHP 1,000,000.00.

The exact table is generated in `payroll-rates.js` and boundary-tested in `tests/statutory.test.js`.

### PhilHealth

The preserved implementation is:

```text
If 10,000.01 <= M <= 99,999.99:
    PhilHealth = round(M x 0.05 / 2)
Else if 100,000.00 <= M <= 1,000,000.00:
    PhilHealth = 2,500.00
Else:
    PhilHealth = 0.00
```

### Pag-IBIG

```text
Pag-IBIG = 200.00
```

### H1 totals

```text
Total statutory deductions = SSS + PhilHealth + Pag-IBIG
H1 taxable basis carried to H2 = H1 gross taxable income - total statutory deductions
H1 net take-home pay = H1 gross income after optional deductions - total statutory deductions
```

The new interface carries the H1 taxable basis into H2 automatically. A manual override is available for reconciliation or approved exceptions.

## H2 withholding-tax implementation

Let `T` be:

```text
T = H1 taxable basis + H2 gross taxable income
```

The preserved H2 implementation uses the following formulas:

| T range | Implemented withholding tax |
|---|---:|
| `T <= 20,833` | `0` |
| `T <= 33,332` | `T x 0.15` |
| `T <= 66,666` | `(T x 0.20) + 1,875.00` |
| `T <= 166,666` | `(T x 0.25) + 8,541.80` |
| `T <= 666,666` | `(T x 0.30) + 33,541.80` |
| `T <= 999,999` | `(T x 0.35) + 183,541.80` |
| `T > 999,999` | `(T x 0.35) + 300,041.80` |

This table intentionally documents the current approved software behavior. Any future reinterpretation or change should be handled as a separately reviewed formula update with new tests and a changelog entry.

## H2 and monthly totals

```text
H2 gross income after optional deductions
    = H2 gross taxable income - H2 optional deductions

H2 net take-home pay
    = H2 gross income after optional deductions - withholding tax

Estimated monthly net pay
    = H1 net take-home pay + H2 net take-home pay
```

## Rounding

The shared helper follows the legacy approach:

```text
round(value x 100) / 100
```

Inputs and individual calculated components are rounded before aggregation. This can differ slightly from systems that preserve more decimal places until the final total.
