Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

2.0.x #71

Merged
merged 12 commits into from
May 3, 2024
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
Loading