Need help with custom shipping method & custom warehouse stock
-
Hi mates – so here’s the issue:
I have the code below – it works well except for when we go to update the order’s status, it decreases the main woocommerce stock. I can’t for the life of me figure out how to block the mechanism from kicking in for the main store stock and only for the warehouse.
? It works fine when we place the order – the main woocommerce stocks are not touched at this stage so far and the warehouse stock for “Sobe” goes down fine.
? Same with when refunding/cancel, the stock levels go up fine and the main WooCommerce stock levels for this product are not touched.<span style=”text-decoration: underline;”>Issue is just when we update the order from say “processing” to anything</span> else but cancelled/refunded.
Can anyone help?
// Custom Sobe Brampton Pickups Shipping Method function custom_sobe_brampton_pickups_shipping_method() { if (!class_exists('WC_Custom_Sobe_Brampton_Pickups_Method')) { class WC_Custom_Sobe_Brampton_Pickups_Method extends WC_Shipping_Method { public function __construct() { $this->id = 'custom_sobe_brampton_pickups'; $this->method_title = __('Sobe Pickup - Brampton', 'woocommerce'); $this->method_description = __('Custom Shipping Method for Sobe Pickup - Brampton', 'woocommerce'); $this->enabled = 'yes'; $this->title = 'Sobe Pickup - Brampton'; $this->init(); } function init() { $this->init_form_fields(); $this->init_settings(); add_action('woocommerce_update_options_shipping_' . $this->id, array($this, 'process_admin_options')); } private function check_stock_availability($package) { global $wpdb; $valid_stock = true; foreach ($package['contents'] as $item) { $product_id = isset($item['variation_id']) && $item['variation_id'] != 0 ? $item['variation_id'] : $item['product_id']; $quantity_in_cart = $item['quantity']; $warehouse_id = '105986'; $stock_field = '_op_qty_warehouse_' . $warehouse_id; $stock_level = $wpdb->get_var($wpdb->prepare( "SELECT meta_value FROM {$wpdb->postmeta} WHERE post_id = %d AND meta_key = %s", $product_id, $stock_field )); if ($quantity_in_cart > intval($stock_level)) { $valid_stock = false; break; } } return $valid_stock; } public function calculate_shipping($package = []) { if (!$this->check_stock_availability($package)) { return; // No stock available } $valid_class = false; foreach (WC()->cart->get_cart() as $cart_item) { if ('partner-pickup-brampton-sobe-treats' === $cart_item['data']->get_shipping_class()) { $valid_class = true; break; } } if ($valid_class) { $rate = array( 'id' => $this->id, 'label' => $this->title, 'cost' => 0, 'calc_tax' => 'per_item' ); $this->add_rate($rate); } } } } } add_action('woocommerce_shipping_init', 'custom_sobe_brampton_pickups_shipping_method'); function add_custom_sobe_brampton_pickups($methods) { $methods['custom_sobe_brampton_pickups'] = 'WC_Custom_Sobe_Brampton_Pickups_Method'; return $methods; } add_filter('woocommerce_shipping_methods', 'add_custom_sobe_brampton_pickups'); // Decrease stock for Sobe warehouse when order is processed add_action('woocommerce_order_status_processing', 'custom_handle_sobe_stock_on_completed', 10, 1); add_action('woocommerce_order_status_completed', 'custom_handle_sobe_stock_on_completed', 10, 1); function custom_handle_sobe_stock_on_completed($order_id) { $order = wc_get_order($order_id); // Check if the order has the custom Sobe shipping method $has_sobe_shipping_method = false; foreach ($order->get_shipping_methods() as $shipping_method) { if ($shipping_method->get_method_id() === 'custom_sobe_brampton_pickups') { $has_sobe_shipping_method = true; break; } } // Decrease Sobe stock levels only if the Sobe shipping method is used if ($has_sobe_shipping_method) { decrease_sobe_stock_levels($order_id); } } function decrease_sobe_stock_levels($order_id) { global $wpdb; $warehouse_id = '105986'; // Your warehouse ID $stock_field = '_op_qty_warehouse_' . $warehouse_id; $order = wc_get_order($order_id); $order_notes = array(); foreach ($order->get_items() as $item) { $product_id = $item->get_product_id(); $variation_id = $item->get_variation_id(); // Get the variation ID if it's a variation if ($variation_id) { // It's a variation, update the variation's stock $current_stock = (int) get_post_meta($variation_id, $stock_field, true); $new_stock = $current_stock - $item->get_quantity(); $new_stock = max($new_stock, 0); update_post_meta($variation_id, $stock_field, $new_stock); // Add note to order $order_notes[] = sprintf(__('Sobe Treats Brampton Stock reduced for "%s": Before - %d, After - %d', 'woocommerce'), get_the_title($variation_id), $current_stock, $new_stock); } else { // It's a simple product, update its stock $current_stock = (int) get_post_meta($product_id, $stock_field, true); $new_stock = $current_stock - $item->get_quantity(); $new_stock = max($new_stock, 0); update_post_meta($product_id, $stock_field, $new_stock); // Add note to order $order_notes[] = sprintf(__('Sobe Treats Brampton Stock reduced for "%s": Before - %d, After - %d', 'woocommerce'), get_the_title($product_id), $current_stock, $new_stock); } } // Add notes to order foreach ($order_notes as $note) { $order->add_order_note($note); } } // Increase stock for Sobe warehouse when order is cancelled or refunded add_action('woocommerce_order_status_cancelled', 'custom_handle_sobe_stock_on_cancel', 10, 1); add_action('woocommerce_order_status_refunded', 'custom_handle_sobe_stock_on_cancel', 10, 1); function custom_handle_sobe_stock_on_cancel($order_id) { increase_sobe_stock_levels($order_id); } function increase_sobe_stock_levels($order_id) { global $wpdb; $warehouse_id = '105986'; // Your warehouse ID $stock_field = '_op_qty_warehouse_' . $warehouse_id; $order = wc_get_order($order_id); $order_notes = array(); foreach ($order->get_items() as $item) { $product_id = $item->get_product_id(); $variation_id = $item->get_variation_id(); // Get the variation ID if it's a variation if ($variation_id) { // It's a variation, update the variation's stock $current_stock = (int) get_post_meta($variation_id, $stock_field, true); $new_stock = $current_stock + $item->get_quantity(); update_post_meta($variation_id, $stock_field, $new_stock); // Add note to order $order_notes[] = sprintf(__('Sobe Treats Brampton Stock increased for "%s": Before - %d, After - %d', 'woocommerce'), get_the_title($variation_id), $current_stock, $new_stock); } else { // It's a simple product, update its stock $current_stock = (int) get_post_meta($product_id, $stock_field, true); $new_stock = $current_stock + $item->get_quantity(); update_post_meta($product_id, $stock_field, $new_stock); // Add note to order $order_notes[] = sprintf(__('Sobe Treats Brampton Stock increased for "%s": Before - %d, After - %d', 'woocommerce'), get_the_title($product_id), $current_stock, $new_stock); } } // Add notes to order foreach ($order_notes as $note) { $order->add_order_note($note); } } // Function to disable automatic stock management for Sobe products function disable_automatic_stock_management_for_sobe_products($product) { if (is_sobe_treats_product($product)) { $product->set_manage_stock(false); } } add_action('woocommerce_product_object', 'disable_automatic_stock_management_for_sobe_products'); function is_sobe_treats_product($product) { $shipping_class = 'partner-pickup-brampton-sobe-treats'; $product_shipping_class_id = $product->get_shipping_class_id(); if ($product_shipping_class_id) { $product_shipping_class = get_term($product_shipping_class_id)->slug; return $product_shipping_class === $shipping_class; } return false; } // Prevent automatic stock reduction for Sobe orders add_filter('woocommerce_can_reduce_order_stock', 'prevent_automatic_stock_reduction_for_sobe_orders', 10, 2); function prevent_automatic_stock_reduction_for_sobe_orders($reduce_stock, $order) { foreach ($order->get_shipping_methods() as $shipping_method) { if ($shipping_method->get_method_id() === 'custom_sobe_brampton_pickups') { return false; } } return $reduce_stock; }
Here’s an explanation of the code:
custom_sobe_brampton_pickups_shipping_method
Function: This function defines a custom shipping method for WooCommerce. It creates a new classWC_Custom_Sobe_Brampton_Pickups_Method
that extends theWC_Shipping_Method
class. This custom shipping method checks stock availability for specific products and adds a shipping rate if the conditions are met.init
Method: Inside theWC_Custom_Sobe_Brampton_Pickups_Method
class, theinit
method is called to initialize the shipping method. It sets up form fields and settings for the method and hooks into the WooCommerce settings update process.check_stock_availability
Method: This private method checks the stock availability of products in a package by querying the database for stock levels. It compares the quantity in the cart with the available stock for each product.calculate_shipping
Method: This method is called when WooCommerce calculates shipping rates. It uses thecheck_stock_availability
method to determine if the products in the cart have sufficient stock. If there’s enough stock and the cart contains a specific shipping class (“partner-pickup-brampton-sobe-treats”), it adds a free shipping rate for the “Sobe Pickup – Brampton” method.- Hooks for Adding and Enabling the Custom Shipping Method: These functions
add_custom_sobe_brampton_pickups
andcustom_sobe_brampton_pickups_shipping_method
add the custom shipping method to WooCommerce and enable it. - Stock Management Hooks: The code includes hooks to decrease stock levels in the warehouse when an order is processed (
custom_handle_sobe_stock_on_completed
) and to increase stock levels when an order is canceled or refunded (custom_handle_sobe_stock_on_cancel
). These hooks are essential for managing inventory accurately. - Disabling Automatic Stock Management for Sobe Products: The function
disable_automatic_stock_management_for_sobe_products
disables the automatic stock management for products with a specific shipping class (“partner-pickup-brampton-sobe-treats”). This allows the code to control stock levels manually. - Preventing Automatic Stock Reduction for Sobe Orders: The
prevent_automatic_stock_reduction_for_sobe_orders
function prevents automatic stock reduction for orders using the “Sobe Pickup – Brampton” shipping method. This ensures that the custom code manages stock levels for Sobe products.
In summary, this code creates a custom shipping method for WooCommerce, checks stock availability for specific products, manages stock levels for a warehouse, and ensures that stock is not automatically reduced for Sobe orders.
- The topic ‘Need help with custom shipping method & custom warehouse stock’ is closed to new replies.