diff --git a/hr_payroll_slip_ytd/__manifest__.py b/hr_payroll_slip_ytd/__manifest__.py index a66480ff..da94f254 100755 --- a/hr_payroll_slip_ytd/__manifest__.py +++ b/hr_payroll_slip_ytd/__manifest__.py @@ -1,7 +1,7 @@ { 'name': 'Payroll Report Year to Date', 'author': 'Hibou Corp. ', - 'version': '12.0.1.1.0', + 'version': '13.0.1.1.0', 'category': 'Human Resources', 'sequence': 95, 'summary': 'Show YTD computations on Payslip Report', diff --git a/hr_payroll_slip_ytd/models/payslip.py b/hr_payroll_slip_ytd/models/payslip.py index fe46d655..984f0d16 100644 --- a/hr_payroll_slip_ytd/models/payslip.py +++ b/hr_payroll_slip_ytd/models/payslip.py @@ -7,11 +7,11 @@ class Payslip(models.Model): def ytd(self, code, allow_draft=False): to_date = self.date_to from_date = str(self.date_to.year) + '-01-01' - state_allowed = ('done', 'verify') if not allow_draft else ('done', 'verify', 'draft') + state_allowed = ('done',) if not allow_draft else ('done', 'verify', 'draft') self.env.cr.execute(""" - SELECT sum(total) as total, - sum(quantity) as quantity, - sum(amount) as amount + SELECT sum(pi.total) as total, + sum(pi.quantity) as quantity, + sum(pi.amount) as amount FROM hr_payslip as hp JOIN hr_payslip_line as pi ON hp.id = pi.slip_id WHERE hp.employee_id = %s @@ -26,3 +26,24 @@ class Payslip(models.Model): else: res = {'total': 0.0, 'quantity': 0.0, 'amount': 0.0} return res + + def worked_ytd(self, code, allow_draft=False): + to_date = self.date_to + from_date = str(self.date_to.year) + '-01-01' + state_allowed = ('done',) if not allow_draft else ('done', 'verify', 'draft') + self.env.cr.execute(""" + SELECT sum(wd.amount) as amount + FROM hr_payslip as hp + JOIN hr_payslip_worked_days as wd ON hp.id = wd.payslip_id + JOIN hr_work_entry_type as wt ON wd.work_entry_type_id = wt.id + WHERE hp.employee_id = %s + AND hp.state in %s + AND hp.date_to >= %s AND hp.date_to <= %s AND wt.code = %s""", + (self.employee_id.id, state_allowed, from_date, to_date, code)) + res = self.env.cr.dictfetchone() + if res: + # Can return dictionary with NULL aka Nones + res['amount'] = res.get('amount', 0.0) + else: + res = {'amount': 0.0} + return res diff --git a/hr_payroll_slip_ytd/tests/test_hr_payslip_ytd.py b/hr_payroll_slip_ytd/tests/test_hr_payslip_ytd.py index 6a563da6..17de71d8 100644 --- a/hr_payroll_slip_ytd/tests/test_hr_payslip_ytd.py +++ b/hr_payroll_slip_ytd/tests/test_hr_payslip_ytd.py @@ -1,31 +1,54 @@ from odoo.addons.hr_payroll.tests.common import TestPayslipBase +from odoo.tests.common import Form +from datetime import date class TestPayslipYtd(TestPayslipBase): def test_00_payslip_ytd(self): - richard_payslip = self.env['hr.payslip'].create({ - 'name': 'Payslip of Richard', - 'employee_id': self.richard_emp.id, - 'contract_id': self.richard_emp.contract_id.id, + # The common test leaves the contract in draft mode + richard_contract = self.richard_emp.contract_ids[0] + richard_contract.state = 'open' + # pay structure in TestPayslipBase is missing default Salary Rules + # I don't need all of them, but I would like to use Basic Salary + self.developer_pay_structure.write({ + 'rule_ids': [(4, self.env['hr.salary.rule'].search([('code', '=', 'BASIC')], limit=1).id)] }) + payslip_form = Form(self.env['hr.payslip']) + payslip_form.employee_id = self.richard_emp + payslip_form.date_from = date(2020, 1, 1) + payslip_form.date_to = date(2020, 1, 31) + richard_payslip = payslip_form.save() + richard_payslip.compute_sheet() richard_payslip.action_payslip_done() + richard_payslip.flush() # Didn't have to do this in 12, but now the test fails if I don't + basic_line = richard_payslip.line_ids.filtered(lambda l: l.code == 'BASIC') self.assertEqual(basic_line.amount, 5000.0) - ytd = richard_payslip.ytd('BASIC', allow_draft=False) + self.assertEqual(basic_line.total, 5000.0) + ytd = richard_payslip.ytd(basic_line.code, allow_draft=False) self.assertEqual(ytd, {'total': 5000.0, 'quantity': 1.0, 'amount': 5000.0}) - richard_payslip_next = self.env['hr.payslip'].create({ - 'name': 'Payslip of Richard', - 'employee_id': self.richard_emp.id, - 'contract_id': self.richard_emp.contract_id.id, - }) + # get worked days + self.assertTrue(richard_payslip.worked_days_line_ids) + worked_day_line = richard_payslip.worked_days_line_ids.filtered(lambda l: l.code == 'WORK100') + self.assertEqual(worked_day_line.amount, 5000.0) + worked_day_ytd = richard_payslip.worked_ytd(worked_day_line.code, allow_draft=False) + self.assertEqual(worked_day_ytd, {'amount': 5000.0}) + payslip_form = Form(self.env['hr.payslip']) + payslip_form.employee_id = self.richard_emp + payslip_form.date_from = date(2020, 2, 1) + payslip_form.date_to = date(2020, 2, 29) + richard_payslip_next = payslip_form.save() richard_payslip_next.compute_sheet() + richard_payslip_next.flush() + basic_line = richard_payslip_next.line_ids.filtered(lambda l: l.code == 'BASIC') self.assertEqual(basic_line.amount, 5000.0) - ytd = richard_payslip_next.ytd('BASIC', allow_draft=True) + self.assertEqual(basic_line.total, 5000.0) + ytd = richard_payslip_next.ytd(basic_line.code, allow_draft=True) self.assertEqual(ytd, {'total': 10000.0, 'quantity': 2.0, 'amount': 10000.0}) - ytd = richard_payslip_next.ytd('BASIC', allow_draft=False) + ytd = richard_payslip_next.ytd(basic_line.code, allow_draft=False) self.assertEqual(ytd, {'total': 5000.0, 'quantity': 1.0, 'amount': 5000.0}) diff --git a/hr_payroll_slip_ytd/views/payslip_views.xml b/hr_payroll_slip_ytd/views/payslip_views.xml index dbe60014..c1a83a5a 100644 --- a/hr_payroll_slip_ytd/views/payslip_views.xml +++ b/hr_payroll_slip_ytd/views/payslip_views.xml @@ -1,15 +1,39 @@