diff --git a/changelog_entry.yaml b/changelog_entry.yaml index e69de29bb..b3e0fdd06 100644 --- a/changelog_entry.yaml +++ b/changelog_entry.yaml @@ -0,0 +1,4 @@ +- bump: minor + changes: + added: + - Quebec Senior Assistance Tax Credit. diff --git a/policyengine_canada/parameters/gov/provinces/qc/tax/income/credits/sa/age_eligibility.yaml b/policyengine_canada/parameters/gov/provinces/qc/tax/income/credits/sa/age_eligibility.yaml new file mode 100644 index 000000000..801f61a6d --- /dev/null +++ b/policyengine_canada/parameters/gov/provinces/qc/tax/income/credits/sa/age_eligibility.yaml @@ -0,0 +1,9 @@ +description: Quebec limits its Senior Assistance Credit to seniors at or above this age. +values: + 2022-01-01: 70 +metadata: + unit: year + label: Quebec senior assistance seniors age eligibility + reference: + - title: Revenu Quebec - Eligibility Conditinos for the Senior Assistance Tax Credit + href: https://www.revenuquebec.ca/en/citizens/tax-credits/senior-assistance-tax-credit/eligibility-conditions/ diff --git a/policyengine_canada/parameters/gov/provinces/qc/tax/income/credits/sa/amount/married_both_eligible.yaml b/policyengine_canada/parameters/gov/provinces/qc/tax/income/credits/sa/amount/married_both_eligible.yaml new file mode 100644 index 000000000..e0db1e6be --- /dev/null +++ b/policyengine_canada/parameters/gov/provinces/qc/tax/income/credits/sa/amount/married_both_eligible.yaml @@ -0,0 +1,9 @@ +description: Quebec limits its Senior Assistance Credit to eligible seniors and spouses at or below this amount. +values: + 2022-01-01: 4_000 +metadata: + unit: currency-CAD + label: Quebec senior assistance credits base amount for both eligible seniors and spouse + reference: + - title: Revenu Quebec - Amount of the Senior Assistance Tax Credit + href: https://www.revenuquebec.ca/en/citizens/tax-credits/senior-assistance-tax-credit/amount-of-the-credit/ diff --git a/policyengine_canada/parameters/gov/provinces/qc/tax/income/credits/sa/amount/married_one_eligible.yaml b/policyengine_canada/parameters/gov/provinces/qc/tax/income/credits/sa/amount/married_one_eligible.yaml new file mode 100644 index 000000000..78173a016 --- /dev/null +++ b/policyengine_canada/parameters/gov/provinces/qc/tax/income/credits/sa/amount/married_one_eligible.yaml @@ -0,0 +1,9 @@ +description: Quebec limits its Senior Assistance Credit to seniors with spouse but only one of them is eligible at or below this amount. +values: + 2022-01-01: 2_000 +metadata: + unit: currency-CAD + label: Quebec senior assistance credits base amount for seniors with spouse but only one eligible + reference: + - title: Revenu Quebec - Amount of the Senior Assistance Tax Credit + href: https://www.revenuquebec.ca/en/citizens/tax-credits/senior-assistance-tax-credit/amount-of-the-credit/ diff --git a/policyengine_canada/parameters/gov/provinces/qc/tax/income/credits/sa/amount/single.yaml b/policyengine_canada/parameters/gov/provinces/qc/tax/income/credits/sa/amount/single.yaml new file mode 100644 index 000000000..c066f0e36 --- /dev/null +++ b/policyengine_canada/parameters/gov/provinces/qc/tax/income/credits/sa/amount/single.yaml @@ -0,0 +1,9 @@ +description: Quebec limits its Senior Assistance Credit to single eligible seniors at or below this amount. +values: + 2022-01-01: 2_000 +metadata: + unit: currency-CAD + label: Quebec senior assistance credits limit single senior base amount + reference: + - title: Revenu Quebec - Amount of the Senior Assistance Tax Credit + href: https://www.revenuquebec.ca/en/citizens/tax-credits/senior-assistance-tax-credit/amount-of-the-credit/ diff --git a/policyengine_canada/parameters/gov/provinces/qc/tax/income/credits/sa/reduction/married.yaml b/policyengine_canada/parameters/gov/provinces/qc/tax/income/credits/sa/reduction/married.yaml new file mode 100644 index 000000000..ff8ed008d --- /dev/null +++ b/policyengine_canada/parameters/gov/provinces/qc/tax/income/credits/sa/reduction/married.yaml @@ -0,0 +1,19 @@ +description: Quebec reduces its senior assistance tax credit at this rate based on family income for married seniors. +metadata: + type: marginal_rate + threshold_unit: currency-CAD + rate_unit: /1 + label: Quebec senior assistance tax credit reduction for seniors with sposue + reference: + - title: Revenu Quebec - Amount of the Senior Assistance Tax Credit + href: https://www.revenuquebec.ca/en/citizens/tax-credits/senior-assistance-tax-credit/amount-of-the-credit/ +brackets: + - threshold: + 2022-01-01: 0 + rate: + 2022-01-01: 0 # no reduction when income under $39,350 + - threshold: + 2022-01-01: 39_350 + rate: + 2022-01-01: 0.05 # The credit is reduced by 5% of your income over $39,350 + diff --git a/policyengine_canada/parameters/gov/provinces/qc/tax/income/credits/sa/reduction/single.yaml b/policyengine_canada/parameters/gov/provinces/qc/tax/income/credits/sa/reduction/single.yaml new file mode 100644 index 000000000..85531f963 --- /dev/null +++ b/policyengine_canada/parameters/gov/provinces/qc/tax/income/credits/sa/reduction/single.yaml @@ -0,0 +1,19 @@ +description: Quebec reduces its senior assistance tax credit at this rate based on family income for single seniors. +metadata: + type: marginal_rate + threshold_unit: currency-CAD + rate_unit: /1 + label: Quebec senior assistance tax credit reduction for seniors with noneligible spouse or no spouse + reference: + - title: Revenu Quebec - Amount of the Senior Assistance Tax Credit + href: https://www.revenuquebec.ca/en/citizens/tax-credits/senior-assistance-tax-credit/amount-of-the-credit/ +brackets: + - threshold: + 2022-01-01: 0 + rate: + 2022-01-01: 0 # no reduction when income under $39,350 + - threshold: + 2022-01-01: 24_195 + rate: + 2022-01-01: 0.05 # The credit is reduced by 5% of your income over $39,350 + diff --git a/policyengine_canada/tests/gov/provinces/qc/tax/income/credits/sa/qc_sa_married_both_eligible.yaml b/policyengine_canada/tests/gov/provinces/qc/tax/income/credits/sa/qc_sa_married_both_eligible.yaml new file mode 100644 index 000000000..fcfcb7cb6 --- /dev/null +++ b/policyengine_canada/tests/gov/provinces/qc/tax/income/credits/sa/qc_sa_married_both_eligible.yaml @@ -0,0 +1,32 @@ +- name: Head is below age eligibility + period: 2022 + input: + people: + c1: + age: 60 + qc_sa_spouse_eligible: true + c2: + age: 50 + qc_sa_spouse_eligible: false + household: + members: [c1, c2] + province_code: QC + output: + qc_sa_married_both_eligible: 0 + + +- name: Head is at or above the age eligibility + period: 2022 + input: + people: + c1: + age: 70 + qc_sa_spouse_eligible: false + c2: + age: 80 + qc_sa_spouse_eligible: true + household: + members: [c1, c2] + province_code: QC + output: + qc_sa_married_both_eligible: 1 \ No newline at end of file diff --git a/policyengine_canada/tests/gov/provinces/qc/tax/income/credits/sa/qc_sa_married_one_eligible.yaml b/policyengine_canada/tests/gov/provinces/qc/tax/income/credits/sa/qc_sa_married_one_eligible.yaml new file mode 100644 index 000000000..6ce860c0e --- /dev/null +++ b/policyengine_canada/tests/gov/provinces/qc/tax/income/credits/sa/qc_sa_married_one_eligible.yaml @@ -0,0 +1,31 @@ +- name: Head is below the age eligibility + period: 2022 + input: + people: + c1: + age: 60 + qc_sa_spouse_eligible: true + c2: + age: 50 + qc_sa_spouse_eligible: false + household: + members: [c1, c2] + province_code: QC + output: + qc_sa_married_one_eligible: 1 + +- name: Head is at or above age eligibility + period: 2022 + input: + people: + c1: + age: 70 + qc_sa_spouse_eligible: false + c2: + age: 75 + qc_sa_spouse_eligible: true + household: + members: [c1, c2] + province_code: QC + output: + qc_sa_married_one_eligible: 1 \ No newline at end of file diff --git a/policyengine_canada/tests/gov/provinces/qc/tax/income/credits/sa/qc_sa_single_eligible.yaml b/policyengine_canada/tests/gov/provinces/qc/tax/income/credits/sa/qc_sa_single_eligible.yaml new file mode 100644 index 000000000..ac8ce2383 --- /dev/null +++ b/policyengine_canada/tests/gov/provinces/qc/tax/income/credits/sa/qc_sa_single_eligible.yaml @@ -0,0 +1,26 @@ +- name: Below age eligibility and no spouse + period: 2022 + input: + age: 60 + is_spouse: false + province_code: QC + output: + qc_sa_single: false + +- name: At age eligibility and no spouse + period: 2022 + input: + age: 70 + is_spouse: false + province_code: QC + output: + qc_sa_single: true + +- name: Above age eligibility but had spouse + period: 2022 + input: + age: 80 + is_spouse: true + province_code: QC + output: + qc_sa_single: false diff --git a/policyengine_canada/tests/gov/provinces/qc/tax/income/credits/sa/qc_sa_spouse_eligible.yaml b/policyengine_canada/tests/gov/provinces/qc/tax/income/credits/sa/qc_sa_spouse_eligible.yaml new file mode 100644 index 000000000..0744cd642 --- /dev/null +++ b/policyengine_canada/tests/gov/provinces/qc/tax/income/credits/sa/qc_sa_spouse_eligible.yaml @@ -0,0 +1,26 @@ +- name: Under age eligibility and is spouse + period: 2022 + input: + age: 60 + is_spouse: true + province_code: QC + output: + qc_sa_spouse_eligible: false + +- name: Above age eligibility and is spouse + period: 2022 + input: + age: 70 + is_spouse: true + province_code: QC + output: + qc_sa_spouse_eligible: true + +- name: Above age eligibility but is not spouse + period: 2022 + input: + age: 80 + is_spouse: false + province_code: QC + output: + qc_sa_spouse_eligible: false diff --git a/policyengine_canada/tests/gov/provinces/qc/tax/income/credits/sa/qc_sa_tax_credit.yaml b/policyengine_canada/tests/gov/provinces/qc/tax/income/credits/sa/qc_sa_tax_credit.yaml new file mode 100644 index 000000000..d2c2d7c70 --- /dev/null +++ b/policyengine_canada/tests/gov/provinces/qc/tax/income/credits/sa/qc_sa_tax_credit.yaml @@ -0,0 +1,65 @@ +- name: Tax credit for eligible couples whose income within maximum family income + period: 2022 + input: + adjusted_family_net_income: 109_350 + qc_sa_married_both_eligible: 1 + qc_sa_married_one_eligible: 0 + qc_sa_single: 0 + province_code: QC + output: + qc_sa_tax_credit: 500 #max(0,2000*2-0.05*(109350-39350)) + +- name: Tax credit for eligible couples whose income above maximum family income + period: 2022 + input: + adjusted_family_net_income: 120_000 + qc_sa_married_both_eligible: 1 + qc_sa_married_one_eligible: 0 + qc_sa_single: 0 + province_code: QC + output: + qc_sa_tax_credit: 0 #max(0,2000*2-0.05*(120000-39350)) + +- name: Tax credit for eligible individual and non-eligible spouse whose income within maximum family income + period: 2022 + input: + adjusted_family_net_income: 69_350 + qc_sa_married_both_eligible: 0 + qc_sa_married_one_eligible: 1 + qc_sa_single: 0 + province_code: QC + output: + qc_sa_tax_credit: 500 #max(0,2000-0.05*(69350-39350)) + +- name: Tax credit for eligible individual and non-eligible spouse whose income above maximum family income + period: 2022 + input: + adjusted_family_net_income: 80_000 + qc_sa_married_both_eligible: 0 + qc_sa_married_one_eligible: 1 + qc_sa_single: 0 + province_code: QC + output: + qc_sa_tax_credit: 0 #max(0,2000-0.05*(80000-39350)) + +- name: Tax credit for eligible individual with no spouse whose income within maximum family income + period: 2022 + input: + adjusted_family_net_income: 24_195 + qc_sa_married_both_eligible: 0 + qc_sa_married_one_eligible: 0 + qc_sa_single: 1 + province_code: QC + output: + qc_sa_tax_credit: 2_000 #max(0,2000-0.05*(24195-24195)) + +- name: Tax credit for eligible individual with no spouse whose income above maximum family income + period: 2022 + input: + adjusted_family_net_income: 65_000 + qc_sa_married_both_eligible: 0 + qc_sa_married_one_eligible: 0 + qc_sa_single: 1 + province_code: QC + output: + qc_sa_tax_credit: 0 #max(0,2000-0.05*(65000-24195)) diff --git a/policyengine_canada/variables/gov/provinces/qc/tax/income/credits/sa/qc_sa_married_both_eligible.py b/policyengine_canada/variables/gov/provinces/qc/tax/income/credits/sa/qc_sa_married_both_eligible.py new file mode 100644 index 000000000..d8af27c57 --- /dev/null +++ b/policyengine_canada/variables/gov/provinces/qc/tax/income/credits/sa/qc_sa_married_both_eligible.py @@ -0,0 +1,19 @@ +from policyengine_canada.model_api import * + + +class qc_sa_married_both_eligible(Variable): + value_type = int + entity = Household + label = "Quebec senior assistance tax credits eligible senior couple" + definition_period = YEAR + defined_for = ProvinceCode.QC + + def formula(household, period, parameters): + p = parameters(period).gov.provinces.qc.tax.income.credits.sa + person = household.members + + age_eligible = person("age", period) >= p.age_eligibility + spouse_eligible = person("qc_sa_spouse_eligible", period) + + eligible = age_eligible & spouse_eligible + return household.sum(eligible) diff --git a/policyengine_canada/variables/gov/provinces/qc/tax/income/credits/sa/qc_sa_married_one_eligible.py b/policyengine_canada/variables/gov/provinces/qc/tax/income/credits/sa/qc_sa_married_one_eligible.py new file mode 100644 index 000000000..f7b52dbd0 --- /dev/null +++ b/policyengine_canada/variables/gov/provinces/qc/tax/income/credits/sa/qc_sa_married_one_eligible.py @@ -0,0 +1,22 @@ +from policyengine_canada.model_api import * + + +class qc_sa_married_one_eligible(Variable): + value_type = int + entity = Household + label = "Quebec senior assistance tax credits for family with only one eligible senior" + definition_period = YEAR + defined_for = ProvinceCode.QC + + def formula(household, period, parameters): + p = parameters(period).gov.provinces.qc.tax.income.credits.sa + + person = household.members + + age_eligible = person("age", period) >= p.age_eligibility + spouse_eligible = person("qc_sa_spouse_eligible", period) + + # ^ is XOR (Exclusive OR) + # only one senior in the household is eligible (either the spouse or the head of the household, not both) + eligible = age_eligible ^ spouse_eligible + return household.sum(eligible) diff --git a/policyengine_canada/variables/gov/provinces/qc/tax/income/credits/sa/qc_sa_single_eligible.py b/policyengine_canada/variables/gov/provinces/qc/tax/income/credits/sa/qc_sa_single_eligible.py new file mode 100644 index 000000000..3c77c3693 --- /dev/null +++ b/policyengine_canada/variables/gov/provinces/qc/tax/income/credits/sa/qc_sa_single_eligible.py @@ -0,0 +1,18 @@ +from policyengine_canada.model_api import * + + +class qc_sa_single(Variable): + value_type = bool + entity = Household + label = "Quebec senior assistance tax credits eligible senior did not have a spouse" + definition_period = YEAR + defined_for = ProvinceCode.QC + + def formula(household, period, parameters): + person = household.members + + p = parameters(period).gov.provinces.qc.tax.income.credits.sa + + age_eligible = person("age", period) >= p.age_eligibility + + return age_eligible & ~person("is_spouse", period) diff --git a/policyengine_canada/variables/gov/provinces/qc/tax/income/credits/sa/qc_sa_spouse_eligible.py b/policyengine_canada/variables/gov/provinces/qc/tax/income/credits/sa/qc_sa_spouse_eligible.py new file mode 100644 index 000000000..85ab6eb53 --- /dev/null +++ b/policyengine_canada/variables/gov/provinces/qc/tax/income/credits/sa/qc_sa_spouse_eligible.py @@ -0,0 +1,17 @@ +from policyengine_canada.model_api import * + + +class qc_sa_spouse_eligible(Variable): + value_type = bool + entity = Person + label = "Quebec senior assistance tax credits eligible senior's spouse" + definition_period = YEAR + defined_for = ProvinceCode.QC + + def formula(person, period, parameters): + p = parameters(period).gov.provinces.qc.tax.income.credits.sa + + age_eligible = person("age", period) >= p.age_eligibility + spouse = person("is_spouse", period) + + return spouse & age_eligible diff --git a/policyengine_canada/variables/gov/provinces/qc/tax/income/credits/sa/qc_sa_tax_credit.py b/policyengine_canada/variables/gov/provinces/qc/tax/income/credits/sa/qc_sa_tax_credit.py new file mode 100644 index 000000000..413d4aaa5 --- /dev/null +++ b/policyengine_canada/variables/gov/provinces/qc/tax/income/credits/sa/qc_sa_tax_credit.py @@ -0,0 +1,41 @@ +from policyengine_canada.model_api import * + + +class qc_sa_tax_credit(Variable): + value_type = float + entity = Household + label = "Quebec senior assistance tax credit" + definition_period = YEAR + defined_for = ProvinceCode.QC + + def formula(household, period, parameters): + p = parameters(period).gov.provinces.qc.tax.income.credits.sa + + income = household("adjusted_family_net_income", period) + + # Your spouse is an eligible individual and you were both 70 or over + married_both_eligible = household( + "qc_sa_married_both_eligible", period + ) + credit_married_both_eligible = married_both_eligible * max_( + 0, + p.amount.married_both_eligible - p.reduction.married.calc(income), + ) + + # Your spouse is not an eligible individual or only one of you was 70 or over + married_one_eligible = household("qc_sa_married_one_eligible", period) + credit_married_one_eligible = married_one_eligible * max_( + 0, p.amount.married_one_eligible - p.reduction.married.calc(income) + ) + + # You did not have a spouse + single = household("qc_sa_single", period) + credit_single = single * max_( + 0, p.amount.single - p.reduction.single.calc(income) + ) + + return ( + credit_married_both_eligible + + credit_married_one_eligible + + credit_single + )