Перейти к содержимому
Меню
Чтобы взаимодействовать с сообществом, необходимо зарегистрироваться.
Этот вопрос был отмечен
1 Ответить
583 Представления

I have an inherited crm_lead model as follows:

class CrmLead(models.Model):

    _inherit = 'crm.lead'

​linked_user_ids = fields.One2many('crm.deal.value', 'lead_id', string='Consultants', index=True, tracking=True)

​total_value = fields.Monetary(string='Total Value', currency_field='company_currency', compute='_compute_total_value', store=True, tracking=True)


    @api.depends('linked_user_ids', 'linked_user_ids.value')

    def _compute_total_value(self):

        for lead in self:

            lead.total_value = sum(user.value or 0.0 for user in lead.linked_user_ids) or 0.0


​@api.constrains('total_value','expected_revenue')

​    def _check_total_value(self):

​        for lead in self:

​            if lead.total_value != lead.expected_revenue:

​                raise ValidationError("Total contribution value should be equal to the opportunity's expected revenue.")

I have the following deal_value model

class DealValue(models.Model):

    _name='crm.deal.value'

    _inherit = ['mail.thread', 'mail.activity.mixin']


​lead_id = fields.Many2one('crm.lead', string='Lead', ondelete='cascade', readonly=True)

​value = fields.Monetary('Contribution Value', currency_field = 'currency_id', tracking=True)

​currency_id = fields.Many2one('res.currency', string='Currency', readonly=True, required=True, default= lambda self: self.env.company.currency_id)

  • When I delete a deal value record and modify other deal value records associated with the lead such that total_value = expected_revenue, I get a validation error saying that these values are not equal. Why does this happen?
  • Currently, the only workaround is first setting the deal value to 0, save the changes, and then delete the deal value record.
  • The compute method works correctly.

[Odoo 18 community edition]

Аватар
Отменить
Лучший ответ

Hi,

Please refer to the code below:


Model:crm.lead

from odoo import models, fields, api
from odoo.exceptions import ValidationError

class CrmLead(models.Model):
_inherit = 'crm.lead'

linked_user_ids = fields.One2many(
'crm.deal.value',
'lead_id',
string='Consultants',
index=True,
tracking=True
)

total_value = fields.Monetary(
string='Total Value',
currency_field='company_currency',
compute='_compute_total_value',
store=True,
tracking=True
)

@api.depends('linked_user_ids', 'linked_user_ids.value')
def _compute_total_value(self):
for lead in self:
lead.total_value = sum(
user.value or 0.0 for user in lead.linked_user_ids) or 0.0

@api.constrains('linked_user_ids', 'linked_user_ids.value',
'expected_revenue')
def _check_total_value(self):
"""
Ensure that the sum of all linked deal values matches the opportunity's expected revenue.

This constraint validates that the combined `value` of all records in `linked_user_ids`
(i.e., all `crm.deal.value` entries linked to the lead) is exactly equal to
the lead's `expected_revenue`.

Why the total is calculated inline:
- Using the stored computed field `total_value` can lead to stale values during
simultaneous create/update/delete operations because Odoo's ORM recomputes
stored fields only after flushing changes to the database.
- By directly summing `linked_user_ids.value`, this method uses the in-memory
state of the recordset, ensuring correctness even when deletions and updates
happen in the same transaction.

Raises:
ValidationError: If the sum of all contributions does not match `expected_revenue`.
"""
for lead in self:
total = sum(user.value or 0.0 for user in lead.linked_user_ids)
if total != lead.expected_revenue:
raise ValidationError(
"Total contribution value should be equal to the opportunity's expected revenue."
)


Hope it helps.

Аватар
Отменить
Related Posts Ответы Просмотры Активность
2
авг. 25
1152
1
июн. 25
1098
0
мая 25
654
Validation Error Решено
4
июл. 25
4778
3
мар. 25
2019