From 22bd20c5202790073c194e957c046ffea1cac902 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=B9=8F=E5=AE=87?= <9664676+pengyuthon@user.noreply.gitee.com> Date: Wed, 17 Dec 2025 15:25:42 +0800 Subject: [PATCH 01/43] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- soong_workflow/models/soong_workflow_record.py | 4 ++-- yuthon_hr_attendance/views/go_approval.xml | 4 ++-- .../views/yuthon_message_login_views.xml | 2 +- .../views/yuthon_onboard_approval_views.xml | 6 +++--- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/soong_workflow/models/soong_workflow_record.py b/soong_workflow/models/soong_workflow_record.py index 36b6d7c50..74d7e599b 100644 --- a/soong_workflow/models/soong_workflow_record.py +++ b/soong_workflow/models/soong_workflow_record.py @@ -353,8 +353,8 @@ class SoongWorkflowRecord(models.Model): for record in record_ids: record_id = record.env[record.res_model].search([('id', '=', record.res_id)]) record_list.append(record.id) - if record_id.log_ids and self.env.user.name != "Administrator": - raise UserError("当前流程不可删除") + # if record_id.log_ids and self.env.user.name != "Administrator": + # raise UserError("当前流程不可删除") wizard = self.env.ref("soong_workflow.view_soong_workflow_record_delete_wizard") return { "name": _("删除确认"), diff --git a/yuthon_hr_attendance/views/go_approval.xml b/yuthon_hr_attendance/views/go_approval.xml index 001234a1a..86fb60055 100644 --- a/yuthon_hr_attendance/views/go_approval.xml +++ b/yuthon_hr_attendance/views/go_approval.xml @@ -67,8 +67,8 @@ - - + + diff --git a/yuthon_hr_employee_approval/views/yuthon_message_login_views.xml b/yuthon_hr_employee_approval/views/yuthon_message_login_views.xml index 3b2d269dd..f7de9a13a 100644 --- a/yuthon_hr_employee_approval/views/yuthon_message_login_views.xml +++ b/yuthon_hr_employee_approval/views/yuthon_message_login_views.xml @@ -92,7 +92,7 @@ - +
diff --git a/yuthon_hr_employee_approval/views/yuthon_onboard_approval_views.xml b/yuthon_hr_employee_approval/views/yuthon_onboard_approval_views.xml index 7a1118ad7..488881b76 100644 --- a/yuthon_hr_employee_approval/views/yuthon_onboard_approval_views.xml +++ b/yuthon_hr_employee_approval/views/yuthon_onboard_approval_views.xml @@ -34,15 +34,15 @@ + + + - - -

From f6b5e3bc31708dc17e7f07d82e2ca87573b55011 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=B9=8F=E5=AE=87?= <9664676+pengyuthon@user.noreply.gitee.com> Date: Wed, 17 Dec 2025 16:15:02 +0800 Subject: [PATCH 02/43] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- soong_workflow/wizard/soong_workflow_comment_wizard.py | 4 ++-- yuthon_notice/views/yuthon_notice_views.xml | 2 +- yuthon_report/views/att_report_view.xml | 6 +++--- yuthon_will_task/models/inherit_room_booking.py | 2 +- yuthon_work_brand/views/hr_menus.xml | 6 +++--- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/soong_workflow/wizard/soong_workflow_comment_wizard.py b/soong_workflow/wizard/soong_workflow_comment_wizard.py index 8138c458f..987fd467a 100644 --- a/soong_workflow/wizard/soong_workflow_comment_wizard.py +++ b/soong_workflow/wizard/soong_workflow_comment_wizard.py @@ -425,7 +425,7 @@ class SoongWorkflowCommentWizard(models.TransientModel): for employee in self.employee_ids: action_id = self.env['ir.actions.act_window'].search([('res_model', '=', self.res_model)])[0] - url = f'https://oa.thtzjt.com/web?login={employee.user_id.login}&oauth_uid={employee.wecom_userid}#id={record_id.id}&cids=2&action={action_id.id}&model={record_id._name}&view_type=form&menu_id=10104' + url = f'https://oa.thtzjt.com/web#id={record_id.id}&cids=2&active_id={action_id.id}&model={record_id._name}&view_type=form' self.sudo().env["wecom.apps"].sync_send_message_textcard(category='oa', user_id=employee.wecom_userid, title=record_id._description, @@ -623,7 +623,7 @@ class SoongWorkflowCommentWizard(models.TransientModel): employees = self.node_btn_id.workflow_id.employee_ids recipients = [emp for emp in employees] for employee in recipients: - url = f'https://oa.thtzjt.com/web?login={employee.user_id.login}&oauth_uid={employee.wecom_userid}#id={record_id.id}&cids=2&action={action_id.id}&model={record_id._name}&view_type=form&menu_id=10104' + url = f'https://oa.thtzjt.com/web#id={record_id.id}&cids=2&active_id={action_id.id}&model={record_id._name}&view_type=form' self.sudo().env["wecom.apps"].sync_send_message_textcard(category='oa', user_id=employee.wecom_userid, title=record_id._description, diff --git a/yuthon_notice/views/yuthon_notice_views.xml b/yuthon_notice/views/yuthon_notice_views.xml index 0c355020c..f760ae790 100644 --- a/yuthon_notice/views/yuthon_notice_views.xml +++ b/yuthon_notice/views/yuthon_notice_views.xml @@ -17,7 +17,7 @@ From 7cff04e0de33e09946c2b9ed143082d70f47fe07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=B9=8F=E5=AE=87?= <9664676+pengyuthon@user.noreply.gitee.com> Date: Fri, 19 Dec 2025 15:24:31 +0800 Subject: [PATCH 37/43] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../{ => header_search_panel}/README.md | 19 +- .../{ => header_search_panel}/__init__.py | 0 .../{ => header_search_panel}/__manifest__.py | 0 .../override_relaxng.py | 0 .../rng/search_view.rng | 0 .../static/src/legacy/backend_utils.js | 33 +++ .../src/search/control_panel/control_panel.js | 0 .../search/control_panel/control_panel.scss | 0 .../search/control_panel/control_panel.xml | 0 .../boolean_filter/boolean_filter.js | 0 .../boolean_filter/boolean_filter.xml | 0 .../fields_filter/char_filter/char_filter.js | 54 +++++ .../fields_filter/char_filter/char_filter.xml | 15 ++ .../fields_filter/date_filter/date_filter.js | 37 ++- .../fields_filter/date_filter/date_filter.xml | 37 +++ .../components/fields_filter/fields_filter.js | 15 ++ .../fields_filter/fields_filter.xml | 0 .../many2one_filter/many2one_filter.js | 1 + .../many2one_filter/many2one_filter.xml | 0 .../selection_filter/selection_filter.js | 0 .../selection_filter/selection_filter.xml | 0 .../standard_field_filter_props.js | 2 + .../x2many_filter/x2many_filter.js | 0 .../x2many_filter/x2many_filter.xml | 0 .../components/quick_filter/quick_filter.js | 0 .../components/quick_filter/quick_filter.xml | 4 +- .../quick_filter/quick_filter_label.scss | 0 .../select_date_filter/select_date_filter.js | 0 .../select_date_filter/select_date_filter.xml | 0 .../header_search/header_search_filter.js | 0 .../header_search/header_search_filter.scss | 14 +- .../header_search/header_search_filter.xml | 0 .../static/src/search/search_arch_parser.js | 14 +- .../static/src/search/search_model.js | 0 header_search_panel/model_test/__init__.py | 4 + .../model_test/__manifest__.py | 21 ++ .../model_test/controllers/__init__.py | 3 + .../model_test/controllers/controllers.py | 21 ++ .../model_test/models/__init__.py | 3 + .../model_test/models/models.py | 211 ++++++++++++++++++ .../model_test/security/ir.model.access.csv | 3 + .../model_test/static/src/model_test_list.xml | 17 ++ .../static/src/model_test_list_controller.js | 10 + .../model_test/views/views.xml | 126 +++++++++++ .../fields_filter/date_filter/date_filter.xml | 30 --- 45 files changed, 636 insertions(+), 58 deletions(-) rename header_search_panel/{ => header_search_panel}/README.md (79%) rename header_search_panel/{ => header_search_panel}/__init__.py (100%) rename header_search_panel/{ => header_search_panel}/__manifest__.py (100%) rename header_search_panel/{ => header_search_panel}/override_relaxng.py (100%) rename header_search_panel/{ => header_search_panel}/rng/search_view.rng (100%) create mode 100644 header_search_panel/header_search_panel/static/src/legacy/backend_utils.js rename header_search_panel/{ => header_search_panel}/static/src/search/control_panel/control_panel.js (100%) rename header_search_panel/{ => header_search_panel}/static/src/search/control_panel/control_panel.scss (100%) rename header_search_panel/{ => header_search_panel}/static/src/search/control_panel/control_panel.xml (100%) rename header_search_panel/{ => header_search_panel}/static/src/search/header_search/components/fields_filter/boolean_filter/boolean_filter.js (100%) rename header_search_panel/{ => header_search_panel}/static/src/search/header_search/components/fields_filter/boolean_filter/boolean_filter.xml (100%) create mode 100644 header_search_panel/header_search_panel/static/src/search/header_search/components/fields_filter/char_filter/char_filter.js create mode 100644 header_search_panel/header_search_panel/static/src/search/header_search/components/fields_filter/char_filter/char_filter.xml rename header_search_panel/{ => header_search_panel}/static/src/search/header_search/components/fields_filter/date_filter/date_filter.js (65%) create mode 100644 header_search_panel/header_search_panel/static/src/search/header_search/components/fields_filter/date_filter/date_filter.xml rename header_search_panel/{ => header_search_panel}/static/src/search/header_search/components/fields_filter/fields_filter.js (93%) rename header_search_panel/{ => header_search_panel}/static/src/search/header_search/components/fields_filter/fields_filter.xml (100%) rename header_search_panel/{ => header_search_panel}/static/src/search/header_search/components/fields_filter/many2one_filter/many2one_filter.js (98%) rename header_search_panel/{ => header_search_panel}/static/src/search/header_search/components/fields_filter/many2one_filter/many2one_filter.xml (100%) rename header_search_panel/{ => header_search_panel}/static/src/search/header_search/components/fields_filter/selection_filter/selection_filter.js (100%) rename header_search_panel/{ => header_search_panel}/static/src/search/header_search/components/fields_filter/selection_filter/selection_filter.xml (100%) rename header_search_panel/{ => header_search_panel}/static/src/search/header_search/components/fields_filter/standard_field_filter_props.js (88%) rename header_search_panel/{ => header_search_panel}/static/src/search/header_search/components/fields_filter/x2many_filter/x2many_filter.js (100%) rename header_search_panel/{ => header_search_panel}/static/src/search/header_search/components/fields_filter/x2many_filter/x2many_filter.xml (100%) rename header_search_panel/{ => header_search_panel}/static/src/search/header_search/components/quick_filter/quick_filter.js (100%) rename header_search_panel/{ => header_search_panel}/static/src/search/header_search/components/quick_filter/quick_filter.xml (92%) rename header_search_panel/{ => header_search_panel}/static/src/search/header_search/components/quick_filter/quick_filter_label.scss (100%) rename header_search_panel/{ => header_search_panel}/static/src/search/header_search/components/select_date_filter/select_date_filter.js (100%) rename header_search_panel/{ => header_search_panel}/static/src/search/header_search/components/select_date_filter/select_date_filter.xml (100%) rename header_search_panel/{ => header_search_panel}/static/src/search/header_search/header_search_filter.js (100%) rename header_search_panel/{ => header_search_panel}/static/src/search/header_search/header_search_filter.scss (96%) rename header_search_panel/{ => header_search_panel}/static/src/search/header_search/header_search_filter.xml (100%) rename header_search_panel/{ => header_search_panel}/static/src/search/search_arch_parser.js (96%) rename header_search_panel/{ => header_search_panel}/static/src/search/search_model.js (100%) create mode 100644 header_search_panel/model_test/__init__.py create mode 100644 header_search_panel/model_test/__manifest__.py create mode 100644 header_search_panel/model_test/controllers/__init__.py create mode 100644 header_search_panel/model_test/controllers/controllers.py create mode 100644 header_search_panel/model_test/models/__init__.py create mode 100644 header_search_panel/model_test/models/models.py create mode 100644 header_search_panel/model_test/security/ir.model.access.csv create mode 100644 header_search_panel/model_test/static/src/model_test_list.xml create mode 100644 header_search_panel/model_test/static/src/model_test_list_controller.js create mode 100644 header_search_panel/model_test/views/views.xml delete mode 100644 header_search_panel/static/src/search/header_search/components/fields_filter/date_filter/date_filter.xml diff --git a/header_search_panel/README.md b/header_search_panel/header_search_panel/README.md similarity index 79% rename from header_search_panel/README.md rename to header_search_panel/header_search_panel/README.md index 5339e4749..9e9d7b0bf 100644 --- a/header_search_panel/README.md +++ b/header_search_panel/header_search_panel/README.md @@ -6,7 +6,7 @@ - 快捷筛选(quick_filter) - 自选时间筛选(select_date_filter)(待移植) -- 字段搜索(field)(待移植) +- 字段搜索(field)(已移植) 通过这些筛选标签,用户可以更灵活地对列表视图中的数据进行筛选。 @@ -20,9 +20,9 @@ #### 支持的属性: -| 属性名 | 类型 | 说明 | 是否可选 | -| ------- | ------ | ---------- | ---- | -| `class` | String | 自定义 CSS 类名 | ✅ | +| 属性名 | 类型 | 说明 | 是否可选 | +| ------- | ------ |-------------------------------------------------------------------| ---- | +| `class` | String | 自定义 CSS 类名,
可使用class="header-search-inline"使所有筛选在同一行并根据宽度自动换行 | ✅ | #### 子标签支持: @@ -56,7 +56,7 @@ | ----------- | ------- | ----------- | ------------ | | `class` | String | 自定义 CSS 类名 | ✅ | | `string` | String | 显示的标头名称 | ✅ | -| `invisible` | Boolean | 是否默认隐藏 | ✅ | +| `invisible` | Boolean | 是否默认隐藏(废弃) | ✅ | | `options` | JSON | 扩展参数,支持以下参数: | ✅ | | | | `radio`: 是否单选 | | | | | `no_label`: 不显示标题 | | @@ -77,16 +77,16 @@ --- -### 3. 自选时间筛选 (select_date_filter) +### 3. 自选时间筛选 (select_date_filter)(废弃) **标签名:** `select_date_filter` #### 支持的属性: | 属性名 | 类型 | 说明 | 是否可选 | -| ------------------- | ------- | -------------- | ---- | +| ------------------- | ------- |----------------| ---- | | `class` | String | 自定义 CSS 类名 | ✅ | -| `invisible` | Boolean | 是否默认隐藏 | ✅ | +| `invisible` | Boolean | 是否默认隐藏(废弃) | ✅ | | `allow_date_fields` | String | 允许筛选的时间字段,逗号分隔 | ✅ | #### 示例: @@ -109,6 +109,9 @@ | `string` | String | 显示的标头名称 | ✅ | | `class` | String | 自定义 CSS | ✅ | | `invisible` | Boolean | 是否默认隐藏 | ✅ | +| `options` | JSON | 扩展参数,支持以下参数: | ✅ | +| | | `radio`: 是否单选 | | +| | | `no_label`: 不显示标题 | | #### 示例: diff --git a/header_search_panel/__init__.py b/header_search_panel/header_search_panel/__init__.py similarity index 100% rename from header_search_panel/__init__.py rename to header_search_panel/header_search_panel/__init__.py diff --git a/header_search_panel/__manifest__.py b/header_search_panel/header_search_panel/__manifest__.py similarity index 100% rename from header_search_panel/__manifest__.py rename to header_search_panel/header_search_panel/__manifest__.py diff --git a/header_search_panel/override_relaxng.py b/header_search_panel/header_search_panel/override_relaxng.py similarity index 100% rename from header_search_panel/override_relaxng.py rename to header_search_panel/header_search_panel/override_relaxng.py diff --git a/header_search_panel/rng/search_view.rng b/header_search_panel/header_search_panel/rng/search_view.rng similarity index 100% rename from header_search_panel/rng/search_view.rng rename to header_search_panel/header_search_panel/rng/search_view.rng diff --git a/header_search_panel/header_search_panel/static/src/legacy/backend_utils.js b/header_search_panel/header_search_panel/static/src/legacy/backend_utils.js new file mode 100644 index 000000000..6f77264e2 --- /dev/null +++ b/header_search_panel/header_search_panel/static/src/legacy/backend_utils.js @@ -0,0 +1,33 @@ +/** @odoo-module **/ +// +// import {patch} from "@web/core/utils/patch"; +// import * as backend_utils from "@web/legacy/backend_utils"; +// +// const originalSearchModelStateToLegacy = backend_utils.searchModelStateToLegacy; +// const originalGetGlobalState = backend_utils.getGlobalState; +// +// patch(backend_utils, "header_search_panel.backend_utils", { +// searchModelStateToLegacy(state) { +// // 原始state +// const originalState = JSON.parse(state); +// // 获取原始state +// let legacyState = JSON.parse(originalSearchModelStateToLegacy(state)); +// if (originalState.headerSearchInfo) { +// legacyState.HeaderSearchInfo = originalState.headerSearchInfo; +// } +// return JSON.stringify(legacyState) +// }, +// +// getGlobalState(legacyControllerState) { +// // 原始search model +// const originalSearchModel = JSON.parse(legacyControllerState.searchModel) +// let globalState = originalGetGlobalState(legacyControllerState); +// let searchModel = JSON.parse(globalState?.searchModel || "{}"); +// if (originalSearchModel.HeaderSearchInfo) { +// searchModel.headerSearchInfo = originalSearchModel.HeaderSearchInfo; +// globalState.searchModel = JSON.stringify(searchModel) +// } +// console.log('headerSearchInfo: getGlobalState') +// return globalState +// }, +// }) \ No newline at end of file diff --git a/header_search_panel/static/src/search/control_panel/control_panel.js b/header_search_panel/header_search_panel/static/src/search/control_panel/control_panel.js similarity index 100% rename from header_search_panel/static/src/search/control_panel/control_panel.js rename to header_search_panel/header_search_panel/static/src/search/control_panel/control_panel.js diff --git a/header_search_panel/static/src/search/control_panel/control_panel.scss b/header_search_panel/header_search_panel/static/src/search/control_panel/control_panel.scss similarity index 100% rename from header_search_panel/static/src/search/control_panel/control_panel.scss rename to header_search_panel/header_search_panel/static/src/search/control_panel/control_panel.scss diff --git a/header_search_panel/static/src/search/control_panel/control_panel.xml b/header_search_panel/header_search_panel/static/src/search/control_panel/control_panel.xml similarity index 100% rename from header_search_panel/static/src/search/control_panel/control_panel.xml rename to header_search_panel/header_search_panel/static/src/search/control_panel/control_panel.xml diff --git a/header_search_panel/static/src/search/header_search/components/fields_filter/boolean_filter/boolean_filter.js b/header_search_panel/header_search_panel/static/src/search/header_search/components/fields_filter/boolean_filter/boolean_filter.js similarity index 100% rename from header_search_panel/static/src/search/header_search/components/fields_filter/boolean_filter/boolean_filter.js rename to header_search_panel/header_search_panel/static/src/search/header_search/components/fields_filter/boolean_filter/boolean_filter.js diff --git a/header_search_panel/static/src/search/header_search/components/fields_filter/boolean_filter/boolean_filter.xml b/header_search_panel/header_search_panel/static/src/search/header_search/components/fields_filter/boolean_filter/boolean_filter.xml similarity index 100% rename from header_search_panel/static/src/search/header_search/components/fields_filter/boolean_filter/boolean_filter.xml rename to header_search_panel/header_search_panel/static/src/search/header_search/components/fields_filter/boolean_filter/boolean_filter.xml diff --git a/header_search_panel/header_search_panel/static/src/search/header_search/components/fields_filter/char_filter/char_filter.js b/header_search_panel/header_search_panel/static/src/search/header_search/components/fields_filter/char_filter/char_filter.js new file mode 100644 index 000000000..80cceca3a --- /dev/null +++ b/header_search_panel/header_search_panel/static/src/search/header_search/components/fields_filter/char_filter/char_filter.js @@ -0,0 +1,54 @@ +/** @odoo-module **/ + +import { Component } from "@odoo/owl"; +import { Domain } from "@web/core/domain"; +import { useService } from "@web/core/utils/hooks"; +import { Many2XAutocomplete } from "@web/views/fields/relational_utils"; +import { standardFieldFilterProps } from "../standard_field_filter_props.js" + + +export class CharFilter extends Component { + setup() { + super.setup(); + this.rpc = useService("rpc"); + this.activeValues = this.env.searchModel.headerSearchInfo.FieldsFilter[this.props.id]?.activeValues || undefined; + } + + /** + * 设置筛选字段的值 + */ + setActiveValues(ev) { + this.activeValues = ev.target.value; + } + + /** + * 获取筛选字段的domain + */ + get domain() { + return this.activeValues ? [[this.props.name, "ilike", this.activeValues]]: []; + } + + /** + * 点击清空筛选时触发 + */ + resetFilter() { + // 清空筛选字段的值 + this.activeValues = undefined; + this.props.fieldOnchange({fieldDomainList: this.domain, activeValues: this.activeValues}); + } + + getDomain() { + return new Domain(this.props.domain).toList({}); + } + + async onInputChange(ev) { + this.setActiveValues(ev); + this.props.fieldOnchange({fieldDomainList: this.domain, activeValues: this.activeValues}); + } +} + +CharFilter.template = "header_search_panel.CharFilter"; +CharFilter.components = {}; +CharFilter.props = { + ...standardFieldFilterProps, +}; diff --git a/header_search_panel/header_search_panel/static/src/search/header_search/components/fields_filter/char_filter/char_filter.xml b/header_search_panel/header_search_panel/static/src/search/header_search/components/fields_filter/char_filter/char_filter.xml new file mode 100644 index 000000000..66f439179 --- /dev/null +++ b/header_search_panel/header_search_panel/static/src/search/header_search/components/fields_filter/char_filter/char_filter.xml @@ -0,0 +1,15 @@ + + + + +
+ +
+
+ +
diff --git a/header_search_panel/static/src/search/header_search/components/fields_filter/date_filter/date_filter.js b/header_search_panel/header_search_panel/static/src/search/header_search/components/fields_filter/date_filter/date_filter.js similarity index 65% rename from header_search_panel/static/src/search/header_search/components/fields_filter/date_filter/date_filter.js rename to header_search_panel/header_search_panel/static/src/search/header_search/components/fields_filter/date_filter/date_filter.js index e72c40f44..d27ef8ff0 100644 --- a/header_search_panel/static/src/search/header_search/components/fields_filter/date_filter/date_filter.js +++ b/header_search_panel/header_search_panel/static/src/search/header_search/components/fields_filter/date_filter/date_filter.js @@ -1,8 +1,9 @@ /** @odoo-module **/ -import {Component} from "@odoo/owl"; -import {Domain} from "@web/core/domain"; -import {standardFieldFilterProps} from "../standard_field_filter_props.js" +import { Component } from "@odoo/owl"; +import { DateTimeInput } from "@web/core/datetime/datetime_input"; +import { deserializeDate } from "@web/core/l10n/dates"; +import { standardFieldFilterProps } from "../standard_field_filter_props.js" export class DateFilter extends Component { setup() { @@ -13,13 +14,21 @@ export class DateFilter extends Component { this.endDate = this.env.searchModel.headerSearchInfo.FieldsFilter[this.props.id]?.endDate; } + get dateFrom() { + return this.startDate ? deserializeDate(this.startDate): undefined; + } + + get dateTo() { + return this.endDate ? deserializeDate(this.endDate): undefined; + } + // 设置筛选字段的值 - setActiveValues(ev) { - const value = ev.target.value; - if (ev.target.id === this.props.id + "_start_date") { + setActiveValues(dateValue, type) { + const value = dateValue ? (this.props.type === "datetime" ? dateValue.toFormat("yyyy-MM-dd HH:mm:ss") : dateValue.toFormat("yyyy-MM-dd")) : undefined; + if (type === "startDate") { this.startDate = value } - if (ev.target.id === this.props.id + "_end_date") { + if (type === "endDate") { this.endDate = value } } @@ -41,9 +50,14 @@ export class DateFilter extends Component { return domain } - // 点击日期选择器时触发 - dateOnchange(ev) { - this.setActiveValues(ev); + startDateOnchange (startDate) { + this.setActiveValues(startDate, "startDate"); + this.props.fieldOnchange({fieldDomainList: this.domain, startDate: this.startDate, endDate: this.endDate}); + + } + + endDateOnchange (endDate) { + this.setActiveValues(endDate, "endDate"); this.props.fieldOnchange({fieldDomainList: this.domain, startDate: this.startDate, endDate: this.endDate}); } @@ -67,6 +81,9 @@ export class DateFilter extends Component { } DateFilter.template = "header_search_panel.DateFilter"; +DateFilter.components = { + DateTimeInput, +}; DateFilter.props = { ...standardFieldFilterProps, }; diff --git a/header_search_panel/header_search_panel/static/src/search/header_search/components/fields_filter/date_filter/date_filter.xml b/header_search_panel/header_search_panel/static/src/search/header_search/components/fields_filter/date_filter/date_filter.xml new file mode 100644 index 000000000..bf86c13a4 --- /dev/null +++ b/header_search_panel/header_search_panel/static/src/search/header_search/components/fields_filter/date_filter/date_filter.xml @@ -0,0 +1,37 @@ + + + + + + +
+ + + + + + + + + + + + + + + +
+ + + + + + + +
+ +
diff --git a/header_search_panel/static/src/search/header_search/components/fields_filter/fields_filter.js b/header_search_panel/header_search_panel/static/src/search/header_search/components/fields_filter/fields_filter.js similarity index 93% rename from header_search_panel/static/src/search/header_search/components/fields_filter/fields_filter.js rename to header_search_panel/header_search_panel/static/src/search/header_search/components/fields_filter/fields_filter.js index c70c0878c..0295ec005 100644 --- a/header_search_panel/static/src/search/header_search/components/fields_filter/fields_filter.js +++ b/header_search_panel/header_search_panel/static/src/search/header_search/components/fields_filter/fields_filter.js @@ -8,6 +8,7 @@ import { BooleanFilter } from "./boolean_filter/boolean_filter"; import { DateFilter } from "./date_filter/date_filter"; import { Many2oneFilter } from "./many2one_filter/many2one_filter"; import { X2ManyFilterFilter } from "./x2many_filter/x2many_filter"; +import { CharFilter } from "./char_filter/char_filter"; const fieldRegistry = registry.category("fields"); @@ -41,6 +42,9 @@ export class FieldsFilter extends Component { case "one2many": this.addX2ManyFieldDependencies(fieldInfo) break; + case "char": + this.addCharFieldDependencies(fieldInfo) + break; } return fieldInfo; } @@ -65,6 +69,9 @@ export class FieldsFilter extends Component { case "many2many": case "one2many": return X2ManyFilterFilter; + case "char": + return CharFilter; + } } @@ -128,6 +135,7 @@ export class FieldsFilter extends Component { domain: field.fieldDomain || "[]", fieldString: field.fieldString, searchLimit: field.fieldOptions?.search_limit || 10, + placeholder: field.placeholder, } this._addFieldBaseProps(field.props, field); } @@ -144,6 +152,13 @@ export class FieldsFilter extends Component { this._addFieldBaseProps(field.props, field); } + addCharFieldDependencies(field) { + field.Component = this._getComponent(field); + // 组件props + field.props = {}; + this._addFieldBaseProps(field.props, field); + } + // 筛选字段的onChange事件,将筛选字段的id和domain传给searchModel fieldFilterOnchange(fieldsFilterId, fieldsFilterInfo) { if (fieldsFilterInfo?.fieldDomainList){ diff --git a/header_search_panel/static/src/search/header_search/components/fields_filter/fields_filter.xml b/header_search_panel/header_search_panel/static/src/search/header_search/components/fields_filter/fields_filter.xml similarity index 100% rename from header_search_panel/static/src/search/header_search/components/fields_filter/fields_filter.xml rename to header_search_panel/header_search_panel/static/src/search/header_search/components/fields_filter/fields_filter.xml diff --git a/header_search_panel/static/src/search/header_search/components/fields_filter/many2one_filter/many2one_filter.js b/header_search_panel/header_search_panel/static/src/search/header_search/components/fields_filter/many2one_filter/many2one_filter.js similarity index 98% rename from header_search_panel/static/src/search/header_search/components/fields_filter/many2one_filter/many2one_filter.js rename to header_search_panel/header_search_panel/static/src/search/header_search/components/fields_filter/many2one_filter/many2one_filter.js index 1c80a1a04..4db0404ab 100644 --- a/header_search_panel/static/src/search/header_search/components/fields_filter/many2one_filter/many2one_filter.js +++ b/header_search_panel/header_search_panel/static/src/search/header_search/components/fields_filter/many2one_filter/many2one_filter.js @@ -104,6 +104,7 @@ export class Many2oneFilter extends Component { activeActions: {create: false, createEdit: false, write: false}, fieldString: this.props.fieldString, searchLimit: this.props.searchLimit, + placeholder: this.props.placeholder, }; } } diff --git a/header_search_panel/static/src/search/header_search/components/fields_filter/many2one_filter/many2one_filter.xml b/header_search_panel/header_search_panel/static/src/search/header_search/components/fields_filter/many2one_filter/many2one_filter.xml similarity index 100% rename from header_search_panel/static/src/search/header_search/components/fields_filter/many2one_filter/many2one_filter.xml rename to header_search_panel/header_search_panel/static/src/search/header_search/components/fields_filter/many2one_filter/many2one_filter.xml diff --git a/header_search_panel/static/src/search/header_search/components/fields_filter/selection_filter/selection_filter.js b/header_search_panel/header_search_panel/static/src/search/header_search/components/fields_filter/selection_filter/selection_filter.js similarity index 100% rename from header_search_panel/static/src/search/header_search/components/fields_filter/selection_filter/selection_filter.js rename to header_search_panel/header_search_panel/static/src/search/header_search/components/fields_filter/selection_filter/selection_filter.js diff --git a/header_search_panel/static/src/search/header_search/components/fields_filter/selection_filter/selection_filter.xml b/header_search_panel/header_search_panel/static/src/search/header_search/components/fields_filter/selection_filter/selection_filter.xml similarity index 100% rename from header_search_panel/static/src/search/header_search/components/fields_filter/selection_filter/selection_filter.xml rename to header_search_panel/header_search_panel/static/src/search/header_search/components/fields_filter/selection_filter/selection_filter.xml diff --git a/header_search_panel/static/src/search/header_search/components/fields_filter/standard_field_filter_props.js b/header_search_panel/header_search_panel/static/src/search/header_search/components/fields_filter/standard_field_filter_props.js similarity index 88% rename from header_search_panel/static/src/search/header_search/components/fields_filter/standard_field_filter_props.js rename to header_search_panel/header_search_panel/static/src/search/header_search/components/fields_filter/standard_field_filter_props.js index 231ebf6b4..2fa7705c2 100644 --- a/header_search_panel/static/src/search/header_search/components/fields_filter/standard_field_filter_props.js +++ b/header_search_panel/header_search_panel/static/src/search/header_search/components/fields_filter/standard_field_filter_props.js @@ -13,4 +13,6 @@ export const standardFieldFilterProps = { type: {type: String, required: true}, // 字段变换监听函数 fieldOnchange: { type: Function, required: true }, + // 提示 + placeholder: {type: String, optional: true}, }; diff --git a/header_search_panel/static/src/search/header_search/components/fields_filter/x2many_filter/x2many_filter.js b/header_search_panel/header_search_panel/static/src/search/header_search/components/fields_filter/x2many_filter/x2many_filter.js similarity index 100% rename from header_search_panel/static/src/search/header_search/components/fields_filter/x2many_filter/x2many_filter.js rename to header_search_panel/header_search_panel/static/src/search/header_search/components/fields_filter/x2many_filter/x2many_filter.js diff --git a/header_search_panel/static/src/search/header_search/components/fields_filter/x2many_filter/x2many_filter.xml b/header_search_panel/header_search_panel/static/src/search/header_search/components/fields_filter/x2many_filter/x2many_filter.xml similarity index 100% rename from header_search_panel/static/src/search/header_search/components/fields_filter/x2many_filter/x2many_filter.xml rename to header_search_panel/header_search_panel/static/src/search/header_search/components/fields_filter/x2many_filter/x2many_filter.xml diff --git a/header_search_panel/static/src/search/header_search/components/quick_filter/quick_filter.js b/header_search_panel/header_search_panel/static/src/search/header_search/components/quick_filter/quick_filter.js similarity index 100% rename from header_search_panel/static/src/search/header_search/components/quick_filter/quick_filter.js rename to header_search_panel/header_search_panel/static/src/search/header_search/components/quick_filter/quick_filter.js diff --git a/header_search_panel/static/src/search/header_search/components/quick_filter/quick_filter.xml b/header_search_panel/header_search_panel/static/src/search/header_search/components/quick_filter/quick_filter.xml similarity index 92% rename from header_search_panel/static/src/search/header_search/components/quick_filter/quick_filter.xml rename to header_search_panel/header_search_panel/static/src/search/header_search/components/quick_filter/quick_filter.xml index 17da74122..7ea0d8bbe 100644 --- a/header_search_panel/static/src/search/header_search/components/quick_filter/quick_filter.xml +++ b/header_search_panel/header_search_panel/static/src/search/header_search/components/quick_filter/quick_filter.xml @@ -2,11 +2,11 @@ - +

diff --git a/header_search_panel/static/src/search/header_search/components/quick_filter/quick_filter_label.scss b/header_search_panel/header_search_panel/static/src/search/header_search/components/quick_filter/quick_filter_label.scss similarity index 100% rename from header_search_panel/static/src/search/header_search/components/quick_filter/quick_filter_label.scss rename to header_search_panel/header_search_panel/static/src/search/header_search/components/quick_filter/quick_filter_label.scss diff --git a/header_search_panel/static/src/search/header_search/components/select_date_filter/select_date_filter.js b/header_search_panel/header_search_panel/static/src/search/header_search/components/select_date_filter/select_date_filter.js similarity index 100% rename from header_search_panel/static/src/search/header_search/components/select_date_filter/select_date_filter.js rename to header_search_panel/header_search_panel/static/src/search/header_search/components/select_date_filter/select_date_filter.js diff --git a/header_search_panel/static/src/search/header_search/components/select_date_filter/select_date_filter.xml b/header_search_panel/header_search_panel/static/src/search/header_search/components/select_date_filter/select_date_filter.xml similarity index 100% rename from header_search_panel/static/src/search/header_search/components/select_date_filter/select_date_filter.xml rename to header_search_panel/header_search_panel/static/src/search/header_search/components/select_date_filter/select_date_filter.xml diff --git a/header_search_panel/static/src/search/header_search/header_search_filter.js b/header_search_panel/header_search_panel/static/src/search/header_search/header_search_filter.js similarity index 100% rename from header_search_panel/static/src/search/header_search/header_search_filter.js rename to header_search_panel/header_search_panel/static/src/search/header_search/header_search_filter.js diff --git a/header_search_panel/static/src/search/header_search/header_search_filter.scss b/header_search_panel/header_search_panel/static/src/search/header_search/header_search_filter.scss similarity index 96% rename from header_search_panel/static/src/search/header_search/header_search_filter.scss rename to header_search_panel/header_search_panel/static/src/search/header_search/header_search_filter.scss index 32a658282..26091f318 100644 --- a/header_search_panel/static/src/search/header_search/header_search_filter.scss +++ b/header_search_panel/header_search_panel/static/src/search/header_search/header_search_filter.scss @@ -74,10 +74,12 @@ .fast-date-filter { display: flex; flex-wrap: wrap; + align-items: center; } - input[type="date"], + .o_datetime_input, .fast-date-filter a { + width: auto; margin: 0.2rem; padding: 0.1rem 1rem; border: 0.1rem solid $o-community-color; /* 将边框颜色改为黑色 */ @@ -149,6 +151,14 @@ } } } + +.header-search-inline { + display: flex; + flex-wrap: wrap; + align-items: start; + gap: 5px; +} + .header_search_toggle { width: 6rem; height: 2rem; @@ -161,4 +171,4 @@ line-height: 2rem; margin-left: 0.5rem; } -} \ No newline at end of file +} diff --git a/header_search_panel/static/src/search/header_search/header_search_filter.xml b/header_search_panel/header_search_panel/static/src/search/header_search/header_search_filter.xml similarity index 100% rename from header_search_panel/static/src/search/header_search/header_search_filter.xml rename to header_search_panel/header_search_panel/static/src/search/header_search/header_search_filter.xml diff --git a/header_search_panel/static/src/search/search_arch_parser.js b/header_search_panel/header_search_panel/static/src/search/search_arch_parser.js similarity index 96% rename from header_search_panel/static/src/search/search_arch_parser.js rename to header_search_panel/header_search_panel/static/src/search/search_arch_parser.js index eaa2fddb4..e53f615e1 100644 --- a/header_search_panel/static/src/search/search_arch_parser.js +++ b/header_search_panel/header_search_panel/static/src/search/search_arch_parser.js @@ -165,6 +165,8 @@ patch(SearchArchParser.prototype, { const fieldString = node.getAttribute("string"); // 自定义css类 const cssClass = node.getAttribute("class"); + // placeholder + const placeholder = node.getAttribute("placeholder"); // 获取字段的options属性,该属性代表字段选项 const fieldOptions = evaluateExpr(node.getAttribute("options") || "{}"); // 获取widget @@ -173,7 +175,7 @@ patch(SearchArchParser.prototype, { if (fieldName) { const field = this.fields[fieldName]; // 如果字段类型为selection或者bool,将字段名和选项添加到headerSearchInfo的fields中 - if (!["selection", "boolean", "date", "datetime", "many2one", "one2many", "many2many"].includes(field.type)) { + if (!["selection", "boolean", "date", "datetime", "many2one", "one2many", "many2many", "char"].includes(field.type)) { return false; } const fieldInfo = { @@ -186,6 +188,7 @@ patch(SearchArchParser.prototype, { fieldOptions: fieldOptions, modifiers: JSON.parse(node.getAttribute("modifiers") || "{}"), class: cssClass, + placeholder: placeholder || undefined, } if (["many2one", "many2many"].includes(field.type)) { fieldInfo.fieldDomain = node.getAttribute("domain"); @@ -237,17 +240,16 @@ patch(SearchArchParser.prototype, { for (const node of headerSearchNode.children) { switch (node.tagName) { case "field": - // // 字段筛选 - // this.visitHeaderField(node); + // 字段筛选 + this.visitHeaderField(node); break; case "quick_filter": // 快捷筛选 this.visitHeaderQuickFilter(node); break; case "select_date_filter": - // // 自选日期筛选 - // this.visitHeaderSelectDateFilter(node); - break; + // 自选日期筛选 + this.visitHeaderSelectDateFilter(node); } } return false; diff --git a/header_search_panel/static/src/search/search_model.js b/header_search_panel/header_search_panel/static/src/search/search_model.js similarity index 100% rename from header_search_panel/static/src/search/search_model.js rename to header_search_panel/header_search_panel/static/src/search/search_model.js diff --git a/header_search_panel/model_test/__init__.py b/header_search_panel/model_test/__init__.py new file mode 100644 index 000000000..511a0ca3a --- /dev/null +++ b/header_search_panel/model_test/__init__.py @@ -0,0 +1,4 @@ +# -*- coding: utf-8 -*- + +from . import controllers +from . import models \ No newline at end of file diff --git a/header_search_panel/model_test/__manifest__.py b/header_search_panel/model_test/__manifest__.py new file mode 100644 index 000000000..42eb43c94 --- /dev/null +++ b/header_search_panel/model_test/__manifest__.py @@ -0,0 +1,21 @@ +# -*- coding: utf-8 -*- +{ + 'name': '模型测试', + 'summary': '', + 'description': '', + 'author': 'XSK', + 'website': '', + 'category': 'Uncategorized', + 'version': '0.1', + 'license': 'LGPL-3', + 'depends': ['base', 'web', 'mail'], + 'data': [ + 'security/ir.model.access.csv', + 'views/views.xml', + ], + 'assets': { + 'web.assets_backend': [ + 'model_test/static/src/**/*', + ], + }, +} diff --git a/header_search_panel/model_test/controllers/__init__.py b/header_search_panel/model_test/controllers/__init__.py new file mode 100644 index 000000000..457bae27e --- /dev/null +++ b/header_search_panel/model_test/controllers/__init__.py @@ -0,0 +1,3 @@ +# -*- coding: utf-8 -*- + +from . import controllers \ No newline at end of file diff --git a/header_search_panel/model_test/controllers/controllers.py b/header_search_panel/model_test/controllers/controllers.py new file mode 100644 index 000000000..22c44a3ab --- /dev/null +++ b/header_search_panel/model_test/controllers/controllers.py @@ -0,0 +1,21 @@ +# -*- coding: utf-8 -*- +# from odoo import http + + +# class FilePreviewTest(http.Controller): +# @http.route('/file_preview_test/file_preview_test', auth='public') +# def index(self, **kw): +# return "Hello, world" + +# @http.route('/file_preview_test/file_preview_test/objects', auth='public') +# def list(self, **kw): +# return http.request.render('file_preview_test.listing', { +# 'root': '/file_preview_test/file_preview_test', +# 'objects': http.request.env['file_preview_test.file_preview_test'].search([]), +# }) + +# @http.route('/file_preview_test/file_preview_test/objects/', auth='public') +# def object(self, obj, **kw): +# return http.request.render('file_preview_test.object', { +# 'object': obj +# }) diff --git a/header_search_panel/model_test/models/__init__.py b/header_search_panel/model_test/models/__init__.py new file mode 100644 index 000000000..5305644df --- /dev/null +++ b/header_search_panel/model_test/models/__init__.py @@ -0,0 +1,3 @@ +# -*- coding: utf-8 -*- + +from . import models \ No newline at end of file diff --git a/header_search_panel/model_test/models/models.py b/header_search_panel/model_test/models/models.py new file mode 100644 index 000000000..a6b58a725 --- /dev/null +++ b/header_search_panel/model_test/models/models.py @@ -0,0 +1,211 @@ +# -*- coding: utf-8 -*- +from datetime import datetime, date, timedelta +import string +import random +from odoo import models, fields, api + + +class ModelTestManyOne(models.Model): + _name = 'model.test.many.one' + _description = '测试模块' + _inherit = ['mail.thread', 'mail.activity.mixin'] + + name = fields.Char(string='字符串字段', tracking=True) + test_id = fields.Many2one(string='多对一字段', comodel_name='model.test', required=True, ondelete='cascade') + file_id = fields.Many2one(string='多对一文件', comodel_name='ir.attachment', tracking=True) + file_ids = fields.Many2many(string='多对多文件', comodel_name='ir.attachment', relation='file_preview_test_many_one_rel', column1='test_id', column2='test_id_2') + + +class ModelTest(models.Model): + _name = 'model.test' + _description = '测试模块' + _inherit = ['mail.thread', 'mail.activity.mixin'] + + name = fields.Char(string='字符串字段', tracking=True) + int_field = fields.Integer(string='整数', tracking=True) + float_field = fields.Float(string='浮点数', tracking=True) + date_field = fields.Date(string='日期字段', tracking=True) + datetime_field = fields.Datetime(string='日期时间字段', tracking=True) + state = fields.Selection(string='状态', selection=[('draft', '草稿'), ('done', '完成')], default='draft') + file_id = fields.Many2one(string='多对一文件', comodel_name='ir.attachment') + file_ids = fields.Many2many(string='多对多文件', comodel_name='ir.attachment', relation='file_preview_test_rel', column1='test_id', column2='test_id_2') + text = fields.Text(string='长文本测试') + one_to_many_field = fields.One2many(string='one2many字段', comodel_name='model.test.many.one', inverse_name='test_id', tracking=True) + bool_test = fields.Boolean(string='布尔字段') + selection_test = fields.Selection(string='选择字段', selection=[('1', '选项一'), ('2', '选项二')]) + + def action_generate_sample_text(self): + """生成长文本样例""" + sample_text = """ + # 这是Markdown格式的样例文本 + + ## 项目概述 + 这是一个测试项目,用于展示Odoo中各种字段类型的功能和显示效果。 + + ### 功能特点 + 1. 支持多种数据类型 + 2. 自动生成测试数据 + 3. 便于开发和测试 + + ### 技术规格 + - 数据库:PostgreSQL + - 框架:Odoo 14.0+ + - 语言:Python/XML/JavaScript + + --- + **注意**:此内容为自动生成,仅用于测试目的。 + """ + self.write({'text': sample_text}) + + # 辅助方法 + def _generate_random_string(self, length): + """生成随机字符串""" + letters = string.ascii_letters + string.digits + return ''.join(random.choice(letters) for _ in range(length)) + + def _generate_random_date(self): + """生成随机日期(最近365天内)""" + days_ago = random.randint(0, 365) + return date.today() - timedelta(days=days_ago) + + def _generate_random_datetime(self): + """生成随机日期时间(最近30天内)""" + hours_ago = random.randint(0, 720) # 30天*24小时 + return datetime.now() - timedelta(hours=hours_ago) + + # 生成随机数据的方法 + def action_insert_random_data(self): + """生成50条随机测试数据""" + # 预先生成一些附件供选择 + attachment_ids = self.env['ir.attachment'].search([], limit=10) + + for i in range(50): + # 生成随机数据 + random_name = f"测试项目_{i + 1}_{self._generate_random_string(6)}" + random_int = random.randint(1, 1000) + random_float = round(random.uniform(1.0, 10000.0), 2) + random_date = self._generate_random_date() + random_datetime = self._generate_random_datetime() + random_state = random.choice(['draft', 'done']) + random_selection = random.choice(['1', '2']) + random_bool = random.choice([True, False]) + + # 生成随机文本 + random_text = f""" + 这是第{i + 1}条测试记录的长文本内容。 + 生成时间:{datetime.now().strftime('%Y-%m-%d %H:%M:%S')} + 随机ID:{self._generate_random_string(10)} + 描述:这是一条自动生成的测试数据,用于演示各种字段类型的显示效果。 + """ + + # 创建主记录 + test_record = self.create({ + 'name': random_name, + 'int_field': random_int, + 'float_field': random_float, + 'date_field': random_date, + 'datetime_field': random_datetime, + 'state': random_state, + 'bool_test': random_bool, + 'selection_test': random_selection, + 'text': random_text, + }) + + # 随机选择附件 + if attachment_ids: + # 随机选择1-3个附件 + num_attachments = random.randint(1, min(3, len(attachment_ids))) + random_attachments = random.sample(attachment_ids.ids, num_attachments) + test_record.write({ + 'file_id': random.choice(attachment_ids).id if attachment_ids else False, + 'file_ids': [(6, 0, random_attachments)] + }) + + # 返回成功消息 + return { + 'type': 'ir.actions.client', + 'tag': 'display_notification', + 'params': { + 'title': '数据生成成功', + 'message': f'已成功生成50条测试数据!', + 'type': 'success', + 'sticky': False, + 'next': {'type': 'ir.actions.act_window_close'}, + } + } + + def action_to_dialog(self): + self.ensure_one() + return { + 'type': 'ir.actions.act_window', + 'res_model': 'model.test', + 'view_mode': 'form', + 'res_id': self.id, + 'views': [[self.env.ref('model_test.view_file_preview_test_form').id, 'form']], + } + + def cancel(self): + self.state = 'done' + + def test_approval(self): + self.verify_rules(self.cancel) + # print(asd) + + +# class TimeCalculation(models.Model): +# _name = 'example.time.calculation' +# _description = 'Example for Start Time, End Time, Duration' +# +# start_time = fields.Datetime(string='Start Time', required=True) +# end_time = fields.Datetime(string='End Time', required=True) +# duration = fields.Float(string='Duration (hours)', compute='_compute_duration', inverse='_inverse_duration', store=True) +# +# @api.depends('start_time', 'end_time') +# def _compute_duration(self): +# """根据开始时间和结束时间计算时间间隔""" +# for record in self: +# if record.start_time and record.end_time: +# delta = record.end_time - record.start_time +# record.duration = delta.total_seconds() / 3600 # 转换为小时 +# +# @api.depends('start_time', 'duration') +# def _compute_end_time(self): +# """根据开始时间和时间间隔计算结束时间""" +# for record in self: +# if record.start_time and record.duration is not None: +# record.end_time = record.start_time + timedelta(hours=record.duration) +# +# @api.depends('end_time', 'duration') +# def _compute_start_time(self): +# """根据结束时间和时间间隔计算开始时间""" +# for record in self: +# if record.end_time and record.duration is not None: +# record.start_time = record.end_time - timedelta(hours=record.duration) +# +# def _inverse_duration(self): +# """反向更新结束时间""" +# for record in self: +# if record.start_time and record.duration is not None: +# record.end_time = record.start_time + timedelta(hours=record.duration) +# +# @api.onchange('start_time', 'end_time') +# def _onchange_duration(self): +# """确保在界面交互中,时间关系自动更新""" +# for record in self: +# if record.start_time and record.end_time: +# delta = record.end_time - record.start_time +# record.duration = delta.total_seconds() / 3600 +# +# @api.onchange('start_time', 'duration') +# def _onchange_end_time(self): +# """确保在界面交互中,时间关系自动更新""" +# for record in self: +# if record.start_time and record.duration is not None: +# record.end_time = record.start_time + timedelta(hours=record.duration) +# +# @api.onchange('end_time', 'duration') +# def _onchange_start_time(self): +# """确保在界面交互中,时间关系自动更新""" +# for record in self: +# if record.end_time and record.duration is not None: +# record.start_time = record.end_time - timedelta(hours=record.duration) diff --git a/header_search_panel/model_test/security/ir.model.access.csv b/header_search_panel/model_test/security/ir.model.access.csv new file mode 100644 index 000000000..583335d26 --- /dev/null +++ b/header_search_panel/model_test/security/ir.model.access.csv @@ -0,0 +1,3 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_model_test,测试模块,model_model_test,,1,1,1,1 +access_model_test_many_one,测试模块多,model_model_test_many_one,,1,1,1,1 \ No newline at end of file diff --git a/header_search_panel/model_test/static/src/model_test_list.xml b/header_search_panel/model_test/static/src/model_test_list.xml new file mode 100644 index 000000000..c80232c10 --- /dev/null +++ b/header_search_panel/model_test/static/src/model_test_list.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/header_search_panel/model_test/static/src/model_test_list_controller.js b/header_search_panel/model_test/static/src/model_test_list_controller.js new file mode 100644 index 000000000..e95ce7236 --- /dev/null +++ b/header_search_panel/model_test/static/src/model_test_list_controller.js @@ -0,0 +1,10 @@ +/** @odoo-module **/ +import { registry } from '@web/core/registry'; +import { listView } from '@web/views/list/list_view'; + + +export const ModelTestListView = { + ...listView, + buttonTemplate: 'ModelTest.buttons' +}; +registry.category('views').add('model_test_list', ModelTestListView); diff --git a/header_search_panel/model_test/views/views.xml b/header_search_panel/model_test/views/views.xml new file mode 100644 index 000000000..c5c99e1c5 --- /dev/null +++ b/header_search_panel/model_test/views/views.xml @@ -0,0 +1,126 @@ + + + + + + model.test + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + model.test.tree + model.test + + +
+
+ + + + + + + +
+
+
+ + + + model.test.form + model.test + +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+ + + + + + + 文件测试 + main + model.test + tree,form + + + + + + + \ No newline at end of file diff --git a/header_search_panel/static/src/search/header_search/components/fields_filter/date_filter/date_filter.xml b/header_search_panel/static/src/search/header_search/components/fields_filter/date_filter/date_filter.xml deleted file mode 100644 index 707547669..000000000 --- a/header_search_panel/static/src/search/header_search/components/fields_filter/date_filter/date_filter.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - -
- - -
- -
- -
From 72f0da291037e3552ebca95bbdb27653f4cfb21e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=B9=8F=E5=AE=87?= <9664676+pengyuthon@user.noreply.gitee.com> Date: Fri, 19 Dec 2025 15:37:59 +0800 Subject: [PATCH 38/43] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../{header_search_panel => }/README.md | 0 .../{header_search_panel => }/__init__.py | 0 .../{header_search_panel => }/__manifest__.py | 0 header_search_panel/model_test/__init__.py | 4 - .../model_test/__manifest__.py | 21 -- .../model_test/controllers/__init__.py | 3 - .../model_test/controllers/controllers.py | 21 -- .../model_test/models/__init__.py | 3 - .../model_test/models/models.py | 211 ------------------ .../model_test/security/ir.model.access.csv | 3 - .../model_test/static/src/model_test_list.xml | 17 -- .../static/src/model_test_list_controller.js | 10 - .../model_test/views/views.xml | 126 ----------- .../override_relaxng.py | 0 .../rng/search_view.rng | 0 .../static/src/legacy/backend_utils.js | 0 .../src/search/control_panel/control_panel.js | 0 .../search/control_panel/control_panel.scss | 0 .../search/control_panel/control_panel.xml | 0 .../boolean_filter/boolean_filter.js | 0 .../boolean_filter/boolean_filter.xml | 0 .../fields_filter/char_filter/char_filter.js | 0 .../fields_filter/char_filter/char_filter.xml | 0 .../fields_filter/date_filter/date_filter.js | 0 .../fields_filter/date_filter/date_filter.xml | 0 .../components/fields_filter/fields_filter.js | 0 .../fields_filter/fields_filter.xml | 0 .../many2one_filter/many2one_filter.js | 0 .../many2one_filter/many2one_filter.xml | 0 .../selection_filter/selection_filter.js | 0 .../selection_filter/selection_filter.xml | 0 .../standard_field_filter_props.js | 0 .../x2many_filter/x2many_filter.js | 0 .../x2many_filter/x2many_filter.xml | 0 .../components/quick_filter/quick_filter.js | 0 .../components/quick_filter/quick_filter.xml | 0 .../quick_filter/quick_filter_label.scss | 0 .../select_date_filter/select_date_filter.js | 0 .../select_date_filter/select_date_filter.xml | 0 .../header_search/header_search_filter.js | 0 .../header_search/header_search_filter.scss | 0 .../header_search/header_search_filter.xml | 0 .../static/src/search/search_arch_parser.js | 0 .../static/src/search/search_model.js | 0 44 files changed, 419 deletions(-) rename header_search_panel/{header_search_panel => }/README.md (100%) rename header_search_panel/{header_search_panel => }/__init__.py (100%) rename header_search_panel/{header_search_panel => }/__manifest__.py (100%) delete mode 100644 header_search_panel/model_test/__init__.py delete mode 100644 header_search_panel/model_test/__manifest__.py delete mode 100644 header_search_panel/model_test/controllers/__init__.py delete mode 100644 header_search_panel/model_test/controllers/controllers.py delete mode 100644 header_search_panel/model_test/models/__init__.py delete mode 100644 header_search_panel/model_test/models/models.py delete mode 100644 header_search_panel/model_test/security/ir.model.access.csv delete mode 100644 header_search_panel/model_test/static/src/model_test_list.xml delete mode 100644 header_search_panel/model_test/static/src/model_test_list_controller.js delete mode 100644 header_search_panel/model_test/views/views.xml rename header_search_panel/{header_search_panel => }/override_relaxng.py (100%) rename header_search_panel/{header_search_panel => }/rng/search_view.rng (100%) rename header_search_panel/{header_search_panel => }/static/src/legacy/backend_utils.js (100%) rename header_search_panel/{header_search_panel => }/static/src/search/control_panel/control_panel.js (100%) rename header_search_panel/{header_search_panel => }/static/src/search/control_panel/control_panel.scss (100%) rename header_search_panel/{header_search_panel => }/static/src/search/control_panel/control_panel.xml (100%) rename header_search_panel/{header_search_panel => }/static/src/search/header_search/components/fields_filter/boolean_filter/boolean_filter.js (100%) rename header_search_panel/{header_search_panel => }/static/src/search/header_search/components/fields_filter/boolean_filter/boolean_filter.xml (100%) rename header_search_panel/{header_search_panel => }/static/src/search/header_search/components/fields_filter/char_filter/char_filter.js (100%) rename header_search_panel/{header_search_panel => }/static/src/search/header_search/components/fields_filter/char_filter/char_filter.xml (100%) rename header_search_panel/{header_search_panel => }/static/src/search/header_search/components/fields_filter/date_filter/date_filter.js (100%) rename header_search_panel/{header_search_panel => }/static/src/search/header_search/components/fields_filter/date_filter/date_filter.xml (100%) rename header_search_panel/{header_search_panel => }/static/src/search/header_search/components/fields_filter/fields_filter.js (100%) rename header_search_panel/{header_search_panel => }/static/src/search/header_search/components/fields_filter/fields_filter.xml (100%) rename header_search_panel/{header_search_panel => }/static/src/search/header_search/components/fields_filter/many2one_filter/many2one_filter.js (100%) rename header_search_panel/{header_search_panel => }/static/src/search/header_search/components/fields_filter/many2one_filter/many2one_filter.xml (100%) rename header_search_panel/{header_search_panel => }/static/src/search/header_search/components/fields_filter/selection_filter/selection_filter.js (100%) rename header_search_panel/{header_search_panel => }/static/src/search/header_search/components/fields_filter/selection_filter/selection_filter.xml (100%) rename header_search_panel/{header_search_panel => }/static/src/search/header_search/components/fields_filter/standard_field_filter_props.js (100%) rename header_search_panel/{header_search_panel => }/static/src/search/header_search/components/fields_filter/x2many_filter/x2many_filter.js (100%) rename header_search_panel/{header_search_panel => }/static/src/search/header_search/components/fields_filter/x2many_filter/x2many_filter.xml (100%) rename header_search_panel/{header_search_panel => }/static/src/search/header_search/components/quick_filter/quick_filter.js (100%) rename header_search_panel/{header_search_panel => }/static/src/search/header_search/components/quick_filter/quick_filter.xml (100%) rename header_search_panel/{header_search_panel => }/static/src/search/header_search/components/quick_filter/quick_filter_label.scss (100%) rename header_search_panel/{header_search_panel => }/static/src/search/header_search/components/select_date_filter/select_date_filter.js (100%) rename header_search_panel/{header_search_panel => }/static/src/search/header_search/components/select_date_filter/select_date_filter.xml (100%) rename header_search_panel/{header_search_panel => }/static/src/search/header_search/header_search_filter.js (100%) rename header_search_panel/{header_search_panel => }/static/src/search/header_search/header_search_filter.scss (100%) rename header_search_panel/{header_search_panel => }/static/src/search/header_search/header_search_filter.xml (100%) rename header_search_panel/{header_search_panel => }/static/src/search/search_arch_parser.js (100%) rename header_search_panel/{header_search_panel => }/static/src/search/search_model.js (100%) diff --git a/header_search_panel/header_search_panel/README.md b/header_search_panel/README.md similarity index 100% rename from header_search_panel/header_search_panel/README.md rename to header_search_panel/README.md diff --git a/header_search_panel/header_search_panel/__init__.py b/header_search_panel/__init__.py similarity index 100% rename from header_search_panel/header_search_panel/__init__.py rename to header_search_panel/__init__.py diff --git a/header_search_panel/header_search_panel/__manifest__.py b/header_search_panel/__manifest__.py similarity index 100% rename from header_search_panel/header_search_panel/__manifest__.py rename to header_search_panel/__manifest__.py diff --git a/header_search_panel/model_test/__init__.py b/header_search_panel/model_test/__init__.py deleted file mode 100644 index 511a0ca3a..000000000 --- a/header_search_panel/model_test/__init__.py +++ /dev/null @@ -1,4 +0,0 @@ -# -*- coding: utf-8 -*- - -from . import controllers -from . import models \ No newline at end of file diff --git a/header_search_panel/model_test/__manifest__.py b/header_search_panel/model_test/__manifest__.py deleted file mode 100644 index 42eb43c94..000000000 --- a/header_search_panel/model_test/__manifest__.py +++ /dev/null @@ -1,21 +0,0 @@ -# -*- coding: utf-8 -*- -{ - 'name': '模型测试', - 'summary': '', - 'description': '', - 'author': 'XSK', - 'website': '', - 'category': 'Uncategorized', - 'version': '0.1', - 'license': 'LGPL-3', - 'depends': ['base', 'web', 'mail'], - 'data': [ - 'security/ir.model.access.csv', - 'views/views.xml', - ], - 'assets': { - 'web.assets_backend': [ - 'model_test/static/src/**/*', - ], - }, -} diff --git a/header_search_panel/model_test/controllers/__init__.py b/header_search_panel/model_test/controllers/__init__.py deleted file mode 100644 index 457bae27e..000000000 --- a/header_search_panel/model_test/controllers/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -# -*- coding: utf-8 -*- - -from . import controllers \ No newline at end of file diff --git a/header_search_panel/model_test/controllers/controllers.py b/header_search_panel/model_test/controllers/controllers.py deleted file mode 100644 index 22c44a3ab..000000000 --- a/header_search_panel/model_test/controllers/controllers.py +++ /dev/null @@ -1,21 +0,0 @@ -# -*- coding: utf-8 -*- -# from odoo import http - - -# class FilePreviewTest(http.Controller): -# @http.route('/file_preview_test/file_preview_test', auth='public') -# def index(self, **kw): -# return "Hello, world" - -# @http.route('/file_preview_test/file_preview_test/objects', auth='public') -# def list(self, **kw): -# return http.request.render('file_preview_test.listing', { -# 'root': '/file_preview_test/file_preview_test', -# 'objects': http.request.env['file_preview_test.file_preview_test'].search([]), -# }) - -# @http.route('/file_preview_test/file_preview_test/objects/', auth='public') -# def object(self, obj, **kw): -# return http.request.render('file_preview_test.object', { -# 'object': obj -# }) diff --git a/header_search_panel/model_test/models/__init__.py b/header_search_panel/model_test/models/__init__.py deleted file mode 100644 index 5305644df..000000000 --- a/header_search_panel/model_test/models/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -# -*- coding: utf-8 -*- - -from . import models \ No newline at end of file diff --git a/header_search_panel/model_test/models/models.py b/header_search_panel/model_test/models/models.py deleted file mode 100644 index a6b58a725..000000000 --- a/header_search_panel/model_test/models/models.py +++ /dev/null @@ -1,211 +0,0 @@ -# -*- coding: utf-8 -*- -from datetime import datetime, date, timedelta -import string -import random -from odoo import models, fields, api - - -class ModelTestManyOne(models.Model): - _name = 'model.test.many.one' - _description = '测试模块' - _inherit = ['mail.thread', 'mail.activity.mixin'] - - name = fields.Char(string='字符串字段', tracking=True) - test_id = fields.Many2one(string='多对一字段', comodel_name='model.test', required=True, ondelete='cascade') - file_id = fields.Many2one(string='多对一文件', comodel_name='ir.attachment', tracking=True) - file_ids = fields.Many2many(string='多对多文件', comodel_name='ir.attachment', relation='file_preview_test_many_one_rel', column1='test_id', column2='test_id_2') - - -class ModelTest(models.Model): - _name = 'model.test' - _description = '测试模块' - _inherit = ['mail.thread', 'mail.activity.mixin'] - - name = fields.Char(string='字符串字段', tracking=True) - int_field = fields.Integer(string='整数', tracking=True) - float_field = fields.Float(string='浮点数', tracking=True) - date_field = fields.Date(string='日期字段', tracking=True) - datetime_field = fields.Datetime(string='日期时间字段', tracking=True) - state = fields.Selection(string='状态', selection=[('draft', '草稿'), ('done', '完成')], default='draft') - file_id = fields.Many2one(string='多对一文件', comodel_name='ir.attachment') - file_ids = fields.Many2many(string='多对多文件', comodel_name='ir.attachment', relation='file_preview_test_rel', column1='test_id', column2='test_id_2') - text = fields.Text(string='长文本测试') - one_to_many_field = fields.One2many(string='one2many字段', comodel_name='model.test.many.one', inverse_name='test_id', tracking=True) - bool_test = fields.Boolean(string='布尔字段') - selection_test = fields.Selection(string='选择字段', selection=[('1', '选项一'), ('2', '选项二')]) - - def action_generate_sample_text(self): - """生成长文本样例""" - sample_text = """ - # 这是Markdown格式的样例文本 - - ## 项目概述 - 这是一个测试项目,用于展示Odoo中各种字段类型的功能和显示效果。 - - ### 功能特点 - 1. 支持多种数据类型 - 2. 自动生成测试数据 - 3. 便于开发和测试 - - ### 技术规格 - - 数据库:PostgreSQL - - 框架:Odoo 14.0+ - - 语言:Python/XML/JavaScript - - --- - **注意**:此内容为自动生成,仅用于测试目的。 - """ - self.write({'text': sample_text}) - - # 辅助方法 - def _generate_random_string(self, length): - """生成随机字符串""" - letters = string.ascii_letters + string.digits - return ''.join(random.choice(letters) for _ in range(length)) - - def _generate_random_date(self): - """生成随机日期(最近365天内)""" - days_ago = random.randint(0, 365) - return date.today() - timedelta(days=days_ago) - - def _generate_random_datetime(self): - """生成随机日期时间(最近30天内)""" - hours_ago = random.randint(0, 720) # 30天*24小时 - return datetime.now() - timedelta(hours=hours_ago) - - # 生成随机数据的方法 - def action_insert_random_data(self): - """生成50条随机测试数据""" - # 预先生成一些附件供选择 - attachment_ids = self.env['ir.attachment'].search([], limit=10) - - for i in range(50): - # 生成随机数据 - random_name = f"测试项目_{i + 1}_{self._generate_random_string(6)}" - random_int = random.randint(1, 1000) - random_float = round(random.uniform(1.0, 10000.0), 2) - random_date = self._generate_random_date() - random_datetime = self._generate_random_datetime() - random_state = random.choice(['draft', 'done']) - random_selection = random.choice(['1', '2']) - random_bool = random.choice([True, False]) - - # 生成随机文本 - random_text = f""" - 这是第{i + 1}条测试记录的长文本内容。 - 生成时间:{datetime.now().strftime('%Y-%m-%d %H:%M:%S')} - 随机ID:{self._generate_random_string(10)} - 描述:这是一条自动生成的测试数据,用于演示各种字段类型的显示效果。 - """ - - # 创建主记录 - test_record = self.create({ - 'name': random_name, - 'int_field': random_int, - 'float_field': random_float, - 'date_field': random_date, - 'datetime_field': random_datetime, - 'state': random_state, - 'bool_test': random_bool, - 'selection_test': random_selection, - 'text': random_text, - }) - - # 随机选择附件 - if attachment_ids: - # 随机选择1-3个附件 - num_attachments = random.randint(1, min(3, len(attachment_ids))) - random_attachments = random.sample(attachment_ids.ids, num_attachments) - test_record.write({ - 'file_id': random.choice(attachment_ids).id if attachment_ids else False, - 'file_ids': [(6, 0, random_attachments)] - }) - - # 返回成功消息 - return { - 'type': 'ir.actions.client', - 'tag': 'display_notification', - 'params': { - 'title': '数据生成成功', - 'message': f'已成功生成50条测试数据!', - 'type': 'success', - 'sticky': False, - 'next': {'type': 'ir.actions.act_window_close'}, - } - } - - def action_to_dialog(self): - self.ensure_one() - return { - 'type': 'ir.actions.act_window', - 'res_model': 'model.test', - 'view_mode': 'form', - 'res_id': self.id, - 'views': [[self.env.ref('model_test.view_file_preview_test_form').id, 'form']], - } - - def cancel(self): - self.state = 'done' - - def test_approval(self): - self.verify_rules(self.cancel) - # print(asd) - - -# class TimeCalculation(models.Model): -# _name = 'example.time.calculation' -# _description = 'Example for Start Time, End Time, Duration' -# -# start_time = fields.Datetime(string='Start Time', required=True) -# end_time = fields.Datetime(string='End Time', required=True) -# duration = fields.Float(string='Duration (hours)', compute='_compute_duration', inverse='_inverse_duration', store=True) -# -# @api.depends('start_time', 'end_time') -# def _compute_duration(self): -# """根据开始时间和结束时间计算时间间隔""" -# for record in self: -# if record.start_time and record.end_time: -# delta = record.end_time - record.start_time -# record.duration = delta.total_seconds() / 3600 # 转换为小时 -# -# @api.depends('start_time', 'duration') -# def _compute_end_time(self): -# """根据开始时间和时间间隔计算结束时间""" -# for record in self: -# if record.start_time and record.duration is not None: -# record.end_time = record.start_time + timedelta(hours=record.duration) -# -# @api.depends('end_time', 'duration') -# def _compute_start_time(self): -# """根据结束时间和时间间隔计算开始时间""" -# for record in self: -# if record.end_time and record.duration is not None: -# record.start_time = record.end_time - timedelta(hours=record.duration) -# -# def _inverse_duration(self): -# """反向更新结束时间""" -# for record in self: -# if record.start_time and record.duration is not None: -# record.end_time = record.start_time + timedelta(hours=record.duration) -# -# @api.onchange('start_time', 'end_time') -# def _onchange_duration(self): -# """确保在界面交互中,时间关系自动更新""" -# for record in self: -# if record.start_time and record.end_time: -# delta = record.end_time - record.start_time -# record.duration = delta.total_seconds() / 3600 -# -# @api.onchange('start_time', 'duration') -# def _onchange_end_time(self): -# """确保在界面交互中,时间关系自动更新""" -# for record in self: -# if record.start_time and record.duration is not None: -# record.end_time = record.start_time + timedelta(hours=record.duration) -# -# @api.onchange('end_time', 'duration') -# def _onchange_start_time(self): -# """确保在界面交互中,时间关系自动更新""" -# for record in self: -# if record.end_time and record.duration is not None: -# record.start_time = record.end_time - timedelta(hours=record.duration) diff --git a/header_search_panel/model_test/security/ir.model.access.csv b/header_search_panel/model_test/security/ir.model.access.csv deleted file mode 100644 index 583335d26..000000000 --- a/header_search_panel/model_test/security/ir.model.access.csv +++ /dev/null @@ -1,3 +0,0 @@ -id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink -access_model_test,测试模块,model_model_test,,1,1,1,1 -access_model_test_many_one,测试模块多,model_model_test_many_one,,1,1,1,1 \ No newline at end of file diff --git a/header_search_panel/model_test/static/src/model_test_list.xml b/header_search_panel/model_test/static/src/model_test_list.xml deleted file mode 100644 index c80232c10..000000000 --- a/header_search_panel/model_test/static/src/model_test_list.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/header_search_panel/model_test/static/src/model_test_list_controller.js b/header_search_panel/model_test/static/src/model_test_list_controller.js deleted file mode 100644 index e95ce7236..000000000 --- a/header_search_panel/model_test/static/src/model_test_list_controller.js +++ /dev/null @@ -1,10 +0,0 @@ -/** @odoo-module **/ -import { registry } from '@web/core/registry'; -import { listView } from '@web/views/list/list_view'; - - -export const ModelTestListView = { - ...listView, - buttonTemplate: 'ModelTest.buttons' -}; -registry.category('views').add('model_test_list', ModelTestListView); diff --git a/header_search_panel/model_test/views/views.xml b/header_search_panel/model_test/views/views.xml deleted file mode 100644 index c5c99e1c5..000000000 --- a/header_search_panel/model_test/views/views.xml +++ /dev/null @@ -1,126 +0,0 @@ - - - - - - model.test - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - model.test.tree - model.test - - -
-
- - - - - - - -
-
-
- - - - model.test.form - model.test - -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- -
- - - - - - - 文件测试 - main - model.test - tree,form - - - - - - - \ No newline at end of file diff --git a/header_search_panel/header_search_panel/override_relaxng.py b/header_search_panel/override_relaxng.py similarity index 100% rename from header_search_panel/header_search_panel/override_relaxng.py rename to header_search_panel/override_relaxng.py diff --git a/header_search_panel/header_search_panel/rng/search_view.rng b/header_search_panel/rng/search_view.rng similarity index 100% rename from header_search_panel/header_search_panel/rng/search_view.rng rename to header_search_panel/rng/search_view.rng diff --git a/header_search_panel/header_search_panel/static/src/legacy/backend_utils.js b/header_search_panel/static/src/legacy/backend_utils.js similarity index 100% rename from header_search_panel/header_search_panel/static/src/legacy/backend_utils.js rename to header_search_panel/static/src/legacy/backend_utils.js diff --git a/header_search_panel/header_search_panel/static/src/search/control_panel/control_panel.js b/header_search_panel/static/src/search/control_panel/control_panel.js similarity index 100% rename from header_search_panel/header_search_panel/static/src/search/control_panel/control_panel.js rename to header_search_panel/static/src/search/control_panel/control_panel.js diff --git a/header_search_panel/header_search_panel/static/src/search/control_panel/control_panel.scss b/header_search_panel/static/src/search/control_panel/control_panel.scss similarity index 100% rename from header_search_panel/header_search_panel/static/src/search/control_panel/control_panel.scss rename to header_search_panel/static/src/search/control_panel/control_panel.scss diff --git a/header_search_panel/header_search_panel/static/src/search/control_panel/control_panel.xml b/header_search_panel/static/src/search/control_panel/control_panel.xml similarity index 100% rename from header_search_panel/header_search_panel/static/src/search/control_panel/control_panel.xml rename to header_search_panel/static/src/search/control_panel/control_panel.xml diff --git a/header_search_panel/header_search_panel/static/src/search/header_search/components/fields_filter/boolean_filter/boolean_filter.js b/header_search_panel/static/src/search/header_search/components/fields_filter/boolean_filter/boolean_filter.js similarity index 100% rename from header_search_panel/header_search_panel/static/src/search/header_search/components/fields_filter/boolean_filter/boolean_filter.js rename to header_search_panel/static/src/search/header_search/components/fields_filter/boolean_filter/boolean_filter.js diff --git a/header_search_panel/header_search_panel/static/src/search/header_search/components/fields_filter/boolean_filter/boolean_filter.xml b/header_search_panel/static/src/search/header_search/components/fields_filter/boolean_filter/boolean_filter.xml similarity index 100% rename from header_search_panel/header_search_panel/static/src/search/header_search/components/fields_filter/boolean_filter/boolean_filter.xml rename to header_search_panel/static/src/search/header_search/components/fields_filter/boolean_filter/boolean_filter.xml diff --git a/header_search_panel/header_search_panel/static/src/search/header_search/components/fields_filter/char_filter/char_filter.js b/header_search_panel/static/src/search/header_search/components/fields_filter/char_filter/char_filter.js similarity index 100% rename from header_search_panel/header_search_panel/static/src/search/header_search/components/fields_filter/char_filter/char_filter.js rename to header_search_panel/static/src/search/header_search/components/fields_filter/char_filter/char_filter.js diff --git a/header_search_panel/header_search_panel/static/src/search/header_search/components/fields_filter/char_filter/char_filter.xml b/header_search_panel/static/src/search/header_search/components/fields_filter/char_filter/char_filter.xml similarity index 100% rename from header_search_panel/header_search_panel/static/src/search/header_search/components/fields_filter/char_filter/char_filter.xml rename to header_search_panel/static/src/search/header_search/components/fields_filter/char_filter/char_filter.xml diff --git a/header_search_panel/header_search_panel/static/src/search/header_search/components/fields_filter/date_filter/date_filter.js b/header_search_panel/static/src/search/header_search/components/fields_filter/date_filter/date_filter.js similarity index 100% rename from header_search_panel/header_search_panel/static/src/search/header_search/components/fields_filter/date_filter/date_filter.js rename to header_search_panel/static/src/search/header_search/components/fields_filter/date_filter/date_filter.js diff --git a/header_search_panel/header_search_panel/static/src/search/header_search/components/fields_filter/date_filter/date_filter.xml b/header_search_panel/static/src/search/header_search/components/fields_filter/date_filter/date_filter.xml similarity index 100% rename from header_search_panel/header_search_panel/static/src/search/header_search/components/fields_filter/date_filter/date_filter.xml rename to header_search_panel/static/src/search/header_search/components/fields_filter/date_filter/date_filter.xml diff --git a/header_search_panel/header_search_panel/static/src/search/header_search/components/fields_filter/fields_filter.js b/header_search_panel/static/src/search/header_search/components/fields_filter/fields_filter.js similarity index 100% rename from header_search_panel/header_search_panel/static/src/search/header_search/components/fields_filter/fields_filter.js rename to header_search_panel/static/src/search/header_search/components/fields_filter/fields_filter.js diff --git a/header_search_panel/header_search_panel/static/src/search/header_search/components/fields_filter/fields_filter.xml b/header_search_panel/static/src/search/header_search/components/fields_filter/fields_filter.xml similarity index 100% rename from header_search_panel/header_search_panel/static/src/search/header_search/components/fields_filter/fields_filter.xml rename to header_search_panel/static/src/search/header_search/components/fields_filter/fields_filter.xml diff --git a/header_search_panel/header_search_panel/static/src/search/header_search/components/fields_filter/many2one_filter/many2one_filter.js b/header_search_panel/static/src/search/header_search/components/fields_filter/many2one_filter/many2one_filter.js similarity index 100% rename from header_search_panel/header_search_panel/static/src/search/header_search/components/fields_filter/many2one_filter/many2one_filter.js rename to header_search_panel/static/src/search/header_search/components/fields_filter/many2one_filter/many2one_filter.js diff --git a/header_search_panel/header_search_panel/static/src/search/header_search/components/fields_filter/many2one_filter/many2one_filter.xml b/header_search_panel/static/src/search/header_search/components/fields_filter/many2one_filter/many2one_filter.xml similarity index 100% rename from header_search_panel/header_search_panel/static/src/search/header_search/components/fields_filter/many2one_filter/many2one_filter.xml rename to header_search_panel/static/src/search/header_search/components/fields_filter/many2one_filter/many2one_filter.xml diff --git a/header_search_panel/header_search_panel/static/src/search/header_search/components/fields_filter/selection_filter/selection_filter.js b/header_search_panel/static/src/search/header_search/components/fields_filter/selection_filter/selection_filter.js similarity index 100% rename from header_search_panel/header_search_panel/static/src/search/header_search/components/fields_filter/selection_filter/selection_filter.js rename to header_search_panel/static/src/search/header_search/components/fields_filter/selection_filter/selection_filter.js diff --git a/header_search_panel/header_search_panel/static/src/search/header_search/components/fields_filter/selection_filter/selection_filter.xml b/header_search_panel/static/src/search/header_search/components/fields_filter/selection_filter/selection_filter.xml similarity index 100% rename from header_search_panel/header_search_panel/static/src/search/header_search/components/fields_filter/selection_filter/selection_filter.xml rename to header_search_panel/static/src/search/header_search/components/fields_filter/selection_filter/selection_filter.xml diff --git a/header_search_panel/header_search_panel/static/src/search/header_search/components/fields_filter/standard_field_filter_props.js b/header_search_panel/static/src/search/header_search/components/fields_filter/standard_field_filter_props.js similarity index 100% rename from header_search_panel/header_search_panel/static/src/search/header_search/components/fields_filter/standard_field_filter_props.js rename to header_search_panel/static/src/search/header_search/components/fields_filter/standard_field_filter_props.js diff --git a/header_search_panel/header_search_panel/static/src/search/header_search/components/fields_filter/x2many_filter/x2many_filter.js b/header_search_panel/static/src/search/header_search/components/fields_filter/x2many_filter/x2many_filter.js similarity index 100% rename from header_search_panel/header_search_panel/static/src/search/header_search/components/fields_filter/x2many_filter/x2many_filter.js rename to header_search_panel/static/src/search/header_search/components/fields_filter/x2many_filter/x2many_filter.js diff --git a/header_search_panel/header_search_panel/static/src/search/header_search/components/fields_filter/x2many_filter/x2many_filter.xml b/header_search_panel/static/src/search/header_search/components/fields_filter/x2many_filter/x2many_filter.xml similarity index 100% rename from header_search_panel/header_search_panel/static/src/search/header_search/components/fields_filter/x2many_filter/x2many_filter.xml rename to header_search_panel/static/src/search/header_search/components/fields_filter/x2many_filter/x2many_filter.xml diff --git a/header_search_panel/header_search_panel/static/src/search/header_search/components/quick_filter/quick_filter.js b/header_search_panel/static/src/search/header_search/components/quick_filter/quick_filter.js similarity index 100% rename from header_search_panel/header_search_panel/static/src/search/header_search/components/quick_filter/quick_filter.js rename to header_search_panel/static/src/search/header_search/components/quick_filter/quick_filter.js diff --git a/header_search_panel/header_search_panel/static/src/search/header_search/components/quick_filter/quick_filter.xml b/header_search_panel/static/src/search/header_search/components/quick_filter/quick_filter.xml similarity index 100% rename from header_search_panel/header_search_panel/static/src/search/header_search/components/quick_filter/quick_filter.xml rename to header_search_panel/static/src/search/header_search/components/quick_filter/quick_filter.xml diff --git a/header_search_panel/header_search_panel/static/src/search/header_search/components/quick_filter/quick_filter_label.scss b/header_search_panel/static/src/search/header_search/components/quick_filter/quick_filter_label.scss similarity index 100% rename from header_search_panel/header_search_panel/static/src/search/header_search/components/quick_filter/quick_filter_label.scss rename to header_search_panel/static/src/search/header_search/components/quick_filter/quick_filter_label.scss diff --git a/header_search_panel/header_search_panel/static/src/search/header_search/components/select_date_filter/select_date_filter.js b/header_search_panel/static/src/search/header_search/components/select_date_filter/select_date_filter.js similarity index 100% rename from header_search_panel/header_search_panel/static/src/search/header_search/components/select_date_filter/select_date_filter.js rename to header_search_panel/static/src/search/header_search/components/select_date_filter/select_date_filter.js diff --git a/header_search_panel/header_search_panel/static/src/search/header_search/components/select_date_filter/select_date_filter.xml b/header_search_panel/static/src/search/header_search/components/select_date_filter/select_date_filter.xml similarity index 100% rename from header_search_panel/header_search_panel/static/src/search/header_search/components/select_date_filter/select_date_filter.xml rename to header_search_panel/static/src/search/header_search/components/select_date_filter/select_date_filter.xml diff --git a/header_search_panel/header_search_panel/static/src/search/header_search/header_search_filter.js b/header_search_panel/static/src/search/header_search/header_search_filter.js similarity index 100% rename from header_search_panel/header_search_panel/static/src/search/header_search/header_search_filter.js rename to header_search_panel/static/src/search/header_search/header_search_filter.js diff --git a/header_search_panel/header_search_panel/static/src/search/header_search/header_search_filter.scss b/header_search_panel/static/src/search/header_search/header_search_filter.scss similarity index 100% rename from header_search_panel/header_search_panel/static/src/search/header_search/header_search_filter.scss rename to header_search_panel/static/src/search/header_search/header_search_filter.scss diff --git a/header_search_panel/header_search_panel/static/src/search/header_search/header_search_filter.xml b/header_search_panel/static/src/search/header_search/header_search_filter.xml similarity index 100% rename from header_search_panel/header_search_panel/static/src/search/header_search/header_search_filter.xml rename to header_search_panel/static/src/search/header_search/header_search_filter.xml diff --git a/header_search_panel/header_search_panel/static/src/search/search_arch_parser.js b/header_search_panel/static/src/search/search_arch_parser.js similarity index 100% rename from header_search_panel/header_search_panel/static/src/search/search_arch_parser.js rename to header_search_panel/static/src/search/search_arch_parser.js diff --git a/header_search_panel/header_search_panel/static/src/search/search_model.js b/header_search_panel/static/src/search/search_model.js similarity index 100% rename from header_search_panel/header_search_panel/static/src/search/search_model.js rename to header_search_panel/static/src/search/search_model.js From 94b03c72d9e09ec6c497c779df304e856ecc13a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=B9=8F=E5=AE=87?= <9664676+pengyuthon@user.noreply.gitee.com> Date: Fri, 19 Dec 2025 16:54:44 +0800 Subject: [PATCH 39/43] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../property_accounts_receivable_views.xml | 39 ++ yuthon_property_approval/__manifest__.py | 1 + .../models/inherit_yuthon_property.py | 287 ++++++-- .../security/ir.model.access.csv | 3 +- .../views/inherit_yuthon_property_views.xml | 46 ++ yuthon_property_approval/wizard/__init__.py | 3 +- .../wizard/property_deposit_wizard.py | 648 ++++++++++++++++++ .../wizard/property_deposit_wizard_views.xml | 65 ++ .../property_reconciliation_wizard_views.xml | 3 +- .../security/salary_security_rule.xml | 5 + yuthon_work_brand/views/hr_menus.xml | 10 +- 11 files changed, 1045 insertions(+), 65 deletions(-) create mode 100644 yuthon_property_approval/wizard/property_deposit_wizard.py create mode 100644 yuthon_property_approval/wizard/property_deposit_wizard_views.xml diff --git a/yuthon_property/views/property_accounts_receivable_views.xml b/yuthon_property/views/property_accounts_receivable_views.xml index 91ce9cf4e..1d06cab4a 100644 --- a/yuthon_property/views/property_accounts_receivable_views.xml +++ b/yuthon_property/views/property_accounts_receivable_views.xml @@ -37,6 +37,45 @@ + + + property.accounts.receivable.tree + property.accounts.receivable + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
- + @@ -22,7 +22,6 @@ - diff --git a/yuthon_salary/security/salary_security_rule.xml b/yuthon_salary/security/salary_security_rule.xml index 6060e35cd..ec308053c 100644 --- a/yuthon_salary/security/salary_security_rule.xml +++ b/yuthon_salary/security/salary_security_rule.xml @@ -1,5 +1,10 @@ + + 职级类型多公司 + + [('company_id', 'in', company_ids)] + 薪资方法多公司 diff --git a/yuthon_work_brand/views/hr_menus.xml b/yuthon_work_brand/views/hr_menus.xml index 839106392..37dc338d0 100644 --- a/yuthon_work_brand/views/hr_menus.xml +++ b/yuthon_work_brand/views/hr_menus.xml @@ -874,7 +874,7 @@ sequence="50"/> @@ -889,8 +889,14 @@ name="应付账单" action="yuthon_property_approval.view_property_bills_list_action" sequence="4"/> + From 8fb842829d07c3cd83954ea89b8d632d3f193bfb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=B9=8F=E5=AE=87?= <9664676+pengyuthon@user.noreply.gitee.com> Date: Fri, 19 Dec 2025 21:57:15 +0800 Subject: [PATCH 40/43] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../property_accounts_receivable_views.xml | 1 - .../models/inherit_yuthon_property.py | 326 +++------ .../models/property_lease_renewal.py | 51 +- .../security/ir.model.access.csv | 3 +- .../views/inherit_yuthon_property_views.xml | 10 +- .../views/property_lease_renewal.xml | 77 +- .../wizard/property_deposit_wizard.py | 659 ++---------------- .../wizard/property_deposit_wizard_views.xml | 53 +- 8 files changed, 252 insertions(+), 928 deletions(-) diff --git a/yuthon_property/views/property_accounts_receivable_views.xml b/yuthon_property/views/property_accounts_receivable_views.xml index 1d06cab4a..9cda09ccb 100644 --- a/yuthon_property/views/property_accounts_receivable_views.xml +++ b/yuthon_property/views/property_accounts_receivable_views.xml @@ -72,7 +72,6 @@ -
+ From 315ff358162b358d1cb17dfa3d5efa40f74cf1ac Mon Sep 17 00:00:00 2001 From: Admin Date: Thu, 11 Dec 2025 13:41:01 +0800 Subject: [PATCH 43/43] =?UTF-8?q?=E8=B7=B3=E8=BD=AC=E6=98=8E=E7=BB=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../static/src/js/financial.js | 32 ++++++++++- .../static/src/js/information.js | 30 ++++++++++ .../static/src/xml/financial.xml | 57 +++++++++++-------- .../static/src/xml/information.xml | 7 ++- yuthon_account_report/views/custom.xml | 54 +++++++++++++++--- .../views/yuthon_hr_employee_views.xml | 2 +- 6 files changed, 147 insertions(+), 35 deletions(-) diff --git a/yuthon_account_report/static/src/js/financial.js b/yuthon_account_report/static/src/js/financial.js index 9838416bc..d8e307ade 100644 --- a/yuthon_account_report/static/src/js/financial.js +++ b/yuthon_account_report/static/src/js/financial.js @@ -1,7 +1,7 @@ /** @odoo-module **/ import {registry} from "@web/core/registry"; -import {useService} from "@web/core/utils/hooks"; +import { useService } from "@web/core/utils/hooks"; const {Component, useState, onWillStart, onMounted} = owl; @@ -409,6 +409,36 @@ class FinancialPage extends Component { } + // 数据点击事件 + onDataCellClick(params){ + const queryParams = { + project_id: params.row.id, + group_id: params.group.id, + date: params.filters.date, + }; + let domain = [] + if(queryParams.date){ + domain.push(['sheet_id.create_date', '<=', queryParams.date]) + } + if(queryParams.group_id){ + domain.push(['sheet_id.company_id.id', '=', queryParams.group_id]) + } + if(queryParams.project_id){ + domain.push(['collection_id', '=', queryParams.project_id]) + } + this.action.doAction({ + type: 'ir.actions.act_window', + res_model: 'financial.sheet.line', + name: '提报数据明细', + view_mode: 'tree', + view_type: 'tree', + views: [[false, 'tree']], + target: 'new', // 以弹窗形式打开 + domain: domain, + context: {}, + }) + } + // 重置筛选条件 onReset() { this.state.filters = { diff --git a/yuthon_account_report/static/src/js/information.js b/yuthon_account_report/static/src/js/information.js index cf2e171e5..fd4aec66d 100644 --- a/yuthon_account_report/static/src/js/information.js +++ b/yuthon_account_report/static/src/js/information.js @@ -260,6 +260,36 @@ export class FinancialSinglePage extends Component { this.notification.add("使用演示数据", { type: "info" }); } + // 数据点击事件 + onDataCellClick(params){ + const queryParams = { + project_id: params.row.id, + group_id: params.group.id, + date: params.filters.date, + }; + let domain = [] + if(queryParams.date){ + domain.push(['summary_id.create_date', '<=', queryParams.date]) + } + if(queryParams.group_id && Number.isFinite(queryParams.group_id)){ + domain.push(['summary_id.company_id.id', '=', queryParams.group_id]) + } + if(queryParams.project_id){ + domain.push(['table_id', '=', queryParams.project_id]) + } + this.action.doAction({ + type: 'ir.actions.act_window', + res_model: 'information.summary.line', + name: '信息汇总明细', + view_mode: 'tree', + view_type: 'tree', + views: [[false, 'tree']], + target: 'new', // 以弹窗形式打开 + domain: domain, + context: {}, + }) + } + fillExampleData() { // 填充一些示例数据以便预览 const rows = this.state.tableData.rows; diff --git a/yuthon_account_report/static/src/xml/financial.xml b/yuthon_account_report/static/src/xml/financial.xml index 3a923dbb7..a44013689 100644 --- a/yuthon_account_report/static/src/xml/financial.xml +++ b/yuthon_account_report/static/src/xml/financial.xml @@ -12,10 +12,10 @@
@@ -23,9 +23,9 @@
@@ -50,19 +50,19 @@
- - + +
@@ -125,7 +127,8 @@ - +
@@ -155,9 +158,14 @@
- + - + @@ -169,7 +177,8 @@ - +

暂无数据

diff --git a/yuthon_account_report/static/src/xml/information.xml b/yuthon_account_report/static/src/xml/information.xml index 13338651d..ebec09c7d 100644 --- a/yuthon_account_report/static/src/xml/information.xml +++ b/yuthon_account_report/static/src/xml/information.xml @@ -160,7 +160,12 @@ - + diff --git a/yuthon_account_report/views/custom.xml b/yuthon_account_report/views/custom.xml index fd9cf7032..741ab03bd 100644 --- a/yuthon_account_report/views/custom.xml +++ b/yuthon_account_report/views/custom.xml @@ -11,15 +11,53 @@ - - - - + - - - - + + + + financial.sheet.line.tree + financial.sheet.line + + + + + + + + + + + + 财务数据表收集明细 + financial.sheet.line + tree + + + + + information.summary.line.tree + information.summary.line + + + + + + + + + + + 信息汇总收集明细 + information.summary.line + tree + diff --git a/yuthon_hr_employee/views/yuthon_hr_employee_views.xml b/yuthon_hr_employee/views/yuthon_hr_employee_views.xml index 035bb0bdd..0ad85d1b5 100644 --- a/yuthon_hr_employee/views/yuthon_hr_employee_views.xml +++ b/yuthon_hr_employee/views/yuthon_hr_employee_views.xml @@ -704,4 +704,4 @@ - \ No newline at end of file +