public function BuyXGetYTest::testAutoAddOrderItem in Commerce Core 8.2
Tests the 'auto-add' offered item capability.
@covers ::apply
File
- modules/
promotion/ tests/ src/ Kernel/ Plugin/ Commerce/ PromotionOffer/ BuyXGetYTest.php, line 535
Class
- BuyXGetYTest
- Tests the "Buy X Get Y" offer.
Namespace
Drupal\Tests\commerce_promotion\Kernel\Plugin\Commerce\PromotionOfferCode
public function testAutoAddOrderItem() {
// Configure a "buy 3 of anything, get 1 specific product free" offer.
$offer = $this->promotion
->getOffer();
$offer_configuration = $offer
->getConfiguration();
// The customer purchases 3 quantities of any product.
$offer_configuration['buy_quantity'] = '3';
$offer_configuration['buy_conditions'] = [];
// The customer receives 1 specific product for free.
$offer_configuration['get_quantity'] = '1';
$offer_configuration['get_conditions'] = [
[
'plugin' => 'order_item_purchased_entity:commerce_product_variation',
'configuration' => [
'entities' => [
$this->variations[2]
->uuid(),
],
],
],
];
$offer_configuration['get_auto_add'] = TRUE;
$offer_configuration['offer_type'] = 'percentage';
$offer_configuration['offer_percentage'] = '1';
$offer_configuration['offer_amount'] = NULL;
$offer
->setConfiguration($offer_configuration);
$this->promotion
->setOffer($offer);
/** @var \Drupal\commerce_order\OrderItemStorageInterface $order_item_storage */
$order_item_storage = \Drupal::entityTypeManager()
->getStorage('commerce_order_item');
// Price of first order item: 10. Matches the first required quantity of the
// buy condition.
$first_order_item = $order_item_storage
->createFromPurchasableEntity($this->variations[0], [
'quantity' => '3',
]);
$this->order
->setItems([
$first_order_item,
]);
$this->order
->save();
$this->container
->get('commerce_order.order_refresh')
->refresh($this->order);
// The offer automatically added a second order item.
list($first_order_item, $second_order_item) = $this->order
->getItems();
$this
->assertCount(0, $first_order_item
->getAdjustments());
$this
->assertCount(1, $second_order_item
->getAdjustments());
$this
->assertEquals(1, $second_order_item
->getQuantity());
$this
->assertEquals($this->variations[2]
->id(), $second_order_item
->getPurchasedEntityId());
$this
->assertAdjustmentPrice($second_order_item
->getAdjustments()[0], '-30');
// Increase the quantity of the "buy" product to 4, the quantity of the
// offered product will not change.
$first_order_item
->setQuantity(4);
$this->order
->setItems([
$first_order_item,
$second_order_item,
]);
$this->order
->save();
$this->container
->get('commerce_order.order_refresh')
->refresh($this->order);
list($first_order_item, $second_order_item) = $this->order
->getItems();
$this
->assertCount(0, $first_order_item
->getAdjustments());
$this
->assertEquals(4, $first_order_item
->getQuantity());
$this
->assertCount(1, $second_order_item
->getAdjustments());
$this
->assertEquals(1, $second_order_item
->getQuantity());
// Increase the quantity of the "buy" product to 6, the quantity of the
// offered product will be increased to 2.
$first_order_item
->setQuantity(6);
$this->order
->setItems([
$first_order_item,
$second_order_item,
]);
$this->order
->save();
$this->container
->get('commerce_order.order_refresh')
->refresh($this->order);
list($first_order_item, $second_order_item) = $this->order
->getItems();
$this
->assertEquals(6, $first_order_item
->getQuantity());
$this
->assertCount(0, $first_order_item
->getAdjustments());
$this
->assertEquals(2, $second_order_item
->getQuantity());
$this
->assertCount(1, $second_order_item
->getAdjustments());
$this
->assertAdjustmentPrice($second_order_item
->getAdjustments()[0], '-60');
// Try to remove the "get" product from the order, it will be added back
// automatically.
$this->order
->removeItem($second_order_item);
$this
->assertCount(1, $this->order
->getItems());
$this->order
->save();
$this->container
->get('commerce_order.order_refresh')
->refresh($this->order);
list($first_order_item, $second_order_item) = $this->order
->getItems();
$this
->assertEquals(6, $first_order_item
->getQuantity());
$this
->assertEquals(2, $second_order_item
->getQuantity());
$this
->assertCount(1, $second_order_item
->getAdjustments());
$this
->assertAdjustmentPrice($second_order_item
->getAdjustments()[0], '-60');
// Decrease the quantity of the "buy" product from the order, the "get"
// quantity will be decreased and the discount will only be applied once.
$first_order_item
->setQuantity(5);
$this->order
->setItems([
$first_order_item,
$second_order_item,
]);
$this->order
->save();
$this->container
->get('commerce_order.order_refresh')
->refresh($this->order);
list($first_order_item, $second_order_item) = $this->order
->getItems();
$this
->assertEquals(5, $first_order_item
->getQuantity());
$this
->assertEquals(1, $second_order_item
->getQuantity());
$this
->assertCount(1, $second_order_item
->getAdjustments());
$this
->assertAdjustmentPrice($second_order_item
->getAdjustments()[0], '-30');
// Test that the order item data key holding the auto-added quantity is
// cleared when the get order item is no longer eligible for the offer, but
// extra quantity was added by the customer.
$this
->assertNotNull($second_order_item
->getData('promotion:1:auto_add_quantity'));
$second_order_item
->setQuantity('2');
$first_order_item
->setQuantity('1');
$this->container
->get('commerce_order.order_refresh')
->refresh($this->order);
list(, $second_order_item) = $this->order
->getItems();
$this
->assertNull($second_order_item
->getData('promotion:1:auto_add_quantity'));
$this
->assertEquals(1, $second_order_item
->getQuantity());
}