diff --git a/commerce_quote_cart.info.yml b/commerce_quote_cart.info.yml index 36ca473..3e55c54 100644 --- a/commerce_quote_cart.info.yml +++ b/commerce_quote_cart.info.yml @@ -3,7 +3,12 @@ type: module description: 'Supports quote items for Drupal Commerce.' version: 8.x-1.x core: 8.x +core_version_requirement: ^8 || ^9 package: Commerce dependencies: - commerce_cart + - commerce_checkout + - commerce_order - commerce_product + - commerce_shipping + - hook_event_dispatcher diff --git a/commerce_quote_cart.module b/commerce_quote_cart.module index 61fb9a3..ebeafff 100644 --- a/commerce_quote_cart.module +++ b/commerce_quote_cart.module @@ -1,9 +1,11 @@ getEntity(); - $order_item->set('field_quote', ['value' => "1"]); + $order_item->set('quote', ['value' => "1"]); $addToCartForm->submitForm($form, $form_state); } @@ -82,7 +84,7 @@ function commerce_quote_cart_submit_quote(array &$form, FormStateInterface $form * Implements hook_preprocess_block(). */ function commerce_quote_cart_preprocess_block(&$variables) { - if (in_array($variables['elements']['#id'], ['product_variations', 'product_variations_mobile'])) { + if (isset($variables['elements']['#id']) && in_array($variables['elements']['#id'], ['product_variations', 'product_variations_mobile'])) { $variables['label'] = commerce_quote_cart_block_label($variables); } @@ -147,7 +149,7 @@ function commerce_quote_cart_block_label($variables) { } function commerce_quote_cart_product_is_purchasable(ProductInterface $product) { - $purchasableField = 'field_available_for_purchase'; + $purchasableField = 'available_for_purchase'; $variations = $product->getVariations(); $purchasable = FALSE; @@ -168,8 +170,8 @@ function commerce_quote_cart_preprocess_field(&$variables) { /** @var FieldableEntityInterface $entity */ $entity = $variables['element']['#object']; - $purchasable = 'field_available_for_purchase'; - $quotable = 'field_available_for_quote'; + $purchasable = 'available_for_purchase'; + $quotable = 'available_for_quote'; if ($entity->hasField($purchasable) && !$entity->get($purchasable)->value) { if (isset($variables['items'][0])) { @@ -242,3 +244,73 @@ function commerce_quote_cart_ga_push_add_alter(&$push_params, $type = GA_PUSH_TY $push_params['params'] = NULL; } } + +/** + * Implements hook_entity_base_field_info(). + * + * Provides base fields for quote, purchase. + */ +function commerce_quote_cart_entity_base_field_info(EntityTypeInterface $entity_type) { + // Add base fields to commerce_order. + if ($entity_type->id() === 'commerce_order') { + $fields['quote'] = BaseFieldDefinition::create('boolean') + ->setLabel(t('Quote')) + ->setDisplayConfigurable('form', TRUE) + ->setDisplayOptions('form', [ + 'type' => 'boolean_checkbox', + 'settings' => [ + 'display_label' => TRUE, + ] + ]) + ->setDisplayConfigurable('view', TRUE); + $fields['purchase'] = BaseFieldDefinition::create('boolean') + ->setLabel(t('Purchase')) + ->setDisplayConfigurable('form', TRUE) + ->setDisplayOptions('form', [ + 'type' => 'boolean_checkbox', + 'settings' => [ + 'display_label' => TRUE, + ] + ]) + ->setDisplayConfigurable('view', TRUE); + return $fields; + } + // Add base field to commerce_order_item. + if ($entity_type->id() === 'commerce_order_item') { + $fields['quote'] = BaseFieldDefinition::create('boolean') + ->setLabel(t('Quote')) + ->setDisplayConfigurable('form', TRUE) + ->setDisplayOptions('form', [ + 'type' => 'boolean_checkbox', + 'settings' => [ + 'display_label' => TRUE, + ] + ]) + ->setDisplayConfigurable('view', TRUE); + return $fields; + } + // Add base fields to commerce_product_variation. + if ($entity_type->id() === 'commerce_product_variation') { + $fields['available_for_purchase'] = BaseFieldDefinition::create('boolean') + ->setLabel(t('Available for Purchase')) + ->setDisplayConfigurable('form', TRUE) + ->setDisplayOptions('form', [ + 'type' => 'boolean_checkbox', + 'settings' => [ + 'display_label' => TRUE, + ] + ]) + ->setDisplayConfigurable('view', TRUE); + $fields['available_for_quote'] = BaseFieldDefinition::create('boolean') + ->setLabel(t('Available for Quote')) + ->setDisplayConfigurable('form', TRUE) + ->setDisplayOptions('form', [ + 'type' => 'boolean_checkbox', + 'settings' => [ + 'display_label' => TRUE, + ] + ]) + ->setDisplayConfigurable('view', TRUE); + return $fields; + } +} diff --git a/src/EventSubscriber/CommerceQuoteCartSubscriber.php b/src/EventSubscriber/CommerceQuoteCartSubscriber.php index b00f016..2a6a801 100644 --- a/src/EventSubscriber/CommerceQuoteCartSubscriber.php +++ b/src/EventSubscriber/CommerceQuoteCartSubscriber.php @@ -5,7 +5,6 @@ use Drupal\commerce_cart\Event\CartEntityAddEvent; use Drupal\commerce_cart\Event\CartOrderItemRemoveEvent; use Drupal\commerce_cart\Event\CartOrderItemUpdateEvent; -use Drupal\commerce_fedex\Event\CommerceFedExEvents; use Drupal\commerce_order\Entity\OrderInterface; use Drupal\commerce_order\Event\OrderEvents; use Drupal\commerce_order\Event\OrderItemEvent; @@ -14,17 +13,29 @@ use Drupal\commerce_shipping\Event\BeforePackEvent; use Drupal\commerce_shipping\Event\CommerceShippingEvents; use Drupal\Core\StringTranslation\StringTranslationTrait; -use Drupal\hook_event_dispatcher\Event\Form\FormAlterEvent; -use Drupal\hook_event_dispatcher\HookEventDispatcherEvents; +use Drupal\core_event_dispatcher\Event\Form\FormAlterEvent; +use Drupal\hook_event_dispatcher\HookEventDispatcherInterface; use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Drupal\commerce_cart\Event\CartEvents; use Drupal\commerce_cart\Event\OrderItemComparisonFieldsEvent; +/** + * Class CommerceQuoteCartSubscriber. + * + * @package Drupal\commerce_quote_cart\EventSubscriber + */ class CommerceQuoteCartSubscriber implements EventSubscriberInterface { use StringTranslationTrait; - private $quoteField = 'field_quote'; - private $purchaseField = 'field_purchase'; + /** + * @var string + */ + private $quoteField = 'quote'; + + /** + * @var string + */ + private $purchaseField = 'purchase'; /** * {@inheritdoc} @@ -36,19 +47,19 @@ public static function getSubscribedEvents() { $events[OrderEvents::ORDER_ITEM_PRESAVE][] = ['onOrderItemPresave']; $events[OrderEvents::ORDER_ITEM_CREATE][] = ['onOrderItemCreate']; $events[CommerceShippingEvents::BEFORE_PACK][] = ['onBeforePack']; - $events[CommerceFedExEvents::BEFORE_PACK][] = ['onBeforePackFedEx']; $events[CartEvents::CART_ENTITY_ADD][] = ['onCartEntityAdd']; $events[CartEvents::CART_ORDER_ITEM_UPDATE][] = ['onCartOrderItemUpdate']; $events[CartEvents::CART_ORDER_ITEM_REMOVE][] = ['onCartOrderItemRemove']; - $events[HookEventDispatcherEvents::FORM_ALTER][] = ['alterCheckoutForm', -10]; - $events[HookEventDispatcherEvents::FORM_ALTER][] = ['alterCartForm']; - $events[HookEventDispatcherEvents::FORM_ALTER][] = ['alterAddToCartForm']; + $events[HookEventDispatcherInterface::FORM_ALTER][] = ['alterCheckoutForm', -10]; + $events[HookEventDispatcherInterface::FORM_ALTER][] = ['alterCartForm']; + $events[HookEventDispatcherInterface::FORM_ALTER][] = ['alterAddToCartForm']; return $events; } /** - * @param FormAlterEvent $event + * @param \Drupal\core_event_dispatcher\Event\Form\FormAlterEvent $event + * The form alter event. * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException */ public function alterAddToCartForm(FormAlterEvent $event) { @@ -64,8 +75,8 @@ public function alterAddToCartForm(FormAlterEvent $event) { return; } - $availableForQuote = $variation->get('field_available_for_quote')->value || QuoteCartHelper::hasQuoteCart(); - $availableForPurchase = $variation->get('field_available_for_purchase')->value; + $availableForQuote = $variation->get('available_for_quote')->value || QuoteCartHelper::hasQuoteCart(); + $availableForPurchase = $variation->get('available_for_purchase')->value; $form['actions']['submit']['#access'] = (bool) $availableForPurchase; @@ -87,9 +98,13 @@ public function alterAddToCartForm(FormAlterEvent $event) { $form['#after_build'][] = 'commerce_quote_cart_set_triggering_element'; - $event->setForm($form); + // $event->setForm($form); } + /** + * @param \Drupal\core_event_dispatcher\Event\Form\FormAlterEvent $event + * The form alter event. + */ public function alterCartForm(FormAlterEvent $event) { $form_id = $event->getFormId(); @@ -122,11 +137,12 @@ public function alterCartForm(FormAlterEvent $event) { } } - $event->setForm($form); + // $event->setForm($form); } /** - * @param \Drupal\hook_event_dispatcher\Event\Form\FormAlterEvent $event + * @param \Drupal\core_event_dispatcher\Event\Form\FormAlterEvent $event + * The form alter event. */ public function alterCheckoutForm(FormAlterEvent $event) { $form_id = $event->getFormId(); @@ -135,7 +151,7 @@ public function alterCheckoutForm(FormAlterEvent $event) { return; } - $form = $event->getForm(); + $form = &$event->getForm(); $is_quote = !QuoteCartHelper::isPurchaseCart(); $label = $is_quote ? 'Quote' : 'Order'; $shipping_label = $is_quote ? 'Contact' : 'Shipping'; @@ -145,10 +161,10 @@ public function alterCheckoutForm(FormAlterEvent $event) { } if (isset($form['shipping_information'])) { - $form['shipping_information']['#title'] = t($shipping_label . ' Information'); + $form['shipping_information']['#title'] = t('@shipping_label Information', ['@shipping_label' => $shipping_label]); $form['#attached']['library'][] = 'commerce_quote_cart/shipping-information'; - // Hide shipping information for quote orders + // Hide shipping information for quote orders. if (isset($form['shipping_information']['shipments']) && $is_quote) { $form['shipping_information']['shipments']['#attributes']['class'][] = 'js-hide'; } @@ -163,7 +179,7 @@ public function alterCheckoutForm(FormAlterEvent $event) { $nextValue = $form['actions']['next']['#value']; if (strtolower($nextValue->getUntranslatedString()) == 'pay and complete purchase') { - $form['actions']['next']['#value'] = t('Complete ' . strtolower($label)); + $form['actions']['next']['#value'] = t('Complete @label', ['@label' => strtolower($label)]); } } @@ -172,32 +188,47 @@ public function alterCheckoutForm(FormAlterEvent $event) { '#type' => 'container', '#weight' => -1, 'title' => [ - '#markup' => t("$label summary"), - ] + '#markup' => t("@label summary", ['@label' => $label]), + ], ]; } - $event->setForm($form); } + /** + * @param \Drupal\commerce_cart\Event\CartEntityAddEvent $event + * The cart entity add event. + */ public function onCartEntityAdd(CartEntityAddEvent $event) { $cart = $event->getCart(); $this->setOrderType($cart); $this->cleanOrderInfo($cart); } + /** + * @param \Drupal\commerce_cart\Event\CartOrderItemUpdateEvent $event + * The cart order item update event. + */ public function onCartOrderItemUpdate(CartOrderItemUpdateEvent $event) { $cart = $event->getCart(); $this->setOrderType($cart); $this->cleanOrderInfo($event->getCart()); } + /** + * @param \Drupal\commerce_cart\Event\CartOrderItemRemoveEvent $event + * The cart order item remove event. + */ public function onCartOrderItemRemove(CartOrderItemRemoveEvent $event) { $cart = $event->getCart(); $this->setOrderType($cart); $this->cleanOrderInfo($event->getCart()); } + /** + * @param \Drupal\commerce_order\Entity\OrderInterface $order + * The order interface. + */ public function setOrderType(OrderInterface $order) { if ($order->hasField($this->quoteField)) { $order->get($this->quoteField)->value = QuoteCartHelper::isQuoteCart($order); @@ -208,6 +239,10 @@ public function setOrderType(OrderInterface $order) { } } + /** + * @param \Drupal\commerce_order\Entity\OrderInterface $cart + * The order interface. + */ public function cleanOrderInfo(OrderInterface $cart) { // Don't do this if it's an order. if (QuoteCartHelper::isPurchaseCart($cart) || is_null($cart->getTotalPrice()) || $cart->getTotalPrice()->isZero()) { @@ -217,19 +252,29 @@ public function cleanOrderInfo(OrderInterface $cart) { $cart->clearAdjustments(); } + /** + * @param \Drupal\commerce_shipping\Event\BeforePackEvent $event + * The before pack event. + */ public function onBeforePack(BeforePackEvent $event) { $event->setOrderItems($this->filterQuoteItems($event->getOrder(), $event->getOrderItems())); } - public function onBeforePackFedEx(\Drupal\commerce_fedex\Event\BeforePackEvent $event) { - $event->setOrderItems($this->filterQuoteItems($event->getOrder(), $event->getOrderItems())); - } - + /** + * @param \Drupal\commerce_order\Entity\OrderInterface $order + * The order. + * @param array $items + * Array of quote order items. + * + * @return array + * $items + */ protected function filterQuoteItems(OrderInterface $order, array $items) { - // Only remove quote items from purchases, as we need as least one shippable item. + // Only remove quote items from purchases, as we need at least one shippable + // item. if (QuoteCartHelper::isPurchaseCart($order)) { foreach ($items as $id => $orderItem) { - if ($orderItem->hasField('field_quote') && $orderItem->get('field_quote')->value) { + if ($orderItem->hasField('quote') && $orderItem->get('quote')->value) { unset($items[$id]); } } @@ -238,6 +283,10 @@ protected function filterQuoteItems(OrderInterface $order, array $items) { return $items; } + /** + * @param \Drupal\commerce_cart\Event\OrderItemComparisonFieldsEvent $event + * The order item comparison fields event. + */ public function onOrderItemComparisonFields(OrderItemComparisonFieldsEvent $event) { $fields = $event->getComparisonFields(); @@ -246,6 +295,10 @@ public function onOrderItemComparisonFields(OrderItemComparisonFieldsEvent $even $event->setComparisonFields($fields); } + /** + * @param \Drupal\commerce_order\Event\OrderItemEvent $event + * The order item event. + */ public function onOrderItemPresave(OrderItemEvent $event) { $orderItem = $event->getOrderItem(); @@ -254,7 +307,12 @@ public function onOrderItemPresave(OrderItemEvent $event) { } } + /** + * @param \Drupal\commerce_order\Event\OrderItemEvent $event + * The order item event. + */ public function onOrderItemCreate(OrderItemEvent $event) { $event->getOrderItem()->set($this->quoteField, ['value' => "0"]); } + } diff --git a/src/Plugin/Commerce/CheckoutFlow/MultistepQuote.php b/src/Plugin/Commerce/CheckoutFlow/MultistepQuote.php index ccd35c9..fccef41 100644 --- a/src/Plugin/Commerce/CheckoutFlow/MultistepQuote.php +++ b/src/Plugin/Commerce/CheckoutFlow/MultistepQuote.php @@ -1,7 +1,12 @@ order->set('checkout_step', $step_id); + if ($step_id == 'complete') { + $transition = $this->order->getState()->getWorkflow()->getTransition('place'); + $this->order->getState()->applyTransition($transition); + } + $this->order->save(); + $url = Url::fromRoute('commerce_checkout.form', [ + 'commerce_order' => $this->order->id(), + 'step' => $step_id, + ], $this->getUrlOptions($step_id)); + throw new NeedsRedirectException($url->toString()); + } + + /** + * @param array $form + * @param \Drupal\Core\Form\FormStateInterface $form_state + */ + public function submitForm(array &$form, FormStateInterface $form_state) { + parent::submitForm($form, $form_state); + if ($next_step_id = $this->getNextStepId($form['#step_id'])) { + if ($next_step_id == 'complete') { + $form_state->setRedirect('commerce_checkout.form', [ + 'commerce_order' => $this->order->id(), + 'step' => $next_step_id, + ], $this->getUrlOptions($next_step_id)); + } + } + } + + /** + * @param $step_id + * + * @return array|\string[][] + */ + protected function getUrlOptions($step_id) { + $options = []; + if ($step_id == 'complete') { + $type = 'quote'; + if (QuoteCartHelper::isMixedCart($this->order)) { + $type = 'mixed'; + } elseif (QuoteCartHelper::isPurchaseCart($this->order)) { + $type = 'order'; + } + + $options = ['query' => ['type' => $type]]; + } + + return $options; + } } diff --git a/src/QuoteCartHelper.php b/src/QuoteCartHelper.php index fd2ce47..0ebd617 100644 --- a/src/QuoteCartHelper.php +++ b/src/QuoteCartHelper.php @@ -71,7 +71,7 @@ public static function isPurchaseCart(OrderInterface $cartOrder = NULL) { $isPurchaseCart = FALSE; - $field = 'field_quote'; + $field = 'quote'; /** @var OrderItemInterface $item */ foreach ($cartOrder->getItems() as $item) { @@ -99,7 +99,7 @@ public static function isQuoteCart(OrderInterface $cartOrder = NULL) { $isQuoteCart = FALSE; - $field = 'field_quote'; + $field = 'quote'; foreach ($cartOrder->getItems() as $item) { if ($item->hasField($field) && $item->get($field)->value) { @@ -116,7 +116,7 @@ public static function isQuoteCart(OrderInterface $cartOrder = NULL) { * @throws EntityStorageException */ public static function convertToQuote(OrderInterface $cartOrder) { - $field = 'field_quote'; + $field = 'quote'; $save = FALSE; foreach ($cartOrder->getItems() as $item) { @@ -137,7 +137,7 @@ public static function convertToQuote(OrderInterface $cartOrder) { } public static function isQuoteItem(OrderItemInterface $orderItem) { - $fieldName = 'field_quote'; + $fieldName = 'quote'; return ($orderItem->hasField($fieldName) && $orderItem->get($fieldName)->value); } @@ -147,7 +147,7 @@ public static function isQuoteItem(OrderItemInterface $orderItem) { * @throws EntityStorageException */ public static function convertItemToQuote(OrderItemInterface $item) { - $field = 'field_quote'; + $field = 'quote'; if (!$item->hasField($field)) { return;