diff --git a/taxcalc/calcfunctions.py b/taxcalc/calcfunctions.py index 60a3ed4a4..4bb6efce0 100644 --- a/taxcalc/calcfunctions.py +++ b/taxcalc/calcfunctions.py @@ -791,8 +791,8 @@ def TaxInc(c00100, standard, c04470, c04600, MARS, e00900, e26270, e02100, e27200, e00650, c01000, PT_SSTB_income, PT_binc_w2_wages, PT_ubia_property, PT_qbid_rt, PT_qbid_taxinc_thd, PT_qbid_taxinc_gap, - PT_qbid_w2_wages_rt, - PT_qbid_alt_w2_wages_rt, PT_qbid_alt_property_rt, + PT_qbid_w2_wages_rt, PT_qbid_alt_w2_wages_rt, + PT_qbid_alt_property_rt, PT_qbid_limit_switch, c04800, qbided): """ Calculates taxable income, c04800, and @@ -813,7 +813,9 @@ def TaxInc(c00100, standard, c04470, c04600, MARS, e00900, e26270, upper_thd = lower_thd + pre_qbid_taxinc_gap if PT_SSTB_income == 1 and pre_qbid_taxinc >= upper_thd: qbided = 0. - else: + # if PT_qbid_limit_switch is True, apply wage/capital + # limitations. + elif PT_qbid_limit_switch: wage_cap = PT_binc_w2_wages * PT_qbid_w2_wages_rt alt_cap = (PT_binc_w2_wages * PT_qbid_alt_w2_wages_rt + PT_ubia_property * PT_qbid_alt_property_rt) @@ -834,6 +836,11 @@ def TaxInc(c00100, standard, c04470, c04600, MARS, e00900, e26270, prt = (pre_qbid_taxinc - lower_thd) / pre_qbid_taxinc_gap adj = prt * (qbid_adjusted - cap_adjusted) qbided = qbid_adjusted - adj + # if PT_qbid_limit_switch is False, assume all taxpayers + # have sufficient wage expenses and capital income to avoid + # QBID limitations. + else: + qbided = qbid_before_limits # apply taxinc cap (assuning cap rate is equal to PT_qbid_rt) net_cg = e00650 + c01000 # per line 34 in 2018 Pub 535 Worksheet 12-A taxinc_cap = PT_qbid_rt * max(0., pre_qbid_taxinc - net_cg) diff --git a/taxcalc/policy_current_law.json b/taxcalc/policy_current_law.json index 37e832b83..4de6f345a 100644 --- a/taxcalc/policy_current_law.json +++ b/taxcalc/policy_current_law.json @@ -12358,6 +12358,32 @@ "cps": false } }, + "PT_qbid_limit_switch": { + "title": "QBID wage and capital limitations switch.", + "description": "A value of True imposes wage/capital limitations. Note that neither the PUF nor CPS have data on wage expenses or capital income, and therefore all taxpayers are fully subject to the QBID limitations. A value of False assumes sufficient wage and capital income to avoid QBID limitations.", + "notes": "", + "section_1": "Personal Income", + "section_2": "Pass-Through", + "indexable": false, + "indexed": false, + "type": "bool", + "value": [ + { + "year": 2013, + "value": true + } + ], + "validators": { + "range": { + "min": false, + "max": true + } + }, + "compatible_data": { + "puf": false, + "cps": false + } + }, "AMT_em": { "title": "AMT exemption amount", "description": "The amount of AMT taxable income exempted from AMT.", diff --git a/taxcalc/tests/test_calculator.py b/taxcalc/tests/test_calculator.py index 4c8da08f2..587e8bcde 100644 --- a/taxcalc/tests/test_calculator.py +++ b/taxcalc/tests/test_calculator.py @@ -863,6 +863,42 @@ def test_qbid_calculation(): assert np.allclose(tc_df.qbided, tpc_df.qbid) +def test_qbid_limit_switch(): + """ + Test Calculator's switch to implement wage/capital limitations + on QBI deduction. + """ + cy = 2019 + ref = {"PT_qbid_limit_switch": {2019: False}} + + # filing unit has $500,000 in wages and $100,000 in QBI. Since + # the household is above the taxable income limitation threshold, + # with full wage/capital limitations, it does not receive a QBI + # deduction. With sufficent wage/capital to avoid the limitation, + # the filing unit receives a deduction of: + # $100,000 * 20% = $20,000. + VARS = 'RECID,MARS,e00200s,e00200p,e00200,e26270,e02000\n' + FUNIT = '1,2,250000,250000,500000,100000,100000' + + funit_df = pd.read_csv(StringIO(VARS + FUNIT)) + recs = Records(data=funit_df, start_year=cy, + gfactors=None, weights=None) + + calc_base = Calculator(policy=Policy(), records=recs) + calc_base.calc_all() + + qbid_base = calc_base.array('qbided') + assert np.equal(qbid_base, 0) + + pol_ref = Policy() + pol_ref.implement_reform(ref) + calc_ref = Calculator(policy=pol_ref, records=recs) + calc_ref.calc_all() + + qbid_ref = calc_ref.array('qbided') + assert np.equal(qbid_ref, 20000) + + def test_calc_all_benefits_amounts(cps_subsample): ''' Testing how benefits are handled in the calc_all method