Release version 1.1.0 - Package quantity restriction feature

Added comprehensive package quantity restriction functionality that allows
limiting product purchases to predefined package sizes only.

Features:
- Global setting to enable package quantity restrictions
- Per-product override for quantity restrictions
- Automatic hiding of quantity input field when restricted
- Frontend validation with package selection UI
- Server-side cart validation
- User-friendly error messages
- Complete translations for all supported languages

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
2025-12-21 15:54:04 +01:00
parent dea2c5f0b3
commit e0a32821ee
22 changed files with 699 additions and 54 deletions

View File

@@ -8,8 +8,9 @@
$(document).ready(function() {
const $quantityInput = $('input.qty');
const $priceDisplay = $('.woocommerce-Price-amount.amount').first();
const isRestrictedMode = $('.wc-tpp-package-pricing-table').hasClass('wc-tpp-restricted-mode');
if ($quantityInput.length === 0) {
if ($quantityInput.length === 0 && !isRestrictedMode) {
return;
}
@@ -164,7 +165,30 @@
const $package = $(this).closest('.wc-tpp-package');
const qty = parseInt($package.data('qty'));
$quantityInput.val(qty).trigger('change');
if (isRestrictedMode) {
// In restricted mode, we need to set a hidden input or use data attribute
// since the quantity field is hidden
if ($quantityInput.length === 0) {
// Create a hidden quantity input if it doesn't exist
if ($('.qty-hidden-input').length === 0) {
$('.single_add_to_cart_button').before('<input type="hidden" name="quantity" class="qty qty-hidden-input" value="1" />');
}
$('.qty-hidden-input').val(qty);
} else {
$quantityInput.val(qty);
}
// Highlight selected package
$('.wc-tpp-package').removeClass('wc-tpp-selected');
$package.addClass('wc-tpp-selected');
// Update price display
const price = parseFloat($package.data('price'));
const unitPrice = price / qty;
updatePrice(unitPrice, 'Package price: ' + formatPrice(price) + ' total');
} else {
$quantityInput.val(qty).trigger('change');
}
// Scroll to add to cart button
$('html, body').animate({
@@ -172,8 +196,22 @@
}, 500);
});
// In restricted mode, prevent form submission if no package is selected
if (isRestrictedMode) {
$('form.cart').on('submit', function(e) {
const hasSelection = $('.wc-tpp-package.wc-tpp-selected').length > 0;
if (!hasSelection) {
e.preventDefault();
alert('Please select a package size before adding to cart.');
return false;
}
});
}
// Initial update
updatePriceDisplay();
if (!isRestrictedMode) {
updatePriceDisplay();
}
});
})(jQuery);