From b736eb18b293ea1c7c80e244b764e071793c2746 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=B9=8F=E5=AE=87?= Date: Mon, 25 Nov 2024 11:22:38 +0800 Subject: [PATCH 1/3] pengyuthon wechat --- yuthon_holiday/models/inherit_hr_leave.py | 10 ++++----- .../models/inherit_hr_leave_allocation.py | 21 +++++-------------- .../models/yuthon_hr_employee.py | 4 +++- .../views/yuthon_hr_employee_views.xml | 1 + 4 files changed, 14 insertions(+), 22 deletions(-) diff --git a/yuthon_holiday/models/inherit_hr_leave.py b/yuthon_holiday/models/inherit_hr_leave.py index f9955cabc..cac6da20a 100644 --- a/yuthon_holiday/models/inherit_hr_leave.py +++ b/yuthon_holiday/models/inherit_hr_leave.py @@ -62,11 +62,11 @@ class HolidaysRequestBatch(models.Model): leave_by_hour = fields.Boolean(string='按小时请假', default=True) leave_unit = fields.Selection(string='时长单位', selection=[('day', '天'), ('hour', '小时')]) - @api.constrains('leave_line_ids') - def _check_leave_line_ids(self): - for rec in self: - if rec.leave_line_ids.filtered(lambda line: line.leave_duration <= 0): - raise ValidationError('请假天数不能小于0') + # @api.constrains('leave_line_ids') + # def _check_leave_line_ids(self): + # for rec in self: + # if rec.leave_line_ids.filtered(lambda line: line.leave_duration <= 0): + # raise ValidationError('请假天数不能小于0') @api.onchange('leave_by_hour') def _onchange_leave_by_hour(self): diff --git a/yuthon_holiday/models/inherit_hr_leave_allocation.py b/yuthon_holiday/models/inherit_hr_leave_allocation.py index 9a3acc53d..1a7d53e91 100644 --- a/yuthon_holiday/models/inherit_hr_leave_allocation.py +++ b/yuthon_holiday/models/inherit_hr_leave_allocation.py @@ -55,16 +55,9 @@ class HrLeaveAllocation(models.Model): # {员工社保时间: 员工列表} emp_dict = {} # 员工根据社保时间创建字典 - for e in employees: - if '年' in e.social_insurance_time: - month_year = int(e.social_insurance_time[0]) * 12 - else: - month_year = 0 - if '月' in e.social_insurance_time: - month = int(e.social_insurance_time[-3]) - else: - month = 0 - key = month_year + month + for e in employees.search([('compute_month', '!=', 0)]): + # [XSK] TODO 使用实际字段 -2024/11/15 17:00 + key = e.compute_month if emp_dict.get(key): emp_dict[key].append(e) else: @@ -80,8 +73,7 @@ class HrLeaveAllocation(models.Model): if level.added_value_type == 'hour': level_month = level.added_value // (30 * 24) for emp_int, emp_list in emp_dict.items(): - if emp_int >= level_month: - # [XSK] TODO(2024/11/15): + if emp_int != 0 and emp_int >= level_month: # 应计方案内时间支持天月年,不支持小时 # 在请求类型中应该只支持小时 info_list = [{**item, 'number_of_days': level.start_count} for item in allocation._prepare_holiday_values(emp_list)] @@ -90,8 +82,5 @@ class HrLeaveAllocation(models.Model): else: super()._action_validate_create_childs() if allocation_vals: - self.env['hr.leave.allocation'].with_context( - mail_notify_force_send=False, - mail_activity_automation_skip=True - ).create(allocation_vals) + self.env['hr.leave.allocation'].with_context(mail_notify_force_send=False, mail_activity_automation_skip=True).create(allocation_vals) self.linked_request_ids.filtered(lambda c: c.state != 'validate').action_validate() diff --git a/yuthon_hr_employee/models/yuthon_hr_employee.py b/yuthon_hr_employee/models/yuthon_hr_employee.py index a8644db3b..cdc4b2ae7 100644 --- a/yuthon_hr_employee/models/yuthon_hr_employee.py +++ b/yuthon_hr_employee/models/yuthon_hr_employee.py @@ -65,6 +65,7 @@ class YuthonHrEmployee(models.Model): open_start_time = fields.Date(string="参加工作时间") social_insurance_date = fields.Date(string="缴纳社保日期") social_insurance_time = fields.Char(string="社保时长", compute='_compute_social_insurance_time', store=True) + compute_month = fields.Integer(string="社保时长假期") open_start_time_today = fields.Date(string="工作至今") interrupt_work_month = fields.Integer(string="中断工作月数") cumulative_work_month = fields.Integer(string="累计工作月数", compute='_compute_cumulative_work_month', store=True) @@ -167,7 +168,7 @@ class YuthonHrEmployee(models.Model): @api.depends('social_insurance_date') def _compute_cumulative_work_month(self): for record in self: - if record.social_insurance_time : + if record.social_insurance_time: today = datetime.now().date() if record.social_insurance_date: delta = relativedelta(today, record.social_insurance_date) @@ -179,6 +180,7 @@ class YuthonHrEmployee(models.Model): def _compute_social_insurance_time(self): for record in self: record.social_insurance_time = record.cumulative_work_month - record.interrupt_work_month + record.compute_month = record.cumulative_work_month - record.interrupt_work_month total_months = int(record.social_insurance_time) if total_months <= 0: record.social_insurance_time = "0个月" diff --git a/yuthon_hr_employee/views/yuthon_hr_employee_views.xml b/yuthon_hr_employee/views/yuthon_hr_employee_views.xml index 09a9c9cb1..6189a1e47 100644 --- a/yuthon_hr_employee/views/yuthon_hr_employee_views.xml +++ b/yuthon_hr_employee/views/yuthon_hr_employee_views.xml @@ -115,6 +115,7 @@ + From 696605924097ebc18e235cfe939c5e308408f60f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=B9=8F=E5=AE=87?= Date: Mon, 25 Nov 2024 11:29:44 +0800 Subject: [PATCH 2/3] pengyuthon wechat --- soong_workflow/models/soong_hr_employee.py | 3 +- soong_workflow/models/soong_workflow_mixin.py | 61 ++++++++++++------- .../views/soong_hr_employee_views.xml | 3 + .../wizard/soong_workflow_comment_wizard.py | 2 +- .../soong_workflow_comment_wizard_view.xml | 2 +- 5 files changed, 46 insertions(+), 25 deletions(-) diff --git a/soong_workflow/models/soong_hr_employee.py b/soong_workflow/models/soong_hr_employee.py index f66955899..2db4227c5 100644 --- a/soong_workflow/models/soong_hr_employee.py +++ b/soong_workflow/models/soong_hr_employee.py @@ -9,4 +9,5 @@ class YuthonHrEmployee(models.Model): _inherit = "hr.employee" user_role_id = fields.Many2one('soong.user.role', string="主角色", store=True) - user_role_ids = fields.Many2many('soong.user.role', string="辅助角色", store=True) \ No newline at end of file + user_role_ids = fields.Many2many('soong.user.role', string="辅助角色", store=True) + department_ids = fields.Many2many('hr.department', string="辅助部门", store=True) \ No newline at end of file diff --git a/soong_workflow/models/soong_workflow_mixin.py b/soong_workflow/models/soong_workflow_mixin.py index 6dce65db6..0390972c9 100644 --- a/soong_workflow/models/soong_workflow_mixin.py +++ b/soong_workflow/models/soong_workflow_mixin.py @@ -151,21 +151,29 @@ class SoongWorkflowMixin(models.AbstractModel): else: if btn_rec.name == '转交': # 如果有下一个节点,发消息通知。 - state_list = ['拟办' if i.node_name == 'start' else i.node_name for i in btn_rec.workflow_id.node_ids] + state_list = ['拟办' if i.node_name == 'start' else i.node_name for i in + btn_rec.workflow_id.node_ids] # 当前节点状态 self_state = state_list.index('拟办' if self.state == 'start' else self.state) # 下一个节点 - next_state = btn_rec.workflow_id.node_ids[self_state + 1].button_ids[1] + next_state = btn_rec.workflow_id.node_ids[self_state + 1].button_ids[0] # 不自动匹配 - employee_user_role_ids = self.env['hr.employee'].search([('user_role_id', '=', next_state.users_role_id.id)]) + employee_user_role_ids = self.env['hr.employee'].search( + ['|', ('user_role_id', '=', next_state.users_role_id.id), + ('user_role_ids', 'in', next_state.users_role_id.id)]) # 自动匹配 - employee_user_role_id = self.env['hr.employee'].search([('user_role_id', '=', next_state.users_role_id.id), - ('department_id', '=', self.department_id.id)]) + employee_user_role_id = self.env['hr.employee'].search( + [('user_role_id', '=', next_state.users_role_id.id), '|', + ('department_id', '=', self.department_id.id), + ('department_ids', 'in', self.department_id.id)]) employee_ids = employee_user_role_ids if not next_state.is_automatic else employee_user_role_id url = 'https://oa.thtzjt.com/mail/view?model={}&res_id={}'.format(self._name, self.id) for employee in employee_ids: - self.sudo().env["wecom.apps"].sync_send_message_textcard(category='oa', user_id=employee.wecom_userid, - title=self.name, description="您有新的审批单{}请及时处理".format(self.name), + self.sudo().env["wecom.apps"].sync_send_message_textcard(category='oa', + user_id=employee.wecom_userid, + title=self.name, + description="您有新的审批单{}请及时处理".format( + self.name), url=url, btntxt="详情") return btn_rec.with_context(cx).run() @@ -197,7 +205,8 @@ class SoongWorkflowMixin(models.AbstractModel): "default_res_model": self._name, "default_log_ids": logs.ids, "default_node_btn_id": btn_rec.id, - "default_node_link_len": '转交2' if len(btn_rec.node_id.out_link_ids) > 1 and btn_rec.name == '转交' else '', + "default_node_link_len": '转交2' if len( + btn_rec.node_id.out_link_ids) > 1 and btn_rec.name == '转交' else '', }, } # 下一个节点 @@ -211,10 +220,15 @@ class SoongWorkflowMixin(models.AbstractModel): 'record_id': self.id, }) # 不自动匹配 - employee_user_role_ids = self.env['hr.employee'].search([('user_role_id', '=', next_state.users_role_id.id)]) + employee_user_role_ids = self.env['hr.employee'].search( + ['|', ('user_role_id', '=', next_state.users_role_id.id), + ('user_role_ids', 'in', next_state.users_role_id.id)]) # 自动匹配 - employee_user_role_id = self.env['hr.employee'].search([('user_role_id', '=', next_state.users_role_id.id), - ('department_id', '=', self.department_id.id)]) + employee_user_role_id = self.env['hr.employee'].search( + [('user_role_id', '=', next_state.users_role_id.id), '|', + ('department_id', '=', self.department_id.id), + ('department_ids', 'in', self.department_id.id)]) + employee_ids = employee_user_role_ids.ids if not next_state.is_automatic else employee_user_role_id.ids if not employee_ids: state = btn_rec.workflow_id.node_ids[self_state + 1] @@ -236,23 +250,25 @@ class SoongWorkflowMixin(models.AbstractModel): "default_is_automatic": next_state.is_automatic, "default_employee_ids": employee_ids, "default_node_btn_id": btn_rec.id, - "default_node_link_len": '转交2' if len(btn_rec.node_id.out_link_ids) > 1 and btn_rec.name == '转交' else '', + "default_node_link_len": '转交2' if len( + btn_rec.node_id.out_link_ids) > 1 and btn_rec.name == '转交' else '', }, } @api.constrains("state") def _update_wkf_records(self): for rec in self: - record_obj = self.env["soong.workflow.record"].search([("res_model", "=", rec._name), ("res_id", "=", rec.id)]) + record_obj = self.env["soong.workflow.record"].search( + [("res_model", "=", rec._name), ("res_id", "=", rec.id)]) current_user_id = self.env.user.id if not record_obj: record_obj = self.env["soong.workflow.record"].create({ - "res_model": rec._name, - "res_id": rec.id, - "workflow_id": rec.workflow_id.id, - "node_id": rec.node_id.id, - "users_ids": [(4, current_user_id)], - }) + "res_model": rec._name, + "res_id": rec.id, + "workflow_id": rec.workflow_id.id, + "node_id": rec.node_id.id, + "users_ids": [(4, current_user_id)], + }) record_obj.update({"workflow_id": rec.workflow_id.id, "node_id": rec.node_id.id, "users_ids": [(4, current_user_id)], @@ -322,17 +338,18 @@ class SoongWorkflowMixin(models.AbstractModel): state_list.append('end') else: state_list.append(state.name) - self_node_id = record.workflow_id.node_ids.search([('name', '=', self.state), ('workflow_id', '=', record.workflow_id.id)]) + self_node_id = record.workflow_id.node_ids.search( + [('name', '=', self.state), ('workflow_id', '=', record.workflow_id.id)]) transmitted = self_node_id.button_ids.search([('name', '=', '转交'), ('node_id', '=', self_node_id.id)])[0] if transmitted.btn_hide: if transmitted.review_type == 'user_role': user_ids_list = employee_id.search(['|', ('user_role_id', '=', transmitted.users_role_id.id), - ('user_role_ids', 'in', [transmitted.users_role_id.id])]).ids + ('user_role_ids', 'in', [transmitted.users_role_id.id])]).ids if self.env.user.employee_id.id in user_ids_list: raise UserError('当前节点不允许收回') else: state_index = state_list.index(self.state) - self.write({'state': state_list[state_index-1]}) + self.write({'state': state_list[state_index - 1]}) else: raise UserError('请配置节点角色') else: diff --git a/soong_workflow/views/soong_hr_employee_views.xml b/soong_workflow/views/soong_hr_employee_views.xml index 49a04e91f..d8fb4199e 100644 --- a/soong_workflow/views/soong_hr_employee_views.xml +++ b/soong_workflow/views/soong_hr_employee_views.xml @@ -9,6 +9,9 @@ + + + diff --git a/soong_workflow/wizard/soong_workflow_comment_wizard.py b/soong_workflow/wizard/soong_workflow_comment_wizard.py index a67635384..c8502cd3d 100644 --- a/soong_workflow/wizard/soong_workflow_comment_wizard.py +++ b/soong_workflow/wizard/soong_workflow_comment_wizard.py @@ -38,7 +38,7 @@ class SoongWorkflowCommentWizard(models.TransientModel): 'custom_id', 'employee_id', string="督办人员", store=True) - is_automatic = fields.Boolean('是否自动识别') + is_automatic = fields.Boolean('是否自动匹配') @api.onchange('record_id') def _onchange_record_id(self): diff --git a/soong_workflow/wizard/soong_workflow_comment_wizard_view.xml b/soong_workflow/wizard/soong_workflow_comment_wizard_view.xml index 5537c0705..234ceaadc 100644 --- a/soong_workflow/wizard/soong_workflow_comment_wizard_view.xml +++ b/soong_workflow/wizard/soong_workflow_comment_wizard_view.xml @@ -19,7 +19,7 @@ - + From fbfa1ee40cd8c1cc2957d09ae288cfc3de2dc4c2 Mon Sep 17 00:00:00 2001 From: zhouzhou <123@qq.com> Date: Mon, 25 Nov 2024 11:56:29 +0800 Subject: [PATCH 3/3] =?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_hr_employee.py | 41 ++++++++----------- yuthon_notice/models/yuthon_notice.py | 4 +- yuthon_notice/views/yuthon_notice_views.xml | 8 +++- yuthon_will_task/models/yuthon_will_task.py | 2 +- .../views/yuthon_will_task_views.xml | 16 ++++---- yuthon_work_brand/views/attendance_menu.xml | 23 +++++++---- 6 files changed, 49 insertions(+), 45 deletions(-) diff --git a/yuthon_hr_employee/models/yuthon_hr_employee.py b/yuthon_hr_employee/models/yuthon_hr_employee.py index cdc4b2ae7..74b56cf6c 100644 --- a/yuthon_hr_employee/models/yuthon_hr_employee.py +++ b/yuthon_hr_employee/models/yuthon_hr_employee.py @@ -68,7 +68,7 @@ class YuthonHrEmployee(models.Model): compute_month = fields.Integer(string="社保时长假期") open_start_time_today = fields.Date(string="工作至今") interrupt_work_month = fields.Integer(string="中断工作月数") - cumulative_work_month = fields.Integer(string="累计工作月数", compute='_compute_cumulative_work_month', store=True) + cumulative_work_month = fields.Integer(string="累计工作月数", compute='_compute_social_insurance_info', store=True) cumulative_work_years = fields.Char(string="累计工作年限", compute='_compute_cumulative_work_years', store=True) # 教育 high_degree = fields.Char(string="最高学历") @@ -165,34 +165,25 @@ class YuthonHrEmployee(models.Model): else: record.company_old = None - @api.depends('social_insurance_date') - def _compute_cumulative_work_month(self): + @api.depends('social_insurance_date', 'interrupt_work_month') + def _compute_social_insurance_info(self): for record in self: - if record.social_insurance_time: + cumulative_months = 0 + if record.social_insurance_date: today = datetime.now().date() - if record.social_insurance_date: - delta = relativedelta(today, record.social_insurance_date) - record.cumulative_work_month = delta.years * 12 + delta.months - else: - record.cumulative_work_month = 0 - - @api.depends('cumulative_work_month', 'interrupt_work_month') - def _compute_social_insurance_time(self): - for record in self: - record.social_insurance_time = record.cumulative_work_month - record.interrupt_work_month - record.compute_month = record.cumulative_work_month - record.interrupt_work_month - total_months = int(record.social_insurance_time) + delta = relativedelta(today, record.social_insurance_date) + cumulative_months = delta.years * 12 + delta.months + record.cumulative_work_month = cumulative_months + total_months = cumulative_months - record.interrupt_work_month + record.compute_month = total_months if total_months <= 0: - record.social_insurance_time = "0个月" - years = total_months // 12 - months = total_months % 12 - if years > 0: - result_str = f"{years}年" - if months > 0: - result_str += f"{months}个月" + social_insurance_time_str = "0个月" else: - result_str = f"{months}个月" - record.social_insurance_time = result_str + years = total_months // 12 + months = total_months % 12 + social_insurance_time_str = f"{years}年{months}个月" if years > 0 and months > 0 else ( + f"{years}年" if years > 0 else f"{months}个月") + record.social_insurance_time = social_insurance_time_str @api.depends('cumulative_work_month') def _compute_cumulative_work_years(self): diff --git a/yuthon_notice/models/yuthon_notice.py b/yuthon_notice/models/yuthon_notice.py index be80b09b7..f0d2a5074 100644 --- a/yuthon_notice/models/yuthon_notice.py +++ b/yuthon_notice/models/yuthon_notice.py @@ -16,7 +16,7 @@ class YuthonNotice(models.Model): department_id = fields.Many2one(related='users_id.employee_id.department_id', string="部门") yuthon_company = fields.Selection(related='users_id.employee_id.yuthon_company', string="公司") notice_type_id = fields.Many2one('yuthon.notice.type', string="类型") - create_date = fields.Date(string="发布日期") + create_date = fields.Date(string="发布日期", default=fields.Date.today()) start_date = fields.Date(string="生效日期", default=fields.Date.today()) end_date = fields.Date(string="终止日期") sequence = fields.Integer(string="顺序", default=1, compute='_compute_sequence') @@ -81,7 +81,7 @@ class YuthonNotice(models.Model): 'state': 'no', }) self.sudo().env["wecom.apps"].sync_send_message_textcard(category='notice', user_id=we_id, - title="通知公告", description=self.name, + title="通知公告", description=self.name+self.users_id.name, url=str, btntxt="详细信息") # partner_ids = self.sudo().env['res.users'].search([('id', 'in', employee_users_list)]).mapped('partner_id').ids # self.sudo().with_context(lang=self.env.lang)._message_auto_subscribe_notify(partner_ids, 'yuthon_notice.message_yuthon_confirm_users_data') diff --git a/yuthon_notice/views/yuthon_notice_views.xml b/yuthon_notice/views/yuthon_notice_views.xml index 3d4af6a6b..f49aa9f6b 100644 --- a/yuthon_notice/views/yuthon_notice_views.xml +++ b/yuthon_notice/views/yuthon_notice_views.xml @@ -33,15 +33,19 @@