Skip to content

Commit

Permalink
Merge PR #180 into 17.0
Browse files Browse the repository at this point in the history
Signed-off-by nimarosa
  • Loading branch information
OCA-git-bot committed Jan 6, 2025
2 parents 180c824 + 9abe7e1 commit cbca692
Show file tree
Hide file tree
Showing 9 changed files with 372 additions and 28 deletions.
10 changes: 5 additions & 5 deletions payroll/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,11 @@ Authors
Contributors
------------

- Odoo SA <[email protected]>
- David James <[email protected]>
- Hilar AK <[email protected]>
- Nimarosa (Nicolas Rodriguez) <[email protected]>
- Henrik Norlin (@appstogrow)
- Odoo SA <[email protected]>
- David James <[email protected]>
- Hilar AK <[email protected]>
- Nimarosa (Nicolas Rodriguez) <[email protected]>
- Henrik Norlin (@appstogrow)

Maintainers
-----------
Expand Down
1 change: 1 addition & 0 deletions payroll/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
"views/res_config_settings_views.xml",
"wizard/hr_payroll_send_email.xml",
"wizard/hr_payslip_change_state_view.xml",
"views/hr_leave_type.xml",
],
"demo": ["demo/hr_payroll_demo.xml"],
"application": True,
Expand Down
268 changes: 267 additions & 1 deletion payroll/models/base_browsable.py
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand All @@ -99,3 +99,269 @@ 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()
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 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()
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 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()
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 min_rule_monthly(self, code, from_date, to_date=None):
if to_date is None:
to_date = fields.Date.today()
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),
)
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()

hierarchy_codes = (
self.env["hr.salary.rule.category"]
.search([("code", "=", code)])
.children_ids.mapped("code")
)
hierarchy_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 hp, hr_payslip_line pl, hr_salary_rule_category 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(hierarchy_codes)),
)
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()

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(case when hp.credit_note is not True then
(pl.total) else (-pl.total) end)
FROM hr_payslip hp, hr_payslip_line pl, hr_salary_rule_category 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(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 hp, hr_payslip_line pl, hr_salary_rule_category 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

def max_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")
)
hierarchy_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 hp, hr_payslip_line pl, hr_salary_rule_category 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(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 hp, hr_payslip_line pl, hr_salary_rule_category 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

def min_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")
)
hierarchy_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 hp, hr_payslip_line pl, hr_salary_rule_category 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(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 hp, hr_payslip_line pl, hr_salary_rule_category 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
28 changes: 23 additions & 5 deletions payroll/models/hr_payslip.py
Original file line number Diff line number Diff line change
Expand Up @@ -471,7 +471,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()
Expand Down Expand Up @@ -533,10 +536,10 @@ def _get_lines_dict(
total = values["quantity"] * values["rate"] * values["amount"] / 100.0
values["total"] = total
# set/overwrite the amount computed for this rule in the localdict
if rule.code:
localdict[rule.code] = total
localdict["rules"].dict[rule.code] = rule
localdict["result_rules"].dict[rule.code] = BaseBrowsableObject(values)
code = rule.code or rule.id
localdict[code] = total
localdict["rules"].dict[code] = rule
localdict["result_rules"].dict[code] = BaseBrowsableObject(values)
# sum the amount for its salary category
localdict = self._sum_salary_rule_category(
localdict, rule.category_id, total - previous_amount
Expand Down Expand Up @@ -781,3 +784,18 @@ def get_salary_line_total(self, code):
return line[0].total
else:
return 0.0

def line_sum_where(self, field_name, value, rules, result_rules):
"""
The method may be used in salary rule code.
It will sum the total of the previously computed rules
where the given field has the given value.
E.g.: total_seq_10 = payslip.line_sum_where("sequence", 10, rules, result_rules)
"""
return sum(
[
result_rules.dict[code].dict["total"]
for code, rule in rules.dict.items()
if getattr(rule, field_name) == value
]
)
4 changes: 3 additions & 1 deletion payroll/models/hr_salary_rule.py
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,9 @@ def _compute_rule(self, localdict):
"""
self.ensure_one()
method = f"_compute_rule_{self.amount_select}"
return api.call_kw(self, method, [self.ids, localdict], {})
return api.call_kw(
self, method, [self.ids, localdict], {"context": self.env.context}
)

def _compute_rule_fix(self, localdict):
try:
Expand Down
Loading

0 comments on commit cbca692

Please sign in to comment.