Only create coupon on specific product purchase woocommerce - wordpress

I am trying to create coupon on specific product purchase. Can you please tell me where i am doing wrong
function coupon_code_akki($order_id){
$order = wc_get_order($order_id);
$items = $order->get_items();
foreach ( $items as $item ) {
$product_id = $item->get_product_id();
}
if ($product_id ='10351'){
$bname= $order->get_billing_first_name();
$bemail= $order->get_billing_email();
$coupon = new WC_Coupon();
$coupon->set_code( $bname . '1990' );
$coupon->set_amount( 1990);
$coupon->set_email_restrictions($bemail)
$coupon->save();
echo 'done';
}
}

Where exactly or at what stage are you using this code?
I think the problem is here:
if ($product_id ='10351'){
In this section, you should check by putting two equals. The equals operator is like this: ==
if ($product_id == '10351'){
And here is the error:
$coupon->set_email_restrictions($bemail)
You should use a semicolon at the end.
function coupon_code_akki($order_id){
$order = wc_get_order($order_id);
$items = $order->get_items();
foreach ( $items as $item ) {
$product_id = $item->get_product_id();
}
if (!empty($product_id) && $product_id == '10351'){
$bname= $order->get_billing_first_name();
$bemail= $order->get_billing_email();
$coupon = new WC_Coupon();
$coupon->set_code( $bname . '1990' );
$coupon->set_amount( 1990);
$coupon->set_email_restrictions($bemail);
$coupon->save();
echo 'done';
}
}
If you want me to help you, just tell me at what stage you want to create a coupon.

Related

wooocmmerce cart loop price not working, remove comma last [duplicate]

I am trying to send the woocommerce cart items to third party shipping tool. I need the item name, quantity and individual price to be sent to the third party. How can this be achieved?
$items = $woocommerce->cart->get_cart();
foreach($items as $item => $values) {
$_product = $values['data']->post;
echo $_product->post_title;
}
How do I get item name and quantity and price?
Try this :
<?php
global $woocommerce;
$items = $woocommerce->cart->get_cart();
foreach($items as $item => $values) {
$_product = wc_get_product( $values['data']->get_id());
echo "<b>".$_product->get_title().'</b> <br> Quantity: '.$values['quantity'].'<br>';
$price = get_post_meta($values['product_id'] , '_price', true);
echo " Price: ".$price."<br>";
}
?>
To get Product Image and Regular & Sale Price:
<?php
global $woocommerce;
$items = $woocommerce->cart->get_cart();
foreach($items as $item => $values) {
$_product = wc_get_product( $values['data']->get_id() );
//product image
$getProductDetail = wc_get_product( $values['product_id'] );
echo $getProductDetail->get_image(); // accepts 2 arguments ( size, attr )
echo "<b>".$_product->get_title() .'</b> <br> Quantity: '.$values['quantity'].'<br>';
$price = get_post_meta($values['product_id'] , '_price', true);
echo " Price: ".$price."<br>";
/*Regular Price and Sale Price*/
echo "Regular Price: ".get_post_meta($values['product_id'] , '_regular_price', true)."<br>";
echo "Sale Price: ".get_post_meta($values['product_id'] , '_sale_price', true)."<br>";
}
?>
Since WooCommerce 2.1 (2014) you should use the WC function instead of the global. You can also call more appropriate functions:
foreach ( WC()->cart->get_cart() as $cart_item ) {
$item_name = $cart_item['data']->get_title();
$quantity = $cart_item['quantity'];
$price = $cart_item['data']->get_price();
...
This will not only be clean code, but it will be better than accessing the post_meta directly because it will apply filters if necessary.
Note on product price
The price of the cart item may be different from that of the
product (stored in the database as post meta).
Some plugins or custom functions (added to the functions.php of the active theme) can change the price of the cart item.
If you want to be sure you get the price of the product added to the cart you will have to get it like this:
foreach ( WC()->cart->get_cart() as $cart_item ) {
// gets the cart item quantity
$quantity = $cart_item['quantity'];
// gets the cart item subtotal
$line_subtotal = $cart_item['line_subtotal'];
$line_subtotal_tax = $cart_item['line_subtotal_tax'];
// gets the cart item total
$line_total = $cart_item['line_total'];
$line_tax = $cart_item['line_tax'];
// unit price of the product
$item_price = $line_subtotal / $quantity;
$item_tax = $line_subtotal_tax / $quantity;
}
Instead of:
foreach ( WC()->cart->get_cart() as $cart_item ) {
// gets the product object
$product = $cart_item['data'];
// gets the product prices
$regular_price = $product->get_regular_price();
$sale_price = $product->get_sale_price();
$price = $product->get_price();
}
Other data you can get:
foreach ( WC()->cart->get_cart() as $cart_item ) {
// get the data of the cart item
$product_id = $cart_item['product_id'];
$variation_id = $cart_item['variation_id'];
// gets the cart item quantity
$quantity = $cart_item['quantity'];
// gets the cart item subtotal
$line_subtotal = $cart_item['line_subtotal'];
$line_subtotal_tax = $cart_item['line_subtotal_tax'];
// gets the cart item total
$line_total = $cart_item['line_total'];
$line_tax = $cart_item['line_tax'];
// unit price of the product
$item_price = $line_subtotal / $quantity;
$item_tax = $line_subtotal_tax / $quantity;
// gets the product object
$product = $cart_item['data'];
// get the data of the product
$sku = $product->get_sku();
$name = $product->get_name();
$regular_price = $product->get_regular_price();
$sale_price = $product->get_sale_price();
$price = $product->get_price();
$stock_qty = $product->get_stock_quantity();
// attributes
$attributes = $product->get_attributes();
$attribute = $product->get_attribute( 'pa_attribute-name' ); // // specific attribute eg. "pa_color"
// custom meta
$custom_meta = $product->get_meta( '_custom_meta_key', true );
// product categories
$categories = wc_get_product_category_list( $product->get_id() ); // returns a string with all product categories separated by a comma
}
This will show only Cart Items Count.
global $woocommerce;
echo $woocommerce->cart->cart_contents_count;
you can get the product name like this
foreach ( $cart_object->cart_contents as $value ) {
$_product = apply_filters( 'woocommerce_cart_item_product', $value['data'] );
if ( ! $_product->is_visible() ) {
echo $_product->get_title();
} else {
echo $_product->get_title();
}
}
Most of the time you want to get the IDs of the products in the cart so that you can make some comparison with some other logic - example settings in the backend.
In such a case you can extend the answer from #Rohil_PHPBeginner and return the IDs in an array as follows :
<?php
function njengah_get_ids_of_products_in_cart(){
global $woocommerce;
$productsInCart = array();
$items = $woocommerce->cart->get_cart();
foreach($items as $item => $values) {
$_product = wc_get_product( $values['data']->get_id());
/* Display Cart Items Content */
echo "<b>".$_product->get_title().'</b> <br> Quantity: '.$values['quantity'].'<br>';
$price = get_post_meta($values['product_id'] , '_price', true);
echo " Price: ".$price."<br>";
/**Get IDs and in put them in an Array**/
$productsInCart_Ids[] = $_product->get_id();
}
/** To Display **/
print_r($productsInCart_Ids);
/**To Return for Comparision with some Other Logic**/
return $productsInCart_Ids;
}

Save order meta when using the "woocommerce_new_order" hook

I need to trace if a product is bought from a user coming from a specific site, that's why I need to set a meta for the order.
Let's focus on this piece of my code:
add_action( 'woocommerce_new_order', 'add_affilate_meta', 10, 1);
function add_affilate_meta( $order_id ){
$targetProd = 3115;
// check if product is present
$order = wc_get_order( $order_id );
$affiliationProduct = false;
foreach ($order->get_items() as $item_key => $item ):
$product_id = $item->get_product_id();
if($product_id == $targetProd):
$affiliationProduct = true;
break;
endif;
endforeach;
// this is just for debug
update_post_meta( $order_id, 'test_affiliate', $product_id );
... some other stuff ...
}
$affiliationProduct and, consequently, test_affiliate meta are always false/empty. Why? I'm sure, of course, that the article is present in the order. It seems like the order is not "ready" when I try to analyze it's content.
I cannot find any other way to debug the code, because I cannot var_dump() nothing without causing JSON errors.
Any help will be appreciated.
You can indeed use the woocommerce_new_order hook, but what is missing in your code is $order->save();
So you get:
function action_woocommerce_new_order( $order_id ) {
// Get the WC_Order Object
$order = wc_get_order( $order_id );
// Setting
$target_prod = 30;
// Initialize
$affiliation_product = false;
$product_id = 0;
// Loop trough
foreach ( $order->get_items() as $item_key => $item ) {
// Get
$product_id = $item->get_product_id();
// Compare
if ( $product_id == $target_prod ) {
$affiliation_product = true;
break;
}
}
// Update meta data
$order->update_meta_data( 'test_affiliate', $product_id );
// Save
$order->save();
// When true
if ( $affiliation_product ) {
// Do something
}
}
add_action( 'woocommerce_new_order', 'action_woocommerce_new_order', 10, 1 );

How to add ACF field to custom column on WooCommerce admin orders list

ACF is set up for post type on WooCommerce products. However, I am trying to add a custom column to WooCommerce orders list within Admin dashboard and add the products ACF field.
I have added the column to display after order_status, but I'm having problems getting the ACF field to display.
// ADD NEW COLUMN
add_filter( 'manage_edit-shop_order_columns', 'custom_shop_order_column', 20 );
function custom_shop_order_column($columns)
{
$reordered_columns = array();
foreach( $columns as $key => $column){
$reordered_columns[$key] = $column;
if( $key == 'order_status' ){
$reordered_columns['my-column'] = __( 'Location','theme_domain');
}
}
return $reordered_columns;
}
Here, adding ACF to new colum.
// ADD ACF FIELD TO COLUMN
add_action( 'manage_shop_order_posts_custom_column' , 'custom_orders_list_column_content', 20, 2 );
function custom_orders_list_column_content( $column, $post_id )
{
if ( 'Location' == $column_name ){
$product_id = method_exists( $product, 'get_id' ) ? $product->get_id() : $product->id;
echo get_field( 'location', $product_id );
}
return true;
}
Still learning and not sure how to do this, any advice?
An order generally consists of several products, therefore you cannot use $product_id directly, but you have to loop through the order items.
So you get:
/**
* Add columns
*/
function filter_manage_edit_shop_order_columns( $columns ) {
$reordered_columns = array();
foreach ( $columns as $key => $column ) {
$reordered_columns[$key] = $column;
if ( $key == 'order_status' ) {
$reordered_columns['my-column'] = __( 'Location','theme_domain' );
}
}
return $reordered_columns;
}
add_filter( 'manage_edit-shop_order_columns', 'filter_manage_edit_shop_order_columns', 10, 1 );
/**
* Populate columns
*/
function filter_manage_shop_order_posts_custom_column( $column, $post_id ) {
// Compare
if ( $column == 'my-column' ) {
// Get order
$order = wc_get_order( $post_id );
// Is a WC_Order
if ( is_a( $order, 'WC_Order' ) ) {
// Get items
$items = $order->get_items();
// Loop through
foreach ( $items as $key => $item ) {
// Product ID
$product_id = $item->get_variation_id() > 0 ? $item->get_variation_id() : $item->get_product_id();
// Get field
$address = get_field( 'location', $product_id );
// Output
echo ($address) ? '<div>Address: ' . $address . '</div>' : '<div>Address: No address found!</div>';
}
}
}
}
add_filter( 'manage_shop_order_posts_custom_column', 'filter_manage_shop_order_posts_custom_column', 10, 2 );

Remove duplicate values from custom column on WooCommerce admin orders list

I have the following code that adds a custom column on WooCommerce admin orders list
add_action( 'manage_shop_order_posts_custom_column', 'inforder_add_new_order_admin_list_column_content' );
function inforder_add_new_order_admin_list_column_content( $column ) {
global $post;
if ( 'product_order' === $column ) {
$order = wc_get_order( $post->ID );
$items = $order->get_items();
$count = count($items);
$i = 1;
foreach($items as $item) {
if($i==$count)
echo $item->get_name();
else
echo $item->get_name() .', ';
$i++;
}
}
}
But this shows duplicate values. I've tried to avoid this using
array_unique(), but unfortunately without the desired result.
Any advice to avoid this?
Your code contains some mistakes
The manage_edit-shop_order_columns is missing, which is for adding columns
The manage_shop_order_posts_custom_column has not 1 but 2 parameters, the 2nd contains the $post_id so the use of global $post is not necessary
You can use in_array(), which checks if a value exists in an array. If this is not the case, we will add this value to the array, this way we avoid duplicate values
So you get:
// Add header
function filter_manage_edit_shop_order_columns( $columns ) {
$columns['product_order'] = __( 'Product', 'woocommerce' );
return $columns;
}
add_filter( 'manage_edit-shop_order_columns', 'filter_manage_edit_shop_order_columns', 10, 1 );
// Display (populate the column)
function action_manage_shop_order_posts_custom_column( $column, $post_id ) {
// Compare
if ( $column == 'product_order' ) {
// Get order
$order = wc_get_order( $post_id );
// Initialize
$names = array();
// Is a WC_Order
if ( is_a( $order, 'WC_Order' ) ) {
// Get items
$items = $order->get_items();
// Loop through
foreach ( $items as $key => $item ) {
// Get name
$name = $item->get_name();
// NOT in array
if ( ! in_array( $name, $names, true ) ) {
// Push one or more elements onto the end of array
array_push( $names, $name );
}
}
// NOT empty, print result
if ( ! empty( $names ) ) {
// Use implode() function to join comma in the array
$list = implode( ', ', $names );
// Output
echo $list;
}
}
}
}
add_action( 'manage_shop_order_posts_custom_column' , 'action_manage_shop_order_posts_custom_column', 10, 2 );

in_category() self defined $post->ID

I have this code:
function add_cert_id_to_notes( $order_id ) {
$order = new WC_Order( $order_id );
$products = $order->get_items();
foreach( $products as $product ){
$product_id = $product['product_id'];
$order->add_order_note( 'First Test: '.$product_id, 0 );
if( in_category('188', $product_id)){
$order->add_order_note( 'Second Test: '.$product_id, 0 );
}
else {
$order->add_order_note( 'Second Test: FAIL', 0 );
}
}
}
Using WooCommerce, but that's not the problem. The issue is with in_category(). I'm not doing this is a standard loop, I've defined my post ID with $product_id.
Problem is, it keeps returning the failure notice I have set up. I've tried with both the category ID and slug and I still get nothing.
I think in_category is only for post's category.
Document says The given categories are checked against the post's categories' term_ids, names and slugs. So it only check for post i think.
Try following function:-
function add_cert_id_to_notes( $order_id )
{
$order = new WC_Order( $order_id );
$products = $order->get_items();
foreach( $products as $product )
{
$categories = array();
$product_id = $product['product_id'];
$order->add_order_note( 'First Test: '.$product_id, 0 );
$terms = wp_get_post_terms( $product_id, 'product_cat' );
foreach ( $terms as $term )
{
$categories[] = $term->term_id;
$categories[] = $term->slug;
}
//if you want to check category slug than you also can use `slug` as $your_cat_id.
//`$term->slug` is also in $categories array..
$your_cat_id = '188';
if ( in_array( $your_cat_id, $categories ) )
{
$order->add_order_note( 'Second Test: '.$product_id, 0 );
} else {
$order->add_order_note( 'Second Test: FAIL', 0 );
}
}
}
I have tested this function and its working...Hope it will work for you..

Resources