Odoo18-Base/addons/product/models/product_combo.py
2025-01-06 10:57:38 +07:00

79 lines
3.3 KiB
Python

# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import _, api, fields, models
from odoo.exceptions import ValidationError
class ProductCombo(models.Model):
_name = 'product.combo'
_description = "Product Combo"
_order = 'sequence, id'
name = fields.Char(string="Name", required=True)
sequence = fields.Integer(default=10, copy=False)
company_id = fields.Many2one(string="Company", comodel_name='res.company', index=True)
combo_item_ids = fields.One2many(
comodel_name='product.combo.item',
inverse_name='combo_id',
copy=True,
)
combo_item_count = fields.Integer(string="Product Count", compute='_compute_combo_item_count')
currency_id = fields.Many2one(comodel_name='res.currency', compute='_compute_currency_id')
base_price = fields.Float(
string="Combo Price",
help="The minimum price among the products in this combo. This value will be used to"
" prorate the price of this combo with respect to the other combos in a combo product."
" This heuristic ensures that whatever product the user chooses in a combo, it will"
" always be the same price.",
digits='Product Price',
compute='_compute_base_price',
)
@api.depends('combo_item_ids')
def _compute_combo_item_count(self):
# Initialize combo_item_count to 0 as _read_group won't return any results for new combos.
self.combo_item_count = 0
# Optimization to count the number of combo items in each combo.
for combo, item_count in self.env['product.combo.item']._read_group(
domain=[('combo_id', 'in', self.ids)],
groupby=['combo_id'],
aggregates=['__count'],
):
combo.combo_item_count = item_count
@api.depends('company_id')
def _compute_currency_id(self):
main_company = self.env['res.company']._get_main_company()
for combo in self:
combo.currency_id = (
combo.company_id.sudo().currency_id or main_company.currency_id
)
@api.depends('combo_item_ids')
def _compute_base_price(self):
for combo in self:
combo.base_price = min(combo.combo_item_ids.mapped(
lambda item: item.currency_id._convert(
from_amount=item.lst_price,
to_currency=combo.currency_id,
company=combo.company_id or self.env.company,
date=self.env.cr.now(),
)
)) if combo.combo_item_ids else 0
@api.constrains('combo_item_ids')
def _check_combo_item_ids_not_empty(self):
if any(not combo.combo_item_ids for combo in self):
raise ValidationError(_("A combo choice must contain at least 1 product."))
@api.constrains('combo_item_ids')
def _check_combo_item_ids_no_duplicates(self):
for combo in self:
if len(combo.combo_item_ids.mapped('product_id')) < len(combo.combo_item_ids):
raise ValidationError(_("A combo choice can't contain duplicate products."))
@api.constrains('company_id')
def _check_company_id(self):
templates = self.env['product.template'].sudo().search([('combo_ids', 'in', self.ids)])
templates._check_company(fnames=['combo_ids'])