/**
  * обработка показа
  *
  * @param VideoView $videoView
  * @param bool      $skipStatusCheck
  *
  * @return boolean false, если транзакция не прошла, в остальных случаях true
  */
 public function reckon(VideoView $videoView, $skipStatusCheck = false)
 {
     $videoViewRepo = $this->em->getRepository('VifeedVideoViewBundle:VideoView');
     $userRepo = $this->em->getRepository('VifeedUserBundle:User');
     $campaignRepo = $this->em->getRepository('VifeedCampaignBundle:Campaign');
     $publisher = $videoView->getPlatform()->getUser();
     $this->em->refresh($publisher);
     // обновляем энтити. Доктрина может брать его из кеша
     if (!$publisher->isEnabled()) {
         // паблишер забанен. Ничего не делаем
         return true;
     }
     // пользователь уже просматривал этот ролик
     $countViewsByViewerId = $videoViewRepo->countCampaignViewsByViewerId($videoView);
     if ($countViewsByViewerId['paid_views'] > 0) {
         return true;
     }
     $campaign = $videoView->getCampaign();
     $this->em->refresh($campaign);
     // обновляем энтити. Доктрина может брать его из кеша
     // перед оплатой обновляем статус по балансу. Если пора выключать - выключаем
     $this->campaignManager->checkUpdateStatusOn($campaign);
     // если просмотр слишком короткий или кампания уже остановлена, инкрементим totalViews и выходим
     if (!$skipStatusCheck && !$this->checkReckonConditions($videoView)) {
         // засчитываем показ только если пользователь ещё не смотрел ролик
         if ($countViewsByViewerId['views'] == 0) {
             // показ участвует в статах
             $videoView->setIsInStats(true);
             $this->em->persist($videoView);
             $campaignRepo->incrementTotalViews($campaign);
         }
         $this->em->flush();
         // на случай, если у кампании обновился статус
         return true;
     }
     $this->em->getConnection()->beginTransaction();
     $this->em->lock($publisher, LockMode::PESSIMISTIC_WRITE);
     $price = $campaign->getBid();
     $comissionValue = round($this->comission * $price, 2);
     $toPay = round($price - $comissionValue, 2);
     $payment = new VideoViewPayment();
     $payment->setVideoView($videoView)->setCharged($price)->setComission($comissionValue)->setPaid($toPay);
     $userRepo->updateBalance($publisher, $toPay);
     $campaignRepo->addPaidView($campaign);
     $this->campaignManager->checkUpdateStatusOn($campaign);
     $videoView->setIsPaid(true)->setIsInStats(true);
     $this->em->persist($publisher);
     $this->em->persist($payment);
     $done = false;
     try {
         $this->em->flush();
         $this->em->getConnection()->commit();
         $this->em->refresh($campaign);
         $this->campaignManager->checkUpdateStatusOn($campaign);
         $this->em->flush();
         // на случай, если у кампании обновился статус
         $done = true;
     } catch (\Exception $e) {
         $this->em->getConnection()->rollback();
         // исключение не бросаем, просто откатываем транзакцию и ставим задачу снова в очередь
     }
     return $done;
 }