I'm using the woocommerce_checkout_create_order_line_item action to update/add some order item meta data.
At the same time, within the same function, I want to use wc_get_order_item_meta to get a different meta value from the same item but I can't get it to work within this action hook.
I think the issue is that I'm not managing to get the $item_id needed to use wc_get_order_item_meta.
Am I going about this in the wrong way?
I've tried the method here How to get order items ids to get some product meta data?
Below code will return all details of order with order item meta.just take those values in count which you want to use remove others.
function action_woocommerce_checkout_create_order_line_item( $item, $cart_item_key, $values, $order ) {
$order_id = $order->get_order_number();
$order = wc_get_order( $order_id );
$order_data = $order->get_data();
//Order Data and order item metas
$order_id = $order_data['id'];
$order_parent_id = $order_data['parent_id'];
$order_status = $order_data['status'];
$order_currency = $order_data['currency'];
$order_version = $order_data['version'];
$order_payment_method = $order_data['payment_method'];
$order_payment_method_title = $order_data['payment_method_title'];
$order_payment_method = $order_data['payment_method'];
$order_payment_method = $order_data['payment_method'];
## Creation and modified WC_DateTime Object date string ##
// Using a formated date ( with php date() function as method)
$order_date_created = $order_data['date_created']->date('Y-m-d H:i:s');
$order_date_modified = $order_data['date_modified']->date('Y-m-d H:i:s');
// Using a timestamp ( with php getTimestamp() function as method)
$order_timestamp_created = $order_data['date_created']->getTimestamp();
$order_timestamp_modified = $order_data['date_modified']->getTimestamp();
$order_discount_total = $order_data['discount_total'];
$order_discount_tax = $order_data['discount_tax'];
$order_shipping_total = $order_data['shipping_total'];
$order_shipping_tax = $order_data['shipping_tax'];
$order_total = $order_data['cart_tax'];
$order_total_tax = $order_data['total_tax'];
$order_customer_id = $order_data['customer_id']; // ... and so on
## BILLING INFORMATION:
$order_billing_first_name = $order_data['billing']['first_name'];
$order_billing_last_name = $order_data['billing']['last_name'];
$order_billing_company = $order_data['billing']['company'];
$order_billing_address_1 = $order_data['billing']['address_1'];
$order_billing_address_2 = $order_data['billing']['address_2'];
$order_billing_city = $order_data['billing']['city'];
$order_billing_state = $order_data['billing']['state'];
$order_billing_postcode = $order_data['billing']['postcode'];
$order_billing_country = $order_data['billing']['country'];
$order_billing_email = $order_data['billing']['email'];
$order_billing_phone = $order_data['billing']['phone'];
## SHIPPING INFORMATION:
$order_shipping_first_name = $order_data['shipping']['first_name'];
$order_shipping_last_name = $order_data['shipping']['last_name'];
$order_shipping_company = $order_data['shipping']['company'];
$order_shipping_address_1 = $order_data['shipping']['address_1'];
$order_shipping_address_2 = $order_data['shipping']['address_2'];
$order_shipping_city = $order_data['shipping']['city'];
$order_shipping_state = $order_data['shipping']['state'];
$order_shipping_postcode = $order_data['shipping']['postcode'];
$order_shipping_country = $order_data['shipping']['country'];
};
//To get Order item metas please use below code
foreach ($order->get_items() as $item_key => $item_values):
## Using WC_Order_Item methods ##
// Item ID is directly accessible from the $item_key in the foreach loop or
$item_id = $item_values->get_id();
## Using WC_Order_Item_Product methods ##
$item_name = $item_values->get_name(); // Name of the product
$item_type = $item_values->get_type(); // Type of the order item ("line_item")
$product_id = $item_values->get_product_id(); // the Product id
$wc_product = $item_values->get_product(); // the WC_Product object
## Access Order Items data properties (in an array of values) ##
$item_data = $item_values->get_data();
$product_name = $item_data['name'];
$product_id = $item_data['product_id'];
$variation_id = $item_data['variation_id'];
$quantity = $item_data['quantity'];
$tax_class = $item_data['tax_class'];
$line_subtotal = $item_data['subtotal'];
$line_subtotal_tax = $item_data['subtotal_tax'];
$line_total = $item_data['total'];
$line_total_tax = $item_data['total_tax'];
endforeach;
// add the action
add_action( 'woocommerce_checkout_create_order_line_item', 'action_woocommerce_checkout_create_order_line_item', 10, 4 );
Related
I am trying to add a random string when the order number is created as the default sequential number can be very easily guessed.
I tried this snippet:
function generate_random_string( $length = 16 ) {
return substr( str_shuffle( str_repeat( $x = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ', ceil( $length / strlen( $x ) ) ) ), 1, $length );
}
add_filter( 'woocommerce_order_number', 'ct_change_woocommerce_order_number', 1, 2);
function ct_change_woocommerce_order_number( $order_id, $order ) {
$random_string1 = generate_random_string(5);
return $random_string1 . $order->get_id();
}
The problem is that this change the order number every time the order number is requested somewhere.
This would work if I will use a constant prefix and suffix, but in the actual way a different order number is shown each time for the same order. Any advice?
To prevent this you can save the result as meta data, once this exists return the meta data instead of the result of the function
So you get:
function generate_random_string( $length = 16 ) {
return substr( str_shuffle( str_repeat( $x = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ', ceil( $length / strlen( $x ) ) ) ), 1, $length );
}
function filter_woocommerce_order_number( $order_number, $order ) {
// Get meta
$random_meta_string = $order->get_meta( '_random_meta_string' );
// When meta empty
if ( empty ( $random_meta_string ) ) {
// Call function
$generate_random_string = generate_random_string( 5 );
// Append
$random_string = $generate_random_string . $order->get_id();
// Add the meta data
$order->update_meta_data( '_random_meta_string', $random_string );
// Return random string
$order_number = $random_string;
} else {
// Return meta
$order_number = $random_meta_string;
}
return $order_number;
}
add_filter( 'woocommerce_order_number', 'filter_woocommerce_order_number', 10, 2 );
I need something like the following.
if ($order->has_status( 'delivered' )):
I want to add custom css class if the package was delivered to the customer.
I use WooCommerce with WooCommerce ShipStation Integration.
First you need to get the instance of your order :
$order = wc_get_order( $order_id );
Then you get the data :
$order_data = $order->get_data();
$order_id = $order_data['id'];
$order_parent_id = $order_data['parent_id'];
$order_status = $order_data['status'];
$order_currency = $order_data['currency'];
$order_version = $order_data['version'];
$order_payment_method = $order_data['payment_method'];
$order_payment_method_title = $order_data['payment_method_title'];
$order_payment_method = $order_data['payment_method'];
$order_payment_method = $order_data['payment_method'];
Now you have this :
$order_status = $order_data['status'];
Then you can apply your CSS.
Source : https://docs.woocommerce.com/wc-apidocs/class-WC_Order.html
The products have the attribute Tempo. This is a text field in which to enter the number.
How to sort products by the minimum and maximum attribute value?
using such url ?filtering=1&filter_min-tempo=100&filter_max-tempo=150
Is it possible to create an attribute of type integer?
All attributes are stored as text, but you can cast them to the type you need.
Look at this code:
function isequal($v1,$v2) {
return intval($v1) == intval($v2);
}
function filter_loop_shop_post_in( $array ) {
if ( !array_key_exists('min_tempo',$_GET) && !array_key_exists('max_tempo',$_GET) ) return $array;
global $wpdb;
$min = isset( $_GET['min_tempo'] ) ? floatval( $_GET['min_tempo'] ) : 0;
$max = isset( $_GET['max_tempo'] ) ? floatval( $_GET['max_tempo'] ) : 9999999999;
$query = "
SELECT DISTINCT
tr.object_id
FROM
{$wpdb->term_relationships} AS tr
LEFT JOIN
{$wpdb->term_taxonomy} AS tt
ON
tr.term_taxonomy_id = tt.term_taxonomy_id
LEFT JOIN
{$wpdb->terms} AS t
ON
tt.term_id = t.term_id
WHERE
tt.`taxonomy` = 'pa_tempo' AND CAST(t.name AS DECIMAL(10, 1)) BETWEEN $min AND $max";
$raw_results = $wpdb->get_results( $query );
if (!sizeof($raw_results)) return $array;
$results = array();
foreach ($raw_results as $res) {
$results[] = intval($res->object_id);
}
if (!sizeof($array)) return $results;
return array_uintersect($results, $array, 'isequal');
};
add_filter( 'loop_shop_post_in', 'filter_loop_shop_post_in', 10, 1 );
It works for me in WooCommerce 2.6.14.
In product page to get input from customer as number of words. To calculate the amount from products add-ons fixed amount to additional 10$ for each above 500 words.
ex: 1. Number of Words: 530
Normal Price + additional price: 180$ + 10$
Total: 190$
Number of Words: 1040
Normal Price + additional price: 180$ + 20$
Total: 200$
This process as to create dynamic input form customer to calculate amount the price and total amount.
`$extra_amount = (int)'10';
$amount = (int)'180'; // how to get amount from woocommerce data
if(isset($_POST['wordnumber'])){ // how to get this paramater form woocommerce post values
$test =$_POST['wordnumber'];
$original_amount = '';
if($test <= (int)'500'){
$original_amount = $amount;
}
elseif($test > (int)'500'){
$div_amount = $test/(int)'500';
$round = floor($div_amount);
//echo '<br/>';
$total_extra = $round*$extra_amount;
$original_amount = $amount+$total_extra;
}
echo $original_amount;
}`
I installed WC Fields Factory plugin then i got value from one field using key. in that i written a function and i overrided the price value.
function calculate_gift_wrap_fee( $cart_object ) {
/* Gift wrap price */
$additionalPrice = 10;
foreach ( $cart_object->cart_contents as $key => $value ) {
$test = $value['custom field'];
if( $test <= 100 ) {
$quantity = floatval( $value['quantity'] );
$orgPrice = floatval( $value['data']->price );
$value['data']->price = ( $orgPrice );
}
elseif( $test > 100 ) {
$div_amount = floatval($test/500);
$round = floor($div_amount);
$total_extra = floatval($round * $additionalPrice);
$quantity = floatval( $value['quantity'] );
$orgPrice = floatval( $value['data']->price );
$pp = ($value['price']);
$total = floatval($pp + $total_extra);
$value['data']->price = ( $orgPrice + $total );
}
}}
add_action( 'woocommerce_before_calculate_totals', calculate_gift_wrap_fee', 1, 1 );
Hi currently i want to get the name of the tax rate in woocommerce. I there any way to get the value that is circled in this picture: http://i.imgur.com/niSraFa.png
My current code:
$items = $order->get_items();
$lineItem = array();
$productInfo = $orderInfo = array();
$order_items = array();
if ($items) foreach ($items as $item_key => $item_value) {
$_tax = new WC_Tax();
$_product = $order->get_product_from_item( $item_value );
$product_tax_class = $_product->get_tax_class();
$tax_class = $item_value['tax_class'];
You would use the WC_Tax()->find_rates() method. It takes an array as an argument, which in your case would be array( 'country' => 'NO' ) and returns an array of matching tax rates. One of the keys of this array is label which contains the name of the tax rate.
$tax = new WC_Tax();
$country_code = 'NO'; // or populate from order to get applicable rates
$rates = $tax->find_rates( array( 'country' => $country_code ) );
foreach( $rates as $rate ){
$tax_rate_name = $rate['label'];
}
To find the applicable tax rates for a specific order, populate the array for find_rates() with values from the shipping/billing address on the order.