Added new cron task to calculate feedback avg

rate for ongoing summits

Change-Id: I49d989a90cd267bc599e3c95b2689d44759e58d4
Signed-off-by: smarcet <smarcet@gmail.com>
This commit is contained in:
smarcet 2020-02-20 15:26:44 -03:00
parent 3d4a9f97b6
commit f9905a528b
7 changed files with 207 additions and 30 deletions

View File

@ -0,0 +1,83 @@
<?php namespace App\Console\Commands;
/**
* Copyright 2020 OpenStack Foundation
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
use Illuminate\Console\Command;
use services\model\ISummitService;
use Exception;
use Illuminate\Support\Facades\Log;
/**
* Class SummitEventSetAvgRateProcessor
* @package App\Console\Commands
*/
class SummitEventSetAvgRateProcessor extends Command
{
/**
* The console command name.
*
* @var string
*/
protected $name = 'summit:feedback-avg-rate-processor';
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'summit:feedback-avg-rate-processor';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Calculate all AVG feedback rate for all schedule for all ongoing summits';
/**
* @var ISummitService
*/
private $summit_service;
/**
* SummitEventSetAvgRateProcessor constructor.
* @param ISummitService $summit_service
*/
public function __construct(ISummitService $summit_service)
{
parent::__construct();
$this->summit_service = $summit_service;
}
/**
* Execute the console command.
*
* @return mixed
*/
public function handle()
{
try {
$this->info("processing SummitEventSetAvgRateProcessor");
$start = time();
$this->summit_service->calculateFeedbackAverageForOngoingSummits();
$end = time();
$delta = $end - $start;
$this->info(sprintf("execution call %s seconds", $delta));
}
catch (Exception $ex) {
Log::error($ex);
}
}
}

View File

@ -11,6 +11,8 @@
* See the License for the specific language governing permissions and
* limitations under the License.
**/
use App\Console\Commands\SummitEventSetAvgRateProcessor;
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
use models\summit\CalendarSync\CalendarSyncInfo;
@ -34,6 +36,7 @@ class Kernel extends ConsoleKernel
\App\Console\Commands\PromoCodesRedeemProcessor::class,
\App\Console\Commands\SummitRoomReservationRevocationCommand::class,
\App\Console\Commands\ExternalScheduleFeedIngestionCommand::class,
\App\Console\Commands\SummitEventSetAvgRateProcessor::class,
];
/**
@ -88,5 +91,8 @@ class Kernel extends ConsoleKernel
// external schedule ingestion task
$schedule->command("summit:external-schedule-feed-ingestion-process")->everyFifteenMinutes()->withoutOverlapping();
// AVG schedule feedback rate
$schedule->command("summit:feedback-avg-rate-processor")->everyFifteenMinutes()->withoutOverlapping();
}
}

View File

@ -12,8 +12,6 @@
* limitations under the License.
**/
use models\utils\IBaseRepository;
use phpDocumentor\Reflection\Types\Array_;
/**
* Interface ISummitRepository
* @package models\summit
@ -66,4 +64,9 @@ interface ISummitRepository extends IBaseRepository
* @return Summit[]
*/
public function getWithExternalFeed():array;
/**
* @return Summit[]
*/
public function getOnGoing(): array;
}

View File

@ -2022,6 +2022,25 @@ SQL;
self::recalculateOrderForCollection($filtered_locations, $location, $new_order);
}
/**
* @return int[]
*/
public function getScheduleEventsIds():array{
$query = <<<SQL
SELECT e.id
FROM models\summit\SummitEvent e
WHERE
e.published = 1
AND e.summit = :summit
SQL;
$native_query = $this->getEM()->createQuery($query);
$native_query->setParameter("summit", $this);
return $native_query->getResult();
}
/**
* @param SummitAbstractLocation $location
* @return int[]

View File

@ -181,4 +181,20 @@ final class DoctrineSummitRepository
->getQuery()
->getResult();
}
/**
* @return array
*/
public function getOnGoing(): array
{
return $this->getEntityManager()->createQueryBuilder()
->select("e")
->from($this->getBaseEntity(), "e")
->where("e.begin_date <= :now")
->andWhere("e.end_date >= :now")
->orderBy('e.id', 'DESC')
->setParameter("now", new \DateTime('now', new \DateTimeZone('UTC')))
->getQuery()
->getResult();
}
}

View File

@ -441,4 +441,7 @@ interface ISummitService
* @return void`
*/
public function shareEventByEmail(Summit $summit, int $event_id, array $data):void;
public function calculateFeedbackAverageForOngoingSummits():void;
}

View File

@ -388,12 +388,12 @@ final class SummitService extends AbstractService implements ISummitService
* @return SummitEventFeedback
* @throws Exception
*/
public function addMyEventFeedback(Member $member, Summit $summit, int $event_id, array $payload):SummitEventFeedback
public function addMyEventFeedback(Member $member, Summit $summit, int $event_id, array $payload): SummitEventFeedback
{
return $this->tx_service->transaction(function () use ($member, $summit, $event_id, $payload) {
$event = $summit->getScheduleEvent($event_id);
if(is_null($event))
if (is_null($event))
throw new EntityNotFoundException("Event not found.");
if (!Summit::allowToSee($event, $member))
@ -423,13 +423,13 @@ final class SummitService extends AbstractService implements ISummitService
* @return SummitEventFeedback
* @throws Exception
*/
public function updateMyEventFeedback(Member $member, Summit $summit, int $event_id, array $payload):SummitEventFeedback
public function updateMyEventFeedback(Member $member, Summit $summit, int $event_id, array $payload): SummitEventFeedback
{
return $this->tx_service->transaction(function () use ($member, $summit, $event_id, $payload) {
$event = $summit->getScheduleEvent($event_id);
if(is_null($event))
if (is_null($event))
throw new EntityNotFoundException("Event not found.");
if (!Summit::allowToSee($event, $member))
@ -455,13 +455,13 @@ final class SummitService extends AbstractService implements ISummitService
* @return SummitEventFeedback
* @throws Exception
*/
public function getMyEventFeedback(Member $member, Summit $summit, int $event_id):SummitEventFeedback
public function getMyEventFeedback(Member $member, Summit $summit, int $event_id): SummitEventFeedback
{
return $this->tx_service->transaction(function () use ($member, $summit, $event_id) {
$event = $summit->getScheduleEvent($event_id);
if(is_null($event))
if (is_null($event))
throw new EntityNotFoundException("Event not found.");
if (!Summit::allowToSee($event, $member))
@ -486,12 +486,12 @@ final class SummitService extends AbstractService implements ISummitService
* @param int $event_id
* @throws Exception
*/
public function deleteMyEventFeedback(Member $member, Summit $summit, int $event_id):void
public function deleteMyEventFeedback(Member $member, Summit $summit, int $event_id): void
{
$this->tx_service->transaction(function () use ($member, $summit, $event_id) {
$event = $summit->getScheduleEvent($event_id);
if(is_null($event))
if (is_null($event))
throw new EntityNotFoundException("Event not found.");
if (!Summit::allowToSee($event, $member))
@ -2287,7 +2287,7 @@ final class SummitService extends AbstractService implements ISummitService
* @return PersonalCalendarShareInfo|null
* @throws Exception
*/
public function createScheduleShareableLink(Summit $summit, Member $member):?PersonalCalendarShareInfo
public function createScheduleShareableLink(Summit $summit, Member $member): ?PersonalCalendarShareInfo
{
return $this->tx_service->transaction(function () use ($summit, $member) {
return $member->createScheduleShareableLink($summit);
@ -2300,11 +2300,11 @@ final class SummitService extends AbstractService implements ISummitService
* @return PersonalCalendarShareInfo|null
* @throws Exception
*/
public function revokeScheduleShareableLink(Summit $summit, Member $member):?PersonalCalendarShareInfo
public function revokeScheduleShareableLink(Summit $summit, Member $member): ?PersonalCalendarShareInfo
{
return $this->tx_service->transaction(function () use ($summit, $member) {
$link = $member->getScheduleShareableLinkBy($summit);
if(is_null($link)){
if (is_null($link)) {
throw new EntityNotFoundException("Schedule shareable link not found for member.");
}
$link->revoke();
@ -2323,18 +2323,18 @@ final class SummitService extends AbstractService implements ISummitService
return $this->tx_service->transaction(function () use ($summit, $cid) {
$link = $summit->getScheduleShareableLinkById($cid);
if(is_null($link)){
if (is_null($link)) {
throw new EntityNotFoundException("Schedule shareable link not found for member.");
}
$owner = $link->getOwner();
$owner = $link->getOwner();
$timeZone = $summit->getTimeZone();
$vCalendar = ICalTimeZoneBuilder::build($timeZone, $summit->getName(), true);
foreach($owner->getScheduleBySummit($summit) as $scheduled){
foreach ($owner->getScheduleBySummit($summit) as $scheduled) {
$summitEvent = $scheduled->getEvent();
$local_start_time = new DateTime($summitEvent->getStartDateNice(), $timeZone);
$local_end_time = new DateTime($summitEvent->getEndDateNice(), $timeZone);
$vEvent = new \Eluceo\iCal\Component\Event($summitEvent->getId());
$local_end_time = new DateTime($summitEvent->getEndDateNice(), $timeZone);
$vEvent = new \Eluceo\iCal\Component\Event($summitEvent->getId());
$vEvent
->setCreated(new DateTime())
@ -2345,19 +2345,18 @@ final class SummitService extends AbstractService implements ISummitService
->setDescription(strip_tags($summitEvent->getAbstract()))
->setDescriptionHTML($summitEvent->getAbstract());
if($timeZone->getName() == 'UTC'){
if ($timeZone->getName() == 'UTC') {
$vEvent->setUseUtc(true)
->setUseTimezone(false);
}
else{
} else {
$vEvent->setUseUtc(false)
->setUseTimezone(true);
}
if($summitEvent->hasLocation()){
if ($summitEvent->hasLocation()) {
$location = $summitEvent;
$geo = null;
if($location instanceof SummitGeoLocatedLocation) {
if ($location instanceof SummitGeoLocatedLocation) {
$geo = sprintf("%s;%s", $location->getLat(), $location->getLng());
}
$vEvent->setLocation($location->getTitle(), $location->getTitle(), $geo);
@ -2375,31 +2374,32 @@ final class SummitService extends AbstractService implements ISummitService
* @param Summit $summit
* @param int $event_id
* @param array $data
* @throws ValidationException
* @throws EntityNotFoundException
* @return void`
* @throws EntityNotFoundException
* @throws ValidationException
*/
public function shareEventByEmail(Summit $summit, int $event_id, array $data):void{
public function shareEventByEmail(Summit $summit, int $event_id, array $data): void
{
$this->tx_service->transaction(function () use ($summit, $event_id, $data) {
$event = $summit->getScheduleEvent($event_id);
if(is_null($event)){
if (is_null($event)) {
throw new EntityNotFoundException(sprintf("Event %s not found.", $event_id));
}
$event_uri = $data['event_uri'] ?? null;
if(empty($event_uri)){
if (empty($event_uri)) {
Log::debug("event_uri not set on payload. trying to get from default one (summit)");
$default_event_uri = $summit->getScheduleDefaultEventDetailUrl();
if(!empty($default_event_uri)){
if (!empty($default_event_uri)) {
Log::debug("default_event_uri set at summit level using it.");
$event_uri = str_replace(":event_id", $event_id, $default_event_uri);
}
}
if(empty($event_uri)){
if (empty($event_uri)) {
throw new ValidationException(sprintf("Property event_url is empty."));
}
@ -2411,4 +2411,51 @@ final class SummitService extends AbstractService implements ISummitService
));
});
}
public function calculateFeedbackAverageForOngoingSummits(): void
{
$ongoing_summits = $this->tx_service->transaction(function () {
return $this->summit_repository->getOnGoing();
});
foreach ($ongoing_summits as $summit) {
Log::debug(sprintf("SummitService::calculateFeedbackAverageForOngoingSummits processing summit %s", $summit->getId()));
$event_ids = $this->tx_service->transaction(function () use ($summit) {
return $summit->getScheduleEventsIds();
});
foreach ($event_ids as $event_id) {
$event_id = $event_id['id'];
$this->tx_service->transaction(function () use ($event_id) {
try {
Log::debug(sprintf("SummitService::calculateFeedbackAverageForOngoingSummits processing event %s", $event_id));
$event = $this->event_repository->getById($event_id);
if (is_null($event) || !$event instanceof SummitEvent){
Log::debug(sprintf("SummitService::calculateFeedbackAverageForOngoingSummits event %s not found", $event_id));
return;
}
$rate_sum = 0;
$rate_count = 0;
foreach ($event->getFeedback() as $feedback) {
$rate_count++;
$rate_sum = $rate_sum + $feedback->getRate();
}
$avg_rate = ($rate_count > 0) ? ($rate_sum / $rate_count) : 0;
$avg_rate = round($avg_rate, 2);
$old_avg_rate = $event->getAvgFeedbackRate();
Log::debug(sprintf("SummitService::calculateFeedbackAverageForOngoingSummits new avg rate %s - old avg rate %s - for event id %s", $avg_rate, $old_avg_rate, $event->getId()));
$event->setAvgFeedbackRate($avg_rate);
}
catch (Exception $ex){
Log::error($ex);
}
});
}
}
}
}