diff --git a/app/Http/Controllers/Apis/Protected/Summit/OAuth2SummitPromoCodesApiController.php b/app/Http/Controllers/Apis/Protected/Summit/OAuth2SummitPromoCodesApiController.php index 7fbab8f7..c5a745ce 100644 --- a/app/Http/Controllers/Apis/Protected/Summit/OAuth2SummitPromoCodesApiController.php +++ b/app/Http/Controllers/Apis/Protected/Summit/OAuth2SummitPromoCodesApiController.php @@ -249,7 +249,7 @@ final class OAuth2SummitPromoCodesApiController extends OAuth2ProtectedControlle $summit = SummitFinderStrategyFactory::build($this->summit_repository, $this->resource_server_context)->find($summit_id); if (is_null($summit)) return $this->error404(); - $rules = PromoCodesValidationRulesFactory::buildAddRules($data->all()); + $rules = PromoCodesValidationRulesFactory::build($data->all()); // Creates a Validator instance and validates the data. $validation = Validator::make($data->all(), $rules); @@ -285,4 +285,46 @@ final class OAuth2SummitPromoCodesApiController extends OAuth2ProtectedControlle return $this->error500($ex); } } + + public function updatePromoCodeBySummit($summit_id, $promo_code_id) + { + try { + if (!Request::isJson()) return $this->error403(); + $data = Input::json(); + + $summit = SummitFinderStrategyFactory::build($this->summit_repository, $this->resource_server_context)->find($summit_id); + if (is_null($summit)) return $this->error404(); + + $rules = PromoCodesValidationRulesFactory::build($data->all()); + // Creates a Validator instance and validates the data. + $validation = Validator::make($data->all(), $rules); + + if ($validation->fails()) { + $messages = $validation->messages()->toArray(); + + return $this->error412 + ( + $messages + ); + } + + $current_member = null; + if (!is_null($this->resource_server_context->getCurrentUserExternalId())) { + $current_member = $this->member_repository->getById($this->resource_server_context->getCurrentUserExternalId()); + } + + $promo_code = $this->promo_code_service->updatePromoCode($summit, $promo_code_id, $data->all(), $current_member); + + return $this->updated(SerializerRegistry::getInstance()->getSerializer($promo_code)->serialize()); + } 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); + } + } } \ No newline at end of file diff --git a/app/Http/Controllers/Apis/Protected/Summit/PromoCodesValidationRulesFactory.php b/app/Http/Controllers/Apis/Protected/Summit/PromoCodesValidationRulesFactory.php index a44c1148..68df76c9 100644 --- a/app/Http/Controllers/Apis/Protected/Summit/PromoCodesValidationRulesFactory.php +++ b/app/Http/Controllers/Apis/Protected/Summit/PromoCodesValidationRulesFactory.php @@ -27,7 +27,7 @@ final class PromoCodesValidationRulesFactory * @return array * @throws ValidationException */ - public static function buildAddRules(array $data){ + public static function build(array $data){ if(!isset($data['class_name'])) throw new ValidationException("class_name parameter is mandatory"); diff --git a/app/Http/routes.php b/app/Http/routes.php index a08c9a80..e4e65cc8 100644 --- a/app/Http/routes.php +++ b/app/Http/routes.php @@ -335,6 +335,9 @@ Route::group([ Route::get('', [ 'middleware' => 'auth.user:administrators|summit-front-end-administrators', 'uses' => 'OAuth2SummitPromoCodesApiController@getAllBySummit']); Route::post('', [ 'middleware' => 'auth.user:administrators|summit-front-end-administrators', 'uses' => 'OAuth2SummitPromoCodesApiController@addPromoCodeBySummit']); Route::get('metadata', [ 'middleware' => 'auth.user:administrators|summit-front-end-administrators', 'uses' => 'OAuth2SummitPromoCodesApiController@getMetadata']); + Route::group(['prefix' => '{promo_code_id}'], function () { + Route::put('', [ 'middleware' => 'auth.user:administrators|summit-front-end-administrators', 'uses' => 'OAuth2SummitPromoCodesApiController@updatePromoCodeBySummit']); + }); }); }); diff --git a/app/Models/Foundation/Summit/Factories/SummitPromoCodeFactory.php b/app/Models/Foundation/Summit/Factories/SummitPromoCodeFactory.php index 416ad716..035cbe7e 100644 --- a/app/Models/Foundation/Summit/Factories/SummitPromoCodeFactory.php +++ b/app/Models/Foundation/Summit/Factories/SummitPromoCodeFactory.php @@ -15,17 +15,50 @@ use models\summit\MemberSummitRegistrationPromoCode; use models\summit\SpeakerSummitRegistrationPromoCode; use models\summit\SponsorSummitRegistrationPromoCode; use models\summit\Summit; +use models\summit\SummitRegistrationPromoCode; /** * Class SummitPromoCodeFactory * @package App\Models\Foundation\Summit\Factories */ final class SummitPromoCodeFactory { + /** + * @param Summit $summit + * @param array $data + * @param array $params + * @return SummitRegistrationPromoCode|null + */ public static function build(Summit $summit, array $data, array $params = []){ $promo_code = null; switch ($data['class_name']){ case MemberSummitRegistrationPromoCode::ClassName:{ $promo_code = new MemberSummitRegistrationPromoCode(); + } + break; + case SpeakerSummitRegistrationPromoCode::ClassName:{ + $promo_code = new SpeakerSummitRegistrationPromoCode(); + } + break; + case SponsorSummitRegistrationPromoCode::ClassName:{ + $promo_code = new SponsorSummitRegistrationPromoCode(); + } + break; + } + + if(is_null($promo_code)) return null; + return self::populate($promo_code, $summit, $data, $params); + } + + /** + * @param SummitRegistrationPromoCode $promo_code + * @param Summit $summit + * @param array $data + * @param array $params + * @return SummitRegistrationPromoCode + */ + public static function populate(SummitRegistrationPromoCode $promo_code, Summit $summit, array $data, array $params = []){ + switch ($data['class_name']){ + case MemberSummitRegistrationPromoCode::ClassName:{ if(isset($params['owner'])) $promo_code->setOwner($params['owner']); if(isset($data['type'])) @@ -37,23 +70,19 @@ final class SummitPromoCodeFactory if(isset($data['email'])) $promo_code->setEmail(trim($data['email'])); } - break; + break; case SpeakerSummitRegistrationPromoCode::ClassName:{ - $promo_code = new SpeakerSummitRegistrationPromoCode(); if(isset($data['type'])) $promo_code->setType($data['type']); $promo_code->setSpeaker($params['speaker']); } - break; + break; case SponsorSummitRegistrationPromoCode::ClassName:{ - $promo_code = new SponsorSummitRegistrationPromoCode(); $promo_code->setSponsor($params['sponsor']); } break; } - if(is_null($promo_code)) return null; - $promo_code->setCode(trim($data['code'])); $summit->addPromoCode($promo_code); return $promo_code; diff --git a/app/Models/Foundation/Summit/Summit.php b/app/Models/Foundation/Summit/Summit.php index 98404f13..964bead5 100644 --- a/app/Models/Foundation/Summit/Summit.php +++ b/app/Models/Foundation/Summit/Summit.php @@ -1362,4 +1362,15 @@ SQL; $promo_code = $this->promo_codes->matching($criteria)->first(); return $promo_code === false ? null : $promo_code; } + + /** + * @param int $promo_code_id + * @return SummitRegistrationPromoCode|null + */ + public function getPromoCodeById($promo_code_id){ + $criteria = Criteria::create(); + $criteria->where(Criteria::expr()->eq('id', $promo_code_id)); + $promo_code = $this->promo_codes->matching($criteria)->first(); + return $promo_code === false ? null : $promo_code; + } } \ No newline at end of file diff --git a/app/Services/Model/ISummitPromoCodeService.php b/app/Services/Model/ISummitPromoCodeService.php index 76802d84..a9ad51c7 100644 --- a/app/Services/Model/ISummitPromoCodeService.php +++ b/app/Services/Model/ISummitPromoCodeService.php @@ -32,4 +32,14 @@ interface ISummitPromoCodeService */ public function addPromoCode(Summit $summit, array $data, Member $current_user = null); + /** + * @param Summit $summit + * @param int $promo_code_id + * @param array $data + * @param Member $current_user + * @return SummitRegistrationPromoCode + * @throws EntityNotFoundException + * @throws ValidationException + */ + public function updatePromoCode(Summit $summit, $promo_code_id, array $data, Member $current_user = null); } \ No newline at end of file diff --git a/app/Services/Model/SummitPromoCodeService.php b/app/Services/Model/SummitPromoCodeService.php index eb2912ea..ea9d315e 100644 --- a/app/Services/Model/SummitPromoCodeService.php +++ b/app/Services/Model/SummitPromoCodeService.php @@ -78,6 +78,38 @@ final class SummitPromoCodeService implements ISummitPromoCodeService $this->tx_service = $tx_service; } + /** + * @param array $data + * @return array + * @throws EntityNotFoundException + */ + private function getPromoCodeParams(array $data){ + $params = []; + + if(isset($data['owner_id'])){ + $owner = $this->member_repository->getById(intval($data['owner_id'])); + if(is_null($owner)) + throw new EntityNotFoundException(sprintf("owner_id %s not found", $data['owner_id'])); + $params['owner'] = $owner; + } + + if(isset($data['speaker_id'])){ + $speaker = $this->speaker_repository->getById(intval($data['speaker_id'])); + if(is_null($speaker)) + throw new EntityNotFoundException(sprintf("speaker_id %s not found", $data['speaker_id'])); + $params['speaker'] = $speaker; + } + + + if(isset($data['sponsor_id'])){ + $sponsor = $this->company_repository->getById(intval($data['sponsor_id'])); + if(is_null($sponsor)) + throw new EntityNotFoundException(sprintf("sponsor_id %s not found", $data['sponsor_id'])); + $params['sponsor'] = $sponsor; + } + + return $params; + } /** * @param Summit $summit * @param array $data @@ -94,33 +126,44 @@ final class SummitPromoCodeService implements ISummitPromoCodeService if(!is_null($old_promo_code)) throw new ValidationException(sprintf("promo code %s already exits on summit id %s", trim($data['code']), $summit->getId())); - $params = []; - if(isset($data['owner_id'])){ - $owner = $this->member_repository->getById(intval($data['owner_id'])); - if(is_null($owner)) - throw new EntityNotFoundException(sprintf("owner_id %s not found", $data['owner_id'])); - $params['owner'] = $owner; - } - - if(isset($data['speaker_id'])){ - $speaker = $this->speaker_repository->getById(intval($data['speaker_id'])); - if(is_null($speaker)) - throw new EntityNotFoundException(sprintf("speaker_id %s not found", $data['speaker_id'])); - $params['speaker'] = $speaker; - } - - - if(isset($data['sponsor_id'])){ - $sponsor = $this->company_repository->getById(intval($data['sponsor_id'])); - if(is_null($sponsor)) - throw new EntityNotFoundException(sprintf("sponsor_id %s not found", $data['sponsor_id'])); - $params['sponsor'] = $sponsor; - } - - $promo_code = SummitPromoCodeFactory::build($summit, $data, $params); + $promo_code = SummitPromoCodeFactory::build($summit, $data, $this->getPromoCodeParams($data)); if(is_null($promo_code)) - throw new ValidationException("class_name %s is invalid", $data['class_name']); + throw new ValidationException(sprintf("class_name %s is invalid", $data['class_name'])); + + if(!is_null($current_user)) + $promo_code->setCreator($current_user); + + $promo_code->setSourceAdmin(); + + return $promo_code; + }); + } + + /** + * @param Summit $summit + * @param int $promo_code_id + * @param array $data + * @param Member $current_user + * @return SummitRegistrationPromoCode + * @throws EntityNotFoundException + * @throws ValidationException + */ + public function updatePromoCode(Summit $summit, $promo_code_id, array $data, Member $current_user = null) + { + return $this->tx_service->transaction(function() use($promo_code_id, $summit, $data, $current_user){ + + $old_promo_code = $summit->getPromoCodeByCode(trim($data['code'])); + + if(!is_null($old_promo_code) && $old_promo_code->getId() != $promo_code_id) + throw new ValidationException(sprintf("promo code %s already exits on summit id %s for promo code id %s", trim($data['code']), $summit->getId(), $old_promo_code->getId())); + + $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())); + + $promo_code = SummitPromoCodeFactory::populate($promo_code, $summit, $data, $this->getPromoCodeParams($data)); + if(!is_null($current_user)) $promo_code->setCreator($current_user); diff --git a/database/seeds/ApiEndpointsSeeder.php b/database/seeds/ApiEndpointsSeeder.php index a70daa01..784b76be 100644 --- a/database/seeds/ApiEndpointsSeeder.php +++ b/database/seeds/ApiEndpointsSeeder.php @@ -676,6 +676,15 @@ class ApiEndpointsSeeder extends Seeder sprintf(SummitScopes::WriteSummitData, $current_realm) ], ], + [ + 'name' => 'update-promo-code', + 'route' => '/api/v1/summits/{id}/promo-codes/{promo_code_id}', + 'http_method' => 'PUT', + 'scopes' => [ + sprintf(SummitScopes::WritePromoCodeData, $current_realm), + sprintf(SummitScopes::WriteSummitData, $current_realm) + ], + ], [ 'name' => 'get-promo-codes-metadata', 'route' => '/api/v1/summits/{id}/promo-codes/metadata', diff --git a/tests/OAuth2PromoCodesApiTest.php b/tests/OAuth2PromoCodesApiTest.php index 2b71c314..20929d22 100644 --- a/tests/OAuth2PromoCodesApiTest.php +++ b/tests/OAuth2PromoCodesApiTest.php @@ -201,9 +201,9 @@ final class OAuth2PromoCodesApiTest extends ProtectedApiTest $this->assertTrue(!is_null($metadata)); } - public function testAddPromoCode($code = "12344KG_SPEAKER"){ + public function testAddPromoCode($summit_id = 23, $code = "12344KG_SPEAKER"){ $params = [ - 'id' => 23, + 'id' => $summit_id, ]; $data = [ @@ -237,4 +237,45 @@ final class OAuth2PromoCodesApiTest extends ProtectedApiTest $this->assertTrue(!is_null($promo_code)); return $promo_code; } + + public function testUpdatePromoCode($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 + ]; + + $data = [ + 'code' => $code.'_UPDATE', + 'class_name' => \models\summit\MemberSummitRegistrationPromoCode::ClassName, + 'first_name' => 'Sebastian update', + 'last_name' => 'Marcet update', + 'email' => 'test@test.com', + 'type' => \models\summit\MemberSummitRegistrationPromoCode::$valid_type_values[2] + ]; + + $headers = [ + "HTTP_Authorization" => " Bearer " . $this->access_token, + "CONTENT_TYPE" => "application/json" + ]; + + $response = $this->action( + "PUT", + "OAuth2SummitPromoCodesApiController@updatePromoCodeBySummit", + $params, + [], + [], + [], + $headers, + json_encode($data) + ); + + $content = $response->getContent(); + $this->assertResponseStatus(201); + $promo_code = json_decode($content); + $this->assertTrue(!is_null($promo_code)); + return $promo_code; + } } \ No newline at end of file