added new endpoint to reassign attendee ticket to another member

PUT /api/v1/summits/{id}/attendees/{attendee_id}/tickets/{ticket_id}/reassign/{other_member_id}

Change-Id: Ice8a25dc0e85479bdbfdf8328ac2c2712c6a4e1a
This commit is contained in:
Sebastian Marcet 2018-09-10 15:10:33 -03:00
parent e193e866cd
commit 6a01b46a72
6 changed files with 121 additions and 3 deletions

View File

@ -17,6 +17,7 @@ use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Request;
use models\exceptions\EntityNotFoundException;
use models\exceptions\ValidationException;
use models\main\IMemberRepository;
use models\oauth2\IResourceServerContext;
use models\summit\IEventFeedbackRepository;
use models\summit\ISpeakerRepository;
@ -67,6 +68,11 @@ final class OAuth2SummitAttendeesApiController extends OAuth2ProtectedController
*/
private $attendee_repository;
/**
* @var IMemberRepository
*/
private $member_repository;
/**
* OAuth2SummitAttendeesApiController constructor.
* @param ISummitAttendeeRepository $attendee_repository
@ -74,6 +80,7 @@ final class OAuth2SummitAttendeesApiController extends OAuth2ProtectedController
* @param ISummitEventRepository $event_repository
* @param ISpeakerRepository $speaker_repository
* @param IEventFeedbackRepository $event_feedback_repository
* @param IMemberRepository $member_repository
* @param ISummitService $summit_service
* @param IAttendeeService $attendee_service
* @param IResourceServerContext $resource_server_context
@ -85,6 +92,7 @@ final class OAuth2SummitAttendeesApiController extends OAuth2ProtectedController
ISummitEventRepository $event_repository,
ISpeakerRepository $speaker_repository,
IEventFeedbackRepository $event_feedback_repository,
IMemberRepository $member_repository,
ISummitService $summit_service,
IAttendeeService $attendee_service,
IResourceServerContext $resource_server_context
@ -95,6 +103,7 @@ final class OAuth2SummitAttendeesApiController extends OAuth2ProtectedController
$this->speaker_repository = $speaker_repository;
$this->event_repository = $event_repository;
$this->event_feedback_repository = $event_feedback_repository;
$this->member_repository = $member_repository;
$this->summit_service = $summit_service;
$this->attendee_service = $attendee_service;
}
@ -654,4 +663,42 @@ final class OAuth2SummitAttendeesApiController extends OAuth2ProtectedController
return $this->error500($ex);
}
}
/**
* @param $summit_id
* @param $attendee_id
* @param $ticket_id
* @param $other_member_id
* @return mixed
*/
public function reassignAttendeeTicket($summit_id, $attendee_id, $ticket_id, $other_member_id){
try {
$summit = SummitFinderStrategyFactory::build($this->repository, $this->resource_server_context)->find($summit_id);
if (is_null($summit)) return $this->error404();
$attendee = $this->attendee_repository->getById($attendee_id);
if(is_null($attendee)) return $this->error404();
$other_member = $this->member_repository->getById($other_member_id);
if(is_null($other_member)) return $this->error404();
$ticket = $this->attendee_service->reassignAttendeeTicket($summit, $attendee, $other_member_id, $ticket_id);
return $this->updated(SerializerRegistry::getInstance()->getSerializer($ticket)->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);
}
}
}

View File

@ -197,7 +197,11 @@ Route::group([
Route::group(array('prefix' => 'tickets'), function ()
{
Route::post('', [ 'middleware' => 'auth.user:administrators|summit-front-end-administrators', 'uses' => 'OAuth2SummitAttendeesApiController@addAttendeeTicket']);
Route::delete('{ticket_id}', [ 'middleware' => 'auth.user:administrators|summit-front-end-administrators', 'uses' => 'OAuth2SummitAttendeesApiController@deleteAttendeeTicket']);
Route::group(array('prefix' => '{ticket_id}'), function (){
Route::delete('', [ 'middleware' => 'auth.user:administrators|summit-front-end-administrators', 'uses' => 'OAuth2SummitAttendeesApiController@deleteAttendeeTicket']);
Route::put('reassign/{other_member_id}', [ 'middleware' => 'auth.user:administrators|summit-front-end-administrators', 'uses' => 'OAuth2SummitAttendeesApiController@reassignAttendeeTicket']);
});
});
});
});

View File

@ -258,4 +258,11 @@ class SummitAttendee extends SilverstripeBaseModel
return $this;
}
/**
* @return bool
*/
public function hasTickets(){
return $this->tickets->count() > 0;
}
}

View File

@ -16,6 +16,7 @@ use libs\utils\ITransactionService;
use models\exceptions\EntityNotFoundException;
use models\exceptions\ValidationException;
use models\main\IMemberRepository;
use models\main\Member;
use models\summit\factories\SummitAttendeeFactory;
use models\summit\factories\SummitAttendeeTicketFactory;
use models\summit\ISummitAttendeeRepository;
@ -293,4 +294,37 @@ final class AttendeeService extends AbstractService implements IAttendeeService
return $has_more_items;
});
}
/**
* @param Summit $summit
* @param SummitAttendee $attendee
* @param Member $other_member
* @param int $ticket_id
* @return SummitAttendeeTicket
* @throws ValidationException
* @throws EntityNotFoundException
*/
public function reassignAttendeeTicket(Summit $summit, SummitAttendee $attendee, Member $other_member, $ticket_id)
{
return $this->tx_service->transaction(function() use($summit, $attendee, $other_member, $ticket_id){
$ticket = $this->ticket_repository->getById($ticket_id);
if(is_null($ticket)){
throw new EntityNotFoundException("ticket not found");
}
$new_owner = $this->attendee_repository->getBySummitAndMember($summit, $other_member);
if(is_null($new_owner)){
$new_owner = SummitAttendeeFactory::build($summit, $other_member, []);
$this->attendee_repository->add($new_owner);
}
if($new_owner->hasTickets()){
throw new ValidationException('This member is already assigned to another ticket');
}
$attendee->removeTicket($ticket);
if(!$attendee->hasTickets()){
$this->attendee_repository->delete($attendee);
}
$new_owner->addTicket($ticket);
return $ticket;
});
}
}

View File

@ -13,6 +13,7 @@
**/
use models\exceptions\EntityNotFoundException;
use models\exceptions\ValidationException;
use models\main\Member;
use models\summit\Summit;
use models\summit\SummitAttendee;
use models\summit\SummitAttendeeTicket;
@ -74,4 +75,15 @@ interface IAttendeeService
* @return mixed
*/
public function updateRedeemedPromoCodes(Summit $summit, $page_nbr = 1);
/**
* @param Summit $summit
* @param SummitAttendee $attendee
* @param Member $other_member
* @param int $ticket_id
* @return SummitAttendeeTicket
* @throws ValidationException
* @throws EntityNotFoundException
*/
public function reassignAttendeeTicket(Summit $summit,SummitAttendee $attendee, Member $other_member, $ticket_id);
}

View File

@ -175,6 +175,7 @@ class ApiEndpointsSeeder extends Seeder
'route' => '/api/v1/summits/{id}/attendees/{attendee_id}',
'http_method' => 'DELETE',
'scopes' => [
sprintf(SummitScopes::WriteSummitData, $current_realm),
sprintf(SummitScopes::WriteAttendeesData, $current_realm),
],
],
@ -183,6 +184,7 @@ class ApiEndpointsSeeder extends Seeder
'route' => '/api/v1/summits/{id}/attendees/{attendee_id}',
'http_method' => 'PUT',
'scopes' => [
sprintf(SummitScopes::WriteSummitData, $current_realm),
sprintf(SummitScopes::WriteAttendeesData, $current_realm),
],
],
@ -218,6 +220,7 @@ class ApiEndpointsSeeder extends Seeder
'route' => '/api/v1/summits/{id}/attendees',
'http_method' => 'POST',
'scopes' => [
sprintf(SummitScopes::WriteSummitData, $current_realm),
sprintf(SummitScopes::WriteAttendeesData, $current_realm),
],
),
@ -226,17 +229,28 @@ class ApiEndpointsSeeder extends Seeder
'route' => '/api/v1/summits/{id}/attendees/{attendee_id}/tickets',
'http_method' => 'POST',
'scopes' => [
sprintf(SummitScopes::WriteSummitData, $current_realm),
sprintf(SummitScopes::WriteAttendeesData, $current_realm),
],
),
array(
[
'name' => 'delete-attendee-ticket',
'route' => '/api/v1/summits/{id}/attendees/{attendee_id}/tickets/{ticket_id}',
'http_method' => 'DELETE',
'scopes' => [
sprintf(SummitScopes::WriteSummitData, $current_realm),
sprintf(SummitScopes::WriteAttendeesData, $current_realm),
],
),
],
[
'name' => 'reassign-attendee-ticket',
'route' => '/api/v1/summits/{id}/attendees/{attendee_id}/tickets/{ticket_id}/reassign/{other_member_id}',
'http_method' => 'PUT',
'scopes' => [
sprintf(SummitScopes::WriteSummitData, $current_realm),
sprintf(SummitScopes::WriteAttendeesData, $current_realm),
],
],
// speakers
array(
'name' => 'get-speakers',