Update WC Multi Inventories using WP All Import

Beside our REST API you can also use WP All import to import multiple inventories into your WooCommerce products. We decide between having one inventory stock file or multiple files.

One Inventory Import file

To import one inventory file, you need to use custom fields in WP All Import. Set the name to “woocommerce_multi_inventory_inventories_stock”. Then make sure it is an array and click to specify the key and value element like in the image below.

Note: the key is the ID of the inventory term. 

woocommerce import multi inventories stock in wp all import

Then you have to add the following code into your child theme > functions.php file. This ensures, that inventory terms & taxonomies will get updated correctly during import.

function welaunch_update_inventory_stock( $post_id, $meta_key, $meta_value) {

    if($meta_key == "woocommerce_multi_inventory_inventories_stock") {

        $product = wc_get_product($post_id);
        if(!$product) {
            return false;
        }

        if(!is_array($meta_value)) {
            die('Inventories data must be an array');
        }

        $meta_value = array_filter($meta_value);

        $productId = $product->get_id();
        if($product->get_type() == "variation") {
            $parentProduct = wc_get_product( $product->get_parent_id() );
            if(!$parentProduct) {
                return false;
            }
            $product = $parentProduct;
        }

        $existingTerms = get_the_terms($product->get_id(), 'inventories');
        if(!empty($existingTerms)) {

            $existingTerms = wp_list_pluck($existingTerms, 'term_id');
            $existingTerms = array_combine($existingTerms, $existingTerms);

            foreach($meta_value as $inventory_id => $inventory_stock) {
                if(empty($inventory_stock) && isset($existingTerms[$inventory_id]) ) {
                    unset($existingTerms[$inventory_id]);
                } elseif($inventory_stock > 0 && !isset($existingTerms[$inventory_id]) ) {
                    $existingTerms[$inventory_id] = $inventory_id;
                }
            }

        } else {
            $existingTerms = array_keys($meta_value);
        }


        wp_set_post_terms($productId, $existingTerms, 'inventories');

        $product->save();
    }

}
add_action( 'pmxi_update_post_meta', 'welaunch_update_inventory_stock', 10, 3 );

Importing Multiple Inventory Files

Having multiple imports and inventory files means you need to control the inventory ID manually. See the code below. Make sure you change the following parameters in this script:

  • import id (the ID of the wp all import job)
  • inventoryId (the inventory term ID you find at products > inventories)
  • stockKey (the stock key in your XML / CSV file)
function welaunch_update_inventory_stock( $post_id, $xml_node, $is_update ) {

    // Retrieve the import ID.
    $import_id = (int) wp_all_import_get_import_id(); 

    $inventoryId = 0; 
    $stockKey = '';

    // inventory import ONE
    // import id 359 = inventory 5957
    if ( $import_id == 359 ) {
        $inventoryId = 5957;
        $stockKey = 'stock_amount';
    // inventory import TWO
    // import id 335 = inventory 5956
    } elseif ( $import_id == 335 ) {
        $inventoryId = 5956;
        $stockKey = 'free_stock';
    } 

    if(empty($inventoryId)) {
        return;
    }

    // Convert SimpleXml object to array for easier use.
    $record = json_decode( json_encode( ( array ) $xml_node ), 1 );

    if(!isset($record[$stockKey])) {
        return;
    }

    $stock = (int) $record[$stockKey];

    $product = wc_get_product($post_id);
    if(!$product) {
        return false;
    }

    $existingInventoryStock = $product->get_meta('woocommerce_multi_inventory_inventories_stock');
    if(empty($existingInventoryStock)) {
        $existingInventoryStock = array(
            $inventoryId => $stock
        );
    } else {
        $existingInventoryStock[$inventoryId] = $stock;
    }
    // var_dump($existingInventoryStock);
    // die();

    $newTotalFrontendStock = 0;
    foreach($existingInventoryStock as $inventoryId => $stockAmount) {
        $frontend = get_term_meta($inventoryId, 'woocommerce_multi_inventory_frontend', true);
        if($frontend) {
            $newTotalFrontendStock += (int) $stockAmount;
        }           
    }


    $product->set_stock_quantity($newTotalFrontendStock);
    $product->update_meta_data('woocommerce_multi_inventory_inventories_stock', $existingInventoryStock);
    $product->save();

    // Update Terms
    $productToGetTermsFrom = $product;
    $productId = $product->get_id();
    if($product->get_type() == "variation") {
        $productToGetTermsFrom = wc_get_product( $product->get_parent_id() );
        if(!$productToGetTermsFrom) {
            return false;
        }
    }

    $existingTerms = get_the_terms($productToGetTermsFrom->get_id(), 'inventories');
    if(!empty($existingTerms)) {

        $existingTerms = wp_list_pluck($existingTerms, 'term_id');
        $existingTerms = array_combine($existingTerms, $existingTerms);

        foreach($existingInventoryStock as $inventory_id => $inventory_stock) {
            if(empty($inventory_stock) && isset($existingTerms[$inventory_id]) ) {
                unset($existingTerms[$inventory_id]);
            } elseif($inventory_stock > 0 && !isset($existingTerms[$inventory_id]) ) {
                $existingTerms[$inventory_id] = $inventory_id;
            }
        }

    } else {
        $existingTerms = array_keys($existingInventoryStock);
    }


    wp_set_post_terms($productToGetTermsFrom->get_id(), $existingTerms, 'inventories');

    $product->save();

}
add_action( 'pmxi_saved_post', 'welaunch_update_inventory_stock', 10, 3 );

Wp All import overrides all custom metas by default. To avoid this make sure you select: update all meta except: “woocommerce_multi_inventory_inventories_stock”. See below configuration example.

Leave a Reply

Your email address will not be published. Required fields are marked *