Related
I need to modify the stock levels for inventory per product using a custom field.
These are the code snippets i have tried and modified.
The goal is to manually modify the inventory levels even when they're in stock so orders cannot be placed when stock is low and the add to cart button is removed.
add_action( 'woocommerce_process_product_meta', 'custom_product_inventory_settings' );
function custom_product_inventory_settings( $post_id ) {
// if ( isset( $_POST['_custom'] ) ) :
$product = wc_get_product( $post_id );
$stock_threshold = get_post_meta( $product->get_id(), '_custom', true );
if ( ! empty( $stock_threshold ) ) {
$new_stock_quantity = $product->get_stock_quantity() - $stock_threshold;
update_post_meta( $post_id, '_stock', $new_stock_quantity );
wc_delete_product_transients( $post_id );
}
// endif;
}
// Save custom field
add_action( 'woocommerce_admin_process_product_object', 'action_woocommerce_admin_process_product_object', 10, 1 );
function action_woocommerce_admin_process_product_object( $product ) {
// if ( isset( $_POST['_out_of_stock_threshold'] ) ) {
$product->update_meta_data( 'custom_field', sanitize_text_field( $_POST['custom_field'] ) );
$stock_threshold = get_post_meta( $product->get_id(), 'custom_field', true );
if ( ! empty( $stock_threshold ) ) {
$new_stock_quantity = $product->get_stock_quantity() - $stock_threshold;
// update_post_meta( $post_id, '_stock', $new_stock_quantity );
$product->update_meta_data( 'custom_field', sanitize_text_field( $_POST['custom_field'] ) );
update_post_meta( $post_id, '_stock', $new_stock_quantity );
$post_id = $product->get_id();
wc_delete_product_transients( $post_id );
}
}
Maybe i need to use a different hook like woocommerce_get_availability or something else?
Not sure what your problem is, or what is happening when you run the code, but at first glance you are using a variable before declaring it:
update_post_meta( $post_id, '_stock', $new_stock_quantity );
$post_id = $product->get_id();
Also, is the custom field you are using really supposed to be called custom_field?
I've been racking my brain for a few days on this issue and can't figure out why my code to import is creating duplicate product categories.
Problem: I am pulling in about 30,000 products from the third party API in JSON format it is then is inserted into a custom database, from which I pull each product's data and format for importing into WooCommerce, these processes are working fine the problem comes when I am inserting the category terms. When categories are inserted using wp_insert_term some categories are duplicated but have a different URL slug.
ie...
— Ranges, Cooktops & Ovens
— — Range Hoods & Downdraft Ventilation (slug: range-hoods-downdraft-ventilation )
— — Range Hoods & Downdraft Ventilation (slug: range-hoods-downdraft-ventilation-ranges-cooktops-ovens)
The child category gets duplicated but with a different slug.
This is the Category array I'm looping through to create the hierarchical category paths:
"categoryPath":[{"id":"cat00000","name":"Company Name"},{"id":"abcat0900000","name":"Appliances"},{"id":"abcat0904000","name":"Ranges, Cooktops & Ovens"},{"id":"abcat0904002","name":"Range Hoods & Downdraft Ventilation"}]
Here is my single product import code the relevant category portion in at the bottom starting with $categoryPath, just wanted to give some context of what Im doing:
$result= $wpdb->get_var( "SELECT `results_array`
FROM $table_name
WHERE `arr_serialize2` = $textProductSku
AND `update_type` = 'create'
");
$final_product_formate_arrays = json_decode($result, true);
$post = array(
'post_title' => $final_product_formate_arrays['parent_or_simple_product']['title'],
'post_content' => $final_product_formate_arrays['parent_or_simple_product']['longDescription'],
'post_excerpt' => isset( $final_product_formate_arrays['parent_or_simple_product']['shortDescription']) ? $final_product_formate_arrays['parent_or_simple_product']['shortDescription'] : '' ,
'post_status' => "publish",
'post_parent' => '',
'post_type' => "product",
);
$post_id = wp_insert_post( $post );
if (!$post_id)
{
return false;
}
update_post_meta($post_id,'_complete_product_data',json_encode($final_product_formate_arrays));
update_post_meta($post_id, '_sku', $final_product_formate_arrays['parent_or_simple_product']['sku']);
update_post_meta( $post_id, '_visibility', 'visible' );
if($final_product_formate_arrays['parent_or_simple_product']['inStoreAvailability'] > 0)
{
update_post_meta( $post_id, '_manage_stock', "yes" );
update_post_meta( $post_id, '_stock', $final_product_formate_arrays['parent_or_simple_product']['stockQuantity'] );
update_post_meta( $post_id, '_stock_status', 'instock');
} elseif($final_product_formate_arrays['is_variation']){
update_post_meta( $post_id, '_manage_stock', "no" );
update_post_meta( $post_id, '_stock_status', 'instock');
} else {
update_post_meta( $post_id, '_manage_stock', "yes" );
update_post_meta( $post_id, '_stock_status', 'outofstock');
update_post_meta( $post_id, '_stock', 0 );
}
update_post_meta( $post_id, '_regular_price', $final_product_formate_arrays['parent_or_simple_product']['regularPrice'] );
update_post_meta( $post_id, '_sale_price', $final_product_formate_arrays['parent_or_simple_product']['salePrice'] );
update_post_meta( $post_id, '_price', $final_product_formate_arrays['parent_or_simple_product']['salePrice'] );
update_post_meta( $post_id, '_weight', $final_product_formate_arrays['parent_or_simple_product']['weight'] );
update_post_meta( $post_id, '_length', $final_product_formate_arrays['parent_or_simple_product']['depth'] );
update_post_meta( $post_id, '_width', $final_product_formate_arrays['parent_or_simple_product']['width'] );
update_post_meta( $post_id, '_height', $final_product_formate_arrays['parent_or_simple_product']['height'] );
update_post_meta( $post_id, '_wc_average_rating', $final_product_formate_arrays['parent_or_simple_product']['reviewAverage'] );
**$categoryPath = $final_product_formate_arrays['parent_or_simple_product']['categoryPath'];
if(!empty($categoryPath))
{
$parent_id='';
foreach ($categoryPath as $key => $value) {
if($key!=0) {
$new_str = str_replace( array( ',', '&' ), '-', $value['name'] );
$new_str = sanitize_title( $new_str );
$parent_term = term_exists( $parent_id, 'product_cat' ); // array is returned if taxonomy is given
if( isset( $parent_term )) {
$parent_id = $parent_term['term_id']; // get numeric term id
} else{
$parent_id = 0;
}
$term = wp_insert_term( $value['name'], 'product_cat', [
'description'=> $value['name'],
'parent' => intval( $parent_id ),
'slug' => $new_str,
]
);
if( is_wp_error( $term ) && isset( $term->error_data['term_exists'] ) )
{
$term_id = isset( $term->error_data['term_exists'] ) ? $term->error_data['term_exists'] :'';
$term_error = $term->get_error_message();
$term_error .="\n";
error_log($term_error, 3, $pluginlog);
} else if ( !is_wp_error( $term ) ) {
$new_term_id = isset( $term['term_id']) ? $term['term_id'] : '';
$term_id = $new_term_id;
}
$term_id = intval($term_id);
$parent_id = !empty($term_id)?$term_id:'';
wp_set_post_terms($post_id, $term_id, 'product_cat');**
// wp_set_object_terms($post_id, $term_id, 'product_cat');
} else {
continue;
}
}
}
I see many examples of use of woocomerce library, but no one of them include any libraries.
This is an example:
$post = array(
'post_author' => $user_id,
'post_content' => '',
'post_status' => "publish",
'post_title' => $product->part_num,
'post_parent' => '',
'post_type' => "product",
);
//Create post
$post_id = wp_insert_post( $post, $wp_error );
if($post_id){
$attach_id = get_post_meta($product->parent_id, "_thumbnail_id", true);
add_post_meta($post_id, '_thumbnail_id', $attach_id);
}
wp_set_object_terms( $post_id, 'Races', 'product_cat' );
wp_set_object_terms( $post_id, 'simple', 'product_type');
update_post_meta( $post_id, '_visibility', 'visible' );
update_post_meta( $post_id, '_stock_status', 'instock');
update_post_meta( $post_id, 'total_sales', '0');
update_post_meta( $post_id, '_downloadable', 'yes');
update_post_meta( $post_id, '_virtual', 'yes');
update_post_meta( $post_id, '_regular_price', "1" );
update_post_meta( $post_id, '_sale_price', "1" );
update_post_meta( $post_id, '_purchase_note', "" );
update_post_meta( $post_id, '_featured', "no" );
update_post_meta( $post_id, '_weight', "" );
update_post_meta( $post_id, '_length', "" );
update_post_meta( $post_id, '_width', "" );
update_post_meta( $post_id, '_height', "" );
update_post_meta( $post_id, '_sku', "");
update_post_meta( $post_id, '_product_attributes', array());
update_post_meta( $post_id, '_sale_price_dates_from', "" );
update_post_meta( $post_id, '_sale_price_dates_to', "" );
update_post_meta( $post_id, '_price', "1" );
update_post_meta( $post_id, '_sold_individually', "" );
update_post_meta( $post_id, '_manage_stock', "no" );
update_post_meta( $post_id, '_backorders', "no" );
update_post_meta( $post_id, '_stock', "" );
// file paths will be stored in an array keyed off md5(file path)
$downdloadArray =array('name'=>"Test", 'file' => $uploadDIR['baseurl']."/video/".$video);
$file_path =md5($uploadDIR['baseurl']."/video/".$video);
$_file_paths[ $file_path ] = $downdloadArray;
// grant permission to any newly added files on any existing orders for this product
// do_action( 'woocommerce_process_product_file_download_paths', $post_id, 0, $downdloadArray );
update_post_meta( $post_id, '_downloadable_files', $_file_paths);
update_post_meta( $post_id, '_download_limit', '');
update_post_meta( $post_id, '_download_expiry', '');
update_post_meta( $post_id, '_download_type', '');
update_post_meta( $post_id, '_product_image_gallery', '');
Where they put this code so there is no:
Fatal error: Uncaught Error: Call to undefined function
Is the only way is to include the library in the script?
I think you are trying to make a plugin for woo-commerce. If yes then here is an example of making a simple woo-commerce plugin
You need to check first if woo-commerce plugin is activated or not. To do that in your main plugin file write this code.
if (in_array('woocommerce/woocommerce.php', apply_filters('active_plugins', get_option('active_plugins')))) {
// code for woocommerce goes here
}
Here is the full demo code you should use in your plugin file
<?php
/**
* Plugin Name: Demo URL button for Woocommerce
*/
/**
* Check if WooCommerce is active
**/
if (in_array('woocommerce/woocommerce.php', apply_filters('active_plugins', get_option('active_plugins')))) {
include 'functions.php';
}
You can check a demo plugin for woo-commerce here https://github.com/prappo/woocommerce-add-demo-link-button
I hope it will help you.
I am working on a custom function to create a woocommerce product programmatically when user click a button on the post contact form. The below is the code i am using to create the product, but yet i am stuck to add this product to the cart via code since i can not manage to get the product id within the function code. Need your help to tell me how to get the product id to add it to the cart.
function contactform7_before_send_mail( $tour_to_product ) {
$tour_to_product = WPCF7_Submission::get_instance();
if ( $tour_to_product ) {
$formData = $tour_to_product->get_posted_data();
}
$tourprice =$formData['tour-price'];
$tourdiscountprice =$formData['tour-discount-price'];
$tourname =$formData['tour-name'];
$noadults =$formData['no-adult'];
$nochild =$formData['no-child'];
if(!empty($formData['tour-discount-price']))
{
$finalprice =$formData['tour-discount-price'];
} else {
$finalprice =$formData['tour-price'];
}
$post = array(
'post_author' => $user_id,
'post_content' => '',
'post_status' => "publish",
'post_title' => $tourname,
'post_parent' => '',
'post_type' => "product",
);
//Create post
$post_id = wp_insert_post( $post, $wp_error );
if($post_id){
global $tour_id;
$attach_id = get_post_meta($product->parent_id, "_thumbnail_id", true);
add_post_meta($post_id, '_thumbnail_id', $attach_id);
// i am trying here to get the product id
$tour_id = get_post_meta($product->id());
}
wp_set_object_terms( $post_id, 'Tours', 'product_cat' );
wp_set_object_terms( $post_id, 'simple', 'product_type');
update_post_meta( $post_id, '_visibility', 'visible' );
update_post_meta( $post_id, '_stock_status', 'instock');
update_post_meta( $post_id, 'total_sales', '0');
update_post_meta( $post_id, '_downloadable', 'no');
update_post_meta( $post_id, '_virtual', 'yes');
update_post_meta( $post_id, '_regular_price', $tourprice );
update_post_meta( $post_id, '_sale_price', $tourdiscountprice );
update_post_meta( $post_id, '_purchase_note', "" );
update_post_meta( $post_id, '_featured', "no" );
update_post_meta( $post_id, '_sku', "");
update_post_meta( $post_id, '_product_attributes', array());
update_post_meta( $post_id, '_sale_price_dates_from', "" );
update_post_meta( $post_id, '_sale_price_dates_to', "" );
update_post_meta( $post_id, '_price', $tourprice );
update_post_meta( $post_id, '_sold_individually', "" );
update_post_meta( $post_id, '_manage_stock', "no" );
update_post_meta( $post_id, '_backorders', "no" );
update_post_meta( $post_id, '_stock', "" );
// i am trying to output the product id for testing
echo "<script type='text/javascript'>alert('$tour_id')</script>";
}
remove_all_filters ('wpcf7_before_send_mail');
add_action( 'wpcf7_before_send_mail', 'contactform7_before_send_mail' );
That's right. The code line below contains the id of the last post added.
$post_id = wp_insert_post( $post, $wp_error ); //<== ID
I'm editing a packing slip, which is generated when the order is paid and being packed. The packing slip automatically adds a coupon which will be printed on it as well, if a product of a certain category is included.
My problem is, that every time I refresh or reopen the packing slip, a new coupon is being generated with the same coupon code. So I would like to implement a rule, that checks if the coupon_code already exists.
add_action( 'wpo_wcpdf_after_order_details', 'wpo_wcpdf_custom_text_categories', 10, 2 );
function wpo_wcpdf_custom_text_categories ($template_type, $order) {
// collect categories from order items
$order_cats = array();
$items = $order->get_items();
foreach ($items as $item_id => $item) {
$product = $order->get_product_from_item($item);
if ($product) {
$terms = get_the_terms( $product->id , 'product_cat' );
foreach ($terms as $term) {
$order_cats[$term->term_id] = $term->name;
}
}
}
$target = array('Testtragen', 'Testtragetuch');
//
// check for your category requirement
if(count(array_intersect($order_cats, $target)) > 0 && $template_type == 'packing-slip'){
$coupon_code = $order->get_order_number();
$discount_type = 'fixed_product'; // Type: fixed_cart, percent, fixed_product, percent_product
$order_date = get_post_meta( $order->id, '_wcpdf_order_date', true );
$due_date = date_i18n( get_option( 'date_format' ), strtotime( $invoice_date . ' + 60 days') );
$email = $order->billing_email;
$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' );
*/
}
}
So I would like to add an if statement before the wp_insert_post($coupon), that all this code only gets executed if the coupon with the coupon_code doesn't already exist.
I tried : term_exists( $coupon_code, ‘coupons’)but this didn't work.
Thanks for your help!
Update (added WooCommerce 3 compatibility)
Here it is a solution creating a special meta_key for the $order->id to avoid new coupon generation with the same coupon code, when refreshing or reopening the packing slip.
Here is your changed code (with comment explanations):
add_action( 'wpo_wcpdf_after_order_details', 'wpo_wcpdf_custom_text_categories', 10, 2 );
function wpo_wcpdf_custom_text_categories ($template_type, $order) {
// collect categories from order items
$order_cats = array();
$order_id = method_exists( $order, 'get_id' ) ? $order->get_id() : $order->id;
// Loop through order items
foreach ($order->get_items() as $item_id => $item) {
$product = version_compare( WC_VERSION, '3.0', '<' ) ? $product_id = version_compare( WC_VERSION, '3.0', '<' ) ? $cart_item['data']->id : $cart_item['data']->get_id() : $item->get_product();
$product_id = method_exists( $product, 'get_id' ) ? $item->get_product_id() : $item['product_id'];
if ($product) {
$terms = get_the_terms( $product_id , 'product_cat' );
foreach ($terms as $term) {
$order_cats[$term->term_id] = $term->name;
}
}
}
$target = array('Testtragen', 'Testtragetuch');
//
// check for your category requirement
if(count(array_intersect($order_cats, $target)) > 0 && $template_type == 'packing-slip'){
$coupon_code = $order->get_order_number();
$discount_type = 'fixed_product'; // Type: fixed_cart, percent, fixed_product, percent_product
$order_date = get_post_meta( $order_id, '_wcpdf_order_date', true );
$due_date = date_i18n( get_option( 'date_format' ), strtotime( $invoice_date . ' + 60 days') );
$email = method_exists( $order, 'get_billing_email' ) ? $order->get_billing_email() : $order->billing_email;
$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'
);
// ### We create a meta_key '_wcpdf_coupon' for this order with value 'no'
if( empty( get_post_meta( $order_id, '_wcpdf_coupon', true) ) ) {
add_post_meta( $order_id, '_wcpdf_coupon', 'no', true );
}
// ### if this meta_key for this order has a value = 'no' was update it to 'yes'
if( get_post_meta( $order_id, '_wcpdf_coupon', true) == 'no' ) {
// Now we update it to 'yes'. This avoid the coupon be reused for this order.
update_post_meta( $order_id, '_wcpdf_coupon', 'yes');
$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' );
}
}
}
This should solve this issue…