/**
* Snippet Name: Product Minimum Quantity and Step per Product
* Snippet Author: coding-bunny.com
* Description: Allows you to set minimum quantity and increment step for each product in WooCommerce.
* Version: 1.0.0
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
function cbedd_add_qty_fields_to_product() {
global $post;
$min_qty = get_post_meta( $post->ID, '_cbedd_min_qty', true );
$qty_step = get_post_meta( $post->ID, '_cbedd_qty_step', true );
woocommerce_wp_text_input( array(
'id' => '_cbedd_min_qty',
'label' => __( 'Minimum Order Quantity', 'cbedd' ),
'desc_tip' => true,
'description' => __( 'Set the minimum quantity allowed for this product.', 'cbedd' ),
'type' => 'number',
'custom_attributes' => array(
'min' => '1',
'step' => '1',
),
'value' => esc_attr( $min_qty ),
) );
woocommerce_wp_text_input( array(
'id' => '_cbedd_qty_step',
'label' => __( 'Quantity Step', 'cbedd' ),
'desc_tip' => true,
'description' => __( 'Set the increment/decrement step for this product.', 'cbedd' ),
'type' => 'number',
'custom_attributes' => array(
'min' => '1',
'step' => '1',
),
'value' => esc_attr( $qty_step ),
) );
}
add_action( 'woocommerce_product_options_inventory_product_data', 'cbedd_add_qty_fields_to_product' );
function cbedd_save_qty_fields( $post_id ) {
if ( ! isset( $_POST['woocommerce_meta_nonce'], $_POST['_cbedd_min_qty'], $_POST['_cbedd_qty_step'] ) ) {
return;
}
$min_qty = isset( $_POST['_cbedd_min_qty'] ) ? absint( $_POST['_cbedd_min_qty'] ) : '';
if ( $min_qty > 0 ) {
update_post_meta( $post_id, '_cbedd_min_qty', $min_qty );
} else {
delete_post_meta( $post_id, '_cbedd_min_qty' );
}
$qty_step = isset( $_POST['_cbedd_qty_step'] ) ? absint( $_POST['_cbedd_qty_step'] ) : '';
if ( $qty_step > 0 ) {
update_post_meta( $post_id, '_cbedd_qty_step', $qty_step );
} else {
delete_post_meta( $post_id, '_cbedd_qty_step' );
}
}
add_action( 'woocommerce_process_product_meta', 'cbedd_save_qty_fields' );
function cbedd_filter_min_qty( $min_value, $product ) {
$product_min = get_post_meta( $product->get_id(), '_cbedd_min_qty', true );
if ( $product_min && is_numeric( $product_min ) && $product_min > 0 ) {
$min_value = absint( $product_min );
}
return $min_value;
}
add_filter( 'woocommerce_quantity_input_min', 'cbedd_filter_min_qty', 10, 2 );
function cbedd_filter_qty_step( $step, $product ) {
$product_step = get_post_meta( $product->get_id(), '_cbedd_qty_step', true );
if ( $product_step && is_numeric( $product_step ) && $product_step > 0 ) {
$step = absint( $product_step );
}
return $step;
}
add_filter( 'woocommerce_quantity_input_step', 'cbedd_filter_qty_step', 10, 2 );
function cbedd_validate_cart_item_quantity( $passed, $product_id, $quantity ) {
$min_qty = get_post_meta( $product_id, '_cbedd_min_qty', true );
$qty_step = get_post_meta( $product_id, '_cbedd_qty_step', true );
if ( $min_qty && is_numeric( $min_qty ) && $min_qty > 0 && $quantity < $min_qty ) {
wc_add_notice(
sprintf(
esc_html__( 'The minimum order quantity for %1$s is %2$d.', 'cbedd' ),
get_the_title( $product_id ),
absint( $min_qty )
),
'error'
);
$passed = false;
}
if ( $qty_step && is_numeric( $qty_step ) && $qty_step > 0 ) {
$min = $min_qty && $min_qty > 0 ? $min_qty : 1;
if ( ( $quantity - $min ) % $qty_step !== 0 ) {
wc_add_notice(
sprintf(
esc_html__( 'Please order %1$s in quantities of %2$d.', 'cbedd' ),
get_the_title( $product_id ),
absint( $qty_step )
),
'error'
);
$passed = false;
}
}
return $passed;
}
add_filter( 'woocommerce_add_to_cart_validation', 'cbedd_validate_cart_item_quantity', 10, 3 );
function cbedd_cleanup_on_product_delete( $post_id ) {
if ( get_post_type( $post_id ) === 'product' ) {
delete_post_meta( $post_id, '_cbedd_min_qty' );
delete_post_meta( $post_id, '_cbedd_qty_step' );
}
}
add_action( 'before_delete_post', 'cbedd_cleanup_on_product_delete' );
Product Minimum Quantity and Step per Product
Allows you to set minimum quantity and increment step for each product in WooCommerce.