diff --git a/includes/class-siti-stock-inventory-manager.php b/includes/class-siti-stock-inventory-manager.php index ab624c4..9791ccb 100644 --- a/includes/class-siti-stock-inventory-manager.php +++ b/includes/class-siti-stock-inventory-manager.php @@ -27,6 +27,8 @@ class Siti_Stock_Inventory_Manager { public function register_hooks() { add_action( 'woocommerce_product_options_stock_fields', array( $this, 'render_external_stock_field' ) ); add_action( 'woocommerce_admin_process_product_object', array( $this, 'save_external_stock_value' ) ); + add_action( 'woocommerce_variation_options_inventory', array( $this, 'render_variation_external_stock_field' ), 10, 3 ); + add_action( 'woocommerce_save_product_variation', array( $this, 'save_variation_external_stock_value' ), 10, 2 ); add_filter( 'woocommerce_product_get_stock_quantity', array( $this, 'filter_stock_quantity_with_external' ), 10, 2 ); add_filter( 'woocommerce_product_variation_get_stock_quantity', array( $this, 'filter_stock_quantity_with_external' ), 10, 2 ); add_filter( 'woocommerce_product_get_stock_status', array( $this, 'filter_stock_status_with_external' ), 10, 2 ); @@ -87,6 +89,67 @@ class Siti_Stock_Inventory_Manager { $product->update_meta_data( $this->external_stock_key, $value ); } + /** + * Render the external stock field for each variation row. + * + * @param int $loop Loop index. + * @param array $variation_data Raw variation data. + * @param WP_Post $variation Variation post object. + */ + public function render_variation_external_stock_field( $loop, $variation_data, $variation ) { + unset( $variation_data ); + + if ( ! function_exists( 'woocommerce_wp_text_input' ) ) { + return; + } + + $product = $variation instanceof WC_Product ? $variation : wc_get_product( $variation->ID ); + + if ( ! $product instanceof WC_Product ) { + return; + } + + $external_stock = $this->get_external_stock( $product ); + $field_key = 'variable_' . $this->external_stock_key; + + woocommerce_wp_text_input( + array( + 'id' => $this->external_stock_key . '_' . $loop, + 'name' => $field_key . '[' . $loop . ']', + 'value' => $external_stock, + 'label' => __( 'Externe voorraad', 'siti-stock-plugin' ), + 'desc_tip' => true, + 'description' => __( 'Voorraad beschikbaar op externe locatie(s).', 'siti-stock-plugin' ), + 'type' => 'number', + 'wrapper_class' => 'form-row form-row-full', + 'custom_attributes' => array( + 'step' => '1', + 'min' => '0', + ), + ) + ); + } + + /** + * Persist external stock for variations. + * + * @param int $variation_id Variation post ID. + * @param int $index Loop index. + */ + public function save_variation_external_stock_value( $variation_id, $index ) { + $field_key = 'variable_' . $this->external_stock_key; + + if ( ! isset( $_POST[ $field_key ][ $index ] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing + return; + } + + $raw_value = wp_unslash( $_POST[ $field_key ][ $index ] ); // phpcs:ignore WordPress.Security.NonceVerification.Missing + $value = function_exists( 'wc_stock_amount' ) ? wc_stock_amount( $raw_value ) : (int) $raw_value; + $value = max( 0, (int) $value ); + + update_post_meta( $variation_id, $this->external_stock_key, $value ); + } + /** * Ensure WooCommerce exposes combined stock (local + external) on the frontend. *