Skip to content

Commit

Permalink
Merge commit 'refs/pull/105/head' of https://github.com/oca/product-pack
Browse files Browse the repository at this point in the history
 into 13.0-258
  • Loading branch information
docker-odoo committed Oct 28, 2022
2 parents 4f62e01 + 9521d18 commit d4cc418
Show file tree
Hide file tree
Showing 4 changed files with 108 additions and 18 deletions.
1 change: 1 addition & 0 deletions product_pack/models/__init__.py
@@ -1,5 +1,6 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).

from . import product_pack_line
from . import product_pricelist
from . import product_product
from . import product_template
78 changes: 78 additions & 0 deletions product_pack/models/product_pricelist.py
@@ -0,0 +1,78 @@
# Copyright 2022 Tecnativa - Pedro M. Baeza
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from itertools import chain

from odoo import fields, models


class ProductPricelist(models.Model):
_inherit = "product.pricelist"

def _compute_price_rule(self, products_qty_partner, date=False, uom_id=False):
"""Don't call super when dealing with detailed and non detailed packs,
as the computations done after calling `price_compute` modify the final returned
price, so we compute it directly in these cases.
"""

if not date:
date = self._context.get("date") or fields.Datetime.now()
if not uom_id and self._context.get("uom"):
uom_id = self._context["uom"]
if uom_id:
# rebrowse with uom if given
products = [
item[0].with_context(uom=uom_id) for item in products_qty_partner
]
products_qty_partner = [
(products[index], data_struct[1], data_struct[2])
for index, data_struct in enumerate(products_qty_partner)
]
else:
products = [item[0] for item in products_qty_partner]
if not products:
return {}
categ_ids = {}
for p in products:
categ = p.categ_id
while categ:
categ_ids[categ.id] = True
categ = categ.parent_id
categ_ids = list(categ_ids)
is_product_template = products[0]._name == "product.template"
if is_product_template:
prod_tmpl_ids = [tmpl.id for tmpl in products]
# all variants of all products
prod_ids = [
p.id
for p in list(
chain.from_iterable([t.product_variant_ids for t in products])
)
]
else:
prod_ids = [product.id for product in products]
prod_tmpl_ids = [product.product_tmpl_id.id for product in products]

items = self._compute_price_rule_get_items(
products_qty_partner, date, uom_id, prod_tmpl_ids, prod_ids, categ_ids
)
for rule in items:
if rule.base == "pricelist" and rule.base_pricelist_id:
return super()._compute_price_rule(
products_qty_partner, date=date, uom_id=uom_id
)

products_qty_partner_super = [
(s[0], s[1], s[2])
for s in products_qty_partner
if not s[0] in s[0].split_pack_products()[0]
]
res = super()._compute_price_rule(
products_qty_partner_super, date=date, uom_id=uom_id
)
for product, _, _ in products_qty_partner:
if product in product.split_pack_products()[0]:
res[product.id] = (
product.price_compute("list_price")[product.id],
False,
)
return res
19 changes: 1 addition & 18 deletions product_pack/models/product_product.py
Expand Up @@ -27,24 +27,7 @@ def get_pack_lines(self):
return self.mapped("pack_line_ids")

def split_pack_products(self):
"""Split products and the pack in 2 separate recordsets.
:return: [packs, no_packs]
"""
packs = self.filtered(
lambda p: p.pack_ok
and (
(p.pack_type == "detailed" and p.pack_component_price == "totalized")
or p.pack_type == "non_detailed"
)
)
# We could need to check the price of the whole pack (e.g.: e-commerce)
if self.env.context.get("whole_pack_price"):
packs |= self.filtered(
lambda p: p.pack_ok
and p.pack_type == "detailed"
and p.pack_component_price == "detailed"
)
packs = self.filtered(lambda p: p.product_tmpl_id._is_pack_to_be_handled())
return packs, (self - packs)

def price_compute(self, price_type, uom=False, currency=False, company=False):
Expand Down
28 changes: 28 additions & 0 deletions product_pack/models/product_template.py
Expand Up @@ -80,3 +80,31 @@ def write(self, vals):
self.product_variant_ids.write({"pack_line_ids": vals.get("pack_line_ids")})
_vals.pop("pack_line_ids")
return super().write(_vals)

def _is_pack_to_be_handled(self):
"""Method for getting if a template is a computable pack.
:return: True or False.
"""
self.ensure_one()
is_pack = False
if self.env.context.get("whole_pack_price"):
# We could need to check the price of the whole pack (e.g.: e-commerce)
is_pack = (
self.pack_ok
and self.pack_type == "detailed"
and self.pack_component_price == "detailed"
)
is_pack |= self.pack_ok and (
(self.pack_type == "detailed" and self.pack_component_price == "totalized")
or self.pack_type == "non_detailed"
)
return is_pack

def split_pack_products(self):
"""Split products and the pack in 2 separate recordsets.
:return: [packs, no_packs]
"""
packs = self.filtered(lambda p: p._is_pack_to_be_handled())
return packs, (self - packs)

0 comments on commit d4cc418

Please sign in to comment.