diff --git a/product_pack/__manifest__.py b/product_pack/__manifest__.py
index 3fbf11e9..f94b1a2a 100644
--- a/product_pack/__manifest__.py
+++ b/product_pack/__manifest__.py
@@ -19,7 +19,7 @@
##############################################################################
{
'name': 'Product Pack',
- 'version': '11.0.1.1.0',
+ 'version': '11.0.1.3.0',
'category': 'Product',
'sequence': 14,
'summary': '',
diff --git a/product_pack/models/product_product.py b/product_pack/models/product_product.py
index 4cd9f016..92623813 100644
--- a/product_pack/models/product_product.py
+++ b/product_pack/models/product_product.py
@@ -67,22 +67,52 @@ def check_recursion(self):
pack_lines = pack_lines.mapped('product_id.pack_line_ids')
@api.multi
- def price_compute(self, price_type, uom=False, currency=False,
- company=False):
+ def separete_pack_products(self):
+ """ Divide the products and the pack products into two separate
+ recordsets.
+ :return: [packs, no_packs]
+ """
packs = self.filtered(lambda p: p.pack and p.pack_price_type in [
'totalice_price',
'none_detailed_assited_price',
'none_detailed_totaliced_price',
])
+
+ # for compatibility with website_sale
+ if self._context.get('website_id', False) and \
+ not self._context.get('from_cart', False):
+ packs |= self.filtered(
+ lambda p: p.pack and p.pack_price_type == 'components_price')
+
no_packs = (self | self.mapped('pack_line_ids.product_id')) - packs
+ return packs, no_packs
+
+ @api.multi
+ def price_compute(self, price_type, uom=False, currency=False,
+ company=False):
+ packs, no_packs = self.separete_pack_products()
prices = super(ProductProduct, no_packs).price_compute(
price_type, uom, currency, company)
for product in packs:
pack_price = 0.0
for pack_line in product.pack_line_ids:
- product_line_price = prices[
- pack_line.product_id.id] * (
+ product_line_price = pack_line.product_id.price * (
1 - (pack_line.discount or 0.0) / 100.0)
pack_price += (product_line_price * pack_line.quantity)
prices[product.id] = pack_price
return prices
+
+ @api.depends('list_price', 'price_extra')
+ def _compute_product_lst_price(self):
+ packs, no_packs = self.separete_pack_products()
+ super(ProductProduct, no_packs)._compute_product_lst_price()
+
+ to_uom = None
+ if 'uom' in self._context:
+ to_uom = self.env['product.uom'].browse([self._context['uom']])
+ for product in packs:
+ list_price = product.price_compute('list_price').get(product.id)
+ if to_uom:
+ list_price = product.uom_id._compute_price(
+ list_price, to_uom)
+ product.lst_price = list_price + product.price_extra
diff --git a/product_pack/models/product_template.py b/product_pack/models/product_template.py
index 307343be..0a56dbd1 100644
--- a/product_pack/models/product_template.py
+++ b/product_pack/models/product_template.py
@@ -39,6 +39,16 @@ class ProductTemplate(models.Model):
related='product_variant_ids.used_pack_line_ids',
readonly=True,
)
+ allow_modify_pack = fields.Boolean(
+ )
+
+ @api.onchange('pack_price_type')
+ def onchange_allow_modify_pack(self):
+ products = self.filtered(
+ lambda x: x.allow_modify_pack and
+ x.pack_price_type and x.pack_price_type != 'components_price')
+ for rec in products:
+ rec.allow_modify_pack = False
@api.constrains(
'product_variant_ids', 'pack_price_type')
diff --git a/product_pack/models/sale_order.py b/product_pack/models/sale_order.py
index 6284c4e9..74fb303c 100644
--- a/product_pack/models/sale_order.py
+++ b/product_pack/models/sale_order.py
@@ -2,7 +2,8 @@
# For copyright and license notices, see __manifest__.py file in module root
# directory
##############################################################################
-from odoo import models, api
+from odoo import models, api, _
+from odoo.exceptions import UserError
class SaleOrder(models.Model):
@@ -16,3 +17,15 @@ def copy(self, default=None):
lambda l: l.pack_parent_line_id.order_id == self)
pack_copied_lines.unlink()
return sale_copy
+
+ @api.onchange('order_line')
+ def check_pack_line_unlink(self):
+ """At least on embeded tree editable view odoo returns a recordset on
+ _origin.order_line only when lines are unlinked and this is exactly
+ what we need
+ """
+ if self._origin.order_line.filtered('pack_parent_line_id'):
+ raise UserError(_(
+ 'You can not delete this line because is part of a pack in'
+ ' this sale order. In order to delete this line you need to'
+ ' delete the pack itself'))
diff --git a/product_pack/models/sale_order_line.py b/product_pack/models/sale_order_line.py
index 675d3a44..a76a7d95 100644
--- a/product_pack/models/sale_order_line.py
+++ b/product_pack/models/sale_order_line.py
@@ -3,6 +3,7 @@
# directory
##############################################################################
from odoo import fields, models, api, _
+from odoo.exceptions import UserError
class SaleOrderLine(models.Model):
@@ -129,3 +130,14 @@ def _get_real_price_currency(
'fixed_price', 'totalice_price']:
new_list_price = 0.0
return new_list_price, currency_id
+
+ @api.onchange('product_id', 'product_uom_qty', 'product_uom', 'price_unit',
+ 'discount', 'name', 'tax_id')
+ def check_pack_line_modify(self):
+ """ Do not let to edit a sale order line if this one belongs to pack
+ """
+ if self._origin.pack_parent_line_id and \
+ not self._origin.pack_parent_line_id.product_id.allow_modify_pack:
+ raise UserError(_(
+ 'You can not change this line because is part of a pack'
+ ' included in this order'))
diff --git a/product_pack/views/product_template_views.xml b/product_pack/views/product_template_views.xml
index c18aaa77..60d13b19 100644
--- a/product_pack/views/product_template_views.xml
+++ b/product_pack/views/product_template_views.xml
@@ -9,6 +9,7 @@
+