mirror of
https://gitlab.com/hibou-io/hibou-odoo/suite.git
synced 2025-01-20 12:37:31 +02:00
MN Minnesota
This commit is contained in:
@@ -7,16 +7,12 @@
|
||||
<field name="country_id" ref="base.us"/>
|
||||
</record>
|
||||
<data noupdate="1">
|
||||
<record id="rule_parameter_us_mn_suta_wage_base_2019" model="hr.rule.parameter.value">
|
||||
<field name="parameter_value">34000.0</field>
|
||||
<field name="rule_parameter_id" ref="rule_parameter_us_mn_suta_wage_base"/>
|
||||
<field name="date_from" eval="datetime(2019, 1, 1).date()"/>
|
||||
</record>
|
||||
<record id="rule_parameter_us_mn_suta_wage_base_2020" model="hr.rule.parameter.value">
|
||||
<field name="parameter_value">35000.0</field>
|
||||
<field name="rule_parameter_id" ref="rule_parameter_us_mn_suta_wage_base"/>
|
||||
<field name="date_from" eval="datetime(2020, 1, 1).date()"/>
|
||||
</record>
|
||||
<!-- todo: 2021 base when published -->
|
||||
</data>
|
||||
|
||||
<!-- Rate -->
|
||||
@@ -26,16 +22,12 @@
|
||||
<field name="country_id" ref="base.us"/>
|
||||
</record>
|
||||
<data noupdate="1">
|
||||
<record id="rule_parameter_us_mn_suta_rate_2019" model="hr.rule.parameter.value">
|
||||
<field name="parameter_value">1.11</field>
|
||||
<field name="rule_parameter_id" ref="rule_parameter_us_mn_suta_rate"/>
|
||||
<field name="date_from" eval="datetime(2019, 1, 1).date()"/>
|
||||
</record>
|
||||
<record id="rule_parameter_us_mn_suta_rate_2020" model="hr.rule.parameter.value">
|
||||
<field name="parameter_value">1.11</field>
|
||||
<field name="rule_parameter_id" ref="rule_parameter_us_mn_suta_rate"/>
|
||||
<field name="date_from" eval="datetime(2020, 1, 1).date()"/>
|
||||
</record>
|
||||
<!-- todo: 2021 rates when published -->
|
||||
</data>
|
||||
|
||||
<record id="rule_parameter_us_mn_sit_tax_rate" model="hr.rule.parameter">
|
||||
@@ -44,24 +36,6 @@
|
||||
<field name="country_id" ref="base.us"/>
|
||||
</record>
|
||||
<data noupdate="1">
|
||||
<record id="rule_parameter_us_mn_sit_tax_rate_2019" model="hr.rule.parameter.value">
|
||||
<field name="parameter_value">{
|
||||
'single': (
|
||||
( 28920, 2400, 5.35, 0.00),
|
||||
( 89510, 28920, 7.05, 1418.82),
|
||||
(166290, 89510, 7.85, 5690.42),
|
||||
( 'inf', 166290, 9.85, 11717.65),
|
||||
),
|
||||
'married': (
|
||||
( 47820, 9050, 5.35, 0.00),
|
||||
( 163070, 47820, 7.05, 2074.20),
|
||||
( 282200, 163070, 7.85, 10199.33),
|
||||
( 'inf', 282200, 9.85, 19551.04),
|
||||
),
|
||||
}</field>
|
||||
<field name="rule_parameter_id" ref="rule_parameter_us_mn_sit_tax_rate"/>
|
||||
<field name="date_from" eval="datetime(2019, 1, 1).date()"/>
|
||||
</record>
|
||||
<!-- https://www.revenue.state.mn.us/sites/default/files/2019-12/wh_inst_20_0.pdf -->
|
||||
<!-- Chart for step 5 value -->
|
||||
<record id="rule_parameter_us_mn_sit_tax_rate_2020" model="hr.rule.parameter.value">
|
||||
@@ -82,6 +56,25 @@
|
||||
<field name="rule_parameter_id" ref="rule_parameter_us_mn_sit_tax_rate"/>
|
||||
<field name="date_from" eval="datetime(2020, 1, 1).date()"/>
|
||||
</record>
|
||||
<!-- page 34 https://www.revenue.state.mn.us/sites/default/files/2021-01/wh_inst_21.pdf -->
|
||||
<record id="rule_parameter_us_mn_sit_tax_rate_2021" model="hr.rule.parameter.value">
|
||||
<field name="parameter_value">{
|
||||
'single': (
|
||||
( 31055, 3825, 5.35, 0.00),
|
||||
( 93265, 31055, 6.80, 1418.82),
|
||||
(169865, 93265, 7.85, 5687.09),
|
||||
( 'inf', 169865, 9.85, 11700.19),
|
||||
),
|
||||
'married': (
|
||||
( 51810, 12000, 5.35, 0.00),
|
||||
( 170140, 51810, 6.80, 2129.84),
|
||||
( 288200, 170140, 7.85, 10176.28),
|
||||
( 'inf', 288200, 9.85, 19443.99),
|
||||
),
|
||||
}</field>
|
||||
<field name="rule_parameter_id" ref="rule_parameter_us_mn_sit_tax_rate"/>
|
||||
<field name="date_from" eval="datetime(2021, 1, 1).date()"/>
|
||||
</record>
|
||||
</data>
|
||||
|
||||
<record id="rule_parameter_us_mn_sit_allowances_rate" model="hr.rule.parameter">
|
||||
@@ -90,11 +83,6 @@
|
||||
<field name="country_id" ref="base.us"/>
|
||||
</record>
|
||||
<data noupdate="1">
|
||||
<record id="rule_parameter_us_mn_sit_allowances_rate_2019" model="hr.rule.parameter.value">
|
||||
<field name="parameter_value">4250.0</field>
|
||||
<field name="rule_parameter_id" ref="rule_parameter_us_mn_sit_allowances_rate"/>
|
||||
<field name="date_from" eval="datetime(2019, 1, 1).date()"/>
|
||||
</record>
|
||||
<!-- https://www.revenue.state.mn.us/sites/default/files/2019-12/wh_inst_20_0.pdf -->
|
||||
<!-- Step 3. -->
|
||||
<record id="rule_parameter_us_mn_sit_allowances_rate_2020" model="hr.rule.parameter.value">
|
||||
@@ -102,6 +90,12 @@
|
||||
<field name="rule_parameter_id" ref="rule_parameter_us_mn_sit_allowances_rate"/>
|
||||
<field name="date_from" eval="datetime(2020, 1, 1).date()"/>
|
||||
</record>
|
||||
<!-- page 34 step 3 https://www.revenue.state.mn.us/sites/default/files/2021-01/wh_inst_21.pdf -->
|
||||
<record id="rule_parameter_us_mn_sit_allowances_rate_2021" model="hr.rule.parameter.value">
|
||||
<field name="parameter_value">4350.0</field>
|
||||
<field name="rule_parameter_id" ref="rule_parameter_us_mn_sit_allowances_rate"/>
|
||||
<field name="date_from" eval="datetime(2021, 1, 1).date()"/>
|
||||
</record>
|
||||
</data>
|
||||
|
||||
<!-- Partners and Contribution Registers -->
|
||||
|
||||
@@ -1,159 +0,0 @@
|
||||
# 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_2021.py
Executable file
36
l10n_us_hr_payroll/tests/test_us_mn_minnesota_payslip_2021.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_2021_taxes_example(self):
|
||||
self._test_er_suta('MN', self.MN_UNEMP, date(2021, 1, 1), wage_base=self.MN_UNEMP_MAX_WAGE)
|
||||
self._test_sit(5000.0, 'single', 1.0, 0.0, 'weekly', date(2021, 1, 1), 388.0)
|
||||
self._test_sit(30000.0, 'single', 1.0, 0.0, 'weekly', date(2021, 1, 1), 2850.0)
|
||||
self._test_sit(5000.0, 'married', 1.0, 0.0, 'weekly', date(2021, 1, 1), 325.0)
|
||||
self._test_sit(6500.0, 'single', 1.0, 0.0, 'semi-monthly', date(2021, 1, 1), 428.0)
|
||||
self._test_sit(5500.0, '', 2.0, 0.0, 'weekly', date(2021, 1, 1), 0.0)
|
||||
self._test_sit(5500.0, 'single', 2.0, 40.0, 'weekly', date(2021, 1, 1), 469.0)
|
||||
Reference in New Issue
Block a user