Skip to content

Commit 26ef9ff

Browse files
zaporyliebojanz
authored andcommitted
Issue #3000882 by zaporylie, Adameue, bojanz: Newly added order item is not aggregated with existing order item if has an empty field
1 parent bc5c177 commit 26ef9ff

2 files changed

Lines changed: 34 additions & 8 deletions

File tree

modules/cart/src/OrderItemMatcher.php

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,12 +68,20 @@ public function matchAll(OrderItemInterface $order_item, array $order_items) {
6868
$matched_order_items = [];
6969
/** @var \Drupal\commerce_order\Entity\OrderItemInterface $existing_order_item */
7070
foreach ($order_items as $existing_order_item) {
71-
foreach ($comparison_fields as $comparison_field) {
72-
if (!$existing_order_item->hasField($comparison_field) || !$order_item->hasField($comparison_field)) {
71+
foreach ($comparison_fields as $field_name) {
72+
if (!$existing_order_item->hasField($field_name) || !$order_item->hasField($field_name)) {
7373
// The field is missing on one of the order items.
7474
continue 2;
7575
}
76-
if (!$existing_order_item->get($comparison_field)->equals($order_item->get($comparison_field))) {
76+
77+
$existing_order_item_field = $existing_order_item->get($field_name);
78+
$order_item_field = $order_item->get($field_name);
79+
// Two empty fields should be considered identical, but an empty item
80+
// can affect the comparison and cause a false mismatch.
81+
$existing_order_item_field = $existing_order_item_field->filterEmptyItems();
82+
$order_item_field = $order_item_field->filterEmptyItems();
83+
84+
if (!$existing_order_item_field->equals($order_item_field)) {
7785
// Order item doesn't match.
7886
continue 2;
7987
}

modules/cart/tests/src/Kernel/OrderItemMatcherTest.php

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,14 @@ public function testCustomField() {
226226
'field_custom_text' => 'Blue',
227227
]);
228228
$order_item3->save();
229+
$order_item4 = OrderItem::create([
230+
'type' => 'default',
231+
'quantity' => 4,
232+
'unit_price' => new Price('12.00', 'USD'),
233+
'purchased_entity' => $this->variation1,
234+
'field_custom_text' => '',
235+
]);
236+
$order_item4->save();
229237

230238
// Same purchased entity, different custom text, no match.
231239
$matches = $this->orderItemMatcher->matchAll($order_item1, [$order_item2]);
@@ -239,21 +247,31 @@ public function testCustomField() {
239247
$this->assertNotEmpty($match);
240248
$this->assertEquals($match, $order_item3);
241249

242-
// Item with missing custom text does not match.
243-
$order_item4 = OrderItem::create([
250+
// Item with missing custom text, no match.
251+
$order_item5 = OrderItem::create([
244252
'type' => 'default',
245253
'quantity' => 5,
246254
'unit_price' => new Price('12.00', 'USD'),
247255
'purchased_entity' => $this->variation1,
248256
]);
249-
$order_item4->save();
250-
251-
$matches = $this->orderItemMatcher->matchAll($order_item4, [
257+
$matches = $this->orderItemMatcher->matchAll($order_item5, [
252258
$order_item1,
253259
$order_item2,
254260
$order_item3,
255261
]);
256262
$this->assertEmpty($matches);
263+
264+
// Empty custom text on both sides, match.
265+
$order_item6 = OrderItem::create([
266+
'type' => 'default',
267+
'quantity' => 5,
268+
'unit_price' => new Price('12.00', 'USD'),
269+
'purchased_entity' => $this->variation1,
270+
'field_custom_text' => '',
271+
]);
272+
$match = $this->orderItemMatcher->match($order_item6, [$order_item4]);
273+
$this->assertNotEmpty($match);
274+
$this->assertEquals($match, $order_item4);
257275
}
258276

259277
}

0 commit comments

Comments
 (0)