[FIX] analytic: field None should not validate model
If an aml has no product, it should not trigger a model that has a product. So, we now define the fields that have to be checked on the model, instead of just being the ones given as parameters. The way the field `company_id` impacts the model has also been changed. The idea is that a model with a company specified should be better than a model without one. But we also want that a model with 1 valid rule and no company is better than one with only a good selected company. closes odoo/odoo#107165 X-original-commit: feff1a8a056f1fbbc852f7cf164e73abf83c4cc9 Signed-off-by: William André (wan) <wan@odoo.com>
This commit is contained in:
@@ -26,12 +26,3 @@ class AccountAnalyticDistributionModel(models.Model):
|
||||
def _create_domain(self, fname, value):
|
||||
if not fname == 'account_prefix':
|
||||
return super()._create_domain(fname, value)
|
||||
|
||||
def _check_score(self, key, value):
|
||||
if key == 'account_prefix':
|
||||
if value.startswith(self.account_prefix):
|
||||
return 1
|
||||
else:
|
||||
return -1
|
||||
else:
|
||||
return super()._check_score(key, value)
|
||||
|
||||
@@ -5,6 +5,10 @@ from odoo import api, fields, models, _
|
||||
from odoo.exceptions import UserError
|
||||
|
||||
|
||||
class NonMatchingDistribution(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class AccountAnalyticDistributionModel(models.Model):
|
||||
_name = 'account.analytic.distribution.model'
|
||||
_inherit = 'analytic.mixin'
|
||||
@@ -57,29 +61,38 @@ class AccountAnalyticDistributionModel(models.Model):
|
||||
domain += self._create_domain(fname, value) or []
|
||||
best_score = 0
|
||||
res = {}
|
||||
fnames = set(self._get_fields_to_check())
|
||||
for rec in self.search(domain):
|
||||
score = 0
|
||||
for key, value in vals.items():
|
||||
if value and rec[key]:
|
||||
if rec._check_score(key, value) == 1:
|
||||
score += 1
|
||||
else:
|
||||
score = -1
|
||||
break
|
||||
if score > best_score:
|
||||
res = rec.analytic_distribution
|
||||
best_score = score
|
||||
try:
|
||||
score = sum(rec._check_score(key, vals.get(key)) for key in fnames)
|
||||
if score > best_score:
|
||||
res = rec.analytic_distribution
|
||||
best_score = score
|
||||
except NonMatchingDistribution:
|
||||
continue
|
||||
return res
|
||||
|
||||
def _get_fields_to_check(self):
|
||||
return (
|
||||
set(self.env['account.analytic.distribution.model']._fields)
|
||||
- set(self.env['analytic.mixin']._fields)
|
||||
- set(models.MAGIC_COLUMNS) - {'display_name', '__last_update'}
|
||||
)
|
||||
|
||||
def _check_score(self, key, value):
|
||||
self.ensure_one()
|
||||
if key == 'partner_category_id':
|
||||
if self[key].id in value:
|
||||
return 1
|
||||
if value == self[key].id:
|
||||
if key == 'company_id':
|
||||
if not self.company_id or value == self.company_id.id:
|
||||
return 1 if self.company_id else 0.5
|
||||
raise NonMatchingDistribution
|
||||
if not self[key]:
|
||||
return 0
|
||||
if value and ((self[key].id in value) if isinstance(value, (list, tuple))
|
||||
else (value.startswith(self[key])) if key.endswith('_prefix')
|
||||
else (value == self[key].id)
|
||||
):
|
||||
return 1
|
||||
else:
|
||||
return -1
|
||||
raise NonMatchingDistribution
|
||||
|
||||
def _create_domain(self, fname, value):
|
||||
if not value:
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
from odoo.tests import tagged
|
||||
from odoo.tests.common import TransactionCase
|
||||
from odoo import Command
|
||||
|
||||
|
||||
@tagged('post_install', '-at_install')
|
||||
@@ -113,9 +114,54 @@ class TestAnalyticAccount(TransactionCase):
|
||||
self.assertEqual(distribution_json, {}, "No distribution should be given")
|
||||
distribution_json = self.env['account.analytic.distribution.model']._get_distribution({
|
||||
"partner_id": self.partner_a.id,
|
||||
"company_id": self.company_data.id,
|
||||
})
|
||||
self.assertEqual(distribution_json, {str(self.analytic_account_3.id): 100}, "Distribution 1 should be given")
|
||||
distribution_json = self.env['account.analytic.distribution.model']._get_distribution({
|
||||
"partner_id": self.partner_b.id,
|
||||
"company_id": self.company_data.id,
|
||||
})
|
||||
self.assertEqual(distribution_json, {str(self.analytic_account_2.id): 100}, "Distribution 2 should be given")
|
||||
|
||||
def test_order_analytic_distribution_model(self):
|
||||
""" Test the distribution returned with company field"""
|
||||
distribution_3 = self.env['account.analytic.distribution.model'].create({
|
||||
'partner_id': self.partner_a.id,
|
||||
'analytic_distribution': {self.analytic_account_1.id: 100},
|
||||
'company_id': self.company_data.id,
|
||||
})
|
||||
distribution_json = self.env['account.analytic.distribution.model']._get_distribution({})
|
||||
self.assertEqual(distribution_json, {}, "No distribution should be given")
|
||||
|
||||
distribution_json = self.env['account.analytic.distribution.model']._get_distribution({
|
||||
"partner_id": self.partner_a.id,
|
||||
"company_id": self.company_data.id,
|
||||
})
|
||||
self.assertEqual(distribution_json, distribution_3.analytic_distribution,
|
||||
"Distribution 3 should be given, as the company is specified in the model")
|
||||
|
||||
distribution_json = self.env['account.analytic.distribution.model']._get_distribution({
|
||||
"partner_id": self.partner_b.id,
|
||||
"company_id": self.company_data.id,
|
||||
})
|
||||
self.assertEqual(distribution_json, {str(self.analytic_account_2.id): 100},
|
||||
"Distribution 2 should be given, for the partner")
|
||||
|
||||
partner_category = self.env['res.partner.category'].create({'name': 'partner_categ'})
|
||||
self.partner_a.write({
|
||||
'category_id': [Command.set([partner_category.id])]
|
||||
})
|
||||
|
||||
distribution_4 = self.env['account.analytic.distribution.model'].create({
|
||||
'partner_id': self.partner_a.id,
|
||||
'analytic_distribution': {self.analytic_account_1.id: 100, self.analytic_account_2.id: 100},
|
||||
'partner_category_id': partner_category.id,
|
||||
})
|
||||
|
||||
distribution_json = self.env['account.analytic.distribution.model']._get_distribution({
|
||||
"partner_id": self.partner_a.id,
|
||||
"company_id": self.company_data.id,
|
||||
"partner_category_id": partner_category.ids,
|
||||
})
|
||||
self.assertEqual(distribution_json, distribution_4.analytic_distribution,
|
||||
"Distribution 4 should be given, as the partner_category_id is better than the company_id")
|
||||
|
||||
Reference in New Issue
Block a user