From 29f91fc3b133980a376f8e6d21cbcd9f2169f485 Mon Sep 17 00:00:00 2001 From: duncanhobbs Date: Wed, 29 Sep 2021 14:06:55 -0400 Subject: [PATCH 01/22] Divide CDCC_crt and CDCC_frt parameters by 100 to match other parameters. --- taxcalc/calcfunctions.py | 2 +- taxcalc/policy_current_law.json | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/taxcalc/calcfunctions.py b/taxcalc/calcfunctions.py index b4dd79d23..d4df6f8f7 100644 --- a/taxcalc/calcfunctions.py +++ b/taxcalc/calcfunctions.py @@ -2159,7 +2159,7 @@ def F2441(MARS, earned_p, earned_s, f2441, CDCC_c, e32800, if c00100 > CDCC_ps2: crate = max(0., CDCC_frt - max(((c00100 - CDCC_ps2) * CDCC_prt), 0.)) - c33200 = c33000 * 0.01 * crate + c33200 = c33000 * crate # credit is limited by tax liability if not refundable if CDCC_refundable: c07180 = 0. diff --git a/taxcalc/policy_current_law.json b/taxcalc/policy_current_law.json index 896813e93..04d275d50 100644 --- a/taxcalc/policy_current_law.json +++ b/taxcalc/policy_current_law.json @@ -14074,21 +14074,21 @@ "value": [ { "year": 2013, - "value": 35.0 + "value": 0.350 }, { "year": 2021, - "value": 50.0 + "value": 0.500 }, { "year": 2022, - "value": 35.0 + "value": 0.350 } ], "validators": { "range": { "min": 0, - "max": 100 + "max": 1 } }, "compatible_data": { @@ -14108,13 +14108,13 @@ "value": [ { "year": 2013, - "value": 20.0 + "value": 0.2 } ], "validators": { "range": { "min": 0, - "max": 100 + "max": 1 } }, "compatible_data": { @@ -18104,4 +18104,4 @@ "cps": true } } -} \ No newline at end of file +} From 25c5cfea7886d3a180e5bb8c2e41b01a3a6fcb41 Mon Sep 17 00:00:00 2001 From: duncanhobbs Date: Wed, 29 Sep 2021 14:07:42 -0400 Subject: [PATCH 02/22] Update documentation for CDCC_crt and CDCC_frt to reflect division by 100. --- docs/guide/policy_params.md | 38 ++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/docs/guide/policy_params.md b/docs/guide/policy_params.md index 9bb20f218..622ccb599 100644 --- a/docs/guide/policy_params.md +++ b/docs/guide/policy_params.md @@ -756,41 +756,41 @@ _Out-of-Range Action:_ error #### `CDCC_crt` -_Description:_ The maximum percentage rate for the CDCC; this percentage rate decreases as AGI rises above the CDCC_ps level. +_Description:_ The maximum rate for the CDCC; this rate decreases as AGI rises above the CDCC_ps level. _Has An Effect When Using:_ _PUF data:_ True _CPS data:_ True _Can Be Inflation Indexed:_ False _Is Inflation Indexed:_ False _Value Type:_ float _Known Values:_ -2013: 35.0 -2014: 35.0 -2015: 35.0 -2016: 35.0 -2017: 35.0 -2018: 35.0 -2019: 35.0 -_Valid Range:_ min = 0 and max = 100 +2013: 0.35 +2014: 0.35 +2015: 0.35 +2016: 0.35 +2017: 0.35 +2018: 0.35 +2019: 0.35 +_Valid Range:_ min = 0 and max = 1 _Out-of-Range Action:_ error #### `CDCC_frt` -_Description:_ The minimum percentage rate for the first AGI phaseout of the CDCC. +_Description:_ The minimum rate for the first AGI phaseout of the CDCC. _Has An Effect When Using:_ _PUF data:_ True _CPS data:_ True _Can Be Inflation Indexed:_ False _Is Inflation Indexed:_ False _Value Type:_ float _Known Values:_ -2013: 20.0 -2014: 20.0 -2015: 20.0 -2016: 20.0 -2017: 20.0 -2018: 20.0 -2019: 20.0 -_Valid Range:_ min = 0 and max = 100 +2013: 0.20 +2014: 0.20 +2015: 0.20 +2016: 0.20 +2017: 0.20 +2018: 0.20 +2019: 0.20 +_Valid Range:_ min = 0 and max = 1 _Out-of-Range Action:_ error #### `CDCC_prt` -_Description:_ The CDCC credit rate is reduced by this many percentage points for each dollary of AGI over the phase-out thresholds. +_Description:_ The CDCC credit rate is reduced by this many percentage points for each dollar of AGI over the phase-out thresholds. _Notes:_ In the law, the credit rate is reduced by 1 percentage point for every $2,000 of AGI over the limit. _Has An Effect When Using:_ _PUF data:_ True _CPS data:_ True _Can Be Inflation Indexed:_ False _Is Inflation Indexed:_ False From 473ae2a05384763d4a588ed26d5780d186d8df78 Mon Sep 17 00:00:00 2001 From: duncanhobbs Date: Tue, 5 Oct 2021 18:18:30 -0400 Subject: [PATCH 03/22] Update test_reforms.py with adjusted parameter values. --- taxcalc/tests/test_reforms.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/taxcalc/tests/test_reforms.py b/taxcalc/tests/test_reforms.py index 0db6aafbc..d1151044d 100644 --- a/taxcalc/tests/test_reforms.py +++ b/taxcalc/tests/test_reforms.py @@ -146,7 +146,7 @@ def test_round_trip_reforms(fyear, tests_path): 'CDCC_c': {2021: 8000, 2022: 3000}, 'CDCC_ps': {2021: 125000, 2022: 15000}, 'CDCC_ps2': {2021: 400000, 2022: 9e+99}, - 'CDCC_crt': {2021: 50.0, 2022: 35.0}, + 'CDCC_crt': {2021: 0.500, 2022: 0.350}, 'CDCC_refundable': {2021: True, 2022: False}, 'ALD_BusinessLosses_c': { 2026: [283535.22, 567070.42, 283535.22, 283535.22, 567070.42], From fac5f21202bcfe4f7b7bec9cc44ee419406cca0f Mon Sep 17 00:00:00 2001 From: duncanhobbs Date: Tue, 5 Oct 2021 18:47:39 -0400 Subject: [PATCH 04/22] Correct precision of CDCC_frt. --- taxcalc/policy_current_law.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/taxcalc/policy_current_law.json b/taxcalc/policy_current_law.json index 04d275d50..4024eb5c5 100644 --- a/taxcalc/policy_current_law.json +++ b/taxcalc/policy_current_law.json @@ -14108,7 +14108,7 @@ "value": [ { "year": 2013, - "value": 0.2 + "value": 0.200 } ], "validators": { From 7fbd861da12a4fe1173ec2f2e8206f599874bad8 Mon Sep 17 00:00:00 2001 From: jdebacker Date: Thu, 21 Oct 2021 06:42:06 -0400 Subject: [PATCH 05/22] make CDCC_prt a rate --- taxcalc/policy_current_law.json | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/taxcalc/policy_current_law.json b/taxcalc/policy_current_law.json index 4024eb5c5..cc6d463b7 100644 --- a/taxcalc/policy_current_law.json +++ b/taxcalc/policy_current_law.json @@ -14063,8 +14063,8 @@ } }, "CDCC_crt": { - "title": "Child & dependent care credit phaseout percentage rate ceiling", - "description": "The maximum percentage rate for the CDCC; this percentage rate decreases as AGI rises above the CDCC_ps level.", + "title": "Child & dependent care credit phaseout rate ceiling", + "description": "The maximum rate for the CDCC; this rate decreases as AGI rises above the CDCC_ps level.", "notes": "", "section_1": "Nonrefundable Credits", "section_2": "Child And Dependent Care", @@ -14097,8 +14097,8 @@ } }, "CDCC_frt": { - "title": "Child & dependent care credit phaseout percentage rate floor", - "description": "The minimum percentage rate for the first AGI phaseout of the CDCC.", + "title": "Child & dependent care credit phaseout rate floor", + "description": "The minimum rate for the first AGI phaseout of the CDCC.", "notes": "", "section_1": "Nonrefundable Credits", "section_2": "Child And Dependent Care", @@ -14123,9 +14123,9 @@ } }, "CDCC_prt": { - "title": "Child & dependent care credit phaseout percentage rate", - "description": "The CDCC credit rate is reduced by this many percentage points for each dollary of AGI over the phase-out thresholds.", - "notes": "In the law, the credit rate is reduced by 1 percentage point for every $2,000 of AGI over the limit.", + "title": "Child & dependent care credit phaseout rate", + "description": "The CDCC credit rate is reduced by this many percentage points for each dollar of AGI over the phase-out thresholds.", + "notes": "In the law, the credit rate is reduced by 1 percentage point for every $2,000 of AGI over the limit. 0.01 / 2000 = 0.000005", "section_1": "Nonrefundable Credits", "section_2": "Child And Dependent Care", "indexable": false, @@ -14134,7 +14134,7 @@ "value": [ { "year": 2013, - "value": 0.0005 + "value": 5e-06 } ], "validators": { From b4b174930085ca091ccf1db31bbf02485e75ac39 Mon Sep 17 00:00:00 2001 From: jdebacker Date: Thu, 21 Oct 2021 06:42:35 -0400 Subject: [PATCH 06/22] update F2441 docstring --- taxcalc/calcfunctions.py | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/taxcalc/calcfunctions.py b/taxcalc/calcfunctions.py index d4df6f8f7..c57de0b72 100644 --- a/taxcalc/calcfunctions.py +++ b/taxcalc/calcfunctions.py @@ -2119,15 +2119,23 @@ def F2441(MARS, earned_p, earned_s, f2441, CDCC_c, e32800, c00100: float Adjusted Gross Income (AGI) CDCC_ps: float - Child/dependent care credit phaseout start + Child/dependent care credit first phaseout start + CDCC_ps2: float + Child/dependent care credit second phaseout start CDCC_crt: float - Child/dependent care credit phaseout percentage rate ceiling + Child/dependent care credit phaseout rate ceiling + CDCC_frt: float + Child/dependent care credit phaseout rate floor + CDCC_prt: float + Child/dependent care credit phaseout rate c05800: float Total (regular + AMT) income tax liability before credits e07300: float Foreign tax credit from Form 1116 c07180: float Credit for child and dependent care expenses from Form 2441 + CDCC_refund: bool + Indicator for whether CDCC is refundable Returns ------- @@ -2159,6 +2167,7 @@ def F2441(MARS, earned_p, earned_s, f2441, CDCC_c, e32800, if c00100 > CDCC_ps2: crate = max(0., CDCC_frt - max(((c00100 - CDCC_ps2) * CDCC_prt), 0.)) + c33200 = c33000 * crate # credit is limited by tax liability if not refundable if CDCC_refundable: From 3cf3a216146018e0d52dcf7a06a3a1f951973355 Mon Sep 17 00:00:00 2001 From: Bodi Yang Date: Tue, 3 Jan 2023 15:28:54 -0500 Subject: [PATCH 07/22] update documentation of policy parameters --- docs/guide/policy_params.md | 67 +++++++++++++++++++++++++++---------- 1 file changed, 49 insertions(+), 18 deletions(-) diff --git a/docs/guide/policy_params.md b/docs/guide/policy_params.md index 9bb20f218..72e70ed22 100644 --- a/docs/guide/policy_params.md +++ b/docs/guide/policy_params.md @@ -80,38 +80,69 @@ _Out-of-Range Action:_ error ### Medicare FICA -#### `FICA_mc_trt` -_Description:_ Medicare FICA rate, including both employer and employee. +#### `FICA_mc_trt_employer` +_Description:_ Employer side Medicare FICA rate. _Has An Effect When Using:_ _PUF data:_ True _CPS data:_ True _Can Be Inflation Indexed:_ False _Is Inflation Indexed:_ False _Value Type:_ float _Known Values:_ -2013: 0.029 -2014: 0.029 -2015: 0.029 -2016: 0.029 -2017: 0.029 -2018: 0.029 -2019: 0.029 +2013: 0.0145 +2014: 0.0145 +2015: 0.0145 +2016: 0.0145 +2017: 0.0145 +2018: 0.0145 +2019: 0.0145 _Valid Range:_ min = 0 and max = 1 _Out-of-Range Action:_ error +#### `FICA_mc_trt_employee` +_Description:_ Employee side Medicare FICA rate. +_Has An Effect When Using:_ _PUF data:_ True _CPS data:_ True +_Can Be Inflation Indexed:_ False _Is Inflation Indexed:_ False +_Value Type:_ float +_Known Values:_ +2013: 0.0145 +2014: 0.0145 +2015: 0.0145 +2016: 0.0145 +2017: 0.0145 +2018: 0.0145 +2019: 0.0145 +_Valid Range:_ min = 0 and max = 1 +_Out-of-Range Action:_ error ### Social Security FICA -#### `FICA_ss_trt` -_Description:_ Social Security FICA rate, including both employer and employee. +#### `FICA_ss_trt_employer` +_Description:_ Employer side Social Security FICA rate. +_Has An Effect When Using:_ _PUF data:_ True _CPS data:_ True +_Can Be Inflation Indexed:_ False _Is Inflation Indexed:_ False +_Value Type:_ float +_Known Values:_ +2013: 0.062 +2014: 0.062 +2015: 0.062 +2016: 0.062 +2017: 0.062 +2018: 0.062 +2019: 0.062 +_Valid Range:_ min = 0 and max = 1 +_Out-of-Range Action:_ error + +#### `FICA_ss_trt_employee` +_Description:_ Employee side Social Security FICA rate. _Has An Effect When Using:_ _PUF data:_ True _CPS data:_ True _Can Be Inflation Indexed:_ False _Is Inflation Indexed:_ False _Value Type:_ float _Known Values:_ -2013: 0.124 -2014: 0.124 -2015: 0.124 -2016: 0.124 -2017: 0.124 -2018: 0.124 -2019: 0.124 +2013: 0.062 +2014: 0.062 +2015: 0.062 +2016: 0.062 +2017: 0.062 +2018: 0.062 +2019: 0.062 _Valid Range:_ min = 0 and max = 1 _Out-of-Range Action:_ error From 73ee2702e8ce3a035efd844f4d959ee10ccea87a Mon Sep 17 00:00:00 2001 From: Bodi Yang Date: Tue, 3 Jan 2023 16:36:42 -0500 Subject: [PATCH 08/22] update functions --- taxcalc/calcfunctions.py | 58 +++++++++++++++++++++++----------------- taxcalc/calculator.py | 8 +++--- taxcalc/parameters.py | 2 +- 3 files changed, 40 insertions(+), 28 deletions(-) diff --git a/taxcalc/calcfunctions.py b/taxcalc/calcfunctions.py index 54322ad13..a758e4f58 100644 --- a/taxcalc/calcfunctions.py +++ b/taxcalc/calcfunctions.py @@ -100,8 +100,9 @@ def BenefitPrograms(calc): @iterate_jit(nopython=True) def EI_PayrollTax(SS_Earnings_c, e00200p, e00200s, pencon_p, pencon_s, - FICA_ss_trt, FICA_mc_trt, ALD_SelfEmploymentTax_hc, - SS_Earnings_thd, SECA_Earnings_thd, + FICA_ss_trt_employer, FICA_ss_trt_employee, + FICA_mc_trt_employer, FICA_mc_trt_employee, + ALD_SelfEmploymentTax_hc, SS_Earnings_thd, SECA_Earnings_thd, e00900p, e00900s, e02100p, e02100s, k1bx14p, k1bx14s, payrolltax, ptax_was, setax, c03260, ptax_oasdi, sey, earned, earned_p, earned_s, @@ -123,10 +124,14 @@ def EI_PayrollTax(SS_Earnings_c, e00200p, e00200s, pencon_p, pencon_s, Contributions to defined-contribution pension plans for taxpayer pencon_s: float Contributions to defined-contribution pension plans for spouse - FICA_ss_trt: float - Social security payroll tax rate, including both employer and employee - FICA_mc_trt: float - Medicare payroll tax rate, including both employer and employee + FICA_ss_trt_employer: float + Employer side social security payroll tax rate + FICA_ss_trt_employee: float + Employee side social security payroll tax rate + FICA_mc_trt_employer: float + Employer side medicare payroll tax rate + FICA_mc_trt_employee: float + Employee side medicare payroll tax rate ALD_SelfEmploymentTax_hc: float Adjustment for self-employment tax haircut If greater than zero, reduces the employer equivalent portion of self-employment adjustment @@ -218,22 +223,22 @@ def EI_PayrollTax(SS_Earnings_c, e00200p, e00200s, pencon_p, pencon_s, txearn_was_s = min(SS_Earnings_c, gross_was_s) # compute OASDI and HI payroll taxes on wage-and-salary income, FICA - ptax_ss_was_p = FICA_ss_trt * txearn_was_p - ptax_ss_was_s = FICA_ss_trt * txearn_was_s - ptax_mc_was_p = FICA_mc_trt * gross_was_p - ptax_mc_was_s = FICA_mc_trt * gross_was_s + ptax_ss_was_p = (FICA_ss_trt_employer + FICA_ss_trt_employee) * txearn_was_p + ptax_ss_was_s = (FICA_ss_trt_employer + FICA_ss_trt_employee) * txearn_was_s + ptax_mc_was_p = (FICA_mc_trt_employer + FICA_mc_trt_employee) * gross_was_p + ptax_mc_was_s = (FICA_mc_trt_employer + FICA_mc_trt_employee) * gross_was_s ptax_was = ptax_ss_was_p + ptax_ss_was_s + ptax_mc_was_p + ptax_mc_was_s # compute taxable self-employment income for OASDI SECA - sey_frac = 1.0 - 0.5 * (FICA_ss_trt + FICA_mc_trt) + sey_frac = 1.0 - 0.5 * (FICA_ss_trt_employer + FICA_ss_trt_employee + FICA_mc_trt_employer + FICA_mc_trt_employee) txearn_sey_p = min(max(0., sey_p * sey_frac), SS_Earnings_c - txearn_was_p) txearn_sey_s = min(max(0., sey_s * sey_frac), SS_Earnings_c - txearn_was_s) # compute self-employment tax on taxable self-employment income, SECA - setax_ss_p = FICA_ss_trt * txearn_sey_p - setax_ss_s = FICA_ss_trt * txearn_sey_s - setax_mc_p = FICA_mc_trt * max(0., sey_p * sey_frac) - setax_mc_s = FICA_mc_trt * max(0., sey_s * sey_frac) + setax_ss_p = (FICA_ss_trt_employer + FICA_ss_trt_employee) * txearn_sey_p + setax_ss_s = (FICA_ss_trt_employer + FICA_ss_trt_employee) * txearn_sey_s + setax_mc_p = (FICA_mc_trt_employer + FICA_mc_trt_employee) * max(0., sey_p * sey_frac) + setax_mc_s = (FICA_mc_trt_employer + FICA_mc_trt_employee) * max(0., sey_s * sey_frac) setax_p = setax_ss_p + setax_mc_p setax_s = setax_ss_s + setax_mc_s setax = setax_p + setax_s @@ -246,13 +251,13 @@ def EI_PayrollTax(SS_Earnings_c, e00200p, e00200s, pencon_p, pencon_s, # compute extra OASDI payroll taxes on the portion of the sum # of wage-and-salary income and taxable self employment income # that exceeds SS_Earnings_thd - sey_frac = 1.0 - 0.5 * FICA_ss_trt + sey_frac = 1.0 - 0.5 * (FICA_ss_trt_employer + FICA_ss_trt_employee) was_plus_sey_p = gross_was_p + max(0., sey_p * sey_frac) was_plus_sey_s = gross_was_s + max(0., sey_s * sey_frac) extra_ss_income_p = max(0., was_plus_sey_p - SS_Earnings_thd) extra_ss_income_s = max(0., was_plus_sey_s - SS_Earnings_thd) - extra_payrolltax = (extra_ss_income_p * FICA_ss_trt + - extra_ss_income_s * FICA_ss_trt) + extra_payrolltax = (extra_ss_income_p * (FICA_ss_trt_employer + FICA_ss_trt_employee) + + extra_ss_income_s * (FICA_ss_trt_employer + FICA_ss_trt_employee)) # compute part of total payroll taxes for filing unit # (the ptax_amc part of total payroll taxes for the filing unit is @@ -1057,7 +1062,8 @@ def ItemDed(e17500_capped, e18400_capped, e18500_capped, e19200_capped, @iterate_jit(nopython=True) def AdditionalMedicareTax(e00200, MARS, AMEDT_ec, sey, AMEDT_rt, - FICA_mc_trt, FICA_ss_trt, + FICA_mc_trt_employer, FICA_mc_trt_employee, + FICA_ss_trt_employer, FICA_ss_trt_employee, ptax_amc, payrolltax): """ Computes Additional Medicare Tax (Form 8959) included in payroll taxes. @@ -1070,10 +1076,14 @@ def AdditionalMedicareTax(e00200, MARS, Additional Medicare Tax earnings exclusion AMEDT_rt: float Additional Medicare Tax rate - FICA_ss_trt: float - FICA Social Security tax rate - FICA_mc_trt: float - FICA Medicare tax rate + FICA_ss_trt_employer: float + Employer side FICA Social Security tax rate + FICA_ss_trt_employee: float + Employee side FICA Social Security tax rate + FICA_mc_trt_employer: float + Employer side FICA Medicare tax rate + FICA_mc_trt_employee: float + Employee side FICA Medicare tax rate e00200: float Wages and salaries sey: float @@ -1090,7 +1100,7 @@ def AdditionalMedicareTax(e00200, MARS, payrolltax: float payroll tax augmented by Additional Medicare Tax """ - line8 = max(0., sey) * (1. - 0.5 * (FICA_mc_trt + FICA_ss_trt)) + line8 = max(0., sey) * (1. - 0.5 * (FICA_mc_trt_employer + FICA_mc_trt_employee + FICA_ss_trt_employer + FICA_ss_trt_employee)) line11 = max(0., AMEDT_ec[MARS - 1] - e00200) ptax_amc = AMEDT_rt * (max(0., e00200 - AMEDT_ec[MARS - 1]) + max(0., line8 - line11)) diff --git a/taxcalc/calculator.py b/taxcalc/calculator.py index 092e15e28..af2abbd84 100644 --- a/taxcalc/calculator.py +++ b/taxcalc/calculator.py @@ -694,9 +694,11 @@ def mtr(self, variable_str='e00200p', variable >= self.policy_param('SS_Earnings_thd') ) adj = np.where(oasdi_taxed, - 0.5 * (self.policy_param('FICA_ss_trt') + - self.policy_param('FICA_mc_trt')), - 0.5 * self.policy_param('FICA_mc_trt')) + 0.5 * (self.policy_param('FICA_ss_trt_employer') + + self.policy_param('FICA_ss_trt_employee') + + self.policy_param('FICA_mc_trt_employer') + + self.policy_param('FICA_mc_trt_employee')), + 0.5 * (self.policy_param('FICA_mc_trt_employer') + self.policy_param('FICA_mc_trt_employee'))) else: adj = 0.0 # compute marginal tax rates diff --git a/taxcalc/parameters.py b/taxcalc/parameters.py index 13424566b..8ebbf04cb 100644 --- a/taxcalc/parameters.py +++ b/taxcalc/parameters.py @@ -61,7 +61,7 @@ class Parameters(pt.Parameters): print(name, value) # parameter_indexing_CPI_offset [0.] - # FICA_ss_trt [0.124] + # FICA_ss_trt_employer [0.062] # SS_Earnings_c [113700.] Check out the ParamTools From 8c9de96b0af51991bbd231d218ac9ad2459b58ee Mon Sep 17 00:00:00 2001 From: Bodi Yang Date: Wed, 4 Jan 2023 10:08:25 -0500 Subject: [PATCH 09/22] update reform, tests files --- taxcalc/reforms/Larson2019.json | 29 +++++++++++++++++++---------- taxcalc/reforms/ptaxes0.json | 28 ++++++++++++++++++---------- taxcalc/tests/reforms.json | 5 +++-- taxcalc/tests/test_policy.py | 20 ++++++++++++++------ 4 files changed, 54 insertions(+), 28 deletions(-) diff --git a/taxcalc/reforms/Larson2019.json b/taxcalc/reforms/Larson2019.json index 7fb5f9520..e984c6337 100644 --- a/taxcalc/reforms/Larson2019.json +++ b/taxcalc/reforms/Larson2019.json @@ -10,18 +10,27 @@ // Reform_Parameter_Map: // - 1: SS_thd50, SS_thd85 // - 2: SS_Earnings_thd -// - 3: FICA_ss_trt +// - 3: FICA_ss_trt_employer, FICA_ss_trt_employee { "SS_thd50": {"2019": [50000, 100000, 50000, 50000, 50000]}, "SS_thd85": {"2019": [50000, 100000, 50000, 50000, 50000]}, "SS_Earnings_thd": {"2019": 400000}, - "FICA_ss_trt": {"2020": 0.125, - "2021": 0.126, - "2022": 0.127, - "2023": 0.128, - "2024": 0.129, - "2025": 0.130, - "2026": 0.131, - "2027": 0.132, - "2028": 0.133} + "FICA_ss_trt_employer": {"2020": 0.0625, + "2021": 0.063, + "2022": 0.0635, + "2023": 0.064, + "2024": 0.0645, + "2025": 0.065, + "2026": 0.0655, + "2027": 0.066, + "2028": 0.0665}, + "FICA_ss_trt_employee": {"2020": 0.0625, + "2021": 0.063, + "2022": 0.0635, + "2023": 0.064, + "2024": 0.0645, + "2025": 0.065, + "2026": 0.0655, + "2027": 0.066, + "2028": 0.0665} } diff --git a/taxcalc/reforms/ptaxes0.json b/taxcalc/reforms/ptaxes0.json index 3bf989cb8..f209db519 100644 --- a/taxcalc/reforms/ptaxes0.json +++ b/taxcalc/reforms/ptaxes0.json @@ -1,6 +1,6 @@ // Raise OASDI ("social security") and HI ("Medicare") payroll tax rates -// : current law OASDI (employee+employer) rate is 0.124 -// : current law HI (employee+employer) rate is 0.029 +// : current law OASDI (employee+employer) rate is 0.124, with 0.062 on employer and employee side +// : current law HI (employee+employer) rate is 0.029, with 0.0145 on employer and employee side // Reform_Baseline: 2017_law.json // Reform_Description: // - raise OASDI payroll tax rate in 2018 and 2020 (1) @@ -8,7 +8,7 @@ // Reform_Parameter_Map: // - 1: FICA_ss_trt // - 2: FICA_mc_trt -// NOTE: this reform produces the following rates by year: +// NOTE: this reform produces the following rates (employee+employer) by year: // 2017: 0.124 0.029 // 2018: 0.130 0.029 // 2019: 0.130 0.030 @@ -16,12 +16,20 @@ // 2021: 0.140 0.032 // 2022: 0.140 0.032 { - "FICA_ss_trt": { - "2018": 0.130, - "2020": 0.140 + "FICA_ss_trt_employer": { + "2018": 0.065, + "2020": 0.070 }, - "FICA_mc_trt": { - "2019": 0.030, - "2021": 0.032 - } + "FICA_ss_trt_employee": { + "2018": 0.065, + "2020": 0.070 + }, + "FICA_mc_trt_employer": { + "2019": 0.015, + "2021": 0.016 + }, + "FICA_mc_trt_employee": { + "2019": 0.015, + "2021": 0.016 + } } diff --git a/taxcalc/tests/reforms.json b/taxcalc/tests/reforms.json index 2c1e5f8cf..5e1cd612e 100644 --- a/taxcalc/tests/reforms.json +++ b/taxcalc/tests/reforms.json @@ -2,8 +2,9 @@ "1": { "baseline": "2017_law.json", "start_year": 2015, - "value": {"FICA_ss_trt": 0.134}, - "name": "Increase OASDI payroll tax rate by 1 pts", + "value": {"FICA_ss_trt_employer": 0.067, + "FICA_ss_trt_employee": 0.067}, + "name": "Increase OASDI payroll tax rate by 1 pts, split evenly on employer and employee sides", "output_type": "payrolltax", "compare_with": {} }, diff --git a/taxcalc/tests/test_policy.py b/taxcalc/tests/test_policy.py index 9b21fe1dd..6e9d28154 100644 --- a/taxcalc/tests/test_policy.py +++ b/taxcalc/tests/test_policy.py @@ -72,14 +72,22 @@ def test_json_reform_url(): reform_str = """ { // raise FICA payroll tax rate in 2018 and 2020 - "FICA_ss_trt": { - "2018": 0.130, - "2020": 0.140 + "FICA_ss_trt_employer": { + "2018": 0.065, + "2020": 0.070 + }, + "FICA_ss_trt_employee": { + "2018": 0.065, + "2020": 0.070 }, // raise Medicare payroll tax rate in 2019 and 2021 - "FICA_mc_trt": { - "2019": 0.030, - "2021": 0.032 + "FICA_mc_trt_employer": { + "2019": 0.015, + "2021": 0.016 + }, + "FICA_mc_trt_employee": { + "2019": 0.015, + "2021": 0.016 } } """ From d25902f72007c71af5869ca20bf2db7ac2936101 Mon Sep 17 00:00:00 2001 From: Bodi Yang Date: Wed, 4 Jan 2023 14:20:35 -0500 Subject: [PATCH 10/22] update parameter in policy law file --- taxcalc/policy_current_law.json | 72 ++++++++++++++++++++++++++++----- 1 file changed, 62 insertions(+), 10 deletions(-) diff --git a/taxcalc/policy_current_law.json b/taxcalc/policy_current_law.json index 37b4f96e8..ce3f92f77 100644 --- a/taxcalc/policy_current_law.json +++ b/taxcalc/policy_current_law.json @@ -117,9 +117,9 @@ "cps": true } }, - "FICA_ss_trt": { - "title": "Social Security payroll tax rate", - "description": "Social Security FICA rate, including both employer and employee.", + "FICA_ss_trt_employer": { + "title": "Employer side Social Security payroll tax rate", + "description": "Employer side Social Security FICA rate, including both employer and employee.", "notes": "", "section_1": "Payroll Taxes", "section_2": "Social Security FICA", @@ -129,13 +129,39 @@ "value": [ { "year": 2013, - "value": 0.124 + "value": 0.062 } ], "validators": { "range": { "min": 0, - "max": 1 + "max": 0.5 + } + }, + "compatible_data": { + "puf": true, + "cps": true + } + }, + "FICA_ss_trt_employee": { + "title": "Employee side Social Security payroll tax rate", + "description": "Employee side Social Security FICA rate, including both employer and employee.", + "notes": "", + "section_1": "Payroll Taxes", + "section_2": "Social Security FICA", + "indexable": false, + "indexed": false, + "type": "float", + "value": [ + { + "year": 2013, + "value": 0.062 + } + ], + "validators": { + "range": { + "min": 0, + "max": 0.5 } }, "compatible_data": { @@ -257,9 +283,9 @@ "cps": true } }, - "FICA_mc_trt": { - "title": "Medicare payroll tax rate", - "description": "Medicare FICA rate, including both employer and employee.", + "FICA_mc_trt_employer": { + "title": "Employer side Medicare payroll tax rate", + "description": "Employer side Medicare FICA rate, including both employer and employee.", "notes": "", "section_1": "Payroll Taxes", "section_2": "Medicare FICA", @@ -269,13 +295,39 @@ "value": [ { "year": 2013, - "value": 0.029 + "value": 0.0145 } ], "validators": { "range": { "min": 0, - "max": 1 + "max": 0.5 + } + }, + "compatible_data": { + "puf": true, + "cps": true + } + }, + "FICA_mc_trt_employee": { + "title": "Employee side Medicare payroll tax rate", + "description": "Employee side Medicare FICA rate, including both employer and employee.", + "notes": "", + "section_1": "Payroll Taxes", + "section_2": "Medicare FICA", + "indexable": false, + "indexed": false, + "type": "float", + "value": [ + { + "year": 2013, + "value": 0.0145 + } + ], + "validators": { + "range": { + "min": 0, + "max": 0.5 } }, "compatible_data": { From 0969fc89dc09abca0fd3f66fadb6def90d7deb26 Mon Sep 17 00:00:00 2001 From: Bodi Yang Date: Wed, 11 Jan 2023 11:03:15 -0500 Subject: [PATCH 11/22] update testing reform file --- taxcalc/tests/reforms.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/taxcalc/tests/reforms.json b/taxcalc/tests/reforms.json index 5e1cd612e..6e6580849 100644 --- a/taxcalc/tests/reforms.json +++ b/taxcalc/tests/reforms.json @@ -21,7 +21,8 @@ "3": { "baseline": "2017_law.json", "start_year": 2015, - "value": {"FICA_mc_trt": 0.039}, + "value": {"FICA_mc_trt_employer": 0.0195, + "FICA_mc_trt_employee": 0.0195}, "name": "Increase HI payroll tax rate by 1 pts", "output_type": "payrolltax", "compare_with": {"Budget Options": [73, 77, 82, 87]} From 8255631e36a2fecac504e8a96e5cb9940b157279 Mon Sep 17 00:00:00 2001 From: Bodi Yang Date: Wed, 11 Jan 2023 20:19:00 -0500 Subject: [PATCH 12/22] solve payroll testing problem --- taxcalc/tests/test_calcfunctions.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/taxcalc/tests/test_calcfunctions.py b/taxcalc/tests/test_calcfunctions.py index 160533b4f..cf1aa1e28 100644 --- a/taxcalc/tests/test_calcfunctions.py +++ b/taxcalc/tests/test_calcfunctions.py @@ -223,22 +223,22 @@ def test_StdDed(test_tuple, expected_value, skip_jit): assert np.allclose(test_value, expected_value) -tuple1 = (120000, 10000, 15000, 100, 2000, 0.12, 0.03, 0, 99999999999, - 400, 0, 0, 0, 0, 0, 0, None, None, None, None, None, None, +tuple1 = (120000, 10000, 15000, 100, 2000, 0.06, 0.06, 0.015, 0.015, 0, 99999999999, + 400, 0, 0, 0, 0, 0, 0, None, None, None, None, None, None, None, None, None, None, None) -tuple2 = (120000, 10000, 15000, 100, 2000, 0.12, 0.03, 0, 99999999999, +tuple2 = (120000, 10000, 15000, 100, 2000, 0.06, 0.06, 0.015, 0.015, 0, 99999999999, 400, 2000, 0, 10000, 0, 0, 3000, None, None, None, None, None, None, None, None, None, None, None) -tuple3 = (120000, 150000, 15000, 100, 2000, 0.12, 0.03, 0, 99999999999, +tuple3 = (120000, 150000, 15000, 100, 2000, 0.06, 0.06, 0.015, 0.015, 0, 99999999999, 400, 2000, 0, 10000, 0, 0, 3000, None, None, None, None, None, None, None, None, None, None, None) -tuple4 = (120000, 500000, 15000, 100, 2000, 0.12, 0.03, 0, 400000, +tuple4 = (120000, 500000, 15000, 100, 2000, 0.06, 0.06, 0.015, 0.015, 0, 400000, 400, 2000, 0, 10000, 0, 0, 3000, None, None, None, None, None, None, None, None, None, None, None) -tuple5 = (120000, 10000, 15000, 100, 2000, 0.12, 0.03, 0, 99999999999, +tuple5 = (120000, 10000, 15000, 100, 2000, 0.06, 0.06, 0.015, 0.015, 0, 99999999999, 400, 300, 0, 0, 0, 0, 0, None, None, None, None, None, None, None, None, None, None, None) -tuple6 = (120000, 10000, 15000, 100, 2000, 0.12, 0.03, 0, 99999999999, +tuple6 = (120000, 10000, 15000, 100, 2000, 0.06, 0.06, 0.015, 0.015, 0, 99999999999, 400, 0, 0, 0, 0, -40000, 0, None, None, None, None, None, None, None, None, None, None, None) expected1 = (0, 4065, 4065, 0, 0, 3252, 25000, 10000, 15000, 10100, From dc5f6b6707bf63c5839f7390501bfe390cc9c6b9 Mon Sep 17 00:00:00 2001 From: jdebacker Date: Thu, 19 Jan 2023 12:27:34 -0500 Subject: [PATCH 13/22] change CDCC rate scale --- taxcalc/reforms/ARPA.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/taxcalc/reforms/ARPA.json b/taxcalc/reforms/ARPA.json index b61e52f80..b162b8f1c 100644 --- a/taxcalc/reforms/ARPA.json +++ b/taxcalc/reforms/ARPA.json @@ -59,8 +59,8 @@ "2022": 15000}, "CDCC_ps2": {"2021": 400000, "2022": 9e+99}, - "CDCC_crt": {"2021": 50.0, - "2022": 35.0}, + "CDCC_crt": {"2021": 0.5, + "2022": 0.35}, "CDCC_refundable": {"2021": true, "2022": false}, "ALD_BusinessLosses_c": {"2026": [283535.22, 567070.42, 283535.22, 283535.22, 567070.42], From ebf0cfa1b9e71ef96f0befc36029f07d0443ceca Mon Sep 17 00:00:00 2001 From: Bodi Yang Date: Thu, 30 May 2024 10:26:58 -0400 Subject: [PATCH 14/22] release doc --- docs/about/releases.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/docs/about/releases.md b/docs/about/releases.md index 1677e0d7d..064f2d27b 100644 --- a/docs/about/releases.md +++ b/docs/about/releases.md @@ -3,6 +3,20 @@ Release history Go [here](https://github.com/PSLmodels/Tax-Calculator/pulls?q=is%3Apr+is%3Aclosed) for a complete commit history. +2024-06-01 Release 4.0.0 +------------------------ +(last merged pull request is +[#2749](https://github.com/PSLmodels/Tax-Calculator/pull/2749)) + +**This is a major release with changes that make Tax-Calculator incompatible with earlier releases.** + +**API Changes** +- Reframewrok of the payroll tax policy parameters: Payroll tax parameters are split into the employer side and employee side ~ `FICA_mc_trt`, `FICA_ss_trt` are replaced by `FICA_mc_trt_employer`, `FICA_mc_trt_employee`, `FICA_ss_trt_employer` and `FICA_ss_trt_employee`. [[#2669](https://github.com/PSLmodels/Tax-Calculator/pull/2669) by Bodi Yang] +- CDCC rate scale (`CDCC_crt`, `CDCC_frt`) changed from 0~1 to 0~100. [[#2628](https://github.com/PSLmodels/Tax-Calculator/pull/2628) by Duncan Hobbs and [#2671](https://github.com/PSLmodels/Tax-Calculator/pull/2671) by Jason DeBacker] + +**New Features** +- Tax-Calculator 4.0.0 starts to incorporate with new [Taxcalc-Payroll](https://github.com/bodiyang/Taxcalc-Payroll) model, micro-simulation model focusing on payroll tax analysis. New features include (1) payroll tax reform simulation upon either employer side or employee side; (2) employer side payroll tax offset. [[Taxcalc-Payroll](https://github.com/bodiyang/Taxcalc-Payroll) developed by Bodi Yang] + 2024-05-10 Release 3.6.0 ------------------------ (last merged pull request is From 8ab58fc2f58e2e1531741243782f84fb65c084b4 Mon Sep 17 00:00:00 2001 From: Bodi Yang Date: Thu, 30 May 2024 10:33:42 -0400 Subject: [PATCH 15/22] update version --- docs/index.md | 2 +- setup.py | 2 +- taxcalc.egg-info/PKG-INFO | 2 +- taxcalc/__init__.py | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/index.md b/docs/index.md index d1c2b8f22..13ddb601f 100644 --- a/docs/index.md +++ b/docs/index.md @@ -57,7 +57,7 @@ The cross-model validation work with NBER's TAXSIM-27 model is described ## Latest release -{doc}`3.6.0 (2024-05-10) ` +{doc}`4.0.0 (2024-06-01) ` If you are already using Tax-Calculator, upgrade using the following command: diff --git a/setup.py b/setup.py index 90891cb60..052cf4884 100644 --- a/setup.py +++ b/setup.py @@ -3,7 +3,7 @@ with open("README.md") as f: longdesc = f.read() -version = "3.6.0" +version = "4.0.0" config = { "description": "Tax Calculator", diff --git a/taxcalc.egg-info/PKG-INFO b/taxcalc.egg-info/PKG-INFO index b06f6189d..faa573225 100644 --- a/taxcalc.egg-info/PKG-INFO +++ b/taxcalc.egg-info/PKG-INFO @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: taxcalc -Version: 3.6.0 +Version: 4.0.0 Summary: taxcalc Home-page: https://github.com/PSLmodels/Tax-Calculator Download-URL: https://github.com/PSLmodels/Tax-Calculator diff --git a/taxcalc/__init__.py b/taxcalc/__init__.py index d77f9f8e1..203473408 100644 --- a/taxcalc/__init__.py +++ b/taxcalc/__init__.py @@ -14,4 +14,4 @@ from taxcalc.utils import * from taxcalc.cli import * -__version__ = '3.6.0' +__version__ = '4.0.0' From ee589b9f3b907a75244cdf289e8354a048d9551c Mon Sep 17 00:00:00 2001 From: Bodi Yang Date: Mon, 3 Jun 2024 14:39:40 -0400 Subject: [PATCH 16/22] change documentation --- docs/about/releases.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/about/releases.md b/docs/about/releases.md index 064f2d27b..97e7d206c 100644 --- a/docs/about/releases.md +++ b/docs/about/releases.md @@ -11,7 +11,7 @@ for a complete commit history. **This is a major release with changes that make Tax-Calculator incompatible with earlier releases.** **API Changes** -- Reframewrok of the payroll tax policy parameters: Payroll tax parameters are split into the employer side and employee side ~ `FICA_mc_trt`, `FICA_ss_trt` are replaced by `FICA_mc_trt_employer`, `FICA_mc_trt_employee`, `FICA_ss_trt_employer` and `FICA_ss_trt_employee`. [[#2669](https://github.com/PSLmodels/Tax-Calculator/pull/2669) by Bodi Yang] +- Apply a new framework for the payroll tax policy parameters: Payroll tax parameters are split into the employer side and employee side ~ `FICA_mc_trt`, `FICA_ss_trt` are replaced by `FICA_mc_trt_employer`, `FICA_mc_trt_employee`, `FICA_ss_trt_employer` and `FICA_ss_trt_employee`. [[#2669](https://github.com/PSLmodels/Tax-Calculator/pull/2669) by Bodi Yang] - CDCC rate scale (`CDCC_crt`, `CDCC_frt`) changed from 0~1 to 0~100. [[#2628](https://github.com/PSLmodels/Tax-Calculator/pull/2628) by Duncan Hobbs and [#2671](https://github.com/PSLmodels/Tax-Calculator/pull/2671) by Jason DeBacker] **New Features** From 50ae0c8f09d448480bd0b0ba23ba432e5a42be43 Mon Sep 17 00:00:00 2001 From: "martin.holmer@gmail.com" Date: Tue, 4 Jun 2024 13:07:39 -0400 Subject: [PATCH 17/22] Add test_tmdcsv.py pytest file --- Makefile | 2 +- taxcalc/records.py | 2 +- taxcalc/tests/conftest.py | 10 ++++++++++ taxcalc/tests/test_tmdcsv.py | 38 ++++++++++++++++++++++++++++++++++++ 4 files changed, 50 insertions(+), 2 deletions(-) create mode 100644 taxcalc/tests/test_tmdcsv.py diff --git a/Makefile b/Makefile index 2d9abe0bd..dcf83aeb9 100644 --- a/Makefile +++ b/Makefile @@ -13,7 +13,7 @@ help: @echo "clean : remove .pyc files and local taxcalc package" @echo "package : build and install local package" @echo "pytest-cps : generate report for and cleanup after" - @echo " pytest -m 'not requires_pufcsv and not pre_release'" + @echo " pytest -m 'not requires_pufcsv and not requires_tmdcsv and not pre_release'" @echo "pytest : generate report for and cleanup after" @echo " pytest -m 'not pre_release'" @echo "pytest-all : generate report for and cleanup after" diff --git a/taxcalc/records.py b/taxcalc/records.py index fedec143f..cc947f90a 100644 --- a/taxcalc/records.py +++ b/taxcalc/records.py @@ -227,7 +227,7 @@ def cps_constructor(data=None, @staticmethod def tmd_constructor(data, # path to tmd.csv file or dataframe gfactors=GrowFactors(), - exact_calculations=False): # pragma: no cover + exact_calculations=False): """ Static method returns a Records object instantiated with TMD input data. This works in a analogous way to Records(), which diff --git a/taxcalc/tests/conftest.py b/taxcalc/tests/conftest.py index 06c334874..cb7c98aaf 100644 --- a/taxcalc/tests/conftest.py +++ b/taxcalc/tests/conftest.py @@ -53,6 +53,16 @@ def puf_subsample(puf_fullsample): return puf_fullsample.sample(frac=0.05, random_state=2222) +@pytest.fixture(scope='session') +def tmd_path(tests_path): + return os.path.join(tests_path, '..', '..', 'tmd.csv') + + +@pytest.fixture(scope='session') +def tmd_fullsample(tmd_path): + return pandas.read_csv(tmd_path) + + @pytest.fixture(scope='session', name='test_reforms_init') def fixture_test_reforms(tests_path): """ diff --git a/taxcalc/tests/test_tmdcsv.py b/taxcalc/tests/test_tmdcsv.py new file mode 100644 index 000000000..6eb350f5c --- /dev/null +++ b/taxcalc/tests/test_tmdcsv.py @@ -0,0 +1,38 @@ +""" +Tests of Tax-Calculator using tmd.csv input. + +Note that the tmd.csv file that is required to run this program has +been constructed in the PSLmodels tax-microdata repository using the +2015 IRS SOI PUF file and recent Census CPS data. If you have +acquired from IRS the 2015 SOI PUF file and want to execute this program, +contact the Tax-Calculator development team to discuss your options. + +Read Tax-Calculator/TESTING.md for details. +""" +# CODING-STYLE CHECKS: +# pycodestyle test_tmdcsv.py +# pylint --disable=locally-disabled test_tmdcsv.py + +import pytest +# pylint: disable=import-error +from taxcalc import Policy, Records, Calculator + + +@pytest.mark.requires_tmdcsv +def test_tmd_input(tmd_fullsample): + """ + Test Tax-Calculator using full-sample tmd.csv file. + """ + taxyear = 2022 + # create a Policy object with current-law policy parameters + pol = Policy() + # create a Records object containing all tmd.csv input records + recs = Records.tmd_constructor(data=tmd_fullsample) + # create a Calculator object using current-law policy and tmd records + calc = Calculator(policy=pol, records=recs) + calc.advance_to_year(taxyear) + calc.calc_all() + assert calc.data_year == Records.TMDCSV_YEAR + assert calc.current_year == taxyear + inctax = calc.weighted_total('iitax') + assert inctax > 0 From 87861f8bd9e5a987f6003bb8b9bc58948a7811ab Mon Sep 17 00:00:00 2001 From: "martin.holmer@gmail.com" Date: Tue, 4 Jun 2024 13:18:49 -0400 Subject: [PATCH 18/22] Add back no-cover pragma because test is requires_tmdcsv --- taxcalc/records.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/taxcalc/records.py b/taxcalc/records.py index cc947f90a..fedec143f 100644 --- a/taxcalc/records.py +++ b/taxcalc/records.py @@ -227,7 +227,7 @@ def cps_constructor(data=None, @staticmethod def tmd_constructor(data, # path to tmd.csv file or dataframe gfactors=GrowFactors(), - exact_calculations=False): + exact_calculations=False): # pragma: no cover """ Static method returns a Records object instantiated with TMD input data. This works in a analogous way to Records(), which From 96e9f169d213d9b6322b67c5136fc5325ca4e47c Mon Sep 17 00:00:00 2001 From: Bodi Yang Date: Wed, 5 Jun 2024 09:05:19 -0400 Subject: [PATCH 19/22] releases.md --- docs/about/releases.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/about/releases.md b/docs/about/releases.md index 97e7d206c..7cf33986d 100644 --- a/docs/about/releases.md +++ b/docs/about/releases.md @@ -15,7 +15,8 @@ for a complete commit history. - CDCC rate scale (`CDCC_crt`, `CDCC_frt`) changed from 0~1 to 0~100. [[#2628](https://github.com/PSLmodels/Tax-Calculator/pull/2628) by Duncan Hobbs and [#2671](https://github.com/PSLmodels/Tax-Calculator/pull/2671) by Jason DeBacker] **New Features** -- Tax-Calculator 4.0.0 starts to incorporate with new [Taxcalc-Payroll](https://github.com/bodiyang/Taxcalc-Payroll) model, micro-simulation model focusing on payroll tax analysis. New features include (1) payroll tax reform simulation upon either employer side or employee side; (2) employer side payroll tax offset. [[Taxcalc-Payroll](https://github.com/bodiyang/Taxcalc-Payroll) developed by Bodi Yang] +- Ablility to perform payroll tax reform upon either employer side or employee side. [by Bodi Yang] + 2024-05-10 Release 3.6.0 ------------------------ From cb7b95ac4072da4296c0d3b3c9197551f1fce836 Mon Sep 17 00:00:00 2001 From: Bodi Yang Date: Wed, 5 Jun 2024 09:06:51 -0400 Subject: [PATCH 20/22] update release file --- docs/about/releases.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/about/releases.md b/docs/about/releases.md index 7cf33986d..3b8818c22 100644 --- a/docs/about/releases.md +++ b/docs/about/releases.md @@ -6,7 +6,7 @@ for a complete commit history. 2024-06-01 Release 4.0.0 ------------------------ (last merged pull request is -[#2749](https://github.com/PSLmodels/Tax-Calculator/pull/2749)) +[#2752](https://github.com/PSLmodels/Tax-Calculator/pull/2752)) **This is a major release with changes that make Tax-Calculator incompatible with earlier releases.** From 5e43e0a859571623c4919f0269dfe2495bd43f89 Mon Sep 17 00:00:00 2001 From: "martin.holmer@gmail.com" Date: Wed, 5 Jun 2024 12:12:32 -0400 Subject: [PATCH 21/22] Revise GrowFactor constructor to handle custom growfactors files. --- taxcalc/growfactors.py | 35 +++++++++++++++++++---------------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/taxcalc/growfactors.py b/taxcalc/growfactors.py index 7a6223505..435fe5149 100644 --- a/taxcalc/growfactors.py +++ b/taxcalc/growfactors.py @@ -17,14 +17,15 @@ class GrowFactors(): Parameters ---------- - growfactors_filename: string - string is name of CSV file in which grow factors reside; - default value is name of file containing baseline grow factors. + growfactors_filename: None or string + string is path to the CSV file in which grow factors reside; + default value of None uses file containing baseline grow factors. Raises ------ ValueError: - if growfactors_filename is not a string. + if growfactors_filename is neither None or a string. + if growfactors_filename string points to a non-existent file. Returns ------- @@ -33,7 +34,7 @@ class instance: GrowFactors Notes ----- Typical usage is "gfactor = GrowFactors()", which produces an object - containing growth factors in the GrowFactors.FILE_NAME file. + containing baseline growth factors in the GrowFactors.FILE_NAME file. """ FILE_NAME = 'growfactors.csv' @@ -48,17 +49,19 @@ class instance: GrowFactors 'ABENSSI', 'ABENSNAP', 'ABENWIC', 'ABENHOUSING', 'ABENTANF', 'ABENVET']) - def __init__(self, growfactors_filename=FILE_NAME): + def __init__(self, growfactors_filename=None): # read grow factors from specified growfactors_filename gfdf = pd.DataFrame() - if isinstance(growfactors_filename, str): - full_filename = os.path.join(GrowFactors.FILE_PATH, - growfactors_filename) - if os.path.isfile(full_filename): - gfdf = pd.read_csv(full_filename, index_col='YEAR') - else: # find file in package - gfdf = read_egg_csv(os.path.basename(growfactors_filename), - index_col='YEAR') # pragma: no cover + if growfactors_filename is None: + # read baseline growfactor from package + gfdf = read_egg_csv(GrowFactors.FILE_NAME, + index_col='YEAR') # pragma: no cover + elif isinstance(growfactors_filename, str): + if os.path.isfile(growfactors_filename): + gfdf = pd.read_csv(growfactors_filename, index_col='YEAR') + else: # file does not exist + msg = f'growfactors file {growfactors_filename} does not exist' + raise ValueError(msg) else: raise ValueError('growfactors_filename is not a string') assert isinstance(gfdf, pd.DataFrame) @@ -143,7 +146,7 @@ def factor_value(self, name, year): if year > self.last_year: msg = 'year={} > GrowFactors.last_year={}' raise ValueError(msg.format(year, self.last_year)) - return self.gfdf.loc[year,name] + return self.gfdf.loc[year, name] def update(self, name, year, diff): """ @@ -156,4 +159,4 @@ def update(self, name, year, diff): assert year >= self.first_year assert year <= self.last_year assert isinstance(diff, float) - self.gfdf.loc[year,name] += diff + self.gfdf.loc[year, name] += diff From afb7df143de6905bce7f891ba32de6f5ad34d82d Mon Sep 17 00:00:00 2001 From: "martin.holmer@gmail.com" Date: Wed, 5 Jun 2024 16:28:07 -0400 Subject: [PATCH 22/22] Add another test to test_growfactors.py --- taxcalc/tests/test_growfactors.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/taxcalc/tests/test_growfactors.py b/taxcalc/tests/test_growfactors.py index 8c4771b8b..5e0e7d163 100644 --- a/taxcalc/tests/test_growfactors.py +++ b/taxcalc/tests/test_growfactors.py @@ -32,6 +32,8 @@ def test_improper_usage(bad_gf_file): """ with pytest.raises(ValueError): gfo = GrowFactors(dict()) + with pytest.raises(ValueError): + gfo = GrowFactors('non_existent_file.csv') with pytest.raises(ValueError): gfo = GrowFactors(bad_gf_file.name) gfo = GrowFactors()