Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[16.0][FIX] website_sale_product_pack: detailed displayed components price on website #144

Closed
wants to merge 16 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions product_pack/models/product_pack_line.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,3 +57,14 @@ def _check_recursion(self):
def get_price(self):
self.ensure_one()
return self.product_id.lst_price * self.quantity

def price_compute(
self, price_type, uom=False, currency=False, company=False, date=False
):
pack_line_prices = self.product_id.price_compute(
price_type, uom, currency, company, date
)
for line in self:
pack_line_prices[line.product_id.id] *= line.quantity

return pack_line_prices
61 changes: 31 additions & 30 deletions product_pack/models/product_product.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,36 +39,13 @@ def price_compute(
)
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
if product.product_tmpl_id.pack_component_price == "detailed":
pack_price = product.list_price
pack_line_prices = product.sudo().pack_line_ids.price_compute(
price_type, uom, currency, company, date
)
prices[product.id] = pack_price + sum(pack_line_prices.values())

return prices

@api.depends("list_price", "price_extra")
Expand All @@ -84,3 +61,27 @@ def _compute_product_lst_price(self):
list_price = product.uom_id._compute_price(list_price, to_uom)
product.lst_price = list_price + product.price_extra
return ret_val


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

def _compute_price_rule(self, products, qty, uom=None, date=False, **kwargs):
self.ensure_one()

packs, no_packs = products.split_pack_products()
res = super()._compute_price_rule(no_packs, qty, uom=uom, date=date, **kwargs)

for pack in packs:
pack_price = 0.0
if pack.pack_component_price == "detailed":
pack_price = pack.list_price
pack_lines = pack.sudo().pack_line_ids
tmp_products = pack_lines.mapped("product_id")
tmp_res = super()._compute_price_rule(
tmp_products, qty, uom=uom, date=date, **kwargs
)
for line in pack_lines:
pack_price += tmp_res[line.product_id.id][0] * line.quantity
res |= dict({pack.id: (pack_price, 0)})
return res
10 changes: 10 additions & 0 deletions sale_product_pack/models/product_pack_line.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,3 +49,13 @@ def get_sale_order_line_vals(self, line, order):
def get_price(self):
self.ensure_one()
return super().get_price() * (1 - self.sale_discount / 100.0)

def price_compute(
self, price_type, uom=False, currency=False, company=False, date=False
):
pack_line_prices = super().price_compute(
price_type, uom, currency, company, date
)
for line in self:
pack_line_prices[line.product_id.id] *= 1 - line.sale_discount / 100.0
return pack_line_prices
29 changes: 29 additions & 0 deletions sale_product_pack/models/sale_order_line.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,3 +126,32 @@ def action_open_parent_pack_product_view(self):
"view_mode": "tree,form",
"domain": domain,
}

# def _get_pricelist_price(self):
# self.ensure_one()
# self.product_id.ensure_one()

# if not self.product_id.product_tmpl_id.pack_ok \
# or not self.product_id.pack_component_price == "totalized":
# return super()._get_pricelist_price()
# else:
# pack_price = 0.0
# pricelist_rule = self.pricelist_item_id
# pricelist_rule_obj = self.env["product.pricelist.item"]
# order_date = self.order_id.date_order or fields.Date.today()
# qty = self.product_uom_qty or 1.0
# uom = self.product_uom or self.product_id.uom_id
# for pack_line in self.product_id.pack_line_ids:
# product = pack_line.product_id.with_context(
# **self._get_product_price_context()
# )
# pricelist_rule = self.order_id.pricelist_id._get_product_rule(
# product, pack_line.quantity or 1.0, uom, order_date
# )
# pack_price += (
# pricelist_rule_obj.browse(pricelist_rule)._compute_price(
# product, qty, uom, order_date, currency=self.currency_id
# )
# * pack_line.quantity
# )
# return pack_price
6 changes: 6 additions & 0 deletions setup/website_sale_product_pack/setup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import setuptools

setuptools.setup(
setup_requires=['setuptools-odoo'],
odoo_addon=True,
)
100 changes: 100 additions & 0 deletions website_sale_product_pack/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
=========================
Website Sale Product Pack
=========================

.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
:target: https://odoo-community.org/page/development-status
:alt: Beta
.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fproduct--pack-lightgray.png?logo=github
:target: https://github.com/OCA/product-pack/tree/13.0/website_sale_product_pack
:alt: OCA/product-pack
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
:target: https://translation.odoo-community.org/projects/product-pack-13-0/product-pack-13-0-website_sale_product_pack
:alt: Translate me on Weblate
.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png
:target: https://runbot.odoo-community.org/runbot/286/13.0
:alt: Try me on Runbot

|badge1| |badge2| |badge3| |badge4| |badge5|

This module introduces compatibility of product packs with e-commerce:

- In the cart summary, the components aren't editable and are shown hanging
from the main pack reference.
- When we remove a pack from the cart, their components are removed as well.
- The cart popup summary only shows the main pack line and discards the sublines in
the units count.
- The cart summary shows the component lines hanging from the main one as well.
- It's ensured the the prices are shown correctly for the whole pack and that they're
correctly summarized depending on the pack type.

**Table of contents**

.. contents::
:local:

Usage
=====

There are several demo packs to test the module. Publish them and add them to the cart
from the frontend. You should have the same quotation as if you do it in the backend.

Known issues / Roadmap
======================

* Improve pack cart display.
* When we have subpacks (a pack inside a pack) we should improve visually how
it's shown in the cart.

Bug Tracker
===========

Bugs are tracked on `GitHub Issues <https://github.com/OCA/product-pack/issues>`_.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us smashing it by providing a detailed and welcomed
`feedback <https://github.com/OCA/product-pack/issues/new?body=module:%20website_sale_product_pack%0Aversion:%2013.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.

Do not contact contributors directly about support or help with technical issues.

Credits
=======

Authors
~~~~~~~

* Tecnativa

Contributors
~~~~~~~~~~~~

* `Tecnativa <https://www.tecnativa.com>`_:

* David Vidal
* `ADHOC SA <https://www.adhoc.com.ar>`_:

* Nicolas Mac Rouillon

Maintainers
~~~~~~~~~~~

This module is maintained by the OCA.

.. image:: https://odoo-community.org/logo.png
:alt: Odoo Community Association
:target: https://odoo-community.org

OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.

This module is part of the `OCA/product-pack <https://github.com/OCA/product-pack/tree/13.0/website_sale_product_pack>`_ project on GitHub.

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
2 changes: 2 additions & 0 deletions website_sale_product_pack/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
from . import models
from . import controllers
19 changes: 19 additions & 0 deletions website_sale_product_pack/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Copyright 2021 Tecnativa - David Vidal
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
{
"name": "Website Sale Product Pack",
"category": "E-Commerce",
"summary": "Compatibility module of product pack with e-commerce",
"version": "16.0.1.0.3",
"license": "AGPL-3",
"depends": ["website_sale", "sale_product_pack"],
"data": ["views/templates.xml"],
"assets": {
"web.assets_tests": [
"website_sale_product_pack/static/src/js/website_sale_product_pack_tour.js",
],
},
"author": "Tecnativa, Odoo Community Association (OCA)",
"website": "https://github.com/OCA/product-pack",
"installable": True,
}
2 changes: 2 additions & 0 deletions website_sale_product_pack/controllers/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
from . import variant
from . import main
8 changes: 8 additions & 0 deletions website_sale_product_pack/controllers/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
from odoo.http import request
from odoo.addons.website_sale.controllers.main import WebsiteSale

class WebsiteSale(WebsiteSale):

def shop(self, page=0, category=None, search='', min_price=0.0, max_price=0.0, ppg=False, **post):
request.update_context(whole_pack_price=True)
return super().shop(page=page, category=category, search=search, min_price=min_price, max_price=max_price, ppg=ppg, **post)
14 changes: 14 additions & 0 deletions website_sale_product_pack/controllers/variant.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
from odoo.addons.website_sale.controllers.variant import WebsiteSaleVariantController


class WebsiteSaleVariantController(WebsiteSaleVariantController):
def get_combination_info_website(
self, product_template_id, product_id, combination, add_qty, **kw
):
if "context" in kw:
kw["context"].update({"whole_pack_price": True})
else:
kw["context"] = {"whole_pack_price": True}
return super(WebsiteSaleVariantController, self).get_combination_info_website(
product_template_id, product_id, combination, add_qty, **kw
)
57 changes: 57 additions & 0 deletions website_sale_product_pack/i18n/website_sale_product_pack.pot
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * website_sale_product_pack
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 13.0\n"
"Report-Msgid-Bugs-To: \n"
"Last-Translator: \n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"

#. module: website_sale_product_pack
#: model:ir.model,name:website_sale_product_pack.model_product_product
msgid "Product"
msgstr ""

#. module: website_sale_product_pack
#: model:ir.model,name:website_sale_product_pack.model_product_template
msgid "Product Template"
msgstr ""

#. module: website_sale_product_pack
#: model:ir.model,name:website_sale_product_pack.model_sale_order
msgid "Sales Order"
msgstr ""

#. module: website_sale_product_pack
#: model:ir.model,name:website_sale_product_pack.model_sale_order_line
msgid "Sales Order Line"
msgstr ""

#. module: website_sale_product_pack
#: model:ir.model,name:website_sale_product_pack.model_website
msgid "Website"
msgstr ""

#. module: website_sale_product_pack
#: code:addons/website_sale_product_pack/models/product_product.py:0
#, python-format
msgid "You can't add unpublished products (%s) to a published pack (%s)"
msgstr ""

#. module: website_sale_product_pack
#: code:addons/website_sale_product_pack/models/product_template.py:0
#, python-format
msgid "You can't unpublished product (%s) for a published pack parents (%s)"
msgstr ""

#. module: website_sale_product_pack
#: code:addons/website_sale_product_pack/models/product_template.py:0
#, python-format
msgid "You can't unpublished products (%s) to a published pack (%s)"
msgstr ""
4 changes: 4 additions & 0 deletions website_sale_product_pack/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
from . import sale_order
from . import website
from . import product_product
from . import product_template
27 changes: 27 additions & 0 deletions website_sale_product_pack/models/product_product.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Copyright 2019 Tecnativa - Ernesto Tejeda
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).

from odoo import _, api, models
from odoo.exceptions import ValidationError


class ProductProduct(models.Model):
_inherit = "product.product"

@api.constrains("pack_line_ids")
def check_website_published(self):
for rec in self.filtered("is_published"):
unpublished = rec.pack_line_ids.mapped("product_id").filtered(
lambda x: not x.is_published
)
if unpublished:
raise ValidationError(
_(
"You can't add unpublished products (%(unpublished_products)s) to"
"a published pack (%(pack_name)s)"
)
% {
"unpublished_products": ", ".join(unpublished.mapped("name")),
"pack_name": rec.name,
}
)
Loading
Loading