commerce_signifyd-1.0.x-dev/src/Signifyd/Cases.php
src/Signifyd/Cases.php
<?php
namespace Drupal\commerce_signifyd\Signifyd;
use Drupal\commerce_order\Entity\OrderInterface;
use Drupal\commerce_signifyd\Entity\SignifydCaseInterface;
use Drupal\commerce_signifyd\Event\SignifydCreateCaseEvent;
use Drupal\commerce_signifyd\Event\SignifydEvents;
use Drupal\Core\Utility\Error;
use Drupal\profile\Entity\ProfileInterface;
/**
* {@inheritdoc}
*/
class Cases extends SignifydAbstract implements CasesInterface {
/**
* {@inheritdoc}
*/
public function createCase(OrderInterface $order): array {
try {
$case = $this->getCaseData($order);
// Trigger event to sent altering payload.
$event = new SignifydCreateCaseEvent($case, $order, $this->getSignifydTeam());
$this->eventDispatcher->dispatch($event, SignifydEvents::SIGNIFYD_CREATE_CASE);
$case = $event->getCase();
$team = $event->getTeam();
if ($this->logging) {
$this->logger->notice(t('<b>Create case with data:</b> <pre><code>@case_data</code></pre>', [
'@case_data' => print_r($case, TRUE),
]));
}
$response = $this->signifydClient->createCase($case, $team);
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 [];
}
/**
* {@inheritdoc}
*/
public function getCase(SignifydCaseInterface $case): array {
try {
$response = $this->signifydClient->getCase($case->id());
if ($this->logging) {
$this->logger->notice(t('. <br><b>Response:</b> <pre><code>@response</code></pre>', [
'@response' => print_r($response, TRUE),
]));
}
return $response;
}
catch (\Exception $e) {
Error::logException($this->logger, $e);
}
return [];
}
/**
* Returns data for createCase.
*
* @param \Drupal\commerce_order\Entity\OrderInterface $order
* The order.
*
* @return array
* Associative array of data.
*/
protected function getCaseData(OrderInterface $order): array {
return [
'policy' => [
'name' => 'POST_AUTH',
],
'decisionRequest' => [
'paymentFraud' => 'GUARANTEE',
],
'purchase' => [
'browserIpAddress' => $order->getIpAddress(),
'orderId' => $order->id(),
'orderSessionId' => self::getOrderSessionId($order),
'createdAt' => date(DATE_ATOM, $order->getPlacedTime() ?? time()),
'currency' => $order->getTotalPrice()->getCurrencyCode(),
'orderChannel' => "WEB",
'totalPrice' => $order->getTotalPrice()->getNumber(),
'customerOrderRecommendation' => "APPROVE",
'products' => $this->getProducts($order),
'discountCodes' => $this->getDiscountCodes($order),
'shipments' => $this->getShipments($order),
],
'recipients' => $this->getRecipients($order),
'transactions' => $this->getTransactions($order),
'userAccount' => $this->getUserAccount($order),
];
}
/**
* Returns products.
*
* @param \Drupal\commerce_order\Entity\OrderInterface $order
* The order.
*
* @return array
* The products.
*
* @throws \Drupal\Core\Entity\EntityMalformedException
* @throws \Drupal\Core\TypedData\Exception\MissingDataException
*/
protected function getProducts(OrderInterface $order): array {
$products = [];
foreach ($order->getItems() as $order_item) {
$purchasable_entity = $order_item->getPurchasedEntity();
/** @var \Drupal\commerce_product\Entity\ProductInterface $product */
$product = $purchasable_entity->getProduct();
$weight = 0;
if ($purchasable_entity->hasField('weight') && !$purchasable_entity->get('weight')->isEmpty()) {
$weight = $purchasable_entity->get('weight')->first()->toMeasurement()->getNumber();
}
// @todo Check values for itemIsDigital, itemCategory, itemSubCategory, itemImage.
$products[] = [
'itemId' => $order_item->id(),
'itemName' => $order_item->label(),
'itemIsDigital' => FALSE,
'itemUrl' => $product->toUrl('canonical', ['absolute' => TRUE])
->toString(),
'itemQuantity' => $order_item->getQuantity(),
'itemPrice' => $order_item->getUnitPrice()->getNumber(),
'itemWeight' => $weight,
];
}
return $products;
}
/**
* Returns discountCodes.
*
* @param \Drupal\commerce_order\Entity\OrderInterface $order
* The order.
*
* @return array
* The discountCodes.
*/
protected function getDiscountCodes(OrderInterface $order): array {
$discounts = [];
if ($this->moduleHandler->moduleExists('commerce_promotion')) {
$adjustments = $order->collectAdjustments(
['promotion', 'shipping_promotion']
);
foreach ($adjustments as $adjustment) {
$discounts[] = [
'amount' => $adjustment->getAmount()->getNumber(),
'code' => $adjustment->getSourceId(),
];
}
}
return $discounts;
}
/**
* Returns shipments.
*
* @param \Drupal\commerce_order\Entity\OrderInterface $order
* The order.
*
* @return array
* The shipments.
*
* @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
* @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
*/
protected function getShipments(OrderInterface $order): array {
$shipments = [];
if ($this->moduleHandler->moduleExists('commerce_shipping')) {
$commerce_shipments = $order->get('shipments')->referencedEntities();
/** @var \Drupal\commerce_shipping\Entity\ShipmentInterface $commerce_shipment */
foreach ($commerce_shipments as $commerce_shipment) {
/** @var \Drupal\commerce_shipping\Entity\ShippingMethod $shipping_method */
if ($shipping_method = $commerce_shipment->getShippingMethod()) {
// @todo Check value for shippingMethod.
$shipments[] = [
'shipper' => $shipping_method->getName(),
'shippingMethod' => $commerce_shipment->getShippingService(),
'shippingPrice' => $commerce_shipment->getAmount()->getNumber(),
];
}
}
}
return $shipments;
}
/**
* Returns recipient.
*
* @param \Drupal\commerce_order\Entity\OrderInterface $order
* The order.
*
* @return array
* The recipients.
*
* @throws \Drupal\Core\TypedData\Exception\MissingDataException
*/
protected function getRecipients(OrderInterface $order): array {
$recipients = [];
if ($this->moduleHandler->moduleExists('commerce_shipping')) {
$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->getFamilyName(),
];
$recipients[] = [
'fullName' => implode(' ', $full_name_parts),
'confirmationEmail' => $order->getEmail(),
'confirmationPhone' => $shipping_profile->hasField('phone') ? $shipping_profile->get('phone')->value : '',
'organization' => $address->getOrganization(),
'deliveryAddress' => [
'streetAddress' => $address->getAddressLine1(),
'unit' => $address->getAddressLine2(),
'city' => $address->getLocality(),
'provinceCode' => $address->getAdministrativeArea(),
'postalCode' => $address->getPostalCode(),
'countryCode' => $address->getCountryCode(),
],
];
}
}
return $recipients;
}
/**
* Returns userAccount.
*
* @param \Drupal\commerce_order\Entity\OrderInterface $order
* The order.
*
* @return array
* The userAccount.
*/
protected function getUserAccount(OrderInterface $order): array {
$user = $order->getCustomer();
return [
'email' => $user->getEmail() ?? $order->getEmail(),
'username' => $user->label(),
'createdDate' => date(DATE_ATOM, $user->getCreatedTime()),
'accountNumber' => $user->id(),
'aggregateOrderCount' => 1,
'aggregateOrderDollars' => 0,
];
}
}
