My site dynamically gives users coupons if they have been a member for a long enough time. When I am generating the coupon I want to assign a description to the coupon. However, I seem to be unable to assign a description by updating the post's metadata with the key description as the docs suggest I should be able to.
Currently I am trying to assign the description like so:
$percent = 25;//DISCOUNT PERCENTAGE
$coupon_code = 'testcoupon'; //Coupon Code
$discount_type = 'percent'; // Type: fixed_cart, percent, fixed_product, percent_product
//ASSIGN COUPON AND DISCOUNT PERCENTAGE
$coupon = array(
'post_title' => $coupon_code,
'post_content' => '',
'post_status' => 'publish',
'post_author' => 1,
'post_type' => 'shop_coupon'
);
$new_coupon_id = wp_insert_post( $coupon );
// Add meta
update_post_meta( $new_coupon_id, 'discount_type', $discount_type );//SET DICOUNT TO BE PERCENTAGE BASED
update_post_meta( $new_coupon_id, 'coupon_amount', $percent );//SET DISCOUNT PERCENTAGE
update_post_meta( $new_coupon_id, 'individual_use', 'yes' );//ONLY ONE CUPON BE USED AT A TIME
update_post_meta( $new_coupon_id, 'product_ids', '' ); //INCLUDE ALL PRODUCTS
update_post_meta( $new_coupon_id, 'exclude_product_ids', '' );//DO NOT EXCLUDE ANY PRODUCTS
update_post_meta( $new_coupon_id, 'usage_limit', '1' );//ONE TIME USE
update_post_meta( $new_coupon_id, 'expiry_date', strtotime("+6 months") );
update_post_meta( $new_coupon_id, 'apply_before_tax', 'yes' );
update_post_meta( $new_coupon_id, 'free_shipping', 'no' );//DO NOT GIVE FREE SHIPPING
//ASSIGN DESCRIPTION TO COUPON
update_post_meta( $new_coupon_id, 'description', 'This is an example description used for the example coupon');
How else should I go about adding a description?
The coupon description has to be added in the post data as post_excerpt key (but not in post meta data)…
So your code should be instead:
$percent = 25;//DISCOUNT PERCENTAGE
$coupon_code = 'testcoupon'; //Coupon Code
$discount_type = 'percent'; // Type: fixed_cart, percent, fixed_product, percent_product
$description = __('This is an example description used for the example coupon');
//ASSIGN COUPON AND DISCOUNT PERCENTAGE
$coupon = array(
'post_title' => $coupon_code,
'post_content' => '',
'post_excerpt' => $description, // <== HERE goes the description
'post_status' => 'publish',
'post_author' => 1,
'post_type' => 'shop_coupon'
);
$new_coupon_id = wp_insert_post( $coupon );
## … / … and so on
Or instead, since WooCommerce 3, you can use any related method on a WC_Coupon Object. In your case you will use setter methods to set the data (as getter methods are used to get the data on an existing coupon object):
// Get an instance of the WC_Coupon object
$wc_coupon = new WC_Coupon($coupon_code);
// Some data
$percent = 25; // DISCOUNT PERCENTAGE
$coupon_code = 'testcoupon'; // Coupon Code
$discount_type = 'percent'; // Type: fixed_cart, percent, fixed_product, percent_product
$description = __('This is an example description used for the example coupon'); // Description
// Set the coupon data
$wc_coupon->set_code($coupon_code);
$wc_coupon->set_description($description);
$wc_coupon->set_discount_type($discount_type);
$wc_coupon->set_amount( floatval($percent) );
$wc_coupon->set_individual_use( true );
$wc_coupon->set_usage_limit( 1 );
$wc_coupon->set_date_expires( strtotime("+6 months") );
## $wc_coupon->apply_before_tax( true ); // ==> Deprecated in WC 3+ with no replacement alternatie
$wc_coupon->set_free_shipping( false );
// Test raw data output before save
var_dump($wc_coupon);
// SAVE the coupon
$wc_coupon->save();
Related
I am attempting to create a custom coupon code in WooCommerce using PHP which essentially discounts the price of each item in the cart with the tag name 'main' to 10. It does this by counting the number of items in the cart tagged with 'main', then calculating the total price of each of these, and from this it calculates the required discount within the $discount variable. See below code:
$tag_name = 'main';
$tag_count = 0;
foreach(WC()->cart->get_cart() as $cart_item) {
if( has_term( $tag_name, 'product_tag', $cart_item['product_id'])){
$tag_count += $cart_item['quantity'];
$price = $cart_item['data']->get_price();
$float_value_price += floatval($price);
}
}
$discount = $float_value_price - (10*$tag_count);
$discount_string = number_format($discount, 2);
$coupon_code = 'testing'; // Code
$amount = $discount_string; // Amount
$discount_type = 'fixed_cart'; // Type: fixed_cart, percent, fixed_product, percent_product
$coupon = array(
'post_title' => $coupon_code,
'post_content' => '',
'post_status' => 'publish',
'post_author' => 1,
'post_type' => 'shop_coupon');
$new_coupon_id = wp_insert_post( $coupon );
// Add meta
update_post_meta( $new_coupon_id, 'discount_type', $discount_type );
update_post_meta( $new_coupon_id, 'coupon_amount', $amount );
update_post_meta( $new_coupon_id, 'individual_use', 'no' );
update_post_meta( $new_coupon_id, 'product_ids', '' );
update_post_meta( $new_coupon_id, 'exclude_product_ids', '' );
update_post_meta( $new_coupon_id, 'usage_limit', '' );
update_post_meta( $new_coupon_id, 'expiry_date', '' );
update_post_meta( $new_coupon_id, 'apply_before_tax', 'yes' );
update_post_meta( $new_coupon_id, 'free_shipping', 'no' );
When I attempt to activate this code, I get the following error message:
The code snippet you are trying to save produced a fatal error on line 4:
Uncaught Error: Call to a member function get_cart() on null in /homepages/9/d392621230/htdocs/clickandbuilds/WOOCOMMERCEExperiment/wp-content/plugins/code-snippets/php/admin-menus/class-edit-menu.php(213) : eval()'d code:4 Stack trace: #0 /homepages/9/d392621230/htdocs/clickandbuilds/WOOCOMMERCEExperiment/wp-content/plugins/code-snippets/php/admin-menus/class-edit-menu.php(213): eval() #1 /homepages/9/d392621230/htdocs/clickandbuilds/WOOCOMMERCEExperiment/wp-content/plugins/code-snippets/php/admin-menus/class-edit-menu.php(263): Code_Snippets_Edit_Menu->test_code(Object(Code_Snippet)) #2 /homepages/9/d392621230/htdocs/clickandbuilds/WOOCOMMERCEExperiment/wp-content/plugins/code-snippets/php/admin-menus/class-edit-menu.php(122): Code_Snippets_Edit_Menu->save_posted_snippet() #3 /homepages/9/d392621230/htdocs/clickandbuilds/WOOCOMMERCEExperiment/wp-content/plugins/code-snippets/php/admin-menus/class-edit-menu.php(99): Code_Snippets_Edit_Menu->process_actions() #4 /homepages/9/d392621230/htdocs/clickandbuilds/W
I have been looking at this for a while now and cannot seem to find a solution. I would be grateful if anyone can solve this. Thanks.
You can achieve the same result with a simpler approach. You can create your coupon code in the WooCommerce dashboard setting it to fixed product discount.
Then with your code find the desired products and their ID's. Then you can pass those ID's to your previously created coupon by using set_product_ids(). Don't forget to save the new meta information by using save().
Then just apply the new coupon code to your cart.
The code would look something like this:
add_action( 'woocommerce_before_cart', 'cw_coupons_matched' );
function cw_coupons_matched() {
global $woocommerce;
$coupon_code = 'your_discount_code';
# Get product ID's
foreach( WC()->cart->get_cart() as $cart_item ){
var_dump($cart_item['data']->name);
if (strpos($cart_item['data']->name, 'string_to_search') !== false) {
$product_ids[] = $cart_item['product_id'];
}
}
# Adding product ID's to coupon
$c = new WC_Coupon($coupon_code);
$c->set_product_ids($product_ids);
$c->save();
# Adding discount coupon to cart
if ( $woocommerce->cart->has_discount( $cw_coupon ) ) return;
foreach ( $woocommerce->cart->cart_contents as $key => $values ) {
if( in_array( $values['product_id'], $product_ids ) ) {
$woocommerce->cart->add_discount( $coupon_code );
wc_print_notices();
}
}
}
I added new custom post type 'giftcard' and extended WooCommerce simple product by adding checkbox 'Gift Card'
Whenever order status changed to 'processing' and it contains product type giftcard, it creates new giftcard post by following code
function status_order_processing( $order_id ) {
$order = wc_get_order( $order_id );
$items = $order->get_items();
foreach ( $items as $item ) {
$is_gift_card = get_post_meta( $item['product_id'], '_woo_giftcard', true );
if($is_gift_card == 'yes'){
$token = base64_encode(openssl_random_pseudo_bytes(32));
$token = bin2hex($token);
$hyphen = chr(45);
$uuid = substr($token, 0, 8).$hyphen
.substr($token, 8, 4).$hyphen
.substr($token,12, 4).$hyphen
.substr($token,16, 4).$hyphen
.substr($token,20,12);
$gift_card = array(
'post_title' => $uuid,
'post_status' => 'publish',
'post_type' => 'giftcard',
);
$gift_card_id = wp_insert_post( $gift_card, $wp_error );
update_post_meta( $gift_card_id, 'woo_gift_card_amount', (int)$item['total'] );
}
}
add_action( 'woocommerce_order_status_processing', 'status_order_processing' );
New post name is a token generated in above code and save item total in meta field 'woo_gift_card_amount'.
Is there any way if I enter giftcard post type token in coupon field and it subtracts amount from Order amount according to meta field 'woo_gift_card_amount' of that post.
Any help would be appreciated.
Coupons are also a custom post. To use your gift card token/uuid as woocommerce coupon, you will need to insert it as a new post in shop_coupon post type.
A quick example (this should go inside your status_order_processing function, or you can use separate function - whichever way suits you):
$coupon_code = $uuid;
$amount = (int)$item['total'];
$discount_type = 'fixed_cart'; //available types: fixed_cart, percent, fixed_product, percent_product
$coupon = array(
'post_title' => $coupon_code,
'post_content' => '',
'post_status' => 'publish',
'post_author' => 1,
'post_type' => 'shop_coupon'
);
$new_coupon_id = wp_insert_post( $coupon );
if ( $new_coupon_id ) {
//add coupon/post meta
update_post_meta($new_coupon_id, 'discount_type', $discount_type);
update_post_meta($new_coupon_id, 'coupon_amount', $amount);
//update_post_meta($new_coupon_id, 'expiry_date', $expiry_date);
//update_post_meta($new_coupon_id, 'usage_limit', '1');
//update_post_meta($new_coupon_id, 'individual_use', 'no');
//update_post_meta( $new_coupon_id, 'product_ids', '' );
//update_post_meta( $new_coupon_id, 'exclude_product_ids', '' );
//update_post_meta( $new_coupon_id, 'usage_limit', '' );
//update_post_meta( $new_coupon_id, 'expiry_date', '' );
//update_post_meta( $new_coupon_id, 'apply_before_tax', 'yes' );
//update_post_meta( $new_coupon_id, 'free_shipping', 'no' );
}
I am trying to use customer email address as their own coupon code with a special discount. To achieve this I tried bellow code but nothing happen shows error Call to undefined function get_currentuserinfo(). Is it possible to use coupon code virtually not saving like custom post_type?
Here is the code what I'm trying so far.
global $current_user;
get_currentuserinfo();
$user_email = $current_user->user_email ;
$coupon_code = $user_email; // Code
$amount = '10'; // Amount
$discount_type = 'fixed_cart'; // Type: fixed_cart, percent, fixed_product, percent_product
$coupon = array(
'post_title' => $coupon_code,
'post_content' => '',
'post_status' => 'publish',
'post_author' => 1,
'post_type' => 'shop_coupon'
);
$new_coupon_id = wp_insert_post( $coupon );
// Add meta
update_post_meta( $new_coupon_id, 'discount_type', $discount_type );
update_post_meta( $new_coupon_id, 'coupon_amount', $amount );
update_post_meta( $new_coupon_id, 'individual_use', 'no' );
update_post_meta( $new_coupon_id, 'product_ids', '' );
update_post_meta( $new_coupon_id, 'exclude_product_ids', '' );
update_post_meta( $new_coupon_id, 'usage_limit', '' );
update_post_meta( $new_coupon_id, 'expiry_date', '' );
update_post_meta( $new_coupon_id, 'apply_before_tax', 'yes' );
update_post_meta( $new_coupon_id, 'free_shipping', 'no' );
The get_currentuserinfo() function is deprecated. Use wp_get_current_user() instead.
You should use in your code:
// (Optional) depending where you are using this code
is_user_logged_in(){
global $current_user;
// If global $current_user is not working
if(empty($current_user))
$current_user = wp_get_current_user();
// Here goes all your other code below… …
}
After that, I have never tried to set an email as coupon code slug programatically, but it should work as it's possible to set in woocommerce a coupon code with an email address (I have test it with success)…
add_action( 'user_register', 'coupon_email', 10, 1 );
function coupon_email( $user_id ) {
if ( isset( $_POST['email_address'] ) )
$coupon = array(
'post_title' => $_POST['email_address'],
'post_content' => '',
'post_status' => 'publish',
'post_author' => 1,
'post_type' => 'shop_coupon'
);
$new_coupon_id = wp_insert_post( $coupon );
}
This will add a coupon with the users email address as the title and input every time a new user registers for your website.
I have being creating a new woocommerce plugin that will provide an option to the apply discount on top of the cart page.
Now when there are products in the cart, the user will click on the Apply Discount button and when clicked and action is triggered from my custom plugin that will add cart discount to that particular Cart Order.
So far it works fine and also shows that cart discount applied. below is the screenshot
As you can see from the screenshot there the Order Total is showing Wrong figure calculated.
Below is the code from my custom woocommerce plugin file.
Following action is called when the button is submitted
if(!empty($_POST['apply_discount_woo'])){
add_action('woocommerce_calculate_totals',array(&$this,'cart_order_total_action'));
}
and the function code:
public function cart_order_total_action(){
if ( is_user_logged_in() ){
global $woocommerce;
global $current_user;
global $wpdb;
$u_id = $current_user->ID;
$table_name = $wpdb->prefix."woocommerce_customer_reward_ms";
$thetable2 = $wpdb->prefix . "woocommerce_customer_reward_cart_ms";
$table_name3 = $wpdb->prefix."woocommerce_customer_reward_points_log_ms";
$data = $wpdb->get_row("SELECT * from $table_name where id=$u_id");
$data2 = $wpdb->get_row("SELECT * from $thetable2");
/* Order Id goes here */
$orders=array();//order ids
$args = array(
'numberposts' => -1,
'meta_key' => '_customer_user',
'meta_value' => $current_user->ID,
'post_type' => 'shop_order',
'post_status' => 'publish',
'tax_query'=>array(
array(
'taxonomy' =>'shop_order_status',
'field' => 'slug',
'terms' =>'on-hold'
)
)
);
$posts=get_posts($args);
//get the post ids as order ids
$orders=wp_list_pluck( $posts, 'ID' );
$order = $orders[0];
/* Order Id ends here */
if($data){
$user_points = $data->points;
$points_set = $data2->woo_pts_set;
print_r($woocommerce->cart->applied_coupons);
echo $woocommerce->cart->discount_cart;
echo $woocommerce->cart->get_cart_total();
/* the line below adds the cart discount to the Cart */
$woocommerce->cart->discount_cart = $data2->woo_discount_set;
}else{
echo 'You dont have any woo points yet.!!';
}
}
}
How can I update the cart total on Cart Discount added?
Maybe it's not 100% how you would like to achieve your goal, but you may generate a coupon on the fly:
$coupon_code = 'UNIQUECODE'; // Code
$amount = '10'; // Amount
$discount_type = 'fixed_cart'; // Type: fixed_cart, percent, fixed_product, percent_product
$coupon = array(
'post_title' => $coupon_code,
'post_content' => '',
'post_status' => 'publish',
'post_author' => 1,
'post_type' => 'shop_coupon'
);
$new_coupon_id = wp_insert_post( $coupon );
// Add meta
update_post_meta( $new_coupon_id, 'discount_type', $discount_type );
update_post_meta( $new_coupon_id, 'coupon_amount', $amount );
update_post_meta( $new_coupon_id, 'individual_use', 'no' );
update_post_meta( $new_coupon_id, 'product_ids', '' );
update_post_meta( $new_coupon_id, 'exclude_product_ids', '' );
update_post_meta( $new_coupon_id, 'usage_limit', '' );
update_post_meta( $new_coupon_id, 'expiry_date', '' );
update_post_meta( $new_coupon_id, 'apply_before_tax', 'yes' );
update_post_meta( $new_coupon_id, 'free_shipping', 'no' );
After hours of research and debugging some Woocommerce Documentation. I found out that there are two types of discount that can be applied to the cart
1- Cart Discount
2- Order Discount
And correct me if I'm wrong, but discount is always applied on use of coupons. What I was trying here is to give a custom Discount of say $5 to the cart and this discount was not treated as an actual discount by Woocommere. Also this custom discount will not reflect the actual cart total on the cart page as well as the checkout page.
In order to do that you will ultimately have to alter your woocommerce class files, which I dont recommend when you are creating an independent custom Woocommerce Plugin.
But I figured out an alternate method of applying discount i.e with help of coupons. I created a custom coupon that will give a $5 discount to the cart. And that was it, Cart total recognised the dicount and showed me the correct total also the discount applied.
Also the checkout page was populated with the correct total.
And after processing the order it showed me the correct discount applied.
Just wanted to share this with you all. As I felt this was the solution that worked like charm and without altering any of the woocommerce core files.
I hope this is useful to you all as well.
Thanks.
I've been looking for a way to add coupons in bulk to WooCommerce, it's actually a list of 800 membership numbers, that grant a discount, and coupons seem to the best way to do this.
I've found a way to add a single coupon programatically: http://docs.woothemes.com/document/create-a-coupon-programatically/ but my limited PHP knowledge doesn't seem adequate to add 800.
I'm guessing an array or somehow linking to a .csv would do it, but I'm not sure. I'd be grateful for any help.
You could create an array of 800 diferent keys and just make a foreach loop to repeat the process for each different key you have on the array like this
forehach ( $your_800_array as $coupon_code){
//the code from the page you posted
$amount = '10'; // Amount
$discount_type = 'fixed_cart'; // Type: fixed_cart, percent, fixed_product, percent_product
$coupon = array(
'post_title' => $coupon_code,
'post_content' => '',
'post_status' => 'publish',
'post_author' => 1,
'post_type' => 'shop_coupon'
);
$new_coupon_id = wp_insert_post( $coupon );
// Add meta
update_post_meta( $new_coupon_id, 'discount_type', $discount_type );
update_post_meta( $new_coupon_id, 'coupon_amount', $amount );
update_post_meta( $new_coupon_id, 'individual_use', 'no' );
update_post_meta( $new_coupon_id, 'product_ids', '' );
update_post_meta( $new_coupon_id, 'exclude_product_ids', '' );
update_post_meta( $new_coupon_id, 'usage_limit', '' );
update_post_meta( $new_coupon_id, 'expiry_date', '' );
update_post_meta( $new_coupon_id, 'apply_before_tax', 'yes' );
update_post_meta( $new_coupon_id, 'free_shipping', 'no' );
}
(Used the code that OP posted inside the loop. Not actually tested)