Update l10n_us_hr_payroll for 2019 Federal Rates and Limits.

This commit is contained in:
Jared Kipe
2019-01-06 17:06:37 -08:00
parent f5a01c485d
commit 52751a3dad
19 changed files with 1642 additions and 2729 deletions

View File

@@ -37,6 +37,39 @@ USA Employee added to Contract Salary Structure Menu
:width: 988
:align: left
Upgrading to 2019
==========================
If you were using this prior to January 2019, then you will need to run the following
migration script.
Odoo Shell code::
def migrate_rule_name(rule_id):
main = env.ref(rule_id)
old_2017 = env.ref(rule_id.replace('2018', '2017'))
old_2016 = env.ref(rule_id.replace('2018', '2016'))
lines = env['hr.payslip.line'].search([('salary_rule_id', 'in', [old_2017.id, old_2016.id,])])
lines.write({'salary_rule_id': main.id})
rules = [
'l10n_us_hr_payroll.hr_payroll_rules_fica_emp_ss_wages_2018',
'l10n_us_hr_payroll.hr_payroll_rules_fica_emp_m_wages_2018',
'l10n_us_hr_payroll.hr_payroll_rules_fica_emp_m_add_wages_2018',
'l10n_us_hr_payroll.hr_payroll_rules_fica_emp_ss_2018',
'l10n_us_hr_payroll.hr_payroll_rules_fica_emp_m_2018',
'l10n_us_hr_payroll.hr_payroll_rules_fica_emp_m_add_2018',
'l10n_us_hr_payroll.hr_payroll_rules_fed_inc_withhold_2018_single',
'l10n_us_hr_payroll.hr_payroll_rules_fed_inc_withhold_2018_married',
'l10n_us_hr_payroll.hr_payroll_rules_futa_wages_2018',
'l10n_us_hr_payroll.hr_payroll_rules_futa_2018',
]
for rule_id in rules:
migrate_rule_name(rule_id)
env.cr.commit()
=======
License
=======

View File

@@ -1,3 +1,3 @@
# -*- coding: utf-8 -*-
from . import l10n_us_hr_payroll
from . import models

View File

@@ -4,7 +4,7 @@
'author': 'Hibou Corp. <hello@hibou.io>',
'license': 'AGPL-3',
'category': 'Localization',
'depends': ['hr_payroll'],
'depends': ['hr_payroll', 'hr_payroll_rate'],
'version': '11.0.2018.1.0',
'description': """
USA Payroll Rules.
@@ -21,11 +21,10 @@ USA Payroll Rules.
'auto_install': False,
'website': 'https://hibou.io/',
'data': [
'l10n_us_hr_payroll_view.xml',
'views/l10n_us_hr_payroll_view.xml',
'data/base.xml',
'data/rules_2016.xml',
'data/rules_2017.xml',
'data/rules_2018.xml',
'data/rates.xml',
'data/rules.xml',
'data/final.xml',
],
'installable': True

View File

@@ -26,111 +26,58 @@
<!-- HR SALARY RULE CATEGORIES-->
<record id="hr_payroll_fica_emp_ss_wages" model="hr.salary.rule.category">
<field name="name">FICA Employee Social Security - Wages</field>
<field name="code">FICA_EMP_SS_WAGES</field>
<field name="name">Wage: US FICA Social Security</field>
<field name="code">WAGE_US_FICA_SS</field>
</record>
<record id="hr_payroll_fica_emp_m_wages" model="hr.salary.rule.category">
<field name="name">FICA Employee Medicare - Wages</field>
<field name="code">FICA_EMP_M_WAGES</field>
<field name="name">Wage: US FICA Medicare</field>
<field name="code">WAGE_US_FICA_M</field>
</record>
<record id="hr_payroll_fica_emp_m_add_wages" model="hr.salary.rule.category">
<field name="name">FICA Employee Medicare Additional - Wages</field>
<field name="code">FICA_EMP_M_ADD_WAGES</field>
<field name="name">Wage: US FICA Medicare Additional</field>
<field name="code">WAGE_US_FICA_M_ADD</field>
</record>
<record id="hr_payroll_futa_wages" model="hr.salary.rule.category">
<field name="name">FUTA Federal Unemployment - Wages</field>
<field name="code">FUTA_WAGES</field>
<field name="name">Wage: US FUTA Federal Unemployment</field>
<field name="code">WAGE_US_FUTA</field>
</record>
<record id="hr_payroll_fica_emp_ss" model="hr.salary.rule.category">
<field name="name">FICA Employee Social Security</field>
<field name="code">FICA_EMP_SS</field>
<field name="name">EE: US FICA Social Security</field>
<field name="code">EE_US_FICA_SS</field>
<field name="parent_id" ref="hr_payroll.DED"/>
</record>
<record id="hr_payroll_fica_emp_m" model="hr.salary.rule.category">
<field name="name">FICA Employee Medicare</field>
<field name="code">FICA_EMP_M</field>
<field name="name">EE: US FICA Medicare</field>
<field name="code">EE_US_FICA_M</field>
<field name="parent_id" ref="hr_payroll.DED"/>
</record>
<record id="hr_payroll_fica_emp_m_add" model="hr.salary.rule.category">
<field name="name">FICA Employee Medicare Additional</field>
<field name="code">FICA_EMP_M_ADD</field>
<field name="name">EE: US FICA Medicare Additional</field>
<field name="code">EE_US_FICA_M_ADD</field>
<field name="parent_id" ref="hr_payroll.DED"/>
</record>
<record id="hr_payroll_fed_income_withhold" model="hr.salary.rule.category">
<field name="name">Federal Income Withholding</field>
<field name="code">FED_INC_WITHHOLD</field>
<field name="name">EE: US Federal Income Tax Withholding</field>
<field name="code">EE_US_FED_INC_WITHHOLD</field>
<field name="parent_id" ref="hr_payroll.DED"/>
</record>
<record id="hr_payroll_fica_comp_ss" model="hr.salary.rule.category">
<field name="name">FICA Company Social Security</field>
<field name="code">FICA_COMP_SS</field>
<field name="name">ER: US FICA Social Security</field>
<field name="code">ER_US_FICA_SS</field>
<field name="parent_id" ref="hr_payroll.COMP"/>
</record>
<record id="hr_payroll_fica_comp_m" model="hr.salary.rule.category">
<field name="name">FICA Company Medicare</field>
<field name="code">FICA_COMP_M</field>
<field name="name">ER: US FICA Medicare</field>
<field name="code">ER_US_FICA_M</field>
<field name="parent_id" ref="hr_payroll.COMP"/>
</record>
<record id="hr_payroll_futa" model="hr.salary.rule.category">
<field name="name">FUTA Federal Unemployment</field>
<field name="code">FUTA</field>
<field name="name">ER: US FUTA Federal Unemployment</field>
<field name="code">ER_US_FUTA</field>
<field name="parent_id" ref="hr_payroll.COMP"/>
</record>
<!-- HR SALARY RULES-->
<!-- Employee Deductions and Calculations -->
<!-- Company Contributions -->
<record id="hr_payroll_rules_fica_comp_ss" model="hr.salary.rule">
<field name="sequence" eval="440"/>
<field name="category_id" ref="hr_payroll_fica_comp_ss"/>
<field name="name">FICA Company Social Security</field>
<field name="code">FICA_COMP_SS</field>
<field name="condition_select">none</field>
<field name="amount_select">code</field>
<field name="amount_python_compute">result = categories.FICA_EMP_SS</field>
<field name="register_id" ref="contrib_register_eftps_941"/>
<field name="appears_on_payslip" eval="False"/>
</record>
<record id="hr_payroll_rules_fica_comp_m" model="hr.salary.rule">
<field name="sequence" eval="441"/>
<field name="category_id" ref="hr_payroll_fica_comp_m"/>
<field name="name">FICA Company Medicare</field>
<field name="code">FICA_COMP_M</field>
<field name="condition_select">none</field>
<field name="amount_select">code</field>
<field name="amount_python_compute">result = categories.FICA_EMP_M</field>
<field name="register_id" ref="contrib_register_eftps_941"/>
<field name="appears_on_payslip" eval="False"/>
</record>
<!-- Salary Rules -->
<!-- Company Contributions -->
<record id="hr_payroll_rules_fica_comp_ss" model="hr.salary.rule">
<field name="sequence" eval="440"/>
<field name="category_id" ref="hr_payroll_fica_comp_ss"/>
<field name="name">FICA Company Social Security</field>
<field name="code">FICA_COMP_SS</field>
<field name="condition_select">none</field>
<field name="amount_select">code</field>
<field name="amount_python_compute">result = categories.FICA_EMP_SS</field>
<field name="register_id" ref="contrib_register_eftps_941"/>
<field name="appears_on_payslip" eval="False"/>
</record>
<record id="hr_payroll_rules_fica_comp_m" model="hr.salary.rule">
<field name="sequence" eval="441"/>
<field name="category_id" ref="hr_payroll_fica_comp_m"/>
<field name="name">FICA Company Medicare</field>
<field name="code">FICA_COMP_M</field>
<field name="condition_select">none</field>
<field name="amount_select">code</field>
<field name="amount_python_compute">result = categories.FICA_EMP_M</field>
<field name="register_id" ref="contrib_register_eftps_941"/>
<field name="appears_on_payslip" eval="False"/>
</record>
</data>
</odoo>

View File

@@ -10,28 +10,6 @@
ref('hr_payroll_rules_fica_comp_ss'),
ref('hr_payroll_rules_fica_comp_m'),
ref('hr_payroll_rules_fica_emp_ss_wages_2016'),
ref('hr_payroll_rules_fica_emp_m_wages_2016'),
ref('hr_payroll_rules_fica_emp_m_add_wages_2016'),
ref('hr_payroll_rules_fica_emp_ss_2016'),
ref('hr_payroll_rules_fica_emp_m_2016'),
ref('hr_payroll_rules_fica_emp_m_add_2016'),
ref('hr_payroll_rules_futa_wages_2016'),
ref('hr_payroll_rules_futa_2016'),
ref('hr_payroll_rules_fed_inc_withhold_2016_single'),
ref('hr_payroll_rules_fed_inc_withhold_2016_married'),
ref('hr_payroll_rules_fica_emp_ss_wages_2017'),
ref('hr_payroll_rules_fica_emp_m_wages_2017'),
ref('hr_payroll_rules_fica_emp_m_add_wages_2017'),
ref('hr_payroll_rules_fica_emp_ss_2017'),
ref('hr_payroll_rules_fica_emp_m_2017'),
ref('hr_payroll_rules_fica_emp_m_add_2017'),
ref('hr_payroll_rules_futa_wages_2017'),
ref('hr_payroll_rules_futa_2017'),
ref('hr_payroll_rules_fed_inc_withhold_2017_single'),
ref('hr_payroll_rules_fed_inc_withhold_2017_married'),
ref('hr_payroll_rules_fica_emp_ss_wages_2018'),
ref('hr_payroll_rules_fica_emp_m_wages_2018'),
ref('hr_payroll_rules_fica_emp_m_add_wages_2018'),

View File

@@ -0,0 +1,68 @@
<?xml version="1.0" encoding="UTF-8" ?>
<odoo>
<!-- FUTA -->
<record id="hr_payroll_rates_futa_exempt" model="hr.payroll.rate">
<field name="name">US FUTA Exempt</field>
<field name="code">US_FUTA_EXEMPT</field>
<field name="rate">0.0</field>
<field name="date_from">2016-01-01</field>
<field name="wage_limit_year" eval="7000"/>
</record>
<record id="hr_payroll_rates_futa_normal" model="hr.payroll.rate">
<field name="name">US FUTA Normal</field>
<field name="code">US_FUTA_NORMAL</field>
<field name="rate">0.6</field>
<field name="date_from">2016-01-01</field>
<field name="wage_limit_year" eval="7000"/>
</record>
<record id="hr_payroll_rates_futa_basic" model="hr.payroll.rate">
<field name="name">US FUTA Basic</field>
<field name="code">US_FUTA_BASIC</field>
<field name="rate">6.0</field>
<field name="date_from">2016-01-01</field>
<field name="wage_limit_year" eval="7000"/>
</record>
<!-- FICA -->
<!-- Social Security -->
<record id="hr_payroll_rates_fica_ss_old" model="hr.payroll.rate">
<field name="name">US FICA Social Security</field>
<field name="code">US_FICA_SS</field>
<field name="rate">6.2</field>
<field name="date_from">2016-01-01</field>
<field name="date_to">2017-12-31</field>
<field name="wage_limit_year" eval="128400.0"/>
</record>
<record id="hr_payroll_rates_fica_ss_2018" model="hr.payroll.rate">
<field name="name">US FICA Social Security</field>
<field name="code">US_FICA_SS</field>
<field name="rate">6.2</field>
<field name="date_from">2018-01-01</field>
<field name="date_to">2018-12-31</field>
<field name="wage_limit_year" eval="128400.0"/>
</record>
<record id="hr_payroll_rates_fica_ss_2019" model="hr.payroll.rate">
<field name="name">US FICA Social Security</field>
<field name="code">US_FICA_SS</field>
<field name="rate">6.2</field>
<field name="date_from">2019-01-01</field>
<field name="date_to">2019-12-31</field>
<field name="wage_limit_year" eval="132900.0"/>
</record>
<!-- Medicare -->
<record id="hr_payroll_rates_fica_m" model="hr.payroll.rate">
<field name="name">US FICA Medicare</field>
<field name="code">US_FICA_M</field>
<field name="rate">1.45</field>
<field name="date_from">2016-01-01</field>
</record>
<!-- Medicare Additional -->
<record id="hr_payroll_rates_fica_m_add" model="hr.payroll.rate">
<field name="name">US FICA Medicare Additional</field>
<field name="code">US_FICA_M_ADD</field>
<field name="rate">0.9</field>
<field name="date_from">2016-01-01</field>
<field name="wage_limit_year">200000.0</field>
</record>
</odoo>

1058
l10n_us_hr_payroll/data/rules.xml Executable file

File diff suppressed because it is too large Load Diff

View File

@@ -1,604 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data>
<!-- HR SALARY RULES-->
<!-- Employee Deductions and Calculations -->
<record id="hr_payroll_rules_fica_emp_ss_wages_2016" model="hr.salary.rule">
<field name="sequence" eval="120"/>
<field name="category_id" ref="hr_payroll_fica_emp_ss_wages"/>
<field name="name">FICA Employee Social Security Wages (2016)</field>
<field name="code">FICA_EMP_SS_WAGES_2016</field>
<field name="condition_select">python</field>
<field name="condition_python">result = (payslip.date_to[:4] == '2016')</field>
<field name="amount_select">code</field>
<field name="amount_python_compute">
###
ytd = payslip.sum('FICA_EMP_SS_WAGES_2016', '2016-01-01', '2017-01-01')
ytd += contract.external_wages
remaining = 118500.0 - ytd
if remaining &lt;= 0.0:
result = 0
elif remaining &lt; categories.GROSS:
result = remaining
else:
result = categories.GROSS
</field>
<field name="appears_on_payslip" eval="False"/>
</record>
<record id="hr_payroll_rules_fica_emp_m_wages_2016" model="hr.salary.rule">
<field name="sequence" eval="121"/>
<field name="category_id" ref="hr_payroll_fica_emp_m_wages"/>
<field name="name">FICA Employee Medicare Wages (2016)</field>
<field name="code">FICA_EMP_M_WAGES_2016</field>
<field name="condition_select">python</field>
<field name="condition_python">result = (payslip.date_to[:4] == '2016')</field>
<field name="amount_select">code</field>
<field name="amount_python_compute">result = categories.GROSS</field>
<field name="appears_on_payslip" eval="False"/>
</record>
<record id="hr_payroll_rules_fica_emp_m_add_wages_2016" model="hr.salary.rule">
<field name="sequence" eval="122"/>
<field name="category_id" ref="hr_payroll_fica_emp_m_add_wages"/>
<field name="name">FICA Employee Medicare Additional Wages (2016)</field>
<field name="code">FICA_EMP_M_ADD_WAGES_2016</field>
<field name="condition_select">python</field>
<field name="condition_python">result = (payslip.date_to[:4] == '2016')</field>
<field name="amount_select">code</field>
<field name="amount_python_compute">
###
ADD_M = 200000.0
norm_med_ytd = payslip.sum('FICA_EMP_M_WAGES_2016', '2016-01-01', '2017-01-01')
norm_med_cur = categories.FICA_EMP_M_WAGES
if ADD_M &gt; norm_med_ytd:
diff = ADD_M - norm_med_ytd
if norm_med_cur &gt; diff:
result = norm_med_cur - diff
else:
result = 0 # normal condition
else:
result = norm_med_cur # after YTD wages have passed the max
</field>
<field name="appears_on_payslip" eval="False"/>
</record>
<record id="hr_payroll_rules_fica_emp_ss_2016" model="hr.salary.rule">
<field name="sequence" eval="140"/>
<field name="category_id" ref="hr_payroll_fica_emp_ss"/>
<field name="name">FICA Employee Social Security (2016)</field>
<field name="code">FICA_EMP_SS_2016</field>
<field name="condition_select">python</field>
<field name="condition_python">result = (payslip.date_to[:4] == '2016')</field>
<field name="amount_select">code</field>
<field name="amount_python_compute">
### this should be "rules.FICA_EMP_SS_WAGES_2016", but it doesn't work
result_rate = -6.2
result = categories.FICA_EMP_SS_WAGES
</field>
<field name="register_id" ref="contrib_register_eftps_941"/>
</record>
<record id="hr_payroll_rules_fica_emp_m_2016" model="hr.salary.rule">
<field name="sequence" eval="141"/>
<field name="category_id" ref="hr_payroll_fica_emp_m"/>
<field name="name">FICA Employee Medicare (2016)</field>
<field name="code">FICA_EMP_M_2016</field>
<field name="condition_select">python</field>
<field name="condition_python">result = (payslip.date_to[:4] == '2016')</field>
<field name="amount_select">code</field>
<field name="amount_python_compute">
### this should be "rules.FICA_EMP_M_WAGES_2016", but it doesn't work
result_rate = -1.45
result = categories.FICA_EMP_M_WAGES
</field>
<field name="register_id" ref="contrib_register_eftps_941"/>
</record>
<record id="hr_payroll_rules_fica_emp_m_add_2016" model="hr.salary.rule">
<field name="sequence" eval="142"/>
<field name="category_id" ref="hr_payroll_fica_emp_m_add"/>
<field name="name">FICA Employee Medicare Additional (2016)</field>
<field name="code">FICA_EMP_M_ADD_2016</field>
<field name="condition_select">python</field>
<field name="condition_python">result = (payslip.date_to[:4] == '2016')</field>
<field name="amount_select">code</field>
<field name="amount_python_compute">
### this should be "rules.FICA_EMP_M_ADD_WAGES_2016", but it doesn't work
result_rate = -0.9
result = categories.FICA_EMP_M_ADD_WAGES
</field>
<field name="register_id" ref="contrib_register_eftps_941"/>
</record>
<!-- Federal Income Tax Withholding -->
<record id="hr_payroll_rules_fed_inc_withhold_2016_single" model="hr.salary.rule">
<field name="sequence" eval="145"/>
<field name="category_id" ref="hr_payroll_fed_income_withhold"/>
<field name="name">Federal Income Withholding - Single (2016)</field>
<field name="code">FED_INC_WITHHOLD_2016_S</field>
<field name="condition_select">python</field>
<field name="condition_python">result = (payslip.date_to[:4] == '2016' and contract.w4_filing_status != 'married' and contract.w4_filing_status)</field>
<field name="amount_select">code</field>
<field name="amount_python_compute">
wages = categories.GROSS
allowances = contract.w4_allowances
is_nra = contract.w4_is_nonresident_alien
schedule_pay = contract.schedule_pay
val = 0.00
additional = contract.w4_additional_withholding
###
# Single WEEKLY
###
if 'weekly' == schedule_pay:
wages -= allowances * 77.90
if is_nra:
wages += 43.30
if wages &gt; 43 and wages &lt;= 222:
val = 0.00 + ((wages - 43) * 0.10)
elif wages &gt; 222 and wages &lt;= 767:
val = 17.90 + ((wages - 222) * 0.15)
elif wages &gt; 767 and wages &lt;= 1796:
val = 99.65 + ((wages - 767) * 0.25)
elif wages &gt; 1796 and wages &lt;= 3700:
val = 356.90 + ((wages - 1796) * 0.28)
elif wages &gt; 3700 and wages &lt;= 7992:
val = 890.02 + ((wages - 3700) * 0.33)
elif wages &gt; 7992 and wages &lt;= 8025:
val = 2306.38 + ((wages - 7992) * 0.35)
elif wages &gt; 8025:
val = 2317.93 + ((wages - 8025) * 0.396)
###
# Single BIWEEKLY
###
elif 'bi-weekly' == schedule_pay:
wages -= allowances * 155.80
if is_nra:
wages += 86.50
if wages &gt; 87 and wages &lt;= 443:
val = 0.00 + ((wages - 87) * 0.10)
elif wages &gt; 443 and wages &lt;= 1535:
val = 35.60 + ((wages - 443) * 0.15)
elif wages &gt; 1535 and wages &lt;= 3592:
val = 199.40 + ((wages - 1535) * 0.25)
elif wages &gt; 3592 and wages &lt;= 7400:
val = 713.65 + ((wages - 3592) * 0.28)
elif wages &gt; 7400 and wages &lt;= 15985:
val = 1779.89 + ((wages - 7400) * 0.33)
elif wages &gt; 15985 and wages &lt;= 16050:
val = 4612.94 + ((wages - 15985) * 0.35)
elif wages &gt; 16050:
val = 4635.69 + ((wages - 16050) * 0.396)
###
# Single SEMIMONTHLY
###
elif 'semi-monthly' == schedule_pay:
wages -= allowances * 168.80
if is_nra:
wages += 93.80
if wages &gt; 94 and wages &lt;= 480:
val = 0.00 + ((wages - 94) * 0.10)
elif wages &gt; 480 and wages &lt;= 1663:
val = 38.60 + ((wages - 480) * 0.15)
elif wages &gt; 1663 and wages &lt;= 3892:
val = 216.05 + ((wages - 1663) * 0.25)
elif wages &gt; 3892 and wages &lt;= 8017:
val = 773.30 + ((wages - 3892) * 0.28)
elif wages &gt; 8017 and wages &lt;= 17317:
val = 1928.30 + ((wages - 8017) * 0.33)
elif wages &gt; 17317 and wages &lt;= 17388:
val = 4997.30 + ((wages - 17317) * 0.35)
elif wages &gt; 17388:
val = 5022.15 + ((wages - 17388) * 0.396)
###
# Single MONTHLY
###
elif 'monthly' == schedule_pay:
wages -= allowances * 337.50
if is_nra:
wages += 187.50
if wages &gt; 188 and wages &lt;= 960:
val = 0.00 + ((wages - 188) * 0.10)
elif wages &gt; 960 and wages &lt;= 3325:
val = 77.20 + ((wages - 960) * 0.15)
elif wages &gt; 3325 and wages &lt;= 7783:
val = 431.95 + ((wages - 3325) * 0.25)
elif wages &gt; 7783 and wages &lt;= 16033:
val = 1546.45 + ((wages - 7783) * 0.28)
elif wages &gt; 16033 and wages &lt;= 34633:
val = 3856.45 + ((wages - 16033) * 0.33)
elif wages &gt; 34633 and wages &lt;= 34775:
val = 9994.45 + ((wages - 34633) * 0.35)
elif wages &gt; 34775:
val = 10044.15 + ((wages - 34775) * 0.396)
###
# Single QUARTERLY
###
elif 'quarterly' == schedule_pay:
wages -= allowances * 1012.50
if is_nra:
wages += 562.50
if wages &gt; 563 and wages &lt;= 2881:
val = 0.00 + ((wages - 563) * 0.10)
elif wages &gt; 2881 and wages &lt;= 9975:
val = 231.80 + ((wages - 2881) * 0.15)
elif wages &gt; 9975 and wages &lt;= 23350:
val = 1295.90 + ((wages - 9975) * 0.25)
elif wages &gt; 23350 and wages &lt;= 48100:
val = 4639.65 + ((wages - 23350) * 0.28)
elif wages &gt; 48100 and wages &lt;= 103900:
val = 11569.65 + ((wages - 48100) * 0.33)
elif wages &gt; 103900 and wages &lt;= 104325:
val = 29983.65 + ((wages - 103900) * 0.35)
elif wages &gt; 104325:
val = 30132.40 + ((wages - 104325) * 0.396)
###
# Single SEMIANNUAL
###
elif 'semi-annually' == schedule_pay:
wages -= allowances * 2025.00
if is_nra:
wages += 1125.0
if wages &gt; 1125 and wages &lt;= 5763:
val = 0.00 + ((wages - 1125) * 0.10)
elif wages &gt; 5763 and wages &lt;= 19950:
val = 463.80 + ((wages - 5763) * 0.15)
elif wages &gt; 19950 and wages &lt;= 46700:
val = 2591.85 + ((wages - 19950) * 0.25)
elif wages &gt; 46700 and wages &lt;= 96200:
val = 9279.35 + ((wages - 46700) * 0.28)
elif wages &gt; 96200 and wages &lt;= 207800:
val = 23139.35 + ((wages - 96200) * 0.33)
elif wages &gt; 207800 and wages &lt;= 208650:
val = 59967.35 + ((wages - 207800) * 0.35)
elif wages &gt; 208650:
val = 60264.85 + ((wages - 208650) * 0.396)
###
# Single ANNUAL
###
elif 'annually' == schedule_pay:
wages -= allowances * 4050.00
if is_nra:
wages += 2250.0
if wages &gt; 2250 and wages &lt;= 11525:
val = 0.00 + ((wages - 2250) * 0.10)
elif wages &gt; 11525 and wages &lt;= 39900:
val = 927.50 + ((wages - 11525) * 0.15)
elif wages &gt; 39900 and wages &lt;= 93400:
val = 5183.75 + ((wages - 39900) * 0.25)
elif wages &gt; 93400 and wages &lt;= 192400:
val = 18558.75 + ((wages - 93400) * 0.28)
elif wages &gt; 192400 and wages &lt;= 415600:
val = 46278.75 + ((wages - 192400) * 0.33)
elif wages &gt; 415600 and wages &lt;= 417300:
val = 119934.75 + ((wages - 415600) * 0.35)
elif wages &gt; 417300:
val = 120529.75 + ((wages - 417300) * 0.396)
else:
raise Exception('Invalid schedule_pay="' + schedule_pay + '" for W4 Allowance calculation')
result = -(val + additional)
</field>
<field name="register_id" ref="contrib_register_eftps_941"/>
</record>
<record id="hr_payroll_rules_fed_inc_withhold_2016_married" model="hr.salary.rule">
<field name="sequence" eval="145"/>
<field name="category_id" ref="hr_payroll_fed_income_withhold"/>
<field name="name">Federal Income Withholding - Married (2016)</field>
<field name="code">FED_INC_WITHHOLD_2016_M</field>
<field name="condition_select">python</field>
<field name="condition_python">result = (payslip.date_to[:4] == '2016' and contract.w4_filing_status == 'married')</field>
<field name="amount_select">code</field>
<field name="amount_python_compute">
wages = categories.GROSS
allowances = contract.w4_allowances
is_nra = contract.w4_is_nonresident_alien
schedule_pay = contract.schedule_pay
val = 0.00
additional = contract.w4_additional_withholding
###
# Married WEEKLY
###
if 'weekly' == schedule_pay:
wages -= allowances * 77.90
if is_nra:
wages += 43.30
if wages &gt; 164 and wages &lt;= 521:
val = 0.00 + ((wages - 164) * 0.10)
elif wages &gt; 521 and wages &lt;= 1613:
val = 35.70 + ((wages - 521) * 0.15)
elif wages &gt; 1613 and wages &lt;= 3086:
val = 199.50 + ((wages - 1613) * 0.25)
elif wages &gt; 3086 and wages &lt;= 4615:
val = 567.75 + ((wages - 3086) * 0.28)
elif wages &gt; 4615 and wages &lt;= 8113:
val = 995.87 + ((wages - 4615) * 0.33)
elif wages &gt; 8113 and wages &lt;= 9144:
val = 2150.21 + ((wages - 8113) * 0.35)
elif wages &gt; 9144:
val = 2511.06 + ((wages - 9144) * 0.396)
###
# Married BIWEEKLY
###
elif 'bi-weekly' == schedule_pay:
wages -= allowances * 155.80
if is_nra:
wages += 86.50
if wages &gt; 329 and wages &lt;= 1042:
val = 0.00 + ((wages - 329) * 0.10)
elif wages &gt; 1042 and wages &lt;= 3225:
val = 71.30 + ((wages - 1042) * 0.15)
elif wages &gt; 3225 and wages &lt;= 6171:
val = 398.75 + ((wages - 3225) * 0.25)
elif wages &gt; 6171 and wages &lt;= 9231:
val = 1135.25 + ((wages - 6171) * 0.28)
elif wages &gt; 9231 and wages &lt;= 16227:
val = 1992.05 + ((wages - 9231) * 0.33)
elif wages &gt; 16227 and wages &lt;= 18288:
val = 4300.73 + ((wages - 16227) * 0.35)
elif wages &gt; 18288:
val = 5022.08 + ((wages - 18288) * 0.396)
###
# Married SEMIMONTHLY
###
elif 'semi-monthly' == schedule_pay:
wages -= allowances * 168.80
if is_nra:
wages += 93.80
if wages &gt; 356 and wages &lt;= 1129:
val = 0.00 + ((wages - 356) * 0.10)
elif wages &gt; 1129 and wages &lt;= 3494:
val = 77.30 + ((wages - 1129) * 0.15)
elif wages &gt; 3494 and wages &lt;= 6685:
val = 432.05 + ((wages - 3494) * 0.25)
elif wages &gt; 6685 and wages &lt;= 10000:
val = 1229.80 + ((wages - 6685) * 0.28)
elif wages &gt; 10000 and wages &lt;= 17579:
val = 2158.00 + ((wages - 10000) * 0.33)
elif wages &gt; 17579 and wages &lt;= 19813:
val = 4659.07 + ((wages - 17579) * 0.35)
elif wages &gt; 19813:
val = 5440.97 + ((wages - 19813) * 0.396)
###
# Married MONTHLY
###
elif 'monthly' == schedule_pay:
wages -= allowances * 337.50
if is_nra:
wages += 187.50
if wages &gt; 713 and wages &lt;= 2258:
val = 0.00 + ((wages - 713) * 0.10)
elif wages &gt; 2258 and wages &lt;= 6988:
val = 154.50 + ((wages - 2258) * 0.15)
elif wages &gt; 6988 and wages &lt;= 13371:
val = 864.00 + ((wages - 6988) * 0.25)
elif wages &gt; 13371 and wages &lt;= 20000:
val = 2459.75 + ((wages - 13371) * 0.28)
elif wages &gt; 20000 and wages &lt;= 35158:
val = 4315.87 + ((wages - 20000) * 0.33)
elif wages &gt; 35158 and wages &lt;= 39625:
val = 9318.01 + ((wages - 35158) * 0.35)
elif wages &gt; 39625:
val = 10881.46 + ((wages - 39625) * 0.396)
###
# Married QUARTERLY
###
elif 'quarterly' == schedule_pay:
wages -= allowances * 1012.50
if is_nra:
wages += 562.50
if wages &gt; 2138 and wages &lt;= 6775:
val = 0.00 + ((wages - 2138) * 0.10)
elif wages &gt; 6775 and wages &lt;= 20963:
val = 463.70 + ((wages - 6775) * 0.15)
elif wages &gt; 20963 and wages &lt;= 40113:
val = 2591.90 + ((wages - 20963) * 0.25)
elif wages &gt; 40113 and wages &lt;= 60000:
val = 7379.40 + ((wages - 40113) * 0.28)
elif wages &gt; 60000 and wages &lt;= 105475:
val = 12947.76 + ((wages - 60000) * 0.33)
elif wages &gt; 105475 and wages &lt;= 118875:
val = 27954.51 + ((wages - 105475) * 0.35)
elif wages &gt; 118875:
val = 32644.51 + ((wages - 118875) * 0.396)
###
# Married SEMIANNUAL
###
elif 'semi-annually' == schedule_pay:
wages -= allowances * 2025.00
if is_nra:
wages += 1125.0
if wages &gt; 4275 and wages &lt;= 13550:
val = 0.00 + ((wages - 4275) * 0.10)
elif wages &gt; 13550 and wages &lt;= 41925:
val = 927.50 + ((wages - 13550) * 0.15)
elif wages &gt; 41925 and wages &lt;= 80225:
val = 5183.75 + ((wages - 41925) * 0.25)
elif wages &gt; 80225 and wages &lt;= 120000:
val = 14758.75 + ((wages - 80225) * 0.28)
elif wages &gt; 120000 and wages &lt;= 210950:
val = 25895.75 + ((wages - 120000) * 0.33)
elif wages &gt; 210950 and wages &lt;= 237750:
val = 55909.25 + ((wages - 210950) * 0.35)
elif wages &gt; 237750:
val = 65289.25 + ((wages - 237750) * 0.396)
###
# Married ANNUAL
###
elif 'annually' == schedule_pay:
wages -= allowances * 4050.00
if is_nra:
wages += 2250.0
if wages &gt; 8550 and wages &lt;= 27100:
val = 0.00 + ((wages - 8550) * 0.10)
elif wages &gt; 27100 and wages &lt;= 83850:
val = 1855.00 + ((wages - 27100) * 0.15)
elif wages &gt; 83850 and wages &lt;= 160450:
val = 10367.50 + ((wages - 83850) * 0.25)
elif wages &gt; 160450 and wages &lt;= 240000:
val = 29517.50 + ((wages - 160450) * 0.28)
elif wages &gt; 240000 and wages &lt;= 421900:
val = 51791.50 + ((wages - 240000) * 0.33)
elif wages &gt; 421900 and wages &lt;= 475500:
val = 111818.50 + ((wages - 421900) * 0.35)
elif wages &gt; 475500:
val = 130578.50 + ((wages - 475500) * 0.396)
else:
raise Exception('Invalid schedule_pay="' + schedule_pay + '" for W4 Allowance calculation')
result = -(val + additional)
</field>
<field name="register_id" ref="contrib_register_eftps_941"/>
</record>
<record id="hr_payroll_rules_futa_wages_2016" model="hr.salary.rule">
<field name="sequence" eval="422"/>
<field name="category_id" ref="hr_payroll_futa_wages"/>
<field name="name">FUTA Federal Unemployment - Wages (2016)</field>
<field name="code">FUTA_WAGES_2016</field>
<field name="condition_select">python</field>
<field name="condition_python">result = (payslip.date_to[:4] == '2016' and contract.futa_type != contract.FUTA_TYPE_EXEMPT)</field>
<field name="amount_select">code</field>
<field name="amount_python_compute">
###
ytd = payslip.sum('FUTA_WAGES_2016', '2016-01-01', '2017-01-01')
ytd += contract.external_wages
remaining = 7000.0 - ytd
if remaining &lt;= 0.0:
result = 0
elif remaining &lt; categories.GROSS:
result = remaining
else:
result = categories.GROSS
</field>
<field name="appears_on_payslip" eval="False"/>
</record>
<record id="hr_payroll_rules_futa_2016" model="hr.salary.rule">
<field name="sequence" eval="442"/>
<field name="category_id" ref="hr_payroll_futa"/>
<field name="name">FUTA Federal Unemployment (2016)</field>
<field name="code">FUTA_2016</field>
<field name="condition_select">python</field>
<field name="condition_python">result = (payslip.date_to[:4] == '2016' and contract.futa_type != contract.FUTA_TYPE_EXEMPT)</field>
<field name="amount_select">code</field>
<field name="amount_python_compute">
result_rate = -(contract.futa_rate(2016))
result = categories.FUTA_WAGES
</field>
<field name="register_id" ref="contrib_register_eftps_940"/>
<field name="appears_on_payslip" eval="False"/>
</record>
</data>
</odoo>

View File

@@ -1,604 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data>
<!-- HR SALARY RULES-->
<!-- Employee Deductions and Calculations -->
<record id="hr_payroll_rules_fica_emp_ss_wages_2017" model="hr.salary.rule">
<field name="sequence" eval="120"/>
<field name="category_id" ref="hr_payroll_fica_emp_ss_wages"/>
<field name="name">FICA Employee Social Security Wages (2017)</field>
<field name="code">FICA_EMP_SS_WAGES_2017</field>
<field name="condition_select">python</field>
<field name="condition_python">result = (payslip.date_to[:4] == '2017')</field>
<field name="amount_select">code</field>
<field name="amount_python_compute">
###
ytd = payslip.sum('FICA_EMP_SS_WAGES_2017', '2017-01-01', '2018-01-01')
ytd += contract.external_wages
remaining = 127200.0 - ytd
if remaining &lt;= 0.0:
result = 0
elif remaining &lt; categories.GROSS:
result = remaining
else:
result = categories.GROSS
</field>
<field name="appears_on_payslip" eval="False"/>
</record>
<record id="hr_payroll_rules_fica_emp_m_wages_2017" model="hr.salary.rule">
<field name="sequence" eval="121"/>
<field name="category_id" ref="hr_payroll_fica_emp_m_wages"/>
<field name="name">FICA Employee Medicare Wages (2017)</field>
<field name="code">FICA_EMP_M_WAGES_2017</field>
<field name="condition_select">python</field>
<field name="condition_python">result = (payslip.date_to[:4] == '2017')</field>
<field name="amount_select">code</field>
<field name="amount_python_compute">result = categories.GROSS</field>
<field name="appears_on_payslip" eval="False"/>
</record>
<record id="hr_payroll_rules_fica_emp_m_add_wages_2017" model="hr.salary.rule">
<field name="sequence" eval="122"/>
<field name="category_id" ref="hr_payroll_fica_emp_m_add_wages"/>
<field name="name">FICA Employee Medicare Additional Wages (2017)</field>
<field name="code">FICA_EMP_M_ADD_WAGES_2017</field>
<field name="condition_select">python</field>
<field name="condition_python">result = (payslip.date_to[:4] == '2017')</field>
<field name="amount_select">code</field>
<field name="amount_python_compute">
###
ADD_M = 200000.0
norm_med_ytd = payslip.sum('FICA_EMP_M_WAGES_2017', '2017-01-01', '2018-01-01')
norm_med_cur = categories.FICA_EMP_M_WAGES
if ADD_M &gt; norm_med_ytd:
diff = ADD_M - norm_med_ytd
if norm_med_cur &gt; diff:
result = norm_med_cur - diff
else:
result = 0 # normal condition
else:
result = norm_med_cur # after YTD wages have passed the max
</field>
<field name="appears_on_payslip" eval="False"/>
</record>
<record id="hr_payroll_rules_fica_emp_ss_2017" model="hr.salary.rule">
<field name="sequence" eval="140"/>
<field name="category_id" ref="hr_payroll_fica_emp_ss"/>
<field name="name">FICA Employee Social Security (2017)</field>
<field name="code">FICA_EMP_SS_2017</field>
<field name="condition_select">python</field>
<field name="condition_python">result = (payslip.date_to[:4] == '2017')</field>
<field name="amount_select">code</field>
<field name="amount_python_compute">
### this should be "rules.FICA_EMP_SS_WAGES_2017", but it doesn't work
result_rate = -6.2
result = categories.FICA_EMP_SS_WAGES
</field>
<field name="register_id" ref="contrib_register_eftps_941"/>
</record>
<record id="hr_payroll_rules_fica_emp_m_2017" model="hr.salary.rule">
<field name="sequence" eval="141"/>
<field name="category_id" ref="hr_payroll_fica_emp_m"/>
<field name="name">FICA Employee Medicare (2017)</field>
<field name="code">FICA_EMP_M_2017</field>
<field name="condition_select">python</field>
<field name="condition_python">result = (payslip.date_to[:4] == '2017')</field>
<field name="amount_select">code</field>
<field name="amount_python_compute">
### this should be "rules.FICA_EMP_M_WAGES_2017", but it doesn't work
result_rate = -1.45
result = categories.FICA_EMP_M_WAGES
</field>
<field name="register_id" ref="contrib_register_eftps_941"/>
</record>
<record id="hr_payroll_rules_fica_emp_m_add_2017" model="hr.salary.rule">
<field name="sequence" eval="142"/>
<field name="category_id" ref="hr_payroll_fica_emp_m_add"/>
<field name="name">FICA Employee Medicare Additional (2017)</field>
<field name="code">FICA_EMP_M_ADD_2017</field>
<field name="condition_select">python</field>
<field name="condition_python">result = (payslip.date_to[:4] == '2017')</field>
<field name="amount_select">code</field>
<field name="amount_python_compute">
### this should be "rules.FICA_EMP_M_ADD_WAGES_2017", but it doesn't work
result_rate = -0.9
result = categories.FICA_EMP_M_ADD_WAGES
</field>
<field name="register_id" ref="contrib_register_eftps_941"/>
</record>
<!-- Federal Income Tax Withholding -->
<record id="hr_payroll_rules_fed_inc_withhold_2017_single" model="hr.salary.rule">
<field name="sequence" eval="145"/>
<field name="category_id" ref="hr_payroll_fed_income_withhold"/>
<field name="name">Federal Income Withholding - Single (2017)</field>
<field name="code">FED_INC_WITHHOLD_2017_S</field>
<field name="condition_select">python</field>
<field name="condition_python">result = (payslip.date_to[:4] == '2017' and contract.w4_filing_status != 'married' and contract.w4_filing_status)</field>
<field name="amount_select">code</field>
<field name="amount_python_compute">
wages = categories.GROSS
allowances = contract.w4_allowances
is_nra = contract.w4_is_nonresident_alien
schedule_pay = contract.schedule_pay
val = 0.00
additional = contract.w4_additional_withholding
###
# Single WEEKLY
###
if 'weekly' == schedule_pay:
wages -= allowances * 77.90
if is_nra:
wages += 44.20
if wages &gt; 44 and wages &lt;= 224:
val = 0.00 + ((wages - 44) * 0.10)
elif wages &gt; 224 and wages &lt;= 774:
val = 18.00 + ((wages - 224) * 0.15)
elif wages &gt; 774 and wages &lt;= 1812:
val = 100.50 + ((wages - 774) * 0.25)
elif wages &gt; 1812 and wages &lt;= 3730:
val = 360.00 + ((wages - 1812) * 0.28)
elif wages &gt; 3730 and wages &lt;= 8058:
val = 897.04 + ((wages - 3730) * 0.33)
elif wages &gt; 8058 and wages &lt;= 8090:
val = 2325.28 + ((wages - 8058) * 0.35)
elif wages &gt; 8090:
val = 2336.48 + ((wages - 8090) * 0.396)
###
# Single BIWEEKLY
###
elif 'bi-weekly' == schedule_pay:
wages -= allowances * 155.80
if is_nra:
wages += 88.50
if wages &gt; 88 and wages &lt;= 447:
val = 0.00 + ((wages - 88) * 0.10)
elif wages &gt; 447 and wages &lt;= 1548:
val = 35.90 + ((wages - 447) * 0.15)
elif wages &gt; 1548 and wages &lt;= 3623:
val = 201.05 + ((wages - 1548) * 0.25)
elif wages &gt; 3623 and wages &lt;= 7460:
val = 719.80 + ((wages - 3623) * 0.28)
elif wages &gt; 7460 and wages &lt;= 16115:
val = 1794.16 + ((wages - 7460) * 0.33)
elif wages &gt; 16115 and wages &lt;= 16181:
val = 4650.31 + ((wages - 16115) * 0.35)
elif wages &gt; 16181:
val = 4673.41 + ((wages - 16181) * 0.396)
###
# Single SEMIMONTHLY
###
elif 'semi-monthly' == schedule_pay:
wages -= allowances * 168.80
if is_nra:
wages += 95.80
if wages &gt; 96 and wages &lt;= 484:
val = 0.00 + ((wages - 96) * 0.10)
elif wages &gt; 484 and wages &lt;= 1677:
val = 38.80 + ((wages - 484) * 0.15)
elif wages &gt; 1677 and wages &lt;= 3925:
val = 217.75 + ((wages - 1677) * 0.25)
elif wages &gt; 3925 and wages &lt;= 8081:
val = 779.75 + ((wages - 3925) * 0.28)
elif wages &gt; 8081 and wages &lt;= 17458:
val = 1943.43 + ((wages - 8081) * 0.33)
elif wages &gt; 17458 and wages &lt;= 17529:
val = 5037.84 + ((wages - 17458) * 0.35)
elif wages &gt; 17529:
val = 5062.69 + ((wages - 17529) * 0.396)
###
# Single MONTHLY
###
elif 'monthly' == schedule_pay:
wages -= allowances * 337.50
if is_nra:
wages += 191.70
if wages &gt; 192 and wages &lt;= 969:
val = 0.00 + ((wages - 192) * 0.10)
elif wages &gt; 969 and wages &lt;= 3354:
val = 77.70 + ((wages - 969) * 0.15)
elif wages &gt; 3354 and wages &lt;= 7850:
val = 435.45 + ((wages - 3354) * 0.25)
elif wages &gt; 7850 and wages &lt;= 16163:
val = 1559.45 + ((wages - 7850) * 0.28)
elif wages &gt; 16163 and wages &lt;= 34917:
val = 3887.09 + ((wages - 16163) * 0.33)
elif wages &gt; 34917 and wages &lt;= 35058:
val = 10075.91 + ((wages - 34917) * 0.35)
elif wages &gt; 35058:
val = 10125.26 + ((wages - 35058) * 0.396)
###
# Single QUARTERLY
###
elif 'quarterly' == schedule_pay:
wages -= allowances * 1012.50
if is_nra:
wages += 575.00
if wages &gt; 575 and wages &lt;= 2906:
val = 0.00 + ((wages - 575) * 0.10)
elif wages &gt; 2906 and wages &lt;= 10063:
val = 233.10 + ((wages - 2906) * 0.15)
elif wages &gt; 10063 and wages &lt;= 23550:
val = 1306.65 + ((wages - 10063) * 0.25)
elif wages &gt; 23550 and wages &lt;= 48488:
val = 4678.40 + ((wages - 23550) * 0.28)
elif wages &gt; 48488 and wages &lt;= 104750:
val = 11661.04 + ((wages - 48488) * 0.33)
elif wages &gt; 104750 and wages &lt;= 105175:
val = 30227.50 + ((wages - 104750) * 0.35)
elif wages &gt; 105175:
val = 30376.25 + ((wages - 105175) * 0.396)
###
# Single SEMIANNUAL
###
elif 'semi-annually' == schedule_pay:
wages -= allowances * 2025.00
if is_nra:
wages += 1150.0
if wages &gt; 1150 and wages &lt;= 5813:
val = 0.00 + ((wages - 1150) * 0.10)
elif wages &gt; 5813 and wages &lt;= 20125:
val = 466.30 + ((wages - 5813) * 0.15)
elif wages &gt; 20125 and wages &lt;= 47100:
val = 2613.10 + ((wages - 20125) * 0.25)
elif wages &gt; 47100 and wages &lt;= 96975:
val = 9356.85 + ((wages - 47100) * 0.28)
elif wages &gt; 96975 and wages &lt;= 209500:
val = 23321.85 + ((wages - 96975) * 0.33)
elif wages &gt; 209500 and wages &lt;= 210350:
val = 60455.10 + ((wages - 209500) * 0.35)
elif wages &gt; 210350:
val = 60752.60 + ((wages - 210350) * 0.396)
###
# Single ANNUAL
###
elif 'annually' == schedule_pay:
wages -= allowances * 4050.00
if is_nra:
wages += 2300.0
if wages &gt; 2300 and wages &lt;= 11625:
val = 0.00 + ((wages - 2300) * 0.10)
elif wages &gt; 11625 and wages &lt;= 40250:
val = 932.50 + ((wages - 11625) * 0.15)
elif wages &gt; 40250 and wages &lt;= 94200:
val = 5226.25 + ((wages - 40250) * 0.25)
elif wages &gt; 94200 and wages &lt;= 193950:
val = 18713.75 + ((wages - 94200) * 0.28)
elif wages &gt; 193950 and wages &lt;= 419000:
val = 46643.75 + ((wages - 193950) * 0.33)
elif wages &gt; 419000 and wages &lt;= 420700:
val = 120910.25 + ((wages - 419000) * 0.35)
elif wages &gt; 420700:
val = 121505.25 + ((wages - 420700) * 0.396)
else:
raise Exception('Invalid schedule_pay="' + schedule_pay + '" for W4 Allowance calculation')
result = -(val + additional)
</field>
<field name="register_id" ref="contrib_register_eftps_941"/>
</record>
<record id="hr_payroll_rules_fed_inc_withhold_2017_married" model="hr.salary.rule">
<field name="sequence" eval="145"/>
<field name="category_id" ref="hr_payroll_fed_income_withhold"/>
<field name="name">Federal Income Withholding - Married (2017)</field>
<field name="code">FED_INC_WITHHOLD_2017_M</field>
<field name="condition_select">python</field>
<field name="condition_python">result = (payslip.date_to[:4] == '2017' and contract.w4_filing_status == 'married')</field>
<field name="amount_select">code</field>
<field name="amount_python_compute">
wages = categories.GROSS
allowances = contract.w4_allowances
is_nra = contract.w4_is_nonresident_alien
schedule_pay = contract.schedule_pay
val = 0.00
additional = contract.w4_additional_withholding
###
# Married WEEKLY
###
if 'weekly' == schedule_pay:
wages -= allowances * 77.90
if is_nra:
wages += 44.20
if wages &gt; 166 and wages &lt;= 525:
val = 0.00 + ((wages - 166) * 0.10)
elif wages &gt; 525 and wages &lt;= 1626:
val = 35.90 + ((wages - 525) * 0.15)
elif wages &gt; 1626 and wages &lt;= 3111:
val = 201.05 + ((wages - 1626) * 0.25)
elif wages &gt; 3111 and wages &lt;= 4654:
val = 572.30 + ((wages - 3111) * 0.28)
elif wages &gt; 4654 and wages &lt;= 8180:
val = 1004.34 + ((wages - 4654) * 0.33)
elif wages &gt; 8180 and wages &lt;= 9218:
val = 2167.92 + ((wages - 8180) * 0.35)
elif wages &gt; 9218:
val = 2531.22 + ((wages - 9218) * 0.396)
###
# Married BIWEEKLY
###
elif 'bi-weekly' == schedule_pay:
wages -= allowances * 155.80
if is_nra:
wages += 88.50
if wages &gt; 333 and wages &lt;= 1050:
val = 0.00 + ((wages - 333) * 0.10)
elif wages &gt; 1050 and wages &lt;= 3252:
val = 71.70 + ((wages - 1050) * 0.15)
elif wages &gt; 3252 and wages &lt;= 6221:
val = 402.00 + ((wages - 3252) * 0.25)
elif wages &gt; 6221 and wages &lt;= 9308:
val = 1144.25 + ((wages - 6221) * 0.28)
elif wages &gt; 9308 and wages &lt;= 16360:
val = 2008.61 + ((wages - 9308) * 0.33)
elif wages &gt; 16360 and wages &lt;= 18437:
val = 4335.77 + ((wages - 16360) * 0.35)
elif wages &gt; 18437:
val = 5062.72 + ((wages - 18437) * 0.396)
###
# Married SEMIMONTHLY
###
elif 'semi-monthly' == schedule_pay:
wages -= allowances * 168.80
if is_nra:
wages += 95.80
if wages &gt; 360 and wages &lt;= 1138:
val = 0.00 + ((wages - 360) * 0.10)
elif wages &gt; 1138 and wages &lt;= 3523:
val = 77.80 + ((wages - 1138) * 0.15)
elif wages &gt; 3523 and wages &lt;= 6740:
val = 435.55 + ((wages - 3523) * 0.25)
elif wages &gt; 6740 and wages &lt;= 10083:
val = 1239.80 + ((wages - 6740) * 0.28)
elif wages &gt; 10083 and wages &lt;= 17723:
val = 2175.84 + ((wages - 10083) * 0.33)
elif wages &gt; 17723 and wages &lt;= 19973:
val = 4697.04 + ((wages - 17723) * 0.35)
elif wages &gt; 19973:
val = 5484.54 + ((wages - 19973) * 0.396)
###
# Married MONTHLY
###
elif 'monthly' == schedule_pay:
wages -= allowances * 337.50
if is_nra:
wages += 191.70
if wages &gt; 721 and wages &lt;= 2275:
val = 0.00 + ((wages - 721) * 0.10)
elif wages &gt; 2275 and wages &lt;= 7046:
val = 155.40 + ((wages - 2275) * 0.15)
elif wages &gt; 7046 and wages &lt;= 13479:
val = 871.05 + ((wages - 7046) * 0.25)
elif wages &gt; 13479 and wages &lt;= 20167:
val = 2479.30 + ((wages - 13479) * 0.28)
elif wages &gt; 20167 and wages &lt;= 35446:
val = 4351.94 + ((wages - 20167) * 0.33)
elif wages &gt; 35446 and wages &lt;= 39946:
val = 9394.01 + ((wages - 35446) * 0.35)
elif wages &gt; 39946:
val = 10969.01 + ((wages - 39946) * 0.396)
###
# Married QUARTERLY
###
elif 'quarterly' == schedule_pay:
wages -= allowances * 1012.50
if is_nra:
wages += 575.00
if wages &gt; 2163 and wages &lt;= 6825:
val = 0.00 + ((wages - 2163) * 0.10)
elif wages &gt; 6825 and wages &lt;= 21138:
val = 466.20 + ((wages - 6825) * 0.15)
elif wages &gt; 21138 and wages &lt;= 40438:
val = 2613.15 + ((wages - 21138) * 0.25)
elif wages &gt; 40438 and wages &lt;= 60500:
val = 7438.15 + ((wages - 40438) * 0.28)
elif wages &gt; 60500 and wages &lt;= 106338:
val = 13055.51 + ((wages - 60500) * 0.33)
elif wages &gt; 106338 and wages &lt;= 119838:
val = 28182.05 + ((wages - 106338) * 0.35)
elif wages &gt; 119838:
val = 32907.05 + ((wages - 119838) * 0.396)
###
# Married SEMIANNUAL
###
elif 'semi-annually' == schedule_pay:
wages -= allowances * 2025.00
if is_nra:
wages += 1150.0
if wages &gt; 4325 and wages &lt;= 13650:
val = 0.00 + ((wages - 4325) * 0.10)
elif wages &gt; 13650 and wages &lt;= 42275:
val = 932.50 + ((wages - 13650) * 0.15)
elif wages &gt; 42275 and wages &lt;= 80875:
val = 5226.25 + ((wages - 42275) * 0.25)
elif wages &gt; 80875 and wages &lt;= 121000:
val = 14876.25 + ((wages - 80875) * 0.28)
elif wages &gt; 121000 and wages &lt;= 212675:
val = 26111.25 + ((wages - 121000) * 0.33)
elif wages &gt; 212675 and wages &lt;= 239675:
val = 56364.00 + ((wages - 212675) * 0.35)
elif wages &gt; 239675:
val = 65814.00 + ((wages - 239675) * 0.396)
###
# Married ANNUAL
###
elif 'annually' == schedule_pay:
wages -= allowances * 4050.00
if is_nra:
wages += 2300.0
if wages &gt; 8650 and wages &lt;= 27300:
val = 0.00 + ((wages - 8650) * 0.10)
elif wages &gt; 27300 and wages &lt;= 84550:
val = 1865.00 + ((wages - 27300) * 0.15)
elif wages &gt; 84550 and wages &lt;= 161750:
val = 10452.50 + ((wages - 84550) * 0.25)
elif wages &gt; 161750 and wages &lt;= 242000:
val = 29752.50 + ((wages - 161750) * 0.28)
elif wages &gt; 242000 and wages &lt;= 425350:
val = 52222.50 + ((wages - 242000) * 0.33)
elif wages &gt; 425350 and wages &lt;= 479350:
val = 112728.00 + ((wages - 425350) * 0.35)
elif wages &gt; 479350:
val = 131628.00 + ((wages - 479350) * 0.396)
else:
raise Exception('Invalid schedule_pay="' + schedule_pay + '" for W4 Allowance calculation')
result = -(val + additional)
</field>
<field name="register_id" ref="contrib_register_eftps_941"/>
</record>
<record id="hr_payroll_rules_futa_wages_2017" model="hr.salary.rule">
<field name="sequence" eval="422"/>
<field name="category_id" ref="hr_payroll_futa_wages"/>
<field name="name">FUTA Federal Unemployment - Wages (2017)</field>
<field name="code">FUTA_WAGES_2017</field>
<field name="condition_select">python</field>
<field name="condition_python">result = (payslip.date_to[:4] == '2017' and contract.futa_type != contract.FUTA_TYPE_EXEMPT)</field>
<field name="amount_select">code</field>
<field name="amount_python_compute">
###
ytd = payslip.sum('FUTA_WAGES_2017', '2017-01-01', '2018-01-01')
ytd += contract.external_wages
remaining = 7000.0 - ytd
if remaining &lt;= 0.0:
result = 0
elif remaining &lt; categories.GROSS:
result = remaining
else:
result = categories.GROSS
</field>
<field name="appears_on_payslip" eval="False"/>
</record>
<record id="hr_payroll_rules_futa_2017" model="hr.salary.rule">
<field name="sequence" eval="442"/>
<field name="category_id" ref="hr_payroll_futa"/>
<field name="name">FUTA Federal Unemployment (2017)</field>
<field name="code">FUTA_2017</field>
<field name="condition_select">python</field>
<field name="condition_python">result = (payslip.date_to[:4] == '2017' and contract.futa_type != contract.FUTA_TYPE_EXEMPT)</field>
<field name="amount_select">code</field>
<field name="amount_python_compute">
result_rate = -(contract.futa_rate(2017))
result = categories.FUTA_WAGES
</field>
<field name="register_id" ref="contrib_register_eftps_940"/>
<field name="appears_on_payslip" eval="False"/>
</record>
</data>
</odoo>

View File

@@ -1,604 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data>
<!-- HR SALARY RULES-->
<!-- Employee Deductions and Calculations -->
<record id="hr_payroll_rules_fica_emp_ss_wages_2018" model="hr.salary.rule">
<field name="sequence" eval="120"/>
<field name="category_id" ref="hr_payroll_fica_emp_ss_wages"/>
<field name="name">FICA Employee Social Security Wages (2018)</field>
<field name="code">FICA_EMP_SS_WAGES_2018</field>
<field name="condition_select">python</field>
<field name="condition_python">result = (payslip.date_to[:4] == '2018') and not contract.fica_exempt</field>
<field name="amount_select">code</field>
<field name="amount_python_compute">
###
ytd = payslip.sum('FICA_EMP_SS_WAGES_2018', '2018-01-01', '2019-01-01')
ytd += contract.external_wages
remaining = 128400.0 - ytd
if remaining &lt;= 0.0:
result = 0
elif remaining &lt; categories.BASIC:
result = remaining
else:
result = categories.BASIC
</field>
<field name="appears_on_payslip" eval="False"/>
</record>
<record id="hr_payroll_rules_fica_emp_m_wages_2018" model="hr.salary.rule">
<field name="sequence" eval="121"/>
<field name="category_id" ref="hr_payroll_fica_emp_m_wages"/>
<field name="name">FICA Employee Medicare Wages (2018)</field>
<field name="code">FICA_EMP_M_WAGES_2018</field>
<field name="condition_select">python</field>
<field name="condition_python">result = (payslip.date_to[:4] == '2018') and not contract.fica_exempt</field>
<field name="amount_select">code</field>
<field name="amount_python_compute">result = categories.BASIC</field>
<field name="appears_on_payslip" eval="False"/>
</record>
<record id="hr_payroll_rules_fica_emp_m_add_wages_2018" model="hr.salary.rule">
<field name="sequence" eval="122"/>
<field name="category_id" ref="hr_payroll_fica_emp_m_add_wages"/>
<field name="name">FICA Employee Medicare Additional Wages (2018)</field>
<field name="code">FICA_EMP_M_ADD_WAGES_2018</field>
<field name="condition_select">python</field>
<field name="condition_python">result = (payslip.date_to[:4] == '2018') and not contract.fica_exempt</field>
<field name="amount_select">code</field>
<field name="amount_python_compute">
###
ADD_M = 200000.0
norm_med_ytd = payslip.sum('FICA_EMP_M_WAGES_2018', '2018-01-01', '2019-01-01')
norm_med_cur = categories.FICA_EMP_M_WAGES
if ADD_M &gt; norm_med_ytd:
diff = ADD_M - norm_med_ytd
if norm_med_cur &gt; diff:
result = norm_med_cur - diff
else:
result = 0 # normal condition
else:
result = norm_med_cur # after YTD wages have passed the max
</field>
<field name="appears_on_payslip" eval="False"/>
</record>
<record id="hr_payroll_rules_fica_emp_ss_2018" model="hr.salary.rule">
<field name="sequence" eval="140"/>
<field name="category_id" ref="hr_payroll_fica_emp_ss"/>
<field name="name">FICA Employee Social Security (2018)</field>
<field name="code">FICA_EMP_SS_2018</field>
<field name="condition_select">python</field>
<field name="condition_python">result = (payslip.date_to[:4] == '2018')</field>
<field name="amount_select">code</field>
<field name="amount_python_compute">
### this should be "rules.FICA_EMP_SS_WAGES_2018", but it doesn't work
result_rate = -6.2
result = categories.FICA_EMP_SS_WAGES
</field>
<field name="register_id" ref="contrib_register_eftps_941"/>
</record>
<record id="hr_payroll_rules_fica_emp_m_2018" model="hr.salary.rule">
<field name="sequence" eval="141"/>
<field name="category_id" ref="hr_payroll_fica_emp_m"/>
<field name="name">FICA Employee Medicare (2018)</field>
<field name="code">FICA_EMP_M_2018</field>
<field name="condition_select">python</field>
<field name="condition_python">result = (payslip.date_to[:4] == '2018')</field>
<field name="amount_select">code</field>
<field name="amount_python_compute">
### this should be "rules.FICA_EMP_M_WAGES_2018", but it doesn't work
result_rate = -1.45
result = categories.FICA_EMP_M_WAGES
</field>
<field name="register_id" ref="contrib_register_eftps_941"/>
</record>
<record id="hr_payroll_rules_fica_emp_m_add_2018" model="hr.salary.rule">
<field name="sequence" eval="142"/>
<field name="category_id" ref="hr_payroll_fica_emp_m_add"/>
<field name="name">FICA Employee Medicare Additional (2018)</field>
<field name="code">FICA_EMP_M_ADD_2018</field>
<field name="condition_select">python</field>
<field name="condition_python">result = (payslip.date_to[:4] == '2018')</field>
<field name="amount_select">code</field>
<field name="amount_python_compute">
### this should be "rules.FICA_EMP_M_ADD_WAGES_2018", but it doesn't work
result_rate = -0.9
result = categories.FICA_EMP_M_ADD_WAGES
</field>
<field name="register_id" ref="contrib_register_eftps_941"/>
</record>
<!-- Federal Income Tax Withholding -->
<record id="hr_payroll_rules_fed_inc_withhold_2018_single" model="hr.salary.rule">
<field name="sequence" eval="145"/>
<field name="category_id" ref="hr_payroll_fed_income_withhold"/>
<field name="name">Federal Income Withholding - Single (2018)</field>
<field name="code">FED_INC_WITHHOLD_2018_S</field>
<field name="condition_select">python</field>
<field name="condition_python">result = (payslip.date_to[:4] == '2018' and contract.w4_filing_status != 'married' and contract.w4_filing_status)</field>
<field name="amount_select">code</field>
<field name="amount_python_compute">
wages = categories.GROSS
allowances = contract.w4_allowances
is_nra = contract.w4_is_nonresident_alien
schedule_pay = contract.schedule_pay
val = 0.00
additional = contract.w4_additional_withholding
###
# Single WEEKLY
###
if 'weekly' == schedule_pay:
wages -= allowances * 79.80
if is_nra:
wages += 151.00
if wages &gt; 71 and wages &lt;= 254:
val = 0.00 + ((wages - 71) * 0.10)
elif wages &gt; 254 and wages &lt;= 815:
val = 18.30 + ((wages - 254) * 0.12)
elif wages &gt; 815 and wages &lt;= 1658:
val = 85.62 + ((wages - 815) * 0.22)
elif wages &gt; 1658 and wages &lt;= 3100:
val = 271.08 + ((wages - 1658) * 0.24)
elif wages &gt; 3100 and wages &lt;= 3917:
val = 617.16 + ((wages - 3100) * 0.32)
elif wages &gt; 3917 and wages &lt;= 9687:
val = 878.60 + ((wages - 3917) * 0.35)
elif wages &gt; 9687:
val = 2898.10 + ((wages - 9687) * 0.37)
###
# Single BIWEEKLY
###
elif 'bi-weekly' == schedule_pay:
wages -= allowances * 159.60
if is_nra:
wages += 301.90
if wages &gt; 142 and wages &lt;= 509:
val = 0.00 + ((wages - 142) * 0.10)
elif wages &gt; 509 and wages &lt;= 1631:
val = 36.70 + ((wages - 509) * 0.12)
elif wages &gt; 1631 and wages &lt;= 3315:
val = 171.34 + ((wages - 1631) * 0.22)
elif wages &gt; 3315 and wages &lt;= 6200:
val = 541.82 + ((wages - 3315) * 0.24)
elif wages &gt; 6200 and wages &lt;= 7835:
val = 1234.22 + ((wages - 6200) * 0.32)
elif wages &gt; 7835 and wages &lt;= 19373:
val = 1757.42 + ((wages - 7835) * 0.35)
elif wages &gt; 19373:
val = 5795.72 + ((wages - 19373) * 0.37)
###
# Single SEMIMONTHLY
###
elif 'semi-monthly' == schedule_pay:
wages -= allowances * 172.90
if is_nra:
wages += 327.10
if wages &gt; 154 and wages &lt;= 551:
val = 0.00 + ((wages - 154) * 0.10)
elif wages &gt; 551 and wages &lt;= 1767:
val = 39.70 + ((wages - 551) * 0.12)
elif wages &gt; 1767 and wages &lt;= 3592:
val = 185.62 + ((wages - 1767) * 0.22)
elif wages &gt; 3592 and wages &lt;= 6717:
val = 587.12 + ((wages - 3592) * 0.24)
elif wages &gt; 6717 and wages &lt;= 8488:
val = 1337.12 + ((wages - 6717) * 0.32)
elif wages &gt; 8488 and wages &lt;= 20988:
val = 1903.84 + ((wages - 8488) * 0.35)
elif wages &gt; 20988:
val = 6278.84 + ((wages - 20988) * 0.37)
###
# Single MONTHLY
###
elif 'monthly' == schedule_pay:
wages -= allowances * 345.80
if is_nra:
wages += 654.20
if wages &gt; 308 and wages &lt;= 1102:
val = 0.00 + ((wages - 308) * 0.10)
elif wages &gt; 1102 and wages &lt;= 3533:
val = 79.40 + ((wages - 1102) * 0.12)
elif wages &gt; 3533 and wages &lt;= 7183:
val = 371.12 + ((wages - 3533) * 0.22)
elif wages &gt; 7183 and wages &lt;= 13433:
val = 1174.12 + ((wages - 7183) * 0.24)
elif wages &gt; 13433 and wages &lt;= 16975:
val = 2674.12 + ((wages - 13433) * 0.32)
elif wages &gt; 16975 and wages &lt;= 41975:
val = 3807.56 + ((wages - 16975) * 0.35)
elif wages &gt; 41975:
val = 12557.56 + ((wages - 41975) * 0.37)
###
# Single QUARTERLY
###
elif 'quarterly' == schedule_pay:
wages -= allowances * 1037.50
if is_nra:
wages += 1962.50
if wages &gt; 925 and wages &lt;= 3306:
val = 0.00 + ((wages - 925) * 0.10)
elif wages &gt; 3306 and wages &lt;= 10600:
val = 238.10 + ((wages - 3306) * 0.12)
elif wages &gt; 10600 and wages &lt;= 21550:
val = 1113.38 + ((wages - 10600) * 0.22)
elif wages &gt; 21550 and wages &lt;= 40300:
val = 3522.38 + ((wages - 21550) * 0.24)
elif wages &gt; 40300 and wages &lt;= 50925:
val = 8022.38 + ((wages - 40300) * 0.32)
elif wages &gt; 50925 and wages &lt;= 125925:
val = 11422.38 + ((wages - 50925) * 0.35)
elif wages &gt; 125925:
val = 37672.38 + ((wages - 125925) * 0.37)
###
# Single SEMIANNUAL
###
elif 'semi-annually' == schedule_pay:
wages -= allowances * 2075.00
if is_nra:
wages += 3925.00
if wages &gt; 1850 and wages &lt;= 6613:
val = 0.00 + ((wages - 1850) * 0.10)
elif wages &gt; 6613 and wages &lt;= 21200:
val = 476.30 + ((wages - 6613) * 0.12)
elif wages &gt; 21200 and wages &lt;= 43100:
val = 2226.74 + ((wages - 21200) * 0.22)
elif wages &gt; 43100 and wages &lt;= 80600:
val = 7044.74 + ((wages - 43100) * 0.24)
elif wages &gt; 80600 and wages &lt;= 101850:
val = 16044.74 + ((wages - 80600) * 0.32)
elif wages &gt; 101850 and wages &lt;= 251850:
val = 22844.74 + ((wages - 101850) * 0.35)
elif wages &gt; 251850:
val = 75344.74 + ((wages - 251850) * 0.37)
###
# Single ANNUAL
###
elif 'annually' == schedule_pay:
wages -= allowances * 4150.00
if is_nra:
wages += 7850.00
if wages &gt; 3700 and wages &lt;= 13225:
val = 0.00 + ((wages - 3700) * 0.10)
elif wages &gt; 13225 and wages &lt;= 42400:
val = 952.50 + ((wages - 13225) * 0.12)
elif wages &gt; 42400 and wages &lt;= 86200:
val = 4453.50 + ((wages - 42400) * 0.22)
elif wages &gt; 86200 and wages &lt;= 161200:
val = 14089.50 + ((wages - 86200) * 0.24)
elif wages &gt; 161200 and wages &lt;= 203700:
val = 32089.50 + ((wages - 161200) * 0.32)
elif wages &gt; 203700 and wages &lt;= 503700:
val = 45689.50 + ((wages - 203700) * 0.35)
elif wages &gt; 503700:
val = 150689.50 + ((wages - 503700) * 0.37)
else:
raise Exception('Invalid schedule_pay="' + schedule_pay + '" for W4 Allowance calculation')
result = -(val + additional)
</field>
<field name="register_id" ref="contrib_register_eftps_941"/>
</record>
<record id="hr_payroll_rules_fed_inc_withhold_2018_married" model="hr.salary.rule">
<field name="sequence" eval="145"/>
<field name="category_id" ref="hr_payroll_fed_income_withhold"/>
<field name="name">Federal Income Withholding - Married (2018)</field>
<field name="code">FED_INC_WITHHOLD_2018_M</field>
<field name="condition_select">python</field>
<field name="condition_python">result = (payslip.date_to[:4] == '2018' and contract.w4_filing_status == 'married')</field>
<field name="amount_select">code</field>
<field name="amount_python_compute">
wages = categories.GROSS
allowances = contract.w4_allowances
is_nra = contract.w4_is_nonresident_alien
schedule_pay = contract.schedule_pay
val = 0.00
additional = contract.w4_additional_withholding
###
# Married WEEKLY
###
if 'weekly' == schedule_pay:
wages -= allowances * 79.80
if is_nra:
wages += 151.00
if wages &gt; 222 and wages &lt;= 588:
val = 0.00 + ((wages - 222) * 0.10)
elif wages &gt; 588 and wages &lt;= 1711:
val = 36.60 + ((wages - 588) * 0.12)
elif wages &gt; 1711 and wages &lt;= 3395:
val = 171.36 + ((wages - 1711) * 0.22)
elif wages &gt; 3395 and wages &lt;= 6280:
val = 541.84 + ((wages - 3395) * 0.24)
elif wages &gt; 6280 and wages &lt;= 7914:
val = 1234.24 + ((wages - 6280) * 0.32)
elif wages &gt; 7914 and wages &lt;= 11761:
val = 1757.12 + ((wages - 7914) * 0.35)
elif wages &gt; 11761:
val = 3103.57 + ((wages - 11761) * 0.37)
###
# Married BIWEEKLY
###
elif 'bi-weekly' == schedule_pay:
wages -= allowances * 159.60
if is_nra:
wages += 301.90
if wages &gt; 444 and wages &lt;= 1177:
val = 0.00 + ((wages - 444) * 0.10)
elif wages &gt; 1177 and wages &lt;= 3421:
val = 73.30 + ((wages - 1177) * 0.12)
elif wages &gt; 3421 and wages &lt;= 6790:
val = 342.58 + ((wages - 3421) * 0.22)
elif wages &gt; 6790 and wages &lt;= 12560:
val = 1083.76 + ((wages - 6790) * 0.24)
elif wages &gt; 12560 and wages &lt;= 15829:
val = 2468.56 + ((wages - 12560) * 0.32)
elif wages &gt; 15829 and wages &lt;= 23521:
val = 3514.64 + ((wages - 15829) * 0.35)
elif wages &gt; 23521:
val = 6206.84 + ((wages - 23521) * 0.37)
###
# Married SEMIMONTHLY
###
elif 'semi-monthly' == schedule_pay:
wages -= allowances * 172.90
if is_nra:
wages += 327.10
if wages &gt; 481 and wages &lt;= 1275:
val = 0.00 + ((wages - 481) * 0.10)
elif wages &gt; 1275 and wages &lt;= 3706:
val = 79.40 + ((wages - 1275) * 0.12)
elif wages &gt; 3706 and wages &lt;= 7356:
val = 371.12 + ((wages - 3706) * 0.22)
elif wages &gt; 7356 and wages &lt;= 13606:
val = 1174.12 + ((wages - 7356) * 0.24)
elif wages &gt; 13606 and wages &lt;= 17148:
val = 2674.12 + ((wages - 13606) * 0.32)
elif wages &gt; 17148 and wages &lt;= 25481:
val = 3807.56 + ((wages - 17148) * 0.35)
elif wages &gt; 25481:
val = 6724.11 + ((wages - 25481) * 0.37)
###
# Married MONTHLY
###
elif 'monthly' == schedule_pay:
wages -= allowances * 345.80
if is_nra:
wages += 654.20
if wages &gt; 963 and wages &lt;= 2550:
val = 0.00 + ((wages - 963) * 0.10)
elif wages &gt; 2550 and wages &lt;= 7413:
val = 158.70 + ((wages - 2550) * 0.12)
elif wages &gt; 7413 and wages &lt;= 14713:
val = 742.26 + ((wages - 7413) * 0.22)
elif wages &gt; 14713 and wages &lt;= 27213:
val = 2348.26 + ((wages - 14713) * 0.24)
elif wages &gt; 27213 and wages &lt;= 34296:
val = 5348.26 + ((wages - 27213) * 0.32)
elif wages &gt; 34296 and wages &lt;= 50963:
val = 7614.82 + ((wages - 34296) * 0.35)
elif wages &gt; 50963:
val = 13448.27 + ((wages - 50963) * 0.37)
###
# Married QUARTERLY
###
elif 'quarterly' == schedule_pay:
wages -= allowances * 1037.50
if is_nra:
wages += 1962.50
if wages &gt; 2888 and wages &lt;= 7650:
val = 0.00 + ((wages - 2888) * 0.10)
elif wages &gt; 7650 and wages &lt;= 22238:
val = 476.20 + ((wages - 7650) * 0.12)
elif wages &gt; 22238 and wages &lt;= 44138:
val = 2226.76 + ((wages - 22238) * 0.22)
elif wages &gt; 44138 and wages &lt;= 81638:
val = 7044.76 + ((wages - 44138) * 0.24)
elif wages &gt; 81638 and wages &lt;= 102888:
val = 16044.76 + ((wages - 81638) * 0.32)
elif wages &gt; 102888 and wages &lt;= 152888:
val = 22844.76 + ((wages - 102888) * 0.35)
elif wages &gt; 152888:
val = 40344.76 + ((wages - 152888) * 0.37)
###
# Married SEMIANNUAL
###
elif 'semi-annually' == schedule_pay:
wages -= allowances * 2075.00
if is_nra:
wages += 3925.00
if wages &gt; 5775 and wages &lt;= 15300:
val = 0.00 + ((wages - 5775) * 0.10)
elif wages &gt; 15300 and wages &lt;= 44475:
val = 952.50 + ((wages - 15300) * 0.12)
elif wages &gt; 44475 and wages &lt;= 88275:
val = 4453.50 + ((wages - 44475) * 0.22)
elif wages &gt; 88275 and wages &lt;= 163275:
val = 14089.50 + ((wages - 88275) * 0.24)
elif wages &gt; 163275 and wages &lt;= 205775:
val = 32089.50 + ((wages - 163275) * 0.32)
elif wages &gt; 205775 and wages &lt;= 305775:
val = 45689.50 + ((wages - 205775) * 0.35)
elif wages &gt; 305775:
val = 80689.50 + ((wages - 305775) * 0.37)
###
# Married ANNUAL
###
elif 'annually' == schedule_pay:
wages -= allowances * 4150.00
if is_nra:
wages += 7850.00
if wages &gt; 11550 and wages &lt;= 30600:
val = 0.00 + ((wages - 11550) * 0.10)
elif wages &gt; 30600 and wages &lt;= 88950:
val = 1905.00 + ((wages - 30600) * 0.12)
elif wages &gt; 88950 and wages &lt;= 176550:
val = 8907.00 + ((wages - 88950) * 0.22)
elif wages &gt; 176550 and wages &lt;= 326550:
val = 28179.00 + ((wages - 176550) * 0.24)
elif wages &gt; 326550 and wages &lt;= 411550:
val = 64179.00 + ((wages - 326550) * 0.32)
elif wages &gt; 411550 and wages &lt;= 611550:
val = 91379.00 + ((wages - 411550) * 0.35)
elif wages &gt; 611550:
val = 161379.00 + ((wages - 611550) * 0.37)
else:
raise Exception('Invalid schedule_pay="' + schedule_pay + '" for W4 Allowance calculation')
result = -(val + additional)
</field>
<field name="register_id" ref="contrib_register_eftps_941"/>
</record>
<record id="hr_payroll_rules_futa_wages_2018" model="hr.salary.rule">
<field name="sequence" eval="422"/>
<field name="category_id" ref="hr_payroll_futa_wages"/>
<field name="name">FUTA Federal Unemployment - Wages (2018)</field>
<field name="code">FUTA_WAGES_2018</field>
<field name="condition_select">python</field>
<field name="condition_python">result = (payslip.date_to[:4] == '2018' and contract.futa_type != contract.FUTA_TYPE_EXEMPT)</field>
<field name="amount_select">code</field>
<field name="amount_python_compute">
###
ytd = payslip.sum('FUTA_WAGES_2018', '2018-01-01', '2019-01-01')
ytd += contract.external_wages
remaining = 7000.0 - ytd
if remaining &lt;= 0.0:
result = 0
elif remaining &lt; categories.BASIC:
result = remaining
else:
result = categories.BASIC
</field>
<field name="appears_on_payslip" eval="False"/>
</record>
<record id="hr_payroll_rules_futa_2018" model="hr.salary.rule">
<field name="sequence" eval="442"/>
<field name="category_id" ref="hr_payroll_futa"/>
<field name="name">FUTA Federal Unemployment (2018)</field>
<field name="code">FUTA_2018</field>
<field name="condition_select">python</field>
<field name="condition_python">result = (payslip.date_to[:4] == '2018' and contract.futa_type != contract.FUTA_TYPE_EXEMPT)</field>
<field name="amount_select">code</field>
<field name="amount_python_compute">
result_rate = -(contract.futa_rate(2018))
result = categories.FUTA_WAGES
</field>
<field name="register_id" ref="contrib_register_eftps_940"/>
<field name="appears_on_payslip" eval="False"/>
</record>
</data>
</odoo>

View File

@@ -0,0 +1 @@
from . import l10n_us_hr_payroll

View File

@@ -1,15 +1,24 @@
from odoo import models, fields, api
class Payslip(models.Model):
_inherit = 'hr.payslip'
def get_futa_rate(self, contract):
self.ensure_one()
if contract.futa_type == USHrContract.FUTA_TYPE_EXEMPT:
rate = self.get_rate('US_FUTA_EXEMPT')
elif contract.futa_type == USHrContract.FUTA_TYPE_NORMAL:
rate = self.get_rate('US_FUTA_NORMAL')
else:
rate = self.get_rate('US_FUTA_BASIC')
return rate
class USHrContract(models.Model):
FUTA_TYPE_EXEMPT = 'exempt'
FUTA_TYPE_BASIC = 'basic'
FUTA_TYPE_NORMAL = 'normal'
FUTA_YEARS_VALID = (
2016,
2017,
2018,
)
_inherit = 'hr.contract'
@@ -33,17 +42,3 @@ class USHrContract(models.Model):
(FUTA_TYPE_NORMAL, 'Normal Net Rate (0.6%)'),
(FUTA_TYPE_BASIC, 'Basic Rate (6%)'),
], string="Federal Unemployment Tax Type (FUTA)", default='normal')
@api.multi
def futa_rate(self, year):
self.ensure_one()
if year not in self.FUTA_YEARS_VALID:
raise NotImplemented('FUTA rate for Year: ' + str(year) + ' not known.')
if self.futa_type == self.FUTA_TYPE_EXEMPT:
return 0.0
elif self.futa_type == self.FUTA_TYPE_NORMAL:
return 0.6
else:
return 6.0

View File

@@ -1,6 +1,5 @@
# -*- coding: utf-8 -*-
from . import test_us_payslip
from . import test_us_payslip_2016
from . import test_us_payslip_2017
from . import test_us_payslip_2018
from . import test_us_payslip_2019

View File

@@ -5,7 +5,7 @@ from sys import float_info as sys_float_info
from odoo.tests import common
from odoo.tools.float_utils import float_round as odoo_float_round
from odoo.addons.l10n_us_hr_payroll.l10n_us_hr_payroll import USHrContract
from odoo.addons.l10n_us_hr_payroll.models.l10n_us_hr_payroll import USHrContract
def process_payslip(payslip):

View File

@@ -1,377 +0,0 @@
from .test_us_payslip import TestUsPayslip, process_payslip
from odoo.addons.l10n_us_hr_payroll.l10n_us_hr_payroll import USHrContract
class TestUsPayslip2016(TestUsPayslip):
FUTA_RATE_NORMAL_2016 = 0.6
FUTA_RATE_BASIC_2016 = 6.0
FUTA_RATE_EXEMPT_2016 = 0.0
###
# 2016 Taxes and Rates
###
def test_2016_taxes(self):
# salary is high so that second payslip runs over max
# social security salary
salary = 80000.0
## tax rates
FICA_SS = -0.062
FICA_M = -0.0145
FUTA = -self.FUTA_RATE_NORMAL_2016 / 100.0
FICA_M_ADD = -0.009
## tax maximums
FICA_SS_MAX_WAGE = 118500.0
FICA_M_MAX_WAGE = self.float_info.max
FICA_M_ADD_START_WAGE = 200000.0
FUTA_MAX_WAGE = 7000.0
employee = self._createEmployee()
contract = self._createContract(employee, salary)
self._log('2016 tax first payslip:')
payslip = self._createPayslip(employee, '2016-01-01', '2016-01-31')
payslip.compute_sheet()
cats = self._getCategories(payslip)
self.assertPayrollEqual(cats['FICA_EMP_SS_WAGES'], salary)
self.assertPayrollEqual(cats['FICA_EMP_SS'], cats['FICA_EMP_SS_WAGES'] * FICA_SS)
self.assertPayrollEqual(cats['FICA_EMP_M_WAGES'], salary)
self.assertPayrollEqual(cats['FICA_EMP_M'], cats['FICA_EMP_M_WAGES'] * FICA_M)
self.assertPayrollEqual(cats['FICA_EMP_M_ADD_WAGES'], 0.0)
self.assertPayrollEqual(cats['FICA_EMP_M_ADD'], 0.0)
self.assertPayrollEqual(cats['FICA_COMP_SS'], cats['FICA_EMP_SS'])
self.assertPayrollEqual(cats['FICA_COMP_M'], cats['FICA_EMP_M'])
self.assertPayrollEqual(cats['FUTA_WAGES'], FUTA_MAX_WAGE)
self.assertPayrollEqual(cats['FUTA'], cats['FUTA_WAGES'] * FUTA)
process_payslip(payslip)
# Make a new payslip, this one will have maximums for FICA Social Security Wages
remaining_ss_wages = FICA_SS_MAX_WAGE - salary if (FICA_SS_MAX_WAGE - 2 * salary < salary) else salary
remaining_m_wages = FICA_M_MAX_WAGE - salary if (FICA_M_MAX_WAGE - 2 * salary < salary) else salary
self._log('2016 tax second payslip:')
payslip = self._createPayslip(employee, '2016-02-01', '2016-02-29') # 2016 is a leap year
payslip.compute_sheet()
cats = self._getCategories(payslip)
self.assertPayrollEqual(cats['FICA_EMP_SS_WAGES'], remaining_ss_wages)
self.assertPayrollEqual(cats['FICA_EMP_SS'], cats['FICA_EMP_SS_WAGES'] * FICA_SS)
self.assertPayrollEqual(cats['FICA_EMP_M_WAGES'], remaining_m_wages)
self.assertPayrollEqual(cats['FICA_EMP_M'], cats['FICA_EMP_M_WAGES'] * FICA_M)
self.assertPayrollEqual(cats['FICA_EMP_M_ADD_WAGES'], 0.0)
self.assertPayrollEqual(cats['FICA_EMP_M_ADD'], 0.0)
self.assertPayrollEqual(cats['FICA_COMP_SS'], cats['FICA_EMP_SS'])
self.assertPayrollEqual(cats['FICA_COMP_M'], cats['FICA_EMP_M'])
self.assertPayrollEqual(cats['FUTA_WAGES'], 0)
self.assertPayrollEqual(cats['FUTA'], 0)
process_payslip(payslip)
# Make a new payslip, this one will have reached Medicare Additional (employee only)
self._log('2016 tax third payslip:')
payslip = self._createPayslip(employee, '2016-03-01', '2016-03-31')
payslip.compute_sheet()
cats = self._getCategories(payslip)
self.assertPayrollEqual(cats['FICA_EMP_M_WAGES'], salary)
self.assertPayrollEqual(cats['FICA_EMP_M_ADD_WAGES'], FICA_M_ADD_START_WAGE - (salary * 2)) # aka 40k
self.assertPayrollEqual(cats['FICA_EMP_M_ADD'], cats['FICA_EMP_M_ADD_WAGES'] * FICA_M_ADD)
process_payslip(payslip)
# Make a new payslip, this one will have all salary as Medicare Additional
self._log('2016 tax fourth payslip:')
payslip = self._createPayslip(employee, '2016-04-01', '2016-04-30')
payslip.compute_sheet()
cats = self._getCategories(payslip)
self.assertPayrollEqual(cats['FICA_EMP_M_WAGES'], salary)
self.assertPayrollEqual(cats['FICA_EMP_M_ADD_WAGES'], salary)
self.assertPayrollEqual(cats['FICA_EMP_M_ADD'], cats['FICA_EMP_M_ADD_WAGES'] * FICA_M_ADD)
process_payslip(payslip)
def test_2016_fed_income_withholding_single(self):
salary = 6000.00
schedule_pay = 'monthly'
w4_allowances = 3
w4_allowance_amt = 337.50 * w4_allowances
adjusted_salary = salary - w4_allowance_amt # should be 4987.50, but would work over a wide value for the rate
###
# Single MONTHLY form Publication 15
expected_withholding = self.float_round(-(431.95 + ((adjusted_salary - 3325) * 0.25)), self.payroll_digits)
employee = self._createEmployee()
contract = self._createContract(employee, salary, schedule_pay, w4_allowances, 'single')
self._log('2016 fed income single payslip: adjusted_salary: ' + str(adjusted_salary))
payslip = self._createPayslip(employee, '2016-01-01', '2016-01-31')
payslip.compute_sheet()
cats = self._getCategories(payslip)
self.assertPayrollEqual(cats['FED_INC_WITHHOLD'], expected_withholding)
def test_2016_fed_income_withholding_married_as_single(self):
salary = 500.00
schedule_pay = 'weekly'
w4_allowances = 1
w4_allowance_amt = 77.90 * w4_allowances
adjusted_salary = salary - w4_allowance_amt # should be 422.10, but would work over a wide value for the rate
###
# Single MONTHLY form Publication 15
expected_withholding = self.float_round(-(17.90 + ((adjusted_salary - 222) * 0.15)), self.payroll_digits)
employee = self._createEmployee()
contract = self._createContract(employee, salary, schedule_pay, w4_allowances, 'married_as_single')
self._log('2016 fed income married_as_single payslip: adjusted_salary: ' + str(adjusted_salary))
payslip = self._createPayslip(employee, '2016-01-01', '2016-01-31')
payslip.compute_sheet()
cats = self._getCategories(payslip)
self.assertPayrollEqual(cats['FED_INC_WITHHOLD'], expected_withholding)
def test_2016_fed_income_withholding_married(self):
salary = 14000.00
schedule_pay = 'bi-weekly'
w4_allowances = 2
w4_allowance_amt = 155.80 * w4_allowances
adjusted_salary = salary - w4_allowance_amt # should be 1368.84, but would work over a wide value for the rate
###
# Single MONTHLY form Publication 15
expected_withholding = self.float_round(-(1992.05 + ((adjusted_salary - 9231) * 0.33)), self.payroll_digits)
employee = self._createEmployee()
contract = self._createContract(employee, salary, schedule_pay, w4_allowances, 'married')
self._log('2016 fed income married payslip: adjusted_salary: ' + str(adjusted_salary))
payslip = self._createPayslip(employee, '2016-01-01', '2016-01-31')
payslip.compute_sheet()
cats = self._getCategories(payslip)
self.assertPayrollEqual(cats['FED_INC_WITHHOLD'], expected_withholding)
def test_2016_taxes_with_external(self):
## tax rates
FICA_SS = -0.062
FICA_M = -0.0145
FUTA = -self.FUTA_RATE_NORMAL_2016 / 100.0
FICA_M_ADD = -0.009
## tax maximums
FICA_SS_MAX_WAGE = 118500.0
FICA_M_MAX_WAGE = self.float_info.max
FICA_M_ADD_START_WAGE = 200000.0
FUTA_MAX_WAGE = 7000.0
# social security salary
salary = FICA_M_ADD_START_WAGE
external_wages = 6000.0
employee = self._createEmployee()
contract = self._createContract(employee, salary, external_wages=external_wages)
self._log('2016 tax first payslip:')
payslip = self._createPayslip(employee, '2016-01-01', '2016-01-31')
payslip.compute_sheet()
cats = self._getCategories(payslip)
self.assertPayrollEqual(cats['FICA_EMP_SS_WAGES'], FICA_SS_MAX_WAGE - external_wages)
self.assertPayrollEqual(cats['FICA_EMP_SS'], cats['FICA_EMP_SS_WAGES'] * FICA_SS)
self.assertPayrollEqual(cats['FICA_EMP_M_WAGES'], salary)
self.assertPayrollEqual(cats['FICA_EMP_M'], cats['FICA_EMP_M_WAGES'] * FICA_M)
self.assertPayrollEqual(cats['FICA_EMP_M_ADD_WAGES'], 0.0)
self.assertPayrollEqual(cats['FICA_EMP_M_ADD'], cats['FICA_EMP_M_ADD_WAGES'] * FICA_M_ADD)
self.assertPayrollEqual(cats['FICA_COMP_SS'], cats['FICA_EMP_SS'])
self.assertPayrollEqual(cats['FICA_COMP_M'], cats['FICA_EMP_M'])
self.assertPayrollEqual(cats['FUTA_WAGES'], FUTA_MAX_WAGE - external_wages)
self.assertPayrollEqual(cats['FUTA'], cats['FUTA_WAGES'] * FUTA)
def test_2016_taxes_with_full_futa(self):
## tax rates
FICA_SS = -0.062
FICA_M = -0.0145
FUTA = -self.FUTA_RATE_BASIC_2016 / 100.0 # because of state exemption
FICA_M_ADD = -0.009
## tax maximums
FICA_SS_MAX_WAGE = 118500.0
FICA_M_MAX_WAGE = self.float_info.max
FICA_M_ADD_START_WAGE = 200000.0
FUTA_MAX_WAGE = 7000.0
# social security salary
salary = FICA_M_ADD_START_WAGE
employee = self._createEmployee()
contract = self._createContract(employee, salary, futa_type=USHrContract.FUTA_TYPE_BASIC)
self._log('2016 tax first payslip:')
payslip = self._createPayslip(employee, '2016-01-01', '2016-01-31')
payslip.compute_sheet()
cats = self._getCategories(payslip)
self.assertPayrollEqual(cats['FICA_EMP_SS_WAGES'], FICA_SS_MAX_WAGE)
self.assertPayrollEqual(cats['FICA_EMP_SS'], cats['FICA_EMP_SS_WAGES'] * FICA_SS)
self.assertPayrollEqual(cats['FICA_EMP_M_WAGES'], salary)
self.assertPayrollEqual(cats['FICA_EMP_M'], cats['FICA_EMP_M_WAGES'] * FICA_M)
self.assertPayrollEqual(cats['FICA_EMP_M_ADD_WAGES'], 0.0)
self.assertPayrollEqual(cats['FICA_EMP_M_ADD'], cats['FICA_EMP_M_ADD_WAGES'] * FICA_M_ADD)
self.assertPayrollEqual(cats['FICA_COMP_SS'], cats['FICA_EMP_SS'])
self.assertPayrollEqual(cats['FICA_COMP_M'], cats['FICA_EMP_M'])
self.assertPayrollEqual(cats['FUTA_WAGES'], FUTA_MAX_WAGE)
self.assertPayrollEqual(cats['FUTA'], cats['FUTA_WAGES'] * FUTA)
def test_2016_taxes_with_futa_exempt(self):
## tax rates
FICA_SS = -0.062
FICA_M = -0.0145
FUTA = self.FUTA_RATE_EXEMPT_2016 # because of exemption
FICA_M_ADD = -0.009
## tax maximums
FICA_SS_MAX_WAGE = 118500.0
FICA_M_MAX_WAGE = self.float_info.max
FICA_M_ADD_START_WAGE = 200000.0
FUTA_MAX_WAGE = 7000.0
# social security salary
salary = FICA_M_ADD_START_WAGE
employee = self._createEmployee()
contract = self._createContract(employee, salary, futa_type=USHrContract.FUTA_TYPE_EXEMPT)
self._log('2016 tax first payslip:')
payslip = self._createPayslip(employee, '2016-01-01', '2016-01-31')
payslip.compute_sheet()
cats = self._getCategories(payslip)
self.assertPayrollEqual(cats['FICA_EMP_SS_WAGES'], FICA_SS_MAX_WAGE)
self.assertPayrollEqual(cats['FICA_EMP_SS'], cats['FICA_EMP_SS_WAGES'] * FICA_SS)
self.assertPayrollEqual(cats['FICA_EMP_M_WAGES'], salary)
self.assertPayrollEqual(cats['FICA_EMP_M'], cats['FICA_EMP_M_WAGES'] * FICA_M)
self.assertPayrollEqual(cats['FICA_EMP_M_ADD_WAGES'], 0.0)
self.assertPayrollEqual(cats['FICA_EMP_M_ADD'], cats['FICA_EMP_M_ADD_WAGES'] * FICA_M_ADD)
self.assertPayrollEqual(cats['FICA_COMP_SS'], cats['FICA_EMP_SS'])
self.assertPayrollEqual(cats['FICA_COMP_M'], cats['FICA_EMP_M'])
FUTA_WAGES = 0.0
if 'FUTA_WAGES' in cats:
FUTA_WAGES = cats['FUTA_WAGES']
FUTA = 0.0
if 'FUTA' in cats:
FUTA = cats['FUTA']
self.assertPayrollEqual(FUTA_WAGES, 0.0)
self.assertPayrollEqual(FUTA, FUTA_WAGES * FUTA)
def test_2016_fed_income_withholding_nonresident_alien(self):
salary = 3500.00
schedule_pay = 'quarterly'
w4_allowances = 1
w4_allowance_amt = 1012.50 * w4_allowances
nra_adjustment = 562.50 # for quarterly
adjusted_salary = salary - w4_allowance_amt + nra_adjustment # 3050
###
# Single QUARTERLY form Publication 15
expected_withholding = self.float_round(-(231.80 + ((adjusted_salary - 2881) * 0.15)), self.payroll_digits)
employee = self._createEmployee()
contract = self._createContract(employee, salary, schedule_pay, w4_allowances, 'single',
w4_is_nonresident_alien=True)
self._log('2016 fed income single payslip nonresident alien: adjusted_salary: ' + str(adjusted_salary))
payslip = self._createPayslip(employee, '2016-01-01', '2016-01-31')
payslip.compute_sheet()
cats = self._getCategories(payslip)
self.assertPayrollEqual(cats['FED_INC_WITHHOLD'], expected_withholding)
def test_2016_fed_income_additional_withholding(self):
salary = 50000.00
schedule_pay = 'annually'
w4_additional_withholding = 5000.0
w4_allowances = 2
w4_allowance_amt = 4050.0 * w4_allowances
adjusted_salary = salary - w4_allowance_amt # 41900
###
# Single ANNUAL form Publication 15
expected_withholding = self.float_round(-((1855 + ((adjusted_salary - 27100) * 0.15)) + w4_additional_withholding),
self.payroll_digits)
employee = self._createEmployee()
contract = self._createContract(employee, salary, schedule_pay, w4_allowances, 'married',
w4_additional_withholding=w4_additional_withholding)
self._log('2016 fed income married payslip additional withholding: adjusted_salary: ' + str(adjusted_salary))
payslip = self._createPayslip(employee, '2016-01-01', '2016-01-31')
payslip.compute_sheet()
cats = self._getCategories(payslip)
self.assertPayrollEqual(cats['FED_INC_WITHHOLD'], expected_withholding)
def test_2016_taxes_with_w4_exempt(self):
salary = 6000.0
schedule_pay = 'bi-weekly'
w4_allowances = 0
employee = self._createEmployee()
contract = self._createContract(employee, salary, schedule_pay, w4_allowances, '')
self._log('2016 tax w4 exempt payslip:')
payslip = self._createPayslip(employee, '2016-01-01', '2016-01-31')
payslip.compute_sheet()
cats = self._getCategories(payslip)
FED_INC_WITHHOLD = 0.0
if 'FED_INC_WITHHOLD' in cats:
FED_INC_WITHHOLD = cats['FED_INC_WITHHOLD']
self.assertPayrollEqual(FED_INC_WITHHOLD, 0.0)

View File

@@ -1,344 +0,0 @@
from .test_us_payslip import TestUsPayslip, process_payslip
from odoo.addons.l10n_us_hr_payroll.l10n_us_hr_payroll import USHrContract
from sys import float_info
class TestUsPayslip2017(TestUsPayslip):
# FUTA Constants
FUTA_RATE_NORMAL = 0.6
FUTA_RATE_BASIC = 6.0
FUTA_RATE_EXEMPT = 0.0
# Wage caps
FICA_SS_MAX_WAGE = 127200.0
FICA_M_MAX_WAGE = float_info.max
FICA_M_ADD_START_WAGE = 200000.0
FUTA_MAX_WAGE = 7000.0
# Rates
FICA_SS = 6.2 / -100.0
FICA_M = 1.45 / -100.0
FUTA = FUTA_RATE_NORMAL / -100.0
FICA_M_ADD = 0.9 / -100.0
###
# 2017 Taxes and Rates
###
def test_2017_taxes(self):
# salary is high so that second payslip runs over max
# social security salary
salary = 80000.0
employee = self._createEmployee()
self._createContract(employee, salary)
self._log('2016 tax last slip')
payslip = self._createPayslip(employee, '2016-12-01', '2016-12-31')
payslip.compute_sheet()
process_payslip(payslip)
self._log('2017 tax first payslip:')
payslip = self._createPayslip(employee, '2017-01-01', '2017-01-31')
payslip.compute_sheet()
cats = self._getCategories(payslip)
self.assertPayrollEqual(cats['FICA_EMP_SS_WAGES'], salary)
self.assertPayrollEqual(cats['FICA_EMP_SS'], cats['FICA_EMP_SS_WAGES'] * self.FICA_SS)
self.assertPayrollEqual(cats['FICA_EMP_M_WAGES'], salary)
self.assertPayrollEqual(cats['FICA_EMP_M'], cats['FICA_EMP_M_WAGES'] * self.FICA_M)
self.assertPayrollEqual(cats['FICA_EMP_M_ADD_WAGES'], 0.0)
self.assertPayrollEqual(cats['FICA_EMP_M_ADD'], 0.0)
self.assertPayrollEqual(cats['FICA_COMP_SS'], cats['FICA_EMP_SS'])
self.assertPayrollEqual(cats['FICA_COMP_M'], cats['FICA_EMP_M'])
self.assertPayrollEqual(cats['FUTA_WAGES'], self.FUTA_MAX_WAGE)
self.assertPayrollEqual(cats['FUTA'], cats['FUTA_WAGES'] * self.FUTA)
process_payslip(payslip)
# Make a new payslip, this one will have maximums for FICA Social Security Wages
remaining_ss_wages = self.FICA_SS_MAX_WAGE - salary if (self.FICA_SS_MAX_WAGE - 2 * salary < salary) else salary
remaining_m_wages = self.FICA_M_MAX_WAGE - salary if (self.FICA_M_MAX_WAGE - 2 * salary < salary) else salary
self._log('2017 tax second payslip:')
payslip = self._createPayslip(employee, '2017-02-01', '2017-02-28')
payslip.compute_sheet()
cats = self._getCategories(payslip)
self.assertPayrollEqual(cats['FICA_EMP_SS_WAGES'], remaining_ss_wages)
self.assertPayrollEqual(cats['FICA_EMP_SS'], cats['FICA_EMP_SS_WAGES'] * self.FICA_SS)
self.assertPayrollEqual(cats['FICA_EMP_M_WAGES'], remaining_m_wages)
self.assertPayrollEqual(cats['FICA_EMP_M'], cats['FICA_EMP_M_WAGES'] * self.FICA_M)
self.assertPayrollEqual(cats['FICA_EMP_M_ADD_WAGES'], 0.0)
self.assertPayrollEqual(cats['FICA_EMP_M_ADD'], 0.0)
self.assertPayrollEqual(cats['FICA_COMP_SS'], cats['FICA_EMP_SS'])
self.assertPayrollEqual(cats['FICA_COMP_M'], cats['FICA_EMP_M'])
self.assertPayrollEqual(cats['FUTA_WAGES'], 0)
self.assertPayrollEqual(cats['FUTA'], 0)
process_payslip(payslip)
# Make a new payslip, this one will have reached Medicare Additional (employee only)
self._log('2017 tax third payslip:')
payslip = self._createPayslip(employee, '2017-03-01', '2017-03-31')
payslip.compute_sheet()
cats = self._getCategories(payslip)
self.assertPayrollEqual(cats['FICA_EMP_M_WAGES'], salary)
self.assertPayrollEqual(cats['FICA_EMP_M_ADD_WAGES'], self.FICA_M_ADD_START_WAGE - (salary * 2)) # aka 40k
self.assertPayrollEqual(cats['FICA_EMP_M_ADD'], cats['FICA_EMP_M_ADD_WAGES'] * self.FICA_M_ADD)
process_payslip(payslip)
# Make a new payslip, this one will have all salary as Medicare Additional
self._log('2017 tax fourth payslip:')
payslip = self._createPayslip(employee, '2017-04-01', '2017-04-30')
payslip.compute_sheet()
cats = self._getCategories(payslip)
self.assertPayrollEqual(cats['FICA_EMP_M_WAGES'], salary)
self.assertPayrollEqual(cats['FICA_EMP_M_ADD_WAGES'], salary)
self.assertPayrollEqual(cats['FICA_EMP_M_ADD'], cats['FICA_EMP_M_ADD_WAGES'] * self.FICA_M_ADD)
process_payslip(payslip)
def test_2017_fed_income_withholding_single(self):
salary = 6000.00
schedule_pay = 'monthly'
w4_allowances = 3
w4_allowance_amt = 337.50 * w4_allowances
adjusted_salary = salary - w4_allowance_amt # should be 4987.50, but would work over a wide value for the rate
###
# Single MONTHLY form Publication 15
expected_withholding = self.float_round(-(435.45 + ((adjusted_salary - 3354) * 0.25)), self.payroll_digits)
employee = self._createEmployee()
self._createContract(employee, salary, schedule_pay, w4_allowances, 'single')
self._log('2017 fed income single payslip: adjusted_salary: ' + str(adjusted_salary))
payslip = self._createPayslip(employee, '2017-01-01', '2017-01-31')
payslip.compute_sheet()
cats = self._getCategories(payslip)
self.assertPayrollEqual(cats['FED_INC_WITHHOLD'], expected_withholding)
def test_2017_fed_income_withholding_married_as_single(self):
salary = 500.00
schedule_pay = 'weekly'
w4_allowances = 1
w4_allowance_amt = 77.90 * w4_allowances
adjusted_salary = salary - w4_allowance_amt # should be 422.10, but would work over a wide value for the rate
###
# Single MONTHLY form Publication 15
expected_withholding = self.float_round(-(18.00 + ((adjusted_salary - 224) * 0.15)), self.payroll_digits)
employee = self._createEmployee()
self._createContract(employee, salary, schedule_pay, w4_allowances, 'married_as_single')
self._log('2017 fed income married_as_single payslip: adjusted_salary: ' + str(adjusted_salary))
payslip = self._createPayslip(employee, '2017-01-01', '2017-01-31')
payslip.compute_sheet()
cats = self._getCategories(payslip)
self.assertPayrollEqual(cats['FED_INC_WITHHOLD'], expected_withholding)
def test_2017_fed_income_withholding_married(self):
salary = 14000.00
schedule_pay = 'bi-weekly'
w4_allowances = 2
w4_allowance_amt = 155.80 * w4_allowances
adjusted_salary = salary - w4_allowance_amt # should be 1368.84, but would work over a wide value for the rate
###
# Single MONTHLY form Publication 15
expected_withholding = self.float_round(-(2008.61 + ((adjusted_salary - 9308) * 0.33)), self.payroll_digits)
employee = self._createEmployee()
self._createContract(employee, salary, schedule_pay, w4_allowances, 'married')
self._log('2017 fed income married payslip: adjusted_salary: ' + str(adjusted_salary))
payslip = self._createPayslip(employee, '2017-01-01', '2017-01-31')
payslip.compute_sheet()
cats = self._getCategories(payslip)
self.assertPayrollEqual(cats['FED_INC_WITHHOLD'], expected_withholding)
def test_2017_taxes_with_external(self):
# social security salary
salary = self.FICA_M_ADD_START_WAGE
external_wages = 6000.0
employee = self._createEmployee()
self._createContract(employee, salary, external_wages=external_wages)
self._log('2017 tax first payslip:')
payslip = self._createPayslip(employee, '2017-01-01', '2017-01-31')
payslip.compute_sheet()
cats = self._getCategories(payslip)
self.assertPayrollEqual(cats['FICA_EMP_SS_WAGES'], self.FICA_SS_MAX_WAGE - external_wages)
self.assertPayrollEqual(cats['FICA_EMP_SS'], cats['FICA_EMP_SS_WAGES'] * self.FICA_SS)
self.assertPayrollEqual(cats['FICA_EMP_M_WAGES'], salary)
self.assertPayrollEqual(cats['FICA_EMP_M'], cats['FICA_EMP_M_WAGES'] * self.FICA_M)
self.assertPayrollEqual(cats['FICA_EMP_M_ADD_WAGES'], 0.0)
self.assertPayrollEqual(cats['FICA_EMP_M_ADD'], cats['FICA_EMP_M_ADD_WAGES'] * self.FICA_M_ADD)
self.assertPayrollEqual(cats['FICA_COMP_SS'], cats['FICA_EMP_SS'])
self.assertPayrollEqual(cats['FICA_COMP_M'], cats['FICA_EMP_M'])
self.assertPayrollEqual(cats['FUTA_WAGES'], self.FUTA_MAX_WAGE - external_wages)
self.assertPayrollEqual(cats['FUTA'], cats['FUTA_WAGES'] * self.FUTA)
def test_2017_taxes_with_full_futa(self):
futa_rate = self.FUTA_RATE_BASIC / -100.0
# social security salary
salary = self.FICA_M_ADD_START_WAGE
employee = self._createEmployee()
self._createContract(employee, salary, futa_type=USHrContract.FUTA_TYPE_BASIC)
self._log('2017 tax first payslip:')
payslip = self._createPayslip(employee, '2017-01-01', '2017-01-31')
payslip.compute_sheet()
cats = self._getCategories(payslip)
self.assertPayrollEqual(cats['FICA_EMP_SS_WAGES'], self.FICA_SS_MAX_WAGE)
self.assertPayrollEqual(cats['FICA_EMP_SS'], cats['FICA_EMP_SS_WAGES'] * self.FICA_SS)
self.assertPayrollEqual(cats['FICA_EMP_M_WAGES'], salary)
self.assertPayrollEqual(cats['FICA_EMP_M'], cats['FICA_EMP_M_WAGES'] * self.FICA_M)
self.assertPayrollEqual(cats['FICA_EMP_M_ADD_WAGES'], 0.0)
self.assertPayrollEqual(cats['FICA_EMP_M_ADD'], cats['FICA_EMP_M_ADD_WAGES'] * self.FICA_M_ADD)
self.assertPayrollEqual(cats['FICA_COMP_SS'], cats['FICA_EMP_SS'])
self.assertPayrollEqual(cats['FICA_COMP_M'], cats['FICA_EMP_M'])
self.assertPayrollEqual(cats['FUTA_WAGES'], self.FUTA_MAX_WAGE)
self.assertPayrollEqual(cats['FUTA'], cats['FUTA_WAGES'] * futa_rate)
def test_2017_taxes_with_futa_exempt(self):
futa_rate = self.FUTA_RATE_EXEMPT / -100.0 # because of exemption
# social security salary
salary = self.FICA_M_ADD_START_WAGE
employee = self._createEmployee()
self._createContract(employee, salary, futa_type=USHrContract.FUTA_TYPE_EXEMPT)
self._log('2017 tax first payslip:')
payslip = self._createPayslip(employee, '2017-01-01', '2017-01-31')
payslip.compute_sheet()
cats = self._getCategories(payslip)
self.assertPayrollEqual(cats['FICA_EMP_SS_WAGES'], self.FICA_SS_MAX_WAGE)
self.assertPayrollEqual(cats['FICA_EMP_SS'], cats['FICA_EMP_SS_WAGES'] * self.FICA_SS)
self.assertPayrollEqual(cats['FICA_EMP_M_WAGES'], salary)
self.assertPayrollEqual(cats['FICA_EMP_M'], cats['FICA_EMP_M_WAGES'] * self.FICA_M)
self.assertPayrollEqual(cats['FICA_EMP_M_ADD_WAGES'], 0.0)
self.assertPayrollEqual(cats['FICA_EMP_M_ADD'], cats['FICA_EMP_M_ADD_WAGES'] * self.FICA_M_ADD)
self.assertPayrollEqual(cats['FICA_COMP_SS'], cats['FICA_EMP_SS'])
self.assertPayrollEqual(cats['FICA_COMP_M'], cats['FICA_EMP_M'])
futa_wages = 0.0
if 'FUTA_WAGES' in cats:
futa_wages = cats['FUTA_WAGES']
futa = 0.0
if 'FUTA' in cats:
futa = cats['FUTA']
self.assertPayrollEqual(futa_wages, 0.0)
self.assertPayrollEqual(futa, futa_wages * futa_rate)
def test_2017_fed_income_withholding_nonresident_alien(self):
salary = 3500.00
schedule_pay = 'quarterly'
w4_allowances = 1
w4_allowance_amt = 1012.50 * w4_allowances
nra_adjustment = 575.00 # for quarterly
adjusted_salary = salary - w4_allowance_amt + nra_adjustment # 3050
###
# Single QUARTERLY form Publication 15
expected_withholding = self.float_round(-(233.10 + ((adjusted_salary - 2906) * 0.15)), self.payroll_digits)
employee = self._createEmployee()
self._createContract(employee, salary, schedule_pay, w4_allowances, 'single',
w4_is_nonresident_alien=True)
self._log('2017 fed income single payslip nonresident alien: adjusted_salary: ' + str(adjusted_salary))
payslip = self._createPayslip(employee, '2017-01-01', '2017-01-31')
payslip.compute_sheet()
cats = self._getCategories(payslip)
self.assertPayrollEqual(cats['FED_INC_WITHHOLD'], expected_withholding)
def test_2017_fed_income_additional_withholding(self):
salary = 50000.00
schedule_pay = 'annually'
w4_additional_withholding = 5000.0
w4_allowances = 2
w4_allowance_amt = 4050.0 * w4_allowances
adjusted_salary = salary - w4_allowance_amt # 41900
###
# Single ANNUAL form Publication 15
expected_withholding = \
self.float_round(-((1865.00 + ((adjusted_salary - 27300) * 0.15)) + w4_additional_withholding),
self.payroll_digits)
employee = self._createEmployee()
self._createContract(employee, salary, schedule_pay, w4_allowances, 'married',
w4_additional_withholding=w4_additional_withholding)
self._log('2017 fed income married payslip additional withholding: adjusted_salary: ' + str(adjusted_salary))
payslip = self._createPayslip(employee, '2017-01-01', '2017-01-31')
payslip.compute_sheet()
cats = self._getCategories(payslip)
self.assertPayrollEqual(cats['FED_INC_WITHHOLD'], expected_withholding)
def test_2017_taxes_with_w4_exempt(self):
salary = 6000.0
schedule_pay = 'bi-weekly'
w4_allowances = 0
employee = self._createEmployee()
self._createContract(employee, salary, schedule_pay, w4_allowances, '')
self._log('2017 tax w4 exempt payslip:')
payslip = self._createPayslip(employee, '2017-01-01', '2017-01-31')
payslip.compute_sheet()
cats = self._getCategories(payslip)
fed_inc_withhold = 0.0
if 'FED_INC_WITHHOLD' in cats:
fed_inc_withhold = cats['FED_INC_WITHHOLD']
self.assertPayrollEqual(fed_inc_withhold, 0.0)

View File

@@ -1,6 +1,6 @@
from .test_us_payslip import TestUsPayslip, process_payslip
from odoo.addons.l10n_us_hr_payroll.l10n_us_hr_payroll import USHrContract
from odoo.addons.l10n_us_hr_payroll.models.l10n_us_hr_payroll import USHrContract
from sys import float_info
@@ -48,16 +48,16 @@ class TestUsPayslip2018(TestUsPayslip):
cats = self._getCategories(payslip)
self.assertPayrollEqual(cats['FICA_EMP_SS_WAGES'], salary)
self.assertPayrollEqual(cats['FICA_EMP_SS'], cats['FICA_EMP_SS_WAGES'] * self.FICA_SS)
self.assertPayrollEqual(cats['FICA_EMP_M_WAGES'], salary)
self.assertPayrollEqual(cats['FICA_EMP_M'], cats['FICA_EMP_M_WAGES'] * self.FICA_M)
self.assertPayrollEqual(cats['FICA_EMP_M_ADD_WAGES'], 0.0)
self.assertPayrollEqual(cats['FICA_EMP_M_ADD'], 0.0)
self.assertPayrollEqual(cats['FICA_COMP_SS'], cats['FICA_EMP_SS'])
self.assertPayrollEqual(cats['FICA_COMP_M'], cats['FICA_EMP_M'])
self.assertPayrollEqual(cats['FUTA_WAGES'], self.FUTA_MAX_WAGE)
self.assertPayrollEqual(cats['FUTA'], cats['FUTA_WAGES'] * self.FUTA)
self.assertPayrollEqual(cats['WAGE_US_FICA_SS'], salary)
self.assertPayrollEqual(cats['EE_US_FICA_SS'], cats['WAGE_US_FICA_SS'] * self.FICA_SS)
self.assertPayrollEqual(cats['WAGE_US_FICA_M'], salary)
self.assertPayrollEqual(cats['EE_US_FICA_M'], cats['WAGE_US_FICA_M'] * self.FICA_M)
self.assertPayrollEqual(cats['WAGE_US_FICA_M_ADD'], 0.0)
self.assertPayrollEqual(cats['EE_US_FICA_M_ADD'], 0.0)
self.assertPayrollEqual(cats['ER_US_FICA_SS'], cats['EE_US_FICA_SS'])
self.assertPayrollEqual(cats['ER_US_FICA_M'], cats['EE_US_FICA_M'])
self.assertPayrollEqual(cats['WAGE_US_FUTA'], self.FUTA_MAX_WAGE)
self.assertPayrollEqual(cats['ER_US_FUTA'], cats['WAGE_US_FUTA'] * self.FUTA)
process_payslip(payslip)
@@ -73,16 +73,16 @@ class TestUsPayslip2018(TestUsPayslip):
cats = self._getCategories(payslip)
self.assertPayrollEqual(cats['FICA_EMP_SS_WAGES'], remaining_ss_wages)
self.assertPayrollEqual(cats['FICA_EMP_SS'], cats['FICA_EMP_SS_WAGES'] * self.FICA_SS)
self.assertPayrollEqual(cats['FICA_EMP_M_WAGES'], remaining_m_wages)
self.assertPayrollEqual(cats['FICA_EMP_M'], cats['FICA_EMP_M_WAGES'] * self.FICA_M)
self.assertPayrollEqual(cats['FICA_EMP_M_ADD_WAGES'], 0.0)
self.assertPayrollEqual(cats['FICA_EMP_M_ADD'], 0.0)
self.assertPayrollEqual(cats['FICA_COMP_SS'], cats['FICA_EMP_SS'])
self.assertPayrollEqual(cats['FICA_COMP_M'], cats['FICA_EMP_M'])
self.assertPayrollEqual(cats['FUTA_WAGES'], 0)
self.assertPayrollEqual(cats['FUTA'], 0)
self.assertPayrollEqual(cats['WAGE_US_FICA_SS'], remaining_ss_wages)
self.assertPayrollEqual(cats['EE_US_FICA_SS'], cats['WAGE_US_FICA_SS'] * self.FICA_SS)
self.assertPayrollEqual(cats['WAGE_US_FICA_M'], remaining_m_wages)
self.assertPayrollEqual(cats['EE_US_FICA_M'], cats['WAGE_US_FICA_M'] * self.FICA_M)
self.assertPayrollEqual(cats['WAGE_US_FICA_M_ADD'], 0.0)
self.assertPayrollEqual(cats['EE_US_FICA_M_ADD'], 0.0)
self.assertPayrollEqual(cats['ER_US_FICA_SS'], cats['EE_US_FICA_SS'])
self.assertPayrollEqual(cats['ER_US_FICA_M'], cats['EE_US_FICA_M'])
self.assertPayrollEqual(cats['WAGE_US_FUTA'], 0)
self.assertPayrollEqual(cats['ER_US_FUTA'], 0)
process_payslip(payslip)
@@ -95,9 +95,9 @@ class TestUsPayslip2018(TestUsPayslip):
cats = self._getCategories(payslip)
self.assertPayrollEqual(cats['FICA_EMP_M_WAGES'], salary)
self.assertPayrollEqual(cats['FICA_EMP_M_ADD_WAGES'], self.FICA_M_ADD_START_WAGE - (salary * 2)) # aka 40k
self.assertPayrollEqual(cats['FICA_EMP_M_ADD'], cats['FICA_EMP_M_ADD_WAGES'] * self.FICA_M_ADD)
self.assertPayrollEqual(cats['WAGE_US_FICA_M'], salary)
self.assertPayrollEqual(cats['WAGE_US_FICA_M_ADD'], self.FICA_M_ADD_START_WAGE - (salary * 2)) # aka 40k
self.assertPayrollEqual(cats['EE_US_FICA_M_ADD'], cats['WAGE_US_FICA_M_ADD'] * self.FICA_M_ADD)
process_payslip(payslip)
@@ -110,9 +110,9 @@ class TestUsPayslip2018(TestUsPayslip):
cats = self._getCategories(payslip)
self.assertPayrollEqual(cats['FICA_EMP_M_WAGES'], salary)
self.assertPayrollEqual(cats['FICA_EMP_M_ADD_WAGES'], salary)
self.assertPayrollEqual(cats['FICA_EMP_M_ADD'], cats['FICA_EMP_M_ADD_WAGES'] * self.FICA_M_ADD)
self.assertPayrollEqual(cats['WAGE_US_FICA_M'], salary)
self.assertPayrollEqual(cats['WAGE_US_FICA_M_ADD'], salary)
self.assertPayrollEqual(cats['EE_US_FICA_M_ADD'], cats['WAGE_US_FICA_M_ADD'] * self.FICA_M_ADD)
process_payslip(payslip)
@@ -136,7 +136,7 @@ class TestUsPayslip2018(TestUsPayslip):
cats = self._getCategories(payslip)
self.assertPayrollEqual(cats['FED_INC_WITHHOLD'], expected_withholding)
self.assertPayrollEqual(cats['EE_US_FED_INC_WITHHOLD'], expected_withholding)
def test_2018_fed_income_withholding_married_as_single(self):
salary = 500.00
@@ -158,7 +158,7 @@ class TestUsPayslip2018(TestUsPayslip):
cats = self._getCategories(payslip)
self.assertPayrollEqual(cats['FED_INC_WITHHOLD'], expected_withholding)
self.assertPayrollEqual(cats['EE_US_FED_INC_WITHHOLD'], expected_withholding)
def test_2018_fed_income_withholding_married(self):
salary = 14000.00
@@ -180,7 +180,7 @@ class TestUsPayslip2018(TestUsPayslip):
cats = self._getCategories(payslip)
self.assertPayrollEqual(cats['FED_INC_WITHHOLD'], expected_withholding)
self.assertPayrollEqual(cats['EE_US_FED_INC_WITHHOLD'], expected_withholding)
def test_2018_taxes_with_external(self):
@@ -199,16 +199,16 @@ class TestUsPayslip2018(TestUsPayslip):
cats = self._getCategories(payslip)
self.assertPayrollEqual(cats['FICA_EMP_SS_WAGES'], self.FICA_SS_MAX_WAGE - external_wages)
self.assertPayrollEqual(cats['FICA_EMP_SS'], cats['FICA_EMP_SS_WAGES'] * self.FICA_SS)
self.assertPayrollEqual(cats['FICA_EMP_M_WAGES'], salary)
self.assertPayrollEqual(cats['FICA_EMP_M'], cats['FICA_EMP_M_WAGES'] * self.FICA_M)
self.assertPayrollEqual(cats['FICA_EMP_M_ADD_WAGES'], 0.0)
self.assertPayrollEqual(cats['FICA_EMP_M_ADD'], cats['FICA_EMP_M_ADD_WAGES'] * self.FICA_M_ADD)
self.assertPayrollEqual(cats['FICA_COMP_SS'], cats['FICA_EMP_SS'])
self.assertPayrollEqual(cats['FICA_COMP_M'], cats['FICA_EMP_M'])
self.assertPayrollEqual(cats['FUTA_WAGES'], self.FUTA_MAX_WAGE - external_wages)
self.assertPayrollEqual(cats['FUTA'], cats['FUTA_WAGES'] * self.FUTA)
self.assertPayrollEqual(cats['WAGE_US_FICA_SS'], self.FICA_SS_MAX_WAGE - external_wages)
self.assertPayrollEqual(cats['EE_US_FICA_SS'], cats['WAGE_US_FICA_SS'] * self.FICA_SS)
self.assertPayrollEqual(cats['WAGE_US_FICA_M'], salary)
self.assertPayrollEqual(cats['EE_US_FICA_M'], cats['WAGE_US_FICA_M'] * self.FICA_M)
self.assertPayrollEqual(cats['WAGE_US_FICA_M_ADD'], 0.0)
self.assertPayrollEqual(cats['EE_US_FICA_M_ADD'], cats['WAGE_US_FICA_M_ADD'] * self.FICA_M_ADD)
self.assertPayrollEqual(cats['ER_US_FICA_SS'], cats['EE_US_FICA_SS'])
self.assertPayrollEqual(cats['ER_US_FICA_M'], cats['EE_US_FICA_M'])
self.assertPayrollEqual(cats['WAGE_US_FUTA'], self.FUTA_MAX_WAGE - external_wages)
self.assertPayrollEqual(cats['ER_US_FUTA'], cats['WAGE_US_FUTA'] * self.FUTA)
def test_2018_taxes_with_full_futa(self):
futa_rate = self.FUTA_RATE_BASIC / -100.0
@@ -226,16 +226,16 @@ class TestUsPayslip2018(TestUsPayslip):
cats = self._getCategories(payslip)
self.assertPayrollEqual(cats['FICA_EMP_SS_WAGES'], self.FICA_SS_MAX_WAGE)
self.assertPayrollEqual(cats['FICA_EMP_SS'], cats['FICA_EMP_SS_WAGES'] * self.FICA_SS)
self.assertPayrollEqual(cats['FICA_EMP_M_WAGES'], salary)
self.assertPayrollEqual(cats['FICA_EMP_M'], cats['FICA_EMP_M_WAGES'] * self.FICA_M)
self.assertPayrollEqual(cats['FICA_EMP_M_ADD_WAGES'], 0.0)
self.assertPayrollEqual(cats['FICA_EMP_M_ADD'], cats['FICA_EMP_M_ADD_WAGES'] * self.FICA_M_ADD)
self.assertPayrollEqual(cats['FICA_COMP_SS'], cats['FICA_EMP_SS'])
self.assertPayrollEqual(cats['FICA_COMP_M'], cats['FICA_EMP_M'])
self.assertPayrollEqual(cats['FUTA_WAGES'], self.FUTA_MAX_WAGE)
self.assertPayrollEqual(cats['FUTA'], cats['FUTA_WAGES'] * futa_rate)
self.assertPayrollEqual(cats['WAGE_US_FICA_SS'], self.FICA_SS_MAX_WAGE)
self.assertPayrollEqual(cats['EE_US_FICA_SS'], cats['WAGE_US_FICA_SS'] * self.FICA_SS)
self.assertPayrollEqual(cats['WAGE_US_FICA_M'], salary)
self.assertPayrollEqual(cats['EE_US_FICA_M'], cats['WAGE_US_FICA_M'] * self.FICA_M)
self.assertPayrollEqual(cats['WAGE_US_FICA_M_ADD'], 0.0)
self.assertPayrollEqual(cats['EE_US_FICA_M_ADD'], cats['WAGE_US_FICA_M_ADD'] * self.FICA_M_ADD)
self.assertPayrollEqual(cats['ER_US_FICA_SS'], cats['EE_US_FICA_SS'])
self.assertPayrollEqual(cats['ER_US_FICA_M'], cats['EE_US_FICA_M'])
self.assertPayrollEqual(cats['WAGE_US_FUTA'], self.FUTA_MAX_WAGE)
self.assertPayrollEqual(cats['ER_US_FUTA'], cats['WAGE_US_FUTA'] * futa_rate)
def test_2018_taxes_with_futa_exempt(self):
futa_rate = self.FUTA_RATE_EXEMPT / -100.0 # because of exemption
@@ -254,21 +254,21 @@ class TestUsPayslip2018(TestUsPayslip):
cats = self._getCategories(payslip)
self.assertPayrollEqual(cats['FICA_EMP_SS_WAGES'], self.FICA_SS_MAX_WAGE)
self.assertPayrollEqual(cats['FICA_EMP_SS'], cats['FICA_EMP_SS_WAGES'] * self.FICA_SS)
self.assertPayrollEqual(cats['FICA_EMP_M_WAGES'], salary)
self.assertPayrollEqual(cats['FICA_EMP_M'], cats['FICA_EMP_M_WAGES'] * self.FICA_M)
self.assertPayrollEqual(cats['FICA_EMP_M_ADD_WAGES'], 0.0)
self.assertPayrollEqual(cats['FICA_EMP_M_ADD'], cats['FICA_EMP_M_ADD_WAGES'] * self.FICA_M_ADD)
self.assertPayrollEqual(cats['FICA_COMP_SS'], cats['FICA_EMP_SS'])
self.assertPayrollEqual(cats['FICA_COMP_M'], cats['FICA_EMP_M'])
self.assertPayrollEqual(cats['WAGE_US_FICA_SS'], self.FICA_SS_MAX_WAGE)
self.assertPayrollEqual(cats['EE_US_FICA_SS'], cats['WAGE_US_FICA_SS'] * self.FICA_SS)
self.assertPayrollEqual(cats['WAGE_US_FICA_M'], salary)
self.assertPayrollEqual(cats['EE_US_FICA_M'], cats['WAGE_US_FICA_M'] * self.FICA_M)
self.assertPayrollEqual(cats['WAGE_US_FICA_M_ADD'], 0.0)
self.assertPayrollEqual(cats['EE_US_FICA_M_ADD'], cats['WAGE_US_FICA_M_ADD'] * self.FICA_M_ADD)
self.assertPayrollEqual(cats['ER_US_FICA_SS'], cats['EE_US_FICA_SS'])
self.assertPayrollEqual(cats['ER_US_FICA_M'], cats['EE_US_FICA_M'])
futa_wages = 0.0
if 'FUTA_WAGES' in cats:
futa_wages = cats['FUTA_WAGES']
if 'WAGE_US_FUTA' in cats:
futa_wages = cats['WAGE_US_FUTA']
futa = 0.0
if 'FUTA' in cats:
futa = cats['FUTA']
if 'ER_US_FUTA' in cats:
futa = cats['ER_US_FUTA']
self.assertPayrollEqual(futa_wages, 0.0)
self.assertPayrollEqual(futa, futa_wages * futa_rate)
@@ -295,7 +295,7 @@ class TestUsPayslip2018(TestUsPayslip):
cats = self._getCategories(payslip)
self.assertPayrollEqual(cats['FED_INC_WITHHOLD'], expected_withholding)
self.assertPayrollEqual(cats['EE_US_FED_INC_WITHHOLD'], expected_withholding)
def test_2018_fed_income_additional_withholding(self):
salary = 50000.00
@@ -322,7 +322,7 @@ class TestUsPayslip2018(TestUsPayslip):
cats = self._getCategories(payslip)
self.assertPayrollEqual(cats['FED_INC_WITHHOLD'], expected_withholding)
self.assertPayrollEqual(cats['EE_US_FED_INC_WITHHOLD'], expected_withholding)
def test_2018_taxes_with_w4_exempt(self):
salary = 6000.0
@@ -339,8 +339,8 @@ class TestUsPayslip2018(TestUsPayslip):
cats = self._getCategories(payslip)
fed_inc_withhold = 0.0
if 'FED_INC_WITHHOLD' in cats:
fed_inc_withhold = cats['FED_INC_WITHHOLD']
if 'EE_US_FED_INC_WITHHOLD' in cats:
fed_inc_withhold = cats['EE_US_FED_INC_WITHHOLD']
self.assertPayrollEqual(fed_inc_withhold, 0.0)
def test_2018_taxes_with_fica_exempt(self):
@@ -358,10 +358,10 @@ class TestUsPayslip2018(TestUsPayslip):
cats = self._getCategories(payslip)
ss_wages = cats.get('FICA_EMP_SS_WAGES', 0.0)
med_wages = cats.get('FICA_EMP_M_WAGES', 0.0)
ss = cats.get('FICA_EMP_SS', 0.0)
med = cats.get('FICA_EMP_M', 0.0)
ss_wages = cats.get('WAGE_US_FICA_SS', 0.0)
med_wages = cats.get('WAGE_US_FICA_M', 0.0)
ss = cats.get('EE_US_FICA_SS', 0.0)
med = cats.get('EE_US_FICA_M', 0.0)
self.assertPayrollEqual(ss_wages, 0.0)
self.assertPayrollEqual(med_wages, 0.0)
self.assertPayrollEqual(ss, 0.0)

View File

@@ -0,0 +1,368 @@
from .test_us_payslip import TestUsPayslip, process_payslip
from odoo.addons.l10n_us_hr_payroll.models.l10n_us_hr_payroll import USHrContract
from sys import float_info
class TestUsPayslip2019(TestUsPayslip):
# FUTA Constants
FUTA_RATE_NORMAL = 0.6
FUTA_RATE_BASIC = 6.0
FUTA_RATE_EXEMPT = 0.0
# Wage caps
FICA_SS_MAX_WAGE = 132900.0
FICA_M_MAX_WAGE = float_info.max
FICA_M_ADD_START_WAGE = 200000.0
FUTA_MAX_WAGE = 7000.0
# Rates
FICA_SS = 6.2 / -100.0
FICA_M = 1.45 / -100.0
FUTA = FUTA_RATE_NORMAL / -100.0
FICA_M_ADD = 0.9 / -100.0
###
# 2019 Taxes and Rates
###
def test_2019_taxes(self):
# salary is high so that second payslip runs over max
# social security salary
salary = 80000.0
employee = self._createEmployee()
self._createContract(employee, salary)
self._log('2018 tax last slip')
payslip = self._createPayslip(employee, '2018-12-01', '2018-12-31')
payslip.compute_sheet()
process_payslip(payslip)
self._log('2019 tax first payslip:')
payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31')
payslip.compute_sheet()
cats = self._getCategories(payslip)
self.assertPayrollEqual(cats['WAGE_US_FICA_SS'], salary)
self.assertPayrollEqual(cats['EE_US_FICA_SS'], cats['WAGE_US_FICA_SS'] * self.FICA_SS)
self.assertPayrollEqual(cats['WAGE_US_FICA_M'], salary)
self.assertPayrollEqual(cats['EE_US_FICA_M'], cats['WAGE_US_FICA_M'] * self.FICA_M)
self.assertPayrollEqual(cats['WAGE_US_FICA_M_ADD'], 0.0)
self.assertPayrollEqual(cats['EE_US_FICA_M_ADD'], 0.0)
self.assertPayrollEqual(cats['ER_US_FICA_SS'], cats['EE_US_FICA_SS'])
self.assertPayrollEqual(cats['ER_US_FICA_M'], cats['EE_US_FICA_M'])
self.assertPayrollEqual(cats['WAGE_US_FUTA'], self.FUTA_MAX_WAGE)
self.assertPayrollEqual(cats['ER_US_FUTA'], cats['WAGE_US_FUTA'] * self.FUTA)
process_payslip(payslip)
# Make a new payslip, this one will have maximums for FICA Social Security Wages
remaining_ss_wages = self.FICA_SS_MAX_WAGE - salary if (self.FICA_SS_MAX_WAGE - 2 * salary < salary) else salary
remaining_m_wages = self.FICA_M_MAX_WAGE - salary if (self.FICA_M_MAX_WAGE - 2 * salary < salary) else salary
self._log('2019 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_FICA_SS'], remaining_ss_wages)
self.assertPayrollEqual(cats['EE_US_FICA_SS'], cats['WAGE_US_FICA_SS'] * self.FICA_SS)
self.assertPayrollEqual(cats['WAGE_US_FICA_M'], remaining_m_wages)
self.assertPayrollEqual(cats['EE_US_FICA_M'], cats['WAGE_US_FICA_M'] * self.FICA_M)
self.assertPayrollEqual(cats['WAGE_US_FICA_M_ADD'], 0.0)
self.assertPayrollEqual(cats['EE_US_FICA_M_ADD'], 0.0)
self.assertPayrollEqual(cats['ER_US_FICA_SS'], cats['EE_US_FICA_SS'])
self.assertPayrollEqual(cats['ER_US_FICA_M'], cats['EE_US_FICA_M'])
self.assertPayrollEqual(cats['WAGE_US_FUTA'], 0)
self.assertPayrollEqual(cats['ER_US_FUTA'], 0)
process_payslip(payslip)
# Make a new payslip, this one will have reached Medicare Additional (employee only)
self._log('2019 tax third payslip:')
payslip = self._createPayslip(employee, '2019-03-01', '2019-03-31')
payslip.compute_sheet()
cats = self._getCategories(payslip)
self.assertPayrollEqual(cats['WAGE_US_FICA_M'], salary)
self.assertPayrollEqual(cats['WAGE_US_FICA_M_ADD'], self.FICA_M_ADD_START_WAGE - (salary * 2)) # aka 40k
self.assertPayrollEqual(cats['EE_US_FICA_M_ADD'], cats['WAGE_US_FICA_M_ADD'] * self.FICA_M_ADD)
process_payslip(payslip)
# Make a new payslip, this one will have all salary as Medicare Additional
self._log('2019 tax fourth payslip:')
payslip = self._createPayslip(employee, '2019-04-01', '2019-04-30')
payslip.compute_sheet()
cats = self._getCategories(payslip)
self.assertPayrollEqual(cats['WAGE_US_FICA_M'], salary)
self.assertPayrollEqual(cats['WAGE_US_FICA_M_ADD'], salary)
self.assertPayrollEqual(cats['EE_US_FICA_M_ADD'], cats['WAGE_US_FICA_M_ADD'] * self.FICA_M_ADD)
process_payslip(payslip)
def test_2019_fed_income_withholding_single(self):
salary = 6000.00
schedule_pay = 'monthly'
w4_allowances = 3
w4_allowance_amt = 350.00 * w4_allowances
adjusted_salary = salary - w4_allowance_amt # should be 4962.60, but would work over a wide value for the rate
###
# Single MONTHLY form Publication 15
expected_withholding = self.float_round(-(378.52 + ((adjusted_salary - 3606) * 0.22)), self.payroll_digits)
employee = self._createEmployee()
self._createContract(employee, salary, schedule_pay, w4_allowances, 'single')
self._log('2019 fed income single payslip: adjusted_salary: ' + str(adjusted_salary))
payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31')
payslip.compute_sheet()
cats = self._getCategories(payslip)
self.assertPayrollEqual(cats['EE_US_FED_INC_WITHHOLD'], expected_withholding)
def test_2019_fed_income_withholding_married_as_single(self):
salary = 500.00
schedule_pay = 'weekly'
w4_allowances = 1
w4_allowance_amt = 80.80 * w4_allowances
adjusted_salary = salary - w4_allowance_amt # should be 420.50, but would work over a wide value for the rate
###
# Single MONTHLY form Publication 15
expected_withholding = self.float_round(-(18.70 + ((adjusted_salary - 260) * 0.12)), self.payroll_digits)
employee = self._createEmployee()
self._createContract(employee, salary, schedule_pay, w4_allowances, 'married_as_single')
self._log('2019 fed income married_as_single payslip: adjusted_salary: ' + str(adjusted_salary))
payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31')
payslip.compute_sheet()
cats = self._getCategories(payslip)
self.assertPayrollEqual(cats['EE_US_FED_INC_WITHHOLD'], expected_withholding)
def test_2019_fed_income_withholding_married(self):
salary = 14000.00
schedule_pay = 'bi-weekly'
w4_allowances = 2
w4_allowance_amt = 161.50 * w4_allowances
adjusted_salary = salary - w4_allowance_amt # should be 13680.80, but would work over a wide value for the rate
###
# Single MONTHLY form Publication 15
expected_withholding = self.float_round(-(2519.06 + ((adjusted_salary - 12817) * 0.32)), self.payroll_digits)
employee = self._createEmployee()
self._createContract(employee, salary, schedule_pay, w4_allowances, 'married')
self._log('2019 fed income married payslip: adjusted_salary: ' + str(adjusted_salary))
payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31')
payslip.compute_sheet()
cats = self._getCategories(payslip)
self.assertPayrollEqual(cats['EE_US_FED_INC_WITHHOLD'], expected_withholding)
def test_2019_taxes_with_external(self):
# social security salary
salary = self.FICA_M_ADD_START_WAGE
external_wages = 6000.0
employee = self._createEmployee()
self._createContract(employee, salary, external_wages=external_wages)
self._log('2019 tax first payslip:')
payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31')
payslip.compute_sheet()
cats = self._getCategories(payslip)
self.assertPayrollEqual(cats['WAGE_US_FICA_SS'], self.FICA_SS_MAX_WAGE - external_wages)
self.assertPayrollEqual(cats['EE_US_FICA_SS'], cats['WAGE_US_FICA_SS'] * self.FICA_SS)
self.assertPayrollEqual(cats['WAGE_US_FICA_M'], salary)
self.assertPayrollEqual(cats['EE_US_FICA_M'], cats['WAGE_US_FICA_M'] * self.FICA_M)
self.assertPayrollEqual(cats['WAGE_US_FICA_M_ADD'], 0.0)
self.assertPayrollEqual(cats['EE_US_FICA_M_ADD'], cats['WAGE_US_FICA_M_ADD'] * self.FICA_M_ADD)
self.assertPayrollEqual(cats['ER_US_FICA_SS'], cats['EE_US_FICA_SS'])
self.assertPayrollEqual(cats['ER_US_FICA_M'], cats['EE_US_FICA_M'])
self.assertPayrollEqual(cats['WAGE_US_FUTA'], self.FUTA_MAX_WAGE - external_wages)
self.assertPayrollEqual(cats['ER_US_FUTA'], cats['WAGE_US_FUTA'] * self.FUTA)
def test_2019_taxes_with_full_futa(self):
futa_rate = self.FUTA_RATE_BASIC / -100.0
# social security salary
salary = self.FICA_M_ADD_START_WAGE
employee = self._createEmployee()
self._createContract(employee, salary, futa_type=USHrContract.FUTA_TYPE_BASIC)
self._log('2019 tax first payslip:')
payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31')
payslip.compute_sheet()
cats = self._getCategories(payslip)
self.assertPayrollEqual(cats['WAGE_US_FICA_SS'], self.FICA_SS_MAX_WAGE)
self.assertPayrollEqual(cats['EE_US_FICA_SS'], cats['WAGE_US_FICA_SS'] * self.FICA_SS)
self.assertPayrollEqual(cats['WAGE_US_FICA_M'], salary)
self.assertPayrollEqual(cats['EE_US_FICA_M'], cats['WAGE_US_FICA_M'] * self.FICA_M)
self.assertPayrollEqual(cats['WAGE_US_FICA_M_ADD'], 0.0)
self.assertPayrollEqual(cats['EE_US_FICA_M_ADD'], cats['WAGE_US_FICA_M_ADD'] * self.FICA_M_ADD)
self.assertPayrollEqual(cats['ER_US_FICA_SS'], cats['EE_US_FICA_SS'])
self.assertPayrollEqual(cats['ER_US_FICA_M'], cats['EE_US_FICA_M'])
self.assertPayrollEqual(cats['WAGE_US_FUTA'], self.FUTA_MAX_WAGE)
self.assertPayrollEqual(cats['ER_US_FUTA'], cats['WAGE_US_FUTA'] * futa_rate)
def test_2019_taxes_with_futa_exempt(self):
futa_rate = self.FUTA_RATE_EXEMPT / -100.0 # because of exemption
# social security salary
salary = self.FICA_M_ADD_START_WAGE
employee = self._createEmployee()
self._createContract(employee, salary, futa_type=USHrContract.FUTA_TYPE_EXEMPT)
self._log('2019 tax first payslip:')
payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31')
payslip.compute_sheet()
cats = self._getCategories(payslip)
self.assertPayrollEqual(cats['WAGE_US_FICA_SS'], self.FICA_SS_MAX_WAGE)
self.assertPayrollEqual(cats['EE_US_FICA_SS'], cats['WAGE_US_FICA_SS'] * self.FICA_SS)
self.assertPayrollEqual(cats['WAGE_US_FICA_M'], salary)
self.assertPayrollEqual(cats['EE_US_FICA_M'], cats['WAGE_US_FICA_M'] * self.FICA_M)
self.assertPayrollEqual(cats['WAGE_US_FICA_M_ADD'], 0.0)
self.assertPayrollEqual(cats['EE_US_FICA_M_ADD'], cats['WAGE_US_FICA_M_ADD'] * self.FICA_M_ADD)
self.assertPayrollEqual(cats['ER_US_FICA_SS'], cats['EE_US_FICA_SS'])
self.assertPayrollEqual(cats['ER_US_FICA_M'], cats['EE_US_FICA_M'])
futa_wages = 0.0
if 'WAGE_US_FUTA' in cats:
futa_wages = cats['WAGE_US_FUTA']
futa = 0.0
if 'ER_US_FUTA' in cats:
futa = cats['ER_US_FUTA']
self.assertPayrollEqual(futa_wages, 0.0)
self.assertPayrollEqual(futa, futa_wages * futa_rate)
def test_2019_fed_income_withholding_nonresident_alien(self):
salary = 3500.00
schedule_pay = 'quarterly'
w4_allowances = 1
w4_allowance_amt = 1050.0 * w4_allowances
nra_adjustment = 2000.0 # for quarterly
adjusted_salary = salary - w4_allowance_amt + nra_adjustment # 4425
###
# Single QUARTERLY form Publication 15
expected_withholding = self.float_round(-(242.50 + ((adjusted_salary - 3375) * 0.12)), self.payroll_digits)
employee = self._createEmployee()
self._createContract(employee, salary, schedule_pay, w4_allowances, 'single',
w4_is_nonresident_alien=True)
self._log('2019 fed income single payslip nonresident alien: adjusted_salary: ' + str(adjusted_salary))
payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31')
payslip.compute_sheet()
cats = self._getCategories(payslip)
self.assertPayrollEqual(cats['EE_US_FED_INC_WITHHOLD'], expected_withholding)
def test_2019_fed_income_additional_withholding(self):
salary = 50000.00
schedule_pay = 'annually'
w4_additional_withholding = 5000.0
w4_allowances = 2
w4_allowance_amt = 4200.0 * w4_allowances
adjusted_salary = salary - w4_allowance_amt # 41700
###
# Single ANNUAL form Publication 15
expected_withholding = \
self.float_round(-((1940.00 + ((adjusted_salary - 31200) * 0.12)) + w4_additional_withholding),
self.payroll_digits)
employee = self._createEmployee()
self._createContract(employee, salary, schedule_pay, w4_allowances, 'married',
w4_additional_withholding=w4_additional_withholding)
self._log('2019 fed income married payslip additional withholding: adjusted_salary: ' + str(adjusted_salary))
payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31')
payslip.compute_sheet()
cats = self._getCategories(payslip)
self.assertPayrollEqual(cats['EE_US_FED_INC_WITHHOLD'], expected_withholding)
def test_2019_taxes_with_w4_exempt(self):
salary = 6000.0
schedule_pay = 'bi-weekly'
w4_allowances = 0
employee = self._createEmployee()
self._createContract(employee, salary, schedule_pay, w4_allowances, '')
self._log('2019 tax w4 exempt payslip:')
payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31')
payslip.compute_sheet()
cats = self._getCategories(payslip)
fed_inc_withhold = 0.0
if 'EE_US_FED_INC_WITHHOLD' in cats:
fed_inc_withhold = cats['EE_US_FED_INC_WITHHOLD']
self.assertPayrollEqual(fed_inc_withhold, 0.0)
def test_2019_taxes_with_fica_exempt(self):
salary = 6000.0
schedule_pay = 'bi-weekly'
w4_allowances = 2
employee = self._createEmployee()
contract = self._createContract(employee, salary, schedule_pay, w4_allowances)
contract.fica_exempt = True
self._log('2019 tax w4 exempt payslip:')
payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31')
payslip.compute_sheet()
cats = self._getCategories(payslip)
ss_wages = cats.get('WAGE_US_FICA_SS', 0.0)
med_wages = cats.get('WAGE_US_FICA_M', 0.0)
ss = cats.get('EE_US_FICA_SS', 0.0)
med = cats.get('EE_US_FICA_M', 0.0)
self.assertPayrollEqual(ss_wages, 0.0)
self.assertPayrollEqual(med_wages, 0.0)
self.assertPayrollEqual(ss, 0.0)
self.assertPayrollEqual(med, 0.0)