Export custom meta from Woocommerce to Shipstation - php

I have a problem with exporting products to shipstation, the fields that are generated using the Product Add-on Ultimate plugin are not exported to shipstation
How can I put together the correct function for exporting additional fields??
// Add this code to your theme functions.php file or a custom plugin
add_filter( 'woocommerce_shipstation_export_custom_field_2', 'shipstation_custom_field_2' );
function shipstation_custom_field_2() {
return '\_meta_key'; // Replace this with the key of your custom field
}
// This is for custom field 3
add_filter( 'woocommerce_shipstation_export_custom_field_3', 'shipstation_custom_field_3' );
function shipstation_custom_field_3() {
return '\_meta_key_2'; // Replace this with the key of your custom field
}
I found this solution in plugin documentation but it doesn't work for me
<?php
/**
* Get add-on metadata from each line item in the order
* #param $order_id
* #param $metakey The add-ons metakey (field label), usually prefixed by an underscore
*/
function prefix_get_addons_metadata_by_key( $order_id, $metakey=false ) {
$order = wc_get_order( $order_id );
$order_line_items = $order->get_items();
foreach( $order_line_items as $line_item ) {
// Here, we can iterate through all the meta for this line item
$all_meta = $line_item->get_meta_data();
if( $all_meta ) {
foreach( $all_meta as $meta ) {
$meta_id = $meta->id;
$meta_key = $meta->key;
$meta_value = $meta->value;
}
}
// Here, we can get the value by a specific metakey
if( $metakey ) {
$meta_value = $line_item->get_meta( $metakey );
}
}
}
This is from the plugin side.

Related

Save WooCommerce order total volume as a custom field for Shipstation

I've been coding a WP plugin for Calculating the square inch total volume for an order and send it via custom field to Shipstation:
<?php
global $woocommerce;
$items = $woocommerce->cart->get_cart();
//Debugging function
function console_log( $data ){
echo '<script>';
echo 'console.log('. json_encode( $data ) .')';
echo '</script>';
}
console_log('$items');
//Custoom field for shipstation
add_filter( 'woocommerce_shipstation_export_custom_field_2', 'shipstation_custom_field_2' );
//Function for processing volume
function shipstation_custom_field_2() {
$cart_prods_in3 = array();
foreach($items as $item => $values) {
$_product = wc_get_product( $values['data']->get_id());
//GET GET PRODUCT IN3
$prod_in3 = $_product->get_length() *
$_product->get_width() *
$_product->get_height();
$prod_in3 = $prod_m3 * $values['quantity'];
//PUSH RESULT TO ARRAY
array_push($cart_prods_in3, $prod_in3);
}
return $cart_prods_in3; // Key for your custom field
}
console_log('shipstation_custom_field_2');
?>
I uploaded it via SFTP to the sites files and it shows up on WP but when I click activate I get a fatal error:
Fatal error: Uncaught Error: Call to a member function get_cart() on null in /nas/content/live/sfmstaging/wp-content/plugins/boxCalc/boxCalc.php:10 Stack trace: #0 /nas/content/live/sfmstaging/wp-admin/includes/plugin.php(2299): include() #1 /nas/content/live/sfmstaging/wp-admin/plugins.php(191): plugin_sandbox_scrape('boxCalc/boxCalc...') #2 {main} thrown in /nas/content/live/sfmstaging/wp-content/plugins/boxCalc/boxCalc.php on line 10
Am I pulling the cart data right? Is there an issue with the Woocommerce global?
Note that cart is live customer Object that you can't get as you are actually doing.
Now in ShipStation plugin documentation the woocommerce_shipstation_export_custom_field_2 filter hook is just to return the meta key of an existing order custom field.
That mean that you need to save the cart total volume as custom order meta data when customer place an order.
Try the following instead:
// Custom function to get the volume of a product
function get_product_volume( $product ) {
return $product->get_length() * $product->get_width() * $product->get_height();
}
// Save the cart total volume as custom order meta data
add_action('woocommerce_checkout_create_order', 'save_order_total_volume');
function save_order_total_volume( $order ) {
$total_volume = 0; // Initializing
// Loop through order items
foreach( $order->get_items() as $item ){
$item_volume = get_product_volume($item->get_product()) * $item->get_quantity();
// For product variations (if volume is not accessible get the volume of the parent variabl product)
if( ! $item_volume ) {
$total_volume += get_product_volume( wc_get_product( $item->get_product_id() ) ) * $item->get_quantity();
} else {
$total_volume += $item_volume;
}
}
$order->update_meta_data( '_total_volume', $total_volume ); // Save total volume as custom order meta data
}
// Add total volume custom field meta key for export to ship station
add_filter( 'woocommerce_shipstation_export_custom_field_2', 'shipstation_custom_field_2' );
function shipstation_custom_field_2( $custom_field_key ) {
return '_total_volume';
}
Code goes in functions.php file of the active child theme (or active theme) or in a plugin file. Tested and works.

About Woocommerce product insertion hooks

I added a field to the product display page. I did some research but was not successful.
I have a form element like the one below, it may be text in this picture.
https://prnt.sc/vql93m
I want to save a field as a post meta while creating the product.
Then I want to show the relevant meta on the order page, actually I did it partially, but I can't save the relevant data.
https://prnt.sc/vqlbfs
And I can only add to cart on the single product display page, all other sections should be removed.
https://prnt.sc/vql8mj
Hooks and codes I used.
add_action('woocommerce_before_add_to_cart_button', 'woocommerce_custom_fields_display');
function woocommerce_custom_fields_display()
{
?>
<label>Product type:</label><br><input type="text" id="product-type" name="product-type"><br><br>
<?php
}
add_action( 'woocommerce_before_order_itemmeta', 'so_32457241_before_order_itemmeta', 10, 3 );
function so_32457241_before_order_itemmeta( $item_id, $item, $_product ){
$order = json_decode( $item );
echo get_post_meta( $order['order_id'], 'product-type', true );
}
add_action( 'woocommerce_new_order', 'custom_woocommerce_order' );
function custom_woocommerce_order( $order_id ) {
if ( ! $order_id ) {
return;
}
$order = wc_get_order( $order_id );
var_dump( $order );
var_dump( $_POST );
}
add_action('woocommerce_add_to_cart', 'custome_add_to_cart');
function custome_add_to_cart() {
$p_id=$_POST['product-type'];
WC()->cart->add_to_cart( $p_id );
}

WooCommerce: How to add product type next to product name in admin product list

I have created a new product type "Crush Video Product". It is saving all the meta fields correctly from its custom tab.
// add a product type
add_filter( 'product_type_selector', 'crush_add_custom_product_type' );
function crush_add_custom_product_type( $types ){
$types[ 'crush_video_product' ] = __( 'Group Video Class' );
return $types;
}
// Initiate Class when plugin is loaded
add_action( 'plugins_loaded', 'crush_create_custom_product_type' );
function crush_create_custom_product_type(){
// declare the product class
class WC_Product_Crush_Video_Product extends WC_Product{
public function __construct( $product ) {
$this->product_type = 'crush_video_product';
parent::__construct( $product );
// add additional functions here
}
// Needed since Woocommerce version 3
public function get_type() {
return 'crush_video_product';
}
}
}
I have seen plugins where the name of the product type is written after the name of the product in the admin area where you can see all the products.
I searched a lot, but couldn't find a hook to do this.
https://github.com/woocommerce/woocommerce/blob/4.1.0/includes/admin/list-tables/class-wc-admin-list-table-products.php#L157-L203
Render column: name.
A more suitable hook seems to be missing, so one way is, use manage_product_posts_custom_columnand if desired some CSS for the display
function action_manage_product_posts_custom_column( $column, $postid ) {
if ( $column == 'name' ) {
// Get product
$product = wc_get_product( $postid );
// Get type
$product_type = $product->get_type();
// Output
echo ' <span>– ' . ucfirst( $product_type ) . '</span>';
}
}
add_action( 'manage_product_posts_custom_column', 'action_manage_product_posts_custom_column', 20, 2 );
Result:

Hide For Specific Pages WooCommerce Description & Additional information & Reviews Tabs Using Wordpress Custom Fields

I'm attempting to make a system whereby I can remove the product tabs but only on certain single product pages, and I need to define which pages are to have their product tabs hidden using wordpress custom fields. The custom field name I want to call: 'hide_product_page_tabs' and the defining values need to be either '1' or '0' for yes or no.
I created a new Wordpress custom field on my chosen woocommerce product pages.
Custom field name: hide_product_tabs
Custom field value: Defined a '1' in the custom field to trigger the code, or anything else such as '0' to turn it off.
I placed in my child theme's functions.php :
/* WooCommerce hide product page tabs - hide_product_tabs */
/**
* Remove existing tabs from single product pages.
* https://gist.github.com/mikejolley/c75083db7f6110cbdbe4808e3af36fe3
*/
function remove_woocommerce_product_tabs( $tabs ) {
unset( $tabs['description'] );
unset( $tabs['reviews'] );
unset( $tabs['additional_information'] );
return $tabs;
}
function hide_product_page_tabs() {
global $post;
$product_id = $post->ID;
$HideProductTabsValue = get_post_meta($product_id,'hide_product_tabs',true);
if (strpos($HideProductTabsValue, '1') !== false) {
return add_filter( 'woocommerce_product_tabs', 'remove_woocommerce_product_tabs', 98 );
}
}
add_action('woocommerce_single_product_summary','hide_product_page_tabs');
Any tips are welcome!
Based on your description, without seeing the code you use for this, you can simply use the following
function hide_product_tabs( $tabs ) {
// Get the global product object
global $product;
// Get product id
$product_id = method_exists( $product, 'get_id' ) ? $product->get_id() : $product->id;
$HideProductTabsValue = get_post_meta( $product_id, 'hide_product_tabs', true);
// 1 = true
if( $HideProductTabsValue == true ) {
unset( $tabs['description'] ); // (Description tab)
unset( $tabs['reviews'] ); // (Reviews tab)
unset( $tabs['additional_information'] ); // (Additional information tab)
}
return $tabs;
}
add_filter( 'woocommerce_product_tabs', 'hide_product_tabs', 98 );

WooCommerce Orders: Is it possible to add another column and populate it with custom meta fields from Users?

So short version is that I am trying to add an extra column in the orders page and have it populated with the custom field I have created for the users on the site (The name for the custom field is account_manager)
What I'm trying to achieve is for it display the customers account manager in a column in the orders section. Bit of a strange request I know!
I had a look at a few guides and tutorials regarding columns and meta data but it all seemed to be regarding the orders rather than data from the customer directly.
Any help would be greatly appreciated. I don't mind having a go, I just need a little guidance :)
I've tried this but it's not returning any values
function wc_orders_add_account_manager_column($columns)
{
$new_columns = [];
foreach ( $columns as $column_name => $column_info ) {
$new_columns[ $column_name ] = $column_info;
if ( 'order_status' === $column_name ) { // Change order_status to manage column orders
$new_columns['account_manager'] = 'Account Manager';
}
}
return $new_columns;
}
add_filter( 'manage_edit-shop_order_columns', 'wc_orders_add_account_manager_column', 20 );
/**
* Adds 'account_manager' column content to 'Orders' page
*
* #param string $column name of column being displayed
*/
function wc_orders_add_account_manager_column_content($column)
{
global $post;
$order_id = $post->ID;
// Get an instance of the WC_Order object
$order = wc_get_order($order_id);
// Get the user ID from WC_Order methods
$user_id = $order->get_customer_id(); // or $order->get_customer_id();
$meta = get_user_meta($user_id, 'account_manager', true);
return $meta;
if ( 'account_manager' === $columns ) {
echo $meta ;
} else {
echo "Not Valid!";
}
}
add_action( 'manage_shop_order_posts_custom_column', 'wc_orders_add_account_manager_column_content' );
I'm assuming you have stored this 'account_manager' as an order meta on postmeta table. You need to use manage_edit-shop_order_columns filter hook to add the new column to admin orders page and manage_shop_order_posts_custom_column action hook to populate this column.
/**
* Adds 'account_manager' column header to 'Orders' page immediately after 'Order Status' and before 'Total' column.
*
* #param array $columns
* #return array
*/
function wc_orders_add_account_manager_column($columns)
{
$new_columns = [];
foreach ( $columns as $column_name => $column_info ) {
$new_columns[ $column_name ] = $column_info;
if ( 'order_status' === $column_name ) { // Change order_status to manage column orders
$new_columns['account_manager'] = 'Account Manager';
}
}
return $new_columns;
}
add_filter( 'manage_edit-shop_order_columns', 'wc_orders_add_account_manager_column', 20 );
/**
* Adds 'account_manager' column content to 'Orders' page
*
* #param string $column name of column being displayed
*/
function wc_orders_add_account_manager_column_content($column)
{
global $post;
$order = wc_get_order( $post->ID );
$user_id = $order->get_customer_id(); // or $order->get_customer_id();
$meta = get_user_meta($user_id, 'account_manager', true);
if ( 'account_manager' === $column ) {
echo $meta ? $meta : 'Not Valid!';
}
}
add_action( 'manage_shop_order_posts_custom_column', 'wc_orders_add_account_manager_column_content' );
Tested & It's Working
Note: As I mentioned in the code comments, you can change the order of the columns by changing order_status in this code block:
if ( 'order_status' === $column_name ) {
$new_columns['account_manager'] = 'Account Manager';
}
In this case, our new account_manager column will display after the order_status column

Categories