Files
enterprise-addons/esg/tests/test_esg_carbon_emissions.py
T

624 lines
41 KiB
Python

from dateutil.relativedelta import relativedelta
from freezegun import freeze_time
from odoo import fields
from odoo.fields import Command
from odoo.fields import Domain
from odoo.tools import float_compare
from odoo.exceptions import ValidationError
from odoo.addons.esg.tests.esg_common import TestEsgCommon
class TestEsgCarbonEmission(TestEsgCommon):
def test_physical_method_other_emission_value(self):
other_emission = self.env['esg.other.emission'].create({
'name': 'Package Delivery',
'date': fields.Date.today(),
'esg_emission_factor_id': self.emission_factor_delivery_transportation.id,
'uom_id': self.env.ref('uom.product_uom_mile').id,
'quantity': 100,
})
self.assertAlmostEqual(other_emission.esg_emissions_value, 16.09344) # 100 (emission quantity) * 0.1 (factor value) * 1.60934 (mile->km conversion) = 16.09344 kgCO2e
self.assertAlmostEqual(other_emission.esg_uncertainty_absolute_value, 5.632704) # 16.09344 (emission value) * 0.35 (factor uncertainty) = 5.632704 kgCO2e
# Change quantity
other_emission.quantity = 200
self.assertAlmostEqual(other_emission.esg_emissions_value, 32.18688) # 200 (emission quantity) * 0.1 (factor value) * 1.60934 (mile->km conversion) = 32.18688 kgCO2e
self.assertAlmostEqual(other_emission.esg_uncertainty_absolute_value, 11.265408) # 32.18688 (emission value) * 0.35 (factor uncertainty) = 11.265408 kgCO2e
def test_monetary_method_other_emission_value(self):
other_emission = self.env['esg.other.emission'].create({
'name': 'Office Electricity',
'date': fields.Date.today(),
'esg_emission_factor_id': self.emission_factor_electricity_consumption.id,
'currency_id': self.env.ref('base.EUR').id,
'quantity': 150,
})
self.assertEqual(other_emission.esg_emissions_value, 1.5) # 150 (emission quantity) * 0.01 (factor value) * 1.0 (EUR->EUR conversion) = 1.5 kgCO2e
self.assertEqual(other_emission.esg_uncertainty_absolute_value, 0.375) # 1.5 (emission value) * 0.25 (factor uncertainty) = 0.375 kgCO2e
# Change quantity
other_emission.quantity = 300
self.assertEqual(other_emission.esg_emissions_value, 3) # 300 (emission quantity) * 0.01 (factor value) * 1.0 (EUR->EUR conversion) = 3 kgCO2e
self.assertEqual(other_emission.esg_uncertainty_absolute_value, 0.75) # 3 (emission value) * 0.25 (factor uncertainty) = 0.75 kgCO2e
other_emission_foreign_currency = self.env['esg.other.emission'].create({
'name': 'Office Electricity',
'date': '2024-12-01',
'esg_emission_factor_id': self.emission_factor_electricity_consumption.id,
'currency_id': self.env.ref('base.USD').id,
'quantity': 150,
})
self.assertEqual(other_emission_foreign_currency.esg_emissions_value, 3) # 150 (emission quantity) * 0.01 (factor value) * 2.0 (USD->EUR conversion) = 3 kgCO2e
self.assertEqual(other_emission_foreign_currency.esg_uncertainty_absolute_value, 0.75) # 3 (emission value) * 0.25 (factor uncertainty) = 0.75 kgCO2e
# Change quantity
other_emission_foreign_currency.quantity = 300
self.assertEqual(other_emission_foreign_currency.esg_emissions_value, 6) # 300 (emission quantity) * 0.01 (factor value) * 2.0 (USD->EUR conversion) = 6 kgCO2e
self.assertEqual(other_emission_foreign_currency.esg_uncertainty_absolute_value, 1.5) # 6 (emission value) * 0.25 (factor uncertainty) = 1.5 kgCO2e
def test_physical_method_account_move_line_emission_value(self):
bill_line = self.env['account.move.line'].create({
'move_id': self.bill_1.id,
'name': 'Computer',
'quantity': 50,
'esg_emission_factor_id': self.emission_factor_computers_production.id,
'product_uom_id': self.env.ref('uom.product_uom_unit').id,
})
self.assertEqual(bill_line.esg_emissions_value, 4648.0) # 50 (aml quantity) * 92.96 (factor value) * 1.0 (unit->unit conversion) = 4648 kgCO2e
self.assertEqual(float_compare(bill_line.esg_uncertainty_absolute_value, 697.199, precision_rounding=3), 0) # 4663.5 (emission value) * 0.15 (factor uncertainty) = 697.199 kgCO2e
# Change quantity
bill_line.quantity = 100
self.assertEqual(bill_line.esg_emissions_value, 9296.0) # 100 (aml quantity) * 92.96 (factor value) * 1.0 (unit->unit conversion) = 9296.0 kgCO2e
self.assertEqual(float_compare(bill_line.esg_uncertainty_absolute_value, 1394.39, precision_rounding=2), 0) # 9327 (emission value) * 0.15 (factor uncertainty) = 1394.39 kgCO2e
def test_physical_method_account_move_line_emission_value_with_relative_uom(self):
self.assertEqual(self.emission_factor_phones_production.uom_id, self.env.ref('uom.product_uom_unit'))
bill_line_values = {
'move_id': self.bill_1.id,
'name': 'Computer',
'quantity': 50,
'esg_emission_factor_id': self.emission_factor_phones_production.id,
}
bill_line_1 = self.env['account.move.line'].create({
**bill_line_values,
'product_uom_id': self.env.ref('uom.product_uom_dozen').id,
})
self.assertEqual(bill_line_1.esg_emissions_value, 45000) # 50 (aml quantity) * 75 (factor value) * 12.0 (pack of 12 units->unit conversion) = 45000 kgCO2e
self.assertEqual(bill_line_1.esg_uncertainty_absolute_value, 11250) # 45000 (emission value) * 0.25 (factor uncertainty) = 11250 kgCO2e
# Inverse both uoms
self.emission_factor_phones_production.uom_id = self.env.ref('uom.product_uom_dozen')
bill_line_2 = self.env['account.move.line'].create({
**bill_line_values,
'product_uom_id': self.env.ref('uom.product_uom_unit').id,
})
self.assertEqual(bill_line_2.esg_emissions_value, 312.5) # 50 (aml quantity) * 75 (factor value) * 1/12.0 (unit->pack of 12 units conversion) = 312.5 kgCO2e
self.assertEqual(bill_line_2.esg_uncertainty_absolute_value, 78.125) # 312.5 (emission value) * 0.25 (factor uncertainty) = 78.125 kgCO2e
def test_monetary_method_account_move_line_emission_value(self):
for account, esg_usable in self.accounts_to_esg_usable.items():
# Test with all usable account types and a non-usable one.
with self.subTest(account=account, esg_usable=esg_usable):
bill_line = self.env['account.move.line'].create({
'move_id': self.bill_1.id,
'name': 'Foreign Electricity Consumption',
'price_unit': 100.0,
'esg_emission_factor_id': self.emission_factor_foreign_electricity_consumption.id,
'account_id': account.id,
})
self.assertEqual(bill_line.esg_emissions_value, 2.5 if esg_usable else 0) # 100.0 (aml price) * 0.05 (factor value) * 0.5 (EUR->USD conversion) = 2.5 kgCO2e
self.assertEqual(bill_line.esg_uncertainty_absolute_value, 1.125 if esg_usable else 0) # 2.5 (emission value) * 0.45 (factor uncertainty) = 1.125 kgCO2e
# Change price
bill_line.price_unit = 200.0
self.assertEqual(bill_line.esg_emissions_value, 5.0 if esg_usable else 0) # 200.0 (aml price) * 0.05 (factor value) * 0.5 (EUR->USD conversion) = 5 kgCO2e
self.assertEqual(bill_line.esg_uncertainty_absolute_value, 2.25 if esg_usable else 0) # 5.0 (emission value) * 0.45 (factor uncertainty) = 2.25 kgCO2e
def test_compute_method_other_emission(self):
other_emission = self.env['esg.other.emission'].create({
'name': 'Package Delivery',
'date': fields.Date.today(),
'esg_emission_factor_id': self.emission_factor_delivery_transportation.id,
'quantity': 100,
})
self.assertEqual(other_emission.compute_method, 'physically', 'The compute method of the emission should be the same as the emission factor')
self.assertEqual(other_emission.uom_id, self.env.ref('uom.product_uom_km'), 'The default UoM should be the same as the emission factor')
other_emission.esg_emission_factor_id = self.emission_factor_electricity_consumption.id
self.assertFalse(other_emission.uom_id, 'The UoM should be empty as the compute method has changed')
self.assertEqual(other_emission.compute_method, 'monetary', 'The compute method of the emission should be the same as the emission factor')
self.assertEqual(other_emission.currency_id, self.env.ref('base.EUR'), 'The default currency should be the same as the emission factor')
def test_gas_multiplicator_value_account_move_line(self):
for account, esg_usable in self.accounts_to_esg_usable.items():
# Test with all usable account types and a non-usable one.
with self.subTest(account=account, esg_usable=esg_usable):
bill_line = self.env['account.move.line'].create({
'move_id': self.bill_1.id,
'name': 'Computer',
'quantity': 50,
'esg_emission_factor_id': self.emission_factor_phones_production.id,
'product_uom_id': self.env.ref('uom.product_uom_unit').id,
'account_id': account.id,
})
# Test on physical compute method
self.assertEqual(bill_line.esg_emission_multiplicator, 50 if esg_usable else 0) # 50 (aml quantity) * 1.0 (unit->unit conversion) = 50
self.assertEqual(bill_line.esg_emissions_value, 3750 if esg_usable else 0) # 50 (gas multiplicator) * 75 (factor value) = 3750 kgCO2e
bill_line.quantity = 100
self.assertEqual(bill_line.esg_emission_multiplicator, 100 if esg_usable else 0, 'The gas multiplicator should have doubled')
self.assertEqual(bill_line.esg_emissions_value, 7500 if esg_usable else 0, 'The emissions value should have doubled too')
# Remove the emission factor from the bill line
bill_line.esg_emission_factor_id = False
self.assertEqual(bill_line.esg_emission_multiplicator, 0, 'The gas multiplicator should be 0 as the emission factor is empty')
self.assertEqual(bill_line.esg_emissions_value, 0, 'The emissions value should be 0 as the emission factor is empty')
# Add a new emission factor to the bill line: test on monetary compute method
bill_line.esg_emission_factor_id = self.emission_factor_electricity_consumption
self.assertEqual(bill_line.esg_emission_multiplicator, 0, 'The gas multiplicator should be 0 as the amount is 0')
self.assertEqual(bill_line.esg_emissions_value, 0, 'The emissions value should be 0 as the amount is 0')
bill_line.price_unit = 5
self.assertEqual(bill_line.price_subtotal, 500) # price_subtotal = 5 * 100 (quantity) = 500 EUR
self.assertEqual(bill_line.esg_emission_multiplicator, 500 if esg_usable else 0) # 500 (aml price_subtotal) * 1.0 (EUR->EUR conversion) = 500
self.assertEqual(bill_line.esg_emissions_value, 5 if esg_usable else 0) # 500 (gas multiplicator) * 0.01 (factor value) = 5 kgCO2e
bill_line.price_unit = 10
self.assertEqual(bill_line.price_subtotal, 1000) # price_subtotal = 10 * 100 (quantity) = 1000 EUR
self.assertEqual(bill_line.esg_emission_multiplicator, 1000 if esg_usable else 0, 'The gas multiplicator should have doubled')
self.assertEqual(bill_line.esg_emissions_value, 10 if esg_usable else 0, 'The emissions value should have doubled too')
# Switch back to physical compute method
bill_line.esg_emission_factor_id = self.emission_factor_phones_production
self.assertEqual(bill_line.esg_emission_multiplicator, 100 if esg_usable else 0, 'The gas multiplicator should have been recomputed')
self.assertEqual(bill_line.esg_emissions_value, 7500 if esg_usable else 0, 'The emissions value should have been recomputed')
def test_gas_multiplicator_value_other_emission(self):
other_emission = self.env['esg.other.emission'].create({
'name': 'Package Delivery',
'date': fields.Date.today(),
'esg_emission_factor_id': self.emission_factor_delivery_transportation.id,
'quantity': 150,
'uom_id': self.env.ref('uom.product_uom_km').id,
})
# Test on physical compute method
self.assertEqual(other_emission.esg_emission_multiplicator, 150) # 150 (emission quantity) * 1.0 (km->km conversion) = 150
self.assertEqual(other_emission.esg_emissions_value, 15) # 150 (gas multiplicator) * 0.1 (factor value) = 15 kgCO2e
other_emission.quantity = 300
self.assertEqual(other_emission.esg_emission_multiplicator, 300, 'The gas multiplicator should have doubled')
self.assertEqual(other_emission.esg_emissions_value, 30, 'The emissions value should have doubled too')
# Remove the emission factor from the other emission
other_emission.esg_emission_factor_id = False
self.assertEqual(other_emission.esg_emission_multiplicator, 0, 'The gas multiplicator should be 0 as the emission factor is empty')
self.assertEqual(other_emission.esg_emissions_value, 0, 'The emissions value should be 0 as the emission factor is empty')
# Add a new emission factor to the other emission: test on monetary compute method
other_emission.currency_id = self.env.ref('base.EUR')
other_emission.esg_emission_factor_id = self.emission_factor_electricity_consumption
self.assertEqual(other_emission.esg_emission_multiplicator, 300) # 300 (emission quantity) * 1.0 (EUR->EUR conversion) = 300
self.assertEqual(other_emission.esg_emissions_value, 3) # 300 (gas multiplicator) * 0.01 (factor value) = 3 kgCO2e
other_emission.quantity = 600
self.assertEqual(other_emission.esg_emission_multiplicator, 600, 'The gas multiplicator should have doubled')
self.assertEqual(other_emission.esg_emissions_value, 6, 'The emissions value should have doubled too')
# Switch back to physical compute method
other_emission.esg_emission_factor_id = self.emission_factor_delivery_transportation
self.assertEqual(other_emission.esg_emission_multiplicator, 600, 'The gas multiplicator should have been recomputed') # 600 (emission quantity) * 1.0 (km->km conversion) = 600
self.assertEqual(other_emission.esg_emissions_value, 60, 'The emissions value should have been recomputed') # 600 (gas multiplicator) * 0.1 (factor value) = 60 kgCO2e
def test_auto_assign_factor_to_account_move_line_case_1(self):
# Assignation rule 1 and 2
for account, esg_usable in self.accounts_to_esg_usable.items():
# Test with all usable account types and a non-usable one.
with self.subTest(account=account, esg_usable=esg_usable):
create_values = [
{
'product_id': self.product_a.id,
'partner_id': self.partner_a.id,
'account_id': account.id,
'esg_emission_factor_id': self.emission_factor_computers_production.id,
},
{
'product_id': self.product_b.id,
'partner_id': self.partner_a.id,
'account_id': account.id,
'esg_emission_factor_id': self.emission_factor_delivery_transportation.id,
},
]
if not esg_usable:
with self.assertRaises(ValidationError, msg='The account should have a valid type for ESG assignation rules'):
self.env['esg.assignation.line'].create(create_values)
else:
self.env['esg.assignation.line'].create(create_values)
bill_line = self.env['account.move.line'].create({
'move_id': self.bill_1.id,
'product_id': self.product_b.id,
'account_id': account.id,
})
self.assertEqual(
bill_line.esg_emission_factor_id,
self.emission_factor_delivery_transportation if esg_usable else self.env['esg.emission.factor'],
'The assignation rule 2 matches the most criteria, so it should be used to assign this emission factor to the move line',
)
def test_auto_assign_factor_to_account_move_line_case_2(self):
# Assignation rule 1 and 2
self.env['esg.assignation.line'].create([
{
'partner_id': self.partner_a.id,
'esg_emission_factor_id': self.emission_factor_computers_production.id,
},
{
'product_id': self.product_b.id,
'partner_id': self.partner_b.id,
'esg_emission_factor_id': self.emission_factor_delivery_transportation.id,
},
])
bill_line = self.env['account.move.line'].create({
'move_id': self.bill_1.id,
'product_id': self.product_b.id,
})
self.assertEqual(
bill_line.esg_emission_factor_id,
self.emission_factor_computers_production,
'The assignation rule 1 matches the most criteria, so it should be used to assign this emission factor to the move line',
)
def test_auto_assign_factor_to_account_move_line_case_3(self):
# Assignation rule 1 and 2
self.env['esg.assignation.line'].create([{
'product_id': self.product_a.id,
'esg_emission_factor_id': self.emission_factor_computers_production.id,
}])
for account, esg_usable in self.accounts_to_esg_usable.items():
# Test with all usable account types and a non-usable one.
with self.subTest(account=account, esg_usable=esg_usable):
create_values = {
'partner_id': self.partner_a.id,
'account_id': account.id,
'esg_emission_factor_id': self.emission_factor_delivery_transportation.id,
}
if not esg_usable:
with self.assertRaises(ValidationError, msg='The account should have a valid type for ESG assignation rules'):
self.env['esg.assignation.line'].create(create_values)
else:
self.env['esg.assignation.line'].create(create_values)
bill_line = self.env['account.move.line'].create({
'move_id': self.bill_1.id,
'product_id': self.product_a.id,
'account_id': account.id,
})
self.assertEqual(
bill_line.esg_emission_factor_id,
self.emission_factor_computers_production if esg_usable else self.env['esg.emission.factor'],
'The assignation rule 1 matches the most important criteria (product > partner > account), so it should be used to assign this emission factor to the move line',
)
def test_auto_assign_factor_to_account_move_line_change_product(self):
# Assignation rule 1 and 2
self.env['esg.assignation.line'].create([
{
'product_id': self.product_a.id,
'esg_emission_factor_id': self.emission_factor_computers_production.id,
},
{
'product_id': self.product_b.id,
'esg_emission_factor_id': self.emission_factor_delivery_transportation.id,
},
])
bill_line = self.env['account.move.line'].create({
'move_id': self.bill_1.id,
'product_id': self.product_a.id,
})
self.assertEqual(
bill_line.esg_emission_factor_id,
self.emission_factor_computers_production,
'The assignation rule 1 matches the product, so it should be used to assign this emission factor to the move line',
)
bill_line.product_id = self.product_b.id
self.assertEqual(
bill_line.esg_emission_factor_id,
self.emission_factor_delivery_transportation,
'The assignation rule 2 matches the product, so it should be used to assign this emission factor to the move line',
)
bill_line.product_id = self.product.id
self.assertFalse(
bill_line.esg_emission_factor_id,
'No assignation rule matches the product, so the emission factor should be empty',
)
@freeze_time('2024-12-31')
def test_apply_factors_auto_assignment_wizard(self):
self.bill_1.date = fields.Date.today() - relativedelta(days=15)
# bill_line_1 & bill_line_2 -> with factor
# bill_line_3 & bill_line_4 -> without factor
bill_line_1, bill_line_2, bill_line_3, bill_line_4 = self.env['account.move.line'].create([
{
'move_id': self.bill_1.id,
'product_id': self.product_a.id,
'price_unit': 250.0,
'account_id': self.expense_account.id,
},
{
'move_id': self.bill_1.id,
'product_id': self.product_b.id,
'price_unit': 150.0,
'account_id': self.expense_account.id,
},
{
'move_id': self.bill_1.id,
'product_id': self.product_a.id,
'quantity': 50,
'account_id': self.expense_account.id,
'esg_emission_factor_id': self.emission_factor_delivery_transportation.id,
},
{
'move_id': self.bill_1.id,
'product_id': self.product_b.id,
'quantity': 200,
'account_id': self.expense_account.id,
'esg_emission_factor_id': self.emission_factor_delivery_transportation.id,
},
])
# Add an assignation rule
assignation_line = self.env['esg.assignation.line'].create({
'product_id': self.product_a.id,
'esg_emission_factor_id': self.emission_factor_computers_production.id,
})
# Run the factor rule matching with factor replacement not allowed
self.env['factors.auto.assignment.wizard'].with_context(active_ids=self.emission_factor_computers_production.ids).create({
'start_date': fields.Date.today() - relativedelta(days=30),
'end_date': fields.Date.today(),
'replace_previous_factors': False,
}).action_save()
self.assertEqual(
bill_line_1.esg_emission_factor_id,
self.emission_factor_computers_production,
'The assignation rule matches the product, so it should be used to assign this emission factor to the move line',
)
self.assertFalse(
bill_line_2.esg_emission_factor_id,
'The assignation rule does not match the product, so the emission factor should be empty',
)
self.assertEqual(
bill_line_3.esg_emission_factor_id,
self.emission_factor_delivery_transportation,
'As this bill line already has a factor, it should not be replaced by the assignation rule',
)
self.assertEqual(
bill_line_4.esg_emission_factor_id,
self.emission_factor_delivery_transportation,
'As this bill line already has a factor and does not match, it should not be replaced by the assignation rule',
)
bill_line_1.esg_emission_factor_id = False # Reset the factor of the first bill line
# Run the factor rule matching with factor replacement allowed
self.env['factors.auto.assignment.wizard'].with_context(active_ids=self.emission_factor_computers_production.ids).create({
'start_date': fields.Date.today() - relativedelta(days=30),
'end_date': fields.Date.today(),
'replace_previous_factors': True,
}).action_save()
self.assertEqual(
bill_line_1.esg_emission_factor_id,
self.emission_factor_computers_production,
'The assignation rule matches the product, so it should be used to assign this emission factor to the move line',
)
self.assertFalse(
bill_line_2.esg_emission_factor_id,
'The assignation rule still does not match the product, so the emission factor should still be empty',
)
self.assertEqual(
bill_line_3.esg_emission_factor_id,
self.emission_factor_computers_production,
'Even if this bill line already had a factor, it should be replaced by the assignation rule',
)
self.assertEqual(
bill_line_4.esg_emission_factor_id,
self.emission_factor_delivery_transportation,
'As this bill line does not match, it should not be replaced by the assignation rule',
)
# Change the assignation rule
assignation_line.product_id = self.product_b.id
# Run the factor rule matching with factor replacement allowed
self.env['factors.auto.assignment.wizard'].with_context(active_ids=self.emission_factor_computers_production.ids).create({
'start_date': fields.Date.today() - relativedelta(days=30),
'end_date': fields.Date.today(),
'replace_previous_factors': True,
}).action_save()
self.assertFalse(
bill_line_1.esg_emission_factor_id,
'The assignation rule does not match the product anymore, so the emission factor should be empty',
)
self.assertEqual(
bill_line_2.esg_emission_factor_id,
self.emission_factor_computers_production,
'The assignation rule matches the product, so it should be used to assign this emission factor to the move line',
)
self.assertFalse(
bill_line_3.esg_emission_factor_id,
'The assignation rule does not match the product anymore, so the emission factor should be empty',
)
self.assertEqual(
bill_line_4.esg_emission_factor_id,
self.emission_factor_computers_production,
'The assignation rule matches the product, so it should be used to assign this emission factor to the move line',
)
def test_auto_generate_assignation_rules(self):
bill_line_1, bill_line_2, bill_line_3, bill_line_4 = self.env['account.move.line'].with_context(auto_generate_esg_assignation_rule=False).create([
{
'move_id': self.bill_1.id,
'product_id': self.product_a.id,
'price_unit': 250.0,
'account_id': self.expense_account.id,
},
{
'move_id': self.bill_1.id,
'product_id': self.product_b.id,
'price_unit': 150.0,
'account_id': self.expense_account.id,
},
{
'move_id': self.bill_1.id,
'product_id': self.product_a.id,
'quantity': 50,
'account_id': self.expense_account.id,
'esg_emission_factor_id': self.emission_factor_delivery_transportation.id,
},
{
'move_id': self.bill_1.id,
'product_id': self.product_b.id,
'quantity': 200,
'account_id': self.expense_account.id,
'esg_emission_factor_id': self.emission_factor_delivery_transportation.id,
},
]).with_context(auto_generate_esg_assignation_rule=True)
emission_factors = self.emission_factor_delivery_transportation + self.emission_factor_electricity_consumption + self.emission_factor_computers_production
esg_assignation_rules_domain = Domain('esg_emission_factor_id', 'in', emission_factors.ids)
assignation_rules = self.env['esg.assignation.line'].search(esg_assignation_rules_domain)
self.assertFalse(assignation_rules, "No rule should exist for the emission factors selected for the test.")
bill2 = self.bill_1.copy({'line_ids': []})
_bill2_line_1, bill2_line_2, _bill2_line_3, bill2_line_4 = (bill_line_1 + bill_line_2 + bill_line_3 + bill_line_4).with_context(auto_generate_esg_assignation_rule=True).copy({'move_id': bill2.id})
assignation_rules = self.env['esg.assignation.line'].search(esg_assignation_rules_domain)
self.assertEqual(len(assignation_rules), 2, "2 rules should have been created for the emission factors used on the bill lines.")
for rule in assignation_rules:
self.assertEqual(rule.esg_emission_factor_id, self.emission_factor_delivery_transportation)
self.assertEqual(rule.partner_id, self.bill_1.partner_id)
self.assertEqual(rule.account_id, self.expense_account)
rule1, rule2 = assignation_rules
self.assertEqual(rule1.product_id, bill_line_3.product_id)
self.assertEqual(rule2.product_id, bill_line_4.product_id)
bill2_line_4.esg_emission_factor_id = self.emission_factor_computers_production
assignation_rules = self.env['esg.assignation.line'].search(esg_assignation_rules_domain)
self.assertEqual(len(assignation_rules), 1, "1 rule should exist, one should be removed since the rule has been breaking because of the changes on the AML.")
self.assertEqual(assignation_rules, rule1, "The remaining rule should be the one checked.")
bill2_line_4.account_id = self.expense_direct_cost_account
bill2_line_4.esg_emission_factor_id = self.emission_factor_delivery_transportation
assignation_rules = self.env['esg.assignation.line'].search(esg_assignation_rules_domain)
self.assertEqual(len(assignation_rules), 2, "2 rules should have been created for the emission factors used on the bill lines.")
for rule in assignation_rules:
self.assertEqual(rule.esg_emission_factor_id, self.emission_factor_delivery_transportation)
self.assertEqual(rule.partner_id, self.bill_1.partner_id)
rule1, rule2 = assignation_rules
self.assertEqual(rule1.product_id, bill_line_3.product_id)
self.assertEqual(rule1.account_id, self.expense_account)
self.assertFalse(rule2.product_id)
self.assertFalse(rule2.account_id)
(bill_line_2 + bill2_line_2).write({'esg_emission_factor_id': self.emission_factor_delivery_transportation.id})
assignation_rules = self.env['esg.assignation.line'].search(esg_assignation_rules_domain)
self.assertEqual(len(assignation_rules), 3, "3 rules should have been created for the emission factors used on the bill lines.")
for rule in assignation_rules:
self.assertEqual(rule.partner_id, self.bill_1.partner_id)
self.assertEqual(rule.partner_id, self.bill_1.partner_id)
self.assertEqual(rule.partner_id, self.bill_1.partner_id)
rule1, rule2, rule3 = assignation_rules
self.assertEqual(rule1.product_id, self.product_a)
self.assertFalse(rule2.product_id)
self.assertEqual(rule3.product_id, self.product_b)
self.assertEqual(rule1.account_id, self.expense_account)
self.assertFalse(rule2.account_id)
self.assertEqual(rule3.account_id, self.expense_account)
def test_auto_generate_assignation_rules_when_2_fields_common(self):
partner_c = self.env['res.partner'].create({'name': 'Partner C'})
self.bill_1.copy({'line_ids': [Command.create({'product_id': self.product_b.id, 'account_id': self.expense_account.id, 'esg_emission_factor_id': self.emission_factor_computers_production.id})], 'partner_id': self.partner_b.id})
self.bill_1.copy({'line_ids': [Command.create({'product_id': self.product_b.id, 'account_id': self.expense_account.id, 'esg_emission_factor_id': self.emission_factor_computers_production.id})], 'partner_id': partner_c.id})
assignation_rules_domain = [
('esg_emission_factor_id', 'in', (self.emission_factor_delivery_transportation + self.emission_factor_computers_production).ids)
]
self.assertFalse(self.env['esg.assignation.line'].search(assignation_rules_domain), "No rule should exist for the emission factors selected for the test.")
self.env['account.move.line'].create([
{'move_id': self.bill_1.id, 'product_id': self.product_a.id, 'account_id': self.expense_account.id, 'esg_emission_factor_id': self.emission_factor_delivery_transportation.id},
{'move_id': self.bill_1.id, 'product_id': self.product_a.id, 'account_id': self.expense_direct_cost_account.id, 'esg_emission_factor_id': self.emission_factor_delivery_transportation.id},
{'move_id': self.bill_1.id, 'product_id': self.product_a.id, 'account_id': self.expense_other_account.id, 'esg_emission_factor_id': self.emission_factor_delivery_transportation.id},
{'move_id': self.bill_1.id, 'product_id': self.product_b.id, 'account_id': self.expense_account.id, 'esg_emission_factor_id': self.emission_factor_computers_production.id},
])
assignation_rules = self.env['esg.assignation.line'].search(assignation_rules_domain)
self.assertEqual(len(assignation_rules), 2, "2 rules should have been created")
rule1, rule2 = assignation_rules
self.assertEqual(rule1.esg_emission_factor_id, self.emission_factor_delivery_transportation)
self.assertEqual(rule1.partner_id, self.partner_a)
self.assertEqual(rule1.product_id, self.product_a)
self.assertFalse(rule1.account_id)
self.assertEqual(rule2.esg_emission_factor_id, self.emission_factor_computers_production)
self.assertFalse(rule2.partner_id)
self.assertEqual(rule2.product_id, self.product_b)
self.assertEqual(rule2.account_id, self.expense_account)
def test_auto_generate_assignation_rules_when_partner_in_common(self):
assignation_rules_domain = [
('esg_emission_factor_id', '=', self.emission_factor_delivery_transportation.id),
]
self.assertFalse(self.env['esg.assignation.line'].search(assignation_rules_domain), "No rule should exist for the emission factors selected for the test.")
self.env['account.move.line'].create([
{'move_id': self.bill_1.id, 'product_id': self.product_a.id, 'account_id': self.expense_account.id, 'esg_emission_factor_id': self.emission_factor_delivery_transportation.id},
{'move_id': self.bill_1.id, 'product_id': self.product_b.id, 'account_id': self.expense_direct_cost_account.id, 'esg_emission_factor_id': self.emission_factor_delivery_transportation.id},
{'move_id': self.bill_1.id, 'product_id': self.product_a.id, 'account_id': self.expense_other_account.id, 'esg_emission_factor_id': self.emission_factor_delivery_transportation.id},
{'move_id': self.bill_1.id, 'product_id': self.product_b.id, 'account_id': self.asset_fixed_account.id, 'esg_emission_factor_id': self.emission_factor_delivery_transportation.id},
])
assignation_rules = self.env['esg.assignation.line'].search(assignation_rules_domain)
self.assertEqual(len(assignation_rules), 1, "1 rules should have been created")
rule = assignation_rules
self.assertEqual(rule.esg_emission_factor_id, self.emission_factor_delivery_transportation)
self.assertEqual(rule.partner_id, self.partner_a)
self.assertFalse(rule.product_id)
self.assertFalse(rule.account_id)
def test_auto_generate_assignation_rules_when_product_in_common(self):
partner_c = self.env['res.partner'].create({'name': 'Partner C'})
self.bill_1.copy({'line_ids': [Command.create({'product_id': self.product_a.id, 'account_id': self.expense_other_account.id, 'esg_emission_factor_id': self.emission_factor_delivery_transportation.id})], 'partner_id': self.partner_b.id})
self.bill_1.copy({'line_ids': [Command.create({'product_id': self.product_a.id, 'account_id': self.expense_direct_cost_account.id, 'esg_emission_factor_id': self.emission_factor_delivery_transportation.id})], 'partner_id': partner_c.id})
assignation_rules_domain = [
('esg_emission_factor_id', 'in', (self.emission_factor_delivery_transportation + self.emission_factor_computers_production).ids)
]
self.assertFalse(self.env['esg.assignation.line'].search(assignation_rules_domain), "No rule should exist for the emission factors selected for the test.")
self.env['account.move.line'].create([
{'move_id': self.bill_1.id, 'product_id': self.product_a.id, 'account_id': self.expense_account.id, 'esg_emission_factor_id': self.emission_factor_delivery_transportation.id},
{'move_id': self.bill_1.id, 'product_id': self.product_a.id, 'account_id': self.expense_direct_cost_account.id, 'esg_emission_factor_id': self.emission_factor_delivery_transportation.id},
])
assignation_rules = self.env['esg.assignation.line'].search(assignation_rules_domain)
self.assertEqual(len(assignation_rules), 1, "1 rule should have been created")
rule = assignation_rules
self.assertEqual(rule.esg_emission_factor_id, self.emission_factor_delivery_transportation)
self.assertFalse(rule.partner_id)
self.assertEqual(rule.product_id, self.product_a)
self.assertFalse(rule.account_id)
def test_auto_generate_assignation_rules_when_account_in_common(self):
partner_c = self.env['res.partner'].create({'name': 'Partner C'})
self.bill_1.copy({'line_ids': [Command.create({'product_id': self.product_b.id, 'account_id': self.expense_account.id, 'esg_emission_factor_id': self.emission_factor_delivery_transportation.id})], 'partner_id': self.partner_b.id})
self.bill_1.copy({'line_ids': [Command.create({'product_id': self.product_a.id, 'account_id': self.expense_account.id, 'esg_emission_factor_id': self.emission_factor_delivery_transportation.id})], 'partner_id': partner_c.id})
assignation_rules_domain = [
('esg_emission_factor_id', 'in', (self.emission_factor_delivery_transportation + self.emission_factor_computers_production).ids)
]
self.assertFalse(self.env['esg.assignation.line'].search(assignation_rules_domain), "No rule should exist for the emission factors selected for the test.")
self.env['account.move.line'].create([
{'move_id': self.bill_1.id, 'product_id': self.product_a.id, 'account_id': self.expense_account.id, 'esg_emission_factor_id': self.emission_factor_delivery_transportation.id},
{'move_id': self.bill_1.id, 'product_id': self.product_b.id, 'account_id': self.expense_account.id, 'esg_emission_factor_id': self.emission_factor_delivery_transportation.id},
])
assignation_rules = self.env['esg.assignation.line'].search(assignation_rules_domain)
self.assertEqual(len(assignation_rules), 1, "1 rule should have been created")
rule = assignation_rules
self.assertEqual(rule.esg_emission_factor_id, self.emission_factor_delivery_transportation)
self.assertFalse(rule.partner_id)
self.assertFalse(rule.product_id)
self.assertEqual(rule.account_id, self.expense_account)
def test_no_auto_generate_assignation_rules_on_copy(self):
assignation_rules_domain = [
('esg_emission_factor_id', '=', self.emission_factor_delivery_transportation.id),
]
self.assertFalse(self.env['esg.assignation.line'].search(assignation_rules_domain), "No rule should exist for the emission factors selected for the test.")
self.env['account.move.line'].create([
{'move_id': self.bill_1.id, 'product_id': self.product_a.id, 'account_id': self.expense_account.id, 'esg_emission_factor_id': self.emission_factor_delivery_transportation.id},
{'move_id': self.bill_1.id, 'product_id': self.product_b.id, 'account_id': self.expense_direct_cost_account.id, 'esg_emission_factor_id': self.emission_factor_delivery_transportation.id},
{'move_id': self.bill_1.id, 'product_id': self.product_a.id, 'account_id': self.expense_other_account.id, 'esg_emission_factor_id': self.emission_factor_delivery_transportation.id},
{'move_id': self.bill_1.id, 'product_id': self.product_b.id, 'account_id': self.asset_fixed_account.id, 'esg_emission_factor_id': self.emission_factor_delivery_transportation.id},
])
assignation_rules = self.env['esg.assignation.line'].search(assignation_rules_domain)
self.assertEqual(len(assignation_rules), 1, "1 rules should have been created")
self.bill_1.copy()
assignation_rules = self.env['esg.assignation.line'].search(assignation_rules_domain)
self.assertEqual(len(assignation_rules), 1, "No new rules should have been created")