Process abandoned carts for automation program enrolment

@param \Magento\Quote\Model\ResourceModel\Quote
@param \Magento\Store\Api\Data\StoreInterface $store
@param int $programId

@return void
@throws \Exception
490369
public function save($quote, $store, $programId)
    {
        try {
            $automation = $this->automationFactory->create()
                ->setEmail($quote->getCustomerEmail())
                ->setAutomationType(\Dotdigitalgroup\Email\Model\Sync\Automation::AUTOMATION_TYPE_ABANDONED_CART_PROGRAM_ENROLMENT)
                ->setEnrolmentStatus(\Dotdigitalgroup\Email\Model\Sync\Automation::AUTOMATION_STATUS_PENDING)
                ->setTypeId($quote->getId())
                ->setWebsiteId($store->getWebsiteId())
                ->setStoreName($store->getName())
                ->setProgramId($programId);
            $this->automationResource->save($automation);
        } catch (\Exception $e) {
            $this->helper->debug((string)$e, []);
        }
    }
415699
private function processAbandonedCartsForCustomers($storeId, $websiteId, $result)
    {
        $secondCustomerEnabled = $this->isLostBasketCustomerEnabled(self::CUSTOMER_LOST_BASKET_TWO, $storeId);
        $thirdCustomerEnabled = $this->isLostBasketCustomerEnabled(self::CUSTOMER_LOST_BASKET_THREE, $storeId);

        //first customer
        if ($this->isLostBasketCustomerEnabled(self::CUSTOMER_LOST_BASKET_ONE, $storeId) ||
            $secondCustomerEnabled ||
            $thirdCustomerEnabled
        ) {
            $result[$storeId]['firstCustomer'] = $this->processCustomerFirstAbandonedCart($storeId);
        }

        //second customer
        if ($secondCustomerEnabled) {
            $result[$storeId]['secondCustomer'] = $this->processExistingAbandonedCart(
                $this->getLostBasketCustomerCampaignId(self::CUSTOMER_LOST_BASKET_TWO, $storeId),
                $storeId,
                $websiteId,
                self::CUSTOMER_LOST_BASKET_TWO
            );
        }

        //third customer
        if ($thirdCustomerEnabled) {
            $result[$storeId]['thirdCustomer'] = $this->processExistingAbandonedCart(
                $this->getLostBasketCustomerCampaignId(self::CUSTOMER_LOST_BASKET_THREE, $storeId),
                $storeId,
                $websiteId,
                self::CUSTOMER_LOST_BASKET_THREE
            );
        }

        return $result;
    }
376866
public static void runExample(AdManagerServices adManagerServices, AdManagerSession session)
      throws RemoteException {
    // Get the OrderService.
    OrderServiceInterface orderService =
        adManagerServices.get(session, OrderServiceInterface.class);

    // Create a statement to select all orders.
    StatementBuilder statementBuilder =
        new StatementBuilder().orderBy("id ASC").limit(StatementBuilder.SUGGESTED_PAGE_LIMIT);

    // Default for total result set size.
    int totalResultSetSize = 0;

    do {
      // Get orders by statement.
      OrderPage page = orderService.getOrdersByStatement(statementBuilder.toStatement());

      if (page.getResults() != null) {
        totalResultSetSize = page.getTotalResultSetSize();
        int i = page.getStartIndex();
        for (Order order : page.getResults()) {
          System.out.printf(
              "%d) Order with ID %d and name '%s' was found.%n",
              i++, order.getId(), order.getName());
        }
      }

      statementBuilder.increaseOffsetBy(StatementBuilder.SUGGESTED_PAGE_LIMIT);
    } while (statementBuilder.getOffset() < totalResultSetSize);

    System.out.printf("Number of results found: %d%n", totalResultSetSize);
  }
1256236
public function process(JobInterface $job, $maxTries = 0, $delay = 0)
    {
        if ($maxTries > 0 && $job->attempts() > $maxTries) {
            $this->fail($job);
            return Result::failed($job);
        }

        try {
            $job->fire();
            return Result::success($job);
        } catch (Exception $e) {
            // If we catch an exception, we will attempt to release the job back onto
            // the queue so it is not lost. This will let is be retried at a later
            // time by another listener (or the same one). We will do that here.
            if (!$job->isDeleted()) {
                $job->release($delay);
            }
            throw $e;
        } // @codeCoverageIgnoreStart
        catch (Throwable $e) {
            if (!$job->isDeleted()) {
                $job->release($delay);
            }
            throw $e;
        }
        // @codeCoverageIgnoreEnd
    }
473578
private function createCustomerFirstAbandonedCart($quoteCollection, $storeId, $campaignId)
    {
        $result = 0;
        foreach ($quoteCollection as $quote) {
            $websiteId = $this->helper->storeManager->getStore($storeId)->getWebsiteId();
            if (! $this->updateDataFieldAndCreateAc($quote, $websiteId, $storeId)) {
                continue;
            }

            //send campaign; check if valid to be sent
            if ($this->isLostBasketCustomerEnabled(self::CUSTOMER_LOST_BASKET_ONE, $storeId)) {
                $this->sendEmailCampaign(
                    $quote->getCustomerEmail(),
                    $quote,
                    $campaignId,
                    self::CUSTOMER_LOST_BASKET_ONE,
                    $websiteId
                );
            }

            $this->totalCustomers++;
            $result = $this->totalCustomers;
        }

        return $result;
    }
449025
function processPulledRecord(chain, tableName, pulledRecord) {
        return chain.then(function() {

            // Update the store as per the pulled record 
            return storeTaskRunner.run(function() {
                if (Validate.isValidId(pulledRecord[idPropertyName])) {
                    throw new Error('Pulled record does not have a valid ID');
                }
                
                return operationTableManager.readPendingOperations(tableName, pulledRecord[idPropertyName]).then(function(pendingOperations) {
                    // If there are pending operations for the record we just pulled, we ignore it.
                    if (pendingOperations.length > 0) {
                        return;
                    }

                    if (pulledRecord[sysProps.deletedColumnName] === true) {
                        return store.del(tableName, pulledRecord.id);
                    } else if (pulledRecord[sysProps.deletedColumnName] === false) {
                        return store.upsert(tableName, pulledRecord);
                    } else {
                        throw new Error("'" + sysProps.deletedColumnName + "' system property is missing. Pull cannot work without it.'");
                    }
                });
            });
        });
    }
1228242
public function execute(DataSetInterface $dataSet): void
    {
        $customerReference = $dataSet[CartDataSetInterface::CUSTOMER_REFERENCE];
        if (!isset($this->customerReferenceCache[$customerReference])) {
            $customerQuery = SpyCustomerQuery::create();
            $idCustomer = $customerQuery
                ->select(SpyCustomerTableMap::COL_ID_CUSTOMER)
                ->findOneByCustomerReference($customerReference);

            if (!$idCustomer) {
                throw new EntityNotFoundException(sprintf('Could not find customer by reference "%s"', $customerReference));
            }

            $this->customerReferenceCache[$customerReference] = $idCustomer;
        }
    }
91712
public function tryAutomaticCoupons(CartInterface $cart)
    {
        if ($cart->getCartLines()->isEmpty()) {
            return;
        }

        $automaticCoupons = $this->getNonAppliedAutomaticCoupons($cart);

        foreach ($automaticCoupons as $coupon) {
            try {
                $this
                    ->cartCouponManager
                    ->addCoupon($cart, $coupon);
            } catch (AbstractCouponException $e) {
                // Silently tries next coupon on controlled exception
            }
        }
    }
418592
public function saveCart(CartInterface $cart)
    {
        if (!$cart->getCartLines()->isEmpty()) {
            $this->cartObjectManager->persist($cart);
        }

        $this
            ->cartObjectManager
            ->flush();
    }
1142177
public static void runExample(AdManagerServices adManagerServices, AdManagerSession session)
      throws RemoteException {
    // Get the InventoryService.
    InventoryServiceInterface inventoryService =
        adManagerServices.get(session, InventoryServiceInterface.class);

    // Get the NetworkService.
    NetworkServiceInterface networkService =
        adManagerServices.get(session, NetworkServiceInterface.class);

    // Set the parent ad unit's ID for all children ad units to be fetched from.
    String parentAdUnitId = networkService.getCurrentNetwork().getEffectiveRootAdUnitId();

    // Create a statement to select ad units under the parent ad unit.
    StatementBuilder statementBuilder =
        new StatementBuilder()
            .where("parentId = :parentId")
            .orderBy("id ASC")
            .limit(StatementBuilder.SUGGESTED_PAGE_LIMIT)
            .withBindVariableValue("parentId", parentAdUnitId);

    // Default for total result set size.
    int totalResultSetSize = 0;

    do {
      // Get ad units by statement.
      AdUnitPage page = inventoryService.getAdUnitsByStatement(statementBuilder.toStatement());

      if (page.getResults() != null) {
        totalResultSetSize = page.getTotalResultSetSize();
        int i = page.getStartIndex();
        for (AdUnit adUnit : page.getResults()) {
          System.out.printf(
              "%d) Ad unit with ID '%s' and name '%s' was found.%n",
              i++, adUnit.getId(), adUnit.getName());
        }
      }

      statementBuilder.increaseOffsetBy(StatementBuilder.SUGGESTED_PAGE_LIMIT);
    } while (statementBuilder.getOffset() < totalResultSetSize);

    System.out.printf("Number of results found: %d%n", totalResultSetSize);
  }
1307123
public function send($quote, $storeId)
    {
        $store = $this->storeManager->getStore($storeId);
        $client = $this->helper->getWebsiteApiClient($store->getWebsiteId());

        $payload = $this->getPayload($quote, $store);
        $client->postAbandonedCartCartInsight($payload);
    }
182098
public function handleOnModuleActivation(ModuleSetting $moduleSetting, string $moduleId, int $shopId)
    {
        if (!$this->canHandle($moduleSetting)) {
            throw new WrongModuleSettingException($moduleSetting, self::class);
        }

        $shopConfigurationSetting = $this->getShopConfigurationSetting($shopId);

        $shopSettingValue = array_merge(
            $shopConfigurationSetting->getValue(),
            [
                $moduleId => $moduleSetting->getValue(),
            ]
        );

        $shopConfigurationSetting->setValue($shopSettingValue);

        $this->shopConfigurationSettingDao->save($shopConfigurationSetting);
    }
605091
public function execute(DataSetInterface $dataSet): void
    {
        $storeName = $dataSet[CartDataSetInterface::KEY_STORE];
        if (!isset($this->idStoreCache[$storeName])) {
            $storeQuery = new SpyStoreQuery();
            $idStore = $storeQuery
                ->select(SpyStoreTableMap::COL_ID_STORE)
                ->findOneByName($storeName);

            if (!$idStore) {
                throw new EntityNotFoundException(sprintf('Could not find store by name "%s"', $storeName));
            }

            $this->idStoreCache[$storeName] = $idStore;
        }

        $dataSet[CartDataSetInterface::ID_STORE] = $this->idStoreCache[$storeName];
    }
1108117
public function orphaned($master, array $processIds)
    {
        $time = Chronos::now()->getTimestamp();

        $shouldRemove = array_diff($this->connection()->hkeys(
            $key = "{$master}:orphans"
        ), $processIds);

        if (! empty($shouldRemove)) {
            $this->connection()->hdel($key, ...$shouldRemove);
        }

        $this->connection()->pipeline(function ($pipe) use ($key, $time, $processIds) {
            foreach ($processIds as $processId) {
                $pipe->hsetnx($key, $processId, $time);
            }
        });
    }
48809
public function processSql(SqlInterface $sql)
    {
        $this->_sql = $sql;
        $this->_getSelectFieldsAndTable()
            ->_setJoins()
            ->_getWhereConditions()
            ->_setOrder()
            ->_setLimit();
        return $this->_statement;
    }
394399
protected function process()
    {

        // prepare the store view code
        $this->prepareStoreViewCode($this->getRow());

        // load the store view code
        $storeViewCode = $this->getStoreViewCode(StoreViewCodes::ADMIN);

        // check if we're in default store
        if (!$this->isDefaultStore($storeViewCode)) {
            // prepare and initialize the bundle selection price
            $productBundleSelectionPrice = $this->initializeBundleSelectionPrice($this->prepareAttributes());

            // persist the bundle selection price
            $this->persistProductBundleSelectionPrice($productBundleSelectionPrice);
        }
    }
122341
public function createAbandonedCartTable($installer, $tableName)
    {
        $abandonedCartTable = $installer->getConnection()->newTable($installer->getTable($tableName));
        $abandonedCartTable = $this->addColumnForAbandonedCartTable($abandonedCartTable);
        $abandonedCartTable = $this->addIndexKeyForAbandonedCarts($installer, $abandonedCartTable);
        $abandonedCartTable->setComment('Abandoned Carts Table');
        $installer->getConnection()->createTable($abandonedCartTable);
    }