-
Notifications
You must be signed in to change notification settings - Fork 259
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
#2863864 - Disable promotions via cron if end date or usage limit hit #708
base: 8.x-2.x
Are you sure you want to change the base?
Changes from 1 commit
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 |
---|---|---|
|
@@ -79,3 +79,30 @@ function commerce_promotion_entity_base_field_info(EntityTypeInterface $entity_t | |
return $fields; | ||
} | ||
} | ||
|
||
/** | ||
* Implements hook_cron() | ||
*/ | ||
function commerce_promotion_cron() { | ||
commerce_promotion_disabled_expired(); | ||
} | ||
|
||
/** | ||
* Get all expired promotions that are still active and disable them. | ||
*/ | ||
function commerce_promotion_disabled_expired() { | ||
/** @var \Drupal\commerce_promotion\PromotionStorageInterface $promotion_storage */ | ||
$promotion_storage = \Drupal::service('entity_type.manager')->getStorage('commerce_promotion'); | ||
|
||
// Get query for all expired promotions. | ||
$promotions = $promotion_storage->loadExpired(); | ||
|
||
if ($promotions !== FALSE) { | ||
// Disable all expired promotions. | ||
foreach ($promotions as $promotion) { | ||
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 I think this is fine versus a queue. There shouldn't be that much activity, generally. |
||
$promotion->setEnabled(FALSE); | ||
$promotion->save(); | ||
} | ||
} | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -106,6 +106,46 @@ public function loadByCoupon(OrderTypeInterface $order_type, StoreInterface $sto | |
return reset($promotions); | ||
} | ||
|
||
/** | ||
* Builds a query that will load all promotions that are no longer valid | ||
* determined by the base field limiting values. | ||
* | ||
* @param bool $only_enabled | ||
* Only include currently enabled promotions that have expired. | ||
* @return array|bool|\Drupal\Core\Entity\EntityInterface[] | ||
* The expired promotion entities. Returns FALSE if none found. | ||
*/ | ||
public function loadExpired($only_enabled = TRUE) { | ||
// Subquery to determine the amount of times a coupon has been used. | ||
$usage_query = $this->database->select('commerce_promotion_usage', 'cpu'); | ||
$usage_query->addExpression('COUNT(cpu.promotion_id)', 'count'); | ||
$usage_query->where('cpu.promotion_id = cpd.promotion_id'); | ||
$usage_query->groupBy('cpu.promotion_id'); | ||
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. We already have this query in the usage service https://github.com/drupalcommerce/commerce/blob/8.x-2.x/modules/promotion/src/PromotionUsage.php#L65 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. Would it work if I add another method to PromotionStorage that will load and check promotion uses by calling getUsageMultiple? That way I can run a quick query to only pass promotions to it which are active and have a usage set. I think the only way I can mess around with getUsageMultiple to handle return usage on its own would be to be just make it load all promotions if none are passed which could be excessive even if we're not too concerned w/ performance. Thoughts? |
||
|
||
$query = $this->database->select($this->getDataTable(), 'cpd'); | ||
|
||
// We want to get results of queries that have passed their final date or | ||
// have met their max usage. | ||
$or_condition = $query->orConditionGroup() | ||
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. This is using a regular select, when we can run I'd actually rather do a load of We need |
||
->condition('cpd.end_date', gmdate('Y-m-d'), '<=') | ||
->condition('cpd.usage_limit', $usage_query, '<='); | ||
|
||
$query->addField('cpd', 'promotion_id'); | ||
$query->condition($or_condition); | ||
|
||
if ($only_enabled) { | ||
$query->condition('cpd.status', 1); | ||
} | ||
|
||
$result = $query->execute()->fetchCol(0); | ||
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. We return the invalid and set them as disabled. Then I'd say run the usage checks afterwards for anything not yet expired |
||
|
||
if (empty($result)) { | ||
return FALSE; | ||
} | ||
|
||
return $this->loadMultiple($result); | ||
} | ||
|
||
/** | ||
* Builds the base query for loading valid promotions. | ||
* | ||
|
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.
If the storage provides a method to load expired, we can just keep this within the cron, no need for its own function. If people want to run this manually then they can.