View source
<?php
namespace Drupal\commerce_recurring\Plugin\AdvancedQueue\JobType;
use Drupal\advancedqueue\JobResult;
use Drupal\advancedqueue\Plugin\AdvancedQueue\JobType\JobTypeBase;
use Drupal\commerce_order\Entity\OrderInterface;
use Drupal\commerce_payment\Exception\DeclineException;
use Drupal\commerce_recurring\Event\PaymentDeclinedEvent;
use Drupal\commerce_recurring\Event\RecurringEvents;
use Drupal\commerce_recurring\RecurringOrderManagerInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
abstract class RecurringJobTypeBase extends JobTypeBase implements ContainerFactoryPluginInterface {
protected $entityTypeManager;
protected $eventDispatcher;
protected $recurringOrderManager;
public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityTypeManagerInterface $entity_type_manager, EventDispatcherInterface $event_dispatcher, RecurringOrderManagerInterface $recurring_order_manager) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
$this->entityTypeManager = $entity_type_manager;
$this->eventDispatcher = $event_dispatcher;
$this->recurringOrderManager = $recurring_order_manager;
}
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
return new static($configuration, $plugin_id, $plugin_definition, $container
->get('entity_type.manager'), $container
->get('event_dispatcher'), $container
->get('commerce_recurring.order_manager'));
}
protected function handleDecline(OrderInterface $order, DeclineException $exception, $num_retries) {
$billing_schedule = $order
->get('billing_schedule')->entity;
$schedule = $billing_schedule
->getRetrySchedule();
$max_retries = count($schedule);
if ($num_retries < $max_retries) {
$retry_days = $schedule[$num_retries];
$result = JobResult::failure($exception
->getMessage(), $max_retries, 86400 * $retry_days);
}
else {
$retry_days = 0;
$result = JobResult::success('Dunning complete, recurring order not paid.');
$this
->handleFailedOrder($order, FALSE);
}
$event = new PaymentDeclinedEvent($order, $retry_days, $num_retries, $max_retries, $exception);
$this->eventDispatcher
->dispatch(RecurringEvents::PAYMENT_DECLINED, $event);
$order
->save();
return $result;
}
protected function handleFailedOrder(OrderInterface $order, $save_order = TRUE) {
$order
->getState()
->applyTransitionById('mark_failed');
$billing_schedule = $order
->get('billing_schedule')->entity;
$unpaid_subscription_state = $billing_schedule
->getUnpaidSubscriptionState();
if ($unpaid_subscription_state != 'active') {
$this
->updateSubscriptions($order, $unpaid_subscription_state);
}
if ($save_order) {
$order
->save();
}
}
protected function updateSubscriptions(OrderInterface $order, $new_state_id) {
$subscriptions = $this->recurringOrderManager
->collectSubscriptions($order);
foreach ($subscriptions as $subscription) {
if ($subscription
->getState()
->getId() != 'active') {
continue;
}
$subscription
->setState($new_state_id);
$subscription
->save();
}
}
}