Commit e3e0f584 authored by jsacksick's avatar jsacksick Committed by jsacksick
Browse files

Issue #3248912 by jsacksick, rszrama: Add an explicit setting to determine...

Issue #3248912 by jsacksick, rszrama: Add an explicit setting to determine whether a promotion requires a coupon code to apply.
parent aa312f90
......@@ -319,3 +319,23 @@ function commerce_promotion_update_8211() {
$definition_update_manager->installFieldStorageDefinition($name, 'commerce_promotion_coupon', 'commerce_promotion', $definition);
}
}
/**
* Allow specifying whether a promotion requires a coupon code to apply.
*/
function commerce_promotion_update_8212() {
$definition = BaseFieldDefinition::create('boolean')
->setLabel(t('Require a coupon to apply this promotion'))
->setDefaultValue(FALSE)
->setDisplayOptions('form', [
'type' => 'boolean_checkbox',
'settings' => [
'display_label' => TRUE,
],
])
->setDisplayConfigurable('view', TRUE)
->setDisplayConfigurable('form', TRUE);
$definition_update_manager = \Drupal::entityDefinitionUpdateManager();
$definition_update_manager->installFieldStorageDefinition('require_coupon', 'commerce_promotion', 'commerce_promotion', $definition);
}
......@@ -500,6 +500,13 @@ class Promotion extends CommerceContentEntityBase implements PromotionInterface
return $this;
}
/**
* {@inheritdoc}
*/
public function requiresCoupon() {
return !empty($this->get('require_coupon')->value);
}
/**
* {@inheritdoc}
*/
......@@ -507,6 +514,11 @@ class Promotion extends CommerceContentEntityBase implements PromotionInterface
if (!$this->isEnabled()) {
return FALSE;
}
// A promotion that requires a coupon to apply should reference coupons
// to apply.
if ($this->requiresCoupon() && !$this->hasCoupons()) {
return FALSE;
}
if (!in_array($order->bundle(), $this->getOrderTypeIds())) {
return FALSE;
}
......@@ -867,6 +879,18 @@ class Promotion extends CommerceContentEntityBase implements PromotionInterface
'weight' => 4,
]);
$fields['require_coupon'] = BaseFieldDefinition::create('boolean')
->setLabel(t('Require a coupon to apply this promotion'))
->setDefaultValue(FALSE)
->setDisplayOptions('form', [
'type' => 'boolean_checkbox',
'settings' => [
'display_label' => TRUE,
],
])
->setDisplayConfigurable('view', TRUE)
->setDisplayConfigurable('form', TRUE);
$fields['status'] = BaseFieldDefinition::create('boolean')
->setLabel(t('Status'))
->setDescription(t('Whether the promotion is enabled.'))
......
......@@ -449,4 +449,12 @@ interface PromotionInterface extends ContentEntityInterface, EntityStoresInterfa
*/
public function setCreatedTime($timestamp);
/**
* Checks whether a coupon is required for the promotion to apply.
*
* @return bool
* TRUE if the promotion requires a coupon, FALSE otherwise.
*/
public function requiresCoupon();
}
......@@ -37,6 +37,8 @@ class PromotionForm extends ContentEntityForm {
public function form(array $form, FormStateInterface $form_state) {
$form = parent::form($form, $form_state);
/** @var \Drupal\commerce_promotion\Entity\PromotionInterface $promotion */
$promotion = $this->entity;
$form['#tree'] = TRUE;
// By default an offer is preselected on the add form because the field
// is required. Select an empty value instead, to force the user to choose.
......@@ -59,6 +61,21 @@ class PromotionForm extends ContentEntityForm {
if ($translating && $hide_non_translatable_fields) {
return $form;
}
if (isset($form['require_coupon'])) {
if (!$promotion->hasCoupons()) {
$description = 'There are no coupons defined for this promotion yet.';
}
else {
$coupons_count = $promotion->get('coupons')->count();
$coupon_code = '';
if ($coupons_count === 1) {
$coupons = $promotion->getCoupons();
$coupon_code = $coupons[0]->getCode();
}
$description = $this->formatPlural($coupons_count, 'There is one coupon defined for this promotion: @coupon_code.', 'There are @count defined for this promotion.', ['@coupon_code' => $coupon_code]);
}
$form['require_coupon']['widget']['value']['#description'] = $description;
}
$form['#theme'] = ['commerce_promotion_form'];
$form['#attached']['library'][] = 'commerce_promotion/form';
......@@ -80,6 +97,12 @@ class PromotionForm extends ContentEntityForm {
'#title' => $this->t('Dates'),
'#group' => 'advanced',
];
$form['coupon_details'] = [
'#type' => 'details',
'#open' => TRUE,
'#title' => $this->t('Coupons'),
'#group' => 'advanced',
];
$form['usage_details'] = [
'#type' => 'details',
'#open' => TRUE,
......@@ -98,6 +121,7 @@ class PromotionForm extends ContentEntityForm {
'weight' => 'option_details',
'order_types' => 'option_details',
'stores' => 'option_details',
'require_coupon' => 'coupon_details',
'start_date' => 'date_details',
'end_date' => 'date_details',
'usage_limit' => 'usage_details',
......
......@@ -54,7 +54,12 @@ class PromotionStorage extends CommerceContentEntityStorage implements Promotion
}
// Only load promotions without coupons. Promotions with coupons are loaded
// coupon-first in a different process.
$query->notExists('coupons');
$coupon_condition = $query->orConditionGroup()
->notExists('require_coupon')
->condition('require_coupon', 0, '=');
$query
->condition($coupon_condition)
->notExists('coupons');
$result = $query->execute();
if (empty($result)) {
return [];
......
......@@ -83,6 +83,7 @@ class PromotionTest extends OrderKernelTestBase {
* @covers ::setOwner
* @covers ::getOwnerId
* @covers ::setOwnerId
* @covers ::requiresCoupon
*/
public function testPromotion() {
$order_type = OrderType::load('default');
......@@ -186,6 +187,10 @@ class PromotionTest extends OrderKernelTestBase {
$this->assertEquals(900, $promotion->getOwnerId());
$promotion->save();
$this->assertEquals(0, $promotion->getOwnerId());
$this->assertFalse($promotion->requiresCoupon());
$promotion->set('require_coupon', TRUE);
$this->assertTrue($promotion->requiresCoupon());
}
/**
......
......@@ -80,6 +80,9 @@ class PromotionAvailabilityTest extends OrderKernelTestBase {
]);
$promotion->save();
$this->assertTrue($promotion->available($this->order));
$promotion->set('require_coupon', TRUE);
$this->assertFalse($promotion->available($this->order));
$promotion->set('require_coupon', FALSE);
$promotion->setEnabled(FALSE);
$this->assertFalse($promotion->available($this->order));
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment