Skip to content

Commit

Permalink
2.0.x (#71)
Browse files Browse the repository at this point in the history
- Add modal map to product page search
- Fix show product offer price if shop has been selected, even in Retail mode
  • Loading branch information
livca-smile authored May 3, 2024
1 parent 2e99fa2 commit 723b4aa
Show file tree
Hide file tree
Showing 15 changed files with 327 additions and 102 deletions.
51 changes: 48 additions & 3 deletions Block/Catalog/Product/Retailer/Availability.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use Magento\Catalog\Api\ProductRepositoryInterface;
use Magento\Catalog\Block\Product\Context;
use Magento\Catalog\Model\Product as ProductModel;
use Magento\Directory\Model\Region;
use Magento\Framework\DataObject\IdentityInterface;
use Magento\Framework\Registry;
use Magento\Framework\View\Element\Template;
Expand All @@ -20,6 +21,10 @@
use Smile\Retailer\Api\Data\RetailerExtensionInterface;
use Smile\Retailer\Api\Data\RetailerInterface;
use Smile\Retailer\Model\ResourceModel\Retailer\CollectionFactory as RetailerCollectionFactory;
use Smile\RetailerOffer\Helper\Config as HelperConfig;
use Smile\StoreLocator\Helper\Data;
use Smile\StoreLocator\Helper\Schedule;
use Smile\StoreLocator\Model\Retailer\ScheduleManagement;

/**
* Block rendering availability in store for a given product.
Expand All @@ -32,13 +37,21 @@ class Availability extends Template implements IdentityInterface
protected Registry $coreRegistry;
protected ?array $storeOffers = null;

/**
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
*/
public function __construct(
Context $context,
protected ProductRepositoryInterface $productRepository,
protected OfferManagement $offerManagement,
protected RetailerCollectionFactory $retailerCollectionFactory,
protected AddressFormatter $addressFormatter,
protected Region $region,
protected HelperConfig $helperConfig,
MapProviderInterface $mapProvider,
protected ScheduleManagement $scheduleManagement,
protected Schedule $scheduleHelper,
protected Data $storeLocatorHelper,
array $data = []
) {
$this->map = $mapProvider->getMap();
Expand All @@ -59,13 +72,27 @@ public function getJsLayout()

$jsLayout['components']['catalog-product-retailer-availability']['productId'] = $this->getProduct()->getId();
$jsLayout['components']['catalog-product-retailer-availability']['storeOffers'] = $this->getStoreOffers();
$jsLayout['components']['catalog-product-retailer-availability']['children']['geocoder']['provider'] =
$this->map->getIdentifier();
$jsLayout['components']['catalog-product-retailer-availability']['searchPlaceholderText'] = $this
->helperConfig->getSearchPlaceholder();

// smile-geocoder child
$jsLayout['components']['catalog-product-retailer-availability']['children']['geocoder']['provider']
= $this->map->getIdentifier();
$jsLayout['components']['catalog-product-retailer-availability']['children']['geocoder'] = array_merge(
$jsLayout['components']['catalog-product-retailer-availability']['children']['geocoder'],
$this->map->getConfig()
);

// smile-map child
$jsLayout['components']['catalog-product-retailer-availability']['children']['map']['provider'] = $this->map
->getIdentifier();
$jsLayout['components']['catalog-product-retailer-availability']['children']['map']['markers']
= $this->getStoreOffers();
$jsLayout['components']['catalog-product-retailer-availability']['children']['map'] = array_merge(
$jsLayout['components']['catalog-product-retailer-availability']['children']['map'],
$this->map->getConfig()
);

return json_encode($jsLayout);
}

Expand All @@ -76,7 +103,9 @@ public function getJsLayout()
*/
public function getIdentities(): array
{
$identities = $this->getProduct()->getIdentities();
/** @var ProductModel $product */
$product = $this->getProduct();
$identities = $product->getIdentities();

foreach ($this->getStoreOffers() as $offer) {
if (isset($offer[OfferInterface::OFFER_ID])) {
Expand Down Expand Up @@ -123,16 +152,32 @@ protected function getStoreOffers(): array
/** @var RetailerExtensionInterface $retailerExtensionInterface */
$retailerExtensionInterface = $retailer->getExtensionAttributes();
$address = $retailerExtensionInterface->getAddress();
$regionName = $this->region->load($address->getRegionId())->getName() ?: null;
$offer = [
'sellerId' => (int) $retailer->getId(),
'name' => $retailer->getName(),
'address' => $this->addressFormatter->formatAddress($address, AddressFormatter::FORMAT_ONELINE),
'postCode' => $address->getPostcode(),
'region' => $regionName,
'city' => $address->getCity(),
'latitude' => $address->getCoordinates()->getLatitude(),
'longitude' => $address->getCoordinates()->getLongitude(),
'setStoreData' => $this->getSetStorePostData($retailer),
'isAvailable' => false,
'url' => $this->storeLocatorHelper->getRetailerUrl($retailer),
];

// phpcs:disable Magento2.Performance.ForeachArrayMerge.ForeachArrayMerge
$offer['schedule'] = array_merge(
$this->scheduleHelper->getConfig(),
[
'calendar' => $this->scheduleManagement->getCalendar($retailer),
'openingHours' => $this->scheduleManagement->getWeekOpeningHours($retailer),
'specialOpeningHours' => $retailerExtensionInterface->getSpecialOpeningHours(),
]
);
// phpcs:enable

if (isset($offerByRetailer[(int) $retailer->getId()])) {
$offer['isAvailable'] = (bool) $offerByRetailer[(int) $retailer->getId()]->isAvailable();
$offer[OfferInterface::OFFER_ID] = $offerByRetailer[(int) $retailer->getId()]->getId();
Expand Down
8 changes: 7 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,13 @@

All notable changes to this project will be documented in this file.

## [2.0.1] - 2023-09-20
## [2.0.2] - 2024-05-03
[2.0.2]: https://github.com/Smile-SA/magento2-module-retailer-offer/compare/2.0.1...2.0.2

- Add modal map to product page search
- Fix show product offer price if shop has been selected, even in Retail mode

## [2.0.1] - 2023-10-05
[2.0.1]: https://github.com/Smile-SA/magento2-module-retailer-offer/compare/2.0.0...2.0.1

- Fix CategoryPlugin closure return type
Expand Down
29 changes: 29 additions & 0 deletions Helper/Config.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php

declare(strict_types=1);

namespace Smile\RetailerOffer\Helper;

use Magento\Framework\App\Helper\AbstractHelper;
use Magento\Store\Model\ScopeInterface;

class Config extends AbstractHelper
{
public const SEARCH_PLACEHOLDER_XML_PATH = 'smile_retailersuite_retailer_base_settings/search/placeholder';

/**
* Get config by config path.
*/
public function getConfigByPath(string $path, string $scope = ScopeInterface::SCOPE_STORE): mixed
{
return $this->scopeConfig->getValue($path, $scope);
}

/**
* Get placeholder for search input of store_locator, default: City, Zipcode, Address, ...
*/
public function getSearchPlaceholder(): string
{
return (string) $this->getConfigByPath(self::SEARCH_PLACEHOLDER_XML_PATH) ?: 'City, Zipcode, Address ...';
}
}
2 changes: 2 additions & 0 deletions Model/Layer/Filter/Price.php
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ public function apply(RequestInterface $request)

if ($filter) {
$this->dataProvider->setInterval($filter);
// @phpstan-ignore-next-line
$priorFilters = $this->dataProvider->getPriorFilters($filterParams);
if ($priorFilters) {
$this->dataProvider->setPriorIntervals($priorFilters);
Expand All @@ -103,6 +104,7 @@ public function apply(RequestInterface $request)
$this->addQueryFilter($fromValue, $toValue);

$this->getLayer()->getState()->addFilter(
// @phpstan-ignore-next-line
$this->_createItem($this->_renderRangeLabel(empty($fromValue) ? 0 : $fromValue, $toValue), $filter)
);
}
Expand Down
6 changes: 4 additions & 2 deletions Plugin/ContextPlugin.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,13 @@ public function aroundDispatch(
RequestInterface $request
): mixed {

if ($this->settingsHelper->isDriveMode()) {
// show product offer price if shop has been selected, even in Retail mode
if ($this->settingsHelper->isDriveMode() || $this->currentStore->getRetailer()) {
// Set a default value to have common vary for all customers without any chosen retailer.
$retailerId = 'default';

if ($this->currentStore->getRetailer() && $this->currentStore->getRetailer()->getId()) {
if ($this->currentStore->getRetailer()
&& $this->currentStore->getRetailer()->getId()) {
$retailerId = $this->currentStore->getRetailer()->getId();
}

Expand Down
34 changes: 29 additions & 5 deletions Plugin/ProductPlugin.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,36 @@

use Closure;
use Magento\Catalog\Model\Product;
use Smile\Retailer\Api\Data\RetailerInterface;
use Smile\RetailerOffer\Helper\Offer;
use Smile\RetailerOffer\Helper\Settings;
use Smile\StoreLocator\CustomerData\CurrentStore;

/**
* Replace is in stock native filter on layer.
*/
class ProductPlugin
{
public function __construct(private Offer $offerHelper, private Settings $settingsHelper)

public function __construct(
private Offer $offerHelper,
private Settings $settingsHelper,
protected CurrentStore $currentStore
) {
}

/**
* Retrieve current retailer.
*/
private function getRetailer(): ?RetailerInterface
{
$retailer = null;
if ($this->currentStore->getRetailer() && $this->currentStore->getRetailer()->getId()) {
/** @var RetailerInterface $retailer */
$retailer = $this->currentStore->getRetailer();
}

return $retailer;
}

/**
Expand All @@ -27,7 +47,8 @@ public function aroundIsAvailable(Product $product, Closure $proceed): bool
{
$isAvailable = $proceed();

if ($this->settingsHelper->useStoreOffers()) {
// show product availability if shop has been selected, even in Retail mode
if ($this->settingsHelper->useStoreOffers() || $this->getRetailer()) {
$isAvailable = false;
$offer = $this->offerHelper->getCurrentOffer($product);

Expand All @@ -46,7 +67,8 @@ public function aroundGetPrice(Product $product, Closure $proceed): mixed
{
$price = $proceed();

if ($this->settingsHelper->useStoreOffers()) {
// show product offer price if shop has been selected, even in Retail mode
if ($this->settingsHelper->useStoreOffers() || $this->getRetailer()) {
$offer = $this->offerHelper->getCurrentOffer($product);

if ($offer && $offer->getPrice()) {
Expand All @@ -66,7 +88,8 @@ public function aroundGetSpecialPrice(Product $product, Closure $proceed): mixed
{
$price = $proceed();

if ($this->settingsHelper->useStoreOffers()) {
// show product offer price if shop has been selected, even in Retail mode
if ($this->settingsHelper->useStoreOffers() || $this->getRetailer()) {
$offer = $this->offerHelper->getCurrentOffer($product);

if ($offer && $offer->getSpecialPrice()) {
Expand All @@ -84,7 +107,8 @@ public function aroundGetFinalPrice(Product $product, Closure $proceed, mixed $q
{
$price = $proceed($qty);

if ($this->settingsHelper->useStoreOffers()) {
// show product offer price if shop has been selected, even in Retail mode
if ($this->settingsHelper->useStoreOffers() || $this->getRetailer()) {
$offer = $this->offerHelper->getCurrentOffer($product);

if ($offer) {
Expand Down
2 changes: 1 addition & 1 deletion Ui/Component/Offer/Listing/DataProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ public function addField($field, $alias = null): void
/**
* @inheritdoc
*/
public function addFilter(Filter $filter): mixed
public function addFilter(Filter $filter): void
{
if (isset($this->addFilterStrategies[$filter->getField()])) {
$this->addFilterStrategies[$filter->getField()]
Expand Down
9 changes: 9 additions & 0 deletions etc/adminhtml/system.xml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
<resource>Magento_Backend::config_smile_retailersuite_retailer_base_settings</resource>

<group id="navigation_settings" translate="label" type="text" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Main Settings</label>
<field id="navigation_mode" translate="label comment" type="select" sortOrder="200" showInDefault="1" showInWebsite="0" showInStore="0">
<label>Navigation mode</label>
<comment>Drive mode : the customer will only see the catalog of the chosen retailer in Front Office. Retail mode : the customer will browse the Web catalog by default.</comment>
Expand All @@ -20,6 +21,14 @@
<source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
</field>
</group>
<!-- avoid nth dependency with Smile_StoreLocator -->
<group id="search" translate="label" type="text" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Search Settings</label>
<field id="placeholder" translate="label" type="text" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Shown placeholder to help user</label>
<comment>default: City, Zipcode, Address ...</comment>
</field>
</group>
</section>
</system>
</config>
3 changes: 3 additions & 0 deletions etc/config.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
<navigation_mode>0</navigation_mode>
<display_offers>1</display_offers>
</navigation_settings>
<search>
<placeholder>City, Zipcode, Address ...</placeholder>
</search>
</smile_retailersuite_retailer_base_settings>
</default>
</config>
1 change: 1 addition & 0 deletions i18n/en_US.csv
Original file line number Diff line number Diff line change
Expand Up @@ -61,3 +61,4 @@ ID,ID
Search,Search
"Retailer Offers","Retailer Offers"
"Not Selected","Not Selected"
"City, Zipcode, Address ...","City, Zipcode, Address ..."
1 change: 1 addition & 0 deletions i18n/fr_FR.csv
Original file line number Diff line number Diff line change
Expand Up @@ -61,3 +61,4 @@ ID,ID
Search,Search
"Retailer Offers","Offres Magasin"
"Not Selected","Non Sélectionné"
"City, Zipcode, Address ...","Ville, code postal, addresse ..."
11 changes: 7 additions & 4 deletions view/frontend/layout/catalog_product_view.xml
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,16 @@
<item name="catalog-product-retailer-availability" xsi:type="array">
<item name="component" xsi:type="string">Smile_RetailerOffer/js/retailer/product-availability</item>
<item name="storeOffersListTemplate" xsi:type="string">Smile_RetailerOffer/retailer/product/store-list</item>
<item name="searchTitleText" xsi:type="string" translate="true">Find a store :</item>
<item name="searchButtonText" xsi:type="string" translate="true">Search</item>
<item name="geolocationButtonText" xsi:type="string" translate="true">Geolocalize me</item>
<item name="radius" xsi:type="string">25000</item>
<item name="children" xsi:type="array">
<item name="geocoder" xsi:type="array">
<item name="component" xsi:type="string">smile-geocoder</item>
<item name="searchTitleText" xsi:type="string" translate="true">Find a store :</item>
<item name="searchPlaceholderText" xsi:type="string" translate="true">City, Zipcode, Department, ...</item>
<item name="searchButtonText" xsi:type="string" translate="true">Search</item>
<item name="radius" xsi:type="string">25000</item>
</item>
<item name="map" xsi:type="array">
<item name="component" xsi:type="string">smile-map</item>
</item>
</item>
</item>
Expand Down
21 changes: 17 additions & 4 deletions view/frontend/templates/product/view/retailer/availability.phtml
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,13 @@ use Smile\RetailerOffer\Block\Catalog\Product\Retailer\Availability;
"modal":true
}
}'>
<div class="fulltext-search-wrapper" data-bind="scope: requestChild('geocoder')">
<div class="geocoder-wrapper" data-bind=" afterRender: initGeocoder">
<div class="fulltext-search-wrapper">
<div class="geocoder-wrapper">
<div class="block-title">
<strong role="heading" aria-level="1" data-bind="text: searchTitleText"></strong>
</div>

<form class="form" data-bind="submit: onSearch">
<form class="form" data-bind="submit: onSearchOffers">
<div class="field">
<input type="text" name="text"
data-bind="value: fulltextSearch, attr: {placeholder: searchPlaceholderText}"/>
Expand All @@ -39,6 +39,13 @@ use Smile\RetailerOffer\Block\Catalog\Product\Retailer\Availability;
<span data-bind="text: searchButtonText"></span>
</button>
</div>
<div data-bind="{ scope: requestChild('geocoder')}">
<div data-bind="afterRender: initGeocoder">
<button data-bind="click: $parent.geolocalizeMe.bind($parent)" class="action primary">
<span data-bind="text: $parent.geolocationButtonText"></span>
</button>
</div>
</div>
</div>
</form>
</div>
Expand All @@ -48,6 +55,12 @@ use Smile\RetailerOffer\Block\Catalog\Product\Retailer\Availability;
<li data-bind="template: $parent.storeOffersListTemplate" class="result-item"></li>
</ul>
</div>

<div data-bind="{ scope: requestChild('map')}">
<div id="store-view-map" class="store-view-map clearfix">
<div id="map-popin-availability" class="map" data-bind="afterRender: initMap"></div>
</div>
</div>
</div>
<div class="catalog-product-retailer-availability-content">
<div class="title">
Expand All @@ -64,7 +77,7 @@ use Smile\RetailerOffer\Block\Catalog\Product\Retailer\Availability;
</div>
</div>
<div class="action showavailability" data-bind="scope: 'catalog-product-retailer-availability'">
<a href="#" class="text" data-bind="text: getLinkLabel()"></a>
<a href="#" class="text" data-bind="text: getLinkLabel(), click: loadRetailerAvailabilityModal"></a>
</div>
</div>

Expand Down
Loading

0 comments on commit 723b4aa

Please sign in to comment.