我正在使用Odoo Payroll 15和一些自定义python结构。
我有某种类型的税,每个员工在一年内必须支付的最高金额。我想把当年的工资单上某一行的工资单加起来,这样我就能正确地计算出工资单上必须支付的金额。
我以前试过这个,但它似乎只使用当前工资单在其计算:
payslip.sum('THE_TAX', '2022-01-01', '2022-12-31')
如何在工资单规则中访问以前的工资单?需要Odoo 16的解决方案也适用于我。
您的示例和sum实现之间的主要区别在于您的代码不检查工资单状态。这意味着它也会计算所有已取消和未完成的工资单。sum实现只计算状态为"done"的工资单。
您可以在工资单模型中添加sum函数的修改,并在需要不同的行为时调用它。
实现来自v12。现在hr_工资单是在企业版。
class Payslips(BrowsableObject):
def sum(self, code, from_date, to_date=None):
if to_date is None:
to_date = fields.Date.today()
self.env.cr.execute("""SELECT sum(pl.total) -- this line is different in v12 and v15
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
https://github.com/odoo/odoo/blob/c53081f10befd4f1c98e46a450ed3bc71a6246ed/addons/hr_payroll/models/hr_payslip.py L300
编辑:我认为是odoo的bug,应该包含付费状态,但是没有。你可以使用代码的变体;过滤和映射函数应该会使它更快。
我不能测试代码:
already_paid = sum(
employee.mapped("slip_ids")
.filtered(lambda s: s.date_from.year == 2022 and s.state in ("done", "paid"))
.mapped("line_ids")
.filtered(lambda l: l.code == "THE_TAX")
.mapped("total")
)
我想我找到了一个丑陋的解决方案,它确实给出了正确的答案:
already_paid = 0.0
for slip in employee.slip_ids:
for line in slip.line_ids:
if line.code != "THE_TAX":
continue
if line.date_from.year != 2022:
continue
already_paid += line.total