I have found a plugin that creates customer specific pricing, but seems to be an external API call that seem to not be the solution I am looking for.
https://woocommerce.com/products/wisdm-customer-specific-pricing/
I was confused to how the cart works and how products are stored. But based on this post it showed me how to replace cart prices with customer ID and sku's being passed to the API.
I used this this ticket to start off my answer
So the big thing I needed to figure out is how to call the cart, loop through each product and grab it's product SKU then overwrite the price.
I added the following to my functions.php in my theme to change my cart to display the correct pricing based off of my customer API pricing. This does a loop through all my cart items then make a call to the API and returns a price for the specific customer and sku.
add_action( 'woocommerce_before_calculate_totals', 'add_custom_price' );
function add_custom_price( $cart_object ) {
foreach ( $cart_object->cart_contents as $key => $value ) {
$response = get_api_response($value['data']->get_sku(), $customer_id);
$custom_price = $response->price;
$value['data']->set_price($custom_price);
}
}
Related
I have a WooCommerce subscription product with 2 purposes (one should never expire and one should expire). I want to enable automatic renewal for one product which is a membership product that never expires and disable automatic renewal for others. WooCommerce provides a Manual Renewal option on the settings page however it applies to all products.
I want to enable manual renewal only for a specific product so that I can use the automatic methods for others. How can I achieve this?
I found one Woocommerce hook when subscription payment is complete, this works fine in my scenario. I compared meta between automatic and manual subscriptions got difference in _requires_manual_renewal
add_action('woocommerce_subscription_payment_complete', function($subscription){
$order_items = $subscription->get_items();
// Loop through order items
foreach ( $order_items as $item_id => $item ) {
// To get the subscription variable product ID and simple subscription product ID
$product_id = $item->get_product_id();
if($product_id == 295 ){
update_post_meta($subscription->id,'_requires_manual_renewal',false);
}
else{
update_post_meta($subscription->id,'_requires_manual_renewal',true);
}
}
},10,2);
I need to add in order metadata the amount of the discount for each product individually. For example, There are ten products in the order. The user has applied a coupon discount to the products. The total amount of the discount was calculated (if there are products on_sale, they were not taken into discount calculate).
But in the end, we got a total discount. And I need to split this discount for all the products that received it and even write this value into order item metadata.
Why don't I even have a sample code? I just don't know where to start. The only thing I think is to take the total discount, divide it by the number of products that can have a discount (these are all products in the order except on_sale), And add the resulting number to the product meta. But there is a problem, I'm not sure if this is the right solution. Could you please share any advice on how to solve this?
You can start with woocommerce_checkout_create_order_line_item action hook where you will be able to set custom order item meta data. This hook has 4 arguments:
$item the order item (object),
$cart_item_key the cart item key (string),
$values the cart item (array),
$order the order (object).
So you can get from the cart item $values the discounted line item totals using:
$line_discount = $value['line_subtotal'] - $value['line_total'];
$line_discount_tax = $value['line_subtotal_tax'] - $value['line_tax'];
Then for example all together to save the line discount total as custom order item meta data:
// Save Line item discount as custom order item meta data
add_action('woocommerce_checkout_create_order_line_item', 'action_checkout_create_order_line_item', 10, 4 );
function action_checkout_create_order_line_item( $item, $cart_item_key, $values, $order ) {
$line_discount = $value['line_subtotal'] - $value['line_total'];
$line_discount_tax = $value['line_subtotal_tax'] - $value['line_tax'];
$item->update_meta_data( '_line_discount', $line_discount + $line_discount_tax );
}
Code goes in functions.php file of the active child theme (or active theme). Tested and works.
Then you can get it from an order item object $item using the WC_Data method get_meta() like:
$line_discount = $item->get_meta('_line_discount');
Related: Get Order items and WC_Order_Item_Product in WooCommerce 3
I am trying to work out if it is possible to prepend a brand name to any shipping options available. I will be setting up a store whereby you can only order one brand at a time, I will have cart limitations built in to prevent mixing two brands together.
I have an external ordering system called Veeqo and without going into too much detail I need to prepend the brand name of the products in the cart to any shipping method selected so that I can filter orders by these shipping options. E.g.
BRAND-NAME UK Next Day
BRAND-NAME UK 3-5 Days
Can this be done ? If so, how ?
Realise I am asking a lot here but if anyone knows of a way to do this that would be much appreciated! :)
Perhaps a function which searches the first line item for "Brand" and then prepends this value to all shipping method titles. WooCommerce would only display relevant shopping methods to them depending on country etc.
Using a custom function hooked in woocommerce_package_rates filter hook, you will be able to prepend the cart item brand name to the shipping method label name.
As there are multiple ways to enable brands in WooCommerce, you will need to define the taxonomy used by the brand plugin that you have enabled in WooCommerce…
For the taxonomy to use, see: How to get the brand name of product in WooCommerce
add_filter( 'woocommerce_package_rates', 'prepend_brand_to_shipping_methods', 10, 2 );
function prepend_brand_to_shipping_methods( $rates, $package ){
// HERE define the taxonomy for product brand (depend of used plugin)
$taxonomy ='product_brand';
// Get the first cart item
$cart_item = reset($package['contents']);
// Get the product brand term name
$brand_name = wp_get_post_terms( $cart_item['product_id'], $taxonomy, ['fields' =>'names']);
$brand_name = reset($brand_name);
// Loop through shipping rates
foreach ( $rates as $rate_key => $rate ){
// Changing shipping method label name
$rates[$rate_key]->label = $brand_name . ' ' . $rate->label;
}
return $rates;
}
Code goes in functions.php file of your active child theme (or active theme). Tested and works.
Refresh the shipping caches:
1). This code is already saved on your function.php file.
2). In a shipping zone settings, disable / save any shipping method, then enable back / save.
You are done and you can test it.
I'm building a website for a wholesale business that is selling plants. They want to provide their customers an option on the cart page to add labels to the plants. Therefore I want to add a custom input field per product in the cart where customers can type in the amount of plants they need. When the update cart button is clicked I want the amount of labels to be added to the cart item data.
I found that I can use woocommerce_add_cart_item_data hook this way:
add_filter( 'woocommerce_add_cart_item_data', 'add_labels', 10, 3 );
function add_labels( $cart_item_data, $product_id, $variation_id ) {
$cart_item_data['amount_of_labels'] = 200;
return $cart_item_data;
}
And when a product is added to the cart, a value of 200 is stored for the key 'amount_of_labels' in the product cart item data. This value is retrievable on the cart and checkout page and can be store in the order item meta data.
My question is:
Is there a same sort of hook/action available for updating cart data on the cart page itself?
I see that there is woocommerce_after_cart_item_quantity_update hook. But it is not working properly for my case. With that hook I can't update my custom cart item data (adding updating or removing).
Example screenshot:
Here you can see what I am trying to build. The inputs in the screenshot take the amount of labels and those should be added to the cart item data when updating the cart.
I am currently developing a webshop where i needed to do a separate price function. So far, with the help of woocommerce hooks, i had managed to manipulate the price in both the shopping cart and the checkout, this works without any problems at all. Hooks i have used woocommerce_cart_item_price, woocommerce_cart_item_subtotals, woocommerce_cart_subtotal and woocommerce_cart_total.
Now we come to my problem that i need to solve in the very near future. The price from my custom function is not included in the woocommerce order. So, is there a hook to manipulate the product prices in the order before the woocommerce creates the order?
I have looked at https://docs.woocommerce.com/wc-apidocs/hook-docs.html
but with no success.
Where does Woocommerce get the price from when it creates the order? The _price meta field, woocommerce_get_price hook, the cart or something else. I would be very grateful if someone could explain this to me. I find that woocommerce is not very consistent with where it's getting the price from.
Please ask questions if you don't understand my problem or my relative poor English. Thanks in advance.
I've use the woocommerce_get_price hook, when you change it, that changed price will be used for the cart to calculate the total (price * qty).
After order is placed, WooCommerce calculates the product based price on the total and qty, if you change one of the 2 values (total or qty) it will change the product price.
In other words, the price is dynamic after order has been created.
Edit:
Added method to change price
function change_price( $cart ) {
// Exit function if price is changed at backend
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
foreach ( $cart->get_cart() as $key => $item ) {
$item['data']->set_price( $custom_price );
}
}
add_action( 'woocommerce_before_calculate_totals', 'change_price', 10, 1);