Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog.d/8529.fixed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
- Included paid Medicare Part A premiums and Medicare Part D IRMAA surcharges in SPM-unit health insurance premiums and medical out-of-pocket expenses.
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
- name: MSP Part A coverage pays the base premium for QMB enrollees.
period: 2025
input:
medicare_enrolled: true
is_qmb_eligible: true
base_part_a_premium: 6_216
output:
msp_part_a_premium_coverage: 6_216
medicare_part_a_premium: 0

- name: MSP Part A coverage is zero for non-QMB enrollees.
period: 2025
input:
medicare_enrolled: true
is_qmb_eligible: false
base_part_a_premium: 6_216
output:
msp_part_a_premium_coverage: 0
medicare_part_a_premium: 6_216
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
age: 70
is_medicare_eligible: true
other_health_insurance_premiums: 500
base_part_a_premium: 0
medicare_part_b_premium: 2_220
tax_units:
tax_unit:
Expand All @@ -29,6 +30,7 @@
age: 70
is_medicare_eligible: true
other_health_insurance_premiums: 500
base_part_a_premium: 0
medicare_part_b_premium: 5_028
tax_units:
tax_unit:
Expand All @@ -43,3 +45,58 @@
output:
spm_unit_health_insurance_premiums: 5_528
spm_unit_medical_out_of_pocket_expenses: 5_528

- name: SPM unit MOOP includes paid Part A and Part D IRMAA premiums.
period: 2025
absolute_error_margin: 0.01
input:
people:
retiree:
age: 70
is_medicare_eligible: true
is_qmb_eligible: false
other_health_insurance_premiums: 500
base_part_a_premium: 6_216
medicare_part_b_premium: 2_220
income_adjusted_part_d_premium_surcharge: 423.6
tax_units:
tax_unit:
members: [retiree]
spm_units:
spm_unit:
members: [retiree]
households:
household:
members: [retiree]
state_code: CA
output:
spm_unit_health_insurance_premiums: 9_359.6
spm_unit_medical_out_of_pocket_expenses: 9_359.6

- name: SPM unit MOOP excludes Part A premiums covered by MSP.
period: 2025
absolute_error_margin: 0.01
input:
people:
retiree:
age: 70
is_medicare_eligible: true
other_health_insurance_premiums: 500
base_part_a_premium: 6_216
msp_part_a_premium_coverage: 6_216
medicare_part_b_premium: 2_220
income_adjusted_part_d_premium_surcharge: 423.6
tax_units:
tax_unit:
members: [retiree]
spm_units:
spm_unit:
members: [retiree]
households:
household:
members: [retiree]
state_code: CA
output:
medicare_part_a_premium: 0
spm_unit_health_insurance_premiums: 3_143.6
spm_unit_medical_out_of_pocket_expenses: 3_143.6
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
from policyengine_us.model_api import *


class medicare_part_a_premium(Variable):
value_type = float
entity = Person
label = "Medicare Part A premium"
unit = USD
definition_period = YEAR
defined_for = "medicare_enrolled"
reference = (
"https://www.medicare.gov/basics/costs/help/medicare-savings-programs",
)
documentation = (
"Annual Medicare Part A premium paid out of pocket by the enrollee, "
"net of Medicare Savings Program coverage."
)

def formula(person, period, parameters):
gross_premium = person("base_part_a_premium", period)
msp_coverage = person("msp_part_a_premium_coverage", period)
return max_(gross_premium - msp_coverage, 0)
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
from policyengine_us.model_api import *


class msp_part_a_premium_coverage(Variable):
value_type = float
entity = Person
unit = USD
label = "Medicare Part A premium amount covered by MSP"
definition_period = YEAR
reference = (
"https://www.medicare.gov/basics/costs/help/medicare-savings-programs",
"https://www.law.cornell.edu/uscode/text/42/1396d#p_3",
)
documentation = (
"Annual Part A premium amount paid on the enrollee's behalf through "
"the Qualified Medicare Beneficiary pathway."
)

def formula(person, period, parameters):
enrolled = person("medicare_enrolled", period)
monthly_part_a_premium = person("base_part_a_premium", period) / MONTHS_IN_YEAR
monthly_coverage = 0
for month in period.get_subperiods(MONTH):
qmb_eligible = person("is_qmb_eligible", month)
monthly_coverage += where(
enrolled & qmb_eligible,
monthly_part_a_premium,
0,
)
return monthly_coverage
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,7 @@ class spm_unit_health_insurance_premiums(Variable):
"chip_premium",
"medicaid_premium",
"marketplace_net_premium",
"medicare_part_a_premium",
"medicare_part_b_premium",
"income_adjusted_part_d_premium_surcharge",
]
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ class spm_unit_medical_out_of_pocket_expenses(Variable):
"Total medical out-of-pocket expenses at the SPM unit level, "
"combining health insurance premiums with non-premium medical "
"expenses. Health insurance premiums include other health insurance "
"premiums plus modeled Marketplace, CHIP, Medicaid, and Medicare Part "
"B premiums net of Medicare Savings Program coverage. Non-premium "
"expenses include other medical expenses and over-the-counter health "
"expenses."
"premiums plus modeled Marketplace, CHIP, Medicaid, Medicare Part A "
"and Part B net of Medicare Savings Program coverage, and Medicare "
"Part D IRMAA premiums. Non-premium expenses include other medical "
"expenses and over-the-counter health expenses."
)

adds = [
Expand Down
Loading