diff --git a/changelog_entry.yaml b/changelog_entry.yaml index e69de29bb2d..77d4aa8f887 100644 --- a/changelog_entry.yaml +++ b/changelog_entry.yaml @@ -0,0 +1,4 @@ +- bump: patch + changes: + fixed: + - Include partnership/S-corp losses in business loss above-the-line deduction. diff --git a/policyengine_us/tests/policy/baseline/gov/irs/income/taxable_income/adjusted_gross_income/above_the_line_deductions/loss_ald.yaml b/policyengine_us/tests/policy/baseline/gov/irs/income/taxable_income/adjusted_gross_income/above_the_line_deductions/loss_ald.yaml new file mode 100644 index 00000000000..62a4d037d41 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/irs/income/taxable_income/adjusted_gross_income/above_the_line_deductions/loss_ald.yaml @@ -0,0 +1,112 @@ +- name: Case 1, S-Corp loss only. + period: 2024 + input: + people: + person1: + partnership_s_corp_income: -50_000 + tax_units: + tax_unit: + members: [person1] + output: + loss_ald: 50_000 + +- name: Case 2, S-Corp loss combined with SE loss. + period: 2024 + input: + people: + person1: + partnership_s_corp_income: -30_000 + self_employment_income: -20_000 + tax_units: + tax_unit: + members: [person1] + output: + loss_ald: 50_000 + +- name: Case 3, losses exceeding section 461(l) cap for single filer. + period: 2024 + input: + people: + person1: + partnership_s_corp_income: -200_000 + self_employment_income: -200_000 + tax_units: + tax_unit: + members: [person1] + filing_status: SINGLE + output: + loss_ald: 305_000 + +- name: Case 4, positive S-Corp income does not affect loss_ald. + period: 2024 + input: + people: + person1: + partnership_s_corp_income: 100_000 + tax_units: + tax_unit: + members: [person1] + output: + loss_ald: 0 + +- name: Case 5, no losses. + period: 2024 + input: + people: + person1: + employment_income: 50_000 + tax_units: + tax_unit: + members: [person1] + output: + loss_ald: 0 + +- name: Case 6, joint filing with losses exceeding joint cap. + period: 2024 + input: + people: + person1: + partnership_s_corp_income: -400_000 + person2: + self_employment_income: -300_000 + tax_units: + tax_unit: + members: [person1, person2] + filing_status: JOINT + output: + # Total losses = 400K + 300K = 700K, joint cap = 610K + loss_ald: 610_000 + +- name: Case 7, mixed positive and negative across people. + period: 2024 + input: + people: + person1: + partnership_s_corp_income: 200_000 + person2: + partnership_s_corp_income: -100_000 + tax_units: + tax_unit: + members: [person1, person2] + filing_status: JOINT + output: + # person1 contributes 0 loss (positive income), person2 contributes 100K + # Losses do not net across people + loss_ald: 100_000 + +- name: Case 8, capital loss combined with partnership loss. + period: 2024 + input: + people: + person1: + partnership_s_corp_income: -50_000 + short_term_capital_gains: -10_000 + tax_units: + tax_unit: + members: [person1] + filing_status: SINGLE + output: + # limited_capital_loss = min(3_000, 10_000) = 3_000 + # partnership loss = 50_000 + # total = 50_000 + 3_000 = 53_000, below cap + loss_ald: 53_000 diff --git a/policyengine_us/tests/policy/baseline/gov/states/wv/tax/income/credits/heptc/wv_homestead_excess_property_tax_credit.yaml b/policyengine_us/tests/policy/baseline/gov/states/wv/tax/income/credits/heptc/wv_homestead_excess_property_tax_credit.yaml index 82bbe11f765..e3456aad6df 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/wv/tax/income/credits/heptc/wv_homestead_excess_property_tax_credit.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/wv/tax/income/credits/heptc/wv_homestead_excess_property_tax_credit.yaml @@ -70,5 +70,7 @@ members: [person1, person2] state_fips: 54 output: - adjusted_gross_income: -3_000 + # Partnership/S-corp losses now recovered via loss_ald, capped at + # $610K (joint, 2024). + adjusted_gross_income: -610_000 wv_homestead_excess_property_tax_credit: 0 diff --git a/policyengine_us/variables/gov/irs/income/taxable_income/adjusted_gross_income/above_the_line_deductions/loss_ald.py b/policyengine_us/variables/gov/irs/income/taxable_income/adjusted_gross_income/above_the_line_deductions/loss_ald.py index 8b2bbaa110e..dd879ae2729 100644 --- a/policyengine_us/variables/gov/irs/income/taxable_income/adjusted_gross_income/above_the_line_deductions/loss_ald.py +++ b/policyengine_us/variables/gov/irs/income/taxable_income/adjusted_gross_income/above_the_line_deductions/loss_ald.py @@ -10,7 +10,10 @@ class loss_ald(Variable): "Above-the-line deduction from gross income for business losses." ) definition_period = YEAR - reference = "https://www.law.cornell.edu/uscode/text/26/165" + reference = ( + "https://www.law.cornell.edu/uscode/text/26/461#l", + "https://www.law.cornell.edu/uscode/text/26/461#l_4", + ) def formula(tax_unit, period, parameters): filing_status = tax_unit("filing_status", period) @@ -18,5 +21,12 @@ def formula(tax_unit, period, parameters): person = tax_unit.members indiv_se_loss = max_(0, -person("self_employment_income", period)) self_employment_loss = tax_unit.sum(indiv_se_loss) + indiv_ps_loss = max_(0, -person("partnership_s_corp_income", period)) + partnership_s_corp_loss = tax_unit.sum(indiv_ps_loss) limited_capital_loss = tax_unit("limited_capital_loss", period) - return min_(max_loss, self_employment_loss + limited_capital_loss) + return min_( + max_loss, + self_employment_loss + + partnership_s_corp_loss + + limited_capital_loss, + ) diff --git a/policyengine_us/variables/gov/states/dc/tax/income/additions/dc_self_employment_loss_addition.py b/policyengine_us/variables/gov/states/dc/tax/income/additions/dc_self_employment_loss_addition.py index 591c08c20f5..f5c15d87742 100644 --- a/policyengine_us/variables/gov/states/dc/tax/income/additions/dc_self_employment_loss_addition.py +++ b/policyengine_us/variables/gov/states/dc/tax/income/additions/dc_self_employment_loss_addition.py @@ -17,10 +17,15 @@ def formula(person, period, parameters): loss_person = max_(0, -person("self_employment_income", period)) loss_taxunit = person.tax_unit.sum(loss_person) # Cap at SE loss actually deducted in federal AGI via loss_ald. - # loss_ald includes both SE and capital losses; isolate SE portion. + # loss_ald includes SE, partnership/S-corp, and capital losses; + # isolate SE portion. loss_ald = person.tax_unit("loss_ald", period) limited_capital_loss = person.tax_unit("limited_capital_loss", period) - se_loss_in_ald = max_(0, loss_ald - limited_capital_loss) + ps_loss = max_(0, -person("partnership_s_corp_income", period)) + ps_loss_taxunit = person.tax_unit.sum(ps_loss) + se_loss_in_ald = max_( + 0, loss_ald - limited_capital_loss - ps_loss_taxunit + ) effective_loss = min_(loss_taxunit, se_loss_in_ald) p = parameters(period).gov.states.dc.tax.income.additions addition_taxunit = max_(