/**
  * If it's configured to capture on shipment - do this.
  *
  * @param \Magento\Framework\Event\Observer $observer
  *
  * @return $this
  */
 public function execute(\Magento\Framework\Event\Observer $observer)
 {
     $dataObject = $observer->getEvent()->getDataObject();
     if ($dataObject->getCustomerId() && $dataObject->getStatusId() == \Magento\Review\Model\Review::STATUS_APPROVED) {
         $customerId = $dataObject->getCustomerId();
         $this->helper->setConnectorContactToReImport($customerId);
         //save review info in the table
         $this->registerReview($dataObject);
         $store = $this->storeManager->getStore($dataObject->getStoreId());
         $storeName = $store->getName();
         $website = $this->storeManager->getStore($store)->getWebsite();
         $customer = $this->customerFactory->create()->load($customerId);
         //if api is not enabled
         if (!$this->helper->isEnabled($website)) {
             return $this;
         }
         $programId = $this->helper->getWebsiteConfig('connector_automation/visitor_automation/review_automation');
         if ($programId) {
             $automation = $this->automationFactory->create();
             $automation->setEmail($customer->getEmail())->setAutomationType(\Dotdigitalgroup\Email\Model\Sync\Automation::AUTOMATION_TYPE_NEW_REVIEW)->setEnrolmentStatus(\Dotdigitalgroup\Email\Model\Sync\Automation::AUTOMATION_STATUS_PENDING)->setTypeId($dataObject->getReviewId())->setWebsiteId($website->getId())->setStoreName($storeName)->setProgramId($programId);
             $automation->save();
         }
     }
     return $this;
 }
 /**
  * Search the configuration data per website.
  *
  * @throws \Magento\Framework\Exception\LocalizedException
  */
 public function _searchAccounts()
 {
     $this->orderIds = [];
     $this->orderIdsForSingleSync = [];
     $websites = $this->helper->getWebsites(true);
     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);
             if (!isset($this->accounts[$this->apiUsername])) {
                 $account = $this->accountFactory->create()->setApiUsername($this->apiUsername)->setApiPassword($this->apiPassword);
                 $this->accounts[$this->apiUsername] = $account;
             }
             $this->accounts[$this->apiUsername]->setOrders($this->getConnectorOrders($website, $limit));
             $this->accounts[$this->apiUsername]->setOrderIds($this->orderIds);
             $this->accounts[$this->apiUsername]->setWebsites($website->getId());
             $this->accounts[$this->apiUsername]->setOrdersForSingleSync($this->getConnectorOrders($website, $limit, true));
             $this->accounts[$this->apiUsername]->setOrderIdsForSingleSync($this->orderIdsForSingleSync);
         }
     }
 }
 /**
  * Search for orders to review per website.
  */
 public function searchOrdersForReview()
 {
     $websites = $this->helper->getwebsites(true);
     foreach ($websites as $website) {
         $apiEnabled = $this->helper->isEnabled($website);
         if ($apiEnabled && $this->helper->getWebsiteConfig(\Dotdigitalgroup\Email\Helper\Config::XML_PATH_CONNECTOR_SYNC_ORDER_ENABLED, $website) && $this->helper->getOrderStatus($website) && $this->helper->getDelay($website)) {
             $storeIds = $website->getStoreIds();
             if (empty($storeIds)) {
                 continue;
             }
             $orderStatusFromConfig = $this->helper->getOrderStatus($website);
             $delayInDays = $this->helper->getDelay($website);
             $campaignCollection = $this->campaignCollection->create()->addFieldToFilter('event_name', 'Order Review');
             $campaignOrderIds = $campaignCollection->getColumnValues('order_increment_id');
             $fromTime = $this->date;
             $fromTime->subDay($delayInDays);
             $toTime = clone $fromTime;
             $to = $toTime->toString('YYYY-MM-dd HH:mm:ss');
             $from = $fromTime->subHour(2)->toString('YYYY-MM-dd HH:mm:ss');
             $created = ['from' => $from, 'to' => $to, 'date' => true];
             $collection = $this->orderCollection->create()->addFieldToFilter('main_table.status', $orderStatusFromConfig)->addFieldToFilter('main_table.created_at', $created)->addFieldToFilter('main_table.store_id', ['in' => $storeIds]);
             if (!empty($campaignOrderIds)) {
                 $collection->addFieldToFilter('main_table.increment_id', ['nin' => $campaignOrderIds]);
             }
             //process rules on collection
             $collection = $this->rulesFactory->create()->process($collection, \Dotdigitalgroup\Email\Model\Rules::REVIEW, $website->getId());
             if ($collection->getSize()) {
                 $this->reviewCollection[$website->getId()] = $collection;
             }
         }
     }
 }
 /**
  * Export reviews for website.
  *
  * @param \Magento\Store\Model\Website $website
  */
 public function _exportReviewsForWebsite(\Magento\Store\Model\Website $website)
 {
     $limit = $this->helper->getWebsiteConfig(\Dotdigitalgroup\Email\Helper\Config::XML_PATH_CONNECTOR_TRANSACTIONAL_DATA_SYNC_LIMIT, $website);
     $emailReviews = $this->_getReviewsToExport($website, $limit);
     $this->reviewIds = [];
     if ($emailReviews->getSize()) {
         $reviews = $this->mageReviewCollection->create()->addFieldToFilter('main_table.review_id', ['in' => $emailReviews->getColumnValues('review_id')])->addFieldToFilter('customer_id', ['notnull' => 'true']);
         $reviews->getSelect()->joinLeft(['c' => $this->coreResource->getTableName('customer_entity')], 'c.entity_id = customer_id', ['email', 'store_id']);
         foreach ($reviews as $mageReview) {
             try {
                 $product = $this->productFactory->create()->getCollection()->addIdFilter($mageReview->getEntityPkValue())->setStoreId($mageReview->getStoreId())->addAttributeToSelect(['product_url', 'name', 'store_id', 'small_image'])->setPage(1, 1)->getFirstItem();
                 $connectorReview = $this->connectorReviewFactory->create()->setReviewData($mageReview)->setProduct($product);
                 $votesCollection = $this->vote->getResourceCollection()->setReviewFilter($mageReview->getReviewId());
                 $votesCollection->getSelect()->join(['rating' => 'rating'], 'rating.rating_id = main_table.rating_id', ['rating_code' => 'rating.rating_code']);
                 foreach ($votesCollection as $ratingItem) {
                     $rating = $this->ratingFactory->create()->setRating($ratingItem);
                     $connectorReview->createRating($ratingItem->getRatingCode(), $rating);
                 }
                 $this->reviews[$website->getId()][] = $connectorReview;
                 $this->reviewIds[] = $mageReview->getReviewId();
             } catch (\Exception $e) {
                 $this->helper->debug((string) $e, []);
             }
         }
     }
 }
 /**
  * Automation new wishlist program.
  *
  * @param array $wishlist
  *
  * @return $this
  *
  * @throws \Magento\Framework\Exception\LocalizedException
  */
 public function registerWishlist($wishlist)
 {
     try {
         $emailWishlist = $this->wishlistFactory->create();
         $customer = $this->customerFactory->create();
         //if wishlist exist not to save again
         if (!$emailWishlist->getWishlist($wishlist['wishlist_id'])) {
             $customer->load($wishlist['customer_id']);
             $email = $customer->getEmail();
             $wishlistId = $wishlist['wishlist_id'];
             $websiteId = $customer->getWebsiteId();
             $emailWishlist->setWishlistId($wishlistId)->setCustomerId($wishlist['customer_id'])->setStoreId($customer->getStoreId())->save();
             $store = $this->storeManager->getStore($customer->getStoreId());
             $storeName = $store->getName();
             //if api is not enabled
             if (!$this->helper->isEnabled($websiteId)) {
                 return $this;
             }
             $programId = $this->helper->getWebsiteConfig('connector_automation/visitor_automation/wishlist_automation', $websiteId);
             //wishlist program mapped
             if ($programId) {
                 $automation = $this->automationFactory->create();
                 //save automation type
                 $automation->setEmail($email)->setAutomationType(\Dotdigitalgroup\Email\Model\Sync\Automation::AUTOMATION_TYPE_NEW_WISHLIST)->setEnrolmentStatus(\Dotdigitalgroup\Email\Model\Sync\Automation::AUTOMATION_STATUS_PENDING)->setTypeId($wishlistId)->setWebsiteId($websiteId)->setStoreName($storeName)->setProgramId($programId);
                 $automation->save();
             }
         }
     } catch (\Exception $e) {
         $this->helper->error((string) $e, []);
     }
 }
 /**
  * Check if api end point exist in DB.
  *
  * @throws \Magento\Framework\Exception\LocalizedException
  */
 public function _checkApiEndPoint()
 {
     $apiEndpoint = $this->helper->getWebsiteConfig(\Dotdigitalgroup\Email\Helper\Config::PATH_FOR_API_ENDPOINT);
     if (!$apiEndpoint) {
         if (!$this->getApiUsername() && !$this->getApiPassword()) {
             $this->setApiUsername($this->helper->getApiUsername())->setApiPassword($this->helper->getApiPassword());
         }
         $accountInfo = $this->getAccountInfo();
         if (is_object($accountInfo) && !isset($accountInfo->message)) {
             //save endpoint for account
             foreach ($accountInfo->properties as $property) {
                 if ($property->name == 'ApiEndpoint' && !empty($property->value)) {
                     $apiEndpoint = $property->value;
                     $this->_saveApiEndpoint($property->value);
                     break;
                 }
             }
         }
         //check api endpoint again
         if (!$apiEndpoint) {
             throw new \Magento\Framework\Exception\LocalizedException(__('API endpoint cannot be empty. Re-save api credentials to retrieve API endpoint.'));
         }
     }
     $this->apiEndpoint = $apiEndpoint;
 }
 /**
  * Register subscriber to automation.
  *
  * @param $email
  * @param $subscriber
  * @param $websiteId
  *
  * @throws \Magento\Framework\Exception\LocalizedException
  */
 public function addSubscriberToAutomation($email, $subscriber, $websiteId)
 {
     $storeId = $subscriber->getStoreId();
     $store = $this->storeManager->getStore($storeId);
     $programId = $this->helper->getWebsiteConfig('connector_automation/visitor_automation/subscriber_automation', $websiteId);
     //not mapped ignore
     if (!$programId) {
         return;
     }
     try {
         //@codingStandardsIgnoreStart
         //check the subscriber alredy exists
         $enrolmentCollection = $this->automationFactory->create()->getCollection()->addFieldToFilter('email', $email)->addFieldToFilter('automation_type', \Dotdigitalgroup\Email\Model\Sync\Automation::AUTOMATION_TYPE_NEW_SUBSCRIBER)->addFieldToFilter('website_id', $websiteId)->setPageSize(1);
         $enrolment = $enrolmentCollection->getFirstItem();
         //@codingStandardsIgnoreEnd
         //add new subscriber to automation
         if (!$enrolment->getId()) {
             //save subscriber to the queue
             $automation = $this->automationFactory->create()->setEmail($email)->setAutomationType(\Dotdigitalgroup\Email\Model\Sync\Automation::AUTOMATION_TYPE_NEW_SUBSCRIBER)->setEnrolmentStatus(\Dotdigitalgroup\Email\Model\Sync\Automation::AUTOMATION_STATUS_PENDING)->setTypeId($subscriber->getId())->setWebsiteId($websiteId)->setStoreName($store->getName())->setProgramId($programId);
             $automation->save();
         }
     } catch (\Exception $e) {
         throw new \Magento\Framework\Exception\LocalizedException(__($e->getMessage()));
     }
 }
 /**
  * Get product collection to export.
  *
  * @param      $store
  * @param bool $modified
  *
  * @return bool
  */
 public function _getProductsToExport($store, $modified = false)
 {
     $limit = $this->helper->getWebsiteConfig(\Dotdigitalgroup\Email\Helper\Config::XML_PATH_CONNECTOR_TRANSACTIONAL_DATA_SYNC_LIMIT);
     $connectorCollection = $this->catalogCollectionFactory->create();
     //for modified catalog
     if ($modified) {
         $connectorCollection->addFieldToFilter('modified', ['eq' => '1']);
     } else {
         $connectorCollection->addFieldToFilter('imported', ['null' => 'true']);
     }
     //set limit for collection
     $connectorCollection->setPageSize($limit);
     //check number of products
     if ($connectorCollection->getSize()) {
         $productIds = $connectorCollection->getColumnValues('product_id');
         $productCollection = $this->productCollection->create()->addAttributeToSelect('*')->addStoreFilter($store)->addAttributeToFilter('entity_id', ['in' => $productIds]);
         //visibility filter
         if ($visibility = $this->helper->getWebsiteConfig(\Dotdigitalgroup\Email\Helper\Config::XML_PATH_CONNECTOR_SYNC_CATALOG_VISIBILITY)) {
             $visibility = explode(',', $visibility);
             $productCollection->addAttributeToFilter('visibility', ['in' => $visibility]);
         }
         //type filter
         if ($type = $this->helper->getWebsiteConfig(\Dotdigitalgroup\Email\Helper\Config::XML_PATH_CONNECTOR_SYNC_CATALOG_TYPE)) {
             $type = explode(',', $type);
             $productCollection->addAttributeToFilter('type_id', ['in' => $type]);
         }
         $productCollection->addWebsiteNamesToResult()->addCategoryIds()->addOptionsToResult();
         return $productCollection;
     }
     return false;
 }
 /**
  * Get culture id needed for trial account.
  *
  * @return mixed
  */
 public function _getCultureId()
 {
     $fallback = 'en_US';
     $supportedCultures = ['en_US' => '1033', 'en_GB' => '2057', 'fr_FR' => '1036', 'es_ES' => '3082', 'de_DE' => '1031', 'it_IT' => '1040', 'ru_RU' => '1049', 'pt_PT' => '2070'];
     $localeCode = $this->helper->getWebsiteConfig(\Magento\Directory\Helper\Data::XML_PATH_DEFAULT_LOCALE);
     if (isset($supportedCultures[$localeCode])) {
         return $supportedCultures[$localeCode];
     }
     return $supportedCultures[$fallback];
 }
 /**
  * Check if both frotnend and backend secure(HTTPS).
  *
  * @return bool
  */
 public function isFrontendAdminSecure()
 {
     $frontend = $this->storeManager->getStore()->isFrontUrlSecure();
     $admin = $this->helper->getWebsiteConfig(\Magento\Store\Model\Store::XML_PATH_SECURE_IN_ADMINHTML);
     $current = $this->storeManager->getStore()->isCurrentlySecure();
     if ($frontend && $admin && $current) {
         return true;
     }
     return false;
 }
 /**
  * If it's configured to capture on shipment - do this.
  *
  * @param \Magento\Framework\Event\Observer $observer
  *
  * @return $this
  */
 public function execute(\Magento\Framework\Event\Observer $observer)
 {
     $object = $observer->getEvent()->getDataObject();
     $customer = $this->customerFactory->create()->load($object->getCustomerId());
     $website = $this->storeManager->getStore($customer->getStoreId())->getWebsite();
     //sync enabled
     $syncEnabled = $this->helper->getWebsiteConfig(\Dotdigitalgroup\Email\Helper\Config::XML_PATH_CONNECTOR_SYNC_WISHLIST_ENABLED, $website->getId());
     if ($this->helper->isEnabled($website->getId()) && $syncEnabled) {
         //Remove wishlist
         try {
             $item = $this->wishlistFactory->create()->getWishlist($object->getWishlistId());
             if ($item instanceof \Magento\Framework\DataObject && $item->getId()) {
                 //register in queue with importer
                 $this->importerFactory->create()->registerQueue(\Dotdigitalgroup\Email\Model\Importer::IMPORT_TYPE_WISHLIST, [$item->getId()], \Dotdigitalgroup\Email\Model\Importer::MODE_SINGLE_DELETE, $website->getId());
                 $item->delete();
             }
         } catch (\Exception $e) {
             $this->helper->debug((string) $e, []);
         }
     }
 }
 /**
  * New customer automation
  *
  * @param $customer
  */
 public function newCustomerAutomation($customer)
 {
     $email = $customer->getEmail();
     $websiteId = $customer->getWebsiteId();
     $customerId = $customer->getId();
     $store = $this->storeManager->getStore($customer->getStoreId());
     $storeName = $store->getName();
     try {
         //Api is enabled
         $apiEnabled = $this->helper->getWebsiteConfig(\Dotdigitalgroup\Email\Helper\Config::XML_PATH_CONNECTOR_API_ENABLED, $websiteId);
         //Automation enrolment
         $programId = $this->helper->getWebsiteConfig(\Dotdigitalgroup\Email\Helper\Config::XML_PATH_CONNECTOR_AUTOMATION_STUDIO_CUSTOMER, $websiteId);
         //new contact program mapped
         if ($programId && $apiEnabled) {
             //save automation type
             $this->setEmail($email)->setAutomationType(\Dotdigitalgroup\Email\Model\Sync\Automation::AUTOMATION_TYPE_NEW_CUSTOMER)->setEnrolmentStatus(\Dotdigitalgroup\Email\Model\Sync\Automation::AUTOMATION_STATUS_PENDING)->setTypeId($customerId)->setWebsiteId($websiteId)->setStoreName($storeName)->setProgramId($programId);
             $this->save();
         }
     } catch (\Exception $e) {
         $this->helper->debug((string) $e, []);
     }
 }
 public function _getBrandValue($id)
 {
     //attribute mapped from the config
     $attribute = $this->helper->getWebsiteConfig(\Dotdigitalgroup\Email\Helper\Config::XML_PATH_CONNECTOR_SYNC_DATA_FIELDS_BRAND_ATTRIBUTE, $this->customer->getWebsiteId());
     //if the id and attribute found
     if ($id && $attribute) {
         $brand = $this->productFactory->create()->setStoreId($this->customer->getStoreId())->load($id)->getAttributeText($attribute);
         //check for brand text
         if ($brand) {
             return $brand;
         }
     }
     return '';
 }
 /**
  * Customer collection with all data ready for export.
  *
  * @param     $customerIds
  * @param int $websiteId
  *
  * @return $this
  *
  * @throws \Magento\Framework\Exception\LocalizedException
  */
 public function _getCustomerCollection($customerIds, $websiteId = 0)
 {
     $customerCollection = $this->customerCollection->create()->addAttributeToSelect('*')->addNameToSelect()->joinAttribute('billing_street', 'customer_address/street', 'default_billing', null, 'left')->joinAttribute('billing_city', 'customer_address/city', 'default_billing', null, 'left')->joinAttribute('billing_country_code', 'customer_address/country_id', 'default_billing', null, 'left')->joinAttribute('billing_postcode', 'customer_address/postcode', 'default_billing', null, 'left')->joinAttribute('billing_telephone', 'customer_address/telephone', 'default_billing', null, 'left')->joinAttribute('billing_region', 'customer_address/region', 'default_billing', null, 'left')->joinAttribute('billing_company', 'customer_address/company', 'default_billing', null, 'left')->joinAttribute('shipping_street', 'customer_address/street', 'default_shipping', null, 'left')->joinAttribute('shipping_city', 'customer_address/city', 'default_shipping', null, 'left')->joinAttribute('shipping_country_code', 'customer_address/country_id', 'default_shipping', null, 'left')->joinAttribute('shipping_postcode', 'customer_address/postcode', 'default_shipping', null, 'left')->joinAttribute('shipping_telephone', 'customer_address/telephone', 'default_shipping', null, 'left')->joinAttribute('shipping_region', 'customer_address/region', 'default_shipping', null, 'left')->joinAttribute('shipping_company', 'customer_address/company', 'default_shipping', null, 'left')->addAttributeToFilter('entity_id', ['in' => $customerIds]);
     $quote = $this->resource->getTableName('quote');
     $salesOrder = $this->resource->getTableName('sales_order');
     $customerLog = $this->resource->getTableName('customer_log');
     $eavAttribute = $this->resource->getTableName('eav_attribute');
     $salesOrderGrid = $this->resource->getTableName('sales_order_grid');
     $salesOrderItem = $this->resource->getTableName('sales_order_item');
     $catalogCategoryProductIndex = $this->resource->getTableName('catalog_category_product');
     $eavAttributeOptionValue = $this->resource->getTableName('eav_attribute_option_value');
     $catalogProductEntityInt = $this->resource->getTableName('catalog_product_entity_int');
     // get the last login date from the log_customer table
     $customerCollection->getSelect()->columns(['last_logged_date' => new \Zend_Db_Expr("(SELECT last_login_at FROM  {$customerLog} WHERE customer_id =e.entity_id ORDER BY log_id DESC LIMIT 1)")]);
     // customer order information
     $alias = 'subselect';
     $statuses = $this->helper->getWebsiteConfig(\Dotdigitalgroup\Email\Helper\Config::XML_PATH_CONNECTOR_SYNC_DATA_FIELDS_STATUS, $websiteId);
     $statuses = explode(',', $statuses);
     $orderTable = $this->resource->getTableName('sales_order');
     $connection = $this->resource->getConnection();
     //@codingStandardsIgnoreStart
     $subselect = $connection->select()->from($orderTable, ['customer_id as s_customer_id', 'sum(grand_total) as total_spend', 'count(*) as number_of_orders', 'avg(grand_total) as average_order_value'])->group('customer_id');
     //any order statuses selected
     if ($statuses) {
         $subselect->where('status in (?)', $statuses);
     }
     $columnData = ['last_order_date' => new \Zend_Db_Expr("(SELECT created_at FROM {$salesOrderGrid} WHERE customer_id =e.entity_id ORDER BY created_at DESC LIMIT 1)"), 'last_order_id' => new \Zend_Db_Expr("(SELECT entity_id FROM {$salesOrderGrid} WHERE customer_id =e.entity_id ORDER BY created_at DESC LIMIT 1)"), 'last_increment_id' => new \Zend_Db_Expr("(SELECT increment_id FROM {$salesOrderGrid} WHERE customer_id =e.entity_id ORDER BY created_at DESC LIMIT 1)"), 'last_quote_id' => new \Zend_Db_Expr("(SELECT entity_id FROM {$quote} WHERE customer_id = e.entity_id ORDER BY created_at DESC LIMIT 1)"), 'first_category_id' => new \Zend_Db_Expr("(\n                        SELECT ccpi.category_id FROM {$salesOrder} as sfo\n                        left join {$salesOrderItem} as sfoi on sfoi.order_id = sfo.entity_id\n                        left join {$catalogCategoryProductIndex} as ccpi on ccpi.product_id = sfoi.product_id\n                        WHERE sfo.customer_id = e.entity_id\n                        ORDER BY sfo.created_at ASC, sfoi.price DESC\n                        LIMIT 1\n                    )"), 'last_category_id' => new \Zend_Db_Expr("(\n                        SELECT ccpi.category_id FROM {$salesOrder} as sfo\n                        left join {$salesOrderItem} as sfoi on sfoi.order_id = sfo.entity_id\n                        left join {$catalogCategoryProductIndex} as ccpi on ccpi.product_id = sfoi.product_id\n                        WHERE sfo.customer_id = e.entity_id\n                        ORDER BY sfo.created_at DESC, sfoi.price DESC\n                        LIMIT 1\n                    )"), 'product_id_for_first_brand' => new \Zend_Db_Expr("(\n                        SELECT sfoi.product_id FROM {$salesOrder} as sfo\n                        left join {$salesOrderItem} as sfoi on sfoi.order_id = sfo.entity_id\n                        WHERE sfo.customer_id = e.entity_id and sfoi.product_type = 'simple'\n                        ORDER BY sfo.created_at ASC, sfoi.price DESC\n                        LIMIT 1\n                    )"), 'product_id_for_last_brand' => new \Zend_Db_Expr("(\n                        SELECT sfoi.product_id FROM {$salesOrder} as sfo\n                        left join {$salesOrderItem} as sfoi on sfoi.order_id = sfo.entity_id\n                        WHERE sfo.customer_id = e.entity_id and sfoi.product_type = 'simple'\n                        ORDER BY sfo.created_at DESC, sfoi.price DESC\n                        LIMIT 1\n                    )"), 'week_day' => new \Zend_Db_Expr("(\n                        SELECT dayname(created_at) as week_day\n                        FROM {$salesOrder}\n                        WHERE customer_id = e.entity_id\n                        GROUP BY week_day\n                        HAVING COUNT(*) > 0\n                        ORDER BY (COUNT(*)) DESC\n                        LIMIT 1\n                    )"), 'month_day' => new \Zend_Db_Expr("(\n                        SELECT monthname(created_at) as month_day\n                        FROM {$salesOrder}\n                        WHERE customer_id = e.entity_id\n                        GROUP BY month_day\n                        HAVING COUNT(*) > 0\n                        ORDER BY (COUNT(*)) DESC\n                        LIMIT 1\n                    )"), 'most_category_id' => new \Zend_Db_Expr("(\n                        SELECT ccpi.category_id FROM {$salesOrder} as sfo\n                        LEFT JOIN {$salesOrderItem} as sfoi on sfoi.order_id = sfo.entity_id\n                        LEFT JOIN {$catalogCategoryProductIndex} as ccpi on ccpi.product_id = sfoi.product_id\n                        WHERE sfo.customer_id = e.entity_id AND ccpi.category_id is not null\n                        GROUP BY category_id\n                        HAVING COUNT(sfoi.product_id) > 0\n                        ORDER BY COUNT(sfoi.product_id) DESC\n                        LIMIT 1\n                    )")];
     /**
      * CatalogStaging fix.
      * @todo this will fix https://github.com/magento/magento2/issues/6478
      */
     $rowIdExists = $this->isRowIdExistsInCatalogProductEntityId();
     if ($rowIdExists) {
         $mostData = new \Zend_Db_Expr("(\n                    SELECT eaov.value from {$salesOrder} sfo\n                    LEFT JOIN {$salesOrderItem} as sfoi on sfoi.order_id = sfo.entity_id\n                    LEFT JOIN {$catalogProductEntityInt} pei on pei.row_id = sfoi.product_id\n                    LEFT JOIN {$eavAttribute} ea ON pei.attribute_id = ea.attribute_id\n                    LEFT JOIN {$eavAttributeOptionValue} as eaov on pei.value = eaov.option_id\n                    WHERE sfo.customer_id = e.entity_id AND ea.attribute_code = 'manufacturer' AND eaov.value is not null\n                    GROUP BY eaov.value\n                    HAVING count(*) > 0\n                    ORDER BY count(*) DESC\n                    LIMIT 1\n                )");
     } else {
         $mostData = new \Zend_Db_Expr("(\n                    SELECT eaov.value from {$salesOrder} sfo\n                    LEFT JOIN {$salesOrderItem} as sfoi on sfoi.order_id = sfo.entity_id\n                    LEFT JOIN {$catalogProductEntityInt} pei on pei.entity_id = sfoi.product_id\n                    LEFT JOIN {$eavAttribute} ea ON pei.attribute_id = ea.attribute_id\n                    LEFT JOIN {$eavAttributeOptionValue} as eaov on pei.value = eaov.option_id\n                    WHERE sfo.customer_id = e.entity_id AND ea.attribute_code = 'manufacturer' AND eaov.value is not null\n                    GROUP BY eaov.value\n                    HAVING count(*) > 0\n                    ORDER BY count(*) DESC\n                    LIMIT 1\n                )");
     }
     $columnData['most_brand'] = $mostData;
     $customerCollection->getSelect()->columns($columnData);
     $customerCollection->getSelect()->joinLeft([$alias => $subselect], "{$alias}.s_customer_id = e.entity_id");
     //@codingStandardsIgnoreEnd
     return $customerCollection;
 }
 /**
  * Export single wishilist for website.
  *
  * @param \Magento\Store\Model\Website $website
  */
 public function exportWishlistForWebsiteInSingle(\Magento\Store\Model\Website $website)
 {
     //transactional data limit
     $limit = $this->helper->getWebsiteConfig(\Dotdigitalgroup\Email\Helper\Config::XML_PATH_CONNECTOR_TRANSACTIONAL_DATA_SYNC_LIMIT, $website);
     $collection = $this->getModifiedWishlistToImport($website, $limit);
     $this->wishlistIds = [];
     //email_wishlist wishlist ids
     $wishlistIds = $collection->getColumnValues('wishlist_id');
     $wishlistCollection = $this->wishlist->create()->getCollection()->addFieldToFilter('wishlist_id', ['in' => $wishlistIds]);
     $wishlistCollection->getSelect()->joinLeft(['c' => $this->resource->getTableName('customer_entity')], 'c.entity_id = customer_id', ['email', 'store_id']);
     foreach ($wishlistCollection as $wishlist) {
         $wishlistId = $wishlist->getid();
         $wishlistItems = $wishlist->getItemCollection();
         $connectorWishlist = $this->wishlistFactory->create();
         $connectorWishlist->setId($wishlistId)->setUpdatedAt($wishlist->getUpdatedAt())->setCustomerId($wishlist->getCustomerId())->setEmail($wishlist->getEmail());
         if ($wishlistItems->getSize()) {
             foreach ($wishlistItems as $item) {
                 $product = $item->getProduct();
                 $wishlistItem = $this->itemFactory->create()->setProduct($product)->setQty($item->getQty())->setPrice($product);
                 //store for wishlists
                 $connectorWishlist->setItem($wishlistItem);
                 $this->countWishlists++;
             }
             //send wishlist as transactional data
             $this->start = microtime(true);
             //register in queue with importer
             $check = $this->importerFactory->create()->registerQueue(Importer::IMPORT_TYPE_WISHLIST, $connectorWishlist, Importer::MODE_SINGLE, $website->getId());
             if ($check) {
                 $this->wishlistIds[] = $wishlistId;
             }
         } else {
             //register in queue with importer
             $check = $this->importerFactory->create()->registerQueue(Importer::IMPORT_TYPE_WISHLIST, [$wishlist->getId()], Importer::MODE_SINGLE, $website->getId());
             if ($check) {
                 $this->wishlistIds[] = $wishlistId;
             }
         }
     }
     if (!empty($this->wishlistIds)) {
         $this->setImported($this->wishlistIds, true);
     }
 }
 /**
  * Build url param.
  *
  * @param string $refreshToken
  *
  * @return string
  */
 public function buildUrlParams($refreshToken)
 {
     $params = 'client_id=' . $this->helper->getWebsiteConfig(\Dotdigitalgroup\Email\Helper\Config::XML_PATH_CONNECTOR_CLIENT_ID) . '&client_secret=' . $this->helper->getWebsiteConfig(\Dotdigitalgroup\Email\Helper\Config::XML_PATH_CONNECTOR_CLIENT_SECRET_ID) . '&refresh_token=' . $refreshToken . '&grant_type=refresh_token';
     return $params;
 }
 /**
  * Get config values.
  *
  * @param $path
  * @param $website
  *
  * @return mixed
  */
 public function _getWebsiteConfigFromHelper($path, $website)
 {
     return $this->helper->getWebsiteConfig($path, $website);
 }
 /**
  * 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()));
                 }
             }
         }
     }
 }
 /**
  * Get login user url with for OAUTH.
  *
  * @param int $website
  *
  * @return string
  */
 public function getLogUserUrl($website = 0)
 {
     if ($this->isAuthorizeCustomDomain($website)) {
         $logUserUrl = $this->helper->getWebsiteConfig(self::XML_PATH_CONNECTOR_CUSTOM_DOMAIN) . self::API_CONNECTOR_OAUTH_URL_LOG_USER;
     } else {
         $logUserUrl = $this->getRegionAuthorize($website) . self::API_CONNECTOR_OAUTH_URL_LOG_USER;
     }
     return $logUserUrl;
 }
 /**
  * Set the order data information.
  *
  * @param $orderData
  *
  * @return $this
  */
 public function setOrderData($orderData)
 {
     $this->id = $orderData->getIncrementId();
     $this->quoteId = $orderData->getQuoteId();
     $this->email = $orderData->getCustomerEmail();
     $this->storeName = $orderData->getStoreName();
     $this->purchaseDate = $this->localeDate->date($orderData->getCreatedAt())->format(\Zend_Date::ISO_8601);
     $this->deliveryMethod = $orderData->getShippingDescription();
     $this->deliveryTotal = (double) number_format($orderData->getShippingAmount(), 2, '.', '');
     $this->currency = $orderData->getStoreCurrencyCode();
     if ($payment = $orderData->getPayment()) {
         $this->payment = $payment->getMethodInstance()->getTitle();
     }
     $this->couponCode = $orderData->getCouponCode();
     /*
      * custom order attributes
      */
     $website = $this->_storeManager->getStore($orderData->getStore())->getWebsite();
     $customAttributes = $this->helper->getConfigSelectedCustomOrderAttributes($website);
     if ($customAttributes) {
         $fields = $this->helper->getOrderTableDescription();
         $this->custom = [];
         foreach ($customAttributes as $customAttribute) {
             if (isset($fields[$customAttribute])) {
                 $field = $fields[$customAttribute];
                 $value = $this->_getCustomAttributeValue($field, $orderData);
                 if ($value) {
                     $this->_assignCustom($field, $value);
                 }
             }
         }
     }
     /*
      * Billing address.
      */
     if ($orderData->getBillingAddress()) {
         $billingData = $orderData->getBillingAddress()->getData();
         $this->billingAddress = ['billing_address_1' => $this->_getStreet($billingData['street'], 1), 'billing_address_2' => $this->_getStreet($billingData['street'], 2), 'billing_city' => $billingData['city'], 'billing_region' => $billingData['region'], 'billing_country' => $billingData['country_id'], 'billing_postcode' => $billingData['postcode']];
     }
     /*
      * Shipping address.
      */
     if ($orderData->getShippingAddress()) {
         $shippingData = $orderData->getShippingAddress()->getData();
         $this->deliveryAddress = ['delivery_address_1' => $this->_getStreet($shippingData['street'], 1), 'delivery_address_2' => $this->_getStreet($shippingData['street'], 2), 'delivery_city' => $shippingData['city'], 'delivery_region' => $shippingData['region'], 'delivery_country' => $shippingData['country_id'], 'delivery_postcode' => $shippingData['postcode']];
     }
     $syncCustomOption = $this->helper->getWebsiteConfig(\Dotdigitalgroup\Email\Helper\Config::XML_PATH_CONNECTOR_SYNC_ORDER_PRODUCT_CUSTOM_OPTIONS, $website);
     /*
      * Order items.
      */
     foreach ($orderData->getAllItems() as $productItem) {
         //product custom options
         $customOptions = [];
         if ($syncCustomOption) {
             $customOptions = $this->_getOrderItemOptions($productItem);
         }
         $productModel = $productItem->getProduct();
         if ($productModel) {
             // category names
             $categoryCollection = $productModel->getCategoryCollection()->addAttributeToSelect('name');
             $productCat = [];
             foreach ($categoryCollection as $cat) {
                 $categories = [];
                 $categories[] = $cat->getName();
                 $productCat[]['Name'] = substr(implode(', ', $categories), 0, 244);
             }
             $attributes = [];
             //selected attributes from config
             $configAttributes = $this->helper->getWebsiteConfig(\Dotdigitalgroup\Email\Helper\Config::XML_PATH_CONNECTOR_SYNC_ORDER_PRODUCT_ATTRIBUTES, $orderData->getStore()->getWebsite());
             if ($configAttributes) {
                 $configAttributes = explode(',', $configAttributes);
                 //attributes from attribute set
                 $attributesFromAttributeSet = $this->_getAttributesArray($productModel->getAttributeSetId());
                 foreach ($configAttributes as $attributeCode) {
                     //if config attribute is in attribute set
                     if (in_array($attributeCode, $attributesFromAttributeSet)) {
                         //attribute input type
                         $inputType = $productModel->getResource()->getAttribute($attributeCode)->getFrontend()->getInputType();
                         //fetch attribute value from product depending on input type
                         switch ($inputType) {
                             case 'multiselect':
                             case 'select':
                             case 'dropdown':
                                 $value = $productModel->getAttributeText($attributeCode);
                                 break;
                             case 'date':
                                 $value = $this->localeDate->date($productModel->getData($attributeCode))->format(\Zend_Date::ISO_8601);
                                 break;
                             default:
                                 $value = $productModel->getData($attributeCode);
                                 break;
                         }
                         if ($value && !is_array($value)) {
                             // check limit on text and assign value to array
                             $attributes[][$attributeCode] = $this->_limitLength($value);
                         } elseif (is_array($value)) {
                             $value = implode($value, ', ');
                             $attributes[][$attributeCode] = $this->_limitLength($value);
                         }
                     }
                 }
             }
             $attributeSetName = $this->getAttributeSetName($productModel);
             $productData = ['name' => $productItem->getName(), 'sku' => $productItem->getSku(), 'qty' => (int) number_format($productItem->getData('qty_ordered'), 2), 'price' => (double) number_format($productItem->getPrice(), 2, '.', ''), 'attribute-set' => $attributeSetName, 'categories' => $productCat, 'attributes' => $attributes, 'custom-options' => $customOptions];
             if (!$customOptions) {
                 unset($productData['custom-options']);
             }
             $this->products[] = $productData;
         } else {
             // when no product information is available limit to this data
             $productData = ['name' => $productItem->getName(), 'sku' => $productItem->getSku(), 'qty' => (int) number_format($productItem->getData('qty_ordered'), 2), 'price' => (double) number_format($productItem->getPrice(), 2, '.', ''), 'attribute-set' => '', 'categories' => [], 'attributes' => [], 'custom-options' => $customOptions];
             if (!$customOptions) {
                 unset($productData['custom-options']);
             }
             $this->products[] = $productData;
         }
     }
     $this->orderSubtotal = (double) number_format($orderData->getData('subtotal'), 2, '.', '');
     $this->discountAmount = (double) number_format($orderData->getData('discount_amount'), 2, '.', '');
     $orderTotal = abs($orderData->getData('grand_total') - $orderData->getTotalRefunded());
     $this->orderTotal = (double) number_format($orderTotal, 2, '.', '');
     $this->orderStatus = $orderData->getStatus();
     unset($this->_storeManager);
     return $this;
 }
 /**
  * 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.');
                 }
             }
         }
     }
 }
 /**
  * Wishlist display mode type.
  *
  * @return mixed
  */
 public function getMode()
 {
     return $this->helper->getWebsiteConfig(\Dotdigitalgroup\Email\Helper\Config::XML_PATH_CONNECTOR_DYNAMIC_CONTENT_WIHSLIST_DISPLAY);
 }
 /**
  * Coupon background color from config.
  *
  * @return mixed
  */
 public function getBackgroundColor()
 {
     return $this->helper->getWebsiteConfig(Config::XML_PATH_CONNECTOR_DYNAMIC_COUPON_BG_COLOR);
 }