diff --git a/setup/website_sale_cart_with_unconfirmed_budget/odoo/addons/website_sale_cart_with_unconfirmed_budget b/setup/website_sale_cart_with_unconfirmed_budget/odoo/addons/website_sale_cart_with_unconfirmed_budget new file mode 120000 index 00000000..c710ba94 --- /dev/null +++ b/setup/website_sale_cart_with_unconfirmed_budget/odoo/addons/website_sale_cart_with_unconfirmed_budget @@ -0,0 +1 @@ +../../../../website_sale_cart_with_unconfirmed_budget \ No newline at end of file diff --git a/setup/website_sale_cart_with_unconfirmed_budget/setup.py b/setup/website_sale_cart_with_unconfirmed_budget/setup.py new file mode 100644 index 00000000..28c57bb6 --- /dev/null +++ b/setup/website_sale_cart_with_unconfirmed_budget/setup.py @@ -0,0 +1,6 @@ +import setuptools + +setuptools.setup( + setup_requires=['setuptools-odoo'], + odoo_addon=True, +) diff --git a/website_sale_cart_with_unconfirmed_budget/README.rst b/website_sale_cart_with_unconfirmed_budget/README.rst new file mode 100644 index 00000000..178d1dd1 --- /dev/null +++ b/website_sale_cart_with_unconfirmed_budget/README.rst @@ -0,0 +1,78 @@ +.. image:: https://img.shields.io/badge/license-LGPL--3-blue.svg + :target: https://opensource.org/licenses/LGPL-3.0 + :alt: License: LGPL-3 + +======================================================== +Website Sale Cart with Unconfirmed Budget +======================================================== + +Overview +======== + +The **Website Sale Cart with Unconfirmed Budget** module enhances the shopping cart functionality by linking unconfirmed budgets with the cart. When a product is added to the cart, it checks for existing unconfirmed budgets for the same customer and utilizes them instead of creating a new order. This ensures that the cart remains consistent and avoids unnecessary order duplication. + +Features +======== + +- **Utilizes Unconfirmed Budgets**: When adding a product to the cart, the module checks for any existing unconfirmed budgets for the customer. If one exists, it will add the product to that budget instead of creating a new order. + +- **Cart Management**: The module maintains the integrity of the cart during the conversion to a confirmed budget, ensuring that products remain in the cart when transitioning between states. + +- **Redirect Handling**: Proper redirection after cart updates, maintaining the user experience during checkout. + +Usage +===== + +1. **Install the Module**: + + - Install the module through the Odoo apps interface or by placing it in your Odoo addons directory. + +2. **Adding Products**: + + - When products are added to the cart, the module will automatically check for unconfirmed budgets and add the product to the appropriate budget if available. + +3. **Budget Confirmation**: + + - Upon confirming the cart, the existing unconfirmed budget will be transformed into a confirmed order, maintaining the added products. + +Configuration +============= + +- **No additional configuration is required** for this module. It integrates seamlessly with the existing website sale module. + +Testing +======= + +Test the following scenarios: + +- **Adding Products to Cart**: + + - Ensure that when a product is added to the cart, it checks for an existing unconfirmed budget and adds the product there. + +- **Confirming the Cart**: + + - Verify that when the cart is confirmed, it correctly transforms the unconfirmed budget into a confirmed sale order, preserving all products. + +- **Cart State After Confirmation**: + + - Check that the cart remains intact when transitioning from the cart to the budget and vice versa. + +Bug Tracker +=========== + +For bugs and issues, please visit `GitHub Issues `_ to report or track issues. + +Credits +======= + +Contributors +------------ + +* Unai Beristain +* Ana Juaristi + +Please contact contributors for module-specific questions, but direct support requests should be made through the official channels. + +License +======= +This project is licensed under the LGPL-3 License. For more details, please refer to the LICENSE file or visit . diff --git a/website_sale_cart_with_unconfirmed_budget/__init__.py b/website_sale_cart_with_unconfirmed_budget/__init__.py new file mode 100644 index 00000000..f7209b17 --- /dev/null +++ b/website_sale_cart_with_unconfirmed_budget/__init__.py @@ -0,0 +1,2 @@ +from . import models +from . import controllers diff --git a/website_sale_cart_with_unconfirmed_budget/__manifest__.py b/website_sale_cart_with_unconfirmed_budget/__manifest__.py new file mode 100644 index 00000000..7670f756 --- /dev/null +++ b/website_sale_cart_with_unconfirmed_budget/__manifest__.py @@ -0,0 +1,12 @@ +{ + "name": "Website Sale Cart with Unconfirmed Budget", + "version": "16.0.1.0.0", + "author": "Avanzosc", + "summary": "Modifies the cart functionality to reuse unconfirmed budgets.", + "website": "https://github.com/avanzosc/sale-addons", + "license": "LGPL-3", + "depends": ["website_sale", "sale"], + "data": [], + "installable": True, + "application": False, +} diff --git a/website_sale_cart_with_unconfirmed_budget/controllers/__init__.py b/website_sale_cart_with_unconfirmed_budget/controllers/__init__.py new file mode 100644 index 00000000..bdae4cca --- /dev/null +++ b/website_sale_cart_with_unconfirmed_budget/controllers/__init__.py @@ -0,0 +1 @@ +from . import website_sale diff --git a/website_sale_cart_with_unconfirmed_budget/controllers/website_sale.py b/website_sale_cart_with_unconfirmed_budget/controllers/website_sale.py new file mode 100644 index 00000000..f55bf691 --- /dev/null +++ b/website_sale_cart_with_unconfirmed_budget/controllers/website_sale.py @@ -0,0 +1,100 @@ +from odoo import fields, http +from odoo.http import request + +from odoo.addons.website_sale.controllers.main import WebsiteSale + + +class WebsiteSale(WebsiteSale): + + @http.route(["/shop/cart"], type="http", auth="public", website=True, sitemap=False) + def cart(self, access_token=None, revive="", **post): + order = request.website.sale_get_order() + if order and order.state != "draft": + request.session["sale_order_id"] = None + order = request.website.sale_get_order() + + request.session["website_sale_cart_quantity"] = order.cart_quantity + + values = { + "website_sale_order": order, + "date": fields.Date.today(), + "suggested_products": [], + } + + if order: + values.update(order._get_website_sale_extra_values()) + order.order_line.filtered( + lambda line: line.product_id and not line.product_id.active + ).unlink() + values["suggested_products"] = order._cart_accessories() + values.update(self._get_express_shop_payment_values(order)) + + return request.render("website_sale.cart", values) + + @http.route( + ["/shop/cart/update"], + type="http", + auth="public", + methods=["POST"], + website=True, + ) + def cart_update( + self, + product_id, + add_qty=1, + set_qty=0, + product_custom_attribute_values=None, + no_variant_attribute_values=None, + express=False, + **kwargs + ): + sale_order = super().cart_update( + product_id=product_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, + express=express, + **kwargs + ) + + request.session["website_sale_cart_quantity"] = sale_order.cart_quantity + + if express: + return request.redirect("/shop/checkout?express=1") + + return request.redirect("/shop/cart") + + @http.route( + ["/shop/cart/update_json"], + type="json", + auth="public", + methods=["POST"], + website=True, + csrf=False, + ) + def cart_update_json( + self, + product_id, + line_id=None, + add_qty=None, + set_qty=None, + display=True, + product_custom_attribute_values=None, + no_variant_attribute_values=None, + **kw + ): + values = super().cart_update_json( + product_id=product_id, + line_id=line_id, + add_qty=add_qty, + set_qty=set_qty, + display=display, + product_custom_attribute_values=product_custom_attribute_values, + no_variant_attribute_values=no_variant_attribute_values, + **kw + ) + + request.session["website_sale_cart_quantity"] = values.get("cart_quantity", 0) + + return values diff --git a/website_sale_cart_with_unconfirmed_budget/models/__init__.py b/website_sale_cart_with_unconfirmed_budget/models/__init__.py new file mode 100644 index 00000000..6aacb753 --- /dev/null +++ b/website_sale_cart_with_unconfirmed_budget/models/__init__.py @@ -0,0 +1 @@ +from . import sale_order diff --git a/website_sale_cart_with_unconfirmed_budget/models/sale_order.py b/website_sale_cart_with_unconfirmed_budget/models/sale_order.py new file mode 100644 index 00000000..3b8e76fd --- /dev/null +++ b/website_sale_cart_with_unconfirmed_budget/models/sale_order.py @@ -0,0 +1,29 @@ +from odoo import api, models + + +class SaleOrder(models.Model): + _inherit = "sale.order" + + @api.model + def create(self, vals): + unconfirmed_budget = self.env["sale.order"].search( + [ + ("state", "=", "draft"), + ("partner_id", "=", vals.get("partner_id")), + ], + limit=1, + ) + + if unconfirmed_budget: + unconfirmed_budget.order_line.unlink() + for line in vals.get("order_line", []): + unconfirmed_budget.order_line.create( + { + "order_id": unconfirmed_budget.id, + "product_id": line[2]["product_id"], + "product_uom_qty": line[2]["product_uom_qty"], + } + ) + return unconfirmed_budget + + return super().create(vals)