diff --git a/app/Http/Controllers/Apis/Protected/Summit/Strategies/CheckMeSpeakerStrategy.php b/app/Http/Controllers/Apis/Protected/Summit/Strategies/CheckMeSpeakerStrategy.php index 97ae33db..73df9a46 100644 --- a/app/Http/Controllers/Apis/Protected/Summit/Strategies/CheckMeSpeakerStrategy.php +++ b/app/Http/Controllers/Apis/Protected/Summit/Strategies/CheckMeSpeakerStrategy.php @@ -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)); } } \ No newline at end of file diff --git a/app/Http/routes.php b/app/Http/routes.php index 6c66d624..56322a8d 100644 --- a/app/Http/routes.php +++ b/app/Http/routes.php @@ -316,8 +316,6 @@ Route::group([ Route::group(['prefix' => '{speaker_id}'], function () { Route::post('/photo', [ 'middleware' => 'auth.user:administrators', 'uses' => 'OAuth2SummitSpeakersApiController@addSpeakerPhoto']); }); - - }); }); diff --git a/app/Models/Foundation/Main/EmailCreationRequests/EmailCreationRequest.php b/app/Models/Foundation/Main/EmailCreationRequests/EmailCreationRequest.php index f425b46a..151c7b03 100644 --- a/app/Models/Foundation/Main/EmailCreationRequests/EmailCreationRequest.php +++ b/app/Models/Foundation/Main/EmailCreationRequests/EmailCreationRequest.php @@ -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 */ diff --git a/app/Models/Foundation/Main/EmailCreationRequests/MemberPromoCodeEmailCreationRequest.php b/app/Models/Foundation/Main/EmailCreationRequests/MemberPromoCodeEmailCreationRequest.php new file mode 100644 index 00000000..49c6c14e --- /dev/null +++ b/app/Models/Foundation/Main/EmailCreationRequests/MemberPromoCodeEmailCreationRequest.php @@ -0,0 +1,96 @@ +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; + } +} \ No newline at end of file diff --git a/app/Models/Foundation/Summit/Events/Presentations/PresentationSpeaker.php b/app/Models/Foundation/Summit/Events/Presentations/PresentationSpeaker.php index c925bcb7..8f359c4b 100644 --- a/app/Models/Foundation/Summit/Events/Presentations/PresentationSpeaker.php +++ b/app/Models/Foundation/Summit/Events/Presentations/PresentationSpeaker.php @@ -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 diff --git a/app/Models/Foundation/Summit/Events/Presentations/PresentationSpeakerSummitAssistanceConfirmationRequest.php b/app/Models/Foundation/Summit/Events/Presentations/PresentationSpeakerSummitAssistanceConfirmationRequest.php index c3d694f2..01c7e94a 100644 --- a/app/Models/Foundation/Summit/Events/Presentations/PresentationSpeakerSummitAssistanceConfirmationRequest.php +++ b/app/Models/Foundation/Summit/Events/Presentations/PresentationSpeakerSummitAssistanceConfirmationRequest.php @@ -52,7 +52,6 @@ class PresentationSpeakerSummitAssistanceConfirmationRequest extends Silverstrip */ private $speaker; - /** * @return string */ diff --git a/app/Models/Foundation/Summit/PromoCodes/SummitRegistrationPromoCode.php b/app/Models/Foundation/Summit/PromoCodes/SummitRegistrationPromoCode.php index 3cdb7566..2b9a8e00 100644 --- a/app/Models/Foundation/Summit/PromoCodes/SummitRegistrationPromoCode.php +++ b/app/Models/Foundation/Summit/PromoCodes/SummitRegistrationPromoCode.php @@ -146,4 +146,8 @@ class SummitRegistrationPromoCode extends SilverstripeBaseModel $this->email_sent = false; parent::__construct(); } + + public function setSourceAdmin(){ + $this->source = 'ADMIN'; + } } \ No newline at end of file diff --git a/app/Models/Foundation/Summit/Summit.php b/app/Models/Foundation/Summit/Summit.php index cba26273..0efff522 100644 --- a/app/Models/Foundation/Summit/Summit.php +++ b/app/Models/Foundation/Summit/Summit.php @@ -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; } diff --git a/app/Repositories/Summit/DoctrineSpeakerRepository.php b/app/Repositories/Summit/DoctrineSpeakerRepository.php index bf1cf9dd..8f06d953 100644 --- a/app/Repositories/Summit/DoctrineSpeakerRepository.php +++ b/app/Repositories/Summit/DoctrineSpeakerRepository.php @@ -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 diff --git a/app/Services/Model/SpeakerService.php b/app/Services/Model/SpeakerService.php index 0d485f2a..ccaee086 100644 --- a/app/Services/Model/SpeakerService.php +++ b/app/Services/Model/SpeakerService.php @@ -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; @@ -120,8 +121,12 @@ final class SpeakerService implements ISpeakerService ("you must provide an email or a member_id in order to create a speaker!"); 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_id = intval($data['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); diff --git a/tests/OAuth2SpeakersApiTest.php b/tests/OAuth2SpeakersApiTest.php index 651c15c2..641afebd 100644 --- a/tests/OAuth2SpeakersApiTest.php +++ b/tests/OAuth2SpeakersApiTest.php @@ -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)); + } + } \ No newline at end of file