You are here

public function FedEx::calculateRates in Commerce FedEx 8

Calculates rates for the given shipment.

Parameters

\Drupal\commerce_shipping\Entity\ShipmentInterface $shipment: The shipment.

Return value

\Drupal\commerce_shipping\ShippingRate[] The rates.

Overrides ShippingMethodInterface::calculateRates

File

src/Plugin/Commerce/ShippingMethod/FedEx.php, line 448

Class

FedEx
Provides the FedEx shipping method.

Namespace

Drupal\commerce_fedex\Plugin\Commerce\ShippingMethod

Code

public function calculateRates(ShipmentInterface $shipment) {
  if ($shipment
    ->getShippingProfile()->address
    ->isEmpty()) {
    return [];
  }
  if (empty($shipment
    ->getPackageType())) {
    $shipment
      ->setPackageType($this
      ->getDefaultPackageType());
  }
  $rate_service = $this->fedExRequest
    ->getRateService($this->configuration);
  $rate_request = $this
    ->getRateRequest($rate_service, $shipment);
  $this
    ->logRequest('Sending FedEx request.', $rate_request);
  $response = $rate_service
    ->getRates($rate_request);
  $rates = [];
  if ($response) {
    $this
      ->logRequest('FedEx response received.', $response);
    $allowed_severities = [
      'SUCCESS',
      'NOTE',
      'WARNING',
    ];
    $highest_severity = $response
      ->getHighestSeverity();
    $severity_map = [
      'NOTE' => LogLevel::NOTICE,
      'WARNING' => LogLevel::WARNING,
      'ERROR' => LogLevel::ERROR,
      'FAILURE' => LogLevel::ERROR,
    ];

    // Log any notifications returned from FedEx.
    foreach ($response
      ->getNotifications() as $notification) {
      if (array_key_exists($notification
        ->getSeverity(), $severity_map)) {
        $this->watchdog
          ->log($severity_map[$notification
          ->getSeverity()], '@message (Code @code)', [
          '@message' => $notification
            ->getMessage(),
          '@code' => $notification
            ->getCode(),
        ]);
      }
    }
    if (in_array($highest_severity, $allowed_severities)) {
      $multiplier = !empty($this->configuration['options']['rate_multiplier']) ? $this->configuration['options']['rate_multiplier'] : 1.0;
      $round = !empty($this->configuration['options']['round']) ? $this->configuration['options']['round'] : PHP_ROUND_HALF_UP;
      foreach ($response
        ->getRateReplyDetails() as $rate_reply_details) {
        if (in_array($rate_reply_details
          ->getServiceType(), array_keys($this
          ->getServices()))) {

          // Fedex returns both Account and List prices within the same
          // RatedShipment object. Loop through each Rate Detail to find the
          // appropriate Account/List rate as configured.
          foreach ($rate_reply_details
            ->getRatedShipmentDetails() as $rated_shipment) {
            $rate_details = $rated_shipment
              ->getShipmentRateDetail();
            $rate_type = strpos($rate_details
              ->getRateType(), 'ACCOUNT') ? RateRequestType::VALUE_NONE : RateRequestType::VALUE_LIST;
            if ($this->configuration['options']['rate_request_type'] !== $rate_type) {
              continue;
            }
            $service = $this->services[$rate_reply_details
              ->getServiceType()];
            $cost = $rate_details
              ->getTotalNetChargeWithDutiesAndTaxes();
            $price = new Price((string) $cost
              ->getAmount(), $cost
              ->getCurrency());
            if ($multiplier != 1) {
              $price = $price
                ->multiply((string) $multiplier);
            }
            $price = $this->rounder
              ->round($price, $round);
            $rates[] = new ShippingRate([
              'shipping_method_id' => $this->parentEntity
                ->id(),
              'service' => $service,
              'amount' => $price,
            ]);
          }
        }
      }
    }
  }
  else {
    $this
      ->logRequest('FedEx sent no response back.', $rate_request, LogLevel::NOTICE, TRUE);
  }
  return $rates;
}