Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions fieldservice_geoengine/models/vector_layer.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,18 @@
from odoo.exceptions import ValidationError

NUMBER_ATT = ["float", "integer", "integer_big"]
SUPPORTED_ATT = [
"float",
"integer",
"integer_big",
"related",
"function",
"date",
"datetime",
"char",
"text",
"selection",
]
Comment on lines +10 to +21
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

chore (non-blocking): I see these elsewhere in the code as well, but I suspect they may have remained from previous versions, as I cannot find values of ttype matching some of these.

On a fresh odoo installation, opening a shell and inspecting env["ir.model.fields"]._fields["ttype"].selection I get the following fields

['binary', 'boolean', 'char', 'date', 'datetime', 'float', 'html', 'integer', 'json', 'many2many', 'many2one', 'many2one_reference', 'monetary', 'one2many', 'properties', 'properties_definition', 'reference', 'selection', 'text', 'serialized']

Copy link
Contributor Author

@anusriNPS anusriNPS Oct 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

env["ir.model.fields"]._fields["ttype"].selection - list all available ttype values.

fieldservice_geoengine supports only fields based on SUPPORTED_ATT and NUM_ATT which is used in domain to filter from ttype values.

ttype will not match the fields of supported_att and num_att variables and it should list all available types. ttype list seems right and this is my understanding. Please correct me, if my views differ from your thoughts.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I probably wasn't very clear. I didn't mean to imply that fields should be added to SUPPORTED_ATT, but rather that some may be removed (maybe?), like integer_big, related and function.

Either way, non-blocking.



class GeoVectorLayer(models.Model):
Expand All @@ -31,3 +43,23 @@ def _check_geo_repr(self):
"You need to select a numeric field",
)
)

@api.depends("geo_field_id", "classification", "geo_repr")
def _compute_attribute_field_id_domain(self):
for rec in self:
if rec.geo_field_id:
if (
rec.geo_repr == "colored"
and rec.classification not in ("unique", "custom")
) or rec.geo_repr == "proportion":
rec.attribute_field_id_domain = [
("ttype", "in", NUMBER_ATT),
("model", "=", rec.geo_field_id.model_id.model),
]
else:
rec.attribute_field_id_domain = [
("ttype", "in", SUPPORTED_ATT),
("model", "=", rec.geo_field_id.model_id.model),
]
else:
rec.attribute_field_id_domain = [("ttype", "in", SUPPORTED_ATT)]
1 change: 1 addition & 0 deletions fieldservice_geoengine/oca_dependencies.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
geospatial https://github.com/OCA/geospatial refs/pull/417/head 9825f67d128918294b67b74d324d1e6d3259399b
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,23 @@ patch(GeoengineRenderer.prototype, "geoengine_renderer_view_patch", {
case "unique":
case "custom":
vals = serie.getClassUniqueValues();
if (
cfg.classification === "custom" &&
vals.some((item) => item === 0)
) {
this.notification.add(
this.env._t(
"Could not generate " +
cfg.classification +
" range for selected Attribute Field: " +
indicator
),
{
type: "warning",
}
);
return false;
}
// "RdYlBu" is a set of colors
scale = chroma.scale("RdYlBu").domain([0, vals.length], vals.length);
break;
Expand All @@ -45,6 +62,18 @@ patch(GeoengineRenderer.prototype, "geoengine_renderer_view_patch", {
case "interval":
serie.getClassEqInterval(nb_class);
vals = serie.getRanges();
if (vals.some((item) => item === "0 - 0")) {
this.notification.add(
this.env._t(
"Could not generate interval range for selected Attribute Field: " +
indicator
),
{
type: "warning",
}
);
return false;
}
scale = scale.domain([0, vals.length], vals.length);
break;
}
Expand Down Expand Up @@ -81,7 +110,13 @@ patch(GeoengineRenderer.prototype, "geoengine_renderer_view_patch", {
} else if (label_text !== "") {
label_text = feature.values_.attributes.stage_name;
}
styles_map[colors[color_idx]][0].text_.text_ = label_text.toString();
try {
styles_map[colors[color_idx]][0].text_.text_ =
label_text.toString();
} catch (error) {
// Do nothing to restore history
return;
}
return styles_map[colors[color_idx]];
},
legend,
Expand Down Expand Up @@ -134,8 +169,39 @@ patch(GeoengineRenderer.prototype, "geoengine_renderer_view_patch", {
}
aux.push(data[i]);
}
const styleInfo = this.styleVectorLayer(cfg, aux);
this.initLegend(styleInfo, cfg);
lv.setStyle(styleInfo.style);
if (this.checkAttributeFieldUsage(cfg, aux)) {
const styleInfo = this.styleVectorLayer(cfg, aux);
if (styleInfo) {
this.initLegend(styleInfo, cfg);
lv.setStyle(styleInfo.style);
}
}
},
/**
* Allows you to find the index of the color to be used according to its value.
* @param {*} val
* @param {*} a
* @returns {Number}
*/
getClass(val, a) {
// Classification uniqueValues
var idx = a.indexOf(val);
if (idx > -1) {
return idx;
}
// Range classification
var separator = " - ";
for (var i = 0; i < a.length; i++) {
// All classification except uniqueValues
if (typeof val !== "object" && a[i].indexOf(separator) !== -1) {
var item = a[i].split(separator);
if (val <= parseFloat(item[1])) {
return i;
}
} else if (val === a[i]) {
// Classification uniqueValues
return i;
}
}
},
});