You've already forked wc-tier-and-package-prices
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:
@@ -13,6 +13,7 @@ class WC_TPP_Cart {
|
||||
add_action('woocommerce_before_calculate_totals', array($this, 'apply_tier_package_pricing'), 10, 1);
|
||||
add_filter('woocommerce_cart_item_price', array($this, 'display_cart_item_price'), 10, 3);
|
||||
add_filter('woocommerce_cart_item_subtotal', array($this, 'display_cart_item_subtotal'), 10, 3);
|
||||
add_filter('woocommerce_add_to_cart_validation', array($this, 'validate_package_quantity'), 10, 3);
|
||||
}
|
||||
|
||||
public function apply_tier_package_pricing($cart) {
|
||||
@@ -89,6 +90,53 @@ class WC_TPP_Cart {
|
||||
}
|
||||
return $subtotal;
|
||||
}
|
||||
|
||||
public function validate_package_quantity($passed, $product_id, $quantity) {
|
||||
// Check if restriction is enabled globally or for this product
|
||||
$global_restrict = get_option('wc_tpp_restrict_package_quantities', 'no') === 'yes';
|
||||
$product_restrict = get_post_meta($product_id, '_wc_tpp_restrict_to_packages', true) === 'yes';
|
||||
|
||||
if (!$global_restrict && !$product_restrict) {
|
||||
return $passed;
|
||||
}
|
||||
|
||||
// Get packages for this product
|
||||
$packages = get_post_meta($product_id, '_wc_tpp_packages', true);
|
||||
|
||||
if (empty($packages) || !is_array($packages)) {
|
||||
return $passed;
|
||||
}
|
||||
|
||||
// Check if the quantity matches any package
|
||||
$valid_quantity = false;
|
||||
$available_quantities = array();
|
||||
|
||||
foreach ($packages as $package) {
|
||||
$available_quantities[] = $package['qty'];
|
||||
if ($quantity == $package['qty']) {
|
||||
$valid_quantity = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$valid_quantity) {
|
||||
$product = wc_get_product($product_id);
|
||||
$product_name = $product ? $product->get_name() : __('this product', 'wc-tier-package-prices');
|
||||
|
||||
wc_add_notice(
|
||||
sprintf(
|
||||
__('The quantity %1$d is not available for %2$s. Please choose from the available package sizes: %3$s', 'wc-tier-package-prices'),
|
||||
$quantity,
|
||||
$product_name,
|
||||
implode(', ', $available_quantities)
|
||||
),
|
||||
'error'
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
return $passed;
|
||||
}
|
||||
}
|
||||
|
||||
new WC_TPP_Cart();
|
||||
|
||||
@@ -14,6 +14,7 @@ class WC_TPP_Frontend {
|
||||
add_action('woocommerce_before_add_to_cart_button', array($this, 'display_pricing_table_before'), 20);
|
||||
add_action('woocommerce_after_add_to_cart_button', array($this, 'display_pricing_table_after'), 10);
|
||||
add_action('woocommerce_single_product_summary', array($this, 'display_pricing_table_after_price'), 15);
|
||||
add_action('woocommerce_before_add_to_cart_quantity', array($this, 'maybe_hide_quantity_input'));
|
||||
}
|
||||
|
||||
public function enqueue_scripts() {
|
||||
@@ -50,6 +51,24 @@ class WC_TPP_Frontend {
|
||||
}
|
||||
}
|
||||
|
||||
public function maybe_hide_quantity_input() {
|
||||
global $product;
|
||||
|
||||
if (!$product || !is_a($product, 'WC_Product')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$product_id = $product->get_id();
|
||||
$global_restrict = get_option('wc_tpp_restrict_package_quantities', 'no') === 'yes';
|
||||
$product_restrict = get_post_meta($product_id, '_wc_tpp_restrict_to_packages', true) === 'yes';
|
||||
$packages = get_post_meta($product_id, '_wc_tpp_packages', true);
|
||||
|
||||
// Hide quantity input if restriction is enabled and packages exist
|
||||
if (($global_restrict || $product_restrict) && !empty($packages)) {
|
||||
echo '<style>.quantity { display: none !important; }</style>';
|
||||
}
|
||||
}
|
||||
|
||||
public function display_pricing_table() {
|
||||
global $product;
|
||||
|
||||
@@ -60,6 +79,8 @@ class WC_TPP_Frontend {
|
||||
$product_id = $product->get_id();
|
||||
$tiers = get_post_meta($product_id, '_wc_tpp_tiers', true);
|
||||
$packages = get_post_meta($product_id, '_wc_tpp_packages', true);
|
||||
$global_restrict = get_option('wc_tpp_restrict_package_quantities', 'no') === 'yes';
|
||||
$product_restrict = get_post_meta($product_id, '_wc_tpp_restrict_to_packages', true) === 'yes';
|
||||
|
||||
if (empty($tiers) && empty($packages)) {
|
||||
return;
|
||||
@@ -68,7 +89,8 @@ class WC_TPP_Frontend {
|
||||
WC_TPP_Template_Loader::get_instance()->display('frontend/pricing-table.twig', array(
|
||||
'product' => $product,
|
||||
'tiers' => $tiers,
|
||||
'packages' => $packages
|
||||
'packages' => $packages,
|
||||
'restrict_to_packages' => $global_restrict || $product_restrict
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
@@ -69,6 +69,15 @@ class WC_TPP_Product_Meta {
|
||||
<p class="form-field">
|
||||
<button type="button" class="button wc-tpp-add-package"><?php _e('Add Package', 'wc-tier-package-prices'); ?></button>
|
||||
</p>
|
||||
|
||||
<?php
|
||||
woocommerce_wp_checkbox(array(
|
||||
'id' => '_wc_tpp_restrict_to_packages',
|
||||
'label' => __('Restrict to Package Quantities', 'wc-tier-package-prices'),
|
||||
'description' => __('Only allow quantities defined in packages above', 'wc-tier-package-prices'),
|
||||
'desc_tip' => true,
|
||||
));
|
||||
?>
|
||||
</div>
|
||||
|
||||
<script type="text/html" id="wc-tpp-tier-row-template">
|
||||
@@ -151,6 +160,10 @@ class WC_TPP_Product_Meta {
|
||||
} else {
|
||||
delete_post_meta($post_id, '_wc_tpp_packages');
|
||||
}
|
||||
|
||||
// Save package quantity restriction setting
|
||||
$restrict_to_packages = isset($_POST['_wc_tpp_restrict_to_packages']) ? 'yes' : 'no';
|
||||
update_post_meta($post_id, '_wc_tpp_restrict_to_packages', $restrict_to_packages);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -104,6 +104,15 @@ class WC_TPP_Settings extends WC_Settings_Page {
|
||||
),
|
||||
),
|
||||
|
||||
array(
|
||||
'title' => __('Restrict to Package Quantities', 'wc-tier-package-prices'),
|
||||
'desc' => __('Limit quantities to defined package sizes only', 'wc-tier-package-prices'),
|
||||
'id' => 'wc_tpp_restrict_package_quantities',
|
||||
'default' => 'no',
|
||||
'type' => 'checkbox',
|
||||
'desc_tip' => __('When enabled, customers can only purchase products in the exact quantities defined in packages. The quantity input field will be hidden and replaced with package selection buttons.', 'wc-tier-package-prices'),
|
||||
),
|
||||
|
||||
array(
|
||||
'type' => 'sectionend',
|
||||
'id' => 'wc_tpp_settings',
|
||||
|
||||
Reference in New Issue
Block a user