Skip to content

Commit 14ce9da

Browse files
committed
Issue #2893367 by bojanz: The Product: Quantity condition doesn't take into account non-combined order items (part 1)
1 parent 30337cc commit 14ce9da

3 files changed

Lines changed: 52 additions & 30 deletions

File tree

modules/order/src/Plugin/Commerce/Condition/OrderItemQuantity.php

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,21 @@
33
namespace Drupal\commerce_order\Plugin\Commerce\Condition;
44

55
use Drupal\commerce\Plugin\Commerce\Condition\ConditionBase;
6+
use Drupal\commerce_price\Calculator;
67
use Drupal\Core\Entity\EntityInterface;
78
use Drupal\Core\Form\FormStateInterface;
89

910
/**
10-
* Provides the quantity condition for order items.
11+
* Provides the total product quantity condition.
12+
*
13+
* Implemented as an order condition to be able to count products across
14+
* non-combined order items.
1115
*
1216
* @CommerceCondition(
1317
* id = "order_item_quantity",
14-
* label = @Translation("Quantity"),
15-
* display_label = @Translation("Total product quantity"),
18+
* label = @Translation("Total product quantity"),
1619
* category = @Translation("Order"),
17-
* entity_type = "commerce_order_item",
20+
* entity_type = "commerce_order",
1821
* )
1922
*/
2023
class OrderItemQuantity extends ConditionBase {
@@ -69,9 +72,13 @@ public function submitConfigurationForm(array &$form, FormStateInterface $form_s
6972
*/
7073
public function evaluate(EntityInterface $entity) {
7174
$this->assertEntity($entity);
72-
/** @var \Drupal\commerce_order\Entity\OrderItemInterface $order_item */
73-
$order_item = $entity;
74-
$quantity = $order_item->getQuantity();
75+
/** @var \Drupal\commerce_order\Entity\OrderInterface $order */
76+
$order = $entity;
77+
$quantity = '0';
78+
foreach ($order->getItems() as $order_item) {
79+
// @todo Filter by offer conditions here, once available.
80+
$quantity = Calculator::add($quantity, $order_item->getQuantity());
81+
}
7582

7683
switch ($this->configuration['operator']) {
7784
case '>=':

modules/order/tests/src/Unit/Plugin/Commerce/Condition/OrderItemQuantityTest.php

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace Drupal\Tests\commerce_order\Unit\Plugin\Commerce\Condition;
44

5+
use Drupal\commerce_order\Entity\OrderInterface;
56
use Drupal\commerce_order\Entity\OrderItemInterface;
67
use Drupal\commerce_order\Plugin\Commerce\Condition\OrderItemQuantity;
78
use Drupal\Tests\UnitTestCase;
@@ -21,13 +22,17 @@ public function testEvaluate($operator, $quantity, $given_quantity, $result) {
2122
$condition = new OrderItemQuantity([
2223
'operator' => $operator,
2324
'quantity' => $quantity,
24-
], 'order_item_quantity', ['entity_type' => 'commerce_order_item']);
25+
], 'order_item_quantity', ['entity_type' => 'commerce_order']);
2526
$order_item = $this->prophesize(OrderItemInterface::class);
2627
$order_item->getEntityTypeId()->willReturn('commerce_order_item');
2728
$order_item->getQuantity()->willReturn($given_quantity);
2829
$order_item = $order_item->reveal();
30+
$order = $this->prophesize(OrderInterface::class);
31+
$order->getEntityTypeId()->willReturn('commerce_order');
32+
$order->getItems()->willReturn([$order_item]);
33+
$order = $order->reveal();
2934

30-
$this->assertEquals($result, $condition->evaluate($order_item));
35+
$this->assertEquals($result, $condition->evaluate($order));
3136
}
3237

3338
/**

tests/src/Unit/ConditionGroupTest.php

Lines changed: 31 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,9 @@
33
namespace Drupal\Tests\commerce\Unit;
44

55
use Drupal\commerce\ConditionGroup;
6-
use Drupal\commerce_order\Entity\OrderItemInterface;
7-
use Drupal\commerce_order\Plugin\Commerce\Condition\OrderItemQuantity;
6+
use Drupal\commerce_order\Entity\OrderInterface;
7+
use Drupal\commerce_order\Plugin\Commerce\Condition\OrderTotalPrice;
8+
use Drupal\commerce_price\Price;
89
use Drupal\Tests\UnitTestCase;
910

1011
/**
@@ -28,10 +29,13 @@ public function testInvalidOperator() {
2829
*/
2930
public function testGetters() {
3031
$conditions = [];
31-
$conditions[] = new OrderItemQuantity([
32+
$conditions[] = new OrderTotalPrice([
3233
'operator' => '>',
33-
'quantity' => '10',
34-
], 'order_item_quantity', []);
34+
'amount' => [
35+
'number' => '10',
36+
'currency_code' => 'USD',
37+
],
38+
], 'order_total_price', ['entity_type' => 'commerce_order']);
3539

3640
$condition_group = new ConditionGroup($conditions, 'AND');
3741
$this->assertEquals($conditions, $condition_group->getConditions());
@@ -43,33 +47,39 @@ public function testGetters() {
4347
*/
4448
public function testEvaluate() {
4549
$conditions = [];
46-
$conditions[] = new OrderItemQuantity([
50+
$conditions[] = new OrderTotalPrice([
4751
'operator' => '>',
48-
'quantity' => '10',
49-
], 'order_item_quantity', ['entity_type' => 'commerce_order_item']);
50-
$conditions[] = new OrderItemQuantity([
52+
'amount' => [
53+
'number' => '10',
54+
'currency_code' => 'USD',
55+
],
56+
], 'order_total_price', ['entity_type' => 'commerce_order']);
57+
$conditions[] = new OrderTotalPrice([
5158
'operator' => '<',
52-
'quantity' => '100',
53-
], 'order_item_quantity', ['entity_type' => 'commerce_order_item']);
54-
$first_order_item = $this->prophesize(OrderItemInterface::class);
55-
$first_order_item->getEntityTypeId()->willReturn('commerce_order_item');
56-
$first_order_item->getQuantity()->willReturn(101);
57-
$first_order_item = $first_order_item->reveal();
59+
'amount' => [
60+
'number' => '100',
61+
'currency_code' => 'USD',
62+
],
63+
], 'order_total_price', ['entity_type' => 'commerce_order']);
64+
$first_order = $this->prophesize(OrderInterface::class);
65+
$first_order->getEntityTypeId()->willReturn('commerce_order');
66+
$first_order->getTotalPrice()->willReturn(new Price('101', 'USD'));
67+
$first_order = $first_order->reveal();
5868

59-
$second_order_item = $this->prophesize(OrderItemInterface::class);
60-
$second_order_item->getEntityTypeId()->willReturn('commerce_order_item');
61-
$second_order_item->getQuantity()->willReturn(90);
69+
$second_order_item = $this->prophesize(OrderInterface::class);
70+
$second_order_item->getEntityTypeId()->willReturn('commerce_order');
71+
$second_order_item->getTotalPrice()->willReturn(new Price('90', 'USD'));
6272
$second_order_item = $second_order_item->reveal();
6373

6474
$empty_condition_group = new ConditionGroup([], 'AND');
65-
$this->assertTrue($empty_condition_group->evaluate($first_order_item));
75+
$this->assertTrue($empty_condition_group->evaluate($first_order));
6676

6777
$and_condition_group = new ConditionGroup($conditions, 'AND');
68-
$this->assertFalse($and_condition_group->evaluate($first_order_item));
78+
$this->assertFalse($and_condition_group->evaluate($first_order));
6979
$this->assertTrue($and_condition_group->evaluate($second_order_item));
7080

7181
$or_condition_group = new ConditionGroup($conditions, 'OR');
72-
$this->assertTrue($or_condition_group->evaluate($first_order_item));
82+
$this->assertTrue($or_condition_group->evaluate($first_order));
7383
$this->assertTrue($or_condition_group->evaluate($second_order_item));
7484
}
7585

0 commit comments

Comments
 (0)