- Notifications
You must be signed in to change notification settings - Fork 256
#2863864 - Disable promotions via cron if end date or usage limit hit #708
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: 8.x-2.x
Are you sure you want to change the base?
Changes from 7 commits
527df0b 221cbd1 2b8f266 caf23a5 863ce8f 24856a6 e7d8a40 0794a1b e0f422f 73e867a 70ce340 029e4c4 4cb8f54 a557186 f659ea1 6bba454 4ac0f14 d3fda01 9aef5f3 04ef19f d5a4e42 File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| | @@ -104,4 +104,61 @@ public function loadAvailable(OrderTypeInterface $order_type, StoreInterface $st | |
| return $promotions; | ||
| } | ||
| | ||
| /** | ||
| * Return active promotions that have passed their end date. | ||
| ||
| * | ||
| * @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. | ||
| ||
| * | ||
| * @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; | ||
| } | ||
| | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| | @@ -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(); | ||
| Contributor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @bojanz name bikeshedding. | ||
| | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| | @@ -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; | ||
| | @@ -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. | ||
| * | ||
| | @@ -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' => [], | ||
| ]); | ||
| } | ||
| | ||
| /** | ||
| | @@ -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); | ||
| ||
| | ||
| $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()); | ||
| } | ||
| | ||
| } | ||
There was a problem hiding this comment.
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.