commerce_amws-8.x-1.x-dev/modules/shipping/src/EntitySync/FieldMapping/ExportHandler.php
modules/shipping/src/EntitySync/FieldMapping/ExportHandler.php
<?php
namespace Drupal\commerce_amws_shipping\EntitySync\FieldMapping;
use Drupal\commerce_amws\MachineName\Field\Order as OrderField;
use Drupal\commerce_amws\MachineName\Field\OrderItem as OrderItemField;
use Drupal\commerce_amws\MachineName\Field\ShippingMethod as ShippingMethodField;
use Drupal\commerce_shipping\Entity\ShipmentInterface;
use Drupal\entity_sync\Exception\FieldExportException;
/**
* Handles conversion of shipment-related fields being exported to Amazon MWS.
*/
class ExportHandler {
/**
* Returns the Amazon MWS seller ID of the order that a shipment belongs to.
*
* @param \Drupal\commerce_shipping\Entity\ShipmentInterface $shipment
* The shipment.
* @param int|string|null $remote_entity_id
* The ID of the remote entity that will be updated, or NULL if we are
* creating a new one.
* @param array $field_info
* The field info.
* See \Drupal\entity_sync\Export\Event\FieldMapping::fieldMapping.
* @param array $params
* An array of custom parameters provided by the synchronization.
*
* @return string
* The seller ID.
*
* @throws \Drupal\entity_sync\Exception\FieldExportException
* If no Amazon MWS store associated with the shipment's order was found.
*/
public static function shipmentToMerchantIdentifier(
ShipmentInterface $shipment,
$remote_entity_id,
array $field_info,
array $params
) {
$order = $shipment->getOrder();
if (!$order) {
throw new FieldExportException(sprintf(
'No order found for shipment with ID "%s".',
$shipment->id()
));
}
$amws_store_field = $order->get(OrderField::AMWS_STORE);
if ($amws_store_field->isEmpty()) {
throw new FieldExportException(sprintf(
'Order with ID "%s" does not belong to an Amazon MWS store.',
$order->id()
));
}
$amws_store = $amws_store_field->entity;
if (!$amws_store) {
throw new FieldExportException(sprintf(
'Order with ID "%s" belongs to a non-existing Amazon MWS store with ID "%s".',
$order->id(),
$amws_store_field->target_id
));
}
return $amws_store->getSellerId();
}
/**
* Returns the Amazon MWS order ID associated with the shipment's order.
*
* @param \Drupal\commerce_shipping\Entity\ShipmentInterface $shipment
* The shipment.
* @param int|string|null $remote_entity_id
* The ID of the remote entity that will be updated, or NULL if we are
* creating a new one.
* @param array $field_info
* The field info.
* See \Drupal\entity_sync\Export\Event\FieldMapping::fieldMapping.
* @param array $params
* An array of custom parameters provided by the synchronization.
*
* @return string
* The Amazon MWS order Id.
*
* @throws \Drupal\entity_sync\Exception\FieldExportException
* If no Amazon MWS order associated with the shipment's order was found.
*/
public static function shipmentToAmwsOrderId(
ShipmentInterface $shipment,
$remote_entity_id,
array $field_info,
array $params
) {
$order = $shipment->getOrder();
if (!$order) {
throw new FieldExportException(sprintf(
'No order found for shipment with ID "%s".',
$shipment->id()
));
}
$remote_id_field = $order->get(OrderField::REMOTE_ID);
if ($remote_id_field->isEmpty()) {
throw new FieldExportException(sprintf(
'Order with ID "%s" does not reference an Amazon MWS order.',
$order->id()
));
}
return $remote_id_field->value;
}
/**
* Returns the fulfillment data for the given shipment.
*
* @param \Drupal\commerce_shipping\Entity\ShipmentInterface $shipment
* The shipment.
* @param int|string|null $remote_entity_id
* The ID of the remote entity that will be updated, or NULL if we are
* creating a new one.
* @param array $field_info
* The field info.
* See \Drupal\entity_sync\Export\Event\FieldMapping::fieldMapping.
* @param array $params
* An array of custom parameters provided by the synchronization.
*
* @return array
* An array containing the fulfillment data.
*/
public static function shipmentToAmwsFulfillmentData(
ShipmentInterface $shipment,
$remote_entity_id,
array $field_info,
array $params
) {
$tracking_code = $shipment->getTrackingCode();
if (!$tracking_code) {
return [];
}
$shipping_method = $shipment->getShippingMethod();
if (!$shipping_method) {
return [];
}
$amws_code = '';
$amws_code_field = $shipping_method->get(ShippingMethodField::CARRIER_CODE);
if (!$amws_code_field->isEmpty()) {
$amws_code = $amws_code_field->first()->getValue()['value'];
}
$amws_method = '';
$amws_method_field = $shipping_method->get(ShippingMethodField::SHIPPING_METHOD);
if (!$amws_method_field->isEmpty()) {
$amws_method = $amws_method_field->first()->getValue()['value'];
}
return [
[
'CarrierCode' => $amws_code,
'ShippingMethod' => $amws_method,
'ShipperTrackingNumber' => $tracking_code,
],
];
}
/**
* Returns the Amazon MWS fulfillment items for the given shipment.
*
* @param \Drupal\commerce_shipping\Entity\ShipmentInterface $shipment
* The shipment.
* @param int|string|null $remote_entity_id
* The ID of the remote entity that will be updated, or NULL if we are
* creating a new one.
* @param array $field_info
* The field info.
* See \Drupal\entity_sync\Export\Event\FieldMapping::fieldMapping.
* @param array $params
* An array of custom parameters provided by the synchronization.
*
* @return array
* An array containing the fulfillment items.
*
* @throws \Drupal\entity_sync\Exception\FieldExportException
* If no Amazon MWS order associated with the shipment's order was found.
*/
public static function shipmentItemsToAmwsFulfillmentItems(
ShipmentInterface $shipment,
$remote_entity_id,
array $field_info,
array $params
) {
$shipment_items = $shipment->getItems();
if (!$shipment_items) {
return [];
}
$value = [];
$order_item_storage = \Drupal::service('entity_type.manager')
->getStorage('commerce_order_item');
foreach ($shipment_items as $shipment_item) {
$order_item = $order_item_storage->load($shipment_item->getOrderItemId());
if (!$order_item) {
throw new FieldExportException(sprintf(
'No order item with ID "%s" found for shipment item with ID "%s".',
$shipment_item->getOrderItemId(),
$shipment_item->id()
));
}
// Skip items that do not reference an Amazon MWS order item. It may be
// that the order item was added to the order after it was imported into
// Drupal. If the only order item referenced is a non-AMWS item, something
// must be wrong. We therefore continue and we'll get an error in the
// Amazon MWS response. Applications can cancel the export if they need to
// match their custom logic with a pre-initiate event subscriber.
if (!$order_item->hasField(OrderItemField::REMOTE_ID)) {
continue;
}
$remote_id_field = $order_item->get(OrderItemField::REMOTE_ID);
if ($remote_id_field->isEmpty()) {
continue;
}
$value[] = [
'AmazonOrderItemCode' => $remote_id_field->value,
'Quantity' => (int) $shipment_item->getQuantity(),
];
}
return $value;
}
}
