1

I'm using:

  • Drupal 9.1.7
  • Commerce 2.24

I'm trying to create my custom condition (based on https://docs.drupalcommerce.org/commerce2/developer-guide/core/conditions). However parent entity is always NULL. Seems like parent entity is only working when I specify commerce_order as entity_type only, but I need commerce_order_item. ParentEntityAwareInterface and ParentEntityAwareTrait are in use. Debugging show that:

  public function evaluate(EntityInterface $entity) {
    $this->assertEntity($entity);
    /** @var \Drupal\commerce_order\Entity\OrderItemInterface $order_item */
    $order_item = $entity;
    /** @var \Drupal\commerce_promotion\Entity\PromotionInterface $promotion */
    $promotion = $this->parentEntity;
    //$promotion is NULL
    // rest of the code
  }

$promotion is always null.

Annotation:

 * @CommerceCondition(
 *   id = "myproj_product_condition",
 *   label = @Translation("Product chooser"),
 *   category = @Translation("Product chooser"),
 *   entity_type = "commerce_order_item",
 *   parent_entity_type = "commerce_promotion",
 *   weight = 9,
 * )
6
  • 1
    I looked at the code used by the Commerce Core module. I cannot say why $this->parentEntity would be NULL, but the explanation could be in Promotion::getConditions(), Promotion::apply(), and Promotion::applies().
    – apaderno
    Aug 30, 2021 at 19:28
  • 1
    See the comment on Promotion::applies(): Filter the conditions just in case there are leftover order item conditions (which have been moved to offer conditions). (Emphasis is mine.)
    – apaderno
    Aug 31, 2021 at 8:24
  • @apaderno I'm debugging and it show that my condition evaluate() method is running before \Drupal\commerce\Plugin\Commerce\Condition\ParentEntityAwareTrait::setParentEntity, so that's why parent entity is NULL. Strange.
    – Codium
    Aug 31, 2021 at 14:50
  • setParentEntity() is not always called. For what I can see, reading the code, the only classes calling that method are Promotion, but only for commerce_order conditions, and PaymentGateway.
    – apaderno
    Sep 1, 2021 at 11:46
  • I don't understand what which have been moved to offer conditions would mean, in the code comment I quoted earlier. What happens when a module implements a condition that is associated to the Promotion class but asks to get a OrderItem instance as argument? Is there code that assigns those conditions to an instance of the OfferItem or Offer class instead of the Promotion class as the class annotation says?
    – apaderno
    Sep 1, 2021 at 11:46

1 Answer 1

0

The docs note this:

(If you want the Condition to apply to multiple parent entity types, you can leave this property unset; however, you will need to be careful in your evaluate() method implementation to check the type of the parent entity before accessing any of the parent entity's methods.)

So it seems the annotation would be:

 * @CommerceCondition(
 *   id = "myproj_product_condition",
 *   label = @Translation("Product chooser"),
 *   category = @Translation("Product chooser"),
 *   entity_type = "commerce_order_item",
 *   weight = 9,
 * )

and assert:

$promotion = $this->parentEntity;

if (check $promotion is a certain entity type) {
 ...
}

Clear your cache after updating the Annotation (and may have to re-create the Rule? unsure if it affects that). Beyond that it could be a bug in Drupal Commerce.

6
  • 1
    The annotation used from the OP isn't wrong. It's the same annotation used by the OrderItemQuantity class, which also uses $promotion = $this->parentEntity; in its evaluate() method. The error isn't setting both entity_type and parent_entity_type; if there is something wrong, it's something else.
    – apaderno
    Aug 30, 2021 at 16:26
  • The entity type in that example is different, though? commerce_order vs commerce_order_item?
    – Kevin
    Aug 30, 2021 at 17:00
  • I meant that the issue should be further investigated, to understand whether $this->parentEntity can always be used and whether there is an alternative.
    – apaderno
    Aug 30, 2021 at 17:14
  • @apaderno I see only examples of commerce_order + commerce_promotion, but condition can work with commerce_order_item as well according to docs
    – Codium
    Aug 31, 2021 at 7:01
  • @Codium It does, but in that case, the condition doesn't get it's parentEntity set. I think I understood why that happens, looking at the methods I linked in the other comment I posted, but I still find something not clear.
    – apaderno
    Aug 31, 2021 at 8:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.