commerce_signifyd-1.0.x-dev/src/Signifyd/Events.php
src/Signifyd/Events.php
<?php namespace Drupal\commerce_signifyd\Signifyd; use Drupal\commerce_order\Entity\OrderInterface; use Drupal\commerce_signifyd\Event\SignifydEvents; use Drupal\commerce_signifyd\Event\SignifydSendFulfillmentsEvent; use Drupal\Core\Utility\Error; use Drupal\profile\Entity\ProfileInterface; /** * {@inheritdoc} */ class Events extends SignifydAbstract implements EventsInterface { /** * {@inheritdoc} */ public function orderFulfilled(OrderInterface $order): array { $signifyd_cases = $this->entityTypeManager->getStorage('signifyd_case')->loadByOrder($order); if (!$signifyd_cases) { return []; } // Take last Signifyd case. $signifyd_case = end($signifyd_cases); try { $fulfillment_items = $this->getFulfillmentsData($order); $event = new SignifydSendFulfillmentsEvent($fulfillment_items, $order); $this->eventDispatcher->dispatch($event, SignifydEvents::SIGNIFYD_SEND_FULFILLMENTS); $fulfillment_items = $event->getFulfillments(); // In case we don't have commerce shipping module enabled. // But still allow this even to be triggered, it can be altered via // event subscriber, so even without commerce shipping module can be // custom filled with required data. if (empty($fulfillment_items)) { return []; } if ($this->logging) { $this->logger->notice(t('<b>Send fulfillments:</b> <pre><code>@fulfillments</code></pre>', [ '@fulfillments' => print_r($fulfillment_items, TRUE), ])); } $response = $this->signifydClient->sendFulfillment($signifyd_case, ['fulfillments' => $fulfillment_items]); if ($this->logging) { $this->logger->notice(t('<b>Response:</b> <pre><code>@response</code></pre>', [ '@response' => print_r($response, TRUE), ])); } return $response; } catch (\Exception $e) { Error::logException($this->logger, $e); } return []; } /** * Gets fulfillment's data. * * @param \Drupal\commerce_order\Entity\OrderInterface $order * The order. * * @return array * Array with fulfillment's data. */ protected function getFulfillmentsData(OrderInterface $order): array { // The default behavior relies on commerce shipping data structure. if (!$this->moduleHandler->moduleExists('commerce_shipping')) { return []; } $fulfillment_items = []; // Prepare delivery address. $delivery_address = []; $profiles = $order->collectProfiles(); $shipping_profile = $profiles['shipping'] ?? NULL; if ($shipping_profile instanceof ProfileInterface && $shipping_profile->hasField('address') && !$shipping_profile->get('address')->isEmpty()) { /** @var \Drupal\address\Plugin\Field\FieldType\AddressItem $address */ $address = $shipping_profile->get('address')->first(); $full_name_parts = [ $address->getGivenName(), $address->getAdditionalName(), $address->getFamilyName(), ]; $recipient_name = implode(' ', $full_name_parts); $delivery_address = [ 'streetAddress' => $address->getAddressLine1(), 'unit' => $address->getAddressLine2(), 'city' => $address->getLocality(), 'provinceCode' => $address->getAdministrativeArea(), 'postalCode' => $address->getPostalCode(), 'countryCode' => $address->getCountryCode(), ]; } $order_item_storage = $this->entityTypeManager->getStorage('commerce_order_item'); $commerce_shipments = $order->get('shipments')->referencedEntities(); /** @var \Drupal\commerce_shipping\Entity\ShipmentInterface $commerce_shipment */ foreach ($commerce_shipments as $commerce_shipment) { $commerce_shipment_items = $commerce_shipment->getItems(); $products = []; foreach ($commerce_shipment_items as $commerce_shipment_item) { /** @var \Drupal\commerce_order\Entity\OrderItemInterface $order_item */ $order_item = $order_item_storage->load($commerce_shipment_item->getOrderItemId()); if (!$order_item) { continue; } /** @var \Drupal\commerce\PurchasableEntityInterface $purchasable_entity */ $purchasable_entity = $order_item->getPurchasedEntity(); $product = $purchasable_entity->getProduct(); $products = [ 'itemId' => $purchasable_entity->id(), 'itemName' => $purchasable_entity->label(), 'itemIsDigital' => FALSE, 'itemCategory' => NULL, 'itemSubCategory' => NULL, 'itemUrl' => $product->toUrl('canonical', ['absolute' => TRUE])->toString(), 'itemImage' => NULL, 'itemQuantity' => $commerce_shipment_item->getQuantity(), 'itemPrice' => $order_item->getUnitPrice()->getNumber(), 'itemWeight' => $commerce_shipment_item->getWeight()->getNumber(), ]; } $tracking_urls = []; $tracking_numbers = []; $shipment_tracking = $commerce_shipment->getTrackingCode(); if (filter_var($shipment_tracking, FILTER_VALIDATE_URL)) { $tracking_urls[] = $shipment_tracking; } else { $tracking_numbers[] = $shipment_tracking; } $shipment_state = $commerce_shipment->getState()->getId(); $fulfillment_item = [ 'id' => $commerce_shipment->id(), 'orderId' => $order->id(), 'createdAt' => date(DATE_ATOM, $commerce_shipment->getChangedTime()), 'recipientName' => $recipient_name ?? NULL, 'deliveryEmail' => $order->getEmail(), // See commerce_shipping.workflows.yml. 'fulfillmentStatus' => $shipment_state === 'canceled' ? 'partial' : 'complete', 'shipmentStatus' => self::COMMERCE_SIGNIFYD_MAP_SHIPMENT_STATUS[$shipment_state] ?? 'delivered', 'shippingCarrier' => $commerce_shipment->getShippingService(), 'trackingNumbers' => $tracking_numbers, 'trackingUrls' => $tracking_urls, 'products' => $products, 'deliveryAddress' => $delivery_address ?? [], 'confirmationName' => $order->getStore()->label(), 'confirmationPhone' => NULL, ]; $fulfillment_items[] = $fulfillment_item; } return $fulfillment_items; } }