125 lines
5.2 KiB
Python
125 lines
5.2 KiB
Python
from odoo import _, models
|
|
|
|
|
|
|
|
class ProductCatalogMixin(models.AbstractModel):
|
|
""" This mixin should be inherited when the model should be able to work
|
|
with the product catalog.
|
|
It assumes the model using this mixin has a O2M field where the products are added/removed and
|
|
this field's co-related model should has a method named `_get_product_catalog_lines_data`.
|
|
"""
|
|
_name = 'product.catalog.mixin'
|
|
_description = 'Product Catalog Mixin'
|
|
|
|
def action_add_from_catalog(self):
|
|
kanban_view_id = self.env.ref('product.product_view_kanban_catalog').id
|
|
search_view_id = self.env.ref('product.product_view_search_catalog').id
|
|
additional_context = self._get_action_add_from_catalog_extra_context()
|
|
return {
|
|
'type': 'ir.actions.act_window',
|
|
'name': _('Products'),
|
|
'res_model': 'product.product',
|
|
'views': [(kanban_view_id, 'kanban'), (False, 'form')],
|
|
'search_view_id': [search_view_id, 'search'],
|
|
'domain': self._get_product_catalog_domain(),
|
|
'context': {**self.env.context, **additional_context},
|
|
}
|
|
|
|
def _default_order_line_values(self):
|
|
return {
|
|
'quantity': 0,
|
|
'readOnly': self._is_readonly() if self else False,
|
|
}
|
|
|
|
def _get_product_catalog_domain(self):
|
|
"""Get the domain to search for products in the catalog.
|
|
|
|
For a model that uses products that has to be hidden in the catalog, it
|
|
must override this method and extend the appropriate domain.
|
|
:returns: A list of tuples that represents a domain.
|
|
:rtype: list
|
|
"""
|
|
return [('company_id', 'in', [self.company_id.id, False])]
|
|
|
|
def _get_product_catalog_record_lines(self, product_ids):
|
|
""" Returns the record's lines grouped by product.
|
|
Must be overrided by each model using this mixin.
|
|
|
|
:param list product_ids: The ids of the products currently displayed in the product catalog.
|
|
:rtype: dict
|
|
"""
|
|
return {}
|
|
|
|
def _get_product_catalog_order_data(self, products, **kwargs):
|
|
""" Returns a dict containing the products' data. Those data are for products who aren't in
|
|
the record yet. For products already in the record, see `_get_product_catalog_lines_data`.
|
|
|
|
For each product, its id is the key and the value is another dict with all needed data.
|
|
By default, the price is the only needed data but each model is free to add more data.
|
|
Must be overrided by each model using this mixin.
|
|
|
|
:param products: Recordset of `product.product`.
|
|
:param dict kwargs: additional values given for inherited models.
|
|
:rtype: dict
|
|
:return: A dict with the following structure:
|
|
{
|
|
'productId': int
|
|
'quantity': float (optional)
|
|
'price': float
|
|
'readOnly': bool (optional)
|
|
}
|
|
"""
|
|
return {}
|
|
|
|
def _get_product_catalog_order_line_info(self, product_ids, **kwargs):
|
|
""" Returns products information to be shown in the catalog.
|
|
:param list product_ids: The products currently displayed in the product catalog, as a list
|
|
of `product.product` ids.
|
|
:param dict kwargs: additional values given for inherited models.
|
|
:rtype: dict
|
|
:return: A dict with the following structure:
|
|
{
|
|
'productId': int
|
|
'quantity': float (optional)
|
|
'price': float
|
|
'readOnly': bool (optional)
|
|
}
|
|
"""
|
|
order_line_info = {}
|
|
default_data = self._default_order_line_values()
|
|
|
|
for product, record_lines in self._get_product_catalog_record_lines(product_ids).items():
|
|
order_line_info[product.id] = record_lines._get_product_catalog_lines_data(**kwargs)
|
|
product_ids.remove(product.id)
|
|
|
|
products = self.env['product.product'].browse(product_ids)
|
|
product_data = self._get_product_catalog_order_data(products, **kwargs)
|
|
for product_id, data in product_data.items():
|
|
order_line_info[product_id] = {**default_data, **data}
|
|
return order_line_info
|
|
|
|
def _get_action_add_from_catalog_extra_context(self):
|
|
return {
|
|
'product_catalog_order_id': self.id,
|
|
'product_catalog_order_model': self._name,
|
|
}
|
|
|
|
def _is_readonly(self):
|
|
""" Must be overrided by each model using this mixin.
|
|
:return: Whether the record is read-only or not.
|
|
:rtype: bool
|
|
"""
|
|
return False
|
|
|
|
def _update_order_line_info(self, product_id, quantity, **kwargs):
|
|
""" Update the line information for a given product or create a new one if none exists yet.
|
|
Must be overrided by each model using this mixin.
|
|
:param int product_id: The product, as a `product.product` id.
|
|
:param int quantity: The product's quantity.
|
|
:param dict kwargs: additional values given for inherited models.
|
|
:return: The unit price of the product, based on the pricelist of the
|
|
purchase order and the quantity selected.
|
|
:rtype: float
|
|
"""
|
|
return 0
|