From f7a01078e63e6a6dca4894fa6fa2bddeb2a4fc21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=B9=8F=E5=AE=87?= <9664676+pengyuthon@user.noreply.gitee.com> Date: Tue, 6 Jan 2026 11:52:02 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../models/yuthon_vacation_reports.py | 114 ++++++++++++------ 1 file changed, 79 insertions(+), 35 deletions(-) diff --git a/yuthon_hr_attendance/models/yuthon_vacation_reports.py b/yuthon_hr_attendance/models/yuthon_vacation_reports.py index d7eec3b17..b6ab5f215 100644 --- a/yuthon_hr_attendance/models/yuthon_vacation_reports.py +++ b/yuthon_hr_attendance/models/yuthon_vacation_reports.py @@ -31,7 +31,7 @@ class YuthonVacationReports(models.Model): year_holiday = fields.Float(string="本年公休日", digits=(16, 3)) year_workday = fields.Float(string="本年工作日", digits=(16, 3)) year_sum = fields.Float(string="本年应休合计", digits=(16, 3), compute="_compute_year_sum") - used_this_year1 = fields.Float(string="本年已休", digits=(16, 3), compute="_compute_year_sum") + used_this_year1 = fields.Float(string="本年已休", digits=(16, 3)) remainder_year1 = fields.Float(string="本年剩余(补休)", digits=(16, 3), compute="_compute_year_sum") company_id = fields.Many2one(related="employee_id.company_id", string="公司", store=True) @@ -875,6 +875,37 @@ class VacationLeaveLine(models.Model): vacation_main = self.env['yuthon.vacation.reports'].browse(vals['vacation_id']) if vacation_main.vacation_state == 'confirmed': vals['is_confirm'] = True + + if vals.get('update_type') == 'reduce' and vals.get('vacation_id'): + vacation_main = self.env['yuthon.vacation.reports'].browse(vals['vacation_id']) + deduct_amount = vals.get('update_lines', 0.0) + + if not vacation_main or deduct_amount <= 0: + return super(VacationLeaveLine, self).create(vals) + + if vacation_main: + used_this_year_new = vacation_main.used_this_year + deduct_amount + vacation_main.write({'used_this_year': used_this_year_new}) + + #处理跨年场景:查找下月1号的假期记录并扣减previous_year + if vacation_main.vacation_date: + current_vacation_date = vacation_main.vacation_date + next_month_first_day = current_vacation_date + relativedelta(months=+1, day=1) + + # 判断是否跨年 + is_cross_year = current_vacation_date.year != next_month_first_day.year + if is_cross_year: + next_month_vacation = self.env['yuthon.vacation.reports'].search([ + ('employee_id', '=', vacation_main.employee_id.id), + ('vacation_date', '=', next_month_first_day), + ('vacation_state', 'in', ['not_sent', 'pending']), + ], limit=1) + + if next_month_vacation: + previous_year_new = next_month_vacation.previous_year- deduct_amount + previous_year_new = max(previous_year_new, 0.0) + next_month_vacation.write({'previous_year': previous_year_new}) + return super(VacationLeaveLine, self).create(vals) def _sync_to_employee(self, reverse=False): @@ -930,32 +961,6 @@ class VacationOverline(models.Model): 'view_mode': 'form', } - # def _sync_to_employee(self, reverse=False): - # """将数据同步到关联员工 - # :param reverse: 是否反向操作(用于删除场景) - # """ - # employee = self.vacation_id.employee_id - # employee.meal_number -= self.meal_number - # # 根据操作类型确定计算方式 - # sign = -1 if reverse else 1 - # if self.update_type == 'add': - # employee.write({ - # 'normal_overtime_hours': employee.normal_overtime_hours + (self.workday * sign), - # 'holiday_overtime_hours': employee.holiday_overtime_hours + (self.legal_day * sign), - # 'weekend_overtime_hours': employee.weekend_overtime_hours + (self.public_holidays * sign) - # }) - # elif self.update_type == 'reduce': - # employee.write({ - # 'normal_overtime_hours': employee.normal_overtime_hours - (self.workday * sign), - # 'holiday_overtime_hours': employee.holiday_overtime_hours - (self.legal_day * sign), - # 'weekend_overtime_hours': employee.weekend_overtime_hours - (self.public_holidays * sign) - # }) - # - # @api.model - # def create(self, vals): - # record = super(VacationOverline, self).create(vals) - # record._sync_to_employee() - # return record @api.model def create(self, vals): if vals.get('vacation_id'): @@ -967,30 +972,69 @@ class VacationOverline(models.Model): vacation_main = self.env['yuthon.vacation.reports'].browse(vals['vacation_id']) deduct_workday = vals.get('workday', 0.0) deduct_public = vals.get('public_holidays', 0.0) + deduct_legal = vals.get('legal_day', 0.0) + deduct_workday_convert = deduct_workday / 8 + deduct_public_convert = deduct_public / 8 + deduct_legal_convert = deduct_legal / 8 + deduct_total = deduct_workday_convert + deduct_public_convert + deduct_legal_convert if vacation_main: - vacation_deduct_vals = { - 'year_workday': vacation_main.year_workday - deduct_workday/8, - 'year_holiday': vacation_main.year_holiday - deduct_public/8, + vacation_used_vals = { + 'used_this_year1': (vacation_main.used_this_year1 or 0.0) + deduct_total } - vacation_main.write(vacation_deduct_vals) + vacation_main.write(vacation_used_vals) + is_cross_year = False + # 计算下月1号并判断是否跨年 if vacation_main.vacation_date: current_vacation_date = vacation_main.vacation_date next_month_first_day = current_vacation_date + relativedelta(months=+1, day=1) - # 必须是跨年才写入上年工作日 is_cross_year = current_vacation_date.year != next_month_first_day.year + + # 跨年场景 + if is_cross_year: + # 查找下月1号的未确认假期记录并扣减上年额度 next_month_vacation = self.env['yuthon.vacation.reports'].search([ ('employee_id', '=', vacation_main.employee_id.id), ('vacation_date', '=', next_month_first_day), ('vacation_state', 'in', ['not_sent', 'pending']), ], limit=1) - if is_cross_year: + if next_month_vacation: next_month_deduct_vals = { - 'last_workday': next_month_vacation.last_workday - deduct_workday/8, - 'last_holiday': next_month_vacation.last_holiday - deduct_public/8, + 'last_workday': next_month_vacation.last_workday - deduct_workday_convert, + 'last_holiday': next_month_vacation.last_holiday - deduct_public_convert, } next_month_vacation.write(next_month_deduct_vals) + if vals.get('update_type') == 'add' and vals.get('vacation_id'): + current_text = vals.get('text', '').strip() + if current_text != '上月额度继承': + vacation_main = self.env['yuthon.vacation.reports'].browse(vals['vacation_id']) + add_workday = vals.get('workday', 0.0) + add_public = vals.get('public_holidays', 0.0) + if vacation_main: + vacation_add_vals = { + 'year_workday': vacation_main.year_workday + add_workday / 8, + 'year_holiday': vacation_main.year_holiday + add_public / 8, + } + vacation_main.write(vacation_add_vals) + + if vacation_main.vacation_date: + current_vacation_date = vacation_main.vacation_date + next_month_first_day = current_vacation_date + relativedelta(months=+1, day=1) + # 必须是跨年才写入上年工作日 + is_cross_year = current_vacation_date.year != next_month_first_day.year + next_month_vacation = self.env['yuthon.vacation.reports'].search([ + ('employee_id', '=', vacation_main.employee_id.id), + ('vacation_date', '=', next_month_first_day), + ('vacation_state', 'in', ['not_sent', 'pending']), + ], limit=1) + if is_cross_year: + next_month_deduct_vals = { + 'last_workday': next_month_vacation.last_workday + add_workday / 8, + 'last_holiday': next_month_vacation.last_holiday + add_public / 8, + } + next_month_vacation.write(next_month_deduct_vals) + return super(VacationOverline, self).create(vals) # def unlink(self):