Skip to content

Commit

Permalink
added gis-spa couples gis reduction plateau
Browse files Browse the repository at this point in the history
  • Loading branch information
alex-rand committed Feb 23, 2023
1 parent fe38e71 commit 94d680a
Show file tree
Hide file tree
Showing 8 changed files with 103 additions and 4 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
description: GIS reduction rate for the 'plateau' range for a GIS recipient married to a SPA recipient.
values:
2021-01-01: 0
metadata:
period: year
label: GIS reduction rate for the 'plateau' range for a GIS recipient married to a SPA recipient.
documentataion: Corresponds to GISRRM and GISRLM in the SPSD/M Variable Guide
reference:
- title: SPSD/M Variable Guide

Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
description: Reduction threshold and rate for pensioners married to pensioners. Applies to COUPLE_BOTH_OAS or COUPLE_ONE_OAS_SPA_ELIGIBLE. Note that this calculates on couples combined income, whereas the other GIS cateogires calculate on the lone pensioner's income. Correponds to GISRRM in the SPSD/M.
description: Reduction threshold and rate for pensioners married to pensioners. Applies to COUPLE_BOTH_OAS. Note that this calculates on couples combined income, whereas the other GIS cateogires calculate on the lone pensioner's income. Correponds to GISRRM in the SPSD/M.
brackets:
- threshold:
2021-01-01: 0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
output:
gis_reduction: 100

- name: OAS pensioner whose spouse is SPA eligible
- name: OAS pensioner whose spouse is SPA eligible, with combined income too low to trigger the plateau in the reduction
period: 2023
input:
gis_spa_category: "COUPLE_ONE_OAS_SPA_ELIGIBLE"
Expand All @@ -16,6 +16,17 @@
output:
gis_reduction: 1_000

- name: Couple with combined income that exceeds the upper plateau threshold given by breakeven_spa_eligible. So the GIS reduction starts again after the plateau.
period: 2023
absolute_error_margin: .01
input:
gis_spa_category: "COUPLE_ONE_OAS_SPA_ELIGIBLE"
individual_net_income: 20_048
spouse_net_income: 20_000
gis_cap: 30000
output:
gis_reduction: 7487.68

- name: Two OAS pensioners
period: 2023
input:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
- name: Couple with combined income less than the plateau threshold.
period: 2023
absolute_error_margin: .01
input:
gis_spa_category: "COUPLE_ONE_OAS_SPA_ELIGIBLE"
individual_net_income: 2_048
spouse_net_income: 2_000
output:
gis_reduction_spa_couple: 1_000

- name: Couple with combined income inside the plateau threshold. So the GIS reduction is frozen at the reduction you would have if your income were the crossover amount.
period: 2023
absolute_error_margin: .01
input:
gis_spa_category: "COUPLE_ONE_OAS_SPA_ELIGIBLE"
individual_net_income: 15_048
spouse_net_income: 15_000
output:
gis_reduction_spa_couple: 6_469.86

- name: Couple with combined income that exceeds the upper plateau threshold given by breakeven_spa_eligible. So the GIS reduction starts again after the plateau.
period: 2023
absolute_error_margin: .01
input:
gis_spa_category: "COUPLE_ONE_OAS_SPA_ELIGIBLE"
individual_net_income: 20_048
spouse_net_income: 20_000
output:
gis_reduction_spa_couple: 7487.68

- name: Automatically 0 if you're not the right gis-spa category
period: 2023
absolute_error_margin: .01
input:
gis_spa_category: "COUPLE_ONE_OAS_SPA_INELIGIBLE"
individual_net_income: 20_048
spouse_net_income: 20_000
output:
gis_reduction_spa_couple: 0



Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,20 @@ def formula(person, period, parameters):
household = person.household
spouse_net_income = household("spouse_net_income", period)
gis_base = person("gis_cap", period)
gis_reduction_spa_couple = person("gis_reduction_spa_couple", period)
p = parameters(period).gov.cra.benefits.gis_spa.gis_reduction

reduction = select(
[
gis_spa_category == gis_spa_categories.SINGLE_WITH_OAS,
gis_spa_category == gis_spa_categories.COUPLE_BOTH_OAS,
(gis_spa_category == gis_spa_categories.COUPLE_ONE_OAS_SPA_ELIGIBLE) & (gis_base > 0), # THIS NEEDS TO CHANGE BASED ON THE 'CROSSOVER' THING. # the gis_base > 0 makes sure this person is the eligible one in the couple, since both people in the couple will have the same category.
(gis_spa_category == gis_spa_categories.COUPLE_ONE_OAS_SPA_ELIGIBLE) & (gis_base > 0), # the gis_base > 0 makes sure this person is the eligible one in the couple, since both people in the couple will have the same category.
(gis_spa_category == gis_spa_categories.COUPLE_ONE_OAS_SPA_INELIGIBLE) & (gis_base > 0)
],
[
p.one_pensioner.calc(individual_net_income),
p.two_pensioners.calc(individual_net_income + spouse_net_income),
p.two_pensioners.calc(individual_net_income + spouse_net_income),
gis_reduction_spa_couple,
p.one_pensioner.calc(individual_net_income)
],
default=0,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
from policyengine_canada.model_api import *

class gis_reduction_spa_couple(Variable):
value_type = float
entity = Person
label = "Guaranteed Income Supplement Reduction for a Recipient with SPA-eligible Spouse"
unit = CAD
documentation = "The amount by which the base GIS is reduced, based on personal net income and the number of pensioners in the household. This is implemented as a variable, not a parameter, due to the complexity and dependencies of the reduction rate."
definition_period = YEAR

def formula(person, period, parameters):
gis_spa_category = person("gis_spa_category", period)
gis_spa_categories = gis_spa_category.possible_values
individual_net_income = person("individual_net_income", period)
household = person.household
spouse_net_income = household("spouse_net_income", period)
combined_net_income = individual_net_income + spouse_net_income
state = person.state
crossover = state("gis_spa_crossover", period)
breakeven_spa_eligible = state("breakeven_spa_eligible", period)
breakeven_spa_ineligible = state("breakeven_spa_ineligible", period)
plateau_range = breakeven_spa_eligible - crossover
p = parameters(period).gov.cra.benefits.gis_spa.gis_reduction

# Reduce like other pensioner couples up to the crossover point
first_part = min(p.two_pensioners.calc(combined_net_income), p.two_pensioners.calc(crossover))
# Plateau until the spouse's SPA-gis-portion is exhausted, as captured by the variable plateau_range. The first part must be maxed-out for this to be non-zero.
second_part = min((combined_net_income - first_part) * p.gis_spa_couple_plateau_rate, plateau_range * p.gis_spa_couple_plateau_rate) * (first_part == (p.two_pensioners.calc(crossover)))
# Start reducing again at the married couple breakeven point for income beyond the crossover maximum. Only be non-zero if there's any income in that range.
third_part = p.two_pensioners.calc(combined_net_income - (crossover - 48) - plateau_range) * ((combined_net_income > (crossover - plateau_range)))

# return(third_part)
return(first_part + second_part + third_part) * (gis_spa_category == gis_spa_categories.COUPLE_ONE_OAS_SPA_ELIGIBLE)


0 comments on commit 94d680a

Please sign in to comment.