Hi Ray,
maybe this fits your request. Maybe not. You'll probably need to ask a developer to adjust it to your setup though.
We use a multisite setup with two sites, so we don't have to use a rest api. Effectively this is called every time stock is changed and then runs the stock changes on the other multisite on shutdown.
``
<?php
namespace Plugin\Classes;
defined( 'ABSPATH' ) || die;
use Atum\Components\AtumQueues;
use AtumLevels\ProductLevels;
use AtumLevels\Inc\Helpers;
use AtumLevels\Models\BOMModel;
class StockSync {
private $products = [];
/**
* The single instance of the class.
* @var StockSync
*
* @since 0.2.1
*/
protected static $_instance = null;
/**
* Main StockSync instance.
*
* Ensures only one instance of StockSync is loaded or can be loaded.
*
* @static
* @return StockSync
*/
public static function instance() {
if ( is_null( self::$_instance ) ) {
self::$_instance = new self();
}
return self::$_instance;
}
/**
* Constructor
*/
private function __construct()
{
add_action( 'woocommerce_product_set_stock', [ $this, 'sync_stock' ], 10 );
add_action( 'woocommerce_variation_set_stock', [ $this, 'sync_stock' ], 10 );
}
/**
* Sync stock between main and wholesale site
*
* For the future: collect all stock changes and go through them at once at shutdown. better performance?
*
* @param WC_Product $product
*/
public function sync_stock( $product )
{
if( ! $product || ! is_multisite() ) return;
$stock = $product->get_stock_quantity();
$sku = $product->get_sku();
if( BOMModel::has_linked_bom($product->get_id()) ) return;
$this->products[$sku] = isset($this->products[$sku]) ? $this->products[$sku] + $stock : $stock;
$callback = [ $this::instance(), 'call_atum_async_actions_on_other_site' ];
if( ! has_action('shutdown', $callback ) ) add_action( 'shutdown', $callback );
}
/**
* BOM trees are recalculated on WP shutdown, so it only run for the current site and not the other one.
* This function enforces the recalculation also on the other site
*/
public function call_atum_async_actions_on_other_site()
{
$blog = is_main_site() ? 2 : 1;
$parents = [];
switch_to_blog( $blog );
foreach( $this->products as $sku => $stock )
{
$_product_id = wc_get_product_id_by_sku( $sku );
$_product = $_product_id ? wc_get_product( $_product_id ) : null;
// we do not care for products with BOM
if( ! $_product || BOMModel::has_linked_bom($_product_id) ) continue;
$_product->set_stock_quantity( $stock );
$_product->save();
wc_delete_product_transients( $_product_id );
// Collect the products that contain this BOM to recalc them later
$_products = Helpers::get_all_bom_parents( $_product_id );
if ( ProductLevels::is_bom_product( $_product ) && ! empty($_products) ) {
$parents = array_unique(array_merge( $parents, $_products ), SORT_REGULAR);
}
}
if( ! empty($parents)) {
AtumQueues::add_async_action( 'recalculate_bom_tree_stock', [ '\AtumLevels\Inc\Helpers', 'bulk_recalculate_bom_tree_stock' ], [ $parents, TRUE ], 1 );
AtumQueues::get_instance()->trigger_async_actions();
}
restore_current_blog();
}
}