Beispiel #1
0
 /**
  * Изменение статуса кампании
  *
  * @param Campaign $campaign
  *
  * @Rest\Put("campaigns/{id}/status", requirements={"id"="\d+"})
  * @ParamConverter("campaign", class="VifeedCampaignBundle:Campaign")
  * @ApiDoc(
  *     section="Campaign API",
  *     requirements={
  *       {"name"="id", "dataType"="integer", "requirement"="\d+", "description"="id кампании"}
  *     },
  *     statusCodes={
  *         200="Returned when successful",
  *         400="Returned when the something was wrong",
  *         403="Returned when the user is not authorized to use this method",
  *         404="Returned when campaign not found"
  *     }
  * )
  *
  * @return Response
  */
 public function putCampaignStatusAction(Campaign $campaign)
 {
     if ($campaign->getUser() != $this->getUser()) {
         throw new AccessDeniedHttpException('Можно изменять только свои кампании');
     }
     $oldStatus = $campaign->getStatus();
     $form = $this->createForm(new CampaignStatusType(), $campaign);
     $form->submit($this->get('request'), false);
     if (!$form->isValid()) {
         return $this->handleView(new View($form, 400));
     }
     $newStatus = $campaign->getStatus();
     if ($newStatus == Campaign::STATUS_ON) {
         // включение
         try {
             $this->campaignManager->tryTurnStatusOn($campaign, $oldStatus);
         } catch (CampaignStatusException $e) {
             $form['status']->addError(new FormError($e->getMessage()));
             return $this->handleView(new View($form, 400));
         }
     } else {
         // пауза или архив
         if ($oldStatus == Campaign::STATUS_ON) {
             $canTurnOffByTime = $this->campaignManager->canTurnOffByTime($campaign);
             if ($canTurnOffByTime !== true) {
                 $msg = 'Невозможно остановить кампанию в течение двух часов после запуска. Вы сможете остановить кампанию через ' . $canTurnOffByTime . ' мин.';
                 $form['status']->addError(new FormError($msg));
                 return $this->handleView(new View($form, 400));
             }
         }
         if ($newStatus == Campaign::STATUS_ARCHIVED) {
             $this->campaignManager->transferMoneyBackToUser($campaign);
         }
     }
     $this->campaignManager->save($campaign);
     $view = new View('', 200);
     return $this->handleView($view);
 }
Beispiel #2
0
 /**
  * обработка показа
  *
  * @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;
 }