[IMP] l10n_us_hr_payroll: Rules and improvements. (+104 squashed commits)

Squashed commits:
[9ca3d040] [FIX] l10n_us_hr_payroll: payslip category sum over date range now includes child categories
[7a92b96e] [FIX] l10n_us_hr_payroll: remove overwrite to correct wage calculation above
[45d130ce] [IMP] l10n_us_hr_payroll: Add migration code to handle known issues from Odoo S.A. migrations.
[54bffced] [FIX] l10n_us_hr_payroll: add missing `semi-monthly` as a default schedule pay
[d7206395] [IMP] l10n_us_hr_payroll: common test call paramaterize defaults for Structure Type and Resource Calendar
[a1174740] [FIX] l10n_us_hr_payroll : Fixed exempt test case for 2019.
[2d8ec31b] [IMP] l10n_us_hr_payroll: Improved Tax table and improved Test case for NJ New Jersey 2020
[51f61ab5] [IMP] l10n_us_hr_payroll: Added comment and improved Test case for MS Mississippi 2020
[5bfe38f3] [IMP] l10n_us_hr_payroll: Improved Test case for MI Michigan 2020
[c21aa7a7] [IMP] l10n_us_hr_payroll: Added comment for MN Minnesota 2020
[ed67319a] [IMP] l10n_us_hr_payroll: Added comment and improved Test case for MO Missouri 2020
[cc68ea2e] [IMP] l10n_us_hr_payroll: Added Tax table and improved Test case for MT Montana 2020
[9450418c] [IMP] l10n_us_hr_payroll: Added Tax table and improved Test case for ID Idaho 2020
[c389748c] [IMP] l10n_us_hr_payroll: Added Tax table and improved Test case for KY Kentucky 2020
[6d4171fc] [IMP] l10n_us_hr_payroll: Reformat tax table, improved comments and test case for IA Iowa 2020
[77588bc6] [IMP] l10n_us_hr_payroll: Improved Tax table and Test case for HI Hawaii 2020
[585f8cbf] [IMP] l10n_us_hr_payroll: Added Tax table for 2020 and improved Test case for GA Georgia 2020
[92a89e59] [IMP] l10n_us_hr_payroll: Reformat tax table, improved comments and test case for CA California 2020
[785b33e3] [IMP] l10n_us_hr_payroll: Improved comments and test case for CT Connecticut 2020
[13198a9e] [IMP] l10n_us_hr_payroll: Improved test case for CO Colorado 2020
[c65b62a7] [IMP] l10n_us_hr_payroll: Improved comments and test case for AR Arkansas 2020
[e01eeb65] [IMP] l10n_us_hr_payroll: Improved test case for AZ Arizona 2020
[5cf0b69e] [IMP] l10n_us_hr_payroll: Improved comments, Tax table, filing status and test case for AL Alabama 2020
[64436b6e] [IMP] l10n_us_hr_payroll: Improved comments and test case for NM New Mexico 2020
[c395c8a9] [IMP] l10n_us_hr_payroll: Added Comment, removed one filing status which was not used in calculation and improve test case for exempt for NC North Carolina 2020
[ff4adfe8] [IMP] l10n_us_hr_payroll: Comment add for table for VA Virginia 2020
[9fc9b3b6] [IMP] l10n_us_hr_payroll: Reformat Tax table and changed wage for VT Vermont 2020
[5c96026b] [IMP] l10n_us_hr_payroll: Reformat Tax table and changed SUTA rate for RI Rhode Island 2020
[2a2abb62] [IMP] l10n_us_hr_payroll: Reformat Tax table, changed SUTA rate and improved test case for UT Utah 2020.
[42edfc06] [IMP] l10n_us_hr_payroll: Refactored Tax table, changed filing status string and Improved test case for KS Kansas 2020.
[733e721a] [IMP] l10n_us_hr_payroll: Reformat Tax table, changed field string and improved test case for OK Oklahoma 2020
[7c2d9a20] [IMP] l10n_us_hr_payroll: Reformat Tax table for WV West Virginia 2020.
[91630c86] [IMP] l10n_us_hr_payroll: Refactored Tax table, changed tax rate and added additional withholding field. Improved test case for ME Maine 2020.
[9c62ebaf] [IMP] l10n_us_hr_payroll: Refactored Tax table and Improved test case for NE Nebraska 2020.
[88118297] [IMP] l10n_us_hr_payroll: Refactored  Tax table and Improved test case for ME Maine 2020.
[641bb815] [IMP] l10n_us_hr_payroll: Refactored sit rate tax table and added allowance field and apply on calculation. Also Improved test case for for ND North Dakota 2020.
[f6f81615] [IMP] l10n_us_hr_payroll: Changed Form name and additional withholding field string for IN Indiana 2020.
[e4c9774f] [IMP] l10n_us_hr_payroll: Added additional withholding, changed suta rate for 2020 and Improved test for SC South Carolina 2020.
[91887067] [IMP] l10n_us_hr_payroll: Improved test and restructured table for WI Wisconsin 2020.
[9110d174] [FIX] l10n_us_hr_payroll: Updated NY New York 2020 rates and tests.
[1a7c26d8] [FIX]  l10n_us_hr_payroll: Added exempt on filing status for NY.
[8f447aaa] [IMP] l10n_us_hr_payroll: Changed wage base and suta rate for NY New York 2019/2020.
[e9a53918] [IMP] l10n_us_hr_payroll: Changed suta rate for WY Wyoming 2020.

H2914
[eddc6431] [IMP] l10n_us_hr_payroll: Changed suta rate and added exempt.

H2816
[dff4a2ca] [IMP] l10n_us_hr_payroll: For Rhode Island 13.0
[baea9412] [IMP] l10n_us_hr_payroll: For West Virginia 13.0
[8fed8e7b] [IMP] l10n_us_hr_payroll: For Wisconsin 13.0
[57182a87] [IMP] l10n_us_hr_payroll: For South Dakota 13.0
[1011c62e] [IMP] l10n_us_hr_payroll: For Tennessee 13.0
[688a3cc1] [IMP] l10n_us_hr_payroll: For Utah 13.0
[ded656db] [IMP] l10n_us_hr_payroll: For Vermont 13.0
[a0da1841] [IMP] l10n_us_hr_payroll: Port `l10n_us_wy_hr_payroll` WY Wyoming including migration.
[977cc3af] [IMP] l10n_us_hr_payroll: For Oklahoma 13.0
[68a0697c] [FIX]l10n_us_hr_payroll: Spell mistake on Kansas state payroll.
[addd5f03] [IMP] l10n_us_hr_payroll: For Kentucky 13.0
[4fb48854] [IMP] l10n_us_hr_payroll: For Kansas 13.0
[60d40449] [IMP] l10n_us_hr_payroll: For Nevada 13.0
[2475250f] [IMP] l10n_us_hr_payroll: For Maine 13.0
[1234467d] [IMP] l10n_us_hr_payroll: For North Dakota 13.0
[d1642bbe] IMP `l10n_us_hr_payroll` Allow configurable changes to payslip summing behavior.

In stock Odoo, summing anything in payroll rules (but most importantly rule amounts and category amounts by code), the considered payslips are referenced from their `date_from` field.  However in the USA, it is in fact the `date_to` that is more important (or accounting date). A Payslip made for 2019-12-20 to 2020-01-04 should in fact be considered a '2020' payslip, and thus the summation on other '2020' payslips must find it by considering payslips `date_to`.
[0af81085] IMP `l10n_us_hr_payroll` Port `l10n_us_ny_hr_payroll` NY New York including migration
[bc5c0b47] IMP `l10n_us_hr_payroll` for Nebraska 13.0
[6f3120f8] IMP `l10n_us_hr_payroll` Port `l10n_us_sc_hr_payroll` SC South Carolina including migration
[9bee1ce7] IMP `l10n_us_hr_payroll` Port `l10n_us_la_hr_payroll` LA Louisiana including migration
[368a7e59] IMP `l10n_us_hr_payroll` for Indiana 13.0
[c7647d08] IMP `l10n_us_hr_payroll` for New Hampshire 13.0
[a738a0af] IMP `l10n_us_hr_payroll` for New Mexico 13.0
[d2898035] IMP `l10n_us_hr_payroll` Port `l10n_us_ia_hr_payroll` IA Iowa including migration
[acdd3d43] IMP `l10n_us_hr_payroll` for Colorado 13.0
[e1eccfc2] IMP `l10n_us_hr_payroll` Port `l10n_us_de_hr_payroll` DE Delaware including migration
[7b4adef4] IMP `l10n_us_hr_payroll` Port `l10n_us_hi_hr_payroll` HI Hawaii including migration
[28eb5b9d] FIX `l10n_us_hr_payroll` Don't give error on Zero wage in FIT
[498137cb] FIX `l10n_us_hr_payroll` Port `l10n_us_id_hr_payroll` Remove supplier from the Partners..
[8895e59f] FIX `l10n_us_hr_payroll` Port `l10n_us_ca_hr_payroll` Added test case on file.
[0082fce8] IMP `l10n_us_hr_payroll` Port `l10n_us_id_hr_payroll` ID Idaho including migration
[92f6d30c] IMP `l10n_us_hr_payroll` Port `l10n_us_ca_hr_payroll` CA California including migration
[2059172b] IMP `l10n_us_hr_payroll` Port `l10n_us_ct_hr_payroll` CT Connecticut including migration
[dd8f7369] IMP `l10n_us_hr_payroll` Port `l10n_us_al_hr_payroll` AL Alabama including migration
[d5c3e427] IMP `l10n_us_hr_payroll` Port `l10n_us_ak_hr_payroll` AK Alaska including migration
[fbba5b2b] FIX `l10n_us_hr_payroll` Changed SUTA Rate for Illinois 2020.
[18421d01] IMP `l10n_us_hr_payroll` Port `l10n_us_az_hr_payroll` AZ Arizona including migration
[f960d135] IMP `l10n_us_hr_payroll` Port `l10n_us_il_hr_payroll` IL Illinois including migration
[b85e7483] IMP `l10n_us_hr_payroll` Port `l10n_us_ar_hr_payroll` AR Arkansas including migration
[61e9530f] IMP `l10n_us_hr_payroll` Create tax exempt categories for table coverage from IRS Pub. 15-B
[38decf71] IMP `l10n_us_hr_payroll` Port `l10n_us_mn_hr_payroll` MN Minnesota including migration
[2c9dca19] IMP `l10n_us_hr_payroll` Port `l10n_us_mi_hr_payroll` MI Michigan including migration
[e175ecbb] IMP `l10n_us_hr_payroll` Port `l10n_us_nc_hr_payroll` NC North Carolina including migration
[db689da4] IMP `l10n_us_hr_payroll` Port `l10n_us_nj_hr_payroll` NJ New Jersey including migration
[130ce65c] IMP `l10n_us_hr_payroll` Add MO Missouri (unemployment, income tax)
[4d4fcd45] IMP `l10n_us_hr_payroll` Use the raw ER rate for Washington LNI (instead of the combined rate and removing EE portion)
[45fb9682] FIX `l10n_us_hr_payroll` Missing Parent Category and Code not matching pattern.
[3ae7b859] IMP `l10n_us_hr_payroll` Refactor to simply tax exempt deductions.
[30eafd14] IMP `l10n_us_hr_payroll` Add MS Mississippi (unemployment, income tax)
[2f7e7b96] IMP `l10n_us_hr_payroll` Add GA Georgia (unemployment, income tax)
[3d79ed81] IMP `l10n_us_hr_payroll` Add form name in Virginia's state box.
[2e6c7050] IMP `l10n_us_hr_payroll` Add VA Virginia (unemployment, income tax)
[8ae58731] IMP `l10n_us_hr_payroll` Add TX Texas (unemployment, OA, ETIA)
[f83bf47c] IMP `l10n_us_hr_payroll` Add WA Washington (unemployment, lni, fml)
[1d661f8d] IMP `l10n_us_hr_payroll` Add OH Ohio (unemployment, income tax)
[edbc8c59] IMP `l10n_us_hr_payroll` Add MT Montana (unemployment (with AFT), income tax)
[dfe38521] IMP `l10n_us_hr_payroll` Implement generic state income tax exempt and additional fields.  Include in PA Tests and State Form section.
[900bc138] IMP `l10n_us_hr_payroll` Add Generic SIT Category and method, add PA Pennsylvania (unemployment (ER, EE), income tax)
[dcafce90] IMP `l10n_us_hr_payroll` Refactor SUTA tests into generic test. (Reworked Florida 2020) (+1 squashed commit)
Squashed commits:
[667cc8c4] IMP `l10n_us_hr_payroll` Add Generic SUTA Category and method, add FL Florida (unemployment, no income tax)
This commit is contained in:
Jared Kipe
2020-01-07 07:52:41 -08:00
parent 5c7c9e6397
commit be1fd5c8d2
184 changed files with 19772 additions and 57 deletions

View File

@@ -0,0 +1 @@
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.

View File

@@ -0,0 +1,80 @@
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
from .general import _state_applies, sit_wage
def al_alabama_state_income_withholding(payslip, categories, worked_days, inputs):
"""
Returns SIT eligible wage and rate.
:return: result, result_rate (wage, percent)
"""
state_code = 'AL'
if not _state_applies(payslip, state_code):
return 0.0, 0.0
# Determine Wage
wage = sit_wage(payslip, categories)
if not wage:
return 0.0, 0.0
exemptions = payslip.contract_id.us_payroll_config_value('al_a4_sit_exemptions')
if not exemptions:
return 0.0, 0.0
personal_exempt = payslip.contract_id.us_payroll_config_value('state_income_tax_exempt')
if personal_exempt:
return 0.0, 0.0
pay_periods = payslip.dict.get_pay_periods_in_year()
additional = payslip.contract_id.us_payroll_config_value('state_income_tax_additional_withholding')
tax_table = payslip.rule_parameter('us_al_sit_tax_rate')
dependent_rate = payslip.rule_parameter('us_al_sit_dependent_rate')
standard_deduction = payslip.rule_parameter('us_al_sit_standard_deduction_rate').get(exemptions, 0.0)
personal_exemption = payslip.rule_parameter('us_al_sit_personal_exemption_rate').get(exemptions, 0.0)
dependent = payslip.contract_id.us_payroll_config_value('al_a4_sit_dependents')
fed_withholding = categories.EE_US_941_FIT
annual_wage = wage * pay_periods
standard_deduction_amt = 0.0
personal_exemption_amt = 0.0
dependent_amt = 0.0
withholding = 0.0
if standard_deduction:
row = standard_deduction
last_amt = 0.0
for data in row:
if annual_wage < float(data[0]):
if len(data) > 3:
increment_count = (- (wage - last_amt) // data[3])
standard_deduction_amt = data[1] - (increment_count * data[2])
else:
standard_deduction_amt = data[1]
else:
last_amt = data[0]
after_deduction = annual_wage - standard_deduction_amt
after_fed_withholding = (fed_withholding * pay_periods) + after_deduction
if not personal_exempt:
personal_exemption_amt = personal_exemption
after_personal_exemption = after_fed_withholding - personal_exemption_amt
for row in dependent_rate:
if annual_wage < float(row[1]):
dependent_amt = row[0] * dependent
break
taxable_amount = after_personal_exemption - dependent_amt
last = 0.0
tax_table = tax_table['M'] if exemptions == 'M' else tax_table['0']
for row in tax_table:
if taxable_amount < float(row[0]):
withholding = withholding + ((taxable_amount - last) * (row[1] / 100))
break
withholding = withholding + ((row[0] - last) * (row[1] / 100))
last = row[0]
if withholding < 0.0:
withholding = 0.0
withholding /= pay_periods
withholding += additional
return wage, -((withholding / wage) * 100.0)

View File

@@ -0,0 +1,47 @@
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
from .general import _state_applies, sit_wage
def ar_arkansas_state_income_withholding(payslip, categories, worked_days, inputs):
"""
Returns SIT eligible wage and rate.
:return: result, result_rate (wage, percent)
"""
state_code = 'AR'
if not _state_applies(payslip, state_code):
return 0.0, 0.0
if payslip.contract_id.us_payroll_config_value('state_income_tax_exempt'):
return 0.0, 0.0
# Determine Wage
wage = sit_wage(payslip, categories)
if not wage:
return 0.0, 0.0
pay_periods = payslip.dict.get_pay_periods_in_year()
additional = payslip.contract_id.us_payroll_config_value('state_income_tax_additional_withholding')
sit_tax_rate = payslip.rule_parameter('us_ar_sit_tax_rate')
standard_deduction = payslip.rule_parameter('us_ar_sit_standard_deduction_rate')
allowances = payslip.contract_id.us_payroll_config_value('ar_ar4ec_sit_allowances')
allowances_amt = allowances * 26.0
taxable_income = (wage * pay_periods) - standard_deduction
if taxable_income < 87001.0:
taxable_income = (taxable_income // 50) * 50.0 + 50.0
withholding = 0.0
for row in sit_tax_rate:
cap, rate, adjust_amount = row
cap = float(cap)
if cap > taxable_income:
withholding = (((rate / 100.0) * taxable_income) - adjust_amount) - allowances_amt
break
# In case withholding or taxable_income is negative
withholding = max(withholding, 0.0)
withholding = round(withholding / pay_periods)
withholding += additional
return wage, -((withholding / wage) * 100.0)

View File

@@ -0,0 +1,35 @@
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
from .general import _state_applies, sit_wage
def az_arizona_state_income_withholding(payslip, categories, worked_days, inputs):
"""
Returns SIT eligible wage and rate.
WAGE = GROSS + DED_FIT_EXEMPT
:return: result, result_rate (wage, percent)
"""
state_code = 'AZ'
if not _state_applies(payslip, state_code):
return 0.0, 0.0
# Determine Wage
wage = sit_wage(payslip, categories)
if not wage:
return 0.0, 0.0
schedule_pay = payslip.contract_id.schedule_pay
additional = payslip.contract_id.us_payroll_config_value('state_income_tax_additional_withholding')
withholding_percent = payslip.contract_id.us_payroll_config_value('az_a4_sit_withholding_percentage')
if withholding_percent <= 0.0:
return 0.0, 0.0
wh_percentage = withholding_percent / 100.0
withholding = wage * wh_percentage
if withholding < 0.0:
withholding = 0.0
withholding += additional
return wage, -((withholding / wage) * 100.0)

View File

@@ -0,0 +1,98 @@
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
from .general import _state_applies, sit_wage
MAX_ALLOWANCES = 10
def ca_california_state_income_withholding(payslip, categories, worked_days, inputs):
"""
Returns SIT eligible wage and rate.
:return: result, result_rate (wage, percent)
"""
state_code = 'CA'
if not _state_applies(payslip, state_code):
return 0.0, 0.0
# Determine Wage
wage = sit_wage(payslip, categories)
if not wage:
return 0.0, 0.0
filing_status = payslip.contract_id.us_payroll_config_value('ca_de4_sit_filing_status')
if not filing_status:
return 0.0, 0.0
schedule_pay = payslip.contract_id.schedule_pay
additional = payslip.contract_id.us_payroll_config_value('state_income_tax_additional_withholding')
sit_allowances = payslip.contract_id.us_payroll_config_value('ca_de4_sit_allowances')
additional_allowances = payslip.contract_id.us_payroll_config_value('ca_de4_sit_additional_allowances')
low_income_exemption = payslip.rule_parameter('us_ca_sit_income_exemption_rate')[schedule_pay]
estimated_deduction = payslip.rule_parameter('us_ca_sit_estimated_deduction_rate')[schedule_pay]
tax_table = payslip.rule_parameter('us_ca_sit_tax_rate')[filing_status].get(schedule_pay)
standard_deduction = payslip.rule_parameter('us_ca_sit_standard_deduction_rate')[schedule_pay]
exemption_allowances = payslip.rule_parameter('us_ca_sit_exemption_allowance_rate')[schedule_pay]
low_income = False
if filing_status == 'head_household':
_, _, _, income = low_income_exemption
if wage <= income:
low_income = True
elif filing_status == 'married':
if sit_allowances >= 2:
_, _, income, _ = low_income_exemption
if wage <= income:
low_income = True
else:
_, income, _, _ = low_income_exemption
if wage <= income:
low_income = True
else:
income, _, _, _ = low_income_exemption
if wage <= income:
low_income = True
withholding = 0.0
taxable_wage = wage
if not low_income:
allowance_index = max(additional_allowances - 1, 0)
if additional_allowances > MAX_ALLOWANCES:
deduction = (estimated_deduction[0] * additional_allowances)
taxable_wage -= deduction
elif additional_allowances > 0:
deduction = estimated_deduction[allowance_index]
taxable_wage -= deduction
if filing_status == 'head_household':
_, _, _, deduction = standard_deduction
taxable_wage -= deduction
elif filing_status == 'married':
if sit_allowances >= 2:
_, _, deduction, _ = standard_deduction
taxable_wage -= deduction
else:
_, deduction, _, _ = standard_deduction
taxable_wage -= deduction
else:
deduction, _, _, _ = standard_deduction
taxable_wage -= deduction
over = 0.0
for row in tax_table:
if taxable_wage <= row[0]:
withholding = ((taxable_wage - over) * row[1]) + row[2]
break
over = row[0]
allowance_index = sit_allowances - 1
if sit_allowances > MAX_ALLOWANCES:
deduction = exemption_allowances[0] * sit_allowances
withholding -= deduction
elif sit_allowances > 0:
deduction = exemption_allowances[allowance_index]
withholding -= deduction
withholding += additional
return wage, -((withholding / wage) * 100.0)

View File

@@ -0,0 +1,45 @@
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
from .general import _state_applies, sit_wage
def co_colorado_state_income_withholding(payslip, categories, worked_days, inputs):
"""
Returns SIT eligible wage and rate.
:return: result, result_rate (wage, percent)
"""
state_code = 'CO'
if not _state_applies(payslip, state_code):
return 0.0, 0.0
# Determine Wage
wage = sit_wage(payslip, categories)
if not wage:
return 0.0, 0.0
filing_status = payslip.contract_id.us_payroll_config_value('fed_941_fit_w4_filing_status')
if not filing_status:
return 0.0, 0.0
state_exempt = payslip.contract_id.us_payroll_config_value('state_income_tax_exempt')
if state_exempt:
return 0.0, 0.0
pay_periods = payslip.dict.get_pay_periods_in_year()
additional = payslip.contract_id.us_payroll_config_value('state_income_tax_additional_withholding')
exemption_rate = payslip.rule_parameter('us_co_sit_exemption_rate')
tax_rate = payslip.rule_parameter('us_co_sit_tax_rate')
taxable_income = wage * pay_periods
if filing_status == 'married':
taxable_income -= exemption_rate * 2
else:
taxable_income -= exemption_rate
withholding = taxable_income * (tax_rate / 100)
withholding = max(withholding, 0.0)
withholding = withholding / pay_periods
withholding += additional
return wage, -((withholding / wage) * 100.0)

View File

@@ -0,0 +1,76 @@
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
from .general import _state_applies, sit_wage
def ct_connecticut_state_income_withholding(payslip, categories, worked_days, inputs):
"""
Returns SIT eligible wage and rate.
:return: result, result_rate (wage, percent)
"""
state_code = 'CT'
if not _state_applies(payslip, state_code):
return 0.0, 0.0
# Determine Wage
wage = sit_wage(payslip, categories)
if not wage:
return 0.0, 0.0
pay_periods = payslip.dict.get_pay_periods_in_year()
additional = payslip.contract_id.us_payroll_config_value('state_income_tax_additional_withholding')
withholding_code = payslip.contract_id.us_payroll_config_value('ct_w4na_sit_code')
exemption_table = payslip.rule_parameter('us_ct_sit_personal_exemption_rate').get(withholding_code, [('inf', 0.0)])
initial_tax_tbl = payslip.rule_parameter('us_ct_sit_initial_tax_rate').get(withholding_code, [('inf', 0.0, 0.0)])
tax_table = payslip.rule_parameter('us_ct_sit_tax_rate').get(withholding_code, [('inf', 0.0)])
recapture_table = payslip.rule_parameter('us_ct_sit_recapture_rate').get(withholding_code, [('inf', 0.0)])
decimal_table = payslip.rule_parameter('us_ct_sit_decimal_rate').get(withholding_code, [('inf', 0.0)])
annual_wages = wage * pay_periods
personal_exemption = 0.0
for bracket in exemption_table:
if annual_wages <= float(bracket[0]):
personal_exemption = bracket[1]
break
withholding = 0.0
taxable_income = annual_wages - personal_exemption
if taxable_income < 0.0:
taxable_income = 0.0
if taxable_income:
initial_tax = 0.0
last = 0.0
for bracket in initial_tax_tbl:
if taxable_income <= float(bracket[0]):
initial_tax = bracket[1] + ((bracket[2] / 100.0) * (taxable_income - last))
break
last = bracket[0]
tax_add_back = 0.0
for bracket in tax_table:
if annual_wages <= float(bracket[0]):
tax_add_back = bracket[1]
break
recapture_amount = 0.0
for bracket in recapture_table:
if annual_wages <= float(bracket[0]):
recapture_amount = bracket[1]
break
withholding = initial_tax + tax_add_back + recapture_amount
decimal_amount = 1.0
for bracket in decimal_table:
if annual_wages <= float(bracket[0]):
decimal_amount= bracket[1]
break
withholding = withholding * (1.00 - decimal_amount)
if withholding < 0.0:
withholding = 0.0
withholding /= pay_periods
withholding += additional
return wage, -((withholding / wage) * 100.0)

View File

@@ -0,0 +1,49 @@
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
from .general import _state_applies, sit_wage
def de_delaware_state_income_withholding(payslip, categories, worked_days, inputs):
"""
Returns SIT eligible wage and rate.
:return: result, result_rate (wage, percent)
"""
state_code = 'DE'
if not _state_applies(payslip, state_code):
return 0.0, 0.0
# Determine Wage
wage = sit_wage(payslip, categories)
if not wage:
return 0.0, 0.0
filing_status = payslip.contract_id.us_payroll_config_value('de_w4_sit_filing_status')
if not filing_status:
return 0.0, 0.0
pay_periods = payslip.dict.get_pay_periods_in_year()
additional = payslip.contract_id.us_payroll_config_value('state_income_tax_additional_withholding')
tax_table = payslip.rule_parameter('us_de_sit_tax_rate')
personal_exemption = payslip.rule_parameter('us_de_sit_personal_exemption_rate')
allowances = payslip.contract_id.us_payroll_config_value('de_w4_sit_dependent')
standard_deduction = payslip.rule_parameter('us_de_sit_standard_deduction_rate')
taxable_income = wage * pay_periods
if filing_status == 'single':
taxable_income -= standard_deduction
else:
taxable_income -= standard_deduction * 2
withholding = 0.0
last = 0.0
for row in tax_table:
if taxable_income <= float(row[0]):
withholding = (row[1] + ((row[2] / 100.0) * (taxable_income - last)) - (allowances * personal_exemption))
break
last = row[0]
withholding = max(withholding, 0.0)
withholding = withholding / pay_periods
withholding += additional
return wage, -((withholding / wage) * 100.0)

View File

@@ -0,0 +1,51 @@
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
from .general import _state_applies, sit_wage
def ga_georgia_state_income_withholding(payslip, categories, worked_days, inputs):
"""
Returns SIT eligible wage and rate.
:return: result, result_rate (wage, percent)
"""
state_code = 'GA'
if not _state_applies(payslip, state_code):
return 0.0, 0.0
ga_filing_status = payslip.contract_id.us_payroll_config_value('ga_g4_sit_filing_status')
if not ga_filing_status:
return 0.0, 0.0
# Determine Wage
wage = sit_wage(payslip, categories)
if not wage:
return 0.0, 0.0
schedule_pay = payslip.contract_id.schedule_pay
additional = payslip.contract_id.us_payroll_config_value('state_income_tax_additional_withholding')
dependent_allowances = payslip.contract_id.us_payroll_config_value('ga_g4_sit_dependent_allowances')
additional_allowances = payslip.contract_id.us_payroll_config_value('ga_g4_sit_additional_allowances')
dependent_allowance_rate = payslip.rule_parameter('us_ga_sit_dependent_allowance_rate').get(schedule_pay)
personal_allowance = payslip.rule_parameter('us_ga_sit_personal_allowance').get(ga_filing_status, {}).get(schedule_pay)
deduction = payslip.rule_parameter('us_ga_sit_deduction').get(ga_filing_status, {}).get(schedule_pay)
withholding_rate = payslip.rule_parameter('us_ga_sit_rate').get(ga_filing_status, {}).get(schedule_pay)
if not all((dependent_allowance_rate, personal_allowance, deduction, withholding_rate)):
return 0.0, 0.0
after_standard_deduction = wage - deduction
allowances = dependent_allowances + additional_allowances
working_wages = after_standard_deduction - (personal_allowance + (allowances * dependent_allowance_rate))
withholding = 0.0
if working_wages > 0.0:
prior_row_base = 0.0
for row in withholding_rate:
wage_base, base, rate = row
wage_base = float(wage_base)
if working_wages < wage_base:
withholding = base + ((working_wages - prior_row_base) * rate / 100.0)
break
prior_row_base = wage_base
withholding += additional
return wage, -((withholding / wage) * 100.0)

View File

@@ -0,0 +1,131 @@
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
from odoo.exceptions import UserError
from ..federal.fed_940 import futa_wage, futa_wage_ytd
from ..federal.fed_941 import fit_wage, fit_wage_ytd
# import logging
# _logger = logging.getLogger(__name__)
suta_wage = futa_wage
suta_wage_ytd = futa_wage_ytd
sit_wage = fit_wage
sit_wage_ytd = fit_wage_ytd
def _state_applies(payslip, state_code):
return state_code == payslip.contract_id.us_payroll_config_value('state_code')
# Export for eval context
is_us_state = _state_applies
def _general_rate(payslip, wage, ytd_wage, wage_base=None, wage_start=None, rate=None):
"""
Function parameters:
wage_base, wage_start, rate can either be strings (rule_parameters) or floats
:return: result, result_rate(wage, percent)
"""
# Resolve parameters. On exception, return (probably missing a year, would rather not have exception)
if wage_base and isinstance(wage_base, str):
try:
wage_base = payslip.rule_parameter(wage_base)
except (KeyError, UserError):
return 0.0, 0.0
if wage_start and isinstance(wage_start, str):
try:
wage_start = payslip.rule_parameter(wage_start)
except (KeyError, UserError):
return 0.0, 0.0
if rate and isinstance(rate, str):
try:
rate = payslip.rule_parameter(rate)
except (KeyError, UserError):
return 0.0, 0.0
if not rate:
return 0.0, 0.0
else:
# Rate assumed positive percentage!
rate = -rate
if wage_base:
remaining = wage_base - ytd_wage
if remaining < 0.0:
result = 0.0
elif remaining < wage:
result = remaining
else:
result = wage
# _logger.warn(' wage_base method result: ' + str(result) + ' rate: ' + str(rate))
return result, rate
if wage_start:
if ytd_wage >= wage_start:
# _logger.warn(' wage_start 1 method result: ' + str(wage) + ' rate: ' + str(rate))
return wage, rate
if ytd_wage + wage <= wage_start:
# _logger.warn(' wage_start 2 method result: ' + str(0.0) + ' rate: ' + str(0.0))
return 0.0, 0.0
# _logger.warn(' wage_start 3 method result: ' + str((wage - (wage_start - ytd_wage))) + ' rate: ' + str(rate))
return (wage - (wage_start - ytd_wage)), rate
# If the wage doesn't have a start or a base
# _logger.warn(' basic result: ' + str(wage) + ' rate: ' + str(rate))
return wage, rate
def general_state_unemployment(payslip, categories, worked_days, inputs, wage_base=None, wage_start=None, rate=None, state_code=None):
"""
Returns SUTA eligible wage and rate.
WAGE = GROSS + DED_FUTA_EXEMPT
The contract's `futa_type` determines if SUTA should be collected.
:return: result, result_rate(wage, percent)
"""
if not _state_applies(payslip, state_code):
return 0.0, 0.0
# Determine Eligible.
if payslip.contract_id.futa_type in (payslip.contract_id.FUTA_TYPE_EXEMPT, payslip.contract_id.FUTA_TYPE_BASIC):
return 0.0, 0.0
# Determine Wage
wage = suta_wage(payslip, categories)
if not wage:
return 0.0, 0.0
ytd_wage = suta_wage_ytd(payslip, categories)
return _general_rate(payslip, wage, ytd_wage, wage_base=wage_base, wage_start=wage_start, rate=rate)
def general_state_income_withholding(payslip, categories, worked_days, inputs, wage_base=None, wage_start=None, rate=None, state_code=None):
"""
Returns SIT eligible wage and rate.
WAGE = GROSS + DED_FIT_EXEMPT
:return: result, result_rate (wage, percent)
"""
if not _state_applies(payslip, state_code):
return 0.0, 0.0
if payslip.contract_id.us_payroll_config_value('state_income_tax_exempt'):
return 0.0, 0.0
# Determine Wage
ytd_wage = sit_wage_ytd(payslip, categories)
wage = sit_wage(payslip, categories)
result, result_rate = _general_rate(payslip, wage, ytd_wage, wage_base=wage_base, wage_start=wage_start, rate=rate)
additional = payslip.contract_id.us_payroll_config_value('state_income_tax_additional_withholding')
if additional:
tax = result * (result_rate / 100.0)
tax -= additional # assumed result_rate is negative and that the 'additional' should increase it.
return result, ((tax / result) * 100.0)
return result, result_rate

View File

@@ -0,0 +1,43 @@
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
from .general import _state_applies, sit_wage
def hi_hawaii_state_income_withholding(payslip, categories, worked_days, inputs):
"""
Returns SIT eligible wage and rate.
:return: result, result_rate (wage, percent)
"""
state_code = 'HI'
if not _state_applies(payslip, state_code):
return 0.0, 0.0
# Determine Wage
wage = sit_wage(payslip, categories)
if not wage:
return 0.0, 0.0
filing_status = payslip.contract_id.us_payroll_config_value('hi_hw4_sit_filing_status')
if not filing_status:
return 0.0, 0.0
pay_periods = payslip.dict.get_pay_periods_in_year()
additional = payslip.contract_id.us_payroll_config_value('state_income_tax_additional_withholding')
allowances = payslip.contract_id.us_payroll_config_value('hi_hw4_sit_allowances')
tax_table = payslip.rule_parameter('us_hi_sit_tax_rate')[filing_status]
personal_exemption = payslip.rule_parameter('us_hi_sit_personal_exemption_rate')
taxable_income = (wage * pay_periods) - (personal_exemption * allowances)
withholding = 0.0
last = 0.0
for row in tax_table:
if taxable_income <= float(row[0]):
withholding = row[1] + ((row[2] / 100.0) * (taxable_income - last))
break
last = row[0]
withholding = max(withholding, 0.0)
withholding = withholding / pay_periods
withholding += additional
return wage, -((withholding / wage) * 100.0)

View File

@@ -0,0 +1,48 @@
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
from .general import _state_applies, sit_wage
def ia_iowa_state_income_withholding(payslip, categories, worked_days, inputs):
"""
Returns SIT eligible wage and rate.
:return: result, result_rate (wage, percent)
"""
state_code = 'IA'
if not _state_applies(payslip, state_code):
return 0.0, 0.0
if payslip.contract_id.us_payroll_config_value('state_income_tax_exempt'):
return 0.0, 0.0
# Determine Wage
wage = sit_wage(payslip, categories)
if not wage:
return 0.0, 0.0
schedule_pay = payslip.contract_id.schedule_pay
fed_withholding = categories.EE_US_941_FIT
additional = payslip.contract_id.us_payroll_config_value('state_income_tax_additional_withholding')
allowances = payslip.contract_id.us_payroll_config_value('ia_w4_sit_allowances')
standard_deduction = payslip.rule_parameter('us_ia_sit_standard_deduction_rate')[schedule_pay]
tax_table = payslip.rule_parameter('us_ia_sit_tax_rate')[schedule_pay]
deduction_per_allowance = payslip.rule_parameter('us_ia_sit_deduction_allowance_rate')[schedule_pay]
t1 = wage + fed_withholding
standard_deduction_amt = standard_deduction[0] if allowances < 2 else standard_deduction[1]
t2 = t1 - standard_deduction_amt
t3 = 0.0
last = 0.0
for row in tax_table:
cap, rate, flat_fee = row
if float(cap) > float(t2):
taxed_amount = t2 - last
t3 = flat_fee + (rate * taxed_amount)
break
last = cap
withholding = t3 - (deduction_per_allowance * allowances)
withholding = max(withholding, 0.0)
withholding += additional
return wage, -((withholding / wage) * 100.0)

View File

@@ -0,0 +1,41 @@
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
from .general import _state_applies, sit_wage
def id_idaho_state_income_withholding(payslip, categories, worked_days, inputs):
"""
Returns SIT eligible wage and rate.
:return: result, result_rate (wage, percent)
"""
state_code = 'ID'
if not _state_applies(payslip, state_code):
return 0.0, 0.0
# Determine Wage
wage = sit_wage(payslip, categories)
if not wage:
return 0.0, 0.0
filing_status = payslip.contract_id.us_payroll_config_value('id_w4_sit_filing_status')
if not filing_status:
return 0.0, 0.0
schedule_pay = payslip.contract_id.schedule_pay
allowances = payslip.contract_id.us_payroll_config_value('id_w4_sit_allowances')
ictcat_table = payslip.rule_parameter('us_id_sit_ictcat_rate')[schedule_pay]
tax_table = payslip.rule_parameter('us_id_sit_tax_rate')[filing_status].get(schedule_pay)
taxable_income = wage - (ictcat_table * allowances)
withholding = 0.0
last = 0.0
for row in tax_table:
if taxable_income <= float(row[0]):
withholding = row[1] + ((row[2] / 100.0) * (taxable_income - last))
break
last = row[0]
withholding = max(withholding, 0.0)
withholding = round(withholding)
return wage, -((withholding / wage) * 100.0)

View File

@@ -0,0 +1,35 @@
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
from .general import _state_applies, sit_wage
def il_illinois_state_income_withholding(payslip, categories, worked_days, inputs):
"""
Returns SIT eligible wage and rate.
WAGE = GROSS + DED_FIT_EXEMPT
:return: result, result_rate (wage, percent)
"""
state_code = 'IL'
if not _state_applies(payslip, state_code):
return 0.0, 0.0
# Determine Wage
wage = sit_wage(payslip, categories)
if not wage:
return 0.0, 0.0
pay_periods = payslip.dict.get_pay_periods_in_year()
additional = payslip.contract_id.us_payroll_config_value('state_income_tax_additional_withholding')
basic_allowances_rate = payslip.rule_parameter('us_il_sit_basic_allowances_rate')
additional_allowances_rate = payslip.rule_parameter('us_il_sit_additional_allowances_rate')
basic_allowances = payslip.contract_id.us_payroll_config_value('il_w4_sit_basic_allowances')
additional_allowances = payslip.contract_id.us_payroll_config_value('il_w4_sit_additional_allowances')
rate = 4.95 / 100.0
withholding = rate * (wage - (((basic_allowances * basic_allowances_rate) + (additional_allowances *
additional_allowances_rate)) / pay_periods))
if withholding < 0.0:
withholding = 0.0
withholding += additional
return wage, -((withholding / wage) * 100.0)

View File

@@ -0,0 +1,34 @@
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
from .general import _state_applies, sit_wage
def in_indiana_state_income_withholding(payslip, categories, worked_days, inputs):
"""
Returns SIT eligible wage and rate.
:return: result, result_rate (wage, percent)
"""
state_code = 'IN'
if not _state_applies(payslip, state_code):
return 0.0, 0.0
# Determine Wage
wage = sit_wage(payslip, categories)
if not wage:
return 0.0, 0.0
schedule_pay = payslip.contract_id.schedule_pay
additional = payslip.contract_id.us_payroll_config_value('state_income_tax_additional_withholding')
personal_exemption = payslip.contract_id.us_payroll_config_value('in_w4_sit_personal_exemption')
personal_exemption_rate = payslip.rule_parameter('us_in_sit_personal_exemption_rate')[schedule_pay][personal_exemption - 1]
dependent_exemption = payslip.contract_id.us_payroll_config_value('in_w4_sit_dependent_exemption')
dependent_exemption_rate = payslip.rule_parameter('us_in_sit_dependent_exemption_rate')[schedule_pay][dependent_exemption - 1]
income_tax_rate = payslip.rule_parameter('us_in_suta_income_rate')
taxable_income = wage - (personal_exemption_rate + dependent_exemption_rate)
withholding = taxable_income * (income_tax_rate / 100.0)
withholding = max(withholding, 0.0)
withholding += additional
return wage, -((withholding / wage) * 100.0)

View File

@@ -0,0 +1,44 @@
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
from .general import _state_applies, sit_wage
def ks_kansas_state_income_withholding(payslip, categories, worked_days, inputs):
"""
Returns SIT eligible wage and rate.
:return: result, result_rate (wage, percent)
"""
state_code = 'KS'
if not _state_applies(payslip, state_code):
return 0.0, 0.0
# Determine Wage
wage = sit_wage(payslip, categories)
if not wage:
return 0.0, 0.0
filing_status = payslip.contract_id.us_payroll_config_value('ks_k4_sit_filing_status')
if not filing_status:
return 0.0, 0.0
schedule_pay = payslip.contract_id.schedule_pay
additional = payslip.contract_id.us_payroll_config_value('state_income_tax_additional_withholding')
allowances = payslip.contract_id.us_payroll_config_value('ks_k4_sit_allowances')
allowances_amt = payslip.rule_parameter('us_ks_sit_allowances_rate')[schedule_pay]
tax_table = payslip.rule_parameter('us_ks_sit_tax_rate')[filing_status].get(schedule_pay)
taxable_income = wage - (allowances * allowances_amt)
withholding = 0.0
last = 0.0
for row in tax_table:
amt, rate, flat_fee = row
if wage <= float(amt):
withholding = ((taxable_income - last) * (rate / 100)) + flat_fee
break
last = amt
withholding = max(withholding, 0.0)
withholding += additional
withholding = round(withholding)
return wage, -((withholding / wage) * 100.0)

View File

@@ -0,0 +1,32 @@
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
from .general import _state_applies, sit_wage
def ky_kentucky_state_income_withholding(payslip, categories, worked_days, inputs):
"""
Returns SIT eligible wage and rate.
:return: result, result_rate (wage, percent)
"""
state_code = 'KY'
if not _state_applies(payslip, state_code):
return 0.0, 0.0
# Determine Wage
wage = sit_wage(payslip, categories)
if not wage:
return 0.0, 0.0
pay_periods = payslip.dict.get_pay_periods_in_year()
additional = payslip.contract_id.us_payroll_config_value('state_income_tax_additional_withholding')
tax_rate = payslip.rule_parameter('us_ky_sit_tax_rate')
standard_deduction = payslip.rule_parameter('us_ky_sit_standard_deduction_rate')
taxable_income = (wage * pay_periods) - standard_deduction
withholding = taxable_income * (tax_rate / 100)
withholding = max(withholding, 0.0)
withholding /= pay_periods
withholding += additional
return wage, -((withholding / wage) * 100.0)

View File

@@ -0,0 +1,62 @@
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
from .general import _state_applies, sit_wage
def la_louisiana_state_income_withholding(payslip, categories, worked_days, inputs):
"""
Returns SIT eligible wage and rate.
:return: result, result_rate (wage, percent)
"""
state_code = 'LA'
if not _state_applies(payslip, state_code):
return 0.0, 0.0
# Determine Wage
wage = sit_wage(payslip, categories)
if not wage:
return 0.0, 0.0
filing_status = payslip.contract_id.us_payroll_config_value('la_l4_sit_filing_status')
if not filing_status:
return 0.0, 0.0
pay_periods = payslip.dict.get_pay_periods_in_year()
personal_exemptions = payslip.contract_id.us_payroll_config_value('la_l4_sit_exemptions')
additional = payslip.contract_id.us_payroll_config_value('state_income_tax_additional_withholding')
dependent_exemptions = payslip.contract_id.us_payroll_config_value('la_l4_sit_dependents')
tax_table = payslip.rule_parameter('us_la_sit_tax_rate')[filing_status]
exemption_rate = payslip.rule_parameter('us_la_sit_personal_exemption_rate')
dependent_rate = payslip.rule_parameter('us_la_sit_dependent_rate')
annual_wage = wage * pay_periods
effect_cap = 0.0
multiplier = 0.0
if filing_status == 'single':
effect_cap = 12500.00
multiplier = 1.60
elif filing_status == 'married':
effect_cap = 25000.00
multiplier = 1.65
after_credits_under = (2.100 / 100) * (((personal_exemptions * exemption_rate) +
(dependent_exemptions * dependent_rate)) / pay_periods)
after_credits_over = 0.00
if after_credits_under > effect_cap:
after_credits_under = effect_cap
after_credits_over_check = ((personal_exemptions * exemption_rate) + (dependent_exemptions * dependent_rate)) - effect_cap
after_credits_over = (multiplier / 100.00) * (after_credits_over_check / pay_periods) if after_credits_over_check > 0 else 0.00
withholding = 0.0
last = 0.0
for amt, rate in tax_table:
withholding = withholding + ((rate / 100.0) * (wage - (last / pay_periods)))
if annual_wage <= float(amt):
break
last = amt
withholding = withholding - (after_credits_under + after_credits_over)
withholding = round(withholding, 2)
withholding += additional
return wage, -((withholding / wage) * 100.0)

View File

@@ -0,0 +1,62 @@
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
from .general import _state_applies, sit_wage
def me_maine_state_income_withholding(payslip, categories, worked_days, inputs):
"""
Returns SIT eligible wage and rate.
WAGE = GROSS + DED_FIT_EXEMPT
:return: result, result_rate (wage, percent)
"""
state_code = 'ME'
if not _state_applies(payslip, state_code):
return 0.0, 0.0
# Determine Wage
wage = sit_wage(payslip, categories)
if not wage:
return 0.0, 0.0
filing_status = payslip.contract_id.us_payroll_config_value('me_w4me_sit_filing_status')
if not filing_status:
return 0.0, 0.0
exempt = payslip.contract_id.us_payroll_config_value('state_income_tax_exempt')
if exempt:
return 0.0, 0.0
pay_periods = payslip.dict.get_pay_periods_in_year()
additional = payslip.contract_id.us_payroll_config_value('state_income_tax_additional_withholding')
allowances = payslip.contract_id.us_payroll_config_value('me_w4me_sit_allowances')
tax_rate = payslip.rule_parameter('us_me_sit_tax_rate')[filing_status]
personal_exemption = payslip.rule_parameter('us_me_sit_personal_exemption_rate')
standard_deduction = payslip.rule_parameter('us_me_sit_standard_deduction_rate')[filing_status]
taxable_income = wage * pay_periods
exemption_amt = allowances * personal_exemption
last = 0.0
standard_deduction_amt = 0.0
for row in standard_deduction:
amt, flat_amt = row
if taxable_income < 82900:
standard_deduction_amt = flat_amt
break
elif taxable_income < amt:
standard_deduction_amt = last * (amt - taxable_income) / flat_amt
break
last = flat_amt
annual_income = taxable_income - (exemption_amt + standard_deduction_amt)
withholding = 0.0
for row in tax_rate:
amt, flat_fee, rate = row
if annual_income < float(amt):
withholding = ((annual_income - last) * (rate / 100)) + flat_fee
break
last = amt
withholding = max(withholding, 0.0)
withholding = round(withholding / pay_periods)
withholding += additional
return wage, -((withholding / wage) * 100.0)

View File

@@ -0,0 +1,35 @@
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
from .general import _state_applies, sit_wage
def mi_michigan_state_income_withholding(payslip, categories, worked_days, inputs):
"""
Returns SIT eligible wage and rate.
WAGE = GROSS + DED_FIT_EXEMPT
:return: result, result_rate (wage, percent)
"""
state_code = 'MI'
if not _state_applies(payslip, state_code):
return 0.0, 0.0
if payslip.contract_id.us_payroll_config_value('state_income_tax_exempt'):
return 0.0, 0.0
# Determine Wage
wage = sit_wage(payslip, categories)
if not wage:
return 0.0, 0.0
pay_periods = payslip.dict.get_pay_periods_in_year()
additional = payslip.contract_id.us_payroll_config_value('state_income_tax_additional_withholding')
exemption_rate = payslip.rule_parameter('us_mi_sit_exemption_rate')
exemption = payslip.contract_id.us_payroll_config_value('mi_w4_sit_exemptions')
annual_exemption = (exemption * exemption_rate) / pay_periods
withholding = ((wage - annual_exemption) * 0.0425)
if withholding < 0.0:
withholding = 0.0
withholding += additional
return wage, -((withholding / wage) * 100.0)

View File

@@ -0,0 +1,44 @@
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
from .general import _state_applies, sit_wage
def mn_minnesota_state_income_withholding(payslip, categories, worked_days, inputs):
"""
Returns SIT eligible wage and rate.
WAGE = GROSS + DED_FIT_EXEMPT
:return: result, result_rate (wage, percent)
"""
state_code = 'MN'
if not _state_applies(payslip, state_code):
return 0.0, 0.0
filing_status = payslip.contract_id.us_payroll_config_value('mn_w4mn_sit_filing_status')
if not filing_status:
return 0.0, 0.0
# Determine Wage
wage = sit_wage(payslip, categories)
if not wage:
return 0.0, 0.0
pay_periods = payslip.dict.get_pay_periods_in_year()
additional = payslip.contract_id.us_payroll_config_value('state_income_tax_additional_withholding')
sit_tax_rate = payslip.rule_parameter('us_mn_sit_tax_rate')[filing_status]
allowances_rate = payslip.rule_parameter('us_mn_sit_allowances_rate')
allowances = payslip.contract_id.us_payroll_config_value('mn_w4mn_sit_allowances')
taxable_income = (wage * pay_periods) - (allowances * allowances_rate)
withholding = 0.0
for row in sit_tax_rate:
cap, subtract_amt, rate, flat_fee = row
cap = float(cap)
if cap > taxable_income:
withholding = ((rate / 100.00) * (taxable_income - subtract_amt)) + flat_fee
break
withholding = round(withholding / pay_periods)
if withholding < 0.0:
withholding = 0.0
withholding += additional
return wage, -((withholding / wage) * 100.0)

View File

@@ -0,0 +1,53 @@
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
from .general import _state_applies, sit_wage
def mo_missouri_state_income_withholding(payslip, categories, worked_days, inputs):
"""
Returns SIT eligible wage and rate.
WAGE = GROSS + DED_FIT_EXEMPT
:return: result, result_rate (wage, percent)
"""
state_code = 'MO'
if not _state_applies(payslip, state_code):
return 0.0, 0.0
filing_status = payslip.contract_id.us_payroll_config_value('mo_mow4_sit_filing_status')
if not filing_status:
return 0.0, 0.0
# Determine Wage
wage = sit_wage(payslip, categories)
if not wage:
return 0.0, 0.0
reduced_withholding = payslip.contract_id.us_payroll_config_value('mo_mow4_sit_withholding')
if reduced_withholding:
return wage, -((reduced_withholding / wage) * 100.0)
pay_periods = payslip.dict.get_pay_periods_in_year()
additional = payslip.contract_id.us_payroll_config_value('state_income_tax_additional_withholding')
sit_table = payslip.rule_parameter('us_mo_sit_rate')
deduction = payslip.rule_parameter('us_mo_sit_deduction')[filing_status]
gross_taxable_income = wage * pay_periods
gross_taxable_income -= deduction
remaining_taxable_income = gross_taxable_income
withholding = 0.0
for amt, rate in sit_table:
amt = float(amt)
rate = rate / 100.0
if (remaining_taxable_income - amt) > 0.0 or (remaining_taxable_income - amt) == 0.0:
withholding += rate * amt
else:
withholding += rate * remaining_taxable_income
break
remaining_taxable_income = remaining_taxable_income - amt
withholding /= pay_periods
withholding += additional
withholding = round(withholding)
return wage, -((withholding / wage) * 100.0)

View File

@@ -0,0 +1,46 @@
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
from .general import _state_applies, sit_wage
def ms_mississippi_state_income_withholding(payslip, categories, worked_days, inputs):
"""
Returns SIT eligible wage and rate.
WAGE = GROSS + DED_FIT_EXEMPT
:return: result, result_rate (wage, percent)
"""
state_code = 'MS'
if not _state_applies(payslip, state_code):
return 0.0, 0.0
filing_status = payslip.contract_id.us_payroll_config_value('ms_89_350_sit_filing_status')
if not filing_status:
return 0.0, 0.0
# Determine Wage
wage = sit_wage(payslip, categories)
if not wage:
return 0.0, 0.0
pay_periods = payslip.dict.get_pay_periods_in_year()
additional = payslip.contract_id.us_payroll_config_value('state_income_tax_additional_withholding')
exemptions = payslip.contract_id.us_payroll_config_value('ms_89_350_sit_exemption_value')
standard_deduction = payslip.rule_parameter('us_ms_sit_deduction').get(filing_status)
withholding_rate = payslip.rule_parameter('us_ms_sit_rate')
wage_annual = wage * pay_periods
taxable_income = wage_annual - (exemptions + standard_deduction)
if taxable_income <= 0.01:
return wage, 0.0
withholding = 0.0
for row in withholding_rate:
wage_base, base, rate = row
if taxable_income >= wage_base:
withholding = base + ((taxable_income - wage_base) * rate)
break
withholding /= pay_periods
withholding = round(withholding)
withholding += round(additional)
return wage, -((withholding / wage) * 100.0)

View File

@@ -0,0 +1,45 @@
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
from .general import _state_applies, sit_wage
def mt_montana_state_income_withholding(payslip, categories, worked_days, inputs):
"""
Returns SIT eligible wage and rate.
WAGE = GROSS + DED_FIT_EXEMPT
:return: result, result_rate (wage, percent)
"""
state_code = 'MT'
if not _state_applies(payslip, state_code):
return 0.0, 0.0
if payslip.contract_id.us_payroll_config_value('mt_mw4_sit_exempt'):
return 0.0, 0.0
# Determine Wage
wage = sit_wage(payslip, categories)
if not wage:
return 0.0, 0.0
schedule_pay = payslip.contract_id.schedule_pay
additional = payslip.contract_id.us_payroll_config_value('state_income_tax_additional_withholding')
exemptions = payslip.contract_id.us_payroll_config_value('mt_mw4_sit_exemptions')
exemption_rate = payslip.rule_parameter('us_mt_sit_exemption_rate').get(schedule_pay)
withholding_rate = payslip.rule_parameter('us_mt_sit_rate').get(schedule_pay)
if not exemption_rate or not withholding_rate:
return 0.0, 0.0
adjusted_wage = wage - (exemption_rate * (exemptions or 0))
withholding = 0.0
if adjusted_wage > 0.0:
prior_wage_cap = 0.0
for row in withholding_rate:
wage_cap, base, rate = row
wage_cap = float(wage_cap) # e.g. 'inf'
if adjusted_wage < wage_cap:
withholding = round(base + ((rate / 100.0) * (adjusted_wage - prior_wage_cap)))
break
prior_wage_cap = wage_cap
withholding += additional
return wage, -((withholding / wage) * 100.0)

View File

@@ -0,0 +1,38 @@
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
from .general import _state_applies, sit_wage
def nc_northcarolina_state_income_withholding(payslip, categories, worked_days, inputs):
"""
Returns SIT eligible wage and rate.
WAGE = GROSS + DED_FIT_EXEMPT
:return: result, result_rate (wage, percent)
"""
state_code = 'NC'
if not _state_applies(payslip, state_code):
return 0.0, 0.0
filing_status = payslip.contract_id.us_payroll_config_value('nc_nc4_sit_filing_status')
if not filing_status:
return 0.0, 0.0
# Determine Wage
wage = sit_wage(payslip, categories)
if not wage:
return 0.0, 0.0
schedule_pay = payslip.contract_id.schedule_pay
additional = payslip.contract_id.us_payroll_config_value('state_income_tax_additional_withholding')
allowances = payslip.contract_id.us_payroll_config_value('nc_nc4_sit_allowances')
allowances_rate = payslip.rule_parameter('us_nc_sit_allowance_rate').get(schedule_pay)['allowance']
deduction = payslip.rule_parameter('us_nc_sit_allowance_rate').get(schedule_pay)['standard_deduction'] if filing_status != 'head_household' else payslip.rule_parameter('us_nc_sit_allowance_rate').get(schedule_pay)['standard_deduction_hh']
taxable_wage = round((wage - (deduction + (allowances * allowances_rate))) * 0.0535)
withholding = 0.0
if taxable_wage < 0.0:
withholding -= taxable_wage
withholding = taxable_wage
withholding += additional
return wage, -((withholding / wage) * 100.0)

View File

@@ -0,0 +1,45 @@
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
from .general import _state_applies, sit_wage
def nd_north_dakota_state_income_withholding(payslip, categories, worked_days, inputs):
"""
Returns SIT eligible wage and rate.
WAGE = GROSS + DED_FIT_EXEMPT
:return: result, result_rate (wage, percent)
"""
state_code = 'ND'
if not _state_applies(payslip, state_code):
return 0.0, 0.0
# Determine Wage
wage = sit_wage(payslip, categories)
if not wage:
return 0.0, 0.0
filing_status = payslip.contract_id.us_payroll_config_value('nd_w4_sit_filing_status')
if not filing_status:
return 0.0, 0.0
schedule_pay = payslip.contract_id.schedule_pay
additional = payslip.contract_id.us_payroll_config_value('state_income_tax_additional_withholding')
allowance = payslip.contract_id.us_payroll_config_value('nd_w4_sit_allowances')
allowance_rate = payslip.rule_parameter('us_nd_sit_allowances_rate')[schedule_pay]
tax_rate = payslip.rule_parameter('us_nd_sit_tax_rate')[filing_status].get(schedule_pay)
taxable_income = wage - (allowance * allowance_rate)
withholding = 0.0
last = 0.0
for row in tax_rate:
amt, flat_fee, rate = row
if taxable_income < float(amt):
withholding = ((taxable_income - last) * (rate / 100)) + flat_fee
break
last = amt
withholding = round(withholding)
withholding = max(withholding, 0.0)
withholding += additional
return wage, -((withholding / wage) * 100.0)

View File

@@ -0,0 +1,49 @@
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
from .general import _state_applies, sit_wage
def ne_nebraska_state_income_withholding(payslip, categories, worked_days, inputs):
"""
Returns SIT eligible wage and rate.
WAGE = GROSS + DED_FIT_EXEMPT
:return: result, result_rate (wage, percent)
"""
state_code = 'NE'
if not _state_applies(payslip, state_code):
return 0.0, 0.0
personal_exempt = payslip.contract_id.us_payroll_config_value('state_income_tax_exempt')
if personal_exempt:
return 0.0, 0.0
# Determine Wage
wage = sit_wage(payslip, categories)
if not wage:
return 0.0, 0.0
filing_status = payslip.contract_id.us_payroll_config_value('ne_w4n_sit_filing_status')
if not filing_status:
return 0.0, 0.0
schedule_pay = payslip.contract_id.schedule_pay
additional = payslip.contract_id.us_payroll_config_value('state_income_tax_additional_withholding')
allowances = payslip.contract_id.us_payroll_config_value('ne_w4n_sit_allowances')
tax_rate = payslip.rule_parameter('us_ne_sit_tax_rate')[filing_status].get(schedule_pay)
sit_allowance = payslip.rule_parameter('us_ne_sit_allowances_rate')[schedule_pay]
allowance_amt = allowances * sit_allowance
taxable_income = wage - allowance_amt
withholding = 0.0
last = 0.0
for row in tax_rate:
amt, flat_fee, rate = row
if taxable_income < float(amt):
withholding = ((taxable_income - last) * (rate / 100)) + flat_fee
break
last = amt
withholding = max(withholding, 0.0)
withholding += additional
return wage, -((withholding / wage) * 100.0)

View File

@@ -0,0 +1,52 @@
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
from .general import _state_applies, sit_wage
def nj_newjersey_state_income_withholding(payslip, categories, worked_days, inputs):
"""
Returns SIT eligible wage and rate.
WAGE = GROSS + DED_FIT_EXEMPT
:return: result, result_rate (wage, percent)
"""
state_code = 'NJ'
if not _state_applies(payslip, state_code):
return 0.0, 0.0
filing_status = payslip.contract_id.us_payroll_config_value('nj_njw4_sit_filing_status')
if not filing_status:
return 0.0, 0.0
# Determine Wage
wage = sit_wage(payslip, categories)
if not wage:
return 0.0, 0.0
allowances = payslip.contract_id.us_payroll_config_value('nj_njw4_sit_allowances')
sit_rate_table_key = payslip.contract_id.us_payroll_config_value('nj_njw4_sit_rate_table')
if not sit_rate_table_key and filing_status in ('single', 'married_joint'):
sit_rate_table_key = 'A'
elif not sit_rate_table_key:
sit_rate_table_key = 'B'
schedule_pay = payslip.contract_id.schedule_pay
additional = payslip.contract_id.us_payroll_config_value('state_income_tax_additional_withholding')
sit_table = payslip.rule_parameter('us_nj_sit_rate')[sit_rate_table_key].get(schedule_pay)
allowance_value = payslip.rule_parameter('us_nj_sit_allowance_rate')[schedule_pay]
if not allowances:
return 0.0, 0.0
gross_taxable_income = wage - (allowance_value * allowances)
withholding = 0.0
prior_wage_base = 0.0
for row in sit_table:
wage_base, base_amt, rate = row
wage_base = float(wage_base)
rate = rate / 100.0
if gross_taxable_income <= wage_base:
withholding = base_amt + ((gross_taxable_income - prior_wage_base) * rate)
break
prior_wage_base = wage_base
withholding += additional
return wage, -((withholding / wage) * 100.0)

View File

@@ -0,0 +1,40 @@
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
from .general import _state_applies, sit_wage
def nm_new_mexico_state_income_withholding(payslip, categories, worked_days, inputs):
"""
Returns SIT eligible wage and rate.
:return: result, result_rate (wage, percent)
"""
state_code = 'NM'
if not _state_applies(payslip, state_code):
return 0.0, 0.0
# Determine Wage
wage = sit_wage(payslip, categories)
if not wage:
return 0.0, 0.0
filing_status = payslip.contract_id.us_payroll_config_value('fed_941_fit_w4_filing_status')
if not filing_status:
return 0.0, 0.0
schedule_pay = payslip.contract_id.schedule_pay
additional = payslip.contract_id.us_payroll_config_value('state_income_tax_additional_withholding')
tax_table = payslip.rule_parameter('us_nm_sit_tax_rate')[filing_status].get(schedule_pay)
taxable_income = wage
withholding = 0.0
last = 0.0
for row in tax_table:
if taxable_income <= float(row[0]):
withholding = row[1] + ((row[2] / 100.0) * (taxable_income - last))
break
last = row[0]
withholding = max(withholding, 0.0)
withholding += additional
return wage, -((withholding / wage) * 100.0)

View File

@@ -0,0 +1,54 @@
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
from .general import _state_applies, sit_wage
def ny_new_york_state_income_withholding(payslip, categories, worked_days, inputs):
"""
Returns SIT eligible wage and rate.
:return: result, result_rate (wage, percent)
"""
state_code = 'NY'
if not _state_applies(payslip, state_code):
return 0.0, 0.0
# Determine Wage
wage = sit_wage(payslip, categories)
if not wage:
return 0.0, 0.0
filing_status = payslip.contract_id.us_payroll_config_value('ny_it2104_sit_filing_status')
if not filing_status:
return 0.0, 0.0
schedule_pay = payslip.contract_id.schedule_pay
additional = payslip.contract_id.us_payroll_config_value('state_income_tax_additional_withholding')
tax_table = payslip.rule_parameter('us_ny_sit_tax_rate')[filing_status].get(schedule_pay)
allowances = payslip.contract_id.us_payroll_config_value('ny_it2104_sit_allowances')
over_10_deduction = payslip.rule_parameter('us_ny_sit_over_10_exemption_rate')[schedule_pay]
deduction_exemption = payslip.rule_parameter('us_ny_sit_deduction_exemption_rate')[filing_status].get(schedule_pay)
if allowances > 10:
if filing_status == 'single':
wage -= over_10_deduction[0] + over_10_deduction[2] * allowances
elif filing_status == 'married':
wage -= over_10_deduction[1] + over_10_deduction[2] * allowances
else:
if filing_status == 'single':
wage -= deduction_exemption[allowances]
elif filing_status == 'married':
wage -= deduction_exemption[allowances]
last = 0.0
withholding = 0.0
for row in tax_table:
amt, rate, flat_fee = row
if wage <= float(amt):
withholding = ((wage - last) * rate) + flat_fee
break
last = amt
withholding = max(withholding, 0.0)
withholding += additional
return wage, -((withholding / wage) * 100.0)

View File

@@ -0,0 +1,47 @@
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
from .general import _state_applies, sit_wage
def oh_ohio_state_income_withholding(payslip, categories, worked_days, inputs):
"""
Returns SIT eligible wage and rate.
WAGE = GROSS + DED_FIT_EXEMPT
:return: result, result_rate (wage, percent)
"""
state_code = 'OH'
if not _state_applies(payslip, state_code):
return 0.0, 0.0
if payslip.contract_id.us_payroll_config_value('state_income_tax_exempt'):
return 0.0, 0.0
# Determine Wage
wage = sit_wage(payslip, categories)
if not wage:
return 0.0, 0.0
pay_periods = payslip.dict.get_pay_periods_in_year()
additional = payslip.contract_id.us_payroll_config_value('state_income_tax_additional_withholding')
exemptions = payslip.contract_id.us_payroll_config_value('oh_it4_sit_exemptions')
exemption_rate = payslip.rule_parameter('us_oh_sit_exemption_rate')
withholding_rate = payslip.rule_parameter('us_oh_sit_rate')
multiplier_rate = payslip.rule_parameter('us_oh_sit_multiplier')
taxable_wage = (wage * pay_periods) - (exemption_rate * (exemptions or 0))
withholding = 0.0
if taxable_wage > 0.0:
prior_wage_cap = 0.0
for row in withholding_rate:
wage_cap, base, rate = row
wage_cap = float(wage_cap) # e.g. 'inf'
if taxable_wage < wage_cap:
withholding = base + (rate * (taxable_wage - prior_wage_cap))
break
prior_wage_cap = wage_cap
# Normalize to pay periods
withholding /= pay_periods
withholding *= multiplier_rate
withholding += additional
return wage, -((withholding / wage) * 100.0)

View File

@@ -0,0 +1,47 @@
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
from .general import _state_applies, sit_wage
def ok_oklahoma_state_income_withholding(payslip, categories, worked_days, inputs):
"""
Returns SIT eligible wage and rate.
:return: result, result_rate (wage, percent)
"""
state_code = 'OK'
if not _state_applies(payslip, state_code):
return 0.0, 0.0
# Determine Wage
wage = sit_wage(payslip, categories)
if not wage:
return 0.0, 0.0
if payslip.contract_id.us_payroll_config_value('state_income_tax_exempt'):
return 0.0, 0.0
filing_status = payslip.contract_id.us_payroll_config_value('ok_w4_sit_filing_status')
if not filing_status:
return 0.0, 0.0
schedule_pay = payslip.contract_id.schedule_pay
additional = payslip.contract_id.us_payroll_config_value('state_income_tax_additional_withholding')
allowances = payslip.contract_id.us_payroll_config_value('ok_w4_sit_allowances')
allowances_amt = payslip.rule_parameter('us_ok_sit_allowances_rate')[schedule_pay]
tax_table = payslip.rule_parameter('us_ok_sit_tax_rate')[filing_status].get(schedule_pay)
taxable_income = wage - (allowances * allowances_amt)
withholding = 0.0
last = 0.0
for row in tax_table:
amt, rate, flat_fee = row
if wage <= float(amt):
withholding = ((taxable_income - last) * (rate / 100)) + flat_fee
break
last = amt
withholding = max(withholding, 0.0)
withholding += additional
withholding = round(withholding)
return wage, -((withholding / wage) * 100.0)

View File

@@ -0,0 +1,48 @@
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
from .general import _state_applies, sit_wage
def ri_rhode_island_state_income_withholding(payslip, categories, worked_days, inputs):
"""
Returns SIT eligible wage and rate.
:return: result, result_rate (wage, percent)
"""
state_code = 'RI'
if not _state_applies(payslip, state_code):
return 0.0, 0.0
# Determine Wage
wage = sit_wage(payslip, categories)
if not wage:
return 0.0, 0.0
if payslip.contract_id.us_payroll_config_value('state_income_tax_exempt'):
return 0.0, 0.0
schedule_pay = payslip.contract_id.schedule_pay
additional = payslip.contract_id.us_payroll_config_value('state_income_tax_additional_withholding')
allowances = payslip.contract_id.us_payroll_config_value('ri_w4_sit_allowances')
exemption_rate = payslip.rule_parameter('us_ri_sit_exemption_rate')[schedule_pay]
tax_table = payslip.rule_parameter('us_ri_sit_tax_rate')[schedule_pay]
exemption_amt = 0.0
for row in exemption_rate:
amt, flat_fee = row
if wage > amt:
exemption_amt = flat_fee
taxable_income = wage - (allowances * exemption_amt)
withholding = 0.0
last = 0.0
for row in tax_table:
amt, flat_fee, rate = row
if wage <= float(amt):
withholding = ((taxable_income - last) * (rate / 100)) + flat_fee
break
last = amt
withholding = max(withholding, 0.0)
withholding += additional
return wage, -((withholding / wage) * 100.0)

View File

@@ -0,0 +1,50 @@
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
from .general import _state_applies, sit_wage
def sc_south_carolina_state_income_withholding(payslip, categories, worked_days, inputs):
"""
Returns SIT eligible wage and rate.
WAGE = GROSS + DED_FIT_EXEMPT
:return: result, result_rate (wage, percent)
"""
state_code = 'SC'
if not _state_applies(payslip, state_code):
return 0.0, 0.0
personal_exempt = payslip.contract_id.us_payroll_config_value('state_income_tax_exempt')
if personal_exempt:
return 0.0, 0.0
# Determine Wage
wage = sit_wage(payslip, categories)
if not wage:
return 0.0, 0.0
pay_periods = payslip.dict.get_pay_periods_in_year()
additional = payslip.contract_id.us_payroll_config_value('state_income_tax_additional_withholding')
allowances = payslip.contract_id.us_payroll_config_value('sc_w4_sit_allowances')
tax_rate = payslip.rule_parameter('us_sc_sit_tax_rate')
personal_exemption = payslip.rule_parameter('us_sc_sit_personal_exemption_rate')
deduction = payslip.rule_parameter('us_sc_sit_standard_deduction_rate')
annual_wage = wage * pay_periods
personal_exemption_amt = allowances * personal_exemption
standard_deduction = 0.0
if allowances > 0:
if (annual_wage * 0.1) > deduction:
standard_deduction = deduction
else:
standard_deduction = annual_wage * (10 / 100)
taxable_income = annual_wage - personal_exemption_amt - standard_deduction
withholding = 0.0
last = 0.0
for cap, rate, flat_amt in tax_rate:
if float(cap) > taxable_income:
withholding = (taxable_income * (rate / 100.0) - flat_amt)
break
withholding /= pay_periods
withholding += additional
return wage, -((withholding / wage) * 100.0)

View File

@@ -0,0 +1,39 @@
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
from .general import _state_applies, sit_wage
def ut_utah_state_income_withholding(payslip, categories, worked_days, inputs):
"""
Returns SIT eligible wage and rate.
:return: result, result_rate (wage, percent)
"""
state_code = 'UT'
if not _state_applies(payslip, state_code):
return 0.0, 0.0
# Determine Wage
wage = sit_wage(payslip, categories)
if not wage:
return 0.0, 0.0
filing_status = payslip.contract_id.us_payroll_config_value('ut_w4_sit_filing_status')
if not filing_status:
return 0.0, 0.0
schedule_pay = payslip.contract_id.schedule_pay
additional = payslip.contract_id.us_payroll_config_value('state_income_tax_additional_withholding')
tax_rate = payslip.rule_parameter('us_ut_tax_rate')
allowances = payslip.rule_parameter('us_ut_sit_allowances_rate')[filing_status].get(schedule_pay)
tax_table = payslip.rule_parameter('us_ut_sit_tax_rate')[filing_status].get(schedule_pay)
taxable_income = wage * tax_rate
withholding = 0.0
amt, rate = tax_table
withholding = taxable_income - (allowances - ((wage - amt) * (rate / 100)))
withholding = max(withholding, 0.0)
withholding += additional
withholding = round(withholding)
return wage, -((withholding / wage) * 100.0)

View File

@@ -0,0 +1,44 @@
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
from .general import _state_applies, sit_wage
def va_virginia_state_income_withholding(payslip, categories, worked_days, inputs):
"""
Returns SIT eligible wage and rate.
WAGE = GROSS + DED_FIT_EXEMPT
:return: result, result_rate (wage, percent)
"""
state_code = 'VA'
if not _state_applies(payslip, state_code):
return 0.0, 0.0
if payslip.contract_id.us_payroll_config_value('state_income_tax_exempt'):
return 0.0, 0.0
# Determine Wage
wage = sit_wage(payslip, categories)
if not wage:
return 0.0, 0.0
pay_periods = payslip.dict.get_pay_periods_in_year()
additional = payslip.contract_id.us_payroll_config_value('state_income_tax_additional_withholding')
personal_exemptions = payslip.contract_id.us_payroll_config_value('va_va4_sit_exemptions')
other_exemptions = payslip.contract_id.us_payroll_config_value('va_va4_sit_other_exemptions')
personal_exemption_rate = payslip.rule_parameter('us_va_sit_exemption_rate')
other_exemption_rate = payslip.rule_parameter('us_va_sit_other_exemption_rate')
deduction = payslip.rule_parameter('us_va_sit_deduction')
withholding_rate = payslip.rule_parameter('us_va_sit_rate')
taxable_wage = (wage * pay_periods) - (deduction + (personal_exemptions * personal_exemption_rate) + (other_exemptions * other_exemption_rate))
withholding = 0.0
if taxable_wage > 0.0:
for row in withholding_rate:
if taxable_wage > row[0]:
selected_row = row
wage_min, base, rate = selected_row
withholding = base + ((taxable_wage - wage_min) * rate / 100.0)
withholding /= pay_periods
withholding += additional
return wage, -((withholding / wage) * 100.0)

View File

@@ -0,0 +1,46 @@
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
from .general import _state_applies, sit_wage
def vt_vermont_state_income_withholding(payslip, categories, worked_days, inputs):
"""
Returns SIT eligible wage and rate.
:return: result, result_rate (wage, percent)
"""
state_code = 'VT'
if not _state_applies(payslip, state_code):
return 0.0, 0.0
# Determine Wage
wage = sit_wage(payslip, categories)
if not wage:
return 0.0, 0.0
if payslip.contract_id.us_payroll_config_value('state_income_tax_exempt'):
return 0.0, 0.0
filing_status = payslip.contract_id.us_payroll_config_value('vt_w4vt_sit_filing_status')
if not filing_status:
return 0.0, 0.0
schedule_pay = payslip.contract_id.schedule_pay
additional = payslip.contract_id.us_payroll_config_value('state_income_tax_additional_withholding')
allowances = payslip.contract_id.us_payroll_config_value('vt_w4vt_sit_allowances')
allowance_amt = payslip.rule_parameter('us_vt_sit_allowances_rate')[schedule_pay]
tax_table = payslip.rule_parameter('us_vt_sit_tax_rate')[filing_status].get(schedule_pay)
taxable_income = wage - (allowances * allowance_amt)
withholding = 0.0
last = 0.0
for row in tax_table:
amt, flat_fee, rate = row
if wage <= float(amt):
withholding = ((taxable_income - last) * (rate / 100)) + flat_fee
break
last = amt
withholding = max(withholding, 0.0)
withholding += additional
return wage, -((withholding / wage) * 100.0)

View File

@@ -0,0 +1,27 @@
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
from .general import _state_applies, _general_rate
def _wa_washington_fml(payslip, categories, worked_days, inputs, inner_rate=None):
if not inner_rate:
return 0.0, 0.0
if not _state_applies(payslip, 'WA'):
return 0.0, 0.0
wage = categories.GROSS
year = payslip.dict.get_year()
ytd_wage = payslip.sum_category('GROSS', str(year) + '-01-01', str(year + 1) + '-01-01')
ytd_wage += payslip.contract_id.external_wages
rate = payslip.rule_parameter('us_wa_fml_rate')
rate *= payslip.rule_parameter(inner_rate) / 100.0
return _general_rate(payslip, wage, ytd_wage, wage_base='us_wa_fml_wage_base', rate=rate)
def wa_washington_fml_er(payslip, categories, worked_days, inputs):
return _wa_washington_fml(payslip, categories, worked_days, inputs, inner_rate='us_wa_fml_rate_er')
def wa_washington_fml_ee(payslip, categories, worked_days, inputs):
return _wa_washington_fml(payslip, categories, worked_days, inputs, inner_rate='us_wa_fml_rate_ee')

View File

@@ -0,0 +1,47 @@
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
from .general import _state_applies, sit_wage
def wi_wisconsin_state_income_withholding(payslip, categories, worked_days, inputs):
"""
Returns SIT eligible wage and rate.
:return: result, result_rate (wage, percent)
"""
state_code = 'WI'
if not _state_applies(payslip, state_code):
return 0.0, 0.0
# Determine Wage
wage = sit_wage(payslip, categories)
if not wage:
return 0.0, 0.0
if payslip.contract_id.us_payroll_config_value('state_income_tax_exempt'):
return 0.0, 0.0
filing_status = payslip.contract_id.us_payroll_config_value('wi_wt4_sit_filing_status')
if not filing_status:
return 0.0, 0.0
pay_periods = payslip.dict.get_pay_periods_in_year()
additional = payslip.contract_id.us_payroll_config_value('state_income_tax_additional_withholding')
exemptions = payslip.contract_id.us_payroll_config_value('wi_wt4_sit_exemptions')
exemption_amt = payslip.rule_parameter('us_wi_sit_exemption_rate')
tax_table = payslip.rule_parameter('us_wi_sit_tax_rate')[filing_status]
taxable_income = wage * pay_periods
withholding = 0.0
last = 0.0
for row in tax_table:
amt, rate, flat_fee = row
if taxable_income <= float(amt):
withholding = (((taxable_income - last) * (rate / 100)) + flat_fee) - (exemptions * exemption_amt)
break
last = amt
withholding = max(withholding, 0.0)
withholding /= pay_periods
withholding += additional
return wage, -((withholding / wage) * 100.0)

View File

@@ -0,0 +1,44 @@
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
from .general import _state_applies, sit_wage
def wv_west_virginia_state_income_withholding(payslip, categories, worked_days, inputs):
"""
Returns SIT eligible wage and rate.
:return: result, result_rate (wage, percent)
"""
state_code = 'WV'
if not _state_applies(payslip, state_code):
return 0.0, 0.0
# Determine Wage
wage = sit_wage(payslip, categories)
if not wage:
return 0.0, 0.0
filing_status = payslip.contract_id.us_payroll_config_value('wv_it104_sit_filing_status')
if not filing_status:
return 0.0, 0.0
schedule_pay = payslip.contract_id.schedule_pay
additional = payslip.contract_id.us_payroll_config_value('state_income_tax_additional_withholding')
exemptions = payslip.contract_id.us_payroll_config_value('wv_it104_sit_exemptions')
exemption_amt = payslip.rule_parameter('us_wv_sit_exemption_rate')[schedule_pay]
tax_table = payslip.rule_parameter('us_wv_sit_tax_rate')[filing_status].get(schedule_pay)
taxable_income = wage - (exemptions * exemption_amt)
withholding = 0.0
last = 0.0
for row in tax_table:
amt, flat_fee, rate = row
if taxable_income <= float(amt):
withholding = ((taxable_income - last) * (rate / 100)) + flat_fee
break
last = amt
withholding = max(withholding, 0.0)
withholding += additional
withholding = round(withholding)
return wage, -((withholding / wage) * 100.0)