Kolejne ciekawe zagadnienie. Klient chciałby pozbyć się końcówek towaru z magazynu. Rzecz jasna aby tego dokonać daje cenę promocyjną. I tutaj zaczyna się problem. W sklepie można dokonywać zamówień z opóźnioną dostawą przy brakach magazynowych. Jednak już nie w cenie promocyjnej. Czyli potrzebny jest kod, który usunie cenę promocyjną w momencie, gdy stan magazynowy produktu spadnie do zera.
Przyjrzymy się jednocześnie czy zastosowany kod będzie poprawny dla woocommerce z nową wersją magazynu HPOS.
function remove_sale_price_when_out_of_stock( $product_id ) {
$product = wc_get_product( $product_id );
if ( ! $product ) {
return;
}
// Sprawdzenie, czy produkt jest prosty czy wariantowy
if ( $product->is_type( 'simple' ) || $product->is_type( 'variation' ) ) {
if ( $product->get_stock_quantity() === 0 ) {
$product->set_sale_price( '' );
$product->save();
}
} elseif ( $product->is_type( 'variable' ) ) {
// Jeśli produkt jest wariantowy, sprawdzamy każdy jego wariant
foreach ( $product->get_children() as $variation_id ) {
$variation = wc_get_product( $variation_id );
if ( $variation && $variation->get_stock_quantity() === 0 ) {
$variation->set_sale_price( '' );
$variation->save();
}
}
}
}
// Akcja uruchamiająca funkcję po zmianie stanu magazynowego
add_action( 'woocommerce_product_set_stock', 'remove_sale_price_when_out_of_stock' );
add_action( 'woocommerce_product_set_stock_status', 'remove_sale_price_when_out_of_stock' );
Nasz kod działa poprawnie w klasycznej wersji WooCommerce, ale nie będzie działał poprawnie z HPOS (High-Performance Order Storage) w każdej sytuacji. HPOS przenosi dane o produktach i zamówieniach do własnych tabel w bazie danych, co może wpłynąć na sposób odczytu i zapisu informacji o stanie magazynowym.
Co poprawić, aby działało w HPOS?
- HPOS nie używa post meta – Operacje zapisu do bazy w HPOS są zoptymalizowane i wymagają lepszego wykorzystania metod WooCommerce.
- Zdarzenia stockowe w HPOS – Należy użyć nowych hooków związanych ze zmianą stanu magazynowego.
Poprawiona wersja kodu – działa na HPOS i klasycznych tabelach WooCommerce:
function remove_sale_price_when_out_of_stock( $product_id ) {
$product = wc_get_product( $product_id );
if ( ! $product ) {
return;
}
// Pobieramy aktualny stan magazynowy
$stock_quantity = $product->get_stock_quantity();
$stock_status = $product->get_stock_status();
// Jeśli produkt jest wyprzedany, usuwamy cenę promocyjną
if ( $stock_quantity === 0 || $stock_status === 'outofstock' ) {
$product->set_sale_price( '' );
$product->save();
}
// Obsługa wariantów w produktach zmiennych
if ( $product->is_type( 'variable' ) ) {
foreach ( $product->get_children() as $variation_id ) {
$variation = wc_get_product( $variation_id );
if ( $variation ) {
$variation_stock_quantity = $variation->get_stock_quantity();
$variation_stock_status = $variation->get_stock_status();
if ( $variation_stock_quantity === 0 || $variation_stock_status === 'outofstock' ) {
$variation->set_sale_price( '' );
$variation->save();
}
}
}
}
}
// HPOS + klasyczne tabele WooCommerce - obsługa zmian magazynowych
add_action( 'woocommerce_product_set_stock', 'remove_sale_price_when_out_of_stock', 10, 1 );
add_action( 'woocommerce_product_set_stock_status', 'remove_sale_price_when_out_of_stock', 10, 1 );
add_action( 'woocommerce_variation_set_stock', 'remove_sale_price_when_out_of_stock', 10, 1 ); // Dodatkowy hook dla wariantów
add_action( 'woocommerce_variation_set_stock_status', 'remove_sale_price_when_out_of_stock', 10, 1 ); // Dodatkowy hook dla wariantów
Optymalna wersja kodu – tylko dla HPOS
function remove_sale_price_when_out_of_stock_hpos( $product ) {
if ( ! is_a( $product, 'WC_Product' ) ) {
return;
}
// Pobieramy aktualny stan magazynowy
$stock_quantity = $product->get_stock_quantity();
$stock_status = $product->get_stock_status();
// Jeśli produkt jest wyprzedany, usuwamy cenę promocyjną
if ( $stock_quantity === 0 || $stock_status === 'outofstock' ) {
$product->set_sale_price( '' );
$product->save();
}
// Obsługa wariantów w produktach zmiennych
if ( $product->is_type( 'variable' ) ) {
foreach ( $product->get_children() as $variation_id ) {
$variation = wc_get_product( $variation_id );
if ( $variation ) {
$variation_stock_quantity = $variation->get_stock_quantity();
$variation_stock_status = $variation->get_stock_status();
if ( $variation_stock_quantity === 0 || $variation_stock_status === 'outofstock' ) {
$variation->set_sale_price( '' );
$variation->save();
}
}
}
}
}
// Obsługa wyłącznie HPOS – WooCommerce 8.0+
add_action( 'woocommerce_product_object_updated_props', 'remove_sale_price_when_out_of_stock_hpos', 10, 1 );
add_action( 'woocommerce_variation_object_updated_props', 'remove_sale_price_when_out_of_stock_hpos', 10, 1 );
Co zmieniłem dla HPOS?
✅ Usunięcie starych hooków – woocommerce_product_set_stock i woocommerce_product_set_stock_status są powiązane z post meta, a w HPOS przechodzimy na woocommerce_product_object_updated_props.
✅ Optymalizacja dla HPOS – Wykorzystujemy woocommerce_product_object_updated_props, które działa na obiektach WC_Product. Jest to zgodne z nowym sposobem przechowywania zamówień i produktów.
✅ Lżejsza i szybsza implementacja – Skupiamy się tylko na WooCommerce 8.x+ z HPOS, nie obciążając starszych systemów.