1

Is it possible to get the order items fields in a price resolver using Drupal 8 and Commerce 2.x?

Indeed, the resolve method in a price resolver only allow to access the purchased entity, quantity and context.

public function resolve(PurchasableEntityInterface $entity, $quantity, Context $contex) {}

I would like to:

  • Define some custom fields in an "Order Item Type" (In my case the fields are dates.)
  • Expose those fields in the add-to-cart form
  • Define product variation and product that uses that custom order item type, to have my custom add-to-cart form
  • Compute the purchased product price (in a custom Price resolver) according to field values provided in the add-to-cart form

I could use product attributes to achieve that, but unfortunately the values entered in the order item fields are not finite.

Notes

How do I implement this in Commerce 2.x? Did I misunderstand something?

thanks in advance

1

The short answer: No

Why:

In the Drupal Commerce Slack Channel, I asked whether it would be possible to add Order Item to the Context class. This was the response:

price resolvers are also called by regular price formatters the whole point of the context is to provide known information when the order item is missing

so changing that would be a big API change if you need order item data, for now use an order processor instead

How to solve the issue:

Replace YOURMODULE with the name of your custom module. The Priority value is used to prioritize what order processors get called first. You need to look at other order processors and figure out when yours should be called and set the priority value appropriately.

In YOURMODULE.services.yml

services:
    YOURMODULE.order_processor:
    class: Drupal\YOURMODULE\OrderProcessor
    arguments: []
    tags:
      - { name: commerce_order.order_processor, priority: 110 }

In YOURMODULE\src\OrderProcessor.php

<?php

namespace Drupal\YOURMODULE;

use Drupal\commerce_order\Entity\OrderInterface;
use Drupal\commerce_order\Entity\OrderItemInterface;
use Drupal\commerce_order\OrderProcessorInterface;

class OrderProcessor implements OrderProcessorInterface {

  /**
   * {@inheritdoc}
   */
  public function process(OrderInterface $order) {
    $order_items = $order->getItems();
    foreach ($order_items as $order_item) {
      if ($order_item->bundle() == 'YOURCUSTOMBUNDLE') {
        // YOUR LOGIC TO FIGURE OUT $calculated_price
        $price = new Price($calculated_price, $currency)
        // Set to TRUE if you want to override unit price.
        $order_item->setUnitPrice($price, FALSE);
      }
    }
  }

Hope this helps!

  • glad I could help – Eric Chew Feb 22 '18 at 18:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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