From 27649e4ed702909ec4bf36ca8e9b7ef29b470aaa 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: Wed, 29 Apr 2026 11:49:02 +0800 Subject: [PATCH 1/5] =?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_shift_planning.py | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/yuthon_hr_attendance/models/yuthon_shift_planning.py b/yuthon_hr_attendance/models/yuthon_shift_planning.py index 52db6b490..2994ef74a 100644 --- a/yuthon_hr_attendance/models/yuthon_shift_planning.py +++ b/yuthon_hr_attendance/models/yuthon_shift_planning.py @@ -183,6 +183,47 @@ class YuthonShiftPlanning(models.Model): current_month = datetime.now().month return str(current_month) # 返回字符串类型的月份 + @api.onchange( + 'planning_a_ids', + 'planning_b_ids', + 'planning_c_ids', + 'planning_ever_white_ids', + 'planning_ever_noon_ids' + ) + def _onchange_sync_lianan_role_employees(self): + lianan_role = self.env['planning.role'].search([('name', '=', '联安粮库')], limit=1) + target_employees = self.env['hr.employee'] + # A组 + for line in self.planning_a_ids: + if line.employee_id: + target_employees |= line.employee_id + # B组 + for line in self.planning_b_ids: + if line.employee_id: + target_employees |= line.employee_id + # C组 + for line in self.planning_c_ids: + if line.employee_id: + target_employees |= line.employee_id + # 常白班 + for line in self.planning_ever_white_ids: + if line.employee_id: + target_employees |= line.employee_id + # 常中班 + for line in self.planning_ever_noon_ids: + if line.employee_id: + target_employees |= line.employee_id + + target_resources = self.env['resource.resource'] + if target_employees: + target_resources = self.env['resource.resource'].search([ + ('id', 'in', target_employees.mapped('resource_id').ids) + ]) + + lianan_role.write({ + 'resource_ids': [(5, 0, 0)] + [(4, res_id, 0) for res_id in target_resources.ids] + }) + class YuthonShiftPlanningALine(models.Model): _name = 'yuthon.shift.planning.a.line' _description = '排班安排A组' From 59668aa56c0e826850bc756d21e92ed5750b64c0 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: Wed, 29 Apr 2026 15:02:45 +0800 Subject: [PATCH 2/5] =?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 --- .../wizard/property_reconciliation_wizard.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yuthon_property_approval/wizard/property_reconciliation_wizard.py b/yuthon_property_approval/wizard/property_reconciliation_wizard.py index f002c4efb..d7eaffbfc 100644 --- a/yuthon_property_approval/wizard/property_reconciliation_wizard.py +++ b/yuthon_property_approval/wizard/property_reconciliation_wizard.py @@ -394,7 +394,7 @@ class PropertyReconciliationWizard(models.Model): final_remark = line.remake if line.collection_type != 'penalty': receivable.delivered1 = receivable.delivered1 + line.amount - if receivable.original_amount == round(receivable.delivered1, 2) + line.amount + round(receivable.discount_amount, 2) : + if receivable.original_amount == round(receivable.delivered1, 2) + round(receivable.discount_amount, 2) : deposit_state = 'paid' else: deposit_state = 'no_paid' From 6aa11b282ec03ae2d2e0c02a12aca2420091ef4c 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: Wed, 29 Apr 2026 15:35:17 +0800 Subject: [PATCH 3/5] =?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 --- .../wizard/soong_workflow_comment_wizard.py | 65 ++++++++++++------- 1 file changed, 43 insertions(+), 22 deletions(-) diff --git a/soong_workflow/wizard/soong_workflow_comment_wizard.py b/soong_workflow/wizard/soong_workflow_comment_wizard.py index ae59dd19d..cfa2a3f89 100644 --- a/soong_workflow/wizard/soong_workflow_comment_wizard.py +++ b/soong_workflow/wizard/soong_workflow_comment_wizard.py @@ -39,7 +39,7 @@ class SoongWorkflowCommentWizard(models.TransientModel): return_link_id = fields.Many2one('trans.link', string='退回节点', ondelete='set null') invalid_link_ids = fields.Many2many( 'trans.link', - string='跳过相同人员', + string='跳过相同人员以及无审批人员', compute='_compute_invalid_link_ids', help='跳过相同人员的节点' ) @@ -170,37 +170,58 @@ class SoongWorkflowCommentWizard(models.TransientModel): all_links = self.env['trans.link'].browse(ctx_links) if isinstance(ctx_links, (list, tuple)) else ctx_links record_id = self.env[record.res_model].browse(record.res_id) if record.res_model and record.res_id else None current_link = record.trans_link_id + if current_link and all_links: sorted_all_links = all_links.sorted('sequence') for idx, link in enumerate(sorted_all_links): approvers = self._get_approvers_for_link(link, record_id) - # 如果当前审批人是 1 个人,才判断跳过 - if len(approvers) == 1: + + # ====================== 逻辑1:跳过无审批人的节点 + if link.id == current_link.id and link.sequence == current_link.sequence: + # 获取已审批人员 + log_records = record_id.log_ids + approved_users = log_records.filtered( + lambda log: log.node_btn_name != '1' and log.done_by).mapped('done_by.employee_ids') + approved_employee_ids = approved_users.ids + employee_ids = approvers.ids + + # 多人审批:全部审批完成则自动切换到下一个节点 + if len(approvers) > 1: + is_all_included = all(emp_id in approved_employee_ids for emp_id in employee_ids) + if is_all_included: + if idx + 1 < len(sorted_all_links): + # 这里必须用 record 而不是 self! + record.trans_link_id = sorted_all_links[idx + 1] + invalid_links |= current_link + break + + # ====================== 逻辑2:单人审批 → 按规则跳过同审批人节点 ====================== + if len(approvers) == 1 and record_id: current_approver = approvers[0] - # 跳过规则 next:跳过【下一个】节点 + # 查找对应节点配置 node_id = record_id.workflow_id.node_ids.search([ ('name', '=', link.name), ('workflow_id', '=', record_id.workflow_id.id) - ]) - if node_id.same_user_skip_type == 'next': - # 有下一个节点 - if idx + 1 < len(sorted_all_links): - next_link = sorted_all_links[idx + 1] - next_approvers = self._get_approvers_for_link(next_link, record_id) - # 下一个节点也是 1 个人,且和当前是同一个 - if len(next_approvers) == 1 and next_approvers[0] == current_approver: - invalid_links |= next_link # 下一个节点无效(跳过) + ], limit=1) # 加 limit=1 更严谨 - # 跳过规则 prev:跳过【上一个】节点 - if node_id.same_user_skip_type == 'prev': - # 有上一个节点 - if idx - 1 >= 0: - prev_link = sorted_all_links[idx - 1] - prev_approvers = self._get_approvers_for_link(prev_link, record_id) - # 上一个节点也是 1 个人,且和当前是同一个 - if len(prev_approvers) == 1 and prev_approvers[0] == current_approver: - invalid_links |= prev_link + if node_id: + # 跳过规则:next → 跳过【下一个】同审批人节点 + if node_id.same_user_skip_type == 'next': + if idx + 1 < len(sorted_all_links): + next_link = sorted_all_links[idx + 1] + next_approvers = self._get_approvers_for_link(next_link, record_id) + if len(next_approvers) == 1 and next_approvers[0] == current_approver: + invalid_links |= next_link + # 跳过规则:prev → 跳过【上一个】同审批人节点 + if node_id.same_user_skip_type == 'prev': + if idx - 1 >= 0: + prev_link = sorted_all_links[idx - 1] + prev_approvers = self._get_approvers_for_link(prev_link, record_id) + if len(prev_approvers) == 1 and prev_approvers[0] == current_approver: + invalid_links |= prev_link + + # 最终赋值 record.invalid_link_ids = invalid_links @api.onchange('trans_link_id') From f6352f7d8263d7dbff5fe8a04e2ef1ca64fa32c8 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: Wed, 29 Apr 2026 15:36:08 +0800 Subject: [PATCH 4/5] =?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/wizard/soong_workflow_comment_wizard.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/soong_workflow/wizard/soong_workflow_comment_wizard.py b/soong_workflow/wizard/soong_workflow_comment_wizard.py index cfa2a3f89..d579b1814 100644 --- a/soong_workflow/wizard/soong_workflow_comment_wizard.py +++ b/soong_workflow/wizard/soong_workflow_comment_wizard.py @@ -185,12 +185,10 @@ class SoongWorkflowCommentWizard(models.TransientModel): approved_employee_ids = approved_users.ids employee_ids = approvers.ids - # 多人审批:全部审批完成则自动切换到下一个节点 if len(approvers) > 1: is_all_included = all(emp_id in approved_employee_ids for emp_id in employee_ids) if is_all_included: if idx + 1 < len(sorted_all_links): - # 这里必须用 record 而不是 self! record.trans_link_id = sorted_all_links[idx + 1] invalid_links |= current_link break From 785a9f498b3d686a61e3bc19e968b5eb745ad707 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: Wed, 29 Apr 2026 15:40:58 +0800 Subject: [PATCH 5/5] =?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 --- .../wizard/soong_workflow_comment_wizard.py | 61 +++++++------------ 1 file changed, 21 insertions(+), 40 deletions(-) diff --git a/soong_workflow/wizard/soong_workflow_comment_wizard.py b/soong_workflow/wizard/soong_workflow_comment_wizard.py index d579b1814..9079201d0 100644 --- a/soong_workflow/wizard/soong_workflow_comment_wizard.py +++ b/soong_workflow/wizard/soong_workflow_comment_wizard.py @@ -170,56 +170,37 @@ class SoongWorkflowCommentWizard(models.TransientModel): all_links = self.env['trans.link'].browse(ctx_links) if isinstance(ctx_links, (list, tuple)) else ctx_links record_id = self.env[record.res_model].browse(record.res_id) if record.res_model and record.res_id else None current_link = record.trans_link_id - if current_link and all_links: sorted_all_links = all_links.sorted('sequence') for idx, link in enumerate(sorted_all_links): approvers = self._get_approvers_for_link(link, record_id) - - # ====================== 逻辑1:跳过无审批人的节点 - if link.id == current_link.id and link.sequence == current_link.sequence: - # 获取已审批人员 - log_records = record_id.log_ids - approved_users = log_records.filtered( - lambda log: log.node_btn_name != '1' and log.done_by).mapped('done_by.employee_ids') - approved_employee_ids = approved_users.ids - employee_ids = approvers.ids - - if len(approvers) > 1: - is_all_included = all(emp_id in approved_employee_ids for emp_id in employee_ids) - if is_all_included: - if idx + 1 < len(sorted_all_links): - record.trans_link_id = sorted_all_links[idx + 1] - invalid_links |= current_link - break - - # ====================== 逻辑2:单人审批 → 按规则跳过同审批人节点 ====================== - if len(approvers) == 1 and record_id: + # 如果当前审批人是 1 个人,才判断跳过 + if len(approvers) == 1: current_approver = approvers[0] - # 查找对应节点配置 + # 跳过规则 next:跳过【下一个】节点 node_id = record_id.workflow_id.node_ids.search([ ('name', '=', link.name), ('workflow_id', '=', record_id.workflow_id.id) - ], limit=1) # 加 limit=1 更严谨 + ]) + if node_id.same_user_skip_type == 'next': + # 有下一个节点 + if idx + 1 < len(sorted_all_links): + next_link = sorted_all_links[idx + 1] + next_approvers = self._get_approvers_for_link(next_link, record_id) + # 下一个节点也是 1 个人,且和当前是同一个 + if len(next_approvers) == 1 and next_approvers[0] == current_approver: + invalid_links |= next_link # 下一个节点无效(跳过) - if node_id: - # 跳过规则:next → 跳过【下一个】同审批人节点 - if node_id.same_user_skip_type == 'next': - if idx + 1 < len(sorted_all_links): - next_link = sorted_all_links[idx + 1] - next_approvers = self._get_approvers_for_link(next_link, record_id) - if len(next_approvers) == 1 and next_approvers[0] == current_approver: - invalid_links |= next_link + # 跳过规则 prev:跳过【上一个】节点 + if node_id.same_user_skip_type == 'prev': + # 有上一个节点 + if idx - 1 >= 0: + prev_link = sorted_all_links[idx - 1] + prev_approvers = self._get_approvers_for_link(prev_link, record_id) + # 上一个节点也是 1 个人,且和当前是同一个 + if len(prev_approvers) == 1 and prev_approvers[0] == current_approver: + invalid_links |= prev_link - # 跳过规则:prev → 跳过【上一个】同审批人节点 - if node_id.same_user_skip_type == 'prev': - if idx - 1 >= 0: - prev_link = sorted_all_links[idx - 1] - prev_approvers = self._get_approvers_for_link(prev_link, record_id) - if len(prev_approvers) == 1 and prev_approvers[0] == current_approver: - invalid_links |= prev_link - - # 最终赋值 record.invalid_link_ids = invalid_links @api.onchange('trans_link_id')