forked from OCA/product-pack
-
Notifications
You must be signed in to change notification settings - Fork 0
/
product_product.py
100 lines (91 loc) · 4.17 KB
/
product_product.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
# Copyright 2019 Tecnativa - Ernesto Tejeda
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from odoo import api, fields, models
class ProductProduct(models.Model):
_inherit = "product.product"
pack_line_ids = fields.One2many(
"product.pack.line",
"parent_product_id",
"Pack Products",
help="Products that are part of this pack.",
)
used_in_pack_line_ids = fields.One2many(
"product.pack.line",
"product_id",
"Found in packs",
help="Packs where product is used.",
)
def get_pack_lines(self):
"""Returns the content (lines) of the packs.
By default, return all the pack_line_ids, but that function
can be overloaded to introduce filtering function by date, etc..."""
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"
)
return packs, (self - packs)
def price_compute(self, price_type, uom=False, currency=False, company=False):
packs, no_packs = self.split_pack_products()
prices = super(ProductProduct, no_packs).price_compute(
price_type, uom, currency, company
)
for product in packs.with_context(prefetch_fields=False):
pack_price = 0.0
for pack_line in product.sudo().pack_line_ids:
pack_price += pack_line.get_price()
pricelist_id_or_name = self._context.get("pricelist")
# if there is a pricelist on the context the returned prices are on
# that currency but, if the pack product has a different currency
# it will be converted again by pp._compute_price_rule, so if
# that is the case we convert the amounts to the pack currency
if pricelist_id_or_name:
if isinstance(pricelist_id_or_name, list):
pricelist_id_or_name = pricelist_id_or_name[0]
if isinstance(pricelist_id_or_name, str):
pricelist_name_search = self.env["product.pricelist"].name_search(
pricelist_id_or_name, operator="=", limit=1
)
if pricelist_name_search:
pricelist = self.env["product.pricelist"].browse(
[pricelist_name_search[0][0]]
)
elif isinstance(pricelist_id_or_name, int):
pricelist = self.env["product.pricelist"].browse(
pricelist_id_or_name
)
if pricelist and pricelist.currency_id != product.currency_id:
pack_price = pricelist.currency_id._convert(
pack_price,
product.currency_id,
self.company_id or self.env.company,
fields.Date.today(),
)
prices[product.id] = pack_price
return prices
@api.depends("list_price", "price_extra")
def _compute_product_lst_price(self):
packs, no_packs = self.split_pack_products()
super(ProductProduct, no_packs)._compute_product_lst_price()
to_uom = None
if "uom" in self._context:
to_uom = self.env["uom.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