Availability Notification feature integration

Edit on GitHub
You are browsing a previous version of the document. The latest version is 202212.0.

Install feature сore

Prerequisites

Ensure that the related features are installed:

Name Version
Mailing and Notifications 202009.0
Inventory Management 202009.0
Product 202009.0
Spryker Core 202009.0

1) Install the required modules using Composer

Install the required modules:

composer require "spryker-feature/availability-notification":"^202009.0" --update-with-dependencies 
Verification
Make sure that the following modules have been installed:
MODULEEXPECTED DIRECTORY
`AvailabilityNotification``vendor/spryker/availability-notification`

2) Set up database schema and transfer objects

Apply database changes, generate entities and transfer changes:

console transfer:generate
console propel:install
console transfer:generate 
Verification
Make sure that the following changes have been implemented in your database:
DATABASE ENTITYTYPEEVENT
`spy_availability_notification_subscription`TABLECREATED
Verification
Make sure that propel entities have been generated successfully by checking their existence. Also, change the generated entity classes to extend from Spryker core classes.
CLASS PATHEXTENDS
`src/Orm/Zed/AvailabilityNotification/Persistence/SpyAvailabilityNotificationSubscription.php``Spryker\Zed\AvailabilityNotification\Persistence\Propel\AbstractSpyAvailabilityNotificationSubscription`
`src/Orm/Zed/AvailabilityNotification/Persistence/SpyAvailabilityNotificationSubscriptionQuery.php``Spryker\Zed\AvailabilityNotification\Persistence\Propel\AbstractSpyAvailabilityNotificationSubscriptionQuery`
Verification
Make sure that the following changes have been implemented in transfer objects:
TRANSFER TYPEEVENTPATH
`AvailabilityNotificationSubscriptionTransfer`classcreated`src/Generated/Shared/Transfer/AvailabilityNotificationSubscriptionTransfer.php`
`AvailabilityNotificationSubscriptionResponseTransfer`classcreated`src/Generated/Shared/Transfer/AvailabilityNotificationSubscriptionResponseTransfer.php`
`AvailabilityNotificationSubscriptionRequestTransfer`classcreated`src/Generated/Shared/Transfer/AvailabilityNotificationSubscriptionRequestTransfer.php`
`AvailabilityNotificationSubscriptionMailDataTransfer`classcreated`src/Generated/Shared/Transfer/AvailabilityNotificationSubscriptionMailDataTransfer.php`
`AvailabilityNotificationDataTransfer`classcreated`src/Generated/Shared/Transfer/AvailabilityNotificationDataTransfer.php`
`CustomerTransfer.availabilityNotificationSubscriptionSkus`columncreated`src/Generated/Shared/Transfer/CustomerTransfer.php`
`MailTransfer.availabilityNotificationSubscriptionMailData`columncreated`src/Generated/Shared/Transfer/MailTransfer.php`

3) Set up behavior

Listening to the availability_notification event

Add the following plugin to your project:

PLUGIN SPECIFICATION PREREQUISITES NAMESPACE
AvailabilityNotificationSubscriber This plugin is responsible for listening to and processing product availability changes. Spryker\Zed\AvailabilityNotification\Business\Subscription

src/Pyz/Zed/Event/EventDependencyProvider.php

<?php

namespace Pyz\Zed\Event;

use Spryker\Zed\AvailabilityNotification\Communication\Plugin\Event\Subscriber\AvailabilityNotificationSubscriber;

use Spryker\Zed\Event\EventDependencyProvider as SprykerEventDependencyProvider;

class EventDependencyProvider extends SprykerEventDependencyProvider
{
 /**
 * @return \Spryker\Zed\Event\Dependency\EventSubscriberCollectionInterface
 */
 public function getEventSubscriberCollection()
 {
 $eventSubscriberCollection = parent::getEventSubscriberCollection();

 $eventSubscriberCollection->add(new AvailabilityNotificationSubscriber());

 return $eventSubscriberCollection;
 }
} 
Verification
To verify that `AvailabilityNotificationSubscriber` is working:
  1. Add a new product and make it unavailable.
  2. As a customer, subscribe to its availability notifications on Yves.
  3. Make the product available.
  4. Check your mailbox for the email about the product's availability.

Email handling

Add the following plugins to your project:

PLUGIN SPECIFICATION PREREQUISITES NAMESPACE
AvailabilityNotificationSubscriptionMailTypePlugin Handles the email sent after subscribing to product availability notification. Spryker\Zed\AvailabilityNotification\Communication\Plugin\Mail
AvailabilityNotificationUnsubscribedMailTypePlugin Handles the email sent after unsubscribing from product availability notification. Spryker\Zed\AvailabilityNotification\Communication\Plugin\Mail
AvailabilityNotificationMailTypePlugin Handles the email sent after the product’s availability status change. None Spryker\Zed\AvailabilityNotification\Communication\Plugin\Mail
src/Pyz/Zed/Mail/MailDependencyProvider.php
<?php

namespace Pyz\Zed\Mail;
...
use Spryker\Zed\AvailabilityNotification\Communication\Plugin\Mail\AvailabilityNotificationMailTypePlugin;
use Spryker\Zed\AvailabilityNotification\Communication\Plugin\Mail\AvailabilityNotificationSubscriptionMailTypePlugin;
use Spryker\Zed\AvailabilityNotification\Communication\Plugin\Mail\AvailabilityNotificationUnsubscribedMailTypePlugin;
...
use Spryker\Zed\Kernel\Container;
use Spryker\Zed\Mail\Business\Model\Mail\MailTypeCollectionAddInterface;
...
use Spryker\Zed\Mail\MailDependencyProvider as SprykerMailDependencyProvider;
...

class MailDependencyProvider extends SprykerMailDependencyProvider
{
 /**
 * @param \Spryker\Zed\Kernel\Container $container
 *
 * @return \Spryker\Zed\Kernel\Container
 */
 public function provideBusinessLayerDependencies(Container $container)
 {
 $container = parent::provideBusinessLayerDependencies($container);

 $container->extend(static::MAIL_TYPE_COLLECTION, function (MailTypeCollectionAddInterface $mailCollection) {
 $mailCollection
 ...
 ->add(new AvailabilityNotificationUnsubscribedMailTypePlugin())
 ->add(new AvailabilityNotificationSubscriptionMailTypePlugin())
 ->add(new AvailabilityNotificationMailTypePlugin())
 ...
 ;

 return $mailCollection;
 });

 ...

 return $container;
 }
} 
Verification
To verify that `AvailabilityNotificationSubscriptionMailTypePlugin`, `AvailabilityNotificationUnsubscribedMailTypePlugin` and `AvailabilityNotificationMailTypePlugin` are working:
  1. Add a new product.
  2. On YVES, as a customer, subscribe to its availability notifications.
  3. Switch the availability status of the product several times.
  4. Check your mailbox for the emails about the product's status being switched to available and unavailable.

Customer behavior

Add the following plugins to your project:

PLUGIN SPECIFICATION PREREQUISITES NAMESPACE
AvailabilityNotificationAnonymizerPlugin Anonymizes customer data during customer anonymization. Spryker\Zed\AvailabilityNotification\Communication\Plugin\CustomerAnonymizer
AvailabilityNotificationSubscriptionCustomerTransferExpanderPlugin Expands CustomerTransfer with availability notification subscriptions data. Spryker\Zed\AvailabilityNotification\Communication\Plugin\Customer

src/Pyz/Zed/Customer/CustomerDependencyProvider.php

<?php

namespace Pyz\Zed\Customer;

...
use Spryker\Zed\AvailabilityNotification\Communication\Plugin\Customer\AvailabilityNotificationSubscriptionCustomerTransferExpanderPlugin;
use Spryker\Zed\AvailabilityNotification\Communication\Plugin\CustomerAnonymizer\AvailabilityNotificationAnonymizerPlugin;
...
use Spryker\Zed\Customer\CustomerDependencyProvider as SprykerCustomerDependencyProvider;
...

class CustomerDependencyProvider extends SprykerCustomerDependencyProvider
{
 ...

 /**
 * @return \Spryker\Zed\Customer\Dependency\Plugin\CustomerAnonymizerPluginInterface[]
 */
 protected function getCustomerAnonymizerPlugins()
 {
 return [
 ...
 new AvailabilityNotificationAnonymizerPlugin(),
 ];
 }

 /**
 * @return \Spryker\Zed\Customer\Dependency\Plugin\CustomerTransferExpanderPluginInterface[]
 */
 protected function getCustomerTransferExpanderPlugins()
 {
 return [
 ...
 new AvailabilityNotificationSubscriptionCustomerTransferExpanderPlugin(),
 ];
 }
} 
Verification
To verify that `AvailabilityNotificationAnonymizerPlugin` is working:
  1. Add a new product.
  2. On Yves, as a company user, subscribe to its availability notifications.
  3. Check that the corresponding line is added to the `spy_availability_notification_subscription` table.
  4. Delete this user.
  5. Check that the line is deleted from the `spy_availability_notification_subscription` table.
Verification
To verify that `AvailabilityNotificationSubscriptionCustomerTransferExpanderPlugin` is working:
  1. Add a new product.
  2. On Yves, as a company user, subscribe to its availability notifications.
  3. On Yves, go to account overview > *Newsletters*.
  4. Check that you are subscribed to the product's availability notifications.

4) Set up the configuration

You can control whether `AvailabilityNotificationFacade::subscribe()` throws an exception \Spryker\Zed\Product\Business\Exception\MissingProductException (if SKU does not exist in the database) or not. You can do it via the `AvailabilityNotificationConfig::AVAILABILITY_NOTIFICATION_CHECK_PRODUCT_EXISTS` config setting. If set to `false` (by default), then the exception is thrown. If set to `true`, then the exception is not thrown, but `AvailabilityNotificationFacade::subscribe()` returns the instance of `AvailabilityNotificationSubscriptionResponseTransfer::$isSuccess = true`.

src/Pyz/Glue/AvailabilityNotification/AvailabilityNotificationConfig.php

<?php

namespace Pyz\Zed\AvailabilityNotification;

use Spryker\Zed\AvailabilityNotification\AvailabilityNotificationConfig as SprykerAvailabilityNotificationConfig;

class AvailabilityNotificationConfig extends SprykerAvailabilityNotificationConfig
{
    protected const AVAILABILITY_NOTIFICATION_CHECK_PRODUCT_EXISTS = true;
}
“Verification”

We recommend setting AVAILABILITY_NOTIFICATION_CHECK_PRODUCT_EXISTS to true.  Make sure that you are not catching the mentioned above exception somewhere in your Pyz code but use check of $availabilityNotificationSubscriptionResponseTransfer->getIsSuccess().

The config setting exists for BC reasons only.

Install feature frontend

Prerequisites

Ensure that the related features are installed:

NAME VERSION
Mailing & Notifications 202009.0
Inventory Management 202009.0
Product 202009.0
Spryker Core 202009.0

1) Install the required modules using Composer

Install the required modules:

composer require "spryker-feature/availability-notification":"^202009.0" --update-with-dependencies 
Verification
Make sure that the following modules have been installed:
ModuleExpected Directory
`AvailabilityNotificationPage``vendor/spryker-shop/availability-notification-page`
`AvailabilityNotificationPageWidget``vendor/spryker-shop/availability-notification-widget`

2) Add translations

Feature-specific glossary keys:

/data/import/glossary.csv
availability_notification.notify_me,Notify me when back in stock,en_US
availability_notification.notify_me,"Benachrichtigen Sie mich, wenn der Artikel wieder verfügbar ist",de_DE
availability_notification.do_not_notify_me,Do not notify me when back in stock,en_US
availability_notification.do_not_notify_me,"Benachrichtigen Sie mich nicht, wenn der Artikel wieder verfügbar ist",de_DE
availability_notification.subscribed,Successfully subscribed,en_US
availability_notification.subscribed,Erfolgreich abonniert,de_DE
availability_notification.unsubscribed,Successfully unsubscribed,en_US
availability_notification.unsubscribed,Erfolgreich abgemeldet,de_DE
availability_notification.successfully_unsubscribed,"Successfully unsubscribed",en_US
availability_notification.successfully_unsubscribed,"Erfolgreich abbestellt",de_DE
availability_notification.successfully_unsubscribed_text,"You have successfully unsubscribed from being notified when the product is available again",en_US
availability_notification.successfully_unsubscribed_text,"Sie haben erfolgreich eine Benachrichtigung erhalten, wenn das produkt wieder verfügbar ist",de_DE
availability_notification_subscription.mail.subscribed.head,"We just informed our purchase team about your subscription!",en_US
availability_notification_subscription.mail.subscribed.head,"Wir haben unser Einkaufsteam gerade über Ihr Abonnement informiert!",de_DE
availability_notification_subscription.mail.subscribed.body,"You will receive an email when the product will be available again",en_US
availability_notification_subscription.mail.subscribed.body,"Sie erhalten eine E-Mail, sobald das Produkt wieder verfügbar ist",de_DE
availability_notification_subscription.mail.subscribed.subject,"We just informed our purchase team about your subscription!",en_US
availability_notification_subscription.mail.subscribed.subject,"Abonnement für Produktverfügbarkeit",de_DE
availability_notification_subscription.mail.unsubscribed.subject,"You will not be notified when the product %name% will be available again.",en_US
availability_notification_subscription.mail.unsubscribed.subject,"Sie werden nicht benachrichtigt, wenn das Produkt %name% wieder verfügbar ist.",de_DE
availability_notification_subscription.mail.unsubscribed.body,"You will not be notified when the product %name% will be available again.",en_US
availability_notification_subscription.mail.unsubscribed.body,"Sie werden nicht benachrichtigt, wenn das Produkt %name% wieder verfügbar ist.",de_DE
availability_notification_subscription.mail.notification.buy_now,"Buy now",en_US
availability_notification_subscription.mail.notification.buy_now,"Kaufe jetzt",de_DE
availability_notification_subscription.mail.notification.subject,"%name% is available again!",en_US
availability_notification_subscription.mail.notification.subject,"%name% ist wieder verfügbar!",de_DE
availability_notification_subscription.mail.notification.head,"%name% is available again!",en_US
availability_notification_subscription.mail.notification.head,"%name% ist wieder verfügbar",de_DE
availability_notification_subscription.mail.notification.body,"The wait is over, you can not add this product inside your cart.",en_US
availability_notification_subscription.mail.notification.body,"Das Warten hat ein Ende, Sie können dieses Produkt nicht in Ihren Warenkorb legen.",de_DE
availability_notification_subscription.mail.copyright,"<em>Copyright © current year company name, All rights reserved.</em><br><br>",en_US
availability_notification_subscription.mail.copyright,"<em>Copyright © Name des aktuellen Jahres, Alle Rechte vorbehalten.</em><br><br>",de_DE
availability_notification_subscription.mail.unsubscribe,"Want to change how you receive these emails?<br>You can <a target=""_blank"" href=""%link%"" style=""mso-line-height-rule: exactly;-ms-text-size-adjust: 100%;-webkit-text-size-adjust: 100%;color: #656565;font-weight: normal;text-decoration: underline;"">unsubscribe from this list</a>.",en_US
availability_notification_subscription.mail.unsubscribe,"Möchten Sie ändern, wie Sie diese E-Mails erhalten?<br>Sie können <a target=""_blank"" href=""%link%"" style=""mso-line-height-rule: exactly;-ms-text-size-adjust: 100%;-webkit-text-size-adjust: 100%;color: #656565;font-weight: normal;text-decoration: underline;"">aus dieser Liste austragen</a>.",de_DE
availability_notification.email_address,"Email address",en_US
availability_notification.email_address,"E-Mail-Addresse",de_DE 

Import data:

console data:import glossary 
Verification
Make sure that, in the database, the configured data is added to the `spy_glossary` table.

3) Enable controllers

Register the following controller providers in Yves application:

PROVIDER NAMESPACE ENABLE CONTROLLER CONTROLLER SPECIFICATION
AvailabilityNotificationPageControllerProvider SprykerShop\Yves\AvailabilityNotificationPage\Plugin\Provider AvailabilityNotificationPageController Provides the functionality of subscription removal by subscription key.
AvailabilityNotificationWidgetControllerProvider SprykerShop\Yves\AvailabilityNotificationWidget\Plugin\Provider AvailabilityNotificationSubscriptionController Provides subscription management functionality for AvailabilityNotificationWidget.

src/Pyz/Yves/ShopApplication/YvesBootstrap.php

<?php

namespace Pyz\Yves\ShopApplication;

...
use SprykerShop\Yves\AvailabilityNotificationPage\Plugin\Provider\AvailabilityNotificationPageControllerProvider;
use SprykerShop\Yves\AvailabilityNotificationWidget\Plugin\Provider\AvailabilityNotificationWidgetControllerProvider;
...
use SprykerShop\Yves\ShopApplication\YvesBootstrap as SprykerYvesBootstrap;
...

class YvesBootstrap extends SprykerYvesBootstrap
{
 ...

 /**
 * @param bool|null $isSsl
 *
 * @return \SprykerShop\Yves\ShopApplication\Plugin\Provider\AbstractYvesControllerProvider[]
 */
 protected function getControllerProviderStack($isSsl)
 {
 return [
 ...
 new AvailabilityNotificationWidgetControllerProvider($isSsl),
 new AvailabilityNotificationPageControllerProvider($isSsl),
 ...
 ];
 }
}
Verification
Make sure that the following URLs are available on Yves:
  • `http://mysprykershop.com/availability-notification/unsubscribe-by-key/{32 characters key}`
  • `http://mysprykershop.com/en/availability-notification/unsubscribe-by-key/{32 characters key}`
  • `http://mysprykershop.com/de/availability-notification/unsubscribe-by-key/{32 characters key}`

If you have any other languages configured, the corresponding links must be available too.

4) Set up widgets

Register the following plugins to enable widgets:

WIDGET DESCRIPTION NAMESPACE
AvailabilityNotificationSubscriptionWidget Renders the subscription form on the product details page. SprykerShop\Yves\AvailabilityNotificationWidget\Widget

src/Pyz/Yves/ShopApplication/ShopApplicationDependencyProvider.php

<?php

namespace Pyz\Yves\ShopApplication;

use SprykerShop\Yves\AvailabilityNotificationWidget\Widget\AvailabilityNotificationSubscriptionWidget;
use SprykerShop\Yves\ShopApplication\ShopApplicationDependencyProvider as SprykerShopApplicationDependencyProvider;

class ShopApplicationDependencyProvider extends SprykerShopApplicationDependencyProvider
{
 /**
 * @return string[]
 */
 protected function getGlobalWidgets(): array
 {
 return [
 AvailabilityNotificationSubscriptionWidget::class,
 ];
 }
} 

Enable Javascript and CSS changes:

console frontend:yves:build 

In case you have a custom template, put AvailabilityNotificationSubscriptionWidget to your src/Pyz/Yves/ProductDetailPage/Theme/default/components/molecules/product-configurator/product-configurator.twig file:

...
{% set isProductAbstract = data.product.idProductConcrete is empty %}
...

{% if not isAvailable and not isProductAbstract %}
    {% widget 'AvailabilityNotificationSubscriptionWidget' args [data.product] only %}{% endwidget %}
{% endif %}
... 
Verification
Make sure that the availability subscription form is present on the *product details* page. To do this, find a concrete product that is out of stock and visit its product details page.