Verified Commit 2c28a66d authored by tuutti's avatar tuutti
Browse files

Issue #3316739: Support commerce shipping

parent 5e892e33
Loading
Loading
Loading
Loading
+76 −0
Original line number Diff line number Diff line
<?php

declare(strict_types = 1);

namespace Drupal\commerce_paytrail\Commerce\Shipping;

use Drupal\commerce_paytrail\Event\ModelEvent;
use Drupal\commerce_price\Calculator;
use Drupal\commerce_price\MinorUnitsConverterInterface;
use Paytrail\Payment\Model\Item;
use Paytrail\Payment\Model\PaymentRequest;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

/**
 * Provides a shipping support.
 */
final class ShippingEventSubscriber implements EventSubscriberInterface {

  /**
   * Constructs a new instance.
   *
   * @param \Drupal\commerce_price\MinorUnitsConverterInterface $converter
   *   The minor unit converter.
   */
  public function __construct(
    private MinorUnitsConverterInterface $converter
  ) {
  }

  /**
   * Subscribes to model event.
   *
   * @param \Drupal\commerce_paytrail\Event\ModelEvent $event
   *   The event to subscribe to.
   */
  public function addShipping(ModelEvent $event) : void {
    if (!$event->model instanceof PaymentRequest || !$order = $event->order) {
      return;
    }

    if (!$order->hasField('shipments') || $order->get('shipments')->isEmpty()) {
      return;
    }
    /** @var \Drupal\commerce_shipping\Entity\ShipmentInterface[] $shipments */
    $shipments = $order->get('shipments')->referencedEntities();

    $items = $event->model->getItems();

    foreach ($shipments as $shipment) {
      $item = (new Item())
        ->setUnitPrice($this->converter->toMinorUnits($shipment->getAdjustedAmount()))
        ->setProductCode($shipment->getShippingMethod()->getPlugin()->getPluginId())
        ->setUnits(1)
        ->setVatPercentage(0);

      if ($taxes = $shipment->getAdjustments(['tax'])) {
        $item->setVatPercentage((int) Calculator::multiply(
          reset($taxes)->getPercentage(),
          '100'
        ));
      }
      $items[] = $item;
    }
    $event->model->setItems($items);
  }

  /**
   * {@inheritdoc}
   */
  public static function getSubscribedEvents() : array {
    return [
      ModelEvent::class => ['addShipping'],
    ];
  }

}
+32 −0
Original line number Diff line number Diff line
<?php

declare(strict_types = 1);

namespace Drupal\commerce_paytrail;

use Drupal\commerce_paytrail\Commerce\Shipping\ShippingEventSubscriber;
use Drupal\Core\DependencyInjection\ContainerBuilder;
use Drupal\Core\DependencyInjection\ServiceProviderBase;
use Symfony\Component\DependencyInjection\Reference;

/**
 * Registers services for non-required modules.
 */
class CommercePaytrailServiceProvider extends ServiceProviderBase {

  /**
   * {@inheritdoc}
   */
  public function register(ContainerBuilder $container) :void {
    // We cannot use the module handler as the container is not yet compiled.
    // @see \Drupal\Core\DrupalKernel::compileContainer()
    $modules = $container->getParameter('container.modules');

    if (isset($modules['commerce_shipping'])) {
      $container->register('commerce_paytrail.shipping_subscriber', ShippingEventSubscriber::class)
        ->addTag('event_subscriber')
        ->addArgument(new Reference('commerce_price.minor_units_converter'));
    }
  }

}
+5 −1
Original line number Diff line number Diff line
@@ -4,6 +4,7 @@ declare(strict_types = 1);

namespace Drupal\commerce_paytrail\Event;

use Drupal\commerce_order\Entity\OrderInterface;
use Drupal\commerce_paytrail\Header;
use Drupal\Component\EventDispatcher\Event;
use Paytrail\Payment\Model\ModelInterface;
@@ -20,10 +21,13 @@ final class ModelEvent extends Event {
   *   The model.
   * @param \Drupal\commerce_paytrail\Header|null $headers
   *   The header.
   * @param \Drupal\commerce_order\Entity\OrderInterface|null $order
   *   The order.
   */
  public function __construct(
    public ModelInterface $model,
    public ?Header $headers = NULL
    public ?Header $headers = NULL,
    public ?OrderInterface $order = NULL
  ) {
  }

+1 −1
Original line number Diff line number Diff line
@@ -190,7 +190,7 @@ final class PaymentRequestBuilder extends RequestBuilderBase implements PaymentR
    $request->setCustomer($customer);

    $this->eventDispatcher
      ->dispatch(new ModelEvent($request));
      ->dispatch(new ModelEvent($request, order: $order));

    // We use reference field to load the order. Make sure it cannot be changed.
    if ($request->getReference() !== $order->id()) {
+1 −1
Original line number Diff line number Diff line
@@ -99,7 +99,7 @@ final class RefundRequestBuilder extends RequestBuilderBase implements RefundReq
      ->setRefundStamp($nonce);

    $this->eventDispatcher
      ->dispatch(new ModelEvent($request));
      ->dispatch(new ModelEvent($request, order: $order));

    return $request;
  }