/**
* Plugin Name: IndieMoto Cart Product Availability
* Description: Adds availability information to cart items based on inventory and selected shipping method.
* Version: 1.4
* Author: Brad Molen
*/
if (!defined('ABSPATH')) {
exit; // Exit if accessed directly
}
class IndieMoto_Cart_Product_Availability {
public function __construct() {
// Hook to add inventory status to cart items
add_filter('woocommerce_get_item_data', [$this, 'add_inventory_status_to_cart_items'], 10, 2);
// Ensure shipping method is updated in the session
add_action('woocommerce_checkout_update_order_review', [$this, 'update_shipping_method_in_session']);
add_action('woocommerce_cart_updated', [$this, 'update_shipping_method_in_session']);
}
/**
* Ensures that the chosen shipping method is updated in the session.
*/
public function update_shipping_method_in_session() {
if (WC()->session && WC()->shipping) {
$packages = WC()->shipping->get_packages();
if (!empty($packages)) {
$chosen_methods = WC()->session->get('chosen_shipping_methods');
if (!$chosen_methods || !is_array($chosen_methods)) {
WC()->session->set('chosen_shipping_methods', array_map(function ($package) {
return key($package['rates']);
}, $packages));
}
}
}
}
/**
* Retrieves the chosen shipping method reliably.
*
* @return string|null The chosen shipping method or null if not found.
*/
private function get_chosen_shipping_method() {
$chosen_methods = WC()->session->get('chosen_shipping_methods');
if (is_array($chosen_methods) && !empty($chosen_methods[0])) {
return $chosen_methods[0];
}
return null;
}
/**
* Adds inventory availability information to cart items.
*
* @param array $item_data Existing cart item data.
* @param array $cart_item Cart item details.
* @return array Modified cart item data.
*/
public function add_inventory_status_to_cart_items($item_data, $cart_item) {
$product_id = $cart_item['product_id'];
$product = wc_get_product($product_id);
// Determine drop-ship eligibility
$is_eligible = get_post_meta($product_id, 'wps_drop_ship_eligible', true);
// Get the chosen shipping method
$chosen_shipping_method = $this->get_chosen_shipping_method();
// Determine inventory status
$woo_inventory = $product->get_stock_quantity();
$sku = $product->get_sku();
$warehouse_inventory_output = do_shortcode('[warehouse_inventory sku="' . esc_attr($sku) . '"]');
// Parse warehouse inventory value using strip_tags and preg_replace
$warehouse_inventory_output = strip_tags($warehouse_inventory_output);
$warehouse_stock = (int) preg_replace('/[^0-9]/', '', $warehouse_inventory_output);
// Add drop-ship eligibility warning
if (!in_array(strtolower($is_eligible), ['1', 'true', 'yes'], true)) {
$item_data[] = [
'name' => __('Shipping Warning', 'woocommerce'),
'value' => '' . __('This item must be picked up in-store.', 'woocommerce') . '',
];
}
// Inventory logic for Pickup
if ($chosen_shipping_method && strpos($chosen_shipping_method, 'pickup') !== false) {
if ($woo_inventory > 0) {
$item_data[] = [
'name' => __('Availability', 'woocommerce'),
'value' => __('Pickup Today', 'woocommerce'),
];
} elseif ($warehouse_stock > 0) {
$item_data[] = [
'name' => __('Availability', 'woocommerce'),
'value' => __('Pickup in 1-3 days', 'woocommerce'),
];
} else {
$item_data[] = [
'name' => __('Availability', 'woocommerce'),
'value' => '' . __('Backordered', 'woocommerce') . '',
];
}
}
// Inventory logic for Shipping
elseif ($chosen_shipping_method && strpos($chosen_shipping_method, 'shipping') !== false) {
if ($woo_inventory > 0 || $warehouse_stock > 0) {
$item_data[] = [
'name' => __('Availability', 'woocommerce'),
'value' => __('Shipping today', 'woocommerce'),
];
} else {
$item_data[] = [
'name' => __('Availability', 'woocommerce'),
'value' => '' . __('Backordered', 'woocommerce') . '',
];
}
}
return $item_data;
}
}
// Instantiate the plugin
new IndieMoto_Cart_Product_Availability();