diff --git a/changelog.d/ma-form-4797-schedule-d.fixed.md b/changelog.d/ma-form-4797-schedule-d.fixed.md new file mode 100644 index 00000000000..eb2980bcf16 --- /dev/null +++ b/changelog.d/ma-form-4797-schedule-d.fixed.md @@ -0,0 +1 @@ +Count Form 4797 gains and losses on Massachusetts Schedule D (Part C) instead of Part B. diff --git a/policyengine_us/tests/policy/baseline/gov/states/ma/tax/income/gross_income/ma_long_term_capital_gains.yaml b/policyengine_us/tests/policy/baseline/gov/states/ma/tax/income/gross_income/ma_long_term_capital_gains.yaml new file mode 100644 index 00000000000..6786cf1e7df --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/ma/tax/income/gross_income/ma_long_term_capital_gains.yaml @@ -0,0 +1,158 @@ +# Form 4797, Part II gains and losses (other_net_gain) go on Massachusetts +# Schedule D, line 7, not on Form 1, lines 3 through 10 (Part B). Expected +# values are computed line by line from the 2023 Form 1, Schedule B and +# Schedule D. A single filer with 60,000 of wages and no other 5.0% income +# has Part B taxable income of 60,000 - 2,000 (Form 1, line 11a) - 4,400 +# (line 18) = 53,600 (line 19), taxed at 5% = 2,680. + +- name: Long-term amounts on Schedule D add long-term gains, distributions and Form 4797 amounts + period: 2023 + absolute_error_margin: 0.01 + input: + people: + head: + age: 40 + long_term_capital_gains: 4_000 + non_sch_d_capital_gains: 1_000 + tax_units: + tax_unit: + members: [head] + other_net_gain: -2_000 + households: + household: + members: [head] + state_code: MA + output: + # Schedule D: line 1 = 4,000; line 6 = 1,000; line 7 = -2,000. + ma_long_term_capital_gains: 3_000 + +- name: A Form 4797 gain is Part C income + period: 2023 + absolute_error_margin: 0.01 + input: + people: + head: + age: 40 + employment_income: 60_000 + tax_units: + tax_unit: + members: [head] + other_net_gain: 5_000 + households: + household: + members: [head] + state_code: MA + output: + # Form 1, line 10 = line 3 = 60,000. + ma_part_b_gross_income: 60_000 + # Schedule D, line 7 = 5,000 = lines 9, 13, 15, 17, 19 and 21. + ma_part_c_gross_income: 5_000 + ma_part_c_agi: 5_000 + # 2,680 + 5% x 5,000. + ma_income_tax_before_credits: 2_930 + +- name: A short-term loss offsets a Form 4797 gain in Part C + period: 2023 + absolute_error_margin: 0.01 + input: + people: + head: + age: 40 + employment_income: 60_000 + short_term_capital_gains: -2_000 + tax_units: + tax_unit: + members: [head] + other_net_gain: 5_000 + households: + household: + members: [head] + state_code: MA + output: + ma_part_b_gross_income: 60_000 + # Schedule B: line 19c = -2,000; line 20 = 0 (line 9 is 0); line 21 + # = -2,000; line 22 = Schedule D, line 14 = min(2,000, 5,000) = 2,000. + # Schedule D, line 15 = 5,000 - 2,000 = 3,000. + ma_part_c_agi: 3_000 + # 2,680 + 5% x 3,000. + ma_income_tax_before_credits: 2_830 + +- name: A Form 4797 loss offsets long-term gains on Schedule D + period: 2023 + absolute_error_margin: 0.01 + input: + people: + head: + age: 40 + employment_income: 60_000 + long_term_capital_gains: 5_000 + tax_units: + tax_unit: + members: [head] + other_net_gain: -3_000 + households: + household: + members: [head] + state_code: MA + output: + ma_part_b_gross_income: 60_000 + # Schedule D: line 1 = 5,000; line 7 = -3,000; line 9 = 2,000 = line 13 + # = line 15 = line 21. + ma_part_c_agi: 2_000 + # 2,680 + 5% x 2,000. + ma_income_tax_before_credits: 2_780 + +- name: A Form 4797 loss offsets short-term gains on Schedule B, line 25 + period: 2023 + absolute_error_margin: 0.01 + input: + people: + head: + age: 40 + employment_income: 60_000 + short_term_capital_gains: 3_000 + tax_units: + tax_unit: + members: [head] + other_net_gain: -1_000 + households: + household: + members: [head] + state_code: MA + output: + ma_part_b_gross_income: 60_000 + # Schedule D, line 13 = line 7 = -1,000; line 14 = Schedule B, line 25 + # = min(1,000, 3,000) = 1,000; line 15 = 0. Schedule B, line 26 + # = 3,000 - 1,000 = 2,000 = line 28 = line 39. + ma_part_a_agi: 2_000 + ma_part_a_taxable_capital_gains_income: 2_000 + ma_part_c_agi: 0 + # 2,680 + 8.5% x 2,000. + ma_income_tax_before_credits: 2_850 + +- name: A Form 4797 loss applies against dividends on Schedule B, line 32 + period: 2023 + absolute_error_margin: 0.01 + input: + people: + head: + age: 40 + employment_income: 60_000 + non_qualified_dividend_income: 1_000 + tax_units: + tax_unit: + members: [head] + other_net_gain: -3_000 + households: + household: + members: [head] + state_code: MA + output: + ma_part_b_gross_income: 60_000 + # Schedule D, line 13 = -3,000; Schedule B, line 24 = 0, so line 14 = 0 + # and line 15 = -3,000. Line 32 worksheet: line 2 = min(1,000, 2,000) + # = 1,000; line 4 = 1,000; line 5 = 3,000; line 6 = 1,000. Schedule B, + # line 33 = 1,000 - 1,000 = 0 = line 35. Schedule D, line 17 = -3,000 + # + 1,000 = -2,000 is carried over (line 23). + ma_part_a_agi: 0 + ma_part_c_agi: 0 diff --git a/policyengine_us/variables/gov/states/ma/tax/income/adjusted_gross_income/ma_long_term_loss_against_dividends.py b/policyengine_us/variables/gov/states/ma/tax/income/adjusted_gross_income/ma_long_term_loss_against_dividends.py index 73a8e2a1ab9..211d6102714 100644 --- a/policyengine_us/variables/gov/states/ma/tax/income/adjusted_gross_income/ma_long_term_loss_against_dividends.py +++ b/policyengine_us/variables/gov/states/ma/tax/income/adjusted_gross_income/ma_long_term_loss_against_dividends.py @@ -23,11 +23,10 @@ class ma_long_term_loss_against_dividends(Variable): def formula(tax_unit, period, parameters): short_term_capital_gains = add(tax_unit, period, ["short_term_capital_gains"]) nonnegative_short_term_capital_gains = max_(0, short_term_capital_gains) - # Massachusetts Schedule D, line 13 includes capital gain - # distributions reported without a federal Schedule D (line 6). - long_term_capital_gains = add( - tax_unit, period, ["long_term_capital_gains", "non_sch_d_capital_gains"] - ) + # Massachusetts Schedule D, line 13: long-term gains and losses, + # capital gain distributions without a federal Schedule D (line 6) + # and Form 4797, Part II (line 7). + long_term_capital_gains = tax_unit("ma_long_term_capital_gains", period) long_term_capital_loss = max_(0, -long_term_capital_gains) # Schedule B, line 25: long-term losses first offset short-term gains. remaining_long_term_loss = max_( diff --git a/policyengine_us/variables/gov/states/ma/tax/income/adjusted_gross_income/ma_part_a_agi.py b/policyengine_us/variables/gov/states/ma/tax/income/adjusted_gross_income/ma_part_a_agi.py index 5cdeac3d392..8ac9369f43f 100644 --- a/policyengine_us/variables/gov/states/ma/tax/income/adjusted_gross_income/ma_part_a_agi.py +++ b/policyengine_us/variables/gov/states/ma/tax/income/adjusted_gross_income/ma_part_a_agi.py @@ -14,11 +14,10 @@ def formula(tax_unit, period, parameters): part_a_gross_income = tax_unit("ma_part_a_gross_income", period) short_term_capital_gains = add(tax_unit, period, ["short_term_capital_gains"]) nonnegative_short_term_capital_gains = max_(0, short_term_capital_gains) - # Massachusetts Schedule D, line 13 includes capital gain - # distributions reported without a federal Schedule D (line 6). - long_term_capital_gains = add( - tax_unit, period, ["long_term_capital_gains", "non_sch_d_capital_gains"] - ) + # Massachusetts Schedule D, line 13: long-term gains and losses, + # capital gain distributions without a federal Schedule D (line 6) + # and Form 4797, Part II (line 7). + long_term_capital_gains = tax_unit("ma_long_term_capital_gains", period) long_term_capital_loss = max_(0, -long_term_capital_gains) long_term_loss_against_short_term_gain = min_( diff --git a/policyengine_us/variables/gov/states/ma/tax/income/adjusted_gross_income/ma_part_c_agi.py b/policyengine_us/variables/gov/states/ma/tax/income/adjusted_gross_income/ma_part_c_agi.py index a214438fb47..3297fdf1f91 100644 --- a/policyengine_us/variables/gov/states/ma/tax/income/adjusted_gross_income/ma_part_c_agi.py +++ b/policyengine_us/variables/gov/states/ma/tax/income/adjusted_gross_income/ma_part_c_agi.py @@ -24,9 +24,8 @@ def formula(tax_unit, period, parameters): "ma_short_term_loss_against_dividends", period ) remaining_short_term_loss = short_term_capital_loss - loss_against_dividends - # Massachusetts Schedule D, line 13 includes capital gain - # distributions reported without a federal Schedule D (line 6). - long_term_capital_gains = add( - tax_unit, period, ["long_term_capital_gains", "non_sch_d_capital_gains"] - ) + # Massachusetts Schedule D, line 13: long-term gains and losses, + # capital gain distributions without a federal Schedule D (line 6) + # and Form 4797, Part II (line 7). + long_term_capital_gains = tax_unit("ma_long_term_capital_gains", period) return max_(0, long_term_capital_gains - remaining_short_term_loss) diff --git a/policyengine_us/variables/gov/states/ma/tax/income/gross_income/ma_long_term_capital_gains.py b/policyengine_us/variables/gov/states/ma/tax/income/gross_income/ma_long_term_capital_gains.py new file mode 100644 index 00000000000..adeb46c1a39 --- /dev/null +++ b/policyengine_us/variables/gov/states/ma/tax/income/gross_income/ma_long_term_capital_gains.py @@ -0,0 +1,27 @@ +from policyengine_us.model_api import * + + +class ma_long_term_capital_gains(Variable): + value_type = float + entity = TaxUnit + label = "MA long-term capital gains and losses" + documentation = ( + "Long-term amounts on Massachusetts Schedule D: long-term capital " + "gains and losses, capital gain distributions reported without a " + "federal Schedule D (line 6) and Form 4797, Part II gains and losses " + "(line 7). PolicyEngine has a single Form 4797 input, so it also " + "counts any gain or loss on business property held one year or less, " + "which belongs on Schedule B, lines 12 and 17." + ) + unit = USD + definition_period = YEAR + reference = ( + "https://taxsim.nber.org/historical_state_tax_forms/MA/2023/dor-2023-inc-sch-d-(form-1).pdf", + "https://taxsim.nber.org/historical_state_tax_forms/MA/2023/dor-2023-inc-form1-instructions.pdf#page=27", + ) + defined_for = StateCode.MA + adds = [ + "long_term_capital_gains", + "non_sch_d_capital_gains", + "other_net_gain", + ] diff --git a/policyengine_us/variables/gov/states/ma/tax/income/gross_income/ma_part_b_gross_income.py b/policyengine_us/variables/gov/states/ma/tax/income/gross_income/ma_part_b_gross_income.py index 302668b8391..7d2646795a7 100644 --- a/policyengine_us/variables/gov/states/ma/tax/income/gross_income/ma_part_b_gross_income.py +++ b/policyengine_us/variables/gov/states/ma/tax/income/gross_income/ma_part_b_gross_income.py @@ -7,7 +7,10 @@ class ma_part_b_gross_income(Variable): label = "MA Part B gross income" unit = USD definition_period = YEAR - reference = "https://www.mass.gov/info-details/mass-general-laws-c62-ss-2" + reference = ( + "https://www.mass.gov/info-details/mass-general-laws-c62-ss-2", + "https://taxsim.nber.org/historical_state_tax_forms/MA/2023/dor-2023-inc-form1-instructions.pdf#page=27", + ) defined_for = StateCode.MA def formula(tax_unit, period, parameters): @@ -25,9 +28,16 @@ def formula(tax_unit, period, parameters): dividends = max_(0, person("dividend_income", period)) capital_gains = max_(0, person("capital_gains", period)) # Capital gain distributions reported without a federal Schedule D - # go on Massachusetts Schedule D, line 6. + # go on Massachusetts Schedule D, line 6, and Form 4797, Part II + # gains on line 7. other_net_gain_gross_income is already the + # filers' positive share. distributions = max_(0, person("non_sch_d_capital_gains", period)) - part_a_and_c_income = tax_unit.sum( - where(is_dependent, 0, dividends + capital_gains + distributions) + form_4797_gains = person("other_net_gain_gross_income", period) + filer_dividends_and_gains = tax_unit.sum( + where( + is_dependent, + 0, + dividends + capital_gains + distributions + form_4797_gains, + ) ) - return max_(0, ma_gross_income - part_a_and_c_income) + return max_(0, ma_gross_income - filer_dividends_and_gains) diff --git a/policyengine_us/variables/gov/states/ma/tax/income/gross_income/ma_part_c_gross_income.py b/policyengine_us/variables/gov/states/ma/tax/income/gross_income/ma_part_c_gross_income.py index cb800ca68d1..ae5d11d83bf 100644 --- a/policyengine_us/variables/gov/states/ma/tax/income/gross_income/ma_part_c_gross_income.py +++ b/policyengine_us/variables/gov/states/ma/tax/income/gross_income/ma_part_c_gross_income.py @@ -7,15 +7,15 @@ class ma_part_c_gross_income(Variable): label = "MA Part C gross income" unit = USD definition_period = YEAR - reference = "https://www.mass.gov/info-details/mass-general-laws-c62-ss-2" # (b)(3) + reference = ( + "https://www.mass.gov/info-details/mass-general-laws-c62-ss-2", # (b)(3) + "https://taxsim.nber.org/historical_state_tax_forms/MA/2023/dor-2023-inc-form1-instructions.pdf#page=27", + ) defined_for = StateCode.MA def formula(tax_unit, period, parameters): - # Long-term capital gains, with capital gain distributions reported - # without a federal Schedule D (Massachusetts Schedule D, line 6) - ltcg = add( - tax_unit, period, ["long_term_capital_gains", "non_sch_d_capital_gains"] - ) + # Long-term amounts on Massachusetts Schedule D + ltcg = tax_unit("ma_long_term_capital_gains", period) # Short-term capital gains (can be negative) stcg = add(tax_unit, period, ["short_term_capital_gains"]) # Per MA Schedule B line 22, short-term losses offset long-term gains