diff --git a/yuthon_hr_attendance/models/yuthon_vacation_reports.py b/yuthon_hr_attendance/models/yuthon_vacation_reports.py index fd10ec1b5..efc12d8af 100644 --- a/yuthon_hr_attendance/models/yuthon_vacation_reports.py +++ b/yuthon_hr_attendance/models/yuthon_vacation_reports.py @@ -219,7 +219,7 @@ class YuthonVacationReports(models.Model): rec.update_line() def update_line(self): - if self.vacation_date == fields.Date.from_string('2026-01-01') or (self.vacation_date == fields.Date.from_string('2026-03-01') and self.employee_id.name == '天河物管'): + if self.vacation_date == fields.Date.from_string('2026-01-01') or (self.vacation_date == fields.Date.from_string('2026-03-01') and self.employee_id.company_id.name == '天河物管'): return self.manage_reject() # ========== 第一步:处理年假逻辑 ========== @@ -931,6 +931,107 @@ class YuthonVacationReports(models.Model): "target": "new", } + def update_holiday(self): + # 获取当前激活的记录 + vacation_ids = self.env["yuthon.vacation.reports"].browse( + self._context.get('active_ids', self._context.get('active_id'))) + current_year = datetime.now().year + for vacation in vacation_ids: + # 1. 处理上年年假剩余 (年假, 时间:上上年3月1日 到 上年2月28/29日) + if vacation.dynamic_previous_year > 0: + start_date = datetime(current_year - 2, 3, 1) + end_date = datetime(current_year - 1, 2, 28) + # 检查是否是闰年, + if (current_year - 1) % 4 == 0 and (current_year - 1) % 100 != 0 or (current_year - 1) % 400 == 0: + end_date = datetime(current_year - 1, 2, 29) + self._create_leave_allocation( + vacation=vacation, + leave_days=vacation.dynamic_previous_year, + allocation_type='accrual', + leave_name='年假', + start_date=start_date, + end_date=end_date + ) + + # 2. 处理本年年假剩余 (本年3月1日 到 明年2月28/29日) + if vacation.dynamic_remainder_year > 0: + start_date = datetime(current_year, 3, 1) + end_date = datetime(current_year + 1, 2, 28) + # 检查闰年 + if (current_year + 1) % 4 == 0 and (current_year + 1) % 100 != 0 or (current_year + 1) % 400 == 0: + end_date = datetime(current_year + 1, 2, 29) + + self._create_leave_allocation( + vacation=vacation, + leave_days=vacation.dynamic_remainder_year, + allocation_type='accrual', + leave_name='年假', + start_date=start_date, + end_date=end_date + ) + + # 3. 处理上年补休剩余 (休假, 时间:上年3月1日 到 上年2月28/29日) + if vacation.dynamic_previous_year1 > 0: + start_date = datetime(current_year - 2, 3, 1) + end_date = datetime(current_year - 1, 2, 28) + # 检查闰年 + if (current_year - 1) % 4 == 0 and (current_year - 1) % 100 != 0 or (current_year - 1) % 400 == 0: + end_date = datetime(current_year - 1, 2, 29) + + self._create_leave_allocation( + vacation=vacation, + leave_days=vacation.dynamic_previous_year1, + allocation_type='regular', + leave_name='休假', + start_date=start_date, + end_date=end_date + ) + + # 4. 处理本年补休剩余 ( 休假, 时间:本年3月1日 到 明年2月28/29日) + if vacation.this_year1 > 0: + start_date = datetime(current_year, 3, 1) + end_date = datetime(current_year + 1, 2, 28) + if (current_year + 1) % 4 == 0 and (current_year + 1) % 100 != 0 or (current_year + 1) % 400 == 0: + end_date = datetime(current_year + 1, 2, 29) + + self._create_leave_allocation( + vacation=vacation, + leave_days=vacation.this_year1, + allocation_type='regular', + leave_name='休假', + start_date=start_date, + end_date=end_date + ) + + def _create_leave_allocation(self, vacation, leave_days, allocation_type, leave_name, start_date, end_date): + """ + 封装创建hr.leave.allocation的逻辑 + :param vacation: 当前yuthon.vacation.reports记录 + :param leave_days: 假期天数 + :param allocation_type: 分配类型 (accrual/regular) + :param leave_name: 假期名称 (年假/休假) + :param start_date: 开始日期 + :param end_date: 结束日期 + """ + accrual_plan_id = self.env['hr.leave.accrual.plan'].search( + [('name', 'ilike', '天河物管')], limit=1 + ) + leave_type = self.env['hr.leave.type'].search([('display_name', 'ilike', leave_name), ('company_id.name', '=', '天河物管')], limit=1) + vals = { + 'name': leave_name, + 'number_of_days': leave_days, + 'holiday_status_id': leave_type.id, + 'allocation_type': allocation_type, + 'date_from': fields.Date.to_string(start_date), + 'date_to': fields.Date.to_string(end_date), + 'notes': leave_name, + } + if allocation_type == 'accrual' and accrual_plan_id: + vals['accrual_plan_id'] = accrual_plan_id.id + vals['employee_id'] = vacation.employee_id.id + self.env['hr.leave.allocation'].create(vals) + + @api.depends('other_fee_ids', 'other_fee_ids.holiday_type', 'other_fee_ids.lines', 'other_fee_ids.is_void', 'other_fee_ids.update_type') def _compute_other_leave(self): diff --git a/yuthon_hr_attendance/views/yuthon_vacation_reports_views.xml b/yuthon_hr_attendance/views/yuthon_vacation_reports_views.xml index bd26037d6..d43a29a1c 100644 --- a/yuthon_hr_attendance/views/yuthon_vacation_reports_views.xml +++ b/yuthon_hr_attendance/views/yuthon_vacation_reports_views.xml @@ -808,6 +808,13 @@ code action = model.update_data() + + 更新休假 + + + code + action = model.update_holiday() + details.tree.tree details.tree diff --git a/yuthon_hr_attendance/wizard/yuthon_vacation_import_wizard.py b/yuthon_hr_attendance/wizard/yuthon_vacation_import_wizard.py index fe0681f6e..86aee4066 100644 --- a/yuthon_hr_attendance/wizard/yuthon_vacation_import_wizard.py +++ b/yuthon_hr_attendance/wizard/yuthon_vacation_import_wizard.py @@ -102,7 +102,7 @@ class YuthonVacationImportWizard(models.TransientModel): leave.write({ 'update_lines': update_value, }) - vacation_id.dynamic_previous_year = update_value / 8 + vacation_id.dynamic_remainder_year = update_value / 8 else: if update_value != 0: self.env[vacation_id.leave_ids._name].create({ @@ -113,7 +113,7 @@ class YuthonVacationImportWizard(models.TransientModel): 'update_lines': update_value, 'vacation_id': vacation_id.id, }) - vacation_id.dynamic_previous_year = update_value / 8 + vacation_id.dynamic_remainder_year = update_value / 8 target_overtimes = vacation_id.overtime_ids.filtered(lambda o: o.text == '上月额度继承') workday_value = float(row[2].value) * 8 @@ -123,7 +123,7 @@ class YuthonVacationImportWizard(models.TransientModel): overtime.unlink() else: overtime.write({'workday': workday_value}) - vacation_id.dynamic_previous_year1 = workday_value / 8 + vacation_id.this_year1 = workday_value / 8 else: if workday_value != 0: self.env[vacation_id.overtime_ids._name].create({ @@ -135,6 +135,9 @@ class YuthonVacationImportWizard(models.TransientModel): 'workday': workday_value, 'vacation_id': vacation_id.id, }) - vacation_id.dynamic_previous_year1 = workday_value / 8 + vacation_id.this_year1 = workday_value / 8 + + vacation_id.dynamic_previous_year = 0 + vacation_id.dynamic_previous_year1 = 0 vacation_id._compute_leave() vacation_id._compute_working_overtime()