diff --git a/l10n_us_hr_payroll/__manifest__.py b/l10n_us_hr_payroll/__manifest__.py index 02c53066..3c0e0c48 100755 --- a/l10n_us_hr_payroll/__manifest__.py +++ b/l10n_us_hr_payroll/__manifest__.py @@ -2,8 +2,12 @@ 'name': 'USA - Payroll', 'author': 'Hibou Corp. ', 'category': 'Localization', - 'depends': ['hr_payroll', 'hr_payroll_rate'], - 'version': '11.0.2020.1.0', + 'depends': [ + 'hr_payroll', + 'hr_payroll_rate', + 'hibou_professional', + ], + 'version': '11.0.2020.2.2', 'description': """ USA Payroll Rules. ================== diff --git a/l10n_us_hr_payroll/data/state/ak_alaska.xml b/l10n_us_hr_payroll/data/state/ak_alaska.xml index bad629f9..d63c387d 100644 --- a/l10n_us_hr_payroll/data/state/ak_alaska.xml +++ b/l10n_us_hr_payroll/data/state/ak_alaska.xml @@ -86,4 +86,4 @@ - + \ No newline at end of file diff --git a/l10n_us_hr_payroll/data/state/al_alabama.xml b/l10n_us_hr_payroll/data/state/al_alabama.xml index 6a45ae75..bf2d0a7f 100644 --- a/l10n_us_hr_payroll/data/state/al_alabama.xml +++ b/l10n_us_hr_payroll/data/state/al_alabama.xml @@ -206,4 +206,4 @@ - + \ No newline at end of file diff --git a/l10n_us_hr_payroll/data/state/ar_arkansas.xml b/l10n_us_hr_payroll/data/state/ar_arkansas.xml index 09ffde3c..1940ef85 100644 --- a/l10n_us_hr_payroll/data/state/ar_arkansas.xml +++ b/l10n_us_hr_payroll/data/state/ar_arkansas.xml @@ -138,4 +138,4 @@ - + \ No newline at end of file diff --git a/l10n_us_hr_payroll/data/state/az_arizona.xml b/l10n_us_hr_payroll/data/state/az_arizona.xml index df864ab8..92bb3ef1 100644 --- a/l10n_us_hr_payroll/data/state/az_arizona.xml +++ b/l10n_us_hr_payroll/data/state/az_arizona.xml @@ -80,4 +80,4 @@ - + \ No newline at end of file diff --git a/l10n_us_hr_payroll/data/state/ca_california.xml b/l10n_us_hr_payroll/data/state/ca_california.xml index 60254b2b..663699bb 100644 --- a/l10n_us_hr_payroll/data/state/ca_california.xml +++ b/l10n_us_hr_payroll/data/state/ca_california.xml @@ -803,4 +803,4 @@ - + \ No newline at end of file diff --git a/l10n_us_hr_payroll/data/state/co_colorado.xml b/l10n_us_hr_payroll/data/state/co_colorado.xml index f982e08e..f28e4f18 100644 --- a/l10n_us_hr_payroll/data/state/co_colorado.xml +++ b/l10n_us_hr_payroll/data/state/co_colorado.xml @@ -86,4 +86,4 @@ - + \ No newline at end of file diff --git a/l10n_us_hr_payroll/data/state/ct_connecticut.xml b/l10n_us_hr_payroll/data/state/ct_connecticut.xml index 4070da98..d74dc140 100644 --- a/l10n_us_hr_payroll/data/state/ct_connecticut.xml +++ b/l10n_us_hr_payroll/data/state/ct_connecticut.xml @@ -1221,4 +1221,4 @@ - + \ No newline at end of file diff --git a/l10n_us_hr_payroll/data/state/de_delaware.xml b/l10n_us_hr_payroll/data/state/de_delaware.xml index 88bf3ee5..c37a2df5 100644 --- a/l10n_us_hr_payroll/data/state/de_delaware.xml +++ b/l10n_us_hr_payroll/data/state/de_delaware.xml @@ -104,4 +104,4 @@ - + \ No newline at end of file diff --git a/l10n_us_hr_payroll/data/state/hi_hawaii.xml b/l10n_us_hr_payroll/data/state/hi_hawaii.xml index 177990d6..e4c07ab2 100644 --- a/l10n_us_hr_payroll/data/state/hi_hawaii.xml +++ b/l10n_us_hr_payroll/data/state/hi_hawaii.xml @@ -174,4 +174,4 @@ - + \ No newline at end of file diff --git a/l10n_us_hr_payroll/data/state/ia_iowa.xml b/l10n_us_hr_payroll/data/state/ia_iowa.xml index f7a62ddc..89e9e036 100644 --- a/l10n_us_hr_payroll/data/state/ia_iowa.xml +++ b/l10n_us_hr_payroll/data/state/ia_iowa.xml @@ -294,4 +294,4 @@ - + \ No newline at end of file diff --git a/l10n_us_hr_payroll/data/state/id_idaho.xml b/l10n_us_hr_payroll/data/state/id_idaho.xml index f14663b7..7331326e 100644 --- a/l10n_us_hr_payroll/data/state/id_idaho.xml +++ b/l10n_us_hr_payroll/data/state/id_idaho.xml @@ -441,4 +441,4 @@ - + \ No newline at end of file diff --git a/l10n_us_hr_payroll/data/state/il_illinois.xml b/l10n_us_hr_payroll/data/state/il_illinois.xml index af722660..2dbcac77 100644 --- a/l10n_us_hr_payroll/data/state/il_illinois.xml +++ b/l10n_us_hr_payroll/data/state/il_illinois.xml @@ -110,4 +110,4 @@ - + \ No newline at end of file diff --git a/l10n_us_hr_payroll/data/state/ks_kansas.xml b/l10n_us_hr_payroll/data/state/ks_kansas.xml index 32caa724..5ad8de4c 100644 --- a/l10n_us_hr_payroll/data/state/ks_kansas.xml +++ b/l10n_us_hr_payroll/data/state/ks_kansas.xml @@ -183,4 +183,4 @@ - + \ No newline at end of file diff --git a/l10n_us_hr_payroll/data/state/ky_kentucky.xml b/l10n_us_hr_payroll/data/state/ky_kentucky.xml index b093375e..53eb3190 100644 --- a/l10n_us_hr_payroll/data/state/ky_kentucky.xml +++ b/l10n_us_hr_payroll/data/state/ky_kentucky.xml @@ -88,4 +88,4 @@ - + \ No newline at end of file diff --git a/l10n_us_hr_payroll/data/state/me_maine.xml b/l10n_us_hr_payroll/data/state/me_maine.xml index d9419559..15fadbb9 100644 --- a/l10n_us_hr_payroll/data/state/me_maine.xml +++ b/l10n_us_hr_payroll/data/state/me_maine.xml @@ -116,4 +116,4 @@ - + \ No newline at end of file diff --git a/l10n_us_hr_payroll/data/state/mi_michigan.xml b/l10n_us_hr_payroll/data/state/mi_michigan.xml index 2aa46a81..df0f6352 100644 --- a/l10n_us_hr_payroll/data/state/mi_michigan.xml +++ b/l10n_us_hr_payroll/data/state/mi_michigan.xml @@ -93,4 +93,4 @@ - + \ No newline at end of file diff --git a/l10n_us_hr_payroll/data/state/mn_minnesota.xml b/l10n_us_hr_payroll/data/state/mn_minnesota.xml index e7ccdd5f..6408358c 100644 --- a/l10n_us_hr_payroll/data/state/mn_minnesota.xml +++ b/l10n_us_hr_payroll/data/state/mn_minnesota.xml @@ -138,4 +138,4 @@ - + \ No newline at end of file diff --git a/l10n_us_hr_payroll/data/state/mo_missouri.xml b/l10n_us_hr_payroll/data/state/mo_missouri.xml index cffd82e4..500126b2 100644 --- a/l10n_us_hr_payroll/data/state/mo_missouri.xml +++ b/l10n_us_hr_payroll/data/state/mo_missouri.xml @@ -144,4 +144,4 @@ - + \ No newline at end of file diff --git a/l10n_us_hr_payroll/data/state/nc_northcarolina.xml b/l10n_us_hr_payroll/data/state/nc_northcarolina.xml index 20dc0db1..4e032b89 100644 --- a/l10n_us_hr_payroll/data/state/nc_northcarolina.xml +++ b/l10n_us_hr_payroll/data/state/nc_northcarolina.xml @@ -107,4 +107,4 @@ - + \ No newline at end of file diff --git a/l10n_us_hr_payroll/data/state/nd_north_dakota.xml b/l10n_us_hr_payroll/data/state/nd_north_dakota.xml index 87c0f27b..37f129b9 100644 --- a/l10n_us_hr_payroll/data/state/nd_north_dakota.xml +++ b/l10n_us_hr_payroll/data/state/nd_north_dakota.xml @@ -269,4 +269,4 @@ - + \ No newline at end of file diff --git a/l10n_us_hr_payroll/data/state/ne_nebraska.xml b/l10n_us_hr_payroll/data/state/ne_nebraska.xml index ee131bbe..bd35fe1f 100644 --- a/l10n_us_hr_payroll/data/state/ne_nebraska.xml +++ b/l10n_us_hr_payroll/data/state/ne_nebraska.xml @@ -227,4 +227,4 @@ - + \ No newline at end of file diff --git a/l10n_us_hr_payroll/data/state/nj_newjersey.xml b/l10n_us_hr_payroll/data/state/nj_newjersey.xml index feb186e2..acd3729e 100644 --- a/l10n_us_hr_payroll/data/state/nj_newjersey.xml +++ b/l10n_us_hr_payroll/data/state/nj_newjersey.xml @@ -1013,4 +1013,4 @@ - + \ No newline at end of file diff --git a/l10n_us_hr_payroll/data/state/nm_new_mexico.xml b/l10n_us_hr_payroll/data/state/nm_new_mexico.xml index 31d9744e..9a8238f7 100644 --- a/l10n_us_hr_payroll/data/state/nm_new_mexico.xml +++ b/l10n_us_hr_payroll/data/state/nm_new_mexico.xml @@ -294,4 +294,4 @@ - + \ No newline at end of file diff --git a/l10n_us_hr_payroll/data/state/nv_nevada.xml b/l10n_us_hr_payroll/data/state/nv_nevada.xml index e90c96b5..59022d7c 100644 --- a/l10n_us_hr_payroll/data/state/nv_nevada.xml +++ b/l10n_us_hr_payroll/data/state/nv_nevada.xml @@ -46,4 +46,4 @@ - + \ No newline at end of file diff --git a/l10n_us_hr_payroll/data/state/ok_oklahoma.xml b/l10n_us_hr_payroll/data/state/ok_oklahoma.xml index 08e606af..86deb82d 100644 --- a/l10n_us_hr_payroll/data/state/ok_oklahoma.xml +++ b/l10n_us_hr_payroll/data/state/ok_oklahoma.xml @@ -291,4 +291,4 @@ - + \ No newline at end of file diff --git a/l10n_us_hr_payroll/data/state/ri_rhode_island.xml b/l10n_us_hr_payroll/data/state/ri_rhode_island.xml index 5738d7f7..35b6041a 100644 --- a/l10n_us_hr_payroll/data/state/ri_rhode_island.xml +++ b/l10n_us_hr_payroll/data/state/ri_rhode_island.xml @@ -132,4 +132,4 @@ - + \ No newline at end of file diff --git a/l10n_us_hr_payroll/data/state/sc_south_carolina.xml b/l10n_us_hr_payroll/data/state/sc_south_carolina.xml index 4739d3b1..add7ed8d 100644 --- a/l10n_us_hr_payroll/data/state/sc_south_carolina.xml +++ b/l10n_us_hr_payroll/data/state/sc_south_carolina.xml @@ -143,4 +143,4 @@ - + \ No newline at end of file diff --git a/l10n_us_hr_payroll/data/state/ut_utah.xml b/l10n_us_hr_payroll/data/state/ut_utah.xml index 055ddb77..b1928223 100644 --- a/l10n_us_hr_payroll/data/state/ut_utah.xml +++ b/l10n_us_hr_payroll/data/state/ut_utah.xml @@ -150,4 +150,4 @@ - + \ No newline at end of file diff --git a/l10n_us_hr_payroll/data/state/vt_vermont.xml b/l10n_us_hr_payroll/data/state/vt_vermont.xml index 62c85d6b..a6df6085 100644 --- a/l10n_us_hr_payroll/data/state/vt_vermont.xml +++ b/l10n_us_hr_payroll/data/state/vt_vermont.xml @@ -182,4 +182,4 @@ - + \ No newline at end of file diff --git a/l10n_us_hr_payroll/data/state/wv_west_virginia.xml b/l10n_us_hr_payroll/data/state/wv_west_virginia.xml index 62bd1498..4cf6eeb5 100644 --- a/l10n_us_hr_payroll/data/state/wv_west_virginia.xml +++ b/l10n_us_hr_payroll/data/state/wv_west_virginia.xml @@ -206,4 +206,4 @@ - + \ No newline at end of file diff --git a/l10n_us_hr_payroll/models/__init__.py b/l10n_us_hr_payroll/models/__init__.py index 97bab130..34f516ee 100644 --- a/l10n_us_hr_payroll/models/__init__.py +++ b/l10n_us_hr_payroll/models/__init__.py @@ -4,4 +4,5 @@ from . import hr_contract from . import hr_payslip from . import hr_salary_rule from . import res_config_settings +from . import update from . import us_payroll_config diff --git a/l10n_us_hr_payroll/models/federal/fed_941.py b/l10n_us_hr_payroll/models/federal/fed_941.py index 0cacfd71..cbe6a0fa 100644 --- a/l10n_us_hr_payroll/models/federal/fed_941.py +++ b/l10n_us_hr_payroll/models/federal/fed_941.py @@ -12,17 +12,18 @@ def fica_wage(payslip, categories): """ wage = categories.GROSS - wage -= categories.ALW_FICA_EXEMPT + \ - categories.ALW_FIT_FICA_EXEMPT + \ - categories.ALW_FIT_FICA_FUTA_EXEMPT + \ - categories.ALW_FICA_FUTA_EXEMPT - wage += categories.DED_FICA_EXEMPT + \ - categories.DED_FIT_FICA_EXEMPT + \ - categories.DED_FIT_FICA_FUTA_EXEMPT + \ - categories.DED_FICA_FUTA_EXEMPT + less_exempt = categories.ALW_FICA_EXEMPT + \ + categories.ALW_FIT_FICA_EXEMPT + \ + categories.ALW_FIT_FICA_FUTA_EXEMPT + \ + categories.ALW_FICA_FUTA_EXEMPT - return wage + plus_exempt = categories.DED_FICA_EXEMPT + \ + categories.DED_FIT_FICA_EXEMPT + \ + categories.DED_FIT_FICA_FUTA_EXEMPT + \ + categories.DED_FICA_FUTA_EXEMPT + # _logger.info('fica wage GROSS: %0.2f less exempt ALW: %0.2f plus exempt DED: %0.2f' % (wage, less_exempt, plus_exempt)) + return wage - less_exempt + plus_exempt def fica_wage_ytd(payslip, categories): @@ -34,18 +35,19 @@ def fica_wage_ytd(payslip, categories): year = payslip.dict.get_year() ytd_wage = payslip.sum_category('GROSS', str(year) + '-01-01', str(year+1) + '-01-01') - ytd_wage -= payslip.sum_category('ALW_FICA_EXEMPT', str(year) + '-01-01', str(year+1) + '-01-01') + \ - payslip.sum_category('ALW_FIT_FICA_EXEMPT', str(year) + '-01-01', str(year+1) + '-01-01') + \ - payslip.sum_category('ALW_FIT_FICA_FUTA_EXEMPT', str(year) + '-01-01', str(year+1) + '-01-01') + \ - payslip.sum_category('ALW_FICA_FUTA_EXEMPT', str(year) + '-01-01', str(year+1) + '-01-01') + less_exempt = payslip.sum_category('ALW_FICA_EXEMPT', str(year) + '-01-01', str(year+1) + '-01-01') + \ + payslip.sum_category('ALW_FIT_FICA_EXEMPT', str(year) + '-01-01', str(year+1) + '-01-01') + \ + payslip.sum_category('ALW_FIT_FICA_FUTA_EXEMPT', str(year) + '-01-01', str(year+1) + '-01-01') + \ + payslip.sum_category('ALW_FICA_FUTA_EXEMPT', str(year) + '-01-01', str(year+1) + '-01-01') - ytd_wage += payslip.sum_category('DED_FICA_EXEMPT', str(year) + '-01-01', str(year+1) + '-01-01') + \ - payslip.sum_category('DED_FIT_FICA_EXEMPT', str(year) + '-01-01', str(year+1) + '-01-01') + \ - payslip.sum_category('DED_FIT_FICA_FUTA_EXEMPT', str(year) + '-01-01', str(year+1) + '-01-01') + \ - payslip.sum_category('DED_FICA_FUTA_EXEMPT', str(year) + '-01-01', str(year+1) + '-01-01') + plus_exempt = payslip.sum_category('DED_FICA_EXEMPT', str(year) + '-01-01', str(year+1) + '-01-01') + \ + payslip.sum_category('DED_FIT_FICA_EXEMPT', str(year) + '-01-01', str(year+1) + '-01-01') + \ + payslip.sum_category('DED_FIT_FICA_FUTA_EXEMPT', str(year) + '-01-01', str(year+1) + '-01-01') + \ + payslip.sum_category('DED_FICA_FUTA_EXEMPT', str(year) + '-01-01', str(year+1) + '-01-01') - ytd_wage += payslip.dict.contract_id.external_wages - return ytd_wage + external_wages = payslip.dict.contract_id.external_wages + # _logger.info('fica ytd wage GROSS: %0.2f less exempt ALW: %0.2f plus exempt DED: %0.2f plus external: %0.2f' % (ytd_wage, less_exempt, plus_exempt, external_wages)) + return ytd_wage - less_exempt + plus_exempt + external_wages def ee_us_941_fica_ss(payslip, categories, worked_days, inputs): diff --git a/l10n_us_hr_payroll/models/hr_payslip.py b/l10n_us_hr_payroll/models/hr_payslip.py index c89a0380..eeae69d7 100644 --- a/l10n_us_hr_payroll/models/hr_payslip.py +++ b/l10n_us_hr_payroll/models/hr_payslip.py @@ -213,12 +213,36 @@ class HRPayslip(models.Model): FROM hr_payslip as hp, hr_payslip_line as pl WHERE hp.employee_id = %s AND hp.state = 'done' AND hp.{sum_field} >= %s AND hp.date_to <= %s AND hp.id = pl.slip_id AND pl.code = %s""".format(sum_field=sum_field) + + # Original (non-recursive) + # self.__browsable_query_category = """ + # SELECT sum(case when hp.credit_note is not True then (pl.total) else (-pl.total) end) + # FROM hr_payslip as hp, hr_payslip_line as pl, hr_salary_rule_category as rc + # WHERE hp.employee_id = %s AND hp.state = 'done' + # AND hp.{sum_field} >= %s AND hp.date_to <= %s AND hp.id = pl.slip_id + # AND rc.id = pl.category_id AND rc.code = %s""".format(sum_field=sum_field) + + # Hibou Recursive version self.__browsable_query_category = """ + WITH RECURSIVE + category_by_code as ( + SELECT id + FROM hr_salary_rule_category + WHERE code = %s + ), + category_ids as ( + SELECT COALESCE((SELECT id FROM category_by_code), -1) AS id + UNION ALL + SELECT rc.id + FROM hr_salary_rule_category AS rc + JOIN category_ids AS rcs ON rcs.id = rc.parent_id + ) + SELECT sum(case when hp.credit_note is not True then (pl.total) else (-pl.total) end) - FROM hr_payslip as hp, hr_payslip_line as pl, hr_salary_rule_category as rc + FROM hr_payslip as hp, hr_payslip_line as pl WHERE hp.employee_id = %s AND hp.state = 'done' AND hp.{sum_field} >= %s AND hp.date_to <= %s AND hp.id = pl.slip_id - AND rc.id = pl.category_id AND rc.code = %s""".format(sum_field=sum_field) + AND pl.category_id in (SELECT id from category_ids)""".format(sum_field=sum_field) def sum(self, code, from_date, to_date=None): if to_date is None: @@ -235,7 +259,10 @@ class HRPayslip(models.Model): if to_date is None: to_date = fields.Date.today() - self.env.cr.execute(self.__browsable_query_category, (self.employee_id, from_date, to_date, code)) + # standard version + # self.env.cr.execute(self.__browsable_query_category, (self.employee_id, from_date, to_date, code)) + # recursive category version + self.env.cr.execute(self.__browsable_query_category, (code, self.employee_id, from_date, to_date)) res = self.env.cr.fetchone() return res and res[0] or 0.0 diff --git a/l10n_us_hr_payroll/models/hr_salary_rule.py b/l10n_us_hr_payroll/models/hr_salary_rule.py index a98029ec..64f0ce8e 100644 --- a/l10n_us_hr_payroll/models/hr_salary_rule.py +++ b/l10n_us_hr_payroll/models/hr_salary_rule.py @@ -1,3 +1,5 @@ +# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details. + from odoo import api, fields, models, _ from odoo.tools.safe_eval import safe_eval from odoo.exceptions import UserError diff --git a/l10n_us_hr_payroll/models/update.py b/l10n_us_hr_payroll/models/update.py new file mode 100644 index 00000000..2184abef --- /dev/null +++ b/l10n_us_hr_payroll/models/update.py @@ -0,0 +1,26 @@ +# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details. + +import datetime +from odoo import fields, models + + +class PublisherWarrantyContract(models.AbstractModel): + _inherit = 'publisher_warranty.contract' + + def _get_hibou_modules(self): + modules = super(PublisherWarrantyContract, self)._get_hibou_modules() + try: + today_date = fields.Date.today() + last_thirty_date = today_date - datetime.timedelta(days=30) + today = fields.Date.to_string(today_date + datetime.timedelta(days=1)) # Dates vs Datetimes, pad out a day + last_thirty = fields.Date.to_string(last_thirty_date) + self.env.cr.execute( + 'SELECT COUNT(DISTINCT(employee_id)) FROM hr_payslip WHERE create_date BETWEEN %s AND %s', + (last_thirty, today)) + employee_count = self.env.cr.fetchone()[0] or 0 + modules.update({ + 'l10n_us_hr_payroll': employee_count, + }) + except: + pass + return modules diff --git a/l10n_us_hr_payroll/tests/test_special.py b/l10n_us_hr_payroll/tests/test_special.py index f87ee5d1..d68df65d 100644 --- a/l10n_us_hr_payroll/tests/test_special.py +++ b/l10n_us_hr_payroll/tests/test_special.py @@ -64,3 +64,56 @@ elif ytd_rule == 0.0: payslip.compute_sheet() cats = self._getCategories(payslip) self.assertEqual(cats['test_sum_behavior'], 0.0) + + def test_recursive_salary_rule_category(self): + self.debug = True + # In this scenario, you are in rule code that will check for the category + # and a subcategory will also + alw_category = self.env.ref('hr_payroll.ALW') + ded_category = self.env.ref('hr_payroll.DED') + test_category = self.env['hr.salary.rule.category'].create({ + 'name': 'Special ALW', + 'code': 'ALW_SPECIAL_RECURSIVE', + 'parent_id': alw_category.id, + }) + test_special_alw = self.env['hr.salary.rule'].create({ + 'name': 'Flat amount 200', + 'code': 'ALW_SPECIAL_RECURSIVE', + 'category_id': test_category.id, + 'condition_select': 'none', + 'amount_select': 'fix', + 'amount_fix': 200.0, + }) + test_recursion = self.env['hr.salary.rule'].create({ + 'name': 'Actual Test Behavior', + 'code': 'RECURSION_TEST', + 'category_id': ded_category.id, + 'condition_select': 'none', + 'amount_select': 'code', + 'amount_python_compute': """ +# this rule will always be the total of the ALW category and YTD ALW category +result = categories.ALW +year = payslip.dict.get_year() +result += payslip.sum_category('ALW', str(year) + '-01-01', str(year+1) + '-01-01') + """, + 'sequence': 101, + }) + struct = self.env.ref('l10n_us_hr_payroll.structure_type_employee') + struct.rule_ids = test_special_alw + test_recursion + + salary = 80000.0 + employee = self._createEmployee() + contract = self._createContract(employee, wage=salary, schedule_pay='bi-weekly') + payslip = self._createPayslip(employee, '2020-01-01', '2020-01-14') + payslip.compute_sheet() + cats = self._getCategories(payslip) + rules = self._getRules(payslip) + self.assertEqual(rules['RECURSION_TEST'], 200.0) + process_payslip(payslip) + + payslip = self._createPayslip(employee, '2020-01-15', '2020-01-27') + payslip.compute_sheet() + cats = self._getCategories(payslip) + rules = self._getRules(payslip) + # two hundred is in the YTD ALW + self.assertEqual(rules['RECURSION_TEST'], 200.0 + 200.0)