From e5fa44dc3ced2c50ffad1efbb999646f18ea603d 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: Thu, 22 Jan 2026 14:48:35 +0800 Subject: [PATCH 01/31] =?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 --- room/models/room_booking.py | 2 +- soong_workflow/views/soong_workflow_record.xml | 2 +- yuthon_contract/models/inherit_hr_contract.py | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/room/models/room_booking.py b/room/models/room_booking.py index e0185e2c3..9288d7252 100644 --- a/room/models/room_booking.py +++ b/room/models/room_booking.py @@ -92,7 +92,7 @@ class RoomBooking(models.Model): def _onchange_meeting_type_id(self): if self.meeting_type_id: self.room_users_ids = self.meeting_type_id.users_ids - self.host = self.meeting_type_id.host_user_id if self.meeting_type_id.host_user_id else False + self.host = self.meeting_type_id.host_user_id.id if self.meeting_type_id.host_user_id else False else: self.room_users_ids = [(5, 0, 0)] self.host = False diff --git a/soong_workflow/views/soong_workflow_record.xml b/soong_workflow/views/soong_workflow_record.xml index 2f82940bd..1392e00a8 100644 --- a/soong_workflow/views/soong_workflow_record.xml +++ b/soong_workflow/views/soong_workflow_record.xml @@ -376,7 +376,7 @@ {'header_search_default_approve_state': 1, 'header_search_default_to_do':1, 'check_employee': 1} - [('is_to_do', '=', True), ('is_company', '=', True)] + [('is_to_do', '=', True)] diff --git a/yuthon_contract/models/inherit_hr_contract.py b/yuthon_contract/models/inherit_hr_contract.py index f2be7a908..9e7751ef6 100644 --- a/yuthon_contract/models/inherit_hr_contract.py +++ b/yuthon_contract/models/inherit_hr_contract.py @@ -111,7 +111,7 @@ class HrContract(models.Model): 'target': 'current', 'context': { 'default_work_end': False, - 'default_self_users_ids':[(6, 0, [self.employee_id.user_id.id])], + 'default_self_users_ids':[(6, 0, [self.env.user.id])], 'default_contract_id': contract_ids.id, 'default_employee_id': contract_ids.employee_id.id }} @@ -172,7 +172,7 @@ class HrContract(models.Model): "default_employee_id": self.employee_id.id, "default_current_status": self.employee_id.contract_id.date_end, "default_department1_id": self.employee_id.department_id.id, - "default_renewal_date": self.employee_id.contract_id.date_end + relativedelta(years=3), + "default_renewal_date": self.employee_id.contract_id.date_end + relativedelta(years=3) if self.employee_id.contract_id.date_end else False, "default_contract_id": self.id, }, } From 5beb1233591063ea832e08fcb87801bba97697f7 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: Thu, 22 Jan 2026 15:02:48 +0800 Subject: [PATCH 02/31] =?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_official/models/yuthon_official.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yuthon_official/models/yuthon_official.py b/yuthon_official/models/yuthon_official.py index 38bc370d2..f8baca6f0 100644 --- a/yuthon_official/models/yuthon_official.py +++ b/yuthon_official/models/yuthon_official.py @@ -100,7 +100,7 @@ class YuthonOfficial(models.Model): 'state': '申请人', 'code': self.env['ir.sequence'].next_by_code('sub_enterprises_code'), 'official_partner_id': official_partner_id.id, - 'reason_application': 'main_text', + 'reason_application': self.main_text, 'document_ids': [(6, 0, all_document_ids)] if all_document_ids else False }) workflow_id = self.env['soong.workflow.record'].search([('code', '=', self.code)], limit=1).id From f82c96c3cadbd1d191ee059ecd670098a125d407 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: Thu, 22 Jan 2026 17:55:58 +0800 Subject: [PATCH 03/31] =?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_hr_attendance/__manifest__.py | 2 + .../models/overtime_approval.py | 11 ++- .../models/yuthon_holiday_statement.py | 1 + .../models/yuthon_vacation_reports.py | 68 ++++++++++++++++- .../static/src/js/button_vacation_confirm.js | 23 ++++++ .../static/src/js/button_vacation_put.js | 54 ++++++++++--- .../src/xml/button_vacation_confirm.xml | 10 +++ .../views/yuthon_holiday_statement.xml | 15 +++- .../views/yuthon_vacation_reports_views.xml | 76 +++++++++++++++---- yuthon_work_brand/views/hr_menus.xml | 29 +++++++ 10 files changed, 257 insertions(+), 32 deletions(-) create mode 100644 yuthon_hr_attendance/static/src/js/button_vacation_confirm.js create mode 100644 yuthon_hr_attendance/static/src/xml/button_vacation_confirm.xml diff --git a/yuthon_hr_attendance/__manifest__.py b/yuthon_hr_attendance/__manifest__.py index 9afb7c4d6..092754072 100644 --- a/yuthon_hr_attendance/__manifest__.py +++ b/yuthon_hr_attendance/__manifest__.py @@ -95,6 +95,8 @@ 'yuthon_hr_attendance/static/src/xml/button_detail_wechat.xml', 'yuthon_hr_attendance/static/src/components/*/*.xml', 'yuthon_hr_attendance/static/src/css/*.css', + 'yuthon_hr_attendance/static/src/js/button_vacation_confirm.js', + 'yuthon_hr_attendance/static/src/xml/button_vacation_confirm.xml', 'yuthon_hr_attendance/static/src/js/planning_gantt_renderer.js', 'yuthon_hr_attendance/static/src/xml/planning_gantt_renderer.xml', 'yuthon_hr_attendance/static/src/js/button_vacation_put.js', diff --git a/yuthon_hr_attendance/models/overtime_approval.py b/yuthon_hr_attendance/models/overtime_approval.py index f31fd0a63..179b35065 100644 --- a/yuthon_hr_attendance/models/overtime_approval.py +++ b/yuthon_hr_attendance/models/overtime_approval.py @@ -219,9 +219,14 @@ class OvertimeApprovals(models.Model): if company_id: company = self.env['res.company'].browse(company_id) if company.name == '天河物管': - if vals.get('duration'): - if (vals['duration']) % 1 != 0.5: - raise ValidationError("时长不对!请重新编辑") + duration = vals.get('duration') + if duration is None: + raise ValidationError("时长不能为空!请填写有效的加班时长") + if duration < 1: + raise ValidationError(f"时长不能小于1!当前填写的是{duration},请重新编辑") + if (duration * 2) % 1 != 0: + raise ValidationError( + f"时长格式错误!请填写1、1.5、2、2.5...等以0.5递增的数值,当前填写的是{duration}") return super(OvertimeApprovals, self).create(vals_list) @api.onchange('is_issues') diff --git a/yuthon_hr_attendance/models/yuthon_holiday_statement.py b/yuthon_hr_attendance/models/yuthon_holiday_statement.py index c8965af07..4841522a4 100644 --- a/yuthon_hr_attendance/models/yuthon_holiday_statement.py +++ b/yuthon_hr_attendance/models/yuthon_holiday_statement.py @@ -12,6 +12,7 @@ class InheritHrLeave(models.Model): caption = fields.Char(string="标题", compute="_compute_application_reason") employee_id = fields.Many2one('hr.employee', string="发起人") leave_stats = fields.Char(string="请假统计", compute="_compute_leave_stats") + is_filing = fields.Boolean(string="归档") application_reason = fields.Char(string="申请原因", compute="_compute_application_reason") @api.depends('batch_id', 'hour_batch_id') diff --git a/yuthon_hr_attendance/models/yuthon_vacation_reports.py b/yuthon_hr_attendance/models/yuthon_vacation_reports.py index 48eee60e9..e14f9dcfa 100644 --- a/yuthon_hr_attendance/models/yuthon_vacation_reports.py +++ b/yuthon_hr_attendance/models/yuthon_vacation_reports.py @@ -85,7 +85,7 @@ class YuthonVacationReports(models.Model): attendance_message_log_ids = fields.One2many('attendance.message.log', 'vacation_id') admin_confirms = fields.Boolean(string="是否管理员确认") - + is_filing = fields.Boolean(string="归档") vacation_state = fields.Selection( selection=[ ('not_sent', "未发送"), @@ -986,7 +986,7 @@ class VacationOverline(models.Model): carry_forward_quantity = fields.Float(string="结转时长") validity = fields.Char(string="有效期") carry_result = fields.Selection([('success', '成功'), ('failed', '失败')], string="结转结果") - is_active = fields.Boolean(string="归档") + is_filing = fields.Boolean(string="归档") carry_forward_state = fields.Selection([('pending', '待结转'),('completed', '已结转'), ('partial', '部分结转') ],string='结转状态', default='pending', @@ -994,7 +994,28 @@ class VacationOverline(models.Model): remaining_quantity = fields.Float(string='剩余数', compute="_compute_remaining_quantity", store=True) def confirm(self): - pass + domain = [ + '|', + ['is_initial_number', '=', True], + '&', + ['is_initial_number', '=', False], + '&', + ['update_type', '=', 'add'], + '&', + ['workflow_record_id', '!=', False], + '!', + '&', + ['start_time', '>=', '2025-12-01 00:00:00'], + ['start_time', '<', '2026-01-01 00:00:00'] + ] + filtered_records = self.search(domain) + if not filtered_records: + return + records_to_update = filtered_records.filtered( + lambda r: fields.float_compare(r.total, r.carry_forward_quantity) == 0 + ) + if records_to_update: + records_to_update.write({'is_filing': True}) def update_line(self): over_ids = self.env["vacation.over.line"].browse( @@ -1181,9 +1202,15 @@ class VacationMealLine(models.Model): _description = '误餐明细' vacation_id = fields.Many2one('yuthon.vacation.reports', string='关联假期额度记录') - employee_id = fields.Many2one('hr.employee', string='员工') + is_filing = fields.Boolean(string="归档") + employee_id = fields.Many2one('hr.employee', string='员工', compute='_compute_employee_id', store=True) + department_id = fields.Many2one('hr.department', related='employee_id.department_id', string="部门", store=True) + company_id = fields.Many2one('res.company', related='employee_id.company_id', string="公司", store=True) workflow_record_id = fields.Many2one('soong.workflow.record', string='流程') + vacation_date = fields.Date(related='vacation_id.vacation_date', string='误餐日期') update_type= fields.Selection([('add', '增加'), ('reduce', '减少')], string='更新类型') + meal_name = fields.Char(string="标题", compute="_compute_overtime", store=True) + start_date = fields.Date(string="日期", compute="_compute_overtime", store=True) update_date = fields.Date(string='更新时间') update_lines = fields.Float(string='更新额度') is_soon = fields.Boolean(string="流程修改") @@ -1194,6 +1221,39 @@ class VacationMealLine(models.Model): text = fields.Text(string='备注') is_confirm = fields.Boolean(string="是否确认") + def update_line(self): + meal_ids = self.env["vacation.meal.line"].browse( + self._context.get('active_ids', self._context.get('active_id'))) + for rec in meal_ids: + rec._compute_employee_id() + rec._compute_overtime() + + @api.depends('workflow_record_id') + def _compute_overtime(self): + for rec in self: + rec.start_date = False + res_model = rec.workflow_record_id.res_model + res_id = rec.workflow_record_id.res_id + if res_model and res_id and res_model in self.env: + if res_model == 'overtime.approval': + overtime_id = rec.env[res_model].search([('id', '=', res_id)], limit=1) + if overtime_id: + rec.start_date = overtime_id.start_time.date() or '' + else: + go_approval_id = rec.env[res_model].search([('id', '=', res_id)], limit=1) + if go_approval_id: + rec.start_date = go_approval_id.date_start.date() or '' + rec.meal_name = rec.workflow_record_id.name or '' + + + @api.depends('vacation_id') + def _compute_employee_id(self): + for rec in self: + if rec.vacation_id: + rec.employee_id = rec.vacation_id.employee_id.id + elif not rec.employee_id: + rec.employee_id = False + def action_void(self): self.is_void = True diff --git a/yuthon_hr_attendance/static/src/js/button_vacation_confirm.js b/yuthon_hr_attendance/static/src/js/button_vacation_confirm.js new file mode 100644 index 000000000..42d44f38c --- /dev/null +++ b/yuthon_hr_attendance/static/src/js/button_vacation_confirm.js @@ -0,0 +1,23 @@ +/** @odoo-module */ +import { ListController } from "@web/views/list/list_controller"; +import { registry } from '@web/core/registry'; +import { listView } from '@web/views/list/list_view'; + +export class CustomAttendanceVacationConfirmController extends ListController { + setup() { + super.setup(); + } + async openConfirm() { + await this.model.orm.call( + 'vacation.over.line', + 'confirm', + [] + ); + } +} + +registry.category("views").add("custom_vacation_confirm_button", { + ...listView, + Controller: CustomAttendanceVacationConfirmController, + buttonTemplate: "vacation_confirm_module.ListView.Buttons", +}); \ No newline at end of file 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 965dbcbb8..9d1cfd6e1 100644 --- a/yuthon_hr_attendance/static/src/js/button_vacation_put.js +++ b/yuthon_hr_attendance/static/src/js/button_vacation_put.js @@ -9,6 +9,19 @@ export class CustomAttendanceVacationPutController extends ListController { } openHrLeaveWizard() { + const now = new Date(); + const lastMonthYear = now.getMonth() === 0 ? now.getFullYear() - 1 : now.getFullYear(); + const lastMonth = now.getMonth() === 0 ? 11 : now.getMonth() - 1; + const lastMonthFirstDay = new Date(lastMonthYear, lastMonth, 1); + const currentMonthFirstDay = new Date(now.getFullYear(), now.getMonth(), 1); + const formatDate = (date) => { + const year = date.getFullYear(); + const month = String(date.getMonth() + 1).padStart(2, '0'); + const day = String(date.getDate()).padStart(2, '0'); + return `${year}-${month}-${day} 00:00:00`; + }; + const lastMonthStart = formatDate(lastMonthFirstDay); + const lastMonthEnd = formatDate(currentMonthFirstDay); this.actionService.doAction({ type: 'ir.actions.act_window', res_model: 'hr.leave', @@ -18,6 +31,11 @@ export class CustomAttendanceVacationPutController extends ListController { views: [[false, 'tree']], target: 'new', // 弹窗形式打开 context: {'tree_view_ref': "yuthon_hr_attendance.view_hr_leave_statement_tree"}, + domain: [ + '&', + ['date_from', '>=', lastMonthStart], + ['date_from', '<', lastMonthEnd] + ], }); } @@ -33,17 +51,14 @@ export class CustomAttendanceVacationPutController extends ListController { context: {'tree_view_ref': "yuthon_hr_attendance.view_yuthon_vacation_overtime_briefly_tree"}, domain: [ '|', - // 条件1:is_initial_number=true → 无视时间,直接显示 ['is_initial_number', '=', true], - // 条件组2:is_initial_number=false + add + workflow_record_id≠空 + 非12月 - '&', // 且:作用于「条件2」和「运算符&的结果」 + '&', ['is_initial_number', '=', false], - '&', // 且:作用于「条件3」和「运算符&的结果」 + '&', ['update_type', '=', 'add'], - '&', // 且:作用于「条件4」和「运算符!的结果」 + '&', ['workflow_record_id', '!=', false], - // 时间过滤:只作用于第二类记录 - '!', // 取反:不是2025年12月 + '!', '&', ['start_time', '>=', '2025-12-01 00:00:00'], ['start_time', '<', '2026-01-01 00:00:00'] @@ -52,16 +67,35 @@ export class CustomAttendanceVacationPutController extends ListController { } openYuthonVacationWizard() { + const now = new Date(); + const lastMonthYear = now.getMonth() === 0 ? now.getFullYear() - 1 : now.getFullYear(); + const lastMonth = now.getMonth() === 0 ? 11 : now.getMonth() - 1; + const lastMonthFirstDay = new Date(lastMonthYear, lastMonth, 1); + const currentMonthFirstDay = new Date(now.getFullYear(), now.getMonth(), 1); + const formatDate = (date) => { + const year = date.getFullYear(); + const month = String(date.getMonth() + 1).padStart(2, '0'); + const day = String(date.getDate()).padStart(2, '0'); + return `${year}-${month}-${day} 00:00:00`; + }; + const lastMonthStart = formatDate(lastMonthFirstDay); + const lastMonthEnd = formatDate(currentMonthFirstDay); this.actionService.doAction({ type: 'ir.actions.act_window', - res_model: 'yuthon.vacation.reports', + res_model: 'vacation.meal.line', name: '误餐情况', view_mode: 'tree', view_type: 'form', views: [[false, 'tree']], target: 'new', - context: {'tree_view_ref': "yuthon_hr_attendance.view_yuthon_vacation_meal_tree"}, - domain: [['meal_fee', '!=', 0]] + context: {'tree_view_ref': "yuthon_hr_attendance.view_vacation_meal_line_tree", + 'group_by': ['employee_id'], + }, + domain: [ + '&', + ['start_date', '>=', lastMonthStart], + ['start_date', '<', lastMonthEnd] + ], }); } } diff --git a/yuthon_hr_attendance/static/src/xml/button_vacation_confirm.xml b/yuthon_hr_attendance/static/src/xml/button_vacation_confirm.xml new file mode 100644 index 000000000..dfe90d6ce --- /dev/null +++ b/yuthon_hr_attendance/static/src/xml/button_vacation_confirm.xml @@ -0,0 +1,10 @@ + + + + + + + + \ No newline at end of file diff --git a/yuthon_hr_attendance/views/yuthon_holiday_statement.xml b/yuthon_hr_attendance/views/yuthon_holiday_statement.xml index b70095a71..e6fab2b51 100644 --- a/yuthon_hr_attendance/views/yuthon_holiday_statement.xml +++ b/yuthon_hr_attendance/views/yuthon_holiday_statement.xml @@ -4,17 +4,18 @@ hr.leave.statement.tree hr.leave - + - + + @@ -40,6 +41,16 @@ 请假情况 hr.leave tree,search + [('is_filing','=', False)] + {'search_default_now_month': 1, 'search_default_group_by_employee_id':1} + + + + + 请假归档 + hr.leave + tree,search + [('is_filing','=', True)] {'search_default_now_month': 1, 'search_default_group_by_employee_id':1} diff --git a/yuthon_hr_attendance/views/yuthon_vacation_reports_views.xml b/yuthon_hr_attendance/views/yuthon_vacation_reports_views.xml index 8f0308028..c962ec04c 100644 --- a/yuthon_hr_attendance/views/yuthon_vacation_reports_views.xml +++ b/yuthon_hr_attendance/views/yuthon_vacation_reports_views.xml @@ -1,15 +1,36 @@ - - yuthon.vacation.reports.tree - yuthon.vacation.reports + + vacation.meal.line.tree + vacation.meal.line - + - + + + + + + vacation.meal.line.search + vacation.meal.line + + + + + + + + + + + + + + yuthon.vacation.reports.tree yuthon.vacation.reports @@ -518,7 +539,7 @@ vacation.over.line.overtime.briefly.tree vacation.over.line - + @@ -526,6 +547,7 @@ + @@ -540,7 +562,7 @@ - + @@ -588,7 +610,7 @@ 加班情况 vacation.over.line tree - ['|', ('workflow_record_id','!=', False), ('is_initial_number', '=', True), ('update_type', '=', 'add')] + ['|', ('workflow_record_id','!=', False), ('is_initial_number', '=', True), ('update_type', '=', 'add'), ('is_filing','=', False)] {'search_default_now_month': 1, 'search_default_group_by_employee_id':1} @@ -597,7 +619,7 @@ 加班情况(归档) vacation.over.line tree - ['|', ('workflow_record_id','!=', False), ('is_initial_number', '=', True), ('update_type', '=', 'add'), ('is_active', '=', True)] + ['|', ('workflow_record_id','!=', False), ('is_initial_number', '=', True), ('update_type', '=', 'add'), ('is_filing','=', True)] {'search_default_group_by_employee_id':1} @@ -611,18 +633,46 @@ 误餐情况 - yuthon.vacation.reports + vacation.meal.line tree - [('meal_fee', '!=', 0)] + [('is_filing','=', False)] {'search_default_now_month': 1, 'search_default_group_by_employee_id':1} - + + (0, 0, {'view_mode': 'tree', 'view_id': ref('yuthon_hr_attendance.view_vacation_meal_line_tree')}),]"/> + + + 触发计算逻辑 + + + code + action = model.update_line() + + + 误餐归档 + vacation.meal.line + tree + [('is_filing','=', True)] + {'search_default_now_month': 1, 'search_default_group_by_employee_id':1} + + 考勤确认单台账 yuthon.vacation.reports tree,form + [('is_filing','=', False)] + {'search_default_now_month': 1, 'search_default_group_by_employee_id':1} + + + + 考勤确认单归档 + yuthon.vacation.reports + tree,form + [('is_filing','=', True)] {'search_default_now_month': 1, 'search_default_group_by_employee_id':1} + + + + + + From e8e42756957f9619809a578175af570a962b2f5d 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: Thu, 22 Jan 2026 18:52:12 +0800 Subject: [PATCH 04/31] =?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 --- soong_workflow/models/soong_workflow_node.py | 57 ++++++++++++++++++- .../views/soong_workflow_node_views.xml | 9 ++- 2 files changed, 63 insertions(+), 3 deletions(-) diff --git a/soong_workflow/models/soong_workflow_node.py b/soong_workflow/models/soong_workflow_node.py index 6bb3310e7..6f20a44c5 100644 --- a/soong_workflow/models/soong_workflow_node.py +++ b/soong_workflow/models/soong_workflow_node.py @@ -86,15 +86,68 @@ class SoongWorkflowNode(models.Model): is_carbon_copy = fields.Boolean(string="抄送/传阅") is_archive = fields.Boolean(string="归档") is_apostille = fields.Boolean(string="加签", default=False) - employee_ids = fields.Many2many('hr.employee', string='抄送/传阅人员') + department1_ids = fields.Many2many( + "hr.department", + string="抄送部门", + relation="soong_workflow_node_department_rel", + column1="node_id", + column2="department_id" + ) + user_role_ids = fields.Many2many("soong.user.role", string="抄送角色", ) + users_role_group_ids = fields.Many2many('soong.user.role.group', string='抄送角色组') + employee1_ids = fields.Many2many( + 'hr.employee', + string='抄送人员', + relation="soong_workflow_node_employee1_rel", + column1="node_id", + column2="employee1_id" + ) + employee_ids = fields.Many2many( + 'hr.employee', + string='抄送/传阅人员(总和)', + relation="soong_workflow_node_employee_total_rel", + column1="node_id", + column2="employee_total_id" + ) is_end = fields.Boolean(string="结束", default=False) is_confirm = fields.Boolean(string="确认", default=False) - department_id = fields.Many2many('hr.department', string='部门转入范围') + department_id = fields.Many2many( + 'hr.department', + string='部门转入范围', + relation="soong_workflow_node_transfer_department_rel", + column1="node_id", + column2="transfer_department_id" + ) comment_id = fields.Many2one('soong.note', string="固定意见") approval_concatenation = fields.Selection([('chuan', '串申'), ('bing', '并申')], string="审批形式", default="bing", help='并:任何人均给意见,最后一个完成的人转交到下一节点.' '串:都会收到消息,但任意一个人转交后,即到下一节点,其他人将不再显示,相当于收回.') + @api.onchange('department1_ids', 'user_role_ids', 'users_role_group_ids', 'employee1_ids') + def _onchange_sync_employee_ids(self): + for record in self: + final_employees = self.env['hr.employee'] + role_group_roles = record.users_role_group_ids.mapped('user_role_ids') + all_target_roles = record.user_role_ids | role_group_roles + if all_target_roles: + role_employees = self.env['hr.employee'].search([ + '|', + ('user_role_id', 'in', all_target_roles.ids), + ('user_role_ids', 'in', all_target_roles.ids) + ]) + final_employees |= role_employees + + if record.department1_ids: + dept_employees = self.env['hr.employee'].search([ + ('department_id', 'in', record.department1_ids.ids) + ]) + final_employees |= dept_employees + + if record.employee1_ids: + final_employees |= record.employee1_ids + + record.employee_ids = final_employees if final_employees else [(5, 0, 0)] + @api.onchange("is_apostille") def onchange_is_apostille(self): for record in self: diff --git a/soong_workflow/views/soong_workflow_node_views.xml b/soong_workflow/views/soong_workflow_node_views.xml index a61f21220..107409e1f 100644 --- a/soong_workflow/views/soong_workflow_node_views.xml +++ b/soong_workflow/views/soong_workflow_node_views.xml @@ -37,8 +37,15 @@ - + + + + From 3ba4b0b56047676cd7c8213fc413ee30a66ff49c 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: Thu, 22 Jan 2026 19:52:19 +0800 Subject: [PATCH 05/31] =?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 --- soong_workflow/models/soong_workflow_mixin.py | 17 +++++++++++++++++ soong_workflow/models/soong_workflow_node.py | 13 +------------ .../views/soong_workflow_node_views.xml | 3 +-- .../wizard/soong_workflow_comment_wizard.py | 4 ++-- .../soong_workflow_comment_wizard_view.xml | 11 ++++++----- .../models/yuthon_holiday_statement.py | 19 +++++++++++++++++++ .../models/yuthon_vacation_reports.py | 19 +++++++++++++++++++ 7 files changed, 65 insertions(+), 21 deletions(-) diff --git a/soong_workflow/models/soong_workflow_mixin.py b/soong_workflow/models/soong_workflow_mixin.py index 84b9c566d..743981bd0 100644 --- a/soong_workflow/models/soong_workflow_mixin.py +++ b/soong_workflow/models/soong_workflow_mixin.py @@ -559,6 +559,22 @@ class SoongWorkflowMixin(models.AbstractModel): comment_note_id = btn_rec.node_id.comment_id.id else: comment_note_id = False + # 加签人员过滤 + if self.log_ids: + log_node_ids = self.log_ids.mapped('node_id.id') + log_nodes = self.env['soong.workflow.node'].browse(log_node_ids) + all_node_employees = log_nodes.mapped('employee_ids') + else: + current_node = node_list[state_list.index(state)] + all_node_employees = current_node.employee_ids + + log_done_by_users = self.log_ids.mapped('done_by') + log2_done_by_users = self.log_ids2.mapped('done_by') + all_done_by_users = log_done_by_users | log2_done_by_users + done_by_employees = self.env['hr.employee'].search([ + ('user_id', 'in', all_done_by_users.ids) + ]) + all_filter_employees = all_node_employees | done_by_employees return { "name": _("评论"), "type": "ir.actions.act_window", @@ -572,6 +588,7 @@ class SoongWorkflowMixin(models.AbstractModel): 'default_comment_note_id': comment_note_id, "default_code": self.code, "default_res_model": self._name, + "default_filter_personnel_ids": [(6, 0, all_filter_employees.ids)], "default_node_btn_id": btn_rec.id, "default_is_supervising": is_supervising, "default_trans_link_id": self.env['trans.link'].search(trans_domain, limit=1).id if btn_rec.name == '转交' else False, diff --git a/soong_workflow/models/soong_workflow_node.py b/soong_workflow/models/soong_workflow_node.py index 6f20a44c5..8a0915b46 100644 --- a/soong_workflow/models/soong_workflow_node.py +++ b/soong_workflow/models/soong_workflow_node.py @@ -95,16 +95,9 @@ class SoongWorkflowNode(models.Model): ) user_role_ids = fields.Many2many("soong.user.role", string="抄送角色", ) users_role_group_ids = fields.Many2many('soong.user.role.group', string='抄送角色组') - employee1_ids = fields.Many2many( - 'hr.employee', - string='抄送人员', - relation="soong_workflow_node_employee1_rel", - column1="node_id", - column2="employee1_id" - ) employee_ids = fields.Many2many( 'hr.employee', - string='抄送/传阅人员(总和)', + string='抄送/传阅人员', relation="soong_workflow_node_employee_total_rel", column1="node_id", column2="employee_total_id" @@ -142,10 +135,6 @@ class SoongWorkflowNode(models.Model): ('department_id', 'in', record.department1_ids.ids) ]) final_employees |= dept_employees - - if record.employee1_ids: - final_employees |= record.employee1_ids - record.employee_ids = final_employees if final_employees else [(5, 0, 0)] @api.onchange("is_apostille") diff --git a/soong_workflow/views/soong_workflow_node_views.xml b/soong_workflow/views/soong_workflow_node_views.xml index 107409e1f..02263bf35 100644 --- a/soong_workflow/views/soong_workflow_node_views.xml +++ b/soong_workflow/views/soong_workflow_node_views.xml @@ -43,9 +43,8 @@ options="{'no_create': True}"/> - - diff --git a/soong_workflow/wizard/soong_workflow_comment_wizard.py b/soong_workflow/wizard/soong_workflow_comment_wizard.py index e5f3e6bf7..4e8945188 100644 --- a/soong_workflow/wizard/soong_workflow_comment_wizard.py +++ b/soong_workflow/wizard/soong_workflow_comment_wizard.py @@ -43,9 +43,9 @@ class SoongWorkflowCommentWizard(models.TransientModel): ) employee_trans_domain_ids = fields.Many2many('hr.employee', 'employee_trans_domain_ids_rel', string="传阅人员", store=True) - + filter_personnel_ids = fields.Many2many('hr.employee', 'filter_personnel_rel', 'custom_id', 'employee_id', string="过滤人员", store=True) employee_ids = fields.Many2many('hr.employee', 'employee_ids_rel', 'custom_id', 'employee_id', string="传阅人员", store=True) - circulated_employee_ids = fields.Many2many('hr.employee', 'circulated_employee_rel', 'custom_id', 'employee_id', help='只可以看不可以评论,看过以后状态自动变为已阅', string="抄送/传阅人员", store=True) + circulated_employee_ids = fields.Many2many('hr.employee', 'circulated_employee_rel', 'custom_id', 'employee_id', help='只可以看不可以评论,看过以后状态自动变为已阅', string="加签人员", store=True) dep_manager_employee_ids = fields.Many2many('hr.employee', 'dep_manager_employee_rel', 'custom_id', 'employee_id', string="承办", store=True) add_employee_ids = fields.Many2many('hr.employee', 'add_employee_rel', 'custom_id', 'employee_id', string="加签人员", help='点击确认以后评论的人员', store=True) supervising_employee_ids = fields.Many2many('hr.employee', 'supervising_employee_rel', 'custom_id', 'employee_id', string="督办人员", store=True) diff --git a/soong_workflow/wizard/soong_workflow_comment_wizard_view.xml b/soong_workflow/wizard/soong_workflow_comment_wizard_view.xml index 513917e64..879a5c809 100644 --- a/soong_workflow/wizard/soong_workflow_comment_wizard_view.xml +++ b/soong_workflow/wizard/soong_workflow_comment_wizard_view.xml @@ -11,6 +11,7 @@ + @@ -34,7 +35,7 @@ - + @@ -48,7 +49,7 @@ - + @@ -58,7 +59,7 @@ - + @@ -94,7 +95,7 @@ - + @@ -108,7 +109,7 @@ - +