Displaying a custom message based on customer postcode in WooCommerce - woocommerce

I am trying to display a custom message based on customer postcode in WooCommerce using Display a custom message based on customer shipping zone in Woocommerce answer code:
add_action( 'woocommerce_cart_totals_after_shipping' , 'shipping_zone_targeted_postcodes_custom_notice' );
add_action( 'woocommerce_review_order_after_shipping' , 'shipping_zone_targeted_postcodes_custom_notice' );
function shipping_zone_targeted_postcodes_custom_notice() {
// HERE DEFINE YOUR SHIPPING ZONE NAME(S)
$targeted_zones_names = array('France'); // <====== <====== <====== <====== <======
// Get the customer shipping zone name
$chosen_methods = WC()->session->get( 'chosen_shipping_methods' ); // The chosen shipping mehod
$chosen_method = explode(':', reset($chosen_methods) );
$shipping_zone = WC_Shipping_Zones::get_zone_by( 'instance_id', $chosen_method[1] );
$current_zone_name = $shipping_zone->get_zone_name();
if( in_array( $current_zone_name, $targeted_zones_names ) ){
echo '<tr class="shipping">
<td colspan="2" style="text-align:center">' . sprintf(
__( "You'll be charged %s more for %s zip code", "woocommerce"),
'<strong>10%</strong>',
'<strong>' . WC()->customer->get_shipping_postcode() . '</strong>'
) . '</td>
</tr>';
}
}
What modifications to make to the code?
Can someone please assist me in what adjustments need to be made for this to happen please?

For a set of defined Postcodes only, use instead the following (defining a set of targeted postcodes):
add_action( 'woocommerce_cart_totals_after_shipping' , 'shipping_zone_targeted_postcodes_custom_notice' );
add_action( 'woocommerce_review_order_after_shipping' , 'shipping_zone_targeted_postcodes_custom_notice' );
function shipping_zone_targeted_postcodes_custom_notice() {
// HERE DEFINE YOUR POSTCODES
$targeted_postcodes = array('89000','89200','89300');
// Get the customer postcode
$customer_postcode = WC()->customer->get_shipping_postcode();
$customer_postcode = ! empty($customer_postcode) ? WC()->customer->get_billing_postcode() : $customer_postcode;;
if( in_array( $customer_postcode, $targeted_postcodes ) ){
echo '<tr class="shipping">
<td colspan="2" style="text-align:center">' . sprintf(
__( "You'll be charged %s more for %s zip code", "woocommerce"),
'<strong>'.wc_price(100).'</strong>',
'<strong>' . $customer_postcode . '</strong>'
) . '</td>
</tr>';
}
}
Code goes in functions.php file of the active child theme (or active theme). Tested and works.

Related

I need create custom order tracking functionality in woo commerce

Hello I have a woo commerce website and I am selling some books every thing is cleared but I need create custom order tracking functionality in woo commerce code to add order tracking functionality for end user is it possible if possible how can I do this please help me.
I create a custom page name as woocommerce-custom-order-tracking.php
and code is given below
<?php
// Register a custom endpoint to handle order tracking
function wc_register_order_tracking_endpoint() {
add_rewrite_endpoint( 'order-tracking', EP_PAGES );
}
add_action( 'init', 'wc_register_order_tracking_endpoint' );
// Display the order tracking form
function wc_display_order_tracking_form() {
if ( ! is_wc_endpoint_url( 'order-tracking' ) ) {
return;
}
// Get the order id from the query string
$order_id = absint( $_GET['order_id'] );
// Get the order
$order = wc_get_order( $order_id );
if ( $order ) {
// Display the order tracking information
echo '<p>Order Number: ' . $order->get_order_number() . '</p>';
echo '<p>Order Status: ' . wc_get_order_status_name( $order->get_status() ) . '</p>';
echo '<p>Tracking Number: ' . get_post_meta( $order_id, '_tracking_number', true ) . '</p>';
} else {
echo '<p>Invalid order ID.</p>';
}
}
add_action( 'woocommerce_before_single_product', 'wc_display_order_tracking_form' );

Display free shipping threshold based on Woocommerce min amount order from shipping settings

I want to display shipping notice based on free shipping settings for min amount order. I have more then one shipping zone based on different country and currency. Tried to use the following code, it works when you add product to cart, the shipping notice is display but as if you update quantity the shipping notice is removed, maybe duo to Ajax load? Can I add something to this code to make it work with qty update on product?
add_action( 'woocommerce_before_mini_cart_contents', 'display_free_shipping_cart_notice_zones' );
function display_free_shipping_cart_notice_zones() {
// Get Shipping Methods for Current Zone
global $woocommerce;
$shipping_methods = $woocommerce->shipping->get_shipping_methods();
// Loop through the array to find min_amount value/s
foreach($shipping_methods as $key => $value) {
if ( $shipping_methods[$key]->min_amount > 0 ) {
$min_amounts[$key] = $shipping_methods[$key]->min_amount;
}
}
if ( is_array($min_amounts) ) {
// Find lowest min_amount
$min_amount = min($min_amounts);
// Get Cart Subtotal inc. Tax excl. Shipping
$current = WC()->cart->subtotal;
// If Subtotal < Min Amount Echo Notice
// and add "Continue Shopping" button
if ( $current < $min_amounts ) {
$added_text = 'Get free shipping if you order ' . wc_price( $min_amount - $current ) . ' more!';
$return_to = wc_get_page_permalink( 'shop' );
$notice = sprintf( '%s %s', esc_url( $return_to ), 'Continue Shopping', $added_text );
wc_print_notice( $notice, 'notice' );
}
else if ( $current = $min_amounts ) {
$added_text = 'Congratulations - Your shipping is now on us and absolutely free :)';
$return_to = wc_get_page_permalink( 'shop' );
//$notice = sprintf( '%s %s', esc_url( $return_to ), 'Continue Shopping', $added_text );
$notice = sprintf( '%s', $added_text );
wc_print_notice( $notice, 'notice' );
}
}
}

Woocommerce show price incl and excl tax in product catalog

I want to show the product price including and exclunding tax under each product in the catalog page of my Woocommerce shop.
Its already working, but it is not showing anything for variable products where I have only one variation. On single products it is also working.
Also I do get the notification:
Notice: WC_Product::get_price_including_tax ist seit Version 3.0 veraltet! Benutze stattdessen wc_get_price_including_tax.
Notice: WC_Product::get_price_excluding_tax ist seit Version 3.0 veraltet! Benutze stattdessen wc_get_price_excluding_tax.
But if I do so, it is not working anymore at all.
add_action( 'woocommerce_after_shop_loop_item_title', 'preise_notice', 10 );
function preise_notice() {
global $product;
if ( $price_html_incl_tax = $product->get_price_including_tax() )
if ( $price_html_excl_tax = $product->get_price_excluding_tax() ) {
echo '<div class="product-prices-excl-vat"><a>ab ' . wc_price($price_html_excl_tax) . ' netto</a></div>';
echo '<div class="product-prices-incl-vat"><a>(' . wc_price($price_html_incl_tax) . ' inkl. 19% MwSt.)</a></div>';
}
}
The wc_get_price_including_tax and wc_get_price_excluding_tax functions expect $product as an argument. So you will have to pass it like this:
wc_get_price_including_tax( $product )
Also it seems like a good idea to get the product's tax rate instead of hard coding it in. Maybe in the future you will have products that do not have a 19% tax rate. I also included the currency argument to the wc_price function so the price will be shown in the shop's currency.
You can use the following snippet that will get the product's tax rate and prints the prices including and excluding tax:
add_action( 'woocommerce_after_shop_loop_item_title', 'add_product_price_incl_and_excl_tax', 10 );
function add_product_price_incl_and_excl_tax() {
global $product;
$tax_rate = '';
$tax_rates = WC_Tax::get_rates( $product->get_tax_class() );
//Check the product tax rate
if ( !empty( $tax_rates ) ) {
$tax_rate = reset($tax_rates);
$tax_rate = sprintf( ' inkl. %.0f%% MwSt.', $tax_rate['rate'] );
}
//Print product prices including tax and tax percentage, and excluding tax
printf( '<div class="product-prices-excl-vat">ab %s netto</div>', wc_price( wc_get_price_excluding_tax( $product ), array( 'currency' => get_woocommerce_currency() ) ) );
printf( '<div class="product-prices-incl-vat">%s%s</div>', wc_price( wc_get_price_including_tax( $product ), array( 'currency' => get_woocommerce_currency() ) ), $tax_rate );
}

WooCommerce: Add input field to every item in cart

I've been trying to add a single text input field to every item in the cart and submit that user input to product's meta info. It's been 2 days and I haven't succeeded yet.
My objective is to:
Take input from user for every item added to the cart.
Display that input in the order's meta info.
Display that input in confirmation email sent to the customer.
So far, I have copied the template file to my theme and added an input field inside a cell. I'm having trouble with the hooks, learned about hooks I will need from WooCommerce Product Gift Wrap plugin as indicated in this woocommerce issue.
Code I added to the cart.php template copied in my theme directory :
$input_url_data = '<div class="input-url"><input type="text" name="cart-url" value="" title="" class="input-text cart-url text" /></div>';
echo apply_filters( 'woocommerce_add_cart_item_data', $input_url_data, $cart_item_key );
Code I added to my theme's functions.php :
add_filter( 'woocommerce_add_cart_item_data','add_cart_item_data', 10, 2 );
add_filter( 'woocommerce_get_cart_item_from_session','get_cart_item_from_session', 10, 2 );
add_filter( 'woocommerce_get_item_data','get_item_data', 10, 2 );
add_filter( 'woocommerce_add_cart_item','add_cart_item', 10, 1 );
add_action( 'woocommerce_add_order_item_meta','add_order_item_meta', 10, 2 );
function add_cart_item_data( $cart_item_meta, $product_id ) {
$input_url_key = "";
$input_url_data['inputurl'] = $input_url_key;
return $input_url_data;
}
function get_cart_item_from_session( $cart_item, $values ) {
if ( ! empty( $values['inputurl'] ) ) {
$cart_item['inputurl'] = true;
}
return $cart_item;
}
function get_item_data( $item_data, $cart_item ) {
if ( ! empty( $cart_item['inputurl'] ) )
$item_data[] = array(
);
return $item_data;
}
function add_cart_item( $cart_item ) {
if ( ! empty( $cart_item['inputurl'] ) ) {
}
return $cart_item;
}
function add_order_item_meta( $item_id, $cart_item ) {
if ( ! empty( $cart_item['inputurl'] ) )
woocommerce_add_order_item_meta( $item_id, __( 'URL by buyer', 'custom_input_url' ), __( 'Yes', 'custom_input_url' ) );
}
Documentation about hook woocommerce_add_cart_item_data isn't very helpful and I'm stuck at this. How do I proceed?
There is a wordpress plugin called WC Fields Factory for the exact purpose.
You can also achieve this by using the following woocommerce hooks woocommerce_before_add_to_cart_button, woocommerce_add_to_cart, woocommerce_cart_item_name,and 'woocommerce_add_order_item_meta'
like for adding text field to product page
function add_name_on_tshirt_field() {
echo '<table class="variations" cellspacing="0">
<tbody>
<tr>
<td class="label"><label for="color">Name On T-Shirt</label></td>
<td class="value">
<input type="text" name="name-on-tshirt" value="" />
</td>
</tr>
</tbody>
</table>';
}
add_action( 'woocommerce_before_add_to_cart_button', 'add_name_on_tshirt_field' );
For displaying custom field on cart item table use the below
function render_meta_on_cart_item( $title = null, $cart_item = null, $cart_item_key = null ) {
if( $cart_item_key && is_cart() ) {
echo $title. '<dl class="">
<dt class="">Name On T-Shirt : </dt>
<dd class=""><p>'. WC()->session->get( $cart_item_key.'_name_on_tshirt') .'</p></dd>
</dl>';
}else {
echo $title;
}
}
add_filter( 'woocommerce_cart_item_name', 'render_meta_on_cart_item', 1, 3 );
to make your custom meta data on you order details, do some thing like this
function tshirt_order_meta_handler( $item_id, $values, $cart_item_key ) {
wc_add_order_item_meta( $item_id, "name_on_tshirt", WC()->session->get( $cart_item_key.'_name_on_tshirt') );
}
add_action( 'woocommerce_add_order_item_meta', 'tshirt_order_meta_handler', 1, 3 );
for detailed implementation, i have an article about how to do this without using any plugins. http://sarkware.com/how-to-pass-custom-data-to-cart-line-item-in-woocommerce-without-using-plugins/
It's easy. Try searching and reading code of Woocommerce.
This much of code got me to point where I can add Url # Cart. And I can see it in Order review as customer and as admin.
I can't test email because I'm lazy. I'm sorry.
Something like this goes in templates\cart\cart.php (there is need for some more code as it's seperate column)
<td class="product-url">
<?php
$html = sprintf( '<div class="url"><input type="text" name="cart[%s][url]" value="%s" size="4" title="Url" class="input-text url text" /></div>', $cart_item_key, esc_attr( $values['url'] ) );
echo $html;
?>
</td>
Functions.php
// get from session your URL variable and add it to item
add_filter('woocommerce_get_cart_item_from_session', 'cart_item_from_session', 99, 3);
function cart_item_from_session( $data, $values, $key ) {
$data['url'] = isset( $values['url'] ) ? $values['url'] : '';
return $data;
}
// this one does the same as woocommerce_update_cart_action() in plugins\woocommerce\woocommerce-functions.php
// but with your URL variable
// this might not be the best way but it works
add_action( 'init', 'update_cart_action', 9);
function update_cart_action() {
global $woocommerce;
if ( ( ! empty( $_POST['update_cart'] ) || ! empty( $_POST['proceed'] ) ) && $woocommerce->verify_nonce('cart')) {
$cart_totals = isset( $_POST['cart'] ) ? $_POST['cart'] : '';
if ( sizeof( $woocommerce->cart->get_cart() ) > 0 ) {
foreach ( $woocommerce->cart->get_cart() as $cart_item_key => $values ) {
if ( isset( $cart_totals[ $cart_item_key ]['url'] ) ) {
$woocommerce->cart->cart_contents[ $cart_item_key ]['url'] = $cart_totals[ $cart_item_key ]['url'];
}
}
}
}
}
// this is in Order summary. It show Url variable under product name. Same place where Variations are shown.
add_filter( 'woocommerce_get_item_data', 'item_data', 10, 2 );
function item_data( $data, $cart_item ) {
if ( isset( $cart_item['url'] ) ) {
$data['url'] = array('name' => 'Url', 'value' => $cart_item['url']);
}
return $data;
}
// this adds Url as meta in Order for item
add_action ('woocommerce_add_order_item_meta', 'add_item_meta', 10, 2);
function add_item_meta( $item_id, $values ) {
woocommerce_add_order_item_meta( $item_id, 'Url', $values['url'] );
}
400$ is nice price.
You can do this fairly easily with the Woocommerce Product Add-ons plugin
From the WooThemes website:
Allow your customers to customise your products by adding new options
such as input boxes, dropdowns or checkboxes. With the Product Add-ons
extension, gift messages, donations, laser engraving and any other
product which may require user input in some way is now an option for
your customers!
Product add-ons supports required fields, textareas, checkboxes,
radios, select boxes, custom price inputs and file upload boxes.
I've used it before to add an additional donation field to a product purchase and display that on the thank you page/receipt email.
It's about $50 US and will get you up and running in no time to add the text input and display the field on thank you page/email like you want. $50 is definitely worth the amount of time you'd save drying to develop this feature yourself.
Here's the flow from the end-users perspective:
End user enters in field data and adds product to cart
When User views cart the data they entered into the custom field displays along with the product
After purchase, end user lands on thank you page and receives receipt email with field data included with the product item.
On the backend:
Create custom field for each product. The option is located on the Add-Ons menu tab.
Create a new Addon Group
Enter a group name (for easier organization)
Add a new option and enter the label (this is what the end user sees and is tied to the product)
Update/Publish product.
For completed orders, this is what you will see in the Order Details admin:
Hope this helps and saves you a ton of time in development!

WooCommerce show custom column

I want to show a additional column in the backend of WooCommerce (in Orders overview).
The column should contain a custom field, which i have defined (delivery date).
How to do this?
In case someone still needs it - instructions on how to add new columns in Woocommerce orders list. No need in unsetting the default columns, just add this in your functions.php and your code will be valid for updates.
1. Define columns position and names
add_filter( 'manage_edit-shop_order_columns', 'MY_COLUMNS_FUNCTION' );
function MY_COLUMNS_FUNCTION($columns){
$new_columns = (is_array($columns)) ? $columns : array();
unset( $new_columns['order_actions'] );
//edit this for you column(s)
//all of your columns will be added before the actions column
$new_columns['MY_COLUMN_ID_1'] = 'MY_COLUMN_1_TITLE';
$new_columns['MY_COLUMN_ID_2'] = 'MY_COLUMN_2_TITLE';
//stop editing
$new_columns['order_actions'] = $columns['order_actions'];
return $new_columns;
}
2. For each custom column, show the values
add_action( 'manage_shop_order_posts_custom_column', 'MY_COLUMNS_VALUES_FUNCTION', 2 );
function MY_COLUMNS_VALUES_FUNCTION($column){
global $post;
$data = get_post_meta( $post->ID );
//start editing, I was saving my fields for the orders as custom post meta
//if you did the same, follow this code
if ( $column == 'MY_COLUMN_ID_1' ) {
echo (isset($data['MY_COLUMN_1_POST_META_ID']) ? $data['MY_COLUMN_1_POST_META_ID'] : '');
}
if ( $column == 'MY_COLUMN_ID_2' ) {
echo (isset($data['MY_COLUMN_2_POST_META_ID']) ? $data['MY_COLUMN_2_POST_META_ID'] : '');
}
//stop editing
}
3. (optional) Function to make the columns sortable
add_filter( "manage_edit-shop_order_sortable_columns", 'MY_COLUMNS_SORT_FUNCTION' );
function MY_COLUMNS_SORT_FUNCTION( $columns ) {
$custom = array(
//start editing
'MY_COLUMN_ID_1' => 'MY_COLUMN_1_POST_META_ID',
'MY_COLUMN_ID_2' => 'MY_COLUMN_2_POST_META_ID'
//stop editing
);
return wp_parse_args( $custom, $columns );
}
To add new column coupon in woo-commerce order table and get all coupon code according to order. you need to copy and paste in you function.php.
add_filter('manage_edit-shop_order_columns', 'custom_shop_order_column', 11);
function custom_shop_order_column($columns) {
//add columns
$columns['my-column1'] = __('Coupons Code', 'theme_slug');
return $columns;
}
// adding the data for each orders by column (example)
add_action('manage_shop_order_posts_custom_column', 'cbsp_credit_details', 10, 2);
function cbsp_credit_details($column) {
global $post, $woocommerce, $the_order;
$order_id = $the_order->id;
switch ($column) {
case 'my-column1' :
// $myVarOne = wc_get_order_item_meta( $order_id, 15, true );
if ($the_order->get_used_coupons()) {
$coupons_count = count($the_order->get_used_coupons());
foreach ($the_order->get_used_coupons() as $coupon) {
echo $coupon;
$i++;
}
echo '</p>';
}
// echo $myVarOne;
break;
}
}
Try this, you will get your solution just write below code on your function.php file.
add_filter( 'manage_edit-shop_order_columns','your_function_name',10 );
function your_function_name($columns){
$columns['delivery_date'] = __('Delivery date','textdomain');
return $columns;
}
add_action( 'manage_shop_order_posts_custom_column','your_other_function_name',20 );
function your_other_function_name($column)
{
swith($column)
{
case 'delivery_date': // your custom code here and do what you want.
}
}
The following works for WooCommerce 2.6.2.
You should look into two new hooks:
woocommerce_admin_order_item_headers, invoked once when orders table header is generated
woocommerce_admin_order_item_values, invoked once per every item inside the order
1. Define columns headers
add_filter('woocommerce_admin_order_item_headers', 'so13683162_headers');
function so13683162_headers($order) {
echo "<th>FIELD1</th>";
}
2. Populate values in rows
add_filter('woocommerce_admin_order_item_values', 'so13683162_values');
function so13683162_values($product) {
if (isset($product -> id)) {
$attrs = get_post_meta($product -> id, "_product_attributes", true);
echo "<td>" . $attrs["FIELD1"]["value"] . "</td>";
}
}
I came across Woocommerce now. Have added a custom field Personal Registration Number - and now wanted it to be displayed in the Order overview page.
I've manage to add the column - but still couldn't get the value of the custom field for each order.
Here is what I did:
// Removed Existing Order Page collumns
remove_filter('manage_edit-shop_order_columns', 'woocommerce_edit_order_columns');
// Added My own filter to Show the PRN - Personal Registration field
add_filter('manage_edit-shop_order_columns', 'omak_edit_order_columns');
// The omak_edit_order_columns definition
/*** Taken from admin/post_types/shop_order.php ***/
function omak_edit_order_columns($columns){
global $woocommerce;
$columns = array();
$columns["cb"] = "<input type=\"checkbox\" />";
$columns["order_status"] = __( 'Status', 'woocommerce' );
$columns["order_title"] = __( 'Order', 'woocommerce' );
$columns["order_prn"] = __( 'PRN', 'woocommerce' ); // This is the line which added the column after the Title Column
$columns["billing_address"] = __( 'Billing', 'woocommerce' );
$columns["shipping_address"] = __( 'Shipping', 'woocommerce' );
$columns["total_cost"] = __( 'Order Total', 'woocommerce' );
$columns["order_comments"] = '<img alt="' . esc_attr__( 'Order Notes', 'woocommerce' ) . '" src="' . $woocommerce->plugin_url() . '/assets/images/order-notes_head.png" class="tips" data-tip="' . __( 'Order Notes', 'woocommerce' ) . '" width="12" height="12" />';
$columns["note"] = '<img src="' . $woocommerce->plugin_url() . '/assets/images/note_head.png" alt="' . __( 'Customer Notes', 'woocommerce' ) . '" class="tips" data-tip="' . __( 'Customer Notes', 'woocommerce' ) . '" width="12" height="12" />';
$columns["order_date"] = __( 'Date', 'woocommerce' );
$columns["order_actions"] = __( 'Actions', 'woocommerce' );
return $columns;
}
Let me know if it helps you...
I am left to deal with how to get its values for each Order.
As commented: the function definition exists in shop_order.php in WooCommerce plugin.
Let me know if anybody sorts it out.. or knows how to do it.
Thanks,
(sorry, was busy in something so couldn't read back to check for errors)

Resources