2

I have added a scheduled update for a product as shown below

enter image description here

Now I want to delete this schedule programatically. How to achieve that?

I see the product staging class Magento\CatalogStaging\Api\ProductStagingInterface which has a function unschedule($product, $version)

Where I can get the information about the version of a specific product which needs to be passed to this function?

I have used below code as an example to unscedule.

<?php

namespace Vendor\CustomImport\Model;

class Test
{
   
    protected $productStaging;
    protected $productRepository;
 

    public function __construct(
        \Magento\CatalogStaging\Model\ProductStaging $productStaging,
        \Magento\Catalog\Api\ProductRepositoryInterface $productRepository
       
    ) {
        $this->productStaging = $productStaging;
        $this->productRepository = $productRepository;
    }

    public function deleteSchedule()
    {
    try {
        $product = $this->productRepository->get('24-WG089', true);
        $version = 1628165040;
        $this->productStaging->unschedule($product, $version);
    }   catch (\Exception $e){
    echo $e->getMessage();
    }
    }
}

I have taken $version from catalog_product_entity table created_in field. After executing above code, product itself gets removed from catalog and cannot be found in admin. Though I can see records for that product in catalog_product_entity table.

enter image description here

2 Answers 2

1

The interface you mentioned is correct, but there is much more useful information inside the model Magento\CatalogStaging\Model\ProductStaging.

In that model, we see the function unschedule() defined as:

/**
 * @param \Magento\Catalog\Api\Data\ProductInterface $product
 * @param string $version
 * @return bool
 */
public function unschedule(\Magento\Catalog\Api\Data\ProductInterface $product, $version)
{
    return (bool)$this->entityManager->delete(
        $product,
        [
            'store_id' => $this->storeManager->getStore()->getId(),
            'created_in' => $version
        ]
    );
}

After looking at my own instance, I see that all the created_at values in the database are set to 1, I don't personally use the schedule update feature but it would seem that you would add 1 to the version when running schedule().

I would recommend you open the model/controller for the scheduled updates page and see if you can get any more information about how the versioning system works from there next.

Edit: Another file that seems to get closer to the answer you are looking for is Magento\Staging\Model\Entity\Update\Action\Delete\RemoveAction.

In it, it passes $this->versionManager->getVersion()->getId() as the version where versionManager is a Magento\Staging\Model\VersionManager.

2
  • 2
    created_in field is 1 when product is created for the first time. If a schedule is added new entry happens in catalog_product_entity table with different created_in value which is supposed to be version number which can be seen in staging_update table. After running the unschedule function with version number deletes the product itself. Added details in the question.
    – amitshree
    Jul 16, 2021 at 18:25
  • Thanks for the info, I understand it better now
    – joeybab3
    Jul 19, 2021 at 16:52
0

I have figured it out. Below is the method which can be used to delete future scheduled updates.

<?php

namespace Vendor\CustomImport\Model\Import;

use Magento\Framework\App\RequestInterface;
use Magento\Framework\Stdlib\DateTime\DateTime;
use Magento\Staging\Model\Entity\Upcoming\SearchResultFactory;
use Magento\Staging\Api\UpdateRepositoryInterface;
use Magento\Staging\Model\VersionManagerFactory;
use Magento\CatalogStaging\Model\ProductStaging;
use Magento\Catalog\Api\ProductRepositoryInterface;

class Test
{

    protected $request;
    protected $searchResultFactory;
    protected $datetimeFormatter;
    protected $updateRepository;
    protected $versionManager;
    protected $productStaging;
    protected $productRepository;


    public function __construct (
        RequestInterface $request,
        SearchResultFactory $searchResultFactory,
        DateTime  $dateTime,
        UpdateRepositoryInterface $updateRepository,
        VersionManagerFactory $versionManagerFactory,
        ProductStaging $productStaging,
        ProductRepositoryInterface $productRepository

    ) {
        $this->request = $request;
        $this->searchResultFactory = $searchResultFactory;
        $this->dateTime = $dateTime;
        $this->updateRepository = $updateRepository;
        $this->versionManager = $versionManagerFactory->create();
        $this->productStaging = $productStaging;
        $this->productRepository = $productRepository;
    }

    public function getSchedule($productId)
    {
        $schedules = [];
        try {
            $params = [
                'entityRequestName' => 'id',
                'entityTable' => 'catalog_product_entity',
                'entityColumn' => 'entity_id'
            ];
            $this->request->setParams( ['id' => $productId]);
            $schedules = $this->searchResultFactory->create($params);
        }   catch (\Exception $e){
            echo $e->getMessage();
        }
        return  $schedules;
    }

    public function deleteSchedule($productId, $productSku) {
        if ($schedules = $this->getSchedule($productId)) {
            foreach ($schedules as $schedule) {
                try {
                    $scheduleStartTime = $schedule->getStartTime();
                    $currentGmtTime = $this->dateTime->gmtDate(\Magento\Framework\Stdlib\DateTime::DATETIME_PHP_FORMAT);
                    if ($scheduleStartTime <= $currentGmtTime) {
                        continue;
                    }
                    $existingSchedule = $this->updateRepository->get($schedule->getId());
                    $updatedIn = $schedule->getId();
                    $this->versionManager->setCurrentVersionId($updatedIn);
                    $product = $this->productRepository->get($productSku);
                    $this->updateRepository->delete($existingSchedule);
                    $this->productStaging->unschedule($product, $this->versionManager->getVersion()->getId());
                    echo 'deleted';
                } catch (\Exception $e) {
                    $this->getLogger()->info('sku '. $productSku . ' ' . $e->getMessage());
                }
            }
        }
    }
}

Now, you need to pass product id and sku to deleteSchedule() function (example: deleteSchedule(19, 'test')) and it will delete the future schedules of that particular product.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.