Skip to content
Open
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
527df0b
Disable expired promotions on cron run.
Apr 4, 2017
221cbd1
Merge branch '8.x-2.x' of https://github.com/swickham78/commerce into…
Apr 7, 2017
2b8f266
Issue #2863864: Moved max usage load of promotions to its own method …
Apr 7, 2017
caf23a5
Issue #2863864: Added tests for loading of expired and maxed usaged p…
Apr 7, 2017
863ce8f
Issue #2863864: Fix merge conflict w/ recent work.
Apr 7, 2017
24856a6
Merge branch '8.x-2.x' of https://github.com/swickham78/commerce into…
Apr 10, 2017
e7d8a40
Issue #2863864: Updates to meet coding standards.
Apr 10, 2017
0794a1b
Disable expired promotions on cron run.
Apr 4, 2017
e0f422f
Issue #2863864: Moved max usage load of promotions to its own method …
Apr 7, 2017
73e867a
Issue #2863864: Added tests for loading of expired and maxed usaged p…
Apr 7, 2017
70ce340
Issue #2863864: Updates to meet coding standards.
Apr 10, 2017
029e4c4
Added cron function test.
Jun 28, 2017
4cb8f54
Merge branch 'promotions_disable_expired' of https://github.com/swick…
Jun 28, 2017
a557186
Disable expired promotions on cron run.
Apr 4, 2017
f659ea1
Issue #2863864: Moved max usage load of promotions to its own method …
Apr 7, 2017
6bba454
Issue #2863864: Added tests for loading of expired and maxed usaged p…
Apr 7, 2017
4ac0f14
Issue #2863864: Updates to meet coding standards.
Apr 10, 2017
d3fda01
Issue #2863864: Moved max usage load of promotions to its own method …
Apr 7, 2017
9aef5f3
Issue #2863864: Updates to meet coding standards.
Apr 10, 2017
04ef19f
Added cron function test.
Jun 28, 2017
d5a4e42
Merge branch 'promotions_disable_expired' of https://github.com/swick…
Aug 11, 2017
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions modules/promotion/commerce_promotion.module
Original file line number Diff line number Diff line change
Expand Up @@ -79,3 +79,34 @@ function commerce_promotion_entity_base_field_info(EntityTypeInterface $entity_t
return $fields;
}
}

/**
* Implements hook_cron().
*/
function commerce_promotion_cron() {
/** @var \Drupal\commerce_promotion\PromotionStorageInterface $promotion_storage */
$promotion_storage = \Drupal::service('entity_type.manager')->getStorage('commerce_promotion');

// Disable any promotions that have passed their end date.
$promotions = $promotion_storage->loadExpired();

if (!empty($promotions)) {
/** @var \Drupal\commerce_promotion\Entity\PromotionInterface $promotion */
foreach ($promotions as $promotion) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bojanz I think this is fine versus a queue. There shouldn't be that much activity, generally.

$promotion->setEnabled(FALSE);
$promotion->save();
}
}

// Disable any promotions that have met their max usage.
$promotions = $promotion_storage->loadMaxedUsage();

if (!empty($promotions)) {
/** @var \Drupal\commerce_promotion\Entity\PromotionInterface $promotion */
foreach ($promotions as $promotion) {
$promotion->setEnabled(FALSE);
$promotion->save();
}
}

}
57 changes: 57 additions & 0 deletions modules/promotion/src/PromotionStorage.php
Original file line number Diff line number Diff line change
Expand Up @@ -104,4 +104,61 @@ public function loadAvailable(OrderTypeInterface $order_type, StoreInterface $st
return $promotions;
}

/**
* Return active promotions that have passed their end date.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Document blocks should only be on the interface, implementers just do {@inheritdoc}

*
* @return \Drupal\commerce_promotion\Entity\PromotionInterface[]
* The expired promotion entities.
*/
public function loadExpired() {
$query = $this->getQuery();

$query
->condition('end_date', gmdate('Y-m-d'), '<')
->condition('status', TRUE);

$result = $query->execute();

if (empty($result)) {
return [];
}

return $this->loadMultiple($result);
}

/**
* Returns active promotions which have a met their maximum usage.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Document blocks should only be on the interface, implementers just do {@inheritdoc}

*
* @return \Drupal\commerce_promotion\Entity\PromotionInterface[]
* Promotions with maxed usage.
*/
public function loadMaxedUsage() {
$query = $this->getQuery();

$query
->condition('usage_limit', 1, '>=')
->condition('status', TRUE);

$result = $query->execute();

if (empty($result)) {
return [];
}

$promotions = $this->loadMultiple($result);
$maxed_promotions = [];

// Get an array of each promotion's use count.
$promotion_uses = $this->usage->getUsageMultiple($promotions);

/** @var \Drupal\commerce_promotion\Entity\PromotionInterface $promotion */
foreach ($promotions as $promotion) {
if ($promotion_uses[$promotion->id()] >= $promotion->getUsageLimit()) {
$maxed_promotions[] = $promotion;
}
}

return $maxed_promotions;
}

}
16 changes: 16 additions & 0 deletions modules/promotion/src/PromotionStorageInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,20 @@ interface PromotionStorageInterface extends ContentEntityStorageInterface {
*/
public function loadAvailable(OrderTypeInterface $order_type, StoreInterface $store);

/**
* Return active promotions that have passed their end date.
*
* @return \Drupal\commerce_promotion\Entity\PromotionInterface[]
* The expired promotion entities.
*/
public function loadExpired();

/**
* Returns active promotions which have a met their maximum usage.
*
* @return \Drupal\commerce_promotion\Entity\PromotionInterface[]
* Promotions with maxed usage.
*/
public function loadMaxedUsage();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bojanz name bikeshedding.


}
95 changes: 95 additions & 0 deletions modules/promotion/tests/src/Kernel/PromotionStorageTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

namespace Drupal\Tests\commerce_promotion\Kernel;

use Drupal\commerce_order\Entity\Order;
use Drupal\commerce_order\Entity\OrderType;
use Drupal\commerce_order\Entity\OrderItemType;
use Drupal\commerce_promotion\Entity\Coupon;
use Drupal\commerce_promotion\Entity\Promotion;
use Drupal\Core\Datetime\DrupalDateTime;
Expand All @@ -22,6 +24,20 @@ class PromotionStorageTest extends CommerceKernelTestBase {
*/
protected $promotionStorage;

/**
* The usage.
*
* @var \Drupal\commerce_promotion\PromotionUsageInterface
*/
protected $usage;

/**
* The test order.
*
* @var \Drupal\commerce_order\Entity\OrderInterface
*/
protected $order;

/**
* Modules to enable.
*
Expand Down Expand Up @@ -54,6 +70,25 @@ protected function setUp() {
$this->installSchema('commerce_promotion', ['commerce_promotion_usage']);

$this->promotionStorage = $this->container->get('entity_type.manager')->getStorage('commerce_promotion');
$this->usage = $this->container->get('commerce_promotion.usage');

OrderItemType::create([
'id' => 'test',
'label' => 'Test',
'orderType' => 'default',
])->save();

$this->order = Order::create([
'type' => 'default',
'state' => 'completed',
'mail' => 'test@example.com',
'ip_address' => '127.0.0.1',
'order_id' => '6',
'order_number' => '6',
'store_id' => $this->store,
'uid' => $this->createUser()->id(),
'order_items' => [],
]);
}

/**
Expand Down Expand Up @@ -215,4 +250,64 @@ public function testWeight() {
$this->assertEquals($promotion1->label(), $promotion->label());
}

/**
* Tests that active promotions which have expired are loaded.
*/
public function testLoadExpired() {
$valid_promotion = Promotion::create([
'name' => 'Valid Promotion',
'status' => TRUE,
'start_date' => gmdate('Y-m-d', time()),
'end_date' => gmdate('Y-m-d', time() + 86400),
]);
$this->assertEquals(SAVED_NEW, $valid_promotion->save());

$expired_promotion = Promotion::create([
'name' => 'Expired Promotion',
'status' => TRUE,
'start_date' => gmdate('Y-m-d', time() - 172800),
'end_date' => gmdate('Y-m-d', time() - 86400),
]);
$this->assertEquals(SAVED_NEW, $expired_promotion->save());

$promotions = $this->promotionStorage->loadExpired();
$this->assertEquals(count($promotions), 1);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can do assertCount


$promotion = reset($promotions);
$this->assertEquals($expired_promotion->label(), $promotion->label());
}

/**
* Tests that active promotions which have met their maximum usage are loaded.
*/
public function testLoadUsed() {
$promotion1 = Promotion::create([
'name' => 'Promotion 1',
'status' => TRUE,
'usage_limit' => 1,
]);
$this->assertEquals(SAVED_NEW, $promotion1->save());
$this->usage->addUsage($this->order, $promotion1);

$promotion2 = Promotion::create([
'name' => 'Promotion 2',
'status' => TRUE,
'usage_limit' => 2,
]);
$this->assertEquals(SAVED_NEW, $promotion2->save());
$this->usage->addUsage($this->order, $promotion2);

$promotion3 = Promotion::create([
'name' => 'Promotion 3',
'status' => TRUE,
]);
$this->assertEquals(SAVED_NEW, $promotion3->save());

$promotions = $this->promotionStorage->loadMaxedUsage();
$this->assertEquals(count($promotions), 1);

$promotion = reset($promotions);
$this->assertEquals($promotion1->label(), $promotion->label());
}

}