123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369 |
- <?php
- namespace Dotdigitalgroup\Email\Model\Sync;
- /**
- * Sync Orders.
- */
- class Order
- {
- /**
- * @var \Dotdigitalgroup\Email\Model\ResourceModel\Contact\CollectionFactory
- */
- public $contactCollectionFactory;
- /**
- * @var array
- */
- private $accounts = [];
- /**
- * @var string
- */
- private $apiUsername;
- /**
- * @var string
- */
- private $apiPassword;
- /**
- * Global number of orders.
- *
- * @var int
- */
- public $countOrders = 0;
- /**
- * @var array
- */
- private $orderIds;
- /**
- * @var \Dotdigitalgroup\Email\Helper\Data
- */
- private $helper;
- /**
- * @var \Dotdigitalgroup\Email\Model\ResourceModel\Contact
- */
- private $contactResource;
- /**
- * @var \Dotdigitalgroup\Email\Model\OrderFactory
- */
- private $orderFactory;
- /**
- * @var \Magento\Sales\Model\OrderFactory
- */
- private $salesOrderFactory;
- /**
- * @var \Dotdigitalgroup\Email\Model\Connector\OrderFactory
- */
- private $connectorOrderFactory;
- /**
- * @var \Dotdigitalgroup\Email\Model\Connector\AccountFactory
- */
- private $accountFactory;
- /**
- * @var \Dotdigitalgroup\Email\Model\ImporterFactory
- */
- private $importerFactory;
- /**
- * @var \Dotdigitalgroup\Email\Model\ResourceModel\Order
- */
- private $orderResource;
- /**
- * @var array
- */
- public $guests = [];
- /**
- * Order constructor.
- * @param \Dotdigitalgroup\Email\Model\ImporterFactory $importerFactory
- * @param \Dotdigitalgroup\Email\Model\OrderFactory $orderFactory
- * @param \Dotdigitalgroup\Email\Model\Connector\AccountFactory $accountFactory
- * @param \Dotdigitalgroup\Email\Model\Connector\OrderFactory $connectorOrderFactory
- * @param \Dotdigitalgroup\Email\Model\ResourceModel\Contact $contactResource
- * @param \Dotdigitalgroup\Email\Model\ResourceModel\Contact\CollectionFactory $contactCollectionFactory
- * @param \Dotdigitalgroup\Email\Model\ResourceModel\Order $orderResource
- * @param \Dotdigitalgroup\Email\Helper\Data $helper
- * @param \Magento\Sales\Model\OrderFactory $salesOrderFactory
- *
- * @SuppressWarnings(PHPMD.ExcessiveParameterList)
- */
- public function __construct(
- \Dotdigitalgroup\Email\Model\ImporterFactory $importerFactory,
- \Dotdigitalgroup\Email\Model\OrderFactory $orderFactory,
- \Dotdigitalgroup\Email\Model\Connector\AccountFactory $accountFactory,
- \Dotdigitalgroup\Email\Model\Connector\OrderFactory $connectorOrderFactory,
- \Dotdigitalgroup\Email\Model\ResourceModel\Contact $contactResource,
- \Dotdigitalgroup\Email\Model\ResourceModel\Contact\CollectionFactory $contactCollectionFactory,
- \Dotdigitalgroup\Email\Model\ResourceModel\Order $orderResource,
- \Dotdigitalgroup\Email\Helper\Data $helper,
- \Magento\Sales\Model\OrderFactory $salesOrderFactory
- ) {
- $this->importerFactory = $importerFactory;
- $this->orderFactory = $orderFactory;
- $this->accountFactory = $accountFactory;
- $this->connectorOrderFactory = $connectorOrderFactory;
- $this->contactResource = $contactResource;
- $this->orderResource = $orderResource;
- $this->helper = $helper;
- $this->salesOrderFactory = $salesOrderFactory;
- $this->contactCollectionFactory = $contactCollectionFactory;
- }
- /**
- * Initial sync the transactional data.
- *
- * @return array
- *
- * @throws \Magento\Framework\Exception\LocalizedException
- */
- public function sync()
- {
- $response = ['success' => true, 'message' => 'Done.'];
- // Initialise a return hash containing results of our sync attempt
- $this->searchWebsiteAccounts();
- foreach ($this->accounts as $account) {
- $orders = $account->getOrders();
- $ordersForSingleSync = $account->getOrdersForSingleSync();
- $numOrders = count($orders);
- $numOrdersForSingleSync = count($ordersForSingleSync);
- $website = $account->getWebsites();
- $this->countOrders += $numOrders;
- $this->countOrders += $numOrdersForSingleSync;
- //create bulk
- if ($numOrders) {
- $this->helper->log('--------- Order sync ---------- : ' . $numOrders);
- //queue order into importer
- $this->importerFactory->create()
- ->registerQueue(
- \Dotdigitalgroup\Email\Model\Importer::IMPORT_TYPE_ORDERS,
- $orders,
- \Dotdigitalgroup\Email\Model\Importer::MODE_BULK,
- $website[0]
- );
- }
- //create single
- if ($numOrdersForSingleSync) {
- $this->createSingleImports($ordersForSingleSync, $website);
- }
- //mark the orders as imported
- $this->orderResource->setImported($this->orderIds);
- unset($this->accounts[$account->getApiUsername()]);
- }
- /**
- * Add guests to contact table.
- */
- if (! empty($this->guests)) {
- $orderEmails = array_keys($this->guests);
- $guestsEmailFound = $this->contactCollectionFactory->create()
- ->addFieldToFilter('email', ['in' => $orderEmails])
- ->getColumnValues('email');
- //remove the contacts that already exists
- foreach ($guestsEmailFound as $email) {
- unset($this->guests[strtolower($email)]);
- }
- //insert new guests contacts
- $this->contactResource->insertGuests($this->guests);
- //mark the existing contacts with is guest in bulk
- $this->contactResource->updateContactsAsGuests($guestsEmailFound);
- }
- if ($this->countOrders) {
- $response['message'] = 'Orders updated ' . $this->countOrders;
- }
- return $response;
- }
- /**
- * Search the configuration data per website.
- *
- * @throws \Magento\Framework\Exception\LocalizedException
- *
- * @return null
- */
- public function searchWebsiteAccounts()
- {
- $websites = $this->helper->getWebsites();
- foreach ($websites as $website) {
- $apiEnabled = $this->helper->isEnabled($website);
- $storeIds = $website->getStoreIds();
- // api and order sync should be enabled, skip website with no store ids
- if ($apiEnabled && $this->helper->getWebsiteConfig(
- \Dotdigitalgroup\Email\Helper\Config::XML_PATH_CONNECTOR_SYNC_ORDER_ENABLED,
- $website
- )
- && !empty($storeIds)
- ) {
- $this->apiUsername = $this->helper->getApiUsername($website);
- $this->apiPassword = $this->helper->getApiPassword($website);
- // limit for orders included to sync
- $limit = $this->helper->getWebsiteConfig(
- \Dotdigitalgroup\Email\Helper\Config::XML_PATH_CONNECTOR_TRANSACTIONAL_DATA_SYNC_LIMIT,
- $website
- );
- //set account for later use
- if (! isset($this->accounts[$this->apiUsername])) {
- $account = $this->accountFactory->create();
- $account->setApiUsername($this->apiUsername);
- $account->setApiPassword($this->apiPassword);
- $this->accounts[$this->apiUsername] = $account;
- }
- $pendingOrders = $this->getPendingConnectorOrders($website, $limit);
- if (! empty($pendingOrders)) {
- $this->accounts[$this->apiUsername]->setOrders($pendingOrders);
- }
- $this->accounts[$this->apiUsername]->setWebsites($website->getId());
- $modifiedOrders = $this->getModifiedOrders($website, $limit);
- if (! empty($modifiedOrders)) {
- $this->accounts[$this->apiUsername]->setOrdersForSingleSync($modifiedOrders);
- }
- }
- }
- }
- /**
- * @param \Magento\Store\Api\Data\WebsiteInterface $website
- * @param int $limit
- *
- * @return array
- */
- public function getPendingConnectorOrders($website, $limit = 100)
- {
- $orders = [];
- $storeIds = $website->getStoreIds();
- /** @var \Dotdigitalgroup\Email\Model\Order $orderModel */
- $orderModel = $this->orderFactory->create();
- //get order statuses set in configuration section
- $orderStatuses = $this->helper->getConfigSelectedStatus($website);
- //no active store for website
- if (empty($storeIds) || empty($orderStatuses)) {
- return [];
- }
- //pending order from email_order
- $orderCollection = $orderModel->getOrdersToImport($storeIds, $limit, $orderStatuses);
- //no orders found
- if (! $orderCollection->getSize()) {
- return $orders;
- }
- $orders = $this->mappOrderData($orderCollection, $orderModel, $orders);
- return $orders;
- }
- /**
- * @param \Magento\Store\Api\Data\WebsiteInterface $website
- * @param int $limit
- *
- * @return array
- */
- protected function getModifiedOrders($website, $limit)
- {
- $orders = [];
- $storeIds = $website->getStoreIds();
- /** @var \Dotdigitalgroup\Email\Model\Order $orderModel */
- $orderModel = $this->orderFactory->create();
- //get order statuses set in configuration section
- $orderStatuses = $this->helper->getConfigSelectedStatus($website);
- //no active store for website
- if (empty($storeIds) || empty($orderStatuses)) {
- return [];
- }
- //pending order from email_order
- $orderCollection = $orderModel->getModifiedOrdersToImport($storeIds, $limit, $orderStatuses);
- //no orders found
- if (! $orderCollection->getSize()) {
- return $orders;
- }
- $orders = $this->mappOrderData($orderCollection, $orderModel, $orders);
- return $orders;
- }
- /**
- * @param \Dotdigitalgroup\Email\Model\ResourceModel\Order\Collection $orderCollection
- * @param \Dotdigitalgroup\Email\Model\Order $orderModel
- * @param array $orders
- *
- * @return array
- */
- protected function mappOrderData($orderCollection, $orderModel, $orders)
- {
- $orderIds = $orderCollection->getColumnValues('order_id');
- //get the order collection
- $salesOrderCollection = $orderModel->getSalesOrdersWithIds($orderIds);
- foreach ($salesOrderCollection as $order) {
- if ($order->getId()) {
- $storeId = $order->getStoreId();
- $websiteId = $this->helper->storeManager->getStore($storeId)->getWebsiteId();
- /**
- * Add guest to array to add to contacts table.
- */
- if ($order->getCustomerIsGuest() && $order->getCustomerEmail()) {
- $email = $order->getCustomerEmail();
- $this->guests[strtolower($email)] = [
- 'email' => $email,
- 'website_id' => $websiteId,
- 'store_id' => $storeId,
- 'is_guest' => 1
- ];
- }
- $connectorOrder = $this->connectorOrderFactory->create();
- $connectorOrder->setOrderData($order);
- $orders[] = $connectorOrder;
- }
- $this->orderIds[] = $order->getId();
- }
- return $orders;
- }
- /**
- * @param array $ordersForSingleSync
- * @param array $website
- *
- * @return null
- */
- protected function createSingleImports($ordersForSingleSync, $website)
- {
- foreach ($ordersForSingleSync as $order) {
- //register in queue with importer
- $this->importerFactory->create()
- ->registerQueue(
- \Dotdigitalgroup\Email\Model\Importer::IMPORT_TYPE_ORDERS,
- $order,
- \Dotdigitalgroup\Email\Model\Importer::MODE_SINGLE,
- $website[0]
- );
- }
- }
- }
|