Skip to content

Commit

Permalink
feat(sustainability): enhance carbon tracking with supplier info inte…
Browse files Browse the repository at this point in the history
…gration

Integrate product supplier information into carbon tracking models to
improve carbon emission calculations. Add support for carbon factor
management in supplier info views, allowing manual and automatic modes.
Enhance carbon distribution validation and computation logic to include
product and supplier data, ensuring more accurate carbon footprint
assessments.
  • Loading branch information
jacopobacci committed Dec 17, 2024
1 parent 0f27725 commit 71b505f
Show file tree
Hide file tree
Showing 8 changed files with 79 additions and 29 deletions.
1 change: 1 addition & 0 deletions sustainability/models/carbon_line_mixin.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ def _get_computation_levels_mapping(self) -> dict:
"product.product": _("Product"),
"product.category": _("Product category"),
"product.template": _("Product template"),
"product.supplierinfo": _("Product supplier"),
"res.partner": _("Partner"),
"account.account": _("Account"),
"res.company": _("Company fallback"),
Expand Down
4 changes: 3 additions & 1 deletion sustainability/models/carbon_mixin.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
# Todo: make this extendable from sub modules
CARBON_MODELS = [
"carbon.factor",
"product.supplierinfo",
"product.category",
"product.product",
"product.template",
Expand Down Expand Up @@ -402,6 +403,8 @@ def has_valid_carbon_value(self, carbon_type: str):

def has_valid_carbon_distribution(self, carbon_type: str):
self.ensure_one()
if not self[f"carbon_{carbon_type}_use_distribution"]:
return True
total_percentage = sum(
[line.percentage for line in self._get_distribution_lines(carbon_type)]
)
Expand Down Expand Up @@ -445,7 +448,6 @@ def action_recompute_carbon(self, carbon_type: str = None):
carbon_type = carbon_type or self.env.context.get("carbon_type", "carbon_in")
if not hasattr(self, f"{carbon_type}_value"):
return False

getattr(self, f"_compute_{carbon_type}_mode")()
return True

Expand Down
2 changes: 1 addition & 1 deletion sustainability_purchase/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
# Data
"data/ir_cron.xml",
# Views
# "views/product_supplierinfo.xml",
"views/product_supplierinfo.xml",
"views/carbon_factor.xml",
"views/carbon_line_origin.xml",
"views/purchase_order.xml",
Expand Down
3 changes: 2 additions & 1 deletion sustainability_purchase/models/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# from . import product_supplierinfo
from . import product_supplierinfo
from . import product_product
from . import account_move_line
from . import product_template
from . import purchase_order
Expand Down
10 changes: 8 additions & 2 deletions sustainability_purchase/models/account_move_line.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,11 @@ class AccountMoveLine(models.Model):
@api.model
def _get_carbon_compute_possible_fields(self) -> list[str]:
res = super()._get_carbon_compute_possible_fields()
res = ["partner_id", "move_partner_id"] + res
res = [
"product_id",
"partner_id",
"move_partner_id",
] + res
return res

# --- Partner ---
Expand All @@ -29,7 +33,9 @@ def can_use_move_partner_id_carbon_value(self) -> bool:
)

@api.depends(
"partner_id.carbon_in_factor_id", "move_partner_id.carbon_in_factor_id"
"partner_id.carbon_in_factor_id",
"move_partner_id.carbon_in_factor_id",
"product_id.carbon_in_factor_id",
)
def _compute_carbon_debt(self, force_compute=None):
return super()._compute_carbon_debt(force_compute)
15 changes: 15 additions & 0 deletions sustainability_purchase/models/product_product.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
from odoo import api, models


class ProductProduct(models.Model):
_inherit = "product.product"

def _get_carbon_in_fallback_records(self) -> list:
res = super()._get_carbon_in_fallback_records()
return [x for x in self.seller_ids] + res

@api.depends(
"seller_ids",
)
def _compute_carbon_in_mode(self):
return super()._compute_carbon_in_mode()
23 changes: 18 additions & 5 deletions sustainability_purchase/models/product_supplierinfo.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from odoo import models
from odoo import api, models


class ProductSupplierInfo(models.Model):
Expand All @@ -10,7 +10,20 @@ def _get_carbon_in_fallback_records(self) -> list:
res = super()._get_carbon_in_fallback_records()
return res + [self.partner_id]

def _get_carbon_out_fallback_records(self) -> list:
self.ensure_one()
res = super()._get_carbon_out_fallback_records()
return res + [self.partner_id]
@api.depends("partner_id.carbon_in_factor_id")
def _compute_carbon_in_mode(self):
return super()._compute_carbon_in_mode()

@api.onchange("carbon_in_factor_id")
def _onchange_carbon_in_factor_id(self):
"""
If carbon_in_factor_id is selected, set carbon_in_is_manual to True
and carbon_in_mode to 'manual'. Otherwise, reset to default values.
"""
for record in self:
if record.carbon_in_factor_id:
record.carbon_in_is_manual = True
record.carbon_in_mode = "manual"
else:
record.carbon_in_is_manual = False
record.carbon_in_mode = "auto"
50 changes: 31 additions & 19 deletions sustainability_purchase/views/product_supplierinfo.xml
Original file line number Diff line number Diff line change
@@ -1,29 +1,41 @@
<?xml version="1.0" encoding="UTF-8" ?>
<odoo>
<data>
<record id="product_supplierinfo_tree_view2" model="ir.ui.view">
<field name="name">product_supplierinfo_tree_view2</field>
<record id="product_supplierinfo_form_view" model="ir.ui.view">
<field name="name">product_supplierinfo_form_view</field>
<field name="model">product.supplierinfo</field>
<field name="inherit_id" ref="product.product_supplierinfo_form_view" />
<field name="arch" type="xml">
<xpath expr="//group[@name='vendor']" position="after">
<group string="CO2 Settings" name="group_carbon_settings">
<field name="carbon_allowed_factor_ids" invisible="1" />
<group string="Purchases">
<label for="carbon_in_is_manual" string="Mode" />
<div class="gap-1 d-inline-flex ml-3">
<div class="opacity-50 mr-2" invisible="not carbon_in_is_manual">Undefined</div>
<div style="font-weight: bold;" invisible="carbon_in_is_manual">Undefined</div>

<field name="carbon_in_is_manual" nolabel="1" widget="boolean_toggle" class="" style="margin-left: 8px;" />
<field name="carbon_in_mode" invisible="1" />

<div class="opacity-50" invisible="carbon_in_is_manual">Set</div>
<div style="font-weight: bold;" invisible="not carbon_in_is_manual">Set</div>
</div>
<field name="carbon_in_fallback_reference" widget="reference" invisible="carbon_in_is_manual" />
<field name="carbon_in_factor_id" string="Emission Factor" invisible="not carbon_in_is_manual" required="carbon_in_is_manual" />
</group>
</group>
</xpath>
</field>
</record>

<record id="sustainability_product_supplierinfo_tree_view" model="ir.ui.view">
<field name="name">sustainability.product.supplierinfo.tree.view</field>
<field name="model">product.supplierinfo</field>
<field name="inherit_id" ref="purchase.product_supplierinfo_tree_view2" />
<field name="arch" type="xml">
<xpath expr="//tree" position="inside">
<field name="carbon_in_value" readonly="carbon_in_factor_id" force_save="1" />
<button
type="object"
name="action_see_carbon_origin"
icon="fa-question-circle"
context="{'carbon_type': 'carbon_in'}"
title="See CO2e value origin"
readonly="carbon_in_factor_id"
/>
<button
type="object"
name="action_recompute_carbon"
icon="fa-refresh"
context="{'carbon_type': 'carbon_in'}"
title="Re-compute CO2e value"
readonly="carbon_in_factor_id"
/>
<field column_invisible="1" name="carbon_allowed_factor_ids" />
<field name="carbon_in_factor_id" string="Emission Factor" />
</xpath>
</field>
Expand Down

0 comments on commit 71b505f

Please sign in to comment.