/**
  * Sending the campaigns
  *
  * @throws \Magento\Framework\Exception\LocalizedException
  */
 public function sendCampaigns()
 {
     foreach ($this->storeManager->getWebsites(true) as $website) {
         //check send status for processing
         $this->_checkSendStatus($website);
         //@codingStandardsIgnoreStart
         //start send process
         $storeIds = $this->websiteFactory->create()->load($website->getId())->getStoreIds();
         //@codingStandardsIgnoreEnd
         $emailsToSend = $this->_getEmailCampaigns($storeIds);
         $campaignsToSend = [];
         foreach ($emailsToSend as $campaign) {
             $email = $campaign->getEmail();
             $campaignId = $campaign->getCampaignId();
             $websiteId = $website->getId();
             $client = false;
             if ($this->helper->isEnabled($websiteId)) {
                 $client = $this->helper->getWebsiteApiClient($websiteId);
             }
             //Only if valid client is returned
             if ($client) {
                 //@codingStandardsIgnoreStart
                 if (!$campaignId) {
                     $campaign->setMessage('Missing campaign id: ' . $campaignId)->setSendStatus(\Dotdigitalgroup\Email\Model\Campaign::FAILED)->save();
                     continue;
                 } elseif (!$email) {
                     $campaign->setMessage('Missing email')->setSendStatus(\Dotdigitalgroup\Email\Model\Campaign::FAILED)->save();
                     continue;
                 }
                 //@codingStandardsIgnoreEnd
                 $campaignsToSend[$campaignId]['client'] = $client;
                 try {
                     $contactId = $this->helper->getContactId($campaign->getEmail(), $websiteId);
                     if (is_numeric($contactId)) {
                         //update data fields for order review camapigns
                         if ($campaign->getEventName() == 'Order Review') {
                             $order = $this->salesOrderFactory->create()->loadByIncrementId($campaign->getOrderIncrementId());
                             if ($lastOrderId = $this->helper->getWebsiteConfig(\Dotdigitalgroup\Email\Helper\Config::XML_PATH_CONNECTOR_CUSTOMER_LAST_ORDER_ID, $websiteId)) {
                                 $data[] = ['Key' => $lastOrderId, 'Value' => $order->getId()];
                             }
                             if ($orderIncrementId = $this->helper->getWebsiteConfig(\Dotdigitalgroup\Email\Helper\Config::XML_PATH_CONNECTOR_CUSTOMER_LAST_ORDER_INCREMENT_ID, $websiteId)) {
                                 $data[] = ['Key' => $orderIncrementId, 'Value' => $order->getIncrementId()];
                             }
                             if (!empty($data)) {
                                 //update data fields
                                 $client->updateContactDatafieldsByEmail($email, $data);
                             }
                         }
                         $campaignsToSend[$campaignId]['contacts'][] = $contactId;
                         $campaignsToSend[$campaignId]['ids'][] = $campaign->getId();
                     } else {
                         //@codingStandardsIgnoreStart
                         //update the failed to send email message error message
                         $campaign->setSendStatus(\Dotdigitalgroup\Email\Model\Campaign::FAILED)->setMessage('contact id returned is not numeric for email ' . $email)->save();
                         //@codingStandardsIgnoreEnd
                     }
                 } catch (\Exception $e) {
                     throw new \Magento\Framework\Exception\LocalizedException(__($e->getMessage()));
                 }
             }
         }
         foreach ($campaignsToSend as $campaignId => $data) {
             if (isset($data['contacts']) && isset($data['client'])) {
                 $contacts = $data['contacts'];
                 /** @var \Dotdigitalgroup\Email\Model\Apiconnector\Client $client */
                 $client = $data['client'];
                 $response = $client->postCampaignsSend($campaignId, $contacts);
                 if (isset($response->message)) {
                     //update  the failed to send email message
                     $this->campaignResourceModel->setMessage($data['ids'], $response->message);
                 } elseif (isset($response->id)) {
                     $this->campaignResourceModel->setProcessing($campaignId, $response->id);
                 } else {
                     //update  the failed to send email message
                     $this->campaignResourceModel->setMessage($data['ids'], 'No send id returned.');
                 }
             }
         }
     }
 }
 /**
  * Sync.
  *
  * @throws \Magento\Framework\Exception\LocalizedException
  */
 public function sync()
 {
     $automationOrderStatusCollection = $this->automationFactory->create()->addFieldToFilter('enrolment_status', self::AUTOMATION_STATUS_PENDING);
     $automationOrderStatusCollection->addFieldToFilter('automation_type', ['like' => '%' . self::ORDER_STATUS_AUTOMATION . '%'])->getSelect()->group('automation_type');
     $statusTypes = $automationOrderStatusCollection->getColumnValues('automation_type');
     foreach ($statusTypes as $type) {
         $this->automationTypes[$type] = \Dotdigitalgroup\Email\Helper\Config::XML_PATH_CONNECTOR_AUTOMATION_STUDIO_ORDER_STATUS;
     }
     //send the campaign by each types
     foreach ($this->automationTypes as $type => $config) {
         $contacts = [];
         $websites = $this->helper->getWebsites(true);
         foreach ($websites as $website) {
             if (strpos($type, self::ORDER_STATUS_AUTOMATION) !== false) {
                 //@codingStandardsIgnoreStart
                 $configValue = unserialize($this->helper->getWebsiteConfig($config, $website));
                 //@codingStandardsIgnoreEnd
                 if (is_array($configValue) && !empty($configValue)) {
                     foreach ($configValue as $one) {
                         if (strpos($type, $one['status']) !== false) {
                             $contacts[$website->getId()]['programId'] = $one['automation'];
                         }
                     }
                 }
             } else {
                 $contacts[$website->getId()]['programId'] = $this->helper->getWebsiteConfig($config, $website);
             }
         }
         //get collection from type
         $automationCollection = $this->automationFactory->create();
         $automationCollection->addFieldToFilter('enrolment_status', self::AUTOMATION_STATUS_PENDING);
         $automationCollection->addFieldToFilter('automation_type', $type);
         //limit because of the each contact request to get the id
         $automationCollection->getSelect()->limit($this->limit);
         foreach ($automationCollection as $automation) {
             $type = $automation->getAutomationType();
             //customerid, subscriberid, wishlistid..
             $email = $automation->getEmail();
             $this->typeId = $automation->getTypeId();
             $this->websiteId = $automation->getWebsiteId();
             $this->storeName = $automation->getStoreName();
             $typeDouble = $type;
             //Set type to generic automation status if type contains constant value
             if (strpos($typeDouble, self::ORDER_STATUS_AUTOMATION) !== false) {
                 $typeDouble = self::ORDER_STATUS_AUTOMATION;
             }
             $contactId = $this->helper->getContactId($email, $this->websiteId);
             //contact id is valid, can update datafields
             if ($contactId) {
                 //need to update datafields
                 $this->updateDatafieldsByType($typeDouble, $email);
                 $contacts[$automation->getWebsiteId()]['contacts'][$automation->getId()] = $contactId;
             } else {
                 // the contact is suppressed or the request failed
                 //@codingStandardsIgnoreStart
                 $automation->setEnrolmentStatus('Suppressed')->save();
                 //@codingStandardsIgnoreEnd
             }
         }
         foreach ($contacts as $websiteId => $websiteContacts) {
             if (isset($websiteContacts['contacts'])) {
                 $this->programId = $websiteContacts['programId'];
                 $contactsArray = $websiteContacts['contacts'];
                 //only for subscribed contacts
                 if (!empty($contactsArray) && $this->_checkCampignEnrolmentActive($this->programId)) {
                     $result = $this->sendContactsToAutomation(array_values($contactsArray), $websiteId);
                     //check for error message
                     if (isset($result->message)) {
                         $this->programStatus = 'Failed';
                         $this->programMessage = $result->message;
                     }
                     //program is not active
                 } elseif ($this->programMessage == 'Error: ERROR_PROGRAM_NOT_ACTIVE ') {
                     $this->programStatus = 'Deactivated';
                 }
                 //update contacts with the new status, and log the error message if failes
                 $coreResource = $this->resource;
                 $conn = $coreResource->getConnection('core_write');
                 try {
                     $contactIds = array_keys($contactsArray);
                     $bind = ['enrolment_status' => $this->programStatus, 'message' => $this->programMessage, 'updated_at' => $this->localeDate->date(null, null, false)->format('Y-m-d H:i:s')];
                     $where = ['id IN(?)' => $contactIds];
                     $num = $conn->update($coreResource->getTableName('email_automation'), $bind, $where);
                     //number of updated records
                     if ($num) {
                         $this->helper->log('Automation type : ' . $type . ', updated : ' . $num);
                     }
                 } catch (\Exception $e) {
                     throw new \Magento\Framework\Exception\LocalizedException(__($e->getMessage()));
                 }
             }
         }
     }
 }