Skip to content

Commit 8f636ba

Browse files
[MIG] web_form_banner: Migration to 15.0
1 parent 9de2fb4 commit 8f636ba

File tree

5 files changed

+81
-82
lines changed

5 files changed

+81
-82
lines changed

web_form_banner/__manifest__.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,22 @@
22
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
33
{
44
"name": "Web Form Banner",
5-
"version": "12.0.1.0.0",
5+
"version": "15.0.1.0.0",
66
"category": "Web",
77
"author": "Quartile, Odoo Community Association (OCA)",
88
"website": "https://github.com/OCA/web",
99
"license": "AGPL-3",
1010
"depends": ["web"],
1111
"data": [
1212
"security/ir.model.access.csv",
13-
"views/assets.xml",
1413
"views/web_form_banner_rule_views.xml",
1514
],
15+
"assets": {
16+
"web.assets_backend": [
17+
"web_form_banner/static/src/js/*.esm.js",
18+
"web_form_banner/static/src/scss/*.scss",
19+
],
20+
},
1621
"demo": ["demo/web_form_banner_rule_demo.xml"],
1722
"installable": True,
1823
}

web_form_banner/models/web_form_banner_rule.py

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
# Copyright 2025 Quartile (https://www.quartile.co)
22
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
33

4-
import datetime as dt
54
import logging
6-
import time
75
from functools import lru_cache
86
from string import Template
97

@@ -14,9 +12,8 @@
1412

1513
from odoo import _, api, fields, models
1614
from odoo.exceptions import ValidationError
17-
from odoo.tools import html_escape
15+
from odoo.tools import html_escape, safe_eval
1816
from odoo.tools.float_utils import float_compare, float_is_zero, float_round
19-
from odoo.tools.safe_eval import safe_eval
2017

2118
_logger = logging.getLogger(__name__)
2219

@@ -115,7 +112,6 @@ class WebFormBannerRule(models.Model):
115112
)
116113
position = fields.Selection(
117114
[("before", "Before target"), ("after", "After target")],
118-
string="Position",
119115
default="before",
120116
required=True,
121117
help="Where to insert the placeholder relative to the first matched node.",
@@ -158,7 +154,7 @@ def _check_target_xpath(self):
158154
try:
159155
etree.XPath(xp or "//sheet")
160156
except (etree.XPathSyntaxError, etree.XPathEvalError) as e:
161-
raise ValidationError(_("Invalid XPath:\n%s") % e)
157+
raise ValidationError(_("Invalid XPath:\n%s") % e) from e
162158

163159
@api.model
164160
def _build_form_url(self, rec):
@@ -179,8 +175,8 @@ def _build_form_url(self, rec):
179175
def _base_eval_ctx_static(self):
180176
# Only static, import-heavy items
181177
return {
182-
"time": time,
183-
"datetime": dt,
178+
"time": safe_eval.time,
179+
"datetime": safe_eval.datetime,
184180
"dateutil": {
185181
"parser": dateparse,
186182
"relativedelta": relativedelta,
@@ -240,9 +236,9 @@ def _run_rule_code(self, rule, eval_ctx):
240236
return {}
241237
code = rule.message_value_code.strip()
242238
try:
243-
out = safe_eval(code, eval_ctx, mode="eval") or {}
239+
out = safe_eval.safe_eval(code, eval_ctx, mode="eval") or {}
244240
except Exception:
245-
safe_eval(code, eval_ctx, mode="exec", nocopy=True)
241+
safe_eval.safe_eval(code, eval_ctx, mode="exec", nocopy=True)
246242
out = eval_ctx.get("result") or {}
247243
return out if isinstance(out, dict) else {}
248244

web_form_banner/static/src/js/web_form_banner.js renamed to web_form_banner/static/src/js/web_form_banner.esm.js

Lines changed: 68 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
odoo.define("web_form_banner.save_plus_load", function (require) {
2-
"use strict";
32
var rpc = require("web.rpc");
43
var FormController = require("web.FormController");
54

@@ -20,7 +19,7 @@ odoo.define("web_form_banner.save_plus_load", function (require) {
2019
var first = function () {
2120
for (var i = 0; i < arguments.length; i++) {
2221
var v = arguments[i];
23-
if (v != null && v !== "") return v;
22+
if (v !== null && v !== "") return v;
2423
}
2524
return null;
2625
};
@@ -44,7 +43,7 @@ odoo.define("web_form_banner.save_plus_load", function (require) {
4443
var k = kv[0],
4544
v = kv[1],
4645
t = typeof v;
47-
if (v == null || t === "string" || t === "number" || t === "boolean") {
46+
if (v === null || t === "string" || t === "number" || t === "boolean") {
4847
o[k] = v;
4948
} else if (v && v.type === "record" && typeof v.res_id === "number") {
5049
o[k] = v.res_id;
@@ -88,61 +87,77 @@ odoo.define("web_form_banner.save_plus_load", function (require) {
8887
return out;
8988
};
9089

90+
function ensureCommitted(ctrl) {
91+
const r = ctrl && ctrl.renderer;
92+
return r && typeof r.confirmChange === "function"
93+
? r.confirmChange()
94+
: Promise.resolve();
95+
}
96+
9197
function refreshBanners(ctrl) {
92-
if (!alive(ctrl)) return;
93-
var st = ctrl.model && ctrl.handle ? ctrl.model.get(ctrl.handle) : null;
94-
var resId = st && st.res_id;
98+
return ensureCommitted(ctrl).then(() => {
99+
if (!alive(ctrl)) return;
100+
var st = ctrl.model && ctrl.handle ? ctrl.model.get(ctrl.handle) : null;
101+
var resId = st && st.res_id;
95102

96-
// Sanitize snapshots
97-
var snap = shrinkDraft(st && st.data) || {};
98-
var diff = resId ? shrinkDraft(st && st.changes) || {} : {};
103+
// Sanitize snapshots
104+
var snap = shrinkDraft(st && st.data) || {};
105+
var diff = resId ? shrinkDraft(st && st.changes) || {} : {};
99106

100-
// For existing: include current values for trigger fields, then overlay diffs
101-
var tset = triggerSet(ctrl);
102-
var formVals = !resId
103-
? snap
104-
: Object.keys(tset).length
105-
? pickKeys(snap, tset)
106-
: {};
107-
Object.keys(diff).forEach(function (k) {
108-
formVals[k] = diff[k];
109-
});
107+
// For existing: include current values for trigger fields, then overlay diffs
108+
var tset = triggerSet(ctrl);
109+
var formVals = !resId
110+
? snap
111+
: Object.keys(tset).length
112+
? pickKeys(snap, tset)
113+
: {};
114+
Object.keys(diff).forEach(function (k) {
115+
formVals[k] = diff[k];
116+
});
110117

111-
var els = bannersIn(ctrl);
112-
for (var i = 0; i < els.length; i++) {
113-
var el = els[i];
114-
var ruleId = parseInt(first(el.dataset.ruleId, el.dataset.wfbRuleId), 10);
115-
var model = first(el.dataset.model, el.dataset.wfbModel, ctrl.modelName);
118+
var els = bannersIn(ctrl);
119+
for (var i = 0; i < els.length; i++) {
120+
var el = els[i];
121+
var ruleId = parseInt(
122+
first(el.dataset.ruleId, el.dataset.wfbRuleId),
123+
10
124+
);
125+
var model = first(
126+
el.dataset.model,
127+
el.dataset.wfbModel,
128+
ctrl.modelName
129+
);
116130

117-
(function (elRef) {
118-
rpc.query({
119-
model: "web.form.banner.rule",
120-
method: "compute_message",
121-
args: [ruleId, model, resId, formVals],
122-
}).then(function (res) {
123-
if (!alive(ctrl)) return;
124-
res = res || {};
125-
if (!res.visible) {
126-
elRef.style.display = "none";
127-
var sp0 = childSpan(elRef);
128-
if (sp0) sp0.innerHTML = "";
129-
else elRef.innerHTML = "";
130-
return;
131-
}
132-
var sev = first(
133-
res.severity,
134-
elRef.dataset.defaultSeverity,
135-
"danger"
136-
);
137-
var html = res.html || "";
138-
elRef.className = "o_form_banner alert alert-" + sev;
139-
var sp = childSpan(elRef);
140-
if (sp) sp.innerHTML = html;
141-
else elRef.innerHTML = html;
142-
elRef.style.display = "";
143-
});
144-
})(el);
145-
}
131+
(function (elRef) {
132+
rpc.query({
133+
model: "web.form.banner.rule",
134+
method: "compute_message",
135+
args: [ruleId, model, resId, formVals],
136+
}).then(function (res) {
137+
if (!alive(ctrl)) return;
138+
res = res || {};
139+
if (!res.visible) {
140+
elRef.style.display = "none";
141+
var sp0 = childSpan(elRef);
142+
if (sp0) sp0.innerHTML = "";
143+
else elRef.innerHTML = "";
144+
return;
145+
}
146+
var sev = first(
147+
res.severity,
148+
elRef.dataset.defaultSeverity,
149+
"danger"
150+
);
151+
var html = res.html || "";
152+
elRef.className = "o_form_banner alert alert-" + sev;
153+
var sp = childSpan(elRef);
154+
if (sp) sp.innerHTML = html;
155+
else elRef.innerHTML = html;
156+
elRef.style.display = "";
157+
});
158+
})(el);
159+
}
160+
});
146161
}
147162

148163
function withRefresh(ctrl, superFn, args) {

web_form_banner/tests/test_web_form_banner.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ def setUpClass(cls):
2020
cls.rule_email.active = False
2121
cls.rule_tag.active = False
2222
cls.partner_form_view = cls.env.ref("base.view_partner_form")
23-
2423
cls.p_len3 = cls.Partner.create({"name": "Bob"}) # 3
2524
cls.p_len12 = cls.Partner.create({"name": "Yoshi Tashiro"}) # 12
2625
cls.p_len22 = cls.Partner.create({"name": "Professor Charles Xavier"}) # 22

web_form_banner/views/assets.xml

Lines changed: 0 additions & 16 deletions
This file was deleted.

0 commit comments

Comments
 (0)