diff --git a/yuthon_holiday/models/inherit_hr_leave.py b/yuthon_holiday/models/inherit_hr_leave.py
index f331e5ac1..a5ebafc17 100644
--- a/yuthon_holiday/models/inherit_hr_leave.py
+++ b/yuthon_holiday/models/inherit_hr_leave.py
@@ -509,8 +509,6 @@ class HolidaysRequestBatch(models.Model):
# 提交
def action_submit(self):
"""提交请假申请,区分年假和其他假期处理"""
- _logger.info(f"开始处理请假申请:{self.code},申请人:{self.users_id.employee_ids.name}")
-
self._process_specific_leaves('年假', is_annual_leave=True)
other_leave_types = [
'产假', '事假', '法定假', '调休', '补休', '值班调休',
@@ -537,45 +535,31 @@ class HolidaysRequestBatch(models.Model):
date_ranges = self._split_by_month(leave['start'], leave['end']) if not is_annual_leave else [
{'start': leave['start'], 'end': leave['end']}]
for period in date_ranges:
- days = self._compute_duration_day(leave['type_id'], period['start'], period['end'])
- if days > 0:
- if is_annual_leave:
- self._create_annual_leave_line(period['start'], leave, days, period)
- else:
- self._create_other_leave_line(period['start'], leave, days, period, leave_type_name)
+ if leave_type_name == '补休':
+ # 计算小时数(天数 * 8)
+ hours = self._compute_duration_day(leave['type_id'], period['start'], period['end']) * 8
+ if hours > 0:
+ self._create_overtime_leave_line(period_start=period['start'], leave_data=leave, hours=hours, period=period, leave_type_name=leave_type_name)
+ else:
+ days = self._compute_duration_day(leave['type_id'], period['start'], period['end'])
+ if days > 0:
+ if is_annual_leave:
+ # 年假以小时为单位(天数 * 8)
+ self._create_annual_leave_line(period_start=period['start'], leave_data=leave, hours=days * 8, period=period)
+ else:
+ self._create_other_leave_line(period_start=period['start'], leave_data=leave, days=days, period=period, leave_type_name=leave_type_name)
# 处理小时假
for leave in hourly_leaves:
leave_date = leave['date']
- days = leave['days']
- if days > 0:
+ hours = leave['days'] * 8
+ if hours > 0:
if is_annual_leave:
- self._create_annual_leave_line(leave_date, leave, days, {'start': leave_date, 'end': leave_date})
+ self._create_annual_leave_line(period_start=leave_date, leave_data=leave, hours=hours, period={'start': leave_date, 'end': leave_date})
+ elif leave_type_name == '补休':
+ self._create_overtime_leave_line(period_start=leave_date, leave_data=leave, hours=hours, period={'start': leave_date, 'end': leave_date}, leave_type_name=leave_type_name)
else:
- self._create_other_leave_line(leave_date, leave, days,{'start': leave_date, 'end': leave_date}, leave_type_name)
-
- def _create_other_leave_line(self, period_start, leave_data, days, period, leave_type_name):
- """为非年假类型创建vacation.other.line记录"""
- # 查找关联的假期额度记录
- report_month = date(period_start.year, period_start.month, 1)
- vacation_report = self.env['yuthon.vacation.reports'].search([
- ('employee_id', '=', self.users_id.employee_ids.id),
- ('vacation_date', '>=', fields.Date.to_string(report_month)),
- ('vacation_date', '<=', fields.Date.to_string(
- date(period_start.year, period_start.month,
- calendar.monthrange(period_start.year, period_start.month)[1]))
- )
- ], limit=1)
-
- self.env['vacation.other.line'].create({
- 'vacation_id': vacation_report.id if vacation_report else False,
- 'holiday_type': leave_data['type_id'].id,
- 'employee_id': self.users_id.employee_ids.id,
- 'workflow_record_id': leave_data['workflow_id'],
- 'update_date': fields.Date.today(),
- 'update_type': 'reduce',
- 'lines': days,
- 'text': f"请假审批"
- })
+ # 其他类型小时假,使用天数
+ self._create_other_leave_line(period_start=leave_date, leave_data=leave,days=leave['days'], period={'start': leave_date, 'end': leave_date}, leave_type_name=leave_type_name)
def _get_day_leaves(self, leave_type_name):
workflow_id = self.env['soong.workflow.record'].search([('code', '=', self.code)], limit=1).id
@@ -601,7 +585,7 @@ class HolidaysRequestBatch(models.Model):
'date': fields.Date.from_string(line.request_date_from),
'type_id': line.holiday_status_id,
'workflow_id': workflow_id,
- 'days': hours / 8 # 转换为天数
+ 'days': hours / 8
})
return hourly_records
@@ -628,8 +612,33 @@ class HolidaysRequestBatch(models.Model):
date_ranges.append({'start': date(end_date.year, end_date.month, 1), 'end': end_date})
return date_ranges
- def _create_annual_leave_line(self, period_start, leave_data, days, period):
- """更新年假记录"""
+ def _create_overtime_leave_line(self, period_start, leave_data, hours, period, leave_type_name):
+ """为补休类型创建加班明细行(vacation.over.line),类型为减少,值赋给workday"""
+ report_month = date(period_start.year, period_start.month, 1)
+ vacation_report = self.env['yuthon.vacation.reports'].search([
+ ('employee_id', '=', self.users_id.employee_ids.id),
+ ('vacation_date', '>=', fields.Date.to_string(report_month)),
+ ('vacation_date', '<=', fields.Date.to_string(
+ date(period_start.year, period_start.month,
+ calendar.monthrange(period_start.year, period_start.month)[1]))
+ )
+ ], limit=1)
+ self.env['vacation.over.line'].create({
+ 'vacation_id': vacation_report.id if vacation_report else False,
+ 'employee_id': self.users_id.employee_ids.id,
+ 'workflow_record_id': leave_data['workflow_id'],
+ 'update_type': 'reduce',
+ 'workday': hours,
+ 'legal_day': 0,
+ 'public_holidays': 0,
+ 'meal_number': 0,
+ 'update_date': fields.Date.today(),
+ 'is_void': False,
+ 'text': f"请假审批"
+ })
+
+ def _create_annual_leave_line(self, period_start, leave_data, hours, period):
+ """更新年假记录,使用小时作为单位"""
report_month = date(period_start.year, period_start.month, 1)
vacation_report = self.env['yuthon.vacation.reports'].search([
('employee_id', '=', self.users_id.employee_ids.id),
@@ -639,20 +648,18 @@ class HolidaysRequestBatch(models.Model):
calendar.monthrange(period_start.year, period_start.month)[1]))
)
], limit=1)
- # 创建年假明细记录
self.env['vacation.leave.line'].create({
'vacation_id': vacation_report.id if vacation_report else False,
'employee_id': self.users_id.employee_ids.id,
'workflow_record_id': leave_data['workflow_id'],
'update_type': 'reduce',
'update_date': fields.Date.today(),
- 'update_lines': days,
+ 'update_lines': hours,
'is_void': False,
'allocation_type': 'vacation',
'text': f"请假审批"
})
-
def _compute_duration_day(self, holiday_status_id, start_date, end_date):
"""
计算请假时长
diff --git a/yuthon_holiday/models/inherit_hr_leave_allocation.py b/yuthon_holiday/models/inherit_hr_leave_allocation.py
index 706932089..d39fe88b9 100644
--- a/yuthon_holiday/models/inherit_hr_leave_allocation.py
+++ b/yuthon_holiday/models/inherit_hr_leave_allocation.py
@@ -100,38 +100,39 @@ class HrLeaveAllocation(models.Model):
for leave in leave_ids:
leave.employee_id.write({'quota_issued': leave.number_of_hours_display})
- @api.model
- def create(self, vals):
- allocation = super(HrLeaveAllocation, self).create(vals)
- employee = allocation.employee_id
- hours = allocation.number_of_hours_display
- if allocation.holiday_status_id.name == '年假' and allocation.state == 'validate':
- employee.write({'quota_issued': employee.quota_issued + hours})
- reports_id = self.env['yuthon.vacation.reports'].search([('employee_id', '=', employee.id)], limit=1)
- # 创建假期明细记录
- self.env['vacation.leave.line'].create({
- 'vacation_id': reports_id.id,
- 'update_type': 'add',
- 'update_date': fields.Datetime.now(),
- 'update_lines': hours,
- 'allocation_type': 'allocation',
- 'text': allocation.name
- })
- elif allocation.holiday_status_id.name == '补休':
- reports_id = self.env['yuthon.vacation.reports'].search([
- ('employee_id', '=', employee.id)
- ], limit=1)
- self.env['vacation.over.line'].create({
- 'vacation_id': reports_id.id,
- 'update_type': 'add',
- 'update_date': fields.Datetime.now(),
- 'workday': hours,
- 'legal_day': 0,
- 'public_holidays': 0,
- 'meal_number': 0,
- 'text': allocation.name
- })
- return allocation
+ # @api.model
+ # def create(self, vals):
+ # allocation = super(HrLeaveAllocation, self).create(vals)
+ # employee = allocation.employee_id
+ # hours = allocation.number_of_hours_display
+ # date_from = allocation.date_from.replace(day=1)
+ # if allocation.holiday_status_id.name == '年假' and allocation.state == 'validate':
+ # employee.write({'quota_issued': employee.quota_issued + hours})
+ # reports_id = self.env['yuthon.vacation.reports'].search([('employee_id', '=', employee.id), ('vacation_date', '=', date_from)], limit=1)
+ # # 创建假期明细记录
+ # self.env['vacation.leave.line'].create({
+ # 'vacation_id': reports_id.id,
+ # 'update_type': 'add',
+ # 'update_date': fields.Datetime.now(),
+ # 'update_lines': hours,
+ # 'allocation_type': 'allocation',
+ # 'text': allocation.name
+ # })
+ # elif allocation.holiday_status_id.name == '补休':
+ # reports_id = self.env['yuthon.vacation.reports'].search([
+ # ('employee_id', '=', employee.id), ('vacation_date', '=', date_from)
+ # ], limit=1)
+ # self.env['vacation.over.line'].create({
+ # 'vacation_id': reports_id.id,
+ # 'update_type': 'add',
+ # 'update_date': fields.Datetime.now(),
+ # 'workday': hours,
+ # 'legal_day': 0,
+ # 'public_holidays': 0,
+ # 'meal_number': 0,
+ # 'text': allocation.name
+ # })
+ # return allocation
def unlink(self):
"""删除记录时同步删除对应的假期明细行"""
diff --git a/yuthon_hr_attendance/models/yuthon_vacation_reports.py b/yuthon_hr_attendance/models/yuthon_vacation_reports.py
index 9b20082d2..10ada9685 100644
--- a/yuthon_hr_attendance/models/yuthon_vacation_reports.py
+++ b/yuthon_hr_attendance/models/yuthon_vacation_reports.py
@@ -156,7 +156,6 @@ class YuthonVacationReports(models.Model):
'调休': 'compensatory_leave',
'事假': 'leave_of_absence',
'法定假': 'statutory_leave',
- '补休': 'cop_leave',
'值班调休': 'duty_off_leave',
'婚假': 'marriage_leave',
'产假': 'maternity_leave',
@@ -284,6 +283,9 @@ class YuthonVacationReports(models.Model):
def monthly_report(self):
today = fields.Date.today()
employees = self.env['hr.employee'].search([])
+ current_month_first = today.replace(day=1)
+ last_month_last = current_month_first - timedelta(days=1)
+ last_month_first = last_month_last.replace(day=1)
for employee in employees:
resource_user_ids = employee.resource_calendar_id.resource_user_ids.ids
is_resource_user = True if employee.id in resource_user_ids else False
@@ -292,10 +294,23 @@ class YuthonVacationReports(models.Model):
('vacation_date', '=', today)
], limit=1)
if not existing_record and not is_resource_user:
+ last_month_record = self.search([
+ ('employee_id', '=', employee.id),
+ ('vacation_date', '>=', fields.Date.to_string(last_month_first)),
+ ('vacation_date', '<=', fields.Date.to_string(last_month_last))
+ ], limit=1)
+ inherit_vals = {}
+ if last_month_record:
+ inherit_vals = {
+ 'leave': last_month_record.leave,
+ 'working_overtime': last_month_record.working_overtime,
+ 'medical_fee': last_month_record.medical_fee,
+ }
+
self.create({
'employee_id': employee.id,
'vacation_date': today,
- # 明细行和计算字段留空,由后续逻辑处理
+ **inherit_vals
})
def disposable_report(self):
@@ -403,15 +418,17 @@ class YuthonVacationReports(models.Model):
)
def _compute_working_overtime(self):
for record in self:
- overtime_hours = 0.0
+ total_add = 0.0
+ total_reduce = 0.0
for line in record.overtime_ids:
if not line.is_void:
line_total = (line.workday or 0) + (line.legal_day or 0) + (line.public_holidays or 0)
if line.update_type == 'add':
- overtime_hours += line_total
+ total_add += line_total
elif line.update_type == 'reduce':
- overtime_hours -= line_total
- record.working_overtime = overtime_hours / 8
+ total_reduce += line_total
+ record.working_overtime = total_add / 8
+ record.cop_leave = total_reduce / 8
@api.depends('meal_fee_ids.update_lines', 'meal_fee_ids.update_type', 'meal_fee_ids.is_void')
def _compute_meal_fee(self):
@@ -426,46 +443,71 @@ class YuthonVacationReports(models.Model):
record.meal_fee = meal_total
def update_vacation(self):
- employees = self.env['hr.employee'].search([
- ('is_salary', '=', True),
- ('contract_id.state', '!=', 'cancel'),
- ('contract_id', '!=', False),
- ])
+ """
+ 从hr.leave.allocation中汇总年假和补休数据,更新到8月份的假期报表
+ """
+ # 定义目标月份:8月1号(当年)
+ current_year = fields.Date.today().year
+ target_month = date(current_year, 8, 4)
+ target_month_str = fields.Date.to_string(target_month)
+ # 获取所有员工
+ employees = self.env['hr.employee'].search([])
for employee in employees:
- vacation_id = self.env['yuthon.vacation.reports'].search([
+ # 1. 处理年假分配
+ annual_allocations = self.env['hr.leave.allocation'].search([
('employee_id', '=', employee.id),
+ ('holiday_status_id.name', '=', '年假'),
+ ('state', '=', 'validate')
])
- if not vacation_id:
- self.env['yuthon.vacation.reports'].create({
- 'employee_id': employee.id,
- 'leave': employee.remainder_year,
- 'working_overtime': employee.overtime_this_month,
- 'meal_fee': employee.meal_number,
- })
- else:
- vacation_id.write({
- 'leave': employee.remainder_year,
- 'working_overtime': employee.overtime_this_month,
- 'meal_fee': employee.meal_number,
- })
- def update_log(self):
- vacation_ids = self.env["yuthon.vacation.reports"].browse(
- self._context.get('active_ids', self._context.get('active_id')))
- for vacation_id in vacation_ids:
- vacation_id.leave_ids.unlink()
- vacation_id.overtime_ids.unlink()
- vacation_id.meal_fee_ids.unlink()
+ # 累加年假总小时数
+ total_annual_hours = sum(alloc.number_of_hours_display for alloc in annual_allocations)
+
+ # 2. 处理补休分配
+ comp_allocations = self.env['hr.leave.allocation'].search([
+ ('employee_id', '=', employee.id),
+ ('holiday_status_id.name', '=', '补休'),
+ ('state', '=', 'validate') # 只处理已验证的分配
+ ])
+
+ # 累加补休总小时数
+ total_comp_hours = sum(alloc.number_of_hours_display for alloc in comp_allocations)
+ # 3. 查找或创建8月份的报表记录
+ vacation_report = self.search([
+ ('employee_id', '=', employee.id),
+ ('vacation_date', '=', target_month_str)
+ ], limit=1)
+ self._update_leave_lines(vacation_report, annual_allocations, total_annual_hours)
+ self._update_over_lines(vacation_report, comp_allocations, total_comp_hours)
+
+ def _update_leave_lines(self, report, allocations, number_of_hours_display):
+ for alloc in allocations:
+ self.env['vacation.leave.line'].create({
+ 'vacation_id': report.id,
+ 'employee_id': report.employee_id.id,
+ 'update_type': 'add',
+ 'update_date': fields.Date.today(),
+ 'update_lines': number_of_hours_display,
+ 'is_void': False,
+ 'allocation_type': 'allocation',
+ 'text': f"年假分配"
+ })
+
+ def _update_over_lines(self, report, allocations, number_of_hours_display):
+ """更新补休明细行"""
+ for alloc in allocations:
+ self.env['vacation.over.line'].create({
+ 'vacation_id': report.id,
+ 'employee_id': report.employee_id.id,
+ 'update_type': 'add',
+ 'update_date': fields.Date.today(),
+ 'workday': number_of_hours_display,
+ 'legal_day': 0,
+ 'public_holidays': 0,
+ 'meal_number': 0,
+ 'text': f"补休分配"
+ })
- return {
- 'type': 'ir.actions.client',
- 'tag': 'display_notification',
- 'params': {
- 'type': 'success',
- 'message': '删除日志成功',
- 'sticky': False,
- }
- }
def log(self):
return {
diff --git a/yuthon_hr_attendance/views/yuthon_vacation_reports_views.xml b/yuthon_hr_attendance/views/yuthon_vacation_reports_views.xml
index ce9fc5ee4..a296de08e 100644
--- a/yuthon_hr_attendance/views/yuthon_vacation_reports_views.xml
+++ b/yuthon_hr_attendance/views/yuthon_vacation_reports_views.xml
@@ -410,13 +410,6 @@
code
action = model.update_vacation()
-
-
- 初始化日志
-
-
- code
- action = model.update_log()
批量发送
@@ -426,7 +419,7 @@
action = model.update_log()
- 清零
+ 初始化日志
code