Is there a way to get the number of items of a specific product by its id? For example, I added to my cart 5 green apples and 10 lemons. I want to get the number of green apples in cart (which is 5), by the id of the green apple product.
Is there a simple way to achieve? Thanks
Ok I cracked it:
$cartId = WC()->cart->generate_cart_id( PRODUCT_ID);
$cartItemKey = WC()->cart->find_product_in_cart( $cartId );
$startingVal = WC()->cart->get_cart_contents()[$cartItemKey]["quantity"];
You can use the following function to get product quantity of a particular product
$quantity = '';
foreach ( WC()->cart->get_cart() as $cart_item ) {
if( $cart_item['product_id'] == 'your_id_here'){
$quantity = $cart_item['quantity'];
}
}
Related
I need to set up shipping price like this:
1 - 5 qty for $60
6 - 10 qty for $90
How can I do this? So if someone buys 3 pieces from the product then is charged 60 for shipping, if 6 or more then 90.
The basic [qty] placeholder woocommerce provides can't do this and did not find any plugin that can do it.
Maybe something like this ? Add following function in your active theme functions.php file
add_filter( 'woocommerce_package_rates', 'custom_shipping_costs', 20, 2 );
function custom_shipping_costs( $rates, $package ) {
global $woocommerce;
$qty = $woocommerce->cart->cart_contents_count;
//error_log($qty);
foreach( $rates as $rate_key => $rate ){
// Excluding free shipping methods
if( $rate->method_id != 'free_shipping'){
// Between 1 and 5
if($qty > 0 && $qty <= 5):
$rates[$rate_key]->cost = '60';
// Between 6 and 10
elseif($qty > 5 && $qty <= 10):
$rates[$rate_key]->cost = '90';
else:
// For over 10
$rates[$rate_key]->cost = '60';
endif;
}
}
return $rates;
}
I'm having trouble showing the ID of the product that I have in the cart, to perform a verification at the time of shipping.
I have the following code:
add_filter( 'woocommerce_package_rates', 'c7_hide_free_shipping_class', 10, 2 );
function c7_hide_free_shipping_class( $rates, $package ) {
echo $in_cart = false;
global $woocommerce;
$product = wc_get_product( $product_id );
$state = $woocommerce->customer->get_billing_state();
$city = explode(' - ', $woocommerce->customer->get_billing_city());
$distrito = '';
if (count($city) > 1) {
$distrito = $city[1];
}
if ($state != 'LMA' ||
!in_array($distrito, ['Surquillo'])
) {
unset( $rates['SD'] );
unset( $rates['ND'] );
}
if ($state == 'LMA' &&
in_array($distrito, ['Chorrillos'])
) {
$rates['flat_rate:7']->cost += 0; // 7.5
$rates['flat_rate:7']->label = 'De 1 a 2 dias';
} else if ($state == 'LMA' && $product == '6721' &&
in_array($distrito, ['Chaclacayo'])
) {
$rates['flat_rate:7']->cost += 9.5; // 17.50
$rates['flat_rate:7']->label = 'De 2 a 3';
//Fin Prueba
} else if ($state == 'LMA' &&
in_array($distrito, [])
){
unset( $rates['flat_rate:7'] );
}
return $rates;
}
I am trying to get Product ID: 6721 to have a different shipping price than other products. That is, if I put it in the cart and I am about to buy a product, eg "Chair", it has a different shipping price than other products. I am trying to do it by code since it is structured for those districts in code.
Chorrillos District has a different shipping price for all products, on the other hand, the Chaclacayo District has another price only if the shipment is with ID 6721, but it does not let me, it does not change the price of the shipment and only shows the default shipment when it should to show 17.50. Any way to verify the product ID when buying? I already appreciate any help.
I wish to set up a specific discount on a particular variable products but for certain selected variations not for all variation:
eg : my varible id - 1571
variation id - 1572
variation id - 1573
So if customer buys one product they get the another (the same) on 50% discount (Buy one get another for 50% off).
I've tried many discount plugins and the closest that I have found are:
Pricing Deals for WooCommerce,
Conditional Discounts for WooCommerce
WooCommerce Extended Coupon Features FREE
With some of them, I was able to setup discount on subtotal or discount on a each product but not exactly what I am looking for (Buy 1 get 1 off). There are other pro plugins I don't want to go for it.
The nearest code that I found is WooCommerce discount: buy one get one 50% off with a notice.
Is it possible to make a discount on the 2nd item for specific product variations of a variable product (only for each product variation)?
mak
To get a 50% Off on the 2nd item for some specific product variations of a variable product, you will use the following instead:
add_action('woocommerce_cart_calculate_fees', 'add_custom_discount_2nd_at_50', 10, 1 );
function add_custom_discount_2nd_at_50( $cart ){
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
// YOUR SETTINGS:
$product_variations_ids = array(1572, 1573); // <== HERE your targeted product variations
// Initializing variables
$discount = 0;
$product_names = array();
// Loop through cart items
foreach ( $cart->get_cart() as $key => $cart_item ) {
if ( in_array( $cart_item['variation_id'], $product_variations_ids ) ) {
$qty = (int) $cart_item['quantity'];
$price = (float) $cart_item['data']->get_price();
$name = (string) $cart_item['data']->get_name();
if ( $qty > 1 ) {
$discount -= number_format( $price / 2, 2 );
}
elseif( $qty = 1 ) {
$product_names[] = $name;
}
}
}
// Applying the discount
if( $discount != 0 ){
$cart->add_fee('Buy one get one 50% off', $discount );
}
// Display a custom reminder notice on cart page (otional)
if( ! empty($product_names) ){
wc_clear_notices(); // clear other notices on checkout page.
if( ! is_checkout() ){
wc_add_notice( sprintf(
__( "Add one more to get 50%% off on the 2nd item for %s" ),
'"<strong>' . implode(', ', $product_names) . '</strong>"'
), 'notice' );
}
}
}
Code goes in functions.php file of your active child theme (or active theme) Tested and works.
To get 1 item at 50% OFF for each item purchased, instead of 50% OFF on the 2nd item, replace:
$discount -= number_format( $price / 2, 2 );
by:
$multiplier = ( $qty % 2 ) === 0 ? $qty / 2 : ( $qty - 1 ) / 2;
$discount -= number_format( $price / 2 * $multiplier, 2 );
To get the 2nd one Free instead of 50% OFF on the 2nd item, replace the code line:
$discount -= number_format( $price / 2, 2 );
by:
$discount -= $price;
To get 1 item free for each item purchased, instead of 50% OFF on the 2nd item, replace:
$discount -= number_format( $price / 2, 2 );
by:
$multiplier = ( $qty % 2 ) === 0 ? $qty / 2 : ( $qty - 1 ) / 2;
$discount -= $price * $multiplier;
You were really close!
The discount amount calculation were wrong
add_action('woocommerce_cart_calculate_fees', 'add_custom_discount_2nd_at_50', 10, 1 );
function add_custom_discount_2nd_at_50( $wc_cart ){
if ( is_admin() && ! defined( 'DOING_AJAX' ) ) return;
$discount = 0;
$items_prices = array();
$qty_notice = 0; // <== Added HERE
// Set HERE your targeted variable product ID
$targeted_product_id = 1571 ;
foreach ( $wc_cart->get_cart() as $key => $cart_item ) {
if( $cart_item['product_id'] == $targeted_product_id ){
$qty = intval( $cart_item['quantity'] );
$qty_notice += intval( $cart_item['quantity'] ); // <== Added HERE
for( $i = 0; $i < $qty; $i++ )
$items_prices[] = floatval( $cart_item['data']->get_price());
}
}
$count_items_prices = count($items_prices);
//to get the discount of lowest price sorting in descending order
rsort($items_prices);
if( $count_items_prices > 1 ) foreach( $items_prices as $key => $price )
if( $key % 2 == 1 ) $discount -= number_format($price / 2, 2 );
if( $discount != 0 ){
// The discount
# Note: Last argument in add_fee() method is related to applying the tax or not to the discount (true or false)
$wc_cart->add_fee('50% off de segunda almohada' , (($price/2)*($discount))^⁻1, true ); //EDITED
// Displaying a custom notice (optional)
wc_clear_notices();
if(!is_checkout()){
wc_add_notice( __("Hurrah!! You got 50% off discount on the 2nd item"), 'notice');
}}
// Display a custom notice on cart page when quantity is equal to 1.
elseif( $qty_notice == 1){
wc_clear_notices();
if(!is_checkout()){
wc_add_notice( __( "Add one more to get 50% off on 2nd item" ), 'notice');
}}
}
I'd like to use Woocommerce over WordPress for my shop, but clients should be able to buy the product by either unit or weight.
If X units were bought, we must measure the actual weight of the purchase (obtained during the picking and packing of the order), and adjust the price accordingly.
Is there an easy way to do this on Woocommerce?
Thanks
You can do your modification using follows code snippet -
function adjust_price_based_on_weight( $cart_object ) {
foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
$_product = $cart_item['data'];
$product_id = $cart_item['product_id'];
$quantity = $cart_item['quantity'];
$product_price = floatval( $_product->get_price() ); // Actual product price
// Do your calculation based on product quantity and weight
// for example suppose product per unit weight 2 kgs and add to cart number of unit is 3.
$product_unit_weights = $quantity * 2; // where 2kg/per unit and $quantity is 3
if( $product_unit_weights > 5 ) { // if units weights is greter than 5 kgs additional cost 10.
$additionalPrice = 10;
$_product->set_price( $product_price + $additionalPrice );
}
}
}
add_action( 'woocommerce_before_calculate_totals', 'adjust_price_based_on_weight', 99 );
My woocommerce products are actually cruise expeditions (two products = two expedition types). For each product, the variations consists of the weeks in which cruises take place (= dates).
So I have Ligurian Sea Expeditions with 20 different weeks and Greece Expeditions with other 20 weeks. Fortunately I have just 2 products like that to deal with (a very simple situation)
The customer usually chooses one week expedition. However I need to apply a 10% discount on the second (or third) week in case a customer decides to apply for > 1 week. Hence the first week is paid full price, but the second and (in case there is) the third week will be discounted 10%.
I have come out with a function that enables to apply the discount in the case of two weeks.
function cart_discount() {
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
global $woocommerce; $cat_count = 0;
$cart = WC()->cart->get_cart();
foreach($cart as $cart_item_key => $values) {
$product_id = $values['product_id']; // product ID (= cruise type)
$variation_id = $values['variation_id']; // variation (=week)
$cart_lines_total = $values["line_total"]; //variation total price
$cart_lines_quantity = $values["quantity"];// variation quantity
//$product = 1394 = Expedition Ligurian eng
//$product = 1389 = Expedition Greece eng
//$product = 13888 = Expedition Ligurian ita
//$product = 13910 = Expedition Greece ita
//I hereby add a condition as we do have the same cruises with students prices which are not eligible to this discount (and are stored with different product_id)
if($product_id == '1394' || $product_id == '1389' || $product_id == '13888' || $product_id == '13910')
{
//put in a new array only the terms I need for the calculation later
$cart_array []= array( $product_id , $variation_id, $cart_lines_quantity, $cart_lines_total);
}
}
// discount percent is 10%
$percent = -0.10;
if ($cart_array[0][0] == $cart_array[1][0]) //if in the cart the same product is present two times
{
$discount = $percent * $cart_array[1][2] * $cart_array[1][3];
$discount_text = __( 'Quantity discount', 'woocommerce' );
WC()->cart->add_fee( $discount_text, $discount, false );
}
}
add_action( 'woocommerce_cart_calculate_fees','cart_discount' );
This code has many limitations as I said before, as it doesn't take in acccount some scenarios such as:
1) it deals only if in the cart tere are only two variations of the same product: in case a customer decides for x weeks to be purchased I should be able to check if the same product is present with > 2 variations;
2) It doesn't take into account the possibility having the two products with 2 ore more variations (ie.a person buying let's say two weeks in Ligurian Sea and two weeks in Greece)
If somebody can help me in improving the code I wrote I would be very happy!!
Just to make sure i got it right, you want to apply a discount if the customer buys more than 1 variation of the same product. Correct?
Here is the final code I wrote (it works, I have tested it)
function cart_discount() {
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
global $woocommerce;
$cart = WC()->cart->get_cart();
$has_coupons = count(WC()->cart->applied_coupons)>0?true:false;
if(!$has_coupons) //verifies that other discounts are not added
{
foreach($cart as $cart_item_key => $values) {
$product_id = $values['product_id']; // product ID
$variation_id = $values['variation_id']; // product quantity
$cart_lines_total = $values["line_total"];
$cart_lines_quantity = $values["quantity"];
//products for which this kind of discount must be applicable:
//$product_id = 1394 = Spedizioni CSR eng
//$product_id = 1389 = Spedizioni IDP eng
//$product_id = 13888 = Spedizioni CSR ita
//$product_id = 13910 = Spedizioni IDP ita
if($product_id == '1394' || $product_id == '1389' || $product_id == '13888' || $product_id == '13910')
{
$cart_array []= array( $product_id , $variation_id, $cart_lines_quantity, $cart_lines_total);
}
}
$conteggio = count($cart_array); //conta il numero di prodotti nel carrello
// percent is 10%
$percent = -0.10;
if ($conteggio < 3 && $cart_array[0][0] == $cart_array[1][0])
{
$discount = $percent * $cart_array[1][3];
$discount_text = __( '10% discount on subsequent week(s)', 'woocommerce' );
WC()->cart->add_fee( $discount_text, $discount, false );
}
if ($conteggio < 4 && $cart_array[0][0] == $cart_array[1][0] && $cart_array[0][0] == $cart_array[2][0])
{
$discount = ($percent * $cart_array[1][3]) + ($percent * $cart_array[2][3]);
$discount_text = __( '10% discount on subsequent week(s)', 'woocommerce' );
WC()->cart->add_fee( $discount_text, $discount, false );
}
if ($conteggio < 5 && $cart_array[0][0] == $cart_array[1][0] && $cart_array[0][0] == $cart_array[2][0] && $cart_array[0][0] == $cart_array[3][0])
{
$discount = ($percent * $cart_array[1][3]) + ($percent * $cart_array[2][3]) + ($percent * $cart_array[3][3]);
$discount_text = __( '10% discount on subsequent week(s)', 'woocommerce' );
WC()->cart->add_fee( $discount_text, $discount, false );
}
} else return;
}
add_action( 'woocommerce_cart_calculate_fees','cart_discount' );
As you see, I had to specify the product_id of the products that are interested in this particular kind of discount, which is fine for me, although it would be nicier if we could set it to categories (I didn't have the time to develop that condition)
Secondly, the part I don't like is the following
if ($conteggio < 3 && $cart_array[0][0] == $cart_array[1][0])
and all the following conditions: I was looking for a function that may go through the $cart_array and find the relations thta I set manually in each if() condition.
Thanks