diff --git a/l10n_us_hr_payroll/README.rst b/l10n_us_hr_payroll/README.rst index 0ced18a0..8f3669b3 100644 --- a/l10n_us_hr_payroll/README.rst +++ b/l10n_us_hr_payroll/README.rst @@ -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 ======= diff --git a/l10n_us_hr_payroll/__init__.py b/l10n_us_hr_payroll/__init__.py index e50a95b6..cde864ba 100755 --- a/l10n_us_hr_payroll/__init__.py +++ b/l10n_us_hr_payroll/__init__.py @@ -1,3 +1,3 @@ # -*- coding: utf-8 -*- -from . import l10n_us_hr_payroll +from . import models diff --git a/l10n_us_hr_payroll/__manifest__.py b/l10n_us_hr_payroll/__manifest__.py index 50ab5121..e695b180 100755 --- a/l10n_us_hr_payroll/__manifest__.py +++ b/l10n_us_hr_payroll/__manifest__.py @@ -4,7 +4,7 @@ 'author': 'Hibou Corp. ', '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 diff --git a/l10n_us_hr_payroll/data/base.xml b/l10n_us_hr_payroll/data/base.xml index 5a2dabcf..0579e8f3 100755 --- a/l10n_us_hr_payroll/data/base.xml +++ b/l10n_us_hr_payroll/data/base.xml @@ -26,111 +26,58 @@ - FICA Employee Social Security - Wages - FICA_EMP_SS_WAGES + Wage: US FICA Social Security + WAGE_US_FICA_SS - FICA Employee Medicare - Wages - FICA_EMP_M_WAGES + Wage: US FICA Medicare + WAGE_US_FICA_M - FICA Employee Medicare Additional - Wages - FICA_EMP_M_ADD_WAGES + Wage: US FICA Medicare Additional + WAGE_US_FICA_M_ADD - FUTA Federal Unemployment - Wages - FUTA_WAGES + Wage: US FUTA Federal Unemployment + WAGE_US_FUTA - FICA Employee Social Security - FICA_EMP_SS + EE: US FICA Social Security + EE_US_FICA_SS - FICA Employee Medicare - FICA_EMP_M + EE: US FICA Medicare + EE_US_FICA_M - FICA Employee Medicare Additional - FICA_EMP_M_ADD + EE: US FICA Medicare Additional + EE_US_FICA_M_ADD - Federal Income Withholding - FED_INC_WITHHOLD + EE: US Federal Income Tax Withholding + EE_US_FED_INC_WITHHOLD - FICA Company Social Security - FICA_COMP_SS + ER: US FICA Social Security + ER_US_FICA_SS - FICA Company Medicare - FICA_COMP_M + ER: US FICA Medicare + ER_US_FICA_M - FUTA Federal Unemployment - FUTA + ER: US FUTA Federal Unemployment + ER_US_FUTA - - - - - - - - - FICA Company Social Security - FICA_COMP_SS - none - code - result = categories.FICA_EMP_SS - - - - - - - FICA Company Medicare - FICA_COMP_M - none - code - result = categories.FICA_EMP_M - - - - - - - - - - - FICA Company Social Security - FICA_COMP_SS - none - code - result = categories.FICA_EMP_SS - - - - - - - FICA Company Medicare - FICA_COMP_M - none - code - result = categories.FICA_EMP_M - - - - + diff --git a/l10n_us_hr_payroll/data/final.xml b/l10n_us_hr_payroll/data/final.xml index 8f355948..a1ae2fd8 100755 --- a/l10n_us_hr_payroll/data/final.xml +++ b/l10n_us_hr_payroll/data/final.xml @@ -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'), diff --git a/l10n_us_hr_payroll/data/rates.xml b/l10n_us_hr_payroll/data/rates.xml new file mode 100644 index 00000000..6af3f48e --- /dev/null +++ b/l10n_us_hr_payroll/data/rates.xml @@ -0,0 +1,68 @@ + + + + + US FUTA Exempt + US_FUTA_EXEMPT + 0.0 + 2016-01-01 + + + + US FUTA Normal + US_FUTA_NORMAL + 0.6 + 2016-01-01 + + + + US FUTA Basic + US_FUTA_BASIC + 6.0 + 2016-01-01 + + + + + + + US FICA Social Security + US_FICA_SS + 6.2 + 2016-01-01 + 2017-12-31 + + + + US FICA Social Security + US_FICA_SS + 6.2 + 2018-01-01 + 2018-12-31 + + + + US FICA Social Security + US_FICA_SS + 6.2 + 2019-01-01 + 2019-12-31 + + + + + US FICA Medicare + US_FICA_M + 1.45 + 2016-01-01 + + + + US FICA Medicare Additional + US_FICA_M_ADD + 0.9 + 2016-01-01 + 200000.0 + + + \ No newline at end of file diff --git a/l10n_us_hr_payroll/data/rules.xml b/l10n_us_hr_payroll/data/rules.xml new file mode 100755 index 00000000..b0abf7cf --- /dev/null +++ b/l10n_us_hr_payroll/data/rules.xml @@ -0,0 +1,1058 @@ + + + + + + + + + + Wage: US FICA Social Security + WAGE_US_FICA_SS + python + result = not contract.fica_exempt + code + +### +year = int(payslip.dict.date_to[:4]) +ytd = payslip.sum('WAGE_US_FICA_SS', str(year) + '-01-01', str(year+1) + '-01-01') +ytd += contract.external_wages +rate = payslip.dict.get_rate('US_FICA_SS') +remaining = rate.wage_limit_year - ytd + +if remaining <= 0.0: + result = 0 +elif remaining < categories.BASIC: + result = remaining +else: + result = categories.BASIC + + + + + + + Wage: US FICA Medicare + WAGE_US_FICA_M + python + result = not contract.fica_exempt + code + result = categories.BASIC + + + + + + Wage: US FICA Medicare Additional + WAGE_US_FICA_M_ADD + python + result = not contract.fica_exempt + code + +### +rate = payslip.dict.get_rate('US_FICA_M_ADD') +ADD_M = rate.wage_limit_year +year = int(payslip.dict.date_to[:4]) +norm_med_ytd = payslip.sum('WAGE_US_FICA_M', str(year) + '-01-01', str(year+1) + '-01-01') +norm_med_cur = categories.WAGE_US_FICA_M + +if ADD_M > norm_med_ytd: + diff = ADD_M - norm_med_ytd + if norm_med_cur > diff: + result = norm_med_cur - diff + else: + result = 0 # normal condition +else: + result = norm_med_cur # after YTD wages have passed the max + + + + + + + + EE: US FICA Social Security + EE_US_FICA_SS + python + result = not contract.fica_exempt + code + +rate = payslip.dict.get_rate('US_FICA_SS') +result_rate = -rate.rate +result = categories.WAGE_US_FICA_SS + + + + + + + EE: US FICA Medicare + EE_US_FICA_M + python + result = not contract.fica_exempt + code + +rate = payslip.dict.get_rate('US_FICA_M') +result_rate = -rate.rate +result = categories.WAGE_US_FICA_M + + + + + + + EE: US FICA Medicare Additional + EE_US_FICA_M_ADD + python + result = not contract.fica_exempt + code + +rate = payslip.dict.get_rate('US_FICA_M_ADD') +result_rate = -rate.rate +result = categories.WAGE_US_FICA_M_ADD + + + + + + + + + EE: US Federal Income Tax Withholding - Single + EE_US_FED_INC_WITHHOLD_S + python + result = (contract.w4_filing_status != 'married' and contract.w4_filing_status) + code + +year = int(payslip.dict.date_to[:4]) +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 + +if year == 2018: + ### + # Single WEEKLY + ### + if 'weekly' == schedule_pay: + wages -= allowances * 79.80 + if is_nra: + wages += 151.00 + + if wages > 71 and wages <= 254: + val = 0.00 + ((wages - 71) * 0.10) + + elif wages > 254 and wages <= 815: + val = 18.30 + ((wages - 254) * 0.12) + + elif wages > 815 and wages <= 1658: + val = 85.62 + ((wages - 815) * 0.22) + + elif wages > 1658 and wages <= 3100: + val = 271.08 + ((wages - 1658) * 0.24) + + elif wages > 3100 and wages <= 3917: + val = 617.16 + ((wages - 3100) * 0.32) + + elif wages > 3917 and wages <= 9687: + val = 878.60 + ((wages - 3917) * 0.35) + + elif wages > 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 > 142 and wages <= 509: + val = 0.00 + ((wages - 142) * 0.10) + + elif wages > 509 and wages <= 1631: + val = 36.70 + ((wages - 509) * 0.12) + + elif wages > 1631 and wages <= 3315: + val = 171.34 + ((wages - 1631) * 0.22) + + elif wages > 3315 and wages <= 6200: + val = 541.82 + ((wages - 3315) * 0.24) + + elif wages > 6200 and wages <= 7835: + val = 1234.22 + ((wages - 6200) * 0.32) + + elif wages > 7835 and wages <= 19373: + val = 1757.42 + ((wages - 7835) * 0.35) + + elif wages > 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 > 154 and wages <= 551: + val = 0.00 + ((wages - 154) * 0.10) + + elif wages > 551 and wages <= 1767: + val = 39.70 + ((wages - 551) * 0.12) + + elif wages > 1767 and wages <= 3592: + val = 185.62 + ((wages - 1767) * 0.22) + + elif wages > 3592 and wages <= 6717: + val = 587.12 + ((wages - 3592) * 0.24) + + elif wages > 6717 and wages <= 8488: + val = 1337.12 + ((wages - 6717) * 0.32) + + elif wages > 8488 and wages <= 20988: + val = 1903.84 + ((wages - 8488) * 0.35) + + elif wages > 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 > 308 and wages <= 1102: + val = 0.00 + ((wages - 308) * 0.10) + + elif wages > 1102 and wages <= 3533: + val = 79.40 + ((wages - 1102) * 0.12) + + elif wages > 3533 and wages <= 7183: + val = 371.12 + ((wages - 3533) * 0.22) + + elif wages > 7183 and wages <= 13433: + val = 1174.12 + ((wages - 7183) * 0.24) + + elif wages > 13433 and wages <= 16975: + val = 2674.12 + ((wages - 13433) * 0.32) + + elif wages > 16975 and wages <= 41975: + val = 3807.56 + ((wages - 16975) * 0.35) + + elif wages > 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 > 925 and wages <= 3306: + val = 0.00 + ((wages - 925) * 0.10) + + elif wages > 3306 and wages <= 10600: + val = 238.10 + ((wages - 3306) * 0.12) + + elif wages > 10600 and wages <= 21550: + val = 1113.38 + ((wages - 10600) * 0.22) + + elif wages > 21550 and wages <= 40300: + val = 3522.38 + ((wages - 21550) * 0.24) + + elif wages > 40300 and wages <= 50925: + val = 8022.38 + ((wages - 40300) * 0.32) + + elif wages > 50925 and wages <= 125925: + val = 11422.38 + ((wages - 50925) * 0.35) + + elif wages > 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 > 1850 and wages <= 6613: + val = 0.00 + ((wages - 1850) * 0.10) + + elif wages > 6613 and wages <= 21200: + val = 476.30 + ((wages - 6613) * 0.12) + + elif wages > 21200 and wages <= 43100: + val = 2226.74 + ((wages - 21200) * 0.22) + + elif wages > 43100 and wages <= 80600: + val = 7044.74 + ((wages - 43100) * 0.24) + + elif wages > 80600 and wages <= 101850: + val = 16044.74 + ((wages - 80600) * 0.32) + + elif wages > 101850 and wages <= 251850: + val = 22844.74 + ((wages - 101850) * 0.35) + + elif wages > 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 > 3700 and wages <= 13225: + val = 0.00 + ((wages - 3700) * 0.10) + + elif wages > 13225 and wages <= 42400: + val = 952.50 + ((wages - 13225) * 0.12) + + elif wages > 42400 and wages <= 86200: + val = 4453.50 + ((wages - 42400) * 0.22) + + elif wages > 86200 and wages <= 161200: + val = 14089.50 + ((wages - 86200) * 0.24) + + elif wages > 161200 and wages <= 203700: + val = 32089.50 + ((wages - 161200) * 0.32) + + elif wages > 203700 and wages <= 503700: + val = 45689.50 + ((wages - 203700) * 0.35) + + elif wages > 503700: + val = 150689.50 + ((wages - 503700) * 0.37) + + else: + raise Exception('Invalid schedule_pay="' + schedule_pay + '" for W4 Allowance calculation') +else: + ######## + # 2019 # + ######## + # Single WEEKLY + ### + if 'weekly' == schedule_pay: + wages -= allowances * 80.80 + if is_nra: + wages += 153.80 + + if wages > 73 and wages <= 260: + val = 0.00 + ((wages - 73) * 0.10) + + elif wages > 260 and wages <= 832: + val = 18.70 + ((wages - 260) * 0.12) + + elif wages > 832 and wages <= 1692: + val = 87.34 + ((wages - 832) * 0.22) + + elif wages > 1692 and wages <= 3164: + val = 276.54 + ((wages - 1692) * 0.24) + + elif wages > 3164 and wages <= 3998: + val = 629.82 + ((wages - 3164) * 0.32) + + elif wages > 3998 and wages <= 9887: + val = 896.70 + ((wages - 3998) * 0.35) + + elif wages > 9887: + val = 2957.85 + ((wages - 9887) * 0.37) + + ### + # Single BIWEEKLY + ### + elif 'bi-weekly' == schedule_pay: + wages -= allowances * 161.50 + if is_nra: + wages += 307.70 + + if wages > 146 and wages <= 519: + val = 0.00 + ((wages - 146) * 0.10) + + elif wages > 519 and wages <= 1664: + val = 37.30 + ((wages - 519) * 0.12) + + elif wages > 1664 and wages <= 3385: + val = 174.70 + ((wages - 1664) * 0.22) + + elif wages > 3385 and wages <= 6328: + val = 553.32 + ((wages - 3385) * 0.24) + + elif wages > 6328 and wages <= 7996: + val = 1259.64 + ((wages - 6328) * 0.32) + + elif wages > 7996 and wages <= 19773: + val = 1793.40 + ((wages - 7996) * 0.35) + + elif wages > 19773: + val = 5915.35 + ((wages - 19773) * 0.37) + + ### + # Single SEMIMONTHLY + ### + elif 'semi-monthly' == schedule_pay: + wages -= allowances * 175.00 + if is_nra: + wages += 333.30 + + if wages > 158 and wages <= 563: + val = 0.00 + ((wages - 158) * 0.10) + + elif wages > 563 and wages <= 1803: + val = 40.50 + ((wages - 563) * 0.12) + + elif wages > 1803 and wages <= 3667: + val = 189.30 + ((wages - 1803) * 0.22) + + elif wages > 3667 and wages <= 6855: + val = 599.38 + ((wages - 3667) * 0.24) + + elif wages > 6855 and wages <= 8663: + val = 1364.50 + ((wages - 6855) * 0.32) + + elif wages > 8663 and wages <= 21421: + val = 1943.06 + ((wages - 8663) * 0.35) + + elif wages > 21421: + val = 6408.36 + ((wages - 21421) * 0.37) + + ### + # Single MONTHLY + ### + elif 'monthly' == schedule_pay: + wages -= allowances * 350.00 + if is_nra: + wages += 666.70 + + if wages > 317 and wages <= 1125: + val = 0.00 + ((wages - 317) * 0.10) + + elif wages > 1125 and wages <= 3606: + val = 80.80 + ((wages - 1125) * 0.12) + + elif wages > 3606 and wages <= 7333: + val = 378.52 + ((wages - 3606) * 0.22) + + elif wages > 7333 and wages <= 13710: + val = 1198.46 + ((wages - 7333) * 0.24) + + elif wages > 13710 and wages <= 17325: + val = 2728.94 + ((wages - 13710) * 0.32) + + elif wages > 17325 and wages <= 42842: + val = 3885.74 + ((wages - 17325) * 0.35) + + elif wages > 42842: + val = 12816.69 + ((wages - 42842) * 0.37) + + ### + # Single QUARTERLY + ### + elif 'quarterly' == schedule_pay: + wages -= allowances * 1050.00 + if is_nra: + wages += 2000.0 + + if wages > 950 and wages <= 3375: + val = 0.00 + ((wages - 950) * 0.10) + + elif wages > 3375 and wages <= 10819: + val = 242.50 + ((wages - 3375) * 0.12) + + elif wages > 10819 and wages <= 22000: + val = 1135.78 + ((wages - 10819) * 0.22) + + elif wages > 22000 and wages <= 41131: + val = 3595.60 + ((wages - 22000) * 0.24) + + elif wages > 41131 and wages <= 51975: + val = 8187.04 + ((wages - 41131) * 0.32) + + elif wages > 51975 and wages <= 128525: + val = 11657.12 + ((wages - 51975) * 0.35) + + elif wages > 128525: + val = 38449.62 + ((wages - 128525) * 0.37) + + ### + # Single SEMIANNUAL + ### + elif 'semi-annually' == schedule_pay: + wages -= allowances * 2100.00 + if is_nra: + wages += 4000.00 + + if wages > 1900 and wages <= 6750: + val = 0.00 + ((wages - 1900) * 0.10) + + elif wages > 6750 and wages <= 21638: + val = 485.00 + ((wages - 6750) * 0.12) + + elif wages > 21638 and wages <= 44000: + val = 2271.56 + ((wages - 21638) * 0.22) + + elif wages > 44000 and wages <= 82263: + val = 7191.20 + ((wages - 44000) * 0.24) + + elif wages > 82263 and wages <= 103950: + val = 16374.32 + ((wages - 82263) * 0.32) + + elif wages > 103950 and wages <= 257050: + val = 23314.16 + ((wages - 103950) * 0.35) + + elif wages > 257050: + val = 76899.16 + ((wages - 257050) * 0.37) + + ### + # Single ANNUAL + ### + elif 'annually' == schedule_pay: + wages -= allowances * 4200.00 + if is_nra: + wages += 8000.00 + + if wages > 3800 and wages <= 13500: + val = 0.00 + ((wages - 3800) * 0.10) + + elif wages > 13500 and wages <= 43275: + val = 970.00 + ((wages - 13500) * 0.12) + + elif wages > 43275 and wages <= 88000: + val = 4543.00 + ((wages - 43275) * 0.22) + + elif wages > 88000 and wages <= 164525: + val = 14382.50 + ((wages - 88000) * 0.24) + + elif wages > 164525 and wages <= 207900: + val = 32748.50 + ((wages - 164525) * 0.32) + + elif wages > 207900 and wages <= 514100: + val = 46628.50 + ((wages - 207900) * 0.35) + + elif wages > 514100: + val = 153798.50 + ((wages - 514100) * 0.37) + + else: + raise Exception('Invalid schedule_pay="' + schedule_pay + '" for W4 Allowance calculation') + +result = -(val + additional) + + + + + + + EE: US Federal Income Tax Withholding - Married + EE_US_FED_INC_WITHHOLD_M + python + result = (contract.w4_filing_status == 'married') + code + +year = int(payslip.dict.date_to[:4]) +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 + +if year == 2018: + ### + # Married WEEKLY + ### + if 'weekly' == schedule_pay: + wages -= allowances * 79.80 + if is_nra: + wages += 151.00 + + if wages > 222 and wages <= 588: + val = 0.00 + ((wages - 222) * 0.10) + + elif wages > 588 and wages <= 1711: + val = 36.60 + ((wages - 588) * 0.12) + + elif wages > 1711 and wages <= 3395: + val = 171.36 + ((wages - 1711) * 0.22) + + elif wages > 3395 and wages <= 6280: + val = 541.84 + ((wages - 3395) * 0.24) + + elif wages > 6280 and wages <= 7914: + val = 1234.24 + ((wages - 6280) * 0.32) + + elif wages > 7914 and wages <= 11761: + val = 1757.12 + ((wages - 7914) * 0.35) + + elif wages > 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 > 444 and wages <= 1177: + val = 0.00 + ((wages - 444) * 0.10) + + elif wages > 1177 and wages <= 3421: + val = 73.30 + ((wages - 1177) * 0.12) + + elif wages > 3421 and wages <= 6790: + val = 342.58 + ((wages - 3421) * 0.22) + + elif wages > 6790 and wages <= 12560: + val = 1083.76 + ((wages - 6790) * 0.24) + + elif wages > 12560 and wages <= 15829: + val = 2468.56 + ((wages - 12560) * 0.32) + + elif wages > 15829 and wages <= 23521: + val = 3514.64 + ((wages - 15829) * 0.35) + + elif wages > 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 > 481 and wages <= 1275: + val = 0.00 + ((wages - 481) * 0.10) + + elif wages > 1275 and wages <= 3706: + val = 79.40 + ((wages - 1275) * 0.12) + + elif wages > 3706 and wages <= 7356: + val = 371.12 + ((wages - 3706) * 0.22) + + elif wages > 7356 and wages <= 13606: + val = 1174.12 + ((wages - 7356) * 0.24) + + elif wages > 13606 and wages <= 17148: + val = 2674.12 + ((wages - 13606) * 0.32) + + elif wages > 17148 and wages <= 25481: + val = 3807.56 + ((wages - 17148) * 0.35) + + elif wages > 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 > 963 and wages <= 2550: + val = 0.00 + ((wages - 963) * 0.10) + + elif wages > 2550 and wages <= 7413: + val = 158.70 + ((wages - 2550) * 0.12) + + elif wages > 7413 and wages <= 14713: + val = 742.26 + ((wages - 7413) * 0.22) + + elif wages > 14713 and wages <= 27213: + val = 2348.26 + ((wages - 14713) * 0.24) + + elif wages > 27213 and wages <= 34296: + val = 5348.26 + ((wages - 27213) * 0.32) + + elif wages > 34296 and wages <= 50963: + val = 7614.82 + ((wages - 34296) * 0.35) + + elif wages > 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 > 2888 and wages <= 7650: + val = 0.00 + ((wages - 2888) * 0.10) + + elif wages > 7650 and wages <= 22238: + val = 476.20 + ((wages - 7650) * 0.12) + + elif wages > 22238 and wages <= 44138: + val = 2226.76 + ((wages - 22238) * 0.22) + + elif wages > 44138 and wages <= 81638: + val = 7044.76 + ((wages - 44138) * 0.24) + + elif wages > 81638 and wages <= 102888: + val = 16044.76 + ((wages - 81638) * 0.32) + + elif wages > 102888 and wages <= 152888: + val = 22844.76 + ((wages - 102888) * 0.35) + + elif wages > 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 > 5775 and wages <= 15300: + val = 0.00 + ((wages - 5775) * 0.10) + + elif wages > 15300 and wages <= 44475: + val = 952.50 + ((wages - 15300) * 0.12) + + elif wages > 44475 and wages <= 88275: + val = 4453.50 + ((wages - 44475) * 0.22) + + elif wages > 88275 and wages <= 163275: + val = 14089.50 + ((wages - 88275) * 0.24) + + elif wages > 163275 and wages <= 205775: + val = 32089.50 + ((wages - 163275) * 0.32) + + elif wages > 205775 and wages <= 305775: + val = 45689.50 + ((wages - 205775) * 0.35) + + elif wages > 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 > 11550 and wages <= 30600: + val = 0.00 + ((wages - 11550) * 0.10) + + elif wages > 30600 and wages <= 88950: + val = 1905.00 + ((wages - 30600) * 0.12) + + elif wages > 88950 and wages <= 176550: + val = 8907.00 + ((wages - 88950) * 0.22) + + elif wages > 176550 and wages <= 326550: + val = 28179.00 + ((wages - 176550) * 0.24) + + elif wages > 326550 and wages <= 411550: + val = 64179.00 + ((wages - 326550) * 0.32) + + elif wages > 411550 and wages <= 611550: + val = 91379.00 + ((wages - 411550) * 0.35) + + elif wages > 611550: + val = 161379.00 + ((wages - 611550) * 0.37) + + else: + raise Exception('Invalid schedule_pay="' + schedule_pay + '" for W4 Allowance calculation') +else: + ######## + # 2019 # + ######## + # Married WEEKLY + ### + if 'weekly' == schedule_pay: + wages -= allowances * 80.80 + if is_nra: + wages += 153.80 + + if wages > 227 and wages <= 600: + val = 0.00 + ((wages - 227) * 0.10) + + elif wages > 600 and wages <= 1745: + val = 37.30 + ((wages - 600) * 0.12) + + elif wages > 1745 and wages <= 3465: + val = 174.70 + ((wages - 1745) * 0.22) + + elif wages > 3465 and wages <= 6409: + val = 553.10 + ((wages - 3465) * 0.24) + + elif wages > 6409 and wages <= 8077: + val = 1259.66 + ((wages - 6409) * 0.32) + + elif wages > 8077 and wages <= 12003: + val = 1793.42 + ((wages - 8077) * 0.35) + + elif wages > 12003: + val = 3167.52 + ((wages - 12003) * 0.37) + + ### + # Married BIWEEKLY + ### + elif 'bi-weekly' == schedule_pay: + wages -= allowances * 161.50 + if is_nra: + wages += 307.70 + + if wages > 454 and wages <= 1200: + val = 0.00 + ((wages - 454) * 0.10) + + elif wages > 1200 and wages <= 3490: + val = 74.60 + ((wages - 1200) * 0.12) + + elif wages > 3490 and wages <= 6931: + val = 349.40 + ((wages - 3490) * 0.22) + + elif wages > 6931 and wages <= 12817: + val = 1106.42 + ((wages - 6931) * 0.24) + + elif wages > 12817 and wages <= 16154: + val = 2519.06 + ((wages - 12817) * 0.32) + + elif wages > 16154 and wages <= 24006: + val = 3586.90 + ((wages - 16154) * 0.35) + + elif wages > 24006: + val = 6335.10 + ((wages - 24006) * 0.37) + + ### + # Married SEMIMONTHLY + ### + elif 'semi-monthly' == schedule_pay: + wages -= allowances * 175.00 + if is_nra: + wages += 333.30 + + if wages > 492 and wages <= 1300: + val = 0.00 + ((wages - 492) * 0.10) + + elif wages > 1300 and wages <= 3781: + val = 80.80 + ((wages - 1300) * 0.12) + + elif wages > 3781 and wages <= 7508: + val = 378.52 + ((wages - 3781) * 0.22) + + elif wages > 7508 and wages <= 13885: + val = 1198.46 + ((wages - 7508) * 0.24) + + elif wages > 13885 and wages <= 17500: + val = 2728.94 + ((wages - 13885) * 0.32) + + elif wages > 17500 and wages <= 26006: + val = 3885.74 + ((wages - 17500) * 0.35) + + elif wages > 26006: + val = 6862.84 + ((wages - 26006) * 0.37) + + ### + # Married MONTHLY + ### + elif 'monthly' == schedule_pay: + wages -= allowances * 350.00 + if is_nra: + wages += 666.70 + + if wages > 983 and wages <= 2600: + val = 0.00 + ((wages - 983) * 0.10) + + elif wages > 2600 and wages <= 7563: + val = 161.70 + ((wages - 2600) * 0.12) + + elif wages > 7563 and wages <= 15017: + val = 757.26 + ((wages - 7563) * 0.22) + + elif wages > 15017 and wages <= 27771: + val = 2397.14 + ((wages - 15017) * 0.24) + + elif wages > 27771 and wages <= 35000: + val = 5458.10 + ((wages - 27771) * 0.32) + + elif wages > 35000 and wages <= 50963: + val = 7771.38 + ((wages - 35000) * 0.35) + + elif wages > 52013: + val = 13725.93 + ((wages - 52013) * 0.37) + + ### + # Married QUARTERLY + ### + elif 'quarterly' == schedule_pay: + wages -= allowances * 1050.00 + if is_nra: + wages += 2000.00 + + if wages > 2950 and wages <= 7800: + val = 0.00 + ((wages - 2950) * 0.10) + + elif wages > 7800 and wages <= 22688: + val = 485.00 + ((wages - 7800) * 0.12) + + elif wages > 22688 and wages <= 45050: + val = 2271.56 + ((wages - 22688) * 0.22) + + elif wages > 45050 and wages <= 83313: + val = 7191.20 + ((wages - 45050) * 0.24) + + elif wages > 83313 and wages <= 105000: + val = 16374.32 + ((wages - 83313) * 0.32) + + elif wages > 105000 and wages <= 156038: + val = 23314.16 + ((wages - 105000) * 0.35) + + elif wages > 156038: + val = 41177.46 + ((wages - 156038) * 0.37) + + ### + # Married SEMIANNUAL + ### + elif 'semi-annually' == schedule_pay: + wages -= allowances * 2100.00 + if is_nra: + wages += 4000.00 + + if wages > 5900 and wages <= 15600: + val = 0.00 + ((wages - 5900) * 0.10) + + elif wages > 15600 and wages <= 45375: + val = 970.00 + ((wages - 15600) * 0.12) + + elif wages > 45375 and wages <= 90100: + val = 4543.00 + ((wages - 45375) * 0.22) + + elif wages > 90100 and wages <= 166625: + val = 14382.50 + ((wages - 90100) * 0.24) + + elif wages > 166625 and wages <= 210000: + val = 32748.50 + ((wages - 166625) * 0.32) + + elif wages > 210000 and wages <= 312075: + val = 46628.50 + ((wages - 210000) * 0.35) + + elif wages > 312075: + val = 82354.75 + ((wages - 312075) * 0.37) + + ### + # Married ANNUAL + ### + elif 'annually' == schedule_pay: + wages -= allowances * 4200.00 + if is_nra: + wages += 8000.00 + + if wages > 11800 and wages <= 31200: + val = 0.00 + ((wages - 11800) * 0.10) + + elif wages > 31200 and wages <= 90750: + val = 1940.00 + ((wages - 31200) * 0.12) + + elif wages > 90750 and wages <= 180200: + val = 9086.00 + ((wages - 90750) * 0.22) + + elif wages > 180200 and wages <= 333250: + val = 28765.00 + ((wages - 180200) * 0.24) + + elif wages > 333250 and wages <= 420000: + val = 65497.00 + ((wages - 333250) * 0.32) + + elif wages > 420000 and wages <= 624150: + val = 93257.00 + ((wages - 420000) * 0.35) + + elif wages > 624150: + val = 164709.50 + ((wages - 624150) * 0.37) + + else: + raise Exception('Invalid schedule_pay="' + schedule_pay + '" for W4 Allowance calculation') + +result = -(val + additional) + + + + + + + + Wage: US FUTA Federal Unemployment + WAGE_US_FUTA + python + result = (contract.futa_type != contract.FUTA_TYPE_EXEMPT) + code + +### +rate = payslip.dict.get_futa_rate(contract) +year = int(payslip.dict.date_to[:4]) +ytd = payslip.sum('WAGE_US_FUTA', str(year) + '-01-01', str(year+1) + '-01-01') +ytd += contract.external_wages +remaining = rate.wage_limit_year - ytd +if remaining <= 0.0: + result = 0 +elif remaining < categories.BASIC: + result = remaining +else: + result = categories.BASIC + + + + + + + ER: US FUTA Federal Unemployment + ER_US_FUTA + python + result = (contract.futa_type != contract.FUTA_TYPE_EXEMPT) + code + +year = int(payslip.dict.date_to[:4]) +rate = payslip.dict.get_futa_rate(contract) +result_rate = -(rate.rate) +result = categories.WAGE_US_FUTA + + + + + + + + + + ER: US FICA Social Security + ER_US_FICA_SS + none + code + result = categories.EE_US_FICA_SS + + + + + + + ER: US FICA Medicare + ER_US_FICA_M + none + code + result = categories.EE_US_FICA_M + + + + + + diff --git a/l10n_us_hr_payroll/data/rules_2016.xml b/l10n_us_hr_payroll/data/rules_2016.xml deleted file mode 100755 index bf81af1c..00000000 --- a/l10n_us_hr_payroll/data/rules_2016.xml +++ /dev/null @@ -1,604 +0,0 @@ - - - - - - - - - - FICA Employee Social Security Wages (2016) - FICA_EMP_SS_WAGES_2016 - python - result = (payslip.date_to[:4] == '2016') - code - -### -ytd = payslip.sum('FICA_EMP_SS_WAGES_2016', '2016-01-01', '2017-01-01') -ytd += contract.external_wages -remaining = 118500.0 - ytd -if remaining <= 0.0: - result = 0 -elif remaining < categories.GROSS: - result = remaining -else: - result = categories.GROSS - - - - - - - FICA Employee Medicare Wages (2016) - FICA_EMP_M_WAGES_2016 - python - result = (payslip.date_to[:4] == '2016') - code - result = categories.GROSS - - - - - - FICA Employee Medicare Additional Wages (2016) - FICA_EMP_M_ADD_WAGES_2016 - python - result = (payslip.date_to[:4] == '2016') - code - -### -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 > norm_med_ytd: - diff = ADD_M - norm_med_ytd - if norm_med_cur > diff: - result = norm_med_cur - diff - else: - result = 0 # normal condition -else: - result = norm_med_cur # after YTD wages have passed the max - - - - - - - - FICA Employee Social Security (2016) - FICA_EMP_SS_2016 - python - result = (payslip.date_to[:4] == '2016') - code - -### this should be "rules.FICA_EMP_SS_WAGES_2016", but it doesn't work -result_rate = -6.2 -result = categories.FICA_EMP_SS_WAGES - - - - - - - FICA Employee Medicare (2016) - FICA_EMP_M_2016 - python - result = (payslip.date_to[:4] == '2016') - code - -### this should be "rules.FICA_EMP_M_WAGES_2016", but it doesn't work -result_rate = -1.45 -result = categories.FICA_EMP_M_WAGES - - - - - - - FICA Employee Medicare Additional (2016) - FICA_EMP_M_ADD_2016 - python - result = (payslip.date_to[:4] == '2016') - code - -### 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 - - - - - - - - - Federal Income Withholding - Single (2016) - FED_INC_WITHHOLD_2016_S - python - result = (payslip.date_to[:4] == '2016' and contract.w4_filing_status != 'married' and contract.w4_filing_status) - code - -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 > 43 and wages <= 222: - val = 0.00 + ((wages - 43) * 0.10) - - elif wages > 222 and wages <= 767: - val = 17.90 + ((wages - 222) * 0.15) - - elif wages > 767 and wages <= 1796: - val = 99.65 + ((wages - 767) * 0.25) - - elif wages > 1796 and wages <= 3700: - val = 356.90 + ((wages - 1796) * 0.28) - - elif wages > 3700 and wages <= 7992: - val = 890.02 + ((wages - 3700) * 0.33) - - elif wages > 7992 and wages <= 8025: - val = 2306.38 + ((wages - 7992) * 0.35) - - elif wages > 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 > 87 and wages <= 443: - val = 0.00 + ((wages - 87) * 0.10) - - elif wages > 443 and wages <= 1535: - val = 35.60 + ((wages - 443) * 0.15) - - elif wages > 1535 and wages <= 3592: - val = 199.40 + ((wages - 1535) * 0.25) - - elif wages > 3592 and wages <= 7400: - val = 713.65 + ((wages - 3592) * 0.28) - - elif wages > 7400 and wages <= 15985: - val = 1779.89 + ((wages - 7400) * 0.33) - - elif wages > 15985 and wages <= 16050: - val = 4612.94 + ((wages - 15985) * 0.35) - - elif wages > 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 > 94 and wages <= 480: - val = 0.00 + ((wages - 94) * 0.10) - - elif wages > 480 and wages <= 1663: - val = 38.60 + ((wages - 480) * 0.15) - - elif wages > 1663 and wages <= 3892: - val = 216.05 + ((wages - 1663) * 0.25) - - elif wages > 3892 and wages <= 8017: - val = 773.30 + ((wages - 3892) * 0.28) - - elif wages > 8017 and wages <= 17317: - val = 1928.30 + ((wages - 8017) * 0.33) - - elif wages > 17317 and wages <= 17388: - val = 4997.30 + ((wages - 17317) * 0.35) - - elif wages > 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 > 188 and wages <= 960: - val = 0.00 + ((wages - 188) * 0.10) - - elif wages > 960 and wages <= 3325: - val = 77.20 + ((wages - 960) * 0.15) - - elif wages > 3325 and wages <= 7783: - val = 431.95 + ((wages - 3325) * 0.25) - - elif wages > 7783 and wages <= 16033: - val = 1546.45 + ((wages - 7783) * 0.28) - - elif wages > 16033 and wages <= 34633: - val = 3856.45 + ((wages - 16033) * 0.33) - - elif wages > 34633 and wages <= 34775: - val = 9994.45 + ((wages - 34633) * 0.35) - - elif wages > 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 > 563 and wages <= 2881: - val = 0.00 + ((wages - 563) * 0.10) - - elif wages > 2881 and wages <= 9975: - val = 231.80 + ((wages - 2881) * 0.15) - - elif wages > 9975 and wages <= 23350: - val = 1295.90 + ((wages - 9975) * 0.25) - - elif wages > 23350 and wages <= 48100: - val = 4639.65 + ((wages - 23350) * 0.28) - - elif wages > 48100 and wages <= 103900: - val = 11569.65 + ((wages - 48100) * 0.33) - - elif wages > 103900 and wages <= 104325: - val = 29983.65 + ((wages - 103900) * 0.35) - - elif wages > 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 > 1125 and wages <= 5763: - val = 0.00 + ((wages - 1125) * 0.10) - - elif wages > 5763 and wages <= 19950: - val = 463.80 + ((wages - 5763) * 0.15) - - elif wages > 19950 and wages <= 46700: - val = 2591.85 + ((wages - 19950) * 0.25) - - elif wages > 46700 and wages <= 96200: - val = 9279.35 + ((wages - 46700) * 0.28) - - elif wages > 96200 and wages <= 207800: - val = 23139.35 + ((wages - 96200) * 0.33) - - elif wages > 207800 and wages <= 208650: - val = 59967.35 + ((wages - 207800) * 0.35) - - elif wages > 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 > 2250 and wages <= 11525: - val = 0.00 + ((wages - 2250) * 0.10) - - elif wages > 11525 and wages <= 39900: - val = 927.50 + ((wages - 11525) * 0.15) - - elif wages > 39900 and wages <= 93400: - val = 5183.75 + ((wages - 39900) * 0.25) - - elif wages > 93400 and wages <= 192400: - val = 18558.75 + ((wages - 93400) * 0.28) - - elif wages > 192400 and wages <= 415600: - val = 46278.75 + ((wages - 192400) * 0.33) - - elif wages > 415600 and wages <= 417300: - val = 119934.75 + ((wages - 415600) * 0.35) - - elif wages > 417300: - val = 120529.75 + ((wages - 417300) * 0.396) - -else: - raise Exception('Invalid schedule_pay="' + schedule_pay + '" for W4 Allowance calculation') - -result = -(val + additional) - - - - - - - Federal Income Withholding - Married (2016) - FED_INC_WITHHOLD_2016_M - python - result = (payslip.date_to[:4] == '2016' and contract.w4_filing_status == 'married') - code - -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 > 164 and wages <= 521: - val = 0.00 + ((wages - 164) * 0.10) - - elif wages > 521 and wages <= 1613: - val = 35.70 + ((wages - 521) * 0.15) - - elif wages > 1613 and wages <= 3086: - val = 199.50 + ((wages - 1613) * 0.25) - - elif wages > 3086 and wages <= 4615: - val = 567.75 + ((wages - 3086) * 0.28) - - elif wages > 4615 and wages <= 8113: - val = 995.87 + ((wages - 4615) * 0.33) - - elif wages > 8113 and wages <= 9144: - val = 2150.21 + ((wages - 8113) * 0.35) - - elif wages > 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 > 329 and wages <= 1042: - val = 0.00 + ((wages - 329) * 0.10) - - elif wages > 1042 and wages <= 3225: - val = 71.30 + ((wages - 1042) * 0.15) - - elif wages > 3225 and wages <= 6171: - val = 398.75 + ((wages - 3225) * 0.25) - - elif wages > 6171 and wages <= 9231: - val = 1135.25 + ((wages - 6171) * 0.28) - - elif wages > 9231 and wages <= 16227: - val = 1992.05 + ((wages - 9231) * 0.33) - - elif wages > 16227 and wages <= 18288: - val = 4300.73 + ((wages - 16227) * 0.35) - - elif wages > 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 > 356 and wages <= 1129: - val = 0.00 + ((wages - 356) * 0.10) - - elif wages > 1129 and wages <= 3494: - val = 77.30 + ((wages - 1129) * 0.15) - - elif wages > 3494 and wages <= 6685: - val = 432.05 + ((wages - 3494) * 0.25) - - elif wages > 6685 and wages <= 10000: - val = 1229.80 + ((wages - 6685) * 0.28) - - elif wages > 10000 and wages <= 17579: - val = 2158.00 + ((wages - 10000) * 0.33) - - elif wages > 17579 and wages <= 19813: - val = 4659.07 + ((wages - 17579) * 0.35) - - elif wages > 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 > 713 and wages <= 2258: - val = 0.00 + ((wages - 713) * 0.10) - - elif wages > 2258 and wages <= 6988: - val = 154.50 + ((wages - 2258) * 0.15) - - elif wages > 6988 and wages <= 13371: - val = 864.00 + ((wages - 6988) * 0.25) - - elif wages > 13371 and wages <= 20000: - val = 2459.75 + ((wages - 13371) * 0.28) - - elif wages > 20000 and wages <= 35158: - val = 4315.87 + ((wages - 20000) * 0.33) - - elif wages > 35158 and wages <= 39625: - val = 9318.01 + ((wages - 35158) * 0.35) - - elif wages > 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 > 2138 and wages <= 6775: - val = 0.00 + ((wages - 2138) * 0.10) - - elif wages > 6775 and wages <= 20963: - val = 463.70 + ((wages - 6775) * 0.15) - - elif wages > 20963 and wages <= 40113: - val = 2591.90 + ((wages - 20963) * 0.25) - - elif wages > 40113 and wages <= 60000: - val = 7379.40 + ((wages - 40113) * 0.28) - - elif wages > 60000 and wages <= 105475: - val = 12947.76 + ((wages - 60000) * 0.33) - - elif wages > 105475 and wages <= 118875: - val = 27954.51 + ((wages - 105475) * 0.35) - - elif wages > 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 > 4275 and wages <= 13550: - val = 0.00 + ((wages - 4275) * 0.10) - - elif wages > 13550 and wages <= 41925: - val = 927.50 + ((wages - 13550) * 0.15) - - elif wages > 41925 and wages <= 80225: - val = 5183.75 + ((wages - 41925) * 0.25) - - elif wages > 80225 and wages <= 120000: - val = 14758.75 + ((wages - 80225) * 0.28) - - elif wages > 120000 and wages <= 210950: - val = 25895.75 + ((wages - 120000) * 0.33) - - elif wages > 210950 and wages <= 237750: - val = 55909.25 + ((wages - 210950) * 0.35) - - elif wages > 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 > 8550 and wages <= 27100: - val = 0.00 + ((wages - 8550) * 0.10) - - elif wages > 27100 and wages <= 83850: - val = 1855.00 + ((wages - 27100) * 0.15) - - elif wages > 83850 and wages <= 160450: - val = 10367.50 + ((wages - 83850) * 0.25) - - elif wages > 160450 and wages <= 240000: - val = 29517.50 + ((wages - 160450) * 0.28) - - elif wages > 240000 and wages <= 421900: - val = 51791.50 + ((wages - 240000) * 0.33) - - elif wages > 421900 and wages <= 475500: - val = 111818.50 + ((wages - 421900) * 0.35) - - elif wages > 475500: - val = 130578.50 + ((wages - 475500) * 0.396) - -else: - raise Exception('Invalid schedule_pay="' + schedule_pay + '" for W4 Allowance calculation') - -result = -(val + additional) - - - - - - - - FUTA Federal Unemployment - Wages (2016) - FUTA_WAGES_2016 - python - result = (payslip.date_to[:4] == '2016' and contract.futa_type != contract.FUTA_TYPE_EXEMPT) - code - -### -ytd = payslip.sum('FUTA_WAGES_2016', '2016-01-01', '2017-01-01') -ytd += contract.external_wages -remaining = 7000.0 - ytd -if remaining <= 0.0: - result = 0 -elif remaining < categories.GROSS: - result = remaining -else: - result = categories.GROSS - - - - - - - FUTA Federal Unemployment (2016) - FUTA_2016 - python - result = (payslip.date_to[:4] == '2016' and contract.futa_type != contract.FUTA_TYPE_EXEMPT) - code - -result_rate = -(contract.futa_rate(2016)) -result = categories.FUTA_WAGES - - - - - - - diff --git a/l10n_us_hr_payroll/data/rules_2017.xml b/l10n_us_hr_payroll/data/rules_2017.xml deleted file mode 100755 index d128e7d0..00000000 --- a/l10n_us_hr_payroll/data/rules_2017.xml +++ /dev/null @@ -1,604 +0,0 @@ - - - - - - - - - - FICA Employee Social Security Wages (2017) - FICA_EMP_SS_WAGES_2017 - python - result = (payslip.date_to[:4] == '2017') - code - -### -ytd = payslip.sum('FICA_EMP_SS_WAGES_2017', '2017-01-01', '2018-01-01') -ytd += contract.external_wages -remaining = 127200.0 - ytd -if remaining <= 0.0: - result = 0 -elif remaining < categories.GROSS: - result = remaining -else: - result = categories.GROSS - - - - - - - FICA Employee Medicare Wages (2017) - FICA_EMP_M_WAGES_2017 - python - result = (payslip.date_to[:4] == '2017') - code - result = categories.GROSS - - - - - - FICA Employee Medicare Additional Wages (2017) - FICA_EMP_M_ADD_WAGES_2017 - python - result = (payslip.date_to[:4] == '2017') - code - -### -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 > norm_med_ytd: - diff = ADD_M - norm_med_ytd - if norm_med_cur > diff: - result = norm_med_cur - diff - else: - result = 0 # normal condition -else: - result = norm_med_cur # after YTD wages have passed the max - - - - - - - - FICA Employee Social Security (2017) - FICA_EMP_SS_2017 - python - result = (payslip.date_to[:4] == '2017') - code - -### this should be "rules.FICA_EMP_SS_WAGES_2017", but it doesn't work -result_rate = -6.2 -result = categories.FICA_EMP_SS_WAGES - - - - - - - FICA Employee Medicare (2017) - FICA_EMP_M_2017 - python - result = (payslip.date_to[:4] == '2017') - code - -### this should be "rules.FICA_EMP_M_WAGES_2017", but it doesn't work -result_rate = -1.45 -result = categories.FICA_EMP_M_WAGES - - - - - - - FICA Employee Medicare Additional (2017) - FICA_EMP_M_ADD_2017 - python - result = (payslip.date_to[:4] == '2017') - code - -### 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 - - - - - - - - - Federal Income Withholding - Single (2017) - FED_INC_WITHHOLD_2017_S - python - result = (payslip.date_to[:4] == '2017' and contract.w4_filing_status != 'married' and contract.w4_filing_status) - code - -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 > 44 and wages <= 224: - val = 0.00 + ((wages - 44) * 0.10) - - elif wages > 224 and wages <= 774: - val = 18.00 + ((wages - 224) * 0.15) - - elif wages > 774 and wages <= 1812: - val = 100.50 + ((wages - 774) * 0.25) - - elif wages > 1812 and wages <= 3730: - val = 360.00 + ((wages - 1812) * 0.28) - - elif wages > 3730 and wages <= 8058: - val = 897.04 + ((wages - 3730) * 0.33) - - elif wages > 8058 and wages <= 8090: - val = 2325.28 + ((wages - 8058) * 0.35) - - elif wages > 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 > 88 and wages <= 447: - val = 0.00 + ((wages - 88) * 0.10) - - elif wages > 447 and wages <= 1548: - val = 35.90 + ((wages - 447) * 0.15) - - elif wages > 1548 and wages <= 3623: - val = 201.05 + ((wages - 1548) * 0.25) - - elif wages > 3623 and wages <= 7460: - val = 719.80 + ((wages - 3623) * 0.28) - - elif wages > 7460 and wages <= 16115: - val = 1794.16 + ((wages - 7460) * 0.33) - - elif wages > 16115 and wages <= 16181: - val = 4650.31 + ((wages - 16115) * 0.35) - - elif wages > 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 > 96 and wages <= 484: - val = 0.00 + ((wages - 96) * 0.10) - - elif wages > 484 and wages <= 1677: - val = 38.80 + ((wages - 484) * 0.15) - - elif wages > 1677 and wages <= 3925: - val = 217.75 + ((wages - 1677) * 0.25) - - elif wages > 3925 and wages <= 8081: - val = 779.75 + ((wages - 3925) * 0.28) - - elif wages > 8081 and wages <= 17458: - val = 1943.43 + ((wages - 8081) * 0.33) - - elif wages > 17458 and wages <= 17529: - val = 5037.84 + ((wages - 17458) * 0.35) - - elif wages > 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 > 192 and wages <= 969: - val = 0.00 + ((wages - 192) * 0.10) - - elif wages > 969 and wages <= 3354: - val = 77.70 + ((wages - 969) * 0.15) - - elif wages > 3354 and wages <= 7850: - val = 435.45 + ((wages - 3354) * 0.25) - - elif wages > 7850 and wages <= 16163: - val = 1559.45 + ((wages - 7850) * 0.28) - - elif wages > 16163 and wages <= 34917: - val = 3887.09 + ((wages - 16163) * 0.33) - - elif wages > 34917 and wages <= 35058: - val = 10075.91 + ((wages - 34917) * 0.35) - - elif wages > 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 > 575 and wages <= 2906: - val = 0.00 + ((wages - 575) * 0.10) - - elif wages > 2906 and wages <= 10063: - val = 233.10 + ((wages - 2906) * 0.15) - - elif wages > 10063 and wages <= 23550: - val = 1306.65 + ((wages - 10063) * 0.25) - - elif wages > 23550 and wages <= 48488: - val = 4678.40 + ((wages - 23550) * 0.28) - - elif wages > 48488 and wages <= 104750: - val = 11661.04 + ((wages - 48488) * 0.33) - - elif wages > 104750 and wages <= 105175: - val = 30227.50 + ((wages - 104750) * 0.35) - - elif wages > 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 > 1150 and wages <= 5813: - val = 0.00 + ((wages - 1150) * 0.10) - - elif wages > 5813 and wages <= 20125: - val = 466.30 + ((wages - 5813) * 0.15) - - elif wages > 20125 and wages <= 47100: - val = 2613.10 + ((wages - 20125) * 0.25) - - elif wages > 47100 and wages <= 96975: - val = 9356.85 + ((wages - 47100) * 0.28) - - elif wages > 96975 and wages <= 209500: - val = 23321.85 + ((wages - 96975) * 0.33) - - elif wages > 209500 and wages <= 210350: - val = 60455.10 + ((wages - 209500) * 0.35) - - elif wages > 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 > 2300 and wages <= 11625: - val = 0.00 + ((wages - 2300) * 0.10) - - elif wages > 11625 and wages <= 40250: - val = 932.50 + ((wages - 11625) * 0.15) - - elif wages > 40250 and wages <= 94200: - val = 5226.25 + ((wages - 40250) * 0.25) - - elif wages > 94200 and wages <= 193950: - val = 18713.75 + ((wages - 94200) * 0.28) - - elif wages > 193950 and wages <= 419000: - val = 46643.75 + ((wages - 193950) * 0.33) - - elif wages > 419000 and wages <= 420700: - val = 120910.25 + ((wages - 419000) * 0.35) - - elif wages > 420700: - val = 121505.25 + ((wages - 420700) * 0.396) - -else: - raise Exception('Invalid schedule_pay="' + schedule_pay + '" for W4 Allowance calculation') - -result = -(val + additional) - - - - - - - Federal Income Withholding - Married (2017) - FED_INC_WITHHOLD_2017_M - python - result = (payslip.date_to[:4] == '2017' and contract.w4_filing_status == 'married') - code - -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 > 166 and wages <= 525: - val = 0.00 + ((wages - 166) * 0.10) - - elif wages > 525 and wages <= 1626: - val = 35.90 + ((wages - 525) * 0.15) - - elif wages > 1626 and wages <= 3111: - val = 201.05 + ((wages - 1626) * 0.25) - - elif wages > 3111 and wages <= 4654: - val = 572.30 + ((wages - 3111) * 0.28) - - elif wages > 4654 and wages <= 8180: - val = 1004.34 + ((wages - 4654) * 0.33) - - elif wages > 8180 and wages <= 9218: - val = 2167.92 + ((wages - 8180) * 0.35) - - elif wages > 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 > 333 and wages <= 1050: - val = 0.00 + ((wages - 333) * 0.10) - - elif wages > 1050 and wages <= 3252: - val = 71.70 + ((wages - 1050) * 0.15) - - elif wages > 3252 and wages <= 6221: - val = 402.00 + ((wages - 3252) * 0.25) - - elif wages > 6221 and wages <= 9308: - val = 1144.25 + ((wages - 6221) * 0.28) - - elif wages > 9308 and wages <= 16360: - val = 2008.61 + ((wages - 9308) * 0.33) - - elif wages > 16360 and wages <= 18437: - val = 4335.77 + ((wages - 16360) * 0.35) - - elif wages > 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 > 360 and wages <= 1138: - val = 0.00 + ((wages - 360) * 0.10) - - elif wages > 1138 and wages <= 3523: - val = 77.80 + ((wages - 1138) * 0.15) - - elif wages > 3523 and wages <= 6740: - val = 435.55 + ((wages - 3523) * 0.25) - - elif wages > 6740 and wages <= 10083: - val = 1239.80 + ((wages - 6740) * 0.28) - - elif wages > 10083 and wages <= 17723: - val = 2175.84 + ((wages - 10083) * 0.33) - - elif wages > 17723 and wages <= 19973: - val = 4697.04 + ((wages - 17723) * 0.35) - - elif wages > 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 > 721 and wages <= 2275: - val = 0.00 + ((wages - 721) * 0.10) - - elif wages > 2275 and wages <= 7046: - val = 155.40 + ((wages - 2275) * 0.15) - - elif wages > 7046 and wages <= 13479: - val = 871.05 + ((wages - 7046) * 0.25) - - elif wages > 13479 and wages <= 20167: - val = 2479.30 + ((wages - 13479) * 0.28) - - elif wages > 20167 and wages <= 35446: - val = 4351.94 + ((wages - 20167) * 0.33) - - elif wages > 35446 and wages <= 39946: - val = 9394.01 + ((wages - 35446) * 0.35) - - elif wages > 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 > 2163 and wages <= 6825: - val = 0.00 + ((wages - 2163) * 0.10) - - elif wages > 6825 and wages <= 21138: - val = 466.20 + ((wages - 6825) * 0.15) - - elif wages > 21138 and wages <= 40438: - val = 2613.15 + ((wages - 21138) * 0.25) - - elif wages > 40438 and wages <= 60500: - val = 7438.15 + ((wages - 40438) * 0.28) - - elif wages > 60500 and wages <= 106338: - val = 13055.51 + ((wages - 60500) * 0.33) - - elif wages > 106338 and wages <= 119838: - val = 28182.05 + ((wages - 106338) * 0.35) - - elif wages > 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 > 4325 and wages <= 13650: - val = 0.00 + ((wages - 4325) * 0.10) - - elif wages > 13650 and wages <= 42275: - val = 932.50 + ((wages - 13650) * 0.15) - - elif wages > 42275 and wages <= 80875: - val = 5226.25 + ((wages - 42275) * 0.25) - - elif wages > 80875 and wages <= 121000: - val = 14876.25 + ((wages - 80875) * 0.28) - - elif wages > 121000 and wages <= 212675: - val = 26111.25 + ((wages - 121000) * 0.33) - - elif wages > 212675 and wages <= 239675: - val = 56364.00 + ((wages - 212675) * 0.35) - - elif wages > 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 > 8650 and wages <= 27300: - val = 0.00 + ((wages - 8650) * 0.10) - - elif wages > 27300 and wages <= 84550: - val = 1865.00 + ((wages - 27300) * 0.15) - - elif wages > 84550 and wages <= 161750: - val = 10452.50 + ((wages - 84550) * 0.25) - - elif wages > 161750 and wages <= 242000: - val = 29752.50 + ((wages - 161750) * 0.28) - - elif wages > 242000 and wages <= 425350: - val = 52222.50 + ((wages - 242000) * 0.33) - - elif wages > 425350 and wages <= 479350: - val = 112728.00 + ((wages - 425350) * 0.35) - - elif wages > 479350: - val = 131628.00 + ((wages - 479350) * 0.396) - -else: - raise Exception('Invalid schedule_pay="' + schedule_pay + '" for W4 Allowance calculation') - -result = -(val + additional) - - - - - - - - FUTA Federal Unemployment - Wages (2017) - FUTA_WAGES_2017 - python - result = (payslip.date_to[:4] == '2017' and contract.futa_type != contract.FUTA_TYPE_EXEMPT) - code - -### -ytd = payslip.sum('FUTA_WAGES_2017', '2017-01-01', '2018-01-01') -ytd += contract.external_wages -remaining = 7000.0 - ytd -if remaining <= 0.0: - result = 0 -elif remaining < categories.GROSS: - result = remaining -else: - result = categories.GROSS - - - - - - - FUTA Federal Unemployment (2017) - FUTA_2017 - python - result = (payslip.date_to[:4] == '2017' and contract.futa_type != contract.FUTA_TYPE_EXEMPT) - code - -result_rate = -(contract.futa_rate(2017)) -result = categories.FUTA_WAGES - - - - - - - diff --git a/l10n_us_hr_payroll/data/rules_2018.xml b/l10n_us_hr_payroll/data/rules_2018.xml deleted file mode 100755 index def495ee..00000000 --- a/l10n_us_hr_payroll/data/rules_2018.xml +++ /dev/null @@ -1,604 +0,0 @@ - - - - - - - - - - FICA Employee Social Security Wages (2018) - FICA_EMP_SS_WAGES_2018 - python - result = (payslip.date_to[:4] == '2018') and not contract.fica_exempt - code - -### -ytd = payslip.sum('FICA_EMP_SS_WAGES_2018', '2018-01-01', '2019-01-01') -ytd += contract.external_wages -remaining = 128400.0 - ytd -if remaining <= 0.0: - result = 0 -elif remaining < categories.BASIC: - result = remaining -else: - result = categories.BASIC - - - - - - - FICA Employee Medicare Wages (2018) - FICA_EMP_M_WAGES_2018 - python - result = (payslip.date_to[:4] == '2018') and not contract.fica_exempt - code - result = categories.BASIC - - - - - - FICA Employee Medicare Additional Wages (2018) - FICA_EMP_M_ADD_WAGES_2018 - python - result = (payslip.date_to[:4] == '2018') and not contract.fica_exempt - code - -### -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 > norm_med_ytd: - diff = ADD_M - norm_med_ytd - if norm_med_cur > diff: - result = norm_med_cur - diff - else: - result = 0 # normal condition -else: - result = norm_med_cur # after YTD wages have passed the max - - - - - - - - FICA Employee Social Security (2018) - FICA_EMP_SS_2018 - python - result = (payslip.date_to[:4] == '2018') - code - -### this should be "rules.FICA_EMP_SS_WAGES_2018", but it doesn't work -result_rate = -6.2 -result = categories.FICA_EMP_SS_WAGES - - - - - - - FICA Employee Medicare (2018) - FICA_EMP_M_2018 - python - result = (payslip.date_to[:4] == '2018') - code - -### this should be "rules.FICA_EMP_M_WAGES_2018", but it doesn't work -result_rate = -1.45 -result = categories.FICA_EMP_M_WAGES - - - - - - - FICA Employee Medicare Additional (2018) - FICA_EMP_M_ADD_2018 - python - result = (payslip.date_to[:4] == '2018') - code - -### 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 - - - - - - - - - Federal Income Withholding - Single (2018) - FED_INC_WITHHOLD_2018_S - python - result = (payslip.date_to[:4] == '2018' and contract.w4_filing_status != 'married' and contract.w4_filing_status) - code - -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 > 71 and wages <= 254: - val = 0.00 + ((wages - 71) * 0.10) - - elif wages > 254 and wages <= 815: - val = 18.30 + ((wages - 254) * 0.12) - - elif wages > 815 and wages <= 1658: - val = 85.62 + ((wages - 815) * 0.22) - - elif wages > 1658 and wages <= 3100: - val = 271.08 + ((wages - 1658) * 0.24) - - elif wages > 3100 and wages <= 3917: - val = 617.16 + ((wages - 3100) * 0.32) - - elif wages > 3917 and wages <= 9687: - val = 878.60 + ((wages - 3917) * 0.35) - - elif wages > 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 > 142 and wages <= 509: - val = 0.00 + ((wages - 142) * 0.10) - - elif wages > 509 and wages <= 1631: - val = 36.70 + ((wages - 509) * 0.12) - - elif wages > 1631 and wages <= 3315: - val = 171.34 + ((wages - 1631) * 0.22) - - elif wages > 3315 and wages <= 6200: - val = 541.82 + ((wages - 3315) * 0.24) - - elif wages > 6200 and wages <= 7835: - val = 1234.22 + ((wages - 6200) * 0.32) - - elif wages > 7835 and wages <= 19373: - val = 1757.42 + ((wages - 7835) * 0.35) - - elif wages > 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 > 154 and wages <= 551: - val = 0.00 + ((wages - 154) * 0.10) - - elif wages > 551 and wages <= 1767: - val = 39.70 + ((wages - 551) * 0.12) - - elif wages > 1767 and wages <= 3592: - val = 185.62 + ((wages - 1767) * 0.22) - - elif wages > 3592 and wages <= 6717: - val = 587.12 + ((wages - 3592) * 0.24) - - elif wages > 6717 and wages <= 8488: - val = 1337.12 + ((wages - 6717) * 0.32) - - elif wages > 8488 and wages <= 20988: - val = 1903.84 + ((wages - 8488) * 0.35) - - elif wages > 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 > 308 and wages <= 1102: - val = 0.00 + ((wages - 308) * 0.10) - - elif wages > 1102 and wages <= 3533: - val = 79.40 + ((wages - 1102) * 0.12) - - elif wages > 3533 and wages <= 7183: - val = 371.12 + ((wages - 3533) * 0.22) - - elif wages > 7183 and wages <= 13433: - val = 1174.12 + ((wages - 7183) * 0.24) - - elif wages > 13433 and wages <= 16975: - val = 2674.12 + ((wages - 13433) * 0.32) - - elif wages > 16975 and wages <= 41975: - val = 3807.56 + ((wages - 16975) * 0.35) - - elif wages > 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 > 925 and wages <= 3306: - val = 0.00 + ((wages - 925) * 0.10) - - elif wages > 3306 and wages <= 10600: - val = 238.10 + ((wages - 3306) * 0.12) - - elif wages > 10600 and wages <= 21550: - val = 1113.38 + ((wages - 10600) * 0.22) - - elif wages > 21550 and wages <= 40300: - val = 3522.38 + ((wages - 21550) * 0.24) - - elif wages > 40300 and wages <= 50925: - val = 8022.38 + ((wages - 40300) * 0.32) - - elif wages > 50925 and wages <= 125925: - val = 11422.38 + ((wages - 50925) * 0.35) - - elif wages > 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 > 1850 and wages <= 6613: - val = 0.00 + ((wages - 1850) * 0.10) - - elif wages > 6613 and wages <= 21200: - val = 476.30 + ((wages - 6613) * 0.12) - - elif wages > 21200 and wages <= 43100: - val = 2226.74 + ((wages - 21200) * 0.22) - - elif wages > 43100 and wages <= 80600: - val = 7044.74 + ((wages - 43100) * 0.24) - - elif wages > 80600 and wages <= 101850: - val = 16044.74 + ((wages - 80600) * 0.32) - - elif wages > 101850 and wages <= 251850: - val = 22844.74 + ((wages - 101850) * 0.35) - - elif wages > 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 > 3700 and wages <= 13225: - val = 0.00 + ((wages - 3700) * 0.10) - - elif wages > 13225 and wages <= 42400: - val = 952.50 + ((wages - 13225) * 0.12) - - elif wages > 42400 and wages <= 86200: - val = 4453.50 + ((wages - 42400) * 0.22) - - elif wages > 86200 and wages <= 161200: - val = 14089.50 + ((wages - 86200) * 0.24) - - elif wages > 161200 and wages <= 203700: - val = 32089.50 + ((wages - 161200) * 0.32) - - elif wages > 203700 and wages <= 503700: - val = 45689.50 + ((wages - 203700) * 0.35) - - elif wages > 503700: - val = 150689.50 + ((wages - 503700) * 0.37) - -else: - raise Exception('Invalid schedule_pay="' + schedule_pay + '" for W4 Allowance calculation') - -result = -(val + additional) - - - - - - - Federal Income Withholding - Married (2018) - FED_INC_WITHHOLD_2018_M - python - result = (payslip.date_to[:4] == '2018' and contract.w4_filing_status == 'married') - code - -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 > 222 and wages <= 588: - val = 0.00 + ((wages - 222) * 0.10) - - elif wages > 588 and wages <= 1711: - val = 36.60 + ((wages - 588) * 0.12) - - elif wages > 1711 and wages <= 3395: - val = 171.36 + ((wages - 1711) * 0.22) - - elif wages > 3395 and wages <= 6280: - val = 541.84 + ((wages - 3395) * 0.24) - - elif wages > 6280 and wages <= 7914: - val = 1234.24 + ((wages - 6280) * 0.32) - - elif wages > 7914 and wages <= 11761: - val = 1757.12 + ((wages - 7914) * 0.35) - - elif wages > 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 > 444 and wages <= 1177: - val = 0.00 + ((wages - 444) * 0.10) - - elif wages > 1177 and wages <= 3421: - val = 73.30 + ((wages - 1177) * 0.12) - - elif wages > 3421 and wages <= 6790: - val = 342.58 + ((wages - 3421) * 0.22) - - elif wages > 6790 and wages <= 12560: - val = 1083.76 + ((wages - 6790) * 0.24) - - elif wages > 12560 and wages <= 15829: - val = 2468.56 + ((wages - 12560) * 0.32) - - elif wages > 15829 and wages <= 23521: - val = 3514.64 + ((wages - 15829) * 0.35) - - elif wages > 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 > 481 and wages <= 1275: - val = 0.00 + ((wages - 481) * 0.10) - - elif wages > 1275 and wages <= 3706: - val = 79.40 + ((wages - 1275) * 0.12) - - elif wages > 3706 and wages <= 7356: - val = 371.12 + ((wages - 3706) * 0.22) - - elif wages > 7356 and wages <= 13606: - val = 1174.12 + ((wages - 7356) * 0.24) - - elif wages > 13606 and wages <= 17148: - val = 2674.12 + ((wages - 13606) * 0.32) - - elif wages > 17148 and wages <= 25481: - val = 3807.56 + ((wages - 17148) * 0.35) - - elif wages > 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 > 963 and wages <= 2550: - val = 0.00 + ((wages - 963) * 0.10) - - elif wages > 2550 and wages <= 7413: - val = 158.70 + ((wages - 2550) * 0.12) - - elif wages > 7413 and wages <= 14713: - val = 742.26 + ((wages - 7413) * 0.22) - - elif wages > 14713 and wages <= 27213: - val = 2348.26 + ((wages - 14713) * 0.24) - - elif wages > 27213 and wages <= 34296: - val = 5348.26 + ((wages - 27213) * 0.32) - - elif wages > 34296 and wages <= 50963: - val = 7614.82 + ((wages - 34296) * 0.35) - - elif wages > 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 > 2888 and wages <= 7650: - val = 0.00 + ((wages - 2888) * 0.10) - - elif wages > 7650 and wages <= 22238: - val = 476.20 + ((wages - 7650) * 0.12) - - elif wages > 22238 and wages <= 44138: - val = 2226.76 + ((wages - 22238) * 0.22) - - elif wages > 44138 and wages <= 81638: - val = 7044.76 + ((wages - 44138) * 0.24) - - elif wages > 81638 and wages <= 102888: - val = 16044.76 + ((wages - 81638) * 0.32) - - elif wages > 102888 and wages <= 152888: - val = 22844.76 + ((wages - 102888) * 0.35) - - elif wages > 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 > 5775 and wages <= 15300: - val = 0.00 + ((wages - 5775) * 0.10) - - elif wages > 15300 and wages <= 44475: - val = 952.50 + ((wages - 15300) * 0.12) - - elif wages > 44475 and wages <= 88275: - val = 4453.50 + ((wages - 44475) * 0.22) - - elif wages > 88275 and wages <= 163275: - val = 14089.50 + ((wages - 88275) * 0.24) - - elif wages > 163275 and wages <= 205775: - val = 32089.50 + ((wages - 163275) * 0.32) - - elif wages > 205775 and wages <= 305775: - val = 45689.50 + ((wages - 205775) * 0.35) - - elif wages > 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 > 11550 and wages <= 30600: - val = 0.00 + ((wages - 11550) * 0.10) - - elif wages > 30600 and wages <= 88950: - val = 1905.00 + ((wages - 30600) * 0.12) - - elif wages > 88950 and wages <= 176550: - val = 8907.00 + ((wages - 88950) * 0.22) - - elif wages > 176550 and wages <= 326550: - val = 28179.00 + ((wages - 176550) * 0.24) - - elif wages > 326550 and wages <= 411550: - val = 64179.00 + ((wages - 326550) * 0.32) - - elif wages > 411550 and wages <= 611550: - val = 91379.00 + ((wages - 411550) * 0.35) - - elif wages > 611550: - val = 161379.00 + ((wages - 611550) * 0.37) - -else: - raise Exception('Invalid schedule_pay="' + schedule_pay + '" for W4 Allowance calculation') - -result = -(val + additional) - - - - - - - - FUTA Federal Unemployment - Wages (2018) - FUTA_WAGES_2018 - python - result = (payslip.date_to[:4] == '2018' and contract.futa_type != contract.FUTA_TYPE_EXEMPT) - code - -### -ytd = payslip.sum('FUTA_WAGES_2018', '2018-01-01', '2019-01-01') -ytd += contract.external_wages -remaining = 7000.0 - ytd -if remaining <= 0.0: - result = 0 -elif remaining < categories.BASIC: - result = remaining -else: - result = categories.BASIC - - - - - - - FUTA Federal Unemployment (2018) - FUTA_2018 - python - result = (payslip.date_to[:4] == '2018' and contract.futa_type != contract.FUTA_TYPE_EXEMPT) - code - -result_rate = -(contract.futa_rate(2018)) -result = categories.FUTA_WAGES - - - - - - - diff --git a/l10n_us_hr_payroll/models/__init__.py b/l10n_us_hr_payroll/models/__init__.py new file mode 100644 index 00000000..ff687165 --- /dev/null +++ b/l10n_us_hr_payroll/models/__init__.py @@ -0,0 +1 @@ +from . import l10n_us_hr_payroll diff --git a/l10n_us_hr_payroll/l10n_us_hr_payroll.py b/l10n_us_hr_payroll/models/l10n_us_hr_payroll.py similarity index 76% rename from l10n_us_hr_payroll/l10n_us_hr_payroll.py rename to l10n_us_hr_payroll/models/l10n_us_hr_payroll.py index a60fe555..d7d4b4f6 100755 --- a/l10n_us_hr_payroll/l10n_us_hr_payroll.py +++ b/l10n_us_hr_payroll/models/l10n_us_hr_payroll.py @@ -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 diff --git a/l10n_us_hr_payroll/tests/__init__.py b/l10n_us_hr_payroll/tests/__init__.py index 774c98d0..984a9040 100755 --- a/l10n_us_hr_payroll/tests/__init__.py +++ b/l10n_us_hr_payroll/tests/__init__.py @@ -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 diff --git a/l10n_us_hr_payroll/tests/test_us_payslip.py b/l10n_us_hr_payroll/tests/test_us_payslip.py index 76360b5f..6e8248d0 100755 --- a/l10n_us_hr_payroll/tests/test_us_payslip.py +++ b/l10n_us_hr_payroll/tests/test_us_payslip.py @@ -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): diff --git a/l10n_us_hr_payroll/tests/test_us_payslip_2016.py b/l10n_us_hr_payroll/tests/test_us_payslip_2016.py deleted file mode 100755 index 0503d0c4..00000000 --- a/l10n_us_hr_payroll/tests/test_us_payslip_2016.py +++ /dev/null @@ -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) diff --git a/l10n_us_hr_payroll/tests/test_us_payslip_2017.py b/l10n_us_hr_payroll/tests/test_us_payslip_2017.py deleted file mode 100755 index f6fed47e..00000000 --- a/l10n_us_hr_payroll/tests/test_us_payslip_2017.py +++ /dev/null @@ -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) diff --git a/l10n_us_hr_payroll/tests/test_us_payslip_2018.py b/l10n_us_hr_payroll/tests/test_us_payslip_2018.py index 341dd803..3bfffda1 100755 --- a/l10n_us_hr_payroll/tests/test_us_payslip_2018.py +++ b/l10n_us_hr_payroll/tests/test_us_payslip_2018.py @@ -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) diff --git a/l10n_us_hr_payroll/tests/test_us_payslip_2019.py b/l10n_us_hr_payroll/tests/test_us_payslip_2019.py new file mode 100755 index 00000000..000c063b --- /dev/null +++ b/l10n_us_hr_payroll/tests/test_us_payslip_2019.py @@ -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) diff --git a/l10n_us_hr_payroll/l10n_us_hr_payroll_view.xml b/l10n_us_hr_payroll/views/l10n_us_hr_payroll_view.xml similarity index 100% rename from l10n_us_hr_payroll/l10n_us_hr_payroll_view.xml rename to l10n_us_hr_payroll/views/l10n_us_hr_payroll_view.xml