Problem/Motivation

While currently not implement, the commerce.availability_manager could run during Add to Cart, Entering Checkout, or Finalizing Order. Currently the manager only passes the purchaseable entity and not any context to what step this is happening in.

For instance, there may be a "Cached availability checker" for add to cart and entering checkout, but on finalizing an order a "Raw avaibility checker" may run to bypass cached results.

Proposed resolution

Allow definition of "when" the check is happening, so that commerce.availability_checker services can properly say if they apply or not.

Remaining tasks

User interface changes

API changes

Data model changes

Comments

mglaman created an issue. See original summary.

mglaman’s picture

Assigned: mglaman » Unassigned

mglaman credited drugan.

mglaman’s picture

drugan proposed one way is to pass the current class in \Drupal\commerce\Context. We can pass an arbitrary data array, one of which can be the current step.

His proposal followed this:

+    $context = new Context($order->getCustomer(), $order->getStore(), time(), [
+      'caller' => self::class,
+    ]);

This turns into more of a pattern than something we can concretely set. The class name doesn't fit current patterns, but this is actually how the event dispatcher works in Symfony 5. The dispatcher uses the class name as the event name unless a specific event name is provided. However, this isn't sustainable if someone made a custom add to cart form (class wouldn't match.) The availability manager also doesn't know about carts, orders, or checkout. Those concepts are provided by the components in Commerce.

drugan’s picture

The issue with the quantity field step is that it should be exactly that step which is used by a customer on an Add to cart form as it's our primary order item quantity input method. So, first we need to detect whether the qty field is enabled on the Add to cart form display and, if it's not, take the Default form display settings disregarding of that whether the qty is enabled there or not.

I think it should be a method in the OrderItem class so it could be used by any code where the $order_item object is passed. The method should return not only step but all the qty field settings such as min, max, default_value, prefix, suffix and any custom setting added by contrib modules.

mglaman’s picture

Title: commerce.availability_manager needs to pass what "step" we're checking in » commerce.availability_manager needs to pass what "phase" we're checking in

@drugan sorry, step here means more of what phase verus quantity number steps. Retitling. This way the availability manager could say if it was Add to cart, Entering Checkout, Placing an order.

Often times we have a database cache layer in Drupal for stock levels. But when entering checkout there is a hard ping to the remote ERP to check live inventory levels.

mglaman’s picture

Status: Active » Closed (won't fix)

Actually, this issue was created before the availability manager check received a context object: #2803221: Create context value object for price resolvers and availability checkers.

I think we can close this issue as there isn't anything else to really do. Custom implementations could pass a step. Or we could opt to modify the order refresh code to provide context data.

  public function process(OrderInterface $order) {
    // @todo Get $context as an argument to process().
    $context = new Context($order->getCustomer(), $order->getStore(), NULL, [
      'phase' => 'refresh',
    ]);

I'm going to just close this issue. Providing a context object "fixed" this issue. Instead of adding a phase parameter it could be part of the context object.

mglaman’s picture

mglaman’s picture