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?
Related
I am currently working on a site based on the Woocommerce Marketplace ('WCMp') with vendors connected.
The plugin adds both a 'parent order' (for admins) and a sub-order (for the vendor to see).
I have some meta-data added to the order when the customer checks out, which I also want to add to the suborder, but I can't seem to get the "suborder-ID" (it simply just "breaks").
What I am trying is this:
add_action( 'woocommerce_checkout_update_order_meta', 'save_custom_fields_with_order' );
function save_custom_fields_with_order( $order_id ) {
global $woocommerce, $WCMp;
if ( $_POST['d_date'] ) update_post_meta( $order_id, '_d_date', esc_attr( $_POST['delivery_date'] ) );
if ( $_POST['g_message'] ) update_post_meta( $order_id, '_g_message', esc_attr( $_POST['_message'] ) );
if ( $_POST['r_phone'] ) update_post_meta( $order_id, 'r_phone', esc_attr( $_POST['r_phone'] ) );
if ( $_POST['instructions'] ) update_post_meta( $order_id, 'instructions', esc_attr( $_POST['instructions'] ) );
if ( $_POST['address'] ) update_post_meta( $order_id, 'address', esc_attr( $_POST['address'] ) );
if ( $_POST['gift'] ) update_post_meta( $order_id, '_gift', esc_attr( $_POST['gift'] ) );
// -----------------------
// Get data from child order.
$order = wc_get_order( $order_id );
$child_order = new WP_Query(array('post_parent' => $order_id));
while($child_order->have_posts()){
$child_order->the_post();
$child_order_id = get_the_ID();
$vendor_id = get_post_meta($child_order_id, '_vendor_id', true);
// Add vendor ID to the main order.
if ( $vendor_id ) update_post_meta( $order_id, '_vendor_id', $vendor_id );
// -----------------------
// Add data to the child order, so meta data is visible.
if ( $_POST['d_date'] ) update_post_meta( $child_order_id, '_d_date', esc_attr( $_POST['d_date'] ) );
if ( $_POST['g_message'] ) update_post_meta( $child_order_id, '_g_message', esc_attr( $_POST['g_message'] ) );
if ( $_POST['r_phone'] ) update_post_meta( $child_order_id, 'r_phone', esc_attr( $_POST['r_phone'] ) );
if ( $_POST['instructions'] ) update_post_meta( $child_order_id, '_instructions', esc_attr( $_POST['instructions'] ) );
if ( $_POST['address'] ) update_post_meta( $child_order_id, '_address', esc_attr( $_POST['address'] ) );
if ( $_POST['gift'] ) update_post_meta( $child_order_id, '_gift', esc_attr( $_POST['gift'] ) );
}
}
My problem is - the meta data is correctly added to the "parent" order, but not the sub-orders, unfortunately.
I am using Dokan to develop a multi Vendor store for a client, I have added two custom product fields but on will not save values (the product info) Screen shot.
''' add_action( 'dokan_new_product_added','save_add_product_meta', 10, 2 );
add_action( 'dokan_product_updated', 'save_add_product_meta', 10, 2 );
function save_add_product_meta($product_id, $postdata){
if ( ! dokan_is_user_seller( get_current_user_id() ) ) {
return;
}
if ( ! empty( $postdata['new_field'] ) ) {
update_post_meta( $product_id, 'new_field', $postdata['new_field'] );
}
if ( ! empty( $postdata['new_field_1'] ) ) {
update_post_meta( $product_id, 'new_field_1', $postdata['new_field_1'] );
}
}
'''
I've written the following code to take Stripe payment details from a Woocommerce subscription and update the related order with those details.
It's grabbing the details fine but the update_post_meta code doesn't seem to fire and just leaves those fields blank in the post meta, what am I missing? The rest of the code works as intended.
$order_id = wc_get_order( '143025' );
$subscriptions = wcs_get_subscriptions_for_order($order_id, array( 'order_type' => 'any' ));
foreach( $subscriptions as $subscription_id => $subscription_obj ){
$current_subs_id = $subscription_obj->get_id(); // This is current subscription id
$stripe_cus = get_post_meta( $current_subs_id, '_stripe_customer_id' );
$stripe_cus = $stripe_cus[0];
$stripe_src = get_post_meta( $current_subs_id, '_stripe_source_id' );
$stripe_src = $stripe_src[0];
update_post_meta( $order_id, '_stripe_customer_id', $stripe_cus );
update_post_meta( $order_id, '_stripe_source_id', $stripe_src );
}
The two strings look like cus_Hjgys757 and src_1nHyyin75 for $stripe_cus and $stripe_src.
It seems that you make a confuncion between order object and order ID in your code. Also you could try using CRUD methods instead like:
$order_id = 143025;
$order = wc_get_order( $order_id ); // Order Object
$subscriptions = wcs_get_subscriptions_for_order( $order_id, array( 'order_type' => 'any' ) ); // Array of subscriptions Objects
foreach( $subscriptions as $subscription_id => $subscription ){
$stripe_cust_id = $subscription->get_meta( '_stripe_customer_id');
$stripe_src_id = $subscription->get_meta( '_stripe_source_id' );
$order->update_meta_data( '_stripe_customer_id', $stripe_cust_id );
$order->update_meta_data( '_stripe_source_id', $stripe_src_id );
$order->save();
}
Or the old way using WordPress get_post_meta() and update_post_meta() functions:
$order_id = 143025;
$order = wc_get_order( $order_id ); // Order Object
$subscriptions = wcs_get_subscriptions_for_order( $order_id, array( 'order_type' => 'any' ) ); // Array of subscriptions Objects
foreach( $subscriptions as $subscription_id => $subscription ){
$stripe_cust_id = get_post_meta( $subscription_id, '_stripe_customer_id', true );
$stripe_src_id = get_post_meta( $subscription_id, '_stripe_source_id', true );
update_post_meta( $order_id, '_stripe_customer_id', $stripe_cust_id );
update_post_meta( $order_id, '_stripe_source_id', $stripe_src_id );
}
Both should work.
I created this function to generate a new position in the database with metakey: “_price” because when I create a new product from frontend this is empty. The code works only when I update the post, not when I create it for the first time the product.
Can you help me? Thank you !!
function wpufe_update_post_price( $post_id ) {
if ( 'product' != $_POST['post_type'] )
return;
$regular_price = get_post_meta( $post_id, '_regular_price', true );
$sale_price = get_post_meta( $post_id, '_price', true );
update_post_meta( $post_id, '_price', $regular_price );
if ( !empty( $sale_price ) ) {
update_post_meta( $post_id, '_price', $sale_price );
}
}
add_action('save_post_product', 'wpufe_update_post_price', 10, 1);
add_action('wp_insert_post', 'wpufe_update_post_price', 10, 1);
I've a problem with adding a new field in WooCommerce, before short description.
I used script in functions.php and my new custom field is displayed correctly but:
Short description disappear when use script, a new field is display fine.
I can edit the content of a field on a product page, but I can't delete it. It is always the last value.
How can I display this custom field without removing the product short description?
How can I reset this custom field content?
Here is my code:
// Add a custom Field
add_action( 'woocommerce_product_options_general_product_data', 'woo_add_custom_general_fields' );
function woo_add_custom_general_fields() {
global $woocommerce, $post;
woocommerce_wp_text_input(
array(
'id' => '_text_field',
'label' => __( 'Termin dostawy', 'woocommerce' ),
'placeholder' => 'np: 7 dni',
'desc_tip' => 'true',
'description' => __( 'Wpisz przewidywany termin dostawy, np: 7 dni.', 'woocommerce' )
)
);
}
// Save the custom field
add_action( 'woocommerce_process_product_meta', 'woo_add_custom_general_fields_save' );
function woo_add_custom_general_fields_save( $post_id ){
$woocommerce_text_field = $_POST['_text_field'];
if( ! empty( $woocommerce_text_field ) )
update_post_meta( $post_id, '_text_field', esc_attr( $woocommerce_text_field ) );
}
// Display the custom field
add_action('woocommerce_short_description', 'magik_custom_text', 10, 1);
function magik_custom_text()
{
global $product;
global $woocommerce, $post;
echo "Termin dostawy: ".get_post_meta( $post->ID, '_text_field', true );
}
Function responsible for display:
add_action('woocommerce_short_description', 'magik_custom_text', 10, 1);
function magik_custom_text()
{
Update 2:
1) You should add it to short description instead of replacing it…
The correct way is to hook your custom function in woocommerce_single_product_summary cation hook before the short description (using a priority between 11 to 19):
add_action('woocommerce_single_product_summary', 'magik_custom_text', 18);
function magik_custom_text()
{
global $post;
$field_value = get_post_meta( $post->ID, '_text_field', true );
// Displaying the custom field only when is set with a value
if( ! empty( $field_value ) )
echo '<p>' . __('Termin dostawy: ', 'woocommerce') . $field_value . '</p>';
}
Code goes in function.php file of your active child theme (or theme) or also in any plugin file.
Tested and works. So you will get this:
2) To be able to delete the content of your product custom field you need to replace:
if( ! empty( $woocommerce_text_field ) )
by:
if( isset( $woocommerce_text_field ) )
in this hooked function:
add_action( 'woocommerce_process_product_meta', 'woo_add_custom_general_fields_save' );
function woo_add_custom_general_fields_save( $post_id ){
$woocommerce_text_field = $_POST['_text_field'];
if( isset( $woocommerce_text_field ) )
update_post_meta( $post_id, '_text_field', esc_attr( $woocommerce_text_field ) );
}