diff --git a/changelog.d/aotc-student-eligibility.added.md b/changelog.d/aotc-student-eligibility.added.md new file mode 100644 index 00000000000..0afd4934bb8 --- /dev/null +++ b/changelog.d/aotc-student-eligibility.added.md @@ -0,0 +1 @@ +Add statutory American Opportunity Credit student eligibility inputs and compute eligibility from those inputs. diff --git a/policyengine_us/parameters/gov/irs/credits/education/american_opportunity_credit/amount.yaml b/policyengine_us/parameters/gov/irs/credits/education/american_opportunity_credit/amount.yaml index 172302d204d..e9d2ed04489 100644 --- a/policyengine_us/parameters/gov/irs/credits/education/american_opportunity_credit/amount.yaml +++ b/policyengine_us/parameters/gov/irs/credits/education/american_opportunity_credit/amount.yaml @@ -19,4 +19,4 @@ metadata: threshold_unit: currency-USD reference: - title: 26 U.S. Code § 25A(b)(1) - url: https://www.law.cornell.edu/uscode/text/26/25A#b_1 + url: https://uscode.house.gov/view.xhtml?edition=prelim&num=0&req=granuleid%3AUSC-prelim-title26-section25A diff --git a/policyengine_us/parameters/gov/irs/credits/education/american_opportunity_credit/eligibility/requires_1098_t_or_exception.yaml b/policyengine_us/parameters/gov/irs/credits/education/american_opportunity_credit/eligibility/requires_1098_t_or_exception.yaml new file mode 100644 index 00000000000..4b6aee67dc8 --- /dev/null +++ b/policyengine_us/parameters/gov/irs/credits/education/american_opportunity_credit/eligibility/requires_1098_t_or_exception.yaml @@ -0,0 +1,13 @@ +description: The IRS requires a Form 1098-T payee statement, or an exception allowed by the Secretary, to claim education credits if this is true. +values: + 0000-01-01: false + 2016-01-01: true +metadata: + unit: bool + period: year + label: American Opportunity Credit Form 1098-T requirement applies + reference: + - title: 26 U.S. Code § 25A(g)(8) + href: https://www.law.cornell.edu/uscode/text/26/25A#g_8 + - title: 26 U.S. Code § 25A effective date notes + href: https://www.law.cornell.edu/uscode/text/26/25A#notes diff --git a/policyengine_us/parameters/gov/irs/credits/education/american_opportunity_credit/eligibility/requires_institution_ein.yaml b/policyengine_us/parameters/gov/irs/credits/education/american_opportunity_credit/eligibility/requires_institution_ein.yaml new file mode 100644 index 00000000000..680c19a0ad3 --- /dev/null +++ b/policyengine_us/parameters/gov/irs/credits/education/american_opportunity_credit/eligibility/requires_institution_ein.yaml @@ -0,0 +1,13 @@ +description: The IRS requires the employer identification number of the educational institution to claim the American Opportunity Credit if this is true. +values: + 0000-01-01: false + 2016-01-01: true +metadata: + unit: bool + period: year + label: American Opportunity Credit institution EIN requirement applies + reference: + - title: 26 U.S. Code § 25A(g)(1)(B) + href: https://www.law.cornell.edu/uscode/text/26/25A#g_1_B + - title: 26 U.S. Code § 25A effective date notes + href: https://www.law.cornell.edu/uscode/text/26/25A#notes diff --git a/policyengine_us/parameters/gov/irs/credits/education/american_opportunity_credit/eligibility/requires_qualifying_ssn.yaml b/policyengine_us/parameters/gov/irs/credits/education/american_opportunity_credit/eligibility/requires_qualifying_ssn.yaml new file mode 100644 index 00000000000..2131f43856e --- /dev/null +++ b/policyengine_us/parameters/gov/irs/credits/education/american_opportunity_credit/eligibility/requires_qualifying_ssn.yaml @@ -0,0 +1,13 @@ +description: The IRS requires a qualifying Social Security number, rather than any taxpayer identification number, for American Opportunity Credit identification if this is true. +values: + 0000-01-01: false + 2026-01-01: true +metadata: + unit: bool + period: year + label: American Opportunity Credit qualifying SSN requirement applies + reference: + - title: 26 U.S. Code § 25A(g)(1) + href: https://www.law.cornell.edu/uscode/text/26/25A#g_1 + - title: 26 U.S. Code § 24(h)(7) + href: https://www.law.cornell.edu/uscode/text/26/24#h_7 diff --git a/policyengine_us/parameters/gov/irs/credits/education/american_opportunity_credit/refundability.yaml b/policyengine_us/parameters/gov/irs/credits/education/american_opportunity_credit/refundability.yaml index a420abc8a87..1fd61c0d66a 100644 --- a/policyengine_us/parameters/gov/irs/credits/education/american_opportunity_credit/refundability.yaml +++ b/policyengine_us/parameters/gov/irs/credits/education/american_opportunity_credit/refundability.yaml @@ -6,4 +6,4 @@ metadata: label: American Opportunity Credit refundable percentage reference: - title: 26 U.S. Code § 25A - url: https://www.law.cornell.edu/uscode/text/26/25A#i + url: https://uscode.house.gov/view.xhtml?edition=prelim&num=0&req=granuleid%3AUSC-prelim-title26-section25A diff --git a/policyengine_us/parameters/gov/irs/credits/education/lifetime_learning_credit/eligibility/requires_1098_t_or_exception.yaml b/policyengine_us/parameters/gov/irs/credits/education/lifetime_learning_credit/eligibility/requires_1098_t_or_exception.yaml new file mode 100644 index 00000000000..e4c4bfa0d4b --- /dev/null +++ b/policyengine_us/parameters/gov/irs/credits/education/lifetime_learning_credit/eligibility/requires_1098_t_or_exception.yaml @@ -0,0 +1,13 @@ +description: The IRS requires a Form 1098-T payee statement, or an exception allowed by the Secretary, to claim the Lifetime Learning Credit if this is true. +values: + 0000-01-01: false + 2016-01-01: true +metadata: + unit: bool + period: year + label: Lifetime Learning Credit Form 1098-T requirement applies + reference: + - title: 26 U.S. Code § 25A(g)(8) + href: https://www.law.cornell.edu/uscode/text/26/25A#g_8 + - title: 26 U.S. Code § 25A effective date notes + href: https://www.law.cornell.edu/uscode/text/26/25A#notes diff --git a/policyengine_us/parameters/gov/irs/credits/education/lifetime_learning_credit/eligibility/requires_qualifying_ssn.yaml b/policyengine_us/parameters/gov/irs/credits/education/lifetime_learning_credit/eligibility/requires_qualifying_ssn.yaml new file mode 100644 index 00000000000..2086fe05f76 --- /dev/null +++ b/policyengine_us/parameters/gov/irs/credits/education/lifetime_learning_credit/eligibility/requires_qualifying_ssn.yaml @@ -0,0 +1,13 @@ +description: The IRS requires a qualifying Social Security number, rather than any taxpayer identification number, for Lifetime Learning Credit identification if this is true. +values: + 0000-01-01: false + 2026-01-01: true +metadata: + unit: bool + period: year + label: Lifetime Learning Credit qualifying SSN requirement applies + reference: + - title: 26 U.S. Code § 25A(g)(1) + href: https://www.law.cornell.edu/uscode/text/26/25A#g_1 + - title: 26 U.S. Code § 24(h)(7) + href: https://www.law.cornell.edu/uscode/text/26/24#h_7 diff --git a/policyengine_us/tests/policy/baseline/gov/irs/credits/education/american_opportunity_credit/american_opportunity_credit.yaml b/policyengine_us/tests/policy/baseline/gov/irs/credits/education/american_opportunity_credit/american_opportunity_credit.yaml index 6bbcbffbe16..4fe9ea75de3 100644 --- a/policyengine_us/tests/policy/baseline/gov/irs/credits/education/american_opportunity_credit/american_opportunity_credit.yaml +++ b/policyengine_us/tests/policy/baseline/gov/irs/credits/education/american_opportunity_credit/american_opportunity_credit.yaml @@ -14,6 +14,19 @@ output: american_opportunity_credit: 1_000 +- name: Eligibility formula, under first threshold of expenses + period: 2024 + input: + is_pursuing_credential_for_american_opportunity_credit: true + attends_eligible_educational_institution_for_american_opportunity_credit: true + is_enrolled_at_least_half_time_for_american_opportunity_credit: true + has_american_opportunity_credit_1098_t_or_exception: true + has_american_opportunity_credit_institution_ein: true + qualified_tuition_expenses: 1_000 + output: + is_eligible_for_american_opportunity_credit: true + american_opportunity_credit: 1_000 + - name: Over phase_out, no entitlement period: 2020 input: diff --git a/policyengine_us/tests/policy/baseline/gov/irs/credits/education/american_opportunity_credit/is_eligible_for_american_opportunity_credit.yaml b/policyengine_us/tests/policy/baseline/gov/irs/credits/education/american_opportunity_credit/is_eligible_for_american_opportunity_credit.yaml new file mode 100644 index 00000000000..0d102e18b78 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/irs/credits/education/american_opportunity_credit/is_eligible_for_american_opportunity_credit.yaml @@ -0,0 +1,179 @@ +- name: Meets American Opportunity Credit student eligibility requirements + period: 2024 + input: + is_pursuing_credential_for_american_opportunity_credit: true + attends_eligible_educational_institution_for_american_opportunity_credit: true + is_enrolled_at_least_half_time_for_american_opportunity_credit: true + has_american_opportunity_credit_1098_t_or_exception: true + has_american_opportunity_credit_institution_ein: true + has_tin: true + output: + is_eligible_for_american_opportunity_credit: true + +- name: Student must pursue a recognized credential + period: 2024 + input: + attends_eligible_educational_institution_for_american_opportunity_credit: true + is_enrolled_at_least_half_time_for_american_opportunity_credit: true + has_american_opportunity_credit_1098_t_or_exception: true + has_american_opportunity_credit_institution_ein: true + has_tin: true + output: + is_eligible_for_american_opportunity_credit: false + +- name: Student must attend an eligible educational institution + period: 2024 + input: + is_pursuing_credential_for_american_opportunity_credit: true + is_enrolled_at_least_half_time_for_american_opportunity_credit: true + has_american_opportunity_credit_1098_t_or_exception: true + has_american_opportunity_credit_institution_ein: true + has_tin: true + output: + is_eligible_for_american_opportunity_credit: false + +- name: Student must be enrolled at least half-time + period: 2024 + input: + is_pursuing_credential_for_american_opportunity_credit: true + attends_eligible_educational_institution_for_american_opportunity_credit: true + has_american_opportunity_credit_1098_t_or_exception: true + has_american_opportunity_credit_institution_ein: true + has_tin: true + output: + is_eligible_for_american_opportunity_credit: false + +- name: Student cannot have completed the first four postsecondary years + period: 2024 + input: + is_pursuing_credential_for_american_opportunity_credit: true + attends_eligible_educational_institution_for_american_opportunity_credit: true + is_enrolled_at_least_half_time_for_american_opportunity_credit: true + has_completed_first_four_years_of_postsecondary_education: true + has_american_opportunity_credit_1098_t_or_exception: true + has_american_opportunity_credit_institution_ein: true + has_tin: true + output: + is_eligible_for_american_opportunity_credit: false + +- name: Student cannot have four prior AOTC or Hope Credit claim years + period: 2024 + input: + is_pursuing_credential_for_american_opportunity_credit: true + attends_eligible_educational_institution_for_american_opportunity_credit: true + is_enrolled_at_least_half_time_for_american_opportunity_credit: true + american_opportunity_credit_claimed_prior_years: 4 + has_american_opportunity_credit_1098_t_or_exception: true + has_american_opportunity_credit_institution_ein: true + has_tin: true + output: + is_eligible_for_american_opportunity_credit: false + +- name: Student cannot have a felony drug conviction + period: 2024 + input: + is_pursuing_credential_for_american_opportunity_credit: true + attends_eligible_educational_institution_for_american_opportunity_credit: true + is_enrolled_at_least_half_time_for_american_opportunity_credit: true + has_felony_drug_conviction: true + has_american_opportunity_credit_1098_t_or_exception: true + has_american_opportunity_credit_institution_ein: true + has_tin: true + output: + is_eligible_for_american_opportunity_credit: false + +- name: Student must have Form 1098-T or an exception + period: 2024 + input: + is_pursuing_credential_for_american_opportunity_credit: true + attends_eligible_educational_institution_for_american_opportunity_credit: true + is_enrolled_at_least_half_time_for_american_opportunity_credit: true + has_american_opportunity_credit_institution_ein: true + has_tin: true + output: + is_eligible_for_american_opportunity_credit: false + +- name: Student must have a TIN before 2026 + period: 2024 + input: + is_pursuing_credential_for_american_opportunity_credit: true + attends_eligible_educational_institution_for_american_opportunity_credit: true + is_enrolled_at_least_half_time_for_american_opportunity_credit: true + has_american_opportunity_credit_1098_t_or_exception: true + has_american_opportunity_credit_institution_ein: true + has_tin: false + output: + is_eligible_for_american_opportunity_credit: false + +- name: Student must have a qualifying SSN starting in 2026 + period: 2026 + input: + is_pursuing_credential_for_american_opportunity_credit: true + attends_eligible_educational_institution_for_american_opportunity_credit: true + is_enrolled_at_least_half_time_for_american_opportunity_credit: true + has_american_opportunity_credit_1098_t_or_exception: true + has_american_opportunity_credit_institution_ein: true + has_tin: true + ssn_card_type: NONE + output: + is_eligible_for_american_opportunity_credit: false + +- name: Filer must provide the institution EIN + period: 2024 + input: + is_pursuing_credential_for_american_opportunity_credit: true + attends_eligible_educational_institution_for_american_opportunity_credit: true + is_enrolled_at_least_half_time_for_american_opportunity_credit: true + has_american_opportunity_credit_1098_t_or_exception: true + has_tin: true + output: + is_eligible_for_american_opportunity_credit: false + +- name: Form 1098-T and institution EIN requirements do not apply before 2016 + period: 2015 + input: + is_pursuing_credential_for_american_opportunity_credit: true + attends_eligible_educational_institution_for_american_opportunity_credit: true + is_enrolled_at_least_half_time_for_american_opportunity_credit: true + has_tin: true + output: + is_eligible_for_american_opportunity_credit: true + +- name: Nonresident alien taxpayers cannot claim the AOTC + period: 2024 + input: + is_pursuing_credential_for_american_opportunity_credit: true + attends_eligible_educational_institution_for_american_opportunity_credit: true + is_enrolled_at_least_half_time_for_american_opportunity_credit: true + has_american_opportunity_credit_1098_t_or_exception: true + has_american_opportunity_credit_institution_ein: true + has_tin: true + is_nonresident_alien_for_american_opportunity_credit: true + output: + is_eligible_for_american_opportunity_credit: false + +- name: Taxpayers barred due to improper claims cannot claim the AOTC + period: 2024 + input: + is_pursuing_credential_for_american_opportunity_credit: true + attends_eligible_educational_institution_for_american_opportunity_credit: true + is_enrolled_at_least_half_time_for_american_opportunity_credit: true + has_american_opportunity_credit_1098_t_or_exception: true + has_american_opportunity_credit_institution_ein: true + has_tin: true + is_barred_from_american_opportunity_credit_due_to_improper_claims: true + output: + is_eligible_for_american_opportunity_credit: false + +- name: Married filing separately cannot claim the AOTC + period: 2024 + input: + filing_status: SEPARATE + is_pursuing_credential_for_american_opportunity_credit: true + attends_eligible_educational_institution_for_american_opportunity_credit: true + is_enrolled_at_least_half_time_for_american_opportunity_credit: true + has_american_opportunity_credit_1098_t_or_exception: true + has_american_opportunity_credit_institution_ein: true + has_tin: true + output: + is_eligible_for_american_opportunity_credit: false diff --git a/policyengine_us/tests/policy/baseline/gov/irs/credits/education/lifetime_learning_credit/is_eligible_for_lifetime_learning_credit.yaml b/policyengine_us/tests/policy/baseline/gov/irs/credits/education/lifetime_learning_credit/is_eligible_for_lifetime_learning_credit.yaml new file mode 100644 index 00000000000..72ca159a702 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/irs/credits/education/lifetime_learning_credit/is_eligible_for_lifetime_learning_credit.yaml @@ -0,0 +1,72 @@ +- name: Student at eligible institution with TIN can qualify for LLC + period: 2024 + input: + attends_eligible_educational_institution_for_lifetime_learning_credit: true + has_lifetime_learning_credit_1098_t_or_exception: true + has_tin: true + output: + is_eligible_for_lifetime_learning_credit: true + +- name: Student must attend an eligible educational institution for LLC + period: 2024 + input: + has_lifetime_learning_credit_1098_t_or_exception: true + has_tin: true + output: + is_eligible_for_lifetime_learning_credit: false + +- name: LLC requires Form 1098-T or an exception starting in 2016 + period: 2024 + input: + attends_eligible_educational_institution_for_lifetime_learning_credit: true + has_tin: true + output: + is_eligible_for_lifetime_learning_credit: false + +- name: LLC Form 1098-T requirement does not apply before 2016 + period: 2015 + input: + attends_eligible_educational_institution_for_lifetime_learning_credit: true + has_tin: true + output: + is_eligible_for_lifetime_learning_credit: true + +- name: LLC accepts TIN before 2026 + period: 2025 + input: + attends_eligible_educational_institution_for_lifetime_learning_credit: true + has_lifetime_learning_credit_1098_t_or_exception: true + has_tin: true + ssn_card_type: NONE + output: + is_eligible_for_lifetime_learning_credit: true + +- name: LLC requires qualifying SSN starting in 2026 + period: 2026 + input: + attends_eligible_educational_institution_for_lifetime_learning_credit: true + has_lifetime_learning_credit_1098_t_or_exception: true + has_tin: true + ssn_card_type: NONE + output: + is_eligible_for_lifetime_learning_credit: false + +- name: Nonresident alien taxpayers cannot claim LLC + period: 2024 + input: + attends_eligible_educational_institution_for_lifetime_learning_credit: true + has_lifetime_learning_credit_1098_t_or_exception: true + has_tin: true + is_nonresident_alien_for_lifetime_learning_credit: true + output: + is_eligible_for_lifetime_learning_credit: false + +- name: Married filing separately cannot claim LLC + period: 2024 + input: + filing_status: SEPARATE + attends_eligible_educational_institution_for_lifetime_learning_credit: true + has_lifetime_learning_credit_1098_t_or_exception: true + has_tin: true + output: + is_eligible_for_lifetime_learning_credit: false diff --git a/policyengine_us/tests/policy/baseline/gov/irs/credits/education/lifetime_learning_credit/lifetime_learning_credit_potential.yaml b/policyengine_us/tests/policy/baseline/gov/irs/credits/education/lifetime_learning_credit/lifetime_learning_credit_potential.yaml index d090adcf43d..14db0488d5e 100644 --- a/policyengine_us/tests/policy/baseline/gov/irs/credits/education/lifetime_learning_credit/lifetime_learning_credit_potential.yaml +++ b/policyengine_us/tests/policy/baseline/gov/irs/credits/education/lifetime_learning_credit/lifetime_learning_credit_potential.yaml @@ -9,6 +9,9 @@ period: 2020 input: qualified_tuition_expenses: 1_000 + attends_eligible_educational_institution_for_lifetime_learning_credit: true + has_lifetime_learning_credit_1098_t_or_exception: true + has_tin: true output: lifetime_learning_credit_potential: 200 @@ -16,6 +19,9 @@ period: 2020 input: qualified_tuition_expenses: 1_000 + attends_eligible_educational_institution_for_lifetime_learning_credit: true + has_lifetime_learning_credit_1098_t_or_exception: true + has_tin: true is_eligible_for_american_opportunity_credit: true output: lifetime_learning_credit_potential: 0 @@ -24,6 +30,9 @@ period: 2020 input: qualified_tuition_expenses: 1_000 + attends_eligible_educational_institution_for_lifetime_learning_credit: true + has_lifetime_learning_credit_1098_t_or_exception: true + has_tin: true adjusted_gross_income: 90_000 output: lifetime_learning_credit_potential: 0 diff --git a/policyengine_us/tests/policy/baseline/gov/irs/credits/education/lifetime_learning_credit/lifetime_learning_credit_pre_2021_phase_out.yaml b/policyengine_us/tests/policy/baseline/gov/irs/credits/education/lifetime_learning_credit/lifetime_learning_credit_pre_2021_phase_out.yaml index 6d6dc393f58..f166dba9ced 100644 --- a/policyengine_us/tests/policy/baseline/gov/irs/credits/education/lifetime_learning_credit/lifetime_learning_credit_pre_2021_phase_out.yaml +++ b/policyengine_us/tests/policy/baseline/gov/irs/credits/education/lifetime_learning_credit/lifetime_learning_credit_pre_2021_phase_out.yaml @@ -15,6 +15,9 @@ qualified_tuition_expenses: 4_000 filing_status: JOINT tax_unit_is_joint: true + attends_eligible_educational_institution_for_lifetime_learning_credit: true + has_lifetime_learning_credit_1098_t_or_exception: true + has_tin: true is_eligible_for_american_opportunity_credit: false output: # Joint LLC phase-out in 2020: starts $118k, ends $138k. @@ -31,6 +34,9 @@ qualified_tuition_expenses: 5_000 filing_status: SINGLE tax_unit_is_joint: false + attends_eligible_educational_institution_for_lifetime_learning_credit: true + has_lifetime_learning_credit_1098_t_or_exception: true + has_tin: true is_eligible_for_american_opportunity_credit: false output: # Single LLC phase-out in 2020: starts $59k, ends $69k. @@ -46,6 +52,9 @@ qualified_tuition_expenses: 4_000 filing_status: JOINT tax_unit_is_joint: true + attends_eligible_educational_institution_for_lifetime_learning_credit: true + has_lifetime_learning_credit_1098_t_or_exception: true + has_tin: true is_eligible_for_american_opportunity_credit: false output: # Starting 2021, LLC and AOC share phase-out ($160k/$180k joint). diff --git a/policyengine_us/variables/gov/irs/credits/education/american_opportunity_credit/american_opportunity_credit.py b/policyengine_us/variables/gov/irs/credits/education/american_opportunity_credit/american_opportunity_credit.py index a9fa4fddaee..5c2e49f6f15 100644 --- a/policyengine_us/variables/gov/irs/credits/education/american_opportunity_credit/american_opportunity_credit.py +++ b/policyengine_us/variables/gov/irs/credits/education/american_opportunity_credit/american_opportunity_credit.py @@ -8,7 +8,7 @@ class american_opportunity_credit(Variable): unit = USD documentation = "Total value of the American Opportunity Credit" definition_period = YEAR - reference = "https://www.law.cornell.edu/uscode/text/26/25A#b" + reference = "https://uscode.house.gov/view.xhtml?edition=prelim&num=0&req=granuleid%3AUSC-prelim-title26-section25A" def formula(tax_unit, period, parameters): education = parameters(period).gov.irs.credits.education diff --git a/policyengine_us/variables/gov/irs/credits/education/american_opportunity_credit/american_opportunity_credit_claimed_prior_years.py b/policyengine_us/variables/gov/irs/credits/education/american_opportunity_credit/american_opportunity_credit_claimed_prior_years.py new file mode 100644 index 00000000000..8c90a0150cc --- /dev/null +++ b/policyengine_us/variables/gov/irs/credits/education/american_opportunity_credit/american_opportunity_credit_claimed_prior_years.py @@ -0,0 +1,10 @@ +from policyengine_us.model_api import * + + +class american_opportunity_credit_claimed_prior_years(Variable): + value_type = int + entity = Person + label = "Prior years claiming the American Opportunity or Hope Credit" + documentation = "Number of prior tax years for which the American Opportunity Credit or former Hope Credit was claimed for the student." + definition_period = YEAR + reference = "https://uscode.house.gov/view.xhtml?edition=prelim&num=0&req=granuleid%3AUSC-prelim-title26-section25A" diff --git a/policyengine_us/variables/gov/irs/credits/education/american_opportunity_credit/attends_eligible_educational_institution_for_american_opportunity_credit.py b/policyengine_us/variables/gov/irs/credits/education/american_opportunity_credit/attends_eligible_educational_institution_for_american_opportunity_credit.py new file mode 100644 index 00000000000..78d26330a92 --- /dev/null +++ b/policyengine_us/variables/gov/irs/credits/education/american_opportunity_credit/attends_eligible_educational_institution_for_american_opportunity_credit.py @@ -0,0 +1,12 @@ +from policyengine_us.model_api import * + + +class attends_eligible_educational_institution_for_american_opportunity_credit( + Variable +): + value_type = bool + entity = Person + label = "Attends an AOTC eligible educational institution" + documentation = "Whether the student attends a post-secondary educational institution eligible to participate in a US Department of Education student aid program for American Opportunity Credit purposes." + definition_period = YEAR + reference = "https://uscode.house.gov/view.xhtml?edition=prelim&num=0&req=granuleid%3AUSC-prelim-title26-section25A" diff --git a/policyengine_us/variables/gov/irs/credits/education/american_opportunity_credit/filer_meets_american_opportunity_credit_identification_requirements.py b/policyengine_us/variables/gov/irs/credits/education/american_opportunity_credit/filer_meets_american_opportunity_credit_identification_requirements.py new file mode 100644 index 00000000000..848040b77e3 --- /dev/null +++ b/policyengine_us/variables/gov/irs/credits/education/american_opportunity_credit/filer_meets_american_opportunity_credit_identification_requirements.py @@ -0,0 +1,18 @@ +from policyengine_us.model_api import * + + +class filer_meets_american_opportunity_credit_identification_requirements(Variable): + value_type = bool + entity = TaxUnit + label = "Filer meets American Opportunity Credit identification requirements" + definition_period = YEAR + reference = "https://uscode.house.gov/view.xhtml?edition=prelim&num=0&req=granuleid%3AUSC-prelim-title26-section25A" + + def formula(tax_unit, period, parameters): + person = tax_unit.members + head_or_spouse = person("is_tax_unit_head_or_spouse", period) + meets_identification_requirements = person( + "meets_american_opportunity_credit_identification_requirements", + period, + ) + return tax_unit.all(~head_or_spouse | meets_identification_requirements) diff --git a/policyengine_us/variables/gov/irs/credits/education/american_opportunity_credit/has_american_opportunity_credit_1098_t_or_exception.py b/policyengine_us/variables/gov/irs/credits/education/american_opportunity_credit/has_american_opportunity_credit_1098_t_or_exception.py new file mode 100644 index 00000000000..b8337b30a25 --- /dev/null +++ b/policyengine_us/variables/gov/irs/credits/education/american_opportunity_credit/has_american_opportunity_credit_1098_t_or_exception.py @@ -0,0 +1,10 @@ +from policyengine_us.model_api import * + + +class has_american_opportunity_credit_1098_t_or_exception(Variable): + value_type = bool + entity = Person + label = "Has Form 1098-T or an AOTC exception" + documentation = "Whether the student received Form 1098-T or meets an exception allowing the American Opportunity Credit to be claimed with substantiated qualified expenses." + definition_period = YEAR + reference = "https://uscode.house.gov/view.xhtml?edition=prelim&num=0&req=granuleid%3AUSC-prelim-title26-section25A" diff --git a/policyengine_us/variables/gov/irs/credits/education/american_opportunity_credit/has_american_opportunity_credit_institution_ein.py b/policyengine_us/variables/gov/irs/credits/education/american_opportunity_credit/has_american_opportunity_credit_institution_ein.py new file mode 100644 index 00000000000..58bd2bc110e --- /dev/null +++ b/policyengine_us/variables/gov/irs/credits/education/american_opportunity_credit/has_american_opportunity_credit_institution_ein.py @@ -0,0 +1,10 @@ +from policyengine_us.model_api import * + + +class has_american_opportunity_credit_institution_ein(Variable): + value_type = bool + entity = Person + label = "Has institution EIN for American Opportunity Credit" + documentation = "Whether the filer includes the employer identification number of the eligible educational institution for this student's American Opportunity Credit expenses." + definition_period = YEAR + reference = "https://uscode.house.gov/view.xhtml?edition=prelim&num=0&req=granuleid%3AUSC-prelim-title26-section25A" diff --git a/policyengine_us/variables/gov/irs/credits/education/american_opportunity_credit/has_completed_first_four_years_of_postsecondary_education.py b/policyengine_us/variables/gov/irs/credits/education/american_opportunity_credit/has_completed_first_four_years_of_postsecondary_education.py new file mode 100644 index 00000000000..f66c8b92027 --- /dev/null +++ b/policyengine_us/variables/gov/irs/credits/education/american_opportunity_credit/has_completed_first_four_years_of_postsecondary_education.py @@ -0,0 +1,10 @@ +from policyengine_us.model_api import * + + +class has_completed_first_four_years_of_postsecondary_education(Variable): + value_type = bool + entity = Person + label = "Completed the first four years of postsecondary education" + documentation = "Whether the student completed the first four years of postsecondary education before the beginning of the tax year." + definition_period = YEAR + reference = "https://uscode.house.gov/view.xhtml?edition=prelim&num=0&req=granuleid%3AUSC-prelim-title26-section25A" diff --git a/policyengine_us/variables/gov/irs/credits/education/american_opportunity_credit/has_felony_drug_conviction.py b/policyengine_us/variables/gov/irs/credits/education/american_opportunity_credit/has_felony_drug_conviction.py new file mode 100644 index 00000000000..a4431b6f162 --- /dev/null +++ b/policyengine_us/variables/gov/irs/credits/education/american_opportunity_credit/has_felony_drug_conviction.py @@ -0,0 +1,10 @@ +from policyengine_us.model_api import * + + +class has_felony_drug_conviction(Variable): + value_type = bool + entity = Person + label = "Has a felony drug conviction" + documentation = "Whether the person has been convicted of a Federal or State felony offense consisting of the possession or distribution of a controlled substance before the end of the tax year." + definition_period = YEAR + reference = "https://uscode.house.gov/view.xhtml?edition=prelim&num=0&req=granuleid%3AUSC-prelim-title26-section25A" diff --git a/policyengine_us/variables/gov/irs/credits/education/american_opportunity_credit/is_barred_from_american_opportunity_credit_due_to_improper_claims.py b/policyengine_us/variables/gov/irs/credits/education/american_opportunity_credit/is_barred_from_american_opportunity_credit_due_to_improper_claims.py new file mode 100644 index 00000000000..0ff3b4fb9bc --- /dev/null +++ b/policyengine_us/variables/gov/irs/credits/education/american_opportunity_credit/is_barred_from_american_opportunity_credit_due_to_improper_claims.py @@ -0,0 +1,10 @@ +from policyengine_us.model_api import * + + +class is_barred_from_american_opportunity_credit_due_to_improper_claims(Variable): + value_type = bool + entity = TaxUnit + label = "Barred from American Opportunity Credit due to improper claims" + documentation = "Whether the taxpayer is barred from the American Opportunity Credit due to prior fraudulent, reckless, intentional-disregard, or deficiency-denied claims." + definition_period = YEAR + reference = "https://uscode.house.gov/view.xhtml?edition=prelim&num=0&req=granuleid%3AUSC-prelim-title26-section25A" diff --git a/policyengine_us/variables/gov/irs/credits/education/american_opportunity_credit/is_eligible_for_american_opportunity_credit.py b/policyengine_us/variables/gov/irs/credits/education/american_opportunity_credit/is_eligible_for_american_opportunity_credit.py index e2301f74b2e..6509aa1f045 100644 --- a/policyengine_us/variables/gov/irs/credits/education/american_opportunity_credit/is_eligible_for_american_opportunity_credit.py +++ b/policyengine_us/variables/gov/irs/credits/education/american_opportunity_credit/is_eligible_for_american_opportunity_credit.py @@ -7,4 +7,63 @@ class is_eligible_for_american_opportunity_credit(Variable): label = "Eligible for American Opportunity Credit" documentation = "Whether the person is eligible for the AOC in respect of qualified tuition expenses for this tax year. The expenses must be for one of the first four years of post-secondary education, and the person must not have claimed the AOC for any four previous tax years." definition_period = YEAR - reference = "https://www.law.cornell.edu/uscode/text/26/25A#b_2" + reference = [ + "https://uscode.house.gov/view.xhtml?edition=prelim&num=0&req=granuleid%3AUSC-prelim-title26-section25A", + "https://uscode.house.gov/view.xhtml?edition=prelim&num=0&req=granuleid%3AUSC-prelim-title20-section1091", + ] + + def formula(person, period, parameters): + aoc = parameters(period).gov.irs.credits.education.american_opportunity_credit + tax_unit = person.tax_unit + filing_status = tax_unit("filing_status", period) + filing_status_values = filing_status.possible_values + filing_status_eligible = filing_status != filing_status_values.SEPARATE + requires_1098_t = aoc.eligibility.requires_1098_t_or_exception + has_1098_t_or_exception = ( + person("has_american_opportunity_credit_1098_t_or_exception", period) + if requires_1098_t + else True + ) + requires_institution_ein = aoc.eligibility.requires_institution_ein + has_institution_ein = ( + person("has_american_opportunity_credit_institution_ein", period) + if requires_institution_ein + else True + ) + + return ( + person("is_pursuing_credential_for_american_opportunity_credit", period) + & person( + "attends_eligible_educational_institution_for_american_opportunity_credit", + period, + ) + & person( + "is_enrolled_at_least_half_time_for_american_opportunity_credit", + period, + ) + & ~person( + "has_completed_first_four_years_of_postsecondary_education", + period, + ) + & (person("american_opportunity_credit_claimed_prior_years", period) < 4) + & ~person("has_felony_drug_conviction", period) + & has_1098_t_or_exception + & has_institution_ein + & person( + "meets_american_opportunity_credit_identification_requirements", + period, + ) + & tax_unit( + "filer_meets_american_opportunity_credit_identification_requirements", + period, + ) + & ~tax_unit( + "is_nonresident_alien_for_american_opportunity_credit", + period, + ) + & ~tax_unit( + "is_barred_from_american_opportunity_credit_due_to_improper_claims", + period, + ) + & filing_status_eligible + ) diff --git a/policyengine_us/variables/gov/irs/credits/education/american_opportunity_credit/is_enrolled_at_least_half_time_for_american_opportunity_credit.py b/policyengine_us/variables/gov/irs/credits/education/american_opportunity_credit/is_enrolled_at_least_half_time_for_american_opportunity_credit.py new file mode 100644 index 00000000000..a7988e8d8be --- /dev/null +++ b/policyengine_us/variables/gov/irs/credits/education/american_opportunity_credit/is_enrolled_at_least_half_time_for_american_opportunity_credit.py @@ -0,0 +1,10 @@ +from policyengine_us.model_api import * + + +class is_enrolled_at_least_half_time_for_american_opportunity_credit(Variable): + value_type = bool + entity = Person + label = "Enrolled at least half-time for the American Opportunity Credit" + documentation = "Whether the student is enrolled at least half-time for at least one academic period beginning in the tax year for American Opportunity Credit purposes." + definition_period = YEAR + reference = "https://uscode.house.gov/view.xhtml?edition=prelim&num=0&req=granuleid%3AUSC-prelim-title26-section25A" diff --git a/policyengine_us/variables/gov/irs/credits/education/american_opportunity_credit/is_nonresident_alien_for_american_opportunity_credit.py b/policyengine_us/variables/gov/irs/credits/education/american_opportunity_credit/is_nonresident_alien_for_american_opportunity_credit.py new file mode 100644 index 00000000000..a4137c303e1 --- /dev/null +++ b/policyengine_us/variables/gov/irs/credits/education/american_opportunity_credit/is_nonresident_alien_for_american_opportunity_credit.py @@ -0,0 +1,10 @@ +from policyengine_us.model_api import * + + +class is_nonresident_alien_for_american_opportunity_credit(Variable): + value_type = bool + entity = TaxUnit + label = "Nonresident alien for American Opportunity Credit" + documentation = "Whether the taxpayer is a nonresident alien for American Opportunity Credit purposes and is not treated as a resident alien under section 6013(g) or 6013(h)." + definition_period = YEAR + reference = "https://uscode.house.gov/view.xhtml?edition=prelim&num=0&req=granuleid%3AUSC-prelim-title26-section25A" diff --git a/policyengine_us/variables/gov/irs/credits/education/american_opportunity_credit/is_pursuing_credential_for_american_opportunity_credit.py b/policyengine_us/variables/gov/irs/credits/education/american_opportunity_credit/is_pursuing_credential_for_american_opportunity_credit.py new file mode 100644 index 00000000000..0f23e19b807 --- /dev/null +++ b/policyengine_us/variables/gov/irs/credits/education/american_opportunity_credit/is_pursuing_credential_for_american_opportunity_credit.py @@ -0,0 +1,13 @@ +from policyengine_us.model_api import * + + +class is_pursuing_credential_for_american_opportunity_credit(Variable): + value_type = bool + entity = Person + label = "Pursuing a credential for the American Opportunity Credit" + documentation = "Whether the student is pursuing a degree, certificate, or other recognized educational credential for American Opportunity Credit purposes." + definition_period = YEAR + reference = [ + "https://uscode.house.gov/view.xhtml?edition=prelim&num=0&req=granuleid%3AUSC-prelim-title26-section25A", + "https://uscode.house.gov/view.xhtml?edition=prelim&num=0&req=granuleid%3AUSC-prelim-title20-section1091", + ] diff --git a/policyengine_us/variables/gov/irs/credits/education/american_opportunity_credit/meets_american_opportunity_credit_identification_requirements.py b/policyengine_us/variables/gov/irs/credits/education/american_opportunity_credit/meets_american_opportunity_credit_identification_requirements.py new file mode 100644 index 00000000000..fffba1812b5 --- /dev/null +++ b/policyengine_us/variables/gov/irs/credits/education/american_opportunity_credit/meets_american_opportunity_credit_identification_requirements.py @@ -0,0 +1,24 @@ +from policyengine_us.model_api import * + + +class meets_american_opportunity_credit_identification_requirements(Variable): + value_type = bool + entity = Person + label = "Meets American Opportunity Credit identification requirements" + documentation = "Whether the person has the taxpayer identification required for the American Opportunity Credit. For tax years beginning after 2025, the required identification is a Social Security number as defined in section 24(h)(7)." + definition_period = YEAR + reference = [ + "https://uscode.house.gov/view.xhtml?edition=prelim&num=0&req=granuleid%3AUSC-prelim-title26-section25A", + "https://uscode.house.gov/view.xhtml?edition=prelim&num=0&req=granuleid%3AUSC-prelim-title26-section24", + ] + + def formula(person, period, parameters): + aoc = parameters(period).gov.irs.credits.education.american_opportunity_credit + if not aoc.eligibility.requires_qualifying_ssn: + return person("has_tin", period) + + ssn_card_type = person("ssn_card_type", period) + ssn_card_types = ssn_card_type.possible_values + citizen = ssn_card_type == ssn_card_types.CITIZEN + non_citizen_valid_ead = ssn_card_type == ssn_card_types.NON_CITIZEN_VALID_EAD + return citizen | non_citizen_valid_ead diff --git a/policyengine_us/variables/gov/irs/credits/education/american_opportunity_credit/non_refundable_american_opportunity_credit.py b/policyengine_us/variables/gov/irs/credits/education/american_opportunity_credit/non_refundable_american_opportunity_credit.py index 8f4bd631e98..f44a2077698 100644 --- a/policyengine_us/variables/gov/irs/credits/education/american_opportunity_credit/non_refundable_american_opportunity_credit.py +++ b/policyengine_us/variables/gov/irs/credits/education/american_opportunity_credit/non_refundable_american_opportunity_credit.py @@ -10,7 +10,7 @@ class non_refundable_american_opportunity_credit(Variable): "Value of the non-refundable portion of the American Opportunity Credit" ) definition_period = YEAR - reference = "https://www.law.cornell.edu/uscode/text/26/25A#i" + reference = "https://uscode.house.gov/view.xhtml?edition=prelim&num=0&req=granuleid%3AUSC-prelim-title26-section25A" def formula(tax_unit, period, parameters): credit_limit = tax_unit( diff --git a/policyengine_us/variables/gov/irs/credits/education/american_opportunity_credit/non_refundable_american_opportunity_credit_credit_limit.py b/policyengine_us/variables/gov/irs/credits/education/american_opportunity_credit/non_refundable_american_opportunity_credit_credit_limit.py index 50cd138800f..e15228acee5 100644 --- a/policyengine_us/variables/gov/irs/credits/education/american_opportunity_credit/non_refundable_american_opportunity_credit_credit_limit.py +++ b/policyengine_us/variables/gov/irs/credits/education/american_opportunity_credit/non_refundable_american_opportunity_credit_credit_limit.py @@ -10,7 +10,7 @@ class non_refundable_american_opportunity_credit_credit_limit(Variable): "Value of the non-refundable portion of the American Opportunity Credit" ) definition_period = YEAR - reference = "https://www.law.cornell.edu/uscode/text/26/25A#i" + reference = "https://uscode.house.gov/view.xhtml?edition=prelim&num=0&req=granuleid%3AUSC-prelim-title26-section25A" def formula(tax_unit, period, parameters): income_tax_before_credits = tax_unit("income_tax_before_credits", period) diff --git a/policyengine_us/variables/gov/irs/credits/education/american_opportunity_credit/non_refundable_american_opportunity_credit_potential.py b/policyengine_us/variables/gov/irs/credits/education/american_opportunity_credit/non_refundable_american_opportunity_credit_potential.py index 7cb5143b0db..0cd1e3fe385 100644 --- a/policyengine_us/variables/gov/irs/credits/education/american_opportunity_credit/non_refundable_american_opportunity_credit_potential.py +++ b/policyengine_us/variables/gov/irs/credits/education/american_opportunity_credit/non_refundable_american_opportunity_credit_potential.py @@ -10,7 +10,7 @@ class non_refundable_american_opportunity_credit_potential(Variable): "Value of the non-refundable portion of the American Opportunity Credit" ) definition_period = YEAR - reference = "https://www.law.cornell.edu/uscode/text/26/25A#i" + reference = "https://uscode.house.gov/view.xhtml?edition=prelim&num=0&req=granuleid%3AUSC-prelim-title26-section25A" adds = ["american_opportunity_credit"] subtracts = ["refundable_american_opportunity_credit"] diff --git a/policyengine_us/variables/gov/irs/credits/education/american_opportunity_credit/refundable_american_opportunity_credit.py b/policyengine_us/variables/gov/irs/credits/education/american_opportunity_credit/refundable_american_opportunity_credit.py index 2aa34b5047c..53c2690ea97 100644 --- a/policyengine_us/variables/gov/irs/credits/education/american_opportunity_credit/refundable_american_opportunity_credit.py +++ b/policyengine_us/variables/gov/irs/credits/education/american_opportunity_credit/refundable_american_opportunity_credit.py @@ -8,7 +8,7 @@ class refundable_american_opportunity_credit(Variable): unit = USD documentation = "Value of the refundable portion of the American Opportunity Credit" definition_period = YEAR - reference = "https://www.law.cornell.edu/uscode/text/26/25A#i" + reference = "https://uscode.house.gov/view.xhtml?edition=prelim&num=0&req=granuleid%3AUSC-prelim-title26-section25A" def formula(tax_unit, period, parameters): aoc = parameters(period).gov.irs.credits.education.american_opportunity_credit diff --git a/policyengine_us/variables/gov/irs/credits/education/attends_eligible_educational_institution_for_lifetime_learning_credit.py b/policyengine_us/variables/gov/irs/credits/education/attends_eligible_educational_institution_for_lifetime_learning_credit.py new file mode 100644 index 00000000000..b2f9c5dcf7a --- /dev/null +++ b/policyengine_us/variables/gov/irs/credits/education/attends_eligible_educational_institution_for_lifetime_learning_credit.py @@ -0,0 +1,10 @@ +from policyengine_us.model_api import * + + +class attends_eligible_educational_institution_for_lifetime_learning_credit(Variable): + value_type = bool + entity = Person + label = "Attends an eligible educational institution for Lifetime Learning Credit" + documentation = "Whether the person is enrolled at an eligible educational institution for Lifetime Learning Credit purposes." + definition_period = YEAR + reference = "https://www.law.cornell.edu/uscode/text/26/25A#f_2" diff --git a/policyengine_us/variables/gov/irs/credits/education/filer_meets_lifetime_learning_credit_identification_requirements.py b/policyengine_us/variables/gov/irs/credits/education/filer_meets_lifetime_learning_credit_identification_requirements.py new file mode 100644 index 00000000000..33f51735552 --- /dev/null +++ b/policyengine_us/variables/gov/irs/credits/education/filer_meets_lifetime_learning_credit_identification_requirements.py @@ -0,0 +1,18 @@ +from policyengine_us.model_api import * + + +class filer_meets_lifetime_learning_credit_identification_requirements(Variable): + value_type = bool + entity = TaxUnit + label = "Filer meets Lifetime Learning Credit identification requirements" + definition_period = YEAR + reference = "https://www.law.cornell.edu/uscode/text/26/25A#g_1" + + def formula(tax_unit, period, parameters): + person = tax_unit.members + head_or_spouse = person("is_tax_unit_head_or_spouse", period) + meets_identification_requirements = person( + "meets_lifetime_learning_credit_identification_requirements", + period, + ) + return tax_unit.all(~head_or_spouse | meets_identification_requirements) diff --git a/policyengine_us/variables/gov/irs/credits/education/has_lifetime_learning_credit_1098_t_or_exception.py b/policyengine_us/variables/gov/irs/credits/education/has_lifetime_learning_credit_1098_t_or_exception.py new file mode 100644 index 00000000000..a5063fd1bf5 --- /dev/null +++ b/policyengine_us/variables/gov/irs/credits/education/has_lifetime_learning_credit_1098_t_or_exception.py @@ -0,0 +1,10 @@ +from policyengine_us.model_api import * + + +class has_lifetime_learning_credit_1098_t_or_exception(Variable): + value_type = bool + entity = Person + label = "Has Form 1098-T or an LLC exception" + documentation = "Whether the student received Form 1098-T or meets an exception allowing the Lifetime Learning Credit to be claimed with substantiated qualified expenses." + definition_period = YEAR + reference = "https://www.law.cornell.edu/uscode/text/26/25A#g_8" diff --git a/policyengine_us/variables/gov/irs/credits/education/is_eligible_for_lifetime_learning_credit.py b/policyengine_us/variables/gov/irs/credits/education/is_eligible_for_lifetime_learning_credit.py new file mode 100644 index 00000000000..3d80f23da5f --- /dev/null +++ b/policyengine_us/variables/gov/irs/credits/education/is_eligible_for_lifetime_learning_credit.py @@ -0,0 +1,48 @@ +from policyengine_us.model_api import * + + +class is_eligible_for_lifetime_learning_credit(Variable): + value_type = bool + entity = Person + label = "Eligible for Lifetime Learning Credit" + documentation = "Whether the person is eligible for the Lifetime Learning Credit in respect of qualified tuition expenses for this tax year." + definition_period = YEAR + reference = [ + "https://www.law.cornell.edu/uscode/text/26/25A#c", + "https://www.law.cornell.edu/uscode/text/26/25A#f", + "https://www.law.cornell.edu/uscode/text/26/25A#g", + ] + + def formula(person, period, parameters): + llc = parameters(period).gov.irs.credits.education.lifetime_learning_credit + tax_unit = person.tax_unit + filing_status = tax_unit("filing_status", period) + filing_status_values = filing_status.possible_values + filing_status_eligible = filing_status != filing_status_values.SEPARATE + requires_1098_t = llc.eligibility.requires_1098_t_or_exception + has_1098_t_or_exception = ( + person("has_lifetime_learning_credit_1098_t_or_exception", period) + if requires_1098_t + else True + ) + + return ( + person( + "attends_eligible_educational_institution_for_lifetime_learning_credit", + period, + ) + & has_1098_t_or_exception + & person( + "meets_lifetime_learning_credit_identification_requirements", + period, + ) + & tax_unit( + "filer_meets_lifetime_learning_credit_identification_requirements", + period, + ) + & ~tax_unit( + "is_nonresident_alien_for_lifetime_learning_credit", + period, + ) + & filing_status_eligible + ) diff --git a/policyengine_us/variables/gov/irs/credits/education/is_nonresident_alien_for_lifetime_learning_credit.py b/policyengine_us/variables/gov/irs/credits/education/is_nonresident_alien_for_lifetime_learning_credit.py new file mode 100644 index 00000000000..16029410d4f --- /dev/null +++ b/policyengine_us/variables/gov/irs/credits/education/is_nonresident_alien_for_lifetime_learning_credit.py @@ -0,0 +1,10 @@ +from policyengine_us.model_api import * + + +class is_nonresident_alien_for_lifetime_learning_credit(Variable): + value_type = bool + entity = TaxUnit + label = "Nonresident alien for Lifetime Learning Credit" + documentation = "Whether the taxpayer is a nonresident alien for Lifetime Learning Credit purposes and is not treated as a resident alien under section 6013(g) or 6013(h)." + definition_period = YEAR + reference = "https://www.law.cornell.edu/uscode/text/26/25A#g_7" diff --git a/policyengine_us/variables/gov/irs/credits/education/lifetime_learning_credit_potential.py b/policyengine_us/variables/gov/irs/credits/education/lifetime_learning_credit_potential.py index 6974c070f57..e7c84437233 100644 --- a/policyengine_us/variables/gov/irs/credits/education/lifetime_learning_credit_potential.py +++ b/policyengine_us/variables/gov/irs/credits/education/lifetime_learning_credit_potential.py @@ -15,8 +15,11 @@ def formula(tax_unit, period, parameters): llc = education.lifetime_learning_credit person = tax_unit.members is_aoc_eligible = person("is_eligible_for_american_opportunity_credit", period) + is_llc_eligible = person("is_eligible_for_lifetime_learning_credit", period) eligible_expenses = tax_unit.sum( - person("qualified_tuition_expenses", period) * ~is_aoc_eligible + person("qualified_tuition_expenses", period) + * is_llc_eligible + * ~is_aoc_eligible ) capped_expenses = min_(llc.expense_limit, eligible_expenses) maximum_amount = llc.rate * capped_expenses diff --git a/policyengine_us/variables/gov/irs/credits/education/meets_lifetime_learning_credit_identification_requirements.py b/policyengine_us/variables/gov/irs/credits/education/meets_lifetime_learning_credit_identification_requirements.py new file mode 100644 index 00000000000..dd6b001e965 --- /dev/null +++ b/policyengine_us/variables/gov/irs/credits/education/meets_lifetime_learning_credit_identification_requirements.py @@ -0,0 +1,24 @@ +from policyengine_us.model_api import * + + +class meets_lifetime_learning_credit_identification_requirements(Variable): + value_type = bool + entity = Person + label = "Meets Lifetime Learning Credit identification requirements" + documentation = "Whether the person has the taxpayer identification required for the Lifetime Learning Credit. For tax years beginning after 2025, the required identification is a Social Security number as defined in section 24(h)(7)." + definition_period = YEAR + reference = [ + "https://www.law.cornell.edu/uscode/text/26/25A#g_1", + "https://www.law.cornell.edu/uscode/text/26/24#h_7", + ] + + def formula(person, period, parameters): + llc = parameters(period).gov.irs.credits.education.lifetime_learning_credit + if not llc.eligibility.requires_qualifying_ssn: + return person("has_tin", period) + + ssn_card_type = person("ssn_card_type", period) + ssn_card_types = ssn_card_type.possible_values + citizen = ssn_card_type == ssn_card_types.CITIZEN + non_citizen_valid_ead = ssn_card_type == ssn_card_types.NON_CITIZEN_VALID_EAD + return citizen | non_citizen_valid_ead