Packer should check that shipment items are valid.

Created on 28 February 2022, almost 3 years ago
Updated 14 March 2024, 9 months ago

Problem/Motivation

Due to the sequencing of order refreshes, there are cases when a shipment item can become invalid, but Commerce FedEx attempts to create the shipment item, causing \Drupal\commerce_shipping\ShipmentItem to throw an exception. The case I discovered has to do with a Buy X / Get Y promotion.

throw new \InvalidArgumentException(sprintf('Missing required property "%s".', $required_property));

Promotions removed
Shipments removed
Shipments created
Promotions re-applied

If I have an item that is only included in an order because of the "Get" condition of my promotion, but when the promotion order processor removes that item, the quantity becomes 0. The commerce fedex packer attempts to create the shipment item, the exception is thrown, checkout is broken.

Steps to reproduce

Create a Buy X / Get Y promotion, use two different variations for the Buy and Get items, and ensure "AUTOMATICALLY ADD THE OFFER PRODUCT TO THE CART IF IT ISN'T IN IT ALREADY." checkbox.
Add the Buy variation to the cart. Note that the Get variation is also added to the cart.
Attempt to checkout. I get a big ol' exception.

Proposed resolution

The simplest thing right now is to add a simple check around https://git.drupalcode.org/project/commerce_fedex/-/blob/8.x-1.x/src/Pac...

    foreach ($this->getOrderItems($order, $shipping_profile) as $order_item) {
      $purchased_entity = $order_item->getPurchasedEntity();

      // Ship only shippable purchasable entity types.
      if (!$purchased_entity || !$purchased_entity->hasField('weight')) {
        continue;
      }

      $quantity = $order_item->getQuantity();
      // Check quantity.
      if (!$quantity) {
        continue;
      }

      $shipments[0]['items'][] = new ShipmentItem([
        'order_item_id' => $order_item->id(),
        'title' => $order_item->getTitle(),
        'quantity' => $quantity,
        'weight' => $this->getWeight($order_item)->multiply($quantity),
        'declared_value' => $order_item->getUnitPrice()->multiply($quantity),
      ]);
    }

Remaining tasks

I'll try to get a patch together tomorrow.

πŸ› Bug report
Status

Fixed

Version

1.0

Component

Code

Created by

πŸ‡ΊπŸ‡ΈUnited States scottsawyer Atlanta

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Merge Requests

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

Production build 0.71.5 2024