Product is Available Again feature integration

Edit on GitHub

Install Feature Core

Prerequisites

Ensure that the related features are installed:

Name Version
Mailing & Notifications 201903.0
Inventory Management 201903.0
Product 201903.0
Spryker Core 201903.0

1) Install the required modules using Composer

Run the following command to install the required modules:

composer require "spryker-feature/availability-notification":"^201903.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

Run the following commands to 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 the availability_notification Event

Add the following plugin in your project:

Plugin Specification Prerequisites Namespace
AvailabilityNotificationSubscriber This plugins is responsible for listening and processing product availability changes. None 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. on Yves, as a customer, subscribe to its availability notifications;
  3. make the product available;
  4. check your mailbox for the email about the product's availability.

Email Handling

Add the following plugins in your project:

Plugin Specification Prerequisites Namespace
AvailabilityNotificationSubscriptionMailTypePlugin Handles the email sent after subscribing to product availability notification. None Spryker\Zed\AvailabilityNotification\Communication\Plugin\Mail
AvailabilityNotificationUnsubscribedMailTypePlugin Handles the email sent after unsubscribing from product availability notification. None Spryker\Zed\AvailabilityNotification\Communication\Plugin\Mail
AvailabilityNotificationMailTypePlugin Handles the email sent after 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 in your project:

Plugin Specification Prerequisites Namespace
AvailabilityNotificationAnonymizerPlugin Anonymizes customer data during customer anonymization. None Spryker\Zed\AvailabilityNotification\Communication\Plugin\CustomerAnonymizer
AvailabilityNotificationSubscriptionCustomerTransferExpanderPlugin Expands CustomerTransfer with availability notification subscriptions data. None 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 `spy_availability_notification_subscription` table;
  4. delete this user;
  5. check that the line is deleted from `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* page;
  4. check that you are subscribed to the product's availability notifications.

Install feature frontend

Prerequisites

Ensure that the related features are installed:

Name Version
Mailing & Notifications 201903.0
Inventory Management 201903.0
Product 201903.0
Spryker Core 201903.0

1) Install the required modules using Composer

Run the following command to install the required modules:

composer require "spryker-feature/availability-notification":"^201903.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 

Run the following console command to 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 Enabled 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 in 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,
 ];
 }
} 

Run the following command to 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 in the *product details* page. To do this, find a concrete product that is out of stock and visit its product details page.