Merchant Opening Hours feature integration

Edit on GitHub

This document describes how to integrate the Merchant Opening Hours feature into a Spryker project.

Install feature core

Follow the steps below to install the Merchant Opening Hours feature core.

Prerequisites

To start feature integration, integrate the required features:

NAME VERSION INTEGRATION GUIDE
Spryker Core 202108.0 Spryker Core feature integration
Marketplace Merchant 202108.0 Marketplace Merchant feature integration

1) Install the required modules using Composer

Install the required modules:

composer require spryker-feature/merchant-opening-hours
Verification

Make sure that the following modules were installed: ModuleExpected DirectoryMerchantOpeningHoursspryker/merchant-opening-hoursMerchantOpeningHoursDataImportspryker/merchant-opening-hours-data-importMerchantOpeningHoursStoragespryker/merchant-opening-hours-storageWeekdaySchedulespryker/weekday-schedule

2) Set up database schema

Adjust the schema definition so entity changes will trigger events:

src/Pyz/Zed/MerchantOpeningHours/Persistence/Propel/Schema/spy_merchant_opening_hours.schema.xml

<?xml version="1.0"?>
<database xmlns="spryker:schema-01" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" name="zed" xsi:schemaLocation="spryker:schema-01 https://static.spryker.com/schema-01.xsd"
          namespace="Orm\Zed\MerchantOpeningHours\Persistence"
          package="src.Orm.Zed.MerchantOpeningHours.Persistence">

    <table name="spy_merchant_opening_hours_date_schedule" phpName="SpyMerchantOpeningHoursDateSchedule" identifierQuoting="true">
        <behavior name="event">
            <parameter name="spy_merchant_opening_hours_date_schedule_all" column="*"/>
        </behavior>
    </table>

    <table name="spy_merchant_opening_hours_weekday_schedule" phpName="SpyMerchantOpeningHoursWeekdaySchedule" identifierQuoting="true">
        <behavior name="event">
            <parameter name="spy_merchant_opening_hours_weekday_schedule_all" column="*"/>
        </behavior>
    </table>

</database>

src/Pyz/Zed/MerchantOpeningHoursStorage/Persistence/Propel/Schema/spy_merchant_opening_hours_storage.schema.xml

<?xml version="1.0"?>
<database xmlns="spryker:schema-01"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          name="zed"
          xsi:schemaLocation="spryker:schema-01 https://static.spryker.com/schema-01.xsd"
          namespace="Orm\Zed\MerchantOpeningHoursStorage\Persistence"
          package="src.Orm.Zed.MerchantOpeningHoursStorage.Persistence">

    <table name="spy_merchant_opening_hours_storage" phpName="SpyMerchantOpeningHoursStorage">
        <behavior name="synchronization">
            <parameter name="queue_pool" value="synchronizationPool"/>
        </behavior>
    </table>

</database>

Generate entity and transfer changes:

console transfer:generate console propel:install console transfer:generate
Verification

Verify the following changes have been applied by checking your database:

DATABASE ENTITY TYPE EVENT
spy_merchant_opening_hours_weekday_schedule table created
spy_merchant_opening_hours_date_schedule table created
spy_weekday_schedule table created
spy_date_schedule table created

Make sure that the following changes in transfer objects:

TRANSFER TYPE EVENT PATH
WeekdaySchedule class created src/Generated/Shared/Transfer/WeekdayScheduleTransfer
DataImporterReaderConfiguration class created src/Generated/Shared/Transfer/DataImporterReaderConfigurationTransfer
MerchantCriteria class created src/Generated/Shared/Transfer/MerchantCriteriaTransfer
MerchantOpeningHoursStorage class created src/Generated/Shared/Transfer/MerchantOpeningHoursStorageTransfer

3) Add Zed translations

Generate a new translation cache for Zed:

console translator:generate-cache

4) Configure export to Redis

This step publishes change events to spy_merchant_opening_hours_storage and synchronizes the data to the storage.

Set up event listeners and publishers

PLUGIN SPECIFICATION PREREQUISITES NAMESPACE
MerchantOpeningHoursWritePublisherPlugin Registers publisher that are responsible for publishing merchant opening hours entity changes to storage. Spryker\Zed\MerchantOpeningHoursStorage\Communication\Plugin\Event\Subscriber

src/Zed/Publisher/PublisherDependencyProvider.php

<?php

namespace Pyz\Zed\Publisher;

use Spryker\Zed\Publisher\PublisherDependencyProvider as SprykerPublisherDependencyProvider;

class PublisherDependencyProvider extends SprykerPublisherDependencyProvider
{
    /**
     * @return array
     */
    protected function getPublisherPlugins(): array
    {
        return [
            new MerchantOpeningHoursWritePublisherPlugin(),
        ];
    }
}

Configure message processors

PLUGIN SPECIFICATION PREREQUISITES NAMESPACE
SynchronizationStorageQueueMessageProcessorPlugin Configures all merchant profile and merchant opening hours messages to sync with Redis storage, and marks messages as failed in case of error. Spryker\Zed\Synchronization\Communication\Plugin\Queue

src/Pyz/Zed/Queue/QueueDependencyProvider.php

<?php

namespace Pyz\Zed\Queue;

use Spryker\Shared\MerchantOpeningHoursStorageConfig\MerchantOpeningHoursStorageConfig;
use Spryker\Zed\Kernel\Container;
use Spryker\Zed\Queue\QueueDependencyProvider as SprykerDependencyProvider;
use Spryker\Zed\Synchronization\Communication\Plugin\Queue\SynchronizationSearchQueueMessageProcessorPlugin;

class QueueDependencyProvider extends SprykerDependencyProvider
{
    /**
     * @param \Spryker\Zed\Kernel\Container $container
     *
     * @return \Spryker\Zed\Queue\Dependency\Plugin\QueueMessageProcessorPluginInterface[]
     */
    protected function getProcessorMessagePlugins(Container $container)
    {
        return [
            MerchantOpeningHoursStorageConfig::MERCHANT_OPENING_HOURS_SYNC_STORAGE_QUEUE => new SynchronizationStorageQueueMessageProcessorPlugin(),
        ];
    }
}

Register the synchronization queue and synchronization error queue:

src/Pyz/Client/RabbitMq/RabbitMqConfig.php

<?php

namespace Pyz\Client\RabbitMq;

use Spryker\Client\RabbitMq\RabbitMqConfig as SprykerRabbitMqConfig;
use Spryker\Shared\MerchantOpeningHoursStorage\MerchantOpeningHoursStorageConfig;

class RabbitMqConfig extends SprykerRabbitMqConfig
{
    /**
     * @return array
     */
    protected function getSynchronizationQueueConfiguration(): array
    {
        return [
            MerchantOpeningHoursStorageConfig::MERCHANT_OPENING_HOURS_SYNC_STORAGE_QUEUE,
        ];
    }

}

Set up, re-generate, and re-sync features

PLUGIN SPECIFICATION PREREQUISITES NAMESPACE
MerchantOpeningHoursSynchronizationDataBulkPlugin Allows synchronizing the entire storage table content into Storage. Spryker\Zed\MerchantOpeningHoursStorage\Communication\Plugin\Synchronization

src/Pyz/Zed/Synchronization/SynchronizationDependencyProvider.php

<?php

namespace Pyz\Zed\Synchronization;

use Spryker\Zed\MerchantOpeningHoursStorage\Communication\Plugin\Synchronization\MerchantOpeningHoursSynchronizationDataBulkPlugin;
use Spryker\Zed\Synchronization\SynchronizationDependencyProvider as SprykerSynchronizationDependencyProvider;

class SynchronizationDependencyProvider extends SprykerSynchronizationDependencyProvider
{
    /**
     * @return \Spryker\Zed\SynchronizationExtension\Dependency\Plugin\SynchronizationDataPluginInterface[]
     */
    protected function getSynchronizationDataPlugins(): array
    {
        return [
            new MerchantOpeningHoursSynchronizationDataBulkPlugin(),
        ];
    }
}

Configure synchronization pool name

src/Pyz/Zed/MerchantOpeningHoursStorage/MerchantOpeningHoursStorageConfig.php

<?php

namespace Pyz\Zed\MerchantOpeningHoursStorage;

use Pyz\Zed\Synchronization\SynchronizationConfig;
use Spryker\Zed\MerchantOpeningHoursStorage\MerchantOpeningHoursStorageConfig as SprykerMerchantOpeningHoursStorageStorageConfig;

class MerchantOpeningHoursStorageConfig extends SprykerMerchantOpeningHoursStorageStorageConfig
{
    /**
     * @return string|null
     */
    public function getMerchantOpeningHoursSynchronizationPoolName(): ?string
    {
        return SynchronizationConfig::DEFAULT_SYNCHRONIZATION_POOL_NAME;
    }
}
Verification
  1. Make sure that after step 1 the command console sync:data merchant_opening_hours exports data from the spy_merchant_opening_hours_storage table to Redis.

  2. Make sure that when merchant opening hours entities get created or updated through ORM, it is exported to Redis accordingly.

TARGET ENTITY EXAMPLE EXPECTED DATA IDENTIFIER
MerchantOpeningHours kv:merchant_opening_hours:1
Example expected data fragment
{
   "weekday_schedule":[
      {
         "day":"MONDAY",
         "time_from":"07:00:00.000000",
         "time_to":"13:00:00.000000"
      },
      {
         "day":"MONDAY",
         "time_from":"14:00:00.000000",
         "time_to":"20:00:00.000000"
      },
      {
         "day":"TUESDAY",
         "time_from":"07:00:00.000000",
         "time_to":"20:00:00.000000"
      },
      {
         "day":"WEDNESDAY",
         "time_from":"07:00:00.000000",
         "time_to":"20:00:00.000000"
      },
      {
         "day":"THURSDAY",
         "time_from":"07:00:00.000000",
         "time_to":"20:00:00.000000"
      },
      {
         "day":"FRIDAY",
         "time_from":"07:00:00.000000",
         "time_to":"20:00:00.000000"
      },
      {
         "day":"SATURDAY",
         "time_from":"07:00:00.000000",
         "time_to":"20:00:00.000000"
      },
      {
         "day":"SUNDAY",
         "time_from":null,
         "time_to":null
      }
   ],
   "date_schedule":[
      {
         "date":"2020-01-01",
         "time_from":null,
         "time_to":null,
         "note":"merchant_weekday_schedule.new_year"
      },
      {
         "date":"2021-12-31",
         "time_from":"10:00:00.000000",
         "time_to":"17:00:00.000000",
         "note":""
      }
   ]
}

5) Import Merchants Opening Hours data

Prepare your data according to your requirements using the demo data:

data/import/common/common/marketplace/merchant_open_hours_date_schedule.csv
>merchant_reference,date,time_from,time_to,note_glossary_key
MER000001,2020-01-01,,,merchant_weekday_schedule.new_year
MER000001,2020-04-10,,,merchant_weekday_schedule.good_friday
MER000001,2020-04-12,,,merchant_weekday_schedule.easter_sunday
MER000001,2020-04-13,,,merchant_weekday_schedule.easter_monday
MER000001,2020-05-01,,,merchant_weekday_schedule.may_day
MER000001,2020-05-21,,,merchant_weekday_schedule.ascension_of_christ
MER000001,2020-05-31,,,merchant_weekday_schedule.whit_sunday
MER000001,2020-06-01,,,merchant_weekday_schedule.whit_monday
MER000001,2020-06-11,,,merchant_weekday_schedule.corpus_christi
MER000001,2020-10-03,,,merchant_weekday_schedule.day_of_german_unity
MER000001,2020-11-01,,,merchant_weekday_schedule.all_saints_day
MER000001,2020-12-25,,,merchant_weekday_schedule.1st_christmas_day
MER000001,2020-12-26,,,merchant_weekday_schedule.2nd_christmas_day
MER000001,2021-11-28,13:00:00,18:00:00,merchant_weekday_schedule.sunday_opening
MER000001,2021-12-31,10:00:00,17:00:00,
MER000002,2020-01-01,,,merchant_weekday_schedule.new_year
MER000002,2020-04-10,,,merchant_weekday_schedule.good_friday
MER000002,2020-04-12,,,merchant_weekday_schedule.easter_sunday
MER000002,2020-04-13,,,merchant_weekday_schedule.easter_monday
MER000002,2020-05-01,,,merchant_weekday_schedule.may_day
MER000002,2020-05-21,,,merchant_weekday_schedule.ascension_of_christ
MER000002,2020-05-31,,,merchant_weekday_schedule.whit_sunday
MER000002,2020-06-01,,,merchant_weekday_schedule.whit_monday
MER000002,2020-06-11,,,merchant_weekday_schedule.corpus_christi
MER000002,2020-10-03,,,merchant_weekday_schedule.day_of_german_unity
MER000002,2020-11-01,,,merchant_weekday_schedule.all_saints_day
MER000002,2020-12-25,,,merchant_weekday_schedule.1st_christmas_day
MER000002,2020-12-26,,,merchant_weekday_schedule.2nd_christmas_day
MER000006,2020-01-01,,,merchant_weekday_schedule.new_year
MER000006,2020-04-10,,,merchant_weekday_schedule.good_friday
MER000006,2020-04-12,,,merchant_weekday_schedule.easter_sunday
MER000006,2020-04-13,,,merchant_weekday_schedule.easter_monday
MER000006,2020-05-01,,,merchant_weekday_schedule.may_day
MER000006,2020-05-21,,,merchant_weekday_schedule.ascension_of_christ
MER000006,2020-05-31,,,merchant_weekday_schedule.whit_sunday
MER000006,2020-06-01,,,merchant_weekday_schedule.whit_monday
MER000006,2020-06-11,,,merchant_weekday_schedule.corpus_christi
MER000006,2020-10-03,,,merchant_weekday_schedule.day_of_german_unity
MER000006,2020-11-01,,,merchant_weekday_schedule.all_saints_day
MER000006,2020-12-25,,,merchant_weekday_schedule.1st_christmas_day
MER000006,2020-12-26,,,merchant_weekday_schedule.2nd_christmas_day
MER000006,2021-11-28,13:00:00,18:00:00,merchant_weekday_schedule.sunday_opening
MER000006,2021-12-31,10:00:00,17:00:00,
MER000005,2020-01-01,,,merchant_weekday_schedule.new_year
MER000005,2020-04-10,,,merchant_weekday_schedule.good_friday
MER000005,2020-04-12,,,merchant_weekday_schedule.easter_sunday
MER000005,2020-04-13,,,merchant_weekday_schedule.easter_monday
MER000005,2020-05-01,,,merchant_weekday_schedule.may_day
MER000005,2020-05-21,,,merchant_weekday_schedule.ascension_of_christ
MER000005,2020-05-31,,,merchant_weekday_schedule.whit_sunday
MER000005,2020-06-01,,,merchant_weekday_schedule.whit_monday
MER000005,2020-06-11,,,merchant_weekday_schedule.corpus_christi
MER000005,2020-10-03,,,merchant_weekday_schedule.day_of_german_unity
MER000005,2020-11-01,,,merchant_weekday_schedule.all_saints_day
MER000005,2020-12-25,,,merchant_weekday_schedule.1st_christmas_day
MER000005,2020-12-26,,,merchant_weekday_schedule.2nd_christmas_day
MER000005,2021-11-28,13:00:00,18:00:00,merchant_weekday_schedule.sunday_opening
MER000005,2021-12-31,10:00:00,13:00:00,
MER000005,2021-12-31,14:00:00,17:00:00,
COLUMN REQUIRED? DATA TYPE DATA EXAMPLE DATA EXPLANATION
merchant_reference string MER000005 Merchant identifier.
date string 2020-01-01 Date with special opening hours
time_from string 10:00:00 Time start when the merchant is open on this special date. Empty means open ended
time_to string 13:00:00 Time end when the merchant is open on this special date. Empty means open ended
note string merchant_weekday_schedule.day_of_german_unity Glossary key to show a note next to special opening hours

data/import/common/common/marketplace/merchant_open_hours_week_day_schedule.csv

>merchant_reference,week_day_key,time_from,time_to
MER000001,MONDAY,7:00:00,13:00:00
MER000001,MONDAY,14:00:00,20:00:00
MER000001,TUESDAY,7:00:00,20:00:00
MER000001,WEDNESDAY,7:00:00,20:00:00
MER000001,THURSDAY,7:00:00,20:00:00
MER000001,FRIDAY,7:00:00,20:00:00
MER000001,SATURDAY,7:00:00,20:00:00
MER000001,SUNDAY,,
MER000002,MONDAY,8:00:00,13:00:00
MER000002,MONDAY,14:00:00,19:00:00
MER000002,TUESDAY,8:00:00,19:00:00
MER000002,WEDNESDAY,8:00:00,19:00:00
MER000002,THURSDAY,8:00:00,19:00:00
MER000002,FRIDAY,8:00:00,19:00:00
MER000002,SATURDAY,8:00:00,19:00:00
MER000002,SUNDAY,,
MER000006,MONDAY,7:00:00,13:00:00
MER000006,MONDAY,14:00:00,20:00:00
MER000006,TUESDAY,7:00:00,20:00:00
MER000006,WEDNESDAY,7:00:00,20:00:00
MER000006,THURSDAY,7:00:00,20:00:00
MER000006,FRIDAY,7:00:00,20:00:00
MER000006,SATURDAY,7:00:00,20:00:00
MER000006,SUNDAY,,
MER000005,MONDAY,8:00:00,13:00:00
MER000005,MONDAY,14:00:00,19:00:00
MER000005,TUESDAY,8:00:00,19:00:00
MER000005,WEDNESDAY,8:00:00,19:00:00
MER000005,THURSDAY,8:00:00,19:00:00
MER000005,FRIDAY,8:00:00,19:00:00
MER000005,SATURDAY,8:00:00,19:00:00
MER000005,SUNDAY,,
COLUMN REQUIRED? DATA TYPE DATA EXAMPLE DATA EXPLANATION
merchant_reference string MER000005 Merchant identifier.
week_day_key string MONDAY Day of the week to assign opening hours to a merchant.It is an enum in database with the following values:MONDAYTUESDAYWEDNESDAYTHURSDAYFRIDAYSATURDAYSUNDAY.
time_from string 8:00:00 Time start when the merchant is open on this week day. Empty means open ended.
time_to string 19:00:00 Time end when the merchant is open on this week day. Empty means open ended.

Register the following plugins to enable data import:

PLUGIN SPECIFICATION PREREQUISITES NAMESPACE
MerchantOpeningHoursDateScheduleDataImportPlugin Imports special dates opening hours into the database. Spryker\Zed\MerchantOpeningHoursDataImport\Communication\Plugin
MerchantOpeningHoursWeekdayScheduleDataImportPlugin Imports weekly schedule opening hours into the database. Spryker\Zed\MerchantOpeningHoursDataImport\Communication\Plugin

src/Pyz/Zed/DataImport/DataImportDependencyProvider.php

<?php

namespace Pyz\Zed\DataImport;

use Spryker\Zed\DataImport\DataImportDependencyProvider as SprykerDataImportDependencyProvider;
use Spryker\Zed\MerchantOpeningHoursDataImport\Communication\Plugin\MerchantOpeningHoursDateScheduleDataImportPlugin;
use Spryker\Zed\MerchantOpeningHoursDataImport\Communication\Plugin\MerchantOpeningHoursWeekdayScheduleDataImportPlugin;

class DataImportDependencyProvider extends SprykerDataImportDependencyProvider
{
    protected function getDataImporterPlugins(): array
    {
        return [
            new MerchantOpeningHoursDateScheduleDataImportPlugin(),
            new MerchantOpeningHoursWeekdayScheduleDataImportPlugin(),
        ];
    }
}

Import data:

console data:import merchant-opening-hours-date-schedule 
console data:import merchant-opening-hours-weekday-schedule
Verification

Make sure that the opening hours data is added to the spy_merchant_opening_hours_weekday_schedule and spy_merchant_opening_hours_date_schedule tables in the database.

Install feature front end

Follow the steps below to install the Merchant Opening Hours feature front end.

Prerequisites

To start feature integration, integrate the required features:

NAME VERSION INTEGRATION GUIDE
Spryker Core 202108.0 Spryker Core

1) Install the required modules using Composer

If installed before, not needed.

Verification

Verify if the following modules were installed:

MODULE EXPECTED DIRECTORY
MerchantOpeningHoursWidget spryker-shop/merchant-opening-hours-widget

2) Add Yves translations

Append glossary according to your configuration:

src/data/import/glossary.csv

merchant_opening_hours.opening_hours_title,Opening Hours,en_US 
merchant_opening_hours.opening_hours_title,Öffnungszeiten,de_DE 
merchant_opening_hours.special_opening_hours_title,Special Opening Hours,en_US 
merchant_opening_hours.special_opening_hours_title,Besondere Öffnungszeiten,de_DE 
merchant_opening_hours.public_holidays_title,Public Holidays,en_US 
merchant_opening_hours.public_holidays_title,Feiertage,de_DE 
merchant_opening_hours.opening_hours_closed,Closed,en_US 
merchant_opening_hours.opening_hours_closed,Geschlossen,de_DE 
merchant_opening_hours.day.title.monday,Monday,en_US 
merchant_opening_hours.day.title.monday,Montag,de_DE 
merchant_opening_hours.day.title.tuesday,Tuesday,en_US 
merchant_opening_hours.day.title.tuesday,Dienstag,de_DE 
merchant_opening_hours.day.title.wednesday,Wednesday,en_US 
merchant_opening_hours.day.title.wednesday,Mittwoch,de_DE 
merchant_opening_hours.day.title.thursday,Thursday,en_US 
merchant_opening_hours.day.title.thursday,Donnerstag,de_DE 
merchant_opening_hours.day.title.friday,Friday,en_US 
merchant_opening_hours.day.title.friday,Freitag,de_DE 
merchant_opening_hours.day.title.saturday,Saturday,en_US 
merchant_opening_hours.day.title.saturday,Samstag,de_DE 
merchant_opening_hours.day.title.sunday,Sunday,en_US 
merchant_opening_hours.day.title.sunday,Sonntag,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) Set up widgets

Register the following plugins to enable widgets:

PLUGIN DESCRIPTION PREREQUISITES NAMESPACE
MerchantOpeningHoursWidget Displays merchant working hours. SprykerShop\Yves\MerchantOpeningHoursWidget\Widget

src/Pyz/Yves/ShopApplication/ShopApplicationDependencyProvider.php

<?php

namespace Pyz\Yves\ShopApplication;

use SprykerShop\Yves\MerchantOpeningHoursWidget\Widget\MerchantOpeningHoursWidget;
use SprykerShop\Yves\ShopApplication\ShopApplicationDependencyProvider as SprykerShopApplicationDependencyProvider;

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

Enable Javascript and CSS changes:

console frontend:yves:build
Verification

Make sure that the following widget was registered:

MODULE TEST
MerchantOpeningHoursWidget Go to a merchant page on the storefront and ensure that merchant working hours are displayed.
FEATURE REQUIRED FOR THE CURRENT FEATURE INTEGRATION GUIDE
Merchant Opening Hours API Glue API: Merchant Opening Hours feature integration