添加功能
This commit is contained in:
@@ -864,30 +864,32 @@ class HolidaysRequestBatch(models.Model):
|
||||
interval_hours = hours / 8
|
||||
else:
|
||||
interval_hours = self._compute_duration_day(holiday_type, interval_start, interval_end)
|
||||
period_start = interval['period_start']
|
||||
vacation_report1 = self.env['yuthon.vacation.reports'].search([
|
||||
period_start = interval['period_start']
|
||||
if not employee_id:
|
||||
continue
|
||||
# 严格按请假所属月份定位报表(不再回退到当前月 first_day)。
|
||||
# 产假等长假期会落到未来月份,而 yuthon.vacation.reports 只提前一个月生成,
|
||||
# 未来月份报表尚未生成 → 按需生成(与 monthly_report 创建方式一致)。
|
||||
vacation_report = self.env['yuthon.vacation.reports'].search([
|
||||
('employee_id', '=', employee_id),
|
||||
('vacation_date', '=', period_start),
|
||||
], limit=1)
|
||||
first_day = fields.Date.today().replace(day=1)
|
||||
vacation_report = self.env['yuthon.vacation.reports'].search([
|
||||
('employee_id', '=', employee_id),
|
||||
('vacation_date', '=', first_day),
|
||||
], limit=1)
|
||||
actual_vacation_report = vacation_report
|
||||
if vacation_report1 and vacation_report1.vacation_state != 'confirmed':
|
||||
actual_vacation_report = vacation_report1
|
||||
if not actual_vacation_report:
|
||||
continue # 无报表,跳过创建
|
||||
if not vacation_report:
|
||||
vacation_report = self.env['yuthon.vacation.reports'].create({
|
||||
'employee_id': employee_id,
|
||||
'vacation_date': period_start,
|
||||
})
|
||||
vacation_report.update_line()
|
||||
vacation_report.vacation_state = 'not_sent'
|
||||
leave_id = leave_data.get('leave_id', False)
|
||||
existing_leave_line = self.env['vacation.other.line'].search([
|
||||
('vacation_id', '=', actual_vacation_report.id),
|
||||
('vacation_id', '=', vacation_report.id),
|
||||
('leave_id', '=', leave_id),
|
||||
], limit=1)
|
||||
if not existing_leave_line:
|
||||
self.env['vacation.other.line'].create({
|
||||
'leave_id': leave_id,
|
||||
'vacation_id': actual_vacation_report.id,
|
||||
'vacation_id': vacation_report.id,
|
||||
'employee_id': employee_id,
|
||||
'workflow_record_id': leave_data.get('workflow_id', False),
|
||||
'update_type': 'reduce',
|
||||
|
||||
@@ -11,6 +11,17 @@ from odoo.tools import date_utils
|
||||
from dateutil.relativedelta import relativedelta
|
||||
from odoo.exceptions import UserError, ValidationError
|
||||
|
||||
# 与 inherit_hr_leave.action_submit 中的 OTHER_LEAVE_TYPES 保持一致:
|
||||
# 排除「年假」「补休」(它们分别落到 vacation.leave.line / vacation.over.line),其余都进 vacation.other.line。
|
||||
# 注:原 update_line 中专门的「产假」分支(unpaid_leaves)已移除,产假统一由此处自愈逻辑处理,
|
||||
# 去重键为 (vacation_id, leave_id),与提交侧 _create_other_leave_line 一致,不会重复。
|
||||
# 如 action_submit 的类型列表有调整,需同步此处。
|
||||
OTHER_LEAVE_SYNC_TYPES = [
|
||||
'产假', '事假', '法定假', '调休', '值班调休', '婚假', '陪产假',
|
||||
'计生假', '丧假', '探亲假', '哺乳假', '家长会假', '病假(普通)',
|
||||
'病假(住院期)', '育儿假', '病假(出院恢复期)', '考试假',
|
||||
]
|
||||
|
||||
|
||||
class YuthonVacationReports(models.Model):
|
||||
_name = 'yuthon.vacation.reports'
|
||||
@@ -482,6 +493,58 @@ class YuthonVacationReports(models.Model):
|
||||
rec._compute_parental_leave()
|
||||
rec._compute_working_overtime()
|
||||
|
||||
# ========== 第三步:自愈 - 补建未计入的「其他类型」请假明细 ==========
|
||||
# 针对产假等长假期:请假跨度覆盖未来月份,而 yuthon.vacation.reports 只提前一个月生成,
|
||||
# 未来月份的报表在对应月份真正到来、重新计算(update_line)时,需把尚未计入的请假补建到明细行。
|
||||
# 年假/补休有各自明细模型(vacation.leave.line / vacation.over.line),不在此处理。
|
||||
for rec in self:
|
||||
rep_month_start = rec.vacation_date
|
||||
if not rep_month_start or not rec.employee_id:
|
||||
continue
|
||||
# 该月最后一天
|
||||
if rep_month_start.month == 12:
|
||||
rep_month_end = date(rep_month_start.year + 1, 1, 1) - timedelta(days=1)
|
||||
else:
|
||||
rep_month_end = date(rep_month_start.year, rep_month_start.month + 1, 1) - timedelta(days=1)
|
||||
# 找覆盖本月、属于「其他类型」的请假明细(hr.leave.detail,batch_id 非空)
|
||||
leaves = self.env['hr.leave'].search([
|
||||
('employee_id', '=', rec.employee_id.id),
|
||||
('holiday_status_id.name', 'in', OTHER_LEAVE_SYNC_TYPES),
|
||||
('state', '=', 'validate'),
|
||||
('request_date_from', '<=', fields.Date.to_string(rep_month_end)),
|
||||
('request_date_to', '>=', fields.Date.to_string(rep_month_start)),
|
||||
('batch_id', '!=', False),
|
||||
])
|
||||
for leave in leaves:
|
||||
# 去重:同一报表 + 同一明细请假 已存在则跳过(避免与提交侧重复创建)
|
||||
if self.env['vacation.other.line'].search([
|
||||
('vacation_id', '=', rec.id),
|
||||
('leave_id', '=', leave.id),
|
||||
], limit=1):
|
||||
continue
|
||||
# 计算本月区间内的天数(与提交侧 _create_other_leave_line 的算法一致)
|
||||
seg_start = max(fields.Date.from_string(leave.request_date_from), rep_month_start)
|
||||
seg_end = min(fields.Date.from_string(leave.request_date_to), rep_month_end)
|
||||
batch = leave.batch_id
|
||||
days = self._compute_duration_day(leave.holiday_status_id, seg_start, seg_end)
|
||||
if not days or days <= 0:
|
||||
continue
|
||||
workflow_id = False
|
||||
if batch and batch.code:
|
||||
workflow_id = self.env['soong.workflow.record'].search([('code', '=', batch.code)], limit=1).id
|
||||
self.env['vacation.other.line'].create({
|
||||
'leave_id': leave.id,
|
||||
'vacation_id': rec.id,
|
||||
'employee_id': rec.employee_id.id,
|
||||
'workflow_record_id': workflow_id,
|
||||
'update_type': 'reduce',
|
||||
'lines': days,
|
||||
'holiday_type': leave.holiday_status_id.id,
|
||||
'update_date': fields.Date.today(),
|
||||
'is_void': False,
|
||||
'text': '请假审批',
|
||||
})
|
||||
|
||||
def update_vacation(self):
|
||||
records = self.env["yuthon.vacation.reports"].browse(
|
||||
self._context.get('active_ids', self._context.get('active_id', self.ids))
|
||||
@@ -1753,11 +1816,6 @@ class YuthonVacationReports(models.Model):
|
||||
for rec in self:
|
||||
employee = rec.employee_id
|
||||
vacation_date = rec.vacation_date
|
||||
unpaid_leaves = self.env['hr.leave'].search([
|
||||
('employee_id', '=', employee.id),
|
||||
('holiday_status_id.name', '=', ['产假']),
|
||||
('state', '=', 'validate')
|
||||
])
|
||||
last_month_last = rec.vacation_date - timedelta(days=1)
|
||||
last_month_first = last_month_last.replace(day=1)
|
||||
last_month_record = self.search([
|
||||
@@ -1811,49 +1869,6 @@ class YuthonVacationReports(models.Model):
|
||||
inherit_vals['valid_date1'] = last_month_record.valid_date1
|
||||
rec.write(inherit_vals)
|
||||
|
||||
if unpaid_leaves:
|
||||
for leave in unpaid_leaves:
|
||||
leave_start = leave.date_from.date()
|
||||
leave_end = leave.date_to.date()
|
||||
current_month_start = vacation_date
|
||||
current_month_end = (current_month_start + relativedelta(months=1)) - timedelta(days=1)
|
||||
real_start = max(leave_start, current_month_start)
|
||||
real_end = min(leave_end, current_month_end)
|
||||
if real_start > real_end:
|
||||
continue
|
||||
# 计算当前月的天数
|
||||
days = self._compute_duration_day(leave.holiday_status_id, real_start, real_end)
|
||||
# 取 workflow
|
||||
if leave.batch_id:
|
||||
main_leave_record = leave.batch_id
|
||||
elif leave.hour_batch_id:
|
||||
main_leave_record = leave.hour_batch_id
|
||||
else:
|
||||
main_leave_record = leave
|
||||
|
||||
workflow = self.env['soong.workflow.record'].search([
|
||||
('code', '=', main_leave_record.code)
|
||||
], limit=1)
|
||||
# 防重
|
||||
existing_line = self.env['vacation.other.line'].search([
|
||||
('vacation_id', '=', rec.id),
|
||||
('employee_id', '=', employee.id),
|
||||
('text', '=', '请假审批'),
|
||||
('workflow_record_id', '=', workflow.id if workflow else False),
|
||||
], limit=1)
|
||||
# 创建
|
||||
if not existing_line and days > 0:
|
||||
self.env['vacation.other.line'].create({
|
||||
'vacation_id': rec.id,
|
||||
'employee_id': employee.id,
|
||||
'workflow_record_id': workflow.id if workflow else False,
|
||||
'update_type': 'reduce',
|
||||
'update_date': fields.Date.today(),
|
||||
'lines': days,
|
||||
'text': '请假审批',
|
||||
'is_void': False,
|
||||
})
|
||||
|
||||
if rec.remain_missed_meals:
|
||||
self._update_meal_lines(rec, [rec], rec.remain_missed_meals)
|
||||
if rec.leave != 0:
|
||||
|
||||
Reference in New Issue
Block a user