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;
}
}
