Fixes on member affiliation API
* added endpoint to add new affiliation /api/v1/members/{member_id}/affiliations * fixed issues on delete affiliation * fixed validation on update affiliation * updated serializer on speaker to get all affiliations Change-Id: I31426265ab9e57e67a6d1ae2a24b49287ab8d700
This commit is contained in:
parent
2414f6a3e9
commit
2535885128
@ -228,6 +228,53 @@ final class OAuth2MembersApiController extends OAuth2ProtectedController
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function addAffiliation($member_id){
|
||||||
|
try {
|
||||||
|
if(!Request::isJson()) return $this->error400();
|
||||||
|
$data = Input::json();
|
||||||
|
|
||||||
|
$member = $this->repository->getById($member_id);
|
||||||
|
if(is_null($member)) return $this->error404();
|
||||||
|
|
||||||
|
$rules = [
|
||||||
|
'is_current' => 'required|boolean',
|
||||||
|
'start_date' => 'required|date_format:U|valid_epoch',
|
||||||
|
'end_date' => 'sometimes|date_format:U|after_or_null_epoch:start_date',
|
||||||
|
'organization_id' => 'required|integer',
|
||||||
|
'job_title' => 'sometimes|string|max:255'
|
||||||
|
];
|
||||||
|
|
||||||
|
// 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
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
$affiliation = $this->member_service->addAffiliation($member, $data->all());
|
||||||
|
|
||||||
|
return $this->created(SerializerRegistry::getInstance()->getSerializer($affiliation)->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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param int $member_id
|
* @param int $member_id
|
||||||
* @param int $affiliation_id
|
* @param int $affiliation_id
|
||||||
@ -263,7 +310,7 @@ final class OAuth2MembersApiController extends OAuth2ProtectedController
|
|||||||
|
|
||||||
$affiliation = $this->member_service->updateAffiliation($member, $affiliation_id, $data->all());
|
$affiliation = $this->member_service->updateAffiliation($member, $affiliation_id, $data->all());
|
||||||
|
|
||||||
return $this->ok(SerializerRegistry::getInstance()->getSerializer($affiliation)->serialize());
|
return $this->updated(SerializerRegistry::getInstance()->getSerializer($affiliation)->serialize());
|
||||||
}
|
}
|
||||||
catch (ValidationException $ex1) {
|
catch (ValidationException $ex1) {
|
||||||
Log::warning($ex1);
|
Log::warning($ex1);
|
||||||
|
@ -46,6 +46,7 @@ Route::group([
|
|||||||
|
|
||||||
Route::group(['prefix' => 'affiliations'], function(){
|
Route::group(['prefix' => 'affiliations'], function(){
|
||||||
Route::get('', [ 'middleware' => 'auth.user:administrators|summit-front-end-administrators', 'uses' => 'OAuth2MembersApiController@getMemberAffiliations']);
|
Route::get('', [ 'middleware' => 'auth.user:administrators|summit-front-end-administrators', 'uses' => 'OAuth2MembersApiController@getMemberAffiliations']);
|
||||||
|
Route::post('', [ 'middleware' => 'auth.user:administrators|summit-front-end-administrators', 'uses' => 'OAuth2MembersApiController@addAffiliation']);
|
||||||
Route::group(['prefix' => '{affiliation_id}'], function(){
|
Route::group(['prefix' => '{affiliation_id}'], function(){
|
||||||
Route::put('', [ 'middleware' => 'auth.user:administrators|summit-front-end-administrators', 'uses' => 'OAuth2MembersApiController@updateAffiliation']);
|
Route::put('', [ 'middleware' => 'auth.user:administrators|summit-front-end-administrators', 'uses' => 'OAuth2MembersApiController@updateAffiliation']);
|
||||||
Route::delete('', [ 'middleware' => 'auth.user:administrators|summit-front-end-administrators', 'uses' => 'OAuth2MembersApiController@deleteAffiliation']);
|
Route::delete('', [ 'middleware' => 'auth.user:administrators|summit-front-end-administrators', 'uses' => 'OAuth2MembersApiController@deleteAffiliation']);
|
||||||
|
@ -111,6 +111,15 @@ final class AdminPresentationSpeakerSerializer extends PresentationSpeakerSerial
|
|||||||
}
|
}
|
||||||
$values['organizational_roles'] = $organizational_roles;
|
$values['organizational_roles'] = $organizational_roles;
|
||||||
|
|
||||||
|
$affiliations = [];
|
||||||
|
if($speaker->hasMember()) {
|
||||||
|
$member = $speaker->getMember();
|
||||||
|
foreach ($member->getAllAffiliations() as $affiliation) {
|
||||||
|
$affiliations[] = SerializerRegistry::getInstance()->getSerializer($affiliation)->serialize('organization');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$values['affiliations'] = $affiliations;
|
||||||
|
|
||||||
if (!empty($expand)) {
|
if (!empty($expand)) {
|
||||||
foreach (explode(',', $expand) as $relation) {
|
foreach (explode(',', $expand) as $relation) {
|
||||||
switch (trim($relation)) {
|
switch (trim($relation)) {
|
||||||
|
@ -135,6 +135,10 @@ class Affiliation extends SilverstripeBaseModel
|
|||||||
return $this->owner;
|
return $this->owner;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function clearOwner(){
|
||||||
|
$this->owner = null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Member $owner
|
* @param Member $owner
|
||||||
*/
|
*/
|
||||||
@ -189,4 +193,14 @@ class Affiliation extends SilverstripeBaseModel
|
|||||||
{
|
{
|
||||||
$this->job_title = $job_title;
|
$this->job_title = $job_title;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
$this->is_current = false;
|
||||||
|
$this->start_date = null;
|
||||||
|
$this->end_date = null;
|
||||||
|
$this->organization = null;
|
||||||
|
$this->owner = null;
|
||||||
|
}
|
||||||
}
|
}
|
@ -61,13 +61,13 @@ class Member extends SilverstripeBaseModel
|
|||||||
private $github_user;
|
private $github_user;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ORM\OneToMany(targetEntity="models\summit\SummitEventFeedback", mappedBy="owner", cascade={"persist"})
|
* @ORM\OneToMany(targetEntity="models\summit\SummitEventFeedback", mappedBy="owner", cascade={"persist"}, orphanRemoval=true)
|
||||||
* @var SummitEventFeedback[]
|
* @var SummitEventFeedback[]
|
||||||
*/
|
*/
|
||||||
private $feedback;
|
private $feedback;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ORM\OneToMany(targetEntity="Affiliation", mappedBy="owner", cascade={"persist"})
|
* @ORM\OneToMany(targetEntity="Affiliation", mappedBy="owner", cascade={"persist"}, orphanRemoval=true)
|
||||||
* @var Affiliation[]
|
* @var Affiliation[]
|
||||||
*/
|
*/
|
||||||
private $affiliations;
|
private $affiliations;
|
||||||
@ -1019,7 +1019,7 @@ SQL;
|
|||||||
*/
|
*/
|
||||||
public function getAffiliationById($affiliation_id){
|
public function getAffiliationById($affiliation_id){
|
||||||
$criteria = Criteria::create();
|
$criteria = Criteria::create();
|
||||||
$criteria->where(Criteria::expr()->eq('id', $affiliation_id));
|
$criteria->where(Criteria::expr()->eq('id', intval($affiliation_id)));
|
||||||
|
|
||||||
$affiliation = $this->affiliations->matching($criteria)->first();
|
$affiliation = $this->affiliations->matching($criteria)->first();
|
||||||
|
|
||||||
@ -1031,7 +1031,22 @@ SQL;
|
|||||||
* @return $this
|
* @return $this
|
||||||
*/
|
*/
|
||||||
public function removeAffiliation(Affiliation $affiliation){
|
public function removeAffiliation(Affiliation $affiliation){
|
||||||
$this->affiliations->removeElement($affiliation);
|
if($this->affiliations->contains($affiliation)) {
|
||||||
|
$this->affiliations->removeElement($affiliation);
|
||||||
|
$affiliation->clearOwner();
|
||||||
|
}
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Affiliation $affiliation
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function addAffiliation(Affiliation $affiliation){
|
||||||
|
if(!$this->affiliations->contains($affiliation)) {
|
||||||
|
$this->affiliations->add($affiliation);
|
||||||
|
$affiliation->setOwner($this);
|
||||||
|
}
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,6 +19,14 @@ use models\main\Member;
|
|||||||
*/
|
*/
|
||||||
interface IMemberService
|
interface IMemberService
|
||||||
{
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Member $member
|
||||||
|
* @param array $data
|
||||||
|
* @return Affiliation
|
||||||
|
*/
|
||||||
|
public function addAffiliation(Member $member, array $data);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Member $member
|
* @param Member $member
|
||||||
* @param int $affiliation_id
|
* @param int $affiliation_id
|
||||||
|
@ -63,7 +63,7 @@ final class MemberService
|
|||||||
$affiliation->setIsCurrent(boolval($data['is_current']));
|
$affiliation->setIsCurrent(boolval($data['is_current']));
|
||||||
if(isset($data['start_date'])) {
|
if(isset($data['start_date'])) {
|
||||||
$start_date = intval($data['start_date']);
|
$start_date = intval($data['start_date']);
|
||||||
$affiliation->setEndDate(new DateTime("@$start_date"));
|
$affiliation->setStartDate(new DateTime("@$start_date"));
|
||||||
}
|
}
|
||||||
if(isset($data['end_date'])) {
|
if(isset($data['end_date'])) {
|
||||||
$end_date = intval($data['end_date']);
|
$end_date = intval($data['end_date']);
|
||||||
@ -125,4 +125,50 @@ final class MemberService
|
|||||||
$member->removeRsvp($rsvp);
|
$member->removeRsvp($rsvp);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Member $member
|
||||||
|
* @param array $data
|
||||||
|
* @return Affiliation
|
||||||
|
*/
|
||||||
|
public function addAffiliation(Member $member, array $data)
|
||||||
|
{
|
||||||
|
return $this->tx_service->transaction(function() use($member, $data){
|
||||||
|
|
||||||
|
$affiliation = new Affiliation();
|
||||||
|
|
||||||
|
if(isset($data['is_current']))
|
||||||
|
$affiliation->setIsCurrent(boolval($data['is_current']));
|
||||||
|
if(isset($data['start_date'])) {
|
||||||
|
$start_date = intval($data['start_date']);
|
||||||
|
$affiliation->setStartDate(new DateTime("@$start_date"));
|
||||||
|
}
|
||||||
|
if(isset($data['end_date'])) {
|
||||||
|
$end_date = intval($data['end_date']);
|
||||||
|
$affiliation->setEndDate($end_date > 0 ? new DateTime("@$end_date") : null);
|
||||||
|
}
|
||||||
|
if(isset($data['organization_id'])) {
|
||||||
|
$org = $this->organization_repository->getById(intval($data['organization_id']));
|
||||||
|
if(is_null($org))
|
||||||
|
throw new EntityNotFoundException(sprintf("organization id %s not found", $data['organization_id']));
|
||||||
|
$affiliation->setOrganization($org);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(isset($data['job_title'])) {
|
||||||
|
$affiliation->setJobTitle(trim($data['job_title']));
|
||||||
|
}
|
||||||
|
|
||||||
|
if($affiliation->isCurrent() && $affiliation->getEndDate() != null)
|
||||||
|
throw new ValidationException
|
||||||
|
(
|
||||||
|
sprintf
|
||||||
|
(
|
||||||
|
"in order to set affiliation as current end_date should be null"
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
$member->addAffiliation($affiliation);
|
||||||
|
return $affiliation;
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
@ -1781,6 +1781,14 @@ class ApiEndpointsSeeder extends Seeder
|
|||||||
'http_method' => 'GET',
|
'http_method' => 'GET',
|
||||||
'scopes' => [sprintf('%s/members/read', $current_realm)],
|
'scopes' => [sprintf('%s/members/read', $current_realm)],
|
||||||
],
|
],
|
||||||
|
[
|
||||||
|
'name' => 'add-member-affiliation',
|
||||||
|
'route' => '/api/v1/members/{member_id}/affiliations',
|
||||||
|
'http_method' => 'POST',
|
||||||
|
'scopes' => [
|
||||||
|
sprintf(SummitScopes::WriteMemberData, $current_realm)
|
||||||
|
],
|
||||||
|
],
|
||||||
[
|
[
|
||||||
'name' => 'update-member-affiliation',
|
'name' => 'update-member-affiliation',
|
||||||
'route' => '/api/v1/members/{member_id}/affiliations/{affiliation_id}',
|
'route' => '/api/v1/members/{member_id}/affiliations/{affiliation_id}',
|
||||||
|
@ -161,16 +161,54 @@ final class OAuth2MembersApiTest extends ProtectedApiTest
|
|||||||
$this->assertResponseStatus(200);
|
$this->assertResponseStatus(200);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testUpdateMemberAffiliation(){
|
public function testAddMemberAffiliation($member_id = 11624){
|
||||||
$params = [
|
$params = [
|
||||||
'member_id' => 11624,
|
'member_id' => $member_id,
|
||||||
'affiliation_id' => 61749,
|
|
||||||
];
|
];
|
||||||
|
|
||||||
|
$start_datetime = new DateTime( "2018-11-10 00:00:00");
|
||||||
|
$start_datetime_unix = $start_datetime->getTimestamp();
|
||||||
|
|
||||||
$data = [
|
$data = [
|
||||||
'is_current' => true,
|
'is_current' => true,
|
||||||
'end_date' => 0,
|
'start_date' => $start_datetime_unix,
|
||||||
'job_title' => 'test update'
|
'job_title' => 'test affiliation',
|
||||||
|
'organization_id' => 1
|
||||||
|
];
|
||||||
|
|
||||||
|
$headers = [
|
||||||
|
"HTTP_Authorization" => " Bearer " . $this->access_token,
|
||||||
|
"CONTENT_TYPE" => "application/json"
|
||||||
|
];
|
||||||
|
|
||||||
|
$response = $this->action(
|
||||||
|
"POST",
|
||||||
|
"OAuth2MembersApiController@addAffiliation",
|
||||||
|
$params,
|
||||||
|
[],
|
||||||
|
[],
|
||||||
|
[],
|
||||||
|
$headers,
|
||||||
|
json_encode($data)
|
||||||
|
);
|
||||||
|
|
||||||
|
$content = $response->getContent();
|
||||||
|
$this->assertResponseStatus(201);
|
||||||
|
$affiliation = json_decode($content);
|
||||||
|
$this->assertTrue(!is_null($affiliation));
|
||||||
|
return $affiliation;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testUpdateMemberAffiliation($member_id = 11624){
|
||||||
|
|
||||||
|
$new_affiliation = $this->testAddMemberAffiliation($member_id);
|
||||||
|
$params = [
|
||||||
|
'member_id' => $member_id,
|
||||||
|
'affiliation_id' => $new_affiliation->id,
|
||||||
|
];
|
||||||
|
|
||||||
|
$data = [
|
||||||
|
'job_title' => 'job title update'
|
||||||
];
|
];
|
||||||
|
|
||||||
$headers = [
|
$headers = [
|
||||||
@ -190,12 +228,39 @@ final class OAuth2MembersApiTest extends ProtectedApiTest
|
|||||||
);
|
);
|
||||||
|
|
||||||
$content = $response->getContent();
|
$content = $response->getContent();
|
||||||
$this->assertResponseStatus(200);
|
$this->assertResponseStatus(201);
|
||||||
$affiliation = json_decode($content);
|
$affiliation = json_decode($content);
|
||||||
$this->assertTrue(!is_null($affiliation));
|
$this->assertTrue(!is_null($affiliation));
|
||||||
return $affiliation;
|
return $affiliation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testDeleteMemberAffiliation($member_id = 11624){
|
||||||
|
|
||||||
|
$new_affiliation = $this->testAddMemberAffiliation($member_id);
|
||||||
|
$params = [
|
||||||
|
'member_id' => $member_id,
|
||||||
|
'affiliation_id' => $new_affiliation->id,
|
||||||
|
];
|
||||||
|
|
||||||
|
$headers = [
|
||||||
|
"HTTP_Authorization" => " Bearer " . $this->access_token,
|
||||||
|
"CONTENT_TYPE" => "application/json"
|
||||||
|
];
|
||||||
|
|
||||||
|
$response = $this->action(
|
||||||
|
"DELETE",
|
||||||
|
"OAuth2MembersApiController@deleteAffiliation",
|
||||||
|
$params,
|
||||||
|
[],
|
||||||
|
[],
|
||||||
|
[],
|
||||||
|
$headers
|
||||||
|
);
|
||||||
|
|
||||||
|
$content = $response->getContent();
|
||||||
|
$this->assertResponseStatus(204);
|
||||||
|
}
|
||||||
|
|
||||||
public function testGetMemberAffiliation($member_id = 11624)
|
public function testGetMemberAffiliation($member_id = 11624)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user