diff --git a/soong_workflow/__manifest__.py b/soong_workflow/__manifest__.py index d4bc1fe3f..95badfff5 100644 --- a/soong_workflow/__manifest__.py +++ b/soong_workflow/__manifest__.py @@ -8,6 +8,7 @@ "depends": ["base", "crnd_web_diagram_plus", "hr"], "data": [ "data/soong_workflow_note_data.xml", + "data/soong_workflow_inspector_code.xml", "security/soong_workflow_security.xml", "security/ir.model.access.csv", "views/kklw_workflow_approval_views.xml", @@ -22,10 +23,13 @@ "views/soong_approval_group.xml", "views/trans_link_views.xml", "views/soong_workflow_entrust_views.xml", - "views/menuitem.xml", + "views/soong_workflow_inspector_views.xml", 'wizard/approval_notice_wizard_views.xml', "wizard/soong_workflow_comment_wizard_view.xml", "templates/soong_workflow_templates.xml", + + + "views/menuitem.xml", ], "installable": True, "auto_install": False, diff --git a/soong_workflow/data/other_data b/soong_workflow/data/other_data index 5ea092352..e69de29bb 100644 --- a/soong_workflow/data/other_data +++ b/soong_workflow/data/other_data @@ -1,2 +0,0 @@ -1. 预置审批分组 -2. 我的请求要开发 \ No newline at end of file diff --git a/soong_workflow/data/soong_workflow_inspector_code.xml b/soong_workflow/data/soong_workflow_inspector_code.xml new file mode 100644 index 000000000..3344fbd84 --- /dev/null +++ b/soong_workflow/data/soong_workflow_inspector_code.xml @@ -0,0 +1,9 @@ + + + + 督办编号 + inspector_code + IC%(y)s%(month)s%(day)s + 3 + + diff --git a/soong_workflow/models/__init__.py b/soong_workflow/models/__init__.py index 1cc856685..c4942f25e 100644 --- a/soong_workflow/models/__init__.py +++ b/soong_workflow/models/__init__.py @@ -14,3 +14,4 @@ from . import soong_workflow_log from . import soong_approval_group from . import trans_link from . import soong_workflow_entrust +from . import soong_workflow_inspector diff --git a/soong_workflow/models/soong_workflow_inspector.py b/soong_workflow/models/soong_workflow_inspector.py new file mode 100644 index 000000000..cffbcc373 --- /dev/null +++ b/soong_workflow/models/soong_workflow_inspector.py @@ -0,0 +1,62 @@ +# -*- coding: utf-8 -*- +import logging +import datetime +from odoo import models, fields, api, _, modules +from odoo.exceptions import ValidationError, UserError + + +class SoongWorkflowInspector(models.Model): + _name = "soong.workflow.inspector" + _description = "督查督办" + + name = fields.Char(string="督办主题") + start_data = fields.Date(string="开始日期") + end_data = fields.Date(string="结束日期") + code = fields.Char(string="督办编号", default=lambda self: self.env['ir.sequence'].next_by_code('inspector_code')) + department_id = fields.Many2one('hr.department', string="部门") + inspector_importance = fields.Selection([('normal', '正常'), ('urgent', '紧急')], string="重要程度") + inspector_html = fields.Html(string="督办内容") + inspector_text = fields.Text(string="督办要求") + document_id = fields.Binary(string="附件") + inspector_line_ids = fields.One2many('soong.workflow.inspector.line', 'workflow_inspector_id', string='任务进度') + inspector_line2_ids = fields.One2many('soong.workflow.inspector.line2', 'workflow_inspector_id', string='督办明细') + attachment_ids = fields.Many2many('ir.attachment', string='Attachments') + + +class SoongWorkflowInspectorLine(models.Model): + _name = "soong.workflow.inspector.line" + _description = "任务进度" + + workflow_inspector_id = fields.Many2one('soong.workflow.inspector', string="督办标题") + department_id = fields.Many2one('hr.department', string="部门") + task_text = fields.Text(string="内容") + end_data = fields.Date(string="截止日期") + task_state = fields.Selection([('no', '未办结'), ('ing', '进行中'), ('ed', '已超时'), ('done', '已办结')], string="状态") + employee_id = fields.Many2one('hr.employee', string="上级负责人") + + + # 办结 + def inspector_task_done(self): + pass + + # 任务下发 + def inspector_task_issued(self): + pass + + # 延期 + def long_end_data(self): + pass + + +class SoongWorkflowInspectorLine2(models.Model): + _name = "soong.workflow.inspector.line2" + _description = "督办事项明细" + + workflow_inspector_id = fields.Many2one('soong.workflow.inspector', string="督办事项") + department_id = fields.Many2one('hr.department', string="部门") + employee_id = fields.Many2one('hr.employee', string="部门负责人") + end_data = fields.Date(string="截止日期") + inspector_line_text = fields.Text(string="工作内容") + + + diff --git a/soong_workflow/models/soong_workflow_mixin.py b/soong_workflow/models/soong_workflow_mixin.py index 9f2a0e5a0..2d6314ca5 100644 --- a/soong_workflow/models/soong_workflow_mixin.py +++ b/soong_workflow/models/soong_workflow_mixin.py @@ -66,6 +66,7 @@ class SoongWorkflowMixin(models.AbstractModel): approval_users_ids = fields.One2many("soong.approval.users", "res_id", domain=lambda self: [('res_model', '=', self._name)], auto_join=True, string="审批明细") + approval_sign_ids = fields.Many2many('res.users', string="加签人员") @api.depends("state") def _compute_workflow_id(self): @@ -152,9 +153,11 @@ class SoongWorkflowMixin(models.AbstractModel): def _add_comment(self, logs, btn_rec): wizard = self.env.ref("soong_workflow.view_soong_workflow_comment_wizard") # 状态列表 - state_list = ['拟办' if i.node_name == 'start' else i.node_name for i in btn_rec.node_id.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[0] self.env['trans.link'].search([]).unlink() if btn_rec.name == '转交' and len(btn_rec.node_id.out_link_ids) > 1: for state in btn_rec.node_id.out_link_ids: @@ -172,6 +175,13 @@ class SoongWorkflowMixin(models.AbstractModel): 'link_type': 'return', '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_id = self.env['hr.employee'].search([('user_role_id', '=', next_state.users_role_id.id), + ('department_id', '=', self.department_id.id)]) + return { "name": _("评论"), "type": "ir.actions.act_window", @@ -184,6 +194,8 @@ class SoongWorkflowMixin(models.AbstractModel): "default_res_id": self.id, "default_res_model": self._name, "default_log_ids": logs.ids, + "default_is_automatic": next_state.is_automatic, + "default_employee_ids": employee_user_role_ids.ids if not next_state.is_automatic else employee_user_role_id.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 '', }, @@ -262,6 +274,7 @@ class SoongWorkflowMixin(models.AbstractModel): res = self._update_fields_view(view_type, res) # res = self._add_state_tree_view(view_type, res) res = self._add_soong_workflow_log(view_type, res, params) + res = self._load_sign_view(view_type, res) return res # 收回 @@ -564,10 +577,31 @@ class SoongWorkflowMixin(models.AbstractModel): res["arch"] = etree.tostring(arch, encoding="unicode").replace("\t", "") return res - def create_field_element(self, field_name): - field_el = etree.Element("field") - field_el.set("name", field_name) - return field_el + def _load_sign_view(self, view_type, res): + arch = etree.fromstring(res["arch"]) + if view_type == "form": + sheet_el = arch.xpath("//sheet") + if sheet_el: + sheet_el = sheet_el[0] + else: + sheet_el = etree.Element("sheet") + arch.insert(0, sheet_el) + notebook_el = sheet_el.xpath(".//notebook") + if notebook_el: + notebook_el = notebook_el[0] + else: + notebook_el = etree.Element("notebook") + sheet_el.append(notebook_el) + page_el = etree.Element("page") + page_el.set("string", "加签人员") # 设置页面标签 + # page_el.set("invisible", "1") # todo domain + field_m2m_el = etree.Element("field") + field_m2m_el.set("name", "approval_sign_ids") + field_m2m_el.set("widget", "many2many_tags") + page_el.append(field_m2m_el) + notebook_el.append(page_el) + res["arch"] = etree.tostring(arch, encoding="unicode").replace("\t", "") + return res def _update_fields_view(self, view_type, res): """ diff --git a/soong_workflow/models/soong_workflow_node.py b/soong_workflow/models/soong_workflow_node.py index edbf8d2a8..605712b95 100644 --- a/soong_workflow/models/soong_workflow_node.py +++ b/soong_workflow/models/soong_workflow_node.py @@ -127,6 +127,23 @@ class SoongWorkflowNode(models.Model): "action_type": "code", "code": "obj.action_withdraw()", },), + (0, 0, { + "name": _("加签"), + "workflow_id": val['workflow_id'], + "sequence": 3, + "action_type": "code", + "has_comment": True, + },), + (0, 0, { + "name": _("加签确认"), + "workflow_id": val['workflow_id'], + "sequence": 3, + "action_type": "code", + "btn_hide": True, + "review_type": 'expression', + # "reviewer_expression": "obj.action_withdraw()", # todo domain + "has_comment": True, + },), (0, 0, { "name": _("退回"), "workflow_id": val['workflow_id'], @@ -205,18 +222,13 @@ class SoongWorkflowNodeButton(models.Model): sequence = fields.Integer( string="Sequence", default=10, help="Arrange buttons by defining sequence." ) - is_highlight = fields.Boolean( - string="Is Highlighted", - default=True, - help="Control highlighting of the button if needs user attention..", - ) + is_highlight = fields.Boolean(string="Is Highlighted", default=True, + help="Control highlighting of the button if needs user attention..", ) has_icon = fields.Boolean( string="Has Icon", help="Enable it to add icon to the button." ) - icon = fields.Char( - string="Icon", - help="Enter icon name like: fa-print, it's recommended to use FontAwesome Icons.", - ) + icon = fields.Char(string="Icon", + help="Enter icon name like: fa-print, it's recommended to use FontAwesome Icons.", ) has_comment = fields.Boolean(string="评论", default=False) btn_key = fields.Char(string="Button Key", default=_generate_key) btn_hide = fields.Boolean( @@ -279,6 +291,7 @@ class SoongWorkflowNodeButton(models.Model): required=True, ondelete="cascade", ) + is_automatic = fields.Boolean('是否自动匹配', default=True) @api.onchange("node_id") def change_workflow(self): @@ -382,8 +395,7 @@ class SoongWorkflowNodeButton(models.Model): user_ids += user_role_id.ids # 发送信息提醒 partner_ids = self.sudo().env['res.users'].search([('id', 'in', user_ids)]).mapped('partner_id').ids - self.sudo().with_context(lang=self.env.lang)._message_auto_subscribe_notify(partner_ids, - 'soong_workflow.message_yuthon_workflow_btn_approval_data') + self.sudo().with_context(lang=self.env.lang)._message_auto_subscribe_notify(partner_ids, 'soong_workflow.message_yuthon_workflow_btn_approval_data') except Exception as e: pass return func_result diff --git a/soong_workflow/security/ir.model.access.csv b/soong_workflow/security/ir.model.access.csv index fc11f8e25..c318a7c27 100644 --- a/soong_workflow/security/ir.model.access.csv +++ b/soong_workflow/security/ir.model.access.csv @@ -26,4 +26,8 @@ access_soong_workflow_log_user,soong_workflow_log_user,model_soong_workflow_log, access_soong_workflow_comment_wizard_user,soong_workflow_comment_wizard_user,model_soong_workflow_comment_wizard,soong_workflow.group_soong_workflow_user,1,1,1,1 access_trans_link,trans_link,model_trans_link,soong_workflow.group_soong_workflow_user,1,1,1,1 access_soong_workflow_entrust,soong_workflow_entrust,model_soong_workflow_entrust,soong_workflow.group_soong_workflow_user,1,1,1,1 -access_entrust_all,entrust_all,model_entrust_all,soong_workflow.group_soong_workflow_user,1,1,1,1 \ No newline at end of file +access_entrust_all,entrust_all,model_entrust_all,soong_workflow.group_soong_workflow_user,1,1,1,1 + +access_soong_workflow_inspector,soong_workflow_inspector,model_soong_workflow_inspector,soong_workflow.group_soong_workflow_user,1,1,1,1 +access_soong_workflow_inspector_line,soong_workflow_inspector_line,model_soong_workflow_inspector_line,soong_workflow.group_soong_workflow_user,1,1,1,1 +access_soong_workflow_inspector_line2,soong_workflow_inspector_line2,model_soong_workflow_inspector_line2,soong_workflow.group_soong_workflow_user,1,1,1,1 \ No newline at end of file diff --git a/soong_workflow/views/menuitem.xml b/soong_workflow/views/menuitem.xml index 62f1103dc..a108c08eb 100644 --- a/soong_workflow/views/menuitem.xml +++ b/soong_workflow/views/menuitem.xml @@ -34,6 +34,34 @@ action="soong_workflow_entrust_action" parent="menu_soong_workflow_root"/> + + + + + + + + + + + + + soong.workflow.inspector.tree + soong.workflow.inspector + + + + + + + + + + + + + + soong.workflow.inspector.form + soong.workflow.inspector + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + 督查督办 + soong.workflow.inspector + tree,form + + + + + soong.workflow.inspector.line.tree + soong.workflow.inspector.line + + + + + + + + +