added new endpoint promo code email send

POST /api/v1/summits/{id}/promo-codes/{promo_code_id}/mail

Change-Id: I96a75856c9822339914b64855782f5d08a844701
This commit is contained in:
Sebastian Marcet 2018-01-23 13:15:40 -03:00
parent fa95004fce
commit b5a1bf7109
11 changed files with 259 additions and 11 deletions

View File

@ -363,4 +363,28 @@ final class OAuth2SummitPromoCodesApiController extends OAuth2ProtectedControlle
return $this->error500($ex);
}
}
/**
* @param $summit_id
* @param $promo_code_id
* @return mixed
*/
public function sendPromoCodeMail($summit_id, $promo_code_id)
{
try {
$summit = SummitFinderStrategyFactory::build($this->summit_repository, $this->resource_server_context)->find($summit_id);
if (is_null($summit)) return $this->error404();
$mail_request = $this->promo_code_service->sendPromoCodeMail($summit, $promo_code_id);
return $this->ok($mail_request->getId());
} catch (ValidationException $ex1) {
Log::warning($ex1);
return $this->error412(array($ex1->getMessage()));
} catch (EntityNotFoundException $ex2) {
Log::warning($ex2);
return $this->error404(array('message' => $ex2->getMessage()));
} catch (Exception $ex) {
Log::error($ex);
return $this->error500($ex);
}
}
}

View File

@ -338,6 +338,7 @@ Route::group([
Route::group(['prefix' => '{promo_code_id}'], function () {
Route::put('', [ 'middleware' => 'auth.user:administrators|summit-front-end-administrators', 'uses' => 'OAuth2SummitPromoCodesApiController@updatePromoCodeBySummit']);
Route::delete('', [ 'middleware' => 'auth.user:administrators|summit-front-end-administrators', 'uses' => 'OAuth2SummitPromoCodesApiController@deletePromoCodeBySummit']);
Route::post('mail', [ 'middleware' => 'auth.user:administrators|summit-front-end-administrators', 'uses' => 'OAuth2SummitPromoCodesApiController@sendPromoCodeMail']);
});
});

View File

@ -1058,4 +1058,16 @@ SQL;
$this->rsvp->removeElement($rsvp);
return $this;
}
/**
* @return string
*/
public function getFullName(){
$fullname = $this->first_name;
if(!empty($this->last_name)){
if(!empty($fullname)) $fullname .= ', ';
$fullname .= $this->last_name;
}
return $fullname;
}
}

View File

@ -88,11 +88,24 @@ class MemberSummitRegistrationPromoCode extends SummitRegistrationPromoCode
}
/**
* @return mixed
* @return string|null
*/
public function getEmail()
{
return $this->email;
if(!empty($this->email)) return $this->email;
if($this->hasOwner()) return $this->getOwner()->getEmail();
return null;
}
public function getFullName(){
$fullname = $this->first_name;
if(!empty($this->last_name)){
if(!empty($fullname)) $fullname .= ', ';
$fullname .= $this->last_name;
}
if(!empty($fullname)) return $fullname;
if($this->hasOwner()) return $this->getOwner()->getFullName();
return null;
}
/**

View File

@ -13,6 +13,7 @@
**/
use models\exceptions\EntityNotFoundException;
use models\exceptions\ValidationException;
use models\main\EmailCreationRequest;
use models\main\Member;
use models\summit\Summit;
use models\summit\SummitRegistrationPromoCode;
@ -51,4 +52,14 @@ interface ISummitPromoCodeService
* @throws ValidationException
*/
public function deletePromoCode(Summit $summit, $promo_code_id);
/**
* @param Summit $summit
* @param int $promo_code_id
* @return EmailCreationRequest
* @throws EntityNotFoundException
* @throws ValidationException
*/
public function sendPromoCodeMail(Summit $summit, $promo_code_id);
}

View File

@ -65,12 +65,12 @@ final class SpeakerService implements ISpeakerService
* @var IEmailCreationRequestRepository
*/
private $email_creation_request_repository;
/**
* @var ITransactionService
*/
private $tx_service;
/**
* SpeakerService constructor.
* @param ISpeakerRepository $speaker_repository

View File

@ -15,11 +15,16 @@ use App\Models\Foundation\Summit\Factories\SummitPromoCodeFactory;
use libs\utils\ITransactionService;
use models\exceptions\EntityNotFoundException;
use models\exceptions\ValidationException;
use models\main\EmailCreationRequest;
use models\main\ICompanyRepository;
use models\main\IEmailCreationRequestRepository;
use models\main\IMemberRepository;
use models\main\Member;
use models\main\MemberPromoCodeEmailCreationRequest;
use models\summit\ISpeakerRepository;
use models\summit\ISummitRegistrationPromoCodeRepository;
use models\summit\MemberSummitRegistrationPromoCode;
use models\summit\SpeakerSummitRegistrationPromoCode;
use models\summit\Summit;
use models\summit\SummitRegistrationPromoCode;
use services\model\ISummitPromoCodeService;
@ -49,6 +54,11 @@ final class SummitPromoCodeService implements ISummitPromoCodeService
*/
private $speaker_repository;
/**
* @var IEmailCreationRequestRepository
*/
private $email_creation_request_repository;
/**
* @var ITransactionService
*/
@ -60,6 +70,7 @@ final class SummitPromoCodeService implements ISummitPromoCodeService
* @param IMemberRepository $member_repository
* @param ICompanyRepository $company_repository
* @param ISpeakerRepository $speaker_repository
* @param IEmailCreationRequestRepository $email_creation_request_repository
* @param ITransactionService $tx_service
*/
public function __construct
@ -68,14 +79,16 @@ final class SummitPromoCodeService implements ISummitPromoCodeService
IMemberRepository $member_repository,
ICompanyRepository $company_repository,
ISpeakerRepository $speaker_repository,
IEmailCreationRequestRepository $email_creation_request_repository,
ITransactionService $tx_service
)
{
$this->promo_code_repository = $promo_code_repository;
$this->member_repository = $member_repository;
$this->company_repository = $company_repository;
$this->speaker_repository = $speaker_repository;
$this->tx_service = $tx_service;
$this->promo_code_repository = $promo_code_repository;
$this->member_repository = $member_repository;
$this->company_repository = $company_repository;
$this->speaker_repository = $speaker_repository;
$this->email_creation_request_repository = $email_creation_request_repository;
$this->tx_service = $tx_service;
}
/**
@ -186,16 +199,72 @@ final class SummitPromoCodeService implements ISummitPromoCodeService
$promo_code = $summit->getPromoCodeById($promo_code_id);
if(is_null($promo_code))
throw new EntityNotFoundException(sprintf("promo code id %s does not belongs to summit id %s", $promo_code_id, $summit->getId()));
throw new EntityNotFoundException
(
trans
(
'not_found_errors.promo_code_delete_code_not_found',
[ 'promo_code_id' => $promo_code_id, 'summit_id' => $summit->getId()]
)
);
if ($promo_code->isEmailSent())
throw new EntityValidationException("Cannot delete a code that has been already sent.");
throw new ValidationException(trans('validation_errors.promo_code_delete_already_sent'));
if ($promo_code->isRedeemed())
throw new EntityValidationException("Cannot delete a code that has been already redeemed.");
throw new ValidationException(trans('validation_errors.promo_code_delete_already_redeemed'));
$summit->removePromoCode($promo_code);
});
}
/**
* @param Summit $summit
* @param int $promo_code_id
* @return EmailCreationRequest
* @throws EntityNotFoundException
* @throws ValidationException
*/
public function sendPromoCodeMail(Summit $summit, $promo_code_id)
{
return $this->tx_service->transaction(function() use($promo_code_id, $summit){
$promo_code = $summit->getPromoCodeById($promo_code_id);
if(is_null($promo_code))
throw new EntityNotFoundException(trans('not_found_errors.promo_code_email_code_not_found', [ 'promo_code_id' => $promo_code_id, 'summit_id' => $summit->getId()]));
if ($promo_code->isEmailSent())
throw new ValidationException(trans('validation_errors.promo_code_email_send_already_sent'));
$name = null;
$email = null;
if($promo_code instanceof SpeakerSummitRegistrationPromoCode){
$name = $promo_code->getSpeaker()->getFullName();
$email = $promo_code->getSpeaker()->getEmail();
}
if($promo_code instanceof MemberSummitRegistrationPromoCode){
$name = $promo_code->getFullName();
$email = $promo_code->getEmail();
}
if(empty($name)){
throw new ValidationException(trans("validation_errors.promo_code_email_send_empty_email"));
}
if(empty($name)){
throw new ValidationException(trans("validation_errors.promo_code_email_send_empty_name"));
}
// create email request
$email_request = new MemberPromoCodeEmailCreationRequest();
$email_request->setPromoCode($promo_code);
$email_request->setEmail($name);
$email_request->setName($email);
$this->email_creation_request_repository->add($email_request);
$promo_code->setEmailSent(true);
return $email_request;
});
}
}

View File

@ -694,6 +694,15 @@ class ApiEndpointsSeeder extends Seeder
sprintf(SummitScopes::WriteSummitData, $current_realm)
],
],
[
'name' => 'send-promo-code-mail',
'route' => '/api/v1/summits/{id}/promo-codes/{promo_code_id}/mail',
'http_method' => 'POST',
'scopes' => [
sprintf(SummitScopes::WritePromoCodeData, $current_realm),
sprintf(SummitScopes::WriteSummitData, $current_realm)
],
],
[
'name' => 'get-promo-codes-metadata',
'route' => '/api/v1/summits/{id}/promo-codes/metadata',

View File

@ -0,0 +1,17 @@
<?php
/**
* 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.
**/
return [
'promo_code_delete_code_not_found' => 'promo code id :promo_code_id does not belongs to summit id :summit_id.',
'promo_code_email_code_not_found' => 'promo code id :promo_code_id does not belongs to summit id :summit_id.',
];

View File

@ -0,0 +1,20 @@
<?php
/**
* Copyright 2018 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.
**/
return [
'promo_code_delete_already_sent' => 'Cannot delete a code that has been already sent.',
'promo_code_delete_already_redeemed' => 'Cannot delete a code that has been already redeemed.',
'promo_code_email_send_already_sent' => 'Cannot resend a code that has been already sent.',
'promo_code_email_send_empty_email' => 'Cannot find an email address for the promocode owner.',
'promo_code_email_send_empty_name' => 'Cannot find a name for the promocode owner.',
];

View File

@ -307,4 +307,76 @@ final class OAuth2PromoCodesApiTest extends ProtectedApiTest
$content = $response->getContent();
$this->assertResponseStatus(204);
}
public function testEmailPromoCode($summit_id = 23){
$code = str_random(16).'_PROMOCODE_TEST';
$promo_code = $this->testAddPromoCode($summit_id, $code);
$params = [
'id' => $summit_id,
'promo_code_id' => $promo_code->id
];
$headers = [
"HTTP_Authorization" => " Bearer " . $this->access_token,
"CONTENT_TYPE" => "application/json"
];
$response = $this->action(
"POST",
"OAuth2SummitPromoCodesApiController@sendPromoCodeMail",
$params,
[],
[],
[],
$headers
);
$content = $response->getContent();
$this->assertResponseStatus(200);
}
public function testEmailPromoCodeSendTwice($summit_id = 23){
$code = str_random(16).'_PROMOCODE_TEST';
$promo_code = $this->testAddPromoCode($summit_id, $code);
$params = [
'id' => $summit_id,
'promo_code_id' => $promo_code->id
];
$headers = [
"HTTP_Authorization" => " Bearer " . $this->access_token,
"CONTENT_TYPE" => "application/json"
];
$response = $this->action(
"POST",
"OAuth2SummitPromoCodesApiController@sendPromoCodeMail",
$params,
[],
[],
[],
$headers
);
$content = $response->getContent();
$this->assertResponseStatus(200);
$response = $this->action(
"POST",
"OAuth2SummitPromoCodesApiController@sendPromoCodeMail",
$params,
[],
[],
[],
$headers
);
$content = $response->getContent();
$this->assertResponseStatus(412);
}
}