GOOGLE ADS

domingo, 1 de mayo de 2022

Forzar la cantidad mínima de pedido para productos específicos, incluidas las variaciones en la página del carrito de WooCommerce

Estoy tratando de lograr lo siguiente en WooCommerce. Quiero establecer una cantidad mínima de pedido para un producto específico.

El problema es que este producto, por ejemplo, es un producto variable, y quiero establecer una cantidad mínima de 12 piezas, pero este mínimo quiero estar en todo el producto, no en cada variación.

Por ejemplo:


  • si un cliente agrega al carrito 2 piezas de este producto eligiendo una variación de XL Black, debe haber un aviso de que la cantidad mínima es de 12 piezas.

  • Cuando este cliente agrega 10 piezas de una variación del mismo producto de L Red, entonces ha cumplido con el requisito de pedido mínimo y debería poder realizar su pedido.


El código que tengo hasta ahora funciona para productos simples, pero cuenta las variaciones como productos diferentes.

¿Cómo puedo ajustar esto para que las cantidades de variantes en el carrito se cuenten como 1 producto?

// Set minimum quantity per product before checking out
add_action( 'woocommerce_check_cart_items', 'spyr_set_min_qty_per_product' );
function spyr_set_min_qty_per_product() {
// Only run in the Cart or Checkout pages
if( is_cart() || is_checkout() ) {
global $woocommerce;
// Product Id and Min. Quantities per Product
$product_min_qty = array(
array( 'id' => 9059, 'min' => 12 ),
);
// Will increment
$i = 0;
// Will hold information about products that have not
// met the minimum order quantity
$bad_products = array();
// Loop through the products in the Cart
foreach( $woocommerce->cart->cart_contents as $product_in_cart ) {
// Loop through our minimum order quantities per product
foreach( $product_min_qty as $product_to_test ) {
// If we can match the product ID to the ID set on the minimum required array
if( $product_to_test['id'] == $product_in_cart['product_id'] ) {
// If the quantity required is less than than the quantity in the cart now
if( $product_in_cart['quantity'] < $product_to_test['min'] ) {
// Get the product ID
$bad_products[$i]['id'] = $product_in_cart['product_id'];
// Get the Product quantity already in the cart for this product
$bad_products[$i]['in_cart'] = $product_in_cart['quantity'];
// Get the minimum required for this product
$bad_products[$i]['min_req'] = $product_to_test['min'];
}
}
}
// Increment $i
$i++;
}
// Time to build our error message to inform the customer
// About the minimum quantity per order.
if( is_array( $bad_products) && count( $bad_products ) > 0 ) {
// Lets begin building our message
$message = '<strong>A minimum quantity per product has not been met.</strong><br />';
foreach( $bad_products as $bad_product ) {
// Append to the current message
$message.= get_the_title( $bad_product['id'] ).' requires a minimum quantity of '
. $bad_product['min_req']
.'. You currently have: '. $bad_product['in_cart'].'.<br />';
}
wc_add_notice( $message, 'error' );
}
}
}


Solución del problema

Para mantenerlo dinámico, puede usar el siguiente código para agregar un campo personalizado a la pestaña de inventario en el cuadro meta de datos del producto (productos simples y variables).

De esta manera, no tiene que codificar las identificaciones del producto.

// Add custom field to the inventory tab in the product data meta box
function action_woocommerce_product_options_stock_status() {
woocommerce_wp_text_input(
array(
'id' => '_min_qty',
'placeholder' => __( 'My placeholder', 'woocommerce' ),
'label' => __( 'My label', 'woocommerce' ),
'desc_tip' => true,
'description' => __( 'My description', 'woocommerce' ),
'type' => 'number',
'custom_attributes' => array(
'step' => 'any',
),
)
);
}
add_action( 'woocommerce_product_options_stock_status', 'action_woocommerce_product_options_stock_status', 10, 0 );
// Save custom field
function action_woocommerce_admin_process_product_object( $product ) {
// Isset
if ( isset( $_POST['_min_qty'] ) ) {
// Update
$product->update_meta_data( '_min_qty', sanitize_text_field( $_POST['_min_qty'] ) );
}
}
add_action( 'woocommerce_admin_process_product_object', 'action_woocommerce_admin_process_product_object', 10, 1 );

campo personalizado

Para establecer una cantidad mínima, puede usar el siguiente código, que funciona tanto para productos simples como para productos con variantes

function get_cart_quantity_variable_product( $child_ids ) { 
// Get cart items quantities
$cart_item_quantities = WC()->cart->get_cart_item_quantities();

// Counter
$qty = 0;

// Loop through the childIDs
foreach ( $child_ids as $child_id ) {
// Checks if the given key or index exists in the array
if ( array_key_exists( $child_id, $cart_item_quantities ) ) {
// Addition
$qty += $cart_item_quantities[$child_id];
}
}

return $qty;
}
function action_woocommerce_check_cart_items() {
// Will increment
$i = 0;

// Will hold information about products that have not met the minimum order quantity
$bad_products = array();

// Will hold information about which product ID has already been checked so that this does not happen twice (especially applies to products with variants)
$already_checked = array();

// Loop through cart items
foreach( WC()->cart->get_cart() as $cart_item ) {
// Get IDs
$product_id = $cart_item['product_id'];
$variation_id = $cart_item['variation_id'];

// NOT in array, already checked? Continue
if (! in_array( $product_id, $already_checked ) ) {
// Push to array
$already_checked[] = $product_id;

// Get the parent variable product for product variation items
$product = $variation_id > 0? wc_get_product( $product_id ): $cart_item['data'];

// Get meta
$min_qty = $product->get_meta( '_min_qty', true );

// NOT empty & minimum quantity is greater than or equal to 2 (1 never needs to be checked)
if (! empty( $min_qty ) && $min_qty >= 2 ) {
// Get current quantity in cart
$cart_qty = $cart_item['quantity'];

// Product type = variable & cart quantity is less than the minimum quantity
if ( $product->get_type() == 'variable' && ( $cart_qty < $min_qty ) ) {
// Get childIDs in an array
$child_ids = $product->get_children();
// Call function, get total quantity in cart for a variable product
$cart_qty = get_cart_quantity_variable_product( $child_ids );
}

// Cart quantity is less than the minimum quantity
if ( $cart_qty < $min_qty ) {
// The product ID
$bad_products[$i]['product_id'] = $product_id;

// The variation ID (optional)
//$bad_products[$i]['variation_id'] = $variation_id;

// The Product quantity already in the cart for this product
$bad_products[$i]['in_cart'] = $cart_qty;

// Get the minimum required for this product
$bad_products[$i]['min_req'] = $min_qty;

// Increment $i
$i++;
}
}
}
}

// Time to build our error message to inform the customer, about the minimum quantity per order.
if ( is_array( $bad_products) && count( $bad_products ) > 0 ) {
// Clear all other notices
wc_clear_notices();

foreach( $bad_products as $bad_product ) {
// Displaying an error notice
wc_add_notice( sprintf(
__( '%s requires a minimum quantity of %d. You currently have %d in cart', 'woocommerce' ),
get_the_title( $bad_product['product_id'] ),
$bad_product['min_req'],
$bad_product['in_cart'],
), 'error' );
}

// Optional: remove proceed to checkout button
remove_action( 'woocommerce_proceed_to_checkout', 'woocommerce_button_proceed_to_checkout', 20 );
}
}
add_action( 'woocommerce_check_cart_items', 'action_woocommerce_check_cart_items', 10, 0 );

error

No hay comentarios:

Publicar un comentario

Regla de Firestore para acceder a la generación de subcolección Permisos faltantes o insuficientes

Tengo problemas con las reglas de Firestore para permitir el acceso a algunos recursos en una subcolección. Tengo algunos requests document...