-
-
Notifications
You must be signed in to change notification settings - Fork 126
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] [MIG] website_sale_product_pack: Migration to 16.0 #135
Changes from all commits
0679726
f1ecd9d
a86f73a
4a6f728
76089e8
ed85de3
eb1bf26
7070308
84b86f6
05d4490
4ab2da0
87c9f7d
f4afb50
820f59e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
../../../../website_sale_product_pack |
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, | ||
) |
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. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
from . import models |
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, | ||
} |
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 "" |
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 |
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, | ||
} | ||
) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
# Copyright 2019 Tecnativa - Ernesto Tejeda | ||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). | ||
|
||
from odoo import _, api, fields, models | ||
from odoo.exceptions import ValidationError | ||
|
||
|
||
class ProductTemplate(models.Model): | ||
_inherit = "product.template" | ||
|
||
@api.constrains("is_published") | ||
def check_website_published(self): | ||
"""For keep the consistent and prevent bugs within the e-commerce, | ||
we force that all childs of a parent pack | ||
stay publish when the parent is published. | ||
Also if any of the childs of the parent pack became unpublish, | ||
we unpublish the parent.""" | ||
for rec in self.filtered(lambda x: x.pack_ok and x.is_published): | ||
unpublished = rec.pack_line_ids.mapped("product_id").filtered( | ||
lambda p: not p.is_published | ||
) | ||
if unpublished: | ||
raise ValidationError( | ||
_( | ||
"You can't unpublished products (%(unpublished_products)s) to a" | ||
"published pack (%(pack_name)s)" | ||
) | ||
% { | ||
"unpublished_products": ", ".join(unpublished.mapped("name")), | ||
"pack_name": rec.name, | ||
} | ||
) | ||
|
||
for rec in self.filtered( | ||
lambda x: not x.is_published and x.used_in_pack_line_ids | ||
): | ||
published = rec.used_in_pack_line_ids.mapped("parent_product_id").filtered( | ||
"is_published" | ||
) | ||
if published: | ||
raise ValidationError( | ||
_( | ||
"You can't unpublished product (%(product_name)s) for a" | ||
"published pack parents (%(pack_parents)s)" | ||
) | ||
% { | ||
"product_name": rec.name, | ||
"pack_parents": ", ".join(published.mapped("name")), | ||
} | ||
) | ||
|
||
# Neccessary for the website_sale_product_pack module because the price in /shop | ||
# is calculated by the product.template.price_compute method | ||
def price_compute( | ||
self, price_type, uom=False, currency=False, company=False, date=False | ||
): | ||
Comment on lines
+52
to
+56
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Wouldn't this override belong to the base module? Isn't there a common method there we can use? |
||
templates_with_packs, templates_without_packs = self.split_pack_products() | ||
prices = super(ProductTemplate, templates_without_packs).price_compute( | ||
price_type, uom, currency, company, date | ||
) | ||
for template in templates_with_packs.with_context(prefetch_fields=False): | ||
pack_price = 0.0 | ||
for pack_line in template.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 != template.currency_id: | ||
pack_price = pricelist.currency_id._convert( | ||
pack_price, | ||
template.currency_id, | ||
self.company_id or self.env.company, | ||
fields.Date.today(), | ||
) | ||
prices[template.id] = pack_price | ||
return prices |
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,53 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
# Copyright 2021 Tecnativa - David Vidal | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
from odoo import api, models | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
class SaleOrder(models.Model): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
_inherit = "sale.order" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
def _cart_update( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
self, product_id=None, line_id=None, add_qty=0, set_qty=0, **kwargs | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
"""We need to keep the discount defined on the components when checking out. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Also when a line comes from a totalized pack, we should flag it to avoid | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
changing it's price in a cart step.""" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
line = self.env["sale.order.line"].browse(line_id) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if line and line.pack_parent_line_id: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
pack = line.pack_parent_line_id.product_id | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
detailed_totalized_pack = ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
pack.pack_type == "detailed" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
and pack.pack_component_price in {"totalized", "ignored"} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return super( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
SaleOrder, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
self.with_context( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
pack_discount=line.discount, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
detailed_totalized_pack=detailed_totalized_pack, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
)._cart_update(product_id, line_id, add_qty, set_qty, **kwargs) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return super()._cart_update(product_id, line_id, add_qty, set_qty, **kwargs) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+9
to
+29
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
@alvaro-domatix Odoo has recently made these changes and now I have an error caused by this module and that I have been able to solve in this way. Can you apply the changes? Or if you think it should be done another way...
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ping @alvaro-domatix There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. LGTM @alvaro-domatix |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
@api.depends("order_line.product_uom_qty", "order_line.product_id") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
def _compute_cart_info(self): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
"""We only want to count the main pack line, not the component lines""" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
res = super()._compute_cart_info() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
for order in self: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
order.cart_quantity = int( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
sum( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
order.website_order_line.filtered( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
lambda x: not x.pack_parent_line_id | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
).mapped("product_uom_qty") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return res | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
class SaleOrderLine(models.Model): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
_inherit = "sale.order.line" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
def unlink(self): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
"""The website calls this method specifically. We want to get rid of | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
the children lines so the user doesn't have to""" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
join_pack_children = self + self.mapped("pack_child_line_ids") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return super(SaleOrderLine, join_pack_children.exists()).unlink() |
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.html). | ||
from odoo import models | ||
|
||
|
||
class Website(models.Model): | ||
_inherit = "website" | ||
|
||
def sale_get_order(self, force_create=False, update_pricelist=False): | ||
"""Communicate with product pack expansion method to check if it's necessary | ||
to expand the product pack lines or not via context""" | ||
if update_pricelist: | ||
return super( | ||
Website, self.with_context(update_pricelist=True) | ||
).sale_get_order(force_create, update_pricelist) | ||
return super().sale_get_order( | ||
force_create, | ||
update_pricelist, | ||
) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
* `Tecnativa <https://www.tecnativa.com>`_: | ||
|
||
* David Vidal | ||
* `ADHOC SA <https://www.adhoc.com.ar>`_: | ||
|
||
* Nicolas Mac Rouillon |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You just need to bump the major version and reset the minor digits :)