Files
enterprise-addons/esg/models/esg_emission_source.py
T

122 lines
4.7 KiB
Python

from odoo import api, fields, models
from odoo.exceptions import ValidationError
from odoo.fields import Domain
class EsgEmissionSource(models.Model):
_name = 'esg.emission.source'
_description = 'Emission Source'
_order = 'level desc,sequence,name'
_rec_name = 'complete_name'
_parent_name = 'parent_id'
_parent_store = True
sequence = fields.Integer(default=10)
name = fields.Char(translate=True, required=True)
parent_id = fields.Many2one('esg.emission.source', domain="['!', ('id', 'child_of', id)]", index=True)
child_ids = fields.One2many('esg.emission.source', 'parent_id')
parent_path = fields.Char(index=True)
complete_name = fields.Char(compute='_compute_complete_name', search='_search_complete_name', recursive=True)
scope = fields.Selection(selection=[
('direct', 'Scope 1: Direct'),
('indirect', 'Scope 2: Indirect'),
('indirect_others', 'Scope 3: Others Indirect')
],
default='direct',
compute='_compute_scope',
store=True,
readonly=False,
recursive=True,
required=True,
)
activity_flow_direct_indirect = fields.Selection(
selection=[
('company_reporting', 'Company Reporting'),
('upstream', 'Upstream'),
],
compute='_compute_activity_flow',
export_string_translation=False,
)
activity_flow_indirect_others = fields.Selection(
selection=[
('upstream', 'Upstream'),
('downstream', 'Downstream'),
],
required=True,
default='upstream',
export_string_translation=False,
)
activity_flow = fields.Selection(
selection=lambda self: list(set(self._fields['activity_flow_direct_indirect'].selection) | set(self._fields['activity_flow_indirect_others'].selection)),
compute='_compute_activity_flow',
)
level = fields.Integer(compute='_compute_level', store=True, recursive=True)
@api.constrains('parent_id')
def _check_no_cyclic_dependencies(self):
for source in self:
parent_path_ids = source.parent_path[:-1].split("/")
if len(parent_path_ids) != len(set(parent_path_ids)):
raise ValidationError(self.env._("You cannot create a cyclic hierarchy of emission sources."))
@api.depends('parent_id.level')
def _compute_level(self):
for source in self:
if not source.parent_id:
source.level = 1
else:
source.level = source.parent_id.level + 1
@api.depends('parent_id.scope')
def _compute_scope(self):
for source in self:
if not source.parent_id:
continue
source.scope = source.parent_id.scope
@api.depends('scope', 'activity_flow_indirect_others')
def _compute_activity_flow(self):
for source in self:
source.activity_flow_direct_indirect = source.activity_flow = False
match source.scope:
case 'direct':
source.activity_flow_direct_indirect = source.activity_flow = 'company_reporting'
case 'indirect':
source.activity_flow_direct_indirect = source.activity_flow = 'upstream'
case 'indirect_others':
source.activity_flow = source.activity_flow_indirect_others
@api.depends('name', 'parent_id.complete_name', 'scope')
def _compute_complete_name(self):
for source in self:
if source.parent_id:
source.complete_name = f"{source.parent_id.complete_name} > {source.name}"
else:
source.complete_name = f"{dict(self.env['esg.emission.source']._fields['scope']._description_selection(self.env)).get(source.scope)} > {source.name}"
@api.model
def _search_complete_name(self, operator, value):
if operator not in ('ilike', 'like', '=', '=ilike'):
raise NotImplementedError(f"Operator {operator} not supported")
domain = Domain('name', operator, value)
scope_labels = dict(self.env['esg.emission.source']._fields['scope']._description_selection(self.env))
matching_scope_keys = [
key for key, label in scope_labels.items()
if (
operator in ('ilike', '=ilike') and value in label.lower()
) or (
operator in ('like', '=') and value in label
)
]
if matching_scope_keys:
domain |= Domain('scope', 'in', matching_scope_keys)
matched_sources = self.env['esg.emission.source'].search(domain)
if not matched_sources:
return Domain.FALSE
return Domain('id', 'child_of', matched_sources.ids)