Cálculo do campo de estoque personalizado com base no valor do estoque atual do produto WooCommerce
Estou fazendo um esforço para melhorar meu gerenciamento de inventário e fazê-lo direto do WooCommerce (para que não seja necessário usar cálculos de arquivo CSV externo)
Preciso saber quanto de cada produto preciso encomendar (Falta de estoque). Para determinar isso, calculo usando _stock valor nativo e 2 campos personalizados:
_missing_stock : Quantidade de estoque ausente / quanto estoque eu preciso pedir
_ref_stock : Número do estoque de referência (definido manualmente, quantidade desejada de estoque no depósito)
portanto: Estoque em falta = Estoque de referência - Valor do estoque
A intenção é calcular e atualizar automaticamente o valor do Estoque em falta com base no estoque de referência que foi definido e o estoque atual do produto. Como o estoque de um produto diminui com as compras, com isso posso rapidamente ver quanto estoque de cada produto precisa ser pedido.
Com base no cálculo do preço normal do produto com base em 2 campos personalizados no código de resposta Woocommerce 3 , que tem algumas semelhanças, consegui criar os campos personalizados e cheguei até agora.
No entanto, não consigo descobrir como finalmente atualizar automaticamente o valor _missing_stock automaticamente.
Este é o código que consegui criar, naturalmente (e provavelmente) não totalmente correto.
// 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 );
}
Agradeço antecipadamente pela atenção e conselhos.
Respostas
O código que você já está usando e adaptou é um pouco mais extenso do que a sua pergunta, portanto, abaixo está uma versão simplificada.
Na verdade, você pode usar woocommerce_admin_process_product_object
quando for salvar o ajuste no backend para determinar o valor do campo personalizado.
No entanto, após um pedido quando ocorre um ajuste do estoque, o valor do seu campo personalizado não será ajustado automaticamente.
Para isso, você pode usar o woocommerce_product_set_stock
gancho de ação.
Este código foi escrito para produtos 'simples', mas pode ser facilmente estendido a outros tipos de produtos, se desejado.
Explicação por meio de tags de comentário adicionadas por meio do código
// 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 );