Fixed Speakers API issues

* fixed promo code updates
* added promo code email registration
* fixed get speaker ( added summit assistance criteria)
* fixed get all speakers ( added summit assistance criteria)

Change-Id: Ia9f245cd28b84c12366377aac00c1de5ff2bbeb2
This commit is contained in:
Sebastian Marcet 2017-12-20 16:04:49 -03:00
parent a15f9aff5f
commit 3db744f078
11 changed files with 288 additions and 54 deletions

View File

@ -49,10 +49,8 @@ class CheckMeSpeakerStrategy implements ICheckSpeakerStrategy
if (is_null($member_id)) {
return null;
}
$speaker = $summit->getSpeakerByMemberId($member_id);
} else {
$speaker = $summit->getSpeaker(intval($speaker_id));
return $summit->getSpeakerByMemberId($member_id, false);
}
return $speaker;
return $summit->getSpeaker(intval($speaker_id, false));
}
}

View File

@ -316,8 +316,6 @@ Route::group([
Route::group(['prefix' => '{speaker_id}'], function () {
Route::post('/photo', [ 'middleware' => 'auth.user:administrators', 'uses' => 'OAuth2SummitSpeakersApiController@addSpeakerPhoto']);
});
});
});

View File

@ -20,7 +20,8 @@ use DateTime;
* @ORM\InheritanceType("JOINED")
* @ORM\DiscriminatorColumn(name="ClassName", type="string")
* @ORM\DiscriminatorMap({"EmailCreationRequest" = "EmailCreationRequest",
* "SpeakerCreationEmailCreationRequest" = "SpeakerCreationEmailCreationRequest" })
* "SpeakerCreationEmailCreationRequest" = "SpeakerCreationEmailCreationRequest",
* "MemberPromoCodeEmailCreationRequest"= "MemberPromoCodeEmailCreationRequest"})
* Class EmailCreationRequest
* @package models\main
*/

View File

@ -0,0 +1,96 @@
<?php namespace models\main;
/**
* Copyright 2017 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 Doctrine\ORM\Mapping AS ORM;
use models\summit\SummitRegistrationPromoCode;
/**
* @ORM\Entity
* @ORM\Table(name="MemberPromoCodeEmailCreationRequest")
* Class MemberPromoCodeEmailCreationRequest
* @package models\main
*/
class MemberPromoCodeEmailCreationRequest extends EmailCreationRequest
{
/**
* @ORM\ManyToOne(targetEntity="models\summit\SummitRegistrationPromoCode")
* @ORM\JoinColumn(name="PromoCodeID", referencedColumnName="ID")
* @var SummitRegistrationPromoCode
*/
protected $promo_code;
/**
* @ORM\Column(name="Email", type="string")
* @var string
*/
protected $email;
/**
* @ORM\Column(name="Name", type="string")
* @var string
*/
protected $name;
public function __construct()
{
$this->template_name = "member-promo-code";
parent::__construct();
}
/**
* @return SummitRegistrationPromoCode
*/
public function getPromoCode()
{
return $this->promo_code;
}
/**
* @param SummitRegistrationPromoCode $promo_code
*/
public function setPromoCode($promo_code)
{
$this->promo_code = $promo_code;
}
/**
* @return string
*/
public function getEmail()
{
return $this->email;
}
/**
* @param string $email
*/
public function setEmail($email)
{
$this->email = $email;
}
/**
* @return string
*/
public function getName()
{
return $this->name;
}
/**
* @param string $name
*/
public function setName($name)
{
$this->name = $name;
}
}

View File

@ -245,6 +245,16 @@ class PresentationSpeaker extends SilverstripeBaseModel
return $this;
}
/**
* @param SpeakerSummitRegistrationPromoCode $code
* @return $this
*/
public function removePromoCode(SpeakerSummitRegistrationPromoCode $code){
$this->promo_codes->removeElement($code);
$code->setSpeaker(null);
return $this;
}
/**
* @param Summit $summit
* @return SpeakerSummitRegistrationPromoCode

View File

@ -52,7 +52,6 @@ class PresentationSpeakerSummitAssistanceConfirmationRequest extends Silverstrip
*/
private $speaker;
/**
* @return string
*/

View File

@ -146,4 +146,8 @@ class SummitRegistrationPromoCode extends SilverstripeBaseModel
$this->email_sent = false;
parent::__construct();
}
public function setSourceAdmin(){
$this->source = 'ADMIN';
}
}

View File

@ -829,29 +829,49 @@ class Summit extends SilverstripeBaseModel
}
/**
* @param bool $filter_published_events
* @return \Doctrine\ORM\QueryBuilder
*/
private function buildModeratorsQuery()
private function buildModeratorsQuery($filter_published_events = true)
{
return $this->createQueryBuilder()
$query = $this->createQueryBuilder()
->select('distinct ps')
->from('models\summit\PresentationSpeaker','ps')
->join('ps.moderated_presentations','p')
->join('p.summit','s')
->where("s.id = :summit_id and p.published = 1")
->setParameter('summit_id', $this->getId());
->where("s.id = :summit_id");
if($filter_published_events)
$query = $query->andWhere("p.published = 1");
return $query->setParameter('summit_id', $this->getId());
}
/**
* @param bool $filter_published_events
* @return \Doctrine\ORM\QueryBuilder
*/
private function buildSpeakersQuery($filter_published_events = true){
$query = $this->createQueryBuilder()
->select('distinct ps')
->from('models\summit\PresentationSpeaker','ps')
->join('ps.presentations','p')
->join('p.summit','s')
->where("s.id = :summit_id");
if($filter_published_events)
$query = $query->andWhere("p.published = 1");
return $query->setParameter('summit_id', $this->getId());
}
/**
* @return \Doctrine\ORM\QueryBuilder
*/
private function buildSpeakersQuery(){
private function buildSpeakerSummitAttendanceQuery(){
return $this->createQueryBuilder()
->select('distinct ps')
->from('models\summit\PresentationSpeaker','ps')
->join('ps.presentations','p')
->join('p.summit','s')
->where("s.id = :summit_id and p.published = 1")
->join('ps.summit_assistances','a')
->join('a.summit','s')
->where("s.id = :summit_id")
->setParameter('summit_id', $this->getId());
}
@ -890,11 +910,12 @@ class Summit extends SilverstripeBaseModel
/**`
* @param int $member_id
* @param bool $filter_published_events
* @return PresentationSpeaker|null
*/
public function getSpeakerByMemberId($member_id){
public function getSpeakerByMemberId($member_id, $filter_published_events = true){
// moderators
$moderator = $this->buildModeratorsQuery()
$moderator = $this->buildModeratorsQuery($filter_published_events)
->join('ps.member','mb')
->andWhere('mb.id = :member_id')
->setParameter('member_id', $member_id)
@ -903,24 +924,34 @@ class Summit extends SilverstripeBaseModel
if(!is_null($moderator)) return $moderator;
// speakers
$speaker = $this->buildSpeakersQuery()
$speaker = $this->buildSpeakersQuery($filter_published_events)
->join('ps.member','mb')
->andWhere('mb.id = :member_id')
->setParameter('member_id', $member_id)
->getQuery()->getOneOrNullResult();
if(!is_null($speaker)) return $speaker;;
if(!is_null($speaker)) return $speaker;
// assistance
$speaker = $this->buildSpeakerSummitAttendanceQuery()
->join('ps.member','mb')
->andWhere('mb.id = :member_id')
->setParameter('member_id', $member_id)
->getQuery()->getOneOrNullResult();
if(!is_null($speaker)) return $speaker;
return null;
}
/**
* @param int $speaker_id
* @param bool $filter_published_events
* @return PresentationSpeaker|null
*/
public function getSpeaker($speaker_id){
public function getSpeaker($speaker_id, $filter_published_events = true){
// moderators
$moderator = $this->buildModeratorsQuery()
$moderator = $this->buildModeratorsQuery($filter_published_events)
->andWhere('ps.id = :speaker_id')
->setParameter('speaker_id', $speaker_id)
->getQuery()->getOneOrNullResult();
@ -928,12 +959,20 @@ class Summit extends SilverstripeBaseModel
if(!is_null($moderator)) return $moderator;
// speakers
$speaker = $this->buildSpeakersQuery()
$speaker = $this->buildSpeakersQuery($filter_published_events)
->andWhere('ps.id = :speaker_id')
->setParameter('speaker_id', $speaker_id)
->getQuery()->getOneOrNullResult();
if(!is_null($speaker)) return $speaker;;
if(!is_null($speaker)) return $speaker;
// attendance
$speaker = $this->buildSpeakerSummitAttendanceQuery()
->andWhere('ps.id = :speaker_id')
->setParameter('speaker_id', $speaker_id)
->getQuery()->getOneOrNullResult();
if(!is_null($speaker)) return $speaker;
return null;
}

View File

@ -11,7 +11,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
**/
use Doctrine\ORM\Query\ResultSetMapping;
use Doctrine\ORM\Query\ResultSetMappingBuilder;
use models\main\Member;
@ -76,8 +75,8 @@ SELECT COUNT(DISTINCT(ID)) AS QTY
FROM (
SELECT S.ID,
IFNULL(M.FirstName, S.FirstName) AS FirstName,
IFNULL(M.Surname,S.LastName) AS LastName,
IFNULL(M.Email,R.Email) AS Email
IFNULL(M.Surname, S.LastName) AS LastName,
IFNULL(M.Email, R.Email) AS Email
FROM PresentationSpeaker S
LEFT JOIN Member M ON M.ID = S.MemberID
LEFT JOIN SpeakerRegistrationRequest R ON R.SpeakerID = S.ID
@ -87,13 +86,13 @@ FROM (
SELECT E.ID FROM SummitEvent E
INNER JOIN Presentation P ON E.ID = P.ID
INNER JOIN Presentation_Speakers PS ON PS.PresentationID = P.ID
WHERE E.SummitID = {$summit->getId()} AND E.Published = 1 AND PS.PresentationSpeakerID = S.ID
WHERE E.SummitID = {$summit->getId()} AND PS.PresentationSpeakerID = S.ID
)
UNION
SELECT S.ID,
IFNULL(M.FirstName, S.FirstName) AS FirstName,
IFNULL(M.Surname,S.LastName) AS LastName,
IFNULL(M.Email,R.Email) AS Email
IFNULL(M.Surname, S.LastName) AS LastName,
IFNULL(M.Email, R.Email) AS Email
FROM PresentationSpeaker S
LEFT JOIN Member M ON M.ID = S.MemberID
LEFT JOIN SpeakerRegistrationRequest R ON R.SpeakerID = S.ID
@ -103,7 +102,21 @@ FROM (
SELECT E.ID FROM SummitEvent E
INNER JOIN Presentation P ON E.ID = P.ID
INNER JOIN Presentation_Speakers PS ON PS.PresentationID = P.ID
WHERE E.SummitID = {$summit->getId()} AND E.Published = 1 AND P.ModeratorID = S.ID
WHERE E.SummitID = {$summit->getId()} AND P.ModeratorID = S.ID
)
UNION
SELECT S.ID,
IFNULL(M.FirstName, S.FirstName) AS FirstName,
IFNULL(M.Surname, S.LastName) AS LastName,
IFNULL(M.Email, R.Email) AS Email
FROM PresentationSpeaker S
LEFT JOIN Member M ON M.ID = S.MemberID
LEFT JOIN SpeakerRegistrationRequest R ON R.SpeakerID = S.ID
WHERE
EXISTS
(
SELECT A.ID FROM PresentationSpeakerSummitAssistanceConfirmationRequest A
WHERE A.SummitID = {$summit->getId()} AND A.SpeakerID = S.ID
)
)
SUMMIT_SPEAKERS
@ -154,7 +167,7 @@ FROM (
SELECT E.ID FROM SummitEvent E
INNER JOIN Presentation P ON E.ID = P.ID
INNER JOIN Presentation_Speakers PS ON PS.PresentationID = P.ID
WHERE E.SummitID = {$summit->getId()} AND E.Published = 1 AND PS.PresentationSpeakerID = S.ID
WHERE E.SummitID = {$summit->getId()} AND PS.PresentationSpeakerID = S.ID
)
UNION
SELECT
@ -186,7 +199,37 @@ FROM (
SELECT E.ID FROM SummitEvent E
INNER JOIN Presentation P ON E.ID = P.ID
INNER JOIN Presentation_Speakers PS ON PS.PresentationID = P.ID
WHERE E.SummitID = {$summit->getId()} AND E.Published = 1 AND P.ModeratorID = S.ID
WHERE E.SummitID = {$summit->getId()} AND P.ModeratorID = S.ID
)
UNION
SELECT
S.ID,
S.ClassName,
S.Created,
S.LastEdited,
S.Title AS SpeakerTitle,
S.Bio,
S.IRCHandle,
S.AvailableForBureau,
S.FundedTravel,
S.Country,
S.MemberID,
S.WillingToTravel,
S.WillingToPresentVideo,
S.Notes,
S.TwitterName,
IFNULL(M.FirstName, S.FirstName) AS FirstName,
IFNULL(M.Surname,S.LastName) AS LastName,
IFNULL(M.Email,R.Email) AS Email,
S.PhotoID
FROM PresentationSpeaker S
LEFT JOIN Member M ON M.ID = S.MemberID
LEFT JOIN SpeakerRegistrationRequest R ON R.SpeakerID = S.ID
WHERE
EXISTS
(
SELECT A.ID FROM PresentationSpeakerSummitAssistanceConfirmationRequest A
WHERE A.SummitID = {$summit->getId()} AND A.SpeakerID = S.ID
)
)
SUMMIT_SPEAKERS

View File

@ -19,6 +19,7 @@ use models\main\File;
use models\main\IEmailCreationRequestRepository;
use models\main\IFolderRepository;
use models\main\IMemberRepository;
use models\main\MemberPromoCodeEmailCreationRequest;
use models\main\SpeakerCreationEmailCreationRequest;
use models\summit\ISpeakerRegistrationRequestRepository;
use models\summit\ISpeakerRepository;
@ -121,7 +122,11 @@ final class SpeakerService implements ISpeakerService
if(isset($data['member_id']) && intval($data['member_id']) > 0){
$member_id = intval($data['member_id']);
$existent_speaker = $this->speaker_repository->getByMember($member_id);
$member = $this->member_repository->getById($member_id);
if(is_null($member))
throw new EntityNotFoundException(sprintf("member id %s does not exists!", $member_id));
$existent_speaker = $this->speaker_repository->getByMember($member);
if(!is_null($existent_speaker))
throw new ValidationException
(
@ -132,9 +137,7 @@ final class SpeakerService implements ISpeakerService
)
);
$member = $this->member_repository->getById($member_id);
if(is_null($member))
throw new EntityNotFoundException(sprintf("member id %s does not exists!", $member_id));
$speaker->setMember($member);
}
@ -236,12 +239,14 @@ final class SpeakerService implements ISpeakerService
$existent_code = $this->registration_code_repository->getBySpeakerAndSummit($speaker, $summit);
// we are trying to update the promo code with another one ....
if ($existent_code && $reg_code !== $existent_code->getCode()) {
if (!is_null($existent_code) && $reg_code !== $existent_code->getCode() && $existent_code->isRedeemed()) {
throw new ValidationException(sprintf(
'speaker has been already assigned to another registration code (%s)', $existent_code->getCode()
'speaker has been already assigned to another registration code (%s) already redeemed!', $existent_code->getCode()
));
}
if(!is_null($existent_code) && $reg_code == $existent_code->getCode()) return $existent_code;
// check if reg code is assigned already to another speaker ...
if ($assigned_code = $this->registration_code_repository->getAssignedCode($reg_code, $summit)) {
@ -250,19 +255,28 @@ final class SpeakerService implements ISpeakerService
'there is another speaker with that code for this summit ( speaker id %s )', $assigned_code->getSpeaker()->getId()
));
}
// check is not assigned already
$new_code = $this->registration_code_repository->getNotAssignedCode($reg_code, $summit);
$code = $this->registration_code_repository->getNotAssignedCode($reg_code, $summit);
if (is_null($code)) {
//create it
$code = new SpeakerSummitRegistrationPromoCode();
$code->setSummit($summit);
$code->setCode($reg_code);
if (is_null($new_code)) {
// create it
$new_code = new SpeakerSummitRegistrationPromoCode();
$new_code->setSummit($summit);
$new_code->setCode($reg_code);
$new_code->setSourceAdmin();
// create email request
$email_request = new MemberPromoCodeEmailCreationRequest();
$email_request->setPromoCode($new_code);
$email_request->setEmail($speaker->getEmail());
$email_request->setName($speaker->getFullName());
$this->email_creation_request_repository->add($email_request);
}
$speaker->addPromoCode($code);
return $code;
$speaker->addPromoCode($new_code);
if(!is_null($existent_code)){
$speaker->removePromoCode($existent_code);
}
return $new_code;
});
}
@ -303,6 +317,7 @@ final class SpeakerService implements ISpeakerService
{
return $this->tx_service->transaction(function() use ($summit, $speaker, $data){
$member_id = isset($data['member_id']) ? intval($data['member_id']) : null;
if($member_id > 0)
{
$member = $this->member_repository->getById($member_id);
@ -326,13 +341,16 @@ final class SpeakerService implements ISpeakerService
$this->updateSpeakerMainData($speaker, $data);
// get summit assistance
$summit_assistance = $speaker->getAssistanceFor($summit);
// if does not exists create it
if(is_null($summit_assistance)){
$speaker->addSummitAssistance(
$this->updateSummitAssistance($speaker->buildAssistanceFor($summit), $data)
);
$summit_assistance = $speaker->buildAssistanceFor($summit);
$speaker->addSummitAssistance($summit_assistance);
}
$this->updateSummitAssistance($summit_assistance, $data);
$reg_code = isset($data['registration_code']) ? trim($data['registration_code']) : null;
if(!empty($reg_code)){
$this->registerSummitPromoCodeByValue($speaker, $summit, $reg_code);

View File

@ -237,7 +237,7 @@ class OAuth2SpeakersApiTest extends ProtectedApiTest
'id' => 23,
'page' => 1,
'per_page' => 10,
'filter' => 'id==1,id==19'
'filter' => 'id==13869,id==19'
];
$headers = [
@ -261,4 +261,32 @@ class OAuth2SpeakersApiTest extends ProtectedApiTest
$this->assertTrue(!is_null($speakers));
}
public function testGetCurrentSummitSpeakersByID()
{
$params = [
'id' => 23,
'speaker_id' => 13869
];
$headers = [
"HTTP_Authorization" => " Bearer " . $this->access_token,
"CONTENT_TYPE" => "application/json"
];
$response = $this->action(
"GET",
"OAuth2SummitSpeakersApiController@getSpeaker",
$params,
[],
[],
[],
$headers
);
$content = $response->getContent();
$this->assertResponseStatus(200);
$speaker = json_decode($content);
$this->assertTrue(!is_null($speaker));
}
}