diff --git a/soong_workflow/__manifest__.py b/soong_workflow/__manifest__.py
index 05ce54166..646266375 100644
--- a/soong_workflow/__manifest__.py
+++ b/soong_workflow/__manifest__.py
@@ -22,7 +22,6 @@
"views/soong_workflow_record.xml",
"views/soong_approval_group.xml",
'wizard/approval_notice_wizard_views.xml',
- 'wizard/soong_transmitted_wizard_views.xml',
"wizard/soong_workflow_comment_wizard_view.xml",
"templates/soong_workflow_templates.xml",
],
diff --git a/soong_workflow/models/soong_workflow.py b/soong_workflow/models/soong_workflow.py
index 9e8652b10..e10a7f865 100644
--- a/soong_workflow/models/soong_workflow.py
+++ b/soong_workflow/models/soong_workflow.py
@@ -49,7 +49,8 @@ class SoongWorkflow(models.Model):
link_ids = fields.One2many(comodel_name="soong.workflow.link", inverse_name="workflow_id", string="Links")
remove_default_btn_until_end = fields.Boolean(string="是否覆盖表头按钮状态", default=False)
- current_stage_highlight_color = fields.Char(default="rgb(0, 255, 255)",help="The color to highlight the current stage on flow",)
+ current_stage_highlight_color = fields.Char(default="rgb(0, 255, 255)",
+ help="The color to highlight the current stage on flow", )
start_time = fields.Datetime(string="生效日期", copy=False, default=fields.Datetime.now)
end_time = fields.Datetime(string="失效日期", copy=False)
is_enable = fields.Boolean(string="是否启用", default="False", compute="compute_is_enable", store=True)
@@ -106,15 +107,18 @@ class SoongWorkflow(models.Model):
@api.depends('start_time', 'end_time')
def compute_is_enable(self):
- # 逻辑调整修改时间的时候判断有无要启用的,只准一个不能冲突
- for rec in self:
- if rec.start_time and rec.end_time:
- if rec.start_time < datetime.datetime.now() and rec.end_time > datetime.datetime.now():
- rec.is_enable = True
+ is_enable_ids = self.search([('model_id', '=', self.model_id.id), ('is_enable', '=', True)])
+ if len(is_enable_ids) <= 1:
+ for rec in self:
+ if rec.start_time and rec.end_time:
+ if rec.start_time < datetime.datetime.now() and rec.end_time > datetime.datetime.now():
+ rec.is_enable = True
+ else:
+ rec.is_enable = False
else:
rec.is_enable = False
- else:
- rec.is_enable = False
+ else:
+ raise UserError('工作流一个模型只能启用一个')
@api.constrains("node_ids")
def validate_nodes(self):
@@ -150,16 +154,17 @@ class SoongWorkflow(models.Model):
if not val["node_ids"]:
val["node_ids"] = [
(0, 0, {
- "name": _("开始"),
- "sequence": 1,
- "node_name": "start",
- "flow_start": True,
- },),
+ "name": _("开始"),
+ "sequence": 1,
+ "node_name": "start",
+ "flow_start": True,
+ "button_ids": ''
+ },),
(0, 0, {
- "name": _("结束"),
- "sequence": 99,
- "node_name": "end",
- "flow_end": True,
+ "name": _("结束"),
+ "sequence": 99,
+ "node_name": "end",
+ "flow_end": True,
},), ]
return super().create(values)
diff --git a/soong_workflow/models/soong_workflow_mixin.py b/soong_workflow/models/soong_workflow_mixin.py
index eb1d71d0b..ef18b2111 100644
--- a/soong_workflow/models/soong_workflow_mixin.py
+++ b/soong_workflow/models/soong_workflow_mixin.py
@@ -112,7 +112,7 @@ class SoongWorkflowMixin(models.AbstractModel):
def _add_comment(self, logs, btn_rec):
wizard = self.env.ref("soong_workflow.view_soong_workflow_comment_wizard")
return {
- "name": _("Comment"),
+ "name": _("评论"),
"type": "ir.actions.act_window",
"view_mode": "form",
"res_model": "soong.workflow.comment.wizard",
@@ -162,6 +162,7 @@ class SoongWorkflowMixin(models.AbstractModel):
cx.update({"active_id": self.id, "active_ids": self.ids})
wkf_btn_obj = self.env["soong.workflow.node.button"]
btn_rec = wkf_btn_obj.search([("btn_key", "=", cx.get("btn_key", False))])
+ # 优化弹窗
if btn_rec:
log_obj = self._create_update_logs(btn_rec)
if btn_rec.has_comment:
@@ -242,37 +243,9 @@ 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)
- # todo 后许可拓展退回层级
- res = self._add_return_button(view_type, res)
- # 转交 如果一条链路直接跳转,如果多条链路选择跳转
- # res = self._add_transmitted_button(view_type, res)
- return res
-
- # 收回逻辑
- def _add_return_button(self, view_type, res):
- model = self._name
- wkf_obj = self.env["soong.workflow"]
- wkf_rec = wkf_obj.search([("model_id", "=", model), ('is_enable', '=', True)])
-
- if not wkf_rec.is_enable_return_button:
- return res
-
- arch = etree.fromstring(res["arch"])
- if view_type == "form":
- header_el = arch.xpath("//form/header")
- header_el = header_el[0] if header_el else False
- if header_el:
- button = etree.Element("button", {
- "name": "action_return",
- "type": "object",
- "string": "收回",
- "class": "btn-primary", # 按钮的样式
- # "icon": "fa-undo", # 按钮图标 (如果需要)
- })
- header_el.append(button)
- res["arch"] = etree.tostring(arch, encoding="unicode").replace("\t", "")
return res
+ # 收回
def action_return(self):
# 收回目前只支持指定用户和指定角色
for record in self:
@@ -309,56 +282,35 @@ class SoongWorkflowMixin(models.AbstractModel):
# 当前单据状态所在的位置
record_number = key.split('_')[1]
for key, values in result_dict.items():
- if self.env.user.id in values:
- # 当前用户所在节点
- user_number = key.split('_')[1]
- user_key = key
+ if values != [False]:
+ if self.env.user.id in values:
+ # 当前用户所在节点
+ user_number = key.split('_')[1]
+ user_key = key
+ else:
+ raise UserError('请配置节点的人员')
number = int(record_number) - int(user_number)
if number == 1:
self.write({'state': user_key.split('_')[0]})
else:
raise UserError('不可收回')
-
-
-
-
-
-
- # for button in header_el.iter("button"):
- # btn_invisible = "state != 'end'"
- # if "invisible" in button.attrib:
- # btn_invisible = btn_invisible + " or " + button.attrib["invisible"]
- # button.set("invisible", btn_invisible)
-
# 转交
- def _add_transmitted_button(self, view_type, res):
- model = self._name
- wkf_obj = self.env["soong.workflow"]
- wkf_rec = wkf_obj.search([("model_id", "=", model), ('is_enable', '=', True)])
-
- if not wkf_rec.is_enable_transmitted_button:
- return res
-
- arch = etree.fromstring(res["arch"])
- if view_type == "form":
- header_el = arch.xpath("//form/header")
- header_el = header_el[0] if header_el else False
- if header_el:
- button = etree.Element("button", {
- "name": "action_transmitted",
- "type": "object",
- "string": "转交",
- "class": "btn-primary", # 按钮的样式
- })
- header_el.append(button)
- res["arch"] = etree.tostring(arch, encoding="unicode").replace("\t", "")
- return res
-
def action_transmitted(self):
+ # 当前节点对应的链路
+ node_ids = self.workflow_id.node_ids.search([('node_name', '=', self.state)])
# 判断链路是一个就跳转
- # 是多个就弹窗选择
- pass
+ if len(node_ids.out_link_ids) == 1:
+ state_next = node_ids.out_link_ids.name.split('-> ')[-1]
+ self.write({'state': state_next})
+ # 多个节点弹窗选择并发送消息提醒
+ elif len(node_ids.out_link_ids) > 1:
+ state_list = []
+ for node in node_ids.out_link_ids:
+ state_list.append(node.name.split('-> ')[-1])
+ # 传入每个节点的对应人员
+ else:
+ raise UserError('节点链路配置错误')
def _remove_default_header(self, view_type, res):
"""
diff --git a/soong_workflow/models/soong_workflow_node.py b/soong_workflow/models/soong_workflow_node.py
index 40df51c27..c2db941b3 100644
--- a/soong_workflow/models/soong_workflow_node.py
+++ b/soong_workflow/models/soong_workflow_node.py
@@ -58,76 +58,49 @@ class SoongWorkflowNode(models.Model):
),
]
- sequence = fields.Integer(
- string="Sequence", default=10, help="Arrange node by defining sequence."
- )
- name = fields.Char(
- string="Name", translate=True, help="Enter string name of the node."
- )
- node_name = fields.Char(
- string="Technical Name",
- help="Generated technical name which used by backend code.",
- )
- workflow_id = fields.Many2one(
- comodel_name="soong.workflow",
- string="Workflow Ref.",
- ondelete="cascade",
- required=True,
- )
- model_id = fields.Many2one(
- "ir.model",
- string="Model Ref.",
- domain="[('state','=','base')]",
- related="workflow_id.model_id",
- required=True,
- )
- flow_start = fields.Boolean(
- string="Flow Start", help="Check it if this node is the starting node."
- )
- flow_end = fields.Boolean(
- string="Flow End", help="Check it if this node is the ending node."
- )
- is_visible = fields.Boolean(
- string="Appear in Statusbar",
- default=True,
- help="Control visiability of the node/state in view.",
- )
- out_link_ids = fields.One2many(
- comodel_name="soong.workflow.link",
- inverse_name="node_from",
- string="Outgoing Transitions",
- )
- in_link_ids = fields.One2many(
- comodel_name="soong.workflow.link",
- inverse_name="node_to",
- string="Incoming Transitions",
- )
-
- field_ids = fields.One2many(
- comodel_name="soong.workflow.node.field",
- inverse_name="node_id",
- string="Fields",
- )
- button_ids = fields.One2many(
- comodel_name="soong.workflow.node.button",
- inverse_name="node_id",
- string="Buttons",
- )
-
+ sequence = fields.Integer(string="Sequence", default=10, help="Arrange node by defining sequence.")
+ name = fields.Char(string="Name", translate=True, help="Enter string name of the node.")
+ node_name = fields.Char(string="Technical Name",help="Generated technical name which used by backend code.",)
+ workflow_id = fields.Many2one(comodel_name="soong.workflow",string="Workflow Ref.",ondelete="cascade",required=True,)
+ model_id = fields.Many2one("ir.model",string="Model Ref.",domain="[('state','=','base')]",related="workflow_id.model_id",required=True,)
+ flow_start = fields.Boolean(string="Flow Start", help="Check it if this node is the starting node.")
+ flow_end = fields.Boolean(string="Flow End", help="Check it if this node is the ending node.")
+ is_visible = fields.Boolean(string="Appear in Statusbar",default=True,help="Control visiability of the node/state in view.",)
+ out_link_ids = fields.One2many(comodel_name="soong.workflow.link",inverse_name="node_from",string="Outgoing Transitions",)
+ in_link_ids = fields.One2many(comodel_name="soong.workflow.link",inverse_name="node_to",string="Incoming Transitions",)
+ field_ids = fields.One2many(comodel_name="soong.workflow.node.field",inverse_name="node_id",string="Fields",)
+ button_ids = fields.One2many(comodel_name="soong.workflow.node.button",inverse_name="node_id",string="Buttons",)
diagram_position = fields.Char(readonly=True, string="Diagram Position")
bg_color = fields.Char(default=DEFAULT_BG_COLOR, string="Background Color")
label_color = fields.Char(default=DEFAULT_LABEL_COLOR, string="Label Color")
-
# Custom colors
- use_custom_colors = fields.Boolean(
- help="Select colors from the palette manually", string="Use Custom Colors"
- )
- res_bg_color = fields.Char(
- compute="_compute_custom_colors", readonly=True, string="Backgroung Color"
- )
- res_label_color = fields.Char(
- compute="_compute_custom_colors", readonly=True, string="Label Color"
- )
+ use_custom_colors = fields.Boolean(help="Select colors from the palette manually", string="Use Custom Colors")
+ res_bg_color = fields.Char(compute="_compute_custom_colors", readonly=True, string="Backgroung Color")
+ res_label_color = fields.Char(compute="_compute_custom_colors", readonly=True, string="Label Color")
+
+ @api.model_create_multi
+ def create(self, values):
+ for val in values:
+ if val['node_name'] != 'end':
+ if not val["button_ids"]:
+ val["button_ids"] = [
+ (0, 0, {
+ "name": _("转交"),
+ "workflow_id": val['workflow_id'],
+ "sequence": 1,
+ "action_type": "code",
+ "code": "obj.action_transmitted()",
+ "has_comment": True,
+ },),
+ (0, 0, {
+ "name": _("收回"),
+ "workflow_id": val['workflow_id'],
+ "sequence": 2,
+ "action_type": "code",
+ "code": "obj.action_return()",
+ },)
+ ]
+ return super().create(values)
@api.depends("bg_color", "label_color", "use_custom_colors", "flow_start", "flow_end")
def _compute_custom_colors(self):
@@ -210,7 +183,7 @@ class SoongWorkflowNodeButton(models.Model):
string="Icon",
help="Enter icon name like: fa-print, it's recommended to use FontAwesome Icons.",
)
- has_comment = fields.Boolean(string="Comment", default=False)
+ has_comment = fields.Boolean(string="评论", default=False)
btn_key = fields.Char(string="Button Key", default=_generate_key)
btn_hide = fields.Boolean(
string="Hide Button if Condition isn't fulfilled",
diff --git a/soong_workflow/security/ir.model.access.csv b/soong_workflow/security/ir.model.access.csv
index bd24009db..ceb16fda0 100644
--- a/soong_workflow/security/ir.model.access.csv
+++ b/soong_workflow/security/ir.model.access.csv
@@ -23,6 +23,4 @@ access_soong_approval_group,soong_approval_group,model_soong_approval_group,soon
access_soong_approval_notice_wizard,soong_approval_notice_wizard,model_soong_approval_notice_wizard,base.group_user,1,1,1,1
access_soong_workflow_log_user,soong_workflow_log_user,model_soong_workflow_log,soong_workflow.group_soong_workflow_user,1,1,1,1
-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_soong_approval_transmitted_wizard,soong_approval_transmitted_wizard,model_soong_approval_transmitted_wizard,soong_workflow.group_soong_workflow_user,1,1,1,1
\ No newline at end of file
+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
\ No newline at end of file
diff --git a/soong_workflow/views/soong_workflow_views.xml b/soong_workflow/views/soong_workflow_views.xml
index 502a5ee36..26677356f 100644
--- a/soong_workflow/views/soong_workflow_views.xml
+++ b/soong_workflow/views/soong_workflow_views.xml
@@ -27,6 +27,7 @@
+
diff --git a/soong_workflow/wizard/__init__.py b/soong_workflow/wizard/__init__.py
index b8d44c6f0..e66025961 100644
--- a/soong_workflow/wizard/__init__.py
+++ b/soong_workflow/wizard/__init__.py
@@ -3,7 +3,6 @@
from . import approval_notice_wizard
-from . import soong_transmitted_wizard
from . import soong_workflow_comment_wizard
diff --git a/soong_workflow/wizard/soong_transmitted_wizard.py b/soong_workflow/wizard/soong_transmitted_wizard.py
deleted file mode 100644
index 3fa508c64..000000000
--- a/soong_workflow/wizard/soong_transmitted_wizard.py
+++ /dev/null
@@ -1,18 +0,0 @@
-# -*- coding: utf-8 -*-
-from odoo import api, fields, models, tools, _
-from datetime import datetime, date, time, timedelta
-from odoo.tools.safe_eval import safe_eval
-from odoo.exceptions import ValidationError, UserError
-import logging
-
-_logger = logging.getLogger(__name__)
-
-
-class SoongApprovalTransmittedWizard(models.TransientModel):
- _name = 'soong.approval.transmitted.wizard'
- _description = """ 转交弹窗 """
-
- name = fields.Char(string='名称')
-
- def confirm(self):
- pass
\ No newline at end of file
diff --git a/soong_workflow/wizard/soong_transmitted_wizard_views.xml b/soong_workflow/wizard/soong_transmitted_wizard_views.xml
deleted file mode 100644
index 162ea4ab4..000000000
--- a/soong_workflow/wizard/soong_transmitted_wizard_views.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-
-
-
- 一键转交
- soong.approval.transmitted.wizard
-
-
-
-
-
\ No newline at end of file
diff --git a/soong_workflow/wizard/soong_workflow_comment_wizard.py b/soong_workflow/wizard/soong_workflow_comment_wizard.py
index c667f15c2..cfd79764b 100644
--- a/soong_workflow/wizard/soong_workflow_comment_wizard.py
+++ b/soong_workflow/wizard/soong_workflow_comment_wizard.py
@@ -12,13 +12,16 @@ class SoongWorkflowCommentWizard(models.TransientModel):
res_id = fields.Integer()
log_ids = fields.Many2many(comodel_name="soong.workflow.log")
node_btn_id = fields.Many2one(comodel_name="soong.workflow.node.button")
+ button_type = fields.Selection([('trans', '转交'), ('other', '其他')], string="按钮类型", default='other')
comment_note_id = fields.Many2one('soong.note', required=True, string="意见")
comment_type = fields.Selection(related="comment_note_id.type", string="意见类型")
comment_return_type = fields.Char(related="comment_note_id.return_type", string="退回类型")
+ state_list = fields.Char(string="状态列表")
+ employee_ids = fields.Many2many('hr.employee', string="提醒经办人")
+ notice_message = fields.Char(string="消息通知")
def add_comment(self):
self.ensure_one()
cx = self.env.context.copy() or {}
-
self.log_ids.write({"comment": self.comment})
return self.node_btn_id.with_context(cx).run()
diff --git a/yuthon_hr_employee/models/yuthon_hr_department.py b/yuthon_hr_employee/models/yuthon_hr_department.py
index a9606bd1e..a34c73e9c 100644
--- a/yuthon_hr_employee/models/yuthon_hr_department.py
+++ b/yuthon_hr_employee/models/yuthon_hr_department.py
@@ -4,7 +4,7 @@ from odoo import api, fields, models
class YuthonHrDepartment(models.Model):
_inherit = "hr.department"
- _order = 'department_code'
+ _order = 'department_code asc'
department_phone = fields.Char(string="部门电话")
department_fax = fields.Char(string="部门传真")
diff --git a/yuthon_hr_employee/models/yuthon_hr_employee.py b/yuthon_hr_employee/models/yuthon_hr_employee.py
index 08f98aae4..da037c3e2 100644
--- a/yuthon_hr_employee/models/yuthon_hr_employee.py
+++ b/yuthon_hr_employee/models/yuthon_hr_employee.py
@@ -20,7 +20,7 @@ class YuthonHrEmployee(models.Model):
对原模型数据的隐藏,字段的开发和添加
"""
_inherit = "hr.employee"
- _order = 'number'
+ _order = 'number asc'
# odoo里是这样做的,一个用户可以多个公司绑定多个员工,每个员工都有自己的部门和岗位
@@ -28,7 +28,6 @@ class YuthonHrEmployee(models.Model):
user_number = fields.Char(string="员工编号", default=lambda self: self.env['ir.sequence'].next_by_code('employee_code'))
use_user_type = fields.Selection([('formal', '正式职工'), ('labor', '劳务协议'),
('part_time', '兼职协议'), ('employment', '兼职用工')], string="用工形式")
-
job_lv_id = fields.Many2one('yuthon.job.lv', string="最新职级")
# 个人信息
user_salary = fields.Float(string="基本工资")
diff --git a/yuthon_work_brand/__manifest__.py b/yuthon_work_brand/__manifest__.py
index cd076bf01..3d42a0977 100644
--- a/yuthon_work_brand/__manifest__.py
+++ b/yuthon_work_brand/__manifest__.py
@@ -9,6 +9,7 @@
""",
'depends': ['base',
'board',
+ 'spreadsheet_dashboard',
'yuthon_notice',
'soong_workflow',
'yuthon_issue',
diff --git a/yuthon_work_brand/views/hr_menus.xml b/yuthon_work_brand/views/hr_menus.xml
index 99055b491..596d19861 100644
--- a/yuthon_work_brand/views/hr_menus.xml
+++ b/yuthon_work_brand/views/hr_menus.xml
@@ -1,21 +1,21 @@
-
+
+
+
-
+
+
+
-
+
+
+
-
+
+
+
-
+
+ parent="holiday_manage_menu_root_board" action="yuthon_hr_attendance.holiday_manage_type_action" sequence="1"/>
+ parent="holiday_manage_menu_root_board" action="yuthon_hr_attendance.holiday_balance_action" sequence="3"/>
diff --git a/yuthon_work_brand/views/work_menus.xml b/yuthon_work_brand/views/work_menus.xml
index 854d4eaed..1ef7fdbd1 100644
--- a/yuthon_work_brand/views/work_menus.xml
+++ b/yuthon_work_brand/views/work_menus.xml
@@ -1,21 +1,21 @@
-
+
+
+
-
+
+
+
-
+
+
+
-
+
+
+
\ No newline at end of file