624 lines
41 KiB
Python
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")
|