Skip to content

Instantly share code, notes, and snippets.

@LichP
Created July 10, 2020 09:34
Show Gist options
  • Save LichP/80ef260ce721f56bf65aa7a87659d404 to your computer and use it in GitHub Desktop.
Save LichP/80ef260ce721f56bf65aa7a87659d404 to your computer and use it in GitHub Desktop.
A Drupal Commerce event subscriber for automatic order fulfillment
<?php
namespace Drupal\commerce_icu_post_checkout\EventSubscriber;
use Drupal\commerce_icu_post_checkout\AutoFulfillmentManagerInterface;
use Drupal\commerce_order\Entity\OrderInterface;
use Drupal\state_machine\Event\WorkflowTransitionEvent;
use Psr\Log\LoggerInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
/**
* Determine whether to split an order and do so if appropriate when an order is placed.
*/
class OrderFulfillmentSubscriber implements EventSubscriberInterface {
/**
* The auto fulfillment manager.
*
* @var \Drupal\commerce_icu_post_checkout\AutoFulfillmentManagerInterface
*/
protected $autoFulfillmentManager;
/**
* Constructs a new OrderFulfillmentSubscriber object.
*
* @param \Drupal\commerce_icu_post_checkout\AutoFulfillmentManagerInterface $auto_fulfillment_manager
* The auto fulfillment manager.
*/
public function __construct(
AutoFulfillmentManagerInterface $auto_fulfillment_manager
) {
$this->autoFulfillmentManager = $auto_fulfillment_manager;
}
/**
* {@inheritdoc}
*/
public static function getSubscribedEvents() {
// We subscribe at a lower priority than
// OrderNumberSubscriber::setOrderNumber to ensure the order number has
// been set before attempting to autofulfill.
$events = [
'commerce_order.pre_transition' => ['checkOrderAtFulfillment', -50],
];
return $events;
}
/**
* Checks whether an order has just transitioned to fullfillment. If so,
* attempt to autofulfill, and if successful transition to complete
*
* @param \Drupal\state_machine\Event\WorkflowTransitionEvent $event
* The event we subscribed to.
*/
public function checkOrderAtFulfillment(WorkflowTransitionEvent $event) {
$toState = $event->getToState();
if ($toState->getId() != 'fulfillment') {
return;
}
/** @var \Drupal\commerce_order\Entity\OrderInterface $order */
$order = $event->getEntity();
$order_fulfilled = $this->autoFulfillmentManager->fulfill($order);
// If the order was completely fulfilled, progress to complete.
// We manually trigger postSave before and preSave after applying the
// transition to allow post transition events to be fired for the
// transition triggering fulfillment and allow pre transition events to
// be fired for the transition to complete
if ($order_fulfilled) {
$order->getState()->postSave(true);
$order->getState()->applyTransitionById('fulfill');
$order->getState()->preSave();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment