diff --git a/modules/log/commerce_log.commerce_log_categories.yml b/modules/log/commerce_log.commerce_log_categories.yml index b921707752..8ea861b096 100644 --- a/modules/log/commerce_log.commerce_log_categories.yml +++ b/modules/log/commerce_log.commerce_log_categories.yml @@ -5,3 +5,7 @@ commerce_cart: commerce_order: label: Order entity_type: commerce_order + +commerce_payment: + label: Payment + entity_type: commerce_payment diff --git a/modules/log/commerce_log.commerce_log_templates.yml b/modules/log/commerce_log.commerce_log_templates.yml index 13dc722d95..9dfb2d34de 100644 --- a/modules/log/commerce_log.commerce_log_templates.yml +++ b/modules/log/commerce_log.commerce_log_templates.yml @@ -23,3 +23,36 @@ order_canceled: category: commerce_order label: 'Order canceled' template: '
The order was canceled.
' + +payment_authorized: + category: commerce_payment + label: 'Payment authorized' + template: 'Payment {{ payment_remote_id }} was authorized.
' +payment_voided: + category: commerce_payment + label: 'Payment voided' + template: 'Payment {{ payment_remote_id }} was voided.
' +payment_expired: + category: commerce_payment + label: 'Payment expired' + template: 'Payment {{ payment_remote_id }} was expired.
' +payment_authorized_captured: + category: commerce_payment + label: 'Payment authorized and captured' + template: 'Payment {{ payment_remote_id }} was authorized and captured.
' +payment_partially_captured: + category: commerce_payment + label: 'Payment partially captured' + template: 'Payment {{ payment_remote_id }} was partially captured ({{ captured_amount }}).
' +payment_captured: + category: commerce_payment + label: 'Payment captured' + template: 'Payment {{ payment_remote_id }} was fully captured.
' +payment_partially_refunded: + category: commerce_payment + label: 'Payment partially refunded' + template: 'Payment {{ payment_remote_id }} was partially refunded ({{ refunded_amount }}).
' +payment_refunded: + category: commerce_payment + label: 'Payment refunded' + template: 'Payment {{ payment_remote_id }} was fully refunded.
' diff --git a/modules/log/commerce_log.module b/modules/log/commerce_log.module index 9c4927c624..7d0bdd2007 100644 --- a/modules/log/commerce_log.module +++ b/modules/log/commerce_log.module @@ -11,11 +11,13 @@ function commerce_log_preprocess_commerce_order(&$variables) { /** @var \Drupal\commerce_order\Entity\OrderInterface $order */ $order = $variables['elements']['#commerce_order']; + $order_payments = \Drupal::entityTypeManager()->getStorage('commerce_payment')->loadByProperties(['order_id' => $order->id()]); + $entity_ids = implode(',', array_merge([$order->id()], array_keys($order_payments))); $variables['order']['activity'] = [ '#type' => 'view', '#name' => 'commerce_activity', '#display_id' => 'default', - '#arguments' => [$order->id(), 'commerce_order'], + '#arguments' => [$entity_ids, 'commerce_order,commerce_payment'], '#embed' => TRUE, '#title' => t('Order activity'), ]; diff --git a/modules/log/config/install/views.view.commerce_activity.yml b/modules/log/config/install/views.view.commerce_activity.yml index 852aecc801..74c49e556d 100644 --- a/modules/log/config/install/views.view.commerce_activity.yml +++ b/modules/log/config/install/views.view.commerce_activity.yml @@ -44,9 +44,8 @@ display: sort_asc_label: Asc sort_desc_label: Desc pager: - type: some + type: none options: - items_per_page: 5 offset: 0 style: type: table @@ -316,7 +315,7 @@ display: type: none fail: 'not found' validate_options: { } - break_phrase: false + break_phrase: true not: false entity_type: commerce_log entity_field: source_entity_id @@ -358,7 +357,7 @@ display: case: none path_case: none transform_dash: false - break_phrase: false + break_phrase: true entity_type: commerce_log entity_field: source_entity_type plugin_id: string diff --git a/modules/log/src/CommerceLogServiceProvider.php b/modules/log/src/CommerceLogServiceProvider.php index 769cc5fc21..a130fab387 100644 --- a/modules/log/src/CommerceLogServiceProvider.php +++ b/modules/log/src/CommerceLogServiceProvider.php @@ -29,6 +29,11 @@ public function register(ContainerBuilder $container) { ->addTag('event_subscriber') ->addArgument(new Reference('entity_type.manager')); } + if (isset($modules['commerce_payment'])) { + $container->register('commerce_log.payment_subscriber', 'Drupal\commerce_log\EventSubscriber\PaymentEventSubscriber') + ->addTag('event_subscriber') + ->addArgument(new Reference('entity_type.manager')); + } } } diff --git a/modules/log/src/EventSubscriber/PaymentEventSubscriber.php b/modules/log/src/EventSubscriber/PaymentEventSubscriber.php new file mode 100644 index 0000000000..31ccf23606 --- /dev/null +++ b/modules/log/src/EventSubscriber/PaymentEventSubscriber.php @@ -0,0 +1,214 @@ +logStorage = $entity_type_manager->getStorage('commerce_log'); + } + + /** + * {@inheritdoc} + */ + public static function getSubscribedEvents() { + $events = [ + 'commerce_payment.authorize.pre_transition' => ['onAuthorizeTransition', -100], + 'commerce_payment.void.pre_transition' => ['onVoidTransition', -100], + 'commerce_payment.expire.pre_transition' => ['onExpireTransition', -100], + 'commerce_payment.authorize_capture.pre_transition' => ['onAuthorizeCaptureTransition', -100], + PaymentEvents::PAYMENT_AUTHORIZED => ['onAuthorize', -100], + PaymentEvents::PAYMENT_VOIDED => ['onVoid', -100], + PaymentEvents::PAYMENT_EXPIRED => ['onExpire', -100], + PaymentEvents::PAYMENT_AUTHORIZED_CAPTURED => ['onAuthorizeCapture', -100], + PaymentEvents::PAYMENT_PARTIALLY_CAPTURED => ['onPartialCapture', -100], + PaymentEvents::PAYMENT_CAPTURED => ['onCapture', -100], + PaymentEvents::PAYMENT_PARTIALLY_REFUNDED => ['onPartialRefund', -100], + PaymentEvents::PAYMENT_REFUNDED => ['onRefund', -100], + ]; + return $events; + } + + /** + * Creates a log when a payment is authorized. + * + * @param \Drupal\state_machine\Event\WorkflowTransitionEvent $event + * The transition event. + */ + public function onAuthorizeTransition(WorkflowTransitionEvent $event) { + $this->dispatch(PaymentEvents::PAYMENT_AUTHORIZED, $event->getEntity()); + } + + /** + * Creates a log when a payment is voided. + * + * @param \Drupal\state_machine\Event\WorkflowTransitionEvent $event + * The transition event. + */ + public function onVoidTransition(WorkflowTransitionEvent $event) { + $this->dispatch(PaymentEvents::PAYMENT_VOIDED, $event->getEntity()); + } + + /** + * Creates a log when a payment is expired. + * + * @param \Drupal\state_machine\Event\WorkflowTransitionEvent $event + * The transition event. + */ + public function onExpireTransition(WorkflowTransitionEvent $event) { + $this->dispatch(PaymentEvents::PAYMENT_EXPIRED, $event->getEntity()); + } + + /** + * Creates a log when a payment is authorized and captured. + * + * @param \Drupal\state_machine\Event\WorkflowTransitionEvent $event + * The transition event. + */ + public function onAuthorizeCaptureTransition(WorkflowTransitionEvent $event) { + $this->dispatch(PaymentEvents::PAYMENT_AUTHORIZED_CAPTURED, $event->getEntity()); + } + + /** + * Dispatches a PaymentEvent for a payment. + * + * @param string $event_name + * A name of the payment event to dispatch. + * @param \Drupal\commerce_payment\Entity\PaymentInterface $payment + * A payment to use for dispatching the event. + */ + private function dispatch($event_name, PaymentInterface $payment) { + /** @var \Drupal\commerce_payment\Event\PaymentEvent $event */ + $event = new PaymentEvent($payment); + /** @var \Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher $event_dispatcher */ + $event_dispatcher = \Drupal::service('event_dispatcher'); + $event_dispatcher->dispatch($event_name, $event); + } + + /** + * Creates a log when a payment is authorized. + * + * @param \Drupal\commerce_payment\Event\PaymentEvent $event + * The payment event. + */ + public function onAuthorize(PaymentEvent $event) { + $payment = $event->getPayment(); + $this->logStorage->generate($payment, 'payment_authorized', [ + 'payment_remote_id' => $payment->getRemoteId(), + ])->save(); + } + + /** + * Creates a log when a payment is voided. + * + * @param \Drupal\commerce_payment\Event\PaymentEvent $event + * The payment event. + */ + public function onVoid(PaymentEvent $event) { + $payment = $event->getPayment(); + $this->logStorage->generate($payment, 'payment_voided', [ + 'payment_remote_id' => $payment->getRemoteId(), + ])->save(); + } + + /** + * Creates a log when a payment is expired. + * + * @param \Drupal\commerce_payment\Event\PaymentEvent $event + * The payment event. + */ + public function onExpire(PaymentEvent $event) { + $payment = $event->getPayment(); + $this->logStorage->generate($payment, 'payment_expired', [ + 'payment_remote_id' => $payment->getRemoteId(), + ])->save(); + } + + /** + * Creates a log when a payment is authorized and captured. + * + * @param \Drupal\commerce_payment\Event\PaymentEvent $event + * The payment event. + */ + public function onAuthorizeCapture(PaymentEvent $event) { + $payment = $event->getPayment(); + $this->logStorage->generate($payment, 'payment_authorized_captured', [ + 'payment_remote_id' => $payment->getRemoteId(), + ])->save(); + } + + /** + * Creates a log when a payment is partially captured. + * + * @param \Drupal\commerce_payment\Event\PaymentEvent $event + * The payment event. + */ + public function onPartialCapture(PaymentEvent $event) { + $payment = $event->getPayment(); + $this->logStorage->generate($payment, 'payment_partially_captured', [ + 'payment_remote_id' => $payment->getRemoteId(), + 'captured_amount' => $event->getAmount(), + ])->save(); + } + + /** + * Creates a log when a payment is fully captured. + * + * @param \Drupal\commerce_payment\Event\PaymentEvent $event + * The payment event. + */ + public function onCapture(PaymentEvent $event) { + $payment = $event->getPayment(); + $this->logStorage->generate($payment, 'payment_captured', [ + 'payment_remote_id' => $payment->getRemoteId(), + ])->save(); + } + + /** + * Creates a log when a payment is partially refunded. + * + * @param \Drupal\commerce_payment\Event\PaymentEvent $event + * The payment event. + */ + public function onPartialRefund(PaymentEvent $event) { + $payment = $event->getPayment(); + $this->logStorage->generate($payment, 'payment_partially_refunded', [ + 'payment_remote_id' => $payment->getRemoteId(), + 'refunded_amount' => $event->getAmount(), + ])->save(); + } + + /** + * Creates a log when a payment is fully refunded. + * + * @param \Drupal\commerce_payment\Event\PaymentEvent $event + * The payment event. + */ + public function onRefund(PaymentEvent $event) { + $payment = $event->getPayment(); + $this->logStorage->generate($payment, 'payment_refunded', [ + 'payment_remote_id' => $payment->getRemoteId(), + ])->save(); + } + +} diff --git a/modules/payment/src/Entity/Payment.php b/modules/payment/src/Entity/Payment.php index 84ecb0d640..1ac7549bcd 100644 --- a/modules/payment/src/Entity/Payment.php +++ b/modules/payment/src/Entity/Payment.php @@ -24,6 +24,7 @@ * bundle_plugin_type = "commerce_payment_type", * handlers = { * "access" = "Drupal\commerce_payment\PaymentAccessControlHandler", + * "event" = "Drupal\commerce_payment\Event\PaymentEvent", * "list_builder" = "Drupal\commerce_payment\PaymentListBuilder", * "storage" = "Drupal\commerce_payment\PaymentStorage", * "form" = { diff --git a/modules/payment/src/Event/PaymentEvent.php b/modules/payment/src/Event/PaymentEvent.php new file mode 100644 index 0000000000..73c874916d --- /dev/null +++ b/modules/payment/src/Event/PaymentEvent.php @@ -0,0 +1,68 @@ +payment = $payment; + } + + /** + * @param \Drupal\commerce_price\Price $amount + * The payment operation amount. + */ + public function setAmount(Price $amount) { + $this->amount = $amount; + } + + /** + * Gets the payment operation amount. + * + * @return \Drupal\commerce_price\Price + * The payment operation amount. + */ + public function getAmount() { + return $this->amount; + } + + /** + * Gets the payment. + * + * @return \Drupal\commerce_payment\Entity\PaymentInterface + * The payment. + */ + public function getPayment() { + return $this->payment; + } + +} diff --git a/modules/payment/src/Event/PaymentEvents.php b/modules/payment/src/Event/PaymentEvents.php new file mode 100644 index 0000000000..d88a976409 --- /dev/null +++ b/modules/payment/src/Event/PaymentEvents.php @@ -0,0 +1,144 @@ +plugin; $payment_gateway_plugin->capturePayment($payment, $amount); + + /** @var \Drupal\commerce_payment\Event\PaymentEvent $event */ + $event = new PaymentEvent($payment); + $event->setAmount($amount); + /** @var \Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher $event_dispatcher */ + $event_dispatcher = \Drupal::service('event_dispatcher'); + $event_name = ($payment->getOrder()->getTotalPrice()->greaterThan($payment->getAmount())) ? PaymentEvents::PAYMENT_PARTIALLY_CAPTURED : PaymentEvents::PAYMENT_CAPTURED; + $event_dispatcher->dispatch($event_name, $event); } } diff --git a/modules/payment/src/PluginForm/PaymentRefundForm.php b/modules/payment/src/PluginForm/PaymentRefundForm.php index 1a580fd268..c4150770ed 100644 --- a/modules/payment/src/PluginForm/PaymentRefundForm.php +++ b/modules/payment/src/PluginForm/PaymentRefundForm.php @@ -2,6 +2,8 @@ namespace Drupal\commerce_payment\PluginForm; +use Drupal\commerce_payment\Event\PaymentEvent; +use Drupal\commerce_payment\Event\PaymentEvents; use Drupal\commerce_price\Price; use Drupal\Core\Form\FormStateInterface; @@ -50,6 +52,14 @@ public function submitConfigurationForm(array &$form, FormStateInterface $form_s /** @var \Drupal\commerce_payment\Plugin\Commerce\PaymentGateway\SupportsRefundsInterface $payment_gateway_plugin */ $payment_gateway_plugin = $this->plugin; $payment_gateway_plugin->refundPayment($payment, $amount); + + /** @var \Drupal\commerce_payment\Event\PaymentEvent $event */ + $event = new PaymentEvent($payment); + $event->setAmount($amount); + /** @var \Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher $event_dispatcher */ + $event_dispatcher = \Drupal::service('event_dispatcher'); + $event_name = ($payment->getBalance()->isZero()) ? PaymentEvents::PAYMENT_REFUNDED : PaymentEvents::PAYMENT_PARTIALLY_REFUNDED; + $event_dispatcher->dispatch($event_name, $event); } }