
本文详解如何在 Odoo 13 中安全扩展 account/static/src/js/tax_group.js 中的 JavaScript 逻辑(如修改 displayEditWidget 判断条件),重点涵盖 Python 层状态字段扩展与 JS 层类方法继承两种方式,并提供可直接复用的代码示例。
本文详解如何在 odoo 13 中安全扩展 `account/static/src/js/tax_group.js` 中的 javascript 逻辑(如修改 `displayeditwidget` 判断条件),重点涵盖 python 层状态字段扩展与 js 层类方法继承两种方式,并提供可直接复用的代码示例。
在 Odoo 13 中,若需修改 account/static/src/js/tax_group.js(实际应为 account/static/src/js/tax_group_field.js 或关联的 TaxGroupCustomField 组件)中类似第 94 行的逻辑:
var displayEditWidget = self._isPurchaseDocument() && this.record.data.state === 'draft' && this.getParent().mode === 'edit';
关键在于:该逻辑依赖后端 account.move 模型的 state 字段值。因此,扩展 JS 行为前,必须先确保新状态已在 Python 模型中正确定义——否则前端 this.record.data.state 将无法匹配到合法值,导致逻辑失效或报错。
✅ 第一步:扩展 Python 状态字段(必需)
在自定义模块中新增模型继承文件(例如 models/my_account_move.py):
from odoo import models, fields
class AccountMove(models.Model):
_inherit = "account.move"
# 使用 selection_add 安全追加新状态,不覆盖原定义
state = fields.Selection(
selection_add=[('mynewstate', 'My New State')],
ondelete={'mynewstate': 'set default'} # 可选:指定删除旧状态时的默认行为
)
同时,在 __manifest__.py 中声明依赖:
{
"name": "My Custom Account Extension",
"depends": ["account"],
"data": [],
"assets": {
"web.assets_backend": [
"my_custom_module/static/src/js/my_tax_group.js"
]
}
}
⚠️ 注意:务必重启服务并升级模块,使新状态写入数据库字段定义;否则前端将无法获取更新后的
state枚举值。
Comprehensive Three.js 3D graphics reference下载详细的 Three.js 3D 图形参考,涵盖场景设置、相机、几何体、材质、光照、动画、控制器、加载器、数学工具和调试。
✅ 第二步:继承并覆盖 JS 方法(按需)
若需进一步定制前端逻辑(例如将 'draft' 扩展为 'draft' || 'mynewstate'),需通过 Odoo 的 include() 机制“打补丁”。创建 static/src/js/my_tax_group.js:
odoo.define('my_custom_module.my_tax_group', function (require) {
"use strict";
var core = require('web.core');
var _t = core._t;
// 正确加载原始组件(注意路径与类名需与 Odoo 13 实际一致)
var TaxGroupCustomField = require('account.TaxGroupCustomField');
TaxGroupCustomField.include({
/**
* 重写 _render 方法以调整 displayEditWidget 逻辑
* @override
*/
_render: function () {
// 调用父类原始渲染逻辑
this._super.apply(this, arguments);
// 在渲染后动态修正 displayEditWidget 判断(推荐方式)
// 或在更合适的生命周期钩子(如 _onDataChanged)中处理
if (this.record && this.record.data && this.getParent()) {
var isPurchase = this._isPurchaseDocument();
var currentState = this.record.data.state;
var isInEditMode = this.getParent().mode === 'edit';
var customDisplayCondition = isPurchase &&
(currentState === 'draft' || currentState === 'mynewstate') &&
isInEditMode;
// 假设组件内部有 displayEditWidget 属性或需触发 UI 更新
// 实际需根据源码确认变量作用域及更新机制(如 this.displayEditWidget = ...; this.renderElement();)
// 示例:若需强制刷新 widget 显示状态,可调用相关私有方法或触发事件
// this._updateEditWidgetVisibility(customDisplayCondition);
}
},
});
});
? 提示:Odoo 13 中
tax_group.js实际对应组件多为TaxGroupCustomField(位于account/static/src/js/account_reconciliation_model.js或account/static/src/js/tax_group_field.js)。请通过浏览器开发者工具检查实际加载的 JS 模块名,并使用require()正确引用。若不确定,可在控制台执行require('account.TaxGroupCustomField')验证。
? 总结与最佳实践
- 优先通过 Python 扩展状态字段:这是 Odoo 数据一致性与权限控制的基础,JS 层逻辑应严格遵循后端定义。
-
JS 继承使用
include()而非重写整个模块:避免破坏原逻辑,仅覆盖必要方法。 -
避免硬编码 DOM 操作:利用 Odoo 组件生命周期(如
_render,_onDataChanged)响应数据变化。 -
测试状态流转:确保新状态
mynewstate在业务流程中可被正确设置(如通过按钮、工作流或默认值),否则前端永远无法命中该分支。
完成上述步骤后,重启服务、升级模块,新状态即可在 JS 条件判断中生效,实现灵活、可维护的前端逻辑扩展。











