# Copyright 2011-2012 Nicolas Bessi (Camptocamp SA) # Copyright 2016 Yannick Payot (Camptocamp SA) # Copyright 2023 ACSONE SA/NV # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). from odoo import _, api, fields, models from odoo.exceptions import ValidationError SUPPORTED_ATT = [ "float", "integer", "integer_big", "related", "function", "date", "datetime", "char", "text", "selection", ] NUMBER_ATT = ["float", "integer", "integer_big"] class GeoVectorLayer(models.Model): _name = "geoengine.vector.layer" _description = "Vector Layer" _order = "sequence ASC, name" geo_repr = fields.Selection( [ ("basic", "Basic"), # Actually we have to think if we should separate it for colored ("proportion", "Proportional Symbol"), ("colored", "Colored range/Chroma.js"), ], string="Representation mode", required=True, ) classification = fields.Selection( [ ("unique", "Unique value"), ("interval", "Interval"), ("quantile", "Quantile"), ("custom", "Custom"), ], string="Classification mode", required=False, ) name = fields.Char("Layer Name", translate=True, required=True) begin_color = fields.Char("Begin color class", required=False, help="hex value") end_color = fields.Char( "End color class", required=False, help="hex value", default="#FF680A" ) nb_class = fields.Integer("Number of class", default=1) geo_field_id = fields.Many2one( "ir.model.fields", "Geo field", required=True, ondelete="cascade", domain=[("ttype", "ilike", "geo_")], ) attribute_field_id = fields.Many2one( "ir.model.fields", "Attribute field", domain=[("ttype", "in", SUPPORTED_ATT)] ) model_id = fields.Many2one( "ir.model", "Model to use", store=True, readonly=False, compute="_compute_model_id", ) model_name = fields.Char(related="model_id.model", readonly=True) view_id = fields.Many2one( "ir.ui.view", "Related View", domain=[("type", "=", "geoengine")], required=True ) sequence = fields.Integer("Layer Priority", default=6) readonly = fields.Boolean("Layer is read only") display_polygon_labels = fields.Boolean("Display Labels on Polygon") active_on_startup = fields.Boolean( help="Layer will be shown on startup if checked." ) layer_opacity = fields.Float(default=1.0) model_domain = fields.Char(default="[]") model_view_id = fields.Many2one( "ir.ui.view", "Model view", domain=[("type", "=", "geoengine")], compute="_compute_model_view_id", readonly=False, ) @api.constrains("geo_field_id", "model_id") def _check_geo_field_id(self): for rec in self: if rec.model_id: if not rec.geo_field_id.model_id == rec.model_id: raise ValidationError( _( "The geo_field_id must be a field in %s model", rec.model_id.display_name, ) ) @api.constrains("geo_repr", "attribute_field_id") def _check_geo_repr(self): for rec in self: if ( rec.attribute_field_id and rec.attribute_field_id.ttype not in NUMBER_ATT ): if ( rec.geo_repr == "colored" and rec.classification != "unique" or rec.geo_repr == "proportion" ): raise ValidationError( _( "You need to select a numeric field", ) ) @api.constrains("attribute_field_id", "geo_field_id") def _check_if_attribute_in_geo_field(self): for rec in self: if rec.attribute_field_id and rec.geo_field_id: if rec.attribute_field_id.model != rec.geo_field_id.model: raise ValidationError( _( "You need to provide an attribute that exists in %s model", rec.geo_field_id.model_id.display_name, ) ) @api.depends("model_id") def _compute_model_view_id(self): for rec in self: if rec.model_id: for view in rec.model_id.view_ids: if view.type == "geoengine": rec.model_view_id = view else: rec.model_view_id = "" @api.depends("geo_field_id", "view_id") def _compute_model_id(self): for rec in self: if rec.view_id and rec.geo_field_id: if rec.view_id.model != rec.geo_field_id.model: rec.model_id = rec.geo_field_id.model_id else: rec.model_id = "" else: rec.model_id = ""