From c9efbda838365c2cd53c997ecda6c979785651d5 Mon Sep 17 00:00:00 2001 From: Risvana Cybro Date: Tue, 28 Oct 2025 12:21:12 +0530 Subject: [PATCH] Oct 28: [FIX] Bug Fixed 'website_decimal_quantity' --- website_decimal_quantity/__manifest__.py | 2 +- website_decimal_quantity/doc/RELEASE_NOTES.md | 8 ++ website_decimal_quantity/models/sale_order.py | 56 +++++------ .../static/src/js/website_sale.js | 95 ++++++++++++------- ...te_sale_product_configurator_templates.xml | 1 - 5 files changed, 92 insertions(+), 70 deletions(-) diff --git a/website_decimal_quantity/__manifest__.py b/website_decimal_quantity/__manifest__.py index 360cb9efe..5a46c2db2 100644 --- a/website_decimal_quantity/__manifest__.py +++ b/website_decimal_quantity/__manifest__.py @@ -21,7 +21,7 @@ ############################################################################# { 'name': 'Website Decimal Quantity', - 'version': '17.0.1.0.0', + 'version': '17.0.1.0.1', 'category': 'Website', 'summary': 'The app allows to select quantity in decimal for products ' 'in Website/Shop', diff --git a/website_decimal_quantity/doc/RELEASE_NOTES.md b/website_decimal_quantity/doc/RELEASE_NOTES.md index 671897d87..d0aaff6d4 100644 --- a/website_decimal_quantity/doc/RELEASE_NOTES.md +++ b/website_decimal_quantity/doc/RELEASE_NOTES.md @@ -4,3 +4,11 @@ #### Version 17.0.1.0.0 #### ADD - Initial Commit for Website Decimal Quantity. + + +#### 27.10.2025 +#### Version 17.0.1.0.1 +##### UPDT +- Enabled decimal quantity support +- Fixed incorrect total when adding the same product multiple times. +- Allowed zero quantity removal without reverting to 0.01. diff --git a/website_decimal_quantity/models/sale_order.py b/website_decimal_quantity/models/sale_order.py index 1036d5a56..0d41b5f2d 100644 --- a/website_decimal_quantity/models/sale_order.py +++ b/website_decimal_quantity/models/sale_order.py @@ -70,51 +70,39 @@ class SaleOrder(models.Model): else: order_line = self.env['sale.order.line'] try: - if add_qty: - pass - except ValueError: - add_qty = 1 + add_qty = float(add_qty) + except (ValueError, TypeError): + add_qty = 0.0 try: - if set_qty: - pass - except ValueError: - set_qty = 0 - quantity = 0 - if set_qty: + set_qty = float(set_qty) + except (ValueError, TypeError): + set_qty = 0.0 + + if set_qty == 0 and not add_qty: + quantity = 0.0 + elif set_qty: quantity = set_qty elif add_qty is not None: - if order_line: - quantity = int(order_line.product_uom_qty) + int(add_qty or 0) - else: - quantity = add_qty or 0 - if float(quantity) > 0: - quantity, warning = self._verify_updated_quantity( - order_line, - product_id, - float(quantity), - **kwargs, - ) + quantity = (order_line.product_uom_qty if order_line else 0.0) + add_qty + else: + quantity = 0.0 + if quantity > 0: + quantity, warning = self._verify_updated_quantity(order_line, product_id, quantity, **kwargs) else: - # If the line will be removed anyway, there is no need to verify - # the requested quantity update. warning = '' - if order_line and int(quantity) <= 0: - # Remove zero or negative lines + + if order_line and quantity == 0: order_line.unlink() order_line = self.env['sale.order.line'] elif order_line: - # Update existing line - update_values = self._prepare_order_line_update_values( - order_line, quantity, **kwargs) + update_values = self._prepare_order_line_update_values(order_line, quantity, **kwargs) if update_values: self._update_cart_line_values(order_line, update_values) - elif int(quantity) >= 0: - # Create new line - order_line_values = self._prepare_order_line_values( - product_id, quantity, **kwargs) - order_line = self.env['sale.order.line'].sudo().create( - order_line_values) + elif quantity > 0: + order_line_values = self._prepare_order_line_values(product_id, quantity, **kwargs) + order_line = self.env['sale.order.line'].sudo().create(order_line_values) + return { 'line_id': order_line.id, 'quantity': quantity, diff --git a/website_decimal_quantity/static/src/js/website_sale.js b/website_decimal_quantity/static/src/js/website_sale.js index 09daa94f0..0e9a0e3c8 100644 --- a/website_decimal_quantity/static/src/js/website_sale.js +++ b/website_decimal_quantity/static/src/js/website_sale.js @@ -4,7 +4,6 @@ import publicWidget from "@web/legacy/js/public/public_widget"; import wSaleUtils from "@website_sale/js/website_sale_utils"; import { Component } from "@odoo/owl"; - publicWidget.registry.WebsiteSale.include({ /** * This module extends the website_sale module to support decimal quantity input for adding products to the cart. @@ -13,29 +12,34 @@ publicWidget.registry.WebsiteSale.include({ */ _onClickAddCartJSON(ev) { ev.preventDefault(); - var $link = $(ev.currentTarget); - var $input = $link.closest('.input-group').find("input"); - var min = parseFloat($input.data("min") || 0); - var max = parseFloat($input.data("max") || Infinity); - var previousQty = parseFloat($input.val() || 0, 10); - var quantity = ($link.has(".fa-minus").length ? -0.1 : 0.1) + previousQty; - var newQt = quantity > min ? (quantity < max ? quantity : max) : min; - if (newQt !== previousQty) { - var newQty = newQt.toFixed(1); - $input.val(newQty).trigger('change'); - } - newQty = newQt.toFixed(1); + const $link = $(ev.currentTarget); + const $input = $link.closest('.input-group').find("input"); + const min = parseFloat($input.attr("min")) || 0.01; + const max = parseFloat($input.attr("max")) || Infinity; + const step = parseFloat($input.attr("step")) || 0.1; + const previousQty = parseFloat($input.val()) || 0; + + const isMinus = $link.find(".fa-minus").length > 0; + + let newQty = isMinus ? previousQty - step : previousQty + step; + + if (newQty < min) newQty = min; + if (newQty > max) newQty = max; + + const precision = step < 1 ? step.toString().split('.')[1]?.length || 1 : 0; + newQty = parseFloat(newQty.toFixed(precision)); + $input.val(newQty).trigger('change'); return false; }, + /** Override the function _changeCartQuantity for changing the cart quantity **/ - _changeCartQuantity: function ($input, value, $dom_optional, line_id, productIDs) { + _changeCartQuantity($input, value, $dom_optional, line_id, productIDs) { $($dom_optional).toArray().forEach((elem) => { - $(elem).find('.js_quantity').text(value); productIDs.push($(elem).find('span[data-product-id]').data('product-id')); }); - $input.data('update_change', true); + $input.data('update_change', true); this.rpc("/shop/cart/update_json", { line_id: line_id, product_id: parseInt($input.data('product-id'), 10), @@ -43,41 +47,64 @@ publicWidget.registry.WebsiteSale.include({ display: true, }).then((data) => { $input.data('update_change', false); - var check_value = parseFloat($input.val()); - if (isNaN(check_value)) { - check_value = 1; - } + let check_value = parseFloat($input.val()); + if (isNaN(check_value)) check_value = value; + if (value !== check_value) { $input.trigger('change'); return; } if (!data.cart_quantity) { - return window.location = '/shop/cart'; + return (window.location = '/shop/cart'); } + $input.val(data.quantity); - $('.js_quantity[data-line-id='+line_id+']').val(data.quantity).text(data.quantity); + $('.js_quantity[data-line-id=' + line_id + ']').val(data.quantity).text(data.quantity); wSaleUtils.updateCartNavBar(data); wSaleUtils.showWarning(data.notification_info.warning); + // Propagating the change to the express checkout forms Component.env.bus.trigger('cart_amount_changed', [data.amount, data.minor_amount]); }); }, -/** Override the function _onChangeCartQuantity **/ - _onChangeCartQuantity: function (ev) { + + /** Override the function _onChangeCartQuantity **/ + _onChangeCartQuantity(ev) { ev.preventDefault(); - var $input = $(ev.currentTarget); - if ($input.data('update_change')) { - return; - } - var value = parseFloat($input.val() || 0, 10); + const $input = $(ev.currentTarget); + if ($input.data('update_change')) return; + + let value = parseFloat($input.val()); if (isNaN(value)) { - value = 1; + value = parseFloat($input.attr("min")) || 0.01; + } else if (value < 0) { + value = parseFloat($input.attr("min")) || 0.01; } - var $dom = $input.closest('tr'); - var $dom_optional = $dom.nextUntil(':not(.optional_product.info)'); - var line_id = parseInt($input.data('line-id'), 10); - var productIDs = [parseInt($input.data('product-id'), 10)]; + const $dom = $input.closest('tr'); + const $dom_optional = $dom.nextUntil(':not(.optional_product.info)'); + const line_id = parseInt($input.data('line-id'), 10); + const productIDs = [parseInt($input.data('product-id'), 10)]; + this._changeCartQuantity($input, value, $dom_optional, line_id, productIDs); }, + + async _onClickDelete(ev) { + ev.preventDefault(); + ev.stopPropagation(); + + const tr = ev.currentTarget.closest('tr'); + const line_id = parseInt(tr.dataset.lineId); + const $input = $(tr).find('.js_quantity'); + + if (!line_id || !$input.length) { + return; + } + + await this._changeCartQuantity($input, 0, [], line_id, []); + + $(tr).fadeOut(300, () => $(tr).remove()); + setTimeout(() => window.location.reload(), 400); + } + }); diff --git a/website_decimal_quantity/views/website_sale_product_configurator_templates.xml b/website_decimal_quantity/views/website_sale_product_configurator_templates.xml index 1c01066fd..5dd0938bb 100644 --- a/website_decimal_quantity/views/website_sale_product_configurator_templates.xml +++ b/website_decimal_quantity/views/website_sale_product_configurator_templates.xml @@ -15,7 +15,6 @@