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

[14.0][ADD] website_sale_cart_quantity_shop: Add plus and minus buttons #967

Open
wants to merge 1 commit into
base: 14.0
Choose a base branch
from
Open
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
6 changes: 6 additions & 0 deletions setup/website_sale_cart_quantity_shop/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,
)
59 changes: 59 additions & 0 deletions website_sale_cart_quantity_shop/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
.. image:: https://pbs.twimg.com/profile_images/547133733149483008/0JKHr3Av_400x400.png
:target: https://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3

Website Sale Cart Quantity Shop
=======================================

- **Plus and Minus Buttons**:
- Users can increase or decrease the quantity of a product by clicking the plus (+) or minus (−) buttons next to the quantity input field.
- Clicking the plus button increments the quantity by 1.
- Clicking the minus button decrements the quantity by 1, with a minimum value of 0.

- **Direct Input**:
- Users can manually enter the desired quantity directly into the input box in the middle of the buttons.
- The input field validates and updates the quantity based on user input.

- **Dynamic Updates**:
- The quantity input field dynamically updates the cart when the quantity is changed using either the buttons or by direct input.
- The system ensures that the quantity displayed is in sync with the quantity available in the cart.

- **Visual Feedback**:
- The input field's background color and text color change when the quantity matches the available stock, providing visual feedback to the user.

Usage
=====

1. **Navigate to the Shop Page**:
- Go to your shop or category page in the Odoo eCommerce interface.

2. **Adjust Product Quantity**:
- Use the plus (+) button to increase the quantity by 1.
- Use the minus (−) button to decrease the quantity by 1, ensuring the quantity does not drop below 0.
- Enter a specific quantity directly into the input field to set the desired amount.

3. **Visual Feedback**:
- Observe changes in the input field color to reflect the available stock.

Configuration
=============

No additional configuration is required. The module integrates seamlessly with the existing product quantity functionality on the shop page.

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

Bugs are tracked on `GitHub Issues <https://github.com/avanzosc/odoo-addons/issues>`_. If you encounter any issues, please check there to see if your issue has already been reported. If not, provide detailed feedback to help us resolve it.

Credits
=======

Contributors
------------
* Unai Beristain <[email protected]>

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

License
=======
This project is licensed under the AGPL-3 License. For more details, please refer to the LICENSE file or visit <http://www.gnu.org/licenses/agpl-3.0-standalone.html>.
5 changes: 5 additions & 0 deletions website_sale_cart_quantity_shop/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
###############################################################################
# For copyright and license notices, see __manifest__.py file in root directory
###############################################################################
from .hooks import pre_init_hook
from . import controllers
24 changes: 24 additions & 0 deletions website_sale_cart_quantity_shop/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Ooops
# Cetmix
# Copyright 2024 Unai Beristain - AvanzOSC
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).

{
"name": "Website Sale Cart Quantity Shop",
"summary": "Choose cart quantity from shop page",
"category": "Website",
"version": "14.0.1.1.0",
"author": "AvanzOSC, Odoo Community Association (OCA)",
"website": "https://github.com/OCA/e-commerce",
"license": "AGPL-3",
"depends": [
"stock",
"website_sale",
],
"data": [
"views/assets.xml",
"views/website_sale.xml",
],
"installable": True,
"pre_init_hook": "pre_init_hook",
}
4 changes: 4 additions & 0 deletions website_sale_cart_quantity_shop/controllers/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
###############################################################################
# For copyright and license notices, see __manifest__.py file in root directory
###############################################################################
from . import website_sale
115 changes: 115 additions & 0 deletions website_sale_cart_quantity_shop/controllers/website_sale.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
# Copyright 2024 Unai Beristain - AvanzOSC
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).

import json

from odoo import fields
from odoo.http import request, route

from odoo.addons.website_sale.controllers.main import WebsiteSaleForm


class WebsiteSaleForm(WebsiteSaleForm):
@route(
["/shop/cart/update_json_from_shop"],
type="json",
auth="public",
methods=["POST"],
website=True,
csrf=False,
)
def cart_update_json_from_shop(
self,
product_id=None,
line_id=None,
add_qty=None,
set_qty=None,
display=True,
**kw
):

# Needed for the test, because the test works in a different wat
data = request.jsonrequest
product_id = data.get("product_id") if not product_id else product_id
line_id = data.get("line_id") if not line_id else line_id
add_qty = data.get("add_qty", 1) if not add_qty else add_qty
set_qty = data.get("set_qty", 0) if not set_qty else set_qty
display = data.get("display") if data.get("display") is not None else display

sale_order = request.website.sale_get_order(force_create=True)

if sale_order.state != "draft":
request.session["sale_order_id"] = None
sale_order = request.website.sale_get_order(force_create=True)

product_custom_attribute_values = None
if kw.get("product_custom_attribute_values"):
product_custom_attribute_values = json.loads(
kw.get("product_custom_attribute_values")
)

no_variant_attribute_values = None
if kw.get("no_variant_attribute_values"):
no_variant_attribute_values = json.loads(
kw.get("no_variant_attribute_values")
)

value = sale_order._cart_update(
product_id=product_id,
line_id=line_id,
add_qty=add_qty,
set_qty=set_qty,
product_custom_attribute_values=product_custom_attribute_values,
no_variant_attribute_values=no_variant_attribute_values,
)
value["cart_quantity"] = sale_order.cart_quantity
if not sale_order.cart_quantity:
request.website.sale_reset()
return value

if not display:
return value

value["website_sale.cart_lines"] = request.env["ir.ui.view"]._render_template(
"website_sale.cart_lines",
{
"website_sale_order": sale_order,
"date": fields.Date.today(),
"suggested_products": sale_order._cart_accessories(),
},
)
value["website_sale.short_cart_summary"] = request.env[
"ir.ui.view"
]._render_template(
"website_sale.short_cart_summary",
{
"website_sale_order": sale_order,
},
)

order_line = (
sale_order.sudo().order_line.filtered(
lambda line: line.product_id.id == product_id
)
if sale_order and sale_order.order_line
else []
)

value["product_cart_qty"] = (
int(order_line[0].sudo().product_uom_qty)
if order_line and order_line[0].product_uom_qty
else 0
)

product = request.env["product.product"].sudo().browse(product_id)
value["product_available_qty"] = product.qty_available - product.outgoing_qty

return value

# Controller needed for testing all lines
@route("/set_sale_order_id", type="json", auth="public", methods=["POST"])
def set_sale_order_id(self):
data = request.jsonrequest
sale_order_id = data.get("sale_order_id")
request.session["sale_order_id"] = sale_order_id
return {"status": "success", "message": "Sale order ID set in session"}
14 changes: 14 additions & 0 deletions website_sale_cart_quantity_shop/hooks.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Copyright 2024 Unai Beristain - AvanzOSC
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).


# Add to Cart button on product page
# Necessary to know product_id to add to cart
def pre_init_hook(cr):
cr.execute(
"""
UPDATE ir_ui_view
SET active = TRUE
WHERE key = 'website_sale.products_add_to_cart'
"""
)
Loading
Loading