From 0a7804905945c63df10ece15e6ea94b52367d25d Mon Sep 17 00:00:00 2001 From: Jared Kipe Date: Tue, 7 May 2019 16:26:15 -0700 Subject: [PATCH] FIX `l10n_us_nj_hr_payroll` Rates for 2019 and improved test coverage. --- l10n_us_nj_hr_payroll/data/base.xml | 6 + l10n_us_nj_hr_payroll/data/final.xml | 1 + l10n_us_nj_hr_payroll/data/rates.xml | 62 + l10n_us_nj_hr_payroll/data/rules.xml | 1446 ++++++++++++----- l10n_us_nj_hr_payroll/tests/__init__.py | 1 + .../tests/test_us_nj_payslip_2019.py | 179 ++ 6 files changed, 1246 insertions(+), 449 deletions(-) create mode 100755 l10n_us_nj_hr_payroll/tests/test_us_nj_payslip_2019.py diff --git a/l10n_us_nj_hr_payroll/data/base.xml b/l10n_us_nj_hr_payroll/data/base.xml index 4d8da28b..d9c71493 100755 --- a/l10n_us_nj_hr_payroll/data/base.xml +++ b/l10n_us_nj_hr_payroll/data/base.xml @@ -145,6 +145,12 @@ + + ER: US-NJ Workforce Development + ER_US_NJ_WF + + + EE: US-NJ Income Withholding EE_US_NJ_INC_WITHHOLD diff --git a/l10n_us_nj_hr_payroll/data/final.xml b/l10n_us_nj_hr_payroll/data/final.xml index 568bd523..58716a41 100755 --- a/l10n_us_nj_hr_payroll/data/final.xml +++ b/l10n_us_nj_hr_payroll/data/final.xml @@ -18,6 +18,7 @@ ref('hr_payroll_rules_nj_fli_2018'), ref('hr_payroll_rules_nj_wf_wages_2018'), ref('hr_payroll_rules_nj_wf_2018'), + ref('hr_payroll_rules_nj_wf_er'), ])]" name="rule_ids"/> diff --git a/l10n_us_nj_hr_payroll/data/rates.xml b/l10n_us_nj_hr_payroll/data/rates.xml index c8173c3d..315bbe5a 100644 --- a/l10n_us_nj_hr_payroll/data/rates.xml +++ b/l10n_us_nj_hr_payroll/data/rates.xml @@ -52,5 +52,67 @@ 0.0425 2018-01-01 + + + + + + US NJ Unemployment (Company) + ER_US_NJ_UNEMP + 2.6825 + 2019-01-01 + + + + US NJ Unemployment (Employee) + EE_US_NJ_UNEMP + 0.3825 + 2019-01-01 + + + + + US NJ State Disability Insurance (Company) + ER_US_NJ_SDI + 0.5000 + 2019-01-01 + + + + US NJ State Disability Insurance (Employee) + EE_US_NJ_SDI + 0.17 + 2019-01-01 + + + + + US NJ Workforce Development (Company) + ER_US_NJ_WF + 0.1175 + 2019-01-01 + + + US NJ Workforce Development (Employee) + EE_US_NJ_WF + 0.0425 + 2019-01-01 + + + + US NJ Family Leave Insurance (Company) + ER_US_NJ_FLI + 0.00 + 2019-01-01 + + + + US NJ Family Leave Insurance (Employee) + EE_US_NJ_FLI + 0.08 + 2019-01-01 + + + \ No newline at end of file diff --git a/l10n_us_nj_hr_payroll/data/rules.xml b/l10n_us_nj_hr_payroll/data/rules.xml index 45b095dc..94a3af95 100755 --- a/l10n_us_nj_hr_payroll/data/rules.xml +++ b/l10n_us_nj_hr_payroll/data/rules.xml @@ -5,7 +5,7 @@ - + Wage: US-NJ Unemployment Insurance WAGE_US_NJ_UNEMP @@ -18,11 +18,14 @@ year = int(payslip.dict.date_to[:4]) rate = payslip.dict.get_rate('ER_US_NJ_UNEMP') ytd = payslip.sum('WAGE_US_NJ_UNEMP', 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 +if rate.wage_limit_year: + remaining = rate.wage_limit_year - ytd + if remaining <= 0.0: + result = 0 + elif remaining < categories.BASIC: + result = remaining + else: + result = categories.BASIC else: result = categories.BASIC @@ -39,14 +42,14 @@ else: rate = payslip.dict.get_rate('EE_US_NJ_UNEMP') result_rate = -rate.rate -result = categories.BASIC +result = categories.WAGE_US_NJ_UNEMP # result_rate of 0 implies 100% due to bug if result_rate == 0.0: result = 0.0 - + @@ -72,7 +75,7 @@ if result_rate == 0.0: - + Wage: US-NJ State Disability Insurance WAGE_US_NJ_SDI @@ -85,11 +88,14 @@ year = int(payslip.dict.date_to[:4]) rate = payslip.dict.get_rate('ER_US_NJ_SDI') ytd = payslip.sum('WAGE_US_NJ_SDI', 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 +if rate.wage_limit_year: + remaining = rate.wage_limit_year - ytd + if remaining <= 0.0: + result = 0 + elif remaining < categories.BASIC: + result = remaining + else: + result = categories.BASIC else: result = categories.BASIC @@ -106,14 +112,14 @@ else: rate = payslip.dict.get_rate('EE_US_NJ_SDI') result_rate = -rate.rate -result = categories.BASIC +result = categories.WAGE_US_NJ_SDI # result_rate of 0 implies 100% due to bug if result_rate == 0.0: result = 0.0 - + @@ -138,7 +144,7 @@ if result_rate == 0.0: - + Wage: US-NJ Family Leave Insurance WAGE_US_NJ_FLI @@ -151,11 +157,14 @@ year = int(payslip.dict.date_to[:4]) rate = payslip.dict.get_rate('ER_US_NJ_FLI') ytd = payslip.sum('WAGE_US_NJ_FLI', 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 +if rate.wage_limit_year: + remaining = rate.wage_limit_year - ytd + if remaining <= 0.0: + result = 0 + elif remaining < categories.BASIC: + result = remaining + else: + result = categories.BASIC else: result = categories.BASIC @@ -172,15 +181,15 @@ else: rate = payslip.dict.get_rate('EE_US_NJ_FLI') result_rate = -rate.rate -result = categories.BASIC +result = categories.WAGE_US_NJ_FLI - + - + Wage: US-NJ Workforce Development Funds WAGE_US_NJ_WF @@ -193,11 +202,14 @@ year = int(payslip.dict.date_to[:4]) rate = payslip.dict.get_rate('ER_US_NJ_WF') ytd = payslip.sum('WAGE_US_NJ_WF', 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 +if rate.wage_limit_year: + remaining = rate.wage_limit_year - ytd + if remaining <= 0.0: + result = 0 + elif remaining < categories.BASIC: + result = remaining + else: + result = categories.BASIC else: result = categories.BASIC @@ -214,7 +226,26 @@ else: rate = payslip.dict.get_rate('EE_US_NJ_WF') result_rate = -rate.rate -result = categories.BASIC +result = categories.WAGE_US_NJ_WF + +if result_rate == 0.0: + result = 0.0 + + + + + + + + ER: US-NJ Workforce Development Funds + ER_US_NJ_WF + python + result = (contract.futa_type != contract.FUTA_TYPE_BASIC) + code + +rate = payslip.dict.get_rate('ER_US_NJ_WF') +result_rate = -rate.rate +result = categories.WAGE_US_NJ_WF if result_rate == 0.0: result = 0.0 @@ -233,6 +264,7 @@ if result_rate == 0.0: result = True code +year = int(payslip.dict.date_to[:4]) wages = categories.GROSS allowances = contract.nj_njw4_allowances additional_withholding = contract.nj_additional_withholding @@ -250,458 +282,974 @@ if not rate_table: # Tables are found in http://www.state.nj.us/treasury/taxation/pdf/current/njwt.pdf # Tax Rate Tables to calculate income withholding -#### RATE 'A' #### -if rate_table == 'A': - ### WEEKLY ### +if year == 2018: + divisor = 1.0 + #### RATE 'A' #### + if rate_table == 'A': + ### WEEKLY ### + if schedule_pay == 'weekly': + wages -= 19.20 * allowances + tax_rate_table = [ + (384, 0.015, 0.0), + (673, 0.02, 5.76), + (769, 0.039, 11.54), + (1442, 0.061, 15.28), + (9615, 0.07, 56.34), + (float('inf'), 0.099, 628.45), + ] + + ### BI-WEEKLY ### + elif schedule_pay == 'bi-weekly': + wages -= 38.40 * allowances + tax_rate_table = [ + (769, 0.015, 0.0), + (1346, 0.02, 11.54), + (1538, 0.039, 23.08), + (2884, 0.061, 30.56), + (19231, 0.07, 112.67), + (float('inf'), 0.099, 1256.96), + ] + + ### SEMI-MONTHLY ### + elif schedule_pay == 'semi-monthly': + wages -= 41.60 * allowances + tax_rate_table = [ + (833, 0.015, 0.0), + (1458, 0.02, 12.50), + (1666, 0.039, 25.00), + (3125, 0.061, 33.11), + (20833, 0.07, 112.11), + (float('inf'), 0.099, 1361.67), + ] + + ### MONTHLY ### + elif schedule_pay == 'monthly': + wages -= 83.30 * allowances + tax_rate_table = [ + (1666, 0.015, 0.0), + (2916, 0.02, 24.99), + (3333, 0.039, 49.99), + (6250, 0.061, 66.25), + (41667, 0.07, 244.19), + (float('inf'), 0.099, 2723.38), + ] + + ### QUARTERLY ### + elif schedule_pay == 'quarterly': + wages -= 250.00 * allowances + tax_rate_table = [ + (5000, 0.015, 0.0), + (8750, 0.02, 75.00), + (10000, 0.039, 150.00), + (18750, 0.061, 198.75), + (125000, 0.07, 732.50), + (float('inf'), 0.099, 8170.00), + ] + + ### SEMI-ANNUAL ### + elif schedule_pay == 'semi-annual': + wages -= 500 * allowances + tax_rate_table = [ + (10000, 0.015, 0.0), + (17500, 0.02, 150.00), + (20000, 0.039, 300.00), + (37500, 0.061, 397.50), + (250000, 0.07, 1465.00), + (float('inf'), 0.099, 16340.00), + ] + + ### ANNUAL ### + elif schedule_pay == 'annually': + wages -= 1000.00 * allowances + tax_rate_table = [ + (20000, 0.015, 0.0), + (35000, 0.02, 300.00), + (40000, 0.039, 600.00), + (75000, 0.061, 795.00), + (500000, 0.07, 2930.00), + (float('inf'), 0.099, 32680.00), + ] + + #### RATE 'B' #### + elif rate_table == 'B': + ### WEEKLY ### + if schedule_pay == 'weekly': + wages -= 19.20 * allowances + tax_rate_table = [ + (384, 0.015, 0.0), + (961, 0.02, 5.76), + (1346, 0.027, 17.30), + (1538, 0.039, 27.70), + (2884, 0.061, 35.18), + (9615, 0.07, 117.29), + (float('inf'), 0.099, 588.46), + ] + + ### BI-WEEKLY ### + elif schedule_pay == 'bi-weekly': + wages -= 38.40 * allowances + tax_rate_table = [ + (769, 0.015, 0.0), + (1923, 0.02, 11.54), + (2692, 0.027, 34.62), + (3076, 0.039, 55.38), + (5769, 0.061, 70.35), + (19231, 0.07, 234.63), + (float('inf'), 0.099, 1176.97), + ] + + ### SEMI-MONTHLY ### + elif schedule_pay == 'semi-monthly': + wages -= 41.60 * allowances + tax_rate_table = [ + (833, 0.015, 0.0), + (2083, 0.02, 12.50), + (2916, 0.027, 37.50), + (3333, 0.039, 59.99), + (6250, 0.061, 76.25), + (20833, 0.07, 254.19), + (float('inf'), 0.099, 1275), + ] + + ### MONTHLY ### + elif schedule_pay == 'monthly': + wages -= 83.30 * allowances + tax_rate_table = [ + (1666, 0.015, 0.0), + (4166, 0.02, 24.99), + (5833, 0.027, 74.99), + (6666, 0.039, 120.00), + (12500, 0.061, 152.49), + (41667, 0.07, 508.36), + (float('inf'), 0.099, 2550.05), + ] + + ### QUARTERLY ### + elif schedule_pay == 'quarterly': + wages -= 250.00 * allowances + tax_rate_table = [ + (5000, 0.015, 0.0), + (12500, 0.02, 75.00), + (17500, 0.027, 225.00), + (20000, 0.039, 360.00), + (37500, 0.061, 457.50), + (125000, 0.07, 1525.00), + (float('inf'), 0.099, 7650.00), + ] + + ### SEMI-ANNUAL ### + elif schedule_pay == 'semi-annual': + wages -= 500.00 * allowances + tax_rate_table = [ + (10000, 0.015, 0.0), + (25000, 0.02, 150.00), + (35000, 0.027, 450.00), + (40000, 0.039, 720.00), + (75000, 0.061, 915.00), + (250000, 0.07, 3050.00), + (float('inf'), 0.099, 15300.00), + ] + + ### ANNUAL ### + elif schedule_pay == 'annually': + wages -= 1000.00 * allowances + tax_rate_table = [ + (20000, 0.015, 0.0), + (50000, 0.02, 300.00), + (70000, 0.027, 900.00), + (80000, 0.039, 1440.00), + (150000, 0.061, 1830.00), + (500000, 0.07, 6100.00), + (float('inf'), 0.099, 30600.00), + ] + + #### RATE 'C' #### + elif rate_table == 'C': + ### WEEKLY ### + if schedule_pay == 'weekly': + wages -= 19.20 * allowances + tax_rate_table = [ + (384, 0.015, 0.0), + (769, 0.023, 5.76), + (961, 0.028, 14.62), + (1153, 0.035, 19.99), + (2884, 0.056, 26.71), + (9615, 0.066, 123.65), + (float('inf'), 0.099, 567.90), + ] + + ### BI-WEEKLY ### + elif schedule_pay == 'bi-weekly': + wages -= 38.40 * allowances + tax_rate_table = [ + (769, 0.015, 0.0), + (1538, 0.023, 11.54), + (1923, 0.028, 29.22), + (2307, 0.035, 40.00), + (5769, 0.056, 53.44), + (19231, 0.066, 247.31), + (float('inf'), 0.099, 1135.80), + ] + + ### SEMI-MONTHLY ### + elif schedule_pay == 'semi-monthly': + wages -= 41.60 * allowances + tax_rate_table = [ + (833, 0.015, 0.0), + (1666, 0.023, 12.50), + (2083, 0.028, 31.65), + (2500, 0.035, 43.33), + (6250, 0.056, 57.93), + (20833, 0.066, 26793), + (float('inf'), 0.099, 1230.41), + ] + + ### MONTHLY ### + elif schedule_pay == 'monthly': + wages -= 83.30 * allowances + tax_rate_table = [ + (1666, 0.015, 0.0), + (3333, 0.023, 24.99), + (4166, 0.028, 63.33), + (5000, 0.035, 86.66), + (12500, 0.056, 115.85), + (41667, 0.066, 535.85), + (float('inf'), 0.099, 2460.87), + ] + + ### QUARTERLY ### + elif schedule_pay == 'quarterly': + wages -= 250.00 * allowances + tax_rate_table = [ + (5000, 0.015, 0.0), + (10000, 0.023, 75.00), + (12500, 0.028, 190.00), + (15000, 0.035, 260.00), + (37500, 0.056, 347.50), + (125000, 0.066, 1607.50), + (float('inf'), 0.099, 7382.50), + ] + + ### SEMI-ANNUAL ### + elif schedule_pay == 'semi-annual': + wages -= 500.00 * allowances + tax_rate_table = [ + (10000, 0.015, 0.0), + (20000, 0.023, 150.00), + (25000, 0.028, 380.00), + (30000, 0.035, 520.00), + (75000, 0.056, 695.00), + (250000, 0.066, 3215.00), + (float('inf'), 0.099, 14765.00), + ] + + ### ANNUAL ### + elif schedule_pay == 'annually': + wages -= 1000.00 * allowances + tax_rate_table = [ + (20000, 0.015, 0.0), + (40000, 0.023, 300.00), + (50000, 0.028, 760.00), + (60000, 0.035, 1040.00), + (150000, 0.056, 1390.00), + (500000, 0.066, 6430.00), + (float('inf'), 0.099, 29530.00), + ] + + #### RATE 'D' #### + elif rate_table == 'D': + ### WEEKLY ### + if schedule_pay == 'weekly': + wages -= 19.20 * allowances + tax_rate_table = [ + (384, 0.015, 0.0), + (769, 0.027, 5.76), + (961, 0.034, 16.16), + (1153, 0.043, 22.68), + (2884, 0.056, 30.94), + (9615, 0.065, 127.88), + (float('inf'), 0.099, 565.40), + ] + + ### BI-WEEKLY ### + elif schedule_pay == 'bi-weekly': + wages -= 38.40 * allowances + tax_rate_table = [ + (769, 0.015, 0.0), + (1538, 0.027, 11.54), + (1923, 0.034, 32.30), + (2307, 0.043, 45.39), + (5769, 0.056, 61.90), + (19231, 0.065, 255.77), + (float('inf'), 0.099, 1130.80), + ] + + ### SEMI-MONTHLY ### + elif schedule_pay == 'semi-monthly': + wages -= 41.60 * allowances + tax_rate_table = [ + (833, 0.015, 0.0), + (1666, 0.027, 12.50), + (2083, 0.034, 34.99), + (2500, 0.043, 49.16), + (6250, 0.056, 67.10), + (20833, 0.065, 277.10), + (float('inf'), 0.099, 1225.00), + ] + + ### MONTHLY ### + elif schedule_pay == 'monthly': + wages -= 83.30 * allowances + tax_rate_table = [ + (1666, 0.015, 0.0), + (3333, 0.027, 24.99), + (4166, 0.034, 70.00), + (5000, 0.043, 98.32), + (12500, 0.056, 134.18), + (41667, 0.065, 554.18), + (float('inf'), 0.099, 2450.04), + ] + + ### QUARTERLY ### + elif schedule_pay == 'quarterly': + wages -= 250.00 * allowances + tax_rate_table = [ + (5000, 0.015, 0.0), + (10000, 0.027, 75.00), + (12500, 0.034, 210.00), + (15000, 0.043, 295.00), + (37500, 0.056, 402.50), + (125000, 0.065, 1662.50), + (float('inf'), 0.099, 7350.00), + ] + + ### SEMI-ANNUAL ### + elif schedule_pay == 'semi-annual': + wages -= 500.00 * allowances + tax_rate_table = [ + (10000, 0.015, 0.0), + (20000, 0.027, 150.00), + (25000, 0.034, 420.00), + (30000, 0.043, 590.00), + (75000, 0.056, 805.00), + (250000, 0.065, 3325.00), + (float('inf'), 0.099, 14700.00), + ] + + ### ANNUAL ### + elif schedule_pay == 'annually': + wages -= 1000.00 * allowances + tax_rate_table = [ + (20000, 0.015, 0.0), + (40000, 0.027, 300.00), + (50000, 0.034, 840.00), + (60000, 0.043, 1180.00), + (150000, 0.056, 1610.00), + (250000, 0.065, 6650.00), + (float('inf'), 0.099, 29400.00), + ] + + #### RATE 'E' #### + elif rate_table == 'E': + ### WEEKLY ### + if schedule_pay == 'weekly': + wages -= 19.20 * allowances + tax_rate_table = [ + (384, 0.015, 0.0), + (673, 0.02, 5.76), + (1923, 0.058, 11.54), + (9615, 0.065, 84.04), + (float('inf'), 0.099, 584.02), + ] + + ### BI-WEEKLY ### + elif schedule_pay == 'bi-weekly': + wages -= 38.40 * allowances + tax_rate_table = [ + (769, 0.015, 0.0), + (1346, 0.02, 11.54), + (3846, 0.058, 23.08), + (19231, 0.065, 168.08), + (float('inf'), 0.099, 1168.11), + ] + + ### SEMI-MONTHLY ### + elif schedule_pay == 'semi-monthly': + wages -= 41.60 * allowances + tax_rate_table = [ + (833, 0.015, 0.0), + (1458, 0.02, 12.50), + (4166, 0.058, 25.00), + (20833, 0.065, 182.06), + (float('inf'), 0.099, 1265.42), + ] + + ### MONTHLY ### + elif schedule_pay == 'monthly': + wages -= 83.30 * allowances + tax_rate_table = [ + (1666, 0.015, 0.0), + (2916, 0.02, 24.99), + (8333, 0.058, 49.99), + (41667, 0.065, 364.18), + (float('inf'), 0.099, 2530.89), + ] + + ### QUARTERLY ### + elif schedule_pay == 'quarterly': + wages -= 250.00 * allowances + tax_rate_table = [ + (5000, 0.015, 0.0), + (8750, 0.02, 75.00), + (25000, 0.058, 150.00), + (125000, 0.065, 1092.50), + (float('inf'), 0.099, 7592.50), + ] + + ### SEMI-ANNUAL ### + elif schedule_pay == 'semi-annual': + wages -= 500.00 * allowances + tax_rate_table = [ + (10000, 0.015, 0.0), + (17500, 0.02, 150.00), + (50000, 0.058, 300.00), + (250000, 0.065, 2185.00), + (float('inf'), 0.099, 15,185.00), + ] + + ### ANNUAL ### + elif schedule_pay == 'annually': + wages -= 1000.00 * allowances + tax_rate_table = [ + (20000, 0.015, 0.0), + (35000, 0.02, 300.00), + (100000, 0.058, 600.00), + (500000, 0.065, 4370.00), + (float('inf'), 0.099, 30370.00), + ] +else: + divisor = 100.0 + # 2019 Table Rates + # All Rate schedules share the same allowance. if schedule_pay == 'weekly': wages -= 19.20 * allowances - tax_rate_table = [ - (384, 0.015, 0.0), - (673, 0.02, 5.76), - (769, 0.039, 11.54), - (1442, 0.061, 15.28), - (9615, 0.07, 56.34), - (float('inf'), 0.099, 628.45), - ] - - ### BI-WEEKLY ### elif schedule_pay == 'bi-weekly': wages -= 38.40 * allowances - tax_rate_table = [ - (769, 0.015, 0.0), - (1346, 0.02, 11.54), - (1538, 0.039, 23.08), - (2884, 0.061, 30.56), - (19231, 0.07, 112.67), - (float('inf'), 0.099, 1256.96), - ] - - ### SEMI-MONTHLY ### elif schedule_pay == 'semi-monthly': wages -= 41.60 * allowances - tax_rate_table = [ - (833, 0.015, 0.0), - (1458, 0.02, 12.50), - (1666, 0.039, 25.00), - (3125, 0.061, 33.11), - (20833, 0.07, 112.11), - (float('inf'), 0.099, 1361.67), - ] - - ### MONTHLY ### elif schedule_pay == 'monthly': wages -= 83.30 * allowances - tax_rate_table = [ - (1666, 0.015, 0.0), - (2916, 0.02, 24.99), - (3333, 0.039, 49.99), - (6250, 0.061, 66.25), - (41667, 0.07, 244.19), - (float('inf'), 0.099, 2723.38), - ] - - ### QUARTERLY ### elif schedule_pay == 'quarterly': wages -= 250.00 * allowances - tax_rate_table = [ - (5000, 0.015, 0.0), - (8750, 0.02, 75.00), - (10000, 0.039, 150.00), - (18750, 0.061, 198.75), - (125000, 0.07, 732.50), - (float('inf'), 0.099, 8170.00), - ] - - ### SEMI-ANNUAL ### - elif schedule_pay == 'semi-annual': - wages -= 500 * allowances - tax_rate_table = [ - (10000, 0.015, 0.0), - (17500, 0.02, 150.00), - (20000, 0.039, 300.00), - (37500, 0.061, 397.50), - (250000, 0.07, 1465.00), - (float('inf'), 0.099, 16340.00), - ] - - ### ANNUAL ### - elif schedule_pay == 'annually': - wages -= 1000.00 * allowances - tax_rate_table = [ - (20000, 0.015, 0.0), - (35000, 0.02, 300.00), - (40000, 0.039, 600.00), - (75000, 0.061, 795.00), - (500000, 0.07, 2930.00), - (float('inf'), 0.099, 32680.00), - ] - -#### RATE 'B' #### -elif rate_table == 'B': - ### WEEKLY ### - if schedule_pay == 'weekly': - wages -= 19.20 * allowances - tax_rate_table = [ - (384, 0.015, 0.0), - (961, 0.02, 5.76), - (1346, 0.027, 17.30), - (1538, 0.039, 27.70), - (2884, 0.061, 35.18), - (9615, 0.07, 117.29), - (float('inf'), 0.099, 588.46), - ] - - ### BI-WEEKLY ### - elif schedule_pay == 'bi-weekly': - wages -= 38.40 * allowances - tax_rate_table = [ - (769, 0.015, 0.0), - (1923, 0.02, 11.54), - (2692, 0.027, 34.62), - (3076, 0.039, 55.38), - (5769, 0.061, 70.35), - (19231, 0.07, 234.63), - (float('inf'), 0.099, 1176.97), - ] - - ### SEMI-MONTHLY ### - elif schedule_pay == 'semi-monthly': - wages -= 41.60 * allowances - tax_rate_table = [ - (833, 0.015, 0.0), - (2083, 0.02, 12.50), - (2916, 0.027, 37.50), - (3333, 0.039, 59.99), - (6250, 0.061, 76.25), - (20833, 0.07, 254.19), - (float('inf'), 0.099, 1275), - ] - - ### MONTHLY ### - elif schedule_pay == 'monthly': - wages -= 83.30 * allowances - tax_rate_table = [ - (1666, 0.015, 0.0), - (4166, 0.02, 24.99), - (5833, 0.027, 74.99), - (6666, 0.039, 120.00), - (12500, 0.061, 152.49), - (41667, 0.07, 508.36), - (float('inf'), 0.099, 2550.05), - ] - - ### QUARTERLY ### - elif schedule_pay == 'quarterly': - wages -= 250.00 * allowances - tax_rate_table = [ - (5000, 0.015, 0.0), - (12500, 0.02, 75.00), - (17500, 0.027, 225.00), - (20000, 0.039, 360.00), - (37500, 0.061, 457.50), - (125000, 0.07, 1525.00), - (float('inf'), 0.099, 7650.00), - ] - - ### SEMI-ANNUAL ### elif schedule_pay == 'semi-annual': wages -= 500.00 * allowances - tax_rate_table = [ - (10000, 0.015, 0.0), - (25000, 0.02, 150.00), - (35000, 0.027, 450.00), - (40000, 0.039, 720.00), - (75000, 0.061, 915.00), - (250000, 0.07, 3050.00), - (float('inf'), 0.099, 15300.00), - ] - - ### ANNUAL ### elif schedule_pay == 'annually': wages -= 1000.00 * allowances - tax_rate_table = [ - (20000, 0.015, 0.0), - (50000, 0.02, 300.00), - (70000, 0.027, 900.00), - (80000, 0.039, 1440.00), - (150000, 0.061, 1830.00), - (500000, 0.07, 6100.00), - (float('inf'), 0.099, 30600.00), - ] -#### RATE 'C' #### -elif rate_table == 'C': - ### WEEKLY ### - if schedule_pay == 'weekly': - wages -= 19.20 * allowances - tax_rate_table = [ - (384, 0.015, 0.0), - (769, 0.023, 5.76), - (961, 0.028, 14.62), - (1153, 0.035, 19.99), - (2884, 0.056, 26.71), - (9615, 0.066, 123.65), - (float('inf'), 0.099, 567.90), + #### RATE 'A' #### + if rate_table == 'A': + base_rate = [ + 1.5, + 2.0, + 3.9, + 6.1, + 7.0, + 9.9, + 11.8, ] + ### WEEKLY ### + if schedule_pay == 'weekly': + tax_rate_table = [ + (385, 0.0), + (673, 5.77), + (769, 11.54), + (1442, 15.29), + (9615, 56.34), + (96154, 628.46), + (float('inf'), 9195.77), + ] - ### BI-WEEKLY ### - elif schedule_pay == 'bi-weekly': - wages -= 38.40 * allowances - tax_rate_table = [ - (769, 0.015, 0.0), - (1538, 0.023, 11.54), - (1923, 0.028, 29.22), - (2307, 0.035, 40.00), - (5769, 0.056, 53.44), - (19231, 0.066, 247.31), - (float('inf'), 0.099, 1135.80), + ### BI-WEEKLY ### + elif schedule_pay == 'bi-weekly': + tax_rate_table = [ + (769, 0.0), + (1346, 12.00), + (1538, 23.00), + (2885, 31.00), + (19231, 113.00), + (192308, 1257.00), + (float('inf'), 18392.00), + ] + + ### SEMI-MONTHLY ### + elif schedule_pay == 'semi-monthly': + tax_rate_table = [ + (833, 0.0), + (1458, 13.00), + (1667, 25.00), + (3125, 33.00), + (20833, 122.00), + (208333, 1362.00), + (float('inf'), 19924.00), + ] + + ### MONTHLY ### + elif schedule_pay == 'monthly': + tax_rate_table = [ + (1667, 0.0), + (2917, 25.00), + (3333, 50.00), + (6250, 66.00), + (41667, 244.00), + (416667, 2723.00), + (float('inf'), 39848.00), + ] + + ### QUARTERLY ### + elif schedule_pay == 'quarterly': + tax_rate_table = [ + (5000, 0.0), + (8750, 75.00), + (10000, 150.00), + (18750, 198.75), + (125000, 732.50), + (1250000, 8170.00), + (float('inf'), 119545.00), + ] + + ### SEMI-ANNUAL ### + elif schedule_pay == 'semi-annual': + tax_rate_table = [ + (10000, 0.0), + (17500, 150.00), + (20000, 300.00), + (37500, 397.50), + (250000, 1465.00), + (2500000, 16340.00), + (float('inf'), 239090.00), + ] + + ### ANNUAL ### + elif schedule_pay == 'annually': + tax_rate_table = [ + (20000, 0.0), + (35000, 300.00), + (40000, 600.00), + (75000, 795.00), + (500000, 2930.00), + (5000000, 32680.00), + (float('inf'), 478180.00), + ] + + #### RATE 'B' #### + elif rate_table == 'B': + base_rate = [ + 1.5, + 2.0, + 2.7, + 3.9, + 6.1, + 7.0, + 9.9, + 11.8, ] + ### WEEKLY ### + if schedule_pay == 'weekly': + tax_rate_table = [ + (385, 0.0), + (962, 5.77), + (1346, 17.31), + (1538, 27.69), + (2885, 35.19), + (9615, 117.31), + (96154, 588.46), + (float('inf'), 9155.77), + ] - ### SEMI-MONTHLY ### - elif schedule_pay == 'semi-monthly': - wages -= 41.60 * allowances - tax_rate_table = [ - (833, 0.015, 0.0), - (1666, 0.023, 12.50), - (2083, 0.028, 31.65), - (2500, 0.035, 43.33), - (6250, 0.056, 57.93), - (20833, 0.066, 26793), - (float('inf'), 0.099, 1230.41), + ### BI-WEEKLY ### + elif schedule_pay == 'bi-weekly': + tax_rate_table = [ + (769, 0.0), + (1923, 12.00), + (2692, 35.00), + (3076, 55.00), + (5769, 70.00), + (19231, 235.00), + (192308, 1177.00), + (float('inf'), 18312.00), + ] + + ### SEMI-MONTHLY ### + elif schedule_pay == 'semi-monthly': + tax_rate_table = [ + (833, 0.0), + (2083, 12.50), + (2917, 37.50), + (3333, 59.99), + (6250, 76.25), + (20833, 254.19), + (208333, 1275.00), + (float('inf'), 19838.00), + ] + + ### MONTHLY ### + elif schedule_pay == 'monthly': + tax_rate_table = [ + (1667, 0.0), + (4167, 25.00), + (5833, 75.00), + (6667, 120.00), + (12500, 153.00), + (41667, 508.00), + (416667, 2550.00), + (float('inf'), 39675.00), + ] + + ### QUARTERLY ### + elif schedule_pay == 'quarterly': + tax_rate_table = [ + (5000, 0.0), + (12500, 75.00), + (17500, 225.00), + (20000, 360.00), + (37500, 457.50), + (125000, 1525.00), + (1250000, 7650.00), + (float('inf'), 119025.00), + ] + + ### SEMI-ANNUAL ### + elif schedule_pay == 'semi-annual': + tax_rate_table = [ + (10000, 0.0), + (25000, 150.00), + (35000, 450.00), + (40000, 720.00), + (75000, 915.00), + (250000, 3050.00), + (2500000, 15300.00), + (float('inf'), 238050.00), + ] + + ### ANNUAL ### + elif schedule_pay == 'annually': + tax_rate_table = [ + (20000, 0.0), + (50000, 300.00), + (70000, 900.00), + (80000, 1440.00), + (150000, 1830.00), + (500000, 6100.00), + (5000000, 30600.00), + (float('inf'), 476100.00), + ] + + #### RATE 'C' #### + elif rate_table == 'C': + base_rate = [ + 1.5, + 2.3, + 2.8, + 3.5, + 5.6, + 6.6, + 9.9, + 11.8, ] + ### WEEKLY ### + if schedule_pay == 'weekly': + tax_rate_table = [ + (385, 0.0), + (769, 5.77), + (962, 14.62), + (1154, 20.00), + (2885, 26.73), + (9615, 123.65), + (96154, 567.88), + (float('inf'), 9135.19), + ] - ### MONTHLY ### - elif schedule_pay == 'monthly': - wages -= 83.30 * allowances - tax_rate_table = [ - (1666, 0.015, 0.0), - (3333, 0.023, 24.99), - (4166, 0.028, 63.33), - (5000, 0.035, 86.66), - (12500, 0.056, 115.85), - (41667, 0.066, 535.85), - (float('inf'), 0.099, 2460.87), + ### BI-WEEKLY ### + elif schedule_pay == 'bi-weekly': + tax_rate_table = [ + (769, 0.0), + (1538, 11.54), + (1923, 29.23), + (2308, 40.00), + (5769, 53.46), + (19231, 247.31), + (192308, 1135.77), + (float('inf'), 18270.38), + ] + + ### SEMI-MONTHLY ### + elif schedule_pay == 'semi-monthly': + tax_rate_table = [ + (833, 0.0), + (1667, 12.50), + (2083, 31.67), + (2500, 43.33), + (6250, 57.92), + (20833, 267.92), + (208333, 1230.42), + (float('inf'), 19792.92), + ] + + ### MONTHLY ### + elif schedule_pay == 'monthly': + tax_rate_table = [ + (1667, 0.0), + (3333, 25.00), + (4167, 63.33), + (5000, 86.67), + (12500, 115.83), + (41667, 535.85), + (416667, 2460.83), + (float('inf'), 39585.83), + ] + + ### QUARTERLY ### + elif schedule_pay == 'quarterly': + tax_rate_table = [ + (5000, 0.0), + (10000, 75.00), + (12500, 190.00), + (15000, 260.00), + (37500, 347.50), + (125000, 1607.50), + (1250000, 7382.50), + (float('inf'), 118757.50), + ] + + ### SEMI-ANNUAL ### + elif schedule_pay == 'semi-annual': + tax_rate_table = [ + (10000, 0.0), + (20000, 150.00), + (25000, 380.00), + (30000, 520.00), + (75000, 695.00), + (250000, 3215.00), + (2500000, 14765.00), + (float('inf'), 237515.00), + ] + + ### ANNUAL ### + elif schedule_pay == 'annually': + tax_rate_table = [ + (20000, 0.0), + (40000, 300.00), + (50000, 760.00), + (60000, 1040.00), + (150000, 1390.00), + (500000, 6430.00), + (5000000, 29530.00), + (float('inf'), 475030.00), + ] + + #### RATE 'D' #### + elif rate_table == 'D': + base_rate = [ + 1.5, + 2.7, + 3.4, + 4.3, + 5.6, + 6.5, + 9.9, + 11.8, ] + ### WEEKLY ### + if schedule_pay == 'weekly': + tax_rate_table = [ + (385, 0.0), + (769, 5.77), + (962, 16.15), + (1154, 22.69), + (2885, 30.96), + (9615, 127.88), + (96154, 565.38), + (float('inf'), 9132.69), + ] - ### QUARTERLY ### - elif schedule_pay == 'quarterly': - wages -= 250.00 * allowances - tax_rate_table = [ - (5000, 0.015, 0.0), - (10000, 0.023, 75.00), - (12500, 0.028, 190.00), - (15000, 0.035, 260.00), - (37500, 0.056, 347.50), - (125000, 0.066, 1607.50), - (float('inf'), 0.099, 7382.50), + ### BI-WEEKLY ### + elif schedule_pay == 'bi-weekly': + tax_rate_table = [ + (769, 0.0), + (1538, 11.54), + (1923, 32.31), + (2308, 45.38), + (5769, 61.92), + (19231, 255.77), + (192308, 1130.77), + (float('inf'), 18265.38), + ] + + ### SEMI-MONTHLY ### + elif schedule_pay == 'semi-monthly': + tax_rate_table = [ + (833, 0.0), + (1667, 12.50), + (2083, 35.00), + (2500, 49.17), + (6250, 67.08), + (20833, 277.08), + (208333, 1225.00), + (float('inf'), 19787.50), + ] + + ### MONTHLY ### + elif schedule_pay == 'monthly': + tax_rate_table = [ + (1667, 0.0), + (3333, 25.00), + (4167, 70.00), + (5000, 98.33), + (12500, 134.17), + (41667, 554.17), + (416667, 2450.00), + (float('inf'), 39575.00), + ] + + ### QUARTERLY ### + elif schedule_pay == 'quarterly': + tax_rate_table = [ + (5000, 0.0), + (10000, 75.00), + (12500, 210.00), + (15000, 295.00), + (37500, 402.50), + (125000, 1662.50), + (1250000, 7350.00), + (float('inf'), 118725.00), + ] + + ### SEMI-ANNUAL ### + elif schedule_pay == 'semi-annual': + tax_rate_table = [ + (10000, 0.0), + (20000, 150.00), + (25000, 420.00), + (30000, 590.00), + (75000, 805.00), + (250000, 3325.00), + (2500000, 14700.00), + (float('inf'), 237450.00), + ] + + ### ANNUAL ### + elif schedule_pay == 'annually': + tax_rate_table = [ + (20000, 0.0), + (40000, 300.00), + (50000, 840.00), + (60000, 1180.00), + (150000, 1610.00), + (250000, 6650.00), + (2500000, 29400.00), + (float('inf'), 474900.00), + ] + + #### RATE 'E' #### + elif rate_table == 'E': + base_rate = [ + 1.5, + 2.0, + 5.8, + 6.5, + 9.9, + 11.8, ] + ### WEEKLY ### + if schedule_pay == 'weekly': + tax_rate_table = [ + (385, 0.0), + (673, 5.77), + (1923, 11.54), + (9615, 84.04), + (96154, 584.04), + (float('inf'), 9151.35), + ] - ### SEMI-ANNUAL ### - elif schedule_pay == 'semi-annual': - wages -= 500.00 * allowances - tax_rate_table = [ - (10000, 0.015, 0.0), - (20000, 0.023, 150.00), - (25000, 0.028, 380.00), - (30000, 0.035, 520.00), - (75000, 0.056, 695.00), - (250000, 0.066, 3215.00), - (float('inf'), 0.099, 14765.00), - ] + ### BI-WEEKLY ### + elif schedule_pay == 'bi-weekly': + tax_rate_table = [ + (769, 0.0), + (1346, 12.00), + (3846, 23.00), + (19231, 168.00), + (192308, 1168.00), + (float('inf'), 18303.00), + ] - ### ANNUAL ### - elif schedule_pay == 'annually': - wages -= 1000.00 * allowances - tax_rate_table = [ - (20000, 0.015, 0.0), - (40000, 0.023, 300.00), - (50000, 0.028, 760.00), - (60000, 0.035, 1040.00), - (150000, 0.056, 1390.00), - (500000, 0.066, 6430.00), - (float('inf'), 0.099, 29530.00), - ] + ### SEMI-MONTHLY ### + elif schedule_pay == 'semi-monthly': + tax_rate_table = [ + (833, 0.0), + (1458, 13.00), + (4167, 25.00), + (20833, 182.00), + (208333, 1265.00), + (float('inf'), 19828.00), + ] -#### RATE 'D' #### -elif rate_table == 'D': - ### WEEKLY ### - if schedule_pay == 'weekly': - wages -= 19.20 * allowances - tax_rate_table = [ - (384, 0.015, 0.0), - (769, 0.027, 5.76), - (961, 0.034, 16.16), - (1153, 0.043, 22.68), - (2884, 0.056, 30.94), - (9615, 0.065, 127.88), - (float('inf'), 0.099, 565.40), - ] + ### MONTHLY ### + elif schedule_pay == 'monthly': + tax_rate_table = [ + (1667, 0.0), + (2916, 25.00), + (8333, 50.00), + (41667, 364.00), + (416667, 2531.00), + (float('inf'), 39656.00), + ] - ### BI-WEEKLY ### - elif schedule_pay == 'bi-weekly': - wages -= 38.40 * allowances - tax_rate_table = [ - (769, 0.015, 0.0), - (1538, 0.027, 11.54), - (1923, 0.034, 32.30), - (2307, 0.043, 45.39), - (5769, 0.056, 61.90), - (19231, 0.065, 255.77), - (float('inf'), 0.099, 1130.80), - ] + ### QUARTERLY ### + elif schedule_pay == 'quarterly': + tax_rate_table = [ + (5000, 0.0), + (8750, 75.00), + (25000, 150.00), + (125000, 1092.50), + (1250000, 7592.50), + (float('inf'), 118967.50), + ] - ### SEMI-MONTHLY ### - elif schedule_pay == 'semi-monthly': - wages -= 41.60 * allowances - tax_rate_table = [ - (833, 0.015, 0.0), - (1666, 0.027, 12.50), - (2083, 0.034, 34.99), - (2500, 0.043, 49.16), - (6250, 0.056, 67.10), - (20833, 0.065, 277.10), - (float('inf'), 0.099, 1225.00), - ] - - ### MONTHLY ### - elif schedule_pay == 'monthly': - wages -= 83.30 * allowances - tax_rate_table = [ - (1666, 0.015, 0.0), - (3333, 0.027, 24.99), - (4166, 0.034, 70.00), - (5000, 0.043, 98.32), - (12500, 0.056, 134.18), - (41667, 0.065, 554.18), - (float('inf'), 0.099, 2450.04), - ] - - ### QUARTERLY ### - elif schedule_pay == 'quarterly': - wages -= 250.00 * allowances - tax_rate_table = [ - (5000, 0.015, 0.0), - (10000, 0.027, 75.00), - (12500, 0.034, 210.00), - (15000, 0.043, 295.00), - (37500, 0.056, 402.50), - (125000, 0.065, 1662.50), - (float('inf'), 0.099, 7350.00), - ] - - ### SEMI-ANNUAL ### - elif schedule_pay == 'semi-annual': - wages -= 500.00 * allowances - tax_rate_table = [ - (10000, 0.015, 0.0), - (20000, 0.027, 150.00), - (25000, 0.034, 420.00), - (30000, 0.043, 590.00), - (75000, 0.056, 805.00), - (250000, 0.065, 3325.00), - (float('inf'), 0.099, 14700.00), - ] - - ### ANNUAL ### - elif schedule_pay == 'annually': - wages -= 1000.00 * allowances - tax_rate_table = [ - (20000, 0.015, 0.0), - (40000, 0.027, 300.00), - (50000, 0.034, 840.00), - (60000, 0.043, 1180.00), - (150000, 0.056, 1610.00), - (250000, 0.065, 6650.00), - (float('inf'), 0.099, 29400.00), - ] - -#### RATE 'E' #### -elif rate_table == 'E': - ### WEEKLY ### - if schedule_pay == 'weekly': - wages -= 19.20 * allowances - tax_rate_table = [ - (384, 0.015, 0.0), - (673, 0.02, 5.76), - (1923, 0.058, 11.54), - (9615, 0.065, 84.04), - (float('inf'), 0.099, 584.02), - ] - - ### BI-WEEKLY ### - elif schedule_pay == 'bi-weekly': - wages -= 38.40 * allowances - tax_rate_table = [ - (769, 0.015, 0.0), - (1346, 0.02, 11.54), - (3846, 0.058, 23.08), - (19231, 0.065, 168.08), - (float('inf'), 0.099, 1168.11), - ] - - ### SEMI-MONTHLY ### - elif schedule_pay == 'semi-monthly': - wages -= 41.60 * allowances - tax_rate_table = [ - (833, 0.015, 0.0), - (1458, 0.02, 12.50), - (4166, 0.058, 25.00), - (20833, 0.065, 182.06), - (float('inf'), 0.099, 1265.42), - ] - - ### MONTHLY ### - elif schedule_pay == 'monthly': - wages -= 83.30 * allowances - tax_rate_table = [ - (1666, 0.015, 0.0), - (2916, 0.02, 24.99), - (8333, 0.058, 49.99), - (41667, 0.065, 364.18), - (float('inf'), 0.099, 2530.89), - ] - - ### QUARTERLY ### - elif schedule_pay == 'quarterly': - wages -= 250.00 * allowances - tax_rate_table = [ - (5000, 0.015, 0.0), - (8750, 0.02, 75.00), - (25000, 0.058, 150.00), - (125000, 0.065, 1092.50), - (float('inf'), 0.099, 7592.50), - ] - - ### SEMI-ANNUAL ### - elif schedule_pay == 'semi-annual': - wages -= 500.00 * allowances - tax_rate_table = [ - (10000, 0.015, 0.0), - (17500, 0.02, 150.00), - (50000, 0.058, 300.00), - (250000, 0.065, 2185.00), - (float('inf'), 0.099, 15,185.00), - ] - - ### ANNUAL ### - elif schedule_pay == 'annually': - wages -= 1000.00 * allowances - tax_rate_table = [ - (20000, 0.015, 0.0), - (35000, 0.02, 300.00), - (100000, 0.058, 600.00), - (500000, 0.065, 4370.00), - (float('inf'), 0.099, 30370.00), - ] + ### SEMI-ANNUAL ### + elif schedule_pay == 'semi-annual': + tax_rate_table = [ + (10000, 0.0), + (17500, 150.00), + (50000, 300.00), + (250000, 2185.00), + (2500000, 15185.00), + (float('inf'), 237935.00), + ] + ### ANNUAL ### + elif schedule_pay == 'annually': + tax_rate_table = [ + (20000, 0.0), + (35000, 300.00), + (100000, 600.00), + (500000, 4370.00), + (5000000, 30370.00), + (float('inf'), 475870.00), + ] over = 0.0 tax = 0.0 -for row in tax_rate_table: +for i, row in enumerate(tax_rate_table): if wages <= row[0]: - tax = ((wages - over) * row[1]) + row[2] - tax += additional_withholding - break + if len(row) == 2: + tax = ((wages - over) * (base_rate[i] / divisor)) + row[1] + tax += additional_withholding + break + else: + # 2018 rates include the base_rate in the row + tax = ((wages - over) * (row[1] / divisor)) + row[2] + tax += additional_withholding + break over = row[0] result = -tax diff --git a/l10n_us_nj_hr_payroll/tests/__init__.py b/l10n_us_nj_hr_payroll/tests/__init__.py index 02adeeae..812ad506 100755 --- a/l10n_us_nj_hr_payroll/tests/__init__.py +++ b/l10n_us_nj_hr_payroll/tests/__init__.py @@ -1 +1,2 @@ from . import test_us_nj_payslip_2018 +from . import test_us_nj_payslip_2019 diff --git a/l10n_us_nj_hr_payroll/tests/test_us_nj_payslip_2019.py b/l10n_us_nj_hr_payroll/tests/test_us_nj_payslip_2019.py new file mode 100755 index 00000000..eabf103c --- /dev/null +++ b/l10n_us_nj_hr_payroll/tests/test_us_nj_payslip_2019.py @@ -0,0 +1,179 @@ +from odoo.addons.l10n_us_hr_payroll.tests.test_us_payslip import TestUsPayslip, process_payslip + + +class TestUsNJPayslip(TestUsPayslip): + ### + # 2018 Taxes and Rates + ### + NJ_UNEMP_MAX_WAGE = 34400.0 # Note that this is used for SDI and FLI as well + + ER_NJ_UNEMP = -2.6825 / 100.0 + EE_NJ_UNEMP = -0.3825 / 100.0 + + ER_NJ_SDI = -0.5 / 100.0 + EE_NJ_SDI = -0.17 / 100.0 + + ER_NJ_WF = -0.1175 / 100.0 + EE_NJ_WF = -0.0425 / 100.0 + + ER_NJ_FLI = 0.0 + EE_NJ_FLI = -0.08 / 100.0 + + # Examples found on page 24 of http://www.state.nj.us/treasury/taxation/pdf/current/njwt.pdf + def test_2019_taxes_example1(self): + salary = 300 + schedule_pay = 'weekly' + allowances = 1 + additional_withholding = 0 + + # Tax Percentage Method for Single, taxable under $385 + wh = -4.21 + + employee = self._createEmployee() + contract = self._createContract(employee, + salary, + struct_id=self.ref( + 'l10n_us_nj_hr_payroll.hr_payroll_salary_structure_us_nj_employee'), + schedule_pay=schedule_pay) + contract.nj_njw4_allowances = allowances + contract.nj_additional_withholding = additional_withholding + contract.nj_njw4_filing_status = 'single' + contract.nj_njw4_rate_table = 'A' + + self.assertEqual(contract.schedule_pay, 'weekly') + + self._log('2019 New Jersey tax first payslip:') + payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31') + + payslip.compute_sheet() + + cats = self._getCategories(payslip) + + self.assertPayrollEqual(cats['WAGE_US_NJ_UNEMP'], salary) + self.assertPayrollEqual(cats['EE_US_NJ_UNEMP'], round(cats['BASIC'] * self.EE_NJ_UNEMP, 2)) + self.assertPayrollEqual(cats['ER_US_NJ_UNEMP'], round(cats['WAGE_US_NJ_UNEMP'] * self.ER_NJ_UNEMP, 2)) + self.assertPayrollEqual(cats['EE_US_NJ_SDI'], cats['WAGE_US_NJ_SDI'] * self.EE_NJ_SDI) + self.assertPayrollEqual(cats['ER_US_NJ_SDI'], cats['WAGE_US_NJ_SDI'] * self.ER_NJ_SDI) + self.assertPayrollEqual(cats['EE_US_NJ_FLI'], cats['WAGE_US_NJ_FLI'] * self.EE_NJ_FLI) + self.assertPayrollEqual(cats['EE_US_NJ_WF'], cats['WAGE_US_NJ_WF'] * self.EE_NJ_WF) + self.assertPayrollEqual(cats['EE_US_NJ_INC_WITHHOLD'], wh) + + process_payslip(payslip) + + # Make a new payslip, this one will have maximums + + remaining_nj_unemp_wages = self.NJ_UNEMP_MAX_WAGE - salary if (self.NJ_UNEMP_MAX_WAGE - 2 * salary < salary) \ + else salary + + self._log('2019 New Jersey tax second payslip:') + payslip = self._createPayslip(employee, '2019-02-01', '2019-02-28') + + payslip.compute_sheet() + + cats = self._getCategories(payslip) + + self.assertPayrollEqual(cats['WAGE_US_NJ_UNEMP'], remaining_nj_unemp_wages) + self.assertPayrollEqual(cats['ER_US_NJ_UNEMP'], round(remaining_nj_unemp_wages * self.ER_NJ_UNEMP, 2)) + self.assertPayrollEqual(cats['EE_US_NJ_UNEMP'], round(cats['BASIC'] * self.EE_NJ_UNEMP, 2)) + + def test_2019_taxes_example2(self): + salary = 1400.00 + schedule_pay = 'weekly' + allowances = 3 + additional_withholding = 0 + + # Tax Percentage Method for Single, taxable pay over $769, under $1442 + wh = -27.58 + + employee = self._createEmployee() + contract = self._createContract(employee, + salary, + struct_id=self.ref( + 'l10n_us_nj_hr_payroll.hr_payroll_salary_structure_us_nj_employee'), + schedule_pay=schedule_pay) + contract.nj_njw4_allowances = allowances + contract.nj_additional_withholding = additional_withholding + contract.nj_njw4_filing_status = 'married_joint' + + self.assertEqual(contract.schedule_pay, 'weekly') + + self._log('2019 New Jersey tax first payslip:') + payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31') + + payslip.compute_sheet() + + cats = self._getCategories(payslip) + + self.assertPayrollEqual(cats['WAGE_US_NJ_UNEMP'], salary) + self.assertPayrollEqual(cats['EE_US_NJ_UNEMP'], cats['WAGE_US_NJ_UNEMP'] * self.EE_NJ_UNEMP) + #self.assertPayrollEqual(cats['ER_US_NJ_UNEMP'], round(cats['WAGE_US_NJ_UNEMP'] * self.ER_NJ_UNEMP, 2)) + # round(37.555, 2) => 37.55 but in reality this should be 37.56, floats are weird ;) + self.assertTrue(abs(cats['ER_US_NJ_UNEMP'] - round(cats['WAGE_US_NJ_UNEMP'] * self.ER_NJ_UNEMP, 2)) < 0.02) + self.assertPayrollEqual(cats['EE_US_NJ_SDI'], cats['WAGE_US_NJ_SDI'] * self.EE_NJ_SDI) + self.assertPayrollEqual(cats['ER_US_NJ_SDI'], cats['WAGE_US_NJ_SDI'] * self.ER_NJ_SDI) + self.assertPayrollEqual(cats['EE_US_NJ_FLI'], cats['WAGE_US_NJ_FLI'] * self.EE_NJ_FLI) + self.assertPayrollEqual(cats['EE_US_NJ_WF'], cats['WAGE_US_NJ_WF'] * self.EE_NJ_WF) + self.assertPayrollEqual(cats['EE_US_NJ_INC_WITHHOLD'], wh) + + process_payslip(payslip) + + def test_2019_taxes_to_the_limits(self): + salary = 30000.00 + schedule_pay = 'quarterly' + allowances = 3 + additional_withholding = 0 + + # Tax Percentage Method for Single, taxable pay over $18750, under 125000 + wh = -1021.75 + + employee = self._createEmployee() + contract = self._createContract(employee, + salary, + struct_id=self.ref( + 'l10n_us_nj_hr_payroll.hr_payroll_salary_structure_us_nj_employee'), + schedule_pay=schedule_pay) + contract.nj_njw4_allowances = allowances + contract.nj_additional_withholding = additional_withholding + contract.nj_njw4_filing_status = 'married_joint' + + self.assertEqual(contract.schedule_pay, 'quarterly') + + self._log('2019 New Jersey tax first payslip:') + payslip = self._createPayslip(employee, '2019-01-01', '2019-03-31') + + payslip.compute_sheet() + + cats = self._getCategories(payslip) + + self.assertPayrollEqual(cats['WAGE_US_NJ_UNEMP'], salary) + self.assertPayrollEqual(cats['EE_US_NJ_UNEMP'], cats['BASIC'] * self.EE_NJ_UNEMP) + #self.assertPayrollEqual(cats['ER_US_NJ_UNEMP'], round(cats['WAGE_US_NJ_UNEMP'] * self.ER_NJ_UNEMP, 2)) + # round(37.555, 2) => 37.55 but in reality this should be 37.56, floats are weird ;) + self.assertTrue(abs(cats['ER_US_NJ_UNEMP'] - round(cats['WAGE_US_NJ_UNEMP'] * self.ER_NJ_UNEMP, 2)) < 0.02) + self.assertPayrollEqual(cats['EE_US_NJ_SDI'], cats['WAGE_US_NJ_SDI'] * self.EE_NJ_SDI) + self.assertPayrollEqual(cats['ER_US_NJ_SDI'], cats['WAGE_US_NJ_SDI'] * self.ER_NJ_SDI) + self.assertPayrollEqual(cats['EE_US_NJ_FLI'], cats['WAGE_US_NJ_FLI'] * self.EE_NJ_FLI) + self.assertPayrollEqual(cats['EE_US_NJ_WF'], cats['WAGE_US_NJ_WF'] * self.EE_NJ_WF) + self.assertPayrollEqual(cats['EE_US_NJ_INC_WITHHOLD'], wh) + + process_payslip(payslip) + + # Make a new payslip, this one will have maximums + + remaining_nj_unemp_wages = self.NJ_UNEMP_MAX_WAGE - salary if (self.NJ_UNEMP_MAX_WAGE - 2 * salary < salary) \ + else salary + + self._log('2019 New Jersey tax second payslip:') + payslip = self._createPayslip(employee, '2019-04-01', '2019-07-31') + + payslip.compute_sheet() + + cats = self._getCategories(payslip) + + self.assertFalse(abs(cats['BASIC'] - remaining_nj_unemp_wages) < 0.02) + self.assertTrue(abs(cats['WAGE_US_NJ_UNEMP'] - remaining_nj_unemp_wages) < 0.02) + self.assertPayrollEqual(cats['WAGE_US_NJ_UNEMP'], remaining_nj_unemp_wages) + self.assertPayrollEqual(cats['ER_US_NJ_UNEMP'], round(remaining_nj_unemp_wages * self.ER_NJ_UNEMP, 2)) + self.assertPayrollEqual(cats['EE_US_NJ_UNEMP'], round(remaining_nj_unemp_wages * self.EE_NJ_UNEMP, 2)) + self.assertPayrollEqual(cats['EE_US_NJ_SDI'], remaining_nj_unemp_wages * self.EE_NJ_SDI) + self.assertPayrollEqual(cats['ER_US_NJ_SDI'], remaining_nj_unemp_wages * self.ER_NJ_SDI) \ No newline at end of file