Niestandardowe obliczanie pola zapasów na podstawie bieżącej wartości zapasów produktu WooCommerce

Nov 29 2020

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

1 7uc1f3r Nov 29 2020 at 22:26

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_objectgdy 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_stockhaka 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 );