From 8594e779d30c236580a085465ff8e02413dcfb0f Mon Sep 17 00:00:00 2001 From: nicolasrsande Date: Fri, 2 Dec 2022 19:17:25 -0300 Subject: [PATCH 1/9] [14.0] [IMP] payroll: Add sum_category payslips browsable method --- payroll/models/base_browsable.py | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/payroll/models/base_browsable.py b/payroll/models/base_browsable.py index 58333ce8..39e0df63 100644 --- a/payroll/models/base_browsable.py +++ b/payroll/models/base_browsable.py @@ -99,3 +99,32 @@ def sum(self, code, from_date, to_date=None): ) res = self.env.cr.fetchone() return res and res[0] or 0.0 + + def sum_category(self, code, from_date, to_date=None): + if to_date is None: + to_date = fields.Date.today() + + self.env["hr.payslip"].flush( + ["credit_note", "employee_id", "state", "date_from", "date_to"] + ) + self.env["hr.payslip.line"].flush(["total", "slip_id", "category_id"]) + self.env["hr.salary.rule.category"].flush(["code"]) + + hicherarchy_codes = ( + self.env["hr.salary.rule.category"] + .search([("code", "=", code)]) + .children_ids.mapped("code") + ) + hicherarchy_codes.append(code) + + self.env.cr.execute( + """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.date_from >= %s AND hp.date_to <= %s AND hp.id = pl.slip_id + AND rc.id = pl.category_id AND rc.code in %s""", + (self.employee_id, from_date, to_date, tuple(hicherarchy_codes)), + ) + res = self.env.cr.fetchone() + return res and res[0] or 0.0 From be10fc2a52a5d8be2c850c3c5442cf28dd07e1be Mon Sep 17 00:00:00 2001 From: nicolasrsande Date: Mon, 5 Dec 2022 18:51:10 -0300 Subject: [PATCH 2/9] [14.0] [IMP] payroll: Add datetime to tools object --- payroll/models/hr_payslip.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/payroll/models/hr_payslip.py b/payroll/models/hr_payslip.py index 6a0e6a7f..f13a6137 100644 --- a/payroll/models/hr_payslip.py +++ b/payroll/models/hr_payslip.py @@ -487,7 +487,10 @@ def get_current_contract_dict(self, contract, contracts): def _get_tools_dict(self): # _get_tools_dict() is intended to be inherited by other private modules # to add tools or python libraries available in localdict - return {"math": math} # "math" object is useful for doing calculations + return { + "math": math, + "datetime": datetime, + } # "math" object is useful for doing calculations def _get_baselocaldict(self, contracts): self.ensure_one() From e01121f836a3b50278b1da513af15429e2ccd2c7 Mon Sep 17 00:00:00 2001 From: nicolasrsande Date: Mon, 5 Dec 2022 19:13:28 -0300 Subject: [PATCH 3/9] [14.0] [IMP] payroll: Add "category_max" and "rule_max" method --- payroll/models/base_browsable.py | 38 ++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/payroll/models/base_browsable.py b/payroll/models/base_browsable.py index 39e0df63..cdb647cf 100644 --- a/payroll/models/base_browsable.py +++ b/payroll/models/base_browsable.py @@ -100,6 +100,21 @@ def sum(self, code, from_date, to_date=None): res = self.env.cr.fetchone() return res and res[0] or 0.0 + def rule_max(self, code, from_date, to_date=None): + if to_date is None: + to_date = fields.Date.today() + self.env.cr.execute( + """SELECT max(case when hp.credit_note = False then + (pl.total) else (-pl.total) end) + FROM hr_payslip as hp, hr_payslip_line as pl + WHERE hp.employee_id = %s AND hp.state = 'done' + AND hp.date_from >= %s AND hp.date_to <= %s AND + hp.id = pl.slip_id AND pl.code = %s""", + (self.employee_id, from_date, to_date, code), + ) + res = self.env.cr.fetchone() + return res and res[0] or 0.0 + def sum_category(self, code, from_date, to_date=None): if to_date is None: to_date = fields.Date.today() @@ -128,3 +143,26 @@ def sum_category(self, code, from_date, to_date=None): ) res = self.env.cr.fetchone() return res and res[0] or 0.0 + + def category_max(self, code, from_date, to_date=None): + if to_date is None: + to_date = fields.Date.today() + + hicherarchy_codes = ( + self.env["hr.salary.rule.category"] + .search([("code", "=", code)]) + .children_ids.mapped("code") + ) + hicherarchy_codes.append(code) + + self.env.cr.execute( + """SELECT max(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.date_from >= %s AND hp.date_to <= %s AND hp.id = pl.slip_id + AND rc.id = pl.category_id AND rc.code in %s""", + (self.employee_id, from_date, to_date, tuple(hicherarchy_codes)), + ) + res = self.env.cr.fetchone() + return res and res[0] or 0.0 From 601fcc0cd9ed17673beb5bb64f7ff72904ea77fb Mon Sep 17 00:00:00 2001 From: nicolasrsande Date: Mon, 5 Dec 2022 19:14:16 -0300 Subject: [PATCH 4/9] [14.0] [IMP] payroll: Add "category_max" and "rule_max" method --- payroll/models/base_browsable.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/payroll/models/base_browsable.py b/payroll/models/base_browsable.py index cdb647cf..e600bd00 100644 --- a/payroll/models/base_browsable.py +++ b/payroll/models/base_browsable.py @@ -100,7 +100,7 @@ def sum(self, code, from_date, to_date=None): res = self.env.cr.fetchone() return res and res[0] or 0.0 - def rule_max(self, code, from_date, to_date=None): + def max_rule(self, code, from_date, to_date=None): if to_date is None: to_date = fields.Date.today() self.env.cr.execute( @@ -144,7 +144,7 @@ def sum_category(self, code, from_date, to_date=None): res = self.env.cr.fetchone() return res and res[0] or 0.0 - def category_max(self, code, from_date, to_date=None): + def max_category(self, code, from_date, to_date=None): if to_date is None: to_date = fields.Date.today() From a903dd8c78653ca70d39575b7bba5f1b8bdacba9 Mon Sep 17 00:00:00 2001 From: nicolasrsande Date: Mon, 5 Dec 2022 19:27:54 -0300 Subject: [PATCH 5/9] [14.0] [IMP] payroll: Add "min_category" and "min_rule" method --- payroll/models/base_browsable.py | 38 ++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/payroll/models/base_browsable.py b/payroll/models/base_browsable.py index e600bd00..0661de13 100644 --- a/payroll/models/base_browsable.py +++ b/payroll/models/base_browsable.py @@ -115,6 +115,21 @@ def max_rule(self, code, from_date, to_date=None): res = self.env.cr.fetchone() return res and res[0] or 0.0 + def min_rule(self, code, from_date, to_date=None): + if to_date is None: + to_date = fields.Date.today() + self.env.cr.execute( + """SELECT min(case when hp.credit_note = False then + (pl.total) else (-pl.total) end) + FROM hr_payslip as hp, hr_payslip_line as pl + WHERE hp.employee_id = %s AND hp.state = 'done' + AND hp.date_from >= %s AND hp.date_to <= %s AND + hp.id = pl.slip_id AND pl.code = %s""", + (self.employee_id, from_date, to_date, code), + ) + res = self.env.cr.fetchone() + return res and res[0] or 0.0 + def sum_category(self, code, from_date, to_date=None): if to_date is None: to_date = fields.Date.today() @@ -166,3 +181,26 @@ def max_category(self, code, from_date, to_date=None): ) res = self.env.cr.fetchone() return res and res[0] or 0.0 + + def min_category(self, code, from_date, to_date=None): + if to_date is None: + to_date = fields.Date.today() + + hicherarchy_codes = ( + self.env["hr.salary.rule.category"] + .search([("code", "=", code)]) + .children_ids.mapped("code") + ) + hicherarchy_codes.append(code) + + self.env.cr.execute( + """SELECT min(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.date_from >= %s AND hp.date_to <= %s AND hp.id = pl.slip_id + AND rc.id = pl.category_id AND rc.code in %s""", + (self.employee_id, from_date, to_date, tuple(hicherarchy_codes)), + ) + res = self.env.cr.fetchone() + return res and res[0] or 0.0 From 8e2a931d0038f97a6b87701da182b6f7bae67d5a Mon Sep 17 00:00:00 2001 From: nicolasrsande Date: Tue, 6 Dec 2022 00:04:26 -0300 Subject: [PATCH 6/9] [14.0] [IMP] payroll: Add "average_category" and "average_rule" --- payroll/models/base_browsable.py | 38 ++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/payroll/models/base_browsable.py b/payroll/models/base_browsable.py index 0661de13..3b9ae06f 100644 --- a/payroll/models/base_browsable.py +++ b/payroll/models/base_browsable.py @@ -100,6 +100,21 @@ def sum(self, code, from_date, to_date=None): res = self.env.cr.fetchone() return res and res[0] or 0.0 + def average_rule(self, code, from_date, to_date=None): + if to_date is None: + to_date = fields.Date.today() + self.env.cr.execute( + """SELECT avg(case when hp.credit_note = False then + (pl.total) else (-pl.total) end) + FROM hr_payslip as hp, hr_payslip_line as pl + WHERE hp.employee_id = %s AND hp.state = 'done' + AND hp.date_from >= %s AND hp.date_to <= %s AND + hp.id = pl.slip_id AND pl.code = %s""", + (self.employee_id, from_date, to_date, code), + ) + res = self.env.cr.fetchone() + return res and res[0] or 0.0 + def max_rule(self, code, from_date, to_date=None): if to_date is None: to_date = fields.Date.today() @@ -159,6 +174,29 @@ def sum_category(self, code, from_date, to_date=None): res = self.env.cr.fetchone() return res and res[0] or 0.0 + def average_category(self, code, from_date, to_date=None): + if to_date is None: + to_date = fields.Date.today() + + hicherarchy_codes = ( + self.env["hr.salary.rule.category"] + .search([("code", "=", code)]) + .children_ids.mapped("code") + ) + hicherarchy_codes.append(code) + + self.env.cr.execute( + """SELECT avg(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.date_from >= %s AND hp.date_to <= %s AND hp.id = pl.slip_id + AND rc.id = pl.category_id AND rc.code in %s""", + (self.employee_id, from_date, to_date, tuple(hicherarchy_codes)), + ) + res = self.env.cr.fetchone() + return res and res[0] or 0.0 + def max_category(self, code, from_date, to_date=None): if to_date is None: to_date = fields.Date.today() From 8361405f04d8d78c5eb726e3a9891d5696f84bce Mon Sep 17 00:00:00 2001 From: nicolasrsande Date: Tue, 6 Dec 2022 10:58:01 -0300 Subject: [PATCH 7/9] [14.0] [IMP] payroll: Rename sum() to sum_rule() and add deprecation warning --- payroll/models/base_browsable.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/payroll/models/base_browsable.py b/payroll/models/base_browsable.py index 3b9ae06f..e701cf01 100644 --- a/payroll/models/base_browsable.py +++ b/payroll/models/base_browsable.py @@ -85,7 +85,7 @@ class Payslips(BrowsableObject): """a class that will be used into the python code, mainly for usability purposes""" - def sum(self, code, from_date, to_date=None): + def sum_rule(self, code, from_date, to_date=None): if to_date is None: to_date = fields.Date.today() self.env.cr.execute( @@ -100,6 +100,12 @@ def sum(self, code, from_date, to_date=None): res = self.env.cr.fetchone() return res and res[0] or 0.0 + def sum(self, code, from_date, to_date=None): + _logger.warning( + "Payslips Object: sum() method is DEPRECATED. Use sum_rule() instead." + ) + return self.sum_rule(code, from_date, to_date) + def average_rule(self, code, from_date, to_date=None): if to_date is None: to_date = fields.Date.today() From b98fee7f4cdae09e5e7a4791399fbf6f8feaadd1 Mon Sep 17 00:00:00 2001 From: nicolasrsande Date: Tue, 6 Dec 2022 23:35:55 -0300 Subject: [PATCH 8/9] [14.0] [IMP] payroll: Add min/max/average monthly methods --- payroll/models/base_browsable.py | 153 +++++++++++++++++++++++++++---- 1 file changed, 135 insertions(+), 18 deletions(-) diff --git a/payroll/models/base_browsable.py b/payroll/models/base_browsable.py index e701cf01..ac0d9283 100644 --- a/payroll/models/base_browsable.py +++ b/payroll/models/base_browsable.py @@ -121,6 +121,21 @@ def average_rule(self, code, from_date, to_date=None): res = self.env.cr.fetchone() return res and res[0] or 0.0 + def average_rule_monthly(self, code, from_date, to_date=None): + if to_date is None: + to_date = fields.Date.today() + self.env.cr.execute( + """SELECT avg(total) FROM (SELECT max(case when hp.credit_note = False then + (pl.total) else (-pl.total) end) + FROM hr_payslip as hp, hr_payslip_line as pl + WHERE hp.employee_id = %s AND hp.state = 'done' + AND hp.date_from >= %s AND hp.date_to <= %s AND + hp.id = pl.slip_id AND pl.code = %s) AS monthly_sum""", + (self.employee_id, from_date, to_date, code), + ) + res = self.env.cr.fetchone() + return res and res[0] or 0.0 + def max_rule(self, code, from_date, to_date=None): if to_date is None: to_date = fields.Date.today() @@ -136,6 +151,21 @@ def max_rule(self, code, from_date, to_date=None): res = self.env.cr.fetchone() return res and res[0] or 0.0 + def max_rule_monthly(self, code, from_date, to_date=None): + if to_date is None: + to_date = fields.Date.today() + self.env.cr.execute( + """SELECT max(total) FROM (SELECT max(case when hp.credit_note = False then + (pl.total) else (-pl.total) end) + FROM hr_payslip as hp, hr_payslip_line as pl + WHERE hp.employee_id = %s AND hp.state = 'done' + AND hp.date_from >= %s AND hp.date_to <= %s AND + hp.id = pl.slip_id AND pl.code = %s) AS monthly_sum""", + (self.employee_id, from_date, to_date, code), + ) + res = self.env.cr.fetchone() + return res and res[0] or 0.0 + def min_rule(self, code, from_date, to_date=None): if to_date is None: to_date = fields.Date.today() @@ -151,22 +181,31 @@ def min_rule(self, code, from_date, to_date=None): res = self.env.cr.fetchone() return res and res[0] or 0.0 - def sum_category(self, code, from_date, to_date=None): + def min_rule_monthly(self, code, from_date, to_date=None): if to_date is None: to_date = fields.Date.today() - - self.env["hr.payslip"].flush( - ["credit_note", "employee_id", "state", "date_from", "date_to"] + self.env.cr.execute( + """SELECT min(total) FROM (SELECT max(case when hp.credit_note = False then + (pl.total) else (-pl.total) end) + FROM hr_payslip as hp, hr_payslip_line as pl + WHERE hp.employee_id = %s AND hp.state = 'done' + AND hp.date_from >= %s AND hp.date_to <= %s AND + hp.id = pl.slip_id AND pl.code = %s) AS monthly_sum""", + (self.employee_id, from_date, to_date, code), ) - self.env["hr.payslip.line"].flush(["total", "slip_id", "category_id"]) - self.env["hr.salary.rule.category"].flush(["code"]) + res = self.env.cr.fetchone() + return res and res[0] or 0.0 - hicherarchy_codes = ( + def sum_category(self, code, from_date, to_date=None): + if to_date is None: + to_date = fields.Date.today() + + hierarchy_codes = ( self.env["hr.salary.rule.category"] .search([("code", "=", code)]) .children_ids.mapped("code") ) - hicherarchy_codes.append(code) + hierarchy_codes.append(code) self.env.cr.execute( """SELECT sum(case when hp.credit_note is not True then @@ -175,7 +214,7 @@ def sum_category(self, code, from_date, to_date=None): WHERE hp.employee_id = %s AND hp.state = 'done' AND hp.date_from >= %s AND hp.date_to <= %s AND hp.id = pl.slip_id AND rc.id = pl.category_id AND rc.code in %s""", - (self.employee_id, from_date, to_date, tuple(hicherarchy_codes)), + (self.employee_id, from_date, to_date, tuple(hierarchy_codes)), ) res = self.env.cr.fetchone() return res and res[0] or 0.0 @@ -184,12 +223,12 @@ def average_category(self, code, from_date, to_date=None): if to_date is None: to_date = fields.Date.today() - hicherarchy_codes = ( + hierarchy_codes = ( self.env["hr.salary.rule.category"] .search([("code", "=", code)]) .children_ids.mapped("code") ) - hicherarchy_codes.append(code) + hierarchy_codes.append(code) self.env.cr.execute( """SELECT avg(case when hp.credit_note is not True then @@ -198,7 +237,33 @@ def average_category(self, code, from_date, to_date=None): WHERE hp.employee_id = %s AND hp.state = 'done' AND hp.date_from >= %s AND hp.date_to <= %s AND hp.id = pl.slip_id AND rc.id = pl.category_id AND rc.code in %s""", - (self.employee_id, from_date, to_date, tuple(hicherarchy_codes)), + (self.employee_id, from_date, to_date, tuple(hierarchy_codes)), + ) + res = self.env.cr.fetchone() + return res and res[0] or 0.0 + + def average_category_monthly(self, code, from_date, to_date=None): + if to_date is None: + to_date = fields.Date.today() + + hierarchy_codes = ( + self.env["hr.salary.rule.category"] + .search([("code", "=", code)]) + .children_ids.mapped("code") + ) + hierarchy_codes.append(code) + + self.env.cr.execute( + """SELECT avg(total) FROM ( + SELECT DATE_TRUNC('month',hp.date_from) AS date_month, + sum(case when hp.credit_note is not True then + (pl.total) else (-pl.total) end) AS total + 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.date_from >= %s AND hp.date_to <= %s AND hp.id = pl.slip_id + AND rc.id = pl.category_id AND rc.code in %s + GROUP BY date_month) AS monthly_sum""", + (self.employee_id, from_date, to_date, tuple(hierarchy_codes)), ) res = self.env.cr.fetchone() return res and res[0] or 0.0 @@ -207,12 +272,12 @@ def max_category(self, code, from_date, to_date=None): if to_date is None: to_date = fields.Date.today() - hicherarchy_codes = ( + hierarchy_codes = ( self.env["hr.salary.rule.category"] .search([("code", "=", code)]) .children_ids.mapped("code") ) - hicherarchy_codes.append(code) + hierarchy_codes.append(code) self.env.cr.execute( """SELECT max(case when hp.credit_note is not True then @@ -221,7 +286,33 @@ def max_category(self, code, from_date, to_date=None): WHERE hp.employee_id = %s AND hp.state = 'done' AND hp.date_from >= %s AND hp.date_to <= %s AND hp.id = pl.slip_id AND rc.id = pl.category_id AND rc.code in %s""", - (self.employee_id, from_date, to_date, tuple(hicherarchy_codes)), + (self.employee_id, from_date, to_date, tuple(hierarchy_codes)), + ) + res = self.env.cr.fetchone() + return res and res[0] or 0.0 + + def max_category_monthly(self, code, from_date, to_date=None): + if to_date is None: + to_date = fields.Date.today() + + hierarchy_codes = ( + self.env["hr.salary.rule.category"] + .search([("code", "=", code)]) + .children_ids.mapped("code") + ) + hierarchy_codes.append(code) + + self.env.cr.execute( + """SELECT max(total) FROM ( + SELECT DATE_TRUNC('month',hp.date_from) AS date_month, + sum(case when hp.credit_note is not True then + (pl.total) else (-pl.total) end) AS total + 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.date_from >= %s AND hp.date_to <= %s AND hp.id = pl.slip_id + AND rc.id = pl.category_id AND rc.code in %s + GROUP BY date_month) AS monthly_sum""", + (self.employee_id, from_date, to_date, tuple(hierarchy_codes)), ) res = self.env.cr.fetchone() return res and res[0] or 0.0 @@ -230,12 +321,12 @@ def min_category(self, code, from_date, to_date=None): if to_date is None: to_date = fields.Date.today() - hicherarchy_codes = ( + hierarchy_codes = ( self.env["hr.salary.rule.category"] .search([("code", "=", code)]) .children_ids.mapped("code") ) - hicherarchy_codes.append(code) + hierarchy_codes.append(code) self.env.cr.execute( """SELECT min(case when hp.credit_note is not True then @@ -244,7 +335,33 @@ def min_category(self, code, from_date, to_date=None): WHERE hp.employee_id = %s AND hp.state = 'done' AND hp.date_from >= %s AND hp.date_to <= %s AND hp.id = pl.slip_id AND rc.id = pl.category_id AND rc.code in %s""", - (self.employee_id, from_date, to_date, tuple(hicherarchy_codes)), + (self.employee_id, from_date, to_date, tuple(hierarchy_codes)), + ) + res = self.env.cr.fetchone() + return res and res[0] or 0.0 + + def min_category_monthly(self, code, from_date, to_date=None): + if to_date is None: + to_date = fields.Date.today() + + hierarchy_codes = ( + self.env["hr.salary.rule.category"] + .search([("code", "=", code)]) + .children_ids.mapped("code") + ) + hierarchy_codes.append(code) + + self.env.cr.execute( + """SELECT min(total) FROM ( + SELECT DATE_TRUNC('month',hp.date_from) AS date_month, + sum(case when hp.credit_note is not True then + (pl.total) else (-pl.total) end) AS total + 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.date_from >= %s AND hp.date_to <= %s AND hp.id = pl.slip_id + AND rc.id = pl.category_id AND rc.code in %s + GROUP BY date_month) AS monthly_sum""", + (self.employee_id, from_date, to_date, tuple(hierarchy_codes)), ) res = self.env.cr.fetchone() return res and res[0] or 0.0 From b52ee7976bb4c005eb2e21e8c4972d0b4bc0c6fe Mon Sep 17 00:00:00 2001 From: nicolasrsande Date: Wed, 7 Dec 2022 13:33:17 -0300 Subject: [PATCH 9/9] [14.0] [IMP] payroll: Add group to controls buttons --- payroll/views/hr_payslip_views.xml | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/payroll/views/hr_payslip_views.xml b/payroll/views/hr_payslip_views.xml index 1ac58210..db6d710f 100644 --- a/payroll/views/hr_payslip_views.xml +++ b/payroll/views/hr_payslip_views.xml @@ -238,15 +238,17 @@ - - - + + + + +