Here's the solution prototype we came up with. Did we take in account all subtleties and complexities / corner cases of the way WooCommerce / ATUM Multi-Inventories work to active this goal?
add_filter('atum/multi_inventory/order_item_inventories', 'atum_mi_order_item_inventories', 10, 2);
add_filter('atum/multi_inventory/quantity_input_args', 'atum_multi_inventory_quantity_input_args', 10, 2);
add_filter('woocommerce_store_api_product_quantity_limit', 'atum_woocommerce_store_api_product_quantity_limit', 10, 2);
/**
* @param \AtumMultiInventory\Models\Inventory[] $sorted_inventories
* @param \WC_Order_Item_Product $item
*/
public function atum_mi_order_item_inventories($sorted_inventories, $item)
{
$item_quantity = $item->get_quantity();
$filtered_inventories = filter_min_stock_level_inventories($sorted_inventories, $item_quantity);
return $filtered_inventories;
}
/**
* @param array $args
* @param \WC_Product $product
*/
public function atum_multi_inventory_quantity_input_args($args, $product)
{
//https://stackoverflow.com/questions/43652755/set-input-field-min-and-max-for-variable-product-in-woocommerce
$max_stock_level = get_product_max_stock_quantity($product, true, 50);
$args['max_value'] = $max_stock_level;
return $args;
}
/**
* @param int $quantity_limit
* @param \WC_Product $product
*/
public function atum_woocommerce_store_api_product_quantity_limit($quantity_limit, $product)
{
$max_stock_level = get_product_max_stock_quantity($product, true, 50);
return $max_stock_level;
}
/**
* @param \AtumMultiInventory\Models\Inventory[] $sorted_inventories
* @param int $min_stock_level
*/
public function filter_min_stock_level_inventories($sorted_inventories, $min_stock_level)
{
if (empty($sorted_inventories))
return $sorted_inventories;
$filtered_inventories = array();
foreach ($sorted_inventories as $inventory) {
if (!$inventory->exists())
continue;
$inventory_stock = $inventory->get_available_stock();
if ($inventory_stock >= $min_stock_level)
$filtered_inventories[] = $inventory;
}
return $filtered_inventories;
}
/**
* @param \WC_Product $product
* @param bool $single_inventory
* @param int $max_lineitem_quantity
*/
public function get_product_max_stock_quantity($product, $single_inventory = false, $max_lineitem_quantity = -1)
{
$max_stock_quantity = $single_inventory && is_product_multi_inventory($product)
? get_product_max_inventory_stock_level($product->get_id())
: $product->get_max_purchase_quantity();
if ($max_lineitem_quantity > 0)
return min($max_stock_quantity, $max_lineitem_quantity);
return $max_stock_quantity;
}
/**
* @param int|\WC_Product $product
*/
public function is_product_multi_inventory($product)
{
//AtumMultiInventory\Inc\Hooks::quantity_input_args
$product_mi_enabled = 'yes' === \AtumMultiInventory\Inc\Helpers::get_product_multi_inventory_status($product);
$product_mi_compatible = \AtumMultiInventory\Inc\Helpers::is_product_multi_inventory_compatible($product);
return $product_mi_enabled && $product_mi_compatible;
}
/**
* @param int $product_id
*/
public function get_product_max_inventory_stock_level($product_id)
{
$sorted_inventories = \AtumMultiInventory\Inc\Helpers::get_product_inventories_sorted($product_id);
$max_stock_level = get_max_inventory_stock_level($sorted_inventories);
return $max_stock_level;
}
/**
* @param \AtumMultiInventory\Models\Inventory[] $inventories
*/
public function get_max_inventory_stock_level($inventories)
{
if (empty($inventories))
return 0;
$max_stock_level = 0;
foreach ($inventories as $inventory) {
if (!$inventory->exists())
continue;
$inventory_stock = $inventory->get_available_stock();
if ($inventory_stock > $max_stock_level)
$max_stock_level = $inventory_stock;
}
return $max_stock_level;
}