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,5 +1,130 @@
|
||||
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
|
||||
|
||||
from . import common
|
||||
|
||||
from . import test_special
|
||||
|
||||
from . import test_us_payslip_2019
|
||||
from . import test_us_payslip_2020
|
||||
|
||||
from . import test_us_ak_alaska_payslip_2019
|
||||
from . import test_us_ak_alaska_payslip_2020
|
||||
|
||||
from . import test_us_al_alabama_payslip_2019
|
||||
from . import test_us_al_alabama_payslip_2020
|
||||
|
||||
from . import test_us_ar_arkansas_payslip_2019
|
||||
from . import test_us_ar_arkansas_payslip_2020
|
||||
|
||||
from . import test_us_az_arizona_payslip_2019
|
||||
from . import test_us_az_arizona_payslip_2020
|
||||
|
||||
from . import test_us_ca_california_payslip_2019
|
||||
from . import test_us_ca_california_payslip_2020
|
||||
|
||||
from . import test_us_co_colorado_payslip_2020
|
||||
|
||||
from . import test_us_ct_connecticut_payslip_2019
|
||||
from . import test_us_ct_connecticut_payslip_2020
|
||||
|
||||
from . import test_us_de_delaware_payslip_2020
|
||||
|
||||
from . import test_us_fl_florida_payslip_2019
|
||||
from . import test_us_fl_florida_payslip_2020
|
||||
|
||||
from . import test_us_ga_georgia_payslip_2019
|
||||
from . import test_us_ga_georgia_payslip_2020
|
||||
|
||||
from . import test_us_hi_hawaii_payslip_2019
|
||||
from . import test_us_hi_hawaii_payslip_2020
|
||||
|
||||
from . import test_us_ia_iowa_payslip_2019
|
||||
from . import test_us_ia_iowa_payslip_2020
|
||||
|
||||
from . import test_us_id_idaho_payslip_2019
|
||||
from . import test_us_id_idaho_payslip_2020
|
||||
|
||||
from . import test_us_il_illinois_payslip_2019
|
||||
from . import test_us_il_illinois_payslip_2020
|
||||
|
||||
from . import test_us_in_indiana_payslip_2020
|
||||
|
||||
from . import test_us_ky_kentucky_payslip_2020
|
||||
|
||||
from . import test_us_ks_kansas_payslip_2020
|
||||
|
||||
from . import test_us_la_louisiana_payslip_2019
|
||||
from . import test_us_la_louisiana_payslip_2020
|
||||
|
||||
from . import test_us_me_maine_payslip_2020
|
||||
|
||||
from . import test_us_mi_michigan_payslip_2019
|
||||
from . import test_us_mi_michigan_payslip_2020
|
||||
|
||||
from . import test_us_mn_minnesota_payslip_2019
|
||||
from . import test_us_mn_minnesota_payslip_2020
|
||||
|
||||
from . import test_us_mo_missouri_payslip_2019
|
||||
from . import test_us_mo_missouri_payslip_2020
|
||||
|
||||
from . import test_us_ms_mississippi_payslip_2019
|
||||
from . import test_us_ms_mississippi_payslip_2020
|
||||
|
||||
from . import test_us_mt_montana_payslip_2019
|
||||
from . import test_us_mt_montana_payslip_2020
|
||||
|
||||
from . import test_us_nc_northcarolina_payslip_2019
|
||||
from . import test_us_nc_northcarolina_payslip_2020
|
||||
|
||||
from . import test_us_nd_north_dakota_payslip_2020
|
||||
|
||||
from . import test_us_ne_nebraska_payslip_2020
|
||||
|
||||
from . import test_us_nh_new_hampshire_payslip_2020
|
||||
|
||||
from . import test_us_nj_newjersey_payslip_2019
|
||||
from . import test_us_nj_newjersey_payslip_2020
|
||||
|
||||
from . import test_us_nm_new_mexico_payslip_2020
|
||||
|
||||
from . import test_us_nv_nevada_payslip_2020
|
||||
|
||||
from . import test_us_ny_new_york_payslip_2019
|
||||
from . import test_us_ny_new_york_payslip_2020
|
||||
|
||||
from . import test_us_oh_ohio_payslip_2019
|
||||
from . import test_us_oh_ohio_payslip_2020
|
||||
|
||||
from . import test_us_ok_oklahoma_payslip_2020
|
||||
|
||||
from . import test_us_pa_pennsylvania_payslip_2019
|
||||
from . import test_us_pa_pennsylvania_payslip_2020
|
||||
|
||||
from . import test_us_ri_rhode_island_payslip_2020
|
||||
|
||||
from . import test_us_sc_south_carolina_payslip_2019
|
||||
from . import test_us_sc_south_carolina_payslip_2020
|
||||
|
||||
from . import test_us_sd_south_dakota_payslip_2020
|
||||
|
||||
from . import test_us_tn_tennessee_payslip_2020
|
||||
|
||||
from . import test_us_tx_texas_payslip_2019
|
||||
from . import test_us_tx_texas_payslip_2020
|
||||
|
||||
from . import test_us_us_utah_payslip_2020
|
||||
|
||||
from . import test_us_vt_vermont_payslip_2020
|
||||
|
||||
from . import test_us_va_virginia_payslip_2019
|
||||
from . import test_us_va_virginia_payslip_2020
|
||||
|
||||
from . import test_us_wa_washington_payslip_2019
|
||||
from . import test_us_wa_washington_payslip_2020
|
||||
|
||||
from . import test_us_wv_west_virginia_payslip_2020
|
||||
|
||||
from . import test_us_wi_wisconsin_payslip_2020
|
||||
|
||||
from . import test_us_wy_wyoming_payslip_2019
|
||||
from . import test_us_wy_wyoming_payslip_2020
|
||||
|
||||
@@ -3,9 +3,11 @@
|
||||
from logging import getLogger
|
||||
from sys import float_info as sys_float_info
|
||||
from collections import defaultdict
|
||||
from datetime import timedelta
|
||||
|
||||
from odoo.tests import common
|
||||
from odoo.tools.float_utils import float_round as odoo_float_round
|
||||
from odoo.addons.l10n_us_hr_payroll.models.hr_contract import USHRContract
|
||||
|
||||
|
||||
def process_payslip(payslip):
|
||||
@@ -20,6 +22,12 @@ class TestUsPayslip(common.TransactionCase):
|
||||
debug = False
|
||||
_logger = getLogger(__name__)
|
||||
|
||||
def setUp(self):
|
||||
super(TestUsPayslip, self).setUp()
|
||||
self.env['ir.config_parameter'].set_param('hr_payroll.payslip.sum_behavior', 'date_to')
|
||||
self.structure_type_id = self.ref('l10n_us_hr_payroll.structure_type_employee')
|
||||
self.resource_calendar_id = self.ref('resource.resource_calendar_std')
|
||||
|
||||
float_info = sys_float_info
|
||||
|
||||
def float_round(self, value, digits):
|
||||
@@ -61,6 +69,10 @@ class TestUsPayslip(common.TransactionCase):
|
||||
'employee_id': employee.id,
|
||||
}
|
||||
|
||||
# Backwards compatability with 'futa_type'
|
||||
if 'futa_type' in kwargs:
|
||||
kwargs['fed_940_type'] = kwargs['futa_type']
|
||||
|
||||
for key, val in kwargs.items():
|
||||
# Assume any Odoo object is in a Many2one
|
||||
if hasattr(val, 'id'):
|
||||
@@ -83,13 +95,13 @@ class TestUsPayslip(common.TransactionCase):
|
||||
if not contract_values.get('state'):
|
||||
contract_values['state'] = 'open' # Running
|
||||
if not contract_values.get('structure_type_id'):
|
||||
contract_values['structure_type_id'] = self.ref('l10n_us_hr_payroll.structure_type_employee')
|
||||
contract_values['structure_type_id'] = self.structure_type_id
|
||||
if not contract_values.get('date_start'):
|
||||
contract_values['date_start'] = '2016-01-01'
|
||||
if not contract_values.get('date_end'):
|
||||
contract_values['date_end'] = '2030-12-31'
|
||||
if not contract_values.get('resource_calendar_id'):
|
||||
contract_values['resource_calendar_id'] = self.ref('resource.resource_calendar_std')
|
||||
contract_values['resource_calendar_id'] = self.resource_calendar_id
|
||||
|
||||
# Compatibility with earlier Odoo versions
|
||||
if not contract_values.get('journal_id') and hasattr(contract_model, 'journal_id'):
|
||||
@@ -140,11 +152,87 @@ class TestUsPayslip(common.TransactionCase):
|
||||
def assertPayrollEqual(self, first, second):
|
||||
self.assertAlmostEqual(first, second, self.payroll_digits)
|
||||
|
||||
def test_semi_monthly(self):
|
||||
salary = 80000.0
|
||||
employee = self._createEmployee()
|
||||
# so the schedule_pay is now on the Structure...
|
||||
contract = self._createContract(employee, wage=salary, schedule_pay='semi-monthly')
|
||||
payslip = self._createPayslip(employee, '2019-01-01', '2019-01-14')
|
||||
def assertPayrollAlmostEqual(self, first, second):
|
||||
self.assertAlmostEqual(first, second, self.payroll_digits-1)
|
||||
|
||||
def get_us_state(self, code, cache={}):
|
||||
country_key = 'US_COUNTRY'
|
||||
if code in cache:
|
||||
return cache[code]
|
||||
if country_key not in cache:
|
||||
cache[country_key] = self.env.ref('base.us')
|
||||
us_country = cache[country_key]
|
||||
us_state = self.env['res.country.state'].search([
|
||||
('country_id', '=', us_country.id),
|
||||
('code', '=', code),
|
||||
], limit=1)
|
||||
cache[code] = us_state
|
||||
return us_state
|
||||
|
||||
def _test_suta(self, category, state_code, rate, date, wage_base=None, relaxed=False, **extra_contract):
|
||||
if relaxed:
|
||||
_assert = self.assertPayrollAlmostEqual
|
||||
else:
|
||||
_assert = self.assertPayrollEqual
|
||||
if wage_base:
|
||||
# Slightly larger than 1/2 the wage_base
|
||||
wage = round(wage_base / 2.0) + 100.0
|
||||
self.assertTrue((2 * wage) > wage_base, 'Granularity of wage_base too low.')
|
||||
else:
|
||||
wage = 1000.0
|
||||
|
||||
employee = self._createEmployee()
|
||||
contract = self._createContract(employee,
|
||||
wage=wage,
|
||||
state_id=self.get_us_state(state_code),
|
||||
**extra_contract)
|
||||
|
||||
rate = -rate / 100.0 # Assumed passed as percent positive
|
||||
|
||||
# Tests
|
||||
payslip = self._createPayslip(employee, date, date + timedelta(days=30))
|
||||
|
||||
# Test exemptions
|
||||
contract.us_payroll_config_id.fed_940_type = USHRContract.FUTA_TYPE_EXEMPT
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
_assert(cats.get(category, 0.0), 0.0)
|
||||
|
||||
contract.us_payroll_config_id.fed_940_type = USHRContract.FUTA_TYPE_BASIC
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
_assert(cats.get(category, 0.0), 0.0)
|
||||
|
||||
# Test Normal
|
||||
contract.us_payroll_config_id.fed_940_type = USHRContract.FUTA_TYPE_NORMAL
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
_assert(cats.get(category, 0.0), wage * rate)
|
||||
process_payslip(payslip)
|
||||
|
||||
# Second Payslip
|
||||
payslip = self._createPayslip(employee, date + timedelta(days=31), date + timedelta(days=60))
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
if wage_base:
|
||||
remaining_unemp_wages = wage_base - wage
|
||||
self.assertTrue((remaining_unemp_wages * rate) <= 0.01) # less than 0.01 because rate is negative
|
||||
_assert(cats.get(category, 0.0), remaining_unemp_wages * rate)
|
||||
|
||||
# As if they were paid once already, so the first "two payslips" would remove all of the tax obligation
|
||||
# 1 wage - Payslip (confirmed)
|
||||
# 1 wage - external_wages
|
||||
# 1 wage - current Payslip
|
||||
contract.external_wages = wage
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
_assert(cats.get(category, 0.0), 0.0)
|
||||
else:
|
||||
_assert(cats.get(category, 0.0), wage * rate)
|
||||
|
||||
def _test_er_suta(self, state_code, rate, date, wage_base=None, relaxed=False, **extra_contract):
|
||||
self._test_suta('ER_US_SUTA', state_code, rate, date, wage_base=wage_base, relaxed=relaxed, **extra_contract)
|
||||
|
||||
def _test_ee_suta(self, state_code, rate, date, wage_base=None, relaxed=False, **extra_contract):
|
||||
self._test_suta('EE_US_SUTA', state_code, rate, date, wage_base=wage_base, relaxed=relaxed, **extra_contract)
|
||||
|
||||
119
l10n_us_hr_payroll/tests/test_special.py
Normal file
119
l10n_us_hr_payroll/tests/test_special.py
Normal file
@@ -0,0 +1,119 @@
|
||||
from .common import TestUsPayslip, process_payslip
|
||||
|
||||
|
||||
class TestSpecial(TestUsPayslip):
|
||||
def test_semi_monthly(self):
|
||||
salary = 80000.0
|
||||
employee = self._createEmployee()
|
||||
# so the schedule_pay is now on the Structure...
|
||||
contract = self._createContract(employee, wage=salary, schedule_pay='semi-monthly')
|
||||
payslip = self._createPayslip(employee, '2019-01-01', '2019-01-14')
|
||||
payslip.compute_sheet()
|
||||
|
||||
def test_payslip_sum_behavior(self):
|
||||
us_structure = self.env.ref('l10n_us_hr_payroll.hr_payroll_structure')
|
||||
rule_category_comp = self.env.ref('hr_payroll.COMP')
|
||||
test_rule_category = self.env['hr.salary.rule.category'].create({
|
||||
'name': 'Test Sum Behavior',
|
||||
'code': 'test_sum_behavior',
|
||||
'parent_id': rule_category_comp.id,
|
||||
})
|
||||
test_rule = self.env['hr.salary.rule'].create({
|
||||
'sequence': 450,
|
||||
'struct_id': us_structure.id,
|
||||
'category_id': test_rule_category.id,
|
||||
'name': 'Test Sum Behavior',
|
||||
'code': 'test_sum_behavior',
|
||||
'condition_select': 'python',
|
||||
'condition_python': 'result = 1',
|
||||
'amount_select': 'code',
|
||||
'amount_python_compute': '''
|
||||
ytd_category = payslip.sum_category('test_sum_behavior', '2020-01-01', '2021-01-01')
|
||||
ytd_rule = payslip.sum('test_sum_behavior', '2020-01-01', '2021-01-01')
|
||||
result = 0.0
|
||||
if ytd_category != ytd_rule:
|
||||
# error
|
||||
result = -1.0
|
||||
elif ytd_rule == 0.0:
|
||||
# first payslip in period
|
||||
result = 1.0
|
||||
'''
|
||||
})
|
||||
salary = 80000.0
|
||||
employee = self._createEmployee()
|
||||
contract = self._createContract(employee, wage=salary, schedule_pay='bi-weekly')
|
||||
payslip = self._createPayslip(employee, '2019-12-30', '2020-01-12')
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
self.assertEqual(cats['test_sum_behavior'], 1.0)
|
||||
process_payslip(payslip)
|
||||
|
||||
# Basic date_from behavior.
|
||||
self.env['ir.config_parameter'].set_param('hr_payroll.payslip.sum_behavior', 'date_from')
|
||||
# The the date_from on the last payslip will not be found
|
||||
payslip = self._createPayslip(employee, '2020-01-13', '2020-01-27')
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
self.assertEqual(cats['test_sum_behavior'], 1.0)
|
||||
|
||||
# date_to behavior.
|
||||
self.env['ir.config_parameter'].set_param('hr_payroll.payslip.sum_behavior', 'date_to')
|
||||
# The date_to on the last payslip is found
|
||||
payslip = self._createPayslip(employee, '2020-01-13', '2020-01-27')
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
self.assertEqual(cats['test_sum_behavior'], 0.0)
|
||||
|
||||
def test_recursive_salary_rule_category(self):
|
||||
# self.debug = True
|
||||
us_structure = self.env.ref('l10n_us_hr_payroll.hr_payroll_structure')
|
||||
# In this scenario, you are in rule code that will check for the category
|
||||
# and a subcategory will also
|
||||
alw_category = self.env.ref('hr_payroll.ALW')
|
||||
ded_category = self.env.ref('hr_payroll.DED')
|
||||
test_category = self.env['hr.salary.rule.category'].create({
|
||||
'name': 'Special ALW',
|
||||
'code': 'ALW_SPECIAL_RECURSIVE',
|
||||
'parent_id': alw_category.id,
|
||||
})
|
||||
test_special_alw = self.env['hr.salary.rule'].create({
|
||||
'name': 'Flat amount 200',
|
||||
'code': 'ALW_SPECIAL_RECURSIVE',
|
||||
'category_id': test_category.id,
|
||||
'condition_select': 'none',
|
||||
'amount_select': 'fix',
|
||||
'amount_fix': 200.0,
|
||||
'struct_id': us_structure.id,
|
||||
})
|
||||
test_recursion = self.env['hr.salary.rule'].create({
|
||||
'name': 'Actual Test Behavior',
|
||||
'code': 'RECURSION_TEST',
|
||||
'category_id': ded_category.id,
|
||||
'condition_select': 'none',
|
||||
'amount_select': 'code',
|
||||
'amount_python_compute': """
|
||||
# this rule will always be the total of the ALW category and YTD ALW category
|
||||
result = categories.ALW
|
||||
year = payslip.dict.get_year()
|
||||
result += payslip.sum_category('ALW', str(year) + '-01-01', str(year+1) + '-01-01')
|
||||
""",
|
||||
'sequence': 101,
|
||||
'struct_id': us_structure.id,
|
||||
})
|
||||
|
||||
salary = 80000.0
|
||||
employee = self._createEmployee()
|
||||
contract = self._createContract(employee, wage=salary, schedule_pay='bi-weekly')
|
||||
payslip = self._createPayslip(employee, '2020-01-01', '2020-01-14')
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
rules = self._getRules(payslip)
|
||||
self.assertEqual(rules['RECURSION_TEST'], 200.0)
|
||||
process_payslip(payslip)
|
||||
|
||||
payslip = self._createPayslip(employee, '2020-01-15', '2020-01-27')
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
rules = self._getRules(payslip)
|
||||
# two hundred is in the YTD ALW
|
||||
self.assertEqual(rules['RECURSION_TEST'], 200.0 + 200.0)
|
||||
61
l10n_us_hr_payroll/tests/test_us_ak_alaska_payslip_2019.py
Normal file
61
l10n_us_hr_payroll/tests/test_us_ak_alaska_payslip_2019.py
Normal file
@@ -0,0 +1,61 @@
|
||||
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
|
||||
|
||||
from .common import TestUsPayslip, process_payslip
|
||||
|
||||
|
||||
class TestUsAKPayslip(TestUsPayslip):
|
||||
# TAXES AND RATES
|
||||
AK_UNEMP_MAX_WAGE = 39900.00
|
||||
AK_UNEMP = -(1.780 / 100.0)
|
||||
AK_UNEMP_EE = -(0.5 / 100.0)
|
||||
|
||||
def test_taxes_monthly_over_max(self):
|
||||
salary = 50000.00
|
||||
schedule_pay = 'monthly'
|
||||
|
||||
employee = self._createEmployee()
|
||||
contract = self._createContract(employee,
|
||||
wage=salary,
|
||||
state_id=self.get_us_state('AK'),
|
||||
state_income_tax_additional_withholding=0.0,
|
||||
schedule_pay=schedule_pay)
|
||||
|
||||
self._log('2019 Alaska tax first payslip monthly:')
|
||||
payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31')
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self.assertPayrollEqual(cats['ER_US_SUTA'], self.AK_UNEMP_MAX_WAGE * self.AK_UNEMP)
|
||||
self.assertPayrollEqual(cats['EE_US_SUTA'], self.AK_UNEMP_MAX_WAGE * self.AK_UNEMP_EE)
|
||||
|
||||
process_payslip(payslip)
|
||||
|
||||
remaining_ak_unemp_wages = 0.00 # We already reached the maximum wage for unemployment insurance.
|
||||
|
||||
self._log('2019 Alaska tax second payslip monthly:')
|
||||
payslip = self._createPayslip(employee, '2019-02-01', '2019-02-28')
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self.assertPayrollEqual(cats['ER_US_SUTA'], remaining_ak_unemp_wages * self.AK_UNEMP) # 0
|
||||
|
||||
def test_taxes_weekly_under_max(self):
|
||||
salary = 5000.00
|
||||
schedule_pay = 'weekly'
|
||||
|
||||
employee = self._createEmployee()
|
||||
contract = self._createContract(employee,
|
||||
wage=salary,
|
||||
state_id=self.get_us_state('AK'),
|
||||
state_income_tax_additional_withholding=0.0,
|
||||
schedule_pay=schedule_pay)
|
||||
|
||||
self._log('2019 Alaska tax first payslip weekly:')
|
||||
payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31')
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self.assertPayrollEqual(cats['ER_US_SUTA'], salary * self.AK_UNEMP)
|
||||
self.assertPayrollEqual(cats['EE_US_SUTA'], salary * self.AK_UNEMP_EE)
|
||||
|
||||
process_payslip(payslip)
|
||||
15
l10n_us_hr_payroll/tests/test_us_ak_alaska_payslip_2020.py
Normal file
15
l10n_us_hr_payroll/tests/test_us_ak_alaska_payslip_2020.py
Normal file
@@ -0,0 +1,15 @@
|
||||
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
|
||||
|
||||
from datetime import date
|
||||
from .common import TestUsPayslip
|
||||
|
||||
|
||||
class TestUsAKPayslip(TestUsPayslip):
|
||||
# TAXES AND RATES
|
||||
AK_UNEMP_MAX_WAGE = 41500.00
|
||||
AK_UNEMP = 1.590
|
||||
AK_UNEMP_EE = 0.5
|
||||
|
||||
def test_2020_taxes(self):
|
||||
self._test_er_suta('AK', self.AK_UNEMP, date(2020, 1, 1), wage_base=self.AK_UNEMP_MAX_WAGE)
|
||||
self._test_ee_suta('AK', self.AK_UNEMP_EE, date(2020, 1, 1), wage_base=self.AK_UNEMP_MAX_WAGE)
|
||||
264
l10n_us_hr_payroll/tests/test_us_al_alabama_payslip_2019.py
Normal file
264
l10n_us_hr_payroll/tests/test_us_al_alabama_payslip_2019.py
Normal file
@@ -0,0 +1,264 @@
|
||||
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
|
||||
|
||||
from .common import TestUsPayslip, process_payslip
|
||||
|
||||
|
||||
class TestUsALPayslip(TestUsPayslip):
|
||||
# TAXES AND RATES
|
||||
AL_UNEMP_MAX_WAGE = 8000.00
|
||||
AL_UNEMP = -2.70 / 100.0
|
||||
|
||||
def test_taxes_weekly(self):
|
||||
salary = 10000.00
|
||||
schedule_pay = 'weekly'
|
||||
dependents = 1
|
||||
filing_status = 'S'
|
||||
# see https://revenue.alabama.gov/wp-content/uploads/2019/01/whbooklet_0119.pdf for reference
|
||||
# Hand Calculated Amount to Test
|
||||
# Step 1 -> 10000.00 for wages per period , 52.0 for weekly -> 10000 * 52 -> 520000.0
|
||||
# Step 2A -> standard deduction for highest wage bracket -> 2000. Subtract from yearly income
|
||||
# 520000 - 2000 = 518000.0
|
||||
# Step 2B -> Subtract Federal Income Tax in yearly form -> Our Fed withholding is -2999.66 * 52 = -155982.32
|
||||
# -> 518000.0 - 155982.32 = 362017.68
|
||||
# Step 2C -> Subtract the personal exemption -> 1500 for single filing_status
|
||||
# -> 362017.68 - 1500 = 360517.68
|
||||
# Step 2D -> Since income is so high, only 300$ per dependent -> 300$. Subtract
|
||||
# -> 360517.68 - 300 = 360217.68
|
||||
#
|
||||
# Step 5 (after adding previous lines) -> Compute marginal taxes.
|
||||
# (500 * (2.00 / 100)) + (2500 * (4.00 / 100)) + ((360217.68 - 500 - 2500) * (5.00 / 100)) -> 17970.884000000002
|
||||
# Convert back to pay period
|
||||
# wh = round(17970.884000000002, 2) -> 17970.88 / 52.0 -> 345.59
|
||||
wh = -345.59
|
||||
|
||||
employee = self._createEmployee()
|
||||
contract = self._createContract(employee,
|
||||
wage=salary,
|
||||
state_id=self.get_us_state('AL'),
|
||||
al_a4_sit_exemptions=filing_status,
|
||||
state_income_tax_additional_withholding=0.0,
|
||||
state_income_tax_exempt=False,
|
||||
al_a4_sit_dependents=dependents,
|
||||
schedule_pay=schedule_pay)
|
||||
|
||||
self._log('2019 Alabama tax first payslip weekly:')
|
||||
payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31')
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self.assertPayrollEqual(cats['EE_US_941_FIT'], -2999.66) # Hand Calculated.
|
||||
self.assertPayrollEqual(cats['ER_US_SUTA'], self.AL_UNEMP_MAX_WAGE * self.AL_UNEMP)
|
||||
self.assertPayrollEqual(cats['EE_US_SIT'], wh)
|
||||
|
||||
process_payslip(payslip)
|
||||
|
||||
remaining_AL_UNEMP_wages = 0.00 # We already reached the maximum wage for unemployment insurance.
|
||||
|
||||
self._log('2019 Alabama tax second payslip weekly:')
|
||||
payslip = self._createPayslip(employee, '2019-02-01', '2019-02-28')
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self.assertPayrollEqual(cats['ER_US_SUTA'], remaining_AL_UNEMP_wages * self.AL_UNEMP) # 0
|
||||
|
||||
def test_taxes_married_jointly(self):
|
||||
salary = 10000.00
|
||||
schedule_pay = 'weekly'
|
||||
dependents = 1
|
||||
filing_status = 'M'
|
||||
|
||||
# see https://revenue.alabama.gov/wp-content/uploads/2019/01/whbooklet_0119.pdf for reference
|
||||
# Hand Calculated Amount to Test
|
||||
# Step 1 -> 10000.00 for wages per period , 52.0 for weekly -> 10000 * 52 -> 520000.0
|
||||
# Step 2A -> standard deduction for highest wage bracket -> 4000. Subtract from yearly income
|
||||
# 520000 - 4000 = 516000.0
|
||||
# Step 2B -> Subtract Federal Income Tax in yearly form -> Our Fed withholding is -2999.66 * 52 = -155982.32
|
||||
# -> 516000.0 - 155982.32 = 360017.68
|
||||
# Step 2C -> Subtract the personal exemption -> 3000 for married filing jointly.
|
||||
# -> 360017.68 - 3000 = 357017.68
|
||||
# Step 2D -> Since income is so high, only 300$ per dependent -> 300$. Subtract
|
||||
# -> 357017.68 - 300 = 356717.68
|
||||
#
|
||||
# Step 5 (after adding previous lines) -> Compute marginal taxes.
|
||||
# (1000 * (2.00 / 100)) + (5000 * (4.00 / 100)) + ((356717.68 - 1000 - 50000) * (5.00 / 100))
|
||||
# -> 17755.884000000002
|
||||
# Convert back to pay period
|
||||
# wh = round(17755.884000000002, 2) -> 15505.88 / 52.0 -> 341.45923076923077
|
||||
wh = -341.46
|
||||
|
||||
employee = self._createEmployee()
|
||||
contract = self._createContract(employee,
|
||||
wage=salary,
|
||||
state_id=self.get_us_state('AL'),
|
||||
al_a4_sit_exemptions=filing_status,
|
||||
state_income_tax_additional_withholding=0.0,
|
||||
state_income_tax_exempt=False,
|
||||
al_a4_sit_dependents=dependents,
|
||||
schedule_pay=schedule_pay)
|
||||
|
||||
self._log('2019 Alabama tax first payslip weekly:')
|
||||
payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31')
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self.assertPayrollEqual(cats['EE_US_941_FIT'], -2999.66) # Hand Calculated.
|
||||
self.assertPayrollEqual(cats['ER_US_SUTA'], self.AL_UNEMP_MAX_WAGE * self.AL_UNEMP)
|
||||
self.assertPayrollEqual(cats['EE_US_SIT'], wh)
|
||||
|
||||
process_payslip(payslip)
|
||||
|
||||
|
||||
def test_taxes_semimonthly_filing_seperate(self):
|
||||
salary = 20000.00
|
||||
schedule_pay = 'monthly'
|
||||
filing_status = 'MS'
|
||||
dependents = 2
|
||||
|
||||
# see https://revenue.alabama.gov/wp-content/uploads/2019/01/whbooklet_0119.pdf for reference
|
||||
# Hand Calculated Amount to Test
|
||||
# Step 1 -> 10000.00 for wages per period , 12.0 for monthly -> 20000 * 12 -> 240000.00
|
||||
# Step 2A -> standard deduction for highest wage bracket -> 2000. Subtract from yearly income
|
||||
# 240000.00 - 2000 = 238000.00
|
||||
# Step 2B -> Subtract Federal Income Tax in yearly form -> Our Fed withholding is -4821.99 * 12 = -57863.88
|
||||
# -> 238000.00 - 57863.88 = 180136.12
|
||||
# Step 2C -> Subtract the personal exemption -> 1500 for married filing separately
|
||||
# -> 180136.12 - 1500 = 178636.12
|
||||
# Step 2D -> Since income is so high, only 300$ per dependent -> 600. Subtract
|
||||
# -> 178636.12 - 600 = 178036.12
|
||||
#
|
||||
# Step 5 (after adding previous lines) -> Compute marginal taxes.
|
||||
# (500 * (2.00 / 100)) + (2500 * (4.00 / 100)) + ((178036.12 - 500 - 2500) * (5.00 / 100)) -> 8861.806
|
||||
# Convert back to pay period
|
||||
# wh = 8861.806 / 12.0 rounded -> 738.48
|
||||
wh = -738.48
|
||||
|
||||
employee = self._createEmployee()
|
||||
contract = self._createContract(employee,
|
||||
wage=salary,
|
||||
state_id=self.get_us_state('AL'),
|
||||
al_a4_sit_exemptions=filing_status,
|
||||
state_income_tax_additional_withholding=0.0,
|
||||
state_income_tax_exempt=False,
|
||||
al_a4_sit_dependents=dependents,
|
||||
schedule_pay=schedule_pay)
|
||||
|
||||
self._log('2019 Alabama tax first payslip monthly:')
|
||||
payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31')
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self.assertPayrollEqual(cats['EE_US_941_FIT'], -4822.00) # Hand Calculated.
|
||||
self.assertPayrollEqual(cats['ER_US_SUTA'], self.AL_UNEMP_MAX_WAGE * self.AL_UNEMP)
|
||||
self.assertPayrollEqual(cats['EE_US_SIT'], wh)
|
||||
|
||||
process_payslip(payslip)
|
||||
|
||||
def test_tax_exempt(self):
|
||||
salary = 5500.00
|
||||
wh = 0
|
||||
schedule_pay = 'weekly'
|
||||
dependents = 2
|
||||
|
||||
employee = self._createEmployee()
|
||||
contract = self._createContract(employee,
|
||||
wage=salary,
|
||||
state_id=self.get_us_state('AL'),
|
||||
al_a4_sit_exemptions='',
|
||||
state_income_tax_additional_withholding=0.0,
|
||||
state_income_tax_exempt=True,
|
||||
al_a4_sit_dependents=dependents,
|
||||
schedule_pay=schedule_pay)
|
||||
|
||||
self._log('2019 Alabama tax first payslip exempt:')
|
||||
payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31')
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self.assertPayrollEqual(cats['ER_US_SUTA'], salary * self.AL_UNEMP)
|
||||
self.assertPayrollEqual(cats.get('EE_US_SIT', 0.0), wh)
|
||||
|
||||
def test_additional_withholding(self):
|
||||
salary = 5500.0
|
||||
schedule_pay = 'weekly'
|
||||
additional_wh = 40.0
|
||||
dependents = 2
|
||||
# filing status default is single
|
||||
|
||||
# see https://revenue.alabama.gov/wp-content/uploads/2019/01/whbooklet_0119.pdf for reference
|
||||
# Hand Calculated Amount to Test
|
||||
# Step 1 -> 5500.00 for wages per period , 52.0 for monthly -> 5500 * 52.0 -> 286000.0
|
||||
# Step 2A -> standard deduction for highest wage bracket -> 2000. Subtract from yearly income
|
||||
# 286000.0 - 2000 = 284000.0
|
||||
# Step 2B -> Subtract Federal Income Tax in yearly form -> Our Fed withholding is -1422.4 * 52.0 = -73964.8
|
||||
# -> 284000.0 - 73964.8 = 210035.2
|
||||
# Step 2C -> Subtract the personal exemption -> 1500 for single
|
||||
# -> 210035.2 - 1500 = 208535.2
|
||||
# Step 2D -> Since income is so high, only 300$ per dependent -> 600. Subtract
|
||||
# -> 208535.2 - 600 = 207935.2
|
||||
#
|
||||
# Step 5 (after adding previous lines) -> Compute marginal taxes.
|
||||
# (500 * (2.00 / 100)) + (2500 * (4.00 / 100)) + ((207935.2 - 500 - 2500) * (5.00 / 100)) -> 10356.76
|
||||
# Convert back to pay period
|
||||
# wh = 10356.76 / 52.0 rounded -> 199.17
|
||||
wh = -199.17
|
||||
|
||||
employee = self._createEmployee()
|
||||
contract = self._createContract(employee,
|
||||
wage=salary,
|
||||
state_id=self.get_us_state('AL'),
|
||||
al_a4_sit_exemptions='S',
|
||||
state_income_tax_additional_withholding=40.0,
|
||||
state_income_tax_exempt=False,
|
||||
al_a4_sit_dependents=dependents,
|
||||
schedule_pay=schedule_pay)
|
||||
|
||||
self._log('2019 Alabama tax first payslip additional withholding:')
|
||||
payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31')
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self.assertPayrollEqual(cats['EE_US_941_FIT'], -1422.4) # Hand Calculated.
|
||||
self.assertPayrollEqual(cats['ER_US_SUTA'], salary * self.AL_UNEMP)
|
||||
self.assertPayrollEqual(cats['EE_US_SIT'], wh - additional_wh)
|
||||
|
||||
def test_personal_exemption(self):
|
||||
salary = 5500.0
|
||||
schedule_pay = 'weekly'
|
||||
# filing status default is single
|
||||
|
||||
# see https://revenue.alabama.gov/wp-content/uploads/2019/01/whbooklet_0119.pdf for reference
|
||||
# Hand Calculated Amount to Test
|
||||
# Step 1 -> 5500.00 for wages per period , 52.0 for monthly -> 5500 * 52.0 -> 286000.0
|
||||
# Step 2A -> standard deduction for highest wage bracket -> 2000. Subtract from yearly income
|
||||
# 286000.0 - 2000 = 284000.0
|
||||
# Step 2B -> Subtract Federal Income Tax in yearly form -> Our Fed withholding is -1422.4 * 52.0 = -73964.8
|
||||
# -> 284000.0 - 73964.8 = 210035.2
|
||||
# Step 2C -> Subtract the personal exemption -> 0 for personal exemptioon
|
||||
# -> 210035.2 - 0 = 210035.2
|
||||
# Step 2D -> Subtract per dependent. No dependents so 0
|
||||
# -> 210035.2 - 0 = 210035.2
|
||||
#
|
||||
# Step 5 (after adding previous lines) -> Compute marginal taxes.
|
||||
# (500 * (2.00 / 100)) + (2500 * (4.00 / 100)) + ((210035.2 - 500 - 2500) * (5.00 / 100)) -> 10461.76
|
||||
# Convert back to pay period
|
||||
# wh = 10461.76 / 52.0 rounded -> 201.19
|
||||
wh = -199.74
|
||||
|
||||
employee = self._createEmployee()
|
||||
contract = self._createContract(employee,
|
||||
wage=salary,
|
||||
state_id=self.get_us_state('AL'),
|
||||
al_a4_sit_exemptions='S',
|
||||
state_income_tax_additional_withholding=0.0,
|
||||
state_income_tax_exempt=False,
|
||||
al_a4_sit_dependents=0.0,
|
||||
schedule_pay=schedule_pay)
|
||||
|
||||
self._log('2019 Alabama tax first payslip additional withholding:')
|
||||
payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31')
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self.assertPayrollEqual(cats['EE_US_941_FIT'], -1422.4) # Hand Calculated.
|
||||
self.assertPayrollEqual(cats['ER_US_SUTA'], salary * self.AL_UNEMP)
|
||||
self.assertPayrollEqual(cats['EE_US_SIT'], wh)
|
||||
36
l10n_us_hr_payroll/tests/test_us_al_alabama_payslip_2020.py
Normal file
36
l10n_us_hr_payroll/tests/test_us_al_alabama_payslip_2020.py
Normal file
@@ -0,0 +1,36 @@
|
||||
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
|
||||
|
||||
from datetime import date, timedelta
|
||||
from .common import TestUsPayslip
|
||||
|
||||
|
||||
class TestUsALPayslip(TestUsPayslip):
|
||||
# Taxes and Rates
|
||||
AL_UNEMP_MAX_WAGE = 8000.00
|
||||
AL_UNEMP = 2.70
|
||||
|
||||
def _test_sit(self, wage, exempt, exemptions, additional_withholding, dependent, schedule_pay, date_start, expected_withholding):
|
||||
|
||||
employee = self._createEmployee()
|
||||
contract = self._createContract(employee,
|
||||
wage=wage,
|
||||
state_id=self.get_us_state('AL'),
|
||||
al_a4_sit_exemptions=exempt,
|
||||
state_income_tax_exempt=exemptions,
|
||||
state_income_tax_additional_withholding=additional_withholding,
|
||||
al_a4_sit_dependents=dependent,
|
||||
schedule_pay=schedule_pay)
|
||||
payslip = self._createPayslip(employee, date_start, date_start + timedelta(days=7))
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self._log('Computed period tax: ' + str(expected_withholding))
|
||||
self.assertPayrollEqual(cats.get('EE_US_SIT', 0.0), -expected_withholding)
|
||||
|
||||
def test_2020_taxes_example(self):
|
||||
self._test_er_suta('AL', self.AL_UNEMP, date(2020, 1, 1), wage_base=self.AL_UNEMP_MAX_WAGE)
|
||||
self._test_sit(10000.0, 'S', False, 0.0, 1.0, 'weekly', date(2020, 1, 1), 349.08)
|
||||
self._test_sit(850.0, 'M', False, 0.0, 2.0, 'weekly', date(2020, 1, 1), 29.98)
|
||||
self._test_sit(5000.0, 'H', False, 0.0, 2.0, 'bi-weekly', date(2020, 1, 1), 191.15)
|
||||
self._test_sit(20000.0, 'MS', False, 2.0, 0, 'monthly', date(2020, 1, 1), 757.6)
|
||||
self._test_sit(5500.0, '', True, 2.0, 150, 'weekly', date(2020, 1, 1), 0.00)
|
||||
72
l10n_us_hr_payroll/tests/test_us_ar_arkansas_payslip_2019.py
Normal file
72
l10n_us_hr_payroll/tests/test_us_ar_arkansas_payslip_2019.py
Normal file
@@ -0,0 +1,72 @@
|
||||
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
|
||||
|
||||
from .common import TestUsPayslip, process_payslip
|
||||
|
||||
|
||||
class TestUsARPayslip(TestUsPayslip):
|
||||
# https://www.dfa.arkansas.gov/images/uploads/incomeTaxOffice/whformula.pdf Calculation based on this file.
|
||||
AR_UNEMP_MAX_WAGE = 10000.00
|
||||
AR_UNEMP = -3.2 / 100.0
|
||||
AR_INC_TAX = -0.0535
|
||||
|
||||
def test_taxes_monthly(self):
|
||||
salary = 2127.0
|
||||
schedule_pay = 'monthly'
|
||||
|
||||
employee = self._createEmployee()
|
||||
contract = self._createContract(employee,
|
||||
wage=salary,
|
||||
state_id=self.get_us_state('AR'),
|
||||
state_income_tax_additional_withholding=0.0,
|
||||
ar_ar4ec_sit_allowances=2.0,
|
||||
state_income_tax_exempt=False,
|
||||
schedule_pay='monthly')
|
||||
|
||||
self._log('2019 Arkansas tax first payslip weekly:')
|
||||
payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31')
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
# Not exempt from rule 1 or rule 2 - unemployment wages., and actual unemployment.
|
||||
self.assertPayrollEqual(cats['ER_US_SUTA'], salary * self.AR_UNEMP)
|
||||
|
||||
process_payslip(payslip)
|
||||
|
||||
# Make a new payslip, this one will have maximums
|
||||
remaining_AR_UNEMP_wages = self.AR_UNEMP_MAX_WAGE - salary if (self.AR_UNEMP_MAX_WAGE - 2*salary < salary) else salary
|
||||
# We reached the cap of 10000.0 in the first payslip.
|
||||
self._log('2019 Arkansas tax second payslip weekly:')
|
||||
payslip = self._createPayslip(employee, '2019-02-01', '2019-02-28')
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self.assertPayrollEqual(cats['ER_US_SUTA'], remaining_AR_UNEMP_wages * self.AR_UNEMP)
|
||||
|
||||
def test_additional_withholding(self):
|
||||
salary = 5000.0
|
||||
schedule_pay = 'monthly'
|
||||
pay_periods = 12
|
||||
allowances = 2
|
||||
# TODO: comment on how it was calculated
|
||||
test_ar_amt = 2598.60
|
||||
|
||||
employee = self._createEmployee()
|
||||
contract = self._createContract(employee,
|
||||
wage=salary,
|
||||
state_id=self.get_us_state('AR'),
|
||||
state_income_tax_additional_withholding=100.0,
|
||||
ar_ar4ec_sit_allowances=2.0,
|
||||
state_income_tax_exempt=False,
|
||||
schedule_pay='monthly')
|
||||
|
||||
|
||||
self._log('2019 Arkansas tax first payslip weekly:')
|
||||
payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31')
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self.assertPayrollEqual(cats['ER_US_SUTA'], salary * self.AR_UNEMP)
|
||||
# TODO: change to hand the test_ar_amt already be divided by pay periods
|
||||
self.assertPayrollAlmostEqual(cats['EE_US_SIT'], -round(test_ar_amt / pay_periods) - 100)
|
||||
|
||||
process_payslip(payslip)
|
||||
35
l10n_us_hr_payroll/tests/test_us_ar_arkansas_payslip_2020.py
Normal file
35
l10n_us_hr_payroll/tests/test_us_ar_arkansas_payslip_2020.py
Normal file
@@ -0,0 +1,35 @@
|
||||
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
|
||||
|
||||
from datetime import date, timedelta
|
||||
from .common import TestUsPayslip
|
||||
|
||||
|
||||
class TestUsARPayslip(TestUsPayslip):
|
||||
# Taxes and Rates
|
||||
AR_UNEMP_MAX_WAGE = 8000.0
|
||||
AR_UNEMP = 2.9
|
||||
|
||||
def _test_sit(self, wage, exemptions, allowances, additional_withholding, schedule_pay, date_start, expected_withholding):
|
||||
|
||||
employee = self._createEmployee()
|
||||
contract = self._createContract(employee,
|
||||
wage=wage,
|
||||
state_id=self.get_us_state('AR'),
|
||||
state_income_tax_exempt=exemptions,
|
||||
state_income_tax_additional_withholding=additional_withholding,
|
||||
ar_ar4ec_sit_allowances=allowances,
|
||||
schedule_pay=schedule_pay)
|
||||
payslip = self._createPayslip(employee, date_start, date_start + timedelta(days=7))
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self._log('Computed period tax: ' + str(expected_withholding))
|
||||
self.assertPayrollEqual(cats.get('EE_US_SIT', 0.0), -expected_withholding)
|
||||
|
||||
def test_2020_taxes_example(self):
|
||||
self._test_er_suta('AR', self.AR_UNEMP, date(2020, 1, 1), wage_base=self.AR_UNEMP_MAX_WAGE)
|
||||
self._test_sit(5000.0, True, 0.0, 0, 'monthly', date(2020, 1, 1), 0.0)
|
||||
self._test_sit(5000.0, False, 0.0, 0, 'monthly', date(2020, 1, 1), 221.0)
|
||||
self._test_sit(700.0, False, 0.0, 150, 'weekly', date(2020, 1, 1), 175.0)
|
||||
self._test_sit(7000.0, False, 2.0, 0, 'semi-monthly', date(2020, 1, 1), 420.0)
|
||||
self._test_sit(3000.0, False, 1.0, 0, 'bi-weekly', date(2020, 1, 1), 142.0)
|
||||
72
l10n_us_hr_payroll/tests/test_us_az_arizona_payslip_2019.py
Normal file
72
l10n_us_hr_payroll/tests/test_us_az_arizona_payslip_2019.py
Normal file
@@ -0,0 +1,72 @@
|
||||
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
|
||||
|
||||
from .common import TestUsPayslip, process_payslip
|
||||
|
||||
|
||||
class TestUsAZPayslip(TestUsPayslip):
|
||||
|
||||
# TAXES AND RATES
|
||||
AZ_UNEMP_MAX_WAGE = 7000.00
|
||||
AZ_UNEMP = -(2.00 / 100.0)
|
||||
|
||||
def test_taxes_with_additional_wh(self):
|
||||
salary = 15000.00
|
||||
schedule_pay = 'weekly'
|
||||
withholding_percentage = 5.1
|
||||
percent_wh = (5.10 / 100) # 5.1%
|
||||
additional_wh = 12.50
|
||||
|
||||
wh_to_test = -((percent_wh * salary) + additional_wh)
|
||||
|
||||
employee = self._createEmployee()
|
||||
contract = self._createContract(employee,
|
||||
wage=salary,
|
||||
state_id=self.get_us_state('AZ'),
|
||||
state_income_tax_additional_withholding=12.50,
|
||||
az_a4_sit_withholding_percentage=withholding_percentage,
|
||||
schedule_pay=schedule_pay)
|
||||
|
||||
self._log('2019 Arizona tax first payslip weekly:')
|
||||
payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31')
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self.assertPayrollEqual(cats['ER_US_SUTA'], self.AZ_UNEMP_MAX_WAGE * self.AZ_UNEMP)
|
||||
self.assertPayrollEqual(cats['EE_US_SIT'], wh_to_test)
|
||||
|
||||
process_payslip(payslip)
|
||||
|
||||
remaining_AZ_UNEMP_wages = 0.0 # We already reached max unemployment wages.
|
||||
|
||||
self._log('2019 Arizona tax second payslip weekly:')
|
||||
payslip = self._createPayslip(employee, '2019-02-01', '2019-02-28')
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self.assertPayrollEqual(cats['ER_US_SUTA'], remaining_AZ_UNEMP_wages * self.AZ_UNEMP)
|
||||
|
||||
def test_taxes_monthly(self):
|
||||
salary = 1000.00
|
||||
schedule_pay = 'monthly'
|
||||
withholding_percentage = 2.7
|
||||
percent_wh = (2.70 / 100) # 2.7%
|
||||
additional_wh = 0.0
|
||||
wh_to_test = -((percent_wh * salary) + additional_wh)
|
||||
|
||||
employee = self._createEmployee()
|
||||
contract = self._createContract(employee,
|
||||
wage=salary,
|
||||
state_id=self.get_us_state('AZ'),
|
||||
state_income_tax_additional_withholding=0.0,
|
||||
az_a4_sit_withholding_percentage=withholding_percentage,
|
||||
schedule_pay=schedule_pay)
|
||||
|
||||
self._log('2019 Arizona tax first payslip monthly:')
|
||||
payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31')
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self.assertPayrollEqual(cats['ER_US_SUTA'], salary * self.AZ_UNEMP)
|
||||
self.assertPayrollEqual(cats['EE_US_SIT'], wh_to_test)
|
||||
|
||||
process_payslip(payslip)
|
||||
34
l10n_us_hr_payroll/tests/test_us_az_arizona_payslip_2020.py
Normal file
34
l10n_us_hr_payroll/tests/test_us_az_arizona_payslip_2020.py
Normal file
@@ -0,0 +1,34 @@
|
||||
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
|
||||
|
||||
from datetime import date, timedelta
|
||||
from .common import TestUsPayslip
|
||||
|
||||
|
||||
class TestUsAZPayslip(TestUsPayslip):
|
||||
# Taxes and Rates
|
||||
AZ_UNEMP_MAX_WAGE = 7000.0
|
||||
AZ_UNEMP = 2.0
|
||||
|
||||
def _test_sit(self, wage, additional_withholding, withholding_percent, schedule_pay, date_start, expected_withholding):
|
||||
|
||||
employee = self._createEmployee()
|
||||
contract = self._createContract(employee,
|
||||
wage=wage,
|
||||
state_id=self.get_us_state('AZ'),
|
||||
state_income_tax_additional_withholding=additional_withholding,
|
||||
az_a4_sit_withholding_percentage=withholding_percent,
|
||||
schedule_pay=schedule_pay)
|
||||
payslip = self._createPayslip(employee, date_start, date_start + timedelta(days=7))
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self._log('Computed period tax: ' + str(expected_withholding))
|
||||
self.assertPayrollEqual(cats.get('EE_US_SIT', 0.0), -expected_withholding)
|
||||
|
||||
def test_2020_taxes_example(self):
|
||||
self._test_er_suta('AZ', self.AZ_UNEMP, date(2020, 1, 1), wage_base=self.AZ_UNEMP_MAX_WAGE)
|
||||
self._test_sit(1000.0, 0.0, 2.70, 'monthly', date(2020, 1, 1), 27.0)
|
||||
self._test_sit(1000.0, 10.0, 2.70, 'monthly', date(2020, 1, 1), 37.0)
|
||||
self._test_sit(15000.0, 0.0, 3.60, 'weekly', date(2020, 1, 1), 540.0)
|
||||
self._test_sit(8000.0, 0.0, 4.20, 'semi-monthly', date(2020, 1, 1), 336.0)
|
||||
self._test_sit(8000.0, 0.0, 0.00, 'semi-monthly', date(2020, 1, 1), 0.0)
|
||||
245
l10n_us_hr_payroll/tests/test_us_ca_california_payslip_2019.py
Normal file
245
l10n_us_hr_payroll/tests/test_us_ca_california_payslip_2019.py
Normal file
@@ -0,0 +1,245 @@
|
||||
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
|
||||
|
||||
from .common import TestUsPayslip, process_payslip
|
||||
|
||||
|
||||
class TestUsCAPayslip(TestUsPayslip):
|
||||
###
|
||||
# Taxes and Rates
|
||||
###
|
||||
CA_MAX_WAGE = 7000
|
||||
CA_UIT = -3.5 / 100.0
|
||||
CA_ETT = -0.1 / 100.0
|
||||
CA_SDI = -1.0 / 100.0
|
||||
|
||||
# Examples from https://www.edd.ca.gov/pdf_pub_ctr/20methb.pdf
|
||||
def test_example_a(self):
|
||||
salary = 210
|
||||
schedule_pay = 'weekly'
|
||||
allowances = 1
|
||||
additional_allowances = 0
|
||||
|
||||
wh = 0.00
|
||||
|
||||
employee = self._createEmployee()
|
||||
|
||||
contract = self._createContract(employee,
|
||||
wage=salary,
|
||||
state_id=self.get_us_state('CA'),
|
||||
ca_de4_sit_filing_status='single',
|
||||
state_income_tax_additional_withholding=0.0,
|
||||
ca_de4_sit_allowances=allowances,
|
||||
ca_de4_sit_additional_allowances=additional_allowances,
|
||||
schedule_pay=schedule_pay)
|
||||
|
||||
self._log('2019 California tax first payslip:')
|
||||
payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31')
|
||||
|
||||
payslip.compute_sheet()
|
||||
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self.assertPayrollEqual(cats['ER_US_SUTA'], salary * (self.CA_UIT + self.CA_ETT))
|
||||
self.assertPayrollEqual(cats['EE_US_SUTA'], salary * self.CA_SDI)
|
||||
self.assertPayrollEqual(cats['EE_US_SIT'], wh)
|
||||
|
||||
process_payslip(payslip)
|
||||
|
||||
def test_example_b(self):
|
||||
salary = 1250
|
||||
schedule_pay = 'bi-weekly'
|
||||
allowances = 2
|
||||
additional_allowances = 1
|
||||
|
||||
# Example B
|
||||
subject_to_withholding = salary - 38
|
||||
taxable_income = subject_to_withholding - 339
|
||||
computed_tax = (taxable_income - 632) * 0.022 + 6.95 # 6.95 Marginal Amount
|
||||
wh = computed_tax - 9.65 # two exemption allowances
|
||||
wh = -wh
|
||||
|
||||
employee = self._createEmployee()
|
||||
contract = self._createContract(employee,
|
||||
wage=salary,
|
||||
state_id=self.get_us_state('CA'),
|
||||
ca_de4_sit_filing_status='married',
|
||||
state_income_tax_additional_withholding=0.0,
|
||||
ca_de4_sit_allowances=allowances,
|
||||
ca_de4_sit_additional_allowances=additional_allowances,
|
||||
schedule_pay=schedule_pay)
|
||||
|
||||
self._log('2019 California tax first payslip:')
|
||||
payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31')
|
||||
|
||||
payslip.compute_sheet()
|
||||
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self.assertPayrollEqual(cats['ER_US_SUTA'], salary * (self.CA_UIT + self.CA_ETT))
|
||||
self.assertPayrollEqual(cats['EE_US_SUTA'], salary * self.CA_SDI)
|
||||
self.assertPayrollEqual(cats['EE_US_SIT'], wh)
|
||||
|
||||
process_payslip(payslip)
|
||||
|
||||
|
||||
def test_example_c(self):
|
||||
salary = 4100
|
||||
schedule_pay = 'monthly'
|
||||
allowances = 5
|
||||
additional_allowances = 0.0
|
||||
|
||||
wh = -9.3
|
||||
|
||||
employee = self._createEmployee()
|
||||
contract = self._createContract(employee,
|
||||
wage=salary,
|
||||
state_id=self.get_us_state('CA'),
|
||||
ca_de4_sit_filing_status='married',
|
||||
state_income_tax_additional_withholding=0.0,
|
||||
ca_de4_sit_allowances=allowances,
|
||||
ca_de4_sit_additional_allowances=additional_allowances,
|
||||
schedule_pay=schedule_pay)
|
||||
|
||||
self._log('2019 California tax first payslip:')
|
||||
payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31')
|
||||
|
||||
payslip.compute_sheet()
|
||||
|
||||
cats = self._getCategories(payslip)
|
||||
self.assertPayrollEqual(cats['ER_US_SUTA'], salary * (self.CA_UIT + self.CA_ETT))
|
||||
self.assertPayrollEqual(cats['EE_US_SUTA'], salary * self.CA_SDI)
|
||||
self.assertPayrollEqual(cats['EE_US_SIT'], wh)
|
||||
|
||||
process_payslip(payslip)
|
||||
|
||||
# Make a new payslip, this one will have maximums
|
||||
|
||||
remaining_ca_uit_wages = self.CA_MAX_WAGE - salary if (self.CA_MAX_WAGE - 2 * salary < salary) \
|
||||
else salary
|
||||
|
||||
self._log('2019 California tax second payslip:')
|
||||
payslip = self._createPayslip(employee, '2019-02-01', '2019-02-28')
|
||||
|
||||
payslip.compute_sheet()
|
||||
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self.assertPayrollEqual(cats['ER_US_SUTA'], round((remaining_ca_uit_wages * (self.CA_UIT + self.CA_ETT)), 2))
|
||||
|
||||
def test_example_d(self):
|
||||
salary = 800
|
||||
schedule_pay = 'weekly'
|
||||
allowances = 3
|
||||
additional_allowances = 0
|
||||
|
||||
wh = -3.18
|
||||
|
||||
employee = self._createEmployee()
|
||||
contract = self._createContract(employee,
|
||||
wage=salary,
|
||||
state_id=self.get_us_state('CA'),
|
||||
ca_de4_sit_filing_status='head_household',
|
||||
state_income_tax_additional_withholding=0.0,
|
||||
ca_de4_sit_allowances=allowances,
|
||||
ca_de4_sit_additional_allowances=additional_allowances,
|
||||
schedule_pay=schedule_pay)
|
||||
|
||||
self._log('2019 California tax first payslip:')
|
||||
payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31')
|
||||
|
||||
payslip.compute_sheet()
|
||||
|
||||
cats = self._getCategories(payslip)
|
||||
self.assertPayrollEqual(cats['ER_US_SUTA'], salary * (self.CA_UIT + self.CA_ETT))
|
||||
self.assertPayrollEqual(cats['EE_US_SUTA'], salary * self.CA_SDI)
|
||||
self.assertPayrollEqual(cats['EE_US_SIT'], wh)
|
||||
|
||||
process_payslip(payslip)
|
||||
|
||||
# Make a new payslip, this one will have maximums
|
||||
|
||||
remaining_ca_uit_wages = self.CA_MAX_WAGE - salary if (self.CA_MAX_WAGE - 2 * salary < salary) \
|
||||
else salary
|
||||
|
||||
self._log('2019 California tax second payslip:')
|
||||
payslip = self._createPayslip(employee, '2019-02-01', '2019-02-28')
|
||||
|
||||
payslip.compute_sheet()
|
||||
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self.assertPayrollEqual(cats['ER_US_SUTA'], round((remaining_ca_uit_wages * (self.CA_UIT + self.CA_ETT)), 2))
|
||||
|
||||
def test_example_e(self):
|
||||
salary = 1800
|
||||
schedule_pay = 'semi-monthly'
|
||||
allowances = 4
|
||||
additional_allowances = 0
|
||||
|
||||
wh = -3.08
|
||||
|
||||
employee = self._createEmployee()
|
||||
contract = self._createContract(employee,
|
||||
wage=salary,
|
||||
state_id=self.get_us_state('CA'),
|
||||
ca_de4_sit_filing_status='married',
|
||||
state_income_tax_additional_withholding=0.0,
|
||||
ca_de4_sit_allowances=allowances,
|
||||
ca_de4_sit_additional_allowances=additional_allowances,
|
||||
schedule_pay=schedule_pay)
|
||||
|
||||
self._log('2019 California tax first payslip:')
|
||||
payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31')
|
||||
|
||||
payslip.compute_sheet()
|
||||
|
||||
cats = self._getCategories(payslip)
|
||||
self.assertPayrollEqual(cats['ER_US_SUTA'], salary * (self.CA_UIT + self.CA_ETT))
|
||||
self.assertPayrollEqual(cats['EE_US_SUTA'], salary * self.CA_SDI)
|
||||
self.assertPayrollEqual(cats['EE_US_SIT'], wh)
|
||||
|
||||
process_payslip(payslip)
|
||||
|
||||
# Make a new payslip, this one will have maximums
|
||||
|
||||
remaining_ca_uit_wages = self.CA_MAX_WAGE - salary if (self.CA_MAX_WAGE - 2 * salary < salary) \
|
||||
else salary
|
||||
|
||||
self._log('2019 California tax second payslip:')
|
||||
payslip = self._createPayslip(employee, '2019-02-01', '2019-02-28')
|
||||
|
||||
payslip.compute_sheet()
|
||||
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self.assertPayrollEqual(cats['ER_US_SUTA'], round((remaining_ca_uit_wages * (self.CA_UIT + self.CA_ETT)), 2))
|
||||
|
||||
def test_example_f(self):
|
||||
salary = 45000
|
||||
schedule_pay = 'annually'
|
||||
allowances = 4
|
||||
additional_allowances = 0
|
||||
|
||||
wh = -113.85
|
||||
|
||||
employee = self._createEmployee()
|
||||
contract = self._createContract(employee,
|
||||
wage=salary,
|
||||
state_id=self.get_us_state('CA'),
|
||||
ca_de4_sit_filing_status='married',
|
||||
state_income_tax_additional_withholding=0.0,
|
||||
ca_de4_sit_allowances=allowances,
|
||||
ca_de4_sit_additional_allowances=additional_allowances,
|
||||
schedule_pay=schedule_pay)
|
||||
|
||||
self._log('2019 California tax first payslip:')
|
||||
payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31')
|
||||
|
||||
payslip.compute_sheet()
|
||||
|
||||
cats = self._getCategories(payslip)
|
||||
self.assertPayrollEqual(cats['ER_US_SUTA'], self.CA_MAX_WAGE * (self.CA_UIT + self.CA_ETT))
|
||||
self.assertPayrollEqual(cats['EE_US_SUTA'], self.CA_MAX_WAGE * self.CA_SDI)
|
||||
self.assertPayrollEqual(cats['EE_US_SIT'], wh)
|
||||
|
||||
process_payslip(payslip)
|
||||
43
l10n_us_hr_payroll/tests/test_us_ca_california_payslip_2020.py
Executable file
43
l10n_us_hr_payroll/tests/test_us_ca_california_payslip_2020.py
Executable file
@@ -0,0 +1,43 @@
|
||||
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
|
||||
|
||||
from datetime import date, timedelta
|
||||
from .common import TestUsPayslip
|
||||
|
||||
|
||||
class TestUsCAPayslip(TestUsPayslip):
|
||||
###
|
||||
# 2020 Taxes and Rates
|
||||
###
|
||||
CA_UNEMP_MAX_WAGE = 7000.0 # Note that this is used for SDI and FLI as well
|
||||
CA_UIT = 3.4
|
||||
CA_ETT = 0.1
|
||||
CA_SDI = 1.0
|
||||
|
||||
def _test_sit(self, wage, filing_status, allowances, additional_allowances, additional_withholding, schedule_pay, date_start, expected_withholding):
|
||||
employee = self._createEmployee()
|
||||
contract = self._createContract(employee,
|
||||
wage=wage,
|
||||
state_id=self.get_us_state('CA'),
|
||||
ca_de4_sit_filing_status=filing_status,
|
||||
ca_de4_sit_allowances=allowances,
|
||||
ca_de4_sit_additional_allowances=additional_allowances,
|
||||
state_income_tax_additional_withholding=additional_withholding,
|
||||
schedule_pay=schedule_pay)
|
||||
payslip = self._createPayslip(employee, date_start, date_start + timedelta(days=7))
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
self.assertPayrollAlmostEqual(cats.get('EE_US_SIT', 0.0), -expected_withholding if filing_status else 0.0)
|
||||
|
||||
def test_2020_taxes_example1(self):
|
||||
combined_er_rate = self.CA_UIT + self.CA_ETT
|
||||
self._test_er_suta('CA', combined_er_rate, date(2020, 1, 1), wage_base=self.CA_UNEMP_MAX_WAGE)
|
||||
self._test_ee_suta('CA', self.CA_SDI, date(2020, 1, 1), wage_base=self.CA_UNEMP_MAX_WAGE, relaxed=True)
|
||||
# these expected values come from https://www.edd.ca.gov/pdf_pub_ctr/20methb.pdf
|
||||
self._test_sit(210.0, 'single', 1, 0, 0, 'weekly', date(2020, 1, 1), 0.00)
|
||||
self._test_sit(1250.0, 'married', 2, 1, 0, 'bi-weekly', date(2020, 1, 1), 1.23)
|
||||
self._test_sit(4100.0, 'married', 5, 0, 0, 'monthly', date(2020, 1, 1), 1.5)
|
||||
self._test_sit(800.0, 'head_household', 3, 0, 0, 'weekly', date(2020, 1, 1), 2.28)
|
||||
self._test_sit(1800.0, 'married', 4, 0, 0, 'semi-monthly', date(2020, 1, 1), 0.84)
|
||||
self._test_sit(45000.0, 'married', 4, 0, 0, 'annually', date(2020, 1, 1), 59.78)
|
||||
self._test_sit(45000.0, 'married', 4, 0, 20.0, 'annually', date(2020, 1, 1), 79.78)
|
||||
self._test_sit(6000.0, '', 4, 0, 20.0, 'annually', date(2020, 1, 1), 0.00)
|
||||
37
l10n_us_hr_payroll/tests/test_us_co_colorado_payslip_2020.py
Executable file
37
l10n_us_hr_payroll/tests/test_us_co_colorado_payslip_2020.py
Executable file
@@ -0,0 +1,37 @@
|
||||
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
|
||||
|
||||
from datetime import date, timedelta
|
||||
from .common import TestUsPayslip
|
||||
|
||||
|
||||
class TestUsCOPayslip(TestUsPayslip):
|
||||
###
|
||||
# 2020 Taxes and Rates
|
||||
###
|
||||
CO_UNEMP_MAX_WAGE = 13600.0
|
||||
CO_UNEMP = 1.7
|
||||
|
||||
def _test_sit(self, wage, filing_status, additional_withholding, schedule_pay, date_start, expected_withholding, state_income_tax_exempt=False):
|
||||
employee = self._createEmployee()
|
||||
contract = self._createContract(employee,
|
||||
wage=wage,
|
||||
state_id=self.get_us_state('CO'),
|
||||
fed_941_fit_w4_filing_status=filing_status,
|
||||
state_income_tax_additional_withholding=additional_withholding,
|
||||
state_income_tax_exempt=state_income_tax_exempt,
|
||||
schedule_pay=schedule_pay)
|
||||
payslip = self._createPayslip(employee, date_start, date_start + timedelta(days=7))
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self._log('Computed period tax: ' + str(expected_withholding))
|
||||
self.assertPayrollEqual(cats.get('EE_US_SIT', 0.0), -expected_withholding)
|
||||
|
||||
def test_2020_taxes_example(self):
|
||||
self._test_er_suta('CO', self.CO_UNEMP, date(2020, 1, 1), wage_base=self.CO_UNEMP_MAX_WAGE)
|
||||
self._test_sit(5000.0, 'married', 0.0, 'semi-monthly', date(2020, 1, 1), 216.07)
|
||||
self._test_sit(800.0, 'single', 0.0, 'weekly', date(2020, 1, 1), 33.48)
|
||||
self._test_sit(20000.0, 'married', 0.0, 'quarterly', date(2020, 1, 1), 833.4)
|
||||
self._test_sit(20000.0, 'married', 10.0, 'quarterly', date(2020, 1, 1), 843.4)
|
||||
self._test_sit(20000.0, 'married', 0.0, 'quarterly', date(2020, 1, 1), 0.0, True)
|
||||
self._test_sit(800.0, '', 0.0, 'weekly', date(2020, 1, 1), 0.00)
|
||||
121
l10n_us_hr_payroll/tests/test_us_ct_connecticut_payslip_2019.py
Normal file
121
l10n_us_hr_payroll/tests/test_us_ct_connecticut_payslip_2019.py
Normal file
@@ -0,0 +1,121 @@
|
||||
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
|
||||
|
||||
from .common import TestUsPayslip, process_payslip
|
||||
|
||||
|
||||
class TestUsCTPayslip(TestUsPayslip):
|
||||
# TAXES AND RATES
|
||||
CT_UNEMP_MAX_WAGE = 15000.00
|
||||
CT_UNEMP = -(3.40 / 100.0)
|
||||
|
||||
def test_taxes_weekly_with_additional_wh(self):
|
||||
|
||||
# Tax tables can be found here:
|
||||
# https://portal.ct.gov/-/media/DRS/Publications/pubsip/2019/IP-2019(1).pdf?la=en
|
||||
# Step 1 - Wages per period -> 10000.00
|
||||
salary = 10000.00
|
||||
# Step 2 and 3 - Annual wages -> 10000.00 * 52.0 -> 520000.0
|
||||
schedule_pay = 'weekly'
|
||||
# Step 4 Employee Withholding Code -> A
|
||||
wh_code = 'a'
|
||||
# Step 5 - Use annual wages and withholding code with table for exemption amount.
|
||||
# exemption_amt = 0 since highest bracket.
|
||||
# Step 6 - Subtract 5 from 3 for taxable income.
|
||||
# taxable income = 520000.00 since we do not have an exemption.
|
||||
# Step 7 - Determine initial amount from table
|
||||
# initial = 31550 + ((6.99 / 100) * (520000.00 - 500000.00))
|
||||
# 32948.0
|
||||
# Step 8 - Determine the tax rate phase out add back from table.
|
||||
# phase_out = 200
|
||||
# Step 9 - Determine the recapture amount from table.
|
||||
# Close to top, but not top. -> 2900
|
||||
# Step 10 - Add Step 7, 8, 9
|
||||
# 32948.0 + 200 + 2900.00 - > 36048.0
|
||||
# Step 11 - Determine decimal amount from personal tax credits.
|
||||
# We get no tax credit.
|
||||
# Step 12 - Multiple Step 10 by 1.00 - Step 11
|
||||
# 36048.0 * 1.00 = 36048.0
|
||||
# Step 13 - Divide by the number of pay periods.
|
||||
# 36048.0 / 52.0 = 693.23
|
||||
# Step 14 & 15 & 16- Add / Subtract the additional or under withholding amount. Then Add this to the amount
|
||||
# for withholding per period.
|
||||
additional_wh = 12.50
|
||||
# 693.23 + 12.50 ->
|
||||
wh = -705.73
|
||||
|
||||
employee = self._createEmployee()
|
||||
contract = self._createContract(employee,
|
||||
wage=salary,
|
||||
state_id=self.get_us_state('CT'),
|
||||
ct_w4na_sit_code=wh_code,
|
||||
state_income_tax_additional_withholding=additional_wh,
|
||||
schedule_pay=schedule_pay)
|
||||
|
||||
self._log('2019 Connecticut tax first payslip weekly:')
|
||||
payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31')
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self.assertPayrollEqual(cats['ER_US_SUTA'], salary * self.CT_UNEMP)
|
||||
self.assertPayrollEqual(cats['EE_US_SIT'], wh)
|
||||
|
||||
process_payslip(payslip)
|
||||
|
||||
remaining_CT_UNEMP_wages = 5000.00 # We already reached the maximum wage for unemployment insurance.
|
||||
self._log('2019 Connecticut tax second payslip weekly:')
|
||||
payslip = self._createPayslip(employee, '2019-02-01', '2019-02-28')
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self.assertPayrollEqual(cats['ER_US_SUTA'], remaining_CT_UNEMP_wages * self.CT_UNEMP)
|
||||
|
||||
def test_taxes_weekly_with_different_code(self):
|
||||
|
||||
# Tax tables can be found here:
|
||||
# https://portal.ct.gov/-/media/DRS/Publications/pubsip/2019/IP-2019(1).pdf?la=en
|
||||
# Step 1 - Wages per period -> 15000.00
|
||||
salary = 15000.00
|
||||
# Step 2 and 3 - Annual wages -> 15000.00 * 12.0 -> 180000.0
|
||||
schedule_pay = 'monthly'
|
||||
# Step 4 Employee Withholding Code -> B
|
||||
wh_code = 'b'
|
||||
# Step 5 - Use annual wages and withholding code with table for exemption amount.
|
||||
# exemption_amt = 0 since highest bracket.
|
||||
# Step 6 - Subtract 5 from 3 for taxable income.
|
||||
# taxable income = 180000.0 since we do not have an exemption.
|
||||
# Step 7 - Determine initial amount from table
|
||||
# initial = 8080 + ((6.00 / 100) * (180000.0 - 160000))
|
||||
# 9280.0
|
||||
# Step 8 - Determine the tax rate phase out add back from table.
|
||||
# phase_out = 320
|
||||
# Step 9 - Determine the recapture amount from table.
|
||||
# Bottom -> 0
|
||||
# Step 10 - Add Step 7, 8, 9
|
||||
# 9280.0 + 320 + 0 - > 9600.0
|
||||
# Step 11 - Determine decimal amount from personal tax credits.
|
||||
# We get no tax credit.
|
||||
# Step 12 - Multiple Step 10 by 1.00 - Step 11
|
||||
# 9600.0 * 1.00 = 9600.0
|
||||
# Step 13 - Divide by the number of pay periods.
|
||||
# 9600.0 / 12.0 = 800.0
|
||||
# Step 14 & 15 & 16- Add / Subtract the additional or under withholding amount. Then Add this to the amount
|
||||
# for withholding per period.
|
||||
additional_wh = 15.00
|
||||
# 800.0 + 15.00 ->
|
||||
wh = -815.0
|
||||
|
||||
employee = self._createEmployee()
|
||||
contract = self._createContract(employee,
|
||||
wage=salary,
|
||||
state_id=self.get_us_state('CT'),
|
||||
ct_w4na_sit_code=wh_code,
|
||||
state_income_tax_additional_withholding=additional_wh,
|
||||
schedule_pay=schedule_pay)
|
||||
|
||||
self._log('2019 Connecticut tax first payslip monthly:')
|
||||
payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31')
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self.assertPayrollEqual(cats['ER_US_SUTA'], self.CT_UNEMP_MAX_WAGE * self.CT_UNEMP)
|
||||
self.assertPayrollEqual(cats['EE_US_SIT'], wh)
|
||||
@@ -0,0 +1,35 @@
|
||||
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
|
||||
|
||||
from datetime import date, timedelta
|
||||
from .common import TestUsPayslip
|
||||
|
||||
|
||||
class TestUsCTPayslip(TestUsPayslip):
|
||||
# Taxes and Rates
|
||||
CT_UNEMP_MAX_WAGE = 15000.0
|
||||
CT_UNEMP = 3.2
|
||||
|
||||
def _test_sit(self, wage, withholding_code, additional_withholding, schedule_pay, date_start, expected_withholding):
|
||||
|
||||
employee = self._createEmployee()
|
||||
contract = self._createContract(employee,
|
||||
wage=wage,
|
||||
state_id=self.get_us_state('CT'),
|
||||
ct_w4na_sit_code=withholding_code,
|
||||
state_income_tax_additional_withholding=additional_withholding,
|
||||
schedule_pay=schedule_pay)
|
||||
payslip = self._createPayslip(employee, date_start, date_start + timedelta(days=7))
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self._log('Computed period tax: ' + str(expected_withholding))
|
||||
self.assertPayrollEqual(cats.get('EE_US_SIT', 0.0), -expected_withholding)
|
||||
|
||||
def test_2020_taxes_example(self):
|
||||
self._test_er_suta('CT', self.CT_UNEMP, date(2020, 1, 1), wage_base=self.CT_UNEMP_MAX_WAGE)
|
||||
self._test_sit(10000.0, 'a', 0.0, 'weekly', date(2020, 1, 1), 693.23)
|
||||
self._test_sit(12000.0, 'b', 15.0, 'bi-weekly', date(2020, 1, 1), 688.85)
|
||||
self._test_sit(5000.0, 'f', 15.0, 'monthly', date(2020, 1, 1), 230.25)
|
||||
self._test_sit(15000.0, 'c', 0.0, 'monthly', date(2020, 1, 1), 783.33)
|
||||
self._test_sit(18000.0, 'b', 0.0, 'weekly', date(2020, 1, 1), 1254.35)
|
||||
self._test_sit(500.0, 'd', 0.0, 'weekly', date(2020, 1, 1), 21.15)
|
||||
36
l10n_us_hr_payroll/tests/test_us_de_delaware_payslip_2020.py
Executable file
36
l10n_us_hr_payroll/tests/test_us_de_delaware_payslip_2020.py
Executable file
@@ -0,0 +1,36 @@
|
||||
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
|
||||
|
||||
from datetime import date, timedelta
|
||||
from .common import TestUsPayslip
|
||||
|
||||
|
||||
class TestUsDEPayslip(TestUsPayslip):
|
||||
###
|
||||
# 2020 Taxes and Rates
|
||||
###
|
||||
DE_UNEMP_MAX_WAGE = 16500.0
|
||||
DE_UNEMP = 1.50
|
||||
# Calculation based on section 17. https://revenue.delaware.gov/employers-guide-withholding-regulations-employers-duties/
|
||||
|
||||
def _test_sit(self, wage, filing_status, additional_withholding, dependents, schedule_pay, date_start, expected_withholding):
|
||||
employee = self._createEmployee()
|
||||
contract = self._createContract(employee,
|
||||
wage=wage,
|
||||
state_id=self.get_us_state('DE'),
|
||||
de_w4_sit_filing_status=filing_status,
|
||||
state_income_tax_additional_withholding=additional_withholding,
|
||||
de_w4_sit_dependent=dependents,
|
||||
schedule_pay=schedule_pay)
|
||||
payslip = self._createPayslip(employee, date_start, date_start + timedelta(days=7))
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self._log('Computed period tax: ' + str(expected_withholding))
|
||||
self.assertPayrollEqual(cats.get('EE_US_SIT', 0.0), -expected_withholding)
|
||||
|
||||
def test_2020_taxes_example(self):
|
||||
self._test_er_suta('DE', self.DE_UNEMP, date(2020, 1, 1), wage_base=self.DE_UNEMP_MAX_WAGE)
|
||||
self._test_sit(480.77, 'single', 0.0, 1.0, 'weekly', date(2020, 1, 1), 13.88)
|
||||
self._test_sit(5000.0, 'single', 0.0, 2.0, 'monthly', date(2020, 1, 1), 211.93)
|
||||
self._test_sit(5000.0, 'single', 10.0, 1.0, 'monthly', date(2020, 1, 1), 231.1)
|
||||
self._test_sit(20000.0, 'married', 0.0, 3.0, 'quarterly', date(2020, 1, 1), 876.0)
|
||||
84
l10n_us_hr_payroll/tests/test_us_fl_florida_payslip_2019.py
Executable file
84
l10n_us_hr_payroll/tests/test_us_fl_florida_payslip_2019.py
Executable file
@@ -0,0 +1,84 @@
|
||||
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
|
||||
|
||||
from .common import TestUsPayslip, process_payslip
|
||||
from odoo.addons.l10n_us_hr_payroll.models.hr_contract import USHRContract
|
||||
|
||||
|
||||
class TestUsFlPayslip(TestUsPayslip):
|
||||
###
|
||||
# 2019 Taxes and Rates
|
||||
###
|
||||
FL_UNEMP_MAX_WAGE = 7000.0
|
||||
FL_UNEMP = -2.7 / 100.0
|
||||
|
||||
def test_2019_taxes(self):
|
||||
salary = 5000.0
|
||||
|
||||
employee = self._createEmployee()
|
||||
contract = self._createContract(employee,
|
||||
wage=salary,
|
||||
state_id=self.get_us_state('FL'))
|
||||
|
||||
self._log('2019 Florida tax first payslip:')
|
||||
payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31')
|
||||
|
||||
payslip.compute_sheet()
|
||||
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self.assertPayrollEqual(cats['ER_US_SUTA'], salary * self.FL_UNEMP)
|
||||
|
||||
process_payslip(payslip)
|
||||
|
||||
# Make a new payslip, this one will have maximums
|
||||
|
||||
remaining_fl_unemp_wages = self.FL_UNEMP_MAX_WAGE - salary if (self.FL_UNEMP_MAX_WAGE - 2*salary < salary) \
|
||||
else salary
|
||||
|
||||
self._log('2019 Florida tax second payslip:')
|
||||
payslip = self._createPayslip(employee, '2019-02-01', '2019-02-28')
|
||||
|
||||
payslip.compute_sheet()
|
||||
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self.assertPayrollEqual(cats['ER_US_SUTA'], remaining_fl_unemp_wages * self.FL_UNEMP)
|
||||
|
||||
def test_2019_taxes_with_external(self):
|
||||
salary = 5000.0
|
||||
external_wages = 6000.0
|
||||
|
||||
employee = self._createEmployee()
|
||||
contract = self._createContract(employee,
|
||||
wage=salary,
|
||||
external_wages=external_wages,
|
||||
state_id=self.get_us_state('FL'))
|
||||
|
||||
self._log('2019 Forida_external tax first payslip:')
|
||||
payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31')
|
||||
|
||||
payslip.compute_sheet()
|
||||
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self.assertPayrollEqual(cats['ER_US_SUTA'], (self.FL_UNEMP_MAX_WAGE - external_wages) * self.FL_UNEMP)
|
||||
|
||||
def test_2019_taxes_with_state_exempt(self):
|
||||
salary = 5000.0
|
||||
external_wages = 6000.0
|
||||
|
||||
employee = self._createEmployee()
|
||||
contract = self._createContract(employee,
|
||||
wage=salary,
|
||||
external_wages=external_wages,
|
||||
futa_type=USHRContract.FUTA_TYPE_BASIC,
|
||||
state_id=self.get_us_state('FL'))
|
||||
|
||||
self._log('2019 Forida_external tax first payslip:')
|
||||
payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31')
|
||||
|
||||
payslip.compute_sheet()
|
||||
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self.assertPayrollEqual(cats.get('ER_US_SUTA', 0.0), 0.0)
|
||||
16
l10n_us_hr_payroll/tests/test_us_fl_florida_payslip_2020.py
Executable file
16
l10n_us_hr_payroll/tests/test_us_fl_florida_payslip_2020.py
Executable file
@@ -0,0 +1,16 @@
|
||||
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
|
||||
|
||||
from datetime import date
|
||||
from .common import TestUsPayslip
|
||||
|
||||
|
||||
class TestUsFlPayslip(TestUsPayslip):
|
||||
###
|
||||
# 2020 Taxes and Rates
|
||||
###
|
||||
FL_UNEMP_MAX_WAGE = 7000.0
|
||||
FL_UNEMP = 2.7
|
||||
|
||||
def test_2020_taxes(self):
|
||||
# Only has state unemployment
|
||||
self._test_er_suta('FL', self.FL_UNEMP, date(2020, 1, 1), wage_base=self.FL_UNEMP_MAX_WAGE)
|
||||
135
l10n_us_hr_payroll/tests/test_us_ga_georgia_payslip_2019.py
Executable file
135
l10n_us_hr_payroll/tests/test_us_ga_georgia_payslip_2019.py
Executable file
@@ -0,0 +1,135 @@
|
||||
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
|
||||
|
||||
from .common import TestUsPayslip, process_payslip
|
||||
|
||||
|
||||
class TestUsGAPayslip(TestUsPayslip):
|
||||
|
||||
# TAXES AND RATES
|
||||
GA_UNEMP_MAX_WAGE = 9500.00
|
||||
GA_UNEMP = -(2.70 / 100.0)
|
||||
|
||||
def test_taxes_weekly_single_with_additional_wh(self):
|
||||
salary = 15000.00
|
||||
schedule_pay = 'weekly'
|
||||
allowances = 1
|
||||
filing_status = 'single'
|
||||
additional_wh = 12.50
|
||||
# Hand Calculated Amount to Test
|
||||
# Step 1 - Subtract standard deduction from wages. Std Deduct for single weekly is 88.50
|
||||
# step1 = 15000.00 - 88.50 = 14911.5
|
||||
# Step 2 - Subtract personal allowance from step1. Allowance for single weekly is 51.92
|
||||
# step2 = step1 - 51.92 = 14859.58
|
||||
# Step 3 - Subtract amount for dependents. Weekly dependent allowance is 57.50
|
||||
# step3 = 14859.58 - 57.50 = 14802.08
|
||||
# Step 4 -Determine wh amount from tables
|
||||
# step4 = 4.42 + ((5.75 / 100.00) * (14802.08 - 135.00))
|
||||
# Add additional_wh
|
||||
# wh = 847.7771 + 12.50 = 860.2771
|
||||
wh = -860.28
|
||||
|
||||
employee = self._createEmployee()
|
||||
contract = self._createContract(employee,
|
||||
wage=salary,
|
||||
state_id=self.get_us_state('GA'),
|
||||
ga_g4_sit_dependent_allowances=allowances,
|
||||
ga_g4_sit_additional_allowances=0,
|
||||
ga_g4_sit_filing_status=filing_status,
|
||||
state_income_tax_additional_withholding=additional_wh,
|
||||
schedule_pay=schedule_pay)
|
||||
|
||||
self.assertEqual(contract.schedule_pay, 'weekly')
|
||||
|
||||
self._log('2019 Georgia tax first payslip weekly:')
|
||||
payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31')
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self.assertPayrollEqual(cats['ER_US_SUTA'], self.GA_UNEMP_MAX_WAGE * self.GA_UNEMP)
|
||||
self.assertPayrollEqual(cats['EE_US_SIT'], wh)
|
||||
|
||||
process_payslip(payslip)
|
||||
|
||||
remaining_GA_UNEMP_wages = 0.0 # We already reached max unemployment wages.
|
||||
|
||||
self._log('2019 Georgia tax second payslip weekly:')
|
||||
payslip = self._createPayslip(employee, '2019-02-01', '2019-02-28')
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self.assertPayrollEqual(cats['ER_US_SUTA'], remaining_GA_UNEMP_wages * self.GA_UNEMP)
|
||||
|
||||
|
||||
def test_taxes_monthly_head_of_household(self):
|
||||
salary = 25000.00
|
||||
schedule_pay = 'monthly'
|
||||
allowances = 2
|
||||
filing_status = 'head of household'
|
||||
additional_wh = 15.00
|
||||
# Hand Calculated Amount to Test
|
||||
# Step 1 - Subtract standard deduction from wages. Std Deduct for head of household monthly is 383.50
|
||||
# step1 = 25000.00 - 383.50 = 24616.5
|
||||
# Step 2 - Subtract personal allowance from step1. Allowance for head of household monthly is 225.00
|
||||
# step2 = 24616.5 - 225.00 = 24391.5
|
||||
# Step 3 - Subtract amount for dependents. Weekly dependent allowance is 250.00
|
||||
# step3 = 24391.5 - (2 * 250.00) = 23891.5
|
||||
# Step 4 - Determine wh amount from tables
|
||||
# step4 = 28.33 + ((5.75 / 100.00) * (23891.5 - 833.00)) = 1354.19375
|
||||
# Add additional_wh
|
||||
# wh = 1354.19375 + 15.00 = 1369.19375
|
||||
wh = -1369.19
|
||||
|
||||
employee = self._createEmployee()
|
||||
contract = self._createContract(employee,
|
||||
wage=salary,
|
||||
state_id=self.get_us_state('GA'),
|
||||
ga_g4_sit_dependent_allowances=allowances,
|
||||
ga_g4_sit_additional_allowances=0,
|
||||
ga_g4_sit_filing_status=filing_status,
|
||||
state_income_tax_additional_withholding=additional_wh,
|
||||
schedule_pay=schedule_pay)
|
||||
|
||||
self.assertEqual(contract.schedule_pay, 'monthly')
|
||||
|
||||
self._log('2019 Georgia tax first payslip monthly:')
|
||||
payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31')
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self.assertPayrollEqual(cats['ER_US_SUTA'], self.GA_UNEMP_MAX_WAGE * self.GA_UNEMP)
|
||||
self.assertPayrollAlmostEqual(cats['EE_US_SIT'], wh)
|
||||
|
||||
process_payslip(payslip)
|
||||
|
||||
remaining_GA_UNEMP_wages = 0.0 # We already reached max unemployment wages.
|
||||
|
||||
self._log('2019 Georgia tax second payslip weekly:')
|
||||
payslip = self._createPayslip(employee, '2019-02-01', '2019-02-28')
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self.assertPayrollEqual(cats['ER_US_SUTA'], remaining_GA_UNEMP_wages * self.GA_UNEMP)
|
||||
|
||||
def test_taxes_exempt(self):
|
||||
salary = 25000.00
|
||||
schedule_pay = 'monthly'
|
||||
allowances = 2
|
||||
filing_status = ''
|
||||
additional_wh = 15.00
|
||||
|
||||
employee = self._createEmployee()
|
||||
contract = self._createContract(employee,
|
||||
wage=salary,
|
||||
state_id=self.get_us_state('GA'),
|
||||
ga_g4_sit_dependent_allowances=allowances,
|
||||
ga_g4_sit_additional_allowances=0,
|
||||
ga_g4_sit_filing_status=filing_status,
|
||||
state_income_tax_additional_withholding=additional_wh,
|
||||
schedule_pay=schedule_pay)
|
||||
|
||||
self._log('2019 Georgia tax first payslip exempt:')
|
||||
payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31')
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self.assertPayrollEqual(cats.get('EE_US_SIT', 0), 0)
|
||||
39
l10n_us_hr_payroll/tests/test_us_ga_georgia_payslip_2020.py
Executable file
39
l10n_us_hr_payroll/tests/test_us_ga_georgia_payslip_2020.py
Executable file
@@ -0,0 +1,39 @@
|
||||
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
|
||||
|
||||
from datetime import date, timedelta
|
||||
from .common import TestUsPayslip
|
||||
|
||||
|
||||
class TestUsGAPayslip(TestUsPayslip):
|
||||
|
||||
# TAXES AND RATES
|
||||
GA_UNEMP_MAX_WAGE = 9500.00
|
||||
GA_UNEMP = 2.70
|
||||
|
||||
# Example calculated based on https://dor.georgia.gov/employers-tax-guide 2020_employer tax gauide
|
||||
|
||||
def _test_sit(self, wage, filing_status, additional_withholding, dependent_allowances, additional_allowances,
|
||||
schedule_pay, date_start, expected_withholding):
|
||||
employee = self._createEmployee()
|
||||
contract = self._createContract(employee,
|
||||
wage=wage,
|
||||
state_id=self.get_us_state('GA'),
|
||||
ga_g4_sit_filing_status=filing_status,
|
||||
state_income_tax_additional_withholding=additional_withholding,
|
||||
ga_g4_sit_dependent_allowances=dependent_allowances,
|
||||
ga_g4_sit_additional_allowances=additional_allowances,
|
||||
schedule_pay=schedule_pay)
|
||||
payslip = self._createPayslip(employee, date_start, date_start + timedelta(days=7))
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self._log('Computed period tax: ' + str(expected_withholding))
|
||||
self.assertPayrollAlmostEqual(cats.get('EE_US_SIT', 0.0), -expected_withholding)
|
||||
|
||||
def test_2020_taxes_example(self):
|
||||
self._test_er_suta('GA', self.GA_UNEMP, date(2020, 1, 1), wage_base=self.GA_UNEMP_MAX_WAGE)
|
||||
self._test_sit(15000.0, 'single', 12.50, 1, 0, 'weekly', date(2020, 1, 1), 860.28)
|
||||
self._test_sit(25000.0, 'head of household', 15.00, 2, 0, 'monthly', date(2020, 1, 1), 1369.19)
|
||||
self._test_sit(425.0, 'married filing separate', 0.0, 1, 0, 'weekly', date(2020, 1, 1), 11.45)
|
||||
self._test_sit(3000.0, 'single', 0.00, 1, 1, 'quarterly', date(2020, 1, 1), 0.0)
|
||||
self._test_sit(2500.0, '', 0.00, 1, 1, 'quarterly', date(2020, 1, 1), 0.0)
|
||||
93
l10n_us_hr_payroll/tests/test_us_hi_hawaii_payslip_2019.py
Normal file
93
l10n_us_hr_payroll/tests/test_us_hi_hawaii_payslip_2019.py
Normal file
@@ -0,0 +1,93 @@
|
||||
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
|
||||
|
||||
from .common import TestUsPayslip, process_payslip
|
||||
|
||||
|
||||
class TestUsHIPayslip(TestUsPayslip):
|
||||
|
||||
# TAXES AND RATES
|
||||
HI_UNEMP_MAX_WAGE = 46800.00
|
||||
HI_UNEMP = -(2.40 / 100.0)
|
||||
|
||||
def test_taxes_single_weekly(self):
|
||||
salary = 375.00
|
||||
schedule_pay = 'weekly'
|
||||
filing_status = 'single'
|
||||
allowances = 3
|
||||
wh_to_check = -15.3
|
||||
# Taxable income = (wage * payperiod ) - (allownaces * personal_exemption)
|
||||
# taxable_income = (375 * 52) - (3 * 1144) = 16068
|
||||
# Last = row[0] = 692
|
||||
# withholding = row[1] + ((row[2] / 100.0) * (taxable_income - last))
|
||||
# withholding = 682 + ((6.80 / 100.0 ) * (16068 - 14400)) = 795.42
|
||||
# wh_to_check = 795.42/52 = 15.3
|
||||
employee = self._createEmployee()
|
||||
contract = self._createContract(employee,
|
||||
wage=salary,
|
||||
state_id=self.get_us_state('HI'),
|
||||
hi_hw4_sit_filing_status=filing_status,
|
||||
state_income_tax_additional_withholding=0.0,
|
||||
hi_hw4_sit_allowances=allowances,
|
||||
schedule_pay=schedule_pay)
|
||||
|
||||
self._log('2019 Hawaii tax first payslip single:')
|
||||
payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31')
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self.assertPayrollEqual(cats['ER_US_SUTA'], salary * self.HI_UNEMP)
|
||||
self.assertPayrollEqual(cats['EE_US_SIT'], wh_to_check)
|
||||
|
||||
process_payslip(payslip)
|
||||
|
||||
remaining_id_unemp_wages = self.HI_UNEMP_MAX_WAGE - salary if (self.HI_UNEMP_MAX_WAGE - 2*salary < salary) \
|
||||
else salary
|
||||
|
||||
self._log('2019 Hawaii tax second payslip single:')
|
||||
payslip = self._createPayslip(employee, '2019-02-01', '2019-02-28')
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self.assertPayrollEqual(cats['ER_US_SUTA'], remaining_id_unemp_wages * self.HI_UNEMP)
|
||||
|
||||
def test_taxes_married_monthly(self):
|
||||
salary = 5000.00
|
||||
schedule_pay = 'monthly'
|
||||
filing_status = 'married'
|
||||
allowances = 2
|
||||
wh_to_check = -287.1
|
||||
# Taxable income = (wage * payperiod ) - (allownaces * personal_exemption)
|
||||
# taxable_income = (5000 * 12) - (2 * 1144) = 57712
|
||||
# Last = row[0] = 48000
|
||||
# withholding = row[1] + ((row[2] / 100.0) * (taxable_income - last))
|
||||
# withholding = 2707 + ((7.70 / 100.0 ) * (57712 - 48000)) = 3445.112
|
||||
# wh_to_check = 3445.112/52 = 287.092
|
||||
employee = self._createEmployee()
|
||||
contract = self._createContract(employee,
|
||||
wage=salary,
|
||||
state_id=self.get_us_state('HI'),
|
||||
hi_hw4_sit_filing_status=filing_status,
|
||||
state_income_tax_additional_withholding=0.0,
|
||||
hi_hw4_sit_allowances=allowances,
|
||||
schedule_pay=schedule_pay)
|
||||
|
||||
self._log('2019 Hawaii tax first payslip monthly:')
|
||||
payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31')
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self.assertPayrollEqual(cats['ER_US_SUTA'], salary * self.HI_UNEMP)
|
||||
self.assertPayrollEqual(cats['EE_US_SIT'], wh_to_check)
|
||||
|
||||
process_payslip(payslip)
|
||||
|
||||
remaining_id_unemp_wages = self.HI_UNEMP_MAX_WAGE - salary if (self.HI_UNEMP_MAX_WAGE - 2*salary < salary) \
|
||||
else salary
|
||||
|
||||
self._log('2019 Hawaii tax second payslip monthly:')
|
||||
payslip = self._createPayslip(employee, '2019-02-01', '2019-02-28')
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self.assertPayrollEqual(cats['ER_US_SUTA'], remaining_id_unemp_wages * self.HI_UNEMP)
|
||||
|
||||
37
l10n_us_hr_payroll/tests/test_us_hi_hawaii_payslip_2020.py
Executable file
37
l10n_us_hr_payroll/tests/test_us_hi_hawaii_payslip_2020.py
Executable file
@@ -0,0 +1,37 @@
|
||||
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
|
||||
|
||||
from datetime import date, timedelta
|
||||
from .common import TestUsPayslip
|
||||
|
||||
|
||||
class TestUsHIPayslip(TestUsPayslip):
|
||||
###
|
||||
# 2020 Taxes and Rates
|
||||
###
|
||||
HI_UNEMP_MAX_WAGE = 48100.00
|
||||
HI_UNEMP = 2.4
|
||||
|
||||
def _test_sit(self, wage, filing_status, additional_withholding, allowances, schedule_pay, date_start, expected_withholding):
|
||||
employee = self._createEmployee()
|
||||
contract = self._createContract(employee,
|
||||
wage=wage,
|
||||
state_id=self.get_us_state('HI'),
|
||||
hi_hw4_sit_filing_status=filing_status,
|
||||
state_income_tax_additional_withholding=additional_withholding,
|
||||
hi_hw4_sit_allowances=allowances,
|
||||
schedule_pay=schedule_pay)
|
||||
payslip = self._createPayslip(employee, date_start, date_start + timedelta(days=7))
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self._log('Computed period tax: ' + str(expected_withholding))
|
||||
self.assertPayrollEqual(cats.get('EE_US_SIT', 0.0), -expected_withholding)
|
||||
|
||||
def test_2020_taxes_example(self):
|
||||
self._test_er_suta('HI', self.HI_UNEMP, date(2020, 1, 1), wage_base=self.HI_UNEMP_MAX_WAGE)
|
||||
self._test_sit(375.0, 'single', 0.0, 3.0, 'weekly', date(2020, 1, 1), 15.3)
|
||||
self._test_sit(5000.0, 'married', 0.0, 2.0, 'monthly', date(2020, 1, 1), 287.1)
|
||||
self._test_sit(5000.0, 'married', 10.0, 2.0, 'monthly', date(2020, 1, 1), 297.1)
|
||||
self._test_sit(50000.0, 'head_of_household', 0.0, 3.0, 'weekly', date(2020, 1, 1), 3933.65)
|
||||
self._test_sit(750.0, 'single', 10.0, 3.0, 'bi-weekly', date(2020, 1, 1), 40.59)
|
||||
self._test_sit(3000.0, '', 0.0, 3.0, 'weekly', date(2020, 1, 1), 0.00)
|
||||
152
l10n_us_hr_payroll/tests/test_us_ia_iowa_payslip_2019.py
Normal file
152
l10n_us_hr_payroll/tests/test_us_ia_iowa_payslip_2019.py
Normal file
@@ -0,0 +1,152 @@
|
||||
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
|
||||
|
||||
from .common import TestUsPayslip, process_payslip
|
||||
|
||||
|
||||
class TestUsIAPayslip(TestUsPayslip):
|
||||
IA_UNEMP_MAX_WAGE = 30600
|
||||
IA_UNEMP = -1.0 / 100.0
|
||||
IA_INC_TAX = -0.0535
|
||||
|
||||
def test_taxes_weekly(self):
|
||||
wages = 30000.00
|
||||
schedule_pay = 'weekly'
|
||||
allowances = 1
|
||||
additional_wh = 0.00
|
||||
employee = self._createEmployee()
|
||||
contract = self._createContract(employee,
|
||||
wage=wages,
|
||||
state_id=self.get_us_state('IA'),
|
||||
state_income_tax_additional_withholding=additional_wh,
|
||||
ia_w4_sit_allowances=allowances,
|
||||
schedule_pay=schedule_pay)
|
||||
|
||||
self._log('2019 Iowa tax first payslip weekly:')
|
||||
payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31')
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
# T1 is the gross taxable wages for the pay period minus the Federal withholding amount. We add the federal
|
||||
# withholding amount because it is calculated in the base US payroll module as a negative
|
||||
# t1 = 30000 - (10399.66) = 19600.34
|
||||
t1_to_test = wages + cats['EE_US_941_FIT']
|
||||
self.assertPayrollAlmostEqual(t1_to_test, 19600.34)
|
||||
|
||||
# T2 is T1 minus our standard deduction which is a table of flat rates dependent on the number of allowances.
|
||||
# In our case, we have a weekly period which on the table has a std deduct. of $32.50 for 0 or 1 allowances,
|
||||
# and 80.00 of 2 or more allowances.
|
||||
standard_deduction = 32.50 # The allowance tells us what standard_deduction amount to use.
|
||||
# t2 = 19600.34 - 32.50 = 19567.84
|
||||
t2_to_test = t1_to_test - standard_deduction
|
||||
self.assertPayrollAlmostEqual(t2_to_test, 19567.84)
|
||||
# T3 is T2 multiplied by the income rates in the large table plus a flat fee for that bracket.
|
||||
# 1153.38 is the bracket floor. 8.53 is the rate, and 67.63 is the flat fee.
|
||||
# t3 = 1638.38
|
||||
t3_to_test = ((t2_to_test - 1153.38) * (8.53 / 100)) + 67.63
|
||||
self.assertPayrollAlmostEqual(t3_to_test, 1638.38)
|
||||
# T4 is T3 minus a flat amount determined by pay period * the number of deductions. For 2019, our weekly
|
||||
# deduction amount per allowance is 0.77
|
||||
# t4 = 1638.38 - 0.77 = 155.03
|
||||
t4_to_test = t3_to_test - (0.77 * allowances)
|
||||
self.assertPayrollAlmostEqual(t4_to_test, 1637.61)
|
||||
# t5 is our T4 plus the additional withholding per period
|
||||
# t5 = 1637.61 + 0.0
|
||||
# Convert to negative as well.
|
||||
t5_to_test = -t4_to_test - additional_wh
|
||||
self.assertPayrollAlmostEqual(t5_to_test, -1637.61)
|
||||
|
||||
self.assertPayrollEqual(cats['ER_US_SUTA'], wages * self.IA_UNEMP)
|
||||
self.assertPayrollEqual(cats['EE_US_SIT'], t5_to_test)
|
||||
|
||||
|
||||
# Make a new payslip, this one will have maximums
|
||||
|
||||
remaining_IA_UNEMP_wages = self.IA_UNEMP_MAX_WAGE - wages if (self.IA_UNEMP_MAX_WAGE - 2*wages < wages) \
|
||||
else wages
|
||||
|
||||
self._log('2019 Iowa tax second payslip weekly:')
|
||||
payslip = self._createPayslip(employee, '2019-02-01', '2019-02-28')
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self.assertPayrollEqual(cats['ER_US_SUTA'], wages * self.IA_UNEMP)
|
||||
|
||||
def test_taxes_biweekly(self):
|
||||
wages = 3000.00
|
||||
schedule_pay = 'bi-weekly'
|
||||
allowances = 1
|
||||
additional_wh = 0.00
|
||||
employee = self._createEmployee()
|
||||
contract = self._createContract(employee,
|
||||
wage=wages,
|
||||
state_id=self.get_us_state('IA'),
|
||||
state_income_tax_additional_withholding=additional_wh,
|
||||
ia_w4_sit_allowances=allowances,
|
||||
schedule_pay=schedule_pay)
|
||||
|
||||
self._log('2019 Iowa tax first payslip bi-weekly:')
|
||||
payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31')
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
# T1 is the gross taxable wages for the pay period minus the Federal withholding amount. We add the federal
|
||||
# withholding amount because it is calculated in the base US payroll module as a negative
|
||||
t1_to_test = wages + cats['EE_US_941_FIT']
|
||||
# T2 is T1 minus our standard deduction which is a table of flat rates dependent on the number of allowances.
|
||||
# In our case, we have a biweekly period which on the table has a std deduct. of $65.00 for 0 or 1 allowances,
|
||||
# and $160.00 of 2 or more allowances.
|
||||
standard_deduction = 65.00 # The allowance tells us what standard_deduction amount to use.
|
||||
t2_to_test = t1_to_test - standard_deduction
|
||||
# T3 is T2 multiplied by the income rates in the large table plus a flat fee for that bracket.
|
||||
t3_to_test = ((t2_to_test - 2306.77) * (8.53 / 100)) + 135.28
|
||||
# T4 is T3 minus a flat amount determined by pay period * the number of deductions. For 2019, our weekly
|
||||
# deduction amount per allowance is 0.77
|
||||
t4_to_test = t3_to_test - (1.54 * allowances)
|
||||
# t5 is our T4 plus the additional withholding per period
|
||||
t5_to_test = -t4_to_test - additional_wh
|
||||
|
||||
self.assertPayrollEqual(cats['ER_US_SUTA'], wages * self.IA_UNEMP)
|
||||
self.assertPayrollEqual(cats['EE_US_SIT'], t5_to_test - additional_wh)
|
||||
|
||||
process_payslip(payslip)
|
||||
|
||||
def test_taxes_with_external_weekly(self):
|
||||
wages = 2500.00
|
||||
schedule_pay = 'weekly'
|
||||
allowances = 1
|
||||
additional_wh = 0.00
|
||||
|
||||
employee = self._createEmployee()
|
||||
contract = self._createContract(employee,
|
||||
wage=wages,
|
||||
state_id=self.get_us_state('IA'),
|
||||
state_income_tax_additional_withholding=additional_wh,
|
||||
ia_w4_sit_allowances=allowances,
|
||||
schedule_pay=schedule_pay)
|
||||
|
||||
self._log('2019 Iowa external tax first payslip external weekly:')
|
||||
payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31')
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
|
||||
# T1 is the gross taxable wages for the pay period minus the Federal withholding amount. We add the federal
|
||||
# withholding amount because it is calculated in the base US payroll module as a negative
|
||||
t1_to_test = wages + cats['EE_US_941_FIT']
|
||||
# T2 is T1 minus our standard deduction which is a table of flat rates dependent on the number of allowances.
|
||||
# In our case, we have a weekly period which on the table has a std deduct. of $32.50 for 0 or 1 allowances,
|
||||
# and 80.00 of 2 or more allowances.
|
||||
standard_deduction = 32.50 # The allowance tells us what standard_deduction amount to use.
|
||||
t2_to_test = t1_to_test - standard_deduction
|
||||
# T3 is T2 multiplied by the income rates in the large table plus a flat fee for that bracket.
|
||||
t3_to_test = ((t2_to_test - 1153.38) * (8.53 / 100)) + 67.63
|
||||
# T4 is T3 minus a flat amount determined by pay period * the number of deductions. For 2019, our weekly
|
||||
# deduction amount per allowance is 0.77
|
||||
t4_to_test = t3_to_test - (0.77 * allowances)
|
||||
# t5 is our T4 plus the additional withholding per period
|
||||
t5_to_test = -t4_to_test - additional_wh
|
||||
|
||||
self.assertPayrollEqual(cats['ER_US_SUTA'], wages * self.IA_UNEMP)
|
||||
self.assertPayrollAlmostEqual(cats['EE_US_SIT'], t5_to_test)
|
||||
|
||||
process_payslip(payslip)
|
||||
36
l10n_us_hr_payroll/tests/test_us_ia_iowa_payslip_2020.py
Executable file
36
l10n_us_hr_payroll/tests/test_us_ia_iowa_payslip_2020.py
Executable file
@@ -0,0 +1,36 @@
|
||||
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
|
||||
|
||||
from datetime import date, timedelta
|
||||
from .common import TestUsPayslip
|
||||
|
||||
|
||||
class TestUsIAPayslip(TestUsPayslip):
|
||||
###
|
||||
# 2020 Taxes and Rates
|
||||
###
|
||||
IA_UNEMP_MAX_WAGE = 31600.00
|
||||
IA_UNEMP = 1.0
|
||||
|
||||
def _test_sit(self, wage, exempt, additional_withholding, allowances, schedule_pay, date_start, expected_withholding):
|
||||
employee = self._createEmployee()
|
||||
contract = self._createContract(employee,
|
||||
wage=wage,
|
||||
state_id=self.get_us_state('IA'),
|
||||
state_income_tax_exempt=exempt,
|
||||
state_income_tax_additional_withholding=additional_withholding,
|
||||
ia_w4_sit_allowances=allowances,
|
||||
schedule_pay=schedule_pay)
|
||||
payslip = self._createPayslip(employee, date_start, date_start + timedelta(days=7))
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self._log('Computed period tax: ' + str(expected_withholding))
|
||||
self.assertPayrollAlmostEqual(cats.get('EE_US_SIT', 0.0), -expected_withholding)
|
||||
|
||||
def test_2020_taxes_example(self):
|
||||
self._test_er_suta('IA', self.IA_UNEMP, date(2020, 1, 1), wage_base=self.IA_UNEMP_MAX_WAGE)
|
||||
self._test_sit(2100.0, False, 0.0, 3.0, 'bi-weekly', date(2020, 1, 1), 83.5)
|
||||
self._test_sit(3000.0, True, 10.0, 1.0, 'bi-weekly', date(2020, 1, 1), 0.00)
|
||||
self._test_sit(300.0, False, 0.0, 1.0, 'weekly', date(2020, 1, 1), 6.77)
|
||||
self._test_sit(5000.0, False, 0.0, 1.0, 'monthly', date(2020, 1, 1), 230.76)
|
||||
self._test_sit(7500.0, False, 10.0, 2.0, 'semi-monthly', date(2020, 1, 1), 432.84)
|
||||
85
l10n_us_hr_payroll/tests/test_us_id_idaho_payslip_2019.py
Normal file
85
l10n_us_hr_payroll/tests/test_us_id_idaho_payslip_2019.py
Normal file
@@ -0,0 +1,85 @@
|
||||
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
|
||||
|
||||
from .common import TestUsPayslip, process_payslip
|
||||
|
||||
|
||||
class TestUsIDPayslip(TestUsPayslip):
|
||||
|
||||
# TAXES AND RATES
|
||||
ID_UNEMP_MAX_WAGE = 40000.00
|
||||
ID_UNEMP = -(1.00 / 100.0)
|
||||
|
||||
def test_taxes_single_biweekly(self):
|
||||
salary = 1212.00
|
||||
schedule_pay = 'bi-weekly'
|
||||
filing_status = 'single'
|
||||
allowances = 4
|
||||
# SEE https://tax.idaho.gov/i-1026.cfm?seg=compute for example calculations
|
||||
wh_to_check = -10.00
|
||||
employee = self._createEmployee()
|
||||
contract = self._createContract(employee,
|
||||
wage=salary,
|
||||
state_id=self.get_us_state('ID'),
|
||||
id_w4_sit_filing_status=filing_status,
|
||||
id_w4_sit_allowances=allowances,
|
||||
schedule_pay=schedule_pay)
|
||||
|
||||
self._log('2019 Idaho tax first payslip single:')
|
||||
payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31')
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self.assertPayrollEqual(cats['ER_US_SUTA'], salary * self.ID_UNEMP)
|
||||
self.assertPayrollEqual(cats['EE_US_SIT'], wh_to_check)
|
||||
|
||||
process_payslip(payslip)
|
||||
|
||||
remaining_id_unemp_wages = self.ID_UNEMP_MAX_WAGE - salary if (self.ID_UNEMP_MAX_WAGE - 2*salary < salary) \
|
||||
else salary
|
||||
|
||||
self._log('2019 Idaho tax second payslip single:')
|
||||
payslip = self._createPayslip(employee, '2019-02-01', '2019-02-28')
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self.assertPayrollEqual(cats['ER_US_SUTA'], remaining_id_unemp_wages * self.ID_UNEMP)
|
||||
|
||||
def test_taxes_married_monthly(self):
|
||||
salary = 5000.00
|
||||
schedule_pay = 'monthly'
|
||||
filing_status = 'married'
|
||||
allowances = 2
|
||||
|
||||
# ICTCAT says monthly allowances are 246.67
|
||||
# we have 2 so 246.67 * 2 = 493.34
|
||||
# 5000.00 - 493.34 = 4506.66
|
||||
# Wh is 89$ plus 6.925% over 3959,00
|
||||
# 126.92545499999999 - > 127.0
|
||||
wh_to_check = -127.0
|
||||
employee = self._createEmployee()
|
||||
contract = self._createContract(employee,
|
||||
wage=salary,
|
||||
state_id=self.get_us_state('ID'),
|
||||
id_w4_sit_filing_status=filing_status,
|
||||
id_w4_sit_allowances=allowances,
|
||||
schedule_pay=schedule_pay)
|
||||
|
||||
self._log('2019 Idaho tax first payslip monthly:')
|
||||
payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31')
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self.assertPayrollEqual(cats['ER_US_SUTA'], salary * self.ID_UNEMP)
|
||||
self.assertPayrollEqual(cats['EE_US_SIT'], wh_to_check)
|
||||
|
||||
process_payslip(payslip)
|
||||
|
||||
remaining_id_unemp_wages = self.ID_UNEMP_MAX_WAGE - salary if (self.ID_UNEMP_MAX_WAGE - 2*salary < salary) \
|
||||
else salary
|
||||
|
||||
self._log('2019 Idaho tax second payslip monthly:')
|
||||
payslip = self._createPayslip(employee, '2019-02-01', '2019-02-28')
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self.assertPayrollEqual(cats['ER_US_SUTA'], remaining_id_unemp_wages * self.ID_UNEMP)
|
||||
35
l10n_us_hr_payroll/tests/test_us_id_idaho_payslip_2020.py
Executable file
35
l10n_us_hr_payroll/tests/test_us_id_idaho_payslip_2020.py
Executable file
@@ -0,0 +1,35 @@
|
||||
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
|
||||
|
||||
from datetime import date, timedelta
|
||||
from .common import TestUsPayslip
|
||||
|
||||
|
||||
class TestUsIDPayslip(TestUsPayslip):
|
||||
###
|
||||
# 2020 Taxes and Rates
|
||||
###
|
||||
ID_UNEMP_MAX_WAGE = 41600.00
|
||||
ID_UNEMP = 1.0
|
||||
|
||||
def _test_sit(self, wage, filing_status, allowances, schedule_pay, date_start, expected_withholding):
|
||||
employee = self._createEmployee()
|
||||
contract = self._createContract(employee,
|
||||
wage=wage,
|
||||
state_id=self.get_us_state('ID'),
|
||||
id_w4_sit_filing_status=filing_status,
|
||||
id_w4_sit_allowances=allowances,
|
||||
schedule_pay=schedule_pay)
|
||||
payslip = self._createPayslip(employee, date_start, date_start + timedelta(days=7))
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self._log('Computed period tax: ' + str(expected_withholding))
|
||||
self.assertPayrollEqual(cats.get('EE_US_SIT', 0.0), -expected_withholding)
|
||||
|
||||
def test_2020_taxes_example(self):
|
||||
self._test_er_suta('ID', self.ID_UNEMP, date(2020, 1, 1), wage_base=self.ID_UNEMP_MAX_WAGE)
|
||||
self._test_sit(1212.0, 'single', 4.0, 'bi-weekly', date(2020, 1, 1), 10.0)
|
||||
self._test_sit(10000.0, 'married', 1.0, 'annually', date(2020, 1, 1), 0.0)
|
||||
self._test_sit(52000.0, 'married', 4.0, 'monthly', date(2020, 1, 1), 3345.0)
|
||||
self._test_sit(5000.0, 'head of household', 0.0, 'semi-monthly', date(2020, 1, 1), 300.0)
|
||||
self._test_sit(5900.0, 'single', 5.0, 'weekly', date(2020, 1, 1), 367.0)
|
||||
71
l10n_us_hr_payroll/tests/test_us_il_illinois_payslip_2019.py
Normal file
71
l10n_us_hr_payroll/tests/test_us_il_illinois_payslip_2019.py
Normal file
@@ -0,0 +1,71 @@
|
||||
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
|
||||
|
||||
from .common import TestUsPayslip, process_payslip
|
||||
|
||||
|
||||
class TestUsILPayslip(TestUsPayslip):
|
||||
# TAXES AND RATES
|
||||
IL_UNEMP_MAX_WAGE = 12960.00
|
||||
IL_UNEMP = -(3.175 / 100.0)
|
||||
|
||||
def test_taxes_monthly(self):
|
||||
salary = 15000.00
|
||||
schedule_pay = 'monthly'
|
||||
basic_allowances = 1
|
||||
additional_allowances = 1
|
||||
flat_rate = (4.95 / 100)
|
||||
wh_to_test = -(flat_rate * (salary - ((basic_allowances * 2275 + additional_allowances * 1000) / 12.0)))
|
||||
|
||||
employee = self._createEmployee()
|
||||
contract = self._createContract(employee,
|
||||
wage=salary,
|
||||
state_id=self.get_us_state('IL'),
|
||||
state_income_tax_additional_withholding=0.0,
|
||||
il_w4_sit_basic_allowances=1.0,
|
||||
il_w4_sit_additional_allowances=1.0,
|
||||
schedule_pay='monthly')
|
||||
|
||||
self._log('2019 Illinois tax first payslip monthly:')
|
||||
payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31')
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self.assertPayrollEqual(cats['ER_US_SUTA'], self.IL_UNEMP_MAX_WAGE * self.IL_UNEMP)
|
||||
self.assertPayrollEqual(cats['EE_US_SIT'], wh_to_test)
|
||||
|
||||
process_payslip(payslip)
|
||||
|
||||
remaining_IL_UNEMP_wages = 0.0 # We already reached max unemployment wages.
|
||||
|
||||
self._log('2019 Illinois tax second payslip monthly:')
|
||||
payslip = self._createPayslip(employee, '2019-02-01', '2019-02-28')
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self.assertPayrollEqual(cats['ER_US_SUTA'], remaining_IL_UNEMP_wages * self.IL_UNEMP)
|
||||
|
||||
def test_taxes_with_additional_wh(self):
|
||||
salary = 15000.00
|
||||
schedule_pay = 'monthly'
|
||||
basic_allowances = 1
|
||||
additional_allowances = 1
|
||||
additional_wh = 15.0
|
||||
flat_rate = (4.95 / 100)
|
||||
wh_to_test = -(flat_rate * (salary - ((basic_allowances * 2275 + additional_allowances * 1000) / 12.0)) + additional_wh)
|
||||
|
||||
employee = self._createEmployee()
|
||||
contract = self._createContract(employee,
|
||||
wage=salary,
|
||||
state_id=self.get_us_state('IL'),
|
||||
state_income_tax_additional_withholding=15.0,
|
||||
il_w4_sit_basic_allowances=1.0,
|
||||
il_w4_sit_additional_allowances=1.0,
|
||||
schedule_pay='monthly')
|
||||
|
||||
self._log('2019 Illinois tax first payslip monthly:')
|
||||
payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31')
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self.assertPayrollEqual(cats['ER_US_SUTA'], self.IL_UNEMP_MAX_WAGE * self.IL_UNEMP)
|
||||
self.assertPayrollEqual(cats['EE_US_SIT'], wh_to_test)
|
||||
36
l10n_us_hr_payroll/tests/test_us_il_illinois_payslip_2020.py
Normal file
36
l10n_us_hr_payroll/tests/test_us_il_illinois_payslip_2020.py
Normal file
@@ -0,0 +1,36 @@
|
||||
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
|
||||
|
||||
from datetime import date, timedelta
|
||||
from .common import TestUsPayslip
|
||||
|
||||
|
||||
class TestUsILPayslip(TestUsPayslip):
|
||||
# Taxes and Rates
|
||||
IL_UNEMP_MAX_WAGE = 12740.0
|
||||
IL_UNEMP = 3.125
|
||||
|
||||
def _test_sit(self, wage, additional_withholding, basic_allowances, additional_allowances, schedule_pay, date_start, expected_withholding):
|
||||
|
||||
employee = self._createEmployee()
|
||||
contract = self._createContract(employee,
|
||||
wage=wage,
|
||||
state_id=self.get_us_state('IL'),
|
||||
state_income_tax_additional_withholding=additional_withholding,
|
||||
il_w4_sit_basic_allowances=basic_allowances,
|
||||
il_w4_sit_additional_allowances=additional_allowances,
|
||||
schedule_pay=schedule_pay)
|
||||
payslip = self._createPayslip(employee, date_start, date_start + timedelta(days=7))
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self._log('Computed period tax: ' + str(expected_withholding))
|
||||
self.assertPayrollEqual(cats.get('EE_US_SIT', 0.0), -expected_withholding)
|
||||
|
||||
def test_2020_taxes_example(self):
|
||||
self._test_er_suta('IL', self.IL_UNEMP, date(2020, 1, 1), wage_base=self.IL_UNEMP_MAX_WAGE)
|
||||
self._test_sit(800.0, 0.0, 2, 2, 'weekly', date(2020, 1, 1), 33.27)
|
||||
self._test_sit(800.0, 10.0, 2, 2, 'weekly', date(2020, 1, 1), 43.27)
|
||||
self._test_sit(2500.0, 0.0, 1, 1, 'monthly', date(2020, 1, 1), 110.04)
|
||||
self._test_sit(2500.0, 0.0, 0, 0, 'monthly', date(2020, 1, 1), 123.75)
|
||||
self._test_sit(3000.0, 15.0, 0, 0, 'quarterly', date(2020, 1, 1), 163.50)
|
||||
|
||||
36
l10n_us_hr_payroll/tests/test_us_in_indiana_payslip_2020.py
Executable file
36
l10n_us_hr_payroll/tests/test_us_in_indiana_payslip_2020.py
Executable file
@@ -0,0 +1,36 @@
|
||||
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
|
||||
|
||||
from datetime import date, timedelta
|
||||
from .common import TestUsPayslip
|
||||
|
||||
|
||||
class TestUsINPayslip(TestUsPayslip):
|
||||
###
|
||||
# 2020 Taxes and Rates
|
||||
###
|
||||
IN_UNEMP_MAX_WAGE = 9500.0
|
||||
IN_UNEMP = 2.5
|
||||
# Calculation based on https://www.in.gov/dor/files/dn01.pdf
|
||||
|
||||
def _test_sit(self, wage, additional_withholding, personal_exemption, dependent_exemption, schedule_pay, date_start, expected_withholding):
|
||||
employee = self._createEmployee()
|
||||
contract = self._createContract(employee,
|
||||
wage=wage,
|
||||
state_id=self.get_us_state('IN'),
|
||||
state_income_tax_additional_withholding=additional_withholding,
|
||||
in_w4_sit_personal_exemption=personal_exemption,
|
||||
in_w4_sit_dependent_exemption=dependent_exemption,
|
||||
schedule_pay=schedule_pay)
|
||||
payslip = self._createPayslip(employee, date_start, date_start + timedelta(days=7))
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self._log('Computed period tax: ' + str(expected_withholding))
|
||||
self.assertPayrollEqual(cats.get('EE_US_SIT', 0.0), -expected_withholding)
|
||||
|
||||
def test_2020_taxes_example(self):
|
||||
self._test_er_suta('IN', self.IN_UNEMP, date(2020, 1, 1), wage_base=self.IN_UNEMP_MAX_WAGE)
|
||||
self._test_sit(800.0, 0.0, 5.0, 3.0, 'weekly', date(2020, 1, 1), 19.94)
|
||||
self._test_sit(800.0, 10.0, 5.0, 3.0, 'weekly', date(2020, 1, 1), 29.94)
|
||||
self._test_sit(9000.0, 0.0, 4.0, 3.0, 'monthly', date(2020, 1, 1), 267.82)
|
||||
self._test_sit(10000.0, 0.0, 2.0, 2.0, 'bi-weekly', date(2020, 1, 1), 316.79)
|
||||
36
l10n_us_hr_payroll/tests/test_us_ks_kansas_payslip_2020.py
Executable file
36
l10n_us_hr_payroll/tests/test_us_ks_kansas_payslip_2020.py
Executable file
@@ -0,0 +1,36 @@
|
||||
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
|
||||
|
||||
from datetime import date, timedelta
|
||||
from .common import TestUsPayslip
|
||||
|
||||
|
||||
class TestUsKSPayslip(TestUsPayslip):
|
||||
###
|
||||
# 2020 Taxes and Rates
|
||||
###
|
||||
KS_UNEMP_MAX_WAGE = 14000.0
|
||||
KS_UNEMP = 2.7
|
||||
# Calculation based on example https://revenue.ky.gov/Forms/42A003(T)%20(12-2019)%202020%20Tax%20Tables.pdf
|
||||
|
||||
def _test_sit(self, wage, filing_status, allowances, additional_withholding, schedule_pay, date_start, expected_withholding):
|
||||
employee = self._createEmployee()
|
||||
contract = self._createContract(employee,
|
||||
wage=wage,
|
||||
state_id=self.get_us_state('KS'),
|
||||
ks_k4_sit_filing_status=filing_status,
|
||||
ks_k4_sit_allowances=allowances,
|
||||
state_income_tax_additional_withholding=additional_withholding,
|
||||
schedule_pay=schedule_pay)
|
||||
payslip = self._createPayslip(employee, date_start, date_start + timedelta(days=7))
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self._log('Computed period tax: ' + str(expected_withholding))
|
||||
self.assertPayrollAlmostEqual(cats.get('EE_US_SIT', 0.0), -expected_withholding)
|
||||
|
||||
def test_2020_taxes_example(self):
|
||||
self._test_er_suta('KS', self.KS_UNEMP, date(2020, 1, 1), wage_base=self.KS_UNEMP_MAX_WAGE)
|
||||
self._test_sit(6250, 'married', 2, 0, 'semi-monthly', date(2020, 1, 1), 290.00)
|
||||
self._test_sit(5000, 'single', 1, 0, 'monthly', date(2020, 1, 1), 222.00)
|
||||
self._test_sit(1500, 'married', 0, 0, 'bi-weekly', date(2020, 1, 1), 39.00)
|
||||
self._test_sit(750, 'single', 2, 10, 'weekly', date(2020, 1, 1), 36.00)
|
||||
35
l10n_us_hr_payroll/tests/test_us_ky_kentucky_payslip_2020.py
Executable file
35
l10n_us_hr_payroll/tests/test_us_ky_kentucky_payslip_2020.py
Executable file
@@ -0,0 +1,35 @@
|
||||
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
|
||||
|
||||
from datetime import date, timedelta
|
||||
from .common import TestUsPayslip
|
||||
|
||||
|
||||
class TestUsKYPayslip(TestUsPayslip):
|
||||
###
|
||||
# 2020 Taxes and Rates
|
||||
###
|
||||
KY_UNEMP_MAX_WAGE = 10800.0
|
||||
KY_UNEMP = 2.7
|
||||
# Calculation based on example https://revenue.ky.gov/Forms/42A003(T)%20(12-2019)%202020%20Tax%20Tables.pdf
|
||||
|
||||
def _test_sit(self, wage, additional_withholding, schedule_pay, date_start, expected_withholding):
|
||||
employee = self._createEmployee()
|
||||
contract = self._createContract(employee,
|
||||
wage=wage,
|
||||
state_id=self.get_us_state('KY'),
|
||||
state_income_tax_additional_withholding=additional_withholding,
|
||||
schedule_pay=schedule_pay)
|
||||
payslip = self._createPayslip(employee, date_start, date_start + timedelta(days=7))
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self._log('Computed period tax: ' + str(expected_withholding))
|
||||
self.assertPayrollEqual(cats.get('EE_US_SIT', 0.0), -expected_withholding)
|
||||
|
||||
def test_2020_taxes_example(self):
|
||||
self._test_er_suta('KY', self.KY_UNEMP, date(2020, 1, 1), wage_base=self.KY_UNEMP_MAX_WAGE)
|
||||
self._test_sit(3020, 0.0, 'monthly', date(2020, 1, 1), 139.96)
|
||||
self._test_sit(1500, 0.0, 'bi-weekly', date(2020, 1, 1), 69.90)
|
||||
self._test_sit(1500, 10.0, 'bi-weekly', date(2020, 1, 1), 79.90)
|
||||
self._test_sit(750, 00.0, 'weekly', date(2020, 1, 1), 34.95)
|
||||
self._test_sit(7000, 0.0, 'semi-monthly', date(2020, 1, 1), 344.48)
|
||||
@@ -0,0 +1,91 @@
|
||||
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
|
||||
|
||||
from .common import TestUsPayslip, process_payslip
|
||||
|
||||
|
||||
class TestUsLAPayslip(TestUsPayslip):
|
||||
|
||||
# TAXES AND RATES
|
||||
LA_UNEMP_MAX_WAGE = 7700.00
|
||||
LA_UNEMP = -(1.14 / 100.0)
|
||||
|
||||
def test_taxes_single_weekly(self):
|
||||
salary = 700.00
|
||||
schedule_pay = 'weekly'
|
||||
filing_status = 'single'
|
||||
exemptions = 1
|
||||
dependents = 2
|
||||
additional_withholding = 0
|
||||
# SEE http://revenue.louisiana.gov/TaxForms/1306(1_12)TF.pdf for example calculations
|
||||
# wh_to test is 19.42
|
||||
# Our algorithm correctly rounds whereas theirs does it prematurely.
|
||||
wh_to_check = -19.43
|
||||
employee = self._createEmployee()
|
||||
contract = self._createContract(employee,
|
||||
wage=salary,
|
||||
state_id=self.get_us_state('LA'),
|
||||
la_l4_sit_filing_status=filing_status,
|
||||
state_income_tax_additional_withholding=additional_withholding,
|
||||
la_l4_sit_exemptions=exemptions,
|
||||
la_l4_sit_dependents=dependents,
|
||||
schedule_pay=schedule_pay)
|
||||
|
||||
self._log('2019 Louisiana tax first payslip weekly:')
|
||||
payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31')
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self.assertPayrollEqual(cats['ER_US_SUTA'], salary * self.LA_UNEMP)
|
||||
self.assertPayrollEqual(cats['EE_US_SIT'], wh_to_check)
|
||||
|
||||
process_payslip(payslip)
|
||||
|
||||
remaining_la_unemp_wages = self.LA_UNEMP_MAX_WAGE - salary if (self.LA_UNEMP_MAX_WAGE - 2*salary < salary) \
|
||||
else salary
|
||||
|
||||
self._log('2019 Louisiana tax second payslip weekly:')
|
||||
payslip = self._createPayslip(employee, '2019-02-01', '2019-02-28')
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self.assertPayrollEqual(cats['ER_US_SUTA'], remaining_la_unemp_wages * self.LA_UNEMP)
|
||||
|
||||
def test_taxes_married_biweekly(self):
|
||||
salary = 4600.00
|
||||
schedule_pay = 'bi-weekly'
|
||||
filing_status = 'married'
|
||||
exemptions = 2
|
||||
dependents = 3
|
||||
additional_withholding = 0
|
||||
# SEE http://revenue.louisiana.gov/TaxForms/1306(1_12)TF.pdf for example calculations
|
||||
# wh_to test is 157.12
|
||||
wh_to_check = -157.12
|
||||
employee = self._createEmployee()
|
||||
contract = self._createContract(employee,
|
||||
wage=salary,
|
||||
state_id=self.get_us_state('LA'),
|
||||
la_l4_sit_filing_status=filing_status,
|
||||
state_income_tax_additional_withholding=additional_withholding,
|
||||
la_l4_sit_exemptions=exemptions,
|
||||
la_l4_sit_dependents=dependents,
|
||||
schedule_pay=schedule_pay)
|
||||
|
||||
self._log('2019 Louisiana tax first payslip bi-weekly:')
|
||||
payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31')
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self.assertPayrollEqual(cats['ER_US_SUTA'], salary * self.LA_UNEMP)
|
||||
self.assertPayrollEqual(cats['EE_US_SIT'], wh_to_check)
|
||||
|
||||
process_payslip(payslip)
|
||||
|
||||
remaining_la_unemp_wages = self.LA_UNEMP_MAX_WAGE - salary if (self.LA_UNEMP_MAX_WAGE - 2*salary < salary) \
|
||||
else salary
|
||||
|
||||
self._log('2019 Louisiana tax second payslip bi-weekly:')
|
||||
payslip = self._createPayslip(employee, '2019-02-01', '2019-02-28')
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self.assertPayrollEqual(cats['ER_US_SUTA'], remaining_la_unemp_wages * self.LA_UNEMP)
|
||||
36
l10n_us_hr_payroll/tests/test_us_la_louisiana_payslip_2020.py
Executable file
36
l10n_us_hr_payroll/tests/test_us_la_louisiana_payslip_2020.py
Executable file
@@ -0,0 +1,36 @@
|
||||
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
|
||||
|
||||
from datetime import date, timedelta
|
||||
from .common import TestUsPayslip
|
||||
|
||||
|
||||
class TestUsLAPayslip(TestUsPayslip):
|
||||
###
|
||||
# 2020 Taxes and Rates
|
||||
###
|
||||
LA_UNEMP_MAX_WAGE = 7700.0
|
||||
LA_UNEMP = 1.14
|
||||
# Calculation based on http://revenue.louisiana.gov/TaxForms/1306(1_12)TF.pdf
|
||||
|
||||
def _test_sit(self, wage, filing_status, additional_withholding, exemptions, dependents, schedule_pay, date_start, expected_withholding):
|
||||
employee = self._createEmployee()
|
||||
contract = self._createContract(employee,
|
||||
wage=wage,
|
||||
state_id=self.get_us_state('LA'),
|
||||
la_l4_sit_filing_status=filing_status,
|
||||
state_income_tax_additional_withholding=additional_withholding,
|
||||
la_l4_sit_exemptions=exemptions,
|
||||
la_l4_sit_dependents=dependents,
|
||||
schedule_pay=schedule_pay)
|
||||
payslip = self._createPayslip(employee, date_start, date_start + timedelta(days=7))
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self._log('Computed period tax: ' + str(expected_withholding))
|
||||
self.assertPayrollAlmostEqual(cats.get('EE_US_SIT', 0.0), -expected_withholding)
|
||||
|
||||
def test_2020_taxes_example(self):
|
||||
self._test_er_suta('LA', self.LA_UNEMP, date(2020, 1, 1), wage_base=self.LA_UNEMP_MAX_WAGE)
|
||||
self._test_sit(700.0, 'single', 0.0, 1.0, 2.0, 'weekly', date(2020, 1, 1), 19.43)
|
||||
self._test_sit(4600.0, 'married', 0.0, 2.0, 3.0, 'bi-weekly', date(2020, 1, 1), 157.12)
|
||||
self._test_sit(6000.0, 'single', 10.0, 2.0, 3.0, 'monthly', date(2020, 1, 1), 219.08)
|
||||
39
l10n_us_hr_payroll/tests/test_us_me_maine_payslip_2020.py
Normal file
39
l10n_us_hr_payroll/tests/test_us_me_maine_payslip_2020.py
Normal file
@@ -0,0 +1,39 @@
|
||||
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
|
||||
|
||||
from datetime import date, timedelta
|
||||
from .common import TestUsPayslip
|
||||
|
||||
|
||||
class TestUsMEPayslip(TestUsPayslip):
|
||||
###
|
||||
# 2020 Taxes and Rates
|
||||
###
|
||||
ME_UNEMP_MAX_WAGE = 12000.0
|
||||
ME_UNEMP = 1.92
|
||||
# Calculation based on this file page.6 and 7 https://www.maine.gov/revenue/forms/with/2020/20_WH_Tab&Instructions.pdf
|
||||
|
||||
def _test_sit(self, wage, filing_status, additional_withholding, exempt, allowances, schedule_pay, date_start, expected_withholding):
|
||||
employee = self._createEmployee()
|
||||
contract = self._createContract(employee,
|
||||
wage=wage,
|
||||
state_id=self.get_us_state('ME'),
|
||||
me_w4me_sit_filing_status=filing_status,
|
||||
state_income_tax_additional_withholding=additional_withholding,
|
||||
state_income_tax_exempt=exempt,
|
||||
me_w4me_sit_allowances=allowances,
|
||||
schedule_pay=schedule_pay)
|
||||
payslip = self._createPayslip(employee, date_start, date_start + timedelta(days=7))
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self._log('Computed period tax: ' + str(expected_withholding))
|
||||
self.assertPayrollAlmostEqual(cats.get('EE_US_SIT', 0.0), -expected_withholding)
|
||||
|
||||
def test_2020_taxes_example(self):
|
||||
self._test_er_suta('ME', self.ME_UNEMP, date(2020, 1, 1), wage_base=self.ME_UNEMP_MAX_WAGE)
|
||||
self._test_sit(300.0, 'single', 0.0, False, 2, 'weekly', date(2020, 1, 1), 0.0)
|
||||
self._test_sit(800.0, 'single', 0.0, False, 2, 'bi-weekly', date(2020, 1, 1), 6.00)
|
||||
self._test_sit(4500.0, 'married', 0.0, True, 0, 'weekly', date(2020, 1, 1), 0.00)
|
||||
self._test_sit(4500.0, 'married', 0.0, False, 2, 'monthly', date(2020, 1, 1), 113.00)
|
||||
self._test_sit(4500.0, 'married', 10.0, False, 2, 'weekly', date(2020, 1, 1), 287.00)
|
||||
self._test_sit(7000.0, '', 10.0, False, 2, 'weekly', date(2020, 1, 1), 0.00)
|
||||
194
l10n_us_hr_payroll/tests/test_us_mi_michigan_payslip_2019.py
Executable file
194
l10n_us_hr_payroll/tests/test_us_mi_michigan_payslip_2019.py
Executable file
@@ -0,0 +1,194 @@
|
||||
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
|
||||
|
||||
from .common import TestUsPayslip, process_payslip
|
||||
|
||||
|
||||
class TestUsMIPayslip(TestUsPayslip):
|
||||
# Taxes and Rates
|
||||
MI_UNEMP_MAX_WAGE = 9500.0
|
||||
MI_UNEMP = - 2.7 / 100.0
|
||||
MI_INC_TAX = - 4.25 / 100.0
|
||||
ANNUAL_EXEMPTION_AMOUNT = 4400.00
|
||||
PAY_PERIOD_DIVISOR = {
|
||||
'weekly': 52.0,
|
||||
'bi-weekly': 26.0,
|
||||
'semi-monthly': 24.0,
|
||||
'monthly': 12.0
|
||||
}
|
||||
|
||||
def test_2019_taxes_weekly(self):
|
||||
salary = 5000.0
|
||||
schedule_pay = 'weekly'
|
||||
exemptions = 1
|
||||
|
||||
employee = self._createEmployee()
|
||||
contract = self._createContract(employee,
|
||||
wage=salary,
|
||||
state_id=self.get_us_state('MI'),
|
||||
state_income_tax_additional_withholding=0.0,
|
||||
mi_w4_sit_exemptions=1.0,
|
||||
schedule_pay='weekly')
|
||||
|
||||
allowance_amount = self.ANNUAL_EXEMPTION_AMOUNT / self.PAY_PERIOD_DIVISOR[schedule_pay]
|
||||
wh = -((salary - (allowance_amount * exemptions)) * -self.MI_INC_TAX)
|
||||
|
||||
self._log('2019 Michigan tax first payslip weekly:')
|
||||
payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31')
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self.assertPayrollEqual(cats['ER_US_SUTA'], salary * self.MI_UNEMP)
|
||||
self.assertPayrollAlmostEqual(cats['EE_US_SIT'], wh)
|
||||
#
|
||||
process_payslip(payslip)
|
||||
|
||||
# Make a new payslip, this one will have maximums
|
||||
remaining_MI_UNEMP_wages = self.MI_UNEMP_MAX_WAGE - salary if (self.MI_UNEMP_MAX_WAGE - 2*salary < salary) \
|
||||
else salary
|
||||
|
||||
self._log('2019 Michigan tax second payslip weekly:')
|
||||
payslip = self._createPayslip(employee, '2019-02-01', '2019-02-28')
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self.assertPayrollEqual(cats['ER_US_SUTA'], remaining_MI_UNEMP_wages * self.MI_UNEMP)
|
||||
|
||||
def test_2019_taxes_biweekly(self):
|
||||
salary = 5000.0
|
||||
schedule_pay = 'bi-weekly'
|
||||
allowance_amount = self.ANNUAL_EXEMPTION_AMOUNT / self.PAY_PERIOD_DIVISOR[schedule_pay]
|
||||
exemption = 2
|
||||
|
||||
wh = -((salary - (allowance_amount * exemption)) * -self.MI_INC_TAX)
|
||||
|
||||
employee = self._createEmployee()
|
||||
contract = self._createContract(employee,
|
||||
wage=salary,
|
||||
state_id=self.get_us_state('MI'),
|
||||
state_income_tax_additional_withholding=0.0,
|
||||
mi_w4_sit_exemptions=2.0,
|
||||
schedule_pay='bi-weekly')
|
||||
|
||||
self._log('2019 Michigan tax first payslip bi-weekly:')
|
||||
payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31')
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self.assertPayrollEqual(cats['ER_US_SUTA'], salary * self.MI_UNEMP)
|
||||
self.assertPayrollEqual(cats['EE_US_SIT'], wh)
|
||||
|
||||
process_payslip(payslip)
|
||||
|
||||
# Make a new payslip, this one will have maximums
|
||||
remaining_MI_UNEMP_wages = self.MI_UNEMP_MAX_WAGE - salary if (self.MI_UNEMP_MAX_WAGE - 2*salary < salary) \
|
||||
else salary
|
||||
|
||||
self._log('2019 Michigan tax second payslip bi-weekly:')
|
||||
payslip = self._createPayslip(employee, '2019-02-01', '2019-02-28')
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self.assertPayrollEqual(cats['ER_US_SUTA'], remaining_MI_UNEMP_wages * self.MI_UNEMP)
|
||||
|
||||
def test_2019_taxes_semimonthly(self):
|
||||
salary = 5000.0
|
||||
schedule_pay = 'semi-monthly'
|
||||
allowance_amount = self.ANNUAL_EXEMPTION_AMOUNT / self.PAY_PERIOD_DIVISOR[schedule_pay]
|
||||
exemption = 1
|
||||
|
||||
wh = -((salary - (allowance_amount * exemption)) * -self.MI_INC_TAX)
|
||||
|
||||
employee = self._createEmployee()
|
||||
contract = self._createContract(employee,
|
||||
wage=salary,
|
||||
state_id=self.get_us_state('MI'),
|
||||
state_income_tax_additional_withholding=0.0,
|
||||
mi_w4_sit_exemptions=1.0,
|
||||
schedule_pay='semi-monthly')
|
||||
|
||||
self._log('2019 Michigan tax first payslip semi-monthly:')
|
||||
payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31')
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self.assertPayrollEqual(cats['ER_US_SUTA'], salary * self.MI_UNEMP)
|
||||
self.assertPayrollEqual(cats['EE_US_SIT'], wh)
|
||||
|
||||
process_payslip(payslip)
|
||||
|
||||
# Make a new payslip, this one will have maximums
|
||||
remaining_MI_UNEMP_wages = self.MI_UNEMP_MAX_WAGE - salary if (self.MI_UNEMP_MAX_WAGE - 2 * salary < salary) \
|
||||
else salary
|
||||
|
||||
self._log('2019 Michigan tax second payslip semi-monthly:')
|
||||
payslip = self._createPayslip(employee, '2019-02-01', '2019-02-28')
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self.assertPayrollEqual(cats['ER_US_SUTA'], remaining_MI_UNEMP_wages * self.MI_UNEMP)
|
||||
|
||||
def test_2019_taxes_monthly(self):
|
||||
salary = 5000.0
|
||||
schedule_pay = 'monthly'
|
||||
allowance_amount = self.ANNUAL_EXEMPTION_AMOUNT / self.PAY_PERIOD_DIVISOR[schedule_pay]
|
||||
exemption = 1
|
||||
|
||||
wh = -((salary - (allowance_amount * exemption)) * -self.MI_INC_TAX)
|
||||
|
||||
employee = self._createEmployee()
|
||||
contract = self._createContract(employee,
|
||||
wage=salary,
|
||||
state_id=self.get_us_state('MI'),
|
||||
state_income_tax_additional_withholding=0.0,
|
||||
mi_w4_sit_exemptions=1.0,
|
||||
schedule_pay='monthly')
|
||||
|
||||
self._log('2019 Michigan tax first payslip monthly:')
|
||||
payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31')
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self.assertPayrollEqual(cats['ER_US_SUTA'], salary * self.MI_UNEMP)
|
||||
self.assertPayrollEqual(cats['EE_US_SIT'], wh)
|
||||
|
||||
process_payslip(payslip)
|
||||
|
||||
# Make a new payslip, this one will have maximums
|
||||
remaining_MI_UNEMP_wages = self.MI_UNEMP_MAX_WAGE - salary if (
|
||||
self.MI_UNEMP_MAX_WAGE - (2 * salary) < salary) \
|
||||
else salary
|
||||
|
||||
self._log('2019 Michigan tax second payslip monthly:')
|
||||
payslip = self._createPayslip(employee, '2019-02-01', '2019-02-28')
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self.assertPayrollEqual(cats['ER_US_SUTA'], remaining_MI_UNEMP_wages * self.MI_UNEMP)
|
||||
|
||||
def test_additional_withholding(self):
|
||||
salary = 5000.0
|
||||
schedule_pay = 'weekly'
|
||||
allowance_amount = 0.0
|
||||
allowance_amount = self.ANNUAL_EXEMPTION_AMOUNT / self.PAY_PERIOD_DIVISOR[schedule_pay]
|
||||
additional_wh = 40.0
|
||||
exemption = 1
|
||||
|
||||
wh = -(((salary - (allowance_amount * exemption)) * -self.MI_INC_TAX) + additional_wh)
|
||||
|
||||
employee = self._createEmployee()
|
||||
contract = self._createContract(employee,
|
||||
wage=salary,
|
||||
state_id=self.get_us_state('MI'),
|
||||
state_income_tax_additional_withholding=40.0,
|
||||
mi_w4_sit_exemptions=1.0,
|
||||
schedule_pay='weekly')
|
||||
|
||||
self._log('2019 Michigan tax first payslip with additional withholding:')
|
||||
payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31')
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self.assertPayrollEqual(cats['ER_US_SUTA'], salary * self.MI_UNEMP)
|
||||
self.assertPayrollAlmostEqual(cats['EE_US_SIT'], wh)
|
||||
|
||||
process_payslip(payslip)
|
||||
35
l10n_us_hr_payroll/tests/test_us_mi_michigan_payslip_2020.py
Executable file
35
l10n_us_hr_payroll/tests/test_us_mi_michigan_payslip_2020.py
Executable file
@@ -0,0 +1,35 @@
|
||||
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
|
||||
|
||||
from datetime import date, timedelta
|
||||
from .common import TestUsPayslip
|
||||
|
||||
|
||||
class TestUsMIPayslip(TestUsPayslip):
|
||||
# Taxes and Rates
|
||||
MI_UNEMP_MAX_WAGE = 9000.0
|
||||
MI_UNEMP = 2.7
|
||||
|
||||
def _test_sit(self, wage, exemptions, additional_withholding, schedule_pay, date_start, expected_withholding):
|
||||
|
||||
employee = self._createEmployee()
|
||||
contract = self._createContract(employee,
|
||||
wage=wage,
|
||||
state_id=self.get_us_state('MI'),
|
||||
mi_w4_sit_exemptions=exemptions,
|
||||
state_income_tax_additional_withholding=additional_withholding,
|
||||
schedule_pay=schedule_pay)
|
||||
payslip = self._createPayslip(employee, date_start, date_start + timedelta(days=7))
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self._log('Computed period tax: ' + str(expected_withholding))
|
||||
self.assertPayrollEqual(cats.get('EE_US_SIT', 0.0), -expected_withholding)
|
||||
|
||||
def test_2020_taxes_example(self):
|
||||
self._test_er_suta('MI', self.MI_UNEMP, date(2020, 1, 1), wage_base=self.MI_UNEMP_MAX_WAGE)
|
||||
self._test_sit(750.0, 1, 100.0, 'weekly', date(2020, 1, 1), 127.99)
|
||||
self._test_sit(1750.0, 1, 0.0, 'bi-weekly', date(2020, 1, 1), 66.61)
|
||||
self._test_sit(5000.0, 1, 5.0, 'semi-monthly', date(2020, 1, 1), 209.09)
|
||||
self._test_sit(8000.0, 1, 5.0, 'monthly', date(2020, 1, 1), 328.18)
|
||||
self._test_sit(5000.0, 2, 0.0, 'monthly', date(2020, 1, 1), 178.86)
|
||||
|
||||
159
l10n_us_hr_payroll/tests/test_us_mn_minnesota_payslip_2019.py
Executable file
159
l10n_us_hr_payroll/tests/test_us_mn_minnesota_payslip_2019.py
Executable file
@@ -0,0 +1,159 @@
|
||||
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
|
||||
|
||||
from .common import TestUsPayslip, process_payslip
|
||||
|
||||
|
||||
class TestUsMNPayslip(TestUsPayslip):
|
||||
# TAXES AND RATES
|
||||
MN_UNEMP_MAX_WAGE = 34000.0
|
||||
MN_UNEMP = -1.11 / 100.0
|
||||
|
||||
def test_taxes_weekly(self):
|
||||
salary = 30000.0
|
||||
# Hand Calculated Amount to Test
|
||||
# Step 1 -> 30000.00 for wages per period Step 2 -> 52.0 for weekly -> 30000 * 52 -> 1560000
|
||||
# Step 3 -> allowances * 4250.0 -> 4250.00 in this case.
|
||||
# Step 4 -> Step 2 - Step 3 -> 1560000 - 4250.00 -> 1555750
|
||||
# Step 5 -> using chart -> we have last row -> ((1555750 - 166290) * (9.85 / 100)) + 11717.65 -> 148579.46
|
||||
# Step 6 -> Convert back to pay period amount and round - > 2857.297 - > 2857.0
|
||||
# wh = 2857.0
|
||||
wh = -2857.0
|
||||
|
||||
employee = self._createEmployee()
|
||||
contract = self._createContract(employee,
|
||||
wage=salary,
|
||||
state_id=self.get_us_state('MN'),
|
||||
mn_w4mn_sit_filing_status='single',
|
||||
state_income_tax_additional_withholding=0.0,
|
||||
mn_w4mn_sit_allowances=1.0,
|
||||
schedule_pay='weekly')
|
||||
|
||||
self._log('2019 Minnesota tax first payslip weekly:')
|
||||
payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31')
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self.assertPayrollEqual(cats['ER_US_SUTA'], salary * self.MN_UNEMP)
|
||||
self.assertPayrollAlmostEqual(cats['EE_US_SIT'], wh) # Test numbers are off by 1 penny
|
||||
|
||||
process_payslip(payslip)
|
||||
|
||||
# Make a new payslip, this one will have maximums
|
||||
remaining_MN_UNEMP_wages = self.MN_UNEMP_MAX_WAGE - salary if (self.MN_UNEMP_MAX_WAGE - 2*salary < salary) \
|
||||
else salary
|
||||
|
||||
self._log('2019 Minnesota tax second payslip weekly:')
|
||||
payslip = self._createPayslip(employee, '2019-02-01', '2019-02-28')
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self.assertPayrollEqual(cats['ER_US_SUTA'], remaining_MN_UNEMP_wages * self.MN_UNEMP)
|
||||
|
||||
def test_taxes_married(self):
|
||||
salary = 5000.00
|
||||
|
||||
# Hand Calculated Amount to Test
|
||||
# Step 1 -> 5000.0 for wages per period Step 2 -> 52.0 for weekly -> 5000 * 52 -> 260,000
|
||||
# Step 3 -> allowances * 4250.0 -> 4250.00 in this case.
|
||||
# Step 4 -> Step 2 - Step 3 -> 260,000 - 4250.00 -> 255750.0
|
||||
# For step five we used the married section
|
||||
# Step 5 -> using chart -> we have 2nd last row -> ((255750 - 163070) * (7.85 / 100)) + 10199.33 ->
|
||||
# Step 6 -> Convert back to pay period amount and round
|
||||
# wh = 336.0
|
||||
wh = -336.0
|
||||
|
||||
employee = self._createEmployee()
|
||||
contract = self._createContract(employee,
|
||||
wage=salary,
|
||||
state_id=self.get_us_state('MN'),
|
||||
mn_w4mn_sit_filing_status='married',
|
||||
state_income_tax_additional_withholding=0.0,
|
||||
mn_w4mn_sit_allowances=1.0,
|
||||
schedule_pay='weekly')
|
||||
|
||||
self._log('2019 Minnesota tax first payslip married:')
|
||||
payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31')
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self.assertPayrollEqual(cats['ER_US_SUTA'], salary * self.MN_UNEMP)
|
||||
self.assertPayrollAlmostEqual(cats['EE_US_SIT'], wh)
|
||||
|
||||
def test_taxes_semimonthly(self):
|
||||
salary = 6500.00
|
||||
# Hand Calculated Amount to Test
|
||||
# Step 1 -> 6500.00 for wages per period Step 2 -> 24 for semi-monthly -> 6500.00 * 24 -> 156000.00
|
||||
# Step 3 -> allowances * 4250.0 -> 4250.00 in this case.
|
||||
# Step 4 -> Step 2 - Step 3 -> 156000.00 - 4250.00 -> 151750.0
|
||||
# Step 5 -> using chart -> we have 2nd last row -> ((151750.0- 89510) * (7.85 / 100)) + 5690.42 -> 10576.26
|
||||
# Step 6 -> Convert back to pay period amount and round
|
||||
# wh = -441
|
||||
wh = -441.00
|
||||
|
||||
employee = self._createEmployee()
|
||||
contract = self._createContract(employee,
|
||||
wage=salary,
|
||||
state_id=self.get_us_state('MN'),
|
||||
mn_w4mn_sit_filing_status='single',
|
||||
state_income_tax_additional_withholding=0.0,
|
||||
mn_w4mn_sit_allowances=1.0,
|
||||
schedule_pay='semi-monthly')
|
||||
|
||||
|
||||
self._log('2019 Minnesota tax first payslip semimonthly:')
|
||||
payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31')
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self.assertPayrollEqual(cats['ER_US_SUTA'], salary * self.MN_UNEMP)
|
||||
self.assertPayrollAlmostEqual(cats['EE_US_SIT'], wh)
|
||||
|
||||
def test_tax_exempt(self):
|
||||
salary = 5500.00
|
||||
wh = 0
|
||||
employee = self._createEmployee()
|
||||
contract = self._createContract(employee,
|
||||
wage=salary,
|
||||
state_id=self.get_us_state('MN'),
|
||||
mn_w4mn_sit_filing_status='',
|
||||
state_income_tax_additional_withholding=0.0,
|
||||
mn_w4mn_sit_allowances=2.0,
|
||||
schedule_pay='weekly')
|
||||
|
||||
self._log('2019 Minnesota tax first payslip exempt:')
|
||||
payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31')
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self.assertPayrollEqual(cats['ER_US_SUTA'], salary * self.MN_UNEMP)
|
||||
self.assertPayrollAlmostEqual(cats['EE_US_SIT'], wh)
|
||||
|
||||
def test_additional_withholding(self):
|
||||
salary = 5500.0
|
||||
# Hand Calculated Amount to Test
|
||||
# Step 1 -> 5500 for wages per period Step 2 -> 52 for weekly -> 5500 * 52 -> 286000.00
|
||||
# Step 3 -> allowances * 4250.0 -> 8500 in this case.
|
||||
# Step 4 -> Step 2 - Step 3 -> 286000.00 - 8500 -> 277500
|
||||
# Step 5 -> using chart -> we have last row -> ((277500- 166290) * (9.85 / 100)) + 11717.65 -> 22671.835
|
||||
# Step 6 -> Convert back to pay period amount and round
|
||||
# wh = -436.0
|
||||
# Add additional_withholding
|
||||
# wh = -436.0 + 40.0
|
||||
wh = -476.0
|
||||
|
||||
employee = self._createEmployee()
|
||||
contract = self._createContract(employee,
|
||||
wage=salary,
|
||||
state_id=self.get_us_state('MN'),
|
||||
mn_w4mn_sit_filing_status='single',
|
||||
state_income_tax_additional_withholding=40.0,
|
||||
mn_w4mn_sit_allowances=2.0,
|
||||
schedule_pay='weekly')
|
||||
|
||||
self._log('2019 Minnesota tax first payslip additional withholding:')
|
||||
payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31')
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self.assertPayrollEqual(cats['ER_US_SUTA'], salary * self.MN_UNEMP)
|
||||
self.assertPayrollAlmostEqual(cats['EE_US_SIT'], wh)
|
||||
36
l10n_us_hr_payroll/tests/test_us_mn_minnesota_payslip_2020.py
Executable file
36
l10n_us_hr_payroll/tests/test_us_mn_minnesota_payslip_2020.py
Executable file
@@ -0,0 +1,36 @@
|
||||
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
|
||||
|
||||
from datetime import date, timedelta
|
||||
from .common import TestUsPayslip
|
||||
|
||||
|
||||
class TestUsMNPayslip(TestUsPayslip):
|
||||
# TAXES AND RATES
|
||||
MN_UNEMP_MAX_WAGE = 35000.0
|
||||
MN_UNEMP = 1.11
|
||||
|
||||
def _test_sit(self, wage, filing_status, allowances, additional_withholding, schedule_pay, date_start, expected_withholding):
|
||||
employee = self._createEmployee()
|
||||
contract = self._createContract(employee,
|
||||
wage=wage,
|
||||
state_id=self.get_us_state('MN'),
|
||||
mn_w4mn_sit_filing_status=filing_status,
|
||||
state_income_tax_additional_withholding=additional_withholding,
|
||||
mn_w4mn_sit_allowances=allowances,
|
||||
schedule_pay=schedule_pay)
|
||||
|
||||
payslip = self._createPayslip(employee, date_start, date_start + timedelta(days=7))
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self._log('Computed period tax: ' + str(expected_withholding))
|
||||
self.assertPayrollEqual(cats.get('EE_US_SIT', 0.0), -expected_withholding)
|
||||
|
||||
def test_2020_taxes_example(self):
|
||||
self._test_er_suta('MN', self.MN_UNEMP, date(2020, 1, 1), wage_base=self.MN_UNEMP_MAX_WAGE)
|
||||
self._test_sit(5000.0, 'single', 1.0, 0.0, 'weekly', date(2020, 1, 1), 389.0)
|
||||
self._test_sit(30000.0, 'single', 1.0, 0.0, 'weekly', date(2020, 1, 1), 2850.99)
|
||||
self._test_sit(5000.0, 'married', 1.0, 0.0, 'weekly', date(2020, 1, 1), 325.0)
|
||||
self._test_sit(6500.0, 'single', 1.0, 0.0, 'semi-monthly', date(2020, 1, 1), 429.0)
|
||||
self._test_sit(5500.0, '', 2.0, 0.0, 'weekly', date(2020, 1, 1), 0.0)
|
||||
self._test_sit(5500.0, 'single', 2.0, 40.0, 'weekly', date(2020, 1, 1), 470.0)
|
||||
188
l10n_us_hr_payroll/tests/test_us_mo_missouri_payslip_2019.py
Executable file
188
l10n_us_hr_payroll/tests/test_us_mo_missouri_payslip_2019.py
Executable file
@@ -0,0 +1,188 @@
|
||||
|
||||
from datetime import date
|
||||
from .common import TestUsPayslip
|
||||
|
||||
|
||||
class TestUsMoPayslip(TestUsPayslip):
|
||||
# Calculations from http://dor.mo.gov/forms/4282_2019.pdf
|
||||
SALARY = 12000.0
|
||||
MO_UNEMP = -2.376 / 100.0
|
||||
|
||||
TAX = [
|
||||
(1053.0, 1.5),
|
||||
(1053.0, 2.0),
|
||||
(1053.0, 2.5),
|
||||
(1053.0, 3.0),
|
||||
(1053.0, 3.5),
|
||||
(1053.0, 4.0),
|
||||
(1053.0, 4.5),
|
||||
(1053.0, 5.0),
|
||||
(999999999.0, 5.4),
|
||||
]
|
||||
|
||||
def test_2019_taxes_single(self):
|
||||
# Payroll Period Monthly
|
||||
salary = self.SALARY
|
||||
pp = 12.0
|
||||
gross_salary = salary * pp
|
||||
spouse_employed = False
|
||||
|
||||
# Single
|
||||
standard_deduction = 12400.0
|
||||
|
||||
employee = self._createEmployee()
|
||||
contract = self._createContract(employee,
|
||||
wage=salary,
|
||||
state_id=self.get_us_state('MO'),
|
||||
mo_mow4_sit_filing_status='single',
|
||||
state_income_tax_additional_withholding=0.0,
|
||||
schedule_pay='monthly')
|
||||
|
||||
self._log('2019 Missouri tax single first payslip:')
|
||||
payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31')
|
||||
|
||||
payslip.compute_sheet()
|
||||
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self.assertPayrollEqual(cats['ER_US_SUTA'], salary * self.MO_UNEMP)
|
||||
|
||||
mo_taxable_income = gross_salary - standard_deduction
|
||||
self._log('%s = %s - %s -' % (mo_taxable_income, gross_salary, standard_deduction))
|
||||
|
||||
remaining_taxable_income = mo_taxable_income
|
||||
tax = 0.0
|
||||
for amt, rate in self.TAX:
|
||||
amt = float(amt)
|
||||
rate = rate / 100.0
|
||||
self._log(str(amt) + ' : ' + str(rate) + ' : ' + str(remaining_taxable_income))
|
||||
if (remaining_taxable_income - amt) > 0.0 or (remaining_taxable_income - amt) == 0.0:
|
||||
tax += rate * amt
|
||||
else:
|
||||
tax += rate * remaining_taxable_income
|
||||
break
|
||||
remaining_taxable_income = remaining_taxable_income - amt
|
||||
|
||||
tax = -tax
|
||||
self._log('Computed annual tax: ' + str(tax))
|
||||
|
||||
tax = tax / pp
|
||||
tax = round(tax)
|
||||
self._log('Computed period tax: ' + str(tax))
|
||||
self.assertPayrollEqual(cats['EE_US_SIT'], tax)
|
||||
|
||||
def test_2019_spouse_not_employed(self):
|
||||
# Payroll Period Semi-monthly
|
||||
salary = self.SALARY
|
||||
pp = 24.0
|
||||
gross_salary = salary * pp
|
||||
|
||||
# Married
|
||||
standard_deduction = 24800.0
|
||||
|
||||
employee = self._createEmployee()
|
||||
|
||||
contract = self._createContract(employee,
|
||||
wage=salary,
|
||||
state_id=self.get_us_state('MO'),
|
||||
mo_mow4_sit_filing_status='married',
|
||||
state_income_tax_additional_withholding=0.0,
|
||||
schedule_pay='semi-monthly')
|
||||
|
||||
self._log('2019 Missouri tax first payslip:')
|
||||
payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31')
|
||||
|
||||
payslip.compute_sheet()
|
||||
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
mo_taxable_income = gross_salary - standard_deduction
|
||||
self._log(mo_taxable_income)
|
||||
|
||||
remaining_taxable_income = mo_taxable_income
|
||||
tax = 0.0
|
||||
for amt, rate in self.TAX:
|
||||
amt = float(amt)
|
||||
rate = rate / 100.0
|
||||
self._log(str(amt) + ' : ' + str(rate) + ' : ' + str(remaining_taxable_income))
|
||||
if (remaining_taxable_income - amt) > 0.0 or (remaining_taxable_income - amt) == 0.0:
|
||||
tax += rate * amt
|
||||
else:
|
||||
tax += rate * remaining_taxable_income
|
||||
break
|
||||
remaining_taxable_income = remaining_taxable_income - amt
|
||||
|
||||
tax = -tax
|
||||
self._log('Computed annual tax: ' + str(tax))
|
||||
|
||||
tax = tax / pp
|
||||
tax = round(tax)
|
||||
self._log('Computed period tax: ' + str(tax))
|
||||
self.assertPayrollEqual(cats['EE_US_SIT'], tax)
|
||||
|
||||
def test_2019_head_of_household(self):
|
||||
# Payroll Period Weekly
|
||||
salary = self.SALARY
|
||||
|
||||
# Payroll Period Weekly
|
||||
salary = self.SALARY
|
||||
pp = 52.0
|
||||
gross_salary = salary * pp
|
||||
|
||||
# Single HoH
|
||||
standard_deduction = 18650.0
|
||||
|
||||
employee = self._createEmployee()
|
||||
|
||||
contract = self._createContract(employee,
|
||||
wage=salary,
|
||||
state_id=self.get_us_state('MO'),
|
||||
mo_mow4_sit_filing_status='head_of_household',
|
||||
state_income_tax_additional_withholding=0.0,
|
||||
schedule_pay='weekly')
|
||||
|
||||
self._log('2019 Missouri tax first payslip:')
|
||||
payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31')
|
||||
|
||||
payslip.compute_sheet()
|
||||
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
mo_taxable_income = gross_salary - standard_deduction
|
||||
self._log(mo_taxable_income)
|
||||
|
||||
remaining_taxable_income = mo_taxable_income
|
||||
tax = 0.0
|
||||
for amt, rate in self.TAX:
|
||||
amt = float(amt)
|
||||
rate = rate / 100.0
|
||||
self._log(str(amt) + ' : ' + str(rate) + ' : ' + str(remaining_taxable_income))
|
||||
if (remaining_taxable_income - amt) > 0.0 or (remaining_taxable_income - amt) == 0.0:
|
||||
tax += rate * amt
|
||||
else:
|
||||
tax += rate * remaining_taxable_income
|
||||
break
|
||||
remaining_taxable_income = remaining_taxable_income - amt
|
||||
tax = -tax
|
||||
self._log('Computed annual tax: ' + str(tax))
|
||||
|
||||
tax = tax / pp
|
||||
tax = round(tax)
|
||||
self._log('Computed period tax: ' + str(tax))
|
||||
self.assertPayrollEqual(cats['EE_US_SIT'], tax)
|
||||
|
||||
def test_2019_underflow(self):
|
||||
# Payroll Period Weekly
|
||||
salary = 200.0
|
||||
|
||||
employee = self._createEmployee()
|
||||
|
||||
contract = self._createContract(employee,
|
||||
wage=salary,
|
||||
state_id=self.get_us_state('MO'))
|
||||
|
||||
payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31')
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self.assertPayrollEqual(cats['EE_US_SIT'], 0.0)
|
||||
34
l10n_us_hr_payroll/tests/test_us_mo_missouri_payslip_2020.py
Executable file
34
l10n_us_hr_payroll/tests/test_us_mo_missouri_payslip_2020.py
Executable file
@@ -0,0 +1,34 @@
|
||||
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
|
||||
|
||||
from datetime import date, timedelta
|
||||
from .common import TestUsPayslip
|
||||
|
||||
|
||||
class TestUsMoPayslip(TestUsPayslip):
|
||||
# Calculations from http://dor.mo.gov/forms/4282_2020.pdf
|
||||
MO_UNEMP_MAX_WAGE = 11500.0
|
||||
MO_UNEMP = 2.376
|
||||
|
||||
def _test_sit(self, wage, filing_status, additional_withholding, schedule_pay, date_start, expected_withholding):
|
||||
employee = self._createEmployee()
|
||||
contract = self._createContract(employee,
|
||||
wage=wage,
|
||||
state_id=self.get_us_state('MO'),
|
||||
mo_mow4_sit_filing_status=filing_status,
|
||||
state_income_tax_additional_withholding=additional_withholding,
|
||||
schedule_pay=schedule_pay)
|
||||
payslip = self._createPayslip(employee, date_start, date_start + timedelta(days=7))
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self._log('Computed period tax: ' + str(expected_withholding))
|
||||
self.assertPayrollAlmostEqual(cats.get('EE_US_SIT', 0.0), -expected_withholding)
|
||||
|
||||
def test_2020_taxes_example(self):
|
||||
self._test_er_suta('MO', self.MO_UNEMP, date(2020, 1, 1), wage_base=self.MO_UNEMP_MAX_WAGE)
|
||||
self._test_sit(750.0, 'single', 0.0, 'weekly', date(2020, 1, 1), 24.00)
|
||||
self._test_sit(2500.0, 'single', 5.0, 'bi-weekly', date(2020, 1, 1), 107.00)
|
||||
self._test_sit(7000.0, 'married', 0.0, 'monthly', date(2020, 1, 1), 251.00)
|
||||
self._test_sit(5000.0, 'married', 10.0, 'semi-monthly', date(2020, 1, 1), 217.00)
|
||||
self._test_sit(6000.0, '', 0.0, 'monthly', date(2020, 1, 1), 0.00)
|
||||
|
||||
94
l10n_us_hr_payroll/tests/test_us_ms_mississippi_payslip_2019.py
Executable file
94
l10n_us_hr_payroll/tests/test_us_ms_mississippi_payslip_2019.py
Executable file
@@ -0,0 +1,94 @@
|
||||
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
|
||||
|
||||
from .common import TestUsPayslip
|
||||
|
||||
|
||||
class TestUsMsPayslip(TestUsPayslip):
|
||||
# Calculations from https://www.dor.ms.gov/Documents/Computer%20Payroll%20Accounting%201-2-19.pdf
|
||||
MS_UNEMP = -1.2 / 100.0
|
||||
|
||||
def test_2019_taxes_one(self):
|
||||
salary = 1250.0
|
||||
ms_89_350_exemption = 11000.0
|
||||
|
||||
employee = self._createEmployee()
|
||||
contract = self._createContract(employee,
|
||||
wage=salary,
|
||||
state_id=self.get_us_state('MS'),
|
||||
ms_89_350_sit_filing_status='head_of_household',
|
||||
ms_89_350_sit_exemption_value=ms_89_350_exemption,
|
||||
state_income_tax_additional_withholding=0.0,
|
||||
schedule_pay='semi-monthly')
|
||||
|
||||
self._log('2019 Mississippi tax single first payslip:')
|
||||
payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31')
|
||||
|
||||
payslip.compute_sheet()
|
||||
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self.assertPayrollEqual(cats['ER_US_SUTA'], salary * self.MS_UNEMP)
|
||||
|
||||
STDED = 3400.0 # Head of Household
|
||||
AGP = salary * 24 # Semi-Monthly
|
||||
TI = AGP - (ms_89_350_exemption + STDED)
|
||||
self.assertPayrollEqual(TI, 15600.0)
|
||||
TAX = ((TI - 10000) * 0.05) + 290 # Over 10,000
|
||||
self.assertPayrollEqual(TAX, 570.0)
|
||||
|
||||
ms_withhold = round(TAX / 24) # Semi-Monthly
|
||||
self.assertPayrollEqual(cats['EE_US_SIT'], -ms_withhold)
|
||||
|
||||
def test_2019_taxes_one_exempt(self):
|
||||
salary = 1250.0
|
||||
ms_89_350_exemption = 11000.0
|
||||
|
||||
employee = self._createEmployee()
|
||||
contract = self._createContract(employee,
|
||||
wage=salary,
|
||||
state_id=self.get_us_state('MS'),
|
||||
ms_89_350_sit_filing_status='',
|
||||
ms_89_350_sit_exemption_value=ms_89_350_exemption,
|
||||
state_income_tax_additional_withholding=0.0,
|
||||
schedule_pay='semi-monthly')
|
||||
|
||||
self._log('2019 Mississippi tax single first payslip:')
|
||||
payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31')
|
||||
|
||||
payslip.compute_sheet()
|
||||
|
||||
cats = self._getCategories(payslip)
|
||||
self.assertPayrollEqual(cats.get('EE_US_SIT', 0.0), 0.0)
|
||||
|
||||
def test_2019_taxes_additional(self):
|
||||
salary = 1250.0
|
||||
ms_89_350_exemption = 11000.0
|
||||
additional = 40.0
|
||||
|
||||
employee = self._createEmployee()
|
||||
contract = self._createContract(employee,
|
||||
wage=salary,
|
||||
state_id=self.get_us_state('MS'),
|
||||
ms_89_350_sit_filing_status='head_of_household',
|
||||
ms_89_350_sit_exemption_value=ms_89_350_exemption,
|
||||
state_income_tax_additional_withholding=additional,
|
||||
schedule_pay='semi-monthly')
|
||||
|
||||
self._log('2019 Mississippi tax single first payslip:')
|
||||
payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31')
|
||||
|
||||
payslip.compute_sheet()
|
||||
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self.assertPayrollEqual(cats['ER_US_SUTA'], salary * self.MS_UNEMP)
|
||||
|
||||
STDED = 3400.0 # Head of Household
|
||||
AGP = salary * 24 # Semi-Monthly
|
||||
TI = AGP - (ms_89_350_exemption + STDED)
|
||||
self.assertPayrollEqual(TI, 15600.0)
|
||||
TAX = ((TI - 10000) * 0.05) + 290 # Over 10,000
|
||||
self.assertPayrollEqual(TAX, 570.0)
|
||||
|
||||
ms_withhold = round(TAX / 24) # Semi-Monthly
|
||||
self.assertPayrollEqual(cats['EE_US_SIT'], -ms_withhold + -additional)
|
||||
35
l10n_us_hr_payroll/tests/test_us_ms_mississippi_payslip_2020.py
Executable file
35
l10n_us_hr_payroll/tests/test_us_ms_mississippi_payslip_2020.py
Executable file
@@ -0,0 +1,35 @@
|
||||
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
|
||||
|
||||
from datetime import date, timedelta
|
||||
from .common import TestUsPayslip
|
||||
|
||||
|
||||
class TestUsMsPayslip(TestUsPayslip):
|
||||
# Calculations from https://www.dor.ms.gov/Documents/Computer%20Payroll%20Flowchart.pdf
|
||||
MS_UNEMP = 1.2
|
||||
MS_UNEMP_MAX_WAGE = 14000.0
|
||||
|
||||
def _test_sit(self, wage, filing_status, additional_withholding, exemption, schedule_pay, date_start, expected_withholding):
|
||||
employee = self._createEmployee()
|
||||
contract = self._createContract(employee,
|
||||
wage=wage,
|
||||
state_id=self.get_us_state('MS'),
|
||||
ms_89_350_sit_filing_status=filing_status,
|
||||
state_income_tax_additional_withholding=additional_withholding,
|
||||
ms_89_350_sit_exemption_value=exemption,
|
||||
schedule_pay=schedule_pay)
|
||||
payslip = self._createPayslip(employee, date_start, date_start + timedelta(days=7))
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self._log('Computed period tax: ' + str(expected_withholding))
|
||||
self.assertPayrollAlmostEqual(cats.get('EE_US_SIT', 0.0), -expected_withholding)
|
||||
|
||||
def test_2020_taxes_example(self):
|
||||
self._test_er_suta('MS', self.MS_UNEMP, date(2020, 1, 1), wage_base=self.MS_UNEMP_MAX_WAGE)
|
||||
self._test_sit(1250.0, 'head_of_household', 0.0, 11000, 'semi-monthly', date(2020, 1, 1), 22.00)
|
||||
self._test_sit(500.0, '', 5.0, 0, 'bi-weekly', date(2020, 1, 1), 0.00)
|
||||
self._test_sit(12000.0, 'single', 0.0, 11000, 'monthly', date(2020, 1, 1), 525.00)
|
||||
self._test_sit(2500.0, 'married', 5.0, 500, 'bi-weekly', date(2020, 1, 1), 111.00)
|
||||
|
||||
|
||||
139
l10n_us_hr_payroll/tests/test_us_mt_montana_payslip_2019.py
Executable file
139
l10n_us_hr_payroll/tests/test_us_mt_montana_payslip_2019.py
Executable file
@@ -0,0 +1,139 @@
|
||||
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
|
||||
|
||||
from .common import TestUsPayslip, process_payslip
|
||||
|
||||
|
||||
class TestUsMtPayslip(TestUsPayslip):
|
||||
# Calculations from https://app.mt.gov/myrevenue/Endpoint/DownloadPdf?yearId=705
|
||||
MT_UNEMP = -1.18 / 100.0
|
||||
MT_UNEMP_AFT = -0.13 / 100.0
|
||||
|
||||
def test_2019_taxes_one(self):
|
||||
# Payroll Period Semi-Monthly example
|
||||
salary = 550
|
||||
mt_mw4_exemptions = 5
|
||||
|
||||
employee = self._createEmployee()
|
||||
contract = self._createContract(employee,
|
||||
wage=salary,
|
||||
state_id=self.get_us_state('MT'),
|
||||
mt_mw4_sit_exemptions=mt_mw4_exemptions,
|
||||
schedule_pay='semi-monthly')
|
||||
|
||||
self._log('2019 Montana tax single first payslip:')
|
||||
payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31')
|
||||
|
||||
payslip.compute_sheet()
|
||||
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self.assertPayrollEqual(cats['ER_US_SUTA'], salary * (self.MT_UNEMP + self.MT_UNEMP_AFT)) # New non-combined...
|
||||
|
||||
mt_taxable_income = salary - (79.0 * mt_mw4_exemptions)
|
||||
mt_withhold = round(0 + (0.018 * (mt_taxable_income - 0)))
|
||||
self.assertPayrollEqual(mt_taxable_income, 155.0)
|
||||
self.assertPayrollEqual(mt_withhold, 3.0)
|
||||
self.assertPayrollEqual(cats['EE_US_SIT'], -mt_withhold)
|
||||
|
||||
def test_2019_taxes_two(self):
|
||||
# Payroll Period Bi-Weekly example
|
||||
salary = 2950
|
||||
mt_mw4_exemptions = 2
|
||||
|
||||
employee = self._createEmployee()
|
||||
contract = self._createContract(employee,
|
||||
wage=salary,
|
||||
state_id=self.get_us_state('MT'),
|
||||
mt_mw4_sit_exemptions=mt_mw4_exemptions,
|
||||
schedule_pay='bi-weekly')
|
||||
|
||||
self._log('2019 Montana tax single first payslip:')
|
||||
payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31')
|
||||
|
||||
payslip.compute_sheet()
|
||||
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self.assertPayrollEqual(cats['ER_US_SUTA'], round(salary * (self.MT_UNEMP + self.MT_UNEMP_AFT), 2))
|
||||
|
||||
# Note!!
|
||||
# The example calculation uses A = 16 but the actual table describes this as A = 18
|
||||
mt_taxable_income = salary - (73.0 * mt_mw4_exemptions)
|
||||
mt_withhold = round(18 + (0.06 * (mt_taxable_income - 577)))
|
||||
self.assertPayrollEqual(mt_taxable_income, 2804.0)
|
||||
self.assertPayrollEqual(mt_withhold, 152.0)
|
||||
self.assertPayrollEqual(cats['EE_US_SIT'], -mt_withhold)
|
||||
|
||||
def test_2019_taxes_three(self):
|
||||
# Payroll Period Weekly example
|
||||
salary = 135
|
||||
mt_mw4_exemptions = 1
|
||||
|
||||
employee = self._createEmployee()
|
||||
contract = self._createContract(employee,
|
||||
wage=salary,
|
||||
state_id=self.get_us_state('MT'),
|
||||
mt_mw4_sit_exemptions=mt_mw4_exemptions,
|
||||
schedule_pay='weekly')
|
||||
|
||||
self._log('2019 Montana tax single first payslip:')
|
||||
payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31')
|
||||
|
||||
payslip.compute_sheet()
|
||||
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self.assertPayrollEqual(cats['ER_US_SUTA'], round(salary * (self.MT_UNEMP + self.MT_UNEMP_AFT), 2))
|
||||
|
||||
mt_taxable_income = salary - (37.0 * mt_mw4_exemptions)
|
||||
mt_withhold = round(0 + (0.018 * (mt_taxable_income - 0)))
|
||||
self.assertPayrollEqual(mt_taxable_income, 98.0)
|
||||
self.assertPayrollEqual(mt_withhold, 2.0)
|
||||
self.assertPayrollEqual(cats['EE_US_SIT'], -mt_withhold)
|
||||
|
||||
def test_2019_taxes_three_exempt(self):
|
||||
# Payroll Period Weekly example
|
||||
salary = 135
|
||||
mt_mw4_exemptions = 1
|
||||
|
||||
employee = self._createEmployee()
|
||||
contract = self._createContract(employee,
|
||||
wage=salary,
|
||||
state_id=self.get_us_state('MT'),
|
||||
mt_mw4_sit_exemptions=mt_mw4_exemptions,
|
||||
mt_mw4_sit_exempt='reserve',
|
||||
schedule_pay='weekly')
|
||||
|
||||
self._log('2019 Montana tax single first payslip:')
|
||||
payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31')
|
||||
|
||||
payslip.compute_sheet()
|
||||
|
||||
cats = self._getCategories(payslip)
|
||||
self.assertPayrollEqual(cats.get('EE_US_SIT', 0.0), 0.0)
|
||||
|
||||
def test_2019_taxes_three_additional(self):
|
||||
# Payroll Period Weekly example
|
||||
salary = 135
|
||||
mt_mw4_exemptions = 1
|
||||
mt_mw4_additional_withholding = 20.0
|
||||
|
||||
employee = self._createEmployee()
|
||||
contract = self._createContract(employee,
|
||||
wage=salary,
|
||||
state_id=self.get_us_state('MT'),
|
||||
mt_mw4_sit_exemptions=mt_mw4_exemptions,
|
||||
state_income_tax_additional_withholding=mt_mw4_additional_withholding,
|
||||
schedule_pay='weekly')
|
||||
|
||||
self._log('2019 Montana tax single first payslip:')
|
||||
payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31')
|
||||
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
mt_taxable_income = salary - (37.0 * mt_mw4_exemptions)
|
||||
mt_withhold = round(0 + (0.018 * (mt_taxable_income - 0)))
|
||||
self.assertPayrollEqual(mt_taxable_income, 98.0)
|
||||
self.assertPayrollEqual(mt_withhold, 2.0)
|
||||
self.assertPayrollEqual(cats['EE_US_SIT'], -mt_withhold + -mt_mw4_additional_withholding)
|
||||
37
l10n_us_hr_payroll/tests/test_us_mt_montana_payslip_2020.py
Executable file
37
l10n_us_hr_payroll/tests/test_us_mt_montana_payslip_2020.py
Executable file
@@ -0,0 +1,37 @@
|
||||
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
|
||||
|
||||
from datetime import date, timedelta
|
||||
from .common import TestUsPayslip
|
||||
|
||||
|
||||
class TestUsMtPayslip(TestUsPayslip):
|
||||
###
|
||||
# 2020 Taxes and Rates
|
||||
###
|
||||
MT_UNEMP_WAGE_MAX = 34100.0
|
||||
MT_UNEMP = 1.18
|
||||
MT_UNEMP_AFT = 0.13
|
||||
|
||||
# Calculations from https://app.mt.gov/myrevenue/Endpoint/DownloadPdf?yearId=705
|
||||
def _test_sit(self, wage, additional_withholding, exemptions, schedule_pay, date_start, expected_withholding):
|
||||
employee = self._createEmployee()
|
||||
contract = self._createContract(employee,
|
||||
wage=wage,
|
||||
state_id=self.get_us_state('MT'),
|
||||
state_income_tax_additional_withholding=additional_withholding,
|
||||
mt_mw4_sit_exemptions=exemptions,
|
||||
schedule_pay=schedule_pay)
|
||||
payslip = self._createPayslip(employee, date_start, date_start + timedelta(days=7))
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self._log('Computed period tax: ' + str(expected_withholding))
|
||||
self.assertPayrollEqual(cats.get('EE_US_SIT', 0.0), -expected_withholding)
|
||||
|
||||
def test_2020_taxes_one(self):
|
||||
combined_rate = self.MT_UNEMP + self.MT_UNEMP_AFT # Combined for test as they both go to the same category and have the same cap
|
||||
self._test_er_suta('MT', combined_rate, date(2020, 1, 1), wage_base=self.MT_UNEMP_WAGE_MAX)
|
||||
self._test_sit(550.0, 0.0, 5.0, 'semi-monthly', date(2020, 1, 1), 3.0)
|
||||
self._test_sit(2950.0, 10.0, 2.0, 'bi-weekly', date(2020, 1, 1), 162.0)
|
||||
self._test_sit(5000.0, 0.0, 1.0, 'monthly', date(2020, 1, 1), 256.0)
|
||||
self._test_sit(750.0, 0.0, 1.0, 'weekly', date(2020, 1, 1), 34.0)
|
||||
270
l10n_us_hr_payroll/tests/test_us_nc_northcarolina_payslip_2019.py
Executable file
270
l10n_us_hr_payroll/tests/test_us_nc_northcarolina_payslip_2019.py
Executable file
@@ -0,0 +1,270 @@
|
||||
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
|
||||
|
||||
from .common import TestUsPayslip, process_payslip
|
||||
|
||||
|
||||
class TestUsNCPayslip(TestUsPayslip):
|
||||
###
|
||||
# Taxes and Rates
|
||||
###
|
||||
NC_UNEMP_MAX_WAGE = 24300.0
|
||||
NC_UNEMP = -1.0 / 100.0
|
||||
NC_INC_TAX = -0.0535
|
||||
|
||||
|
||||
def test_2019_taxes_weekly(self):
|
||||
salary = 20000.0
|
||||
# allowance_multiplier and Portion of Standard Deduction for weekly
|
||||
allowance_multiplier = 48.08
|
||||
PST = 192.31
|
||||
exemption = 1
|
||||
# Algorithm derived from percentage method in https://files.nc.gov/ncdor/documents/files/nc-30_book_web.pdf
|
||||
wh = -round((salary - (PST + (allowance_multiplier * exemption))) * -self.NC_INC_TAX)
|
||||
|
||||
employee = self._createEmployee()
|
||||
contract = self._createContract(employee,
|
||||
wage=salary,
|
||||
state_id=self.get_us_state('NC'),
|
||||
nc_nc4_sit_filing_status='married',
|
||||
state_income_tax_additional_withholding=0.0,
|
||||
nc_nc4_sit_allowances=1.0,
|
||||
schedule_pay='weekly')
|
||||
|
||||
self._log('2019 North Carolina tax first payslip weekly:')
|
||||
payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31')
|
||||
|
||||
payslip.compute_sheet()
|
||||
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self.assertPayrollEqual(cats['EE_US_SIT'], wh)
|
||||
|
||||
process_payslip(payslip)
|
||||
|
||||
# Make a new payslip, this one will have maximums
|
||||
|
||||
remaining_NC_UNEMP_wages = self.NC_UNEMP_MAX_WAGE - salary if (self.NC_UNEMP_MAX_WAGE - 2*salary < salary) \
|
||||
else salary
|
||||
self._log('2019 North Carolina tax second payslip weekly:')
|
||||
payslip = self._createPayslip(employee, '2019-02-01', '2019-02-28')
|
||||
|
||||
payslip.compute_sheet()
|
||||
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self.assertPayrollEqual(cats['ER_US_SUTA'], remaining_NC_UNEMP_wages * self.NC_UNEMP)
|
||||
|
||||
def test_2019_taxes_with_external_weekly(self):
|
||||
salary = 5000.0
|
||||
schedule_pay = 'weekly'
|
||||
|
||||
employee = self._createEmployee()
|
||||
|
||||
contract = self._createContract(employee,
|
||||
wage=salary,
|
||||
state_id=self.get_us_state('NC'),
|
||||
nc_nc4_sit_filing_status='married',
|
||||
state_income_tax_additional_withholding=0.0,
|
||||
nc_nc4_sit_allowances=1.0,
|
||||
schedule_pay='weekly')
|
||||
|
||||
self._log('2019 NorthCarolina_external tax first payslip weekly:')
|
||||
payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31')
|
||||
|
||||
payslip.compute_sheet()
|
||||
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self.assertPayrollEqual(cats['ER_US_SUTA'], salary * self.NC_UNEMP)
|
||||
|
||||
def test_2019_taxes_biweekly(self):
|
||||
salary = 5000.0
|
||||
schedule_pay = 'bi-weekly'
|
||||
# allowance_multiplier and Portion of Standard Deduction for weekly
|
||||
allowance_multiplier = 96.15
|
||||
PST = 384.62
|
||||
|
||||
allowances = 2
|
||||
# Algorithm derived from percentage method in https://files.nc.gov/ncdor/documents/files/nc-30_book_web.pdf
|
||||
|
||||
wh = -round((salary - (PST + (allowance_multiplier * allowances))) * -self.NC_INC_TAX)
|
||||
|
||||
employee = self._createEmployee()
|
||||
|
||||
contract = self._createContract(employee,
|
||||
wage=salary,
|
||||
state_id=self.get_us_state('NC'),
|
||||
nc_nc4_sit_filing_status='married',
|
||||
state_income_tax_additional_withholding=0.0,
|
||||
nc_nc4_sit_allowances=2.0,
|
||||
schedule_pay='bi-weekly')
|
||||
|
||||
self._log('2019 North Carolina tax first payslip bi-weekly:')
|
||||
payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31')
|
||||
|
||||
payslip.compute_sheet()
|
||||
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self.assertPayrollEqual(cats['ER_US_SUTA'], salary * self.NC_UNEMP)
|
||||
self.assertPayrollEqual(cats['EE_US_SIT'], wh)
|
||||
|
||||
process_payslip(payslip)
|
||||
|
||||
# Make a new payslip, this one will have maximums
|
||||
|
||||
remaining_NC_UNEMP_wages = self.NC_UNEMP_MAX_WAGE - salary if (self.NC_UNEMP_MAX_WAGE - 2*salary < salary) \
|
||||
else salary
|
||||
|
||||
self._log('2019 North Carolina tax second payslip bi-weekly:')
|
||||
payslip = self._createPayslip(employee, '2019-02-01', '2019-02-28')
|
||||
|
||||
payslip.compute_sheet()
|
||||
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self.assertPayrollEqual(cats['ER_US_SUTA'], remaining_NC_UNEMP_wages * self.NC_UNEMP)
|
||||
|
||||
def test_2019_taxes_semimonthly(self):
|
||||
salary = 4000.0
|
||||
# allowance_multiplier and Portion of Standard Deduction for weekly
|
||||
allowance_multiplier = 104.17
|
||||
PST = 625.00
|
||||
|
||||
allowances = 1
|
||||
# Algorithm derived from percentage method in https://files.nc.gov/ncdor/documents/files/nc-30_book_web.pdf
|
||||
|
||||
wh = -round((salary - (PST + (allowance_multiplier * allowances))) * -self.NC_INC_TAX)
|
||||
|
||||
employee = self._createEmployee()
|
||||
|
||||
contract = self._createContract(employee,
|
||||
wage=salary,
|
||||
state_id=self.get_us_state('NC'),
|
||||
nc_nc4_sit_filing_status='head_household',
|
||||
state_income_tax_additional_withholding=0.0,
|
||||
nc_nc4_sit_allowances=1.0,
|
||||
schedule_pay='semi-monthly')
|
||||
|
||||
self._log('2019 North Carolina tax first payslip:')
|
||||
payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31')
|
||||
|
||||
payslip.compute_sheet()
|
||||
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self.assertPayrollEqual(cats['ER_US_SUTA'], salary * self.NC_UNEMP)
|
||||
self.assertPayrollEqual(cats['EE_US_SIT'], wh)
|
||||
|
||||
process_payslip(payslip)
|
||||
|
||||
# Make a new payslip, this one will have maximums
|
||||
|
||||
remaining_NC_UNEMP_wages = self.NC_UNEMP_MAX_WAGE - salary if (self.NC_UNEMP_MAX_WAGE - 2 * salary < salary) \
|
||||
else salary
|
||||
|
||||
self._log('2019 North Carolina tax second payslip:')
|
||||
payslip = self._createPayslip(employee, '2019-02-01', '2019-02-28')
|
||||
|
||||
payslip.compute_sheet()
|
||||
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self.assertPayrollEqual(cats['ER_US_SUTA'], remaining_NC_UNEMP_wages * self.NC_UNEMP)
|
||||
|
||||
def test_2019_taxes_monthly(self):
|
||||
salary = 4000.0
|
||||
schedule_pay = 'monthly'
|
||||
# allowance_multiplier and Portion of Standard Deduction for weekly
|
||||
allowance_multiplier = 208.33
|
||||
PST = 833.33
|
||||
|
||||
allowances = 1
|
||||
# Algorithm derived from percentage method in https://files.nc.gov/ncdor/documents/files/nc-30_book_web.pdf
|
||||
|
||||
wh = -round((salary - (PST + (allowance_multiplier * allowances))) * -self.NC_INC_TAX)
|
||||
|
||||
employee = self._createEmployee()
|
||||
|
||||
contract = self._createContract(employee,
|
||||
wage=salary,
|
||||
state_id=self.get_us_state('NC'),
|
||||
nc_nc4_sit_filing_status='single',
|
||||
state_income_tax_additional_withholding=0.0,
|
||||
nc_nc4_sit_allowances=1.0,
|
||||
schedule_pay='monthly')
|
||||
|
||||
self._log('2019 North Carolina tax first payslip:')
|
||||
payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31')
|
||||
|
||||
payslip.compute_sheet()
|
||||
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self.assertPayrollEqual(cats['ER_US_SUTA'], salary * self.NC_UNEMP)
|
||||
self.assertPayrollEqual(cats['EE_US_SIT'], wh)
|
||||
|
||||
process_payslip(payslip)
|
||||
|
||||
# Make a new payslip, this one will have maximums
|
||||
|
||||
remaining_NC_UNEMP_wages = self.NC_UNEMP_MAX_WAGE - salary if (
|
||||
self.NC_UNEMP_MAX_WAGE - 2 * salary < salary) \
|
||||
else salary
|
||||
|
||||
self._log('2019 North Carolina tax second payslip:')
|
||||
payslip = self._createPayslip(employee, '2019-02-01', '2019-02-28')
|
||||
|
||||
payslip.compute_sheet()
|
||||
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self.assertPayrollEqual(cats['ER_US_SUTA'], remaining_NC_UNEMP_wages * self.NC_UNEMP)
|
||||
|
||||
def test_additional_withholding(self):
|
||||
salary = 4000.0
|
||||
# allowance_multiplier and Portion of Standard Deduction for weekly
|
||||
allowance_multiplier = 48.08
|
||||
PST = 192.31
|
||||
additional_wh = 40.0
|
||||
|
||||
#4000 - (168.27 + (48.08 * 1)
|
||||
|
||||
allowances = 1
|
||||
# Algorithm derived from percentage method in https://files.nc.gov/ncdor/documents/files/nc-30_book_web.pdf
|
||||
|
||||
wh = -round(((salary - (PST + (allowance_multiplier * allowances))) * -self.NC_INC_TAX) + additional_wh)
|
||||
|
||||
employee = self._createEmployee()
|
||||
|
||||
contract = self._createContract(employee,
|
||||
wage=salary,
|
||||
state_id=self.get_us_state('NC'),
|
||||
nc_nc4_sit_filing_status='married',
|
||||
state_income_tax_additional_withholding=40.0,
|
||||
nc_nc4_sit_allowances=1.0,
|
||||
schedule_pay='weekly')
|
||||
|
||||
self._log('2019 North Carolina tax first payslip weekly:')
|
||||
payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31')
|
||||
|
||||
payslip.compute_sheet()
|
||||
|
||||
cats = self._getCategories(payslip)
|
||||
self.assertPayrollEqual(cats['EE_US_SIT'], wh)
|
||||
|
||||
process_payslip(payslip)
|
||||
|
||||
# Make a new payslip, this one will have maximums
|
||||
|
||||
remaining_NC_UNEMP_wages = self.NC_UNEMP_MAX_WAGE - salary if (self.NC_UNEMP_MAX_WAGE - 2 * salary < salary) \
|
||||
else salary
|
||||
|
||||
self._log('2019 North Carolina tax second payslip weekly:')
|
||||
payslip = self._createPayslip(employee, '2019-02-01', '2019-02-28')
|
||||
|
||||
payslip.compute_sheet()
|
||||
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self.assertPayrollEqual(cats['ER_US_SUTA'], remaining_NC_UNEMP_wages * self.NC_UNEMP)
|
||||
37
l10n_us_hr_payroll/tests/test_us_nc_northcarolina_payslip_2020.py
Executable file
37
l10n_us_hr_payroll/tests/test_us_nc_northcarolina_payslip_2020.py
Executable file
@@ -0,0 +1,37 @@
|
||||
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
|
||||
|
||||
from datetime import date, timedelta
|
||||
from .common import TestUsPayslip
|
||||
|
||||
|
||||
class TestUsNCPayslip(TestUsPayslip):
|
||||
###
|
||||
# 2020 Taxes and Rates
|
||||
###
|
||||
NC_UNEMP_MAX_WAGE = 25200.0
|
||||
NC_UNEMP = 1.0
|
||||
NC_INC_TAX = 0.0535
|
||||
# Example based on https://files.nc.gov/ncdor/documents/files/NC-30_book_Web_1-16-19_v4_Final.pdf
|
||||
def _test_sit(self, wage, filing_status, allowances, additional_withholding, schedule_pay, date_start, expected_withholding):
|
||||
|
||||
employee = self._createEmployee()
|
||||
contract = self._createContract(employee,
|
||||
wage=wage,
|
||||
state_id=self.get_us_state('NC'),
|
||||
nc_nc4_sit_filing_status=filing_status,
|
||||
nc_nc4_sit_allowances=allowances,
|
||||
state_income_tax_additional_withholding=additional_withholding,
|
||||
schedule_pay=schedule_pay)
|
||||
payslip = self._createPayslip(employee, date_start, date_start + timedelta(days=7))
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self._log('Computed period tax: ' + str(expected_withholding))
|
||||
self.assertPayrollEqual(cats.get('EE_US_SIT', 0.0), -expected_withholding if filing_status else 0.0)
|
||||
|
||||
def test_2020_taxes_example(self):
|
||||
self._test_er_suta('NC', self.NC_UNEMP, date(2020, 1, 1), wage_base=self.NC_UNEMP_MAX_WAGE)
|
||||
self._test_sit(20000.0, 'single', 1, 100.0, 'weekly', date(2020, 1, 1), 1156.0)
|
||||
self._test_sit(5000.0, 'married', 1, 0.0, 'weekly', date(2020, 1, 1), 254.0)
|
||||
self._test_sit(4000.0, 'head_household', 1, 5.0, 'semi-monthly', date(2020, 1, 1), 177.0)
|
||||
self._test_sit(7000.0, '', 1, 5.0, 'monthly', date(2020, 1, 1), 0.0)
|
||||
@@ -0,0 +1,37 @@
|
||||
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
|
||||
|
||||
from datetime import date, timedelta
|
||||
from .common import TestUsPayslip
|
||||
|
||||
|
||||
class TestUsNDPayslip(TestUsPayslip):
|
||||
###
|
||||
# 2020 Taxes and Rates
|
||||
###
|
||||
ND_UNEMP_MAX_WAGE = 37900.0
|
||||
ND_UNEMP = 1.02
|
||||
# Calculation based on this file page.47 https://www.nd.gov/tax/data/upfiles/media/rates-and-instructions.pdf?20200110115917
|
||||
|
||||
def _test_sit(self, wage, filing_status, additional_withholding, allowances, schedule_pay, date_start, expected_withholding):
|
||||
employee = self._createEmployee()
|
||||
contract = self._createContract(employee,
|
||||
wage=wage,
|
||||
state_id=self.get_us_state('ND'),
|
||||
nd_w4_sit_filing_status=filing_status,
|
||||
state_income_tax_additional_withholding=additional_withholding,
|
||||
nd_w4_sit_allowances=allowances,
|
||||
schedule_pay=schedule_pay)
|
||||
payslip = self._createPayslip(employee, date_start, date_start + timedelta(days=7))
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self._log('Computed period tax: ' + str(expected_withholding))
|
||||
self.assertPayrollAlmostEqual(cats.get('EE_US_SIT', 0.0), -expected_withholding)
|
||||
|
||||
def test_2020_taxes_example(self):
|
||||
self._test_er_suta('ND', self.ND_UNEMP, date(2020, 1, 1), wage_base=self.ND_UNEMP_MAX_WAGE)
|
||||
self._test_sit(700.0, 'single', 0.0, 0.0, 'weekly', date(2020, 1, 1), 6.0)
|
||||
self._test_sit(5000.0, 'married', 0.0, 2.0, 'bi-weekly', date(2020, 1, 1), 76.0)
|
||||
self._test_sit(25000.0, 'head_household', 0.0, 0.0, 'monthly', date(2020, 1, 1), 534.0)
|
||||
self._test_sit(25000.0, 'head_household', 10.0, 2.0, 'monthly', date(2020, 1, 1), 525.0)
|
||||
self._test_sit(3000.0, '', 10.0, 2.0, 'monthly', date(2020, 1, 1), 0.0)
|
||||
38
l10n_us_hr_payroll/tests/test_us_ne_nebraska_payslip_2020.py
Normal file
38
l10n_us_hr_payroll/tests/test_us_ne_nebraska_payslip_2020.py
Normal file
@@ -0,0 +1,38 @@
|
||||
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
|
||||
|
||||
from datetime import date, timedelta
|
||||
from .common import TestUsPayslip
|
||||
|
||||
|
||||
class TestUsNEPayslip(TestUsPayslip):
|
||||
###
|
||||
# 2020 Taxes and Rates
|
||||
###
|
||||
NE_UNEMP_MAX_WAGE = 9000.0
|
||||
NE_UNEMP = 1.25
|
||||
|
||||
def _test_sit(self, wage, filing_status, exempt, additional_withholding, allowances, schedule_pay, date_start, expected_withholding):
|
||||
employee = self._createEmployee()
|
||||
contract = self._createContract(employee,
|
||||
wage=wage,
|
||||
state_id=self.get_us_state('NE'),
|
||||
ne_w4n_sit_filing_status=filing_status,
|
||||
state_income_tax_exempt=exempt,
|
||||
state_income_tax_additional_withholding=additional_withholding,
|
||||
ne_w4n_sit_allowances=allowances,
|
||||
schedule_pay=schedule_pay)
|
||||
payslip = self._createPayslip(employee, date_start, date_start + timedelta(days=7))
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self._log('Computed period tax: ' + str(expected_withholding))
|
||||
self.assertPayrollAlmostEqual(cats.get('EE_US_SIT', 0.0), -expected_withholding)
|
||||
|
||||
def test_2020_taxes_example(self):
|
||||
self._test_er_suta('NE', self.NE_UNEMP, date(2020, 1, 1), wage_base=self.NE_UNEMP_MAX_WAGE)
|
||||
self._test_sit(750.0, 'single', False, 0.0, 2, 'weekly', date(2020, 1, 1), 27.53)
|
||||
self._test_sit(9500.0, 'single', False, 0.0, 1, 'bi-weekly', date(2020, 1, 1), 612.63)
|
||||
self._test_sit(10500.0, 'married', False, 0.0, 1, 'bi-weekly', date(2020, 1, 1), 659.85)
|
||||
self._test_sit(9500.0, 'single', True, 0.0, 1, 'bi-weekly', date(2020, 1, 1), 0.0)
|
||||
self._test_sit(10500.0, 'single', False, 10.0, 2, 'monthly', date(2020, 1, 1), 625.2)
|
||||
self._test_sit(4000.0, 'single', False, 0.0, 1, 'monthly', date(2020, 1, 1), 179.44)
|
||||
@@ -0,0 +1,13 @@
|
||||
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
|
||||
|
||||
from datetime import date
|
||||
from .common import TestUsPayslip
|
||||
|
||||
|
||||
class TestUsNHPayslip(TestUsPayslip):
|
||||
# TAXES AND RATES
|
||||
NH_UNEMP_MAX_WAGE = 14000.00
|
||||
NH_UNEMP = 1.2
|
||||
|
||||
def test_2020_taxes(self):
|
||||
self._test_er_suta('NH', self.NH_UNEMP, date(2020, 1, 1), wage_base=self.NH_UNEMP_MAX_WAGE)
|
||||
128
l10n_us_hr_payroll/tests/test_us_nj_newjersey_payslip_2019.py
Executable file
128
l10n_us_hr_payroll/tests/test_us_nj_newjersey_payslip_2019.py
Executable file
@@ -0,0 +1,128 @@
|
||||
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
|
||||
|
||||
from .common import TestUsPayslip, process_payslip
|
||||
|
||||
|
||||
class TestUsNJPayslip(TestUsPayslip):
|
||||
###
|
||||
# 2019 Taxes and Rates
|
||||
###
|
||||
NJ_UNEMP_MAX_WAGE = 34400.0 # Note that this is used for SDI and FLI as well
|
||||
|
||||
ER_NJ_UNEMP = -2.6825 / 100.0
|
||||
EE_NJ_UNEMP = -0.3825 / 100.0
|
||||
|
||||
ER_NJ_SDI = -0.5 / 100.0
|
||||
EE_NJ_SDI = -0.17 / 100.0
|
||||
|
||||
ER_NJ_WF = -0.1175 / 100.0
|
||||
EE_NJ_WF = -0.0425 / 100.0
|
||||
|
||||
ER_NJ_FLI = 0.0
|
||||
EE_NJ_FLI = -0.08 / 100.0
|
||||
|
||||
# Examples found on page 24 of http://www.state.nj.us/treasury/taxation/pdf/current/njwt.pdf
|
||||
def test_2019_taxes_example1(self):
|
||||
salary = 300
|
||||
|
||||
# Tax Percentage Method for Single, taxable under $385
|
||||
wh = -4.21
|
||||
|
||||
employee = self._createEmployee()
|
||||
contract = self._createContract(employee,
|
||||
wage=salary,
|
||||
state_id=self.get_us_state('NJ'),
|
||||
nj_njw4_sit_filing_status='single',
|
||||
nj_njw4_sit_allowances=1,
|
||||
state_income_tax_additional_withholding=0.0,
|
||||
nj_njw4_sit_rate_table='A',
|
||||
schedule_pay='weekly')
|
||||
|
||||
self._log('2019 New Jersey tax first payslip:')
|
||||
payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31')
|
||||
|
||||
payslip.compute_sheet()
|
||||
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self.assertPayrollEqual(cats['EE_US_SUTA'], salary * (self.EE_NJ_UNEMP + self.EE_NJ_SDI + self.EE_NJ_WF + self.EE_NJ_FLI))
|
||||
self.assertPayrollEqual(cats['ER_US_SUTA'], salary * (self.ER_NJ_UNEMP + self.ER_NJ_SDI + self.ER_NJ_WF + self.ER_NJ_FLI))
|
||||
self.assertTrue(all((cats['EE_US_SUTA'], cats['ER_US_SUTA'])))
|
||||
# self.assertPayrollEqual(cats['EE_US_NJ_SDI_SIT'], cats['EE_US_NJ_SDI_SIT'] * self.EE_NJ_SDI)
|
||||
# self.assertPayrollEqual(cats['ER_US_NJ_SDI_SUTA'], cats['ER_US_NJ_SDI_SUTA'] * self.ER_NJ_SDI)
|
||||
# self.assertPayrollEqual(cats['EE_US_NJ_FLI_SIT'], cats['EE_US_NJ_FLI_SIT'] * self.EE_NJ_FLI)
|
||||
# self.assertPayrollEqual(cats['EE_US_NJ_WF_SIT'], cats['EE_US_NJ_WF_SIT'] * self.EE_NJ_WF)
|
||||
self.assertPayrollEqual(cats['EE_US_SIT'], wh)
|
||||
|
||||
process_payslip(payslip)
|
||||
|
||||
# # Make a new payslip, this one will have maximums
|
||||
#
|
||||
remaining_nj_unemp_wages = self.NJ_UNEMP_MAX_WAGE - salary if (self.NJ_UNEMP_MAX_WAGE - 2 * salary < salary) \
|
||||
else salary
|
||||
|
||||
self._log('2019 New Jersey tax second payslip:')
|
||||
payslip = self._createPayslip(employee, '2019-02-01', '2019-02-28')
|
||||
|
||||
payslip.compute_sheet()
|
||||
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
# self.assertPayrollEqual(cats['WAGE_US_NJ_UNEMP'], remaining_nj_unemp_wages)
|
||||
self.assertPayrollEqual(cats['ER_US_SUTA'], remaining_nj_unemp_wages * (self.ER_NJ_UNEMP + self.ER_NJ_SDI + self.ER_NJ_WF + self.ER_NJ_FLI))
|
||||
self.assertPayrollEqual(cats['EE_US_SUTA'], remaining_nj_unemp_wages * (self.EE_NJ_UNEMP + self.EE_NJ_SDI + self.EE_NJ_WF + self.EE_NJ_FLI))
|
||||
|
||||
def test_2019_taxes_example2(self):
|
||||
salary = 1400.00
|
||||
|
||||
# Tax Percentage Method for Single, taxable pay over $962, under $1346
|
||||
wh = -27.58
|
||||
|
||||
employee = self._createEmployee()
|
||||
contract = self._createContract(employee,
|
||||
wage=salary,
|
||||
state_id=self.get_us_state('NJ'),
|
||||
nj_njw4_sit_filing_status='married_separate',
|
||||
nj_njw4_sit_allowances=3,
|
||||
state_income_tax_additional_withholding=0.0,
|
||||
#nj_njw4_sit_rate_table='B',
|
||||
schedule_pay='weekly')
|
||||
|
||||
self.assertEqual(contract.schedule_pay, 'weekly')
|
||||
|
||||
self._log('2019 New Jersey tax first payslip:')
|
||||
payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31')
|
||||
|
||||
payslip.compute_sheet()
|
||||
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self.assertPayrollEqual(cats['EE_US_SIT'], wh)
|
||||
|
||||
|
||||
def test_2019_taxes_to_the_limits(self):
|
||||
salary = 30000.00
|
||||
|
||||
# Tax Percentage Method for Single, taxable pay over $18750, under 125000
|
||||
wh = -1467.51
|
||||
|
||||
employee = self._createEmployee()
|
||||
contract = self._createContract(employee,
|
||||
wage=salary,
|
||||
state_id=self.get_us_state('NJ'),
|
||||
nj_njw4_sit_filing_status='married_joint',
|
||||
nj_njw4_sit_allowances=3,
|
||||
state_income_tax_additional_withholding=0.0,
|
||||
# nj_njw4_sit_rate_table='B',
|
||||
schedule_pay='quarterly')
|
||||
|
||||
self.assertEqual(contract.schedule_pay, 'quarterly')
|
||||
|
||||
self._log('2019 New Jersey tax first payslip:')
|
||||
payslip = self._createPayslip(employee, '2019-01-01', '2019-03-31')
|
||||
|
||||
payslip.compute_sheet()
|
||||
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self.assertPayrollEqual(cats['EE_US_SIT'], wh)
|
||||
51
l10n_us_hr_payroll/tests/test_us_nj_newjersey_payslip_2020.py
Executable file
51
l10n_us_hr_payroll/tests/test_us_nj_newjersey_payslip_2020.py
Executable file
@@ -0,0 +1,51 @@
|
||||
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
|
||||
|
||||
from datetime import date, timedelta
|
||||
from .common import TestUsPayslip
|
||||
|
||||
|
||||
class TestUsNJPayslip(TestUsPayslip):
|
||||
###
|
||||
# 2020 Taxes and Rates
|
||||
###
|
||||
NJ_UNEMP_MAX_WAGE = 35300.0 # Note that this is used for SDI and FLI as well
|
||||
|
||||
ER_NJ_UNEMP = 2.6825
|
||||
EE_NJ_UNEMP = 0.3825
|
||||
|
||||
ER_NJ_SDI = 0.5
|
||||
EE_NJ_SDI = 0.26
|
||||
|
||||
ER_NJ_WF = 0.1175
|
||||
EE_NJ_WF = 0.0425
|
||||
|
||||
ER_NJ_FLI = 0.0
|
||||
EE_NJ_FLI = 0.16
|
||||
|
||||
def _test_sit(self, wage, filing_status, allowances, schedule_pay, date_start, expected_withholding, rate_table=False):
|
||||
employee = self._createEmployee()
|
||||
contract = self._createContract(employee,
|
||||
wage=wage,
|
||||
state_id=self.get_us_state('NJ'),
|
||||
nj_njw4_sit_filing_status=filing_status,
|
||||
nj_njw4_sit_allowances=allowances,
|
||||
state_income_tax_additional_withholding=0.0,
|
||||
nj_njw4_sit_rate_table=rate_table,
|
||||
schedule_pay=schedule_pay)
|
||||
payslip = self._createPayslip(employee, date_start, date_start + timedelta(days=7))
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
self.assertPayrollAlmostEqual(cats.get('EE_US_SIT', 0.0), -expected_withholding if filing_status else 0.0)
|
||||
|
||||
def test_2020_taxes_example1(self):
|
||||
combined_er_rate = self.ER_NJ_UNEMP + self.ER_NJ_FLI + self.ER_NJ_SDI + self.ER_NJ_WF
|
||||
self._test_er_suta('NJ', combined_er_rate, date(2020, 1, 1), wage_base=self.NJ_UNEMP_MAX_WAGE)
|
||||
combined_ee_rate = self.EE_NJ_UNEMP + self.EE_NJ_FLI + self.EE_NJ_SDI + self.EE_NJ_WF
|
||||
self._test_ee_suta('NJ', combined_ee_rate, date(2020, 1, 1), wage_base=self.NJ_UNEMP_MAX_WAGE, relaxed=True)
|
||||
# these expected values come from https://www.state.nj.us/treasury/taxation/pdf/current/njwt.pdf
|
||||
self._test_sit(300.0, 'single', 1, 'weekly', date(2020, 1, 1), 4.21)
|
||||
self._test_sit(375.0, 'married_separate', 3, 'weekly', date(2020, 1, 1), 4.76)
|
||||
self._test_sit(1400.0, 'head_household', 3, 'weekly', date(2020, 1, 1), 27.60)
|
||||
self._test_sit(1400.0, '', 3, 'weekly', date(2020, 1, 1), 0.00)
|
||||
self._test_sit(2500.0, 'single', 3, 'bi-weekly', date(2020, 1, 1), 82.66)
|
||||
self._test_sit(15000.0, 'married_joint', 2, 'monthly', date(2020, 1, 1), 844.85)
|
||||
36
l10n_us_hr_payroll/tests/test_us_nm_new_mexico_payslip_2020.py
Executable file
36
l10n_us_hr_payroll/tests/test_us_nm_new_mexico_payslip_2020.py
Executable file
@@ -0,0 +1,36 @@
|
||||
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
|
||||
|
||||
from datetime import date, timedelta
|
||||
from .common import TestUsPayslip
|
||||
|
||||
|
||||
class TestUsNMPayslip(TestUsPayslip):
|
||||
###
|
||||
# 2020 Taxes and Rates
|
||||
###
|
||||
NM_UNEMP_MAX_WAGE = 25800.0
|
||||
NM_UNEMP = 1.0
|
||||
# Calculation based on section 17. https://s3.amazonaws.com/realFile34821a95-73ca-43e7-b06d-fad20f5183fd/a9bf1098-533b-4a3d-806a-4bf6336af6e4?response-content-disposition=filename%3D%22FYI-104+-+New+Mexico+Withholding+Tax+-+Effective+January+1%2C+2020.pdf%22&response-content-type=application%2Fpdf&AWSAccessKeyId=AKIAJBI25DHBYGD7I7TA&Signature=feu%2F1oJvU6BciRfKcoR0iNxoVZE%3D&Expires=1585159702
|
||||
|
||||
def _test_sit(self, wage, filing_status, additional_withholding, schedule_pay, date_start, expected_withholding):
|
||||
employee = self._createEmployee()
|
||||
contract = self._createContract(employee,
|
||||
wage=wage,
|
||||
state_id=self.get_us_state('NM'),
|
||||
fed_941_fit_w4_filing_status=filing_status,
|
||||
state_income_tax_additional_withholding=additional_withholding,
|
||||
schedule_pay=schedule_pay)
|
||||
payslip = self._createPayslip(employee, date_start, date_start + timedelta(days=7))
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self._log('Computed period tax: ' + str(expected_withholding))
|
||||
self.assertPayrollEqual(cats.get('EE_US_SIT', 0.0), -expected_withholding)
|
||||
|
||||
def test_2020_taxes_example(self):
|
||||
self._test_er_suta('NM', self.NM_UNEMP, date(2020, 1, 1), wage_base=self.NM_UNEMP_MAX_WAGE)
|
||||
self._test_sit(1000.0, 'married', 0.0, 'weekly', date(2020, 1, 1), 29.47)
|
||||
self._test_sit(1000.0, 'married', 10.0, 'weekly', date(2020, 1, 1), 39.47)
|
||||
self._test_sit(25000.0, 'single', 0.0, 'bi-weekly', date(2020, 1, 1), 1202.60)
|
||||
self._test_sit(25000.0, 'married_as_single', 0.0, 'monthly', date(2020, 1, 1), 1152.95)
|
||||
self._test_sit(4400.0, '', 0.0, 'monthly', date(2020, 1, 1), 0.00)
|
||||
16
l10n_us_hr_payroll/tests/test_us_nv_nevada_payslip_2020.py
Executable file
16
l10n_us_hr_payroll/tests/test_us_nv_nevada_payslip_2020.py
Executable file
@@ -0,0 +1,16 @@
|
||||
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
|
||||
|
||||
from datetime import date
|
||||
from .common import TestUsPayslip
|
||||
|
||||
|
||||
class TestUsNVPayslip(TestUsPayslip):
|
||||
###
|
||||
# 2020 Taxes and Rates
|
||||
###
|
||||
NV_UNEMP_MAX_WAGE = 32500.0
|
||||
NV_UNEMP = 2.95
|
||||
|
||||
def test_2020_taxes(self):
|
||||
# Only has state unemployment
|
||||
self._test_er_suta('NV', self.NV_UNEMP, date(2020, 1, 1), wage_base=self.NV_UNEMP_MAX_WAGE)
|
||||
133
l10n_us_hr_payroll/tests/test_us_ny_new_york_payslip_2019.py
Normal file
133
l10n_us_hr_payroll/tests/test_us_ny_new_york_payslip_2019.py
Normal file
@@ -0,0 +1,133 @@
|
||||
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
|
||||
|
||||
from .common import TestUsPayslip, process_payslip
|
||||
|
||||
|
||||
class TestUsNYPayslip(TestUsPayslip):
|
||||
###
|
||||
# Taxes and Rates
|
||||
###
|
||||
NY_UNEMP_MAX_WAGE = 11400.0
|
||||
NY_UNEMP = 2.5
|
||||
NY_RSF = 0.075
|
||||
NY_MCTMT = 0.0
|
||||
|
||||
def test_single_example1(self):
|
||||
salary = 400
|
||||
schedule_pay = 'weekly'
|
||||
allowances = 3
|
||||
additional_withholding = 0
|
||||
filing_status = 'single'
|
||||
additional = 0.0
|
||||
wh = -8.20
|
||||
|
||||
employee = self._createEmployee()
|
||||
|
||||
contract = self._createContract(employee,
|
||||
wage=salary,
|
||||
state_id=self.get_us_state('NY'),
|
||||
ny_it2104_sit_filing_status=filing_status,
|
||||
state_income_tax_additional_withholding=additional,
|
||||
ny_it2104_sit_allowances=allowances,
|
||||
schedule_pay=schedule_pay)
|
||||
|
||||
self.assertEqual(contract.schedule_pay, 'weekly')
|
||||
self._log('2018 New York tax first payslip:')
|
||||
payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31')
|
||||
|
||||
payslip.compute_sheet()
|
||||
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self.assertPayrollEqual(cats['NY_UNEMP'], cats['NY_UNEMP_WAGES'] * self.NY_UNEMP)
|
||||
self.assertPayrollEqual(cats['NY_RSF'], cats['NY_UNEMP_WAGES'] * self.NY_RSF)
|
||||
self.assertPayrollEqual(cats['NY_MCTMT'], cats['NY_UNEMP_WAGES'] * self.NY_MCTMT)
|
||||
self.assertPayrollEqual(cats['EE_US_SIT'], wh)
|
||||
|
||||
process_payslip(payslip)
|
||||
|
||||
def test_married_example2(self):
|
||||
salary = 5000
|
||||
schedule_pay = 'semi-monthly'
|
||||
allowances = 3
|
||||
additional = 0
|
||||
filing_status = 'married'
|
||||
wh = -284.19
|
||||
|
||||
employee = self._createEmployee()
|
||||
contract = self._createContract(employee,
|
||||
wage=salary,
|
||||
state_id=self.get_us_state('NY'),
|
||||
ny_it2104_sit_filing_status=filing_status,
|
||||
state_income_tax_additional_withholding=additional,
|
||||
ny_it2104_sit_allowances=allowances,
|
||||
schedule_pay=schedule_pay)
|
||||
|
||||
self._log('2019 New York tax first payslip:')
|
||||
payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31')
|
||||
|
||||
payslip.compute_sheet()
|
||||
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self.assertPayrollEqual(cats['NY_UNEMP'], cats['NY_UNEMP_WAGES'] * self.NY_UNEMP)
|
||||
self.assertPayrollEqual(cats['NY_RSF'], cats['NY_UNEMP_WAGES'] * self.NY_RSF)
|
||||
self.assertPayrollEqual(cats['NY_MCTMT'], cats['NY_UNEMP_WAGES'] * self.NY_MCTMT)
|
||||
self.assertPayrollEqual(cats['EE_US_SIT'], wh)
|
||||
|
||||
process_payslip(payslip)
|
||||
|
||||
def test_single_example3(self):
|
||||
salary = 50000
|
||||
schedule_pay = 'monthly'
|
||||
allowances = 3
|
||||
additional = 0
|
||||
filing_status = 'single'
|
||||
wh = -3575.63
|
||||
|
||||
employee = self._createEmployee()
|
||||
|
||||
contract = self._createContract(employee,
|
||||
wage=salary,
|
||||
state_id=self.get_us_state('NY'),
|
||||
ny_it2104_sit_filing_status=filing_status,
|
||||
state_income_tax_additional_withholding=additional,
|
||||
ny_it2104_sit_allowances=allowances,
|
||||
schedule_pay=schedule_pay)
|
||||
|
||||
self._log('2019 New York tax first payslip:')
|
||||
payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31')
|
||||
|
||||
payslip.compute_sheet()
|
||||
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self.assertPayrollEqual(cats['EE_US_SIT'], wh)
|
||||
|
||||
def test_exempt_example3(self):
|
||||
salary = 50000
|
||||
schedule_pay = 'monthly'
|
||||
allowances = 3
|
||||
additional = 0
|
||||
filing_status = ''
|
||||
wh = 0.0
|
||||
|
||||
employee = self._createEmployee()
|
||||
|
||||
contract = self._createContract(employee,
|
||||
wage=salary,
|
||||
state_id=self.get_us_state('NY'),
|
||||
ny_it2104_sit_filing_status=filing_status,
|
||||
state_income_tax_additional_withholding=additional,
|
||||
ny_it2104_sit_allowances=allowances,
|
||||
schedule_pay=schedule_pay)
|
||||
|
||||
self._log('2019 New York tax first payslip:')
|
||||
payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31')
|
||||
|
||||
payslip.compute_sheet()
|
||||
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self.assertPayrollEqual(cats['EE_US_SIT'], wh)
|
||||
|
||||
39
l10n_us_hr_payroll/tests/test_us_ny_new_york_payslip_2020.py
Normal file
39
l10n_us_hr_payroll/tests/test_us_ny_new_york_payslip_2020.py
Normal file
@@ -0,0 +1,39 @@
|
||||
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
|
||||
|
||||
from datetime import date, timedelta
|
||||
from .common import TestUsPayslip
|
||||
|
||||
|
||||
class TestUsNYPayslip(TestUsPayslip):
|
||||
###
|
||||
# 2020 Taxes and Rates
|
||||
###
|
||||
NY_UNEMP_MAX_WAGE = 11600.0
|
||||
NY_UNEMP = 2.5
|
||||
NY_RSF = 0.075
|
||||
NY_MCTMT = 0.0
|
||||
|
||||
def _test_sit(self, wage, filing_status, additional_withholding, allowances, schedule_pay, date_start, expected_withholding):
|
||||
employee = self._createEmployee()
|
||||
contract = self._createContract(employee,
|
||||
wage=wage,
|
||||
state_id=self.get_us_state('NY'),
|
||||
ny_it2104_sit_filing_status=filing_status,
|
||||
state_income_tax_additional_withholding=additional_withholding,
|
||||
ny_it2104_sit_allowances=allowances,
|
||||
schedule_pay=schedule_pay)
|
||||
payslip = self._createPayslip(employee, date_start, date_start + timedelta(days=7))
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self._log('Computed period tax: ' + str(expected_withholding))
|
||||
self.assertPayrollAlmostEqual(cats.get('EE_US_SIT', 0.0), -expected_withholding)
|
||||
|
||||
def test_2020_taxes_example(self):
|
||||
combined_er_rate = self.NY_UNEMP + self.NY_RSF + self.NY_MCTMT
|
||||
self._test_er_suta('NY', combined_er_rate, date(2020, 1, 1), wage_base=self.NY_UNEMP_MAX_WAGE, relaxed=True)
|
||||
self._test_sit(400.0, 'single', 0.0, 3, 'weekly', date(2020, 1, 1), 8.20)
|
||||
self._test_sit(10000.0, 'single', 0.0, 3, 'monthly', date(2020, 1, 1), 554.09)
|
||||
self._test_sit(8000.0, 'married', 0.0, 5, 'monthly', date(2020, 1, 1), 400.32)
|
||||
self._test_sit(4500.0, 'married', 10.0, 3, 'semi-monthly', date(2020, 1, 1), 247.69)
|
||||
self._test_sit(50000.0, '', 0.0, 0, 'monthly', date(2020, 1, 1), 0.00)
|
||||
96
l10n_us_hr_payroll/tests/test_us_oh_ohio_payslip_2019.py
Executable file
96
l10n_us_hr_payroll/tests/test_us_oh_ohio_payslip_2019.py
Executable file
@@ -0,0 +1,96 @@
|
||||
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
|
||||
|
||||
from .common import TestUsPayslip, process_payslip
|
||||
from odoo.addons.l10n_us_hr_payroll.models.hr_contract import USHRContract
|
||||
|
||||
|
||||
class TestUsOhPayslip(TestUsPayslip):
|
||||
###
|
||||
# Taxes and Rates
|
||||
###
|
||||
OH_UNEMP_MAX_WAGE = 9500.0
|
||||
OH_UNEMP = -2.7 / 100.0
|
||||
|
||||
def test_2019_taxes(self):
|
||||
salary = 5000.0
|
||||
|
||||
# For formula here
|
||||
# http://www.tax.ohio.gov/Portals/0/employer_withholding/August2015Rates/WTH_OptionalComputerFormula_073015.pdf
|
||||
tw = salary * 12 # = 60000
|
||||
wd = ((tw - 40000) * 0.035 + 900) / 12 * 1.075
|
||||
|
||||
employee = self._createEmployee()
|
||||
|
||||
contract = self._createContract(employee,
|
||||
wage=salary,
|
||||
state_id=self.get_us_state('OH'),
|
||||
)
|
||||
|
||||
self._log('2019 Ohio tax first payslip:')
|
||||
payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31')
|
||||
|
||||
payslip.compute_sheet()
|
||||
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self.assertPayrollEqual(cats['ER_US_SUTA'], salary * self.OH_UNEMP)
|
||||
self.assertPayrollAlmostEqual(cats['EE_US_SIT'], -wd) # Off by 0.6 cents so it rounds off by a penny
|
||||
#self.assertPayrollEqual(cats['EE_US_SIT'], -wd)
|
||||
|
||||
process_payslip(payslip)
|
||||
|
||||
# Make a new payslip, this one will have maximums
|
||||
|
||||
remaining_oh_unemp_wages = self.OH_UNEMP_MAX_WAGE - salary if (self.OH_UNEMP_MAX_WAGE - 2*salary < salary) \
|
||||
else salary
|
||||
|
||||
self._log('2019 Ohio tax second payslip:')
|
||||
payslip = self._createPayslip(employee, '2019-02-01', '2019-02-28')
|
||||
|
||||
payslip.compute_sheet()
|
||||
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self.assertPayrollEqual(cats['ER_US_SUTA'], remaining_oh_unemp_wages * self.OH_UNEMP)
|
||||
|
||||
def test_2019_taxes_with_external(self):
|
||||
salary = 5000.0
|
||||
external_wages = 6000.0
|
||||
|
||||
employee = self._createEmployee()
|
||||
|
||||
contract = self._createContract(employee,
|
||||
wage=salary,
|
||||
state_id=self.get_us_state('OH'),
|
||||
external_wages=external_wages,
|
||||
)
|
||||
|
||||
self._log('2019 Ohio_external tax first payslip:')
|
||||
payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31')
|
||||
|
||||
payslip.compute_sheet()
|
||||
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self.assertPayrollEqual(cats['ER_US_SUTA'], (self.OH_UNEMP_MAX_WAGE - external_wages) * self.OH_UNEMP)
|
||||
|
||||
def test_2019_taxes_with_state_exempt(self):
|
||||
salary = 5000.0
|
||||
external_wages = 6000.0
|
||||
|
||||
employee = self._createEmployee()
|
||||
contract = self._createContract(employee,
|
||||
wage=salary,
|
||||
state_id=self.get_us_state('OH'),
|
||||
external_wages=external_wages,
|
||||
futa_type=USHRContract.FUTA_TYPE_BASIC)
|
||||
|
||||
self._log('2019 Ohio exempt tax first payslip:')
|
||||
payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31')
|
||||
|
||||
payslip.compute_sheet()
|
||||
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
# FUTA_TYPE_BASIC
|
||||
self.assertPayrollEqual(cats.get('ER_US_SUTA', 0.0), salary * 0.0)
|
||||
108
l10n_us_hr_payroll/tests/test_us_oh_ohio_payslip_2020.py
Executable file
108
l10n_us_hr_payroll/tests/test_us_oh_ohio_payslip_2020.py
Executable file
@@ -0,0 +1,108 @@
|
||||
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
|
||||
|
||||
from datetime import date
|
||||
from .common import TestUsPayslip, process_payslip
|
||||
|
||||
|
||||
class TestUsOhPayslip(TestUsPayslip):
|
||||
###
|
||||
# Taxes and Rates
|
||||
###
|
||||
OH_UNEMP_MAX_WAGE = 9000.0
|
||||
OH_UNEMP = 2.7
|
||||
|
||||
def test_2020_taxes(self):
|
||||
self._test_er_suta('OH', self.OH_UNEMP, date(2020, 1, 1), wage_base=self.OH_UNEMP_MAX_WAGE)
|
||||
|
||||
def _run_test_sit(self,
|
||||
wage=0.0,
|
||||
schedule_pay='monthly',
|
||||
filing_status='single',
|
||||
dependent_credit=0.0,
|
||||
other_income=0.0,
|
||||
deductions=0.0,
|
||||
additional_withholding=0.0,
|
||||
is_nonresident_alien=False,
|
||||
state_income_tax_exempt=False,
|
||||
state_income_tax_additional_withholding=0.0,
|
||||
oh_it4_sit_exemptions=0,
|
||||
expected=0.0,
|
||||
):
|
||||
employee = self._createEmployee()
|
||||
contract = self._createContract(employee,
|
||||
wage=wage,
|
||||
schedule_pay=schedule_pay,
|
||||
fed_941_fit_w4_is_nonresident_alien=is_nonresident_alien,
|
||||
fed_941_fit_w4_filing_status=filing_status,
|
||||
fed_941_fit_w4_multiple_jobs_higher=False,
|
||||
fed_941_fit_w4_dependent_credit=dependent_credit,
|
||||
fed_941_fit_w4_other_income=other_income,
|
||||
fed_941_fit_w4_deductions=deductions,
|
||||
fed_941_fit_w4_additional_withholding=additional_withholding,
|
||||
state_income_tax_exempt=state_income_tax_exempt,
|
||||
state_income_tax_additional_withholding=state_income_tax_additional_withholding,
|
||||
oh_it4_sit_exemptions=oh_it4_sit_exemptions,
|
||||
state_id=self.get_us_state('OH'),
|
||||
)
|
||||
payslip = self._createPayslip(employee, '2020-01-01', '2020-01-31')
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
# Instead of PayrollEqual after initial first round of testing.
|
||||
self.assertPayrollAlmostEqual(cats.get('EE_US_SIT', 0.0), -expected)
|
||||
return payslip
|
||||
|
||||
def test_2020_sit_1(self):
|
||||
wage = 400.0
|
||||
exemptions = 1
|
||||
additional = 10.0
|
||||
pay_periods = 12.0
|
||||
annual_adjusted_wage = (wage * pay_periods) - (650.0 * exemptions)
|
||||
self.assertPayrollEqual(4150.0, annual_adjusted_wage)
|
||||
WD = ((annual_adjusted_wage * 0.005) / pay_periods) * 1.032
|
||||
self.assertPayrollEqual(WD, 1.7845)
|
||||
expected = WD + additional
|
||||
self._run_test_sit(wage=wage,
|
||||
schedule_pay='monthly',
|
||||
state_income_tax_exempt=False,
|
||||
state_income_tax_additional_withholding=additional,
|
||||
oh_it4_sit_exemptions=exemptions,
|
||||
expected=expected,
|
||||
)
|
||||
|
||||
# the above agrees with online calculator to the penny 0.01
|
||||
# below expected coming from calculator to 0.10
|
||||
#
|
||||
# semi-monthly
|
||||
self._run_test_sit(wage=1200,
|
||||
schedule_pay='semi-monthly',
|
||||
state_income_tax_exempt=False,
|
||||
state_income_tax_additional_withholding=20.0,
|
||||
oh_it4_sit_exemptions=2,
|
||||
expected=42.58,
|
||||
)
|
||||
|
||||
# bi-weekly
|
||||
self._run_test_sit(wage=3000,
|
||||
schedule_pay='bi-weekly',
|
||||
state_income_tax_exempt=False,
|
||||
#state_income_tax_additional_withholding=0.0,
|
||||
oh_it4_sit_exemptions=0,
|
||||
expected=88.51,
|
||||
)
|
||||
# weekly
|
||||
self._run_test_sit(wage=355,
|
||||
schedule_pay='weekly',
|
||||
state_income_tax_exempt=False,
|
||||
# state_income_tax_additional_withholding=0.0,
|
||||
oh_it4_sit_exemptions=1,
|
||||
expected=4.87,
|
||||
)
|
||||
|
||||
# Exempt!
|
||||
self._run_test_sit(wage=355,
|
||||
schedule_pay='weekly',
|
||||
state_income_tax_exempt=True,
|
||||
# state_income_tax_additional_withholding=0.0,
|
||||
oh_it4_sit_exemptions=1,
|
||||
expected=0.0,
|
||||
)
|
||||
38
l10n_us_hr_payroll/tests/test_us_ok_oklahoma_payslip_2020.py
Executable file
38
l10n_us_hr_payroll/tests/test_us_ok_oklahoma_payslip_2020.py
Executable file
@@ -0,0 +1,38 @@
|
||||
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
|
||||
|
||||
from datetime import date, timedelta
|
||||
from .common import TestUsPayslip
|
||||
|
||||
|
||||
class TestUsOKPayslip(TestUsPayslip):
|
||||
###
|
||||
# 2020 Taxes and Rates
|
||||
###
|
||||
OK_UNEMP_MAX_WAGE = 18700.0
|
||||
OK_UNEMP = 1.5
|
||||
# Calculation based on example https://www.ok.gov/tax/documents/2020WHTables.pdf
|
||||
|
||||
def _test_sit(self, wage, filing_status, allowances, additional_withholding, exempt, schedule_pay, date_start, expected_withholding):
|
||||
employee = self._createEmployee()
|
||||
contract = self._createContract(employee,
|
||||
wage=wage,
|
||||
state_id=self.get_us_state('OK'),
|
||||
ok_w4_sit_filing_status=filing_status,
|
||||
ok_w4_sit_allowances=allowances,
|
||||
state_income_tax_additional_withholding=additional_withholding,
|
||||
state_income_tax_exempt=exempt,
|
||||
schedule_pay=schedule_pay)
|
||||
payslip = self._createPayslip(employee, date_start, date_start + timedelta(days=7))
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self._log('Computed period tax: ' + str(expected_withholding))
|
||||
self.assertPayrollEqual(cats.get('EE_US_SIT', 0.0), -expected_withholding)
|
||||
|
||||
def test_2020_taxes_example(self):
|
||||
self._test_er_suta('OK', self.OK_UNEMP, date(2020, 1, 1), wage_base=self.OK_UNEMP_MAX_WAGE)
|
||||
self._test_sit(1825, 'married', 2, 0, False, 'semi-monthly', date(2020, 1, 1), 46.00)
|
||||
self._test_sit(1825, 'married', 2, 0, True, 'monthly', date(2020, 1, 1), 0.00)
|
||||
self._test_sit(1000, 'single', 1, 0, False, 'weekly', date(2020, 1, 1), 39.00)
|
||||
self._test_sit(1000, 'single', 1, 10, False, 'weekly', date(2020, 1, 1), 49.00)
|
||||
self._test_sit(5000, 'head_household', 2, 10, False, 'monthly', date(2020, 1, 1), 210.00)
|
||||
33
l10n_us_hr_payroll/tests/test_us_pa_pennsylvania_payslip_2019.py
Executable file
33
l10n_us_hr_payroll/tests/test_us_pa_pennsylvania_payslip_2019.py
Executable file
@@ -0,0 +1,33 @@
|
||||
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
|
||||
|
||||
from .common import TestUsPayslip, process_payslip
|
||||
|
||||
|
||||
class TestUsPAPayslip(TestUsPayslip):
|
||||
###
|
||||
# Taxes and Rates
|
||||
###
|
||||
PA_UNEMP_MAX_WAGE = 10000.0
|
||||
ER_PA_UNEMP = -3.6890 / 100.0
|
||||
EE_PA_UNEMP = -0.06 / 100.0
|
||||
PA_INC_WITHHOLD = 3.07
|
||||
|
||||
def test_2019_taxes(self):
|
||||
salary = 4166.67
|
||||
wh = -127.92
|
||||
|
||||
|
||||
employee = self._createEmployee()
|
||||
contract = self._createContract(employee,
|
||||
wage=salary,
|
||||
state_id=self.get_us_state('PA'))
|
||||
|
||||
self._log('2019 Pennsylvania tax first payslip:')
|
||||
payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31')
|
||||
payslip.compute_sheet()
|
||||
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self.assertPayrollEqual(cats['EE_US_SUTA'], cats['GROSS'] * self.EE_PA_UNEMP)
|
||||
self.assertPayrollEqual(cats['ER_US_SUTA'], cats['GROSS'] * self.ER_PA_UNEMP)
|
||||
self.assertPayrollEqual(cats['EE_US_SIT'], wh)
|
||||
43
l10n_us_hr_payroll/tests/test_us_pa_pennsylvania_payslip_2020.py
Executable file
43
l10n_us_hr_payroll/tests/test_us_pa_pennsylvania_payslip_2020.py
Executable file
@@ -0,0 +1,43 @@
|
||||
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
|
||||
|
||||
from datetime import date
|
||||
from .common import TestUsPayslip
|
||||
|
||||
|
||||
class TestUsPAPayslip(TestUsPayslip):
|
||||
###
|
||||
# Taxes and Rates
|
||||
###
|
||||
PA_UNEMP_MAX_WAGE = 10000.0
|
||||
ER_PA_UNEMP = 3.6890
|
||||
EE_PA_UNEMP = 0.06
|
||||
PA_INC_WITHHOLD = 3.07
|
||||
|
||||
def test_2020_taxes(self):
|
||||
self._test_er_suta('PA', self.ER_PA_UNEMP, date(2020, 1, 1), wage_base=self.PA_UNEMP_MAX_WAGE)
|
||||
self._test_ee_suta('PA', self.EE_PA_UNEMP, date(2020, 1, 1))
|
||||
|
||||
salary = 4166.67
|
||||
wh = -127.92
|
||||
employee = self._createEmployee()
|
||||
contract = self._createContract(employee,
|
||||
wage=salary,
|
||||
state_id=self.get_us_state('PA'))
|
||||
|
||||
self._log('2019 Pennsylvania tax first payslip:')
|
||||
payslip = self._createPayslip(employee, '2020-01-01', '2020-01-31')
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
self.assertPayrollEqual(cats['EE_US_SIT'], wh)
|
||||
|
||||
# Test Additional
|
||||
contract.us_payroll_config_id.state_income_tax_additional_withholding = 100.0
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
self.assertPayrollEqual(cats['EE_US_SIT'], wh - 100.0)
|
||||
|
||||
# Test Exempt
|
||||
contract.us_payroll_config_id.state_income_tax_exempt = True
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
self.assertPayrollEqual(cats.get('EE_US_SIT', 0.0), 0.0)
|
||||
37
l10n_us_hr_payroll/tests/test_us_ri_rhode_island_payslip_2020.py
Executable file
37
l10n_us_hr_payroll/tests/test_us_ri_rhode_island_payslip_2020.py
Executable file
@@ -0,0 +1,37 @@
|
||||
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
|
||||
|
||||
from datetime import date, timedelta
|
||||
from .common import TestUsPayslip
|
||||
|
||||
|
||||
class TestUsRIPayslip(TestUsPayslip):
|
||||
###
|
||||
# 2020 Taxes and Rates
|
||||
###
|
||||
RI_UNEMP_MAX_WAGE = 24000.0
|
||||
RI_UNEMP = 1.06
|
||||
# Calculation based on example http://www.tax.ri.gov/forms/2020/Withholding/2020%20Withhholding%20Tax%20Booklet.pdf
|
||||
|
||||
def _test_sit(self, wage, allowances, additional_withholding, exempt, schedule_pay, date_start, expected_withholding):
|
||||
employee = self._createEmployee()
|
||||
contract = self._createContract(employee,
|
||||
wage=wage,
|
||||
state_id=self.get_us_state('RI'),
|
||||
ri_w4_sit_allowances=allowances,
|
||||
state_income_tax_additional_withholding=additional_withholding,
|
||||
state_income_tax_exempt=exempt,
|
||||
schedule_pay=schedule_pay)
|
||||
payslip = self._createPayslip(employee, date_start, date_start + timedelta(days=7))
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self._log('Computed period tax: ' + str(expected_withholding))
|
||||
self.assertPayrollEqual(cats.get('EE_US_SIT', 0.0), -expected_withholding)
|
||||
|
||||
def test_2020_taxes_example(self):
|
||||
self._test_er_suta('RI', self.RI_UNEMP, date(2020, 1, 1), wage_base=self.RI_UNEMP_MAX_WAGE)
|
||||
self._test_sit(2195, 1, 0, False, 'weekly', date(2020, 1, 1), 90.80)
|
||||
self._test_sit(1800, 2, 10, True, 'weekly', date(2020, 1, 1), 0.00)
|
||||
self._test_sit(10000, 1, 0, False, 'bi-weekly', date(2020, 1, 1), 503.15)
|
||||
self._test_sit(18000, 2, 0, False, 'monthly', date(2020, 1, 1), 860.54)
|
||||
self._test_sit(18000, 2, 10, False, 'monthly', date(2020, 1, 1), 870.55)
|
||||
@@ -0,0 +1,97 @@
|
||||
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
|
||||
|
||||
from .common import TestUsPayslip, process_payslip
|
||||
|
||||
|
||||
class TestUsSCPayslip(TestUsPayslip):
|
||||
|
||||
# Taxes and Rates
|
||||
SC_UNEMP_MAX_WAGE = 14000.0
|
||||
US_SC_UNEMP = -1.09 / 100
|
||||
US_SC_exemption_amount = 2510.00
|
||||
|
||||
def test_2019_taxes_weekly(self):
|
||||
# We will hand calculate the amount to test for state withholding.
|
||||
schedule_pay = 'weekly'
|
||||
salary = 50000.00 # Employee is paid 50000 per week to be in top tax bracket
|
||||
allowances = 2
|
||||
# Calculate annual wages
|
||||
annual = 50000 * 52.0
|
||||
# From our annual we deduct personal exemption amounts.
|
||||
# We deduct 2510.00 per exemption. Since we have two exemptions:
|
||||
personal_exemption = self.US_SC_exemption_amount * allowances # 5020.0
|
||||
# From annual, we will also deduct a standard_deduction of 3470.00 or .1 of salary, which ever
|
||||
# is small -> if 1 or more exemptions, else 0
|
||||
standard_deduction = 3470.00
|
||||
taxable_income = annual - personal_exemption - standard_deduction # 2591510.0
|
||||
# We then calculate the amounts off the SC tax pdf tables.
|
||||
# 2591478.0 is in the highest bracket
|
||||
test_amt = (taxable_income * (7.0 / 100.0)) - 467.95
|
||||
test_amt = 180935.51
|
||||
# Make it per period then negative
|
||||
test_amt = (test_amt / 52.0) # Divided by 52 since it is weekly.
|
||||
# test_amt = 3479.52
|
||||
test_amt = -test_amt
|
||||
|
||||
employee = self._createEmployee()
|
||||
contract = self._createContract(employee,
|
||||
wage=salary,
|
||||
state_id=self.get_us_state('SC'),
|
||||
state_income_tax_exempt=False,
|
||||
sc_w4_sit_allowances=allowances,
|
||||
schedule_pay=schedule_pay)
|
||||
|
||||
self._log('2019 South Carolina tax first payslip:')
|
||||
payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31')
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self.assertPayrollAlmostEqual(cats['ER_US_SUTA'], self.SC_UNEMP_MAX_WAGE * self.US_SC_UNEMP)
|
||||
self.assertPayrollAlmostEqual(cats['EE_US_SIT'], test_amt)
|
||||
|
||||
process_payslip(payslip)
|
||||
|
||||
remaining_SC_UNEMP_wages = self.SC_UNEMP_MAX_WAGE - annual if (annual < self.SC_UNEMP_MAX_WAGE) \
|
||||
else 0.00
|
||||
|
||||
self._log('2019 South Carolina tax second payslip:')
|
||||
|
||||
payslip = self._createPayslip(employee, '2019-02-01', '2019-02-28')
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self.assertEqual(0.0, remaining_SC_UNEMP_wages)
|
||||
self.assertPayrollEqual(cats['ER_US_SUTA'], remaining_SC_UNEMP_wages * self.US_SC_UNEMP)
|
||||
|
||||
def test_2019_taxes_filing_status(self):
|
||||
salary = 20000.00 # Wages per pay period
|
||||
schedule_pay = 'monthly'
|
||||
annual = salary * 12
|
||||
allowances = 1
|
||||
# Hand Calculations
|
||||
personal_exemption = 2510.00
|
||||
standard_deduction = min(3470.00, .1 * annual) # 3470.0 but min is shown for the process
|
||||
taxable = annual - personal_exemption - standard_deduction
|
||||
# taxable = 234020
|
||||
test_amt = ((taxable) * (7.0 / 100.0)) - 467.95 # 15991.850000000002
|
||||
test_amt = test_amt / 12.0 # Put it into monthly -> 1332.654166666667
|
||||
# Make it negative
|
||||
test_amt = -test_amt
|
||||
|
||||
employee = self._createEmployee()
|
||||
contract = self._createContract(employee,
|
||||
wage=salary,
|
||||
state_id=self.get_us_state('SC'),
|
||||
state_income_tax_exempt=False,
|
||||
sc_w4_sit_allowances=allowances,
|
||||
schedule_pay=schedule_pay)
|
||||
|
||||
self._log('2019 South Carolina tax first payslip: ')
|
||||
payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31')
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self.assertPayrollEqual(cats['ER_US_SUTA'], self.SC_UNEMP_MAX_WAGE * self.US_SC_UNEMP)
|
||||
self.assertPayrollAlmostEqual(cats['EE_US_SIT'], test_amt)
|
||||
|
||||
process_payslip(payslip)
|
||||
@@ -0,0 +1,36 @@
|
||||
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
|
||||
|
||||
from datetime import date, timedelta
|
||||
from .common import TestUsPayslip
|
||||
|
||||
|
||||
class TestUsSCPayslip(TestUsPayslip):
|
||||
###
|
||||
# 2020 Taxes and Rates
|
||||
###
|
||||
SC_UNEMP_MAX_WAGE = 14000.0
|
||||
SC_UNEMP = 0.55
|
||||
# Calculation based on https://dor.sc.gov/forms-site/Forms/WH1603F_2020.pdf
|
||||
|
||||
def _test_sit(self, wage, additional_withholding, exempt, allowances, schedule_pay, date_start, expected_withholding):
|
||||
employee = self._createEmployee()
|
||||
contract = self._createContract(employee,
|
||||
wage=wage,
|
||||
state_id=self.get_us_state('SC'),
|
||||
state_income_tax_additional_withholding=additional_withholding,
|
||||
state_income_tax_exempt=exempt,
|
||||
sc_w4_sit_allowances=allowances,
|
||||
schedule_pay=schedule_pay)
|
||||
payslip = self._createPayslip(employee, date_start, date_start + timedelta(days=7))
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self._log('Computed period tax: ' + str(expected_withholding))
|
||||
self.assertPayrollAlmostEqual(cats.get('EE_US_SIT', 0.0), -expected_withholding)
|
||||
|
||||
def test_2020_taxes_example(self):
|
||||
self._test_er_suta('SC', self.SC_UNEMP, date(2020, 1, 1), wage_base=self.SC_UNEMP_MAX_WAGE)
|
||||
self._test_sit(750.0, 0.0, False, 3.0, 'weekly', date(2020, 1, 1), 28.73)
|
||||
self._test_sit(800.0, 0.0, True, 0.0, 'weekly', date(2020, 1, 1), 0.00)
|
||||
self._test_sit(9000.0, 0.0, False, 0.0, 'monthly', date(2020, 1, 1), 594.61)
|
||||
self._test_sit(5000.0, 10.0, False, 2.0, 'semi-monthly', date(2020, 1, 1), 316.06)
|
||||
@@ -0,0 +1,13 @@
|
||||
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
|
||||
|
||||
from datetime import date
|
||||
from .common import TestUsPayslip
|
||||
|
||||
|
||||
class TestUsSDPayslip(TestUsPayslip):
|
||||
# TAXES AND RATES
|
||||
SD_UNEMP_MAX_WAGE = 15000.00
|
||||
SD_UNEMP = 1.75
|
||||
|
||||
def test_2020_taxes(self):
|
||||
self._test_er_suta('SD', self.SD_UNEMP, date(2020, 1, 1), wage_base=self.SD_UNEMP_MAX_WAGE)
|
||||
@@ -0,0 +1,13 @@
|
||||
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
|
||||
|
||||
from datetime import date
|
||||
from .common import TestUsPayslip
|
||||
|
||||
|
||||
class TestUsTNPayslip(TestUsPayslip):
|
||||
# TAXES AND RATES
|
||||
TN_UNEMP_MAX_WAGE = 7000.00
|
||||
TN_UNEMP = 2.7
|
||||
|
||||
def test_2020_taxes(self):
|
||||
self._test_er_suta('TN', self.TN_UNEMP, date(2020, 1, 1), wage_base=self.TN_UNEMP_MAX_WAGE)
|
||||
100
l10n_us_hr_payroll/tests/test_us_tx_texas_payslip_2019.py
Executable file
100
l10n_us_hr_payroll/tests/test_us_tx_texas_payslip_2019.py
Executable file
@@ -0,0 +1,100 @@
|
||||
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
|
||||
|
||||
from .common import TestUsPayslip, process_payslip
|
||||
from odoo.addons.l10n_us_hr_payroll.models.hr_contract import USHRContract
|
||||
|
||||
class TestUsTXPayslip(TestUsPayslip):
|
||||
###
|
||||
# 2019 Taxes and Rates
|
||||
###
|
||||
TX_UNEMP_MAX_WAGE = 9000.0
|
||||
TX_UNEMP = -2.7 / 100.0
|
||||
TX_OA = 0.0
|
||||
TX_ETIA = -0.1 / 100.0
|
||||
|
||||
def test_2019_taxes(self):
|
||||
salary = 5000.0
|
||||
|
||||
employee = self._createEmployee()
|
||||
contract = self._createContract(employee,
|
||||
wage=salary,
|
||||
state_id=self.get_us_state('TX'),
|
||||
)
|
||||
|
||||
self._log('2019 Texas tax first payslip:')
|
||||
payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31')
|
||||
|
||||
payslip.compute_sheet()
|
||||
|
||||
cats = self._getCategories(payslip)
|
||||
rules = self._getRules(payslip)
|
||||
|
||||
self.assertPayrollEqual(rules['ER_US_TX_SUTA'], salary * self.TX_UNEMP)
|
||||
self.assertPayrollEqual(rules['ER_US_TX_SUTA_OA'], salary * self.TX_OA)
|
||||
self.assertPayrollEqual(rules['ER_US_TX_SUTA_ETIA'], salary * self.TX_ETIA)
|
||||
|
||||
process_payslip(payslip)
|
||||
|
||||
# Make a new payslip, this one will have maximums
|
||||
|
||||
remaining_tx_unemp_wages = self.TX_UNEMP_MAX_WAGE - salary if (self.TX_UNEMP_MAX_WAGE - 2*salary < salary) \
|
||||
else salary
|
||||
|
||||
self._log('2019 Texas tax second payslip:')
|
||||
payslip = self._createPayslip(employee, '2019-02-01', '2019-02-28')
|
||||
|
||||
payslip.compute_sheet()
|
||||
|
||||
cats = self._getCategories(payslip)
|
||||
rules = self._getRules(payslip)
|
||||
|
||||
self.assertPayrollEqual(rules['ER_US_TX_SUTA'], remaining_tx_unemp_wages * self.TX_UNEMP)
|
||||
|
||||
def test_2019_taxes_with_external(self):
|
||||
salary = 5000.0
|
||||
external_wages = 6000.0
|
||||
|
||||
employee = self._createEmployee()
|
||||
|
||||
contract = self._createContract(employee,
|
||||
wage=salary,
|
||||
state_id=self.get_us_state('TX'),
|
||||
external_wages=external_wages,
|
||||
)
|
||||
|
||||
self._log('2019 Texas_external tax first payslip:')
|
||||
payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31')
|
||||
|
||||
payslip.compute_sheet()
|
||||
|
||||
cats = self._getCategories(payslip)
|
||||
rules = self._getRules(payslip)
|
||||
|
||||
expected_wage = self.TX_UNEMP_MAX_WAGE - external_wages
|
||||
self.assertPayrollEqual(rules['ER_US_TX_SUTA'], expected_wage * self.TX_UNEMP)
|
||||
self.assertPayrollEqual(rules['ER_US_TX_SUTA_OA'], expected_wage * self.TX_OA)
|
||||
self.assertPayrollEqual(rules['ER_US_TX_SUTA_ETIA'], expected_wage * self.TX_ETIA)
|
||||
|
||||
def test_2019_taxes_with_state_exempt(self):
|
||||
salary = 5000.0
|
||||
external_wages = 6000.0
|
||||
|
||||
employee = self._createEmployee()
|
||||
|
||||
contract = self._createContract(employee,
|
||||
wage=salary,
|
||||
state_id=self.get_us_state('TX'),
|
||||
external_wages=external_wages,
|
||||
futa_type=USHRContract.FUTA_TYPE_BASIC)
|
||||
|
||||
self._log('2019 Texas_external tax first payslip:')
|
||||
payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31')
|
||||
|
||||
payslip.compute_sheet()
|
||||
|
||||
cats = self._getCategories(payslip)
|
||||
rules = self._getRules(payslip)
|
||||
|
||||
self.assertPayrollEqual(rules.get('ER_US_TX_SUTA', 0.0), 0.0)
|
||||
self.assertPayrollEqual(rules.get('ER_US_TX_SUTA_OA', 0.0), 0.0)
|
||||
self.assertPayrollEqual(rules.get('ER_US_TX_SUTA_ETIA', 0.0), 0.0)
|
||||
17
l10n_us_hr_payroll/tests/test_us_tx_texas_payslip_2020.py
Executable file
17
l10n_us_hr_payroll/tests/test_us_tx_texas_payslip_2020.py
Executable file
@@ -0,0 +1,17 @@
|
||||
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
|
||||
|
||||
from datetime import date
|
||||
from .common import TestUsPayslip
|
||||
|
||||
class TestUsTXPayslip(TestUsPayslip):
|
||||
###
|
||||
# 2020 Taxes and Rates
|
||||
###
|
||||
TX_UNEMP_MAX_WAGE = 9000.0
|
||||
TX_UNEMP = 2.7
|
||||
TX_OA = 0.0
|
||||
TX_ETIA = 0.1
|
||||
|
||||
def test_2020_taxes(self):
|
||||
combined_rate = self.TX_UNEMP + self.TX_OA + self.TX_ETIA
|
||||
self._test_er_suta('TX', combined_rate, date(2020, 1, 1), wage_base=self.TX_UNEMP_MAX_WAGE)
|
||||
36
l10n_us_hr_payroll/tests/test_us_us_utah_payslip_2020.py
Executable file
36
l10n_us_hr_payroll/tests/test_us_us_utah_payslip_2020.py
Executable file
@@ -0,0 +1,36 @@
|
||||
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
|
||||
|
||||
from datetime import date, timedelta
|
||||
from .common import TestUsPayslip
|
||||
|
||||
|
||||
class TestUsUTPayslip(TestUsPayslip):
|
||||
###
|
||||
# 2020 Taxes and Rates
|
||||
###
|
||||
UT_UNEMP_MAX_WAGE = 36600.0
|
||||
UT_UNEMP = 0.1
|
||||
# Calculation based on example https://tax.utah.gov/forms/pubs/pub-14.pdf
|
||||
|
||||
def _test_sit(self, wage, filing_status, additional_withholding, schedule_pay, date_start, expected_withholding):
|
||||
employee = self._createEmployee()
|
||||
contract = self._createContract(employee,
|
||||
wage=wage,
|
||||
state_id=self.get_us_state('UT'),
|
||||
ut_w4_sit_filing_status=filing_status,
|
||||
state_income_tax_additional_withholding=additional_withholding,
|
||||
schedule_pay=schedule_pay)
|
||||
payslip = self._createPayslip(employee, date_start, date_start + timedelta(days=7))
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self._log('Computed period tax: ' + str(expected_withholding))
|
||||
self.assertPayrollAlmostEqual(cats.get('EE_US_SIT', 0.0), -expected_withholding)
|
||||
|
||||
def test_2020_taxes_example(self):
|
||||
self._test_er_suta('UT', self.UT_UNEMP, date(2020, 1, 1), wage_base=self.UT_UNEMP_MAX_WAGE)
|
||||
self._test_sit(400, 'single', 0, 'weekly', date(2020, 1, 1), 16.00)
|
||||
self._test_sit(1000, 'single', 0, 'bi-weekly', date(2020, 1, 1), 45.00)
|
||||
self._test_sit(855, 'married', 0, 'semi-monthly', date(2020, 1, 1), 16.00)
|
||||
self._test_sit(2500, 'married', 0, 'monthly', date(2020, 1, 1), 81.00)
|
||||
self._test_sit(8000, 'head_household', 10, 'quarterly', date(2020, 1, 1), 397.00)
|
||||
133
l10n_us_hr_payroll/tests/test_us_va_virginia_payslip_2019.py
Normal file
133
l10n_us_hr_payroll/tests/test_us_va_virginia_payslip_2019.py
Normal file
@@ -0,0 +1,133 @@
|
||||
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
|
||||
|
||||
from datetime import date
|
||||
from .common import TestUsPayslip, process_payslip
|
||||
from odoo.addons.l10n_us_hr_payroll.models.hr_contract import USHRContract
|
||||
|
||||
|
||||
class TestUsVaPayslip(TestUsPayslip):
|
||||
###
|
||||
# Taxes and Rates
|
||||
###
|
||||
VA_UNEMP_MAX_WAGE = 8000.0
|
||||
VA_UNEMP = 2.51
|
||||
VA_SIT_DEDUCTION = 4500.0
|
||||
VA_SIT_EXEMPTION = 930.0
|
||||
VA_SIT_OTHER_EXEMPTION = 800.0
|
||||
|
||||
def test_2019_taxes(self):
|
||||
salary = 5000.0
|
||||
|
||||
# For formula from https://www.tax.virginia.gov/withholding-calculator
|
||||
"""
|
||||
Key
|
||||
G = Gross Pay for Pay Period P = Pay periods per year
|
||||
A = Annualized gross pay E1 = Personal and Dependent Exemptions
|
||||
T = Annualized taxable income E2 = Age 65 and Over & Blind Exemptions
|
||||
WH = Tax to be withheld for pay period W = Annualized tax to be withheld
|
||||
G x P - [$3000+ (E1 x 930) + (E2 x 800)] = T
|
||||
Calculate W as follows:
|
||||
If T is: W is:
|
||||
Not over $3,000 2% of T
|
||||
Over But Not Over Then
|
||||
$3,000 $5,000 $60 + (3% of excess over $3,000)
|
||||
$5,000 $17,000 $120 + (5% of excess over $5,000)
|
||||
$17,000 $720 + (5.75% of excess over $17,000)
|
||||
W / P = WH
|
||||
"""
|
||||
e1 = 2
|
||||
e2 = 0
|
||||
t = salary * 12 - (self.VA_SIT_DEDUCTION + (e1 * self.VA_SIT_EXEMPTION) + (e2 * self.VA_SIT_OTHER_EXEMPTION))
|
||||
|
||||
if t <= 3000:
|
||||
w = 0.02 * t
|
||||
elif t <= 5000:
|
||||
w = 60 + (0.03 * (t - 3000))
|
||||
elif t <= 17000:
|
||||
w = 120 + (0.05 * (t - 5000))
|
||||
else:
|
||||
w = 720 + (0.0575 * (t - 17000))
|
||||
|
||||
wh = w / 12
|
||||
|
||||
employee = self._createEmployee()
|
||||
|
||||
contract = self._createContract(employee,
|
||||
wage=salary,
|
||||
state_id=self.get_us_state('VA'),
|
||||
va_va4_sit_exemptions=e1,
|
||||
va_va4_sit_other_exemptions=e2
|
||||
)
|
||||
|
||||
# tax rates
|
||||
va_unemp = self.VA_UNEMP / -100.0
|
||||
|
||||
self._log('2019 Virginia tax first payslip:')
|
||||
payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31')
|
||||
|
||||
payslip.compute_sheet()
|
||||
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self.assertPayrollEqual(cats['ER_US_SUTA'], salary * va_unemp)
|
||||
self.assertPayrollEqual(cats['EE_US_SIT'], -wh)
|
||||
|
||||
process_payslip(payslip)
|
||||
|
||||
# Make a new payslip, this one will have maximums
|
||||
|
||||
remaining_va_unemp_wages = self.VA_UNEMP_MAX_WAGE - salary if (self.VA_UNEMP_MAX_WAGE - 2*salary < salary) \
|
||||
else salary
|
||||
|
||||
self._log('2019 Virginia tax second payslip:')
|
||||
payslip = self._createPayslip(employee, '2019-02-01', '2019-02-28')
|
||||
|
||||
payslip.compute_sheet()
|
||||
|
||||
cats = self._getCategories(payslip)
|
||||
self.assertPayrollEqual(cats['ER_US_SUTA'], remaining_va_unemp_wages * va_unemp)
|
||||
|
||||
def test_2019_taxes_with_external(self):
|
||||
salary = 5000.0
|
||||
external_wages = 6000.0
|
||||
|
||||
employee = self._createEmployee()
|
||||
|
||||
contract = self._createContract(employee,
|
||||
wage=salary,
|
||||
state_id=self.get_us_state('VA'),
|
||||
external_wages=external_wages,
|
||||
)
|
||||
|
||||
# tax rates
|
||||
va_unemp = self.VA_UNEMP / -100.0
|
||||
|
||||
self._log('2019 Virginia_external tax first payslip:')
|
||||
payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31')
|
||||
|
||||
payslip.compute_sheet()
|
||||
|
||||
cats = self._getCategories(payslip)
|
||||
self.assertPayrollEqual(cats['ER_US_SUTA'], (self.VA_UNEMP_MAX_WAGE - external_wages) * va_unemp)
|
||||
|
||||
def test_2019_taxes_with_state_exempt(self):
|
||||
salary = 5000.0
|
||||
external_wages = 6000.0
|
||||
|
||||
employee = self._createEmployee()
|
||||
|
||||
contract = self._createContract(employee,
|
||||
wage=salary,
|
||||
state_id=self.get_us_state('VA'),
|
||||
external_wages=external_wages,
|
||||
futa_type=USHRContract.FUTA_TYPE_BASIC)
|
||||
|
||||
# tax rates
|
||||
self._log('2019 Virginia exempt tax first payslip:')
|
||||
payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31')
|
||||
|
||||
payslip.compute_sheet()
|
||||
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self.assertPayrollEqual(cats['ER_US_SUTA'], 0.0)
|
||||
116
l10n_us_hr_payroll/tests/test_us_va_virginia_payslip_2020.py
Normal file
116
l10n_us_hr_payroll/tests/test_us_va_virginia_payslip_2020.py
Normal file
@@ -0,0 +1,116 @@
|
||||
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
|
||||
|
||||
from datetime import date
|
||||
from .common import TestUsPayslip
|
||||
|
||||
|
||||
class TestUsVaPayslip(TestUsPayslip):
|
||||
###
|
||||
# Taxes and Rates
|
||||
###
|
||||
VA_UNEMP_MAX_WAGE = 8000.0
|
||||
VA_UNEMP = 2.51
|
||||
VA_SIT_DEDUCTION = 4500.0
|
||||
VA_SIT_EXEMPTION = 930.0
|
||||
VA_SIT_OTHER_EXEMPTION = 800.0
|
||||
|
||||
def _run_test_sit(self,
|
||||
wage=0.0,
|
||||
schedule_pay='monthly',
|
||||
filing_status='single',
|
||||
dependent_credit=0.0,
|
||||
other_income=0.0,
|
||||
deductions=0.0,
|
||||
additional_withholding=0.0,
|
||||
is_nonresident_alien=False,
|
||||
state_income_tax_exempt=False,
|
||||
state_income_tax_additional_withholding=0.0,
|
||||
va_va4_sit_exemptions=0,
|
||||
va_va4_sit_other_exemptions=0,
|
||||
expected=0.0,
|
||||
):
|
||||
employee = self._createEmployee()
|
||||
contract = self._createContract(employee,
|
||||
wage=wage,
|
||||
schedule_pay=schedule_pay,
|
||||
fed_941_fit_w4_is_nonresident_alien=is_nonresident_alien,
|
||||
fed_941_fit_w4_filing_status=filing_status,
|
||||
fed_941_fit_w4_multiple_jobs_higher=False,
|
||||
fed_941_fit_w4_dependent_credit=dependent_credit,
|
||||
fed_941_fit_w4_other_income=other_income,
|
||||
fed_941_fit_w4_deductions=deductions,
|
||||
fed_941_fit_w4_additional_withholding=additional_withholding,
|
||||
state_income_tax_exempt=state_income_tax_exempt,
|
||||
state_income_tax_additional_withholding=state_income_tax_additional_withholding,
|
||||
va_va4_sit_exemptions=va_va4_sit_exemptions,
|
||||
va_va4_sit_other_exemptions=va_va4_sit_other_exemptions,
|
||||
state_id=self.get_us_state('VA'),
|
||||
)
|
||||
payslip = self._createPayslip(employee, '2020-01-01', '2020-01-31')
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
# Instead of PayrollEqual after initial first round of testing.
|
||||
self.assertPayrollAlmostEqual(cats.get('EE_US_SIT', 0.0), -expected)
|
||||
return payslip
|
||||
|
||||
def test_2020_taxes(self):
|
||||
self._test_er_suta('VA', self.VA_UNEMP, date(2020, 1, 1), wage_base=self.VA_UNEMP_MAX_WAGE)
|
||||
|
||||
salary = 5000.0
|
||||
|
||||
# For formula from https://www.tax.virginia.gov/withholding-calculator
|
||||
e1 = 2
|
||||
e2 = 0
|
||||
t = salary * 12 - (self.VA_SIT_DEDUCTION + (e1 * self.VA_SIT_EXEMPTION) + (e2 * self.VA_SIT_OTHER_EXEMPTION))
|
||||
|
||||
if t <= 3000:
|
||||
w = 0.02 * t
|
||||
elif t <= 5000:
|
||||
w = 60 + (0.03 * (t - 3000))
|
||||
elif t <= 17000:
|
||||
w = 120 + (0.05 * (t - 5000))
|
||||
else:
|
||||
w = 720 + (0.0575 * (t - 17000))
|
||||
|
||||
wh = w / 12
|
||||
|
||||
self._run_test_sit(wage=salary,
|
||||
schedule_pay='monthly',
|
||||
state_income_tax_exempt=False,
|
||||
state_income_tax_additional_withholding=0.0,
|
||||
va_va4_sit_exemptions=e1,
|
||||
va_va4_sit_other_exemptions=e2,
|
||||
expected=wh,)
|
||||
self.assertPayrollEqual(wh, 235.57) # To test against calculator
|
||||
|
||||
# Below expected comes from the calculator linked above
|
||||
self._run_test_sit(wage=450.0,
|
||||
schedule_pay='weekly',
|
||||
state_income_tax_exempt=False,
|
||||
state_income_tax_additional_withholding=0.0,
|
||||
va_va4_sit_exemptions=3,
|
||||
va_va4_sit_other_exemptions=1,
|
||||
expected=12.22,)
|
||||
self._run_test_sit(wage=2500.0,
|
||||
schedule_pay='bi-weekly',
|
||||
state_income_tax_exempt=False,
|
||||
state_income_tax_additional_withholding=0.0,
|
||||
va_va4_sit_exemptions=1,
|
||||
va_va4_sit_other_exemptions=0,
|
||||
expected=121.84,)
|
||||
self._run_test_sit(wage=10000.0,
|
||||
schedule_pay='semi-monthly',
|
||||
state_income_tax_exempt=False,
|
||||
state_income_tax_additional_withholding=100.0,
|
||||
va_va4_sit_exemptions=0,
|
||||
va_va4_sit_other_exemptions=1,
|
||||
expected=651.57,)
|
||||
|
||||
# Test exempt
|
||||
self._run_test_sit(wage=2400.0,
|
||||
schedule_pay='monthly',
|
||||
state_income_tax_exempt=True,
|
||||
state_income_tax_additional_withholding=0.0,
|
||||
va_va4_sit_exemptions=1,
|
||||
va_va4_sit_other_exemptions=1,
|
||||
expected=0.0,)
|
||||
37
l10n_us_hr_payroll/tests/test_us_vt_vermont_payslip_2020.py
Executable file
37
l10n_us_hr_payroll/tests/test_us_vt_vermont_payslip_2020.py
Executable file
@@ -0,0 +1,37 @@
|
||||
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
|
||||
|
||||
from datetime import date, timedelta
|
||||
from .common import TestUsPayslip
|
||||
|
||||
|
||||
class TestUsVTPayslip(TestUsPayslip):
|
||||
###
|
||||
# 2020 Taxes and Rates
|
||||
###
|
||||
VT_UNEMP_MAX_WAGE = 16100.0
|
||||
VT_UNEMP = 1.0
|
||||
# Calculation based on example https://tax.vermont.gov/sites/tax/files/documents/WithholdingInstructions.pdf
|
||||
|
||||
def _test_sit(self, wage, filing_status, allowances, additional_withholding, exempt, schedule_pay, date_start, expected_withholding):
|
||||
employee = self._createEmployee()
|
||||
contract = self._createContract(employee,
|
||||
wage=wage,
|
||||
state_id=self.get_us_state('VT'),
|
||||
vt_w4vt_sit_filing_status=filing_status,
|
||||
vt_w4vt_sit_allowances=allowances,
|
||||
state_income_tax_additional_withholding=additional_withholding,
|
||||
state_income_tax_exempt=exempt,
|
||||
schedule_pay=schedule_pay)
|
||||
payslip = self._createPayslip(employee, date_start, date_start + timedelta(days=7))
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self._log('Computed period tax: ' + str(expected_withholding))
|
||||
self.assertPayrollEqual(cats.get('EE_US_SIT', 0.0), -expected_withholding)
|
||||
|
||||
def test_2020_taxes_example(self):
|
||||
self._test_er_suta('VT', self.VT_UNEMP, date(2020, 1, 1), wage_base=self.VT_UNEMP_MAX_WAGE)
|
||||
self._test_sit(1800, 'married', 2, 0, False, 'weekly', date(2020, 1, 1), 53.73)
|
||||
self._test_sit(1800, 'married', 2, 10, False, 'weekly', date(2020, 1, 1), 63.73)
|
||||
self._test_sit(1000, 'single', 1, 0, True, 'weekly', date(2020, 1, 1), 0.00)
|
||||
self._test_sit(8000, 'single', 1, 10, False, 'bi-weekly', date(2020, 1, 1), 506.58)
|
||||
92
l10n_us_hr_payroll/tests/test_us_wa_washington_payslip_2019.py
Executable file
92
l10n_us_hr_payroll/tests/test_us_wa_washington_payslip_2019.py
Executable file
@@ -0,0 +1,92 @@
|
||||
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
|
||||
|
||||
from datetime import date
|
||||
from .common import TestUsPayslip, process_payslip
|
||||
|
||||
|
||||
class TestUsWAPayslip(TestUsPayslip):
|
||||
###
|
||||
# Taxes and Rates
|
||||
###
|
||||
WA_UNEMP_MAX_WAGE = 49800.0
|
||||
WA_UNEMP_RATE = 1.18
|
||||
WA_FML_RATE = 0.4
|
||||
WA_FML_RATE_EE = 66.33
|
||||
WA_FML_RATE_ER = 33.67
|
||||
|
||||
def setUp(self):
|
||||
super(TestUsWAPayslip, self).setUp()
|
||||
# self.lni = self.env['hr.contract.lni.wa'].create({
|
||||
# 'name': '5302 Computer Consulting',
|
||||
# 'rate': 0.1261,
|
||||
# 'rate_emp_withhold': 0.05575,
|
||||
# })
|
||||
self.test_ee_lni = 0.05575 # per 100 hours
|
||||
self.test_er_lni = 0.1261 # per 100 hours
|
||||
self.parameter_lni_ee = self.env['hr.rule.parameter'].create({
|
||||
'name': 'Test LNI EE',
|
||||
'code': 'test_lni_ee',
|
||||
'parameter_version_ids': [(0, 0, {
|
||||
'date_from': date(2019, 1, 1),
|
||||
'parameter_value': str(self.test_ee_lni * 100),
|
||||
})],
|
||||
})
|
||||
self.parameter_lni_er = self.env['hr.rule.parameter'].create({
|
||||
'name': 'Test LNI ER',
|
||||
'code': 'test_lni_er',
|
||||
'parameter_version_ids': [(0, 0, {
|
||||
'date_from': date(2019, 1, 1),
|
||||
'parameter_value': str(self.test_er_lni * 100),
|
||||
})],
|
||||
})
|
||||
|
||||
def test_2019_taxes(self):
|
||||
salary = 25000.0
|
||||
|
||||
employee = self._createEmployee()
|
||||
|
||||
contract = self._createContract(employee,
|
||||
wage=salary,
|
||||
state_id=self.get_us_state('WA'),
|
||||
workers_comp_ee_code=self.parameter_lni_ee.code,
|
||||
workers_comp_er_code=self.parameter_lni_er.code,
|
||||
)
|
||||
self._log(str(contract.resource_calendar_id) + ' ' + contract.resource_calendar_id.name)
|
||||
|
||||
|
||||
# tax rates
|
||||
wa_unemp = self.WA_UNEMP_RATE / -100.0
|
||||
|
||||
self._log('2019 Washington tax first payslip:')
|
||||
payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31')
|
||||
hours_in_period = payslip.worked_days_line_ids.filtered(lambda l: l.code == 'WORK100').number_of_hours
|
||||
self.assertEqual(hours_in_period, 184) # only asserted to test algorithm
|
||||
payslip.compute_sheet()
|
||||
|
||||
|
||||
cats = self._getCategories(payslip)
|
||||
rules = self._getRules(payslip)
|
||||
|
||||
self.assertPayrollEqual(cats['ER_US_SUTA'], salary * wa_unemp)
|
||||
self.assertPayrollEqual(rules['EE_US_WA_LNI'], -(self.test_ee_lni * hours_in_period))
|
||||
self.assertPayrollEqual(rules['ER_US_WA_LNI'], -(self.test_er_lni * hours_in_period))
|
||||
# Both of these are known to be within 1 penny
|
||||
self.assertPayrollAlmostEqual(rules['EE_US_WA_FML'], -(salary * (self.WA_FML_RATE / 100.0) * (self.WA_FML_RATE_EE / 100.0)))
|
||||
self.assertPayrollAlmostEqual(rules['ER_US_WA_FML'], -(salary * (self.WA_FML_RATE / 100.0) * (self.WA_FML_RATE_ER / 100.0)))
|
||||
|
||||
# FML
|
||||
|
||||
process_payslip(payslip)
|
||||
|
||||
# Make a new payslip, this one will have maximums
|
||||
|
||||
remaining_wa_unemp_wages = self.WA_UNEMP_MAX_WAGE - salary if (self.WA_UNEMP_MAX_WAGE - 2*salary < salary) \
|
||||
else salary
|
||||
|
||||
self._log('2019 Washington tax second payslip:')
|
||||
payslip = self._createPayslip(employee, '2019-02-01', '2019-02-28')
|
||||
payslip.compute_sheet()
|
||||
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self.assertPayrollEqual(cats['ER_US_SUTA'], remaining_wa_unemp_wages * wa_unemp)
|
||||
90
l10n_us_hr_payroll/tests/test_us_wa_washington_payslip_2020.py
Executable file
90
l10n_us_hr_payroll/tests/test_us_wa_washington_payslip_2020.py
Executable file
@@ -0,0 +1,90 @@
|
||||
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
|
||||
|
||||
from datetime import date
|
||||
from .common import TestUsPayslip, process_payslip
|
||||
|
||||
|
||||
class TestUsWAPayslip(TestUsPayslip):
|
||||
###
|
||||
# Taxes and Rates
|
||||
###
|
||||
WA_UNEMP_MAX_WAGE = 52700.00
|
||||
WA_UNEMP_RATE = 1.0
|
||||
WA_FML_MAX_WAGE = 137700.00
|
||||
WA_FML_RATE = 0.4
|
||||
WA_FML_RATE_EE = 66.33
|
||||
WA_FML_RATE_ER = 33.67
|
||||
|
||||
def setUp(self):
|
||||
super(TestUsWAPayslip, self).setUp()
|
||||
# self.lni = self.env['hr.contract.lni.wa'].create({
|
||||
# 'name': '5302 Computer Consulting',
|
||||
# 'rate': 0.1261,
|
||||
# 'rate_emp_withhold': 0.05575,
|
||||
# })
|
||||
self.test_ee_lni = 0.05575 # per 100 hours
|
||||
self.test_er_lni = 0.1261 # per 100 hours
|
||||
self.parameter_lni_ee = self.env['hr.rule.parameter'].create({
|
||||
'name': 'Test LNI EE',
|
||||
'code': 'test_lni_ee',
|
||||
'parameter_version_ids': [(0, 0, {
|
||||
'date_from': date(2020, 1, 1),
|
||||
'parameter_value': str(self.test_ee_lni * 100),
|
||||
})],
|
||||
})
|
||||
self.parameter_lni_er = self.env['hr.rule.parameter'].create({
|
||||
'name': 'Test LNI ER',
|
||||
'code': 'test_lni_er',
|
||||
'parameter_version_ids': [(0, 0, {
|
||||
'date_from': date(2020, 1, 1),
|
||||
'parameter_value': str(self.test_er_lni * 100),
|
||||
})],
|
||||
})
|
||||
|
||||
def test_2020_taxes(self):
|
||||
self._test_er_suta('WA', self.WA_UNEMP_RATE, date(2020, 1, 1), wage_base=self.WA_UNEMP_MAX_WAGE)
|
||||
|
||||
salary = (self.WA_FML_MAX_WAGE / 2.0) + 1000.0
|
||||
|
||||
employee = self._createEmployee()
|
||||
|
||||
contract = self._createContract(employee,
|
||||
wage=salary,
|
||||
state_id=self.get_us_state('WA'),
|
||||
workers_comp_ee_code=self.parameter_lni_ee.code,
|
||||
workers_comp_er_code=self.parameter_lni_er.code,
|
||||
)
|
||||
self._log(str(contract.resource_calendar_id) + ' ' + contract.resource_calendar_id.name)
|
||||
|
||||
|
||||
# Non SUTA
|
||||
self._log('2020 Washington tax first payslip:')
|
||||
payslip = self._createPayslip(employee, '2020-01-01', '2020-01-31')
|
||||
hours_in_period = payslip.worked_days_line_ids.filtered(lambda l: l.code == 'WORK100').number_of_hours
|
||||
self.assertEqual(hours_in_period, 184) # only asserted to test algorithm
|
||||
payslip.compute_sheet()
|
||||
|
||||
rules = self._getRules(payslip)
|
||||
|
||||
self.assertPayrollEqual(rules['EE_US_WA_LNI'], -(self.test_ee_lni * hours_in_period))
|
||||
self.assertPayrollEqual(rules['ER_US_WA_LNI'], -(self.test_er_lni * hours_in_period))
|
||||
# Both of these are known to be within 1 penny
|
||||
self.assertPayrollAlmostEqual(rules['EE_US_WA_FML'], -(salary * (self.WA_FML_RATE / 100.0) * (self.WA_FML_RATE_EE / 100.0)))
|
||||
self.assertPayrollAlmostEqual(rules['ER_US_WA_FML'], -(salary * (self.WA_FML_RATE / 100.0) * (self.WA_FML_RATE_ER / 100.0)))
|
||||
process_payslip(payslip)
|
||||
|
||||
# Second payslip
|
||||
remaining_wage = self.WA_FML_MAX_WAGE - salary
|
||||
payslip = self._createPayslip(employee, '2020-03-01', '2020-03-31')
|
||||
payslip.compute_sheet()
|
||||
rules = self._getRules(payslip)
|
||||
self.assertPayrollAlmostEqual(rules['EE_US_WA_FML'], -(remaining_wage * (self.WA_FML_RATE / 100.0) * (self.WA_FML_RATE_EE / 100.0)))
|
||||
self.assertPayrollAlmostEqual(rules['ER_US_WA_FML'], -(remaining_wage * (self.WA_FML_RATE / 100.0) * (self.WA_FML_RATE_ER / 100.0)))
|
||||
process_payslip(payslip)
|
||||
|
||||
# Third payslip
|
||||
payslip = self._createPayslip(employee, '2020-04-01', '2020-04-30')
|
||||
payslip.compute_sheet()
|
||||
rules = self._getRules(payslip)
|
||||
self.assertPayrollAlmostEqual(rules['EE_US_WA_FML'], 0.0)
|
||||
self.assertPayrollAlmostEqual(rules['ER_US_WA_FML'], 0.0)
|
||||
39
l10n_us_hr_payroll/tests/test_us_wi_wisconsin_payslip_2020.py
Executable file
39
l10n_us_hr_payroll/tests/test_us_wi_wisconsin_payslip_2020.py
Executable file
@@ -0,0 +1,39 @@
|
||||
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
|
||||
|
||||
from datetime import date, timedelta
|
||||
from .common import TestUsPayslip
|
||||
|
||||
|
||||
class TestUsWIPayslip(TestUsPayslip):
|
||||
###
|
||||
# 2020 Taxes and Rates
|
||||
###
|
||||
WI_UNEMP_MAX_WAGE = 14000.0
|
||||
WI_UNEMP = 3.05
|
||||
# Calculation based on example https://www.revenue.wi.gov/DOR%20Publications/pb166.pdf
|
||||
|
||||
def _test_sit(self, wage, filing_status, exemption, additional_withholding, exempt, schedule_pay, date_start, expected_withholding):
|
||||
employee = self._createEmployee()
|
||||
contract = self._createContract(employee,
|
||||
wage=wage,
|
||||
state_id=self.get_us_state('WI'),
|
||||
wi_wt4_sit_filing_status=filing_status,
|
||||
wi_wt4_sit_exemptions=exemption,
|
||||
state_income_tax_additional_withholding=additional_withholding,
|
||||
state_income_tax_exempt=exempt,
|
||||
schedule_pay=schedule_pay)
|
||||
payslip = self._createPayslip(employee, date_start, date_start + timedelta(days=7))
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self._log('Computed period tax: ' + str(expected_withholding))
|
||||
self.assertPayrollAlmostEqual(cats.get('EE_US_SIT', 0.0), -expected_withholding)
|
||||
|
||||
def test_2020_taxes_example(self):
|
||||
self._test_er_suta('WI', self.WI_UNEMP, date(2020, 1, 1), wage_base=self.WI_UNEMP_MAX_WAGE)
|
||||
self._test_sit(300, 'single', 1, 0, False, 'weekly', date(2020, 1, 1), 7.21)
|
||||
self._test_sit(700, 'married', 3, 0, False, 'bi-weekly', date(2020, 1, 1), 13.35)
|
||||
self._test_sit(7000, 'single', 1, 10, True, 'bi-weekly', date(2020, 1, 1), 0.00)
|
||||
self._test_sit(10000, 'married', 3, 10, False, 'bi-weekly', date(2020, 1, 1), 633.65)
|
||||
# ((48000 - 26227) * (7.0224 /100) + 1073.55 - 44) / 12
|
||||
self._test_sit(4000, 'single', 2, 0, False, 'monthly', date(2020, 1, 1), 213.21)
|
||||
36
l10n_us_hr_payroll/tests/test_us_wv_west_virginia_payslip_2020.py
Executable file
36
l10n_us_hr_payroll/tests/test_us_wv_west_virginia_payslip_2020.py
Executable file
@@ -0,0 +1,36 @@
|
||||
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
|
||||
|
||||
from datetime import date, timedelta
|
||||
from .common import TestUsPayslip
|
||||
|
||||
|
||||
class TestUsWVPayslip(TestUsPayslip):
|
||||
###
|
||||
# 2020 Taxes and Rates
|
||||
###
|
||||
WV_UNEMP_MAX_WAGE = 12000.0
|
||||
WV_UNEMP = 2.7
|
||||
# Calculation based on example https://tax.wv.gov/Documents/TaxForms/it100.1a.pdf
|
||||
|
||||
def _test_sit(self, wage, filing_status, exemption, additional_withholding, schedule_pay, date_start, expected_withholding):
|
||||
employee = self._createEmployee()
|
||||
contract = self._createContract(employee,
|
||||
wage=wage,
|
||||
state_id=self.get_us_state('WV'),
|
||||
wv_it104_sit_filing_status=filing_status,
|
||||
wv_it104_sit_exemptions=exemption,
|
||||
state_income_tax_additional_withholding=additional_withholding,
|
||||
schedule_pay=schedule_pay)
|
||||
payslip = self._createPayslip(employee, date_start, date_start + timedelta(days=7))
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self._log('Computed period tax: ' + str(expected_withholding))
|
||||
self.assertPayrollEqual(cats.get('EE_US_SIT', 0.0), -expected_withholding)
|
||||
|
||||
def test_2020_taxes_example(self):
|
||||
self._test_er_suta('WV', self.WV_UNEMP, date(2020, 1, 1), wage_base=self.WV_UNEMP_MAX_WAGE)
|
||||
self._test_sit(1250, 'married', 2, 0, 'semi-monthly', date(2020, 1, 1), 44.00)
|
||||
self._test_sit(1300, 'single', 1, 0, 'bi-weekly', date(2020, 1, 1), 46.00)
|
||||
self._test_sit(1300, 'single', 1, 10, 'bi-weekly', date(2020, 1, 1), 56.00)
|
||||
self._test_sit(15000, 'single', 2, 0, 'monthly', date(2020, 1, 1), 860.00)
|
||||
58
l10n_us_hr_payroll/tests/test_us_wy_wyoming_payslip_2019.py
Normal file
58
l10n_us_hr_payroll/tests/test_us_wy_wyoming_payslip_2019.py
Normal file
@@ -0,0 +1,58 @@
|
||||
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
|
||||
|
||||
from datetime import date
|
||||
from .common import TestUsPayslip, process_payslip
|
||||
|
||||
|
||||
class TestUsWYPayslip(TestUsPayslip):
|
||||
|
||||
# TAXES AND RATES
|
||||
WY_UNEMP_MAX_WAGE = 25400
|
||||
WY_UNEMP = -2.10 / 100.0
|
||||
|
||||
def test_2019_taxes(self):
|
||||
salary = 15000.00
|
||||
|
||||
employee = self._createEmployee()
|
||||
contract = self._createContract(employee,
|
||||
wage=salary,
|
||||
state_id=self.get_us_state('WY'))
|
||||
|
||||
self._log('2019 Wyoming tax first payslip:')
|
||||
payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31')
|
||||
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self.assertPayrollEqual(cats['ER_US_SUTA'], salary * self.WY_UNEMP)
|
||||
|
||||
process_payslip(payslip)
|
||||
|
||||
# Make a new payslip, this one will have maximums
|
||||
|
||||
remaining_wy_unemp_wages = self.WY_UNEMP_MAX_WAGE - salary if (self.WY_UNEMP_MAX_WAGE - 2*salary < salary) \
|
||||
else salary
|
||||
|
||||
self._log('2019 Wyoming tax second payslip:')
|
||||
payslip = self._createPayslip(employee, '2019-02-01', '2019-02-28')
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self.assertPayrollEqual(cats['ER_US_SUTA'], remaining_wy_unemp_wages * self.WY_UNEMP)
|
||||
|
||||
def test_2019_taxes_with_external(self):
|
||||
# Wage is the cap itself, 25400
|
||||
# so salary is equal to self.WY_UNEMP
|
||||
salary = 25400
|
||||
|
||||
employee = self._createEmployee()
|
||||
contract = self._createContract(employee,
|
||||
wage=salary,
|
||||
state_id=self.get_us_state('WY'))
|
||||
|
||||
self._log('2019 Wyoming External tax first payslip:')
|
||||
payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31')
|
||||
payslip.compute_sheet()
|
||||
cats = self._getCategories(payslip)
|
||||
|
||||
self.assertPayrollEqual(cats['ER_US_SUTA'], salary * self.WY_UNEMP)
|
||||
13
l10n_us_hr_payroll/tests/test_us_wy_wyoming_payslip_2020.py
Normal file
13
l10n_us_hr_payroll/tests/test_us_wy_wyoming_payslip_2020.py
Normal file
@@ -0,0 +1,13 @@
|
||||
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
|
||||
|
||||
from datetime import date
|
||||
from .common import TestUsPayslip
|
||||
|
||||
|
||||
class TestUsWYPayslip(TestUsPayslip):
|
||||
# TAXES AND RATES
|
||||
WY_UNEMP_MAX_WAGE = 26400.00
|
||||
WY_UNEMP = 8.5
|
||||
|
||||
def test_2020_taxes(self):
|
||||
self._test_er_suta('WY', self.WY_UNEMP, date(2020, 1, 1), wage_base=self.WY_UNEMP_MAX_WAGE)
|
||||
Reference in New Issue
Block a user