diff --git a/modules/promotion/src/Plugin/Commerce/PromotionCondition/OrderTotalItems.php b/modules/promotion/src/Plugin/Commerce/PromotionCondition/OrderTotalItems.php new file mode 100644 index 0000000000..95478c4c1d --- /dev/null +++ b/modules/promotion/src/Plugin/Commerce/PromotionCondition/OrderTotalItems.php @@ -0,0 +1,105 @@ + NULL, + 'operator' => '>=', + ] + parent::defaultConfiguration(); + } + + /** + * {@inheritdoc} + */ + public function buildConfigurationForm(array $form, FormStateInterface $form_state) { + $form = parent::buildConfigurationForm($form, $form_state); + + $form['operator'] = [ + '#type' => 'select', + '#title' => t('Operator'), + '#options' => $this->getComparisonOperators(), + '#default_value' => $this->configuration['operator'], + '#required' => TRUE, + ]; + $form['qty'] = [ + '#type' => 'number', + '#step' => 1, + '#title' => t('Quantity'), + '#default_value' => $this->configuration['qty'], + '#required' => TRUE, + ]; + + return $form; + } + + /** + * {@inheritdoc} + */ + public function submitConfigurationForm(array &$form, FormStateInterface $form_state) { + parent::submitConfigurationForm($form, $form_state); + + $values = $form_state->getValue($form['#parents']); + $this->configuration['qty'] = $values['qty']; + $this->configuration['operator'] = $values['operator']; + } + + /** + * {@inheritdoc} + */ + public function evaluate() { + $qty = $this->configuration['qty']; + /** @var \Drupal\commerce_order\Entity\OrderInterface $order */ + $order = $this->getTargetEntity(); + $total_items = 0; + foreach ($order->getItems() as $item) { + $total_items += (int) $item->getQuantity(); + } + + switch ($this->configuration['operator']) { + case '>=': + return $total_items >= $qty; + + case '>': + return $total_items > $qty; + + case '<=': + return $total_items <= $qty; + + case '<': + return $total_items < $qty; + + case '==': + return $total_items == $qty; + + default: + return FALSE; + } + + } + + /** + * {@inheritdoc} + */ + public function summary() { + return $this->t('Compares the total quantity of order items.'); + } + +} diff --git a/modules/promotion/tests/src/Kernel/PromotionConditionTest.php b/modules/promotion/tests/src/Kernel/PromotionConditionTest.php index 865bfde37e..b0058bd3be 100644 --- a/modules/promotion/tests/src/Kernel/PromotionConditionTest.php +++ b/modules/promotion/tests/src/Kernel/PromotionConditionTest.php @@ -158,6 +158,76 @@ public function testOrderTotal() { $this->assertFalse($result); } + /** + * Tests the order total items condition. + */ + public function testOrderTotalItems() { + // Use addOrderItem so the total is calculated. + $order_item = OrderItem::create([ + 'type' => 'test', + 'quantity' => 10, + 'unit_price' => [ + 'number' => '10.00', + 'currency_code' => 'USD', + ], + ]); + $order_item->save(); + $this->order->addItem($order_item); + + // Starts now, enabled. No end time. + $promotion = Promotion::create([ + 'name' => 'Promotion 1', + 'order_types' => [$this->order->bundle()], + 'stores' => [$this->store->id()], + 'status' => TRUE, + 'offer' => [ + 'target_plugin_id' => 'commerce_promotion_order_percentage_off', + 'target_plugin_configuration' => [ + 'amount' => '0.10', + ], + ], + 'conditions' => [ + [ + 'target_plugin_id' => 'commerce_promotion_order_total_items', + 'target_plugin_configuration' => [ + 'qty' => '10', + 'operator' => '>=', + ], + ], + ], + ]); + $promotion->save(); + + $result = $promotion->applies($this->order); + $this->assertTrue($result); + + $promotion = Promotion::create([ + 'name' => 'Promotion 1', + 'order_types' => [$this->order->bundle()], + 'stores' => [$this->store->id()], + 'status' => TRUE, + 'offer' => [ + 'target_plugin_id' => 'commerce_promotion_order_percentage_off', + 'target_plugin_configuration' => [ + 'amount' => '0.10', + ], + ], + 'conditions' => [ + [ + 'target_plugin_id' => 'commerce_promotion_order_total_items', + 'target_plugin_configuration' => [ + 'qty' => '11', + 'operator' => '>=', + ], + ], + ], + ]); + $promotion->save(); + + $result = $promotion->applies($this->order); + $this->assertFalse($result); + } + /** * Tests the specific SKU test condition. */