Merge pull request !556 from 李鹏宇/dev
This commit is contained in:
李鹏宇
2024-11-25 04:02:46 +00:00
committed by Gitee
14 changed files with 107 additions and 90 deletions
+2 -1
View File
@@ -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)
user_role_ids = fields.Many2many('soong.user.role', string="辅助角色", store=True)
department_ids = fields.Many2many('hr.department', string="辅助部门", store=True)
+39 -22
View File
@@ -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:
@@ -9,6 +9,9 @@
<field name="user_role_id"/>
<field name="user_role_ids" widget="many2many_tags"/>
</xpath>
<xpath expr="//field[@name='department_id']" position="after">
<field name="department_ids" widget="many2many_tags"/>
</xpath>
</field>
</record>
<record id="view_employee_inherit_tree_soong" model="ir.ui.view">
@@ -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):
@@ -19,7 +19,7 @@
<!-- 转交人员 -->
<field name="trans_link_id" invisible="not node_link_len" string="转交节点"/>
<field name="comment_note_id"/>
<field name="employee_ids" widget="many2many_tags" string="人员范围" invisible="is_automatic"/>
<field name="employee_ids" widget="many2many_tags" string="人员范围"/>
</group>
<group string="流程选择" invisible="node_btn_name != '分发'">
<field name="comment_note_id"/>
+5 -5
View File
@@ -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):
@@ -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()
+17 -24
View File
@@ -65,9 +65,10 @@ 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)
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="最高学历")
@@ -164,33 +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
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):
@@ -115,6 +115,7 @@
<field name="open_start_time"/>
<field name="open_start_time_today"/>
<field name="social_insurance_date"/>
<field name="compute_month" invisible="1"/>
<field name="social_insurance_time"/>
<field name="interrupt_work_month"/>
<field name="cumulative_work_month"/>
+2 -2
View File
@@ -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')
+6 -2
View File
@@ -33,15 +33,19 @@
<button name="notice_publish" string="发布" type="object" class="btn-primary"/>
</header>
<sheet>
<group col="2">
<group col="4">
<group>
<field name="notice_type_id" required="1"/>
</group>
<group>
<field name="users_id" required="1"/>
</group>
<group>
<field name="yuthon_company" string="发布公司"/>
</group>
<group>
<field name="department_id" string="发布部门" invisible="1"/>
<field name="create_date"/>
<field name="users_id" required="1"/>
</group>
<group>
<field name="is_notice_roger" invisible="1"/>
+1 -1
View File
@@ -43,7 +43,7 @@ class YuthonWillTask(models.Model):
raise UserError("请同步{}的企业微信".format(employee_id.name))
url = "https://oa.thtzjt.com/mail/view?model={}&res_id={}".format(self._name, self.id)
self.sudo().env["wecom.apps"].sync_send_message_textcard(category='task', user_id=employee_id.wecom_userid,
title="待办事项提醒", description="请注意你的待办事项" + self.task_content,
title="待办事项提醒", description=self.task_content,
url=url, btntxt="详细信息")
def button_add_comment(self):
@@ -4,7 +4,7 @@
<field name='name'>yuthon.will.task.tree</field>
<field name='model'>yuthon.will.task</field>
<field name='arch' type='xml'>
<tree string='待办任务' editable="bottom"
<tree string='日程' editable="bottom"
decoration-danger="priority == 'very_urgent'"
decoration-info="priority == 'urgent'"
decoration-success="priority == 'important'">
@@ -25,7 +25,7 @@
<field name='name'>yuthon.will.task.search</field>
<field name='model'>yuthon.will.task</field>
<field name='arch' type='xml'>
<search string='待办任务'>
<search string='日程'>
<field name="task_content"/>
<filter name="next_seven_days" string="周内事项" domain="[('start_time', '>=', context_today()),
('start_time', '&lt;=', context_today() + relativedelta(days=7))]"/>
@@ -38,7 +38,7 @@
<field name="name">yuthon.will.task.form</field>
<field name="model">yuthon.will.task</field>
<field name="arch" type="xml">
<form string="待办任务">
<form string="日程">
<sheet>
<group>
<group>
@@ -64,7 +64,7 @@
<field name="model">yuthon.will.task</field>
<field name="priority" eval="2"/>
<field name="arch" type="xml">
<calendar string="待办事项"
<calendar string="日程"
date_start="start_time"
date_stop="end_time"
event_open_popup="true"
@@ -78,17 +78,17 @@
</field>
</record>
<record id='view_yuthon_will_task_action' model='ir.actions.act_window'>
<field name='name'>待办任务</field>
<field name='name'>日程</field>
<field name='res_model'>yuthon.will.task</field>
<field name='view_mode'>tree,calendar</field>
<field name="context">{'search_default_next_seven_days': 1}</field>
</record>
<menuitem id='menu_yuthon_will_task'
name='待办'
name='日程'
web_icon="yuthon_will_task,static/description/icon.png"
sequence='1'/>
<menuitem id='menu_yuthon_will_task_root'
name='待办任务'
name='日程任务'
parent='menu_yuthon_will_task'
action='view_yuthon_will_task_action'
sequence='1'/>
@@ -97,7 +97,7 @@
parent="menu_yuthon_will_task"
sequence="1"/>
<menuitem id="task_type_setting_menu"
name="任务类型设置"
name="任务类型"
parent="task_type_menu"
action="view_task_type_setting_action"
sequence="5"/>
+16 -7
View File
@@ -82,16 +82,25 @@
parent="menu_hr_attendance_duty_summary_menu_board"
action="yuthon_hr_attendance.yuthon_duty_summary_wizard_action"
sequence="5"/>
<menuitem id="menu_adjustments_approval_board"
name="值班调休申请"
parent="menu_hr_attendance_duty_summary_menu_board"
sequence="7"
action="yuthon_hr_attendance.view_yuthon_adjustments_approval_action"/>
<menuitem id="menu_yuthon_duty_setting_board"
<menuitem id="menu_yuthon_duty_shows_board"
name="值班说明"
parent="menu_hr_attendance_duty_summary_menu_board"
sequence="9"
sequence="7"
action="yuthon_hr_attendance.action_yuthon_duty_setting"/>
<menuitem id="menu_hr_attendance_duty_summary_flow_board"
name="流程"
parent="menu_hr_attendance_duty_summary_menu_board"
sequence="9"/>
<menuitem id="menu_adjustments_approval_board"
name="值班调休申请"
parent="menu_hr_attendance_duty_summary_flow_board"
sequence="1"
action="yuthon_hr_attendance.view_yuthon_adjustments_approval_action"/>
<menuitem id="menu_yuthon_abnormal_approval_board"
name="值班异常申请"
parent="menu_hr_attendance_duty_summary_flow_board"
sequence="3"
action="yuthon_hr_attendance.view_yuthon_abnormal_approval_action"/>
<!-- 计划相关 -->
<menuitem id="menu_hr_attendance_approval_request_board"
name="流程"