From 5d9572f152e1a8ce40ba90df236749c008512d87 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E6=9D=8E=E9=B9=8F=E5=AE=87?=
Date: Mon, 21 Apr 2025 08:24:42 +0800
Subject: [PATCH] 1
---
docx_report_pro/controllers/controllers.py | 4 +-
docx_report_pro/models/ir_actions_report.py | 19 +++-
docx_report_pro/views/views.xml | 11 +-
search_panel_extension/__manifest__.py | 2 +-
.../static/src/js/search_model.js | 72 ++++++------
.../wizard/soong_workflow_comment_wizard.py | 4 +-
tree_view_advanced_filter/__init__.py | 1 +
tree_view_advanced_filter/override_relaxng.py | 21 ++++
tree_view_advanced_filter/rng/tree_view.rng | 104 ++++++++++++++++++
.../list_arch_parser.js | 19 ++++
.../src/tree_view_advanced_filter/tree.js | 1 +
11 files changed, 208 insertions(+), 50 deletions(-)
create mode 100644 tree_view_advanced_filter/override_relaxng.py
create mode 100644 tree_view_advanced_filter/rng/tree_view.rng
create mode 100644 tree_view_advanced_filter/static/src/tree_view_advanced_filter/list_arch_parser.js
diff --git a/docx_report_pro/controllers/controllers.py b/docx_report_pro/controllers/controllers.py
index 39db997bb..8377cfbbd 100644
--- a/docx_report_pro/controllers/controllers.py
+++ b/docx_report_pro/controllers/controllers.py
@@ -152,7 +152,9 @@ class ReportControllerDocx(ReportController):
ids = [int(x) for x in docids.split(",")]
obj = request.env[report.model].browse(ids)
if report.print_report_name and not len(obj) > 1:
- report_name = safe_eval(report.print_report_name, {"object": obj, "time": time})
+ report_name = safe_eval(
+ report.print_report_name, {"object": obj, "time": time}
+ )
filename = "%s.%s" % (report_name, extension)
response.headers.add(
"Content-Disposition", content_disposition(filename)
diff --git a/docx_report_pro/models/ir_actions_report.py b/docx_report_pro/models/ir_actions_report.py
index af51a4be8..246f8aaa6 100644
--- a/docx_report_pro/models/ir_actions_report.py
+++ b/docx_report_pro/models/ir_actions_report.py
@@ -171,6 +171,23 @@ class IrActionsReport(models.Model):
def _render_docx(self, report_ref, res_ids, data=None):
return self.render_docx(report_ref, res_ids, data)
+ def _get_context(self, doc):
+ # [XSK] TODO(2025/4/20 22:01):
+ # 改成递归获取关联字段,
+ # 但是可能会存在无限递归的字段,需要注意
+ # 可以添加最大递归层级,超过最大递归层级时停止递归
+ deep_field_type = ['many2one', 'many2many', 'one2many']
+ doc.ensure_one()
+ context = doc.sudo().read()[0]
+ fields_dict = doc.fields_get()
+ for field, field_info in fields_dict.items():
+ try:
+ if field_info['type'] in deep_field_type:
+ context[field] = doc[field].sudo().read()
+ except Exception as e:
+ _logger.error("Error get field " + field + " in model " + doc._name + " " + str(e))
+ return context
+
@api.model
def render_docx(self, report_ref, docids, data=None):
self = self.sudo()
@@ -195,7 +212,7 @@ class IrActionsReport(models.Model):
for doc in data["docs"]:
# add all record fields by default data to insert
- context = doc.sudo().read()[0]
+ context = self._get_context(doc)
# add prepare python method data to insert
if self.python_function_prepare:
diff --git a/docx_report_pro/views/views.xml b/docx_report_pro/views/views.xml
index f4ef16ed6..cbcd4bb78 100644
--- a/docx_report_pro/views/views.xml
+++ b/docx_report_pro/views/views.xml
@@ -15,13 +15,13 @@
+ invisible="report_type not in ['docx']" />
+ invisible="report_type not in ['docx']" />
-
-
+
+
Change rights and give all users access + writing to the directory you want the documents to be saved in: /tmp/backups
-
- 报表类型
-
diff --git a/search_panel_extension/__manifest__.py b/search_panel_extension/__manifest__.py
index 4f7553f81..c583e9f4c 100644
--- a/search_panel_extension/__manifest__.py
+++ b/search_panel_extension/__manifest__.py
@@ -9,7 +9,7 @@
'license': 'LGPL-3',
'depends': ['base', 'sale_management'],
'data': [
- 'views/product_views.xml',
+ # 'views/product_views.xml',
],
'assets': {
'web.assets_backend': [
diff --git a/search_panel_extension/static/src/js/search_model.js b/search_panel_extension/static/src/js/search_model.js
index e2b5b6c1d..a29db4d47 100644
--- a/search_panel_extension/static/src/js/search_model.js
+++ b/search_panel_extension/static/src/js/search_model.js
@@ -1,7 +1,7 @@
/** @odoo-module */
-import {SearchModel} from "@web/search/search_model";
-import {Domain} from "@web/core/domain";
-import {patch} from "@web/core/utils/patch";
+import { SearchModel } from "@web/search/search_model";
+import { Domain } from "@web/core/domain";
+import { patch } from "@web/core/utils/patch";
export function childrenSize(children) {
if (children instanceof Map) {
@@ -10,16 +10,15 @@ export function childrenSize(children) {
return children.length
} else if (children instanceof Object) {
return Object.keys(children).length > 0
- } else {
+ }else {
return false
}
}
patch(SearchModel.prototype, {
- _createFilterTree(sectionId, result) {
- debugger;
+ _createFilterTree(sectionId, result) {
super._createFilterTree(sectionId, result)
- let {values} = result;
+ let { values } = result;
const filter = this.sections.get(sectionId)
const valIds = result['values'].map(item => item.id).filter(item => item)
@@ -28,28 +27,30 @@ patch(SearchModel.prototype, {
groups.forEach((group, key) => {
// 求和
// Array.from(group.values.values()).map(item => item.__count).reduce((acc, cur) => acc + cur, 0)
- group.__count = (values.find(item => item.id === key)?.__count ?? 0)
- if (!key) {
+ group.__count = values.find(item => item.id === key)?.__count ?? 0;
+ if (!key) return;
+
+ const currentItem = values.find(item => item.id === key); // 集中获取当前项
+ const group_id = currentItem?.group_id;
+
+ const parentGroup = valIds.includes(group_id)
+ ? groups.get(group_id)
+ : groups.get(false);
+
+ if (!parentGroup) return;
+
+ // 统一处理子节点逻辑
+ if (group_id === key) {
+ group.parent = false;
return;
}
- const group_id = values.find(item => item.id === key)?.group_id
- if (valIds.includes(group_id)) {
- if (group_id === key) {
- group.parent = false;
- return;
- }
- if (!childrenSize(groups.get(group_id).children)) {
- groups.get(group_id).children = new Map()
- }
- groups.get(group_id).children.set(key, group)
- } else {
- if (!groups.get(false)) return;
- if (!childrenSize(groups.get(false).children)) {
- groups.get(group_id).children = new Map()
- }
- groups.get(false).children.set(key, group)
+
+ if (!parentGroup.children || !childrenSize(parentGroup.children)) {
+ parentGroup.children = new Map();
}
- group.parent = group_id;
+
+ parentGroup.children.set(key, group);
+ group.parent = parentGroup === groups.get(false) ? false : group_id;
})
}
filter.groups = groups;
@@ -96,8 +97,8 @@ patch(SearchModel.prototype, {
if (groups) {
groups.forEach((group, key) => {
// Array.from(group.values.values()).map(item => item.__count).reduce((acc, cur) => acc + cur, 0)
- group.__count = (Array.from(section?.values?.values() ?? []).find(item => item.id === key)?.__count ?? 0);
- const group_id = Array.from(section?.values?.values() ?? []).find(item => item.id === key)?.group_id;
+ group.__count = (section.values.values().find(item => item.id === key)?.__count ?? 0)
+ const group_id = section.values.values().find(item => item.id === key)?.group_id
if (ids.includes(group_id)) {
if (group_id === key) {
group.parent = false;
@@ -109,11 +110,8 @@ patch(SearchModel.prototype, {
groups.get(group_id).children.set(key, group)
} else {
if (!groups.get(false)) return;
- // if (!childrenSize(groups.get(false).children)) {
- // groups.get(group_id).children = new Map()
- // }
- if (!childrenSize(groups.get(group_id).children)) {
- groups.get(group_id).children = new Map();
+ if (!childrenSize(groups.get(false).children)) {
+ groups.get(group_id).children = new Map()
}
groups.get(false).children.set(key, group)
}
@@ -130,7 +128,6 @@ patch(SearchModel.prototype, {
// debugger;
const domain = [];
const domainList = [];
-
function addCondition(fieldName, valueMap) {
const ids = [];
for (const [valueId, value] of valueMap) {
@@ -143,12 +140,11 @@ patch(SearchModel.prototype, {
domainList.push(it);
}
}
-
for (const filter of this.filters) {
if (filter.id === excludedFilterId) {
continue;
}
- const {fieldName, groups, values} = filter;
+ const { fieldName, groups, values } = filter;
if (groups) {
for (const group of groups.values()) {
addCondition(fieldName, group.values);
@@ -163,8 +159,8 @@ patch(SearchModel.prototype, {
_getGroupDomain(filter) {
// debugger;
- const {fieldName, groups, enableCounters} = filter;
- const {type: fieldType} = this.searchViewFields[fieldName];
+ const { fieldName, groups, enableCounters } = filter;
+ const { type: fieldType } = this.searchViewFields[fieldName];
const groupDomain = super._getGroupDomain(filter);
diff --git a/soong_workflow/wizard/soong_workflow_comment_wizard.py b/soong_workflow/wizard/soong_workflow_comment_wizard.py
index 6628d59cf..b32980686 100644
--- a/soong_workflow/wizard/soong_workflow_comment_wizard.py
+++ b/soong_workflow/wizard/soong_workflow_comment_wizard.py
@@ -96,8 +96,8 @@ class SoongWorkflowCommentWizard(models.TransientModel):
employee_user_role_id = self.env['hr.employee'].search(
['|', ('user_role_id', '=', link_users_id.id), ('user_role_ids', 'in', link_users_id.id),
'|', ('department_id', '=', record_id.department_id.parent_id.id), ('department_ids', 'in', record_id.department_id.parent_id.id)])
- self.employee_trans_domain_ids = employee_user_role_ids if next_is_automatic else employee_user_role_id
- self.employee_ids = employee_user_role_ids if next_is_automatic else employee_user_role_id
+ self.employee_trans_domain_ids = employee_user_role_ids if not next_is_automatic else employee_user_role_id
+ self.employee_ids = employee_user_role_ids if not next_is_automatic else employee_user_role_id
if '分发' in ret.name:
self.employee_ids = record_id.users_id.employee_id
diff --git a/tree_view_advanced_filter/__init__.py b/tree_view_advanced_filter/__init__.py
index 40a96afc6..be0b804c9 100644
--- a/tree_view_advanced_filter/__init__.py
+++ b/tree_view_advanced_filter/__init__.py
@@ -1 +1,2 @@
# -*- coding: utf-8 -*-
+from . import override_relaxng
diff --git a/tree_view_advanced_filter/override_relaxng.py b/tree_view_advanced_filter/override_relaxng.py
new file mode 100644
index 000000000..d7cd6fb72
--- /dev/null
+++ b/tree_view_advanced_filter/override_relaxng.py
@@ -0,0 +1,21 @@
+# -*- coding: utf-8 -*-
+import os
+import logging
+from lxml import etree
+from odoo import tools
+from odoo.tools import view_validation
+
+_logger = logging.getLogger(__name__)
+
+_relaxng_cache = view_validation._relaxng_cache
+_relaxng_cache['tree'] = None
+
+
+with tools.file_open(os.path.join(os.path.dirname(__file__), 'rng', 'tree_view.rng')) as frng:
+ try:
+ text = frng.read()
+ relaxng_doc = etree.fromstring(text.encode('utf-8'))
+ _relaxng_cache['tree'] = etree.RelaxNG(relaxng_doc)
+ except Exception as error:
+ _logger.exception('Failed to load RelaxNG XML schema for views validation, {error}'.format(error=error))
+ _relaxng_cache['search'] = None
diff --git a/tree_view_advanced_filter/rng/tree_view.rng b/tree_view_advanced_filter/rng/tree_view.rng
new file mode 100644
index 000000000..bd0b869ff
--- /dev/null
+++ b/tree_view_advanced_filter/rng/tree_view.rng
@@ -0,0 +1,104 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ top
+ bottom
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tree_view_advanced_filter/static/src/tree_view_advanced_filter/list_arch_parser.js b/tree_view_advanced_filter/static/src/tree_view_advanced_filter/list_arch_parser.js
new file mode 100644
index 000000000..3f1606bd6
--- /dev/null
+++ b/tree_view_advanced_filter/static/src/tree_view_advanced_filter/list_arch_parser.js
@@ -0,0 +1,19 @@
+/** @odoo-module **/
+import { archParseBoolean } from "@web/views/utils";
+import { patch } from "@web/core/utils/patch";
+import { visitXML, parseXML } from "@web/core/utils/xml";
+import { ListArchParser } from "@web/views/list/list_arch_parser";
+
+
+patch(ListArchParser.prototype, {
+
+ parse(arch, models, modelName) {
+ let parse_return = super.parse(arch, models, modelName);
+ visitXML(arch, (node) => {
+ if (["tree", "list"].includes(node.tagName)){
+ parse_return.advanced_filter = archParseBoolean(arch.getAttribute("advanced_filter"), false);
+ }
+ });
+ return parse_return
+ }
+})
\ No newline at end of file
diff --git a/tree_view_advanced_filter/static/src/tree_view_advanced_filter/tree.js b/tree_view_advanced_filter/static/src/tree_view_advanced_filter/tree.js
index a63450689..8c3dd0f9c 100644
--- a/tree_view_advanced_filter/static/src/tree_view_advanced_filter/tree.js
+++ b/tree_view_advanced_filter/static/src/tree_view_advanced_filter/tree.js
@@ -26,6 +26,7 @@ export const ListRendererCust = {
},
_renderSearchPanel: async function () {
+ if (!this.props.archInfo.advanced_filter) return;
// await loadJS("https://cdn.jsdelivr.net/jquery/latest/jquery.min.js")
// await loadJS("https://cdn.jsdelivr.net/momentjs/latest/moment.min.js")
// await loadJS("https://cdn.jsdelivr.net/npm/daterangepicker/daterangepicker.min.js")