You are here

protected function ShipmentSubscriber::clearShipments in Commerce Shipping 8.2

Clears the shipments that were deleted during this request.

This will ensure the order no longer references the deleted shipments and take care of removing any leftover adjustments.

1 call to ShipmentSubscriber::clearShipments()
ShipmentSubscriber::destruct in src/EventSubscriber/ShipmentSubscriber.php

File

src/EventSubscriber/ShipmentSubscriber.php, line 133

Class

ShipmentSubscriber

Namespace

Drupal\commerce_shipping\EventSubscriber

Code

protected function clearShipments() {

  /** @var \Drupal\commerce_order\Entity\OrderInterface[] $orders */
  $orders = $this->entityTypeManager
    ->getStorage('commerce_order')
    ->loadMultiple(array_keys($this->shipmentsToClear));
  foreach ($orders as $order) {

    // Skip orders that no longer references shipments.
    if (!$order
      ->hasField('shipments') || $order
      ->get('shipments')
      ->isEmpty()) {
      continue;
    }
    $order_shipments = $order
      ->get('shipments');
    $save_order = FALSE;
    foreach ($this->shipmentsToClear[$order
      ->id()] as $shipment_to_clear) {
      $shipment_id = $shipment_to_clear['id'];

      // Make sure the shipment is not being referenced by the order anymore.

      /** @var \Drupal\Core\Field\FieldItemListInterface $order_shipments */
      foreach ($order_shipments as $delta => $item) {
        if ($item->target_id != $shipment_id) {
          continue;
        }
        $save_order = TRUE;

        // The shipment is still referenced by the order, clear the reference.
        $order_shipments
          ->removeItem($delta);

        /** @var \Drupal\commerce_order\Adjustment[] $shipment_adjustments */
        $shipment_adjustments = $shipment_to_clear['adjustments'];
        $adjustments = [];

        // Loop over the order adjustments, to remove any adjustment added
        // by the shipment that was removed during the request.
        foreach ($order
          ->getAdjustments() as $adjustment) {

          // Ensure the shipping adjustment is skipped/i.e not re-added
          // if present.
          if ($adjustment
            ->getSourceId() == $shipment_id) {
            continue;
          }
          $matching_adjustment = FALSE;

          // Loop over the shipment adjustments, to see if the order has a
          // matching adjustment that needs to be removed.
          foreach ($shipment_adjustments as $shipment_adjustment) {
            if ($shipment_adjustment
              ->toArray() != $adjustment
              ->toArray()) {
              continue;
            }

            // A matching adjustment was found on the order, no need to
            // continue the loop.
            $matching_adjustment = TRUE;
            break;
          }

          // A matching adjustment was found on the order, it should be
          // removed, skipping it will ensure it's not re-added to the order.
          if ($matching_adjustment) {
            continue;
          }
          $adjustments[] = $adjustment;
        }
        $order
          ->setAdjustments($adjustments);
      }
    }
    if ($save_order) {
      $order
        ->save();
    }
  }
}