Problem/Motivation

If you do not set a price of the purchased item from the form in the handler, ie you have not overridden the 'amount', any commerce price resolvers still don't get a chance to set the item price. The particular case where we noticed this was using Commerce Pricelist, which is the source for prices on the site, not the variation itself. This will however be the case for any setup using price resolvers.

The reason for this is at the moment the OrderItem created always overrides the price.

        $this->orderItem
          ->set('purchased_entity', $data['purchasable_entity'])
          ->set('commerce_webform_order_submission', $webform_submission->id())
          ->setTitle($data['title'], TRUE)
          ->setUnitPrice($data['price'], TRUE)
          ->setQuantity($data['quantity']);

https://git.drupalcode.org/project/commerce_webform_order/-/blob/3.x/src...

The price coming from the price returned by the purchasable entity if there is no override set from the form via the handler

    $amount = $data['order_item']['amount'];
    if ((empty($amount) || !is_numeric($amount)) && !empty($prepared_data['purchasable_entity'])) {
      $data['order_item']['amount'] = $prepared_data['purchasable_entity']->getPrice()->getNumber();
    }

    if (empty($data['order_item']['currency']) && !empty($prepared_data['purchasable_entity'])) {
      $data['order_item']['currency'] = $prepared_data['purchasable_entity']->getPrice()->getCurrencyCode();
    }
    else {
      $currency = $this->loadEntityValue(
        $data['order_item']['currency'],
        'commerce_currency',
        ['currencyCode', 'name', 'numericCode']
      );

      $data['order_item']['currency'] = $currency->getCurrencyCode();
    }

    $prepared_data['price'] = new Price((string) $data['order_item']['amount'], $data['order_item']['currency']);

https://git.drupalcode.org/project/commerce_webform_order/-/blob/3.x/src...

(Aside this code will rather unceremoniously error if there's an incorrect combination of entity, amount and currency set.)

In a site without any resolvers, not setting the 'amount', will cause the item price to be overridden with the price of the item. Add a resolver it won't kick in because the price is overridden.

Proposed resolution

Don't set the price if it is not overridden by a value from the form.

        $this->orderItem
          ->set('purchased_entity', $data['purchasable_entity'])
          ->set('commerce_webform_order_submission', $webform_submission->id())
          ->setTitle($data['title'], TRUE)
          ->setQuantity($data['quantity']);
        if (isset($data['price'])) {
          $this->orderItem->setUnitPrice($data['price'], TRUE);
        }

Where the code in https://git.drupalcode.org/project/commerce_webform_order/-/blob/3.x/src... has been refactored such that $data['price'] has not been set unless either, or both, of the 'amount' and 'currency' have been configured to be overridden.

This means:

  • if there is an 'amount' or 'currency' has been set, the price gets overridden, just as it is now;
  • if 'amount' and 'currency' have not been set, and there are no resolvers, the price from the item is used, just as it now, but done by commerce itself;
  • but if 'amount' and 'currency' have not been set, and there are resolvers, the price as negotiated by them is used by commerce.

Remaining tasks

Refactor code as described, make a MR.
Possibly make more elegant handling of the case where there isn't a purchasable entity on the way?

Review.

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

ekes created an issue. See original summary.

ekes’s picture

Issue summary: View changes

ekes’s picture

Status: Active » Needs review
ekes’s picture

Issue summary: View changes
rattusrattus’s picture

I've tested this issue fork and the calculated price was as expected when not overriding the price and using Commerce Pricelist. Thanks

  • facine committed fd6d5029 on 3.x authored by ekes
    Issue #3564158: Allow commerce to set OrderItem price, unless it is...
facine’s picture

Status: Needs review » Fixed

Thanks for the work on this issue. Everything looks fine, I’ve just merged it.

Thank you!

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.