From 76ddff97ef97f6e11f5dadc485d07b4681f01142 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=B9=8F=E5=AE=87?= Date: Sat, 26 Jul 2025 21:43:27 +0800 Subject: [PATCH 1/4] 1 --- .../static/src/views/form/form_controller.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sh_backmate_theme_adv_enterprise/static/src/views/form/form_controller.js b/sh_backmate_theme_adv_enterprise/static/src/views/form/form_controller.js index 808618bc1..b09df8697 100644 --- a/sh_backmate_theme_adv_enterprise/static/src/views/form/form_controller.js +++ b/sh_backmate_theme_adv_enterprise/static/src/views/form/form_controller.js @@ -108,9 +108,9 @@ patch(FormController.prototype, { const currentUserId = this.env.services.user.userId; if (resModel && resId) { // 1. 判断是否存在 self_users_ids(经办人)字段 - if (fields.users_ids) { - const result = await this.orm.read(resModel, [resId], ["users_ids"]); - const selfUsers = result[0]?.users_ids || []; + if (fields.self_users_ids) { + const result = await this.orm.read(resModel, [resId], ["self_users_ids"]); + const selfUsers = result[0]?.self_users_ids || []; if (!selfUsers.includes(currentUserId)) { this.buttonState.showEditButton = false; return; // 如果不是经办人,直接返回 From 6e9b21c3d36cda1f856e5433170f5092fa68a764 Mon Sep 17 00:00:00 2001 From: zhou <123@> Date: Sun, 27 Jul 2025 15:32:06 +0800 Subject: [PATCH 2/4] =?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 --- yuthon_holiday/models/inherit_hr_leave.py | 2 +- .../models/hr_attendance_month.py | 5 +-- .../views/hr_attendance_month_views.xml | 2 ++ .../models/inherit_hr_payroll_structure.py | 36 +++++++++---------- 4 files changed, 24 insertions(+), 21 deletions(-) diff --git a/yuthon_holiday/models/inherit_hr_leave.py b/yuthon_holiday/models/inherit_hr_leave.py index b95dd193c..26f215014 100644 --- a/yuthon_holiday/models/inherit_hr_leave.py +++ b/yuthon_holiday/models/inherit_hr_leave.py @@ -597,7 +597,7 @@ class HolidaysRequestBatch(models.Model): @api.depends('users_id') def _compute_holiday_allowance(self): for record in self: - reports_id = self.env['yuthon.vacation.reports'].search([('employee_id', '=', record.users_id.employee_id.id)]) + reports_id = self.env['yuthon.vacation.reports'].search([('employee_id', '=', record.users_id.employee_id.id)], limit=1) if reports_id: leave_hours_str = reports_id.leave.split('小时')[0].strip() leave_hours = float(leave_hours_str) diff --git a/yuthon_hr_attendance/models/hr_attendance_month.py b/yuthon_hr_attendance/models/hr_attendance_month.py index b9bb88b95..07cd074dd 100644 --- a/yuthon_hr_attendance/models/hr_attendance_month.py +++ b/yuthon_hr_attendance/models/hr_attendance_month.py @@ -81,7 +81,7 @@ class HrAttendanceMonthDetail(models.Model): name = fields.Char(related='employee_id.name') employee_id = fields.Many2one('hr.employee', string="员工", readonly=True) company_id = fields.Many2one(related="employee_id.company_id", string="公司", store=True) - department_id = fields.Many2one('hr.department', string="部门", related="employee_id.department_id", readonly=True) + department_id = fields.Many2one('hr.department', string="部门", related="employee_id.department_id", readonly=True, store=True) # userid = fields.Char(string='userid') attendance_year_id = fields.Many2one('hr.attendance.year', string="统计年份") current_year = fields.Char(string='统计年份', related="attendance_year_id.year") @@ -160,7 +160,8 @@ class HrAttendanceMonthDetail(models.Model): record.with_context(lang=lang)._message_auto_subscribe_notify(partner_ids, 'yuthon_hr_attendance.mail_action_hr_attendance_message') # 给企业微信发送消息 user_id = record.employee_id.user_id.oauth_uid - url = self.env['ir.config_parameter'].sudo().get_param('web.base.url') + menu_id = self.env['ir.ui.menu'].search([('name', '=', '考勤确认单')]) + url = f'https://oa.thtzjt.com/web?login={record.employee_id.user_id.login}&oauth_uid={record.employee_id.wecom_userid}#id={self.id}&cids=2&action={menu_id.action.id}&model={self._name}&view_type=form' attendance_url = "{0}/my/attendance/month/detail/{1}".format(str(url), str(record.id)) message = '您的{0}年{1}月的考勤已生成 \n 点击查看 '.format(str(record.current_year), str(record.current_month), str(attendance_url)) # self.env['wx.work.api'].sudo().send_text_message(user_id, message) diff --git a/yuthon_hr_attendance/views/hr_attendance_month_views.xml b/yuthon_hr_attendance/views/hr_attendance_month_views.xml index e0d1d1e16..1265e69fb 100644 --- a/yuthon_hr_attendance/views/hr_attendance_month_views.xml +++ b/yuthon_hr_attendance/views/hr_attendance_month_views.xml @@ -248,6 +248,8 @@ hr.attendance.month.detail + + diff --git a/yuthon_salary/models/inherit_hr_payroll_structure.py b/yuthon_salary/models/inherit_hr_payroll_structure.py index 0b91bb85c..9d9ed32ee 100644 --- a/yuthon_salary/models/inherit_hr_payroll_structure.py +++ b/yuthon_salary/models/inherit_hr_payroll_structure.py @@ -20,13 +20,13 @@ class HrPayrollStructure(models.Model): end_time = fields.Date(string="失效日期") is_enable = fields.Boolean(string="启用", default=True) currency_id = fields.Many2one("res.currency", string="货币", required=True, default=lambda self: self.env.company.currency_id) - base_salary = fields.Monetary(string="基本工资", currency_field="currency_id") - rank_salary = fields.Monetary(string="职级工资", currency_field="currency_id") - communication_subsidy = fields.Monetary(string="通讯补贴", currency_field="currency_id") - position_salary = fields.Monetary(string="岗位工资", currency_field="currency_id") - position_subsidy = fields.Monetary(string="岗位补贴", currency_field="currency_id") - integrated_subsidy = fields.Monetary(string="综合补贴", currency_field="currency_id") - advance_performance_bonuses = fields.Monetary(string="预发绩效奖金", currency_field="currency_id") + base_salary = fields.Float(string="基本工资") + rank_salary = fields.Float(string="职级工资") + communication_subsidy = fields.Float(string="通讯补贴") + position_salary = fields.Float(string="岗位工资") + position_subsidy = fields.Float(string="岗位补贴") + integrated_subsidy = fields.Float(string="综合补贴") + advance_performance_bonuses = fields.Float(string="预发绩效奖金") renk_log_ids = fields.One2many("rank.log.line", "structure_id", string="职级日志明细行") @api.model @@ -238,20 +238,20 @@ class HrPayrollStructure(models.Model): today = date.today() for structure in self.search([]): # 获取该职级下所有有效的日志记录 - valid_logs = structure.renk_log_ids.filtered( - lambda log: log.is_enable and - log.effective_date and - log.effective_date <= today and - (not log.lapse_date or log.lapse_date >= today) - ).sorted(key=lambda l: l.effective_date, reverse=True) + valid_logs = self.env['rank.log.line'].search([ + ('structure_id', '=', structure.id), + ('effective_date', '!=', False), + ('effective_date', '<=', today), + '|', ('lapse_date', '>=', today), ('lapse_date', '=', False) + ], order='effective_date DESC', limit=1) if valid_logs: latest_log = valid_logs[0] structure.write({ - 'base_salary': latest_log.base_salary, - 'rank_salary': latest_log.rank_salary, - 'communication_subsidy': latest_log.communication_subsidy, - 'position_salary': latest_log.position_salary, - 'advance_performance_bonuses': latest_log.advance_performance_bonuses, + 'base_salary': float(latest_log.base_salary or 0.0), + 'rank_salary': float(latest_log.rank_salary or 0.0), + 'communication_subsidy': float(latest_log.communication_subsidy or 0.0), + 'position_salary': float(latest_log.position_salary or 0.0), + 'advance_performance_bonuses': float(latest_log.advance_performance_bonuses or 0.0), }) class RankLogLine(models.Model): From 367100f73c47c0d5a5e1356c6660cc64a8b87197 Mon Sep 17 00:00:00 2001 From: zhou <123@> Date: Sun, 27 Jul 2025 15:38:36 +0800 Subject: [PATCH 3/4] =?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/inherit_hr_payroll_structure.py | 38 +++++++++---------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/yuthon_salary/models/inherit_hr_payroll_structure.py b/yuthon_salary/models/inherit_hr_payroll_structure.py index 9d9ed32ee..16c88b05e 100644 --- a/yuthon_salary/models/inherit_hr_payroll_structure.py +++ b/yuthon_salary/models/inherit_hr_payroll_structure.py @@ -20,13 +20,13 @@ class HrPayrollStructure(models.Model): end_time = fields.Date(string="失效日期") is_enable = fields.Boolean(string="启用", default=True) currency_id = fields.Many2one("res.currency", string="货币", required=True, default=lambda self: self.env.company.currency_id) - base_salary = fields.Float(string="基本工资") - rank_salary = fields.Float(string="职级工资") - communication_subsidy = fields.Float(string="通讯补贴") - position_salary = fields.Float(string="岗位工资") - position_subsidy = fields.Float(string="岗位补贴") - integrated_subsidy = fields.Float(string="综合补贴") - advance_performance_bonuses = fields.Float(string="预发绩效奖金") + base_salary = fields.Monetary(string="基本工资", currency_field="currency_id") + rank_salary = fields.Monetary(string="职级工资", currency_field="currency_id") + communication_subsidy = fields.Monetary(string="通讯补贴", currency_field="currency_id") + position_salary = fields.Monetary(string="岗位工资", currency_field="currency_id") + position_subsidy = fields.Monetary(string="岗位补贴", currency_field="currency_id") + integrated_subsidy = fields.Monetary(string="综合补贴", currency_field="currency_id") + advance_performance_bonuses = fields.Monetary(string="预发绩效奖金", currency_field="currency_id") renk_log_ids = fields.One2many("rank.log.line", "structure_id", string="职级日志明细行") @api.model @@ -236,22 +236,22 @@ class HrPayrollStructure(models.Model): def rank_log_time(self): """定时任务:根据日志记录的生效时间更新主模型字段值""" today = date.today() - for structure in self.search([]): + for structure in self.env['hr.payroll.structure'].search([('company_id.name', '=', '集团本部')]): # 获取该职级下所有有效的日志记录 - valid_logs = self.env['rank.log.line'].search([ - ('structure_id', '=', structure.id), - ('effective_date', '!=', False), - ('effective_date', '<=', today), - '|', ('lapse_date', '>=', today), ('lapse_date', '=', False) - ], order='effective_date DESC', limit=1) + valid_logs = structure.renk_log_ids.filtered( + lambda log: log.is_enable and + log.effective_date and + log.effective_date <= today and + (not log.lapse_date or log.lapse_date >= today) + ).sorted(key=lambda l: l.effective_date, reverse=True) if valid_logs: latest_log = valid_logs[0] structure.write({ - 'base_salary': float(latest_log.base_salary or 0.0), - 'rank_salary': float(latest_log.rank_salary or 0.0), - 'communication_subsidy': float(latest_log.communication_subsidy or 0.0), - 'position_salary': float(latest_log.position_salary or 0.0), - 'advance_performance_bonuses': float(latest_log.advance_performance_bonuses or 0.0), + 'base_salary': latest_log.base_salary, + 'rank_salary': latest_log.rank_salary, + 'communication_subsidy': latest_log.communication_subsidy, + 'position_salary': latest_log.position_salary, + 'advance_performance_bonuses': latest_log.advance_performance_bonuses, }) class RankLogLine(models.Model): From d39ca5310f1482380027fc8cd607c454f1137678 Mon Sep 17 00:00:00 2001 From: zhou <123@> Date: Sun, 27 Jul 2025 16:03:41 +0800 Subject: [PATCH 4/4] =?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/inherit_hr_payroll_structure.py | 31 ++++++++++--------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/yuthon_salary/models/inherit_hr_payroll_structure.py b/yuthon_salary/models/inherit_hr_payroll_structure.py index 16c88b05e..1fcabeeed 100644 --- a/yuthon_salary/models/inherit_hr_payroll_structure.py +++ b/yuthon_salary/models/inherit_hr_payroll_structure.py @@ -57,7 +57,7 @@ class HrPayrollStructure(models.Model): name_pinyin = pinyin(field_name, style=Style.FIRST_LETTER) code = "".join([p[0][0] for p in name_pinyin]).upper() salary_id = self.env['hr.salary.rule'].search( - [('name', '=', field_name), ('struct_id', '=', self.id.origin)], limit=1) + [('name', '=', field_name), ('struct_id', '=', self.id)], limit=1) if not salary_id: self.env['hr.salary.rule'].create({ 'name': field_name, @@ -110,15 +110,18 @@ class HrPayrollStructure(models.Model): def write(self, vals): result = super(HrPayrollStructure, self).write(vals) - field_mapping = { - 'base_salary': '基本工资', - 'rank_salary': '职级工资', - 'communication_subsidy': '通讯补贴', - 'position_salary': '岗位工资' - } - for field, name in field_mapping.items(): - if field in vals: - self._handle_salary_rule(name, self[field]) + if result: + field_mapping = { + 'base_salary': '基本工资', + 'rank_salary': '职级工资', + 'communication_subsidy': '通讯补贴', + 'position_salary': '岗位工资', + 'advance_performance_bonuses': '预发绩效奖金' # 补充新增字段 + } + for record in self: + for field, name in field_mapping.items(): + if field in vals: + record._handle_salary_rule(name, record[field]) return result def action_yuthon_payroll_wizard(self): @@ -235,18 +238,16 @@ class HrPayrollStructure(models.Model): def rank_log_time(self): """定时任务:根据日志记录的生效时间更新主模型字段值""" + # 出发一下 today = date.today() for structure in self.env['hr.payroll.structure'].search([('company_id.name', '=', '集团本部')]): # 获取该职级下所有有效的日志记录 valid_logs = structure.renk_log_ids.filtered( - lambda log: log.is_enable and - log.effective_date and - log.effective_date <= today and - (not log.lapse_date or log.lapse_date >= today) + lambda log: log.is_enable and log.effective_date and log.effective_date <= today and (not log.lapse_date or log.lapse_date >= today) ).sorted(key=lambda l: l.effective_date, reverse=True) if valid_logs: latest_log = valid_logs[0] - structure.write({ + structure.sudo().write({ 'base_salary': latest_log.base_salary, 'rank_salary': latest_log.rank_salary, 'communication_subsidy': latest_log.communication_subsidy,