Skip to content

How to track source item status change programatically in magento 2

I have been trying to notify customer when the stock status changed to in stock of the subscribed product from backend (product->edit).

Tried with many events and partially won with the catalog_product_save_after event.
and below is the function I used for it:

public function execute(Observer $observer): void
    {
        try {
            $product = $observer->getEvent()->getProduct();
            if (!$product) {
                return;
            }

            $sku = $product->getSku();
            $productId = (int) $product->getId();

            // Fetch all source items for the product SKU
            $sourceItems = $this->getSourceItemsBySku->execute($sku);
            $inStockSourceCodes = [];

            // Iterate over source items to check stock status
            foreach ($sourceItems as $sourceItem) {
                $sourceCode = $sourceItem->getSourceCode();
                $stockStatus = (int) $sourceItem->getStatus();

                // Add source code to array if In Stock
                if ($stockStatus == 1) {
                    $inStockSourceCodes[] = $sourceCode; 
                }
            }

            // Fetch stock notify records for the product where is_notified = 0
            $stockNotifyCollection = $this->stockNotifyCollectionFactory->create()
                ->addFieldToFilter('product_id', $productId)
                ->addFieldToFilter('is_notified', 0);

            // Check if there are matching records for any in-stock source codes
            foreach ($inStockSourceCodes as $sourceCode) {
                foreach ($stockNotifyCollection as $record) {
                    $storeId = $record->getStoreId();
                    $store = $this->storeManager->getStore($storeId); 
                    $storeCode = $store->getCode(); 


                    if ($storeCode == $sourceCode) {
                        $logger->info("Sending email for {$storeCode}");
                        // Send notification only to the matching source
                        $this->stockNotifyManager->sendProductBackInStockNotification($productId, $sourceCode);
                        break;
                    }
                }
            }
        } catch (Exception $e) {
            $this->logger->error(__('Error in ProductSaveAfter Observer for Notify Me: %1', $e->getMessage()));
        }
    }

this works only for the second time when product update. which means:

first I updated source A to instock -> no email
then I update source B to instock -> received email for source A
on third update -> received email for source B

It seems this event wont work as I needed, is there any other way for it? any plugins?