Skip to content

NJ gross income incorrectly includes net losses from income categories; missing 'same category rule' #7017

@PavelMakarchuk

Description

@PavelMakarchuk

Summary

PolicyEngine's New Jersey gross income calculation incorrectly includes net losses from income categories like capital gains and S-corp income. Under NJ's unique "same category rule" (N.J.S. 54A:5-1), if any of the 16 income categories has a net loss, that loss must be disregarded (treated as $0) - it cannot offset income from other categories.

Root Cause

In /policyengine_us/variables/gov/states/nj/tax/income/adjusted_gross_income/nj_gross_income.py:

class nj_gross_income(Variable):
    adds = "gov.states.nj.tax.income.gross_income_sources"

The gross_income_sources.yaml includes:

  • long_term_capital_gains
  • short_term_capital_gains
  • partnership_s_corp_income

These are added directly without applying NJ's rule that net losses in any category must be disregarded.

Legal Reference

N.J.S. 54A:5-1 defines 16 separate categories of gross income:

  • Category (a): Salaries, wages, tips
  • Category (c): Net gains from disposition of property (capital gains)
  • Category (e): Interest
  • Category (f): Dividends
  • Category (k): Distributive share of partnership income
  • Category (p): Net pro rata share of S corporation income
  • etc.

The "Same Category Rule": Losses within one category can offset gains in that same category, but a net loss in any category is disregarded when computing total NJ gross income. Losses cannot:

  • Offset income from other categories
  • Be carried forward to future years

From the NJ Division of Taxation:

"You can deduct federal passive losses in full in the year incurred against any gain within the same category of income"

Example (from policyengine-taxsim issue #673)

Input:

  • MFJ, ages 54 and 54
  • Wages: $136,639
  • Interest: $343
  • Dividends: $1,661
  • Short-term capital losses: -$237,873
  • Long-term capital losses: -$2,252
  • S-corp losses: -$29,134

PE calculates:

  • NJ Gross Income: -$133,628 (incorrectly includes full losses)
  • NJ AGI: $3,011
  • NJ Tax: $0

TaxAct (correct) calculates:

  • NJ Gross Income: $138,673 (losses disregarded per same category rule)
    • Wages: $136,639
    • Interest: $343
    • Dividends: $1,661
    • Capital gains: $0 (net loss → disregarded)
    • S-corp: $0 (net loss → disregarded)
    • Other: $30
  • NJ Tax: $4,776

Files to Fix

  1. policyengine_us/variables/gov/states/nj/tax/income/adjusted_gross_income/nj_gross_income.py

    • Restructure to calculate each NJ income category separately
    • Apply max_(0, category_total) to each category before summing
  2. New variables needed for NJ income categories:

    • nj_category_c_income (capital gains - net of losses, capped at 0)
    • nj_category_k_income (partnership income - net, capped at 0)
    • nj_category_p_income (S-corp income - net, capped at 0)
    • etc.

Suggested Fix

class nj_gross_income(Variable):
    value_type = float
    entity = Person
    label = "New Jersey gross income"
    unit = USD
    definition_period = YEAR
    defined_for = StateCode.NJ

    def formula(person, period, parameters):
        # Category (a): Wages - always positive
        cat_a = person("employment_income", period)
        
        # Category (c): Net gains from disposition of property
        # Net loss is disregarded (capped at 0)
        cat_c = max_(0, 
            person("short_term_capital_gains", period) +
            person("long_term_capital_gains", period)
        )
        
        # Category (e): Interest
        cat_e = person("taxable_interest_income", period)
        
        # Category (f): Dividends
        cat_f = person("dividend_income", period)
        
        # Category (k): Partnership income - net loss disregarded
        # Category (p): S-corp income - net loss disregarded
        cat_k_p = max_(0, person("partnership_s_corp_income", period))
        
        # ... other categories ...
        
        # Sum all categories (each already capped at 0 if net loss)
        return cat_a + cat_c + cat_e + cat_f + cat_k_p + ...

Integration Test

- name: NJ same category rule - capital and S-corp losses disregarded
  period: 2024
  absolute_error_margin: 1
  input:
    people:
      person1:
        age: 54
        employment_income: 0
        qualified_dividend_income: 830.69
        long_term_capital_gains: -1126.16
        short_term_capital_gains: -118936.69
        partnership_s_corp_income: -14566.96
        taxable_interest_income: 171.53
        is_tax_unit_head: true
      person2:
        age: 54
        employment_income: 136639.06
        qualified_dividend_income: 830.69
        long_term_capital_gains: -1126.16
        short_term_capital_gains: -118936.69
        partnership_s_corp_income: -14566.96
        taxable_interest_income: 171.53
        is_tax_unit_spouse: true
    tax_units:
      tax_unit:
        members: [person1, person2]
    spm_units:
      spm_unit:
        members: [person1, person2]
    households:
      household:
        members: [person1, person2]
        state_fips: 34
  output:
    nj_gross_income: 138673  # Losses disregarded per same category rule
    nj_income_tax: 4776

Related Issues

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions