diff --git a/l10n_us_wa_hr_payroll/__init__.py b/l10n_us_wa_hr_payroll/__init__.py
index e99aa24a..0650744f 100644
--- a/l10n_us_wa_hr_payroll/__init__.py
+++ b/l10n_us_wa_hr_payroll/__init__.py
@@ -1 +1 @@
-from . import hr_payroll
+from . import models
diff --git a/l10n_us_wa_hr_payroll/__manifest__.py b/l10n_us_wa_hr_payroll/__manifest__.py
index efad9188..2fc72921 100755
--- a/l10n_us_wa_hr_payroll/__manifest__.py
+++ b/l10n_us_wa_hr_payroll/__manifest__.py
@@ -4,7 +4,7 @@
'license': 'AGPL-3',
'category': 'Localization',
'depends': ['l10n_us_hr_payroll'],
- 'version': '11.0.2018.0.0',
+ 'version': '12.0.2019.0.0',
'description': """
USA::Washington Payroll Rules.
==============================
@@ -19,9 +19,10 @@ USA::Washington Payroll Rules.
'website': 'https://hibou.io/',
'data': [
'security/ir.model.access.csv',
- 'hr_payroll_view.xml',
+ 'views/hr_payroll_views.xml',
'data/base.xml',
- 'data/rules_2018.xml',
+ 'data/rates.xml',
+ 'data/rules.xml',
'data/final.xml',
],
'installable': True
diff --git a/l10n_us_wa_hr_payroll/data/base.xml b/l10n_us_wa_hr_payroll/data/base.xml
index 3aea7bed..20ce5d4e 100755
--- a/l10n_us_wa_hr_payroll/data/base.xml
+++ b/l10n_us_wa_hr_payroll/data/base.xml
@@ -26,63 +26,27 @@
- Washington Unemployment - Wages
- WA_UNEMP_WAGES
+ Wage: US-WA Unemployment
+ WAGE_US_WA_UNEMP
- Washington Unemployment
- WA_UNEMP
+ ER: US-WA Unemployment
+ ER_US_WA_UNEMP
- Washington LNI
- WA_LNI
+ ER: US-WA LNI
+ ER_US_WA_LNI
- Washington LNI Withholding
- WA_LNI_WITHHOLD
+ EE: US-WA LNI
+ EE_US_WA_LNI
-
-
-
-
- Washington LNI Withholding
- WA_LNI_WITHHOLD
- none
- code
-
-hours = worked_days.WORK100.number_of_hours
-rate = contract.wa_lni.rate_emp_withhold
-if rate:
- result = -(hours * rate)
-
-
-
-
-
-
-
- Washington LNI
- WA_LNI
-
- none
- code
-
-hours = worked_days.WORK100.number_of_hours
-rate = contract.wa_lni.rate
-withholding = categories.WA_LNI_WITHHOLD
-if rate:
- result = -(hours * rate) - withholding
-
-
-
-
-
diff --git a/l10n_us_wa_hr_payroll/data/rates.xml b/l10n_us_wa_hr_payroll/data/rates.xml
new file mode 100644
index 00000000..0278f36a
--- /dev/null
+++ b/l10n_us_wa_hr_payroll/data/rates.xml
@@ -0,0 +1,19 @@
+
+
+
+
+ US Washington Unemployment
+ US_WA_UNEMP
+ 1.16
+ 2018-01-01
+
+
+
+ US Washington Unemployment
+ US_WA_UNEMP
+ 1.03
+ 2019-01-01
+
+
+
+
\ No newline at end of file
diff --git a/l10n_us_wa_hr_payroll/data/rules.xml b/l10n_us_wa_hr_payroll/data/rules.xml
new file mode 100755
index 00000000..cfe87748
--- /dev/null
+++ b/l10n_us_wa_hr_payroll/data/rules.xml
@@ -0,0 +1,87 @@
+
+
+
+
+
+
+
+ Wage: US-WA Unemployment
+ WAGE_US_WA_UNEMP
+ python
+ result = (contract.futa_type != contract.FUTA_TYPE_BASIC)
+ code
+
+###
+year = payslip.dict.date_to.year
+rate = payslip.dict.get_rate('US_WA_UNEMP')
+ytd = payslip.sum('WAGE_US_WA_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
+else:
+ result = categories.BASIC
+
+
+
+
+
+
+
+ ER: US-WA Unemployment
+ ER_US_WA_UNEMP
+ python
+ result = (contract.futa_type != contract.FUTA_TYPE_BASIC)
+ code
+
+rate = payslip.dict.get_rate('US_WA_UNEMP')
+result_rate = -rate.rate
+result = categories.WAGE_US_WA_UNEMP
+
+# result_rate of 0 implies 100% due to bug
+if result_rate == 0.0:
+ result = 0.0
+
+
+
+
+
+
+
+
+ EE: US-WA LNI
+ EE_US_WA_LNI
+ none
+ code
+
+hours = worked_days.WORK100.number_of_hours
+rate = contract.wa_lni.rate_emp_withhold
+if rate:
+ result = -(hours * rate)
+
+
+
+
+
+
+
+
+ ER: US-WA LNI
+ ER_US_WA_LNI
+
+ none
+ code
+
+hours = worked_days.WORK100.number_of_hours
+rate = contract.wa_lni.rate
+withholding = categories.EE_US_WA_LNI
+if rate:
+ result = -(hours * rate) - withholding
+
+
+
+
+
+
diff --git a/l10n_us_wa_hr_payroll/data/rules_2018.xml b/l10n_us_wa_hr_payroll/data/rules_2018.xml
deleted file mode 100755
index cf77a274..00000000
--- a/l10n_us_wa_hr_payroll/data/rules_2018.xml
+++ /dev/null
@@ -1,49 +0,0 @@
-
-
-
-
-
-
-
-
- Washington Unemployment - Wages (2018)
- WA_UNEMP_WAGES_2018
- python
- result = (payslip.date_to[:4] == '2018')
- code
-
-###
-ytd = payslip.sum('WA_UNEMP_WAGES_2018', '2018-01-01', '2019-01-01')
-ytd += contract.external_wages
-remaining = 47300.0 - ytd
-if remaining <= 0.0:
- result = 0
-elif remaining < categories.BASIC:
- result = remaining
-else:
- result = categories.BASIC
-
-
-
-
-
-
- Washington Unemployment (2018)
- WA_UNEMP_2018
- python
- result = (payslip.date_to[:4] == '2018')
- code
-
-result_rate = -contract.wa_unemp_rate(2018)
-result = categories.WA_UNEMP_WAGES
-
-# result_rate of 0 implies 100% due to bug
-if result_rate == 0.0:
- result = 0.0
-
-
-
-
-
-
-
diff --git a/l10n_us_wa_hr_payroll/hr_payroll.py b/l10n_us_wa_hr_payroll/hr_payroll.py
deleted file mode 100755
index 6e45dbc8..00000000
--- a/l10n_us_wa_hr_payroll/hr_payroll.py
+++ /dev/null
@@ -1,33 +0,0 @@
-from odoo import models, fields, api
-
-
-class USWAHrContract(models.Model):
- _inherit = 'hr.contract'
-
- wa_lni = fields.Many2one('hr.contract.lni.wa', string='WA State LNI')
-
- @api.multi
- def wa_unemp_rate(self, year):
- self.ensure_one()
- if self.futa_type == self.FUTA_TYPE_BASIC:
- return 0.0
-
- if hasattr(self.employee_id.company_id, 'wa_unemp_rate_' + str(year)):
- return self.employee_id.company_id['wa_unemp_rate_' + str(year)]
-
- raise NotImplemented('Year (' + str(year) + ') Not implemented for US Washington.')
-
-
-class WACompany(models.Model):
- _inherit = 'res.company'
-
- # No Defaults, need to sign up with the Employment Security Department
- wa_unemp_rate_2018 = fields.Float(string="Washington Unemployment Rate 2018", default=0.0)
-
-
-class WALNI(models.Model):
- _name = 'hr.contract.lni.wa'
-
- name = fields.Char(string='Name')
- rate = fields.Float(string='Rate (per hour worked)', digits=(7, 6))
- rate_emp_withhold = fields.Float(string='Employee Payroll Deduction Rate (per hour worked)', digits=(7, 6))
diff --git a/l10n_us_wa_hr_payroll/models/__init__.py b/l10n_us_wa_hr_payroll/models/__init__.py
new file mode 100644
index 00000000..e99aa24a
--- /dev/null
+++ b/l10n_us_wa_hr_payroll/models/__init__.py
@@ -0,0 +1 @@
+from . import hr_payroll
diff --git a/l10n_us_wa_hr_payroll/models/hr_payroll.py b/l10n_us_wa_hr_payroll/models/hr_payroll.py
new file mode 100755
index 00000000..6b5c023a
--- /dev/null
+++ b/l10n_us_wa_hr_payroll/models/hr_payroll.py
@@ -0,0 +1,15 @@
+from odoo import models, fields, api
+
+
+class USWAHrContract(models.Model):
+ _inherit = 'hr.contract'
+
+ wa_lni = fields.Many2one('hr.contract.lni.wa', string='WA State LNI')
+
+
+class WALNI(models.Model):
+ _name = 'hr.contract.lni.wa'
+
+ name = fields.Char(string='Name')
+ rate = fields.Float(string='Rate (per hour worked)', digits=(7, 6))
+ rate_emp_withhold = fields.Float(string='Employee Payroll Deduction Rate (per hour worked)', digits=(7, 6))
diff --git a/l10n_us_wa_hr_payroll/tests/__init__.py b/l10n_us_wa_hr_payroll/tests/__init__.py
index c6d19c7c..be35a060 100755
--- a/l10n_us_wa_hr_payroll/tests/__init__.py
+++ b/l10n_us_wa_hr_payroll/tests/__init__.py
@@ -1 +1,2 @@
from . import test_us_wa_payslip_2018
+from . import test_us_wa_payslip_2019
diff --git a/l10n_us_wa_hr_payroll/tests/test_us_wa_payslip_2018.py b/l10n_us_wa_hr_payroll/tests/test_us_wa_payslip_2018.py
index 63090be9..9482b460 100755
--- a/l10n_us_wa_hr_payroll/tests/test_us_wa_payslip_2018.py
+++ b/l10n_us_wa_hr_payroll/tests/test_us_wa_payslip_2018.py
@@ -6,6 +6,7 @@ class TestUsWAPayslip(TestUsPayslip):
# Taxes and Rates
###
WA_UNEMP_MAX_WAGE = 47300.0
+ WA_UNEMP_RATE = 1.16
def setUp(self):
super(TestUsWAPayslip, self).setUp()
@@ -19,14 +20,13 @@ class TestUsWAPayslip(TestUsPayslip):
salary = 25000.0
employee = self._createEmployee()
- employee.company_id.wa_unemp_rate_2018 = 1.16
contract = self._createContract(employee, salary, struct_id=self.ref('l10n_us_wa_hr_payroll.hr_payroll_salary_structure_us_wa_employee'))
self._log(str(contract.resource_calendar_id) + ' ' + contract.resource_calendar_id.name)
contract.wa_lni = self.lni
# tax rates
- wa_unemp = contract.wa_unemp_rate(2018) / -100.0
+ wa_unemp = self.WA_UNEMP_RATE / -100.0
self._log('2018 Washington tax first payslip:')
payslip = self._createPayslip(employee, '2018-01-01', '2018-01-31')
@@ -37,10 +37,10 @@ class TestUsWAPayslip(TestUsPayslip):
cats = self._getCategories(payslip)
- self.assertPayrollEqual(cats['WA_UNEMP_WAGES'], salary)
- self.assertPayrollEqual(cats['WA_UNEMP'], cats['WA_UNEMP_WAGES'] * wa_unemp)
- self.assertPayrollEqual(cats['WA_LNI_WITHHOLD'], -(self.lni.rate_emp_withhold * hours_in_period))
- self.assertPayrollEqual(cats['WA_LNI'], -(self.lni.rate * hours_in_period) - cats['WA_LNI_WITHHOLD'])
+ self.assertPayrollEqual(cats['WAGE_US_WA_UNEMP'], salary)
+ self.assertPayrollEqual(cats['ER_US_WA_UNEMP'], cats['WAGE_US_WA_UNEMP'] * wa_unemp)
+ self.assertPayrollEqual(cats['EE_US_WA_LNI'], -(self.lni.rate_emp_withhold * hours_in_period))
+ self.assertPayrollEqual(cats['ER_US_WA_LNI'], -(self.lni.rate * hours_in_period) - cats['EE_US_WA_LNI'])
process_payslip(payslip)
@@ -56,5 +56,5 @@ class TestUsWAPayslip(TestUsPayslip):
cats = self._getCategories(payslip)
- self.assertPayrollEqual(cats['WA_UNEMP_WAGES'], remaining_wa_unemp_wages)
- self.assertPayrollEqual(cats['WA_UNEMP'], remaining_wa_unemp_wages * wa_unemp)
+ self.assertPayrollEqual(cats['WAGE_US_WA_UNEMP'], remaining_wa_unemp_wages)
+ self.assertPayrollEqual(cats['ER_US_WA_UNEMP'], remaining_wa_unemp_wages * wa_unemp)
diff --git a/l10n_us_wa_hr_payroll/tests/test_us_wa_payslip_2019.py b/l10n_us_wa_hr_payroll/tests/test_us_wa_payslip_2019.py
new file mode 100755
index 00000000..72c0fc75
--- /dev/null
+++ b/l10n_us_wa_hr_payroll/tests/test_us_wa_payslip_2019.py
@@ -0,0 +1,60 @@
+from odoo.addons.l10n_us_hr_payroll.tests.test_us_payslip import TestUsPayslip, process_payslip
+
+
+class TestUsWAPayslip(TestUsPayslip):
+ ###
+ # Taxes and Rates
+ ###
+ WA_UNEMP_MAX_WAGE = 49800.0
+ WA_UNEMP_RATE = 1.03
+
+ def setUp(self):
+ super(TestUsWAPayslip, self).setUp()
+ self.lni = self.env['hr.contract.lni.wa'].create({
+ 'name': '5302 Computer Consulting',
+ 'rate': 0.1261,
+ 'rate_emp_withhold': 0.05575,
+ })
+
+ def test_2019_taxes(self):
+ salary = 25000.0
+
+ employee = self._createEmployee()
+
+ contract = self._createContract(employee, salary, struct_id=self.ref('l10n_us_wa_hr_payroll.hr_payroll_salary_structure_us_wa_employee'))
+ self._log(str(contract.resource_calendar_id) + ' ' + contract.resource_calendar_id.name)
+ contract.wa_lni = self.lni
+
+ # tax rates
+ wa_unemp = self.WA_UNEMP_RATE / -100.0
+
+ self._log('2019 Washington tax first payslip:')
+ payslip = self._createPayslip(employee, '2019-01-01', '2019-01-31')
+ payslip.onchange_contract()
+ hours_in_period = payslip.worked_days_line_ids.filtered(lambda l: l.code == 'WORK100').number_of_hours
+ payslip.compute_sheet()
+
+
+ cats = self._getCategories(payslip)
+
+ self.assertPayrollEqual(cats['WAGE_US_WA_UNEMP'], salary)
+ self.assertPayrollEqual(cats['ER_US_WA_UNEMP'], cats['WAGE_US_WA_UNEMP'] * wa_unemp)
+ self.assertPayrollEqual(cats['EE_US_WA_LNI'], -(self.lni.rate_emp_withhold * hours_in_period))
+ self.assertPayrollEqual(cats['ER_US_WA_LNI'], -(self.lni.rate * hours_in_period) - cats['EE_US_WA_LNI'])
+
+ process_payslip(payslip)
+
+ # Make a new payslip, this one will have maximums
+
+ remaining_wa_unemp_wages = self.WA_UNEMP_MAX_WAGE - salary if (self.WA_UNEMP_MAX_WAGE - 2*salary < salary) \
+ else salary
+
+ self._log('2019 Washington tax second payslip:')
+ payslip = self._createPayslip(employee, '2019-02-01', '2019-02-28')
+ payslip.onchange_contract()
+ payslip.compute_sheet()
+
+ cats = self._getCategories(payslip)
+
+ self.assertPayrollEqual(cats['WAGE_US_WA_UNEMP'], remaining_wa_unemp_wages)
+ self.assertPayrollEqual(cats['ER_US_WA_UNEMP'], remaining_wa_unemp_wages * wa_unemp)
diff --git a/l10n_us_wa_hr_payroll/hr_payroll_view.xml b/l10n_us_wa_hr_payroll/views/hr_payroll_views.xml
similarity index 57%
rename from l10n_us_wa_hr_payroll/hr_payroll_view.xml
rename to l10n_us_wa_hr_payroll/views/hr_payroll_views.xml
index 3f502872..abd56634 100755
--- a/l10n_us_wa_hr_payroll/hr_payroll_view.xml
+++ b/l10n_us_wa_hr_payroll/views/hr_payroll_views.xml
@@ -1,19 +1,6 @@
-
- res.company.form
- res.company
- 64
-
-
-
-
-
-
-
-
-
hr.contract.form.inherit
hr.contract