diff --git a/policyengine_canada/parameters/gov/cra/benefits/employment_insurance/maximum_insurable_earnings.yaml b/policyengine_canada/parameters/gov/cra/benefits/employment_insurance/maximum_insurable_earnings.yaml new file mode 100644 index 000000000..71c4a255c --- /dev/null +++ b/policyengine_canada/parameters/gov/cra/benefits/employment_insurance/maximum_insurable_earnings.yaml @@ -0,0 +1,15 @@ +description: Maximum annual insurable earnings for Employment Insurance +values: + 2020-01-01: 54_200 + 2021-01-01: 56_300 + 2022-01-01: 60_300 + 2023-01-01: 61_500 + 2024-01-01: 63_200 + 2025-01-01: 65_700 +metadata: + unit: currency-CAD + period: year + label: EI maximum insurable earnings + reference: + - title: EI premium rates and maximums + href: https://www.canada.ca/en/revenue-agency/services/tax/businesses/topics/payroll/payroll-deductions-contributions/employment-insurance-ei/ei-premium-rates-maximums.html \ No newline at end of file diff --git a/policyengine_canada/parameters/gov/cra/benefits/employment_insurance/maximum_weekly_benefit.yaml b/policyengine_canada/parameters/gov/cra/benefits/employment_insurance/maximum_weekly_benefit.yaml new file mode 100644 index 000000000..07ac4680a --- /dev/null +++ b/policyengine_canada/parameters/gov/cra/benefits/employment_insurance/maximum_weekly_benefit.yaml @@ -0,0 +1,17 @@ +description: Maximum weekly Employment Insurance benefit amount +values: + 2020-01-01: 573 + 2021-01-01: 595 + 2022-01-01: 638 + 2023-01-01: 650 + 2024-01-01: 668 + 2025-01-01: 695 +metadata: + unit: currency-CAD + period: week + label: EI maximum weekly benefit + reference: + - title: Employment Insurance benefit amounts + href: https://www.canada.ca/en/services/benefits/ei/ei-regular-benefit/benefit-amount.html + - title: EI premium rates and maximums + href: https://www.canada.ca/en/revenue-agency/services/tax/businesses/topics/payroll/payroll-deductions-contributions/employment-insurance-ei/ei-premium-rates-maximums.html \ No newline at end of file diff --git a/policyengine_canada/parameters/gov/cra/benefits/employment_insurance/minimum_hours.yaml b/policyengine_canada/parameters/gov/cra/benefits/employment_insurance/minimum_hours.yaml new file mode 100644 index 000000000..fd05bea90 --- /dev/null +++ b/policyengine_canada/parameters/gov/cra/benefits/employment_insurance/minimum_hours.yaml @@ -0,0 +1,10 @@ +description: Minimum insurable hours required for Employment Insurance eligibility +values: + 2020-01-01: 420 +metadata: + unit: hour + period: year + label: EI minimum insurable hours + reference: + - title: Employment Insurance eligibility + href: https://www.canada.ca/en/services/benefits/ei/ei-regular-benefit/eligibility.html \ No newline at end of file diff --git a/policyengine_canada/parameters/gov/cra/benefits/employment_insurance/rate.yaml b/policyengine_canada/parameters/gov/cra/benefits/employment_insurance/rate.yaml new file mode 100644 index 000000000..5ef8bdac5 --- /dev/null +++ b/policyengine_canada/parameters/gov/cra/benefits/employment_insurance/rate.yaml @@ -0,0 +1,10 @@ +description: Employment Insurance benefit replacement rate +values: + 2020-01-01: 0.55 +metadata: + unit: /1 + period: year + label: EI benefit rate + reference: + - title: Employment Insurance benefit amounts + href: https://www.canada.ca/en/services/benefits/ei/ei-regular-benefit/benefit-amount.html \ No newline at end of file diff --git a/policyengine_canada/tests/benefits/employment_insurance/ei_benefit.yaml b/policyengine_canada/tests/benefits/employment_insurance/ei_benefit.yaml new file mode 100644 index 000000000..08f38d394 --- /dev/null +++ b/policyengine_canada/tests/benefits/employment_insurance/ei_benefit.yaml @@ -0,0 +1,56 @@ +- name: Basic EI benefit calculation + period: 2024 + input: + employment_income: 50_000 + ei_insurable_hours: 600 + output: + # Weekly: min($50,000, $63,200) / 52 * 0.55 = $528.85 + # Capped at maximum $668/week, so $528.85 + # Annual: $528.85 * 26 weeks = $13,750 + ei_benefit: 13_750 + +- name: EI benefit at maximum + period: 2024 + input: + employment_income: 80_000 + ei_insurable_hours: 1_000 + output: + # Weekly: min($80,000, $63,200) / 52 * 0.55 = $668 (at maximum) + # Annual: $668 * 26 weeks = $17,368 + ei_benefit: 17_368 + +- name: Below minimum hours - no benefit + period: 2024 + input: + employment_income: 40_000 + ei_insurable_hours: 400 + output: + ei_benefit: 0 + +- name: No employment income - no benefit + period: 2024 + input: + employment_income: 0 + ei_insurable_hours: 600 + output: + ei_benefit: 0 + +- name: EI benefit for 2025 + period: 2025 + input: + employment_income: 60_000 + ei_insurable_hours: 800 + output: + # Weekly: $60,000 / 52 * 0.55 = $634.62 + # Annual: $634.62 * 26 weeks = $16,500 + ei_benefit: 16_500 + +- name: EI benefit at 2025 maximum + period: 2025 + input: + employment_income: 90_000 + ei_insurable_hours: 1_200 + output: + # Weekly: min($90,000, $65,700) / 52 * 0.55 = $694.90 + # Annual: $694.90 * 26 weeks = $18,067.50 + ei_benefit: 18_067.50 \ No newline at end of file diff --git a/policyengine_canada/variables/gov/benefits.py b/policyengine_canada/variables/gov/benefits.py index 052eae5ed..ee081cca0 100644 --- a/policyengine_canada/variables/gov/benefits.py +++ b/policyengine_canada/variables/gov/benefits.py @@ -12,6 +12,7 @@ class benefits(Variable): "child_disability_benefit", "canada_workers_benefit", "dental_benefit", + "ei_benefit", "oas_net", # Ontario programs. "on_benefits", diff --git a/policyengine_canada/variables/gov/cra/benefits/employment_insurance/ei_benefit.py b/policyengine_canada/variables/gov/cra/benefits/employment_insurance/ei_benefit.py new file mode 100644 index 000000000..b42912f71 --- /dev/null +++ b/policyengine_canada/variables/gov/cra/benefits/employment_insurance/ei_benefit.py @@ -0,0 +1,20 @@ +from policyengine_canada.model_api import * + + +class ei_benefit(Variable): + value_type = float + entity = Person + label = "Employment Insurance benefit" + definition_period = YEAR + unit = CAD + documentation = "Annual Employment Insurance benefit amount" + adds = ["ei_benefit"] + + def formula(person, period, parameters): + # Get the weekly benefit amount + weekly_benefit = person("ei_weekly_benefit", period) + + # For simplicity, assume 26 weeks of benefits (halfway between min 14 and max 45) + weeks_of_benefits = 26 + + return weekly_benefit * weeks_of_benefits \ No newline at end of file diff --git a/policyengine_canada/variables/gov/cra/benefits/employment_insurance/ei_eligible.py b/policyengine_canada/variables/gov/cra/benefits/employment_insurance/ei_eligible.py new file mode 100644 index 000000000..61c1a2ecd --- /dev/null +++ b/policyengine_canada/variables/gov/cra/benefits/employment_insurance/ei_eligible.py @@ -0,0 +1,22 @@ +from policyengine_canada.model_api import * + + +class ei_eligible(Variable): + value_type = bool + entity = Person + label = "Eligible for Employment Insurance" + definition_period = YEAR + documentation = "Whether person is eligible for Employment Insurance benefits" + + def formula(person, period, parameters): + p = parameters(period).gov.cra.benefits.employment_insurance + + # Check minimum hours requirement + insurable_hours = person("ei_insurable_hours", period) + meets_hours = insurable_hours >= p.minimum_hours + + # Must have insurable earnings + insurable_earnings = person("ei_insurable_earnings", period) + has_earnings = insurable_earnings > 0 + + return meets_hours & has_earnings \ No newline at end of file diff --git a/policyengine_canada/variables/gov/cra/benefits/employment_insurance/ei_insurable_earnings.py b/policyengine_canada/variables/gov/cra/benefits/employment_insurance/ei_insurable_earnings.py new file mode 100644 index 000000000..e3ce741a7 --- /dev/null +++ b/policyengine_canada/variables/gov/cra/benefits/employment_insurance/ei_insurable_earnings.py @@ -0,0 +1,17 @@ +from policyengine_canada.model_api import * + + +class ei_insurable_earnings(Variable): + value_type = float + entity = Person + label = "Employment Insurance insurable earnings" + definition_period = YEAR + unit = CAD + documentation = "Total insurable earnings in the qualifying period" + + def formula(person, period, parameters): + employment_income = person("employment_income", period) + p = parameters(period).gov.cra.benefits.employment_insurance + + # Cap at maximum insurable earnings + return min_(employment_income, p.maximum_insurable_earnings) \ No newline at end of file diff --git a/policyengine_canada/variables/gov/cra/benefits/employment_insurance/ei_insurable_hours.py b/policyengine_canada/variables/gov/cra/benefits/employment_insurance/ei_insurable_hours.py new file mode 100644 index 000000000..2b5e557ef --- /dev/null +++ b/policyengine_canada/variables/gov/cra/benefits/employment_insurance/ei_insurable_hours.py @@ -0,0 +1,10 @@ +from policyengine_canada.model_api import * + + +class ei_insurable_hours(Variable): + value_type = float + entity = Person + label = "Employment Insurance insurable hours" + definition_period = YEAR + unit = "hour" + documentation = "Number of insurable hours worked in the qualifying period" \ No newline at end of file diff --git a/policyengine_canada/variables/gov/cra/benefits/employment_insurance/ei_weekly_benefit.py b/policyengine_canada/variables/gov/cra/benefits/employment_insurance/ei_weekly_benefit.py new file mode 100644 index 000000000..4fbb7bab0 --- /dev/null +++ b/policyengine_canada/variables/gov/cra/benefits/employment_insurance/ei_weekly_benefit.py @@ -0,0 +1,29 @@ +from policyengine_canada.model_api import * + + +class ei_weekly_benefit(Variable): + value_type = float + entity = Person + label = "Employment Insurance weekly benefit" + definition_period = YEAR + unit = CAD + documentation = "Weekly Employment Insurance benefit amount (calculated annually)" + + def formula(person, period, parameters): + p = parameters(period).gov.cra.benefits.employment_insurance + + # Check eligibility + eligible = person("ei_eligible", period) + + # Calculate average weekly earnings + # Simplified - using annual earnings divided by 52 + insurable_earnings = person("ei_insurable_earnings", period) + weekly_earnings = insurable_earnings / 52 + + # Apply benefit rate + benefit_amount = weekly_earnings * p.rate + + # Cap at maximum + capped_benefit = min_(benefit_amount, p.maximum_weekly_benefit) + + return where(eligible, capped_benefit, 0) \ No newline at end of file