Basically I am interested in using woocommerce to sell a product . This product is a Print Order of a external printing service that I have implemented in a brand new plugin.
What I want now is after the order, is to be able to put that "order" in the buy cart, and buy it normally as just another woocommerce product.
The product has to be created on the fly, manually by a way of some function that I can use to create a product during a certain workflow point.
Can you help me to find a solution?
Using woocommerce or not!
What i understand from your requirement/comments is that you want to be able to dynamically create a product, which is bad idea. But here is my suggestion.
Lets say you have a simple product called "Print Job" with a price of $1 and with an id of 10. And i am supposing that your external printing service would send back a response with the order and the price of printing, lets say $64.
Once you recieve the response you can simply call add_product_to_cart(10), this will automatically add the print job product to your cart.
/************* functions.php ***************/
function add_product_to_cart($product_id) {
if ( ! is_admin() ) {
$found = false;
//check if product already in cart
if ( sizeof( WC()->cart->get_cart() ) > 0 ) {
foreach ( WC()->cart->get_cart() as $cart_item_key => $values ) {
$_product = $values['data'];
if ( $_product->id == $product_id )
$found = true;
}
// if product not found, add it
if ( ! $found )
WC()->cart->add_to_cart( $product_id );
} else {
// if no products in cart, add it
WC()->cart->add_to_cart( $product_id );
}
}
}
You also need to add this function in your functions.php, this function will override the price of the product i.e "Print Job" with the actual price of $64.
/******************* Functions.php ****************/
add_action( 'woocommerce_before_calculate_totals', 'override_printing_price' );
function override_printing_price( $cart_object ) {
$custom_price = 64;
foreach ( $cart_object->cart_contents as $key => $value ) {
$value['data']->price = $custom_price;
}
}
Related
So I need a little help. I have a wooocommerce webshop where there are two main products, and then 3 products, that visitors only will be able to buy, if one of the two main products are in the cart. I have found some code, that works like this: If I remove a main product, the additional product will be removed automatic, which it should. My problem is, i dont know how to modify the code, so it includes 3 products id's (one id, for each of the additional products). I have tried plenty of things, but cant get it to work. Can you maybe help me? This it the code I have (which now contains one product id, and it should contain three id's):
// Add to cart validation for the discounted product
add_filter( 'woocommerce_add_to_cart_validation', 'check_specific_discounted_product', 10, 3 );
function check_specific_discounted_product( $passed, $product_id, $quantity ) {
// Settings
$discounted_product_id = 3008;
if( WC()->cart->is_empty() && $discounted_product_id == $product_id ) {
wc_add_notice( __("This product can't be purchased alone."), 'notice' );
return false;
}
return $passed;
}
// Removing the discounted product if it's alone in cart
add_action( 'woocommerce_before_calculate_totals', 'conditionally_remove_a_discounted_product' );
function conditionally_remove_a_discounted_product( $cart ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
// Settings
$discounted_product_id = 3008;
// Initializing variables
$discounted_item_key = false;
// Loop through cart items (first loop)
foreach ( $cart->get_cart() as $cart_item_key => $cart_item ){
// When free productis is cart
if ( in_array( $discounted_product_id, array($cart_item['product_id'], $cart_item['variation_id']) ) ) {
$discounted_item_key = $cart_item_key;
}
// if any other product is in cart: EXIT
else {
return;
}
}
// When the discounted product is alone in cart, remove it
if( $discounted_item_key ) {
// display notice on removal (optional)
wc_clear_notices();
wc_add_notice( __("The discounted product can't be purchased alone and has been removed."), 'notice' );
$cart->remove_cart_item( $discounted_item_key ); // Remove
}
}
I have tried to modify the code like this:
$discounted_product_id = 3004, 3008, 3157;
And like this:
$discounted_product_id = 3004;$discounted_product_id = 3008;$discounted_product_id = 3157;
Also like this:
$discounted_product_id = array('3004','3008','3157');
But it's not working :(
I am using WooCommerce Multivendor Marketplace plugin in Wordpress for multivendor site. I want to restrict a user so they can add only one vendor's product in their cart. I am writing a custom function to get vendor id.
I'm trying to use the get_wcfm_product_vendors function but it isn't working; I think that it might not be supported. I've search for other possible solutions but I could not find any. Is there any other method I can use to get vendor id for a product?
You may try WCFM single vendor checkout function, add this code to your child theme :
add_action( 'woocommerce_add_to_cart_validation', function( $is_allow, $product_id, $quantity ) {
$product = get_post( $product_id );
$product_author = $product->post_author;
//Iterating through each cart item
foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
$cart_product_id = $cart_item['product_id'];
$cart_product = get_post( $cart_product_id );
$cart_product_author = $cart_product->post_author;
if( $cart_product_author != $product_author ) {
$is_allow = false;
break;
}
}
if( !$is_allow ){
// We display an error message
wc_clear_notices();
wc_add_notice( __( "Well, you already have some item in your cart. First checkout with those and then purchase other items!", "wcfm" ), 'error' );
}
return $is_allow;
}, 50, 3 );
https://docs.wclovers.com/tweaks/#single-vendor-checkout
I'm building a WooCommerce e-shop and I need to tweak my checkout page by doing the following:
Hide a certain shipping method (only one) if the order total > 100€.
Hide the cash on delivery payment method if local pickup is selected.
Does anyone know how to do that? I have the Code Snippets plugin so I can easily add any custom code.
To hide specific shipping method based on the cart total, you can use below code snippet. You need to update your shipping method name in the code.
Disable shipping method as per cart total
Add this snippet in your theme's functions.php file or custom plugin file.
add_filter( 'woocommerce_package_rates', 'shipping_based_on_price', 10, 2 );
function shipping_based_on_price( $rates, $package ) {
$total = WC()->cart->cart_contents_total;
//echo $total;
if ( $total > 100 ) {
unset( $rates['local_delivery'] ); // Unset your shipping method
}
return $rates;
}
Disable Payment Gateway For Specific Shipping Method
Use below code snippet. Update code as per your payment method & shipping method.
add_filter( 'woocommerce_available_payment_gateways', 'x34fg_gateway_disable_shipping' );
function x34fg_gateway_disable_shipping( $available_gateways ) {
global $woocommerce;
if ( !is_admin() ) {
$chosen_methods = WC()->session->get( 'chosen_shipping_methods' );
$chosen_shipping = $chosen_methods[0];
if ( isset( $available_gateways['cod'] ) && 0 === strpos( $chosen_shipping, 'local_pickup' ) ) {
unset( $available_gateways['cod'] );
}
}
return $available_gateways;
}
There are a number of plugins that will do this for you, take a look at this one WooCommerce Conditional Shipping and Payments
You'll want to tie in to the "woocommerce_payment_gateways" action
Something along these lines:
function alter_payment_gateways( $gateways ){
$chosen_rates = ( isset( WC()->session ) ) ? WC()->session->get( 'chosen_shipping_methods' ) : array();
if( in_array( 'local-pickup:6', $chosen_rates ) ) {
$array_diff = array('cod');
$list = array_diff( $list, $array_diff );
}
return $list;
}
add_action('woocommerce_payment_gateways', 'alter_payment_gateways', 50, 1);
The number on the end of 'local-pickup' on line 4 will depend on your woocommerce setup. You can find the string you need to put in here by adding something to a basket, going to the checkout, right clicking on the "Local Pickup" option in the delivery methods and looking at the value attribute.
We have a WooCommerce Multi-step checkout. One checkout step is for insurance, but this insurance is only for the rental category.
Looking to only show the insurance step if a rental product is in the cart. Found a great article on Checking if the WooCommerce Cart Contains a Product Category but the code is not giving the desired result when we place our add_action snippet to load the checkout step:
Here is our add_action call for the custom template (
add_action('woocommerce_multistep_checkout_after_shipping', 'add_my_insurance_step_with_new_field');
function add_my_insurance_step_with_new_field( $checkout ) {
wc_get_template( 'checkout/insurance.php', array( 'checkout' => $checkout ) );
}
And here is it placed within the code from SkyVerge:
// set our flag to be false until we find a product in that category
$cat_check = false;
// check each cart item for our category
foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
$product = $cart_item['data'];
// replace 'membership' with your category's slug
if ( has_term( 'rentals', 'product_cat', $product->id ) ) {
$cat_check = true;
// break because we only need one "true" to matter here
break;
}
}
// if a product in the cart is in our category, do something
if ( $cat_check ) {
// we have the category, do what we want
add_action('woocommerce_multistep_checkout_after_shipping', 'add_my_insurance_step_with_new_field');
function add_my_insurance_step_with_new_field( $checkout ) {
wc_get_template( 'checkout/insurance.php', array( 'checkout' => $checkout ) );
}
}
So very close! Not sure what could be going wrong.
Thanks for your help,
-L
This did the fix. Set $cat_check to false, run through each product in the cart, check if it has our category slug (rentals) in the cart, if true we break out and run the next if statement.
Which gets the template file and loads it before checkout order info (woocommerce_multistep_checkout_before_order_info).
function cclever_show_insurance_step_if_rentals() {
if ( function_exists( 'wc_checkout_add_ons' ) ) {
// set to false first
$cat_check = false;
// check each cart item for our category
foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
$product = $cart_item['data'];
// replace 'rentals' with your category's slug
if ( has_term( 'rentals', 'product_cat', $product->id ) ) {
$cat_check = true;
// we only need one "true" to leave
break;
}
}
// if a product in the cart is in our category, remove the add-ons
if ( $cat_check ) {
add_action('woocommerce_multistep_checkout_before_order_info', 'cclever_add_insurance_custom_step');
function cclever_add_insurance_custom_step( $checkout ) {
wc_get_template( 'checkout/insurance.php', array( 'checkout' => $checkout ) );
}
}
}
}
add_action( 'woocommerce_before_checkout_form', 'cclever_show_insurance_step_if_rentals' );
Hope that helps someone out. ** or if there is anything wrong with my code, please let me know. Thanks!
I'm creating a plugin for WooCommerce to modify the Checkout page. I would like to do some conditional filters based on the users shopping cart. Is there a way to look at the items in the shopping cart, and determine if any of the items are NOT downloadable/virtual?
So far I have a filter and in the filter I want to hide the address fields. This works great, but now I want to make it conditional, and only hide the address fields if a non-downloadable product is included. Thanks
// Our hooked in function - $fields is passed via the filter!
function custom_override_checkout_fields( $fields ) {
$hasPhysicalProduct = 0;
if ( sizeof( $woocommerce->cart->get_cart() ) > 0 ) {
foreach ( $woocommerce->cart->get_cart() as $cart_item_key => $values ) {
$_product = $values['data'];
if ( SOMEHOW CHECK IF THE PRODUCT IS DOWNLOADABLE ) {
$hasPhysicalProduct = 1;
}
}
}
$_product is an instance of WC_Product, so you should be able to do this:
if ( $_product.is_downloadable() ) {
$hasPhysicalProduct = 1;
}
The WooCommerce docs has information about the WC_Product class members