Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added special cases for state_income_tax #172

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
Next Next commit
updated logic for files separately special cases
noman404 committed Dec 16, 2024
commit dc5d6e7efee8c99c1f495933affb0fb5bbf28179
66 changes: 51 additions & 15 deletions policyengine_taxsim/config/variable_mappings.yaml
Original file line number Diff line number Diff line change
@@ -357,8 +357,8 @@ policyengine_to_taxsim:
full_text_group: "Federal Tax Calculation"
group_column: 1
v30:
variable: na_pe
implemented: false
variable: household_net_income
implemented: true
idtl:
- full: 2
- full_text: 5
@@ -413,25 +413,43 @@ policyengine_to_taxsim:
group_order: 4
full_text_group: "State Tax Calculation"
group_column: 1
special_cases:
pre_simulation:
- ms:
implemented: false
variable: na_pe
implemented: true
pre_variable: ms_files_separately
variables:
- ms_standard_deduction_indiv
- ms_standard_deduction_joint
- ar:
implemented: false
variable: na_pe
implemented: true
pre_variable: ar_files_separately
variables:
- ar_standard_deduction_indiv
- ar_standard_deduction_joint
- mt:
implemented: false
variable: na_pe
implemented: true
pre_variable: mt_files_separately
variables:
- mt_standard_deduction_indiv
- mt_standard_deduction_joint
- de:
implemented: false
variable: na_pe
implemented: true
pre_variable: de_files_separately
variables:
- de_standard_deduction_indiv
- de_standard_deduction_joint
- ia:
implemented: false
variable: na_pe
implemented: true
pre_variable: ia_files_separately
variables:
- ia_standard_deduction_indiv
- ia_standard_deduction_joint
- ky:
implemented: false
variable: na_pe
implemented: true
pre_variable: ky_files_separately
variables:
- ky_standard_deduction_indiv
- ky_standard_deduction_joint
v35:
variable: state_itemized_deductions
implemented: true
@@ -446,6 +464,9 @@ policyengine_to_taxsim:
- il:
implemented: false
variable: na_pe
- ms:
implemented: false
variable: na_pe
v36:
variable: state_taxable_income
implemented: true
@@ -456,6 +477,10 @@ policyengine_to_taxsim:
group_order: 4
full_text_group: "State Tax Calculation"
group_column: 1
special_cases:
- ms:
implemented: false
variable: na_pe
tax_before_credits:
variable: state_income_tax_before_non_refundable_credits
implemented: true
@@ -488,6 +513,9 @@ policyengine_to_taxsim:
- mn:
implemented: false
variable: na_pe
- ms:
implemented: false
variable: na_pe
rent_credit:
variable: na_pe
implemented: false
@@ -522,6 +550,10 @@ policyengine_to_taxsim:
group_order: 4
full_text_group: "State Tax Calculation"
group_column: 1
special_cases:
- ms:
implemented: false
variable: na_pe
energy_fuel_credit:
variable: na_pe
implemented: false
@@ -557,6 +589,10 @@ policyengine_to_taxsim:
variables:
- state_non_refundable_credit
- state_refundable_credits
special_cases:
- ms:
implemented: false
variable: na_pe
energy_fuel_credit2:
variable: na_pe
implemented: false
117 changes: 103 additions & 14 deletions policyengine_taxsim/core/output_mapper.py
Original file line number Diff line number Diff line change
@@ -9,6 +9,8 @@
def generate_non_description_output(taxsim_output, mappings, year, state_name, simulation, output_type, logs):
outputs = []
for key, each_item in mappings.items():
state_initial = state_name.lower()

if each_item['implemented']:
if key == "taxsimid":
taxsim_output[key] = taxsim_output["taxsimid"]
@@ -18,10 +20,28 @@ def generate_non_description_output(taxsim_output, mappings, year, state_name, s
taxsim_output[key] = get_state_number(state_name)
elif 'variables' in each_item and len(each_item['variables']) > 0:
pe_variables = each_item['variables']
taxsim_output[key] = simulate_multiple(simulation, pe_variables, year)

if 'special_cases' in each_item:
found_state = next((each for each in each_item['special_cases'] if state_initial in each),
None)
if found_state and found_state[state_initial]['implemented']:
pe_variable = found_state[state_initial]['variable'].replace("state",
state_initial) if "state" in \
found_state[
state_initial][
'variable'] else \
found_state[state_initial]['variable']
taxsim_output[key] = simulate(simulation, pe_variable, year)

outputs.append({'variable': pe_variable, 'value': taxsim_output[key]})
else:
taxsim_output[key] = simulate_multiple(simulation, pe_variables, year, state_initial)

for pe_variable in pe_variables:
outputs.append({'variable': pe_variable, 'value': taxsim_output[key]})

else:
pe_variable = each_item['variable']
state_initial = state_name.lower()

if "state" in pe_variable:
pe_variable = pe_variable.replace("state", state_initial)
@@ -30,11 +50,40 @@ def generate_non_description_output(taxsim_output, mappings, year, state_name, s
if output_type in entry.values():

if 'special_cases' in each_item:
found_state = next((each for each in each_item['special_cases'] if state_initial in each), None)
found_state = next((each for each in each_item['special_cases'] if state_initial in each),
None)
if found_state and found_state[state_initial]['implemented']:
pe_variable = found_state[state_initial]['variable'].replace("state", state_initial) if "state" in found_state[state_initial]['variable'] else found_state[state_initial]['variable']
taxsim_output[key] = simulate(simulation, pe_variable, year)
outputs.append({'variable': pe_variable, 'value': taxsim_output[key]})
pe_variable = found_state[state_initial]['variable'].replace("state",
state_initial) if "state" in \
found_state[
state_initial][
'variable'] else \
found_state[state_initial]['variable']
taxsim_output[key] = simulate(simulation, pe_variable, year)

outputs.append({'variable': pe_variable, 'value': taxsim_output[key]})

elif 'pre_simulation' in each_item:
found_state = next((each for each in each_item['pre_simulation'] if state_initial in each),
None)
if found_state and found_state[state_initial]['implemented']:
pre_simulation_variable = found_state[state_initial]['pre_variable']
use_indiv = simulate_to_decide(simulation, pre_simulation_variable, year)
variables = found_state[state_initial]['variables']

if use_indiv:
pe_variable = variables[0]
else:
pe_variable = variables[1]

taxsim_output[key] = simulate(simulation, pe_variable, year)

outputs.append({'variable': pe_variable, 'value': taxsim_output[key]})

else:
taxsim_output[key] = simulate(simulation, pe_variable, year)

outputs.append({'variable': pe_variable, 'value': taxsim_output[key]})

file_name = f"{taxsim_output['taxsimid']}-{state_name}.yaml"
generate_pe_tests_yaml(simulation.situation_input, outputs, file_name, logs)
@@ -120,14 +169,39 @@ def generate_text_description_output(taxsim_input, mappings, year, state_name, s
elif var_name == "state":
value = f"{get_state_number(state_name)}{' ' * LEFT_MARGIN}{state_name}"
elif 'variables' in each_item and len(each_item['variables']) > 0:
value = simulate_multiple(simulation, each_item['variables'], year)
value = simulate_multiple(simulation, each_item['variables'], year, state_initial)
else:
if 'special_cases' in each_item:
found_state = next((each for each in each_item['special_cases'] if state_initial in each), None)
if found_state and found_state[state_initial]['implemented']:
variable = found_state[state_initial]['variable'].replace("state", state_initial) if "state" in found_state[state_initial]['variable'] else found_state[state_initial]['variable']
value = simulate(simulation, variable, year)
outputs.append({'variable': variable, 'value': value})
variable = found_state[state_initial]['variable'].replace("state",
state_initial) if "state" in \
found_state[
state_initial][
'variable'] else \
found_state[state_initial]['variable']
value = simulate(simulation, variable, year)

outputs.append({'variable': variable, 'value': value})

elif 'pre_simulation' in each_item:
found_state = next((each for each in each_item['pre_simulation'] if state_initial in each),
None)
if found_state and found_state[state_initial]['implemented']:
pre_simulation_variable = found_state[state_initial]['pre_variable']
use_indiv = simulate_to_decide(simulation, pre_simulation_variable, year)
variables = found_state[state_initial]['variables']
print('use indiv', use_indiv)
if use_indiv:
value = simulate(simulation, variables[0], year)
else:
value = simulate(simulation, variables[1], year)

outputs.append({'variable': variable, 'value': value})

else:
value = simulate(simulation, variable, year)
outputs.append({'variable': variable, 'value': value})

# Format the base value
if isinstance(value, (int, float)):
@@ -138,13 +212,18 @@ def generate_text_description_output(taxsim_input, mappings, year, state_name, s
# Format second column value if needed
if has_second_column:
if 'variables' in each_item and len(each_item['variables']) > 0:
second_value = simulate_multiple(simulation_1dollar_more, each_item['variables'], year)
second_value = simulate_multiple(simulation_1dollar_more, each_item['variables'], year, state_initial)
else:
if 'special_cases' in each_item:
found_state = next((each for each in each_item['special_cases'] if state_initial in each),
None)
if found_state and found_state[state_initial]['implemented']:
variable = found_state[state_initial]['variable'].replace("state", state_initial) if "state" in found_state[state_initial]['variable'] else found_state[state_initial]['variable']
variable = found_state[state_initial]['variable'].replace("state",
state_initial) if "state" in \
found_state[
state_initial][
'variable'] else \
found_state[state_initial]['variable']
second_value = simulate(simulation_1dollar_more, variable, year)

if isinstance(second_value, (int, float)):
@@ -318,12 +397,22 @@ def simulate(simulation, variable, year):
try:
return to_roundedup_number(simulation.calculate(variable, period=year))
except Exception as error:
print(error)
return 0.00


def simulate_multiple(simulation, variables, year):
def simulate_to_decide(simulation, variable, year) -> bool:
try:
return simulation.calculate(variable, period=year)[0]
except Exception as error:
print(error)
return False


def simulate_multiple(simulation, variables, year, state):
try:
total = sum(to_roundedup_number(simulation.calculate(variable, period=year)) for variable in variables)
total = sum(to_roundedup_number(simulation.calculate(variable.replace("state", state), period=year)) for variable in variables)
except Exception as error:
print(error)
total = 0.00
return to_roundedup_number(total)