Skip to content

API Reference

This section provides a complete API reference for the nztaxmicrosim package, automatically generated from the source code docstrings.

Core Simulation

Simulation Pipeline

src.pipeline

Simple plug-in pipeline for orchestrating tax and benefit rules.

SimulationPipeline dataclass

A pipeline for running a series of simulation rules.

The pipeline stores a list of rules and executes them sequentially on a given data dictionary. Rules can be enabled, disabled, or replaced.

Source code in src/pipeline.py
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
@dataclass
class SimulationPipeline:
    """A pipeline for running a series of simulation rules.

    The pipeline stores a list of rules and executes them sequentially on a
    given data dictionary. Rules can be enabled, disabled, or replaced.
    """

    rules: list[Rule] = field(default_factory=list)

    @classmethod
    def from_config(cls, config_path: str) -> "SimulationPipeline":
        """Create a SimulationPipeline from a YAML configuration file.

        The configuration file should specify a list of rules to be included
        in the pipeline. This method uses the RULE_REGISTRY to find and
        instantiate the rules. The rules are instantiated without parameters;
        they are expected to receive them from the `data` dictionary during
        the `run` phase.

        Args:
            config_path: The path to the YAML configuration file.

        Returns:
            A new `SimulationPipeline` instance.
        """
        with open(config_path) as f:
            config = yaml.safe_load(f)

        rules: list[Rule] = []

        # Import all rule modules to ensure they are registered

        for rule_config in config["rules"]:
            rule_name = rule_config.get("name") or rule_config.get("rule")
            if rule_name not in RULE_REGISTRY:
                # Fallback for old format
                if "." in rule_name:
                    module_path, class_name = rule_name.rsplit(".", 1)
                    try:
                        module = importlib.import_module(module_path)
                        rule_class = getattr(module, class_name)
                    except (ImportError, AttributeError):
                        raise ValueError(f"Unknown rule: {rule_name}")
                else:
                    raise ValueError(f"Unknown rule: {rule_name}")
            else:
                rule_class = RULE_REGISTRY[rule_name]

            # Rules are instantiated without arguments here.
            # They will get their data from the context dict passed to run().
            rules.append(rule_class())

        return cls(rules)

    def _find_rule_index(self, name: str) -> int | None:
        """Find the index of a rule by its name.

        Args:
            name: The name of the rule to find.

        Returns:
            The index of the rule, or `None` if the rule is not found.
        """
        for i, rule in enumerate(self.rules):
            if rule.name == name:
                return i
        return None

    def run(self, data: dict[str, Any] | None = None) -> dict[str, Any]:
        """Run all enabled rules in the pipeline sequentially.

        Each rule is called with the `data` dictionary, which it can modify
        in-place.

        Args:
            data: The data dictionary to be processed by the rules. It is
                expected to contain a 'df' key with a pandas DataFrame.

        Returns:
            The modified data dictionary.
        """
        if data is None:
            data = {}
        for rule in self.rules:
            if getattr(rule, "enabled", True):
                rule(data)
        return data

    def enable(self, name: str) -> None:
        """Enable a rule in the pipeline.

        Args:
            name: The name of the rule to enable.
        """
        if (idx := self._find_rule_index(name)) is not None:
            self.rules[idx].enabled = True

    def disable(self, name: str) -> None:
        """Disable a rule in the pipeline.

        Args:
            name: The name of the rule to disable.
        """
        if (idx := self._find_rule_index(name)) is not None:
            self.rules[idx].enabled = False

    def replace(self, name: str, new_rule: Rule) -> None:
        """Replace a rule in the pipeline.

        Args:
            name: The name of the rule to replace.
            new_rule: The new rule to insert into the pipeline.
        """
        if (idx := self._find_rule_index(name)) is not None:
            self.rules[idx] = new_rule

disable(name)

Disable a rule in the pipeline.

Parameters:

Name Type Description Default
name str

The name of the rule to disable.

required
Source code in src/pipeline.py
112
113
114
115
116
117
118
119
def disable(self, name: str) -> None:
    """Disable a rule in the pipeline.

    Args:
        name: The name of the rule to disable.
    """
    if (idx := self._find_rule_index(name)) is not None:
        self.rules[idx].enabled = False

enable(name)

Enable a rule in the pipeline.

Parameters:

Name Type Description Default
name str

The name of the rule to enable.

required
Source code in src/pipeline.py
103
104
105
106
107
108
109
110
def enable(self, name: str) -> None:
    """Enable a rule in the pipeline.

    Args:
        name: The name of the rule to enable.
    """
    if (idx := self._find_rule_index(name)) is not None:
        self.rules[idx].enabled = True

from_config(config_path) classmethod

Create a SimulationPipeline from a YAML configuration file.

The configuration file should specify a list of rules to be included in the pipeline. This method uses the RULE_REGISTRY to find and instantiate the rules. The rules are instantiated without parameters; they are expected to receive them from the data dictionary during the run phase.

Parameters:

Name Type Description Default
config_path str

The path to the YAML configuration file.

required

Returns:

Type Description
'SimulationPipeline'

A new SimulationPipeline instance.

Source code in src/pipeline.py
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
@classmethod
def from_config(cls, config_path: str) -> "SimulationPipeline":
    """Create a SimulationPipeline from a YAML configuration file.

    The configuration file should specify a list of rules to be included
    in the pipeline. This method uses the RULE_REGISTRY to find and
    instantiate the rules. The rules are instantiated without parameters;
    they are expected to receive them from the `data` dictionary during
    the `run` phase.

    Args:
        config_path: The path to the YAML configuration file.

    Returns:
        A new `SimulationPipeline` instance.
    """
    with open(config_path) as f:
        config = yaml.safe_load(f)

    rules: list[Rule] = []

    # Import all rule modules to ensure they are registered

    for rule_config in config["rules"]:
        rule_name = rule_config.get("name") or rule_config.get("rule")
        if rule_name not in RULE_REGISTRY:
            # Fallback for old format
            if "." in rule_name:
                module_path, class_name = rule_name.rsplit(".", 1)
                try:
                    module = importlib.import_module(module_path)
                    rule_class = getattr(module, class_name)
                except (ImportError, AttributeError):
                    raise ValueError(f"Unknown rule: {rule_name}")
            else:
                raise ValueError(f"Unknown rule: {rule_name}")
        else:
            rule_class = RULE_REGISTRY[rule_name]

        # Rules are instantiated without arguments here.
        # They will get their data from the context dict passed to run().
        rules.append(rule_class())

    return cls(rules)

replace(name, new_rule)

Replace a rule in the pipeline.

Parameters:

Name Type Description Default
name str

The name of the rule to replace.

required
new_rule Rule

The new rule to insert into the pipeline.

required
Source code in src/pipeline.py
121
122
123
124
125
126
127
128
129
def replace(self, name: str, new_rule: Rule) -> None:
    """Replace a rule in the pipeline.

    Args:
        name: The name of the rule to replace.
        new_rule: The new rule to insert into the pipeline.
    """
    if (idx := self._find_rule_index(name)) is not None:
        self.rules[idx] = new_rule

run(data=None)

Run all enabled rules in the pipeline sequentially.

Each rule is called with the data dictionary, which it can modify in-place.

Parameters:

Name Type Description Default
data dict[str, Any] | None

The data dictionary to be processed by the rules. It is expected to contain a 'df' key with a pandas DataFrame.

None

Returns:

Type Description
dict[str, Any]

The modified data dictionary.

Source code in src/pipeline.py
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
def run(self, data: dict[str, Any] | None = None) -> dict[str, Any]:
    """Run all enabled rules in the pipeline sequentially.

    Each rule is called with the `data` dictionary, which it can modify
    in-place.

    Args:
        data: The data dictionary to be processed by the rules. It is
            expected to contain a 'df' key with a pandas DataFrame.

    Returns:
        The modified data dictionary.
    """
    if data is None:
        data = {}
    for rule in self.rules:
        if getattr(rule, "enabled", True):
            rule(data)
    return data

Main Simulation Logic

src.microsim

calctax(taxy, split, params1, params2)

Calculate income tax for a year with a mid-year policy change (split year).

This is used when tax rules change during a financial year. It calculates the tax for the full year under the old rules (params1) and the new rules (params2), then prorates the results based on the split month.

Parameters:

Name Type Description Default
taxy float

The total taxable income for the year.

required
split int

The month number (1-12) in which the tax change occurs. The new rules apply from this month onwards.

required
params1 TaxBracketParams

The tax bracket parameters for the first part of the year.

required
params2 TaxBracketParams

The tax bracket parameters for the second part of the year.

required

Returns:

Type Description
float

The total income tax for the split year.

Source code in src/microsim.py
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
def calctax(taxy: float, split: int, params1: TaxBracketParams, params2: TaxBracketParams) -> float:
    """
    Calculate income tax for a year with a mid-year policy change (split year).

    This is used when tax rules change during a financial year. It calculates
    the tax for the full year under the old rules (`params1`) and the new rules
    (`params2`), then prorates the results based on the `split` month.

    Args:
        taxy: The total taxable income for the year.
        split: The month number (1-12) in which the tax change occurs. The
            new rules apply from this month onwards.
        params1: The tax bracket parameters for the first part of the year.
        params2: The tax bracket parameters for the second part of the year.

    Returns:
        The total income tax for the split year.
    """

    taxa: float = taxit(taxy, params1)
    taxb: float = taxit(taxy, params2)
    return taxa * (split / 12) + taxb * ((12 - split) / 12)

calculate_net_weekly_income(gross_weekly_income, acc_earners_premium_rate, tax_params)

Calculate the net average weekly income after tax and ACC levy.

This function annualizes the weekly income, calculates the annual income tax, deducts the ACC Earner's Premium, and then converts the result back to a weekly net income.

Parameters:

Name Type Description Default
gross_weekly_income float

The gross weekly income.

required
acc_earners_premium_rate float

The ACC Earner's Premium rate.

required
tax_params TaxBracketParams

The tax bracket parameters.

required

Returns:

Type Description
float

The net average weekly income, rounded to two decimal places.

Source code in src/microsim.py
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
def calculate_net_weekly_income(
    gross_weekly_income: float,
    acc_earners_premium_rate: float,
    tax_params: TaxBracketParams,
) -> float:
    """
    Calculate the net average weekly income after tax and ACC levy.

    This function annualizes the weekly income, calculates the annual income tax,
    deducts the ACC Earner's Premium, and then converts the result back to a
    weekly net income.

    Args:
        gross_weekly_income: The gross weekly income.
        acc_earners_premium_rate: The ACC Earner's Premium rate.
        tax_params: The tax bracket parameters.

    Returns:
        The net average weekly income, rounded to two decimal places.
    """
    annual_earnings = gross_weekly_income * 52
    annual_tax = taxit(annual_earnings, tax_params)
    net_annual_income = annual_earnings * (1 - acc_earners_premium_rate) - annual_tax
    net_weekly_income = int(100 * net_annual_income / 52) / 100
    return net_weekly_income

load_parameters(year)

Load policy parameters for year from the SQLite database.

This function connects to the parameters database, queries for all policy parameters for the given year, reconstructs the parameter dictionary, and validates it using the Pydantic model.

Parameters:

Name Type Description Default
year str

The start year for which to load the parameters (e.g., "2023"). Note: The input should be the start year as an integer or string, not the "YYYY-YYYY" format.

required

Returns:

Name Type Description
Parameters Parameters

A Pydantic model containing all parameter groups for the year.

Source code in src/microsim.py
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
def load_parameters(year: str) -> Parameters:
    """Load policy parameters for ``year`` from the SQLite database.

    This function connects to the parameters database, queries for all policy
    parameters for the given year, reconstructs the parameter dictionary,
    and validates it using the Pydantic model.

    Args:
        year: The start year for which to load the parameters (e.g., ``"2023"``).
              Note: The input should be the start year as an integer or string,
              not the "YYYY-YYYY" format.

    Returns:
        Parameters: A Pydantic model containing all parameter groups for the year.
    """
    # The database stores years as integers (e.g., 2023 for "2023-2024")
    try:
        start_year = int(year.split("-")[0])
    except (ValueError, IndexError):
        start_year = int(year)

    if not os.path.exists(DB_PATH):
        raise FileNotFoundError(f"Parameters database not found at {DB_PATH}")

    conn = sqlite3.connect(DB_PATH)
    cursor = conn.cursor()

    cursor.execute("SELECT policy_key, parameters FROM policy_parameters WHERE year = ?", (start_year,))
    rows = cursor.fetchall()
    conn.close()

    if not rows:
        raise ValueError(f"No parameters found for year {start_year} in the database.")

    params_dict = {}
    for key, params_json in rows:
        if params_json is not None:
            params_dict[key] = json.loads(params_json)
        else:
            params_dict[key] = None

    try:
        return Parameters.model_validate(params_dict)
    except ValidationError as e:
        raise ValueError(f"Parameter validation for year {start_year} failed: {e}") from e

simrwt(interest, rwt_rate)

Calculates the Resident Withholding Tax (RWT).

Parameters:

Name Type Description Default
interest float

The interest income.

required
rwt_rate float

The RWT rate to apply.

required

Returns:

Name Type Description
float float

The calculated RWT.

Source code in src/microsim.py
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
def simrwt(interest: float, rwt_rate: float) -> float:
    """
    Calculates the Resident Withholding Tax (RWT).

    Args:
        interest (float): The interest income.
        rwt_rate (float): The RWT rate to apply.

    Returns:
        float: The calculated RWT.
    """
    if interest <= 0:
        return 0.0
    if not (0 <= rwt_rate <= 1):
        raise ValueError("RWT rate must be between 0 and 1.")
    return interest * rwt_rate

supstd(cpi_factors, average_weekly_earnings, earner_premium_rates, super_floor_relativities, tax_parameters, base_year_average_weekly_earnings, base_year_earner_premium_rate, base_year_tax_parameters)

Calculates standard superannuation rates for a base year and 4 simulation years.

This function projects superannuation payments, ensuring they are indexed to the higher of CPI inflation or a "floor" relative to the average weekly earnings. It calculates both gross and net superannuation amounts.

This function replicates the logic of the SAS macro %supstd.

Parameters:

Name Type Description Default
cpi_factors list[float]

A list of 4 CPI factors for the simulation years.

required
average_weekly_earnings list[float]

A list of 4 average weekly earnings for the simulation years.

required
earner_premium_rates list[float]

A list of 4 ACC earner premium rates for the simulation years.

required
super_floor_relativities list[float]

A list of 4 superannuation accord floor relativities for the simulation years.

required
tax_parameters list[TaxBracketParams]

A list of 4 tax parameter sets for the simulation years.

required
base_year_average_weekly_earnings float

The average weekly earnings for the base year.

required
base_year_earner_premium_rate float

The ACC earner premium rate for the base year.

required
base_year_tax_parameters TaxBracketParams

Tax parameters for the base year.

required

Returns:

Type Description
dict[str, float]

A dictionary containing the calculated gross and net standard

dict[str, float]

superannuation amounts for the base year and 4 simulation years.

Source code in src/microsim.py
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
def supstd(
    cpi_factors: list[float],
    average_weekly_earnings: list[float],
    earner_premium_rates: list[float],
    super_floor_relativities: list[float],
    tax_parameters: list[TaxBracketParams],
    base_year_average_weekly_earnings: float,
    base_year_earner_premium_rate: float,
    base_year_tax_parameters: TaxBracketParams,
) -> dict[str, float]:
    """
    Calculates standard superannuation rates for a base year and 4 simulation years.

    This function projects superannuation payments, ensuring they are indexed
    to the higher of CPI inflation or a "floor" relative to the average weekly
    earnings. It calculates both gross and net superannuation amounts.

    This function replicates the logic of the SAS macro `%supstd`.

    Args:
        cpi_factors: A list of 4 CPI factors for the simulation years.
        average_weekly_earnings: A list of 4 average weekly earnings for the
            simulation years.
        earner_premium_rates: A list of 4 ACC earner premium rates for the
            simulation years.
        super_floor_relativities: A list of 4 superannuation accord floor
            relativities for the simulation years.
        tax_parameters: A list of 4 tax parameter sets for the simulation years.
        base_year_average_weekly_earnings: The average weekly earnings for the
            base year.
        base_year_earner_premium_rate: The ACC earner premium rate for the
            base year.
        base_year_tax_parameters: Tax parameters for the base year.

    Returns:
        A dictionary containing the calculated gross and net standard
        superannuation amounts for the base year and 4 simulation years.
    """
    results: dict[str, float] = {}

    # Base year
    base_year_super: float = base_year_average_weekly_earnings * 0.66 * 2
    base_year_net_super: float = calculate_net_weekly_income(
        gross_weekly_income=base_year_super / 2,
        acc_earners_premium_rate=base_year_earner_premium_rate,
        tax_params=base_year_tax_parameters,
    )
    results["std22"] = base_year_super
    results["stdnet22"] = base_year_net_super

    # Simulation years
    super_values: list[float] = []
    net_super_values: list[float] = []

    previous_super: float = base_year_super
    for i in range(4):
        current_super: float = max(
            average_weekly_earnings[i] * super_floor_relativities[i] * 2,
            previous_super * cpi_factors[i],
        )
        net_super: float = calculate_net_weekly_income(
            gross_weekly_income=current_super / 2,
            acc_earners_premium_rate=earner_premium_rates[i],
            tax_params=tax_parameters[i],
        )
        super_values.append(current_super)
        net_super_values.append(net_super)
        previous_super = current_super

    results["std"] = super_values[0]
    results["stdnet"] = net_super_values[0]
    results["std1"] = super_values[1]
    results["stdnet1"] = net_super_values[1]
    results["std2"] = super_values[2]
    results["stdnet2"] = net_super_values[2]
    results["std3"] = super_values[3]
    results["stdnet3"] = net_super_values[3]

    return results

taxit(taxy, params)

Calculate income tax using a progressive tax bracket system.

This function iterates through the tax brackets defined in params. For each bracket, it calculates the tax owed on the portion of income that falls within that bracket's range. The total tax is the sum of the tax from each bracket.

Parameters:

Name Type Description Default
taxy float

The taxable income.

required
params Mapping[str, Any] | TaxBracketParams

A TaxBracketParams instance or a mapping containing rates and thresholds for the tax brackets.

required

Returns:

Type Description
float

The total calculated income tax.

Source code in src/microsim.py
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
def taxit(taxy: float, params: Mapping[str, Any] | TaxBracketParams) -> float:
    """
    Calculate income tax using a progressive tax bracket system.

    This function iterates through the tax brackets defined in `params`. For each
    bracket, it calculates the tax owed on the portion of income that falls
    within that bracket's range. The total tax is the sum of the tax from
    each bracket.

    Args:
        taxy: The taxable income.
        params: A `TaxBracketParams` instance or a mapping containing
            `rates` and `thresholds` for the tax brackets.

    Returns:
        The total calculated income tax.
    """

    if taxy <= 0:
        return 0.0

    tax_params = _coerce_tax_brackets(params)
    t_extended: list[float] = [0.0] + tax_params.thresholds
    tax: float = 0.0

    for i, rate in enumerate(tax_params.rates):
        if taxy > t_extended[i]:
            if i == len(t_extended) - 1 or taxy <= t_extended[i + 1]:
                tax += (taxy - t_extended[i]) * rate
                break
            tax += (t_extended[i + 1] - t_extended[i]) * rate
        else:
            break

    return tax

Tax & Levy Calculations

Main Tax Calculator

src.tax_calculator

TaxCalculator

Bases: BaseModel

Convenience wrapper around core tax calculations.

The class stores a set of policy parameters and exposes small helper methods which delegate to the functions defined in :mod:microsim.

Source code in src/tax_calculator.py
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
class TaxCalculator(BaseModel):
    """Convenience wrapper around core tax calculations.

    The class stores a set of policy parameters and exposes small helper
    methods which delegate to the functions defined in :mod:`microsim`.
    """

    params: Parameters

    def income_tax(self, taxable_income: float) -> float:
        """
        Calculate income tax for a given taxable income.

        This method uses a progressive tax system with multiple tax brackets.
        The tax rates and thresholds for these brackets are drawn from
        `params.tax_brackets`.

        The calculation is performed by the `taxit` function.

        Args:
            taxable_income: The amount of income to calculate tax on.

        Returns:
            The amount of income tax payable.
        """
        tax_params: TaxBracketParams = self.params.tax_brackets
        return taxit(taxy=taxable_income, params=tax_params)

    def ietc(
        self,
        taxable_income: float,
        is_wff_recipient: bool,
        is_super_recipient: bool,
        is_benefit_recipient: bool,
    ) -> float:
        """
        Calculate the Independent Earner Tax Credit (IETC).

        The IETC is a tax credit for individuals who are not receiving
        certain other benefits, such as Working for Families or NZ Super.

        The calculation is performed by the `calcietc` function.

        Args:
            taxable_income: The individual's taxable income.
            is_wff_recipient: Whether the individual is a recipient of
                Working for Families tax credits.
            is_super_recipient: Whether the individual is a recipient of
                NZ Superannuation.
            is_benefit_recipient: Whether the individual is a recipient of
                a main benefit.

        Returns:
            The amount of IETC the individual is entitled to.
        """
        if self.params.ietc is None:
            return 0.0
        return calcietc(
            taxable_income=taxable_income,
            is_wff_recipient=is_wff_recipient,
            is_super_recipient=is_super_recipient,
            is_benefit_recipient=is_benefit_recipient,
            ietc_params=self.params.ietc,
        )

    def rwt(self, interest: float, taxable_income: float) -> float:
        """
        Calculate Resident Withholding Tax (RWT) on interest income.

        RWT is a tax on interest earned from sources like bank accounts and
        investments. The tax rate depends on the individual's income tax
        bracket. This method determines the correct RWT rate based on the
        provided taxable income and then calculates the RWT amount.

        Args:
            interest: The amount of interest income subject to RWT.
            taxable_income: The individual's total taxable income, used to
                determine the RWT rate.

        Returns:
            The amount of RWT payable.
        """
        tax_brackets = self.params.tax_brackets
        rwt_rates = self.params.rwt

        if rwt_rates is None:
            return 0.0

        # Determine the marginal tax rate to find the corresponding RWT rate.
        # The last rate in the list applies to all income above the last threshold.
        rate = tax_brackets.rates[-1]
        for i, threshold in enumerate(tax_brackets.thresholds):
            if taxable_income <= threshold:
                rate = tax_brackets.rates[i]
                break

        # Map the income tax rate to the corresponding RWT rate.
        rwt_rate = 0.0
        if math.isclose(rate, 0.105):
            rwt_rate = rwt_rates.rwt_rate_10_5
        elif math.isclose(rate, 0.175):
            rwt_rate = rwt_rates.rwt_rate_17_5
        elif math.isclose(rate, 0.30):
            rwt_rate = rwt_rates.rwt_rate_30
        elif math.isclose(rate, 0.33):
            rwt_rate = rwt_rates.rwt_rate_33
        elif math.isclose(rate, 0.39):
            rwt_rate = rwt_rates.rwt_rate_39

        return simrwt(interest, rwt_rate)

    def family_boost_credit(self, family_income: float, childcare_costs: float) -> float:
        """
        Calculates the FamilyBoost childcare tax credit.

        Args:
            family_income: The total family income.
            childcare_costs: The total childcare costs for the period.

        Returns:
            The calculated FamilyBoost credit amount.
        """
        if self.params.family_boost is None:
            return 0.0
        return family_boost_credit(
            family_income=family_income,
            childcare_costs=childcare_costs,
            family_boost_params=self.params.family_boost,
        )

    def eitc(
        self,
        is_credit_enabled: bool,
        is_eligible: bool,
        income: float,
        min_income_threshold: float,
        max_entitlement_income: float,
        abatement_income_threshold: float,
        earning_rate: float,
        abatement_rate: float,
    ) -> float:
        """
        Calculates the Earned Income Tax Credit (EITC).

        Args:
            is_credit_enabled: Flag to enable or disable the credit calculation.
            is_eligible: Flag indicating if the individual is eligible for the credit.
            income: The income amount to base the calculation on.
            min_income_threshold: The income level at which the credit begins.
            max_entitlement_income: The income level where the credit reaches its maximum.
            abatement_income_threshold: The income level at which the credit begins to abate.
            earning_rate: The rate at which the credit is earned during phase-in.
            abatement_rate: The rate at which the credit is reduced during phase-out.

        Returns:
            The calculated EITC amount.
        """
        return eitc(
            is_credit_enabled=is_credit_enabled,
            is_eligible=is_eligible,
            income=income,
            min_income_threshold=min_income_threshold,
            max_entitlement_income=max_entitlement_income,
            abatement_income_threshold=abatement_income_threshold,
            earning_rate=earning_rate,
            abatement_rate=abatement_rate,
        )

    def pie_tax(self, pie_income: float, taxable_income: float) -> float:
        """
        Calculates tax on Portfolio Investment Entity (PIE) income.

        Args:
            pie_income: The income from the PIE investment.
            taxable_income: The individual's total taxable income for the year,
                used to determine the Prescribed Investor Rate (PIR).

        Returns:
            The calculated tax on the PIE income. Returns 0 if PIE parameters
            are not available for the year.
        """
        if self.params.pie is None:
            return 0.0

        return calculate_pie_tax(
            pie_income=pie_income,
            taxable_income=taxable_income,
            pie_params=self.params.pie,
        )

    def donation_credit(self, total_donations: float, taxable_income: float) -> float:
        """
        Calculates the tax credit for charitable donations.

        Args:
            total_donations: The total amount of donations made in the year.
            taxable_income: The individual's total taxable income for the year.

        Returns:
            The calculated donation tax credit. Returns 0 if donation credit
            parameters are not available for the year.
        """
        if self.params.donation_credit is None:
            return 0.0

        return calculate_donation_credit(
            total_donations=total_donations,
            taxable_income=taxable_income,
            params=self.params.donation_credit,
        )

    def _calculate_net_income(self, individual_data: dict) -> float:
        """Helper function to calculate net income for a single individual."""
        # This is a simplified calculation and assumes individual_data contains all necessary fields.
        # A more robust implementation would handle missing keys gracefully.

        income = individual_data.get("income", 0)

        # Calculate taxes
        tax = self.income_tax(income)
        # In a real model, we would also include ACC levies etc.

        # Calculate benefits
        # This is highly simplified. A real calculation would need family context.
        benefits = 0.0
        if self.params.ietc:
            benefits += self.ietc(
                taxable_income=income,
                is_wff_recipient=individual_data.get("is_wff_recipient", False),
                is_super_recipient=individual_data.get("is_super_recipient", False),
                is_benefit_recipient=individual_data.get("is_benefit_recipient", False),
            )
        # In a real model, we would add all other relevant benefits (WFF, etc.)

        net_income = income - tax + benefits
        return net_income

    def calculate_emtr(self, individual_data: dict) -> float:
        """
        Calculates the Effective Marginal Tax Rate (EMTR) for an individual.

        The EMTR is the proportion of an additional dollar of earnings that is
        lost to taxes and reduced benefits. It is calculated by simulating the
        individual's net income with and without a small increase in income.

        Args:
            individual_data: A dictionary representing a single person,
                containing all necessary fields for tax and benefit calculations
                (e.g., 'income', 'age', etc.).

        Returns:
            The Effective Marginal Tax Rate as a float (e.g., 0.3 for 30%).
        """
        # 1. Calculate net income at the original income level
        net_income_original = self._calculate_net_income(individual_data)

        # 2. Calculate net income at a slightly higher income level
        data_plus_one = individual_data.copy()
        data_plus_one["income"] = data_plus_one.get("income", 0) + 1
        net_income_plus_one = self._calculate_net_income(data_plus_one)

        # 3. Calculate the change in net income
        change_in_net_income = net_income_plus_one - net_income_original

        # 4. The EMTR is 1 minus the change in net income
        # This represents the fraction of the extra dollar that was "lost".
        emtr = 1 - change_in_net_income

        return emtr

    @classmethod
    def from_year(cls, year: str) -> "TaxCalculator":
        """
        Construct a :class:`TaxCalculator` from stored parameter files.

        This method loads the parameters for a given tax year from the
        corresponding JSON file (e.g., `parameters_2023-2024.json`).

        Args:
            year: The tax year to load parameters for (e.g., "2023-2024").

        Returns:
            A new `TaxCalculator` instance with the loaded parameters.
        """
        params = load_parameters(year)
        return cls(params=params)

calculate_emtr(individual_data)

Calculates the Effective Marginal Tax Rate (EMTR) for an individual.

The EMTR is the proportion of an additional dollar of earnings that is lost to taxes and reduced benefits. It is calculated by simulating the individual's net income with and without a small increase in income.

Parameters:

Name Type Description Default
individual_data dict

A dictionary representing a single person, containing all necessary fields for tax and benefit calculations (e.g., 'income', 'age', etc.).

required

Returns:

Type Description
float

The Effective Marginal Tax Rate as a float (e.g., 0.3 for 30%).

Source code in src/tax_calculator.py
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
def calculate_emtr(self, individual_data: dict) -> float:
    """
    Calculates the Effective Marginal Tax Rate (EMTR) for an individual.

    The EMTR is the proportion of an additional dollar of earnings that is
    lost to taxes and reduced benefits. It is calculated by simulating the
    individual's net income with and without a small increase in income.

    Args:
        individual_data: A dictionary representing a single person,
            containing all necessary fields for tax and benefit calculations
            (e.g., 'income', 'age', etc.).

    Returns:
        The Effective Marginal Tax Rate as a float (e.g., 0.3 for 30%).
    """
    # 1. Calculate net income at the original income level
    net_income_original = self._calculate_net_income(individual_data)

    # 2. Calculate net income at a slightly higher income level
    data_plus_one = individual_data.copy()
    data_plus_one["income"] = data_plus_one.get("income", 0) + 1
    net_income_plus_one = self._calculate_net_income(data_plus_one)

    # 3. Calculate the change in net income
    change_in_net_income = net_income_plus_one - net_income_original

    # 4. The EMTR is 1 minus the change in net income
    # This represents the fraction of the extra dollar that was "lost".
    emtr = 1 - change_in_net_income

    return emtr

donation_credit(total_donations, taxable_income)

Calculates the tax credit for charitable donations.

Parameters:

Name Type Description Default
total_donations float

The total amount of donations made in the year.

required
taxable_income float

The individual's total taxable income for the year.

required

Returns:

Type Description
float

The calculated donation tax credit. Returns 0 if donation credit

float

parameters are not available for the year.

Source code in src/tax_calculator.py
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
def donation_credit(self, total_donations: float, taxable_income: float) -> float:
    """
    Calculates the tax credit for charitable donations.

    Args:
        total_donations: The total amount of donations made in the year.
        taxable_income: The individual's total taxable income for the year.

    Returns:
        The calculated donation tax credit. Returns 0 if donation credit
        parameters are not available for the year.
    """
    if self.params.donation_credit is None:
        return 0.0

    return calculate_donation_credit(
        total_donations=total_donations,
        taxable_income=taxable_income,
        params=self.params.donation_credit,
    )

eitc(is_credit_enabled, is_eligible, income, min_income_threshold, max_entitlement_income, abatement_income_threshold, earning_rate, abatement_rate)

Calculates the Earned Income Tax Credit (EITC).

Parameters:

Name Type Description Default
is_credit_enabled bool

Flag to enable or disable the credit calculation.

required
is_eligible bool

Flag indicating if the individual is eligible for the credit.

required
income float

The income amount to base the calculation on.

required
min_income_threshold float

The income level at which the credit begins.

required
max_entitlement_income float

The income level where the credit reaches its maximum.

required
abatement_income_threshold float

The income level at which the credit begins to abate.

required
earning_rate float

The rate at which the credit is earned during phase-in.

required
abatement_rate float

The rate at which the credit is reduced during phase-out.

required

Returns:

Type Description
float

The calculated EITC amount.

Source code in src/tax_calculator.py
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
def eitc(
    self,
    is_credit_enabled: bool,
    is_eligible: bool,
    income: float,
    min_income_threshold: float,
    max_entitlement_income: float,
    abatement_income_threshold: float,
    earning_rate: float,
    abatement_rate: float,
) -> float:
    """
    Calculates the Earned Income Tax Credit (EITC).

    Args:
        is_credit_enabled: Flag to enable or disable the credit calculation.
        is_eligible: Flag indicating if the individual is eligible for the credit.
        income: The income amount to base the calculation on.
        min_income_threshold: The income level at which the credit begins.
        max_entitlement_income: The income level where the credit reaches its maximum.
        abatement_income_threshold: The income level at which the credit begins to abate.
        earning_rate: The rate at which the credit is earned during phase-in.
        abatement_rate: The rate at which the credit is reduced during phase-out.

    Returns:
        The calculated EITC amount.
    """
    return eitc(
        is_credit_enabled=is_credit_enabled,
        is_eligible=is_eligible,
        income=income,
        min_income_threshold=min_income_threshold,
        max_entitlement_income=max_entitlement_income,
        abatement_income_threshold=abatement_income_threshold,
        earning_rate=earning_rate,
        abatement_rate=abatement_rate,
    )

family_boost_credit(family_income, childcare_costs)

Calculates the FamilyBoost childcare tax credit.

Parameters:

Name Type Description Default
family_income float

The total family income.

required
childcare_costs float

The total childcare costs for the period.

required

Returns:

Type Description
float

The calculated FamilyBoost credit amount.

Source code in src/tax_calculator.py
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
def family_boost_credit(self, family_income: float, childcare_costs: float) -> float:
    """
    Calculates the FamilyBoost childcare tax credit.

    Args:
        family_income: The total family income.
        childcare_costs: The total childcare costs for the period.

    Returns:
        The calculated FamilyBoost credit amount.
    """
    if self.params.family_boost is None:
        return 0.0
    return family_boost_credit(
        family_income=family_income,
        childcare_costs=childcare_costs,
        family_boost_params=self.params.family_boost,
    )

from_year(year) classmethod

Construct a :class:TaxCalculator from stored parameter files.

This method loads the parameters for a given tax year from the corresponding JSON file (e.g., parameters_2023-2024.json).

Parameters:

Name Type Description Default
year str

The tax year to load parameters for (e.g., "2023-2024").

required

Returns:

Type Description
'TaxCalculator'

A new TaxCalculator instance with the loaded parameters.

Source code in src/tax_calculator.py
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
@classmethod
def from_year(cls, year: str) -> "TaxCalculator":
    """
    Construct a :class:`TaxCalculator` from stored parameter files.

    This method loads the parameters for a given tax year from the
    corresponding JSON file (e.g., `parameters_2023-2024.json`).

    Args:
        year: The tax year to load parameters for (e.g., "2023-2024").

    Returns:
        A new `TaxCalculator` instance with the loaded parameters.
    """
    params = load_parameters(year)
    return cls(params=params)

ietc(taxable_income, is_wff_recipient, is_super_recipient, is_benefit_recipient)

Calculate the Independent Earner Tax Credit (IETC).

The IETC is a tax credit for individuals who are not receiving certain other benefits, such as Working for Families or NZ Super.

The calculation is performed by the calcietc function.

Parameters:

Name Type Description Default
taxable_income float

The individual's taxable income.

required
is_wff_recipient bool

Whether the individual is a recipient of Working for Families tax credits.

required
is_super_recipient bool

Whether the individual is a recipient of NZ Superannuation.

required
is_benefit_recipient bool

Whether the individual is a recipient of a main benefit.

required

Returns:

Type Description
float

The amount of IETC the individual is entitled to.

Source code in src/tax_calculator.py
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
def ietc(
    self,
    taxable_income: float,
    is_wff_recipient: bool,
    is_super_recipient: bool,
    is_benefit_recipient: bool,
) -> float:
    """
    Calculate the Independent Earner Tax Credit (IETC).

    The IETC is a tax credit for individuals who are not receiving
    certain other benefits, such as Working for Families or NZ Super.

    The calculation is performed by the `calcietc` function.

    Args:
        taxable_income: The individual's taxable income.
        is_wff_recipient: Whether the individual is a recipient of
            Working for Families tax credits.
        is_super_recipient: Whether the individual is a recipient of
            NZ Superannuation.
        is_benefit_recipient: Whether the individual is a recipient of
            a main benefit.

    Returns:
        The amount of IETC the individual is entitled to.
    """
    if self.params.ietc is None:
        return 0.0
    return calcietc(
        taxable_income=taxable_income,
        is_wff_recipient=is_wff_recipient,
        is_super_recipient=is_super_recipient,
        is_benefit_recipient=is_benefit_recipient,
        ietc_params=self.params.ietc,
    )

income_tax(taxable_income)

Calculate income tax for a given taxable income.

This method uses a progressive tax system with multiple tax brackets. The tax rates and thresholds for these brackets are drawn from params.tax_brackets.

The calculation is performed by the taxit function.

Parameters:

Name Type Description Default
taxable_income float

The amount of income to calculate tax on.

required

Returns:

Type Description
float

The amount of income tax payable.

Source code in src/tax_calculator.py
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
def income_tax(self, taxable_income: float) -> float:
    """
    Calculate income tax for a given taxable income.

    This method uses a progressive tax system with multiple tax brackets.
    The tax rates and thresholds for these brackets are drawn from
    `params.tax_brackets`.

    The calculation is performed by the `taxit` function.

    Args:
        taxable_income: The amount of income to calculate tax on.

    Returns:
        The amount of income tax payable.
    """
    tax_params: TaxBracketParams = self.params.tax_brackets
    return taxit(taxy=taxable_income, params=tax_params)

pie_tax(pie_income, taxable_income)

Calculates tax on Portfolio Investment Entity (PIE) income.

Parameters:

Name Type Description Default
pie_income float

The income from the PIE investment.

required
taxable_income float

The individual's total taxable income for the year, used to determine the Prescribed Investor Rate (PIR).

required

Returns:

Type Description
float

The calculated tax on the PIE income. Returns 0 if PIE parameters

float

are not available for the year.

Source code in src/tax_calculator.py
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
def pie_tax(self, pie_income: float, taxable_income: float) -> float:
    """
    Calculates tax on Portfolio Investment Entity (PIE) income.

    Args:
        pie_income: The income from the PIE investment.
        taxable_income: The individual's total taxable income for the year,
            used to determine the Prescribed Investor Rate (PIR).

    Returns:
        The calculated tax on the PIE income. Returns 0 if PIE parameters
        are not available for the year.
    """
    if self.params.pie is None:
        return 0.0

    return calculate_pie_tax(
        pie_income=pie_income,
        taxable_income=taxable_income,
        pie_params=self.params.pie,
    )

rwt(interest, taxable_income)

Calculate Resident Withholding Tax (RWT) on interest income.

RWT is a tax on interest earned from sources like bank accounts and investments. The tax rate depends on the individual's income tax bracket. This method determines the correct RWT rate based on the provided taxable income and then calculates the RWT amount.

Parameters:

Name Type Description Default
interest float

The amount of interest income subject to RWT.

required
taxable_income float

The individual's total taxable income, used to determine the RWT rate.

required

Returns:

Type Description
float

The amount of RWT payable.

Source code in src/tax_calculator.py
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
def rwt(self, interest: float, taxable_income: float) -> float:
    """
    Calculate Resident Withholding Tax (RWT) on interest income.

    RWT is a tax on interest earned from sources like bank accounts and
    investments. The tax rate depends on the individual's income tax
    bracket. This method determines the correct RWT rate based on the
    provided taxable income and then calculates the RWT amount.

    Args:
        interest: The amount of interest income subject to RWT.
        taxable_income: The individual's total taxable income, used to
            determine the RWT rate.

    Returns:
        The amount of RWT payable.
    """
    tax_brackets = self.params.tax_brackets
    rwt_rates = self.params.rwt

    if rwt_rates is None:
        return 0.0

    # Determine the marginal tax rate to find the corresponding RWT rate.
    # The last rate in the list applies to all income above the last threshold.
    rate = tax_brackets.rates[-1]
    for i, threshold in enumerate(tax_brackets.thresholds):
        if taxable_income <= threshold:
            rate = tax_brackets.rates[i]
            break

    # Map the income tax rate to the corresponding RWT rate.
    rwt_rate = 0.0
    if math.isclose(rate, 0.105):
        rwt_rate = rwt_rates.rwt_rate_10_5
    elif math.isclose(rate, 0.175):
        rwt_rate = rwt_rates.rwt_rate_17_5
    elif math.isclose(rate, 0.30):
        rwt_rate = rwt_rates.rwt_rate_30
    elif math.isclose(rate, 0.33):
        rwt_rate = rwt_rates.rwt_rate_33
    elif math.isclose(rate, 0.39):
        rwt_rate = rwt_rates.rwt_rate_39

    return simrwt(interest, rwt_rate)

Tax Credits

src.tax_credits

calcietc(taxable_income, is_wff_recipient, is_super_recipient, is_benefit_recipient, ietc_params)

Calculates the Independent Earner Tax Credit (IETC).

This function determines the IETC entitlement based on taxable income and eligibility criteria. It replicates the logic of the SAS macro %calcietc.

Parameters:

Name Type Description Default
taxable_income float

The individual's taxable income.

required
is_wff_recipient bool

True if the individual receives Working for Families tax credits.

required
is_super_recipient bool

True if the individual receives superannuation payments.

required
is_benefit_recipient bool

True if the individual receives a main benefit.

required
ietc_params Mapping[str, Any] | IETCParams

Structured IETC parameters.

required

Returns:

Name Type Description
float float

The calculated IETC amount.

Source code in src/tax_credits.py
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
def calcietc(
    taxable_income: float,
    is_wff_recipient: bool,
    is_super_recipient: bool,
    is_benefit_recipient: bool,
    ietc_params: Mapping[str, Any] | IETCParams,
) -> float:
    """
    Calculates the Independent Earner Tax Credit (IETC).

    This function determines the IETC entitlement based on taxable income and
    eligibility criteria. It replicates the logic of the SAS macro `%calcietc`.

    Args:
        taxable_income (float): The individual's taxable income.
        is_wff_recipient (bool): True if the individual receives Working for Families tax credits.
        is_super_recipient (bool): True if the individual receives superannuation payments.
        is_benefit_recipient (bool): True if the individual receives a main benefit.
        ietc_params: Structured IETC parameters.

    Returns:
        float: The calculated IETC amount.
    """
    # IETC is not available to recipients of WFF, superannuation, or main benefits.
    if is_wff_recipient or is_super_recipient or is_benefit_recipient:
        return 0.0

    params = _coerce_ietc(ietc_params)
    income_threshold_min = params.thrin
    income_threshold_max = params.thrab
    max_entitlement = params.ent
    abatement_rate = params.abrate

    # Calculate IETC based on income thresholds.
    if taxable_income <= income_threshold_min:
        return 0.0
    elif taxable_income <= income_threshold_max:
        return max_entitlement
    else:
        # Abate the credit for income above the maximum threshold.
        abatement = (taxable_income - income_threshold_max) * abatement_rate
        return max(0.0, max_entitlement - abatement)

calculate_donation_credit(total_donations, taxable_income, params)

Calculates the tax credit for charitable donations.

Parameters:

Name Type Description Default
total_donations float

The total amount of donations made in the year.

required
taxable_income float

The individual's total taxable income for the year.

required
params DonationCreditParams

The parameters for the donation tax credit.

required

Returns:

Type Description
float

The calculated donation tax credit.

Source code in src/tax_credits.py
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
def calculate_donation_credit(
    total_donations: float,
    taxable_income: float,
    params: DonationCreditParams,
) -> float:
    """
    Calculates the tax credit for charitable donations.

    Args:
        total_donations: The total amount of donations made in the year.
        taxable_income: The individual's total taxable income for the year.
        params: The parameters for the donation tax credit.

    Returns:
        The calculated donation tax credit.
    """
    if total_donations < params.min_donation:
        return 0.0

    eligible_amount = min(total_donations, taxable_income)
    return eligible_amount * params.credit_rate

eitc(is_credit_enabled, is_eligible, income, min_income_threshold, max_entitlement_income, abatement_income_threshold, earning_rate, abatement_rate)

Calculates the Earned Income Tax Credit (EITC).

The EITC calculation has three phases based on income: 1. Phase-in: For income between min_income_threshold and max_entitlement_income, the credit increases at the earning_rate. 2. Plateau: For income between max_entitlement_income and abatement_income_threshold, the credit is at its maximum. 3. Phase-out: For income above abatement_income_threshold, the credit is reduced at the abatement_rate.

This function replicates the logic of the SAS macro %eitc.

Parameters:

Name Type Description Default
is_credit_enabled bool

Flag to enable or disable the credit calculation.

required
is_eligible bool

Flag indicating if the individual is eligible for the credit.

required
income float

The income amount to base the calculation on.

required
min_income_threshold float

The income level at which the credit begins.

required
max_entitlement_income float

The income level where the credit reaches its maximum.

required
abatement_income_threshold float

The income level at which the credit begins to abate.

required
earning_rate float

The rate at which the credit is earned during phase-in.

required
abatement_rate float

The rate at which the credit is reduced during phase-out.

required

Returns:

Type Description
float

The calculated EITC amount.

Source code in src/tax_credits.py
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
def eitc(
    is_credit_enabled: bool,
    is_eligible: bool,
    income: float,
    min_income_threshold: float,
    max_entitlement_income: float,
    abatement_income_threshold: float,
    earning_rate: float,
    abatement_rate: float,
) -> float:
    """
    Calculates the Earned Income Tax Credit (EITC).

    The EITC calculation has three phases based on income:
    1.  **Phase-in:** For income between `min_income_threshold` and
        `max_entitlement_income`, the credit increases at the `earning_rate`.
    2.  **Plateau:** For income between `max_entitlement_income` and
        `abatement_income_threshold`, the credit is at its maximum.
    3.  **Phase-out:** For income above `abatement_income_threshold`, the
        credit is reduced at the `abatement_rate`.

    This function replicates the logic of the SAS macro `%eitc`.

    Args:
        is_credit_enabled: Flag to enable or disable the credit calculation.
        is_eligible: Flag indicating if the individual is eligible for the credit.
        income: The income amount to base the calculation on.
        min_income_threshold: The income level at which the credit begins.
        max_entitlement_income: The income level where the credit reaches its maximum.
        abatement_income_threshold: The income level at which the credit begins to abate.
        earning_rate: The rate at which the credit is earned during phase-in.
        abatement_rate: The rate at which the credit is reduced during phase-out.

    Returns:
        The calculated EITC amount.
    """
    if not is_credit_enabled or not is_eligible:
        return 0.0

    if income <= min_income_threshold:
        return 0.0
    elif income <= max_entitlement_income:
        return earning_rate * (income - min_income_threshold)
    elif income <= abatement_income_threshold:
        return (max_entitlement_income - min_income_threshold) * earning_rate
    else:
        return max(
            0.0,
            (max_entitlement_income - min_income_threshold) * earning_rate
            - (income - abatement_income_threshold) * abatement_rate,
        )

family_boost_credit(family_income, childcare_costs, family_boost_params)

Calculates the FamilyBoost childcare tax credit.

The credit is calculated as 25% of childcare costs, up to a maximum credit amount. The credit is then abated for families with income above a certain threshold.

Parameters:

Name Type Description Default
family_income float

The total family income.

required
childcare_costs float

The total childcare costs for the period.

required
family_boost_params FamilyBoostParams

The parameters for the FamilyBoost credit, including max credit, income thresholds, and abatement rate.

required

Returns:

Type Description
float

The calculated FamilyBoost credit amount.

Source code in src/tax_credits.py
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
def family_boost_credit(
    family_income: float,
    childcare_costs: float,
    family_boost_params: FamilyBoostParams,
) -> float:
    """
    Calculates the FamilyBoost childcare tax credit.

    The credit is calculated as 25% of childcare costs, up to a maximum
    credit amount. The credit is then abated for families with income above
    a certain threshold.

    Args:
        family_income: The total family income.
        childcare_costs: The total childcare costs for the period.
        family_boost_params: The parameters for the FamilyBoost credit,
            including max credit, income thresholds, and abatement rate.

    Returns:
        The calculated FamilyBoost credit amount.
    """
    max_credit = family_boost_params.max_credit
    income_threshold = family_boost_params.income_threshold
    abatement_rate = family_boost_params.abatement_rate
    max_income = family_boost_params.max_income

    if family_income > max_income:
        return 0.0

    credit = min(childcare_costs * 0.25, max_credit)

    if family_income > income_threshold:
        abatement = (family_income - income_threshold) * abatement_rate
        credit = max(0.0, credit - abatement)

    return credit

ACC Levy

src.acc_levy

ACC earner's levy calculations.

calculate_acc_levy(income, levy_rate, max_income)

Calculate the ACC (Accident Compensation Corporation) earner's levy.

The ACC earner's levy is a compulsory payment that helps fund the cost of accidents in New Zealand. It is calculated as a flat rate on income up to a specified maximum.

Parameters:

Name Type Description Default
income float

The annual earnings subject to the levy.

required
levy_rate float

The ACC levy rate, expressed as a decimal (e.g., 1.46% is 0.0146).

required
max_income float

The maximum income on which the levy is charged.

required

Returns:

Type Description
float

The total ACC levy owed for the year.

Source code in src/acc_levy.py
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
def calculate_acc_levy(income: float, levy_rate: float, max_income: float) -> float:
    """
    Calculate the ACC (Accident Compensation Corporation) earner's levy.

    The ACC earner's levy is a compulsory payment that helps fund the cost of
    accidents in New Zealand. It is calculated as a flat rate on income up to
    a specified maximum.

    Args:
        income: The annual earnings subject to the levy.
        levy_rate: The ACC levy rate, expressed as a decimal (e.g., 1.46%
            is 0.0146).
        max_income: The maximum income on which the levy is charged.

    Returns:
        The total ACC levy owed for the year.
    """
    if income <= 0 or levy_rate <= 0 or max_income <= 0:
        return 0.0

    chargeable_income = min(income, max_income)
    return chargeable_income * levy_rate

calculate_payroll_deductions(income, tax_params, levy_rate, levy_max_income)

Calculate total payroll deductions, including income tax and ACC levy.

This function provides a combined calculation of the two main deductions from an individual's income: income tax and the ACC earner's levy.

Parameters:

Name Type Description Default
income float

The annual income.

required
tax_params 'TaxBracketParams'

The tax bracket parameters for the income tax calculation.

required
levy_rate float

The ACC levy rate.

required
levy_max_income float

The maximum income for the ACC levy.

required

Returns:

Type Description
float

The total amount of payroll deductions.

Source code in src/acc_levy.py
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
def calculate_payroll_deductions(
    income: float,
    tax_params: "TaxBracketParams",
    levy_rate: float,
    levy_max_income: float,
) -> float:
    """
    Calculate total payroll deductions, including income tax and ACC levy.

    This function provides a combined calculation of the two main deductions
    from an individual's income: income tax and the ACC earner's levy.

    Args:
        income: The annual income.
        tax_params: The tax bracket parameters for the income tax calculation.
        levy_rate: The ACC levy rate.
        levy_max_income: The maximum income for the ACC levy.

    Returns:
        The total amount of payroll deductions.
    """
    from .microsim import taxit

    income_tax = taxit(income, tax_params)
    levy = calculate_acc_levy(income, levy_rate, levy_max_income)
    return income_tax + levy

Investment Income Tax (PIE)

src.investment_tax

calculate_pie_tax(pie_income, taxable_income, pie_params)

Calculates tax on Portfolio Investment Entity (PIE) income.

This function determines the Prescribed Investor Rate (PIR) based on the individual's taxable income and then calculates the tax on the PIE income.

.. warning:: The current implementation uses a simplified logic based on a single year's income to determine the PIR. The official IRD rules require looking at income from the two preceding years. This implementation should be updated when the definitive two-year lookback logic is clarified.

Parameters:

Name Type Description Default
pie_income float

The income from the PIE investment.

required
taxable_income float

The individual's total taxable income for the year.

required
pie_params PIEParams

The parameters for PIE tax, including rates and thresholds.

required

Returns:

Type Description
float

The calculated tax on the PIE income.

Source code in src/investment_tax.py
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
def calculate_pie_tax(
    pie_income: float,
    taxable_income: float,
    pie_params: PIEParams,
) -> float:
    """
    Calculates tax on Portfolio Investment Entity (PIE) income.

    This function determines the Prescribed Investor Rate (PIR) based on the
    individual's taxable income and then calculates the tax on the PIE income.

    .. warning::
        The current implementation uses a simplified logic based on a single
        year's income to determine the PIR. The official IRD rules require
        looking at income from the two preceding years. This implementation
        should be updated when the definitive two-year lookback logic is
        clarified.

    Args:
        pie_income: The income from the PIE investment.
        taxable_income: The individual's total taxable income for the year.
        pie_params: The parameters for PIE tax, including rates and thresholds.

    Returns:
        The calculated tax on the PIE income.
    """
    if pie_income <= 0:
        return 0.0

    total_income = taxable_income + pie_income

    # Determine the PIR rate based on income thresholds.
    # This is a simplified logic. The official rules are more complex.
    pir = pie_params.rates[-1]  # Default to the highest rate
    for i, taxable_thresh in enumerate(pie_params.taxable_income_thresholds):
        if taxable_income <= taxable_thresh:
            if total_income <= pie_params.taxable_plus_pie_income_thresholds[i]:
                pir = pie_params.rates[i]
                break

    return pie_income * pir

Payroll Deductions (KiwiSaver, Student Loans)

src.payroll_deductions

Helper functions for payroll deductions.

calculate_kiwisaver_contribution(income, rate)

Calculate the employee's KiwiSaver contribution.

KiwiSaver is a voluntary savings scheme to help New Zealanders save for their retirement. This function calculates the employee's contribution based on their income and a specified contribution rate.

Parameters:

Name Type Description Default
income float

The annual income subject to KiwiSaver contributions.

required
rate float

The contribution rate, expressed as a decimal (e.g., 0.03 for 3%).

required

Returns:

Type Description
float

The calculated KiwiSaver contribution. Returns 0.0 for negative or

float

zero income or rate.

Source code in src/payroll_deductions.py
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
def calculate_kiwisaver_contribution(income: float, rate: float) -> float:
    """
    Calculate the employee's KiwiSaver contribution.

    KiwiSaver is a voluntary savings scheme to help New Zealanders save for
    their retirement. This function calculates the employee's contribution
    based on their income and a specified contribution rate.

    Args:
        income: The annual income subject to KiwiSaver contributions.
        rate: The contribution rate, expressed as a decimal (e.g., 0.03 for 3%).

    Returns:
        The calculated KiwiSaver contribution. Returns 0.0 for negative or
        zero income or rate.
    """
    if income <= 0 or rate <= 0:
        return 0.0
    return income * rate

calculate_student_loan_repayment(income, repayment_threshold, repayment_rate)

Calculate the mandatory student loan repayment for a given income.

This function calculates the amount of student loan repayment required based on an individual's income. Repayments are only required if the income is above a certain threshold.

Parameters:

Name Type Description Default
income float

The annual taxable income.

required
repayment_threshold float

The income threshold above which repayments apply.

required
repayment_rate float

The rate applied to income above the threshold, expressed as a decimal.

required

Returns:

Type Description
float

The calculated student loan repayment amount.

Source code in src/payroll_deductions.py
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
def calculate_student_loan_repayment(income: float, repayment_threshold: float, repayment_rate: float) -> float:
    """
    Calculate the mandatory student loan repayment for a given income.

    This function calculates the amount of student loan repayment required
    based on an individual's income. Repayments are only required if the
    income is above a certain threshold.

    Args:
        income: The annual taxable income.
        repayment_threshold: The income threshold above which repayments apply.
        repayment_rate: The rate applied to income above the threshold,
            expressed as a decimal.

    Returns:
        The calculated student loan repayment amount.
    """
    if income <= repayment_threshold or repayment_rate <= 0:
        return 0.0
    return (income - repayment_threshold) * repayment_rate

Benefit Calculations

Benefit Rule Classes

src.benefit_rules

AccommodationSupplementRule dataclass

Bases: Rule

A rule to calculate the Accommodation Supplement.

The Accommodation Supplement is a weekly payment that helps people with their rent, board, or mortgage payments.

This rule calculates the Accommodation Supplement entitlement based on household income, housing costs, region, and number of dependent children.

The calculation is performed by the calculate_accommodation_supplement function.

Source code in src/benefit_rules.py
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
@register_rule
@dataclass
class AccommodationSupplementRule(Rule):
    """A rule to calculate the Accommodation Supplement.

    The Accommodation Supplement is a weekly payment that helps people with
    their rent, board, or mortgage payments.

    This rule calculates the Accommodation Supplement entitlement based on
    household income, housing costs, region, and number of dependent children.

    The calculation is performed by the `calculate_accommodation_supplement`
    function.
    """

    name: str = "AccommodationSupplementRule"
    enabled: bool = True
    as_params: Union[AccommodationSupplementParams, None] = None

    def __call__(self, data: dict[str, Any]) -> None:
        """Calculate Accommodation Supplement entitlement and add it to the DataFrame."""
        as_params = data["params"].accommodation_supplement
        if not as_params:
            return
        data["df"]["accommodation_supplement_entitlement"] = data["df"].apply(
            lambda row: calculate_accommodation_supplement(
                household_income=(row["total_individual_income_weekly"] * row["household_size"]),
                housing_costs=row["housing_costs"],
                region=row["region"],
                num_dependent_children=row["num_children"],
                as_params=as_params,
            ),
            axis=1,
        )

__call__(data)

Calculate Accommodation Supplement entitlement and add it to the DataFrame.

Source code in src/benefit_rules.py
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
def __call__(self, data: dict[str, Any]) -> None:
    """Calculate Accommodation Supplement entitlement and add it to the DataFrame."""
    as_params = data["params"].accommodation_supplement
    if not as_params:
        return
    data["df"]["accommodation_supplement_entitlement"] = data["df"].apply(
        lambda row: calculate_accommodation_supplement(
            household_income=(row["total_individual_income_weekly"] * row["household_size"]),
            housing_costs=row["housing_costs"],
            region=row["region"],
            num_dependent_children=row["num_children"],
            as_params=as_params,
        ),
        axis=1,
    )

BSTCRule dataclass

Bases: Rule

A rule to calculate the Best Start Tax Credit (BSTC).

The BSTC is a payment for families with a new baby. It is designed to help with the costs of raising a child in their first few years.

This rule calculates the BSTC entitlement based on family income and the age of the youngest child.

The calculation is performed by the calculate_bstc function.

Source code in src/benefit_rules.py
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
@register_rule
@dataclass
class BSTCRule(Rule):
    """A rule to calculate the Best Start Tax Credit (BSTC).

    The BSTC is a payment for families with a new baby. It is designed to
    help with the costs of raising a child in their first few years.

    This rule calculates the BSTC entitlement based on family income and the
    age of the youngest child.

    The calculation is performed by the `calculate_bstc` function.
    """

    name: str = "BSTCRule"
    enabled: bool = True
    bstc_params: Union[BSTCParams, None] = None

    def __call__(self, data: dict[str, Any]) -> None:
        """Calculate BSTC entitlement and add it to the DataFrame."""
        bstc_params = data["params"].bstc
        if not bstc_params:
            return
        df = data["df"]
        # Assume the first child's age is the relevant one for this calculation
        df["bstc_entitlement"] = df.apply(
            lambda row: calculate_bstc(
                family_income=row["familyinc"],
                child_age=row["ages_of_children"][0]
                if row.get("ages_of_children") and len(row["ages_of_children"]) > 0
                else 99,
                bstc_params=bstc_params,
            ),
            axis=1,
        )

__call__(data)

Calculate BSTC entitlement and add it to the DataFrame.

Source code in src/benefit_rules.py
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
def __call__(self, data: dict[str, Any]) -> None:
    """Calculate BSTC entitlement and add it to the DataFrame."""
    bstc_params = data["params"].bstc
    if not bstc_params:
        return
    df = data["df"]
    # Assume the first child's age is the relevant one for this calculation
    df["bstc_entitlement"] = df.apply(
        lambda row: calculate_bstc(
            family_income=row["familyinc"],
            child_age=row["ages_of_children"][0]
            if row.get("ages_of_children") and len(row["ages_of_children"]) > 0
            else 99,
            bstc_params=bstc_params,
        ),
        axis=1,
    )

DisabilityAllowanceRule dataclass

Bases: Rule

A rule to calculate the Disability Allowance.

The Disability Allowance is a weekly payment for people who have regular, ongoing costs because of a disability.

This rule calculates the Disability Allowance entitlement based on income, disability-related costs, and family situation.

The calculation is performed by the calculate_disability_allowance function.

Source code in src/benefit_rules.py
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
@register_rule
@dataclass
class DisabilityAllowanceRule(Rule):
    """A rule to calculate the Disability Allowance.

    The Disability Allowance is a weekly payment for people who have regular,
    ongoing costs because of a disability.

    This rule calculates the Disability Allowance entitlement based on income,
    disability-related costs, and family situation.

    The calculation is performed by the `calculate_disability_allowance`
    function.
    """

    name: str = "DisabilityAllowanceRule"
    enabled: bool = True
    disability_allowance_params: Union[DisabilityAllowanceParams, None] = None

    def __call__(self, data: dict[str, Any]) -> None:
        """Calculate Disability Allowance entitlement and add it to the DataFrame."""
        disability_allowance_params = data["params"].disability_allowance
        if not disability_allowance_params:
            return
        data["df"]["disability_allowance_entitlement"] = data["df"].apply(
            lambda row: calculate_disability_allowance(
                weekly_income=row["total_individual_income_weekly"],
                disability_costs=row.get("disability_costs", 0),
                family_situation=row["family_household_type"],
                params=disability_allowance_params,
            ),
            axis=1,
        )

__call__(data)

Calculate Disability Allowance entitlement and add it to the DataFrame.

Source code in src/benefit_rules.py
86
87
88
89
90
91
92
93
94
95
96
97
98
99
def __call__(self, data: dict[str, Any]) -> None:
    """Calculate Disability Allowance entitlement and add it to the DataFrame."""
    disability_allowance_params = data["params"].disability_allowance
    if not disability_allowance_params:
        return
    data["df"]["disability_allowance_entitlement"] = data["df"].apply(
        lambda row: calculate_disability_allowance(
            weekly_income=row["total_individual_income_weekly"],
            disability_costs=row.get("disability_costs", 0),
            family_situation=row["family_household_type"],
            params=disability_allowance_params,
        ),
        axis=1,
    )

FTCRule dataclass

Bases: Rule

A rule to calculate the Family Tax Credit (FTC).

The FTC is a payment for families with dependent children. It is designed to help with the costs of raising a family.

This rule calculates the FTC entitlement based on family income and the number of children.

The calculation is performed by the calculate_ftc function.

Source code in src/benefit_rules.py
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
@register_rule
@dataclass
class FTCRule(Rule):
    """A rule to calculate the Family Tax Credit (FTC).

    The FTC is a payment for families with dependent children. It is designed
    to help with the costs of raising a family.

    This rule calculates the FTC entitlement based on family income and the
    number of children.

    The calculation is performed by the `calculate_ftc` function.
    """

    name: str = "FTCRule"
    enabled: bool = True
    ftc_params: Union[FTCParams, None] = None

    def __call__(self, data: dict[str, Any]) -> None:
        """Calculate FTC entitlement and add it to the DataFrame."""
        ftc_params = data["params"].ftc
        if not ftc_params:
            return
        df = data["df"]
        df["ftc_entitlement"] = df.apply(
            lambda row: calculate_ftc(
                family_income=row["familyinc"],
                num_children=row["num_children"],
                ftc_params=ftc_params,
            ),
            axis=1,
        )

__call__(data)

Calculate FTC entitlement and add it to the DataFrame.

Source code in src/benefit_rules.py
189
190
191
192
193
194
195
196
197
198
199
200
201
202
def __call__(self, data: dict[str, Any]) -> None:
    """Calculate FTC entitlement and add it to the DataFrame."""
    ftc_params = data["params"].ftc
    if not ftc_params:
        return
    df = data["df"]
    df["ftc_entitlement"] = df.apply(
        lambda row: calculate_ftc(
            family_income=row["familyinc"],
            num_children=row["num_children"],
            ftc_params=ftc_params,
        ),
        axis=1,
    )

IWTCRule dataclass

Bases: Rule

A rule to calculate the In-Work Tax Credit (IWTC).

The IWTC is a payment for working families with dependent children. It is designed to help make work pay for low to middle-income families.

This rule calculates the IWTC entitlement based on family income, number of children, and hours worked.

The calculation is performed by the calculate_iwtc function.

Source code in src/benefit_rules.py
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
@register_rule
@dataclass
class IWTCRule(Rule):
    """A rule to calculate the In-Work Tax Credit (IWTC).

    The IWTC is a payment for working families with dependent children. It is
    designed to help make work pay for low to middle-income families.

    This rule calculates the IWTC entitlement based on family income, number
    of children, and hours worked.

    The calculation is performed by the `calculate_iwtc` function.
    """

    name: str = "IWTCRule"
    enabled: bool = True
    iwtc_params: Union[IWTCParams, None] = None

    def __call__(self, data: dict[str, Any]) -> None:
        """Calculate IWTC entitlement and add it to the DataFrame."""
        iwtc_params = data["params"].iwtc
        if not iwtc_params:
            return
        df = data["df"]
        df["iwtc_entitlement"] = df.apply(
            lambda row: calculate_iwtc(
                family_income=row["familyinc"],
                num_children=row["num_children"],
                hours_worked=row["hours_worked"],
                iwtc_params=iwtc_params,
            ),
            axis=1,
        )

__call__(data)

Calculate IWTC entitlement and add it to the DataFrame.

Source code in src/benefit_rules.py
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
def __call__(self, data: dict[str, Any]) -> None:
    """Calculate IWTC entitlement and add it to the DataFrame."""
    iwtc_params = data["params"].iwtc
    if not iwtc_params:
        return
    df = data["df"]
    df["iwtc_entitlement"] = df.apply(
        lambda row: calculate_iwtc(
            family_income=row["familyinc"],
            num_children=row["num_children"],
            hours_worked=row["hours_worked"],
            iwtc_params=iwtc_params,
        ),
        axis=1,
    )

JSSRule dataclass

Bases: Rule

A rule to calculate Jobseeker Support (JSS).

JSS is a weekly payment for people who are not in full-time employment, are available for and looking for work, or are unable to work due to a health condition, injury, or disability.

This rule calculates the JSS entitlement based on an individual's income, marital status, and number of dependent children.

The calculation is performed by the calculate_jss function.

Source code in src/benefit_rules.py
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
@register_rule
@dataclass
class JSSRule(Rule):
    """A rule to calculate Jobseeker Support (JSS).

    JSS is a weekly payment for people who are not in full-time employment,
    are available for and looking for work, or are unable to work due to a
    health condition, injury, or disability.

    This rule calculates the JSS entitlement based on an individual's income,
    marital status, and number of dependent children.

    The calculation is performed by the `calculate_jss` function.
    """

    name: str = "JSSRule"
    enabled: bool = True
    jss_params: Union[JSSParams, None] = None

    def __call__(self, data: dict[str, Any]) -> None:
        """Calculate JSS entitlement and add it to the DataFrame."""
        jss_params = data["params"].jss
        if not jss_params:
            return
        data["df"]["jss_entitlement"] = data["df"].apply(
            lambda row: calculate_jss(
                individual_income=row["total_individual_income_weekly"],
                is_single=row["marital_status"] == "Single",
                is_partnered=row["marital_status"] == "Married",
                num_dependent_children=row["num_children"],
                jss_params=jss_params,
            ),
            axis=1,
        )

__call__(data)

Calculate JSS entitlement and add it to the DataFrame.

Source code in src/benefit_rules.py
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
def __call__(self, data: dict[str, Any]) -> None:
    """Calculate JSS entitlement and add it to the DataFrame."""
    jss_params = data["params"].jss
    if not jss_params:
        return
    data["df"]["jss_entitlement"] = data["df"].apply(
        lambda row: calculate_jss(
            individual_income=row["total_individual_income_weekly"],
            is_single=row["marital_status"] == "Single",
            is_partnered=row["marital_status"] == "Married",
            num_dependent_children=row["num_children"],
            jss_params=jss_params,
        ),
        axis=1,
    )

MFTCRule dataclass

Bases: Rule

A rule to calculate the Minimum Family Tax Credit (MFTC).

The MFTC is a payment for working families who would otherwise be better off on a benefit. It tops up their after-tax income to a guaranteed minimum amount.

This rule calculates the MFTC entitlement based on family income and tax paid.

The calculation is performed by the calculate_mftc function.

Source code in src/benefit_rules.py
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
@dataclass
class MFTCRule(Rule):
    """A rule to calculate the Minimum Family Tax Credit (MFTC).

    The MFTC is a payment for working families who would otherwise be better
    off on a benefit. It tops up their after-tax income to a guaranteed
    minimum amount.

    This rule calculates the MFTC entitlement based on family income and tax
    paid.

    The calculation is performed by the `calculate_mftc` function.
    """

    name: str = "MFTCRule"
    enabled: bool = True
    mftc_params: Union[MFTCParams, None] = None

    def __call__(self, data: dict[str, Any]) -> None:
        """Calculate MFTC entitlement and add it to the DataFrame."""
        mftc_params = data["params"].mftc
        if not mftc_params:
            return
        df = data["df"]
        df["mftc_entitlement"] = df.apply(
            lambda row: calculate_mftc(
                family_income=row["familyinc"],
                tax_paid=row["tax_liability"],
                mftc_params=mftc_params,
            ),
            axis=1,
        )

__call__(data)

Calculate MFTC entitlement and add it to the DataFrame.

Source code in src/benefit_rules.py
120
121
122
123
124
125
126
127
128
129
130
131
132
133
def __call__(self, data: dict[str, Any]) -> None:
    """Calculate MFTC entitlement and add it to the DataFrame."""
    mftc_params = data["params"].mftc
    if not mftc_params:
        return
    df = data["df"]
    df["mftc_entitlement"] = df.apply(
        lambda row: calculate_mftc(
            family_income=row["familyinc"],
            tax_paid=row["tax_liability"],
            mftc_params=mftc_params,
        ),
        axis=1,
    )

SLPRule dataclass

Bases: Rule

A rule to calculate Supported Living Payment (SLP).

SLP is a weekly payment for people who have, or are caring for someone with, a significant health condition, injury, or disability.

This rule calculates the SLP entitlement based on an individual's income, marital status, and disability status.

The calculation is performed by the calculate_slp function.

Source code in src/benefit_rules.py
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
@register_rule
@dataclass
class SLPRule(Rule):
    """A rule to calculate Supported Living Payment (SLP).

    SLP is a weekly payment for people who have, or are caring for someone
    with, a significant health condition, injury, or disability.

    This rule calculates the SLP entitlement based on an individual's income,
    marital status, and disability status.

    The calculation is performed by the `calculate_slp` function.
    """

    name: str = "SLPRule"
    enabled: bool = True
    slp_params: Union[SLPParams, None] = None

    def __call__(self, data: dict[str, Any]) -> None:
        """Calculate SLP entitlement and add it to the DataFrame."""
        slp_params = data["params"].slp
        if not slp_params:
            return
        data["df"]["slp_entitlement"] = data["df"].apply(
            lambda row: calculate_slp(
                individual_income=row["total_individual_income_weekly"],
                is_single=row["marital_status"] == "Single",
                is_partnered=row["marital_status"] == "Married",
                is_disabled=row["disability_status"],
                slp_params=slp_params,
            ),
            axis=1,
        )

__call__(data)

Calculate SLP entitlement and add it to the DataFrame.

Source code in src/benefit_rules.py
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
def __call__(self, data: dict[str, Any]) -> None:
    """Calculate SLP entitlement and add it to the DataFrame."""
    slp_params = data["params"].slp
    if not slp_params:
        return
    data["df"]["slp_entitlement"] = data["df"].apply(
        lambda row: calculate_slp(
            individual_income=row["total_individual_income_weekly"],
            is_single=row["marital_status"] == "Single",
            is_partnered=row["marital_status"] == "Married",
            is_disabled=row["disability_status"],
            slp_params=slp_params,
        ),
        axis=1,
    )

SPSRule dataclass

Bases: Rule

A rule to calculate Sole Parent Support (SPS).

SPS is a weekly payment for single parents with dependent children.

This rule calculates the SPS entitlement based on an individual's income and the number of dependent children.

The calculation is performed by the calculate_sps function.

Source code in src/benefit_rules.py
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
@register_rule
@dataclass
class SPSRule(Rule):
    """A rule to calculate Sole Parent Support (SPS).

    SPS is a weekly payment for single parents with dependent children.

    This rule calculates the SPS entitlement based on an individual's income
    and the number of dependent children.

    The calculation is performed by the `calculate_sps` function.
    """

    name: str = "SPSRule"
    enabled: bool = True
    sps_params: Union[SPSParams, None] = None

    def __call__(self, data: dict[str, Any]) -> None:
        """Calculate SPS entitlement and add it to the DataFrame."""
        sps_params = data["params"].sps
        if not sps_params:
            return
        data["df"]["sps_entitlement"] = data["df"].apply(
            lambda row: calculate_sps(
                individual_income=row["total_individual_income_weekly"],
                num_dependent_children=row["num_children"],
                sps_params=sps_params,
            ),
            axis=1,
        )

__call__(data)

Calculate SPS entitlement and add it to the DataFrame.

Source code in src/benefit_rules.py
299
300
301
302
303
304
305
306
307
308
309
310
311
def __call__(self, data: dict[str, Any]) -> None:
    """Calculate SPS entitlement and add it to the DataFrame."""
    sps_params = data["params"].sps
    if not sps_params:
        return
    data["df"]["sps_entitlement"] = data["df"].apply(
        lambda row: calculate_sps(
            individual_income=row["total_individual_income_weekly"],
            num_dependent_children=row["num_children"],
            sps_params=sps_params,
        ),
        axis=1,
    )

WEPRule dataclass

Bases: Rule

A rule to calculate the Winter Energy Payment (WEP).

The WEP is a payment to help with the cost of heating during the winter months. It is available to people receiving certain benefits or superannuation.

This rule calculates the WEP entitlement based on eligibility, marital status, and number of dependent children.

The calculation is performed by the calculate_wep function.

Source code in src/benefit_rules.py
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
@register_rule
@dataclass
class WEPRule(Rule):
    """A rule to calculate the Winter Energy Payment (WEP).

    The WEP is a payment to help with the cost of heating during the winter
    months. It is available to people receiving certain benefits or
    superannuation.

    This rule calculates the WEP entitlement based on eligibility, marital
    status, and number of dependent children.

    The calculation is performed by the `calculate_wep` function.
    """

    name: str = "WEPRule"
    enabled: bool = True
    wep_params: Union[WEPParams, None] = None

    def __call__(self, data: dict[str, Any]) -> None:
        """Calculate WEP entitlement and add it to the DataFrame."""
        wep_params = data["params"].wep
        if not wep_params:
            return
        df = data["df"]
        df["wep_entitlement"] = df.apply(
            lambda row: calculate_wep(
                is_eligible=row.get("is_jss_recipient", False)
                or row.get("is_sps_recipient", False)
                or row.get("is_slp_recipient", False)
                or row.get("is_nz_super_recipient", False),
                is_single=row["marital_status"] == "Single",
                is_partnered=row["marital_status"] == "Married",
                num_dependent_children=row["num_children"],
                wep_params=wep_params,
            ),
            axis=1,
        )

__call__(data)

Calculate WEP entitlement and add it to the DataFrame.

Source code in src/benefit_rules.py
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
def __call__(self, data: dict[str, Any]) -> None:
    """Calculate WEP entitlement and add it to the DataFrame."""
    wep_params = data["params"].wep
    if not wep_params:
        return
    df = data["df"]
    df["wep_entitlement"] = df.apply(
        lambda row: calculate_wep(
            is_eligible=row.get("is_jss_recipient", False)
            or row.get("is_sps_recipient", False)
            or row.get("is_slp_recipient", False)
            or row.get("is_nz_super_recipient", False),
            is_single=row["marital_status"] == "Single",
            is_partnered=row["marital_status"] == "Married",
            num_dependent_children=row["num_children"],
            wep_params=wep_params,
        ),
        axis=1,
    )

Benefit Calculation Functions

src.benefits

calculate_accommodation_supplement(household_income, housing_costs, region, num_dependent_children, as_params)

Calculate the Accommodation Supplement entitlement.

The Accommodation Supplement is a weekly payment that helps people with their rent, board, or mortgage payments. The entitlement is based on household income, housing costs, region, and the number of dependent children.

Parameters:

Name Type Description Default
household_income float

The total weekly income of the household.

required
housing_costs float

The weekly housing costs.

required
region str

The region where the household is located.

required
num_dependent_children int

The number of dependent children in the household.

required
as_params AccommodationSupplementParams

The parameters for the Accommodation Supplement.

required

Returns:

Type Description
float

The weekly Accommodation Supplement entitlement.

Source code in src/benefits.py
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
def calculate_accommodation_supplement(
    household_income: float,
    housing_costs: float,
    region: str,
    num_dependent_children: int,
    as_params: AccommodationSupplementParams,
) -> float:
    """Calculate the Accommodation Supplement entitlement.

    The Accommodation Supplement is a weekly payment that helps people with
    their rent, board, or mortgage payments. The entitlement is based on
    household income, housing costs, region, and the number of dependent
    children.

    Args:
        household_income: The total weekly income of the household.
        housing_costs: The weekly housing costs.
        region: The region where the household is located.
        num_dependent_children: The number of dependent children in the
            household.
        as_params: The parameters for the Accommodation Supplement.

    Returns:
        The weekly Accommodation Supplement entitlement.
    """
    family_type = "single_no_children"
    if num_dependent_children > 0:
        family_type = "with_children"

    income_threshold = as_params.income_thresholds.get(family_type, 0.0)
    max_entitlement = as_params.max_entitlement_rates.get(region, {}).get(family_type, 0.0)

    initial_entitlement = max(
        0.0, (housing_costs - as_params.housing_cost_threshold) * as_params.housing_cost_contribution_rate
    )
    initial_entitlement = min(initial_entitlement, max_entitlement)

    if household_income > income_threshold:
        abatement = (household_income - income_threshold) * as_params.abatement_rate
        return max(0.0, initial_entitlement - abatement)
    return initial_entitlement

calculate_bstc(family_income, child_age, bstc_params)

Calculate the Best Start Tax Credit (BSTC) entitlement.

The BSTC is a payment for families with a new baby. It is designed to help with the costs of raising a child in their first few years. The entitlement is based on family income and the age of the youngest child.

Parameters:

Name Type Description Default
family_income float

The total annual family income.

required
child_age int

The age of the youngest child in years.

required
bstc_params BSTCParams

The parameters for the BSTC.

required

Returns:

Type Description
float

The annual BSTC entitlement.

Source code in src/benefits.py
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
def calculate_bstc(
    family_income: float,
    child_age: int,
    bstc_params: BSTCParams,
) -> float:
    """Calculate the Best Start Tax Credit (BSTC) entitlement.

    The BSTC is a payment for families with a new baby. It is designed to
    help with the costs of raising a child in their first few years. The
    entitlement is based on family income and the age of the youngest child.

    Args:
        family_income: The total annual family income.
        child_age: The age of the youngest child in years.
        bstc_params: The parameters for the BSTC.

    Returns:
        The annual BSTC entitlement.
    """
    if child_age > bstc_params.max_age:
        return 0.0

    base_rate = bstc_params.amount

    if child_age >= 1:
        return _apply_abatement(
            base_rate,
            family_income,
            bstc_params.threshold,
            bstc_params.rate,
        )
    return base_rate

calculate_child_support(liable_income, cs_params)

Calculate child support payments based on liable income.

.. warning:: This is a simplified implementation and does not reflect the full complexity of the official formula, which includes the other parent's income, care arrangements, and other factors.

Child support is a payment made by a parent who does not live with their child to the parent or caregiver who does. This function calculates the amount of child support payable based on the liable parent's income.

Parameters:

Name Type Description Default
liable_income float

The liable parent's annual income.

required
cs_params ChildSupportParams

The parameters for child support.

required

Returns:

Type Description
float

The amount of child support payable.

Source code in src/benefits.py
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
def calculate_child_support(liable_income: float, cs_params: ChildSupportParams) -> float:
    """Calculate child support payments based on liable income.

    .. warning::
        This is a simplified implementation and does not reflect the full
        complexity of the official formula, which includes the other parent's
        income, care arrangements, and other factors.

    Child support is a payment made by a parent who does not live with their
    child to the parent or caregiver who does. This function calculates the
    amount of child support payable based on the liable parent's income.

    Args:
        liable_income: The liable parent's annual income.
        cs_params: The parameters for child support.

    Returns:
        The amount of child support payable.
    """
    if not cs_params.enabled:
        return 0.0

    child_support_income = max(0.0, liable_income - cs_params.living_allowance)
    return child_support_income * cs_params.support_rate

calculate_disability_allowance(weekly_income, disability_costs, family_situation, params)

Calculate the Disability Allowance entitlement.

The Disability Allowance is a weekly payment for people who have regular, ongoing costs because of a disability.

Parameters:

Name Type Description Default
weekly_income float

The individual's or couple's weekly income before tax.

required
disability_costs float

The weekly costs due to disability.

required
family_situation str

The family situation of the person, which determines the income threshold.

required
params DisabilityAllowanceParams

The parameters for the Disability Allowance.

required

Returns:

Type Description
float

The weekly Disability Allowance entitlement.

Source code in src/benefits.py
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
def calculate_disability_allowance(
    weekly_income: float,
    disability_costs: float,
    family_situation: str,
    params: DisabilityAllowanceParams,
) -> float:
    """Calculate the Disability Allowance entitlement.

    The Disability Allowance is a weekly payment for people who have regular,
    ongoing costs because of a disability.

    Args:
        weekly_income: The individual's or couple's weekly income before tax.
        disability_costs: The weekly costs due to disability.
        family_situation: The family situation of the person, which determines
            the income threshold.
        params: The parameters for the Disability Allowance.

    Returns:
        The weekly Disability Allowance entitlement.
    """
    income_threshold = params.income_thresholds.get(family_situation)
    if income_threshold is None or weekly_income > income_threshold:
        return 0.0

    return min(disability_costs, params.max_payment)

calculate_ftc(family_income, num_children, ftc_params)

Calculate the Family Tax Credit (FTC) entitlement.

The FTC is a payment for families with dependent children. It is designed to help with the costs of raising a family. The entitlement is based on family income and the number of children.

Parameters:

Name Type Description Default
family_income float

The total annual family income.

required
num_children int

The number of dependent children.

required
ftc_params FTCParams

The parameters for the FTC.

required

Returns:

Type Description
float

The annual FTC entitlement.

Source code in src/benefits.py
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
def calculate_ftc(
    family_income: float,
    num_children: int,
    ftc_params: FTCParams,
) -> float:
    """Calculate the Family Tax Credit (FTC) entitlement.

    The FTC is a payment for families with dependent children. It is designed
    to help with the costs of raising a family. The entitlement is based on
    family income and the number of children.

    Args:
        family_income: The total annual family income.
        num_children: The number of dependent children.
        ftc_params: The parameters for the FTC.

    Returns:
        The annual FTC entitlement.
    """
    if num_children == 0:
        return 0.0

    base_rate = ftc_params.base_rate
    base_rate += (num_children - 1) * ftc_params.child_rate

    return _apply_abatement(
        base_rate,
        family_income,
        ftc_params.income_threshold,
        ftc_params.abatement_rate,
    )

calculate_iwtc(family_income, num_children, hours_worked, iwtc_params)

Calculate the In-Work Tax Credit (IWTC) entitlement.

The IWTC is a payment for working families with dependent children. It is designed to help make work pay for low to middle-income families. The entitlement is based on family income, the number of children, and the hours worked.

Parameters:

Name Type Description Default
family_income float

The total annual family income.

required
num_children int

The number of dependent children.

required
hours_worked int

The number of hours worked per week.

required
iwtc_params IWTCParams

The parameters for the IWTC.

required

Returns:

Type Description
float

The annual IWTC entitlement.

Source code in src/benefits.py
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
def calculate_iwtc(
    family_income: float,
    num_children: int,
    hours_worked: int,
    iwtc_params: IWTCParams,
) -> float:
    """Calculate the In-Work Tax Credit (IWTC) entitlement.

    The IWTC is a payment for working families with dependent children. It is
    designed to help make work pay for low to middle-income families. The
    entitlement is based on family income, the number of children, and the
    hours worked.

    Args:
        family_income: The total annual family income.
        num_children: The number of dependent children.
        hours_worked: The number of hours worked per week.
        iwtc_params: The parameters for the IWTC.

    Returns:
        The annual IWTC entitlement.
    """
    if num_children == 0:
        return 0.0

    if hours_worked < iwtc_params.min_hours_worked:
        return 0.0

    base_rate = iwtc_params.base_rate
    base_rate += (num_children - 1) * iwtc_params.child_rate

    return _apply_abatement(
        base_rate,
        family_income,
        iwtc_params.income_threshold,
        iwtc_params.abatement_rate,
    )

calculate_jss(individual_income, is_single, is_partnered, num_dependent_children, jss_params)

Calculate the Jobseeker Support (JSS) entitlement.

JSS is a weekly payment for people who are not in full-time employment. The entitlement is based on the individual's income, marital status, and the number of dependent children.

Parameters:

Name Type Description Default
individual_income float

The individual's weekly income.

required
is_single bool

Whether the individual is single.

required
is_partnered bool

Whether the individual is partnered.

required
num_dependent_children int

The number of dependent children.

required
jss_params JSSParams

The parameters for JSS.

required

Returns:

Type Description
float

The weekly JSS entitlement.

Source code in src/benefits.py
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
def calculate_jss(
    individual_income: float,
    is_single: bool,
    is_partnered: bool,
    num_dependent_children: int,
    jss_params: JSSParams,
) -> float:
    """Calculate the Jobseeker Support (JSS) entitlement.

    JSS is a weekly payment for people who are not in full-time employment.
    The entitlement is based on the individual's income, marital status, and
    the number of dependent children.

    Args:
        individual_income: The individual's weekly income.
        is_single: Whether the individual is single.
        is_partnered: Whether the individual is partnered.
        num_dependent_children: The number of dependent children.
        jss_params: The parameters for JSS.

    Returns:
        The weekly JSS entitlement.
    """
    base_rate = 0.0
    if is_single:
        base_rate = jss_params.single_rate
    elif is_partnered:
        base_rate = jss_params.couple_rate
    base_rate += num_dependent_children * jss_params.child_rate

    if individual_income > jss_params.income_abatement_threshold:
        abatement = (individual_income - jss_params.income_abatement_threshold) * jss_params.abatement_rate
        return max(0.0, base_rate - abatement)
    return base_rate

calculate_mftc(family_income, tax_paid, mftc_params)

Calculate the Minimum Family Tax Credit (MFTC) entitlement.

The MFTC is a payment for working families who would otherwise be better off on a benefit. It tops up their after-tax income to a guaranteed minimum amount.

Parameters:

Name Type Description Default
family_income float

The total annual family income.

required
tax_paid float

The amount of tax paid by the family.

required
mftc_params MFTCParams

The parameters for the MFTC.

required

Returns:

Type Description
float

The annual MFTC entitlement.

Source code in src/benefits.py
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
def calculate_mftc(
    family_income: float,
    tax_paid: float,
    mftc_params: MFTCParams,
) -> float:
    """Calculate the Minimum Family Tax Credit (MFTC) entitlement.

    The MFTC is a payment for working families who would otherwise be better
    off on a benefit. It tops up their after-tax income to a guaranteed
    minimum amount.

    Args:
        family_income: The total annual family income.
        tax_paid: The amount of tax paid by the family.
        mftc_params: The parameters for the MFTC.

    Returns:
        The annual MFTC entitlement.
    """
    guaranteed_income = mftc_params.guaranteed_income
    net_income = family_income - tax_paid

    if net_income >= guaranteed_income:
        return 0.0

    return guaranteed_income - net_income

calculate_ppl(weeks_taken, ppl_params)

Calculate Paid Parental Leave (PPL) payments.

PPL is a payment for eligible parents to help them take time off work to care for a new baby or a child under six who has come into their care.

Parameters:

Name Type Description Default
weeks_taken int

The number of weeks of PPL taken.

required
ppl_params PPLParams

The parameters for PPL.

required

Returns:

Type Description
float

The total PPL payment.

Source code in src/benefits.py
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
def calculate_ppl(weeks_taken: int, ppl_params: PPLParams) -> float:
    """Calculate Paid Parental Leave (PPL) payments.

    PPL is a payment for eligible parents to help them take time off work to
    care for a new baby or a child under six who has come into their care.

    Args:
        weeks_taken: The number of weeks of PPL taken.
        ppl_params: The parameters for PPL.

    Returns:
        The total PPL payment.
    """
    if not ppl_params.enabled:
        return 0.0

    weeks = max(0, min(weeks_taken, ppl_params.max_weeks))
    return weeks * ppl_params.weekly_rate

calculate_slp(individual_income, is_single, is_partnered, is_disabled, slp_params)

Calculate the Supported Living Payment (SLP) entitlement.

SLP is a weekly payment for people who have, or are caring for someone with, a significant health condition, injury, or disability. The entitlement is based on the individual's income, marital status, and disability status.

Parameters:

Name Type Description Default
individual_income float

The individual's weekly income.

required
is_single bool

Whether the individual is single.

required
is_partnered bool

Whether the individual is partnered.

required
is_disabled bool

Whether the individual has a disability.

required
slp_params SLPParams

The parameters for SLP.

required

Returns:

Type Description
float

The weekly SLP entitlement.

Source code in src/benefits.py
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
def calculate_slp(
    individual_income: float,
    is_single: bool,
    is_partnered: bool,
    is_disabled: bool,
    slp_params: SLPParams,
) -> float:
    """Calculate the Supported Living Payment (SLP) entitlement.

    SLP is a weekly payment for people who have, or are caring for someone
    with, a significant health condition, injury, or disability. The
    entitlement is based on the individual's income, marital status, and
    disability status.

    Args:
        individual_income: The individual's weekly income.
        is_single: Whether the individual is single.
        is_partnered: Whether the individual is partnered.
        is_disabled: Whether the individual has a disability.
        slp_params: The parameters for SLP.

    Returns:
        The weekly SLP entitlement.
    """
    if not is_disabled:
        return 0.0

    base_rate = 0.0
    if is_single:
        base_rate = slp_params.single_rate
    elif is_partnered:
        base_rate = slp_params.couple_rate

    if individual_income > slp_params.income_abatement_threshold:
        abatement = (individual_income - slp_params.income_abatement_threshold) * slp_params.abatement_rate
        return max(0.0, base_rate - abatement)
    return base_rate

calculate_sps(individual_income, num_dependent_children, sps_params)

Calculate the Sole Parent Support (SPS) entitlement.

SPS is a weekly payment for single parents with dependent children. The entitlement is based on the individual's income and the number of dependent children.

Parameters:

Name Type Description Default
individual_income float

The individual's weekly income.

required
num_dependent_children int

The number of dependent children.

required
sps_params SPSParams

The parameters for SPS.

required

Returns:

Type Description
float

The weekly SPS entitlement.

Source code in src/benefits.py
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
def calculate_sps(
    individual_income: float,
    num_dependent_children: int,
    sps_params: SPSParams,
) -> float:
    """Calculate the Sole Parent Support (SPS) entitlement.

    SPS is a weekly payment for single parents with dependent children. The
    entitlement is based on the individual's income and the number of
    dependent children.

    Args:
        individual_income: The individual's weekly income.
        num_dependent_children: The number of dependent children.
        sps_params: The parameters for SPS.

    Returns:
        The weekly SPS entitlement.
    """
    if num_dependent_children == 0:
        return 0.0

    base_rate = sps_params.base_rate
    if individual_income > sps_params.income_abatement_threshold:
        abatement = (individual_income - sps_params.income_abatement_threshold) * sps_params.abatement_rate
        return max(0.0, base_rate - abatement)
    return base_rate

calculate_wep(is_eligible, is_single, is_partnered, num_dependent_children, wep_params)

Calculate the Winter Energy Payment (WEP) entitlement.

The WEP is a payment to help with the cost of heating during the winter months. It is available to people receiving certain benefits or superannuation.

Parameters:

Name Type Description Default
is_eligible bool

Whether the individual is eligible for the WEP.

required
is_single bool

Whether the individual is single.

required
is_partnered bool

Whether the individual is partnered.

required
num_dependent_children int

The number of dependent children.

required
wep_params WEPParams

The parameters for the WEP.

required

Returns:

Type Description
float

The weekly WEP entitlement.

Source code in src/benefits.py
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
def calculate_wep(
    is_eligible: bool,
    is_single: bool,
    is_partnered: bool,
    num_dependent_children: int,
    wep_params: WEPParams,
) -> float:
    """Calculate the Winter Energy Payment (WEP) entitlement.

    The WEP is a payment to help with the cost of heating during the winter
    months. It is available to people receiving certain benefits or
    superannuation.

    Args:
        is_eligible: Whether the individual is eligible for the WEP.
        is_single: Whether the individual is single.
        is_partnered: Whether the individual is partnered.
        num_dependent_children: The number of dependent children.
        wep_params: The parameters for the WEP.

    Returns:
        The weekly WEP entitlement.
    """
    if not is_eligible:
        return 0.0

    base_rate = 0.0
    if is_single:
        base_rate = wep_params.single_rate
    elif is_partnered:
        base_rate = wep_params.couple_rate
    base_rate += num_dependent_children * wep_params.child_rate

    return base_rate