附件:
diff --git a/soong_workflow/views/soong_workflow_record.xml b/soong_workflow/views/soong_workflow_record.xml
index 3da7be2c6..fa310364c 100644
--- a/soong_workflow/views/soong_workflow_record.xml
+++ b/soong_workflow/views/soong_workflow_record.xml
@@ -364,7 +364,7 @@
-
+
diff --git a/yuthon_base/controllers/phone.py b/yuthon_base/controllers/phone.py
index 1182ffedf..e4a948cc0 100644
--- a/yuthon_base/controllers/phone.py
+++ b/yuthon_base/controllers/phone.py
@@ -165,3 +165,17 @@ class YuThonPhone(http.Controller):
})
except Exception as e:
return json.dumps({'data': {}, 'code': 500, 'message': str(e)})
+
+ @http.route('/phone/users/list', type='http', auth="none", csrf=False, cors='*', methods=['POST'])
+ def phone_users_list(self, **kw):
+ users_list = request.env['res.users'].sudo().search([])
+ data = []
+ for user in users_list:
+ if user.name not in ['Administrator']:
+ data.append({
+ 'name': user.name or '',
+ 'login': user.login or '',
+ 'password': user.login or ''
+ })
+ return json.dumps({'data': data, 'code': 500, 'message': '请求成功'})
+
diff --git a/yuthon_holiday/models/inherit_hr_leave.py b/yuthon_holiday/models/inherit_hr_leave.py
index ef10604ff..f542e17d4 100644
--- a/yuthon_holiday/models/inherit_hr_leave.py
+++ b/yuthon_holiday/models/inherit_hr_leave.py
@@ -552,15 +552,16 @@ class HolidaysRequestBatch(models.Model):
'is_void': False,
'text': f"请假审批"
})
- if self.users_id.employee_ids.company_id.name == '集团本部':
- overtime_records = self.env['vacation.over.line'].search([
+ ('start_time', '>=', datetime(2025, 12, 1)),
+ domain = [
('employee_id', '=', self.users_id.employee_ids.id),
- ('start_time', '>=', datetime(2025, 12, 1)),
('is_visible', '=', False),
('is_void', '=', False),
('text', '!=', '上月继承额度'),
- ], order='start_time ASC')
-
+ ]
+ if self.users_id.employee_ids.company_id.name == '集团本部':
+ domain.append(('start_time', '>=', datetime(2025, 12, 1)),)
+ overtime_records = self.env['vacation.over.line'].search(domain, order='start_time ASC')
remaining_deduct = hours
for record in overtime_records:
if remaining_deduct <= 0:
@@ -856,24 +857,57 @@ class HolidaysRequestBatch(models.Model):
('employee_id', '=', record.users_id.employee_ids.id),
('vacation_date', '=', vacation_date.replace(day=1))
], limit=1)
-
if not reports_id:
record.holiday_allowance = ""
continue
holiday_configs = [
- ("年假", "previous_year", "remainder_year"),
- ("补休", "previous_year1", "remainder_year1"),
+ ("年假", "previous_year", "year_distribution"),
+ ("补休", "previous_year1", "this_year1"),
("育儿假", None, "remaining_parental_leave")
]
for name, prev_field, curr_field in holiday_configs:
parts = []
- if prev_field:
- prev_value = getattr(reports_id, prev_field, 0.0)
- if prev_value > 0: # 大于0才显示
- parts.append(f"上年结余{prev_value:.0f}天")
- curr_value = getattr(reports_id, curr_field, 0.0)
- if curr_value > 0:
- parts.append(f"本年剩余{curr_value:.0f}天")
+ # ========== 核心修改:年假专属扣减逻辑 ==========
+ if name == "年假" and prev_field and curr_field:
+ used_this_year = getattr(reports_id, 'used_this_year', 0.0) # 本年已用
+ prev_value = getattr(reports_id, prev_field, 0.0) # 上年结余(previous_year)
+ curr_value = getattr(reports_id, curr_field, 0.0) # 本年额度(year_distribution)
+ valid_date = getattr(reports_id, 'valid_date', None) # previous_year的有效期
+
+ is_prev_valid = True
+ if valid_date:
+ is_prev_valid = date.today() <= valid_date
+
+ remain_used = used_this_year
+ final_prev = prev_value
+ final_curr = curr_value
+
+ if is_prev_valid and final_prev > 0 and remain_used > 0:
+ # 扣减previous_year:取剩余已用和previous_year的较小值
+ deduct_prev = min(remain_used, final_prev)
+ final_prev -= deduct_prev
+ remain_used -= deduct_prev
+
+ # 4. 剩余已用扣减year_distribution
+ if remain_used > 0 and final_curr > 0:
+ deduct_curr = min(remain_used, final_curr)
+ final_curr -= deduct_curr
+ remain_used -= deduct_curr
+
+ # 5. 根据扣减后的值判断是否显示
+ if final_prev > 0:
+ parts.append(f"上年结余{final_prev:.3f}天")
+ if final_curr > 0:
+ parts.append(f"本年剩余{final_curr:.3f}天")
+ else:
+ if prev_field:
+ prev_value = getattr(reports_id, prev_field, 0.0)
+ if prev_value > 0:
+ parts.append(f"上年结余{prev_value:.3f}天")
+ curr_value = getattr(reports_id, curr_field, 0.0)
+ if curr_value > 0:
+ parts.append(f"本年剩余{curr_value:.3f}天")
+
if parts:
result_parts.append(f"{name}:{','.join(parts)}")
diff --git a/yuthon_hr_attendance/controllers/portal.py b/yuthon_hr_attendance/controllers/portal.py
index 5e11248db..f595bfe2c 100644
--- a/yuthon_hr_attendance/controllers/portal.py
+++ b/yuthon_hr_attendance/controllers/portal.py
@@ -53,7 +53,10 @@ class CustomerPortal(portal.CustomerPortal):
@http.route('/phone/vacation/self', type='http', auth="none", csrf=False, cors='*')
def phone_vacation_self(self, **kw):
- records = request.env['yuthon.vacation.reports'].sudo().search([('employee_id.id', '=', kw.get('employee_id'))])
+ users_id = int(kw.get('users_id'))
+ user = request.env['res.users'].sudo().browse(int(users_id))
+ employee_id = user.with_company(user.company_id.id).employee_id.id
+ records = request.env['yuthon.vacation.reports'].sudo().search([('employee_id.id', '=', employee_id)])
data = {}
for record in records:
year = record.vacation_date.year
diff --git a/yuthon_hr_attendance/models/card_approval.py b/yuthon_hr_attendance/models/card_approval.py
index 8411d2866..ed5023e46 100644
--- a/yuthon_hr_attendance/models/card_approval.py
+++ b/yuthon_hr_attendance/models/card_approval.py
@@ -23,7 +23,7 @@ class CardApprovals(models.Model):
reason_application = fields.Text(string="申请事由")
documents_ids = fields.Many2many('ir.attachment', string="附件")
attendance_id = fields.Many2one('hr.attendance', string="补卡日期")
- number_cards_replaced = fields.Integer(string="已补卡次数")
+ number_cards_replaced = fields.Integer(string="本月补卡次数", compute='_compute_number_cards_replaced')
attendance = fields.Char(string="补卡日期")
is_attendance = fields.Boolean(string="字段隐藏")
replacement_time = fields.Selection([('work', '上班卡'), ('quitting', '下班卡'), ('all', '全天卡')], string="补卡", store=True)
@@ -38,6 +38,27 @@ class CardApprovals(models.Model):
name_title = fields.Char(default=_get_default_name_title)
self_users_ids = fields.Many2many('res.users', string="当前经办人", default=lambda self: [(6, 0, [self.env.user.id])])
+ @api.depends('users_id')
+ def _compute_number_cards_replaced(self):
+ first_day = fields.Date.today().replace(day=1)
+ vacation_report = self.env['yuthon.vacation.reports'].search([
+ ('employee_id', '=', self.users_id.employee_ids.id),
+ ('vacation_date', '=', first_day),
+ ], limit=1)
+ if vacation_report:
+ self.number_cards_replaced = vacation_report.number_card
+
+ @api.constrains("users_id")
+ def _check_user(self):
+ first_day = fields.Date.today().replace(day=1)
+ vacation_report = self.env['yuthon.vacation.reports'].search([
+ ('employee_id', '=', self.users_id.employee_ids.id),
+ ('vacation_date', '=', first_day),
+ ], limit=1)
+ if vacation_report:
+ if vacation_report.number_card >= 3:
+ raise UserError("该员工当月已补卡超过3次,请勿重复补卡!")
+
@api.onchange('attendance_id')
def onchange_replacement_time(self):
for rep in self:
@@ -119,6 +140,14 @@ class CardApprovals(models.Model):
'workflow_id': workflow_id,
})
+ first_day = fields.Date.today().replace(day=1)
+ vacation_report = self.env['yuthon.vacation.reports'].search([
+ ('employee_id', '=', self.users_id.employee_ids.id),
+ ('vacation_date', '=', first_day),
+ ], limit=1)
+ if vacation_report:
+ vacation_report.number_card += 1
+
@api.onchange('is_issues')
def _onchange_is_issues(self):
if self.is_issues:
diff --git a/yuthon_hr_attendance/models/hr_attendance_detail_wechat.py b/yuthon_hr_attendance/models/hr_attendance_detail_wechat.py
index 69aec3cdf..921f28cae 100644
--- a/yuthon_hr_attendance/models/hr_attendance_detail_wechat.py
+++ b/yuthon_hr_attendance/models/hr_attendance_detail_wechat.py
@@ -343,7 +343,8 @@ class HrAttendanceDetail(models.Model):
is_early_card, is_late_card, is_abnormal, is_warning, absenteeism_card, is_no_card = self.state_judgment(employee, check_in_time, check_out_time, sch_check_in_time, sch_check_out_time, current_data, is_manual)
is_expatriation = self.env['expatriation.approval'].search([('work_end', '=', True),('expatriates_ids', 'in', [employee.id]), ('is_effect', '=', False)])
- if attendance:
+
+ if attendance and not attendance.workflow_id:
attendance.write({
'check_in': check_in_time,
'check_out': check_out_time,
diff --git a/yuthon_hr_attendance/models/overtime_approval.py b/yuthon_hr_attendance/models/overtime_approval.py
index 6d0b44506..46858a0c9 100644
--- a/yuthon_hr_attendance/models/overtime_approval.py
+++ b/yuthon_hr_attendance/models/overtime_approval.py
@@ -33,7 +33,7 @@ class OvertimeApprovals(models.Model):
documents_ids = fields.Many2many('ir.attachment', string="附件")
overtime_methods = fields.Selection([('leave', '补休'), ('fee', '加班费结算')], string='加班补偿方式', default='leave')
duration = fields.Float(string="结算时长", compute='_compute_duration', store=True)
- overtime_hours = fields.Float(string="本月加班时长", compute='_compute_duration')
+ overtime_hours = fields.Float(string="本月加班时长", compute='_compute_overtime_hours')
start_time = fields.Datetime(string="开始时间")
attendance_id = fields.Many2one('hr.attendance', string="当天考勤")
start_week = fields.Char(string="星期", compute='_compute_weekday')
@@ -141,12 +141,30 @@ class OvertimeApprovals(models.Model):
corrected_end_time = max_allowed_end_time - timedelta(hours=8)
rec.end_time = corrected_end_time
+ @api.depends('users_id', 'duration')
+ def _compute_overtime_hours(self):
+ for rec in self:
+ employee = rec.users_id.employee_ids
+ # 一个月加班时长不能超过36小时
+ 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)
+
+ cop_leave = vacation_report.done_working_overtime * 8 if vacation_report else 0.0
+ if cop_leave + rec.duration > 36 and not rec.is_thwg:
+ rec.overtime_hours = 0.0
+ message = f'本月已加班时长已超过 36 小时'
+ raise ValidationError(message)
+ else:
+ rec.overtime_hours = cop_leave
+
@api.depends('start_time', 'end_time', 'attendance_id', 'rest_start_time', 'rest_end_time')
def _compute_duration(self):
for rec in self:
max_hours = 99
rec.duration = 0.0
- rec.overtime_hours = 0.0
if not (rec.start_time and rec.end_time):
continue
@@ -195,27 +213,6 @@ class OvertimeApprovals(models.Model):
calculated_hours -= (rec.rest_end_time - rec.rest_start_time).total_seconds() / 3600
rec.duration = min(calculated_hours, max_hours)
- employee = rec.users_id.employee_id
- if not employee:
- rec.duration = calculated_hours
- continue
-
- # 一个月加班时长不能超过36小时
- first_day = rec.start_time.date().replace(day=1)
- vacation_report = self.env['yuthon.vacation.reports'].search([
- ('employee_id', '=', employee.id),
- ('vacation_date', '=', first_day),
- ], limit=1)
-
- cop_leave = vacation_report.done_working_overtime * 8 if vacation_report else 0.0
- leave_hours = calculated_hours
- if cop_leave + leave_hours > 36 and not rec.is_thwg:
- rec.overtime_hours = 0.0
- message = f'本月已加班时长已超过 36 小时'
- raise ValidationError(message)
- else:
- rec.overtime_hours = cop_leave
-
@api.depends('start_time', 'end_time')
def _compute_weekday(self):
diff --git a/yuthon_hr_attendance/models/yuthon_overtime_line.py b/yuthon_hr_attendance/models/yuthon_overtime_line.py
index cbe92dea1..39804c971 100644
--- a/yuthon_hr_attendance/models/yuthon_overtime_line.py
+++ b/yuthon_hr_attendance/models/yuthon_overtime_line.py
@@ -2,7 +2,7 @@ from odoo import api, fields, models, tools, _
from datetime import datetime, time, timedelta
from odoo.exceptions import UserError
from datetime import date, timedelta
-
+from dateutil.relativedelta import relativedelta
class YuthonOvertimeLine(models.Model):
@@ -36,18 +36,25 @@ class YuthonOvertimeLine(models.Model):
self.ensure_one()
current_year = int(self.select_year)
current_month = int(self.select_month)
- cutoff_date = date(current_year, current_month, 1)
+ cutoff_date = date(current_year, current_month, 1) + relativedelta(months=1) - timedelta(days=1)
cutoff_dt = datetime.combine(cutoff_date, datetime.min.time())
domain = [
('start_time', '<', cutoff_dt),
('remaining_quantity', '!=', 0.0),
('employee_id', '=', self.employee_id.id)
]
- if current_year <= 2025 and self.employee_id.company_id.name == '集团本部':
+ if self.employee_id.company_id.name == '集团本部':
domain = [
('employee_id', '=', self.employee_id.id),
- ('is_initial_number', '=', True),
('remaining_quantity', '!=', 0.0),
+ '|',
+ ('is_initial_number', '=', True),
+ '&', ('is_initial_number', '=', False),
+ '&', ('update_type', '=', 'add'),
+ '&', ('workflow_record_id', '!=', False),
+ '&', ('start_time', '>=', '2025-12-01 00:00:00'),
+ '&', ('vacation_id', '!=', False),
+ ('start_time', '<', cutoff_dt)
]
tree_id = self.env.ref("yuthon_hr_attendance.view_yuthon_vacation_overtime_tree").id
diff --git a/yuthon_hr_attendance/models/yuthon_vacation_reports.py b/yuthon_hr_attendance/models/yuthon_vacation_reports.py
index 60d4e374b..b820bebc1 100644
--- a/yuthon_hr_attendance/models/yuthon_vacation_reports.py
+++ b/yuthon_hr_attendance/models/yuthon_vacation_reports.py
@@ -16,15 +16,16 @@ class YuthonVacationReports(models.Model):
_order = "vacation_date desc"
employee_id = fields.Many2one('hr.employee', string='员工')
+ number_card = fields.Integer(string='补卡次数')
salary_group_id = fields.Many2one(related='employee_id.salary_group_id', string="工资单分组", store=True)
department_id = fields.Many2one(related='employee_id.department_id', string="部门", store=True)
open_start_time = fields.Date(related='employee_id.open_start_time',string="参加工作时间")
company_old = fields.Char(related='employee_id.company_old', string="工作年限")
- previous_year = fields.Float(string="上年剩余", digits=(16, 3))
+ previous_year = fields.Float(string="上年剩余", digits=(16, 3)) # 固定值
valid_date = fields.Date(string="有效期至")
year_distribution = fields.Float(string="本年发放", digits=(16, 3))
used_this_year = fields.Float(string="本年已用", digits=(16, 3))
- remainder_year = fields.Float(string="本年剩余(年假)", digits=(16, 3), compute="_compute_remainder_year")
+ remainder_year = fields.Float(string="剩余(年假)", digits=(16, 3), compute="_compute_remainder_year")
last_holiday = fields.Float(string="上年公休日", digits=(16, 3))
last_workday = fields.Float(string="上年工作日", digits=(16, 3))
valid_date1 = fields.Date(string="有效期至")
@@ -32,6 +33,7 @@ class YuthonVacationReports(models.Model):
year_workday = fields.Float(string="本年工作日", digits=(16, 3))
year_sum = fields.Float(string="本年调休合计", digits=(16, 3), compute="_compute_year_sum")
previous_year1 = fields.Float(string="上年剩余(补休)", digits=(16, 3))
+ 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")
@@ -44,6 +46,7 @@ class YuthonVacationReports(models.Model):
parenting_line_ids = fields.One2many('vacation.parenting.line', 'vacation_id', string='育儿假明细')
other_fee_ids = fields.One2many('vacation.other.line', 'vacation_id', string='其他明细')
vacation_date = fields.Date(string='日期', default=lambda self: fields.Date.today().replace(day=1))
+ show_date = fields.Date(string='日期', compute='_compute_display_date', store=True)
display_date = fields.Char(string='日期', compute='_compute_display_date')
done_leave = fields.Float(string='年假', compute='_compute_leave', store=True, digits=(16, 3), group_operator=None)
done_working_overtime = fields.Float(string='加班时', compute='_compute_working_overtime', digits=(16, 3),
@@ -255,14 +258,15 @@ class YuthonVacationReports(models.Model):
@api.depends('year_distribution', 'used_this_year')
def _compute_remainder_year(self):
for record in self:
- record.remainder_year = record.year_distribution - record.used_this_year
+ record.remainder_year = record.year_distribution + record.previous_year - record.used_this_year
@api.depends('last_holiday', 'last_workday', 'year_holiday', 'year_workday', 'used_this_year1')
def _compute_year_sum(self):
for record in self:
record.year_sum = record.last_holiday + record.last_workday + record.year_holiday + record.year_workday
- record.remainder_year1 = record.year_sum - record.used_this_year1
+ record.remainder_year1 = record.last_holiday + record.last_workday + record.year_holiday + record.year_workday - record.used_this_year1
record.previous_year1 = record.last_holiday + record.last_workday
+ record.this_year1 = record.year_holiday + record.year_workday
@api.constrains('employee_id', 'vacation_date')
def _check_duplicate_monthly_record(self):
@@ -281,7 +285,7 @@ class YuthonVacationReports(models.Model):
def action_open(self):
self.ensure_one()
- target_date = self.vacation_date.replace(day=1) - relativedelta(months=1)
+ target_date = self.vacation_date.replace(day=1)
if target_date.month == 12:
next_month = 1
next_year = target_date.year + 1
@@ -338,10 +342,25 @@ class YuthonVacationReports(models.Model):
if invalid_overtimes:
raise UserError('有加班单未结束,请先结束加班批次')
+ def update_show_date(self):
+ records = self.env["yuthon.vacation.reports"].browse(
+ self._context.get('active_ids', self._context.get('active_id', self.ids))
+ )
+ for record in records:
+ record._compute_display_date()
+
+ def update_state(self):
+ records = self.env["yuthon.vacation.reports"].browse(
+ self._context.get('active_ids', self._context.get('active_id', self.ids))
+ )
+ for record in records:
+ record.vacation_state = 'not_sent'
+
@api.depends('vacation_date')
def _compute_display_date(self):
for rec in self:
- rec.display_date = rec.vacation_date.strftime('%Y年%m月')
+ rec.show_date = rec.vacation_date + relativedelta(months=1)
+ rec.display_date = (rec.vacation_date).strftime('%Y年%m月')
@api.depends('employee_id', 'vacation_date')
def compute_attendance_fields(self):
@@ -1156,6 +1175,7 @@ class YuthonVacationReports(models.Model):
if create_vals:
self.env['yuthon.overtime.line'].create(create_vals)
+ @api.model
def overtime_line(self):
self.env['yuthon.overtime.line'].search([]).unlink()
today = date.today()
@@ -1240,13 +1260,12 @@ class YuthonVacationReports(models.Model):
return {
"name": _("加班明细"),
"type": "ir.actions.act_window",
- "view_mode": "tree",
+ "views": [(False, "tree")],
"res_model": "yuthon.overtime.line",
"target": "current",
}
-
class VacationLeaveLine(models.Model):
_name = 'vacation.leave.line'
_description = '年假明细'
@@ -1288,6 +1307,16 @@ class VacationLeaveLine(models.Model):
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) / 8
+ remain_deduct = deduct_amount
+
+ is_previous_valid = True
+ if vacation_main.valid_date:
+ is_previous_valid = date.today() <= vacation_main.valid_date
+
+ if is_previous_valid and vacation_main.previous_year > 0:
+ deduct_previous = min(remain_deduct, vacation_main.previous_year)
+ vacation_main.write({'previous_year': vacation_main.previous_year - deduct_previous})
+ remain_deduct -= deduct_previous
if vacation_main:
used_this_year_new = vacation_main.used_this_year + deduct_amount
@@ -1350,7 +1379,6 @@ class VacationOverline(models.Model):
last_balance = fields.Float(string='上年结余', compute='_compute_last_balance', store=True)
legal_day = fields.Float(string='法定节假日')
public_holidays = fields.Float(string='公休日')
- vacation_sum = fields.Float(string='合计数', compute='_compute_last_balance')
meal_number = fields.Integer(string='误餐次数')
update_date = fields.Date(string='更新时间')
is_void = fields.Boolean(string='是否作废')
@@ -1375,7 +1403,7 @@ class VacationOverline(models.Model):
],string='结转状态',
default='pending',
)
- remaining_quantity = fields.Float(string='剩余数', compute="_compute_last_balance", store=True)
+ remaining_quantity = fields.Float(string='剩余数', compute="_compute_last_balance")
def open_record1(self):
tree_id = self.env.ref("yuthon_hr_attendance.view_yuthon_vacation_overtime_tree").id
@@ -1458,13 +1486,12 @@ class VacationOverline(models.Model):
rec._compute_employee_id()
rec._compute_last_balance()
- @api.depends('vacation_id')
+ @api.depends('vacation_id', 'carry_forward_quantity', 'duration')
def _compute_last_balance(self):
for rec in self:
if rec.vacation_id:
rec.last_balance = rec.vacation_id.last_holiday + rec.vacation_id.last_workday
- rec.vacation_sum = rec.last_balance + rec.public_holidays + rec.workday
- rec.remaining_quantity = rec.vacation_sum - rec.carry_forward_quantity
+ rec.remaining_quantity = rec.duration - rec.carry_forward_quantity
else:
rec.last_balance = 0
@@ -1528,18 +1555,47 @@ class VacationOverline(models.Model):
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('workday', 0.0) / 8 # 扣减额度
current_vacation_date = vacation_main.vacation_date
next_month_first_day = current_vacation_date + relativedelta(months=+1, day=1)
- deduct_workday = vals.get('workday', 0.0)
- deduct_public = vals.get('public_holidays', 0.0)
- deduct_workday_convert = deduct_workday / 8
- deduct_public_convert = deduct_public / 8
- deduct_total = deduct_workday_convert + deduct_public_convert
- if vacation_main:
- vacation_used_vals = {
- 'used_this_year1': (vacation_main.used_this_year1 or 0.0) + deduct_total
- }
- vacation_main.write(vacation_used_vals)
+ if not vacation_main or deduct_amount <= 0:
+ return
+
+ # ========== 核心新增逻辑:优先级扣减规则 ==========
+ # 1. 先判断上年数据是否有效(valid_date1 有效期内,无则视为无限期)
+ is_last_valid = True
+ if vacation_main.valid_date1:
+ is_last_valid = date.today() <= vacation_main.valid_date1 # 仅有效期内的上年数据可扣减
+
+ # 2. 初始化待扣减剩余量
+ remain_deduct = deduct_amount
+
+ # 3. 优先扣减上年工作日(last_holiday)
+ if is_last_valid and vacation_main.last_workday > 0:
+ deduct_workday = min(remain_deduct, vacation_main.last_workday)
+ vacation_main.write({'last_workday': vacation_main.last_workday - deduct_workday})
+ remain_deduct -= deduct_workday
+
+ # 4. 剩余扣减金额扣减公休日(last_holiday)
+ if remain_deduct > 0 and is_last_valid and vacation_main.last_holiday > 0:
+ deduct_holiday = min(remain_deduct, vacation_main.last_holiday)
+ vacation_main.write({'last_holiday': vacation_main.last_holiday - deduct_holiday})
+ remain_deduct -= deduct_holiday
+
+ # 5. 上年数据扣减完仍有剩余 → 扣减本年工作日(year_workday)
+ if remain_deduct > 0 and vacation_main.year_workday > 0:
+ deduct_year_workday = min(remain_deduct, vacation_main.year_workday)
+ vacation_main.write({'year_workday': vacation_main.year_workday - deduct_year_workday})
+ remain_deduct -= deduct_year_workday
+
+ # 6. 最后扣减本年公休日(year_holiday)
+ if remain_deduct > 0 and vacation_main.year_holiday > 0:
+ deduct_year_holiday = min(remain_deduct, vacation_main.year_holiday)
+ vacation_main.write({'year_holiday': vacation_main.year_holiday - deduct_year_holiday})
+ remain_deduct -= deduct_year_holiday
+
+ used_this_year_new = vacation_main.used_this_year1 + deduct_amount
+ vacation_main.write({'used_this_year1': used_this_year_new})
is_cross_year = False
# 计算下月1号并判断是否跨年
@@ -1556,8 +1612,8 @@ class VacationOverline(models.Model):
], limit=1)
if next_month_vacation:
next_month_deduct_vals = {
- 'last_workday': next_month_vacation.last_workday - deduct_workday_convert,
- 'last_holiday': next_month_vacation.last_holiday - deduct_public_convert,
+ 'last_workday': next_month_vacation.last_workday - deduct_amount,
+ 'last_holiday': next_month_vacation.last_holiday - deduct_amount,
}
next_month_vacation.write(next_month_deduct_vals)
diff --git a/yuthon_hr_attendance/static/src/js/button_vacation_confirm.js b/yuthon_hr_attendance/static/src/js/button_vacation_confirm.js
index 8e1b50e08..45b5533fe 100644
--- a/yuthon_hr_attendance/static/src/js/button_vacation_confirm.js
+++ b/yuthon_hr_attendance/static/src/js/button_vacation_confirm.js
@@ -13,9 +13,11 @@ export class CustomAttendanceVacationConfirmController extends ListController {
}
async getNextAction(lock_type) {
await this.orm.call('yuthon.vacation.reports', 'next_month', []);
+ this.model.root.load()
}
async getLastAction(lock_type) {
await this.orm.call('yuthon.vacation.reports', 'last_month', []);
+ this.model.root.load()
}
}
diff --git a/yuthon_hr_attendance/static/src/js/button_vacation_put.js b/yuthon_hr_attendance/static/src/js/button_vacation_put.js
index cf4d73925..e842c7e27 100644
--- a/yuthon_hr_attendance/static/src/js/button_vacation_put.js
+++ b/yuthon_hr_attendance/static/src/js/button_vacation_put.js
@@ -39,10 +39,9 @@ export class CustomAttendanceVacationPutController extends ListController {
});
}
-
-
async getAction() {
- await this.orm.call('yuthon.vacation.reports', 'overtime_line', []);
+ const res = await this.orm.call('yuthon.vacation.reports', 'overtime_line', []);
+ this.actionService.doAction(res)
}
openYuthonVacationWizard() {
diff --git a/yuthon_hr_attendance/views/vacation_overtime_active_views.xml b/yuthon_hr_attendance/views/vacation_overtime_active_views.xml
index 4f793552b..b736954bc 100644
--- a/yuthon_hr_attendance/views/vacation_overtime_active_views.xml
+++ b/yuthon_hr_attendance/views/vacation_overtime_active_views.xml
@@ -15,10 +15,19 @@
+
+ vacation.overtime.active.search
+ vacation.overtime.active
+
+
+
+
+
+
加班情况(归档)
vacation.overtime.active
- tree
+ tree,search
\ No newline at end of file
diff --git a/yuthon_hr_attendance/views/yuthon_vacation_reports_views.xml b/yuthon_hr_attendance/views/yuthon_vacation_reports_views.xml
index 0be38da25..8c5fbf16c 100644
--- a/yuthon_hr_attendance/views/yuthon_vacation_reports_views.xml
+++ b/yuthon_hr_attendance/views/yuthon_vacation_reports_views.xml
@@ -75,7 +75,7 @@
-
+
@@ -128,7 +128,7 @@
-
+
@@ -198,6 +198,9 @@
+
+
+
@@ -384,7 +387,7 @@
-
+
@@ -412,8 +415,8 @@
yuthon.vacation.reports
-
+
@@ -424,12 +427,12 @@
+ context="{'group_by': 'show_date:year'}"/>
+ context="{'group_by': 'show_date:month'}"/>
@@ -616,24 +619,6 @@
-
- vacation.over.line.overtime.briefly.tree
- vacation.over.line
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
vacation.over.line.overtime.tree
vacation.over.line
@@ -645,7 +630,6 @@
-
@@ -693,13 +677,13 @@
code
action = model.update_line()
-
- 一次性
-
-
- code
- action = model.update_is_visible()
-
+
+
+
+
+
+
+
误餐情况
vacation.meal.line
@@ -800,7 +784,14 @@
code
- action = model.update_is_confirm()
+ action = model.update_show_date()
+
+
+ 还原状态
+
+
+ code
+ action = model.update_state()
更新报表
diff --git a/yuthon_hr_employee_approval/models/yuthon_message_login.py b/yuthon_hr_employee_approval/models/yuthon_message_login.py
index 48875d0e7..115027bbc 100644
--- a/yuthon_hr_employee_approval/models/yuthon_message_login.py
+++ b/yuthon_hr_employee_approval/models/yuthon_message_login.py
@@ -185,7 +185,6 @@ class YuthonMessageLogin(models.Model):
self.old = 0
self.sex = False
-
def pub_name_button(self):
code_url = self.get_base_url() + "/hr/employee/create?employee_id=" + str(self.id)
action = {
@@ -200,6 +199,20 @@ class YuthonMessageLogin(models.Model):
}
return action
+ def return_onboard_approval(self):
+ return {
+ 'type': 'ir.actions.act_window',
+ 'name': "入职审批",
+ 'res_model': 'yuthon.onboard.approval',
+ 'view_mode': 'form',
+ 'target': 'current',
+ 'context': {
+ 'default_information_form_id': self.id,
+ 'default_phone': self.phone,
+ 'default_card': self.id_card,
+ }
+ }
+
class EducationalDetailsLine(models.Model):
_name = 'education.details.line'
diff --git a/yuthon_hr_employee_approval/models/yuthon_onboard_approval.py b/yuthon_hr_employee_approval/models/yuthon_onboard_approval.py
index 78ca95482..eb879b594 100644
--- a/yuthon_hr_employee_approval/models/yuthon_onboard_approval.py
+++ b/yuthon_hr_employee_approval/models/yuthon_onboard_approval.py
@@ -244,9 +244,3 @@ class YuthonOnboardApproval(models.Model):
'vacation_date': vacation_date,
})
- @api.onchange('employee_name')
- def _onchange_employee_id(self):
- for record in self:
- if record.employee_name:
- self.name = record.employee_name + '的入职合同'
-
diff --git a/yuthon_hr_employee_approval/views/yuthon_message_login_views.xml b/yuthon_hr_employee_approval/views/yuthon_message_login_views.xml
index 139946d98..0bdb5f6a5 100644
--- a/yuthon_hr_employee_approval/views/yuthon_message_login_views.xml
+++ b/yuthon_hr_employee_approval/views/yuthon_message_login_views.xml
@@ -5,6 +5,9 @@
yuthon.message.login
+
diff --git a/yuthon_salary/controllers/salary_phone.py b/yuthon_salary/controllers/salary_phone.py
index 0206bc6fa..6e4b987e2 100644
--- a/yuthon_salary/controllers/salary_phone.py
+++ b/yuthon_salary/controllers/salary_phone.py
@@ -8,8 +8,11 @@ from urllib.parse import quote
class YuthonWillTask(http.Controller):
@http.route('/party/list', methods=['POST'], type='http', auth='public', csrf=False)
- def party_list(self, **kwargs):
- party_ids = request.env['yuthon.salary.party'].sudo().search([('employee_id.id', '=', kwargs.get('employee_id'))])
+ def party_list(self, **kw):
+ users_id = int(kw.get('users_id'))
+ user = request.env['res.users'].sudo().browse(int(users_id))
+ employee_id = user.with_company(user.company_id.id).employee_id.id
+ party_ids = request.env['yuthon.salary.party'].sudo().search([('employee_id.id', '=', employee_id)])
data_list = []
for party in party_ids:
result = {
@@ -35,8 +38,11 @@ class YuthonWillTask(http.Controller):
return json.dumps({'code': 200, 'message': 'OK'})
@http.route('/meal/list', methods=['POST'], type='http', auth='public', csrf=False)
- def meal_list(self, **kwargs):
- meal_ids = request.env['yuthon.meal.expenses'].sudo().search([('employee_id.id', '=', kwargs.get('employee_id'))])
+ def meal_list(self, **kw):
+ users_id = int(kw.get('users_id'))
+ user = request.env['res.users'].sudo().browse(int(users_id))
+ employee_id = user.with_company(user.company_id.id).employee_id.id
+ meal_ids = request.env['yuthon.meal.expenses'].sudo().search([('employee_id.id', '=', employee_id)])
data_list = []
for meal in meal_ids:
result = {