Skip to content

Add get_payroll_tax_revenue function for correct payroll tax revenue - #1184

Open
arihantlodha-cmd wants to merge 3 commits into
PSLmodels:masterfrom
arihantlodha-cmd:payroll-tax-revenue-function
Open

Add get_payroll_tax_revenue function for correct payroll tax revenue#1184
arihantlodha-cmd wants to merge 3 commits into
PSLmodels:masterfrom
arihantlodha-cmd:payroll-tax-revenue-function

Conversation

@arihantlodha-cmd

Copy link
Copy Markdown

Closes #1023.

Adds a dedicated get_payroll_tax_revenue function in aggregates.py and calls it from revenue() in place of the two inline calculations.

Previously payroll tax revenue was always computed as frac_tax_payroll * iit_payroll_tax_revenue, which assumes payroll taxes are embedded in the estimated income and payroll tax functions and separated out via the frac_tax_payroll series. As noted in the issue, that is incorrect when a user instead models payroll taxes explicitly through tau_payroll (and excludes them from etr_params/mtrx_params/mtry_params). The new function branches on tau_payroll:

  • if np.any(tau_payroll != 0): payroll_tax_revenue = tau_payroll * w * L (aggregate labor summed across industries)
  • otherwise (the default, tau_payroll == 0): the existing frac_tax_payroll * iit_payroll_tax_revenue

The two are identical when tau_payroll == 0, so default runs are unchanged (existing test_revenue still passes).

A few implementation choices, flagged for review:

  • Named it get_payroll_tax_revenue rather than payroll_tax_revenue to match the module's get_* convention and to avoid shadowing the local payroll_tax_revenue variable inside revenue(). Happy to rename if you'd prefer.
  • L arrives per-industry in revenue(), so aggregate labor income uses L.sum(-1).
  • Consolidated to a single call after the SS/TPI branches rather than duplicating the calculation in each.

Testing

  • Added test_get_payroll_tax_revenue covering both branches for SS and TPI.
  • pytest tests/test_aggregates.py -m "not local and not benchmark" → 43 passed; ruff format --check . and ruff check . clean.

One question for maintainers: when payroll taxes are modeled via tau_payroll and excluded from the tax functions, iit_payroll_tax_revenue no longer contains payroll revenue, so iit_revenue = iit_payroll_tax_revenue - payroll_tax_revenue (and payroll's contribution to total_tax_revenue) may also need revisiting. I left those as-is to keep this PR scoped to the issue — glad to follow up if you'd like that handled here too.

Closes PSLmodels#1023. Previously payroll tax revenue was always computed as
frac_tax_payroll * iit_payroll_tax_revenue, which is incorrect when a user
models payroll taxes explicitly via tau_payroll (and excludes them from the
tax functions). Adds get_payroll_tax_revenue, which uses tau_payroll * w * L
when tau_payroll is nonzero and falls back to the existing fraction-of-
combined-revenue calculation otherwise. Identical results when tau_payroll
is zero (the default), so default runs are unchanged.

Adds test_get_payroll_tax_revenue covering both branches for SS and TPI.
@codecov-commenter

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
⚠️ Please upload report for BASE (master@b0986ac). Learn more about missing BASE report.
⚠️ Report is 7 commits behind head on master.

Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff            @@
##             master    #1184   +/-   ##
=========================================
  Coverage          ?   72.70%           
=========================================
  Files             ?       22           
  Lines             ?     5734           
  Branches          ?        0           
=========================================
  Hits              ?     4169           
  Misses            ?     1565           
  Partials          ?        0           
Flag Coverage Δ
unittests 72.70% <100.00%> (?)

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
ogcore/aggregates.py 100.00% <100.00%> (ø)
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@jdebacker

Copy link
Copy Markdown
Member

@arihantlodha-cmd Thanks for this PR.

Regarding your question, yes, let's fix the calculation of iit_revenue. I think something like the following could work (placed before the total_tax_revenue = line):

payroll_tax_revenue = get_payroll_tax_revenue(
        w, L, iit_payroll_tax_revenue, p, method
    )
if np.any(p.tau_payroll != 0):
    iit_payroll_tax_revenue += payroll_tax_revenue
iit_revenue = iit_payroll_tax_revenue - payroll_tax_revenue

@jdebacker

Copy link
Copy Markdown
Member

Also, please run make format to resolve formatting issues. Thanks!

Per review feedback (PSLmodels#1184): when payroll taxes are modeled explicitly via
tau_payroll (and excluded from the income+payroll tax functions),
iit_payroll_tax_revenue holds only income tax, so payroll_tax_revenue is now
added back into it before computing total_tax_revenue and iit_revenue.

Regenerated the test_revenue golden values, whose params use tau_payroll=0.5:
each new total equals the previous total plus payroll_tax_revenue (verified
by construction). No change to default (tau_payroll == 0) runs.
@arihantlodha-cmd

Copy link
Copy Markdown
Author

Thanks for the review! Addressed both points:

  • Added the iit_revenue fix as suggested: iit_payroll_tax_revenue += payroll_tax_revenue when np.any(p.tau_payroll != 0), so the explicitly-modeled payroll revenue now flows into both total_tax_revenue and iit_revenue.
  • Regenerated the test_revenue golden values, since its params use tau_payroll=0.5. Each new total equals the previous total plus payroll_tax_revenue (verified by construction); default tau_payroll==0 runs are unchanged.

Ran make format and synced with master, so the lint check passes now (ruff format --check ., ruff check ., linecheck all clean). Full test_aggregates.py passes (43).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Computing payroll tax revenue

3 participants