This commit is contained in:
李鹏宇
2025-02-02 22:07:05 +08:00
parent a82fa56a8f
commit d35ee2b9f1
16 changed files with 359 additions and 154 deletions
@@ -1,3 +1,14 @@
.. image:: https://tools.huo15.com/uploads/images/system/logo-colours.png
:width: 100
:alt: logo
辉火云企业套件社区版 - 附加模块
===========================
HuihuoYun Business Suite Community addons
-----------------------------------------
.. image:: https://img.shields.io/badge/license-LGPL--3-green.svg
:target: https://www.gnu.org/licenses/lgpl-3.0-standalone.html
:alt: License: LGPL-3
@@ -1,22 +1,173 @@
/** @odoo-module **/
/** This file will used to stick the selected header and column in the list view **/
import { patch } from "@web/core/utils/patch";
import { ListRenderer } from "@web/views/list/list_renderer";
import {patch} from "@web/core/utils/patch";
import {ListRenderer} from "@web/views/list/list_renderer";
import {onMounted, onWillUnmount} from "@odoo/owl";
/**
* @file list_view_sticky_header_and_column.js
* @description 辉火云企业套件
* @author Job Zhao - 青岛火一五信息科技有限公司
* @contact postmaster@huo15.com | 18554898815
* @date 2025/1/28
* @copyright 青岛火一五信息科技有限公司 保留所有权利
* @see https://www.huo15.com
*/
patch(ListRenderer.prototype, {
/** super the setup function **/
setup() {
super.setup();
// >>> 青岛火一五信息科技有限公司 - JobZhao - postmaster@huo15.com - 2025/1/28
onMounted(() => {
this.root = this.__owl__.bdom.parentEl;
this._adjustColumnWidths();
const $thead = $(this.__owl__.bdom.parentEl.querySelectorAll('.o_list_table thead')[0]);
$thead.css('z-index', '100000')
//移除现有的粘性列和选中标记
const $clickedHeader = $(this.__owl__.bdom.parentEl.querySelectorAll('.o_list_table th')[1]);
$(this.__owl__.bdom.parentEl.querySelectorAll('.sticky-column')).removeClass('sticky-column');
console.log($(this.__owl__.bdom.parentEl.querySelectorAll('.sticky-column')).removeClass('sticky-column'));
$(this.__owl__.bdom.parentEl.querySelectorAll('.clicked-header')).removeClass('clicked-header');
$clickedHeader.addClass('clicked-header');
const columnIndex = $clickedHeader.index();
//获取表头、表行和表尾的元素
const $tableHeaders = $(this.__owl__.bdom.parentEl.querySelectorAll('.o_list_table th'));
const $tableRows = $(this.__owl__.bdom.parentEl.querySelectorAll('.o_list_table tr'));
const $tfootRow = $(this.__owl__.bdom.parentEl.querySelectorAll('.o_list_table tfoot tr')[0].children);
//为选中的列和表头添加粘性效果
const $selectedFooterCells = $tfootRow.filter(`td:nth-child(-n+${columnIndex + 1})`);
$selectedFooterCells.addClass('sticky-column');
const $selectedColumns = $(this.__owl__.bdom.parentEl.querySelectorAll(`.o_data_row td:nth-child(-n+${columnIndex + 1})`));
const $selectedHeaderCells = $tableHeaders.filter(`th:nth-child(-n+${columnIndex + 1})`);
$tableHeaders.removeClass('sticky-column').css('left', '');
$(this.__owl__.bdom.parentEl.querySelectorAll('.o_data_row td')).removeClass('sticky-column').css('left', '');
$selectedColumns.addClass('sticky-column');
$selectedHeaderCells.addClass('sticky-column');
$tableHeaders.filter('.sticky-column').css('top', '0');
// 调整列的 left 位置
const $targetColumn = $selectedColumns.eq(columnIndex);
const targetLeftPosition = $targetColumn.position().left;
const columnsToAdjust = columnIndex + 1;
$tableRows.each(function (index, row) {
const $headerCells = $(row).find('th');
const $rowCells = $(row).find('td');
for (let i = 0; i < columnsToAdjust; i++) {
if ($headerCells.eq(i).length > 0) {
$headerCells.eq(i).css('left', `${$headerCells.eq(i).position().left}px`);
}
if ($rowCells.eq(i).length > 0) {
$rowCells.eq(i).css('left', `${$rowCells.eq(i).position().left}px`);
}
}
});
// 监听窗口缩放事件
this.resizeObserver = new ResizeObserver(() => {
this._adjustColumnWidths();
});
this.resizeObserver.observe(this.root);
});
// 在组件卸载时停止监听
onWillUnmount(() => {
if (this.resizeObserver) {
this.resizeObserver.disconnect();
}
});
},
/**
* 调整列宽和换行逻辑
*/
_adjustColumnWidths() {
// >>> 青岛火一五信息科技有限公司 - JobZhao - postmaster@huo15.com - 2025/1/28
this.root = this.__owl__.bdom.parentEl;
const table = this.root.querySelector(".o_list_table"); // 获取表格元素
if (!table) return;
const columns = table.querySelectorAll("th"); // 获取所有表头
const rows = table.querySelectorAll(".o_data_row"); // 获取所有数据行
columns.forEach((column, colIndex) => {
let maxWidth = 0;
let maxContent = "";
const thContent = column.textContent.trim();
console.log('th length:', thContent.length)
// 遍历每一行,找到最长的单元格内容
rows.forEach((row) => {
const cell = row.querySelector(`td:nth-child(${colIndex + 1})`);
if (cell) {
const content = cell.textContent.trim();
let isChinese = /[\u4e00-\u9fa5]/.test(thContent); // 判断是否包含汉字
let contentLength = content.length;
let thContentLength = thContent.length;
if (thContentLength<=2){
thContentLength*=1.5;
}
if (isChinese) {
thContentLength *= 2.5;
}
if (contentLength <= thContentLength) {
contentLength = thContentLength;
}
isChinese = /[\u4e00-\u9fa5]/.test(content); // 判断是否包含汉字
if (isChinese) {
contentLength *= 2;
}
// 更新最大宽度和最长内容
if (contentLength > maxWidth) {
maxWidth = contentLength;
maxContent = content;
}
// 更新最大宽度和最长内容
if (contentLength > maxWidth) {
maxWidth = contentLength;
maxContent = content;
}
}
});
// 设置列宽
if (maxWidth > 0 && maxWidth < 30) {
const columnWidth = maxWidth * 1; // 假设每个字符占 8px
column.style.minWidth = `${columnWidth}ch`;
column.style.maxWidth = `${columnWidth}ch`;
column.style.width = `${columnWidth}ch`;
} else if (maxWidth >= 30) {
column.style.minWidth = `240px`;
column.style.maxWidth = `240px`;
column.style.width = `240px`;
}
// 如果最长内容超过 30 个字符,设置换行
if (maxWidth > 30) {
rows.forEach((row) => {
const cell = row.querySelector(`td:nth-child(${colIndex + 1})`);
if (cell) {
console.log('cell:', cell)
cell.style.whiteSpace = "normal"; // 允许换行
cell.style.wordWrap = "break-word"; // 允许长单词换行
}
});
}
});
},
/**
* function defining the button having t-on-click _onClick
*/
_onClickIcon(ev, record) {
ev.preventDefault();
ev.stopPropagation()
console.log('target current:', $(ev.currentTarget))
const $clickedHeader = $(ev.currentTarget).closest('th');
const columnIndex = $clickedHeader.index();
console.log(this.__owl__.bdom.parentEl)
$(this.__owl__.bdom.parentEl.querySelectorAll('.sticky-column')).removeClass('sticky-column');
console.log($(this.__owl__.bdom.parentEl.querySelectorAll('.sticky-column')).removeClass('sticky-column'))
$(this.__owl__.bdom.parentEl.querySelectorAll('.clicked-header')).removeClass('clicked-header');
@@ -42,6 +193,7 @@ patch(ListRenderer.prototype, {
for (let i = 0; i < columnsToAdjust; i++) {
if ($headerCells.eq(i).length > 0) {
$headerCells.eq(i).css('left', `${$headerCells.eq(i).position().left}px`);
}
if ($rowCells.eq(i).length > 0) {
$rowCells.eq(i).css('left', `${$rowCells.eq(i).position().left}px`);
@@ -1,67 +1,99 @@
.o_action .o_content {
z-index: 1;
z-index: 1;
}
.sticky-column {
position: sticky !important;
background-color: white;
z-index: 2;
position: sticky !important;
background-color: white;
z-index: 2;
}
.o_list_view .o_list_table td.sticky-column {
z-index: 4;
background-color: white;
z-index: 4;
background-color: white;
}
.o_list_view .o_list_table thead {
position: sticky;
top: 0;
z-index: 3;
background-color: white;
position: sticky;
top: 0;
z-index: 3;
background-color: white;
}
.o_list_view .o_list_table th.sticky-column {
z-index: 4;
background-color: white;
z-index: 4;
background-color: white;
}
.o_account_reports_page .table-responsive {
overflow-x: auto;
overflow-y: visible;
overflow-x: auto;
overflow-y: visible;
}
.table-responsive {
overflow: visible;
overflow: visible;
}
.o_list_view .table-responsive .table thead {
z-index: 1;
z-index: 1;
}
.o_form_view:not(.o_field_highlight) .o_field_widget:not(.o_field_invalid):not(.o_field_highlight) .o_input:not(:hover):not(:focus) {
--o-input-border-color: transparent;
//border-style: solid;
//border-color: #000;
//border-width: 0px;
//border-bottom-width: 1px;
--o-input-border-color: transparent;
//border-style: solid;
//border-color: #000;
//border-width: 0px;
//border-bottom-width: 1px;
}
body.white .table {
width: -webkit-fill-available !important;
width: -webkit-fill-available !important;
}
.o_list_renderer .o_list_table thead {
position: sticky;
top: 0;
z-index: 6;
position: sticky;
top: 0;
z-index: 6;
}
th.sticky-column::before {
content: "";
position: absolute;
width: 5px;
height: 100%;
background: white;
top: 0;
left: -4px;
content: "";
position: absolute;
width: 5px;
height: 100%;
background: white;
top: 0;
left: -4px;
}
.fa-thumb-tack {
display: none;
display: none;
}
th:hover .fa-thumb-tack,
th.clicked-header .fa-thumb-tack {
display: block;
display: block;
}
//.o_input:hover{background: #b3c8df!important;}
// >>> 青岛火一五信息科技有限公司 - JobZhao - postmaster@huo15.com - 2025/1/28
// 解决宽度调整
.o_list_view {
.o_list_table {
table-layout: auto; // 让表格宽度根据内容自动调整
width: 100%; // 确保表格宽度占满容器
th, td {
white-space: nowrap; // 默认不换行
overflow: hidden; // 超出部分隐藏
text-overflow: ellipsis; // 超出部分显示省略号
}
td.long-text {
white-space: normal; // 允许换行
word-wrap: break-word; // 允许长单词换行
}
}
}
+3 -3
View File
@@ -38,9 +38,9 @@ class SoongWorkflowLog(models.Model):
done_by = fields.Many2one(comodel_name="res.users", string="审批人")
lase_click_date = fields.Datetime(string="操作时间")
approval_state = fields.Selection([
('0', '待审批'),
('1', '审批中'),
('2', '已审批'),
('0', '待办'),
('1', '办理中'),
('2', '已办结'),
], string='审批状态', default='0')
comment = fields.Char(string="意见")
date_create = fields.Datetime(string="时间", default=lambda self: fields.Datetime.now())
@@ -155,7 +155,7 @@ class SoongWorkflowMixin(models.AbstractModel):
log_ids = fields.One2many(
comodel_name="soong.workflow.log",
inverse_name="res_id",
string="Logs",
string=" ",
domain=lambda self: [("model", "=", self._name)],
auto_join=True,
)
@@ -716,6 +716,8 @@ class SoongWorkflowMixin(models.AbstractModel):
if button.is_highlight:
btn_exec_action_el.set("class", "oe_highlight")
# if button.is_high_red:
# btn_exec_action_el.set("style", "background-color: red !important;color: white !important;")
if button.has_icon:
btn_exec_action_el.set("icon", button.icon)
if is_review_type_invisible:
+66 -45
View File
@@ -84,10 +84,9 @@ class SoongWorkflowNode(models.Model):
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")
is_carbon_copy = fields.Boolean(string="抄送")
is_carbon_copy = fields.Boolean(string="抄送/传阅")
is_apostille = fields.Boolean(string="加签", default=False)
employee_ids = fields.Many2many('hr.employee', string='抄送人员')
employee_ids = fields.Many2many('hr.employee', string='抄送/传阅人员')
@api.onchange("is_apostille")
def onchange_is_apostille(self):
@@ -95,7 +94,7 @@ class SoongWorkflowNode(models.Model):
if record.is_apostille:
sequence = max([r.sequence for r in record.button_ids] if record.button_ids else [1])
record.button_ids = [
(0, 0, {
(0, 0, {
"name": _("加签"),
"workflow_id": record.workflow_id,
"node_id": record.id,
@@ -117,60 +116,76 @@ class SoongWorkflowNode(models.Model):
else:
record.button_ids.filtered(lambda r: r.name in ["加签", "加签确认"]).unlink()
@api.model_create_multi
def create(self, values):
for val in values:
if val['node_name'] != 'end':
if not val["button_ids"]:
if val['node_name'] == 'start':
val["button_ids"] = [
records = super().create(values)
for record in records:
if record.node_name != 'end':
if not record.button_ids:
if record.node_name == 'start':
record.write({"button_ids": [
(0, 0, {
"name": _("转交"),
"workflow_id": val['workflow_id'],
"sequence": 1,
},),
"workflow_id": record.workflow_id.id,
"sequence": 1}),
(0, 0, {
"name": _("收回"),
"workflow_id": val['workflow_id'],
"workflow_id": record.workflow_id.id,
"sequence": 2,
"action_type": "code",
"code": "obj.action_withdraw()",
},)]
elif val['node_name'] == '分发':
val["button_ids"] = [
(0, 0, {
"name": _("分发"),
"workflow_id": val['workflow_id'],
"sequence": 1,
"action_type": "code",
"has_comment": True,
},)]
})
]})
elif record.node_name == '分发':
record.write({"button_ids": [(0, 0, {
"name": _("分发"),
"workflow_id": record.workflow_id.id,
"sequence": 1,
"action_type": "code",
"has_comment": True,
})]})
else:
val["button_ids"] = [
record.write({"button_ids": [
(0, 0, {
"name": _("转交"),
"workflow_id": val['workflow_id'],
"workflow_id": record.workflow_id.id,
"sequence": 1,
"action_type": "code",
"has_comment": True,
},),
"has_comment": True}),
(0, 0, {
"name": _("收回"),
"workflow_id": val['workflow_id'],
"workflow_id": record.workflow_id.id,
"sequence": 2,
"action_type": "code",
"code": "obj.action_withdraw()",
},),
"code": "obj.action_withdraw()"}),
(0, 0, {
"name": _("退回"),
"workflow_id": val['workflow_id'],
"workflow_id": record.workflow_id.id,
"sequence": 2,
"action_type": "code",
"has_comment": True,
},)]
return super().create(values)
"has_comment": True})
]})
# 运行时执行加载所有form,并且只读
model_id = self.env['soong.workflow'].search([('id', '=', record.workflow_id.id), ('is_enable', '=', True)]).model_id
form_view = self.env["ir.ui.view"].search([("model", "=", model_id.model), ("type", "=", "form")], limit=1)
if form_view:
xml_tree = etree.fromstring(form_view.arch)
field_names = set()
for field_node in xml_tree.xpath("//field"):
field_name = field_node.get("name")
if field_name:
field_names.add(field_name)
for field in self.env["ir.model.fields"].search(
[("model_id", "=", model_id.id), ("name", "in", list(field_names))]):
self.field_ids.create({
"model_id": model_id.id,
"node_id": record.id,
"name": field.id,
"readonly": True,
})
else:
raise UserError('该模型未找到form视图')
return records
@api.depends("bg_color", "label_color", "use_custom_colors", "flow_start", "flow_end")
def _compute_custom_colors(self):
@@ -205,7 +220,8 @@ class SoongWorkflowNode(models.Model):
# 加载form视图中的字段
for rec in self:
rec.field_ids.unlink()
form_view = self.env["ir.ui.view"].search([("model", "=", rec.model_id.model), ("type", "=", "form")], limit=1)
form_view = self.env["ir.ui.view"].search([("model", "=", rec.model_id.model), ("type", "=", "form")],
limit=1)
if form_view:
xml_tree = etree.fromstring(form_view.arch)
field_names = set()
@@ -213,12 +229,13 @@ class SoongWorkflowNode(models.Model):
field_name = field_node.get("name")
if field_name:
field_names.add(field_name)
for field in self.env["ir.model.fields"].search([("model_id", "=", rec.model_id.id), ("name", "in", list(field_names))]):
for field in self.env["ir.model.fields"].search(
[("model_id", "=", rec.model_id.id), ("name", "in", list(field_names))]):
rec.field_ids.create({
"model_id": rec.model_id.id,
"node_id": rec.id,
"name": field.id,
})
"model_id": rec.model_id.id,
"node_id": rec.id,
"name": field.id,
})
else:
raise UserError('该模型未找到form视图')
@@ -256,6 +273,7 @@ class SoongWorkflowNodeButton(models.Model):
)
is_highlight = fields.Boolean(string="Is Highlighted", default=True,
help="Control highlighting of the button if needs user attention..", )
# is_high_red = fields.Boolean(string="红色突出")
has_icon = fields.Boolean(
string="Has Icon", help="Enable it to add icon to the button."
)
@@ -281,7 +299,8 @@ class SoongWorkflowNodeButton(models.Model):
)
reviewer_id = fields.Many2one(comodel_name="res.users", string="Reviewer")
reviewer_group_id = fields.Many2one(comodel_name="res.groups", string="Reviewer group")
users_role_id = fields.Many2one(comodel_name="soong.user.role", string="主角色", domain=[('user_type', '!=', 'lv_role')])
users_role_id = fields.Many2one(comodel_name="soong.user.role", string="主角色",
domain=[('user_type', '!=', 'lv_role')])
reviewer_expression = fields.Text(
string="Review Expression",
default=CONDITION_CODE_TEMP,
@@ -331,7 +350,8 @@ class SoongWorkflowNodeButton(models.Model):
ondelete="cascade",
)
invisible_expression_model = fields.Char(related="workflow_id.model_id.model")
is_automatic = fields.Boolean('是否自动匹配', default=True, help='该节点默认拟办人员的部门相应人员。必须是系统全局角色')
is_automatic = fields.Boolean('是否自动匹配', default=True,
help='该节点默认拟办人员的部门相应人员。必须是系统全局角色')
@api.onchange("node_id")
def change_workflow(self):
@@ -430,7 +450,8 @@ class SoongWorkflowNodeButton(models.Model):
elif button_id.review_type == "group":
user_ids += button_id.reviewer_group_id.users.ids
elif button_id.review_type == "user_role":
user_role_id = self.env['res.users'].search([('employee_id.user_role_id', '=', button_id.users_role_id.id)])
user_role_id = self.env['res.users'].search(
[('employee_id.user_role_id', '=', button_id.users_role_id.id)])
user_ids += user_role_id.ids
# # 发送信息提醒
# partner_ids = self.sudo().env['res.users'].search([('id', 'in', user_ids)]).mapped('partner_id').ids
@@ -24,6 +24,7 @@ class SoongWorkflowRecord(models.Model):
rec.name = False
name = fields.Char(string="Name", compute="compute_name", store=True)
code = fields.Char(string="流水号")
res_model = fields.Char(string="Res Model", required=True)
res_id = fields.Integer(string="Res ID", required=True)
users_ids = fields.Many2many('res.users', string="用户")
@@ -1,19 +1,18 @@
<?xml version="1.0" encoding="UTF-8" ?>
<odoo>
<template id="soong_workflow_log">
<field name="log_ids" invisible="not log_ids" style="width:100%%; margin-top: 10px;">
<tree create="false" edit="false" delete="false" editable="bottom">
<field name="sequence" string=""/>
<field name="name" string=""/>
<!-- <field name="node_btn_id" />-->
<field name="done_by" string=""/>
<field name="lase_click_date" string=""/>
<field name="comment" string=""/>
<field name="approval_state" string=""/>
<field name="node_btn_name" string=""/>
</tree>
</field>
<group string="审批详情" invisible="not log_ids">
<field name="log_ids" invisible="not log_ids" style="width:100%%; margin-top: 10px;">
<tree create="false" edit="false" delete="false" editable="bottom">
<field name="sequence" string=""/>
<field name="name" string=""/>
<field name="done_by" string=""/>
<field name="lase_click_date" string=""/>
<field name="comment" string=""/>
<field name="approval_state" string=""/>
<field name="node_btn_name" string=""/>
</tree>
</field>
</group>
</template>
</odoo>
+16 -23
View File
@@ -14,17 +14,27 @@
sequence="3"/>
<menuitem id="menu_workflow_approval_request_my"
name="我的流程"
name="待办流程"
parent="menu_soong_workflow_root"
action="soong_workflow_record_action"
sequence="1"/>
<menuitem id="menu_workflow_approval_request_copy"
name="抄送/传阅流程"
parent="menu_soong_workflow_root"
action="soong_workflow_record_action"
sequence="2"/>
<menuitem id="menu_workflow_approval_request_entrust"
name="委托流程"
parent="menu_soong_workflow_root"
action="soong_workflow_record_action"
sequence="3"/>
<menuitem id="menu_workflow_approval_request_all"
name="流程查询"
parent="menu_soong_workflow_root"
action="soong_workflow_record_action_all"
sequence="2"/>
日程
sequence="4"/>
<menuitem id="menu_soong_workflow_entrust"
sequence="5"
name="流程委托"
@@ -38,30 +48,13 @@
sequence="7"/>
<menuitem id="menu_soong_workflow_inspector_approval"
sequence="4"
name="督察审批"
sequence="5"
name="督办审批"
action="soong_workflow_inspector_action"
parent="menu_soong_workflow_root"/>
<!-- <menuitem id="menu_soong_workflow_inspector_transact"-->
<!-- sequence="3"-->
<!-- name="督察办理"-->
<!-- parent="menu_soong_workflow_inspector"/>-->
<!-- 督办事项的表单 -->
<!-- <menuitem id="menu_soong_workflow_inspector_transact_sth"-->
<!-- sequence="1"-->
<!-- name="督察事项"-->
<!-- action="soong_workflow_inspector_line_action"-->
<!-- parent="menu_soong_workflow_inspector_transact"/>-->
<!-- <menuitem id="menu_soong_workflow_inspector_transact_my"-->
<!-- sequence="3"-->
<!-- name="我的任务"-->
<!-- action="soong_workflow_inspector_line_action"-->
<!-- parent="menu_soong_workflow_inspector_transact"/>-->
<menuitem id="menu_soong_other_setting"
sequence="5"
sequence="6"
name="其他配置"
parent="menu_soong_workflow_root"
action="soong_note_action"/>
@@ -6,6 +6,7 @@
<field name="model">soong.workflow.log</field>
<field name="arch" type="xml">
<tree string="工作流日志" default_order="lase_click_date desc">
<field name="sequence"/>
<field name="name"/>
<field name="code"/>
<!-- <field name="model"/>-->
@@ -149,6 +149,7 @@
<field name="sequence" required="1"/>
<field name="name" required="1"/>
<field name="is_highlight"/>
<!-- <field name="is_high_red"/>-->
<field name="has_comment"/>
<field name="is_automatic"/>
</group>
@@ -20,6 +20,7 @@
<tree string="WorkFollow Record" action="open_record" delete="false" type="object"
decoration-muted="approve_state == 'end'" decoration-warning="approve_state != 'end'"
create="false" default_order="write_date desc">
<field name="code"/>
<field name="name"/>
<field name="workflow_id" string="审批类型"/>
<field name="node_id" string="当前节点"/>
@@ -115,10 +115,10 @@ class SoongWorkflowCommentWizard(models.TransientModel):
self.ensure_one()
cx = self.env.context.copy() or {}
record_id = self.env[self.res_model].search([('id', '=', self.res_id)])
# 抄送人员
if self.node_btn_name == '转交':
self_node_id = record_id.workflow_id.node_ids.search(
[('name', '=', record_id.state), ('workflow_id', '=', record_id.workflow_id.id)])
self_node_id = record_id.workflow_id.node_ids.search([('name', '=', record_id.state), ('workflow_id', '=', record_id.workflow_id.id)])
# 工作流更新,转交节点日志记录。
now_record_obj = self.sudo().env["soong.workflow.log"].search(
[("model", "=", self.res_model),
("res_id", "=", self.res_id),
@@ -128,8 +128,7 @@ class SoongWorkflowCommentWizard(models.TransientModel):
("node_btn_id", "=", self.node_btn_id.id),
], order="lase_click_date DESC", limit=1)
if not now_record_obj:
now_record_obj = self.sudo().env["soong.workflow.log"].create(
{
now_record_obj = self.sudo().env["soong.workflow.log"].create({
"model": self.res_model,
"res_id": self.res_id,
"node_id": self.node_btn_id.node_id.id,
@@ -139,8 +138,7 @@ class SoongWorkflowCommentWizard(models.TransientModel):
"node_btn_id": self.node_btn_id.id,
"lase_click_date": fields.Datetime.now(),
"approval_state": "2"
}
)
})
now_record_obj.write({"comment": self.comment_note_id.name, "approval_state": "2"})
if self_node_id.is_carbon_copy:
for employee in self_node_id.employee_ids:
@@ -191,14 +189,14 @@ class SoongWorkflowCommentWizard(models.TransientModel):
('department_id', '=', record_id.department_id.id),
('department_ids', 'in', record_id.department_id.id)])
employee_ids = employee_user_role_ids if not is_automatic else employee_user_role_id
record_obj = self.sudo().env["soong.workflow.log"].search([("model", "=", self.res_model),
("res_id", "=", self.res_id),
("node_id", "=", next_node_id.id),
("workflow_id", "=", record_id.workflow_id.id),
("node_btn_name", "=", "0"),
record_obj = self.sudo().env["soong.workflow.log"].search([("model", "=", self.res_model), ("res_id", "=", self.res_id)])[-1]
# ("node_id", "=", next_node_id.id),
# ("workflow_id", "=", record_id.workflow_id.id),
# ("node_btn_name", "=", "0"),
# ("node_btn_id", "=", record_id.node_btn_id.id),
], order="lase_click_date DESC", limit=1)
if not record_obj:
# ], order="lase_click_date DESC", limit=1)
# 生成下一个节点的数据。如果当前节点不等于当前状态创建新数据
if record_id.state != record_obj.name:
record_obj = self.sudo().env["soong.workflow.log"].create(
{
"model": self.res_model,
@@ -262,12 +260,6 @@ class SoongWorkflowCommentWizard(models.TransientModel):
}
)
return self.node_btn_id.with_context(cx).run()
# # 填写审批记录
# if self.node_btn_name != '加签':
# self.log_ids.write({"comment": self.comment_note_id.name})
# # 加签人员写入
# if self.node_btn_name == '加签':
# record_id.approval_sign_ids = self.approval_users_ids
# if self.node_btn_name == '分发':
# if self.circulated_employee_ids:
# url = 'https://oa.thtzjt.com/mail/view?model={}&res_id={}'.format(self.res_model, self.res_id)
@@ -282,7 +274,7 @@ class SoongWorkflowCommentWizard(models.TransientModel):
# url=url, btntxt="查看详情")
# partner_ids = self.circulated_employee_ids.user_id.partner_id.ids
# self.with_context(lang=self.env.lang)._message_auto_subscribe_notify(partner_ids,'soong_workflow.message_soong_workflow_distribute')
if self.employee_ids:
state = self.node_btn_id.node_id.out_link_ids.name.split('-> ')[-1]
record_id.write({'state': 'end' if state == '结束' else state})
if self.employee_ids:
state = self.node_btn_id.node_id.out_link_ids.name.split('-> ')[-1]
record_id.write({'state': 'end' if state == '结束' else state})
return self.node_btn_id.with_context(cx).run()
+3 -4
View File
@@ -25,11 +25,10 @@ class CardApprovals(models.Model):
reason_application = fields.Html(string="申请事由")
documents_ids = fields.Many2many('ir.attachment', string="附件")
attendance_id = fields.Many2one('hr.attendance', string="补卡日期")
replacement_time = fields.Selection([('work', '上班卡'), ('quitting', '下班卡'), ('all', '全天卡')], string="补卡",
compute='_compute_replacement_time')
replacement_time = fields.Selection([('work', '上班卡'), ('quitting', '下班卡'), ('all', '全天卡')], string="补卡")
@api.depends('attendance_id')
def _compute_replacement_time(self):
@api.onchange('attendance_id')
def onchange_replacement_time(self):
for rep in self:
rep.replacement_time = None
if rep.attendance_id.is_early_card and not rep.attendance_id.is_late_card:
+2 -2
View File
@@ -26,7 +26,7 @@
<field name="reason_application"/>
<field name="documents_ids" widget="preview_many2many"/>
</group>
<group string="个人信息" col="4">
<group col="4">
<group>
<field name="users_id"/>
<field name="employee_id" invisible="1"/>
@@ -36,7 +36,7 @@
<field name="attendance_id" domain="[('employee_id', '=', employee_id), ('is_abnormal', '=', 1)]"/>
</group>
<group>
<field name="replacement_time" readonly='0'/>
<field name="replacement_time"/>
</group>
<group>
<field name="shift_id" invisible="1"/>
+2 -2
View File
@@ -52,8 +52,8 @@ class YuthonWillTask(models.Model):
def will_task_time(self):
for i in self.search([('state', '=', 'will')]):
if datetime.now() + timedelta(hours=8) > self.start_time:
i.write({'state', 'done'})
if datetime.now() + timedelta(hours=8) > i.start_time:
i.write({'state': 'done'})
for task in self.search([('state', '=', 'will')]):
now = datetime.now() + timedelta(hours=8)
start_time = task.start_time + timedelta(hours=8)