Niestandardowe obliczanie pola zapasów na podstawie bieżącej wartości zapasów produktu WooCommerce
Staram się usprawnić zarządzanie zapasami i robię to bezpośrednio z WooCommerce (aby nie trzeba było korzystać z obliczeń z zewnętrznego pliku CSV)
Muszę wiedzieć, ile każdego produktu muszę zamówić (brak towaru). Aby to ustalić, obliczam, używając wartości natywnej _stock i 2 pól niestandardowych:
_missing_stock : Ilość brakujących zapasów / ilość potrzebna do zamówienia
_ref_stock : Numer referencyjny zapasu (ustawiany ręcznie, żądana ilość towaru w magazynie)
so: Missing Stock = Zasoby referencyjne - Wartość zapasów
Celem jest automatyczne obliczenie i zaktualizowanie wartości Brakujących zapasów w oparciu o ustalony zapas referencyjny i bieżący stan produktu. Ponieważ zapasy produktów zmniejszają się wraz z zakupami, dzięki temu mogę szybko sprawdzić, ile zapasów każdego produktu należy zamówić.
Na podstawie regularnej kalkulacji ceny produktu na podstawie 2 niestandardowych pól w kodzie odpowiedzi Woocommerce 3, który ma pewne podobieństwa, udało mi się utworzyć niestandardowe pola i doszedłem do tej pory.
Jednak nie jestem w stanie dowiedzieć się, jak ostatecznie automatycznie zaktualizować wartość _missing_stock.
To jest kod, który udało mi się wymyślić, naturalnie (i prawdopodobnie) nie do końca poprawny.
// Adding and displaying additional Stock custom fields
add_action( 'woocommerce_product_options_stock_status', 'additional_product_stock_option_fields', 50 );
function additional_product_stock_option_fields() {
$domain = "woocommerce"; global $post;
echo '</div><div class="options_group stock show_if_simple show_if_external show_if_composite">';
woocommerce_wp_text_input( array(
'id' => '_ref_stock',
'label' => __("Reference Stock", $domain ), 'placeholder' => '', 'description' => __("Amount of desired target stock in warehouse )", $domain ),
'desc_tip' => true,
) );
woocommerce_wp_text_input( array(
'id' => '_missing_stock',
'label' => __("Missing Stock", $domain ) . ' ('. get_woocommerce_currency_symbol() . ')', 'placeholder' => '', 'description' => __("Amount of stock that needs to be ordered", $domain ),
'desc_tip' => true,
) );
echo '<input type="hidden" name="_custom_stock_nonce" value="' . wp_create_nonce() . '">';
}
// Utility function that save "Reference Stock" and "missing_stock" custom fields values
function saving_ref_stock_and_missing_stock( $product ) { // Security check if ( isset($_POST['_custom_stock_nonce']) && ! wp_verify_nonce($_POST['_custom_stock_nonce']) ) { return; } // Save "Reference Stock" and "missing_stock" custom fields values if( isset($_POST['_ref_stock']) && isset($_POST['_missing_stock']) ) { $product->update_meta_data('_ref_stock', sanitize_text_field( (float) $_POST['_ref_stock'] ) ); $product->update_meta_data('_missing_stock', sanitize_text_field( (float) $_POST['_missing_stock'] ) ); } } // Utility function: Calculate and save product "missing stock" custom field from the "Reference Stock" custom field and the "Stock" field function calculate_and_save_new_product_stock( $product ) {
// Check if product stock management is enabled
if ( !$product->managing_stock() ) { // Calculate and save the missing stock if( isset($_POST['_ref_stock']) && isset($_POST['_missing_stock']) && $_POST['_ref_stock'] > 0 && $_POST['_missing_stock'] > 0 ) { // Catch the stock data $ref_stock = (float) $_POST['_ref_stock']; $missing_stock = (float) $_POST['_missing_stock']; $current_stock = (float) $product->get_stock_quantity(); // Calculating missing stock $missing_stock = $ref_stock - $current_stock;
}
}
}
// Saving and calculating Stock values
add_action( 'woocommerce_admin_process_product_object', 'update_product_meta_data', 100, 1 );
function update_product_meta_data( $product ) { // Saving "Reference Stock" and "missing_stock" custom fields values saving_ref_stock_and_missing_stock( $product ); // <== To be removed if not used with the first function
// Calculate and save Missing Stock from the "Reference Stock" and the "Stock" custom fields
calculate_and_save_new_product_missing_stock( $product );
}
Z góry dziękuję za uwagę i radę.
Odpowiedzi
Kod, którego już używasz i dostosowałeś, jest nieco bardziej obszerny niż twoje pytanie, więc poniżej znajduje się uproszczona wersja.
Rzeczywiście możesz użyć, woocommerce_admin_process_product_object
gdy zamierzasz zapisać korektę w zapleczu, aby określić wartość pola niestandardowego.
Jednak po zamówieniu, w którym następuje korekta zapasów, wartość niestandardowego pola nie dostosuje się automatycznie.
W tym celu możesz użyć woocommerce_product_set_stock
haka akcji.
Ten kod jest napisany dla „prostych” produktów, ale w razie potrzeby można go łatwo rozszerzyć na inne typy produktów.
Wyjaśnienie za pomocą tagów komentarzy dodanych za pomocą w kodzie
// Adding and displaying additional custom fields
function action_woocommerce_product_options_stock_status() {
$domain = 'woocommerce'; echo '</div><div class="options_group">'; woocommerce_wp_text_input( array( 'id' => '_ref_stock', 'label' => __( 'Reference Stock', $domain ),
'placeholder' => '',
'description' => __( 'Amount of desired target stock in warehouse', $domain ), 'desc_tip' => true, )); woocommerce_wp_text_input( array( 'id' => '_missing_stock', 'label' => __( 'Missing Stock', $domain ),
'placeholder' => '',
'description' => __( 'Amount of stock that needs to be ordered', $domain ), 'desc_tip' => true, 'custom_attributes' => array( 'readonly' => 'readonly' ), )); } add_action( 'woocommerce_product_options_stock_status', 'action_woocommerce_product_options_stock_status', 10, 1 ); // Save custom field function action_woocommerce_admin_process_product_object( $product ) {
// Isset
if ( isset( $_POST['_ref_stock'] ) ) { // ID & value $ref_stock_id = '_ref_stock';
$ref_stock_val = sanitize_text_field( $_POST['_ref_stock'] );
// Update ref stock
$product->update_meta_data( $ref_stock_id, $ref_stock_val ); // Get stock quantity $current_stock = (float) $product->get_stock_quantity(); // NOT empty if ( ! empty ( $current_stock ) ) {
// ID
$missing_stock_id = '_missing_stock'; // Calculating missing stock $missing_stock_val = $ref_stock_val - $current_stock;
// Update missing stock
$product->update_meta_data( $missing_stock_id, $missing_stock_val ); } } } add_action( 'woocommerce_admin_process_product_object', 'action_woocommerce_admin_process_product_object', 10, 1 ); // When the stock changed function action_woocommerce_product_set_stock ( $product_with_stock ) {
global $pagenow; // Exit if ( is_admin() && $pagenow === 'post.php' )
return;
// Get meta
$ref_stock_val = $product_with_stock->get_meta( '_ref_stock' );
// NOT empty
if ( ! empty ( $ref_stock_val ) ) { // Get stock quantity $current_stock = (float) $product_with_stock->get_stock_quantity(); // NOT empty if ( ! empty ( $current_stock ) ) {
// ID
$missing_stock_id = '_missing_stock'; // Calculating missing stock $missing_stock_val = $ref_stock_val - $current_stock;
// Update missing stock
$product_with_stock->update_meta_data( $missing_stock_id, $missing_stock_val ); // Save $product_with_stock->save();
}
}
}
add_action( 'woocommerce_product_set_stock', 'action_woocommerce_product_set_stock', 10, 1 );