I am writing a plugin that connects WooCommerce to the Metrc API and pulls products in if they do not exist or updates products with the information from the API.
// Other Code Above
// Decode the JSON response
$data = json_decode($response_body, true);
// Format the JSON response with indentation
$formatted_data = json_encode($data, JSON_PRETTY_PRINT);
// Log the formatted JSON response to a file in the root of the active plugin folder
$log_file = plugin_dir_path(__FILE__) . 'metrc_response.log'; // Path to the log file
$log_data = date('Y-m-d H:i:s') . " - " . $formatted_data . "\n"; // Log data to write
// Append the log data to the log file
file_put_contents($log_file, $log_data, FILE_APPEND);
// Extract the relevant information from the API response
$packages = $data['Data'];
// Get all published products in WooCommerce
$products = wc_get_products(array('status' => 'publish'));
foreach ($products as $product) {
$product_package = get_post_meta($product->get_id(), '_metrc_package', true);
$matched = false;
foreach ($packages as $package) {
$label = $package['Label'];
if ($product_package === $label) {
$matched = true;
break;
}
}
}
// Import new products based on the API response
foreach ($packages as $package) {
$label = $package['Label'];
$quantity = $package['Quantity'];
$uom = $package['UnitOfMeasureAbbreviation'];
$prodcat = $package['Item']['ProductCategoryName'];
$itemName = $package['Item']['Name'];
// Check if product exists based on package meta value, else create a new product
$product_id = get_product_id_by_meta('_metrc_package', $label);
if (!$product_id) {
$new_product = new WC_Product();
// Set the product properties
$new_product->set_name($package['Item']['Name']);
$new_product->set_status('pending');
$new_product->set_regular_price(0);
// Enable stock management
$new_product->set_manage_stock(true);
$new_product->set_stock_status('instock');
// Save the product
$product_id = $new_product->save();
// Update the package meta value for the new product
update_post_meta($product_id, '_metrc_package', $label);
update_post_meta($product_id, '_metrc_category', $prodcat);
update_post_meta($product_id, '_metrc_item', $itemName);
// Assign the initial default category to the new product
wp_set_object_terms($product_id, $prodcat, 'product_cat', true);
// Set the Product SKU
update_post_meta($product_id, '_sku', $label);
} else {
$new_product = wc_get_product($product_id);
}
// Update _metrc_qty and _metrc_uom with the package quantity and unit of measurement
update_post_meta($product_id, '_metrc_qty', $quantity);
update_post_meta($product_id, '_metrc_uom', $uom);
update_post_meta($product_id, '_metrc_item', $itemName);
Update_post_meta($product_id, '_metrc_category', $prodcat);
// Set Product SKU
update_post_meta($product_id, '_sku', $label);
}
}
There is another function that is handling some basic math to convert weight based products into unit based products, where the formula is:
_qty = _metrc_qty / _package_size
This takes the value in the quantity input box in the Metrc Data tab and divides it against the Package Size value entered in the inventory tab and outputs the result in the Quantity input field in the inventory tab. The Quantity input field in the Metrc Data Tab is populated by the handling of the response from the API by the function get_active() which is used to query the API via a curl request set via action scheduler to run every 15 minutes and gather all the "active" products in the third parties system and each product information such as description, qty etc... where it sends us back that data as a response.
From here a foreach
loop is created which iterates through all the products in the WooCommerce database looking to see if the product already exists and if not creates a new product with a pending status and adds the information. If the product already exists, it updates the relevant product meta information and moves on to the next product.
However, what is occurring that the updated values resulting from the API call on existing products only appear to be visible on the edit product page unless you click the update button when editing a product manually. The all products listing page will display the old information such as in stock (20) rather than the updated value that was set by the API
See Screenshots for example:
Screenshot of product listing page
Edit Product Page on the Inventory Tab
Edit Product Page on my created Metrc Data Tab
Now if I manually update the product the stock quantity in WooCommerce updates to reflect the new value both on the front end and on the product listing page
Can someone point me in the right direction or let me know what i am missing and how I can get the new value to be displayed after each import without having to manually perform zero change updates on each product to make it populate the proper stock amounts.
I assumed this could be being caused by the default stock caching as it was displaying the transient values rather than the most up-to-date values from the import, So I included a function below to disable the stock caching, however this made no difference.
function disable_woocommerce_stock_caching() {
return false;
}
add_filter('woocommerce_stock_html_cache_stock_html_enabled', 'disable_woocommerce_stock_caching');
This did not cause the front end or the product listing page in WooCommerce admin to display the proper values.