forked from Sylius/Sylius
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request Sylius#5216 from Zales0123/list-checkout-shipping-…
…methods-also-by-channel [Core][Shipping] Fix shipping method choice type
- Loading branch information
Showing
2 changed files
with
233 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
<?php | ||
|
||
/* | ||
* This file is part of the Sylius package. | ||
* | ||
* (c) Paweł Jędrzejewski | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
namespace Sylius\Component\Core\Resolver; | ||
|
||
use Sylius\Component\Addressing\Matcher\ZoneMatcherInterface; | ||
use Sylius\Component\Core\Model\ChannelInterface; | ||
use Sylius\Component\Core\Model\OrderInterface; | ||
use Sylius\Component\Core\Model\ShipmentInterface; | ||
use Sylius\Component\Shipping\Model\ShippingSubjectInterface; | ||
use Sylius\Component\Shipping\Repository\ShippingMethodRepositoryInterface; | ||
use Sylius\Component\Shipping\Resolver\MethodsResolverInterface; | ||
|
||
/** | ||
* @author Mateusz Zalewski <mateusz.zalewski@lakion.com> | ||
*/ | ||
class ShippingMethodsByZonesAndChannelResolver implements MethodsResolverInterface | ||
{ | ||
/** | ||
* @var ShippingMethodRepositoryInterface | ||
*/ | ||
private $shippingMethodRepository; | ||
|
||
/** | ||
* @var ZoneMatcherInterface | ||
*/ | ||
private $zoneMatcher; | ||
|
||
/** | ||
* @param ShippingMethodRepositoryInterface $shippingMethodRepository | ||
* @param ZoneMatcherInterface $zoneMatcher | ||
*/ | ||
public function __construct( | ||
ShippingMethodRepositoryInterface $shippingMethodRepository, | ||
ZoneMatcherInterface $zoneMatcher | ||
) { | ||
$this->shippingMethodRepository = $shippingMethodRepository; | ||
$this->zoneMatcher = $zoneMatcher; | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function getSupportedMethods(ShippingSubjectInterface $subject) | ||
{ | ||
$zones = $this->getZonesIdsForAddress($subject->getOrder()); | ||
if (empty($zones)) { | ||
return []; | ||
} | ||
|
||
/** @var ChannelInterface $channel */ | ||
$channel = $subject->getOrder()->getChannel(); | ||
|
||
$methods = []; | ||
foreach ($this->shippingMethodRepository->findBy(['enabled' => true, 'zone' => $zones]) as $method) { | ||
if ($channel->hasShippingMethod($method)) { | ||
$methods[] = $method; | ||
} | ||
} | ||
|
||
return $methods; | ||
} | ||
|
||
/** | ||
* @param OrderInterface $order | ||
* | ||
* @return array | ||
*/ | ||
private function getZonesIdsForAddress(OrderInterface $order) | ||
{ | ||
$matchedZones = $this->zoneMatcher->matchAll($order->getShippingAddress()); | ||
if (empty($matchedZones)) { | ||
return []; | ||
} | ||
|
||
$zones = []; | ||
foreach ($matchedZones as $zone) { | ||
$zones[] = $zone->getId(); | ||
} | ||
|
||
return $zones; | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function supports(ShippingSubjectInterface $subject) | ||
{ | ||
return $subject instanceof ShipmentInterface && | ||
null !== $subject->getOrder() && | ||
null !== $subject->getOrder()->getShippingAddress() | ||
; | ||
} | ||
} |
131 changes: 131 additions & 0 deletions
131
spec/Resolver/ShippingMethodsByZonesAndChannelResolverSpec.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
<?php | ||
|
||
/* | ||
* This file is part of the Sylius package. | ||
* | ||
* (c) Paweł Jędrzejewski | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
namespace spec\Sylius\Component\Core\Resolver; | ||
|
||
use PhpSpec\ObjectBehavior; | ||
use Sylius\Component\Addressing\Matcher\ZoneMatcherInterface; | ||
use Sylius\Component\Addressing\Model\ZoneInterface; | ||
use Sylius\Component\Core\Model\AddressInterface; | ||
use Sylius\Component\Core\Model\ChannelInterface; | ||
use Sylius\Component\Core\Model\OrderInterface; | ||
use Sylius\Component\Core\Model\ShipmentInterface; | ||
use Sylius\Component\Core\Model\ShippingMethodInterface; | ||
use Sylius\Component\Core\Resolver\ShippingMethodsByZonesAndChannelResolver; | ||
use Sylius\Component\Shipping\Model\ShippingSubjectInterface; | ||
use Sylius\Component\Shipping\Repository\ShippingMethodRepositoryInterface; | ||
use Sylius\Component\Shipping\Resolver\MethodsResolverInterface; | ||
|
||
/** | ||
* @mixin ShippingMethodsByZonesAndChannelResolver | ||
* | ||
* @author Mateusz Zalewski <mateusz.zalewski@lakion.com> | ||
*/ | ||
class ShippingMethodsByZonesAndChannelResolverSpec extends ObjectBehavior | ||
{ | ||
function let( | ||
ShippingMethodRepositoryInterface $shippingMethodRepository, | ||
ZoneMatcherInterface $zoneMatcher | ||
) { | ||
$this->beConstructedWith($shippingMethodRepository, $zoneMatcher); | ||
} | ||
|
||
function it_is_initializable() | ||
{ | ||
$this->shouldHaveType('Sylius\Component\Core\Resolver\ShippingMethodsByZonesAndChannelResolver'); | ||
} | ||
|
||
function it_implements_shipping_methods_by_zones_and_channel_resolver_interface() | ||
{ | ||
$this->shouldImplement(MethodsResolverInterface::class); | ||
} | ||
|
||
function it_returns_shipping_methods_matched_for_shipment_order_shipping_address_and_order_channel( | ||
AddressInterface $address, | ||
ChannelInterface $channel, | ||
OrderInterface $order, | ||
ShipmentInterface $shipment, | ||
ShippingMethodInterface $firstShippingMethod, | ||
ShippingMethodInterface $secondShippingMethod, | ||
ShippingMethodInterface $thirdShippingMethod, | ||
ShippingMethodRepositoryInterface $shippingMethodRepository, | ||
ZoneInterface $firstZone, | ||
ZoneInterface $secondZone, | ||
ZoneMatcherInterface $zoneMatcher | ||
) { | ||
$shipment->getOrder()->willReturn($order); | ||
$order->getShippingAddress()->willReturn($address); | ||
$order->getChannel()->willReturn($channel); | ||
|
||
$zoneMatcher->matchAll($address)->willReturn([$firstZone, $secondZone]); | ||
|
||
$firstZone->getId()->willReturn(1); | ||
$secondZone->getId()->willReturn(4); | ||
|
||
$shippingMethodRepository | ||
->findBy(['enabled' => true, 'zone' => [1, 4]]) | ||
->willReturn([$firstShippingMethod, $secondShippingMethod, $thirdShippingMethod]) | ||
; | ||
|
||
$channel->hasShippingMethod($firstShippingMethod)->willReturn(true); | ||
$channel->hasShippingMethod($secondShippingMethod)->willReturn(true); | ||
$channel->hasShippingMethod($thirdShippingMethod)->willReturn(false); | ||
|
||
$this->getSupportedMethods($shipment)->shouldReturn([$firstShippingMethod, $secondShippingMethod]); | ||
} | ||
|
||
function it_returns_empty_array_if_zone_matcher_could_not_match_any_zone( | ||
AddressInterface $address, | ||
OrderInterface $order, | ||
ShipmentInterface $shipment, | ||
ZoneMatcherInterface $zoneMatcher | ||
) { | ||
$shipment->getOrder()->willReturn($order); | ||
$order->getShippingAddress()->willReturn($address); | ||
|
||
$zoneMatcher->matchAll($address)->willReturn([]); | ||
|
||
$this->getSupportedMethods($shipment)->shouldReturn([]); | ||
} | ||
|
||
function it_supports_shipments_with_order_and_its_shipping_address_defined( | ||
AddressInterface $address, | ||
OrderInterface $order, | ||
ShipmentInterface $shipment | ||
) { | ||
$shipment->getOrder()->willReturn($order); | ||
$order->getShippingAddress()->willReturn($address); | ||
|
||
$this->supports($shipment)->shouldReturn(true); | ||
} | ||
|
||
function it_does_not_support_shipments_which_order_has_no_shipping_address_defined( | ||
OrderInterface $order, | ||
ShipmentInterface $shipment | ||
) { | ||
$shipment->getOrder()->willReturn($order); | ||
$order->getShippingAddress()->willReturn(null); | ||
|
||
$this->supports($shipment)->shouldReturn(false); | ||
} | ||
|
||
function it_does_not_support_shipments_which_has_no_order_defined(ShipmentInterface $shipment) | ||
{ | ||
$shipment->getOrder()->willReturn(null); | ||
|
||
$this->supports($shipment)->shouldReturn(false); | ||
} | ||
|
||
function it_does_not_support_different_shipping_subject_than_shipment(ShippingSubjectInterface $subject) | ||
{ | ||
$this->supports($subject)->shouldReturn(false); | ||
} | ||
} |