diff --git a/CHANGELOG.md b/CHANGELOG.md index 7c313af8..633004ba 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,53 @@ # Changelog +## 21.0.0 - [59](https://github.com/digitalaotearoa/openfisca-aotearoa/pull/59) + +* Tax and benefit system evolution. +* Impacted periods: all. +* Impacted areas: `sole_parent_support`, `jobseeker_support` +* Details: + - Add `income_test_n` as the result of applying an income test to a benefit. + +#### Discussion + +Main benefits are income-tested (subject to an abatement rate based on income). +Non-main benefits can be income-tested via main benefits (i.e. accommodation +supplement via jobseeker). However, some benefits change the definitions of +certain things, i.e. income is not the same for accommodation supplement and +for jobseeker support. Furthermore, the notion of income-tested benefit has +been replaced with that of main benefit, which can create confusion when a +benefit like accommodation supplement is income-tested via jobseeker support. + +This poses a challenge to the rule-maker, because in order to define a general +rule for an income test, that applies to benefits with different definitions of +income, it has to make it _high order_. In plain English, it has to create a +_rule factory_. A rule that creates a rule, depending on the context of its +application (i.e. the benefit it is applied to). + +There are several ways to solve this problem, yet all gravitate around two +philosophies: + +1. Stick to the letter: if the rule-maker defines a _pure high-order function_ + that can't be applied directly, one solution is to just model it as close to + the letter that is possible. + +2. Incorporate: if the rule can't be applied directly, ignore it, and + incorporate it as many times as is used without abstracting it into a rule + the way the rule-maker did (cf. copy-paste several times). + +Currently the OpenFisca DSL does not provide any native way of modelling this +cases, as it is assumed as an invariant that, what can be modelled, can be +directly applied at definition time (just following the text), and not at +run time (depending on the context it is being applied). + +As usually the law doesn't contain this kind of abstractions, their use has +always been discouraged as _not being truthful to the text_ or _modelling as a +developer and not as a policy folk_. This case is, then, peculiar. + +The solution adopted here is to model the income test as a normal `Variable`, +and capturing the context of its application from the stack. While it works, +it is not a very elegant solution, and it is likely error-prone. + ### 20.1.1 - [48](https://github.com/digitalaotearoa/openfisca-aotearoa/pull/48) * Test case. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 815139e0..b32c17ec 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -275,12 +275,10 @@ This project currently utilises one specific pattern however for benefit calcula - `jobseeker_support__entitled` (true/false) - or - `jobseeker_support__eligible` (true/false) - `jobseeker_support__base` (float) - `jobseeker_support__cutoff` (float) -- `jobseeker_support__reduction` (float) +- `jobseeker_support__abatement` (float) - `jobseeker_support__benefit` (float) i.e. the formula for `jobseeker_support__benefit` would be: ``` - jobseeker_support__entitled * min(jobseeker_support__base - jobseeker_support__reduction, jobseeker_support__cutoff) + jobseeker_support__entitled * min(jobseeker_support__base - jobseeker_support__abatement, jobseeker_support__cutoff) ``` - - diff --git a/openfisca_aotearoa/parameters/social_security/income_test_1.yaml b/openfisca_aotearoa/parameters/social_security/dictionary/income_test_1.yaml similarity index 51% rename from openfisca_aotearoa/parameters/social_security/income_test_1.yaml rename to openfisca_aotearoa/parameters/social_security/dictionary/income_test_1.yaml index e48062a4..2ce7a5e6 100644 --- a/openfisca_aotearoa/parameters/social_security/income_test_1.yaml +++ b/openfisca_aotearoa/parameters/social_security/dictionary/income_test_1.yaml @@ -1,9 +1,16 @@ -description: Social Security Income Test 1 +description: > + Social Security Act 2018 - + Schedule 2 Dictionary - + Income test 1 - + The applicable rate of benefit must be reduced— + (a) by 30 cents for every $1 of the total income of the beneficiary and + the beneficiary’s spouse or partner that is more than $160 a week but + not more than $250 a week + (b) by 70 cents for every $1 of that income that is more than $250 a week metadata: -# currency or /1 (rate) or year (never used) - unit: currency -# single_amount or marginal_rate or marginal_amount or value? - type: value + type: marginal_rate + rate_unit: /1 + threshold_unit: currency-NZD reference: 2018-11-26: title: Social Security Act 2018 (as enacted) @@ -17,13 +24,25 @@ metadata: brackets: - rate: 2018-11-26: - value: 0 + value: 0.0 + 2020-04-01: + value: 0.0 + 2021-04-01: + value: 0.0 threshold: 2018-11-26: value: 0 + 2020-04-01: + value: 0 + 2021-04-01: + value: 0 - rate: 2018-11-26: value: 0.3 + 2020-04-01: + value: 0.3 + 2021-04-01: + value: 0.3 threshold: 2018-11-26: value: 100 @@ -31,12 +50,13 @@ brackets: value: 115 2021-04-01: value: 160 - # no change in 2022 - # no change in 2023 - # https://www.legislation.govt.nz/all/results.aspx?search=ad_act%40bill%40regulation%40deemedreg__%22Income+Test+1%22____25_ac%40bc%40rc%40dc%40apub%40aloc%40apri%40apro%40aimp%40bgov%40bloc%40bpri%40bmem%40rpub%40rimp_ac%40bc%40rc%40ainf%40anif%40bcur%40rinf%40rnif%40raif%40rasm%40rrev_a_aw_se_&p=1 - rate: 2018-11-26: value: 0.7 + 2020-04-01: + value: 0.7 + 2021-04-01: + value: 0.7 threshold: 2018-11-26: value: 200 @@ -44,6 +64,3 @@ brackets: value: 215 2021-04-01: value: 250 - # no change in 2022 - # no change in 2023 - # https://www.legislation.govt.nz/all/results.aspx?search=ad_act%40bill%40regulation%40deemedreg__%22Income+Test+1%22____25_ac%40bc%40rc%40dc%40apub%40aloc%40apri%40apro%40aimp%40bgov%40bloc%40bpri%40bmem%40rpub%40rimp_ac%40bc%40rc%40ainf%40anif%40bcur%40rinf%40rnif%40raif%40rasm%40rrev_a_aw_se_&p=1 diff --git a/openfisca_aotearoa/parameters/social_security/income_test_2.yaml b/openfisca_aotearoa/parameters/social_security/dictionary/income_test_2.yaml similarity index 65% rename from openfisca_aotearoa/parameters/social_security/income_test_2.yaml rename to openfisca_aotearoa/parameters/social_security/dictionary/income_test_2.yaml index ef24ea78..c95c8a6d 100644 --- a/openfisca_aotearoa/parameters/social_security/income_test_2.yaml +++ b/openfisca_aotearoa/parameters/social_security/dictionary/income_test_2.yaml @@ -1,9 +1,16 @@ -description: Social Security Income Test 2 +description: > + Social Security Act 2018 - + Schedule 2 Dictionary - + Income test 2 - + The applicable rate of benefit must be reduced— + (a) by 15 cents for every $1 of the total income of the beneficiary and + the beneficiary’s spouse or partner that is more than $160 a week but + not more than $250 a week; and + (b) by 35 cents for every $1 of that income that is more than $250 a week metadata: -# currency or /1 (rate) or year (never used) - unit: currency -# single_amount or marginal_rate or marginal_amount or value? - type: value + type: marginal_rate + rate_unit: /1 + threshold_unit: currency-NZD reference: 2018-11-26: title: Social Security Act 2018 (as enacted) diff --git a/openfisca_aotearoa/parameters/social_security/income_test_3a.yaml b/openfisca_aotearoa/parameters/social_security/dictionary/income_test_3a.yaml similarity index 100% rename from openfisca_aotearoa/parameters/social_security/income_test_3a.yaml rename to openfisca_aotearoa/parameters/social_security/dictionary/income_test_3a.yaml diff --git a/openfisca_aotearoa/parameters/social_security/income_test_3b.yaml b/openfisca_aotearoa/parameters/social_security/dictionary/income_test_3b.yaml similarity index 55% rename from openfisca_aotearoa/parameters/social_security/income_test_3b.yaml rename to openfisca_aotearoa/parameters/social_security/dictionary/income_test_3b.yaml index 2fa602cc..d3e82c19 100644 --- a/openfisca_aotearoa/parameters/social_security/income_test_3b.yaml +++ b/openfisca_aotearoa/parameters/social_security/dictionary/income_test_3b.yaml @@ -1,9 +1,15 @@ -description: Social Security Income Test 3b +description: > + Social Security Act 2018 - + Schedule 2 Dictionary - + Income test 3 b - + The applicable rate of benefit must be reduced by 70 cents for every $1 of + total income of the beneficiary and the beneficiary’s spouse or partner + that is more than,— [...] + (b) in any other case, $160 a week metadata: -# currency or /1 (rate) or year (never used) - unit: currency -# single_amount or marginal_rate or marginal_amount or value? - type: value + type: marginal_rate + rate_unit: /1 + threshold_unit: currency-NZD reference: 2018-11-26: title: Social Security Act 2018 (as enacted) @@ -31,10 +37,3 @@ brackets: value: 90 2021-04-01: value: 160 -# Income Test 3 means that the applicable rate of benefit must be reduced by 70 -# cents for every $1 of total income of the beneficiary and the beneficiary’s -# spouse or partner that is more than,— -# (a) if the rate of benefit is a rate of New Zealand superannuation stated in -# clause 1 of Part 2 of Schedule 1 of the New Zealand Superannuation and -# Retirement Income Act 2001, $160 a week; or -# (b) in any other case, $160 a week diff --git a/openfisca_aotearoa/parameters/social_security/income_test_4.yaml b/openfisca_aotearoa/parameters/social_security/dictionary/income_test_4.yaml similarity index 68% rename from openfisca_aotearoa/parameters/social_security/income_test_4.yaml rename to openfisca_aotearoa/parameters/social_security/dictionary/income_test_4.yaml index ac10cea3..077b92f1 100644 --- a/openfisca_aotearoa/parameters/social_security/income_test_4.yaml +++ b/openfisca_aotearoa/parameters/social_security/dictionary/income_test_4.yaml @@ -1,9 +1,14 @@ -description: Social Security Income Test 4 +description: > + Social Security Act 2018 - + Schedule 2 Dictionary - + Income test 4 - + The applicable rate of benefit must be reduced by 35 cents for every $1 of + the total income of the beneficiary and the beneficiary’s spouse or partner + that is more than $160 a week metadata: -# currency or /1 (rate) or year (never used) - unit: currency -# single_amount or marginal_rate or marginal_amount or value? - type: value + type: marginal_rate + rate_unit: /1 + threshold_unit: currency-NZD reference: 2018-11-26: title: Social Security Act 2018 (as enacted) diff --git a/openfisca_aotearoa/tests/social_security/jobseeker_support/abatement.yaml b/openfisca_aotearoa/tests/social_security/jobseeker_support/abatement.yaml new file mode 100644 index 00000000..cba7bfb4 --- /dev/null +++ b/openfisca_aotearoa/tests/social_security/jobseeker_support/abatement.yaml @@ -0,0 +1,59 @@ +- name: > + Social Security Act 2018 - + Schedule 2 Dictionary - + Income test 1 - + The applicable rate of benefit must be reduced— + (a) by 30 cents for every $1 of the total income of the beneficiary and + the beneficiary’s spouse or partner that is more than $160 a week but + not more than $250 a week + (b) by 70 cents for every $1 of that income that is more than $250 a week + period: 2018-11-26 + input: + jobseeker_support__income: + 2023-W01: [159.99, 160.00, 160.01, 161.99, 249.99, 250.00, 250.01, 251.99] + schedule_4__part1_1_c: + 2023-W01: [true, true, true, true, true, true, true, true] + output: + jobseeker_support__abatement: + 2023-W01: [0, 0, 0, 0.30, 26.70, 27.00, 27.00, 27.70] + + +- name: > + Social Security Act 2018 - + Schedule 2 Dictionary - + Income test 3 - + The applicable rate of benefit must be reduced by 70 cents for every $1 of + the total income of the beneficiary and the beneficiary’s spouse or partner + that is more than,— + (b) [...] $160 a week + period: 2018-11-26 + input: + jobseeker_support__income: + 2023-W01: [159.99, 160.00, 160.01, 161.99, 249.99, 250.00, 250.01, 251.99] + schedule_4__part1_1_a: + 2023-W01: [true, true, true, true, true, true, true, true] + output: + jobseeker_support__abatement: + 2023-W01: [0, 0, 0, 0.70, 62.30, 63.00, 63.00, 63.70] + + +- name: > + Social Security Act 2018 - + Schedule 2 Dictionary - + Income test 4 - + The applicable rate of benefit must be reduced by 35 cents for every $1 of + the total income of the beneficiary and the beneficiary’s spouse or partner + that is more than $160 a week + period: 2018-11-26 + input: + jobseeker_support__income: + 2023-W01: [159.99, 160.00, 160.01, 161.99, 249.99, 250.00, 250.01, 251.99] + schedule_4__part1_1_d: + 2023-W01: [false, false, false, false, false, false, false, false] + schedule_4__part1_1_g: + 2023-W01: [true, true, true, true, true, true, true, true] + output: + jobseeker_support__abatement: + 2023-W01: [0, 0, 0, 0.35, 31.15, 31.50, 31.50, 31.85] + schedule_4__part1_1_d: + 2023-W01: [false, false, false, false, false, false, false, false] diff --git a/openfisca_aotearoa/tests/social_security/jobseeker_support/base.yaml b/openfisca_aotearoa/tests/social_security/jobseeker_support/base.yaml index 5154aad2..8e44cc5d 100644 --- a/openfisca_aotearoa/tests/social_security/jobseeker_support/base.yaml +++ b/openfisca_aotearoa/tests/social_security/jobseeker_support/base.yaml @@ -216,13 +216,6 @@ 2022-W01: [240.65, 406.78, 239.70] 2023-W01: [283.00, 440.96, 274.37] 2023-W15: [303.43, 472.79, 294.18] - jobseeker_support__reduction: - 2020-W01: [143.5, 0, 0] - 2021-W01: [59.5, 0, 0] - 2021-W23: [0, 0, 0] - 2022-W01: [138.6, 0, 0] - 2023-W01: [31.5, 0, 0] - 2023-W15: [31.5, 0, 0] jobseeker_support__benefit: 2020-W01: [52, 0, 0] 2021-W01: [154.53, 0, 0] diff --git a/openfisca_aotearoa/tests/social_security/jobseeker_support/income.yaml b/openfisca_aotearoa/tests/social_security/jobseeker_support/income.yaml new file mode 100644 index 00000000..fd646740 --- /dev/null +++ b/openfisca_aotearoa/tests/social_security/jobseeker_support/income.yaml @@ -0,0 +1,53 @@ +- name: > + Social Security Act 2018 - + Schedule 2 Dictionary - + Income test 1-4 - + The applicable rate of benefit must be reduced [...] of the total income of + the beneficiary and the beneficiary’s spouse or partner. + period: 2018-11-26 + input: + persons: + Vrenda: + social_security__income: + 2023-W01: 0 + 2023-W02: 100 + 2023-W03: 100 + Piedad: + social_security__income: + 2023-W01: 0 + 2023-W02: 0 + 2023-W03: 100 + output: + jobseeker_support__income: + 2023-W01: [0, 0] + 2023-W02: [100, 0] + 2023-W03: [100, 100] + + +- name: > + Social Security Act 2018 - + Schedule 2 Dictionary - + Income test 1-4 - + The applicable rate of benefit must be reduced [...] of the total income of + the beneficiary and the beneficiary’s spouse or partner. + period: 2018-11-26 + input: + persons: + Vrenda: + social_security__income: + 2023-W01: 0 + 2023-W02: 100 + 2023-W03: 100 + Piedad: + social_security__income: + 2023-W01: 0 + 2023-W02: 0 + 2023-W03: 100 + family: + principal: Vrenda + partners: [Piedad] + output: + jobseeker_support__income: + 2023-W01: [0, 0] + 2023-W02: [100, 100] + 2023-W03: [200, 200] diff --git a/openfisca_aotearoa/variables/__init__.py b/openfisca_aotearoa/variables/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/openfisca_aotearoa/variables/acts/__init__.py b/openfisca_aotearoa/variables/acts/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/openfisca_aotearoa/variables/acts/social_security/__init__.py b/openfisca_aotearoa/variables/acts/social_security/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/openfisca_aotearoa/variables/acts/social_security/accommodation_supplement/income_tests.py b/openfisca_aotearoa/variables/acts/social_security/accommodation_supplement/income_tests.py new file mode 100644 index 00000000..35535aaf --- /dev/null +++ b/openfisca_aotearoa/variables/acts/social_security/accommodation_supplement/income_tests.py @@ -0,0 +1,192 @@ +"""This module provides the calculation of Accommodation Supplement's Income Tests.""" + +import numpy + +from openfisca_core import periods + +from openfisca_aotearoa import entities +from openfisca_aotearoa.variables.acts.social_security import dictionary + + +class accommodation_supplement__income_test_1(dictionary.social_security__income_test_1): + label = "Accommodation Supplement — Income Test 1" + reference = "https://www.legislation.govt.nz/act/public/2018/0032/latest/whole.html#DLM6784375" + documentation = """ + Income Test 1 means that the applicable rate of [a] benefit must be + reduced by 30 cents for every $1 of the total income of the beneficiary + and the beneficiary’s spouse or partner that is more than $160 a week + but not more than $250 a week; and by 70 cents for every $1 of that + income that is more than $250 a week. + """ + entity = entities.Family + value_type = float + default_value = 0 + definition_period = periods.DateUnit.WEEK + + def formula_2018_11_26(families, period, params): + # Income Test 1 means that the applicable rate of [a] benefit must be + # reduced— + + # List of people with families. + people = families.members + + applicable_rate = families.sum( + people("accommodation_supplement__base", period), + role = entities.Family.PRINCIPAL, + ) + + # (a) by 30 cents for every $1 of the total income of the beneficiary + # and the beneficiary’s spouse or partner that is more than $160 a + # week but not more than $250 a week; and + total_income = families("accommodation_supplement__income", period) + + # Required for income tests as i.e. x¢ for every $y. + floor = numpy.floor(total_income) + + # (b) by 70 cents for every $1 of that income that is more than $250 a + # week + scale = params(period).social_security.dictionary.income_test_1 + + # The abatement rate regardless of benefit rate. + abatement_rate = scale.calc(floor) + + # The abatement rate capped at the applicable benefit rate. + return numpy.minimum(abatement_rate, applicable_rate) + + +class accommodation_supplement__income_test_2(dictionary.social_security__income_test_1): + label = "Accommodation Supplement — Income Test 2" + reference = "https://www.legislation.govt.nz/act/public/2018/0032/latest/whole.html#DLM6784375" + documentation = """ + Income Test 2 means that the applicable rate of [a] benefit must be + reduced by 15 cents for every $1 of the total income of the beneficiary + and the beneficiary’s spouse or partner that is more than $160 a week + but not more than $250 a week; and by 35 cents for every $1 of that + income that is more than $250 a week. + """ + entity = entities.Family + value_type = float + default_value = 0 + definition_period = periods.DateUnit.WEEK + + def formula_2018_11_26(families, period, params): + # Income Test 2 means that the applicable rate of benefit must be + # reduced— + + # List of people with families. + people = families.members + + applicable_rate = families.sum( + people("accommodation_supplement__base", period), + role = entities.Family.PRINCIPAL, + ) + + # (a) by 15 cents for every $1 of the total income of the beneficiary + # and the beneficiary’s spouse or partner that is more than $160 a + # week but not more than $250 a week; and + total_income = families("accommodation_supplement__income", period) + + # Required for income tests as i.e. x¢ for every $y. + floor = numpy.floor(total_income) + + # (b) by 35 cents for every $1 of that income that is more than $250 a + # week + scale = params(period).social_security.dictionary.income_test_2 + + # The abatement rate regardless of benefit rate. + abatement_rate = scale.calc(floor) + + # The abatement rate capped at the applicable benefit rate. + return numpy.minimum(abatement_rate, applicable_rate) + + +class accommodation_supplement__income_test_3(dictionary.social_security__income_test_3): + label = "Accommodation Supplement — Income Test 3" + reference = "https://www.legislation.govt.nz/act/public/2018/0032/latest/whole.html#DLM6784375" + documentation = """ + Income Test 3 means that the applicable rate of [a] benefit must be + reduced by 70 cents for every $1 of total income of the beneficiary and + the beneficiary’s spouse or partner that is more than, if the rate of + benefit is a rate of New Zealand superannuation stated in clause 1 of + Part 2 of Schedule 1 of the New Zealand Superannuation and Retirement + Income Act 2001, $160 a week; or in any other case, $160 a week. + """ + entity = entities.Family + value_type = float + default_value = 0 + definition_period = periods.DateUnit.WEEK + + def formula_2018_11_26(families, period, params): + # Income Test 3 means that the applicable rate of benefit must be + # reduced— + + # List of people with families. + people = families.members + + applicable_rate = families.sum( + people("accommodation_supplement__base", period), + role = entities.Family.PRINCIPAL, + ) + + # by 70 cents for every $1 of total income of the + # beneficiary and the beneficiary’s spouse or partner that + # is more than,— + total_income = families("accommodation_supplement__income", period) + + # Required for income tests as i.e. x¢ for every $y. + floor = numpy.floor(total_income) + + # (a) if the rate of benefit is a rate of New Zealand + # superannuation stated in clause 1 of Part 2 of + # Schedule 1 of the New Zealand Superannuation and + # Retirement Income Act 2001, $160 a week; or + # (b) in any other case, $160 a week + scale = params(period).social_security.dictionary.income_test_3b + + # The abatement rate regardless of benefit rate. + abatement_rate = scale.calc(floor) + + # The abatement rate capped at the applicable benefit rate. + return numpy.minimum(abatement_rate, applicable_rate) + + +class accommodation_supplement__income_test_4(dictionary.social_security__income_test_4): + label = "Accommodation Supplement — Income Test 4" + reference = "https://www.legislation.govt.nz/act/public/2018/0032/latest/whole.html#DLM6784375" + documentation = """ + Income Test 4 means that the applicable rate of [a] benefit must be + reduced by 35 cents for every $1 of the total income of the beneficiary + and the beneficiary’s spouse or partner that is more than $160 a week. + """ + entity = entities.Family + value_type = float + default_value = 0 + definition_period = periods.DateUnit.WEEK + + def formula_2018_11_26(families, period, params): + # Income Test 4 means that the applicable rate of [a] benefit must be + # reduced + + # List of people with families. + people = families.members + + applicable_rate = families.sum( + people("accommodation_supplement__base", period), + role = entities.Family.PRINCIPAL, + ) + + # by 35 cents for every $1 of the total income of the + # beneficiary and the beneficiary’s spouse or partner that + # is more than $160 a week. + total_income = families("accommodation_supplement__income", period) + + # Required for income tests as i.e. x¢ for every $y. + floor = numpy.floor(total_income) + + scale = params(period).social_security.dictionary.income_test_4 + + # The abatement rate regardless of benefit rate. + abatement_rate = scale.calc(floor) + + # The abatement rate capped at the applicable benefit rate. + return numpy.minimum(abatement_rate, applicable_rate) diff --git a/openfisca_aotearoa/variables/acts/social_security/dictionary/__init__.py b/openfisca_aotearoa/variables/acts/social_security/dictionary/__init__.py new file mode 100644 index 00000000..44c2b29c --- /dev/null +++ b/openfisca_aotearoa/variables/acts/social_security/dictionary/__init__.py @@ -0,0 +1,13 @@ +"""Social Security Act's Dictionary.""" + +from .income_test_1 import social_security__income_test_1 +from .income_test_2 import social_security__income_test_2 +from .income_test_3 import social_security__income_test_3 +from .income_test_4 import social_security__income_test_4 + +__all__ = ( + "social_security__income_test_1", + "social_security__income_test_2", + "social_security__income_test_3", + "social_security__income_test_4", + ) diff --git a/openfisca_aotearoa/variables/acts/social_security/dictionary/income_test_1.py b/openfisca_aotearoa/variables/acts/social_security/dictionary/income_test_1.py new file mode 100644 index 00000000..c9e4adec --- /dev/null +++ b/openfisca_aotearoa/variables/acts/social_security/dictionary/income_test_1.py @@ -0,0 +1,37 @@ +"""This module provides the base Variable for calculation of Income Test 1. + +Income Test 1 means that the applicable rate of [a] benefit must be +reduced by 30 cents for every $1 of the total income of the beneficiary and the +beneficiary’s spouse or partner that is more than $160 a week but not more than +$250 a week; and by 70 cents for every $1 of that income that is more than $250 +a week. + +""" + +from abc import abstractmethod + +# We import the required OpenFisca modules needed to define a formula. +from openfisca_core import periods, variables + +# We import the required `entities` corresponding to our formulas. +from openfisca_aotearoa import entities + + +class social_security__income_test_1(variables.Variable): + label = "Dictionary — Income Test 1" + reference = "https://www.legislation.govt.nz/act/public/2018/0032/latest/whole.html#DLM6784375" + documentation = """ + Income Test 1 means that the applicable rate of [a] benefit must be + reduced by 30 cents for every $1 of the total income of the beneficiary + and the beneficiary’s spouse or partner that is more than $160 a week + but not more than $250 a week; and by 70 cents for every $1 of that + income that is more than $250 a week. + """ + entity = entities.Family + value_type = float + default_value = 0 + definition_period = periods.DateUnit.WEEK + + @abstractmethod + def formula_2018_11_26(families, period, params): + raise NotImplementedError() diff --git a/openfisca_aotearoa/variables/acts/social_security/dictionary/income_test_2.py b/openfisca_aotearoa/variables/acts/social_security/dictionary/income_test_2.py new file mode 100644 index 00000000..5e7cddc7 --- /dev/null +++ b/openfisca_aotearoa/variables/acts/social_security/dictionary/income_test_2.py @@ -0,0 +1,37 @@ +"""This module provides the calculation of Income Test 2. + +Income Test 2 means that the applicable rate of [a] benefit must be reduced by +15 cents for every $1 of the total income of the beneficiary and the +beneficiary’s spouse or partner that is more than $160 a week but not more than +$250 a week; and by 35 cents for every $1 of that income that is more than +$250 a week. + +""" + +from abc import abstractmethod + +# We import the required OpenFisca modules needed to define a formula. +from openfisca_core import periods, variables + +# We import the required `entities` corresponding to our formulas. +from openfisca_aotearoa import entities + + +class social_security__income_test_2(variables.Variable): + label = "Dictionary — Income Test 2" + reference = "https://www.legislation.govt.nz/act/public/2018/0032/latest/whole.html#DLM6784375" + documentation = """ + Income Test 2 means that the applicable rate of [a] benefit must be + reduced by 15 cents for every $1 of the total income of the beneficiary + and the beneficiary’s spouse or partner that is more than $160 a week + but not more than $250 a week; and by 35 cents for every $1 of that + income that is more than $250 a week. + """ + entity = entities.Family + value_type = float + default_value = 0 + definition_period = periods.DateUnit.WEEK + + @abstractmethod + def formula_2018_11_26(families, period, params): + raise NotImplementedError() diff --git a/openfisca_aotearoa/variables/acts/social_security/dictionary/income_test_3.py b/openfisca_aotearoa/variables/acts/social_security/dictionary/income_test_3.py new file mode 100644 index 00000000..6481c465 --- /dev/null +++ b/openfisca_aotearoa/variables/acts/social_security/dictionary/income_test_3.py @@ -0,0 +1,39 @@ +"""This module provides the calculation of Income Test 3. + +Income Test 3 means that the applicable rate of [a] benefit must be reduced by +70 cents for every $1 of total income of the beneficiary and the beneficiary’s +spouse or partner that is more than, if the rate of benefit is a rate of New +Zealand superannuation stated in clause 1 of Part 2 of Schedule 1 of the New +Zealand Superannuation and Retirement Income Act 2001, $160 a week; or +in any other case, $160 a week. + +""" + +from abc import abstractmethod + +# We import the required OpenFisca modules needed to define a formula. +from openfisca_core import periods, variables + +# We import the required `entities` corresponding to our formulas. +from openfisca_aotearoa import entities + + +class social_security__income_test_3(variables.Variable): + label = "Dictionary — Income Test 3" + reference = "https://www.legislation.govt.nz/act/public/2018/0032/latest/whole.html#DLM6784375" + documentation = """ + Income Test 3 means that the applicable rate of [a] benefit must be + reduced by 70 cents for every $1 of total income of the beneficiary and + the beneficiary’s spouse or partner that is more than, if the rate of + benefit is a rate of New Zealand superannuation stated in clause 1 of + Part 2 of Schedule 1 of the New Zealand Superannuation and Retirement + Income Act 2001, $160 a week; or in any other case, $160 a week. + """ + entity = entities.Family + value_type = float + default_value = 0 + definition_period = periods.DateUnit.WEEK + + @abstractmethod + def formula_2018_11_26(families, period, params): + raise NotImplementedError() diff --git a/openfisca_aotearoa/variables/acts/social_security/dictionary/income_test_4.py b/openfisca_aotearoa/variables/acts/social_security/dictionary/income_test_4.py new file mode 100644 index 00000000..a71e8dc5 --- /dev/null +++ b/openfisca_aotearoa/variables/acts/social_security/dictionary/income_test_4.py @@ -0,0 +1,33 @@ +"""This module provides the calculation of Income Test 4. + +Income Test 4 means that the applicable rate of [a] benefit must be reduced by +35 cents for every $1 of the total income of the beneficiary and the +beneficiary’s spouse or partner that is more than $160 a week. + +""" + +from abc import abstractmethod + +# We import the required OpenFisca modules needed to define a formula. +from openfisca_core import periods, variables + +# We import the required `entities` corresponding to our formulas. +from openfisca_aotearoa import entities + + +class social_security__income_test_4(variables.Variable): + label = "Dictionary — Income Test 4" + reference = "https://www.legislation.govt.nz/act/public/2018/0032/latest/whole.html#DLM6784375" + documentation = """ + Income Test 4 means that the applicable rate of [a] benefit must be + reduced by 35 cents for every $1 of the total income of the beneficiary + and the beneficiary’s spouse or partner that is more than $160 a week. + """ + entity = entities.Family + value_type = float + default_value = 0 + definition_period = periods.DateUnit.WEEK + + @abstractmethod + def formula_2018_11_26(families, period, params): + raise NotImplementedError() diff --git a/openfisca_aotearoa/variables/acts/social_security/emergency_benefit/income_tests.py b/openfisca_aotearoa/variables/acts/social_security/emergency_benefit/income_tests.py new file mode 100644 index 00000000..fd240561 --- /dev/null +++ b/openfisca_aotearoa/variables/acts/social_security/emergency_benefit/income_tests.py @@ -0,0 +1,192 @@ +"""This module provides the calculation of Emergency Benefit's Income Tests.""" + +import numpy + +from openfisca_core import periods + +from openfisca_aotearoa import entities +from openfisca_aotearoa.variables.acts.social_security import dictionary + + +class emergency_benefit__income_test_1(dictionary.social_security__income_test_1): + label = "Emergency Benefit — Income Test 1" + reference = "https://www.legislation.govt.nz/act/public/2018/0032/latest/whole.html#DLM6784375" + documentation = """ + Income Test 1 means that the applicable rate of [a] benefit must be + reduced by 30 cents for every $1 of the total income of the beneficiary + and the beneficiary’s spouse or partner that is more than $160 a week + but not more than $250 a week; and by 70 cents for every $1 of that + income that is more than $250 a week. + """ + entity = entities.Family + value_type = float + default_value = 0 + definition_period = periods.DateUnit.WEEK + + def formula_2018_11_26(families, period, params): + # Income Test 1 means that the applicable rate of [a] benefit must be + # reduced— + + # List of people with families. + people = families.members + + applicable_rate = families.sum( + people("emergency_benefit__base", period), + role = entities.Family.PRINCIPAL, + ) + + # (a) by 30 cents for every $1 of the total income of the beneficiary + # and the beneficiary’s spouse or partner that is more than $160 a + # week but not more than $250 a week; and + total_income = families("emergency_benefit__income", period) + + # Required for income tests as i.e. x¢ for every $y. + floor = numpy.floor(total_income) + + # (b) by 70 cents for every $1 of that income that is more than $250 a + # week + scale = params(period).social_security.dictionary.income_test_1 + + # The abatement rate regardless of benefit rate. + abatement_rate = scale.calc(floor) + + # The abatement rate capped at the applicable benefit rate. + return numpy.minimum(abatement_rate, applicable_rate) + + +class emergency_benefit__income_test_2(dictionary.social_security__income_test_1): + label = "Emergency Benefit — Income Test 2" + reference = "https://www.legislation.govt.nz/act/public/2018/0032/latest/whole.html#DLM6784375" + documentation = """ + Income Test 2 means that the applicable rate of [a] benefit must be + reduced by 15 cents for every $1 of the total income of the beneficiary + and the beneficiary’s spouse or partner that is more than $160 a week + but not more than $250 a week; and by 35 cents for every $1 of that + income that is more than $250 a week. + """ + entity = entities.Family + value_type = float + default_value = 0 + definition_period = periods.DateUnit.WEEK + + def formula_2018_11_26(families, period, params): + # Income Test 2 means that the applicable rate of benefit must be + # reduced— + + # List of people with families. + people = families.members + + applicable_rate = families.sum( + people("emergency_benefit__base", period), + role = entities.Family.PRINCIPAL, + ) + + # (a) by 15 cents for every $1 of the total income of the beneficiary + # and the beneficiary’s spouse or partner that is more than $160 a + # week but not more than $250 a week; and + total_income = families("emergency_benefit__income", period) + + # Required for income tests as i.e. x¢ for every $y. + floor = numpy.floor(total_income) + + # (b) by 35 cents for every $1 of that income that is more than $250 a + # week + scale = params(period).social_security.dictionary.income_test_2 + + # The abatement rate regardless of benefit rate. + abatement_rate = scale.calc(floor) + + # The abatement rate capped at the applicable benefit rate. + return numpy.minimum(abatement_rate, applicable_rate) + + +class emergency_benefit__income_test_3(dictionary.social_security__income_test_3): + label = "Emergency Benefit — Income Test 3" + reference = "https://www.legislation.govt.nz/act/public/2018/0032/latest/whole.html#DLM6784375" + documentation = """ + Income Test 3 means that the applicable rate of [a] benefit must be + reduced by 70 cents for every $1 of total income of the beneficiary and + the beneficiary’s spouse or partner that is more than, if the rate of + benefit is a rate of New Zealand superannuation stated in clause 1 of + Part 2 of Schedule 1 of the New Zealand Superannuation and Retirement + Income Act 2001, $160 a week; or in any other case, $160 a week. + """ + entity = entities.Family + value_type = float + default_value = 0 + definition_period = periods.DateUnit.WEEK + + def formula_2018_11_26(families, period, params): + # Income Test 3 means that the applicable rate of benefit must be + # reduced— + + # List of people with families. + people = families.members + + applicable_rate = families.sum( + people("emergency_benefit__base", period), + role = entities.Family.PRINCIPAL, + ) + + # by 70 cents for every $1 of total income of the + # beneficiary and the beneficiary’s spouse or partner that + # is more than,— + total_income = families("emergency_benefit__income", period) + + # Required for income tests as i.e. x¢ for every $y. + floor = numpy.floor(total_income) + + # (a) if the rate of benefit is a rate of New Zealand + # superannuation stated in clause 1 of Part 2 of + # Schedule 1 of the New Zealand Superannuation and + # Retirement Income Act 2001, $160 a week; or + # (b) in any other case, $160 a week + scale = params(period).social_security.dictionary.income_test_3b + + # The abatement rate regardless of benefit rate. + abatement_rate = scale.calc(floor) + + # The abatement rate capped at the applicable benefit rate. + return numpy.minimum(abatement_rate, applicable_rate) + + +class emergency_benefit__income_test_4(dictionary.social_security__income_test_4): + label = "Emergency Benefit — Income Test 4" + reference = "https://www.legislation.govt.nz/act/public/2018/0032/latest/whole.html#DLM6784375" + documentation = """ + Income Test 4 means that the applicable rate of [a] benefit must be + reduced by 35 cents for every $1 of the total income of the beneficiary + and the beneficiary’s spouse or partner that is more than $160 a week. + """ + entity = entities.Family + value_type = float + default_value = 0 + definition_period = periods.DateUnit.WEEK + + def formula_2018_11_26(families, period, params): + # Income Test 4 means that the applicable rate of [a] benefit must be + # reduced + + # List of people with families. + people = families.members + + applicable_rate = families.sum( + people("emergency_benefit__base", period), + role = entities.Family.PRINCIPAL, + ) + + # by 35 cents for every $1 of the total income of the + # beneficiary and the beneficiary’s spouse or partner that + # is more than $160 a week. + total_income = families("emergency_benefit__income", period) + + # Required for income tests as i.e. x¢ for every $y. + floor = numpy.floor(total_income) + + scale = params(period).social_security.dictionary.income_test_4 + + # The abatement rate regardless of benefit rate. + abatement_rate = scale.calc(floor) + + # The abatement rate capped at the applicable benefit rate. + return numpy.minimum(abatement_rate, applicable_rate) diff --git a/openfisca_aotearoa/variables/acts/social_security/jobseeker_support/abatement.py b/openfisca_aotearoa/variables/acts/social_security/jobseeker_support/abatement.py new file mode 100644 index 00000000..fdfab628 --- /dev/null +++ b/openfisca_aotearoa/variables/acts/social_security/jobseeker_support/abatement.py @@ -0,0 +1,86 @@ +"""Jobseeker Support — Abatement. + +The amount the base benefit is reduced based on the appropriate Income Test and +the person & their partners income. + +""" + +from openfisca_core import periods, variables + +from openfisca_aotearoa import entities + + +class jobseeker_support__abatement(variables.Variable): + label = "Jobseeker Support — Abatement" + reference = "https://www.legislation.govt.nz/act/public/2018/0032/latest/DLM6784850.html" + documentation = """ + The amount the base benefit is reduced based on the appropriate Income + Test and the person & their partners income. + """ + entity = entities.Person + value_type = float + default_value = 0 + definition_period = periods.WEEK + + def formula_2018_11_26(people, period, _params): + families = people.family + + case_1 = ( + + people("schedule_4__part1_1_c", period) + + people("schedule_4__part1_1_e", period) + + people("schedule_4__part1_1_f", period) + ) + + case_3 = ( + + people("schedule_4__part1_1_a", period) + + people("schedule_4__part1_1_b", period) + + people("schedule_4__part1_1_d", period) + + people("schedule_4__part1_1_i", period) + + people("schedule_4__part1_1_j", period) + ) + + case_4 = ( + + people("schedule_4__part1_1_g", period) + + people("schedule_4__part1_1_h", period) + ) + + income_test_1 = families("jobseeker_support__income_test_1", period) + income_test_3 = families("jobseeker_support__income_test_3", period) + income_test_4 = families("jobseeker_support__income_test_4", period) + + return ( + + case_1 * income_test_1 + + case_3 * income_test_3 + + case_4 * income_test_4 + ) + + def formula_2020_11_09(people, period, _params): + families = people.family + + case_1 = ( + + people("schedule_4__part1_1_c", period) + + people("schedule_4__part1_1_e", period) + + people("schedule_4__part1_1_f", period) + ) + + case_3 = ( + + people("schedule_4__part1_1_a", period) + + people("schedule_4__part1_1_b", period) + + people("schedule_4__part1_1_d", period) + + people("schedule_4__part1_1_j", period) + ) + + case_4 = ( + + people("schedule_4__part1_1_g", period) + + people("schedule_4__part1_1_h", period) + ) + + income_test_1 = families("jobseeker_support__income_test_1", period) + income_test_3 = families("jobseeker_support__income_test_3", period) + income_test_4 = families("jobseeker_support__income_test_4", period) + + return ( + + case_1 * income_test_1 + + case_3 * income_test_3 + + case_4 * income_test_4 + ) diff --git a/openfisca_aotearoa/variables/acts/social_security/jobseeker_support/income.py b/openfisca_aotearoa/variables/acts/social_security/jobseeker_support/income.py new file mode 100644 index 00000000..97b6678e --- /dev/null +++ b/openfisca_aotearoa/variables/acts/social_security/jobseeker_support/income.py @@ -0,0 +1,35 @@ +"""Jobseeker Support — Income. + +The income upon which the applicable rate of Jobseeker Support is calculated +and eventually reduced. + +""" + +from openfisca_core import periods, variables + +from openfisca_aotearoa import entities + + +class jobseeker_support__income(variables.Variable): + label = "Jobseeker support — Income" + reference = "https://www.legislation.govt.nz/act/public/2018/0032/latest/DLM6784850.html" + documentation = """Total income of people and their partners.""" + entity = entities.Family + value_type = float + default_value = 0 + definition_period = periods.WEEK + + def formula_2018_11_26(families, period, _params): + people = families.members + + beneficiary_income = families.sum( + people("social_security__income", period), + role = entities.Family.PRINCIPAL, + ) + + spouse_or_partner_income = families.sum( + people("social_security__income", period), + role = entities.Family.PARTNER, + ) + + return beneficiary_income + spouse_or_partner_income diff --git a/openfisca_aotearoa/variables/acts/social_security/jobseeker_support/income_tests.py b/openfisca_aotearoa/variables/acts/social_security/jobseeker_support/income_tests.py new file mode 100644 index 00000000..80403e75 --- /dev/null +++ b/openfisca_aotearoa/variables/acts/social_security/jobseeker_support/income_tests.py @@ -0,0 +1,192 @@ +"""This module provides the calculation of Jobseeker Support's Income Tests.""" + +import numpy + +from openfisca_core import periods + +from openfisca_aotearoa import entities +from openfisca_aotearoa.variables.acts.social_security import dictionary + + +class jobseeker_support__income_test_1(dictionary.social_security__income_test_1): + label = "Jobseeker Support — Income Test 1" + reference = "https://www.legislation.govt.nz/act/public/2018/0032/latest/whole.html#DLM6784375" + documentation = """ + Income Test 1 means that the applicable rate of [a] benefit must be + reduced by 30 cents for every $1 of the total income of the beneficiary + and the beneficiary’s spouse or partner that is more than $160 a week + but not more than $250 a week; and by 70 cents for every $1 of that + income that is more than $250 a week. + """ + entity = entities.Family + value_type = float + default_value = 0 + definition_period = periods.DateUnit.WEEK + + def formula_2018_11_26(families, period, params): + # Income Test 1 means that the applicable rate of [a] benefit must be + # reduced— + + # List of people with families. + people = families.members + + applicable_rate = families.sum( + people("jobseeker_support__base", period), + role = entities.Family.PRINCIPAL, + ) + + # (a) by 30 cents for every $1 of the total income of the beneficiary + # and the beneficiary’s spouse or partner that is more than $160 a + # week but not more than $250 a week; and + total_income = families("jobseeker_support__income", period) + + # Required for income tests as i.e. x¢ for every $y. + floor = numpy.floor(total_income) + + # (b) by 70 cents for every $1 of that income that is more than $250 a + # week + scale = params(period).social_security.dictionary.income_test_1 + + # The abatement rate regardless of benefit rate. + abatement_rate = scale.calc(floor) + + # The abatement rate capped at the applicable benefit rate. + return numpy.minimum(abatement_rate, applicable_rate) + + +class jobseeker_support__income_test_2(dictionary.social_security__income_test_1): + label = "Jobseeker Support — Income Test 2" + reference = "https://www.legislation.govt.nz/act/public/2018/0032/latest/whole.html#DLM6784375" + documentation = """ + Income Test 2 means that the applicable rate of [a] benefit must be + reduced by 15 cents for every $1 of the total income of the beneficiary + and the beneficiary’s spouse or partner that is more than $160 a week + but not more than $250 a week; and by 35 cents for every $1 of that + income that is more than $250 a week. + """ + entity = entities.Family + value_type = float + default_value = 0 + definition_period = periods.DateUnit.WEEK + + def formula_2018_11_26(families, period, params): + # Income Test 2 means that the applicable rate of benefit must be + # reduced— + + # List of people with families. + people = families.members + + applicable_rate = families.sum( + people("jobseeker_support__base", period), + role = entities.Family.PRINCIPAL, + ) + + # (a) by 15 cents for every $1 of the total income of the beneficiary + # and the beneficiary’s spouse or partner that is more than $160 a + # week but not more than $250 a week; and + total_income = families("jobseeker_support__income", period) + + # Required for income tests as i.e. x¢ for every $y. + floor = numpy.floor(total_income) + + # (b) by 35 cents for every $1 of that income that is more than $250 a + # week + scale = params(period).social_security.dictionary.income_test_2 + + # The abatement rate regardless of benefit rate. + abatement_rate = scale.calc(floor) + + # The abatement rate capped at the applicable benefit rate. + return numpy.minimum(abatement_rate, applicable_rate) + + +class jobseeker_support__income_test_3(dictionary.social_security__income_test_3): + label = "Jobseeker Support — Income Test 3" + reference = "https://www.legislation.govt.nz/act/public/2018/0032/latest/whole.html#DLM6784375" + documentation = """ + Income Test 3 means that the applicable rate of [a] benefit must be + reduced by 70 cents for every $1 of total income of the beneficiary and + the beneficiary’s spouse or partner that is more than, if the rate of + benefit is a rate of New Zealand superannuation stated in clause 1 of + Part 2 of Schedule 1 of the New Zealand Superannuation and Retirement + Income Act 2001, $160 a week; or in any other case, $160 a week. + """ + entity = entities.Family + value_type = float + default_value = 0 + definition_period = periods.DateUnit.WEEK + + def formula_2018_11_26(families, period, params): + # Income Test 3 means that the applicable rate of benefit must be + # reduced— + + # List of people with families. + people = families.members + + applicable_rate = families.sum( + people("jobseeker_support__base", period), + role = entities.Family.PRINCIPAL, + ) + + # by 70 cents for every $1 of total income of the + # beneficiary and the beneficiary’s spouse or partner that + # is more than,— + total_income = families("jobseeker_support__income", period) + + # Required for income tests as i.e. x¢ for every $y. + floor = numpy.floor(total_income) + + # (a) if the rate of benefit is a rate of New Zealand + # superannuation stated in clause 1 of Part 2 of + # Schedule 1 of the New Zealand Superannuation and + # Retirement Income Act 2001, $160 a week; or + # (b) in any other case, $160 a week + scale = params(period).social_security.dictionary.income_test_3b + + # The abatement rate regardless of benefit rate. + abatement_rate = scale.calc(floor) + + # The abatement rate capped at the applicable benefit rate. + return numpy.minimum(abatement_rate, applicable_rate) + + +class jobseeker_support__income_test_4(dictionary.social_security__income_test_4): + label = "Jobseeker Support — Income Test 4" + reference = "https://www.legislation.govt.nz/act/public/2018/0032/latest/whole.html#DLM6784375" + documentation = """ + Income Test 4 means that the applicable rate of [a] benefit must be + reduced by 35 cents for every $1 of the total income of the beneficiary + and the beneficiary’s spouse or partner that is more than $160 a week. + """ + entity = entities.Family + value_type = float + default_value = 0 + definition_period = periods.DateUnit.WEEK + + def formula_2018_11_26(families, period, params): + # Income Test 4 means that the applicable rate of [a] benefit must be + # reduced + + # List of people with families. + people = families.members + + applicable_rate = families.sum( + people("jobseeker_support__base", period), + role = entities.Family.PRINCIPAL, + ) + + # by 35 cents for every $1 of the total income of the + # beneficiary and the beneficiary’s spouse or partner that + # is more than $160 a week. + total_income = families("jobseeker_support__income", period) + + # Required for income tests as i.e. x¢ for every $y. + floor = numpy.floor(total_income) + + scale = params(period).social_security.dictionary.income_test_4 + + # The abatement rate regardless of benefit rate. + abatement_rate = scale.calc(floor) + + # The abatement rate capped at the applicable benefit rate. + return numpy.minimum(abatement_rate, applicable_rate) diff --git a/openfisca_aotearoa/variables/acts/social_security/jobseeker_support/jobseeker_support__benefit.py b/openfisca_aotearoa/variables/acts/social_security/jobseeker_support/jobseeker_support__benefit.py index 39993465..183d68f9 100644 --- a/openfisca_aotearoa/variables/acts/social_security/jobseeker_support/jobseeker_support__benefit.py +++ b/openfisca_aotearoa/variables/acts/social_security/jobseeker_support/jobseeker_support__benefit.py @@ -26,68 +26,7 @@ class jobseeker_support__benefit(variables.Variable): reference = "https://www.legislation.govt.nz/act/public/2018/0032/latest/DLM6784850.html" def formula_2018_11_26(people, period, parameters): - return people("jobseeker_support__entitled", period) * numpy.clip(people("jobseeker_support__base", period) - people("jobseeker_support__reduction", period), 0, people("jobseeker_support__base", period)) - - -class jobseeker_support__reduction(variables.Variable): - value_type = float - entity = entities.Person - definition_period = periods.WEEK - label = "The amount the base benefit is reduced base on the appropriate Income Test and the person & their partners income" - reference = "https://www.legislation.govt.nz/act/public/2018/0032/latest/DLM6784850.html" - - def formula_2018_11_26(people, period, parameters): - family_income = people.family.sum(people.family.members("social_security__income", period), role=entities.Family.PARTNER) + people.family.sum(people.family.members("social_security__income", period), role=entities.Family.PRINCIPAL) - - # numpy.floor required for income tests as it's "35c for every $1" - family_income = numpy.floor(family_income) - - test_1 = people("schedule_4__part1_1_c", period) + \ - people("schedule_4__part1_1_e", period) + \ - people("schedule_4__part1_1_f", period) - - test_3 = people("schedule_4__part1_1_a", period) + \ - people("schedule_4__part1_1_b", period) + \ - people("schedule_4__part1_1_d", period) + \ - people("schedule_4__part1_1_i", period) + \ - people("schedule_4__part1_1_j", period) - - test_4 = people("schedule_4__part1_1_g", period) + \ - people("schedule_4__part1_1_h", period) - - scale_1 = parameters(period).social_security.income_test_1 - scale_3 = parameters(period).social_security.income_test_3b - scale_4 = parameters(period).social_security.income_test_4 - return people("jobseeker_support__entitled", period) * \ - ( - (scale_1.calc(family_income) * test_1) + (scale_3.calc(family_income) * test_3) + (scale_4.calc(family_income) * test_4) - ) - - def formula_2020_11_09(people, period, parameters): - family_income = people.family.sum(people.family.members("social_security__income", period), role=entities.Family.PARTNER) + people.family.sum(people.family.members("social_security__income", period), role=entities.Family.PRINCIPAL) - - # numpy.floor required for income tests as it's "35c for every $1" - family_income = numpy.floor(family_income) - - test_1 = people("schedule_4__part1_1_c", period) + \ - people("schedule_4__part1_1_e", period) + \ - people("schedule_4__part1_1_f", period) - - test_3 = people("schedule_4__part1_1_a", period) + \ - people("schedule_4__part1_1_b", period) + \ - people("schedule_4__part1_1_d", period) + \ - people("schedule_4__part1_1_j", period) - - test_4 = people("schedule_4__part1_1_g", period) + \ - people("schedule_4__part1_1_h", period) - - scale_1 = parameters(period).social_security.income_test_1 - scale_3 = parameters(period).social_security.income_test_3b - scale_4 = parameters(period).social_security.income_test_4 - return people("jobseeker_support__entitled", period) * \ - ( - (scale_1.calc(family_income) * test_1) + (scale_3.calc(family_income) * test_3) + (scale_4.calc(family_income) * test_4) - ) + return people("jobseeker_support__entitled", period) * numpy.clip(people("jobseeker_support__base", period) - people("jobseeker_support__abatement", period), 0, people("jobseeker_support__base", period)) class jobseeker_support__base(variables.Variable): diff --git a/openfisca_aotearoa/variables/acts/social_security/sole_parent_support/income_tests.py b/openfisca_aotearoa/variables/acts/social_security/sole_parent_support/income_tests.py new file mode 100644 index 00000000..491570f2 --- /dev/null +++ b/openfisca_aotearoa/variables/acts/social_security/sole_parent_support/income_tests.py @@ -0,0 +1,192 @@ +"""This module provides the calculation of Sole Parent Support's Income Tests.""" + +import numpy + +from openfisca_core import periods + +from openfisca_aotearoa import entities +from openfisca_aotearoa.variables.acts.social_security import dictionary + + +class sole_parent_support__income_test_1(dictionary.social_security__income_test_1): + label = "Sole Parent Support — Income Test 1" + reference = "https://www.legislation.govt.nz/act/public/2018/0032/latest/whole.html#DLM6784375" + documentation = """ + Income Test 1 means that the applicable rate of [a] benefit must be + reduced by 30 cents for every $1 of the total income of the beneficiary + and the beneficiary’s spouse or partner that is more than $160 a week + but not more than $250 a week; and by 70 cents for every $1 of that + income that is more than $250 a week. + """ + entity = entities.Family + value_type = float + default_value = 0 + definition_period = periods.DateUnit.WEEK + + def formula_2018_11_26(families, period, params): + # Income Test 1 means that the applicable rate of [a] benefit must be + # reduced— + + # List of people with families. + people = families.members + + applicable_rate = families.sum( + people("sole_parent_support__base", period), + role = entities.Family.PRINCIPAL, + ) + + # (a) by 30 cents for every $1 of the total income of the beneficiary + # and the beneficiary’s spouse or partner that is more than $160 a + # week but not more than $250 a week; and + total_income = families("sole_parent_support__income", period) + + # Required for income tests as i.e. x¢ for every $y. + floor = numpy.floor(total_income) + + # (b) by 70 cents for every $1 of that income that is more than $250 a + # week + scale = params(period).social_security.dictionary.income_test_1 + + # The abatement rate regardless of benefit rate. + abatement_rate = scale.calc(floor) + + # The abatement rate capped at the applicable benefit rate. + return numpy.minimum(abatement_rate, applicable_rate) + + +class sole_parent_support__income_test_2(dictionary.social_security__income_test_1): + label = "Sole Parent Support — Income Test 2" + reference = "https://www.legislation.govt.nz/act/public/2018/0032/latest/whole.html#DLM6784375" + documentation = """ + Income Test 2 means that the applicable rate of [a] benefit must be + reduced by 15 cents for every $1 of the total income of the beneficiary + and the beneficiary’s spouse or partner that is more than $160 a week + but not more than $250 a week; and by 35 cents for every $1 of that + income that is more than $250 a week. + """ + entity = entities.Family + value_type = float + default_value = 0 + definition_period = periods.DateUnit.WEEK + + def formula_2018_11_26(families, period, params): + # Income Test 2 means that the applicable rate of benefit must be + # reduced— + + # List of people with families. + people = families.members + + applicable_rate = families.sum( + people("sole_parent_support__base", period), + role = entities.Family.PRINCIPAL, + ) + + # (a) by 15 cents for every $1 of the total income of the beneficiary + # and the beneficiary’s spouse or partner that is more than $160 a + # week but not more than $250 a week; and + total_income = families("sole_parent_support__income", period) + + # Required for income tests as i.e. x¢ for every $y. + floor = numpy.floor(total_income) + + # (b) by 35 cents for every $1 of that income that is more than $250 a + # week + scale = params(period).social_security.dictionary.income_test_2 + + # The abatement rate regardless of benefit rate. + abatement_rate = scale.calc(floor) + + # The abatement rate capped at the applicable benefit rate. + return numpy.minimum(abatement_rate, applicable_rate) + + +class sole_parent_support__income_test_3(dictionary.social_security__income_test_3): + label = "Sole Parent Support — Income Test 3" + reference = "https://www.legislation.govt.nz/act/public/2018/0032/latest/whole.html#DLM6784375" + documentation = """ + Income Test 3 means that the applicable rate of [a] benefit must be + reduced by 70 cents for every $1 of total income of the beneficiary and + the beneficiary’s spouse or partner that is more than, if the rate of + benefit is a rate of New Zealand superannuation stated in clause 1 of + Part 2 of Schedule 1 of the New Zealand Superannuation and Retirement + Income Act 2001, $160 a week; or in any other case, $160 a week. + """ + entity = entities.Family + value_type = float + default_value = 0 + definition_period = periods.DateUnit.WEEK + + def formula_2018_11_26(families, period, params): + # Income Test 3 means that the applicable rate of benefit must be + # reduced— + + # List of people with families. + people = families.members + + applicable_rate = families.sum( + people("sole_parent_support__base", period), + role = entities.Family.PRINCIPAL, + ) + + # by 70 cents for every $1 of total income of the + # beneficiary and the beneficiary’s spouse or partner that + # is more than,— + total_income = families("sole_parent_support__income", period) + + # Required for income tests as i.e. x¢ for every $y. + floor = numpy.floor(total_income) + + # (a) if the rate of benefit is a rate of New Zealand + # superannuation stated in clause 1 of Part 2 of + # Schedule 1 of the New Zealand Superannuation and + # Retirement Income Act 2001, $160 a week; or + # (b) in any other case, $160 a week + scale = params(period).social_security.dictionary.income_test_3b + + # The abatement rate regardless of benefit rate. + abatement_rate = scale.calc(floor) + + # The abatement rate capped at the applicable benefit rate. + return numpy.minimum(abatement_rate, applicable_rate) + + +class sole_parent_support__income_test_4(dictionary.social_security__income_test_4): + label = "Sole Parent Support — Income Test 4" + reference = "https://www.legislation.govt.nz/act/public/2018/0032/latest/whole.html#DLM6784375" + documentation = """ + Income Test 4 means that the applicable rate of [a] benefit must be + reduced by 35 cents for every $1 of the total income of the beneficiary + and the beneficiary’s spouse or partner that is more than $160 a week. + """ + entity = entities.Family + value_type = float + default_value = 0 + definition_period = periods.DateUnit.WEEK + + def formula_2018_11_26(families, period, params): + # Income Test 4 means that the applicable rate of [a] benefit must be + # reduced + + # List of people with families. + people = families.members + + applicable_rate = families.sum( + people("sole_parent_support__base", period), + role = entities.Family.PRINCIPAL, + ) + + # by 35 cents for every $1 of the total income of the + # beneficiary and the beneficiary’s spouse or partner that + # is more than $160 a week. + total_income = families("sole_parent_support__income", period) + + # Required for income tests as i.e. x¢ for every $y. + floor = numpy.floor(total_income) + + scale = params(period).social_security.dictionary.income_test_4 + + # The abatement rate regardless of benefit rate. + abatement_rate = scale.calc(floor) + + # The abatement rate capped at the applicable benefit rate. + return numpy.minimum(abatement_rate, applicable_rate) diff --git a/openfisca_aotearoa/variables/acts/social_security/sole_parent_support/sole_parent_support_benefit.py b/openfisca_aotearoa/variables/acts/social_security/sole_parent_support/sole_parent_support_benefit.py index a3347f04..dffc3a7d 100644 --- a/openfisca_aotearoa/variables/acts/social_security/sole_parent_support/sole_parent_support_benefit.py +++ b/openfisca_aotearoa/variables/acts/social_security/sole_parent_support/sole_parent_support_benefit.py @@ -1,4 +1,4 @@ -"""This module provides eligibility and amount for Jobseeker Support.""" +"""This module provides eligibility and amount for Sole Parent Support.""" import numpy @@ -26,41 +26,104 @@ class sole_parent_support__benefit(variables.Variable): reference = "https://www.legislation.govt.nz/act/public/2018/0032/latest/DLM6784854.html" set_input = holders.set_input_dispatch_by_period - def formula_2018_11_26(people, period, parameters): - return people("sole_parent_support__entitled", period) * numpy.clip(people("sole_parent_support__base", period) - people("sole_parent_support__reduction", period), 0, people("sole_parent_support__base", period)) + def formula_2018_11_26(people, period, _params): + entitled = people("sole_parent_support__entitled", period) + applicable_rate = people("sole_parent_support__base", period) + abatement_rate = people("sole_parent_support__abatement", period) + + return ( + + entitled + * numpy.clip(applicable_rate - abatement_rate, 0, applicable_rate) + ) class sole_parent_support__base(variables.Variable): - value_type = float + label = "Sole Parent Support — Applicable rate" + reference = "https://www.legislation.govt.nz/act/public/2018/0032/latest/DLM6784854.html" + documentation = """ + Base amount or applicable rate of sole parent support (this is, taxed, + and the amounts are supplied after tax, i.e. net). + """ entity = entities.Person + value_type = float + default_value = 0 definition_period = periods.WEEK - reference = "https://www.legislation.govt.nz/act/public/2018/0032/latest/DLM6784854.html" - label = "Jobseeker Support - Base Amount, (this is taxed and the amounts are supplied after tax, i.e. net)" - - def formula_2018_11_26(people, period, parameters): - clause_1_weekly_benefit = parameters(period.first_day).social_security.sole_parent_support.base + def formula_2018_11_26(people, period, params): + clause_1_weekly_benefit = ( + params(period.first_day) + .social_security + .sole_parent_support.base + ) - return people("sole_parent_support__entitled", period) * clause_1_weekly_benefit + return ( + + people("sole_parent_support__entitled", period) + * clause_1_weekly_benefit + ) -class sole_parent_support__reduction(variables.Variable): - value_type = float +class sole_parent_support__abatement(variables.Variable): + label = "Sole Parent Support — Abatement rate" + reference = "https://www.legislation.govt.nz/act/public/2018/0032/latest/DLM6784854.html" + documentation = """ + The amount the base benefit is reduced based on the appropriate Income + Test and the person & their partners income. + """ entity = entities.Person + value_type = float + default_value = 0 definition_period = periods.WEEK - label = "The amount the base benefit is reduced base on the appropriate Income Test and the person & their partners income" - reference = "https://www.legislation.govt.nz/act/public/2018/0032/latest/DLM6784850.html" - def formula_2018_11_26(people, period, parameters): - family_income = people.family.sum(people.family.members("social_security__income", period), role=entities.Family.PARTNER) + people.family.sum(people.family.members("social_security__income", period), role=entities.Family.PRINCIPAL) + def formula_2018_11_26(people, period, _params): + return people.family("sole_parent_support__income_test_1", period) + - childcare_deduction_limit = parameters(period.first_day).social_security.sole_parent_support.childcare_deduction_limit - family_income = family_income - numpy.clip(people("sole_parent_support__weekly_childcare_cost", period), 0, childcare_deduction_limit) - # numpy.floor required for income tests as it's "35c for every $1" - family_income = numpy.floor(family_income) +class sole_parent_support__income(variables.Variable): + label = "Sole Parent Support — Income" + reference = "https://www.legislation.govt.nz/act/public/2018/0032/latest/DLM6784854.html" + documentation = """Total income of the people and their partners.""" + entity = entities.Family + value_type = float + default_value = 0 + definition_period = periods.WEEK - scale_1 = parameters(period).social_security.income_test_1 - return people("sole_parent_support__entitled", period) * scale_1.calc(family_income) + def formula_2018_11_26(families, period, params): + # 1. To a beneficiary with 1 or more dependent children + beneficiary_income = families.sum( + families.members("social_security__income", period), + role = entities.Family.PRINCIPAL, + ) + + spouse_or_partner_income = families.sum( + families.members("social_security__income", period), + role = entities.Family.PARTNER, + ) + + family_income = beneficiary_income + spouse_or_partner_income + + # 2. For the purposes of clause 1, MSD may disregard up to $20 a week + # of the beneficiary’s personal earnings used to meet the cost of + # childcare for any of the beneficiary’s dependent children. + childcare_deduction_limit = ( + params(period.first_day) + .social_security + .sole_parent_support + .childcare_deduction_limit + ) + + childcare_costs = families.sum( + families.members( + "sole_parent_support__weekly_childcare_cost", + period, + ), + ) + + total_income = ( + + family_income + - numpy.clip(childcare_costs, 0, childcare_deduction_limit) + ) + + return total_income class sole_parent_support__weekly_childcare_cost(variables.Variable): diff --git a/openfisca_aotearoa/variables/acts/social_security/superannuation/income_tests.py b/openfisca_aotearoa/variables/acts/social_security/superannuation/income_tests.py new file mode 100644 index 00000000..ab47f5a4 --- /dev/null +++ b/openfisca_aotearoa/variables/acts/social_security/superannuation/income_tests.py @@ -0,0 +1,192 @@ +"""This module provides the calculation of Superannuation's Income Tests.""" + +import numpy + +from openfisca_core import periods + +from openfisca_aotearoa import entities +from openfisca_aotearoa.variables.acts.social_security import dictionary + + +class superannuation__income_test_1(dictionary.social_security__income_test_1): + label = "Superannuation — Income Test 1" + reference = "https://www.legislation.govt.nz/act/public/2018/0032/latest/whole.html#DLM6784375" + documentation = """ + Income Test 1 means that the applicable rate of [a] benefit must be + reduced by 30 cents for every $1 of the total income of the beneficiary + and the beneficiary’s spouse or partner that is more than $160 a week + but not more than $250 a week; and by 70 cents for every $1 of that + income that is more than $250 a week. + """ + entity = entities.Family + value_type = float + default_value = 0 + definition_period = periods.DateUnit.WEEK + + def formula_2018_11_26(families, period, params): + # Income Test 1 means that the applicable rate of [a] benefit must be + # reduced— + + # List of people with families. + people = families.members + + applicable_rate = families.sum( + people("superannuation__base", period), + role = entities.Family.PRINCIPAL, + ) + + # (a) by 30 cents for every $1 of the total income of the beneficiary + # and the beneficiary’s spouse or partner that is more than $160 a + # week but not more than $250 a week; and + total_income = families("superannuation__income", period) + + # Required for income tests as i.e. x¢ for every $y. + floor = numpy.floor(total_income) + + # (b) by 70 cents for every $1 of that income that is more than $250 a + # week + scale = params(period).social_security.dictionary.income_test_1 + + # The abatement rate regardless of benefit rate. + abatement_rate = scale.calc(floor) + + # The abatement rate capped at the applicable benefit rate. + return numpy.minimum(abatement_rate, applicable_rate) + + +class superannuation__income_test_2(dictionary.social_security__income_test_1): + label = "Superannuation — Income Test 2" + reference = "https://www.legislation.govt.nz/act/public/2018/0032/latest/whole.html#DLM6784375" + documentation = """ + Income Test 2 means that the applicable rate of [a] benefit must be + reduced by 15 cents for every $1 of the total income of the beneficiary + and the beneficiary’s spouse or partner that is more than $160 a week + but not more than $250 a week; and by 35 cents for every $1 of that + income that is more than $250 a week. + """ + entity = entities.Family + value_type = float + default_value = 0 + definition_period = periods.DateUnit.WEEK + + def formula_2018_11_26(families, period, params): + # Income Test 2 means that the applicable rate of benefit must be + # reduced— + + # List of people with families. + people = families.members + + applicable_rate = families.sum( + people("superannuation__base", period), + role = entities.Family.PRINCIPAL, + ) + + # (a) by 15 cents for every $1 of the total income of the beneficiary + # and the beneficiary’s spouse or partner that is more than $160 a + # week but not more than $250 a week; and + total_income = families("superannuation__income", period) + + # Required for income tests as i.e. x¢ for every $y. + floor = numpy.floor(total_income) + + # (b) by 35 cents for every $1 of that income that is more than $250 a + # week + scale = params(period).social_security.dictionary.income_test_2 + + # The abatement rate regardless of benefit rate. + abatement_rate = scale.calc(floor) + + # The abatement rate capped at the applicable benefit rate. + return numpy.minimum(abatement_rate, applicable_rate) + + +class superannuation__income_test_3(dictionary.social_security__income_test_3): + label = "Superannuation — Income Test 3" + reference = "https://www.legislation.govt.nz/act/public/2018/0032/latest/whole.html#DLM6784375" + documentation = """ + Income Test 3 means that the applicable rate of [a] benefit must be + reduced by 70 cents for every $1 of total income of the beneficiary and + the beneficiary’s spouse or partner that is more than, if the rate of + benefit is a rate of New Zealand superannuation stated in clause 1 of + Part 2 of Schedule 1 of the New Zealand Superannuation and Retirement + Income Act 2001, $160 a week; or in any other case, $160 a week. + """ + entity = entities.Family + value_type = float + default_value = 0 + definition_period = periods.DateUnit.WEEK + + def formula_2018_11_26(families, period, params): + # Income Test 3 means that the applicable rate of benefit must be + # reduced— + + # List of people with families. + people = families.members + + applicable_rate = families.sum( + people("superannuation__base", period), + role = entities.Family.PRINCIPAL, + ) + + # by 70 cents for every $1 of total income of the + # beneficiary and the beneficiary’s spouse or partner that + # is more than,— + total_income = families("superannuation__income", period) + + # Required for income tests as i.e. x¢ for every $y. + floor = numpy.floor(total_income) + + # (a) if the rate of benefit is a rate of New Zealand + # superannuation stated in clause 1 of Part 2 of + # Schedule 1 of the New Zealand Superannuation and + # Retirement Income Act 2001, $160 a week; or + # (b) in any other case, $160 a week + scale = params(period).social_security.dictionary.income_test_3a + + # The abatement rate regardless of benefit rate. + abatement_rate = scale.calc(floor) + + # The abatement rate capped at the applicable benefit rate. + return numpy.minimum(abatement_rate, applicable_rate) + + +class superannuation__income_test_4(dictionary.social_security__income_test_4): + label = "Superannuation — Income Test 4" + reference = "https://www.legislation.govt.nz/act/public/2018/0032/latest/whole.html#DLM6784375" + documentation = """ + Income Test 4 means that the applicable rate of [a] benefit must be + reduced by 35 cents for every $1 of the total income of the beneficiary + and the beneficiary’s spouse or partner that is more than $160 a week. + """ + entity = entities.Family + value_type = float + default_value = 0 + definition_period = periods.DateUnit.WEEK + + def formula_2018_11_26(families, period, params): + # Income Test 4 means that the applicable rate of [a] benefit must be + # reduced + + # List of people with families. + people = families.members + + applicable_rate = families.sum( + people("superannuation__base", period), + role = entities.Family.PRINCIPAL, + ) + + # by 35 cents for every $1 of the total income of the + # beneficiary and the beneficiary’s spouse or partner that + # is more than $160 a week. + total_income = families("superannuation__income", period) + + # Required for income tests as i.e. x¢ for every $y. + floor = numpy.floor(total_income) + + scale = params(period).social_security.dictionary.income_test_4 + + # The abatement rate regardless of benefit rate. + abatement_rate = scale.calc(floor) + + # The abatement rate capped at the applicable benefit rate. + return numpy.minimum(abatement_rate, applicable_rate) diff --git a/openfisca_aotearoa/variables/acts/social_security/supported_living_payment/income_tests.py b/openfisca_aotearoa/variables/acts/social_security/supported_living_payment/income_tests.py new file mode 100644 index 00000000..b6230249 --- /dev/null +++ b/openfisca_aotearoa/variables/acts/social_security/supported_living_payment/income_tests.py @@ -0,0 +1,192 @@ +"""This module provides the calculation of Supported Living Payment's Income Tests.""" + +import numpy + +from openfisca_core import periods + +from openfisca_aotearoa import entities +from openfisca_aotearoa.variables.acts.social_security import dictionary + + +class supported_living_payment__income_test_1(dictionary.social_security__income_test_1): + label = "Supported Living Payment — Income Test 1" + reference = "https://www.legislation.govt.nz/act/public/2018/0032/latest/whole.html#DLM6784375" + documentation = """ + Income Test 1 means that the applicable rate of [a] benefit must be + reduced by 30 cents for every $1 of the total income of the beneficiary + and the beneficiary’s spouse or partner that is more than $160 a week + but not more than $250 a week; and by 70 cents for every $1 of that + income that is more than $250 a week. + """ + entity = entities.Family + value_type = float + default_value = 0 + definition_period = periods.DateUnit.WEEK + + def formula_2018_11_26(families, period, params): + # Income Test 1 means that the applicable rate of [a] benefit must be + # reduced— + + # List of people with families. + people = families.members + + applicable_rate = families.sum( + people("supported_living_payment__base", period), + role = entities.Family.PRINCIPAL, + ) + + # (a) by 30 cents for every $1 of the total income of the beneficiary + # and the beneficiary’s spouse or partner that is more than $160 a + # week but not more than $250 a week; and + total_income = families("supported_living_payment__income", period) + + # Required for income tests as i.e. x¢ for every $y. + floor = numpy.floor(total_income) + + # (b) by 70 cents for every $1 of that income that is more than $250 a + # week + scale = params(period).social_security.dictionary.income_test_1 + + # The abatement rate regardless of benefit rate. + abatement_rate = scale.calc(floor) + + # The abatement rate capped at the applicable benefit rate. + return numpy.minimum(abatement_rate, applicable_rate) + + +class supported_living_payment__income_test_2(dictionary.social_security__income_test_1): + label = "Supported Living Payment — Income Test 2" + reference = "https://www.legislation.govt.nz/act/public/2018/0032/latest/whole.html#DLM6784375" + documentation = """ + Income Test 2 means that the applicable rate of [a] benefit must be + reduced by 15 cents for every $1 of the total income of the beneficiary + and the beneficiary’s spouse or partner that is more than $160 a week + but not more than $250 a week; and by 35 cents for every $1 of that + income that is more than $250 a week. + """ + entity = entities.Family + value_type = float + default_value = 0 + definition_period = periods.DateUnit.WEEK + + def formula_2018_11_26(families, period, params): + # Income Test 2 means that the applicable rate of benefit must be + # reduced— + + # List of people with families. + people = families.members + + applicable_rate = families.sum( + people("supported_living_payment__base", period), + role = entities.Family.PRINCIPAL, + ) + + # (a) by 15 cents for every $1 of the total income of the beneficiary + # and the beneficiary’s spouse or partner that is more than $160 a + # week but not more than $250 a week; and + total_income = families("supported_living_payment__income", period) + + # Required for income tests as i.e. x¢ for every $y. + floor = numpy.floor(total_income) + + # (b) by 35 cents for every $1 of that income that is more than $250 a + # week + scale = params(period).social_security.dictionary.income_test_2 + + # The abatement rate regardless of benefit rate. + abatement_rate = scale.calc(floor) + + # The abatement rate capped at the applicable benefit rate. + return numpy.minimum(abatement_rate, applicable_rate) + + +class supported_living_payment__income_test_3(dictionary.social_security__income_test_3): + label = "Supported Living Payment — Income Test 3" + reference = "https://www.legislation.govt.nz/act/public/2018/0032/latest/whole.html#DLM6784375" + documentation = """ + Income Test 3 means that the applicable rate of [a] benefit must be + reduced by 70 cents for every $1 of total income of the beneficiary and + the beneficiary’s spouse or partner that is more than, if the rate of + benefit is a rate of New Zealand superannuation stated in clause 1 of + Part 2 of Schedule 1 of the New Zealand Superannuation and Retirement + Income Act 2001, $160 a week; or in any other case, $160 a week. + """ + entity = entities.Family + value_type = float + default_value = 0 + definition_period = periods.DateUnit.WEEK + + def formula_2018_11_26(families, period, params): + # Income Test 3 means that the applicable rate of benefit must be + # reduced— + + # List of people with families. + people = families.members + + applicable_rate = families.sum( + people("supported_living_payment__base", period), + role = entities.Family.PRINCIPAL, + ) + + # by 70 cents for every $1 of total income of the + # beneficiary and the beneficiary’s spouse or partner that + # is more than,— + total_income = families("supported_living_payment__income", period) + + # Required for income tests as i.e. x¢ for every $y. + floor = numpy.floor(total_income) + + # (a) if the rate of benefit is a rate of New Zealand + # superannuation stated in clause 1 of Part 2 of + # Schedule 1 of the New Zealand Superannuation and + # Retirement Income Act 2001, $160 a week; or + # (b) in any other case, $160 a week + scale = params(period).social_security.dictionary.income_test_3b + + # The abatement rate regardless of benefit rate. + abatement_rate = scale.calc(floor) + + # The abatement rate capped at the applicable benefit rate. + return numpy.minimum(abatement_rate, applicable_rate) + + +class supported_living_payment__income_test_4(dictionary.social_security__income_test_4): + label = "Supported Living Payment — Income Test 4" + reference = "https://www.legislation.govt.nz/act/public/2018/0032/latest/whole.html#DLM6784375" + documentation = """ + Income Test 4 means that the applicable rate of [a] benefit must be + reduced by 35 cents for every $1 of the total income of the beneficiary + and the beneficiary’s spouse or partner that is more than $160 a week. + """ + entity = entities.Family + value_type = float + default_value = 0 + definition_period = periods.DateUnit.WEEK + + def formula_2018_11_26(families, period, params): + # Income Test 4 means that the applicable rate of [a] benefit must be + # reduced + + # List of people with families. + people = families.members + + applicable_rate = families.sum( + people("supported_living_payment__base", period), + role = entities.Family.PRINCIPAL, + ) + + # by 35 cents for every $1 of the total income of the + # beneficiary and the beneficiary’s spouse or partner that + # is more than $160 a week. + total_income = families("supported_living_payment__income", period) + + # Required for income tests as i.e. x¢ for every $y. + floor = numpy.floor(total_income) + + scale = params(period).social_security.dictionary.income_test_4 + + # The abatement rate regardless of benefit rate. + abatement_rate = scale.calc(floor) + + # The abatement rate capped at the applicable benefit rate. + return numpy.minimum(abatement_rate, applicable_rate) diff --git a/openfisca_aotearoa/variables/acts/social_security/veterans_pension/income_tests.py b/openfisca_aotearoa/variables/acts/social_security/veterans_pension/income_tests.py new file mode 100644 index 00000000..d5131131 --- /dev/null +++ b/openfisca_aotearoa/variables/acts/social_security/veterans_pension/income_tests.py @@ -0,0 +1,192 @@ +"""This module provides the calculation of Veteran's Pension's Income Tests.""" + +import numpy + +from openfisca_core import periods + +from openfisca_aotearoa import entities +from openfisca_aotearoa.variables.acts.social_security import dictionary + + +class veterans_pension__income_test_1(dictionary.social_security__income_test_1): + label = "Veteran's Pension — Income Test 1" + reference = "https://www.legislation.govt.nz/act/public/2018/0032/latest/whole.html#DLM6784375" + documentation = """ + Income Test 1 means that the applicable rate of [a] benefit must be + reduced by 30 cents for every $1 of the total income of the beneficiary + and the beneficiary’s spouse or partner that is more than $160 a week + but not more than $250 a week; and by 70 cents for every $1 of that + income that is more than $250 a week. + """ + entity = entities.Family + value_type = float + default_value = 0 + definition_period = periods.DateUnit.WEEK + + def formula_2018_11_26(families, period, params): + # Income Test 1 means that the applicable rate of [a] benefit must be + # reduced— + + # List of people with families. + people = families.members + + applicable_rate = families.sum( + people("veterans_pension__base", period), + role = entities.Family.PRINCIPAL, + ) + + # (a) by 30 cents for every $1 of the total income of the beneficiary + # and the beneficiary’s spouse or partner that is more than $160 a + # week but not more than $250 a week; and + total_income = families("veterans_pension__income", period) + + # Required for income tests as i.e. x¢ for every $y. + floor = numpy.floor(total_income) + + # (b) by 70 cents for every $1 of that income that is more than $250 a + # week + scale = params(period).social_security.dictionary.income_test_1 + + # The abatement rate regardless of benefit rate. + abatement_rate = scale.calc(floor) + + # The abatement rate capped at the applicable benefit rate. + return numpy.minimum(abatement_rate, applicable_rate) + + +class veterans_pension__income_test_2(dictionary.social_security__income_test_1): + label = "Veteran's Pension — Income Test 2" + reference = "https://www.legislation.govt.nz/act/public/2018/0032/latest/whole.html#DLM6784375" + documentation = """ + Income Test 2 means that the applicable rate of [a] benefit must be + reduced by 15 cents for every $1 of the total income of the beneficiary + and the beneficiary’s spouse or partner that is more than $160 a week + but not more than $250 a week; and by 35 cents for every $1 of that + income that is more than $250 a week. + """ + entity = entities.Family + value_type = float + default_value = 0 + definition_period = periods.DateUnit.WEEK + + def formula_2018_11_26(families, period, params): + # Income Test 2 means that the applicable rate of benefit must be + # reduced— + + # List of people with families. + people = families.members + + applicable_rate = families.sum( + people("veterans_pension__base", period), + role = entities.Family.PRINCIPAL, + ) + + # (a) by 15 cents for every $1 of the total income of the beneficiary + # and the beneficiary’s spouse or partner that is more than $160 a + # week but not more than $250 a week; and + total_income = families("veterans_pension__income", period) + + # Required for income tests as i.e. x¢ for every $y. + floor = numpy.floor(total_income) + + # (b) by 35 cents for every $1 of that income that is more than $250 a + # week + scale = params(period).social_security.dictionary.income_test_2 + + # The abatement rate regardless of benefit rate. + abatement_rate = scale.calc(floor) + + # The abatement rate capped at the applicable benefit rate. + return numpy.minimum(abatement_rate, applicable_rate) + + +class veterans_pension__income_test_3(dictionary.social_security__income_test_3): + label = "Veteran's Pension — Income Test 3" + reference = "https://www.legislation.govt.nz/act/public/2018/0032/latest/whole.html#DLM6784375" + documentation = """ + Income Test 3 means that the applicable rate of [a] benefit must be + reduced by 70 cents for every $1 of total income of the beneficiary and + the beneficiary’s spouse or partner that is more than, if the rate of + benefit is a rate of New Zealand superannuation stated in clause 1 of + Part 2 of Schedule 1 of the New Zealand Superannuation and Retirement + Income Act 2001, $160 a week; or in any other case, $160 a week. + """ + entity = entities.Family + value_type = float + default_value = 0 + definition_period = periods.DateUnit.WEEK + + def formula_2018_11_26(families, period, params): + # Income Test 3 means that the applicable rate of benefit must be + # reduced— + + # List of people with families. + people = families.members + + applicable_rate = families.sum( + people("veterans_pension__base", period), + role = entities.Family.PRINCIPAL, + ) + + # by 70 cents for every $1 of total income of the + # beneficiary and the beneficiary’s spouse or partner that + # is more than,— + total_income = families("veterans_pension__income", period) + + # Required for income tests as i.e. x¢ for every $y. + floor = numpy.floor(total_income) + + # (a) if the rate of benefit is a rate of New Zealand + # superannuation stated in clause 1 of Part 2 of + # Schedule 1 of the New Zealand Superannuation and + # Retirement Income Act 2001, $160 a week; or + # (b) in any other case, $160 a week + scale = params(period).social_security.dictionary.income_test_3a + + # The abatement rate regardless of benefit rate. + abatement_rate = scale.calc(floor) + + # The abatement rate capped at the applicable benefit rate. + return numpy.minimum(abatement_rate, applicable_rate) + + +class veterans_pension__income_test_4(dictionary.social_security__income_test_4): + label = "Veteran's Pension — Income Test 4" + reference = "https://www.legislation.govt.nz/act/public/2018/0032/latest/whole.html#DLM6784375" + documentation = """ + Income Test 4 means that the applicable rate of [a] benefit must be + reduced by 35 cents for every $1 of the total income of the beneficiary + and the beneficiary’s spouse or partner that is more than $160 a week. + """ + entity = entities.Family + value_type = float + default_value = 0 + definition_period = periods.DateUnit.WEEK + + def formula_2018_11_26(families, period, params): + # Income Test 4 means that the applicable rate of [a] benefit must be + # reduced + + # List of people with families. + people = families.members + + applicable_rate = families.sum( + people("veterans_pension__base", period), + role = entities.Family.PRINCIPAL, + ) + + # by 35 cents for every $1 of the total income of the + # beneficiary and the beneficiary’s spouse or partner that + # is more than $160 a week. + total_income = families("veterans_pension__income", period) + + # Required for income tests as i.e. x¢ for every $y. + floor = numpy.floor(total_income) + + scale = params(period).social_security.dictionary.income_test_4 + + # The abatement rate regardless of benefit rate. + abatement_rate = scale.calc(floor) + + # The abatement rate capped at the applicable benefit rate. + return numpy.minimum(abatement_rate, applicable_rate) diff --git a/openfisca_aotearoa/variables/acts/social_security/young_parent_payment/income_tests.py b/openfisca_aotearoa/variables/acts/social_security/young_parent_payment/income_tests.py new file mode 100644 index 00000000..b5f9b490 --- /dev/null +++ b/openfisca_aotearoa/variables/acts/social_security/young_parent_payment/income_tests.py @@ -0,0 +1,192 @@ +"""This module provides the calculation of Youth Parent Payment's Income Tests.""" + +import numpy + +from openfisca_core import periods + +from openfisca_aotearoa import entities +from openfisca_aotearoa.variables.acts.social_security import dictionary + + +class youth_parent_payment__income_test_1(dictionary.social_security__income_test_1): + label = "Youth Parent Payment — Income Test 1" + reference = "https://www.legislation.govt.nz/act/public/2018/0032/latest/whole.html#DLM6784375" + documentation = """ + Income Test 1 means that the applicable rate of [a] benefit must be + reduced by 30 cents for every $1 of the total income of the beneficiary + and the beneficiary’s spouse or partner that is more than $160 a week + but not more than $250 a week; and by 70 cents for every $1 of that + income that is more than $250 a week. + """ + entity = entities.Family + value_type = float + default_value = 0 + definition_period = periods.DateUnit.WEEK + + def formula_2018_11_26(families, period, params): + # Income Test 1 means that the applicable rate of [a] benefit must be + # reduced— + + # List of people with families. + people = families.members + + applicable_rate = families.sum( + people("youth_parent_payment__base", period), + role = entities.Family.PRINCIPAL, + ) + + # (a) by 30 cents for every $1 of the total income of the beneficiary + # and the beneficiary’s spouse or partner that is more than $160 a + # week but not more than $250 a week; and + total_income = families("youth_parent_payment__income", period) + + # Required for income tests as i.e. x¢ for every $y. + floor = numpy.floor(total_income) + + # (b) by 70 cents for every $1 of that income that is more than $250 a + # week + scale = params(period).social_security.dictionary.income_test_1 + + # The abatement rate regardless of benefit rate. + abatement_rate = scale.calc(floor) + + # The abatement rate capped at the applicable benefit rate. + return numpy.minimum(abatement_rate, applicable_rate) + + +class youth_parent_payment__income_test_2(dictionary.social_security__income_test_1): + label = "Youth Parent Payment — Income Test 2" + reference = "https://www.legislation.govt.nz/act/public/2018/0032/latest/whole.html#DLM6784375" + documentation = """ + Income Test 2 means that the applicable rate of [a] benefit must be + reduced by 15 cents for every $1 of the total income of the beneficiary + and the beneficiary’s spouse or partner that is more than $160 a week + but not more than $250 a week; and by 35 cents for every $1 of that + income that is more than $250 a week. + """ + entity = entities.Family + value_type = float + default_value = 0 + definition_period = periods.DateUnit.WEEK + + def formula_2018_11_26(families, period, params): + # Income Test 2 means that the applicable rate of benefit must be + # reduced— + + # List of people with families. + people = families.members + + applicable_rate = families.sum( + people("youth_parent_payment__base", period), + role = entities.Family.PRINCIPAL, + ) + + # (a) by 15 cents for every $1 of the total income of the beneficiary + # and the beneficiary’s spouse or partner that is more than $160 a + # week but not more than $250 a week; and + total_income = families("youth_parent_payment__income", period) + + # Required for income tests as i.e. x¢ for every $y. + floor = numpy.floor(total_income) + + # (b) by 35 cents for every $1 of that income that is more than $250 a + # week + scale = params(period).social_security.dictionary.income_test_2 + + # The abatement rate regardless of benefit rate. + abatement_rate = scale.calc(floor) + + # The abatement rate capped at the applicable benefit rate. + return numpy.minimum(abatement_rate, applicable_rate) + + +class youth_parent_payment__income_test_3(dictionary.social_security__income_test_3): + label = "Youth Parent Payment — Income Test 3" + reference = "https://www.legislation.govt.nz/act/public/2018/0032/latest/whole.html#DLM6784375" + documentation = """ + Income Test 3 means that the applicable rate of [a] benefit must be + reduced by 70 cents for every $1 of total income of the beneficiary and + the beneficiary’s spouse or partner that is more than, if the rate of + benefit is a rate of New Zealand superannuation stated in clause 1 of + Part 2 of Schedule 1 of the New Zealand Superannuation and Retirement + Income Act 2001, $160 a week; or in any other case, $160 a week. + """ + entity = entities.Family + value_type = float + default_value = 0 + definition_period = periods.DateUnit.WEEK + + def formula_2018_11_26(families, period, params): + # Income Test 3 means that the applicable rate of benefit must be + # reduced— + + # List of people with families. + people = families.members + + applicable_rate = families.sum( + people("youth_parent_payment__base", period), + role = entities.Family.PRINCIPAL, + ) + + # by 70 cents for every $1 of total income of the + # beneficiary and the beneficiary’s spouse or partner that + # is more than,— + total_income = families("youth_parent_payment__income", period) + + # Required for income tests as i.e. x¢ for every $y. + floor = numpy.floor(total_income) + + # (a) if the rate of benefit is a rate of New Zealand + # superannuation stated in clause 1 of Part 2 of + # Schedule 1 of the New Zealand Superannuation and + # Retirement Income Act 2001, $160 a week; or + # (b) in any other case, $160 a week + scale = params(period).social_security.dictionary.income_test_3b + + # The abatement rate regardless of benefit rate. + abatement_rate = scale.calc(floor) + + # The abatement rate capped at the applicable benefit rate. + return numpy.minimum(abatement_rate, applicable_rate) + + +class youth_parent_payment__income_test_4(dictionary.social_security__income_test_4): + label = "Youth Parent Payment — Income Test 4" + reference = "https://www.legislation.govt.nz/act/public/2018/0032/latest/whole.html#DLM6784375" + documentation = """ + Income Test 4 means that the applicable rate of [a] benefit must be + reduced by 35 cents for every $1 of the total income of the beneficiary + and the beneficiary’s spouse or partner that is more than $160 a week. + """ + entity = entities.Family + value_type = float + default_value = 0 + definition_period = periods.DateUnit.WEEK + + def formula_2018_11_26(families, period, params): + # Income Test 4 means that the applicable rate of [a] benefit must be + # reduced + + # List of people with families. + people = families.members + + applicable_rate = families.sum( + people("youth_parent_payment__base", period), + role = entities.Family.PRINCIPAL, + ) + + # by 35 cents for every $1 of the total income of the + # beneficiary and the beneficiary’s spouse or partner that + # is more than $160 a week. + total_income = families("youth_parent_payment__income", period) + + # Required for income tests as i.e. x¢ for every $y. + floor = numpy.floor(total_income) + + scale = params(period).social_security.dictionary.income_test_4 + + # The abatement rate regardless of benefit rate. + abatement_rate = scale.calc(floor) + + # The abatement rate capped at the applicable benefit rate. + return numpy.minimum(abatement_rate, applicable_rate) diff --git a/openfisca_aotearoa/variables/acts/social_security/youth_payment/income_tests.py b/openfisca_aotearoa/variables/acts/social_security/youth_payment/income_tests.py new file mode 100644 index 00000000..de065803 --- /dev/null +++ b/openfisca_aotearoa/variables/acts/social_security/youth_payment/income_tests.py @@ -0,0 +1,192 @@ +"""This module provides the calculation of Youth Payment's Income Tests.""" + +import numpy + +from openfisca_core import periods + +from openfisca_aotearoa import entities +from openfisca_aotearoa.variables.acts.social_security import dictionary + + +class youth_payment__income_test_1(dictionary.social_security__income_test_1): + label = "Youth Payment — Income Test 1" + reference = "https://www.legislation.govt.nz/act/public/2018/0032/latest/whole.html#DLM6784375" + documentation = """ + Income Test 1 means that the applicable rate of [a] benefit must be + reduced by 30 cents for every $1 of the total income of the beneficiary + and the beneficiary’s spouse or partner that is more than $160 a week + but not more than $250 a week; and by 70 cents for every $1 of that + income that is more than $250 a week. + """ + entity = entities.Family + value_type = float + default_value = 0 + definition_period = periods.DateUnit.WEEK + + def formula_2018_11_26(families, period, params): + # Income Test 1 means that the applicable rate of [a] benefit must be + # reduced— + + # List of people with families. + people = families.members + + applicable_rate = families.sum( + people("youth_payment__base", period), + role = entities.Family.PRINCIPAL, + ) + + # (a) by 30 cents for every $1 of the total income of the beneficiary + # and the beneficiary’s spouse or partner that is more than $160 a + # week but not more than $250 a week; and + total_income = families("youth_payment__income", period) + + # Required for income tests as i.e. x¢ for every $y. + floor = numpy.floor(total_income) + + # (b) by 70 cents for every $1 of that income that is more than $250 a + # week + scale = params(period).social_security.dictionary.income_test_1 + + # The abatement rate regardless of benefit rate. + abatement_rate = scale.calc(floor) + + # The abatement rate capped at the applicable benefit rate. + return numpy.minimum(abatement_rate, applicable_rate) + + +class youth_payment__income_test_2(dictionary.social_security__income_test_1): + label = "Youth Payment — Income Test 2" + reference = "https://www.legislation.govt.nz/act/public/2018/0032/latest/whole.html#DLM6784375" + documentation = """ + Income Test 2 means that the applicable rate of [a] benefit must be + reduced by 15 cents for every $1 of the total income of the beneficiary + and the beneficiary’s spouse or partner that is more than $160 a week + but not more than $250 a week; and by 35 cents for every $1 of that + income that is more than $250 a week. + """ + entity = entities.Family + value_type = float + default_value = 0 + definition_period = periods.DateUnit.WEEK + + def formula_2018_11_26(families, period, params): + # Income Test 2 means that the applicable rate of benefit must be + # reduced— + + # List of people with families. + people = families.members + + applicable_rate = families.sum( + people("youth_payment__base", period), + role = entities.Family.PRINCIPAL, + ) + + # (a) by 15 cents for every $1 of the total income of the beneficiary + # and the beneficiary’s spouse or partner that is more than $160 a + # week but not more than $250 a week; and + total_income = families("youth_payment__income", period) + + # Required for income tests as i.e. x¢ for every $y. + floor = numpy.floor(total_income) + + # (b) by 35 cents for every $1 of that income that is more than $250 a + # week + scale = params(period).social_security.dictionary.income_test_2 + + # The abatement rate regardless of benefit rate. + abatement_rate = scale.calc(floor) + + # The abatement rate capped at the applicable benefit rate. + return numpy.minimum(abatement_rate, applicable_rate) + + +class youth_payment__income_test_3(dictionary.social_security__income_test_3): + label = "Youth Payment — Income Test 3" + reference = "https://www.legislation.govt.nz/act/public/2018/0032/latest/whole.html#DLM6784375" + documentation = """ + Income Test 3 means that the applicable rate of [a] benefit must be + reduced by 70 cents for every $1 of total income of the beneficiary and + the beneficiary’s spouse or partner that is more than, if the rate of + benefit is a rate of New Zealand superannuation stated in clause 1 of + Part 2 of Schedule 1 of the New Zealand Superannuation and Retirement + Income Act 2001, $160 a week; or in any other case, $160 a week. + """ + entity = entities.Family + value_type = float + default_value = 0 + definition_period = periods.DateUnit.WEEK + + def formula_2018_11_26(families, period, params): + # Income Test 3 means that the applicable rate of benefit must be + # reduced— + + # List of people with families. + people = families.members + + applicable_rate = families.sum( + people("youth_payment__base", period), + role = entities.Family.PRINCIPAL, + ) + + # by 70 cents for every $1 of total income of the + # beneficiary and the beneficiary’s spouse or partner that + # is more than,— + total_income = families("youth_payment__income", period) + + # Required for income tests as i.e. x¢ for every $y. + floor = numpy.floor(total_income) + + # (a) if the rate of benefit is a rate of New Zealand + # superannuation stated in clause 1 of Part 2 of + # Schedule 1 of the New Zealand Superannuation and + # Retirement Income Act 2001, $160 a week; or + # (b) in any other case, $160 a week + scale = params(period).social_security.dictionary.income_test_3b + + # The abatement rate regardless of benefit rate. + abatement_rate = scale.calc(floor) + + # The abatement rate capped at the applicable benefit rate. + return numpy.minimum(abatement_rate, applicable_rate) + + +class youth_payment__income_test_4(dictionary.social_security__income_test_4): + label = "Youth Payment — Income Test 4" + reference = "https://www.legislation.govt.nz/act/public/2018/0032/latest/whole.html#DLM6784375" + documentation = """ + Income Test 4 means that the applicable rate of [a] benefit must be + reduced by 35 cents for every $1 of the total income of the beneficiary + and the beneficiary’s spouse or partner that is more than $160 a week. + """ + entity = entities.Family + value_type = float + default_value = 0 + definition_period = periods.DateUnit.WEEK + + def formula_2018_11_26(families, period, params): + # Income Test 4 means that the applicable rate of [a] benefit must be + # reduced + + # List of people with families. + people = families.members + + applicable_rate = families.sum( + people("youth_payment__base", period), + role = entities.Family.PRINCIPAL, + ) + + # by 35 cents for every $1 of the total income of the + # beneficiary and the beneficiary’s spouse or partner that + # is more than $160 a week. + total_income = families("youth_payment__income", period) + + # Required for income tests as i.e. x¢ for every $y. + floor = numpy.floor(total_income) + + scale = params(period).social_security.dictionary.income_test_4 + + # The abatement rate regardless of benefit rate. + abatement_rate = scale.calc(floor) + + # The abatement rate capped at the applicable benefit rate. + return numpy.minimum(abatement_rate, applicable_rate) diff --git a/pyproject.toml b/pyproject.toml index 22b05544..92adb3a2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "OpenFisca-Aotearoa" -version = "20.1.1" +version = "21.0.0" description = "OpenFisca rules-as-code system for Aotearoa." license = "AGPL-3.0-only" authors = [