如何修改Odoo v17休假计提逻辑,新增无薪假时自动重算?
解决Odoo v17无薪假新增后自动重算休假计提的方案
核心思路
监听hr.leave模型的创建、修改、删除操作,当操作的假别为无薪假时,触发对应员工的休假分配记录重新执行你已实现的计提计算逻辑。
具体实现步骤
1. 继承hr.leave模型,添加触发逻辑
在自定义模块中继承hr.leave,重写核心操作方法,判断假别类型后调用重算逻辑:
from odoo import models, api class HrLeave(models.Model): _inherit = 'hr.leave' @api.model def create(self, vals): leave = super().create(vals) # 用xml_id判断更可靠,避免名称修改失效,替换为你的无薪假xml_id if leave.holiday_status_id.xml_id == 'your_module.unpaid_leave_type': self._trigger_leave_allocation_recalc(leave.employee_id) return leave def write(self, vals): res = super().write(vals) # 假别、员工变更,或当前是无薪假时触发重算 if 'holiday_status_id' in vals or 'employee_id' in vals or self.holiday_status_id.xml_id == 'your_module.unpaid_leave_type': for leave in self: self._trigger_leave_allocation_recalc(leave.employee_id) return res def unlink(self): # 删除前记录关联员工和假别类型 target_employees = self.mapped('employee_id') is_unpaid_leave = any(leave.holiday_status_id.xml_id == 'your_module.unpaid_leave_type' for leave in self) res = super().unlink() if is_unpaid_leave: for emp in target_employees: self._trigger_leave_allocation_recalc(emp) return res def _trigger_leave_allocation_recalc(self, employee): # 筛选该员工的年度休假分配记录,替换为你的年假类型xml_id allocations = self.env['hr.leave.allocation'].search([ ('employee_id', '=', employee.id), ('holiday_status_id.xml_id', '=', 'your_module.annual_leave_type'), ('state', 'in', ['draft', 'validate']) # 针对未提交/已审核的分配记录 ]) # 调用你已实现的计提计算方法 for alloc in allocations: calc_entitlement = alloc._compute_annual_leave_entitlement() alloc.write({'number_of_days': calc_entitlement}) # 若需同步可用余额,可调用Odoo内置方法或自定义更新逻辑 alloc.action_refresh()
2. 确保计提计算逻辑可复用
把你之前在HolidaysAllocation中实现的计算逻辑封装成独立方法,方便触发调用:
class HolidaysAllocation(models.Model): _inherit = 'hr.leave.allocation' def _compute_annual_leave_entitlement(self): # 你的核心计算逻辑:总工作天数 - 已审核无薪假天数,再计算计提 total_work_days = self._get_employee_total_work_days() # 自定义总工作天数计算方法 unpaid_days = self.env['hr.leave'].search([ ('employee_id', '=', self.employee_id.id), ('holiday_status_id.xml_id', '=', 'your_module.unpaid_leave_type'), ('state', '=', 'validate') ]).mapped('number_of_days') adjusted_days = total_work_days - sum(unpaid_days) # 替换为你的计提公式 return adjusted_days * 0.12 # 示例:按12%比例计提年假
3. 处理状态与权限细节
- 若分配记录已处于
validate状态,直接修改number_of_days后需调用action_refresh()同步可用余额; - 批量操作时可优化逻辑,避免重复触发同一员工的多次计算,比如用
set去重员工后统一处理。
4. 测试验证
- 新增并审核无薪假,检查对应员工年假计提数值是否自动更新;
- 修改无薪假天数/时间段,确认计提重新计算;
- 删除无薪假,验证计提恢复至正确数值。
注意事项
- 始终使用假别的
xml_id而非名称判断类型,避免业务中修改假别名称导致逻辑失效; - 若涉及多公司或权限控制,需在搜索条件中添加对应过滤字段。
内容的提问来源于stack exchange,提问作者Nir Vana
相关产品推荐
相关产品推荐

