WooCommerce: дополнительное место хранения запасов
Опубликовано: 2022-12-07Плагин WooCommerce позволяет вам управлять запасами для каждого продукта, но у вас есть только одно поле количества запасов!
Что делать, если у вас есть два склада и администратору магазина необходимо управлять запасами в каждом из них ? Кроме того, что, если товара нет в наличии в магазине 1, но он есть в наличии в магазине 2, и поэтому покупатель должен иметь возможность его купить?
Этот удивительный обходной путь добавит второй входной номер в настройки продукта, переопределит количество и статус запаса во внешнем интерфейсе, суммируя запас 1 + запас 2, и, наконец, уменьшит запас 1, пока он не станет равным 0, после чего он уменьшит запас 2.
Конечно, это поведение по умолчанию можно изменить, например, можно определить, откуда запас уменьшается (на расстояние?) с помощью дополнительного кода. Кроме того, можно написать дополнительный код, чтобы сделать его совместимым с переменными продуктами или пользовательскими типами продуктов, а также заставить его работать с возвратами. В любом случае, наслаждайтесь!

Фрагмент кода PHP: второе управление местонахождением запасов
/**
* @snippet Second Stock Location @ WooCommerce Edit Product
* @how-to Get CustomizeWoo.com FREE
* @author Rodolfo Melogli
* @compatible WooCommerce 7
* @donate $9 https://businessbloomer.com/bloomer-armada/
*/
add_action( 'woocommerce_product_options_stock', 'bbloomer_additional_stock_location' );
function bbloomer_additional_stock_location() {
global $product_object;
echo '<div class="show_if_simple show_if_variable">';
woocommerce_wp_text_input(
array(
'id' => '_stock2',
'value' => get_post_meta( $product_object->get_id(), '_stock2', true ),
'label' => '2nd Stock Location',
'data_type' => 'stock',
)
);
echo '</div>';
}
add_action( 'save_post_product', 'bbloomer_save_additional_stock' );
function bbloomer_save_additional_stock( $product_id ) {
global $typenow;
if ( 'product' === $typenow ) {
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) return;
if ( isset( $_POST['_stock2'] ) ) {
update_post_meta( $product_id, '_stock2', $_POST['_stock2'] );
}
}
}
add_filter( 'woocommerce_product_get_stock_quantity' , 'bbloomer_get_overall_stock_quantity', 9999, 2 );
function bbloomer_get_overall_stock_quantity( $value, $product ) {
$value = (int) $value + (int) get_post_meta( $product->get_id(), '_stock2', true );
return $value;
}
add_filter( 'woocommerce_product_get_stock_status' , 'bbloomer_get_overall_stock_status', 9999, 2 );
function bbloomer_get_overall_stock_status( $status, $product ) {
if ( ! $product->managing_stock() ) return $status;
$stock = (int) $product->get_stock_quantity() + (int) get_post_meta( $product->get_id(), '_stock2', true );
$status = $stock && ( $stock > 0 ) ? 'instock' : 'outofstock';
return $status;
}
add_filter( 'woocommerce_payment_complete_reduce_order_stock', 'bbloomer_maybe_reduce_second_stock', 9999, 2 );
function bbloomer_maybe_reduce_second_stock( $reduce, $order_id ) {
$order = wc_get_order( $order_id );
$atleastastock2change = false;
foreach ( $order->get_items() as $item ) {
if ( ! $item->is_type( 'line_item' ) ) {
continue;
}
$product = $item->get_product();
$item_stock_reduced = $item->get_meta( '_reduced_stock', true );
if ( $item_stock_reduced || ! $product || ! $product->managing_stock() ) {
continue;
}
$qty = apply_filters( 'woocommerce_order_item_quantity', $item->get_quantity(), $order, $item );
$stock1 = (int) get_post_meta( $product->get_id(), '_stock', true );
if ( $qty <= $stock1 ) continue;
$atleastastock2change = true;
}
if ( ! $atleastastock2change ) return $reduce;
foreach ( $order->get_items() as $item ) {
if ( ! $item->is_type( 'line_item' ) ) {
continue;
}
$product = $item->get_product();
$item_stock_reduced = $item->get_meta( '_reduced_stock', true );
if ( $item_stock_reduced || ! $product || ! $product->managing_stock() ) {
continue;
}
$item_name = $product->get_formatted_name();
$qty = apply_filters( 'woocommerce_order_item_quantity', $item->get_quantity(), $order, $item );
$stock1 = (int) get_post_meta( $product->get_id(), '_stock', true );
$stock2 = (int) get_post_meta( $product->get_id(), '_stock2', true );
if ( $qty <= $stock1 ) {
wc_update_product_stock( $product, $qty, 'decrease' );
$order->add_order_note( sprintf( 'Reduced stock for item "%s"; Stock 1: "%s" to "%s".', $item_name, $stock1, $stock1 - $qty ) );
} else {
$newstock2 = $stock2 - ( $qty - $stock1 );
wc_update_product_stock( $product, $stock1, 'decrease' );
update_post_meta( $product->get_id(), '_stock2', $newstock2 );
$item->add_meta_data( '_reduced_stock', $qty, true );
$item->save();
$order->add_order_note( sprintf( 'Reduced stock for item "%s"; Stock 1: "%s" to "0" and Stock 2: "%s" to "%s".', $item_name, $stock1, $stock2, $newstock2 ) );
}
}
$order->get_data_store()->set_stock_reduced( $order_id, true );
return false;
}
На простом английском:

- bbloomer_additional_stock_location показывает второе поле количества запасов
- bbloomer_save_additional_stock сохраняет количество пользовательских запасов
- bbloomer_get_overall_stock_quantity устанавливает запас товара на запас 1 + запас 2
- bbloomer_get_overall_stock_status устанавливает статус запаса товара на основе запаса 1 + запаса 2.
- bbloomer_maybe_reduce_second_stock уменьшает запас со склада 1, а затем со склада 2, если заказанное количество больше запаса 1, в противном случае он позволяет WooCommerce уменьшить запас по умолчанию.