/**
  * @param AbstractLogger $logger
  *
  * @return int
  */
 public function recalculate(AbstractLogger $logger)
 {
     $logger->notice('Recalculating contacting activities...');
     $logger->info(sprintf('<info>Processing started at %s</info>', date('Y-m-d H:i:s')));
     /** @var ConfigProvider $activityConfigProvider */
     $activityConfigProvider = $this->getContainer()->get('oro_entity_config.provider.activity');
     /** @var ActivityContactProvider $activityContactProvider */
     $activityContactProvider = $this->getContainer()->get('orocrm_activity_contact.provider');
     $contactingActivityClasses = $activityContactProvider->getSupportedActivityClasses();
     $entityConfigsWithApplicableActivities = $activityConfigProvider->filter(function (ConfigInterface $entity) use($contactingActivityClasses) {
         return $entity->get('activities') && array_intersect($contactingActivityClasses, $entity->get('activities'));
     });
     if ($entityConfigsWithApplicableActivities) {
         $logger->info(sprintf('<comment>Total found %d entities with enabled contacting activities</comment>', count($entityConfigsWithApplicableActivities)));
         $this->em = $this->getContainer()->get('doctrine')->getManager();
         $this->activityListRepository = $this->em->getRepository(ActivityList::ENTITY_NAME);
         /** @var ActivityListener $activityListener */
         $activityListener = $this->getContainer()->get('orocrm_activity_contact.listener.activity_listener');
         /** @var ActivityListFilterHelper $activityListHelper */
         $activityListHelper = $this->getContainer()->get('oro_activity_list.filter.helper');
         foreach ($entityConfigsWithApplicableActivities as $activityScopeConfig) {
             $entityClassName = $activityScopeConfig->getId()->getClassName();
             $offset = 0;
             $startTimestamp = time();
             $allRecordIds = $this->getTargetIds($entityClassName);
             while ($allRecords = $this->getRecordsToRecalculate($entityClassName, $allRecordIds, $offset)) {
                 $needsFlush = false;
                 foreach ($allRecords as $record) {
                     $this->resetRecordStatistic($record);
                     /** @var QueryBuilder $qb */
                     $qb = $this->activityListRepository->getBaseActivityListQueryBuilder($entityClassName, $record->getId());
                     $activityListHelper->addFiltersToQuery($qb, ['activityType' => ['value' => $contactingActivityClasses]]);
                     /** @var ActivityList[] $activities */
                     $activities = $qb->getQuery()->getResult();
                     if ($activities) {
                         foreach ($activities as $activityListItem) {
                             /** @var object $activity */
                             $activity = $this->em->getRepository($activityListItem->getRelatedActivityClass())->find($activityListItem->getRelatedActivityId());
                             $activityListener->onAddActivity(new ActivityEvent($activity, $record));
                         }
                         $this->em->persist($record);
                         $needsFlush = true;
                     }
                 }
                 if ($needsFlush) {
                     $this->em->flush();
                 }
                 $this->em->clear();
                 $offset += self::BATCH_SIZE;
             }
             $endTimestamp = time();
             $logger->info(sprintf('Entity "%s", %d records processed (<comment>%d sec.</comment>).', $entityClassName, count($allRecordIds), $endTimestamp - $startTimestamp));
         }
     }
     $logger->info(sprintf('<info>Processing finished at %s</info>', date('Y-m-d H:i:s')));
     return self::STATUS_SUCCESS;
 }
 /**
  * @param string $entityClassName
  * @param array $recordIdsWithActivities
  */
 protected function resetRecordsWithoutActivities($entityClassName, array $recordIdsWithActivities)
 {
     $offset = 0;
     while ($records = $this->getRecordsToReset($entityClassName, $recordIdsWithActivities, $offset)) {
         array_map([$this, 'resetRecordStatistic'], $records);
         $this->em->flush();
         $this->em->clear();
         $offset += self::BATCH_SIZE;
     }
 }