Use Data Exchange Api to create a product - page_search entries missing

LukasB
LukasB Posts: 13 ✨ - Novice

Hello,

I'm currently trying to import products via the Data Exchange Api. I'm using this list of requests to create the product abstract and the one concrete:

  1. POST /dynamic-entity/product-abstracts
  2. POST /dynamic-entity/products
  3. POST /dynamic-entity/product-abstract-localized-attributes
  4. POST /dynamic-entity/product-localized-attributes
  5. POST /dynamic-entity/product-abstract-stores
  6. POST /dynamic-entity/product-categories
  7. POST /dynamic-entity/availability-abstracts
  8. POST /dynamic-entity/availabilities
  9. POST /dynamic-entity/stock-products
  10. POST /dynamic-entity/product-searches
  11. POST /dynamic-entity/price-products
  12. POST /dynamic-entity/price-product-stores
  13. POST /dynamic-entity/price-product-defaults

When I have a look at the data in the backoffice everything seems to be ok. However the product is not displayed in the storefront because the entries in the tables spy_product_abstract_page_search and spy_product_concrete_page_search are missing.

If I trigger a 'console publish:trigger-events' or save the product in the backoffice again the entires are there.

Has anybody encountered something similiar? Are there any events that are missing when using the Data Exchange Api or does the order of the requests matter?

Answers

  • victor.vanherpt
    victor.vanherpt Spryker Solution Partner Posts: 55 🪐 - Explorer

    Good morning @LukasB!
    Just as a sanity check, did you try console sync:data?

    Also, are queues empty in rabbit? (no exceptions in the search queues?)

    Are the products marked as searchable?

  • LukasB
    LukasB Posts: 13 ✨ - Novice

    Good morning @victor.vanherpt!

    Thanks for your answer. Yes I also tried console sync:data but that doesn't yield any result.

    I also got no entries in any queues/ error queues in RabbitMQ.

    And yes, the concrete product is marked as searchable.

  • victor.vanherpt
    victor.vanherpt Spryker Solution Partner Posts: 55 🪐 - Explorer

    ah, it was worth checking the low hanging fruit :)

    Good luck, I would be interested to see some comment if you find a solution

  • Fred Jung
    Fred Jung Spryker Customer Posts: 24 ✨ - Novice
    edited July 16

    In 5+ horrible years of product import I can say for sure: No trigger no P&S 😂

    You can implement a check on spy_product to see which product was updated and then get concrete/abstract id in order to run trigger-events with -r product-concrete/product-abstract and —ids/i.

    Best one is

    vendor/bin/console publish:trigger-events -r product_configuration,product_abstract_category,url,product_concrete,product_abstract,availability
    

    REALLY, don´t try to work around, it will always have a sideeffect which will get you nuts 🤣

  • LukasB
    LukasB Posts: 13 ✨ - Novice

    Thanks @Fred Jung! I was hoping not to run any publish:trigger-events commands because the events are fired already when the table is filled within the data exchange api request

  • jose.isasa
    jose.isasa Spryker Solution Partner Posts: 1 🧑🏻‍🚀 - Cadet

    Hi @LukasB & @victor.vanherpt 😀

    As discussed we ran into a similar situation when and we found inside the documentation a possible workaround worth sharing here

    In the Data Exchange setup documentation with category management two methods are presented \Pyz\Zed\DynamicEntity\DynamicEntityDependencyProvider::getDynamicEntityPostUpdatePlugins and \Pyz\Zed\DynamicEntity\DynamicEntityDependencyProvider::getDynamicEntityPostCreatePlugins

    https://docs.spryker.com/docs/pbc/all/data-exchange/202404.0/install-and-upgrade/install-the-data-exchange-api-category-management-feature.html#set-up-behavior

    Plugins implementing the DynamicEntityPostCreatePluginInterface that are returned by those arrays are executed after the data is stored in the database.

    This has allowed us to make a working prototype to publish the specific product(s) with the code below:

    <?php
    
    namespace Pyz\Zed\DynamicEntityExtension\Dependency\Plugin;
    
    use Generated\Shared\Transfer\DynamicEntityPostEditRequestTransfer;
    use Generated\Shared\Transfer\DynamicEntityPostEditResponseTransfer;
    use Spryker\Zed\DynamicEntityExtension\Dependency\Plugin\DynamicEntityPostUpdatePluginInterface;
    use Spryker\Zed\Kernel\Communication\AbstractPlugin;
    
    /**
     * @method \Pyz\Zed\DynamicEntityExtension\Communication\DynamicEntityExtensionCommunicationFactory getFactory()
     */
    class ProductPostUpdatePlugin extends AbstractPlugin implements DynamicEntityPostUpdatePluginInterface
    {
        protected const FIELD_ID_PRODUCT = 'id_product';
    
        public function postUpdate(DynamicEntityPostEditRequestTransfer $dynamicEntityPostEditRequestTransfer): DynamicEntityPostEditResponseTransfer
        {
            $productPageSearchFacade = $this->getFactory()->getProductPageSearchFacade();
    
            $products = $dynamicEntityPostEditRequestTransfer->getRawDynamicEntities();
            $productConcreteIds = [];
    
            foreach ($products as $product) {
                $productConcreteIds[] = $product->getFields()[static::FIELD_ID_PRODUCT];
            }
    
            $productPageSearchFacade->publishProductConcretes($productConcreteIds);
    
            return new DynamicEntityPostEditResponseTransfer();
        }
    }
    
    <?php
    
    namespace Pyz\Zed\DynamicEntity;
    
    use Pyz\Zed\DynamicEntityExtension\Dependency\Plugin\ProductPostUpdatePlugin;
    use Spryker\Zed\DynamicEntity\DynamicEntityDependencyProvider as SprykerDynamicEntityDependencyProvider;
    
    class DynamicEntityDependencyProvider extends SprykerDynamicEntityDependencyProvider
    {
        /**
         * @return list<\Spryker\Zed\DynamicEntityExtension\Dependency\Plugin\DynamicEntityPostUpdatePluginInterface>
         */
        protected function getDynamicEntityPostUpdatePlugins(): array
        {
            return [
                new ProductPostUpdatePlugin(),
            ];
        }
    }
    

    I personally haven't been able to find any Spryker OOTB implementation for such a trigger in the product abstract/concrete entities. Only for category management (and if my memory doesn't fail also for stock but cannot seem to find it now) as can be found in the code where the "inspiration" for the code above came from:

    https://github.com/spryker/category-dynamic-entity-connector/blob/master/src/Spryker/Zed/CategoryDynamicEntityConnector/Communication/Plugin/DynamicEntity/CategoryTreeDynamicEntityPostUpdatePlugin.php

    https://github.com/spryker/category-dynamic-entity-connector/blob/master/src/Spryker/Zed/CategoryDynamicEntityConnector/Communication/Plugin/DynamicEntity/CategoryTreeDynamicEntityPostCreatePlugin.php

  • LukasB
    LukasB Posts: 13 ✨ - Novice

    Great @jose.isasa thanks a lot for sharing this 😊