Commit f8655757 authored by Dimitris Bozelos's avatar Dimitris Bozelos
Browse files

Issue #3307891 Added shipment export entity sync client/factory

parent 28f9c7bf
Loading
Loading
Loading
Loading
+20 −0
Original line number Diff line number Diff line
@@ -2,14 +2,34 @@

namespace Drupal\commerce_amws_shipping;

use Drupal\commerce_amws_shipping\EntitySync\FeedPostOrderFulfillmentDataFactory;
use Drupal\Core\DependencyInjection\ContainerBuilder;
use Drupal\Core\DependencyInjection\ServiceProviderBase;
use Symfony\Component\DependencyInjection\Reference;

/**
 * Service alterations.
 */
class CommerceAmwsShippingServiceProvider extends ServiceProviderBase {

  /**
   * {@inheritdoc}
   */
  public function register(ContainerBuilder $container) {
    $modules = $container->getParameter('container.modules');
    if (!isset($modules['commerce_amws_feed'])) {
      return;
    }

    $container
      ->register(
        'commerce_amws_shipping.entity_sync_client.feed_post_order_fulfillment_data_factory',
        FeedPostOrderFulfillmentDataFactory::class
      )
      ->addArgument(new Reference('entity_type.manager'))
      ->addArgument(new Reference('commerce_amws_feed.xml_content_builder'));
  }

  /**
   * {@inheritdoc}
   */
+185 −0
Original line number Diff line number Diff line
<?php

namespace Drupal\commerce_amws_shipping\EntitySync;

use Drupal\commerce_amws\Entity\StoreInterface;
use Drupal\commerce_amws_feed\Content\XmlBuilderInterface as FeedContentBuilderInterface;
use Drupal\entity_sync\Client\ClientInterface as EntitySyncClientInterface;

use Drupal\Core\Entity\EntityTypeManagerInterface;

use SellingPartnerApi\Api\FeedsApi;
use SellingPartnerApi\Document;
use SellingPartnerApi\FeedType;
use SellingPartnerApi\Model\Feeds\CreateFeedDocumentSpecification;
use SellingPartnerApi\Model\Feeds\CreateFeedSpecification;

/**
 * Adapter that bridges Entity Sync to the Amazon MWS SPI-API client.
 *
 * phpcs:disable
 * @I Extract common functionality to a base feed client
 *    type     : task
 *    priority : normal
 *    labels   : modularity
 * phpcs:enable
 */
class FeedPostOrderFulfillmentDataClient implements EntitySyncClientInterface {

  /**
   * The entity type manager.
   *
   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
   */
  protected $entityTypeManager;

  /**
   * The XML feed content builder.
   *
   * @var \Drupal\commerce_amws_feed\Content\XmlBuilderInterface
   */
  protected $feedContentBuilder;

  /**
   * The Feeds API.
   *
   * @var \SellingPartnerApi\Api\FeedsApi
   */
  protected $feedsApi;

  /**
   * The Amazon MWS store that the feed will be submitted to.
   *
   * @var \Drupal\commerce_amws\Entity\StoreInterface
   */
  protected $amwsStore;

  /**
   * Constructs a new FeedPostOrderFulfilmentDataClient object.
   *
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
   *   The entity type manager.
   * @param \Drupal\commerce_amws_feed\Content\XmlBuilderInterface $feed_content_builder
   *   The XML feed content builder.
   * @param \SellingPartnerApi\Api\FeedsApi $feeds_api
   *   The Feeds API client.
   * @param \Drupal\commerce_amws\Entity\StoreInterface $amws_store
   *   The Amazon MWS store that the feed will be submitted to.
   */
  public function __construct(
    EntityTypeManagerInterface $entity_type_manager,
    FeedContentBuilderInterface $feed_content_builder,
    FeedsApi $feeds_api,
    StoreInterface $amws_store
  ) {
    $this->entityTypeManager = $entity_type_manager;
    $this->feedContentBuilder = $feed_content_builder;
    $this->feedsApi = $feeds_api;
    $this->amwsStore = $amws_store;
  }

  /**
   * {@inheritdoc}
   */
  public function importList(array $filters = [], array $options = []) {
    throw new \Exception(
      'Importing a list of Amazon MWS shipments is not supported.'
    );
  }

  /**
   * {@inheritdoc}
   */
  public function importEntity($id) {
    throw new \Exception('Importing an Amazon MWS shipment is not supported.');
  }

  /**
   * {@inheritdoc}
   */
  public function create(array $fields) {
    $feed_type = FeedType::POST_ORDER_FULFILLMENT_DATA;
    $content = $this->feedContentBuilder->build(
      $this->buildContent($fields)
    );

    // First, we create the document that will be submitted with the feed, and
    // upload its content.
    $document_response = $this->feedsApi->createFeedDocument(
      new CreateFeedDocumentSpecification(
        ['content_type' => $feed_type['contentType']]
      )
    );
    $feed_document_id = $document_response->getFeedDocumentId();

    $document = new Document($document_response, $feed_type);
    $document->upload($content);

    // Then, we create and submit the feed.
    $feed_response = $this->feedsApi->createFeed(
      new CreateFeedSpecification(
        [
          'feed_type' => $feed_type['name'],
          'marketplace_ids' => [$this->amwsStore->getMarketplaceId()],
          'input_feed_document_id' => $feed_document_id,
        ]
      )
    );
    $feed_id = $feed_response->getFeedId();

    // We store the feed and document IDs in the response so that even
    // subscribers can store them in the operation entity fields.
    $response = new \stdClass();
    $response->feedId = $feed_id;
    $response->feedDocumentId = $feed_document_id;

    return $response;
  }

  /**
   * {@inheritdoc}
   */
  public function update($id, array $fields) {
    throw new \Exception(
      'Updating an already submitted Feed for an Amazon MWS shipment is not supported. A new Feed should be submitted instead.'
    );
  }

  /**
   * Builds the content for the feed document.
   *
   * @param array $fields
   *   An associative array containing the values required for building the
   *   feed content.
   *
   * @return array
   *   The content in array format, as required for passing it to the XML
   *   builder.
   */
  protected function buildContent(array $fields) {
    $message = [
      'OrderFulfillment' => [
        'AmazonOrderID' => $fields['AmazonOrderID'],
      ],
    ];

    if ($fields['FulfillmentDate']) {
      $message['OrderFulfillment']['FulfillmentDate'] = $fields['FulfillmentDate'];
    }
    if ($fields['FulfillmentData']) {
      $message['OrderFulfillment']['FulfillmentData'] = $fields['FulfillmentData'];
    }
    if ($fields['Item']) {
      $message['OrderFulfillment']['Item'] = $fields['Item'];
    }

    return [
      'Header' => [
        'MerchantIdentifier' => $fields['MerchantIdentifier'],
      ],
      'MessageType' => 'OrderFulfillment',
      'Message' => [$message],
    ];
  }

}
+74 −0
Original line number Diff line number Diff line
<?php

namespace Drupal\commerce_amws_shipping\EntitySync;

use Drupal\commerce_amws_feed\Content\XmlBuilderInterface as FeedContentBuilderInterface;
use Drupal\entity_sync\Client\ProviderClientFactoryInterface;

use Drupal\Core\Entity\EntityTypeManagerInterface;

use SellingPartnerApi\Api\FeedsApi;
use SellingPartnerApi\Configuration;
use SellingPartnerApi\Endpoint;

/**
 * Factory for generating feed API clients.
 */
class FeedPostOrderFulfillmentDataFactory implements
  ProviderClientFactoryInterface {

  /**
   * The entity type manager.
   *
   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
   */
  protected $entityTypeManager;

  /**
   * The XML feed content builder.
   *
   * @var \Drupal\commerce_amws_feed\Content\XmlBuilderInterface
   */
  protected $feedContentBuilder;

  /**
   * Constructs a new FeedPostOrderFulfillmentDataFactory object.
   *
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
   *   The entity type manager.
   * @param \Drupal\commerce_amws_feed\Content\XmlBuilderInterface $feed_content_builder
   *   The XML feed content builder.
   */
  public function __construct(
    EntityTypeManagerInterface $entity_type_manager,
    FeedContentBuilderInterface $feed_content_builder
  ) {
    $this->entityTypeManager = $entity_type_manager;
    $this->feedContentBuilder = $feed_content_builder;
  }

  /**
   * {@inheritdoc}
   */
  public function get($sync_id, array $parameters) {
    $amws_store = $parameters['amws_store'];
    $configuration = new Configuration([
      'lwaClientId' => $amws_store->getLwaClientId(),
      'lwaClientSecret' => $amws_store->getLwaClientSecret(),
      'lwaRefreshToken' => $amws_store->getLwaRefreshToken(),
      'awsAccessKeyId' => $amws_store->getAwsAccessKeyId(),
      'awsSecretAccessKey' => $amws_store->getAwsSecretAccessKey(),
      'endpoint' => Endpoint::getByMarketplaceId(
        $amws_store->getMarketplaceId()
      ),
    ]);

    return new FeedPostOrderFulfillmentDataClient(
      $this->entityTypeManager,
      $this->feedContentBuilder,
      new FeedsApi($configuration),
      $amws_store
    );
  }

}