Browse Source

Oct 28: [FIX] Bug Fixed 'website_decimal_quantity'

17.0
Risvana Cybro 2 days ago
parent
commit
c9efbda838
  1. 2
      website_decimal_quantity/__manifest__.py
  2. 8
      website_decimal_quantity/doc/RELEASE_NOTES.md
  3. 54
      website_decimal_quantity/models/sale_order.py
  4. 93
      website_decimal_quantity/static/src/js/website_sale.js
  5. 1
      website_decimal_quantity/views/website_sale_product_configurator_templates.xml

2
website_decimal_quantity/__manifest__.py

@ -21,7 +21,7 @@
############################################################################# #############################################################################
{ {
'name': 'Website Decimal Quantity', 'name': 'Website Decimal Quantity',
'version': '17.0.1.0.0', 'version': '17.0.1.0.1',
'category': 'Website', 'category': 'Website',
'summary': 'The app allows to select quantity in decimal for products ' 'summary': 'The app allows to select quantity in decimal for products '
'in Website/Shop', 'in Website/Shop',

8
website_decimal_quantity/doc/RELEASE_NOTES.md

@ -4,3 +4,11 @@
#### Version 17.0.1.0.0 #### Version 17.0.1.0.0
#### ADD #### ADD
- Initial Commit for Website Decimal Quantity. - 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.

54
website_decimal_quantity/models/sale_order.py

@ -70,51 +70,39 @@ class SaleOrder(models.Model):
else: else:
order_line = self.env['sale.order.line'] order_line = self.env['sale.order.line']
try: try:
if add_qty: add_qty = float(add_qty)
pass except (ValueError, TypeError):
except ValueError: add_qty = 0.0
add_qty = 1
try: try:
if set_qty: set_qty = float(set_qty)
pass except (ValueError, TypeError):
except ValueError: set_qty = 0.0
set_qty = 0
quantity = 0 if set_qty == 0 and not add_qty:
if set_qty: quantity = 0.0
elif set_qty:
quantity = set_qty quantity = set_qty
elif add_qty is not None: elif add_qty is not None:
if order_line: quantity = (order_line.product_uom_qty if order_line else 0.0) + add_qty
quantity = int(order_line.product_uom_qty) + int(add_qty or 0)
else: else:
quantity = add_qty or 0 quantity = 0.0
if float(quantity) > 0:
quantity, warning = self._verify_updated_quantity(
order_line,
product_id,
float(quantity),
**kwargs,
)
if quantity > 0:
quantity, warning = self._verify_updated_quantity(order_line, product_id, quantity, **kwargs)
else: else:
# If the line will be removed anyway, there is no need to verify
# the requested quantity update.
warning = '' warning = ''
if order_line and int(quantity) <= 0:
# Remove zero or negative lines if order_line and quantity == 0:
order_line.unlink() order_line.unlink()
order_line = self.env['sale.order.line'] order_line = self.env['sale.order.line']
elif 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: if update_values:
self._update_cart_line_values(order_line, update_values) self._update_cart_line_values(order_line, update_values)
elif int(quantity) >= 0: elif quantity > 0:
# Create new line order_line_values = self._prepare_order_line_values(product_id, quantity, **kwargs)
order_line_values = self._prepare_order_line_values( order_line = self.env['sale.order.line'].sudo().create(order_line_values)
product_id, quantity, **kwargs)
order_line = self.env['sale.order.line'].sudo().create(
order_line_values)
return { return {
'line_id': order_line.id, 'line_id': order_line.id,
'quantity': quantity, 'quantity': quantity,

93
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 wSaleUtils from "@website_sale/js/website_sale_utils";
import { Component } from "@odoo/owl"; import { Component } from "@odoo/owl";
publicWidget.registry.WebsiteSale.include({ publicWidget.registry.WebsiteSale.include({
/** /**
* This module extends the website_sale module to support decimal quantity input for adding products to the cart. * 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) { _onClickAddCartJSON(ev) {
ev.preventDefault(); ev.preventDefault();
var $link = $(ev.currentTarget); const $link = $(ev.currentTarget);
var $input = $link.closest('.input-group').find("input"); const $input = $link.closest('.input-group').find("input");
var min = parseFloat($input.data("min") || 0); const min = parseFloat($input.attr("min")) || 0.01;
var max = parseFloat($input.data("max") || Infinity); const max = parseFloat($input.attr("max")) || Infinity;
var previousQty = parseFloat($input.val() || 0, 10); const step = parseFloat($input.attr("step")) || 0.1;
var quantity = ($link.has(".fa-minus").length ? -0.1 : 0.1) + previousQty; const previousQty = parseFloat($input.val()) || 0;
var newQt = quantity > min ? (quantity < max ? quantity : max) : min;
if (newQt !== previousQty) { const isMinus = $link.find(".fa-minus").length > 0;
var newQty = newQt.toFixed(1);
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'); $input.val(newQty).trigger('change');
}
newQty = newQt.toFixed(1);
return false; return false;
}, },
/** Override the function _changeCartQuantity for changing the cart quantity **/ /** 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) => { $($dom_optional).toArray().forEach((elem) => {
$(elem).find('.js_quantity').text(value); $(elem).find('.js_quantity').text(value);
productIDs.push($(elem).find('span[data-product-id]').data('product-id')); 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", { this.rpc("/shop/cart/update_json", {
line_id: line_id, line_id: line_id,
product_id: parseInt($input.data('product-id'), 10), product_id: parseInt($input.data('product-id'), 10),
@ -43,41 +47,64 @@ publicWidget.registry.WebsiteSale.include({
display: true, display: true,
}).then((data) => { }).then((data) => {
$input.data('update_change', false); $input.data('update_change', false);
var check_value = parseFloat($input.val()); let check_value = parseFloat($input.val());
if (isNaN(check_value)) { if (isNaN(check_value)) check_value = value;
check_value = 1;
}
if (value !== check_value) { if (value !== check_value) {
$input.trigger('change'); $input.trigger('change');
return; return;
} }
if (!data.cart_quantity) { if (!data.cart_quantity) {
return window.location = '/shop/cart'; return (window.location = '/shop/cart');
} }
$input.val(data.quantity); $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.updateCartNavBar(data);
wSaleUtils.showWarning(data.notification_info.warning); wSaleUtils.showWarning(data.notification_info.warning);
// Propagating the change to the express checkout forms // Propagating the change to the express checkout forms
Component.env.bus.trigger('cart_amount_changed', [data.amount, data.minor_amount]); 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(); ev.preventDefault();
var $input = $(ev.currentTarget); const $input = $(ev.currentTarget);
if ($input.data('update_change')) { if ($input.data('update_change')) return;
return;
} let value = parseFloat($input.val());
var value = parseFloat($input.val() || 0, 10);
if (isNaN(value)) { 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'); const $dom = $input.closest('tr');
var $dom_optional = $dom.nextUntil(':not(.optional_product.info)'); const $dom_optional = $dom.nextUntil(':not(.optional_product.info)');
var line_id = parseInt($input.data('line-id'), 10); const line_id = parseInt($input.data('line-id'), 10);
var productIDs = [parseInt($input.data('product-id'), 10)]; const productIDs = [parseInt($input.data('product-id'), 10)];
this._changeCartQuantity($input, value, $dom_optional, line_id, productIDs); 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);
}
}); });

1
website_decimal_quantity/views/website_sale_product_configurator_templates.xml

@ -15,7 +15,6 @@
<input type="text" <input type="text"
class="js_quantity form-control quantity text-center" class="js_quantity form-control quantity text-center"
style="max-width: 4rem" style="max-width: 4rem"
data-min="1"
name="add_qty" name="add_qty"
t-att-value="add_qty or 1"/> t-att-value="add_qty or 1"/>
<a class="btn btn-primary float_left js_add_cart_json" <a class="btn btn-primary float_left js_add_cart_json"

Loading…
Cancel
Save