This commit is contained in:
pengyuthon
2026-01-07 01:07:20 +08:00
parent 05b06fdf81
commit 40eef70bff
9 changed files with 136 additions and 150 deletions
+1 -1
View File
@@ -82,7 +82,7 @@ class SoongWorkflowLog2(models.Model):
sequence = fields.Integer(string="序号", compute="_compute_sequence")
done_by = fields.Many2one(comodel_name="res.users", string="审批人")
name = fields.Char(string="节点名称", compute="_compute_name", store=True)
approval_state = fields.Selection([('0', '未读'), ('1', '已读')], string='状态', default='0')
approval_state = fields.Selection([('0', '待办理'), ('1', '办理中'), ('2', '已办结')], string='状态', default='0')
document_ids = fields.Many2many('ir.attachment', string="附件")
lase_click_date = fields.Datetime(string="操作时间")
commit = fields.Char(string="意见")
+40 -15
View File
@@ -81,11 +81,9 @@ class SoongWorkflowMixin(models.AbstractModel):
domain=lambda self: [('res_model', '=', self._name)], auto_join=True,
string="审批明细")
approval_sign_ids = fields.Many2many('res.users', store=False, compute="_compute_approval_sign_ids", string="加签人员")
is_back = fields.Boolean(
string='是否允许收回',
compute='_compute_is_back',
store=False,
)
is_back = fields.Boolean(string='是否允许收回', compute='_compute_is_back', store=False,)
is_confirm = fields.Boolean(string="未确认", compute='_compute_is_confirm', store=False,)
is_end = fields.Boolean(string="未结束", compute='_compute_is_confirm', store=False,)
def _compute_is_back(self):
for record in self:
@@ -97,6 +95,22 @@ class SoongWorkflowMixin(models.AbstractModel):
if matched_logs and all(log.approval_state == '0' for log in matched_logs):
record.is_back = True
def _compute_is_confirm(self):
for record in self:
record.is_confirm = True
record.is_end = True
domain = [('done_by', '=', self.env.user.id), ('workflow_id', '=', record.workflow_id.id),
('res_id', '=', record.id), ('approval_state', 'in', ['0', '1'])]
lg2 = record.log_ids2.search(domain)
lg1 = record.log_ids.search(domain)
if lg2:
record.is_confirm = False
if lg1:
record.is_end = False
@api.depends("node_id", "log_ids")
def _compute_approval_sign_ids(self):
for record in self:
@@ -819,18 +833,21 @@ class SoongWorkflowMixin(models.AbstractModel):
domain = eval(button.invisible_expression)
btn_invisible = self.sudo().env[button.workflow_id.model_id.model].search(domain).ids
invisible += " or id not in {0} ".format(str(btn_invisible))
# 如果是加签确认
# if is_apostille:
# id_el = etree.Element("field")
# id_el.set("name", "approval_sign_ids")
# id_el.set("invisible", "1")
# invisible += " or uid not in approval_sign_ids"
if button.name in ["退回", "结束"]:
if button.name == '确认':
id_el = etree.Element("field")
id_el.set("name", "log_ids")
id_el.set("invisible", "1")
invisible += " or not log_ids or is_confirm"
if button.name == '结束':
id_el = etree.Element("field")
id_el.set("name", "log_ids")
id_el.set("invisible", "1")
invisible += " or not log_ids or is_end"
if button.name == "退回":
id_el = etree.Element("field")
id_el.set("name", "log_ids")
id_el.set("invisible", "1")
invisible += " or not log_ids "
if button.name == "分发":
invisible += " or is_send"
if button.name == "收回":
@@ -839,10 +856,8 @@ class SoongWorkflowMixin(models.AbstractModel):
id_el.set("invisible", "1")
invisible += " or not log_ids or not is_back"
invisible += " or work_end"
if model == 'purchase.order':
invisible = invisible.replace("询价", "draft")
btn_exec_action_el.set("invisible", invisible)
btn_exec_action_el.set("context", "{'btn_key':'%s','active_model':'%s'}" % (button.btn_key, self._name),)
res["arch"] = etree.tostring(arch, encoding="unicode").replace("\t", "")
@@ -902,6 +917,16 @@ class SoongWorkflowMixin(models.AbstractModel):
header_el = arch.xpath("//form/header")
header_el = header_el[0] if header_el else False
# Create State Element If not Exists
end_el = etree.Element("field")
end_el.set("name", "is_end")
end_el.set("invisible", "1")
header_el.append(end_el)
confirm_el = etree.Element("field")
confirm_el.set("name", "is_confirm")
confirm_el.set("invisible", "1")
header_el.append(end_el)
if header_el is not False:
state_el = etree.Element("field")
state_el.set("name", "state")
@@ -87,6 +87,7 @@ class SoongWorkflowNode(models.Model):
is_apostille = fields.Boolean(string="加签", default=False)
employee_ids = fields.Many2many('hr.employee', string='抄送/传阅人员')
is_end = fields.Boolean(string="结束", default=False)
is_confirm = fields.Boolean(string="确认", default=False)
department_id = fields.Many2many('hr.department', string='部门转入范围')
comment_id = fields.Many2one('soong.note', string="固定意见")
approval_concatenation = fields.Selection([('chuan', '串申'), ('bing', '并申')], string="审批形式", default="bing",
@@ -148,6 +149,31 @@ class SoongWorkflowNode(models.Model):
remove_ids = record.button_ids.filtered(lambda r: r.name in ["结束"])
record.button_ids = [(3, remove_id.id) for remove_id in remove_ids]
@api.onchange("is_confirm")
def onchange_is_confirm(self):
for record in self:
if record.is_confirm:
record.use_custom_colors = True
sequence = max([r.sequence for r in record.button_ids] if record.button_ids else [1])
record.button_ids = [
(0, 0, {
"name": _("确认"),
# "workflow_id": record.workflow_id.ids[0] if record.workflow_id.ids else None,
"node_id": record.id,
"sequence": sequence + 1,
"action_type": "confirm",
"btn_hide": False, # 对所有人显示
"has_comment": False, # 对所有人显示
"review_type": "confirm",
}),
]
else:
record.use_custom_colors = True
record.bg_color = DEFAULT_BG_COLOR
record.res_bg_color = DEFAULT_BG_COLOR
remove_ids = record.button_ids.filtered(lambda r: r.name in ["确认"])
record.button_ids = [(3, remove_id.id) for remove_id in remove_ids]
def btn_role_sync(self):
for record in self:
now_btn = record.button_ids.filtered(lambda r: r.name in ["转交"])
@@ -344,6 +370,7 @@ class SoongWorkflowNodeButton(models.Model):
# ('invisible', '隐藏条件'),
('apostille', '加签确认'),
('end', "结束"),
('confirm', "确认"),
('withdraw', '收回'),
],
)
@@ -377,6 +404,7 @@ class SoongWorkflowNodeButton(models.Model):
("win_act", "Window Action"),
("apostille", "加签按钮"),
('end', "结束"),
('confirm', "确认"),
],
string="Action Type",
default="link",
@@ -43,16 +43,6 @@
</tree>
</field>
</page>
<!-- <page string="加签记录" invisible="not log_ids3">-->
<!-- <field name="log_ids3" style="width:100%; margin-top: 10px;">-->
<!-- <tree editable="bottom">-->
<!-- <field name="done_by" string=""/>-->
<!-- <field name="name" string=""/>-->
<!-- <field name="approval_state" string=""/>-->
<!-- <field name="lase_click_date" string=""/>-->
<!-- </tree>-->
<!-- </field>-->
<!-- </page>-->
<page string="关联流程" invisible="not soong_record_ids">
<field name="soong_record_ids" style="width:100%; margin-top: 10px;">
<tree edit="true" delete="False" editable="bottom" type="object">
@@ -82,8 +72,7 @@
<notebook>
<page string="审批详情">
<field name="log_ids" style="width:100%%; margin-top: 10px;" domain="[('node_btn_name', '!=', '1')]" mode="kanban,tree" context="{'kanban_view_ref':'soong_workflow.soong_workflow_log_kanban'}">
<tree create="false" edit="false" delete="false" editable="bottom"
decoration-danger="node_btn_name == '1'">
<tree create="false" edit="false" delete="false" editable="bottom" decoration-danger="node_btn_name == '1'">
<field name="sequence" string="" column_invisible="1"/>
<field name="name" string="" readonly="0"/>
<field name="comment" string=""/>
@@ -107,16 +96,6 @@
</tree>
</field>
</page>
<!-- <page string="加签记录" invisible="not log_ids3">-->
<!-- <field name="log_ids3" style="width:100%%; margin-top: 10px;">-->
<!-- <tree create="false" edit="false" delete="false" editable="bottom">-->
<!-- <field name="done_by" string=""/>-->
<!-- <field name="name" string=""/>-->
<!-- <field name="approval_state" string=""/>-->
<!-- <field name="lase_click_date" string=""/>-->
<!-- </tree>-->
<!-- </field>-->
<!-- </page>-->
<page string="关联流程" invisible="not soong_record_ids">
<field name="soong_record_ids" style="width:100%%; margin-top: 10px;">
<tree editable="bottom" delete="False">
+10 -5
View File
@@ -31,11 +31,11 @@
parent="menu_soong_workflow_root"
action="soong_workflow_hr_employee_action"
sequence="5"/>
<menuitem id="menu_workflow_approval_request_copy"
name="抄送/传阅流程"
parent="menu_soong_workflow_root"
action="soong_workflow_record_action_copy"
sequence="8"/>
<!-- <menuitem id="menu_workflow_approval_request_copy"-->
<!-- name="抄送/传阅流程"-->
<!-- parent="menu_soong_workflow_root"-->
<!-- action="soong_workflow_record_action_copy"-->
<!-- sequence="8"/>-->
<menuitem id="menu_workflow_approval_request_admin"
name="流程监控"
parent="menu_soong_workflow_root"
@@ -71,6 +71,11 @@
parent="menu_soong_other_setting"
action="action_soong_workflow_log"
sequence="2"/>
<menuitem id="menu_soong_workflow_log2"
name="工作流传阅日志"
parent="menu_soong_other_setting"
action="action_soong_workflow_log2"
sequence="3"/>
<menuitem id="menu_soong_workflow_log"
name="工作流按钮"
parent="menu_soong_other_setting"
@@ -1,59 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?>
<odoo>
<record id="soong_workflow_log_kanban" model="ir.ui.view">
<field name="name">soong.workflow.log.kanban</field>
<field name="model">soong.workflow.log</field>
<field name="arch" type="xml">
<kanban class="o_kanban_mobile">
<field name="name"/>
<field name="comment"/>
<field name="done_by"/>
<field name="lase_click_date"/>
<field name="approval_state"/>
<field name="node_btn_name"/>
<templates>
<t t-name="kanban-box">
<div class="o_kanban_record d-md-none card h-100">
<div class="card-header d-flex justify-content-between align-items-center">
<strong>
<field name="name" />
</strong>
<span>
<field name="approval_state" widget="selection"/>
</span>
</div>
<div class="card-body">
<div class="mb-2">
<small>经办人: [<field name="done_by" />] </small>
</div>
<div class="mb-2">
<small>
<field name="lase_click_date"
widget="datetime" format="short" />
</small>
</div>
<t t-if="record.comment.raw_value">
<div class="mb-2">
<small>
[<field name="done_by" />]<field name="comment"/>
</small>
</div>
</t>
<t t-if="record.document_ids.raw_value and record.document_ids.raw_value.length > 0">
<div class="mb-2">
<small>
<field name="document_ids" string="" widget="preview_many2many"/>
</small>
</div>
</t>
</div>
</div>
</t>
</templates>
</kanban>
</field>
</record>
<!-- Views -->
<record id="view_soong_workflow_log_tree" model="ir.ui.view">
<field name="name">soong.workflow.log.tree</field>
<field name="model">soong.workflow.log</field>
@@ -62,8 +8,6 @@
<field name="sequence"/>
<field name="name"/>
<field name="code"/>
<!-- <field name="model"/>-->
<!-- <field name="res_id"/>-->
<field name="workflow_id" string="审批类型"/>
<field name="node_btn_id"/>
<field name="done_by"/>
@@ -73,22 +17,32 @@
</tree>
</field>
</record>
<record id="soong_workflow_log_search" model="ir.ui.view">
<field name="name">soong.workflow.log.search</field>
<field name="model">soong.workflow.log</field>
<field name="arch" type="xml">
<search>
<field name="name"/>
<group>
<filter name="code" string="事项类别上级" context="{'group_by': 'code'}"/>
</group>
</search>
</field>
</record>
<record id="action_soong_workflow_log" model="ir.actions.act_window">
<field name="name">工作流日志</field>
<field name="res_model">soong.workflow.log</field>
<field name="view_mode">tree</field>
<field name="context">{'search_default_code': 1}</field>
</record>
<record id="view_soong_workflow_log2_tree" model="ir.ui.view">
<field name="name">soong.workflow.log2.tree</field>
<field name="model">soong.workflow.log2</field>
<field name="arch" type="xml">
<tree string="传阅日志" default_order="lase_click_date desc">
<field name="sequence"/>
<field name="name"/>
<field name="workflow_id" string="审批类型"/>
<field name="node_btn_id"/>
<field name="done_by"/>
<field name="lase_click_date"/>
<field name="commit"/>
</tree>
</field>
</record>
<record id="action_soong_workflow_log2" model="ir.actions.act_window">
<field name="name">传阅日志</field>
<field name="res_model">soong.workflow.log2</field>
<field name="view_mode">tree</field>
</record>
</odoo>
@@ -41,6 +41,7 @@
options="{'no_create': True}"/>
<field name="is_apostille"/>
<field name="is_end"/>
<field name="is_confirm"/>
</group>
</group>
<group>
@@ -202,7 +202,7 @@ class SoongWorkflowCommentWizard(models.TransientModel):
('name', '=', link.name),
('workflow_id', '=', workflow_id.id)
])
button_priority_list = ["分发", "下发","转交", "结束"]
button_priority_list = ["分发", "下发", "转交", "结束"]
button = False
if node.button_ids:
for btn_name in button_priority_list:
@@ -517,7 +517,7 @@ class SoongWorkflowCommentWizard(models.TransientModel):
if hasattr(related_record, 'self_users_ids'):
related_record.self_users_ids = [(6, 0, user_ids)] if user_ids else [(5,)]
workflow_record_id.users_ids = [(6, 0, user_ids)]
if self.node_btn_name == '结束':
if self.node_btn_name in ['结束', '确认']:
current_user = self.env.user
current_datetime = fields.Datetime.now()
is_admin = current_user.has_group('soong_workflow.group_soong_workflow_manager')
@@ -541,10 +541,21 @@ class SoongWorkflowCommentWizard(models.TransientModel):
'lase_click_date': current_datetime,
'document_ids': [(6, 0, self.document_ids.ids)]
})
if record_id.log_ids2 and self.node_btn_name == '确认':
user_log2 = record_id.log_ids2.filtered(lambda log: log.done_by == current_user)
if user_log2:
user_log2.write({
'commit': self.comment,
'approval_state': "2",
'lase_click_date': current_datetime,
})
for employee in self.circulated_employee_ids:
action_id = self.env['ir.actions.act_window'].search([('res_model', '=', self.res_model)])[0]
url = f'https://oa.thtzjt.com/web#id={record_id.id}&cids=2&action={action_id.id}&model={self.res_model}&view_type=from&menu_id={record_id.id}'
description = "标题: {}\n".format(record_id.name) + self.env.user.name + ' ' + str(fields.Datetime.now() + timedelta(hours=8))
workflow_record_id = self.env['soong.workflow.record'].search([('code', '=', record_id.code)])
workflow_record_id.users_ids = [(4, employee.user_id.id) for employee in self.circulated_employee_ids if employee.user_id]
workflow_record_id.employee_ids = [(4, self.circulated_employee_ids.ids)]
workflow_record_id.employee_ids = [(4, employee.id)]
record_id = self.env[self.res_model].search([('id', '=', self.res_id)])
self.sudo().env["soong.workflow.record.copy"].create({
"code": record_id.code,
@@ -564,6 +575,10 @@ class SoongWorkflowCommentWizard(models.TransientModel):
"node_btn_id": self.node_btn_id.id,
"approval_state": "0",
})
# self.sudo().env["wecom.apps"].sync_send_message_textcard(category='oa', user_id=employee.wecom_userid,
# title=record_id._description + "传阅/抄送",
# description=description, url=url,
# btntxt="查看详情")
if not record_id.log_ids.search([('approval_state', 'in', ['0', '1'])]) and not record_id.log_ids2.search([('approval_state', '=', '0')]):
record_id.work_end = True
# last_log = log_records[-1] if log_records else None
@@ -632,37 +647,6 @@ class SoongWorkflowCommentWizard(models.TransientModel):
description=f"编号为{record_id.code}的{record_id._description}已结束,请归档",
url=url, btntxt="查看详情")
self.node_btn_id.with_context(cx).run()
if self.node_btn_name == '确认':
log_rec_id = record_id.log_ids2.filtered(lambda log: log.done_by == self.env.user)
log_rec_id.write({
'comment': self.comment,
'approval_state': "1",
'lase_click_date': fields.datetime.now(),
'document_ids': [(6, 0, self.document_ids.ids)]
})
for employee in self.circulated_employee_ids:
workflow_record_id = self.env['soong.workflow.record'].search([('code', '=', record_id.code)])
workflow_record_id.users_ids = [(4, employee.user_id.id) for employee in self.circulated_employee_ids if employee.user_id]
workflow_record_id.employee_ids = [(4, self.circulated_employee_ids.ids)]
record_id = self.env[self.res_model].search([('id', '=', self.res_id)])
self.sudo().env["soong.workflow.record.copy"].create({
"code": record_id.code,
"name": record_id.name,
"res_model": self.res_model,
"workflow_id": self.node_btn_id.workflow_id.id,
"res_id": self.res_id,
"done_by": employee.user_id.id,
"approval_state_copy": "0",
})
self.sudo().env["soong.workflow.log2"].create({
"model": self.res_model,
"res_id": self.res_id,
"node_id": self.node_btn_id.node_id.id,
"workflow_id": self.node_btn_id.workflow_id.id,
"done_by": employee.user_id.id,
"node_btn_id": self.node_btn_id.id,
"approval_state": "0",
})
if self.node_btn_name == "分发":
record_id.is_send = True
workflow_record_id = self.env['soong.workflow.record'].search([('code', '=', record_id.code)])
@@ -744,7 +728,7 @@ class SoongWorkflowCommentWizard(models.TransientModel):
self.node_btn_id.with_context(cx).run()
if self.node_btn_name != "收回":
menu_id = self.env.ref("soong_workflow.menu_soong_workflow_todo_record_first").id
menu_id = self.env.ref("yuthon_work_brand.menu_soong_workflow_todo_record").id
return {
"type": "ir.actions.client",
"tag": "reload",
@@ -14,7 +14,7 @@
<field name="user_role_ids"/>
<field name="comment"/>
</group>
<group invisible="node_btn_name in ['分发', '结束', '收回']">
<group invisible="node_btn_name in ['分发', '结束', '收回', '确认']">
<div class="oe_comment_block" style=" width:1200%; border: 1px solid #dee2e6; border-radius: 4px; padding: 12px; margin-bottom: 16px;">
<label for="comment_note_id" string="常用意见"
style="font-weight: bold; margin-bottom: 8px; display: block;"/>
@@ -35,6 +35,16 @@
<field name="circulated_employee_ids" widget="many2many_tags" options="{'no_create': True}"/>
</group>
</group>
<group invisible="node_btn_name != '确认'">
<div class="oe_comment_block" style=" width:1200%; border: 1px solid #dee2e6; border-radius: 4px; padding: 12px; margin-bottom: 16px;">
<label for="comment_note_id" string="确认意见" style="font-weight: bold; margin-bottom: 8px; display: block;"/>
<field name="comment_note_id" class="mb-3" style="width: 100%;" options="{'no_create': True}" domain="[('note_setting_id.users_role_ids', 'in', user_role_ids)]"/>
<field name="comment_note" placeholder="请输入意见内容..." style="width: 100%;"/>
</div>
<group>
<field name="circulated_employee_ids" widget="many2many_tags" options="{'no_create': True}"/>
</group>
</group>
<group invisible="node_btn_name != '分发'">
<div class="oe_comment_block" style=" width:1200%; border: 1px solid #dee2e6; border-radius: 4px; padding: 12px; margin-bottom: 16px;">
<label for="comment_note_id" string="分发意见"
@@ -43,7 +53,7 @@
<field name="comment_note" placeholder="请输入意见内容..." style="width: 100%;"/>
</div>
</group>
<group invisible="node_btn_name in ['分发', '结束', '收回']">
<group invisible="node_btn_name in ['分发', '结束', '收回', '确认']">
<field name="user_id" invisible="1"/>
<field name="user_role_ids" widget="many2many_tags" invisible="1"/>
<field name="node_btn_id" invisible="1"/>
@@ -53,7 +63,7 @@
<field name="is_automatic" invisible="1"/>
<field name="is_supervising" invisible="1"/>
</group>
<group col="2" invisible="node_btn_name in ['分发', '结束', '收回']">
<group col="2" invisible="node_btn_name in ['分发', '结束', '收回', '确认']">
<group>
<!-- 转交人员 -->
<field name="trans_link_id" string="转交节点" invisible="node_btn_name == '退回'" domain="[('id', 'not in', invalid_link_ids)]" options="{'no_open': True}" widget="radio"/>