mirror of
https://gitlab.com/hibou-io/hibou-odoo/suite.git
synced 2025-01-20 12:37:31 +02:00
[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:
1
l10n_us_hr_payroll/models/state/__init__.py
Normal file
1
l10n_us_hr_payroll/models/state/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
|
||||
80
l10n_us_hr_payroll/models/state/al_alabama.py
Normal file
80
l10n_us_hr_payroll/models/state/al_alabama.py
Normal 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)
|
||||
47
l10n_us_hr_payroll/models/state/ar_arkansas.py
Normal file
47
l10n_us_hr_payroll/models/state/ar_arkansas.py
Normal 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)
|
||||
35
l10n_us_hr_payroll/models/state/az_arizona.py
Normal file
35
l10n_us_hr_payroll/models/state/az_arizona.py
Normal 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)
|
||||
98
l10n_us_hr_payroll/models/state/ca_california.py
Normal file
98
l10n_us_hr_payroll/models/state/ca_california.py
Normal 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)
|
||||
45
l10n_us_hr_payroll/models/state/co_colorado.py
Normal file
45
l10n_us_hr_payroll/models/state/co_colorado.py
Normal 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)
|
||||
76
l10n_us_hr_payroll/models/state/ct_connecticut.py
Normal file
76
l10n_us_hr_payroll/models/state/ct_connecticut.py
Normal 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)
|
||||
49
l10n_us_hr_payroll/models/state/de_delaware.py
Normal file
49
l10n_us_hr_payroll/models/state/de_delaware.py
Normal 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)
|
||||
51
l10n_us_hr_payroll/models/state/ga_georgia.py
Normal file
51
l10n_us_hr_payroll/models/state/ga_georgia.py
Normal 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)
|
||||
131
l10n_us_hr_payroll/models/state/general.py
Normal file
131
l10n_us_hr_payroll/models/state/general.py
Normal 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
|
||||
43
l10n_us_hr_payroll/models/state/hi_hawaii.py
Normal file
43
l10n_us_hr_payroll/models/state/hi_hawaii.py
Normal 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)
|
||||
48
l10n_us_hr_payroll/models/state/ia_iowa.py
Normal file
48
l10n_us_hr_payroll/models/state/ia_iowa.py
Normal 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)
|
||||
41
l10n_us_hr_payroll/models/state/id_idaho.py
Normal file
41
l10n_us_hr_payroll/models/state/id_idaho.py
Normal 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)
|
||||
35
l10n_us_hr_payroll/models/state/il_illinois.py
Normal file
35
l10n_us_hr_payroll/models/state/il_illinois.py
Normal 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)
|
||||
34
l10n_us_hr_payroll/models/state/in_indiana.py
Normal file
34
l10n_us_hr_payroll/models/state/in_indiana.py
Normal 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)
|
||||
44
l10n_us_hr_payroll/models/state/ks_kansas.py
Normal file
44
l10n_us_hr_payroll/models/state/ks_kansas.py
Normal 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)
|
||||
32
l10n_us_hr_payroll/models/state/ky_kentucky.py
Normal file
32
l10n_us_hr_payroll/models/state/ky_kentucky.py
Normal 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)
|
||||
62
l10n_us_hr_payroll/models/state/la_louisiana.py
Normal file
62
l10n_us_hr_payroll/models/state/la_louisiana.py
Normal 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)
|
||||
62
l10n_us_hr_payroll/models/state/me_maine.py
Normal file
62
l10n_us_hr_payroll/models/state/me_maine.py
Normal 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)
|
||||
35
l10n_us_hr_payroll/models/state/mi_michigan.py
Normal file
35
l10n_us_hr_payroll/models/state/mi_michigan.py
Normal 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)
|
||||
44
l10n_us_hr_payroll/models/state/mn_minnesota.py
Normal file
44
l10n_us_hr_payroll/models/state/mn_minnesota.py
Normal 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)
|
||||
53
l10n_us_hr_payroll/models/state/mo_missouri.py
Normal file
53
l10n_us_hr_payroll/models/state/mo_missouri.py
Normal 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)
|
||||
46
l10n_us_hr_payroll/models/state/ms_mississippi.py
Normal file
46
l10n_us_hr_payroll/models/state/ms_mississippi.py
Normal 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)
|
||||
45
l10n_us_hr_payroll/models/state/mt_montana.py
Normal file
45
l10n_us_hr_payroll/models/state/mt_montana.py
Normal 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)
|
||||
38
l10n_us_hr_payroll/models/state/nc_northcarolina.py
Normal file
38
l10n_us_hr_payroll/models/state/nc_northcarolina.py
Normal 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)
|
||||
45
l10n_us_hr_payroll/models/state/nd_north_dakota.py
Normal file
45
l10n_us_hr_payroll/models/state/nd_north_dakota.py
Normal 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)
|
||||
49
l10n_us_hr_payroll/models/state/ne_nebraska.py
Normal file
49
l10n_us_hr_payroll/models/state/ne_nebraska.py
Normal 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)
|
||||
52
l10n_us_hr_payroll/models/state/nj_newjersey.py
Normal file
52
l10n_us_hr_payroll/models/state/nj_newjersey.py
Normal 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)
|
||||
40
l10n_us_hr_payroll/models/state/nm_new_mexico.py
Normal file
40
l10n_us_hr_payroll/models/state/nm_new_mexico.py
Normal 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)
|
||||
54
l10n_us_hr_payroll/models/state/ny_new_york.py
Normal file
54
l10n_us_hr_payroll/models/state/ny_new_york.py
Normal 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)
|
||||
47
l10n_us_hr_payroll/models/state/oh_ohio.py
Normal file
47
l10n_us_hr_payroll/models/state/oh_ohio.py
Normal 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)
|
||||
47
l10n_us_hr_payroll/models/state/ok_oklahoma.py
Normal file
47
l10n_us_hr_payroll/models/state/ok_oklahoma.py
Normal 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)
|
||||
48
l10n_us_hr_payroll/models/state/ri_rhode_island.py
Normal file
48
l10n_us_hr_payroll/models/state/ri_rhode_island.py
Normal 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)
|
||||
50
l10n_us_hr_payroll/models/state/sc_south_carolina.py
Normal file
50
l10n_us_hr_payroll/models/state/sc_south_carolina.py
Normal 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)
|
||||
39
l10n_us_hr_payroll/models/state/ut_utah.py
Normal file
39
l10n_us_hr_payroll/models/state/ut_utah.py
Normal 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)
|
||||
44
l10n_us_hr_payroll/models/state/va_virginia.py
Normal file
44
l10n_us_hr_payroll/models/state/va_virginia.py
Normal 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)
|
||||
46
l10n_us_hr_payroll/models/state/vt_vermont.py
Normal file
46
l10n_us_hr_payroll/models/state/vt_vermont.py
Normal 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)
|
||||
27
l10n_us_hr_payroll/models/state/wa_washington.py
Normal file
27
l10n_us_hr_payroll/models/state/wa_washington.py
Normal 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')
|
||||
47
l10n_us_hr_payroll/models/state/wi_wisconsin.py
Normal file
47
l10n_us_hr_payroll/models/state/wi_wisconsin.py
Normal 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)
|
||||
44
l10n_us_hr_payroll/models/state/wv_west_virginia.py
Normal file
44
l10n_us_hr_payroll/models/state/wv_west_virginia.py
Normal 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)
|
||||
Reference in New Issue
Block a user