/** * Proccess abandoned carts. * * @param string $mode */ public function proccessAbandonedCarts($mode = 'all') { /* * Save lost baskets to be send in Send table. */ $stores = $this->_helper->getStores(); foreach ($stores as $store) { $storeId = $store->getId(); if ($mode == 'all' || $mode == 'customers') { /* * Customers campaigns */ foreach ($this->lostBasketCustomers as $num) { //customer enabled if ($this->_isLostBasketCustomerEnabled($num, $storeId)) { //number of the campaign use minutes if ($num == 1) { $minutes = $this->_getLostBasketCustomerInterval($num, $storeId); $interval = new \DateInterval('PT' . $minutes . 'M'); } else { $hours = (int) $this->_getLostBasketCustomerInterval($num, $storeId); $interval = new \DateInterval('PT' . $hours . 'H'); } $fromTime = new \DateTime('now', new \DateTimeZone('UTC')); $fromTime->sub($interval); $toTime = clone $fromTime; $fromTime->sub(new \DateInterval('PT5M')); //format time $fromDate = $fromTime->format('Y-m-d H:i:s'); $toDate = $toTime->format('Y-m-d H:i:s'); //active quotes $quoteCollection = $this->_getStoreQuotes($fromDate, $toDate, $guest = false, $storeId); //found abandoned carts if ($quoteCollection->getSize()) { $this->_helper->log('Customer cart : ' . $num . ', from : ' . $fromDate . ' ,to ' . $toDate); } //campaign id for customers $campaignId = $this->_getLostBasketCustomerCampaignId($num, $storeId); foreach ($quoteCollection as $quote) { $email = $quote->getCustomerEmail(); $websiteId = $store->getWebsiteId(); $quoteId = $quote->getId(); //api - set the last quote id for customer $this->_helper->updateLastQuoteId($quoteId, $email, $websiteId); $items = $quote->getAllItems(); $mostExpensiveItem = false; foreach ($items as $item) { if ($mostExpensiveItem == false) { $mostExpensiveItem = $item; } elseif ($item->getPrice() > $mostExpensiveItem->getPrice()) { $mostExpensiveItem = $item; } } //api-send the most expensive product for abandoned cart if ($mostExpensiveItem) { $this->_helper->updateAbandonedProductName($mostExpensiveItem->getName(), $email, $websiteId); } //send email only if the interval limit passed, no emails during this interval $intervalLimit = $this->_checkCustomerCartLimit($email, $storeId); //no campign found for interval pass if (!$intervalLimit) { //save lost basket for sending //@codingStandardsIgnoreStart $this->_campaignFactory->create()->setEmail($email)->setCustomerId($quote->getCustomerId())->setEventName('Lost Basket')->setQuoteId($quoteId)->setMessage('Abandoned Cart ' . $num)->setCampaignId($campaignId)->setStoreId($storeId)->setWebsiteId($websiteId)->setIsSent(null)->save(); //@codingStandardsIgnoreEnd } } } } } if ($mode == 'all' || $mode == 'guests') { /* * Guests campaigns */ foreach ($this->lostBasketGuests as $num) { if ($this->_isLostBasketGuestEnabled($num, $storeId)) { //for the first cart which use the minutes if ($num == 1) { $minutes = $this->_getLostBasketGuestIterval($num, $storeId); $interval = new \DateInterval('PT' . $minutes . 'M'); } else { $hours = $this->_getLostBasketGuestIterval($num, $storeId); $interval = new \DateInterval('PT' . $hours . 'H'); } $fromTime = new \DateTime('now', new \DateTimeZone('UTC')); $fromTime->sub($interval); $toTime = clone $fromTime; $fromTime->sub(new \DateInterval('PT5M')); //format time $fromDate = $fromTime->format('Y-m-d H:i:s'); $toDate = $toTime->format('Y-m-d H:i:s'); //active guest quotes $quoteCollection = $this->_getStoreQuotes($fromDate, $toDate, $guest = true, $storeId); //log the time for carts found if ($quoteCollection->getSize()) { $this->_helper->log('Guest cart : ' . $num . ', from : ' . $fromDate . ' ,to : ' . $toDate); } $guestCampaignId = $this->_getLostBasketGuestCampaignId($num, $storeId); foreach ($quoteCollection as $quote) { $email = $quote->getCustomerEmail(); $websiteId = $store->getWebsiteId(); $quoteId = $quote->getId(); // upate last quote id for the contact $this->_helper->updateLastQuoteId($quoteId, $email, $websiteId); // update abandoned product name for contact $items = $quote->getAllItems(); $mostExpensiveItem = false; foreach ($items as $item) { if ($mostExpensiveItem == false) { $mostExpensiveItem = $item; } elseif ($item->getPrice() > $mostExpensiveItem->getPrice()) { $mostExpensiveItem = $item; } } //api- set the most expensive product to datafield if ($mostExpensiveItem) { $this->_helper->updateAbandonedProductName($mostExpensiveItem->getName(), $email, $websiteId); } //send email only if the interval limit passed, no emails during this interval $campignFound = $this->_checkCustomerCartLimit($email, $storeId); //no campign found for interval pass if (!$campignFound) { //save lost basket for sending //@codingStandardsIgnoreStart $this->_campaignFactory->create()->setEmail($email)->setEventName('Lost Basket')->setQuoteId($quoteId)->setCheckoutMethod('Guest')->setMessage('Guest Abandoned Cart ' . $num)->setCampaignId($guestCampaignId)->setStoreId($storeId)->setWebsiteId($websiteId)->setIsSent(null)->save(); //@codingStandardsIgnoreEnd } } } } } } }
/** * Catalog sync. * * @return array */ public function sync() { $response = ['success' => true, 'message' => 'Done.']; $this->start = microtime(true); $enabled = $this->helper->isEnabled(); $catalogSyncEnabled = $this->helper->isCatalogSyncEnabled(); //api and catalog sync enabled if ($enabled && $catalogSyncEnabled) { try { //remove product with product id set and no product $write = $this->resource->getConnection('core_write'); $catalogTable = $this->resource->getTableName('email_catalog'); $select = $write->select(); $select->reset()->from(['c' => $catalogTable], ['c.product_id'])->joinLeft(['e' => $this->resource->getTableName('catalog_product_entity')], 'c.product_id = e.entity_id')->where('e.entity_id is NULL'); //delete sql statement $deleteSql = $select->deleteFromSelect('c'); //run query $write->query($deleteSql); $scope = $this->scopeConfig->getValue(\Dotdigitalgroup\Email\Helper\Config::XML_PATH_CONNECTOR_SYNC_CATALOG_VALUES); //if only to pull default value if ($scope == 1) { $products = $this->_exportCatalog(\Magento\Store\Model\Store::DEFAULT_STORE_ID); if ($products) { //register in queue with importer $this->importerFactory->create()->registerQueue('Catalog_Default', $products, \Dotdigitalgroup\Email\Model\Importer::MODE_BULK, \Magento\Store\Model\Store::DEFAULT_STORE_ID); //set imported $this->_setImported($this->productIds); //set number of product imported $this->countProducts += count($products); } //using single api $this->_exportInSingle(\Magento\Store\Model\Store::DEFAULT_STORE_ID, 'Catalog_Default', \Magento\Store\Model\Store::DEFAULT_STORE_ID); //if to pull store values. will be pulled for each store } elseif ($scope == 2) { $stores = $this->helper->getStores(); foreach ($stores as $store) { $websiteCode = $store->getWebsite()->getCode(); $storeCode = $store->getCode(); $products = $this->_exportCatalog($store); if ($products) { //register in queue with importer $this->importerFactory->create()->registerQueue('Catalog_' . $websiteCode . '_' . $storeCode, $products, \Dotdigitalgroup\Email\Model\Importer::MODE_BULK, $store->getWebsite()->getId()); //set imported $this->_setImported($this->productIds); //set number of product imported //@codingStandardsIgnoreStart $this->countProducts += count($products); //@codingStandardsIgnoreEnd } //using single api $this->_exportInSingle($store, 'Catalog_' . $websiteCode . '_' . $storeCode, $store->getWebsite()->getId()); } } } catch (\Exception $e) { $this->helper->debug((string) $e, []); } } if ($this->countProducts) { $message = 'Total time for sync : ' . gmdate('H:i:s', microtime(true) - $this->start) . ', Total synced = ' . $this->countProducts; $this->helper->log($message); $response['message'] = $message; } return $response; }