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 @@