[FIX] sale: prevent inconsistent company field on products

If a user changes the company of a product, we should make sure that the
product was not sold in another company in the past; otherwise it could
make some orders un-invoiceable.

closes odoo/odoo#43187

X-original-commit: 069f04935ebc22c15b4903b526401ebf0df830a3
Signed-off-by: Damien Bouvy (dbo) <dbo@odoo.com>
This commit is contained in:
Damien Bouvy
2020-01-13 10:47:14 +00:00
parent bc086e4c79
commit 69c86a2c1a
2 changed files with 31 additions and 0 deletions
+11
View File
@@ -3538,6 +3538,17 @@ msgstr ""
msgid "The fixed amount to be invoiced in advance, taxes excluded."
msgstr ""
#. module: sale
#: code:addons/sale/models/product_template.py:0
msgid ""
"The following products cannot be restricted to the company"
" %s because they have already been used in quotations or "
"sales orders in another company:\n%s\n"
"You can archive these products and recreate them "
"with your company restriction instead, or leave them as "
"shared product."
msgstr ""
#. module: sale
#: model:ir.model.fields,help:sale.field_res_config_settings__automatic_invoice
msgid ""
+20
View File
@@ -6,6 +6,7 @@ import logging
from odoo import api, fields, models, _
from odoo.addons.base.models.res_partner import WARNING_MESSAGE, WARNING_HELP
from odoo.exceptions import ValidationError
from odoo.tools.float_utils import float_round
_logger = logging.getLogger(__name__)
@@ -47,6 +48,25 @@ class ProductTemplate(models.Model):
for product in self:
product.sales_count = float_round(sum([p.sales_count for p in product.with_context(active_test=False).product_variant_ids]), precision_rounding=product.uom_id.rounding)
@api.constrains('company_id')
def _check_sale_product_company(self):
"""Ensure the product is not being restricted to a single company while
having been sold in another one in the past, as this could cause issues."""
target_company = self.company_id
if target_company: # don't prevent writing `False`, should always work
product_data = self.env['product.product'].sudo().with_context(active_test=False).search_read([('product_tmpl_id', 'in', self.ids)], fields=['id'])
product_ids = list(map(lambda p: p['id'], product_data))
so_lines = self.env['sale.order.line'].sudo().search_read([('product_id', 'in', product_ids), ('company_id', '!=', target_company.id)], fields=['id', 'product_id'])
used_products = list(map(lambda sol: sol['product_id'][1], so_lines))
if so_lines:
raise ValidationError(_('The following products cannot be restricted to the company'
' %s because they have already been used in quotations or '
'sales orders in another company:\n%s\n'
'You can archive these products and recreate them '
'with your company restriction instead, or leave them as '
'shared product.') % (target_company.name, ', '.join(used_products)))
def action_view_sales(self):
action = self.env.ref('sale.report_all_channels_sales_action').read()[0]
action['domain'] = [('product_tmpl_id', 'in', self.ids)]