Добавление своего условия в Promotions от Drupal Commerce

Команда ra-don.ru
Наш кумулятивный опыт и статьи от нескольких авторов

Небольшой сниппет для частой задачи: у вас есть желание делать скидки в зависимости от объема заказа. И хочется какую-то категорию исключить из раздачи скидок. В стандартной поставке есть вариант наоборот - перечислить какие категории включить в выдачу. 

Ниже пример кастомного условия:

Это структурно плагин, сделаем заглушку модуля с файлом

/src/Plugin/Commerce/Condition/OrderItemProductNotCategory.php

<?php

namespace Drupal\custom_commerce\Plugin\Commerce\Condition;

use Drupal\commerce\EntityUuidMapperInterface;
use Drupal\commerce\Plugin\Commerce\Condition\ConditionBase;
use Drupal\Core\Entity\EntityFieldManagerInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\commerce_product\Plugin\Commerce\Condition\OrderItemProductCategory;

/**
 * Provides the product category condition for order items.
 *
 * @CommerceCondition(
 *   id = "order_item_product_not_category",
 *   label = @Translation("Product not in category"),
 *   display_label = @Translation("Product don't contains in categories"),
 *   category = @Translation("Products"),
 *   entity_type = "commerce_order_item",
 * )
 */
class OrderItemProductNotCategory extends OrderItemProductCategory {

  /**
   * {@inheritdoc}
   */
  public function evaluate(EntityInterface $entity) {
    $this->assertEntity($entity);
    /** @var \Drupal\commerce_order\Entity\OrderItemInterface $order_item */
    $order_item = $entity;
    /** @var \Drupal\commerce_product\Entity\ProductVariationInterface $purchased_entity */
    $purchased_entity = $order_item->getPurchasedEntity();
    if (!$purchased_entity || $purchased_entity->getEntityTypeId() != 'commerce_product_variation') {
      return FALSE;
    }
    $term_ids = $this->getTermIds();
    $referenced_ids = $this->getReferencedIds($purchased_entity->getProduct());

    return !(bool) array_intersect($referenced_ids, $term_ids);
  }

}

Всё) Больше никакого кода не требуется, он определит и покажет нужный вариант условия.