Booking Rooms Model
* model changes * Endpoint to get all avaible booking rooms per summit GET /api/v1/summits/{id}/locations/bookable-rooms query string params page ( int ) current page number per_page ( int) max amount of items per page filter ( allowed fields: name, description, cost, capacity, availability_day[epoch], attribute[string|number]) order ( allowed fields id,name,capacity) expand ( allowed relations venue,floor,attribute_type) scopes %s/bookable-rooms/read %s/summits/read/all * Endpoint to get slot availability per room GET /api/v1/summits/{id}/locations/bookable-rooms/{room_id}/availability/{day} where id is summit id (integer) room_id ( integer) and day (epoch timestamp) scopes %s/bookable-rooms/read %s/summits/read/all * endpoint create reservation POST /api/v1/summits/{id}/locations/bookable-rooms/{room_id}/reservations payload 'currency' => 'required|string|currency_iso', 'amount' => 'required|integer', 'start_datetime' => 'required|date_format:U', 'end_datetime' => 'required|date_format:U|after:start_datetime', scopes %s/bookable-rooms/my-reservations/write * endpoint to get all my reservations GET /api/v1/summits/{id}/locations/bookable-rooms/all/reservations/me query string params expand [owner, room, type] scopes %s/bookable-rooms/my-reservations/read * endpoint to cancel/ask for refund a reservation DELETE /api/v1/summits/{id}/locations/bookable-rooms/all/reservations/{reservation_id} scopes %s/bookable-rooms/my-reservations/write Change-Id: I741878c6ffc833ba23fca40f09f4664b42c8edd4
This commit is contained in:
parent
6a674a6dd8
commit
9f01b9e3b3
@ -133,7 +133,7 @@ abstract class AbstractSerializer implements IModelSerializer
|
||||
* @param array $params
|
||||
* @return array
|
||||
*/
|
||||
public function serialize($expand = null, array $fields = array(), array $relations = array(), array $params = array() )
|
||||
public function serialize($expand = null, array $fields = [], array $relations = [], array $params = [])
|
||||
{
|
||||
$values = [];
|
||||
$method_prefix = ['get', 'is'];
|
||||
|
@ -0,0 +1,36 @@
|
||||
<?php namespace App\Http\Controllers;
|
||||
/**
|
||||
* Copyright 2019 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.
|
||||
**/
|
||||
use models\exceptions\ValidationException;
|
||||
/**
|
||||
* Class SummitRoomReservationValidationRulesFactory
|
||||
* @package App\Http\Controllers
|
||||
*/
|
||||
final class SummitRoomReservationValidationRulesFactory
|
||||
{
|
||||
/**
|
||||
* @param array $data
|
||||
* @param bool $update
|
||||
* @return array
|
||||
* @throws ValidationException
|
||||
*/
|
||||
public static function build(array $data, $update = false){
|
||||
|
||||
return [
|
||||
'currency' => 'required|string|currency_iso',
|
||||
'amount' => 'required|integer',
|
||||
'start_datetime' => 'required|date_format:U',
|
||||
'end_datetime' => 'required|date_format:U|after:start_datetime',
|
||||
];
|
||||
}
|
||||
}
|
@ -211,6 +211,28 @@ final class OAuth2SummitApiController extends OAuth2ProtectedController
|
||||
}
|
||||
}
|
||||
|
||||
public function getAllSummitByIdOrSlug($id){
|
||||
|
||||
$expand = Request::input('expand', '');
|
||||
|
||||
try {
|
||||
$summit = $this->repository->getById(intval($id));
|
||||
if(is_null($summit))
|
||||
$summit = $this->repository->getBySlug(trim($id));
|
||||
if (is_null($summit)) return $this->error404();
|
||||
$serializer_type = $this->serializer_type_selector->getSerializerType();
|
||||
return $this->ok(SerializerRegistry::getInstance()->getSerializer($summit, $serializer_type)->serialize($expand));
|
||||
}
|
||||
catch(HTTP403ForbiddenException $ex1){
|
||||
Log::warning($ex1);
|
||||
return $this->error403();
|
||||
}
|
||||
catch (Exception $ex) {
|
||||
Log::error($ex);
|
||||
return $this->error500($ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
|
@ -16,8 +16,10 @@ use App\Models\Foundation\Summit\Locations\Banners\SummitLocationBannerConstants
|
||||
use App\Models\Foundation\Summit\Locations\SummitLocationConstants;
|
||||
use App\Models\Foundation\Summit\Repositories\ISummitLocationBannerRepository;
|
||||
use App\Models\Foundation\Summit\Repositories\ISummitLocationRepository;
|
||||
use App\Services\Apis\IPaymentGatewayAPI;
|
||||
use App\Services\Model\ILocationService;
|
||||
use Exception;
|
||||
use Illuminate\Http\Request as LaravelRequest;
|
||||
use Illuminate\Support\Facades\Input;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Facades\Request;
|
||||
@ -25,6 +27,7 @@ use Illuminate\Support\Facades\Validator;
|
||||
use libs\utils\HTMLCleaner;
|
||||
use models\exceptions\EntityNotFoundException;
|
||||
use models\exceptions\ValidationException;
|
||||
use models\main\IMemberRepository;
|
||||
use models\oauth2\IResourceServerContext;
|
||||
use models\summit\IEventFeedbackRepository;
|
||||
use models\summit\ISpeakerRepository;
|
||||
@ -45,9 +48,6 @@ use utils\FilterParserException;
|
||||
use utils\OrderParser;
|
||||
use utils\PagingInfo;
|
||||
use utils\PagingResponse;
|
||||
use Illuminate\Http\Request as LaravelRequest;
|
||||
use utils\ParseMultiPartFormDataInputStream;
|
||||
|
||||
/**
|
||||
* Class OAuth2SummitLocationsApiController
|
||||
* @package App\Http\Controllers
|
||||
@ -79,6 +79,11 @@ final class OAuth2SummitLocationsApiController extends OAuth2ProtectedController
|
||||
*/
|
||||
private $location_repository;
|
||||
|
||||
/**
|
||||
* @var IMemberRepository
|
||||
*/
|
||||
private $member_repository;
|
||||
|
||||
/**
|
||||
* @var ILocationService
|
||||
*/
|
||||
@ -89,6 +94,11 @@ final class OAuth2SummitLocationsApiController extends OAuth2ProtectedController
|
||||
*/
|
||||
private $location_banners_repository;
|
||||
|
||||
/**
|
||||
* @var IPaymentGatewayAPI
|
||||
*/
|
||||
private $payment_gateway;
|
||||
|
||||
/**
|
||||
* OAuth2SummitLocationsApiController constructor.
|
||||
* @param ISummitRepository $summit_repository
|
||||
@ -97,8 +107,10 @@ final class OAuth2SummitLocationsApiController extends OAuth2ProtectedController
|
||||
* @param IEventFeedbackRepository $event_feedback_repository
|
||||
* @param ISummitLocationRepository $location_repository
|
||||
* @param ISummitLocationBannerRepository $location_banners_repository
|
||||
* @param IMemberRepository $member_repository
|
||||
* @param ISummitService $summit_service
|
||||
* @param ILocationService $location_service
|
||||
* @param IPaymentGatewayAPI $payment_gateway
|
||||
* @param IResourceServerContext $resource_server_context
|
||||
*/
|
||||
public function __construct
|
||||
@ -109,19 +121,23 @@ final class OAuth2SummitLocationsApiController extends OAuth2ProtectedController
|
||||
IEventFeedbackRepository $event_feedback_repository,
|
||||
ISummitLocationRepository $location_repository,
|
||||
ISummitLocationBannerRepository $location_banners_repository,
|
||||
IMemberRepository $member_repository,
|
||||
ISummitService $summit_service,
|
||||
ILocationService $location_service,
|
||||
IPaymentGatewayAPI $payment_gateway,
|
||||
IResourceServerContext $resource_server_context
|
||||
) {
|
||||
parent::__construct($resource_server_context);
|
||||
$this->repository = $summit_repository;
|
||||
$this->speaker_repository = $speaker_repository;
|
||||
$this->event_repository = $event_repository;
|
||||
$this->member_repository = $member_repository;
|
||||
$this->event_feedback_repository = $event_feedback_repository;
|
||||
$this->location_repository = $location_repository;
|
||||
$this->location_banners_repository = $location_banners_repository;
|
||||
$this->location_service = $location_service;
|
||||
$this->summit_service = $summit_service;
|
||||
$this->payment_gateway = $payment_gateway;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2211,4 +2227,8 @@ final class OAuth2SummitLocationsApiController extends OAuth2ProtectedController
|
||||
}
|
||||
}
|
||||
|
||||
// bookable rooms
|
||||
|
||||
use SummitBookableVenueRoomApi;
|
||||
|
||||
}
|
@ -0,0 +1,384 @@
|
||||
<?php namespace App\Http\Controllers;
|
||||
/**
|
||||
* Copyright 2019 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.
|
||||
**/
|
||||
use App\Http\Utils\PagingConstants;
|
||||
use Exception;
|
||||
use Illuminate\Support\Facades\Input;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Facades\Request;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use models\exceptions\EntityNotFoundException;
|
||||
use models\exceptions\ValidationException;
|
||||
use models\summit\SummitBookableVenueRoom;
|
||||
use models\summit\SummitBookableVenueRoomAvailableSlot;
|
||||
use ModelSerializers\SerializerRegistry;
|
||||
use utils\Filter;
|
||||
use utils\FilterParser;
|
||||
use utils\OrderParser;
|
||||
use utils\PagingInfo;
|
||||
use utils\PagingResponse;
|
||||
use Illuminate\Http\Request as LaravelRequest;
|
||||
/**
|
||||
* Trait SummitBookableVenueRoomApi
|
||||
* @package App\Http\Controllers
|
||||
*/
|
||||
trait SummitBookableVenueRoomApi
|
||||
{
|
||||
/**
|
||||
* @param $summit_id
|
||||
* @return \Illuminate\Http\JsonResponse|mixed
|
||||
*/
|
||||
public function getBookableVenueRooms($summit_id){
|
||||
$values = Input::all();
|
||||
$rules = [
|
||||
'page' => 'integer|min:1',
|
||||
'per_page' => sprintf('required_with:page|integer|min:%s|max:%s', PagingConstants::MinPageSize, PagingConstants::MaxPageSize),
|
||||
];
|
||||
|
||||
try {
|
||||
|
||||
$summit = $summit_id === 'current' ? $this->repository->getCurrent() : $this->repository->getById(intval($summit_id));
|
||||
if (is_null($summit)) return $this->error404();
|
||||
|
||||
$validation = Validator::make($values, $rules);
|
||||
|
||||
if ($validation->fails()) {
|
||||
$ex = new ValidationException();
|
||||
throw $ex->setMessages($validation->messages()->toArray());
|
||||
}
|
||||
|
||||
// default values
|
||||
$page = 1;
|
||||
$per_page = PagingConstants::DefaultPageSize;
|
||||
|
||||
if (Input::has('page')) {
|
||||
$page = intval(Input::get('page'));
|
||||
$per_page = intval(Input::get('per_page'));
|
||||
}
|
||||
|
||||
$filter = null;
|
||||
|
||||
if (Input::has('filter')) {
|
||||
$filter = FilterParser::parse(Input::get('filter'), [
|
||||
'name' => ['==', '=@'],
|
||||
'description' => ['=@'],
|
||||
'capacity' => ['>', '<', '<=', '>=', '=='],
|
||||
'availability_day' => ['=='],
|
||||
'attribute' => ['=='],
|
||||
]);
|
||||
}
|
||||
if(is_null($filter)) $filter = new Filter();
|
||||
|
||||
$filter->validate([
|
||||
'name' => 'sometimes|string',
|
||||
'description' => 'sometimes|string',
|
||||
'capacity' => 'sometimes|integer',
|
||||
'availability_day' => 'sometimes|date_format:U',
|
||||
'attribute' => 'sometimes|string',
|
||||
]);
|
||||
|
||||
$order = null;
|
||||
|
||||
if (Input::has('order'))
|
||||
{
|
||||
$order = OrderParser::parse(Input::get('order'), [
|
||||
'id',
|
||||
'name',
|
||||
'capacity',
|
||||
]);
|
||||
}
|
||||
|
||||
$filter->addFilterCondition(FilterParser::buildFilter('class_name','==', SummitBookableVenueRoom::ClassName));
|
||||
|
||||
$data = $this->location_repository->getBySummit($summit, new PagingInfo($page, $per_page), $filter, $order);
|
||||
|
||||
return $this->ok
|
||||
(
|
||||
$data->toArray
|
||||
(
|
||||
Request::input('expand', ''),
|
||||
[],
|
||||
[],
|
||||
[]
|
||||
)
|
||||
);
|
||||
}
|
||||
catch (ValidationException $ex1)
|
||||
{
|
||||
Log::warning($ex1);
|
||||
return $this->error412([$ex1->getMessage()]);
|
||||
}
|
||||
catch (EntityNotFoundException $ex2)
|
||||
{
|
||||
Log::warning($ex2);
|
||||
return $this->error404(['message' => $ex2->getMessage()]);
|
||||
}
|
||||
catch(\HTTP401UnauthorizedException $ex3)
|
||||
{
|
||||
Log::warning($ex3);
|
||||
return $this->error401();
|
||||
}
|
||||
catch (Exception $ex) {
|
||||
Log::error($ex);
|
||||
return $this->error500($ex);
|
||||
}
|
||||
}
|
||||
|
||||
public function getBookableVenueRoom($summit_id, $room_id){
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $summit_id
|
||||
* @param $room_id
|
||||
* @param $day
|
||||
* @return \Illuminate\Http\JsonResponse|mixed
|
||||
*/
|
||||
public function getBookableVenueRoomAvailability($summit_id, $room_id, $day){
|
||||
try {
|
||||
$day = intval($day);
|
||||
$summit = $summit_id === 'current' ? $this->repository->getCurrent() : $this->repository->getById(intval($summit_id));
|
||||
if (is_null($summit)) return $this->error404();
|
||||
|
||||
$room = $summit->getLocation($room_id);
|
||||
|
||||
if(!$room instanceof SummitBookableVenueRoom)
|
||||
return $this->error404();
|
||||
|
||||
$slots_definitions = $room->getAvailableSlots(new \DateTime("@$day"));
|
||||
$list = [];
|
||||
foreach($slots_definitions as $slot_label => $is_free){
|
||||
$dates = explode('|', $slot_label);
|
||||
$list[] = new SummitBookableVenueRoomAvailableSlot
|
||||
(
|
||||
$room,
|
||||
$summit->convertDateFromTimeZone2UTC(new \DateTime($dates[0], $summit->getTimeZone())),
|
||||
$summit->convertDateFromTimeZone2UTC(new \DateTime($dates[1], $summit->getTimeZone())),
|
||||
$is_free
|
||||
);
|
||||
}
|
||||
|
||||
$response = new PagingResponse
|
||||
(
|
||||
count($list),
|
||||
count($list),
|
||||
1,
|
||||
1,
|
||||
$list
|
||||
);
|
||||
|
||||
return $this->ok(
|
||||
$response->toArray()
|
||||
);
|
||||
}
|
||||
catch (ValidationException $ex1)
|
||||
{
|
||||
Log::warning($ex1);
|
||||
return $this->error412([$ex1->getMessage()]);
|
||||
}
|
||||
catch (EntityNotFoundException $ex2)
|
||||
{
|
||||
Log::warning($ex2);
|
||||
return $this->error404(['message' => $ex2->getMessage()]);
|
||||
}
|
||||
catch(\HTTP401UnauthorizedException $ex3)
|
||||
{
|
||||
Log::warning($ex3);
|
||||
return $this->error401();
|
||||
}
|
||||
catch (Exception $ex) {
|
||||
Log::error($ex);
|
||||
return $this->error500($ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $summit_id
|
||||
* @param $room_id
|
||||
* @return \Illuminate\Http\JsonResponse|mixed
|
||||
*/
|
||||
public function createBookableVenueRoomReservation($summit_id, $room_id){
|
||||
try {
|
||||
if(!Request::isJson()) return $this->error400();
|
||||
|
||||
$current_member_id = $this->resource_server_context->getCurrentUserExternalId();
|
||||
if (is_null($current_member_id))
|
||||
return $this->error403();
|
||||
|
||||
$summit = $summit_id === 'current' ? $this->repository->getCurrent() : $this->repository->getById(intval($summit_id));
|
||||
if (is_null($summit)) return $this->error404();
|
||||
|
||||
$room = $summit->getLocation($room_id);
|
||||
|
||||
if(!$room instanceof SummitBookableVenueRoom)
|
||||
return $this->error404();
|
||||
|
||||
$payload = Input::json()->all();
|
||||
$payload['owner_id'] = $current_member_id;
|
||||
$rules = SummitRoomReservationValidationRulesFactory::build($payload);
|
||||
// Creates a Validator instance and validates the data.
|
||||
$validation = Validator::make($payload, $rules);
|
||||
|
||||
if ($validation->fails()) {
|
||||
$messages = $validation->messages()->toArray();
|
||||
return $this->error412
|
||||
(
|
||||
$messages
|
||||
);
|
||||
}
|
||||
|
||||
$reservation = $this->location_service->addBookableRoomReservation($summit, $room_id, $payload);
|
||||
|
||||
return $this->created(SerializerRegistry::getInstance()->getSerializer($reservation)->serialize());
|
||||
|
||||
}
|
||||
catch (ValidationException $ex1)
|
||||
{
|
||||
Log::warning($ex1);
|
||||
return $this->error412([$ex1->getMessage()]);
|
||||
}
|
||||
catch (EntityNotFoundException $ex2)
|
||||
{
|
||||
Log::warning($ex2);
|
||||
return $this->error404(['message' => $ex2->getMessage()]);
|
||||
}
|
||||
catch(\HTTP401UnauthorizedException $ex3)
|
||||
{
|
||||
Log::warning($ex3);
|
||||
return $this->error401();
|
||||
}
|
||||
catch (Exception $ex) {
|
||||
Log::error($ex);
|
||||
return $this->error500($ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $summit_id
|
||||
* @return mixed
|
||||
*/
|
||||
public function getMyBookableVenueRoomReservations($summit_id){
|
||||
try{
|
||||
$current_member_id = $this->resource_server_context->getCurrentUserExternalId();
|
||||
if (is_null($current_member_id))
|
||||
return $this->error403();
|
||||
|
||||
$summit = $summit_id === 'current' ? $this->repository->getCurrent() : $this->repository->getById(intval($summit_id));
|
||||
if (is_null($summit)) return $this->error404();
|
||||
|
||||
$member = $this->member_repository->getById($current_member_id);
|
||||
if(is_null($member))
|
||||
return $this->error403();
|
||||
|
||||
$reservations = $member->getReservations()->toArray();
|
||||
|
||||
$response = new PagingResponse
|
||||
(
|
||||
count($reservations),
|
||||
count($reservations),
|
||||
1,
|
||||
1,
|
||||
$reservations
|
||||
);
|
||||
|
||||
return $this->ok(
|
||||
$response->toArray(
|
||||
Request::input('expand', '')
|
||||
)
|
||||
);
|
||||
}
|
||||
catch (ValidationException $ex1)
|
||||
{
|
||||
Log::warning($ex1);
|
||||
return $this->error412([$ex1->getMessage()]);
|
||||
}
|
||||
catch (EntityNotFoundException $ex2)
|
||||
{
|
||||
Log::warning($ex2);
|
||||
return $this->error404(['message' => $ex2->getMessage()]);
|
||||
}
|
||||
catch(\HTTP401UnauthorizedException $ex3)
|
||||
{
|
||||
Log::warning($ex3);
|
||||
return $this->error401();
|
||||
}
|
||||
catch (Exception $ex) {
|
||||
Log::error($ex);
|
||||
return $this->error500($ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $summit_id
|
||||
* @param $reservation_id
|
||||
* @return mixed
|
||||
*/
|
||||
public function cancelMyBookableVenueRoomReservation($summit_id, $reservation_id){
|
||||
try{
|
||||
$current_member_id = $this->resource_server_context->getCurrentUserExternalId();
|
||||
if (is_null($current_member_id))
|
||||
return $this->error403();
|
||||
|
||||
$summit = $summit_id === 'current' ? $this->repository->getCurrent() : $this->repository->getById(intval($summit_id));
|
||||
if (is_null($summit)) return $this->error404();
|
||||
|
||||
$member = $this->member_repository->getById($current_member_id);
|
||||
if(is_null($member))
|
||||
return $this->error403();
|
||||
|
||||
$this->location_service->cancelReservation($summit, $member, $reservation_id);
|
||||
|
||||
return $this->deleted();
|
||||
}
|
||||
catch (ValidationException $ex1)
|
||||
{
|
||||
Log::warning($ex1);
|
||||
return $this->error412([$ex1->getMessage()]);
|
||||
}
|
||||
catch (EntityNotFoundException $ex2)
|
||||
{
|
||||
Log::warning($ex2);
|
||||
return $this->error404(['message' => $ex2->getMessage()]);
|
||||
}
|
||||
catch(\HTTP401UnauthorizedException $ex3)
|
||||
{
|
||||
Log::warning($ex3);
|
||||
return $this->error401();
|
||||
}
|
||||
catch (Exception $ex) {
|
||||
Log::error($ex);
|
||||
return $this->error500($ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param LaravelRequest $request
|
||||
* @return mixed
|
||||
*/
|
||||
public function confirmBookableVenueRoomReservation(LaravelRequest $request){
|
||||
|
||||
if(!Request::isJson())
|
||||
return $this->error400();
|
||||
|
||||
try {
|
||||
$response = $this->payment_gateway->processCallback($request);
|
||||
$this->location_service->processBookableRoomPayment($response);
|
||||
return $this->ok();
|
||||
}
|
||||
catch (Exception $ex){
|
||||
Log::error($ex);
|
||||
return $this->error400(["error" => 'payload error']);
|
||||
}
|
||||
return $this->error400(["error" => 'invalid event type']);
|
||||
}
|
||||
}
|
@ -51,6 +51,15 @@ Route::group([
|
||||
Route::group(['prefix' => 'selection-plans'], function () {
|
||||
Route::get('current/{status}', 'OAuth2SummitSelectionPlansApiController@getCurrentSelectionPlanByStatus')->where('status', 'submission|selection|voting');
|
||||
});
|
||||
|
||||
Route::group(['prefix' => 'bookable-rooms'], function () {
|
||||
Route::group(['prefix' => 'all'], function () {
|
||||
Route::group(['prefix' => 'reservations'], function () {
|
||||
// api/public/v1/summits/all/bookable-rooms/all/reservations/confirm ( open endpoint for payment gateway callbacks)
|
||||
Route::post("confirm", "OAuth2SummitLocationsApiController@confirmBookableVenueRoomReservation");
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Route::group(['prefix' => '{id}'], function () {
|
||||
|
@ -109,11 +109,7 @@ final class PagingResponse
|
||||
$items = [];
|
||||
foreach($this->items as $i)
|
||||
{
|
||||
if($i instanceof IEntity)
|
||||
{
|
||||
$i = SerializerRegistry::getInstance()->getSerializer($i, $serializer_type)->serialize($expand, $fields, $relations, $params);
|
||||
}
|
||||
$items[] = $i;
|
||||
$items[] = SerializerRegistry::getInstance()->getSerializer($i, $serializer_type)->serialize($expand, $fields, $relations, $params);;
|
||||
}
|
||||
|
||||
return
|
||||
|
@ -86,12 +86,15 @@ Route::group([
|
||||
Route::group(array('prefix' => 'summits'), function () {
|
||||
|
||||
Route::get('', [ 'middleware' => 'cache:'.Config::get('cache_api_response.get_summits_response_lifetime', 600), 'uses' => 'OAuth2SummitApiController@getSummits']);
|
||||
|
||||
Route::group(['prefix' => 'all'], function () {
|
||||
Route::get('', [ 'middleware' => 'auth.user:administrators|summit-front-end-administrators|summit-room-administrators', 'uses' => 'OAuth2SummitApiController@getAllSummits']);
|
||||
Route::get('{id}', 'OAuth2SummitApiController@getAllSummitByIdOrSlug');
|
||||
Route::group(['prefix' => 'selection-plans'], function () {
|
||||
Route::get('current/{status}', ['uses' => 'OAuth2SummitSelectionPlansApiController@getCurrentSelectionPlanByStatus'])->where('status', 'submission|selection|voting');
|
||||
});
|
||||
});
|
||||
|
||||
Route::post('', [ 'middleware' => 'auth.user:administrators|summit-front-end-administrators', 'uses' => 'OAuth2SummitApiController@addSummit']);
|
||||
|
||||
Route::group(['prefix' => '{id}'], function () {
|
||||
@ -312,10 +315,43 @@ Route::group([
|
||||
Route::post('', [ 'middleware' => 'auth.user:administrators|summit-front-end-administrators', 'uses' => 'OAuth2SummitLocationsApiController@addLocation']);
|
||||
|
||||
Route::get('metadata', [ 'middleware' => 'auth.user:administrators|summit-front-end-administrators', 'uses' => 'OAuth2SummitLocationsApiController@getMetadata']);
|
||||
|
||||
// bookable-rooms
|
||||
Route::group(['prefix' => 'bookable-rooms'], function () {
|
||||
// GET /api/v1/summits/{id}/bookable-rooms
|
||||
Route::get('', 'OAuth2SummitLocationsApiController@getBookableVenueRooms');
|
||||
|
||||
Route::group(['prefix' => 'all'], function () {
|
||||
Route::group(['prefix' => 'reservations'], function () {
|
||||
// GET /api/v1/summits/{id}/bookable-rooms/all/reservations/me
|
||||
Route::get('me', 'OAuth2SummitLocationsApiController@getMyBookableVenueRoomReservations');
|
||||
Route::group(['prefix' => '{reservation_id}'], function () {
|
||||
// DELETE /api/v1/summits/{id}/bookable-rooms/all/reservations/{reservation_id}
|
||||
Route::delete('', 'OAuth2SummitLocationsApiController@cancelMyBookableVenueRoomReservation');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Route::group(['prefix' => '{room_id}'], function () {
|
||||
// GET /api/v1/summits/{id}/locations/bookable-rooms/{room_id}
|
||||
Route::get('', 'OAuth2SummitLocationsApiController@getBookableVenueRoom');
|
||||
// GET /api/v1/summits/{id}/locations/bookable-rooms/{room_id}/availability/{day}
|
||||
Route::get('availability/{day}', 'OAuth2SummitLocationsApiController@getBookableVenueRoomAvailability');
|
||||
Route::group(['prefix' => 'reservations'], function () {
|
||||
// POST /api/v1/summits/{id}/locations/bookable-rooms/{room_id}/reservations
|
||||
Route::post('', 'OAuth2SummitLocationsApiController@createBookableVenueRoomReservation');
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
// venues
|
||||
|
||||
Route::group(['prefix' => 'venues'], function () {
|
||||
|
||||
Route::get('', 'OAuth2SummitLocationsApiController@getVenues');
|
||||
Route::post('', [ 'middleware' => 'auth.user:administrators|summit-front-end-administrators', 'uses' => 'OAuth2SummitLocationsApiController@addVenue']);
|
||||
|
||||
Route::group(['prefix' => '{venue_id}'], function () {
|
||||
Route::put('', [ 'middleware' => 'auth.user:administrators|summit-front-end-administrators', 'uses' => 'OAuth2SummitLocationsApiController@updateVenue']);
|
||||
|
||||
@ -328,6 +364,20 @@ Route::group([
|
||||
});
|
||||
});
|
||||
|
||||
// bookable-rooms
|
||||
Route::group(['prefix' => 'bookable-rooms'], function () {
|
||||
// POST /api/v1/summits/{id}/locations/venues/{venue_id}/bookable-rooms
|
||||
Route::post('', [ 'middleware' => 'auth.user:administrators|summit-front-end-administrators', 'uses' => 'OAuth2SummitLocationsApiController@addBookableVenueRoom']);
|
||||
Route::group(['prefix' => '{room_id}'], function () {
|
||||
// GET /api/v1/summits/{id}/locations/venues/{venue_id}/bookable-rooms/{room_id}
|
||||
Route::get('', 'OAuth2SummitLocationsApiController@getBookableVenueRoom');
|
||||
// PUT /api/v1/summits/{id}/locations/venues/{venue_id}/bookable-rooms/{room_id}
|
||||
Route::put('', [ 'middleware' => 'auth.user:administrators|summit-front-end-administrators', 'uses' => 'OAuth2SummitLocationsApiController@updateBookableVenueRoom']);
|
||||
// DELETE /api/v1/summits/{id}/locations/venues/{venue_id}/bookable-rooms/{room_id}
|
||||
Route::delete('', [ 'middleware' => 'auth.user:administrators|summit-front-end-administrators', 'uses' => 'OAuth2SummitLocationsApiController@deleteBookableVenueRoom']);
|
||||
});
|
||||
});
|
||||
|
||||
Route::group(['prefix' => 'floors'], function () {
|
||||
Route::post('', [ 'middleware' => 'auth.user:administrators|summit-front-end-administrators', 'uses' => 'OAuth2SummitLocationsApiController@addVenueFloor']);
|
||||
Route::group(['prefix' => '{floor_id}'], function () {
|
||||
|
@ -0,0 +1,25 @@
|
||||
<?php namespace App\ModelSerializers\Locations;
|
||||
/**
|
||||
* Copyright 2019 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.
|
||||
**/
|
||||
use ModelSerializers\SilverStripeSerializer;
|
||||
/**
|
||||
* Class SummitBookableVenueRoomAttributeTypeSerializer
|
||||
* @package App\ModelSerializers\Locations
|
||||
*/
|
||||
class SummitBookableVenueRoomAttributeTypeSerializer extends SilverStripeSerializer
|
||||
{
|
||||
protected static $array_mappings = [
|
||||
'Type' => 'type:json_string',
|
||||
'SummitId' => 'summit_id:json_int',
|
||||
];
|
||||
}
|
@ -0,0 +1,52 @@
|
||||
<?php namespace App\ModelSerializers\Locations;
|
||||
/**
|
||||
* Copyright 2019 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.
|
||||
**/
|
||||
|
||||
use models\summit\SummitBookableVenueRoomAttributeValue;
|
||||
use ModelSerializers\SerializerRegistry;
|
||||
use ModelSerializers\SilverStripeSerializer;
|
||||
/**
|
||||
* Class SummitBookableVenueRoomAttributeValueSerializer
|
||||
* @package App\ModelSerializers\Locations
|
||||
*/
|
||||
class SummitBookableVenueRoomAttributeValueSerializer extends SilverStripeSerializer
|
||||
{
|
||||
protected static $array_mappings = [
|
||||
'Value' => 'value:json_string',
|
||||
'TypeId' => 'type_id:json_int',
|
||||
];
|
||||
|
||||
public function serialize($expand = null, array $fields = array(), array $relations = array(), array $params = array() )
|
||||
{
|
||||
$attr_value = $this->object;
|
||||
if(!$attr_value instanceof SummitBookableVenueRoomAttributeValue)
|
||||
return [];
|
||||
|
||||
$values = parent::serialize($expand, $fields, $relations, $params);
|
||||
|
||||
if (!empty($expand)) {
|
||||
$exp_expand = explode(',', $expand);
|
||||
foreach ($exp_expand as $relation) {
|
||||
switch (trim($relation)) {
|
||||
case 'attribute_type': {
|
||||
unset($values['type_id']);
|
||||
$values['type'] = SerializerRegistry::getInstance()->getSerializer($attr_value->getType())->serialize();
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
return $values;
|
||||
}
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
<?php namespace App\ModelSerializers\Locations;
|
||||
/**
|
||||
* Copyright 2019 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.
|
||||
**/
|
||||
use Libs\ModelSerializers\AbstractSerializer;
|
||||
/**
|
||||
* Class SummitBookableVenueRoomAvailableSlotSerializer
|
||||
* @package App\ModelSerializers\Locations
|
||||
*/
|
||||
final class SummitBookableVenueRoomAvailableSlotSerializer extends AbstractSerializer
|
||||
{
|
||||
protected static $array_mappings = [
|
||||
'StartDate' => 'start_date:datetime_epoch',
|
||||
'EndDate' => 'end_date:datetime_epoch',
|
||||
'LocalStartDate' => 'local_start_date:datetime_epoch',
|
||||
'LocalEndDate' => 'local_end_date:datetime_epoch',
|
||||
'Free' => 'is_free:json_boolean',
|
||||
];
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
<?php namespace App\ModelSerializers\Locations;
|
||||
/**
|
||||
* Copyright 2019 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.
|
||||
**/
|
||||
use models\summit\SummitBookableVenueRoom;
|
||||
use ModelSerializers\Locations\SummitVenueRoomSerializer;
|
||||
use ModelSerializers\SerializerRegistry;
|
||||
/**
|
||||
* Class SummitBookableVenueRoomSerializer
|
||||
* @package App\ModelSerializers\Locations
|
||||
*/
|
||||
class SummitBookableVenueRoomSerializer extends SummitVenueRoomSerializer
|
||||
{
|
||||
protected static $array_mappings = [
|
||||
'TimeSlotCost' => 'time_slot_cost:json_float',
|
||||
'Currency' => 'currency:json_string',
|
||||
];
|
||||
|
||||
public function serialize($expand = null, array $fields = array(), array $relations = array(), array $params = array() )
|
||||
{
|
||||
$room = $this->object;
|
||||
if(!$room instanceof SummitBookableVenueRoom)
|
||||
return [];
|
||||
|
||||
$values = parent::serialize($expand, $fields, $relations, $params);
|
||||
|
||||
$attributes = [];
|
||||
foreach ($room->getAttributes() as $attribute){
|
||||
$attributes[] = SerializerRegistry::getInstance()->getSerializer($attribute)->serialize($expand);
|
||||
}
|
||||
$values['attributes'] = $attributes;
|
||||
return $values;
|
||||
}
|
||||
}
|
@ -0,0 +1,73 @@
|
||||
<?php namespace App\ModelSerializers\Locations;
|
||||
/**
|
||||
* Copyright 2019 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.
|
||||
**/
|
||||
use models\summit\SummitRoomReservation;
|
||||
use ModelSerializers\SerializerRegistry;
|
||||
use ModelSerializers\SilverStripeSerializer;
|
||||
/**
|
||||
* Class SummitRoomReservationSerializer
|
||||
* @package App\ModelSerializers\Locations
|
||||
*/
|
||||
final class SummitRoomReservationSerializer extends SilverStripeSerializer
|
||||
{
|
||||
protected static $array_mappings = [
|
||||
'RoomId' => 'room_id:json_int',
|
||||
'OwnerId' => 'owner_id:json_int',
|
||||
'Amount' => 'amount:json_int',
|
||||
'Currency' => 'currency:json_string',
|
||||
'Status' => 'status:json_string',
|
||||
'StartDatetime' => 'start_datetime:datetime_epoch',
|
||||
'EndDatetime' => 'end_datetime:datetime_epoch',
|
||||
'LocalStartDatetime' => 'local_start_datetime:datetime_epoch',
|
||||
'LocalEndDatetime' => 'local_end_datetime:datetime_epoch',
|
||||
'ApprovedPaymentDate' => 'approved_payment_date:datetime_epoch',
|
||||
'LastError' => 'last_error:json_string',
|
||||
'PaymentGatewayClientToken' => 'payment_gateway_client_token:json_string'
|
||||
];
|
||||
|
||||
/**
|
||||
* @param null $expand
|
||||
* @param array $fields
|
||||
* @param array $relations
|
||||
* @param array $params
|
||||
* @return array
|
||||
*/
|
||||
public function serialize($expand = null, array $fields = [], array $relations = [], array $params = [])
|
||||
{
|
||||
$reservation = $this->object;
|
||||
if(!$reservation instanceof SummitRoomReservation)
|
||||
return [];
|
||||
|
||||
$values = parent::serialize($expand, $fields, $relations, $params);
|
||||
|
||||
if (!empty($expand)) {
|
||||
$exp_expand = explode(',', $expand);
|
||||
foreach ($exp_expand as $relation) {
|
||||
switch (trim($relation)) {
|
||||
case 'room': {
|
||||
unset($values['room_id']);
|
||||
$values['room'] = SerializerRegistry::getInstance()->getSerializer($reservation->getRoom())->serialize($expand);
|
||||
}
|
||||
break;
|
||||
case 'owner': {
|
||||
unset($values['owner_id']);
|
||||
$values['owner'] = SerializerRegistry::getInstance()->getSerializer($reservation->getOwner())->serialize($expand);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $values;
|
||||
}
|
||||
}
|
@ -12,12 +12,11 @@
|
||||
* limitations under the License.
|
||||
**/
|
||||
use ModelSerializers\SerializerRegistry;
|
||||
|
||||
/**
|
||||
* Class SummitVenueRoomSerializer
|
||||
* @package ModelSerializers\Locations
|
||||
*/
|
||||
final class SummitVenueRoomSerializer extends SummitAbstractLocationSerializer
|
||||
class SummitVenueRoomSerializer extends SummitAbstractLocationSerializer
|
||||
{
|
||||
protected static $array_mappings = [
|
||||
'VenueId' => 'venue_id:json_int',
|
||||
|
@ -14,6 +14,11 @@
|
||||
use App\ModelSerializers\CCLA\TeamSerializer;
|
||||
use App\ModelSerializers\FileSerializer;
|
||||
use App\ModelSerializers\LanguageSerializer;
|
||||
use App\ModelSerializers\Locations\SummitBookableVenueRoomAttributeTypeSerializer;
|
||||
use App\ModelSerializers\Locations\SummitBookableVenueRoomAttributeValueSerializer;
|
||||
use App\ModelSerializers\Locations\SummitBookableVenueRoomAvailableSlotSerializer;
|
||||
use App\ModelSerializers\Locations\SummitBookableVenueRoomSerializer;
|
||||
use App\ModelSerializers\Locations\SummitRoomReservationSerializer;
|
||||
use App\ModelSerializers\Marketplace\CloudServiceOfferedSerializer;
|
||||
use App\ModelSerializers\Marketplace\ConfigurationManagementTypeSerializer;
|
||||
use App\ModelSerializers\Marketplace\ConsultantClientSerializer;
|
||||
@ -191,15 +196,20 @@ final class SerializerRegistry
|
||||
$this->registry['SponsorSummitRegistrationPromoCode'] = SponsorSummitRegistrationPromoCodeSerializer::class;
|
||||
$this->registry['PresentationSpeakerSummitAssistanceConfirmationRequest'] = PresentationSpeakerSummitAssistanceConfirmationRequestSerializer::class;
|
||||
// locations
|
||||
$this->registry['SummitVenue'] = SummitVenueSerializer::class;
|
||||
$this->registry['SummitVenueRoom'] = SummitVenueRoomSerializer::class;
|
||||
$this->registry['SummitVenueFloor'] = SummitVenueFloorSerializer::class;
|
||||
$this->registry['SummitExternalLocation'] = SummitExternalLocationSerializer::class;
|
||||
$this->registry['SummitHotel'] = SummitHotelSerializer::class;
|
||||
$this->registry['SummitAirport'] = SummitAirportSerializer::class;
|
||||
$this->registry['SummitLocationImage'] = SummitLocationImageSerializer::class;
|
||||
$this->registry['SummitLocationBanner'] = SummitLocationBannerSerializer::class;
|
||||
$this->registry['ScheduledSummitLocationBanner'] = ScheduledSummitLocationBannerSerializer::class;
|
||||
$this->registry['SummitVenue'] = SummitVenueSerializer::class;
|
||||
$this->registry['SummitVenueRoom'] = SummitVenueRoomSerializer::class;
|
||||
$this->registry['SummitVenueFloor'] = SummitVenueFloorSerializer::class;
|
||||
$this->registry['SummitExternalLocation'] = SummitExternalLocationSerializer::class;
|
||||
$this->registry['SummitHotel'] = SummitHotelSerializer::class;
|
||||
$this->registry['SummitAirport'] = SummitAirportSerializer::class;
|
||||
$this->registry['SummitLocationImage'] = SummitLocationImageSerializer::class;
|
||||
$this->registry['SummitLocationBanner'] = SummitLocationBannerSerializer::class;
|
||||
$this->registry['ScheduledSummitLocationBanner'] = ScheduledSummitLocationBannerSerializer::class;
|
||||
$this->registry['SummitBookableVenueRoom'] = SummitBookableVenueRoomSerializer::class;
|
||||
$this->registry['SummitBookableVenueRoomAttributeType'] = SummitBookableVenueRoomAttributeTypeSerializer::class;
|
||||
$this->registry['SummitBookableVenueRoomAttributeValue'] = SummitBookableVenueRoomAttributeValueSerializer::class;
|
||||
$this->registry['SummitBookableVenueRoomAvailableSlot'] = SummitBookableVenueRoomAvailableSlotSerializer::class;
|
||||
$this->registry['SummitRoomReservation'] = SummitRoomReservationSerializer::class;
|
||||
|
||||
// track tag groups
|
||||
$this->registry['TrackTagGroup'] = TrackTagGroupSerializer::class;
|
||||
|
@ -52,6 +52,10 @@ class SummitSerializer extends SilverStripeSerializer
|
||||
'SecondaryRegistrationLink' => 'secondary_registration_link:json_string',
|
||||
'SecondaryRegistrationLabel' => 'secondary_registration_label:json_string',
|
||||
'RawSlug' => 'slug:json_string',
|
||||
'MeetingRoomBookingStartTime' => 'meeting_room_booking_start_time:datetime_epoch',
|
||||
'MeetingRoomBookingEndTime' => 'meeting_room_booking_end_time:datetime_epoch',
|
||||
'MeetingRoomBookingSlotLength' => 'meeting_room_booking_slot_length:json_int',
|
||||
'MeetingRoomBookingMaxAllowed' => 'meeting_room_booking_max_allowed:json_int',
|
||||
];
|
||||
|
||||
protected static $allowed_relations = [
|
||||
@ -59,6 +63,7 @@ class SummitSerializer extends SilverStripeSerializer
|
||||
'locations',
|
||||
'wifi_connections',
|
||||
'selection_plans',
|
||||
'meeting_booking_room_allowed_attributes',
|
||||
];
|
||||
|
||||
/**
|
||||
@ -110,7 +115,16 @@ class SummitSerializer extends SilverStripeSerializer
|
||||
$values['ticket_types'] = $ticket_types;
|
||||
}
|
||||
|
||||
//locations
|
||||
// meeting_booking_room_allowed_attributes
|
||||
if(in_array('meeting_booking_room_allowed_attributes', $relations)) {
|
||||
$meeting_booking_room_allowed_attributes = [];
|
||||
foreach ($summit->getMeetingBookingRoomAllowedAttributes() as $attr) {
|
||||
$meeting_booking_room_allowed_attributes[] = SerializerRegistry::getInstance()->getSerializer($attr)->serialize($expand);
|
||||
}
|
||||
$values['meeting_booking_room_allowed_attributes'] = $meeting_booking_room_allowed_attributes;
|
||||
}
|
||||
|
||||
// locations
|
||||
if(in_array('locations', $relations)) {
|
||||
$locations = [];
|
||||
foreach ($summit->getLocations() as $location) {
|
||||
|
@ -24,6 +24,7 @@ use models\summit\RSVP;
|
||||
use models\summit\Summit;
|
||||
use models\summit\SummitEvent;
|
||||
use models\summit\SummitEventFeedback;
|
||||
use models\summit\SummitRoomReservation;
|
||||
use models\utils\SilverstripeBaseModel;
|
||||
use Doctrine\ORM\Mapping AS ORM;
|
||||
/**
|
||||
@ -207,6 +208,12 @@ class Member extends SilverstripeBaseModel
|
||||
*/
|
||||
private $favorites;
|
||||
|
||||
/**
|
||||
* @ORM\OneToMany(targetEntity="models\summit\SummitRoomReservation", mappedBy="owner", cascade={"persist"}, orphanRemoval=true)
|
||||
* @var ArrayCollection
|
||||
*/
|
||||
private $reservations;
|
||||
|
||||
/**
|
||||
* Member constructor.
|
||||
*/
|
||||
@ -223,6 +230,7 @@ class Member extends SilverstripeBaseModel
|
||||
$this->rsvp = new ArrayCollection();
|
||||
$this->calendars_sync = new ArrayCollection();
|
||||
$this->schedule_sync_info = new ArrayCollection();
|
||||
$this->reservations = new ArrayCollection();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1123,4 +1131,33 @@ SQL;
|
||||
}
|
||||
return $photoUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param SummitRoomReservation $reservation
|
||||
* @return $this
|
||||
*/
|
||||
public function addReservation(SummitRoomReservation $reservation){
|
||||
if($this->reservations->contains($reservation)) return $this;
|
||||
$this->reservations->add($reservation);
|
||||
$reservation->setOwner($this);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ArrayCollection
|
||||
*/
|
||||
public function getReservations(){
|
||||
return $this->reservations;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $reservation_id
|
||||
* @return SummitRoomReservation
|
||||
*/
|
||||
public function getReservationById(int $reservation_id): ?SummitRoomReservation {
|
||||
$criteria = Criteria::create()
|
||||
->where(Criteria::expr()->eq("id", $reservation_id));
|
||||
|
||||
return $this->reservations->matching($criteria)->first();
|
||||
}
|
||||
}
|
@ -0,0 +1,53 @@
|
||||
<?php namespace App\Models\Foundation\Summit\Factories;
|
||||
/**
|
||||
* Copyright 2019 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.
|
||||
**/
|
||||
use models\summit\Summit;
|
||||
use models\summit\SummitRoomReservation;
|
||||
/**
|
||||
* Class SummitRoomReservationFactory
|
||||
* @package App\Models\Foundation\Summit\Factories
|
||||
*/
|
||||
final class SummitRoomReservationFactory
|
||||
{
|
||||
/**
|
||||
* @param Summit $summit
|
||||
* @param array $data
|
||||
* @return SummitRoomReservation
|
||||
*/
|
||||
public static function build(Summit $summit, array $data){
|
||||
$reservation = new SummitRoomReservation;
|
||||
if(isset($data['owner']))
|
||||
$reservation->setOwner($data['owner']);
|
||||
if(isset($data['currency']))
|
||||
$reservation->setCurrency(trim($data['currency']));
|
||||
if(isset($data['amount']))
|
||||
$reservation->setAmount(floatval($data['amount']));
|
||||
|
||||
// dates ( they came on local time epoch , so must be converted to utc using
|
||||
// summit timezone
|
||||
if(isset($data['start_datetime'])) {
|
||||
$val = intval($data['start_datetime']);
|
||||
$val = new \DateTime("@$val", $summit->getTimeZone());
|
||||
$reservation->setStartDatetime($summit->convertDateFromTimeZone2UTC($val));
|
||||
}
|
||||
|
||||
if(isset($data['end_datetime'])){
|
||||
$val = intval($data['end_datetime']);
|
||||
$val = new \DateTime("@$val", $summit->getTimeZone());
|
||||
$reservation->setEndDatetime($summit->convertDateFromTimeZone2UTC($val));
|
||||
}
|
||||
|
||||
return $reservation;
|
||||
}
|
||||
|
||||
}
|
@ -40,7 +40,16 @@ use Doctrine\ORM\Mapping AS ORM;
|
||||
* @ORM\Table(name="SummitAbstractLocation")
|
||||
* @ORM\InheritanceType("JOINED")
|
||||
* @ORM\DiscriminatorColumn(name="ClassName", type="string")
|
||||
* @ORM\DiscriminatorMap({"SummitAbstractLocation" = "SummitAbstractLocation", "SummitGeoLocatedLocation" = "SummitGeoLocatedLocation", "SummitExternalLocation" = "SummitExternalLocation", "SummitVenue" = "SummitVenue", "SummitHotel" = "SummitHotel", "SummitAirport" = "SummitAirport", "SummitVenueRoom" = "SummitVenueRoom"})
|
||||
* @ORM\DiscriminatorMap({
|
||||
* "SummitAbstractLocation" = "SummitAbstractLocation",
|
||||
* "SummitGeoLocatedLocation" = "SummitGeoLocatedLocation",
|
||||
* "SummitExternalLocation" = "SummitExternalLocation",
|
||||
* "SummitVenue" = "SummitVenue",
|
||||
* "SummitHotel" = "SummitHotel",
|
||||
* "SummitAirport" = "SummitAirport",
|
||||
* "SummitVenueRoom" = "SummitVenueRoom",
|
||||
* "SummitBookableVenueRoom" = "SummitBookableVenueRoom"
|
||||
* })
|
||||
* Class SummitAbstractLocation
|
||||
* @package models\summit
|
||||
*/
|
||||
|
@ -0,0 +1,280 @@
|
||||
<?php namespace models\summit;
|
||||
/**
|
||||
* Copyright 2019 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.
|
||||
**/
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
use Doctrine\Common\Collections\Criteria;
|
||||
use Doctrine\ORM\Mapping AS ORM;
|
||||
use models\exceptions\ValidationException;
|
||||
/**
|
||||
* @ORM\Entity
|
||||
* @ORM\Table(name="SummitBookableVenueRoom")
|
||||
* Class SummitBookableVenueRoom
|
||||
* @package models\summit
|
||||
*/
|
||||
class SummitBookableVenueRoom extends SummitVenueRoom
|
||||
{
|
||||
|
||||
const ClassName = 'SummitBookableVenueRoom';
|
||||
|
||||
/**
|
||||
* @ORM\Column(name="TimeSlotCost", type="decimal")
|
||||
* @var float
|
||||
*/
|
||||
private $time_slot_cost;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
* @ORM\Column(name="Currency", type="string")
|
||||
*/
|
||||
private $currency;
|
||||
|
||||
/**
|
||||
* @ORM\OneToMany(targetEntity="models\summit\SummitRoomReservation", mappedBy="room", cascade={"persist"}, orphanRemoval=true)
|
||||
* @var ArrayCollection
|
||||
*/
|
||||
private $reservations;
|
||||
|
||||
/**
|
||||
* @ORM\ManyToMany(targetEntity="models\summit\SummitBookableVenueRoomAttributeValue")
|
||||
* @ORM\JoinTable(name="SummitBookableVenueRoom_Attributes",
|
||||
* joinColumns={@ORM\JoinColumn(name="SummitBookableVenueRoomID", referencedColumnName="ID")},
|
||||
* inverseJoinColumns={@ORM\JoinColumn(name="SummitBookableVenueRoomAttributeValueID", referencedColumnName="ID", unique=true)}
|
||||
* )
|
||||
*/
|
||||
private $attributes;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->reservations = new ArrayCollection();
|
||||
$this->attributes = new ArrayCollection();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param SummitRoomReservation $reservation
|
||||
* @return $this
|
||||
* @throws ValidationException
|
||||
*/
|
||||
public function addReservation(SummitRoomReservation $reservation){
|
||||
$criteria = Criteria::create();
|
||||
|
||||
$start_date = $reservation->getStartDatetime();
|
||||
$end_date = $reservation->getEndDatetime();
|
||||
|
||||
$criteria
|
||||
->where(Criteria::expr()->eq('start_datetime', $start_date))
|
||||
->andWhere(Criteria::expr()->eq('end_datetime',$end_date))
|
||||
->andWhere(Criteria::expr()->notIn("status", [SummitRoomReservation::RequestedRefundStatus, SummitRoomReservation::RefundedStatus]));
|
||||
|
||||
if($this->reservations->matching($criteria)->count() > 0)
|
||||
throw new ValidationException(sprintf("reservation overlaps an existent reservation"));
|
||||
|
||||
$criteria
|
||||
->where(Criteria::expr()->lte('start_datetime', $end_date))
|
||||
->andWhere(Criteria::expr()->gte('end_datetime', $start_date))
|
||||
->andWhere(Criteria::expr()->notIn("status", [SummitRoomReservation::RequestedRefundStatus, SummitRoomReservation::RefundedStatus]));
|
||||
|
||||
if($this->reservations->matching($criteria)->count() > 0)
|
||||
throw new ValidationException(sprintf("reservation overlaps an existent reservation"));
|
||||
|
||||
$summit = $this->summit;
|
||||
|
||||
$local_start_date = $summit->convertDateFromUTC2TimeZone($start_date);
|
||||
$local_end_date = $summit->convertDateFromUTC2TimeZone($end_date);
|
||||
$start_time = $summit->getMeetingRoomBookingStartTime();
|
||||
$end_time = $summit->getMeetingRoomBookingEndTime();
|
||||
|
||||
if(!$summit->isTimeFrameInsideSummitDuration($local_start_date, $local_end_date))
|
||||
throw new ValidationException("requested reservation period does not belong to summit period");
|
||||
$local_start_time = new \DateTime("now", $this->summit->getTimeZone());
|
||||
$local_start_time->setTime(
|
||||
intval($start_time->format("H")),
|
||||
intval($start_time->format("i")),
|
||||
intval($start_time->format("s"))
|
||||
);
|
||||
|
||||
$local_end_time = new \DateTime("now", $this->summit->getTimeZone());
|
||||
$local_end_time->setTime(
|
||||
intval($end_time->format("H")),
|
||||
intval($end_time->format("i")),
|
||||
intval($end_time->format("s"))
|
||||
);
|
||||
|
||||
$local_start_time->setDate
|
||||
(
|
||||
intval($start_date->format("Y")),
|
||||
intval($start_date->format("m")),
|
||||
intval($start_date->format("d"))
|
||||
);
|
||||
|
||||
$local_end_time->setDate
|
||||
(
|
||||
intval($start_date->format("Y")),
|
||||
intval($start_date->format("m")),
|
||||
intval($start_date->format("d"))
|
||||
);
|
||||
|
||||
if(!($local_start_time <= $local_start_date
|
||||
&& $local_end_date <= $local_end_time))
|
||||
throw new ValidationException("requested booking time slot is not allowed!");
|
||||
|
||||
$interval = $end_date->diff($start_date);
|
||||
$minutes = ($interval->d * 24 * 60) + ($interval->h * 60) + $interval->i;
|
||||
if($minutes != $summit->getMeetingRoomBookingSlotLength())
|
||||
throw new ValidationException("requested booking time slot is not allowed!");
|
||||
|
||||
$this->reservations->add($reservation);
|
||||
$reservation->setRoom($this);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return float
|
||||
*/
|
||||
public function getTimeSlotCost(): float
|
||||
{
|
||||
return floatval($this->time_slot_cost);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param float $time_slot_cost
|
||||
*/
|
||||
public function setTimeSlotCost(float $time_slot_cost): void
|
||||
{
|
||||
$this->time_slot_cost = $time_slot_cost;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ArrayCollection
|
||||
*/
|
||||
public function getReservations(): ArrayCollection
|
||||
{
|
||||
return $this->reservations;
|
||||
}
|
||||
|
||||
public function clearReservations(){
|
||||
$this->reservations->clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getClassName()
|
||||
{
|
||||
return self::ClassName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \DateTime $day should be on local summit day
|
||||
* @return array
|
||||
* @throws ValidationException
|
||||
*/
|
||||
public function getAvailableSlots(\DateTime $day):array{
|
||||
$availableSlots = [];
|
||||
$summit = $this->summit;
|
||||
$day = $day->setTimezone($summit->getTimeZone())->setTime(0, 0,0);
|
||||
$booking_start_time = $summit->getMeetingRoomBookingStartTime();
|
||||
if(is_null($booking_start_time))
|
||||
throw new ValidationException("MeetingRoomBookingStartTime is null!");
|
||||
|
||||
$booking_end_time = $summit->getMeetingRoomBookingEndTime();
|
||||
if(is_null($booking_end_time))
|
||||
throw new ValidationException("MeetingRoomBookingEndTime is null!");
|
||||
|
||||
$booking_slot_len = $summit->getMeetingRoomBookingSlotLength();
|
||||
$start_datetime = clone $day;
|
||||
$end_datetime = clone $day;
|
||||
|
||||
$start_datetime->setTime(
|
||||
intval($booking_start_time->format("H")),
|
||||
intval($booking_start_time->format("i")),
|
||||
0);
|
||||
$start_datetime->setTimezone($summit->getTimeZone());
|
||||
|
||||
$end_datetime->setTime(
|
||||
intval($booking_end_time->format("H")),
|
||||
intval($booking_end_time->format("i")),
|
||||
00);
|
||||
$end_datetime->setTimezone($summit->getTimeZone());
|
||||
$criteria = Criteria::create();
|
||||
if(!$summit->isTimeFrameInsideSummitDuration($start_datetime, $end_datetime))
|
||||
throw new ValidationException("requested day does not belong to summit period");
|
||||
|
||||
$criteria
|
||||
->where(Criteria::expr()->gte('start_datetime', $summit->convertDateFromTimeZone2UTC($start_datetime)))
|
||||
->andWhere(Criteria::expr()->lte('end_datetime', $summit->convertDateFromTimeZone2UTC($end_datetime)))
|
||||
->andWhere(Criteria::expr()->notIn("status", [SummitRoomReservation::RequestedRefundStatus, SummitRoomReservation::RefundedStatus]));
|
||||
|
||||
$reservations = $this->reservations->matching($criteria);
|
||||
|
||||
while($start_datetime <= $end_datetime) {
|
||||
$current_time_slot_end = clone $start_datetime;
|
||||
$current_time_slot_end->add(new \DateInterval("PT" . $booking_slot_len . 'M'));
|
||||
if($current_time_slot_end<=$end_datetime)
|
||||
$availableSlots[$start_datetime->format('Y-m-d H:i:s').'|'.$current_time_slot_end->format('Y-m-d H:i:s')] = true;
|
||||
$start_datetime = $current_time_slot_end;
|
||||
}
|
||||
|
||||
foreach ($reservations as $reservation){
|
||||
if(!$reservation instanceof SummitRoomReservation) continue;
|
||||
$availableSlots[
|
||||
$summit->convertDateFromUTC2TimeZone($reservation->getStartDatetime())->format("Y-m-d H:i:s")
|
||||
.'|'.
|
||||
$summit->convertDateFromUTC2TimeZone($reservation->getEndDatetime())->format("Y-m-d H:i:s")
|
||||
] = false;
|
||||
}
|
||||
|
||||
return $availableSlots;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \DateTime $day
|
||||
* @return array
|
||||
* @throws ValidationException
|
||||
*/
|
||||
public function getFreeSlots(\DateTime $day):array{
|
||||
$slots = $this->getAvailableSlots($day);
|
||||
$free_slots = [];
|
||||
foreach ($slots as $label => $status){
|
||||
if(!$status) continue;
|
||||
$free_slots[] = $label;
|
||||
}
|
||||
return $free_slots;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getCurrency(): string
|
||||
{
|
||||
return $this->currency;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $currency
|
||||
*/
|
||||
public function setCurrency(string $currency): void
|
||||
{
|
||||
$this->currency = $currency;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getAttributes()
|
||||
{
|
||||
return $this->attributes;
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,85 @@
|
||||
<?php namespace models\summit;
|
||||
/**
|
||||
* Copyright 2019 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.
|
||||
**/
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
use Doctrine\Common\Collections\Criteria;
|
||||
use Doctrine\ORM\Mapping AS ORM;
|
||||
use models\exceptions\ValidationException;
|
||||
use models\summit\SummitOwned;
|
||||
use models\utils\SilverstripeBaseModel;
|
||||
/**
|
||||
* @ORM\Entity
|
||||
* @ORM\Table(name="SummitBookableVenueRoomAttributeType")
|
||||
* @ORM\AssociationOverrides({
|
||||
* @ORM\AssociationOverride(
|
||||
* name="summit",
|
||||
* inversedBy="booking_room_allowed_attributes"
|
||||
* )
|
||||
* })
|
||||
* Class SummitBookableVenueRoomAttributeType
|
||||
* @package models\summit
|
||||
*/
|
||||
class SummitBookableVenueRoomAttributeType extends SilverstripeBaseModel
|
||||
{
|
||||
/**
|
||||
* @ORM\Column(name="Type", type="string")
|
||||
* @var string
|
||||
*/
|
||||
private $type;
|
||||
|
||||
use SummitOwned;
|
||||
|
||||
/**
|
||||
* @ORM\OneToMany(targetEntity="models\summit\SummitBookableVenueRoomAttributeValue", mappedBy="type", cascade={"persist"}, orphanRemoval=true)
|
||||
* @var ArrayCollection
|
||||
*/
|
||||
private $values;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->values = new ArrayCollection();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getType(): string
|
||||
{
|
||||
return $this->type;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $type
|
||||
*/
|
||||
public function setType(string $type): void
|
||||
{
|
||||
$this->type = $type;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ArrayCollection
|
||||
*/
|
||||
public function getValues(): ArrayCollection
|
||||
{
|
||||
return $this->values;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ArrayCollection $values
|
||||
*/
|
||||
public function setValues(ArrayCollection $values): void
|
||||
{
|
||||
$this->values = $values;
|
||||
}
|
||||
}
|
@ -0,0 +1,84 @@
|
||||
<?php namespace models\summit;
|
||||
/**
|
||||
* Copyright 2019 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.
|
||||
**/
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
use Doctrine\Common\Collections\Criteria;
|
||||
use Doctrine\ORM\Mapping AS ORM;
|
||||
use models\exceptions\ValidationException;
|
||||
use models\utils\SilverstripeBaseModel;
|
||||
/**
|
||||
* @ORM\Entity
|
||||
* @ORM\Table(name="SummitBookableVenueRoomAttributeValue")
|
||||
* Class SummitBookableVenueRoomAttributeValue
|
||||
* @package models\summit
|
||||
*/
|
||||
class SummitBookableVenueRoomAttributeValue extends SilverstripeBaseModel
|
||||
{
|
||||
/**
|
||||
* @ORM\Column(name="Value", type="string")
|
||||
* @var string
|
||||
*/
|
||||
private $value;
|
||||
|
||||
/**
|
||||
* @ORM\ManyToOne(targetEntity="models\summit\SummitBookableVenueRoomAttributeType", inversedBy="values")
|
||||
* @ORM\JoinColumn(name="TypeID", referencedColumnName="ID")
|
||||
* @var SummitBookableVenueRoomAttributeType
|
||||
*/
|
||||
private $type;
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getValue(): string
|
||||
{
|
||||
return $this->value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $value
|
||||
*/
|
||||
public function setValue(string $value): void
|
||||
{
|
||||
$this->value = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return SummitBookableVenueRoomAttributeType
|
||||
*/
|
||||
public function getType(): SummitBookableVenueRoomAttributeType
|
||||
{
|
||||
return $this->type;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param SummitBookableVenueRoomAttributeType $type
|
||||
*/
|
||||
public function setType(SummitBookableVenueRoomAttributeType $type): void
|
||||
{
|
||||
$this->type = $type;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getTypeId():int{
|
||||
try {
|
||||
return is_null($this->type) ? 0 : $this->type->getId();
|
||||
}
|
||||
catch(\Exception $ex){
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,88 @@
|
||||
<?php namespace models\summit;
|
||||
/**
|
||||
* Copyright 2019 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.
|
||||
**/
|
||||
final class SummitBookableVenueRoomAvailableSlot
|
||||
{
|
||||
/**
|
||||
* @var \DateTime
|
||||
*/
|
||||
private $start_date;
|
||||
|
||||
/**
|
||||
* @var \DateTime
|
||||
*/
|
||||
private $end_date;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $is_free;
|
||||
|
||||
/**
|
||||
* @var SummitBookableVenueRoom
|
||||
*/
|
||||
private $room;
|
||||
|
||||
/**
|
||||
* SummitBookableVenueRoomAvailableSlot constructor.
|
||||
* @param SummitBookableVenueRoom $room
|
||||
* @param \DateTime $start_date
|
||||
* @param \DateTime $end_date
|
||||
* @param bool $is_free
|
||||
*/
|
||||
public function __construct(SummitBookableVenueRoom $room, \DateTime $start_date, \DateTime $end_date, bool $is_free)
|
||||
{
|
||||
|
||||
$this->room = $room;
|
||||
$this->start_date = $start_date;
|
||||
$this->end_date = $end_date;
|
||||
$this->is_free = $is_free;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \DateTime
|
||||
*/
|
||||
public function getStartDate(): \DateTime
|
||||
{
|
||||
return $this->start_date;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \DateTime
|
||||
*/
|
||||
public function getEndDate(): \DateTime
|
||||
{
|
||||
return $this->end_date;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \DateTime
|
||||
*/
|
||||
public function getLocalStartDate(): \DateTime
|
||||
{
|
||||
return $this->room->getSummit()->convertDateFromUTC2TimeZone($this->start_date);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \DateTime
|
||||
*/
|
||||
public function getLocalEndDate(): \DateTime
|
||||
{
|
||||
return $this->room->getSummit()->convertDateFromUTC2TimeZone($this->end_date);
|
||||
}
|
||||
|
||||
public function isFree():bool{
|
||||
return $this->is_free;
|
||||
}
|
||||
|
||||
}
|
329
app/Models/Foundation/Summit/Locations/SummitRoomReservation.php
Normal file
329
app/Models/Foundation/Summit/Locations/SummitRoomReservation.php
Normal file
@ -0,0 +1,329 @@
|
||||
<?php namespace models\summit;
|
||||
/**
|
||||
* Copyright 2019 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.
|
||||
**/
|
||||
use Doctrine\ORM\Mapping AS ORM;
|
||||
use models\main\Member;
|
||||
use models\utils\SilverstripeBaseModel;
|
||||
/**
|
||||
* @ORM\Entity(repositoryClass="App\Repositories\Summit\DoctrineSummitRoomReservationRepository")
|
||||
* @ORM\Table(name="SummitRoomReservation")
|
||||
* Class SummitRoomReservation
|
||||
* @package models\summit
|
||||
*/
|
||||
class SummitRoomReservation extends SilverstripeBaseModel
|
||||
{
|
||||
/**
|
||||
* @var \DateTime
|
||||
* @ORM\Column(name="StartDateTime", type="datetime")
|
||||
*/
|
||||
private $start_datetime;
|
||||
|
||||
/**
|
||||
* @var \DateTime
|
||||
* @ORM\Column(name="EndDateTime", type="datetime")
|
||||
*/
|
||||
private $end_datetime;
|
||||
|
||||
/**
|
||||
* @var \DateTime
|
||||
* @ORM\Column(name="ApprovedPaymentDate", type="datetime")
|
||||
*/
|
||||
private $approved_payment_date;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
* @ORM\Column(name="Status", type="string")
|
||||
*/
|
||||
private $status;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
* @ORM\Column(name="LastError", type="string")
|
||||
*/
|
||||
private $last_error;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
* @ORM\Column(name="PaymentGatewayCartId", type="string")
|
||||
*/
|
||||
private $payment_gateway_cart_id;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $payment_gateway_client_token;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
* @ORM\Column(name="Currency", type="string")
|
||||
*/
|
||||
private $currency;
|
||||
|
||||
/**
|
||||
* @var float
|
||||
* @ORM\Column(name="Amount", type="float")
|
||||
*/
|
||||
private $amount;
|
||||
|
||||
/**
|
||||
* @ORM\ManyToOne(targetEntity="models\main\Member", inversedBy="reservations")
|
||||
* @ORM\JoinColumn(name="OwnerID", referencedColumnName="ID")
|
||||
* @var Member
|
||||
*/
|
||||
private $owner;
|
||||
|
||||
/**
|
||||
* @ORM\ManyToOne(targetEntity="models\summit\SummitBookableVenueRoom", inversedBy="reservations")
|
||||
* @ORM\JoinColumn(name="RoomID", referencedColumnName="ID")
|
||||
* @var SummitBookableVenueRoom
|
||||
*/
|
||||
private $room;
|
||||
|
||||
const ReservedStatus = "Reserved";
|
||||
const ErrorStatus = "Error";
|
||||
const PayedStatus = "Payed";
|
||||
const RequestedRefundStatus = "RequestedRefund";
|
||||
const RefundedStatus = "Refunded";
|
||||
|
||||
public static $valid_status = [
|
||||
self::ReservedStatus,
|
||||
self::PayedStatus,
|
||||
self::RequestedRefundStatus,
|
||||
self::RefundedStatus,
|
||||
self::ErrorStatus,
|
||||
];
|
||||
|
||||
/**
|
||||
* @return \DateTime
|
||||
*/
|
||||
public function getStartDatetime(): \DateTime
|
||||
{
|
||||
return $this->start_datetime;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \DateTime
|
||||
*/
|
||||
public function getLocalStartDatetime(): \DateTime
|
||||
{
|
||||
return $this->room->getSummit()->convertDateFromUTC2TimeZone($this->start_datetime);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \DateTime $start_datetime
|
||||
*/
|
||||
public function setStartDatetime(\DateTime $start_datetime): void
|
||||
{
|
||||
$this->start_datetime = $start_datetime;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \DateTime
|
||||
*/
|
||||
public function getEndDatetime(): \DateTime
|
||||
{
|
||||
return $this->end_datetime;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \DateTime
|
||||
*/
|
||||
public function getLocalEndDatetime(): \DateTime
|
||||
{
|
||||
return $this->room->getSummit()->convertDateFromUTC2TimeZone($this->end_datetime);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \DateTime $end_datetime
|
||||
*/
|
||||
public function setEndDatetime(\DateTime $end_datetime): void
|
||||
{
|
||||
$this->end_datetime = $end_datetime;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getStatus(): string
|
||||
{
|
||||
return $this->status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $status
|
||||
*/
|
||||
public function setStatus(string $status): void
|
||||
{
|
||||
$this->status = $status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Member
|
||||
*/
|
||||
public function getOwner(): Member
|
||||
{
|
||||
return $this->owner;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Member $owner
|
||||
*/
|
||||
public function setOwner(Member $owner): void
|
||||
{
|
||||
$this->owner = $owner;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return SummitBookableVenueRoom
|
||||
*/
|
||||
public function getRoom(): SummitBookableVenueRoom
|
||||
{
|
||||
return $this->room;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param SummitBookableVenueRoom $room
|
||||
*/
|
||||
public function setRoom(SummitBookableVenueRoom $room): void
|
||||
{
|
||||
$this->room = $room;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getPaymentGatewayCartId(): string
|
||||
{
|
||||
return $this->payment_gateway_cart_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $payment_gateway_cart_id
|
||||
*/
|
||||
public function setPaymentGatewayCartId(string $payment_gateway_cart_id): void
|
||||
{
|
||||
$this->payment_gateway_cart_id = $payment_gateway_cart_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \DateTime|null
|
||||
*/
|
||||
public function getApprovedPaymentDate(): ?\DateTime
|
||||
{
|
||||
return $this->approved_payment_date;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \DateTime $approved_payment_date
|
||||
*/
|
||||
public function setApprovedPaymentDate(\DateTime $approved_payment_date): void
|
||||
{
|
||||
$this->approved_payment_date = $approved_payment_date;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getCurrency(): string
|
||||
{
|
||||
return $this->currency;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $currency
|
||||
*/
|
||||
public function setCurrency(string $currency): void
|
||||
{
|
||||
$this->currency = $currency;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return float
|
||||
*/
|
||||
public function getAmount(): float
|
||||
{
|
||||
return $this->amount;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param float $amount
|
||||
*/
|
||||
public function setAmount(float $amount): void
|
||||
{
|
||||
$this->amount = $amount;
|
||||
}
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->amount = 0.0;
|
||||
$this->status = self::ReservedStatus;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string|null
|
||||
*/
|
||||
public function getPaymentGatewayClientToken(): ?string
|
||||
{
|
||||
return $this->payment_gateway_client_token;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $payment_gateway_client_token
|
||||
*/
|
||||
public function setPaymentGatewayClientToken(string $payment_gateway_client_token): void
|
||||
{
|
||||
$this->payment_gateway_client_token = $payment_gateway_client_token;
|
||||
}
|
||||
|
||||
public function setPayed():void{
|
||||
$this->status = self::PayedStatus;
|
||||
$now = new \DateTime('now', new \DateTimeZone('UTC'));
|
||||
$this->approved_payment_date = $now;
|
||||
}
|
||||
|
||||
public function requestRefund():void{
|
||||
$this->status = self::RequestedRefundStatus;
|
||||
}
|
||||
|
||||
public function setPaymentError(string $error):void{
|
||||
$this->status = self::ErrorStatus;
|
||||
$this->last_error = $error;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getOwnerId(){
|
||||
try {
|
||||
return is_null($this->owner) ? 0 : $this->owner->getId();
|
||||
}
|
||||
catch(\Exception $ex){
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getRoomId(){
|
||||
try {
|
||||
return is_null($this->room) ? 0 : $this->room->getId();
|
||||
}
|
||||
catch(\Exception $ex){
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -16,7 +16,6 @@ use Doctrine\Common\Collections\Criteria;
|
||||
use Doctrine\ORM\Mapping AS ORM;
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
use models\exceptions\ValidationException;
|
||||
|
||||
/**
|
||||
* @ORM\Entity
|
||||
* @ORM\Table(name="SummitVenue")
|
||||
|
@ -53,4 +53,10 @@ interface ISummitRepository extends IBaseRepository
|
||||
* @return Summit[]
|
||||
*/
|
||||
public function getCurrentAndFutureSummits();
|
||||
|
||||
/**
|
||||
* @param string $slug
|
||||
* @return Summit
|
||||
*/
|
||||
public function getBySlug(string $slug):Summit;
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
<?php namespace App\Models\Foundation\Summit\Repositories;
|
||||
/**
|
||||
* Copyright 2019 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.
|
||||
**/
|
||||
use models\summit\SummitRoomReservation;
|
||||
use models\utils\IBaseRepository;
|
||||
/**
|
||||
* Interface ISummitRoomReservationRepository
|
||||
* @package App\Models\Foundation\Summit\Repositories
|
||||
*/
|
||||
interface ISummitRoomReservationRepository extends IBaseRepository
|
||||
{
|
||||
/**
|
||||
* @param string $payment_gateway_cart_id
|
||||
* @return SummitRoomReservation
|
||||
*/
|
||||
public function getByPaymentGatewayCartId(string $payment_gateway_cart_id):SummitRoomReservation;
|
||||
}
|
@ -165,11 +165,40 @@ class Summit extends SilverstripeBaseModel
|
||||
*/
|
||||
private $calendar_sync_desc;
|
||||
|
||||
/**
|
||||
* @ORM\Column(name="MeetingRoomBookingStartTime", type="time", nullable=true)
|
||||
* @var DateTime
|
||||
*/
|
||||
private $meeting_room_booking_start_time;
|
||||
|
||||
/**
|
||||
* @ORM\Column(name="MeetingRoomBookingEndTime", type="time", nullable=true)
|
||||
* @var DateTime
|
||||
*/
|
||||
private $meeting_room_booking_end_time;
|
||||
|
||||
/**
|
||||
* @ORM\Column(name="MeetingRoomBookingSlotLength", type="integer", nullable=true)
|
||||
* @var int
|
||||
*/
|
||||
private $meeting_room_booking_slot_length;
|
||||
|
||||
/**
|
||||
* @ORM\Column(name="MeetingRoomBookingMaxAllowed", type="integer", nullable=true)
|
||||
* @var int
|
||||
*/
|
||||
private $meeting_room_booking_max_allowed;
|
||||
|
||||
/**
|
||||
* @ORM\OneToMany(targetEntity="SummitAbstractLocation", mappedBy="summit", cascade={"persist"}, orphanRemoval=true, fetch="EXTRA_LAZY")
|
||||
*/
|
||||
private $locations;
|
||||
|
||||
/**
|
||||
* @ORM\OneToMany(targetEntity="models\summit\SummitBookableVenueRoomAttributeType", mappedBy="summit", cascade={"persist"}, orphanRemoval=true, fetch="EXTRA_LAZY")
|
||||
*/
|
||||
private $meeting_booking_room_allowed_attributes;
|
||||
|
||||
/**
|
||||
* @ORM\OneToMany(targetEntity="SummitEvent", mappedBy="summit", cascade={"persist"}, orphanRemoval=true, fetch="EXTRA_LAZY")
|
||||
*/
|
||||
@ -549,6 +578,7 @@ class Summit extends SilverstripeBaseModel
|
||||
$this->track_tag_groups = new ArrayCollection;
|
||||
$this->notifications = new ArrayCollection;
|
||||
$this->selection_plans = new ArrayCollection;
|
||||
$this->meeting_booking_room_allowed_attributes = new ArrayCollection();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -641,6 +671,17 @@ class Summit extends SilverstripeBaseModel
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @return SummitBookableVenueRoom[]
|
||||
*/
|
||||
public function getBookableRooms()
|
||||
{
|
||||
return $this->locations->filter(function ($e) {
|
||||
return $e instanceof SummitBookableVenueRoom;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return SummitAirport[]
|
||||
*/
|
||||
@ -2420,4 +2461,85 @@ SQL;
|
||||
public function setRawSlug(string $slug):void{
|
||||
$this->slug = $slug;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return DateTime
|
||||
*/
|
||||
public function getMeetingRoomBookingStartTime():?DateTime
|
||||
{
|
||||
return $this->meeting_room_booking_start_time;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param DateTime $meeting_room_booking_start_time
|
||||
*/
|
||||
public function setMeetingRoomBookingStartTime(DateTime $meeting_room_booking_start_time): void
|
||||
{
|
||||
$this->meeting_room_booking_start_time = $meeting_room_booking_start_time;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return DateTime
|
||||
*/
|
||||
public function getMeetingRoomBookingEndTime():?DateTime
|
||||
{
|
||||
return $this->meeting_room_booking_end_time;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param DateTime $meeting_room_booking_end_time
|
||||
*/
|
||||
public function setMeetingRoomBookingEndTime(DateTime $meeting_room_booking_end_time): void
|
||||
{
|
||||
$this->meeting_room_booking_end_time = $meeting_room_booking_end_time;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getMeetingRoomBookingSlotLength(): int
|
||||
{
|
||||
return $this->meeting_room_booking_slot_length;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $meeting_room_booking_slot_length
|
||||
*/
|
||||
public function setMeetingRoomBookingSlotLength(int $meeting_room_booking_slot_length): void
|
||||
{
|
||||
$this->meeting_room_booking_slot_length = $meeting_room_booking_slot_length;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getMeetingRoomBookingMaxAllowed(): int
|
||||
{
|
||||
return $this->meeting_room_booking_max_allowed;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $meeting_room_booking_max_allowed
|
||||
*/
|
||||
public function setMeetingRoomBookingMaxAllowed(int $meeting_room_booking_max_allowed): void
|
||||
{
|
||||
$this->meeting_room_booking_max_allowed = $meeting_room_booking_max_allowed;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getMeetingBookingRoomAllowedAttributes()
|
||||
{
|
||||
return $this->meeting_booking_room_allowed_attributes;
|
||||
}
|
||||
|
||||
public function getMaxReservationsPerDay():int {
|
||||
$interval = $this->meeting_room_booking_end_time->diff( $this->meeting_room_booking_start_time);
|
||||
$minutes = $interval->days * 24 * 60;
|
||||
$minutes += $interval->h * 60;
|
||||
$minutes += $interval->i;
|
||||
return intval ($minutes / $this->meeting_room_booking_slot_length);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -597,8 +597,27 @@ class AppServiceProvider extends ServiceProvider
|
||||
$value = trim($value);
|
||||
return isset($countries[$value]);
|
||||
});
|
||||
|
||||
Validator::extend('currency_iso', function($attribute, $value, $parameters, $validator)
|
||||
{
|
||||
$currencies =
|
||||
[
|
||||
'USD' => 'USD',
|
||||
'EUR' => 'EUR',
|
||||
'GBP' => 'GBP'
|
||||
];
|
||||
|
||||
$validator->addReplacer('currency_iso', function($message, $attribute, $rule, $parameters) use ($validator) {
|
||||
return sprintf("%s should be a valid currency iso 4217 code", $attribute);
|
||||
});
|
||||
if(!is_string($value)) return false;
|
||||
$value = trim($value);
|
||||
return isset($currencies[$value]);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Register any application services.
|
||||
* @return void
|
||||
|
@ -1,10 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace App\Providers;
|
||||
|
||||
<?php namespace App\Providers;
|
||||
/**
|
||||
* 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.
|
||||
**/
|
||||
use Illuminate\Contracts\Auth\Access\Gate as GateContract;
|
||||
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
|
||||
|
||||
/**
|
||||
* Class AuthServiceProvider
|
||||
* @package App\Providers
|
||||
*/
|
||||
class AuthServiceProvider extends ServiceProvider
|
||||
{
|
||||
/**
|
||||
|
@ -1,10 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace App\Providers;
|
||||
|
||||
<?php namespace App\Providers;
|
||||
/**
|
||||
* 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.
|
||||
**/
|
||||
use Illuminate\Routing\Router;
|
||||
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
|
||||
|
||||
/**
|
||||
* Class RouteServiceProvider
|
||||
* @package App\Providers
|
||||
*/
|
||||
class RouteServiceProvider extends ServiceProvider
|
||||
{
|
||||
/**
|
||||
|
@ -30,6 +30,7 @@ use App\Models\Foundation\Summit\Repositories\ISpeakerOrganizationalRoleReposito
|
||||
use App\Models\Foundation\Summit\Repositories\ISummitEventTypeRepository;
|
||||
use App\Models\Foundation\Summit\Repositories\ISummitLocationBannerRepository;
|
||||
use App\Models\Foundation\Summit\Repositories\ISummitLocationRepository;
|
||||
use App\Models\Foundation\Summit\Repositories\ISummitRoomReservationRepository;
|
||||
use App\Models\Foundation\Summit\Repositories\ISummitTrackRepository;
|
||||
use App\Models\Foundation\Summit\Repositories\ITrackQuestionTemplateRepository;
|
||||
use App\Models\Foundation\Summit\Repositories\ITrackTagGroupAllowedTagsRepository;
|
||||
@ -58,6 +59,7 @@ use models\summit\SpeakerSummitRegistrationPromoCode;
|
||||
use models\summit\SummitAbstractLocation;
|
||||
use models\summit\SummitEventType;
|
||||
use models\summit\SummitRegistrationPromoCode;
|
||||
use models\summit\SummitRoomReservation;
|
||||
use models\summit\SummitTicketType;
|
||||
/**
|
||||
* Class RepositoriesProvider
|
||||
@ -401,5 +403,12 @@ final class RepositoriesProvider extends ServiceProvider
|
||||
}
|
||||
);
|
||||
|
||||
App::singleton(
|
||||
ISummitRoomReservationRepository::class,
|
||||
function(){
|
||||
return EntityManager::getRepository(SummitRoomReservation::class);
|
||||
}
|
||||
);
|
||||
|
||||
}
|
||||
}
|
@ -96,6 +96,6 @@ final class DoctrineApiEndpointRepository
|
||||
*/
|
||||
protected function applyExtraFilters(QueryBuilder $query)
|
||||
{
|
||||
return [];
|
||||
return $query;
|
||||
}
|
||||
}
|
@ -17,10 +17,13 @@ use Doctrine\ORM\Tools\Pagination\Paginator;
|
||||
use models\summit\Summit;
|
||||
use models\summit\SummitAbstractLocation;
|
||||
use models\summit\SummitAirport;
|
||||
use models\summit\SummitBookableVenueRoom;
|
||||
use models\summit\SummitBookableVenueRoomAttributeValue;
|
||||
use models\summit\SummitExternalLocation;
|
||||
use models\summit\SummitGeoLocatedLocation;
|
||||
use models\summit\SummitHotel;
|
||||
use models\summit\SummitVenue;
|
||||
use utils\DoctrineFilterMapping;
|
||||
use utils\DoctrineInstanceOfFilterMapping;
|
||||
use utils\Filter;
|
||||
use utils\Order;
|
||||
@ -51,23 +54,31 @@ final class DoctrineSummitLocationRepository
|
||||
protected function getFilterMappings()
|
||||
{
|
||||
return [
|
||||
'name' => 'al.name:json_string',
|
||||
'description' => 'al.description:json_string',
|
||||
'address_1' => 'gll.address1:json_string',
|
||||
'address_2' => 'gll.address2:json_string',
|
||||
'zip_code' => 'gll.zip_code:json_string',
|
||||
'city' => 'gll.city:json_string',
|
||||
'state' => 'gll.state:json_string',
|
||||
'country' => 'gll.country:json_string',
|
||||
'sold_out' => 'h.sold_out:json_boolean',
|
||||
'is_main' => 'v.is_main:json_boolean',
|
||||
'class_name' => new DoctrineInstanceOfFilterMapping(
|
||||
'name' => 'al.name:json_string',
|
||||
'description' => 'al.description:json_string',
|
||||
'address_1' => 'gll.address1:json_string',
|
||||
'address_2' => 'gll.address2:json_string',
|
||||
'zip_code' => 'gll.zip_code:json_string',
|
||||
'city' => 'gll.city:json_string',
|
||||
'state' => 'gll.state:json_string',
|
||||
'country' => 'gll.country:json_string',
|
||||
'sold_out' => 'h.sold_out:json_boolean',
|
||||
'is_main' => 'v.is_main:json_boolean',
|
||||
'time_slot_cost' => 'br.time_slot_cost',
|
||||
'currency' => 'br.currency',
|
||||
'capacity' => 'r.capacity',
|
||||
'attribute' => new DoctrineFilterMapping
|
||||
(
|
||||
"(bra.value :operator ':value' or bra.id = ':value')"
|
||||
),
|
||||
'class_name' => new DoctrineInstanceOfFilterMapping(
|
||||
"al",
|
||||
[
|
||||
SummitVenue::ClassName => SummitVenue::class,
|
||||
SummitHotel::ClassName => SummitHotel::class,
|
||||
SummitExternalLocation::ClassName => SummitExternalLocation::class,
|
||||
SummitAirport::ClassName => SummitAirport::class,
|
||||
SummitVenue::ClassName => SummitVenue::class,
|
||||
SummitHotel::ClassName => SummitHotel::class,
|
||||
SummitExternalLocation::ClassName => SummitExternalLocation::class,
|
||||
SummitAirport::ClassName => SummitAirport::class,
|
||||
SummitBookableVenueRoom::ClassName => SummitBookableVenueRoom::class,
|
||||
]
|
||||
)
|
||||
];
|
||||
@ -109,6 +120,9 @@ final class DoctrineSummitLocationRepository
|
||||
->leftJoin(SummitExternalLocation::class, 'el', 'WITH', 'el.id = gll.id')
|
||||
->leftJoin(SummitHotel::class, 'h', 'WITH', 'h.id = el.id')
|
||||
->leftJoin(SummitAirport::class, 'ap', 'WITH', 'ap.id = el.id')
|
||||
->leftJoin(SummitVenueRoom::class, 'r', 'WITH', 'r.id = al.id')
|
||||
->leftJoin(SummitBookableVenueRoom::class, 'br', 'WITH', 'br.id = al.id')
|
||||
->leftJoin('br.attributes', 'bra')
|
||||
->leftJoin('al.summit', 's')
|
||||
->where("s.id = :summit_id");
|
||||
|
||||
@ -133,6 +147,28 @@ final class DoctrineSummitLocationRepository
|
||||
$query = $query->addOrderBy("al.id",'ASC');
|
||||
}
|
||||
|
||||
if($filter->hasFilter("availability_day")){
|
||||
// special case, we need to figure if each room has available slots
|
||||
$res = $query->getQuery()->execute();
|
||||
$rooms = [];
|
||||
$availability_day = $filter->getUniqueFilter("availability_day")->getValue();
|
||||
$day = new \DateTime("@$availability_day");
|
||||
foreach ($res as $room){
|
||||
if(!$room instanceof SummitBookableVenueRoom) continue;
|
||||
if(count($room->getFreeSlots($day)) > 0)
|
||||
$rooms[] = $room;
|
||||
}
|
||||
|
||||
return new PagingResponse
|
||||
(
|
||||
count($rooms),
|
||||
$paging_info->getPerPage(),
|
||||
$paging_info->getCurrentPage(),
|
||||
$paging_info->getLastPage(count($rooms)),
|
||||
array_slice( $rooms, $paging_info->getOffset(), $paging_info->getPerPage() )
|
||||
);
|
||||
}
|
||||
|
||||
$query = $query
|
||||
->setFirstResult($paging_info->getOffset())
|
||||
->setMaxResults($paging_info->getPerPage());
|
||||
|
@ -105,6 +105,21 @@ final class DoctrineSummitRepository
|
||||
->getOneOrNullResult();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $slug
|
||||
* @return Summit
|
||||
*/
|
||||
public function getBySlug(string $slug):Summit
|
||||
{
|
||||
return $this->getEntityManager()->createQueryBuilder()
|
||||
->select("s")
|
||||
->from(\models\summit\Summit::class, "s")
|
||||
->where('s.slug = :slug')
|
||||
->setParameter('slug', $slug)
|
||||
->getQuery()
|
||||
->getOneOrNullResult();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Summit
|
||||
*/
|
||||
|
@ -0,0 +1,42 @@
|
||||
<?php namespace App\Repositories\Summit;
|
||||
/**
|
||||
* Copyright 2019 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.
|
||||
**/
|
||||
use App\Models\Foundation\Summit\Repositories\ISummitRoomReservationRepository;
|
||||
use App\Repositories\SilverStripeDoctrineRepository;
|
||||
use models\summit\SummitRoomReservation;
|
||||
/**
|
||||
* Class DoctrineSummitRoomReservationRepository
|
||||
* @package App\Repositories\Summit
|
||||
*/
|
||||
class DoctrineSummitRoomReservationRepository
|
||||
extends SilverStripeDoctrineRepository
|
||||
implements ISummitRoomReservationRepository
|
||||
{
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
protected function getBaseEntity()
|
||||
{
|
||||
return SummitRoomReservation::class;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $payment_gateway_cart_id
|
||||
* @return SummitRoomReservation
|
||||
*/
|
||||
public function getByPaymentGatewayCartId(string $payment_gateway_cart_id): SummitRoomReservation
|
||||
{
|
||||
return $this->findOneBy(["payment_gateway_cart_id" => trim($payment_gateway_cart_id)]);
|
||||
}
|
||||
}
|
@ -18,47 +18,44 @@
|
||||
*/
|
||||
final class SummitScopes
|
||||
{
|
||||
const ReadSummitData = '%s/summits/read';
|
||||
const ReadAllSummitData = '%s/summits/read/all';
|
||||
const ReadNotifications = '%s/summits/read-notifications';
|
||||
const WriteNotifications = '%s/summits/write-notifications';
|
||||
const ReadSummitData = '%s/summits/read';
|
||||
const ReadAllSummitData = '%s/summits/read/all';
|
||||
|
||||
const WriteSummitData = '%s/summits/write';
|
||||
const WriteSpeakersData = '%s/speakers/write';
|
||||
const ReadSpeakersData = '%s/speakers/read';
|
||||
const WriteTrackTagGroupsData = '%s/track-tag-groups/write';
|
||||
const WriteTrackQuestionTemplateData = '%s/track-question-templates/write';
|
||||
const WriteMySpeakersData = '%s/speakers/write/me';
|
||||
const ReadMySpeakersData = '%s/speakers/read/me';
|
||||
// bookable rooms
|
||||
const ReadBookableRoomsData = '%s/bookable-rooms/read';
|
||||
const WriteMyBookableRoomsReservationData = '%s/bookable-rooms/my-reservations/write';
|
||||
const ReadMyBookableRoomsReservationData = '%s/bookable-rooms/my-reservations/read';
|
||||
const BookableRoomsReservation = '%s/bookable-rooms/reserve';
|
||||
const WriteBookableRoomsData = '%s/bookable-rooms/write';
|
||||
|
||||
const PublishEventData = '%s/summits/publish-event';
|
||||
const WriteEventData = '%s/summits/write-event';
|
||||
const WriteVideoData = '%s/summits/write-videos';
|
||||
const WritePresentationVideosData = '%s/summits/write-presentation-videos';
|
||||
const WritePresentationLinksData = '%s/summits/write-presentation-links';
|
||||
const WritePresentationSlidesData = '%s/summits/write-presentation-slides';
|
||||
const WritePresentationMaterialsData = '%s/summits/write-presentation-materials';
|
||||
const ReadNotifications = '%s/summits/read-notifications';
|
||||
const WriteNotifications = '%s/summits/write-notifications';
|
||||
|
||||
const WriteSummitData = '%s/summits/write';
|
||||
const WriteSpeakersData = '%s/speakers/write';
|
||||
const ReadSpeakersData = '%s/speakers/read';
|
||||
const WriteTrackTagGroupsData = '%s/track-tag-groups/write';
|
||||
const WriteTrackQuestionTemplateData = '%s/track-question-templates/write';
|
||||
const WriteMySpeakersData = '%s/speakers/write/me';
|
||||
const ReadMySpeakersData = '%s/speakers/read/me';
|
||||
|
||||
const WriteAttendeesData = '%s/attendees/write';
|
||||
const PublishEventData = '%s/summits/publish-event';
|
||||
const WriteEventData = '%s/summits/write-event';
|
||||
const WriteVideoData = '%s/summits/write-videos';
|
||||
const WritePresentationVideosData = '%s/summits/write-presentation-videos';
|
||||
const WritePresentationLinksData = '%s/summits/write-presentation-links';
|
||||
const WritePresentationSlidesData = '%s/summits/write-presentation-slides';
|
||||
const WritePresentationMaterialsData = '%s/summits/write-presentation-materials';
|
||||
|
||||
const WritePromoCodeData = '%s/promo-codes/write';
|
||||
|
||||
const WriteEventTypeData = '%s/event-types/write';
|
||||
|
||||
const WriteTracksData = '%s/tracks/write';
|
||||
|
||||
const WriteTrackGroupsData = '%s/track-groups/write';
|
||||
|
||||
const WriteLocationsData = '%s/locations/write';
|
||||
|
||||
const WriteRSVPTemplateData = '%s/rsvp-templates/write';
|
||||
|
||||
const WriteLocationBannersData = '%s/locations/banners/write';
|
||||
|
||||
const WriteSummitSpeakerAssistanceData = '%s/summit-speaker-assistance/write';
|
||||
|
||||
const WriteTicketTypeData = '%s/ticket-types/write';
|
||||
|
||||
const WritePresentationData = '%s/summits/write-presentation';
|
||||
const WriteAttendeesData = '%s/attendees/write';
|
||||
const WritePromoCodeData = '%s/promo-codes/write';
|
||||
const WriteEventTypeData = '%s/event-types/write';
|
||||
const WriteTracksData = '%s/tracks/write';
|
||||
const WriteTrackGroupsData = '%s/track-groups/write';
|
||||
const WriteLocationsData = '%s/locations/write';
|
||||
const WriteRSVPTemplateData = '%s/rsvp-templates/write';
|
||||
const WriteLocationBannersData = '%s/locations/banners/write';
|
||||
const WriteSummitSpeakerAssistanceData = '%s/summit-speaker-assistance/write';
|
||||
const WriteTicketTypeData = '%s/ticket-types/write';
|
||||
const WritePresentationData = '%s/summits/write-presentation';
|
||||
}
|
52
app/Services/Apis/IPaymentGatewayAPI.php
Normal file
52
app/Services/Apis/IPaymentGatewayAPI.php
Normal file
@ -0,0 +1,52 @@
|
||||
<?php namespace App\Services\Apis;
|
||||
/**
|
||||
* Copyright 2019 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.
|
||||
**/
|
||||
use models\summit\SummitRoomReservation;
|
||||
use Illuminate\Http\Request as LaravelRequest;
|
||||
/**
|
||||
* Interface IPaymentGatewayAPI
|
||||
* @package App\Services\Apis
|
||||
*/
|
||||
interface IPaymentGatewayAPI
|
||||
{
|
||||
/**
|
||||
* @param SummitRoomReservation $reservation
|
||||
* @return array
|
||||
*/
|
||||
public function generatePayment(SummitRoomReservation $reservation):array;
|
||||
|
||||
/**
|
||||
* @param LaravelRequest $request
|
||||
* @return array
|
||||
*/
|
||||
public function processCallback(LaravelRequest $request):array;
|
||||
|
||||
/**
|
||||
* @param array $payload
|
||||
* @return bool
|
||||
*/
|
||||
public function isSuccessFullPayment(array $payload):bool;
|
||||
|
||||
/**
|
||||
* @param array $payload
|
||||
* @return string
|
||||
*/
|
||||
public function getPaymentError(array $payload):string;
|
||||
|
||||
/**
|
||||
* @param string $cart_id
|
||||
* @param int $amount
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function refundPayment(string $cart_id, int $amount = 0): void;
|
||||
}
|
174
app/Services/Apis/PaymentGateways/StripeApi.php
Normal file
174
app/Services/Apis/PaymentGateways/StripeApi.php
Normal file
@ -0,0 +1,174 @@
|
||||
<?php namespace App\Services\Apis\PaymentGateways;
|
||||
/**
|
||||
* Copyright 2019 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.
|
||||
**/
|
||||
use App\Services\Apis\IPaymentGatewayAPI;
|
||||
use Illuminate\Http\Request as LaravelRequest;
|
||||
use models\summit\SummitRoomReservation;
|
||||
use Stripe\Charge;
|
||||
use Stripe\Error\SignatureVerification;
|
||||
use Stripe\Event;
|
||||
use Stripe\Stripe;
|
||||
use Stripe\PaymentIntent;
|
||||
use Stripe\WebhookSignature;
|
||||
/**
|
||||
* Class StripesApi
|
||||
* @package App\Services\Apis\PaymentGateways
|
||||
*/
|
||||
final class StripeApi implements IPaymentGatewayAPI
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $api_key;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $webhook_secret;
|
||||
|
||||
/**
|
||||
* StripeApi constructor.
|
||||
* @param string $api_key
|
||||
* @param string $webhook_secret
|
||||
*/
|
||||
public function __construct(string $api_key, string $webhook_secret)
|
||||
{
|
||||
$this->api_key = $api_key;
|
||||
$this->webhook_secret = $webhook_secret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param SummitRoomReservation $reservation
|
||||
* @return array
|
||||
*/
|
||||
public function generatePayment(SummitRoomReservation $reservation):array
|
||||
{
|
||||
if(empty($this->api_key))
|
||||
throw new \InvalidArgumentException();
|
||||
|
||||
Stripe::setApiKey($this->api_key);
|
||||
|
||||
$intent = PaymentIntent::create([
|
||||
'amount' => $reservation->getAmount(),
|
||||
'currency' => $reservation->getCurrency(),
|
||||
'receipt_email' => $reservation->getOwner()->getEmail()
|
||||
]);
|
||||
|
||||
return [
|
||||
'client_token' => $intent->client_secret,
|
||||
'cart_id' => $intent->id,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param LaravelRequest $request
|
||||
* @return array
|
||||
* @throws SignatureVerification
|
||||
* @throws \Exception
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function processCallback(LaravelRequest $request): array
|
||||
{
|
||||
try {
|
||||
|
||||
WebhookSignature::verifyHeader(
|
||||
$request->getContent(),
|
||||
$request->header('Stripe-Signature'),
|
||||
$this->webhook_secret
|
||||
);
|
||||
|
||||
$event = Event::constructFrom(json_decode($request->getContent(), true));
|
||||
if(!in_array($event->type, ["payment_intent.succeeded", "payment_intent.payment_failed"]))
|
||||
throw new \InvalidArgumentException();
|
||||
|
||||
$intent = $event->data->object;
|
||||
if ($event->type == "payment_intent.succeeded") {
|
||||
return [
|
||||
"event_type" => $event->type,
|
||||
"cart_id" => $intent->id,
|
||||
];
|
||||
}
|
||||
|
||||
if ($event->type == "payment_intent.payment_failed") {
|
||||
$intent = $event->data->object;
|
||||
return [
|
||||
"event_type" => $event->type,
|
||||
"cart_id" => $intent->id,
|
||||
"error" => [
|
||||
"last_payment_error" => $intent->last_payment_error,
|
||||
"message" => $intent->last_payment_error->message
|
||||
]
|
||||
];
|
||||
}
|
||||
}
|
||||
catch(\UnexpectedValueException $e) {
|
||||
// Invalid payload
|
||||
throw $e;
|
||||
}
|
||||
catch(SignatureVerification $e) {
|
||||
// Invalid signature
|
||||
throw $e;
|
||||
}
|
||||
catch (\Exception $e){
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $payload
|
||||
* @return bool
|
||||
*/
|
||||
public function isSuccessFullPayment(array $payload): bool
|
||||
{
|
||||
if(isset($payload['type']) && $payload['type'] == "payment_intent.succeeded") return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $payload
|
||||
* @return string
|
||||
*/
|
||||
public function getPaymentError(array $payload): string
|
||||
{
|
||||
if(isset($payload['type']) && $payload['type'] == "payment_intent.payment_failed"){
|
||||
$error_message = $payload['error']["message"];
|
||||
return $error_message;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $cart_id
|
||||
* @param int $amount
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function refundPayment(string $cart_id, int $amount = 0): void
|
||||
{
|
||||
if(empty($this->api_key))
|
||||
throw new \InvalidArgumentException();
|
||||
|
||||
Stripe::setApiKey($this->api_key);
|
||||
$intent = PaymentIntent::retrieve($cart_id);
|
||||
|
||||
if(is_null($intent))
|
||||
throw new \InvalidArgumentException();
|
||||
$charge = $intent->charges->data[0];
|
||||
if(!$charge instanceof Charge)
|
||||
throw new \InvalidArgumentException();
|
||||
$params = [];
|
||||
if($amount > 0 ){
|
||||
$params['amount'] = $amount;
|
||||
}
|
||||
$charge->refund($params);
|
||||
}
|
||||
}
|
@ -12,7 +12,9 @@
|
||||
* limitations under the License.
|
||||
**/
|
||||
use App\Models\Foundation\Summit\Locations\Banners\SummitLocationBanner;
|
||||
use models\main\Member;
|
||||
use models\summit\SummitLocationImage;
|
||||
use models\summit\SummitRoomReservation;
|
||||
use models\summit\SummitVenueRoom;
|
||||
use models\exceptions\EntityNotFoundException;
|
||||
use models\exceptions\ValidationException;
|
||||
@ -213,4 +215,30 @@ interface ILocationService
|
||||
*/
|
||||
public function deleteLocationImage(Summit $summit, $location_id, $image_id);
|
||||
|
||||
/**
|
||||
* @param Summit $summit
|
||||
* @param int $room_id
|
||||
* @param array $payload
|
||||
* @return SummitRoomReservation
|
||||
* @throws EntityNotFoundException
|
||||
* @throws ValidationException
|
||||
*/
|
||||
public function addBookableRoomReservation(Summit $summit, int $room_id, array $payload):SummitRoomReservation;
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
* @throws EntityNotFoundException
|
||||
* @throws ValidationException
|
||||
*/
|
||||
public function processBookableRoomPayment(array $payload):void;
|
||||
|
||||
|
||||
/**
|
||||
* @param Summit $sumit
|
||||
* @param Member $owner
|
||||
* @param int $reservation_id
|
||||
* @throws EntityNotFoundException
|
||||
* @throws ValidationException
|
||||
*/
|
||||
public function cancelReservation(Summit $sumit, Member $owner, int $reservation_id):void;
|
||||
}
|
@ -28,11 +28,14 @@ use App\Http\Utils\IFileUploader;
|
||||
use App\Models\Foundation\Summit\Factories\SummitLocationBannerFactory;
|
||||
use App\Models\Foundation\Summit\Factories\SummitLocationFactory;
|
||||
use App\Models\Foundation\Summit\Factories\SummitLocationImageFactory;
|
||||
use App\Models\Foundation\Summit\Factories\SummitRoomReservationFactory;
|
||||
use App\Models\Foundation\Summit\Factories\SummitVenueFloorFactory;
|
||||
use App\Models\Foundation\Summit\Locations\Banners\SummitLocationBanner;
|
||||
use App\Models\Foundation\Summit\Repositories\ISummitLocationRepository;
|
||||
use App\Models\Foundation\Summit\Repositories\ISummitRoomReservationRepository;
|
||||
use App\Services\Apis\GeoCodingApiException;
|
||||
use App\Services\Apis\IGeoCodingAPI;
|
||||
use App\Services\Apis\IPaymentGatewayAPI;
|
||||
use App\Services\Model\Strategies\GeoLocation\GeoLocationStrategyFactory;
|
||||
use Illuminate\Http\UploadedFile;
|
||||
use Illuminate\Support\Facades\Event;
|
||||
@ -40,10 +43,14 @@ use Illuminate\Support\Facades\Log;
|
||||
use libs\utils\ITransactionService;
|
||||
use models\exceptions\EntityNotFoundException;
|
||||
use models\exceptions\ValidationException;
|
||||
use models\main\IMemberRepository;
|
||||
use models\main\Member;
|
||||
use models\summit\Summit;
|
||||
use models\summit\SummitAbstractLocation;
|
||||
use models\summit\SummitBookableVenueRoom;
|
||||
use models\summit\SummitGeoLocatedLocation;
|
||||
use models\summit\SummitLocationImage;
|
||||
use models\summit\SummitRoomReservation;
|
||||
use models\summit\SummitVenue;
|
||||
use models\summit\SummitVenueFloor;
|
||||
use models\summit\SummitVenueRoom;
|
||||
@ -70,28 +77,53 @@ final class SummitLocationService
|
||||
*/
|
||||
private $folder_service;
|
||||
|
||||
/**
|
||||
* @var IPaymentGatewayAPI
|
||||
*/
|
||||
private $payment_gateway;
|
||||
|
||||
/**
|
||||
* @var IMemberRepository
|
||||
*/
|
||||
private $member_repository;
|
||||
|
||||
/**
|
||||
* @var ISummitRoomReservationRepository
|
||||
*/
|
||||
private $reservation_repository;
|
||||
|
||||
/**
|
||||
* SummitLocationService constructor.
|
||||
* @param ISummitLocationRepository $location_repository
|
||||
* @param IMemberRepository $member_repository
|
||||
* @param ISummitRoomReservationRepository $reservation_repository
|
||||
* @param IGeoCodingAPI $geo_coding_api
|
||||
* @param IFolderService $folder_service
|
||||
* @param IFileUploader $file_uploader
|
||||
* @param IPaymentGatewayAPI $payment_gateway
|
||||
* @param ITransactionService $tx_service
|
||||
*/
|
||||
public function __construct
|
||||
(
|
||||
ISummitLocationRepository $location_repository,
|
||||
IMemberRepository $member_repository,
|
||||
ISummitRoomReservationRepository $reservation_repository,
|
||||
IGeoCodingAPI $geo_coding_api,
|
||||
IFolderService $folder_service,
|
||||
IFileUploader $file_uploader,
|
||||
IPaymentGatewayAPI $payment_gateway,
|
||||
ITransactionService $tx_service
|
||||
)
|
||||
{
|
||||
parent::__construct($tx_service);
|
||||
$this->location_repository = $location_repository;
|
||||
$this->geo_coding_api = $geo_coding_api;
|
||||
$this->file_uploader = $file_uploader;
|
||||
$this->folder_service = $folder_service;
|
||||
|
||||
$this->location_repository = $location_repository;
|
||||
$this->member_repository = $member_repository;
|
||||
$this->reservation_repository = $reservation_repository;
|
||||
$this->geo_coding_api = $geo_coding_api;
|
||||
$this->file_uploader = $file_uploader;
|
||||
$this->folder_service = $folder_service;
|
||||
$this->payment_gateway = $payment_gateway;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1646,4 +1678,107 @@ final class SummitLocationService
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Summit $summit
|
||||
* @param int $room_id
|
||||
* @param array $payload
|
||||
* @return SummitRoomReservation
|
||||
* @throws EntityNotFoundException
|
||||
* @throws ValidationException
|
||||
*/
|
||||
public function addBookableRoomReservation(Summit $summit, int $room_id, array $payload): SummitRoomReservation
|
||||
{
|
||||
return $this->tx_service->transaction(function () use ($summit, $room_id, $payload) {
|
||||
|
||||
$room = $summit->getLocation($room_id);
|
||||
|
||||
if (is_null($room)) {
|
||||
throw new EntityNotFoundException();
|
||||
}
|
||||
|
||||
if(!$room instanceof SummitBookableVenueRoom){
|
||||
throw new EntityNotFoundException();
|
||||
}
|
||||
|
||||
$owner_id = $payload["owner_id"];
|
||||
|
||||
$owner = $this->member_repository->getById($owner_id);
|
||||
|
||||
if (is_null($owner)) {
|
||||
throw new EntityNotFoundException();
|
||||
}
|
||||
|
||||
$payload['owner'] = $owner;
|
||||
|
||||
$reservation = SummitRoomReservationFactory::build($summit, $payload);
|
||||
|
||||
$room->addReservation($reservation);
|
||||
|
||||
$result = $this->payment_gateway->generatePayment
|
||||
(
|
||||
$reservation
|
||||
);
|
||||
|
||||
$reservation->setPaymentGatewayCartId($result['cart_id']);
|
||||
$reservation->setPaymentGatewayClientToken($result['client_token']);
|
||||
|
||||
return $reservation;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $payload
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function processBookableRoomPayment(array $payload): void
|
||||
{
|
||||
$this->tx_service->transaction(function () use ($payload) {
|
||||
$reservation = $this->reservation_repository->getByPaymentGatewayCartId($payload['cart_id']);
|
||||
|
||||
if(is_null($reservation)){
|
||||
throw new EntityNotFoundException();
|
||||
}
|
||||
|
||||
if($this->payment_gateway->isSuccessFullPayment($payload)) {
|
||||
$reservation->setPayed();
|
||||
return;
|
||||
}
|
||||
|
||||
$reservation->setPaymentError($this->payment_gateway->getPaymentError($payload));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Summit $summit
|
||||
* @param Member $owner
|
||||
* @param int $reservation_id
|
||||
* @throws EntityNotFoundException
|
||||
* @throws ValidationException
|
||||
*/
|
||||
public function cancelReservation(Summit $summit, Member $owner, int $reservation_id): void
|
||||
{
|
||||
$this->tx_service->transaction(function () use ($summit, $owner, $reservation_id) {
|
||||
|
||||
$reservation = $owner->getReservationById($reservation_id);
|
||||
|
||||
if(is_null($reservation)){
|
||||
throw new EntityNotFoundException();
|
||||
}
|
||||
|
||||
if($reservation->getRoom()->getSummitId() != $summit->getId()){
|
||||
throw new EntityNotFoundException();
|
||||
}
|
||||
|
||||
if($reservation->getStatus() == SummitRoomReservation::ReservedStatus)
|
||||
throw new ValidationException("can not request a refund on a reserved booking!");
|
||||
|
||||
if($reservation->getStatus() == SummitRoomReservation::RequestedRefundStatus ||
|
||||
$reservation->getStatus() == SummitRoomReservation::RefundedStatus
|
||||
)
|
||||
throw new ValidationException("can not request a refund on an already refunded booking!");
|
||||
|
||||
$reservation->requestRefund();
|
||||
});
|
||||
}
|
||||
}
|
@ -13,10 +13,11 @@
|
||||
**/
|
||||
use App\Permissions\IPermissionsManager;
|
||||
use App\Permissions\PermissionsManager;
|
||||
use App\Repositories\DoctrineRepository;
|
||||
use App\Services\Apis\CalendarSync\ICalendarSyncRemoteFacadeFactory;
|
||||
use App\Services\Apis\GoogleGeoCodingAPI;
|
||||
use App\Services\Apis\IGeoCodingAPI;
|
||||
use App\Services\Apis\IPaymentGatewayAPI;
|
||||
use App\Services\Apis\PaymentGateways\StripeApi;
|
||||
use App\Services\Model\AttendeeService;
|
||||
use App\Services\Model\FolderService;
|
||||
use App\Services\Model\IAttendeeService;
|
||||
@ -125,6 +126,13 @@ final class ServicesProvider extends ServiceProvider
|
||||
return $api;
|
||||
});
|
||||
|
||||
App::singleton(IPaymentGatewayAPI::class, function(){
|
||||
return new StripeApi(
|
||||
Config::get("stripe.private_key", null),
|
||||
Config::get("stripe.endpoint_secret", null)
|
||||
);
|
||||
});
|
||||
|
||||
App::singleton
|
||||
(
|
||||
IAttendeeService::class,
|
||||
|
@ -34,6 +34,7 @@
|
||||
"s-ichikawa/laravel-sendgrid-driver": "^2.0",
|
||||
"smarcet/caldavclient": "1.1.6",
|
||||
"smarcet/outlook-rest-client": "dev-master",
|
||||
"stripe/stripe-php": "^6.37",
|
||||
"symfony/yaml": "4.2.2"
|
||||
},
|
||||
"require-dev": {
|
||||
|
58
composer.lock
generated
58
composer.lock
generated
@ -4,7 +4,7 @@
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "d03caf628ec9076f0ab50d8cdab0685d",
|
||||
"content-hash": "e8960c590d5b3ce6a88c1a2544a3751f",
|
||||
"packages": [
|
||||
{
|
||||
"name": "cocur/slugify",
|
||||
@ -3792,6 +3792,62 @@
|
||||
],
|
||||
"time": "2017-08-05T01:36:59+00:00"
|
||||
},
|
||||
{
|
||||
"name": "stripe/stripe-php",
|
||||
"version": "v6.37.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/stripe/stripe-php.git",
|
||||
"reference": "6915bed0b988ca837f3e15a1f31517a6172a663a"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/stripe/stripe-php/zipball/6915bed0b988ca837f3e15a1f31517a6172a663a",
|
||||
"reference": "6915bed0b988ca837f3e15a1f31517a6172a663a",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-curl": "*",
|
||||
"ext-json": "*",
|
||||
"ext-mbstring": "*",
|
||||
"php": ">=5.4.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"php-coveralls/php-coveralls": "1.*",
|
||||
"phpunit/phpunit": "~4.0",
|
||||
"squizlabs/php_codesniffer": "~2.0",
|
||||
"symfony/process": "~2.8"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.0-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Stripe\\": "lib/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Stripe and contributors",
|
||||
"homepage": "https://github.com/stripe/stripe-php/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Stripe PHP Library",
|
||||
"homepage": "https://stripe.com/",
|
||||
"keywords": [
|
||||
"api",
|
||||
"payment processing",
|
||||
"stripe"
|
||||
],
|
||||
"time": "2019-05-23T23:59:23+00:00"
|
||||
},
|
||||
{
|
||||
"name": "swiftmailer/swiftmailer",
|
||||
"version": "v6.2.0",
|
||||
|
20
config/stripe.php
Normal file
20
config/stripe.php
Normal file
@ -0,0 +1,20 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright 2019 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 [
|
||||
// Set your secret key: remember to change this to your live secret key in production
|
||||
// See your keys here: https://dashboard.stripe.com/account/apikeys
|
||||
"private_key" => env('STRIPE_PRIVATE_KEY', ''),
|
||||
// You can find your endpoint's secret in your webhook settings
|
||||
"endpoint_secret" => env('STRIPE_ENDPOINT_SECRET', ''),
|
||||
];
|
54
database/migrations/model/Version20190529015655.php
Normal file
54
database/migrations/model/Version20190529015655.php
Normal file
@ -0,0 +1,54 @@
|
||||
<?php namespace Database\Migrations\Model;
|
||||
/**
|
||||
* Copyright 2019 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.
|
||||
**/
|
||||
use Doctrine\Migrations\AbstractMigration;
|
||||
use Doctrine\DBAL\Schema\Schema as Schema;
|
||||
use LaravelDoctrine\Migrations\Schema\Table;
|
||||
use LaravelDoctrine\Migrations\Schema\Builder;
|
||||
/**
|
||||
* Class Version20190529015655
|
||||
* @package Database\Migrations\Model
|
||||
*/
|
||||
class Version20190529015655 extends AbstractMigration
|
||||
{
|
||||
/**
|
||||
* @param Schema $schema
|
||||
*/
|
||||
public function up(Schema $schema)
|
||||
{
|
||||
$builder = new Builder($schema);
|
||||
if(!$builder->hasColumn("Summit","MeetingRoomBookingStartTime")) {
|
||||
$builder->table('Summit', function (Table $table) {
|
||||
$table->time("MeetingRoomBookingStartTime")->setNotnull(false);
|
||||
$table->time("MeetingRoomBookingEndTime")->setNotnull(false);
|
||||
$table->integer("MeetingRoomBookingSlotLength")->setNotnull(true)->setDefault(0);
|
||||
$table->integer("MeetingRoomBookingMaxAllowed")->setNotnull(true)->setDefault(0);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Schema $schema
|
||||
*/
|
||||
public function down(Schema $schema)
|
||||
{
|
||||
$builder = new Builder($schema);
|
||||
|
||||
$builder->table('Summit', function (Table $table) {
|
||||
$table->dropColumn("MeetingRoomBookingStartTime");
|
||||
$table->dropColumn("MeetingRoomBookingEndTime");
|
||||
$table->dropColumn("MeetingRoomBookingSlotLength");
|
||||
$table->dropColumn("MeetingRoomBookingMaxAllowed");
|
||||
});
|
||||
}
|
||||
}
|
57
database/migrations/model/Version20190529142913.php
Normal file
57
database/migrations/model/Version20190529142913.php
Normal file
@ -0,0 +1,57 @@
|
||||
<?php namespace Database\Migrations\Model;
|
||||
/**
|
||||
* Copyright 2019 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.
|
||||
**/
|
||||
use Doctrine\Migrations\AbstractMigration;
|
||||
use Doctrine\DBAL\Schema\Schema as Schema;
|
||||
use LaravelDoctrine\Migrations\Schema\Table;
|
||||
use LaravelDoctrine\Migrations\Schema\Builder;
|
||||
/**
|
||||
* Class Version20190529142913
|
||||
* @package Database\Migrations\Model
|
||||
*/
|
||||
class Version20190529142913 extends AbstractMigration
|
||||
{
|
||||
/**
|
||||
* @param Schema $schema
|
||||
*/
|
||||
public function up(Schema $schema)
|
||||
{
|
||||
if(!$schema->hasTable("SummitBookableVenueRoom")) {
|
||||
$sql = <<<SQL
|
||||
ALTER TABLE SummitAbstractLocation MODIFY ClassName enum('SummitAbstractLocation', 'SummitGeoLocatedLocation', 'SummitExternalLocation', 'SummitAirport', 'SummitHotel', 'SummitVenue', 'SummitVenueRoom', 'SummitBookableVenueRoom') DEFAULT 'SummitAbstractLocation';
|
||||
SQL;
|
||||
$builder = new Builder($schema);
|
||||
$this->addSql($sql);
|
||||
$builder->create('SummitBookableVenueRoom', function (Table $table) {
|
||||
$table->integer("ID", true, false);
|
||||
$table->primary("ID");
|
||||
$table->string("Currency",3);
|
||||
$table->decimal("TimeSlotCost", 9, 2)->setDefault('0.00');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Schema $schema
|
||||
*/
|
||||
public function down(Schema $schema)
|
||||
{
|
||||
$sql = <<<SQL
|
||||
ALTER TABLE SummitAbstractLocation MODIFY ClassName enum('SummitAbstractLocation', 'SummitGeoLocatedLocation', 'SummitExternalLocation', 'SummitAirport', 'SummitHotel', 'SummitVenue', 'SummitVenueRoom') DEFAULT 'SummitAbstractLocation';
|
||||
SQL;
|
||||
$builder = new Builder($schema);
|
||||
$this->addSql($sql);
|
||||
|
||||
$builder->drop('SummitBookableVenueRoom');
|
||||
}
|
||||
}
|
64
database/migrations/model/Version20190529142927.php
Normal file
64
database/migrations/model/Version20190529142927.php
Normal file
@ -0,0 +1,64 @@
|
||||
<?php namespace Database\Migrations\Model;
|
||||
/**
|
||||
* Copyright 2019 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.
|
||||
**/
|
||||
use Doctrine\Migrations\AbstractMigration;
|
||||
use Doctrine\DBAL\Schema\Schema as Schema;
|
||||
use LaravelDoctrine\Migrations\Schema\Table;
|
||||
use LaravelDoctrine\Migrations\Schema\Builder;
|
||||
/**
|
||||
* Class Version20190529142927
|
||||
* @package Database\Migrations\Model
|
||||
*/
|
||||
class Version20190529142927 extends AbstractMigration
|
||||
{
|
||||
/**
|
||||
* @param Schema $schema
|
||||
*/
|
||||
public function up(Schema $schema)
|
||||
{
|
||||
$builder = new Builder($schema);
|
||||
if(!$schema->hasTable("SummitRoomReservation")) {
|
||||
$builder->create('SummitRoomReservation', function (Table $table) {
|
||||
$table->integer("ID", true, false);
|
||||
$table->primary("ID");
|
||||
$table->string('ClassName')->setDefault("SummitRoomReservation");
|
||||
$table->index("ClassName", "ClassName");
|
||||
$table->timestamp('Created');
|
||||
$table->timestamp('LastEdited');
|
||||
$table->timestamp('ApprovedPaymentDate')->setNotnull(false);
|
||||
$table->timestamp('StartDateTime')->setNotnull(false);
|
||||
$table->timestamp('EndDateTime')->setNotnull(false);
|
||||
$table->string("Status");
|
||||
$table->string("LastError");
|
||||
$table->string("PaymentGatewayCartId", 512);
|
||||
$table->decimal("Amount", 9, 2)->setDefault('0.00');
|
||||
$table->string("Currency", 3);
|
||||
$table->index("PaymentGatewayCartId", "PaymentGatewayCartId");
|
||||
$table->integer("OwnerID", false, false)->setNotnull(false);
|
||||
$table->index("OwnerID", "OwnerID");
|
||||
//$table->foreign("Member", "OwnerID", "ID");
|
||||
$table->integer("RoomID", false, false)->setNotnull(false);
|
||||
$table->index("RoomID", "RoomID");
|
||||
//$table->foreign("SummitBookableVenueRoom", "RoomID", "ID");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Schema $schema
|
||||
*/
|
||||
public function down(Schema $schema)
|
||||
{
|
||||
(new Builder($schema))->drop('SummitRoomReservation');
|
||||
}
|
||||
}
|
42
database/migrations/model/Version20190530205326.php
Normal file
42
database/migrations/model/Version20190530205326.php
Normal file
@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Migrations\Model;
|
||||
|
||||
use Doctrine\Migrations\AbstractMigration;
|
||||
use Doctrine\DBAL\Schema\Schema as Schema;
|
||||
use LaravelDoctrine\Migrations\Schema\Table;
|
||||
use LaravelDoctrine\Migrations\Schema\Builder;
|
||||
|
||||
class Version20190530205326 extends AbstractMigration
|
||||
{
|
||||
/**
|
||||
* @param Schema $schema
|
||||
*/
|
||||
public function up(Schema $schema)
|
||||
{
|
||||
$builder = new Builder($schema);
|
||||
if(!$schema->hasTable("SummitBookableVenueRoomAttributeType")) {
|
||||
$builder->create('SummitBookableVenueRoomAttributeType', function (Table $table) {
|
||||
$table->integer("ID", true, false);
|
||||
$table->primary("ID");
|
||||
$table->string('ClassName')->setDefault("SummitBookableVenueRoomAttributeType");
|
||||
$table->index("ClassName", "ClassName");
|
||||
$table->timestamp('Created');
|
||||
$table->timestamp('LastEdited');
|
||||
$table->string("Type", 255);
|
||||
$table->index("Type", "Type");
|
||||
$table->integer("SummitID", false, false)->setNotnull(false);
|
||||
$table->index("SummitID", "SummitID");
|
||||
$table->unique(["SummitID", "Type"], "SummitID_Type");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Schema $schema
|
||||
*/
|
||||
public function down(Schema $schema)
|
||||
{
|
||||
(new Builder($schema))->drop('BookableSummitVenueRoomAttributeType');
|
||||
}
|
||||
}
|
56
database/migrations/model/Version20190530205344.php
Normal file
56
database/migrations/model/Version20190530205344.php
Normal file
@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Migrations\Model;
|
||||
|
||||
use Doctrine\Migrations\AbstractMigration;
|
||||
use Doctrine\DBAL\Schema\Schema as Schema;
|
||||
use LaravelDoctrine\Migrations\Schema\Table;
|
||||
use LaravelDoctrine\Migrations\Schema\Builder;
|
||||
|
||||
class Version20190530205344 extends AbstractMigration
|
||||
{
|
||||
/**
|
||||
* @param Schema $schema
|
||||
*/
|
||||
public function up(Schema $schema)
|
||||
{
|
||||
|
||||
$builder = new Builder($schema);
|
||||
if(!$schema->hasTable("SummitBookableVenueRoomAttributeValue")) {
|
||||
$builder->create('SummitBookableVenueRoomAttributeValue', function (Table $table) {
|
||||
$table->integer("ID", true, false);
|
||||
$table->primary("ID");
|
||||
$table->string('ClassName')->setDefault("SummitBookableVenueRoomAttributeValue");
|
||||
$table->index("ClassName", "ClassName");
|
||||
$table->timestamp('Created');
|
||||
$table->timestamp('LastEdited');
|
||||
$table->string("Value", 255);
|
||||
$table->index("Value", "Value");
|
||||
$table->integer("TypeID", false, false)->setNotnull(false);
|
||||
$table->index("TypeID", "TypeID");
|
||||
$table->unique(["TypeID", "Value"], "TypeID_Value");
|
||||
});
|
||||
}
|
||||
|
||||
if(!$schema->hasTable("SummitBookableVenueRoom_Attributes")) {
|
||||
$builder->create('SummitBookableVenueRoom_Attributes', function (Table $table) {
|
||||
$table->integer("ID", true, false);
|
||||
$table->primary("ID");
|
||||
$table->integer("SummitBookableVenueRoomID", false, false)->setNotnull(false)->setDefault(0);
|
||||
$table->index("SummitBookableVenueRoomID", "SummitBookableVenueRoomID");
|
||||
$table->integer("SummitBookableVenueRoomAttributeValueID", false, false)->setNotnull(false)->setDefault(0);
|
||||
$table->index("SummitBookableVenueRoomAttributeValueID", "SummitBookableVenueRoomAttributeValueID");
|
||||
$table->unique(["SummitBookableVenueRoomID", "SummitBookableVenueRoomAttributeValueID"], "RoomID_ValueID");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Schema $schema
|
||||
*/
|
||||
public function down(Schema $schema)
|
||||
{
|
||||
(new Builder($schema))->drop('SummitBookableVenueRoomAttributeValue');
|
||||
(new Builder($schema))->drop('SummitBookableVenueRoom_Attributes');
|
||||
}
|
||||
}
|
@ -93,6 +93,15 @@ class ApiEndpointsSeeder extends Seeder
|
||||
sprintf(SummitScopes::ReadAllSummitData, $current_realm)
|
||||
],
|
||||
],
|
||||
[
|
||||
'name' => 'get-summits-all-by-id-slug',
|
||||
'route' => '/api/v1/summits/all/{id}',
|
||||
'http_method' => 'GET',
|
||||
'scopes' => [
|
||||
sprintf(SummitScopes::ReadAllSummitData, $current_realm),
|
||||
sprintf(SummitScopes::ReadBookableRoomsData, $current_realm),
|
||||
],
|
||||
],
|
||||
[
|
||||
'name' => 'get-summit-cached',
|
||||
'route' => '/api/v1/summits/{id}',
|
||||
@ -1050,6 +1059,85 @@ class ApiEndpointsSeeder extends Seeder
|
||||
sprintf(SummitScopes::WriteLocationsData, $current_realm)
|
||||
],
|
||||
],
|
||||
// bookable rooms
|
||||
[
|
||||
'name' => 'get-bookable-venue-rooms',
|
||||
'route' => '/api/v1/summits/{id}/locations/bookable-rooms',
|
||||
'http_method' => 'GET',
|
||||
'scopes' => [
|
||||
sprintf(SummitScopes::ReadBookableRoomsData, $current_realm),
|
||||
sprintf(SummitScopes::ReadAllSummitData, $current_realm)
|
||||
],
|
||||
],
|
||||
[
|
||||
'name' => 'get-bookable-venue-room',
|
||||
'route' => '/api/v1/summits/{id}/locations/bookable-rooms/{room_id}',
|
||||
'http_method' => 'GET',
|
||||
'scopes' => [
|
||||
sprintf(SummitScopes::ReadBookableRoomsData, $current_realm),
|
||||
sprintf(SummitScopes::ReadAllSummitData, $current_realm)
|
||||
],
|
||||
],
|
||||
[
|
||||
'name' => 'get-bookable-venue-room-availability',
|
||||
'route' => '/api/v1/summits/{id}/locations/bookable-rooms/{room_id}/availability/{day}',
|
||||
'http_method' => 'GET',
|
||||
'scopes' => [
|
||||
sprintf(SummitScopes::ReadBookableRoomsData, $current_realm),
|
||||
sprintf(SummitScopes::ReadAllSummitData, $current_realm)
|
||||
],
|
||||
],
|
||||
[
|
||||
'name' => 'get-my-bookable-venue-room-reservations',
|
||||
'route' => '/api/v1/summits/{id}/locations/bookable-rooms/all/reservations/me',
|
||||
'http_method' => 'GET',
|
||||
'scopes' => [
|
||||
sprintf(SummitScopes::ReadMyBookableRoomsReservationData, $current_realm),
|
||||
],
|
||||
],
|
||||
[
|
||||
'name' => 'cancel-my-bookable-venue-room-reservation',
|
||||
'route' => '/api/v1/summits/{id}/locations/bookable-rooms/all/reservations/{reservation_id}',
|
||||
'http_method' => 'DELETE',
|
||||
'scopes' => [
|
||||
sprintf(SummitScopes::WriteMyBookableRoomsReservationData, $current_realm),
|
||||
],
|
||||
],
|
||||
[
|
||||
'name' => 'create-bookable-venue-room-reservation',
|
||||
'route' => '/api/v1/summits/{id}/locations/bookable-rooms/{room_id}/reservations',
|
||||
'http_method' => 'POST',
|
||||
'scopes' => [
|
||||
sprintf(SummitScopes::WriteMyBookableRoomsReservationData, $current_realm),
|
||||
],
|
||||
],
|
||||
[
|
||||
'name' => 'add-bookable-venue-room',
|
||||
'route' => '/api/v1/summits/{id}/locations/venues/{venue_id}/bookable-rooms',
|
||||
'http_method' => 'POST',
|
||||
'scopes' => [
|
||||
sprintf(SummitScopes::WriteSummitData, $current_realm),
|
||||
sprintf(SummitScopes::WriteBookableRoomsData, $current_realm),
|
||||
],
|
||||
],
|
||||
[
|
||||
'name' => 'update-bookable-venue-room',
|
||||
'route' => '/api/v1/summits/{id}/locations/venues/{venue_id}/bookable-rooms/{room_id}',
|
||||
'http_method' => 'PUT',
|
||||
'scopes' => [
|
||||
sprintf(SummitScopes::WriteSummitData, $current_realm),
|
||||
sprintf(SummitScopes::WriteBookableRoomsData, $current_realm),
|
||||
],
|
||||
],
|
||||
[
|
||||
'name' => 'delete-bookable-venue-room',
|
||||
'route' => '/api/v1/summits/{id}/locations/venues/{venue_id}/bookable-rooms/{room_id}',
|
||||
'http_method' => 'DELETE',
|
||||
'scopes' => [
|
||||
sprintf(SummitScopes::WriteSummitData, $current_realm),
|
||||
sprintf(SummitScopes::WriteBookableRoomsData, $current_realm),
|
||||
],
|
||||
],
|
||||
// floor rooms
|
||||
[
|
||||
'name' => 'get-venue-floor-room',
|
||||
|
@ -186,6 +186,16 @@ final class ApiScopesSeeder extends Seeder
|
||||
'short_description' => 'Write Summit Presentation Materials Data',
|
||||
'description' => 'Grants write access for Summit Materials Links Data',
|
||||
],
|
||||
[
|
||||
'name' => sprintf(SummitScopes::ReadMyBookableRoomsReservationData, $current_realm),
|
||||
'short_description' => 'Read my bookable rooms reservations',
|
||||
'description' => 'Read my bookable rooms reservations',
|
||||
],
|
||||
[
|
||||
'name' => sprintf(SummitScopes::WriteMyBookableRoomsReservationData, $current_realm),
|
||||
'short_description' => 'Write my bookable rooms reservations',
|
||||
'description' => 'Write my bookable rooms reservations',
|
||||
],
|
||||
];
|
||||
|
||||
foreach ($scopes as $scope_info) {
|
||||
|
53
tests/MeetingRoomTest.php
Normal file
53
tests/MeetingRoomTest.php
Normal file
@ -0,0 +1,53 @@
|
||||
<?php namespace Tests;
|
||||
/**
|
||||
* Copyright 2019 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.
|
||||
**/
|
||||
use LaravelDoctrine\ORM\Facades\EntityManager;
|
||||
use Illuminate\Support\Facades\Redis;
|
||||
use models\summit\Summit;
|
||||
/**
|
||||
* Class MeetingRoomTest
|
||||
* @package Tests
|
||||
*/
|
||||
class MeetingRoomTest extends TestCase
|
||||
{
|
||||
use CreatesApplication;
|
||||
|
||||
private $redis;
|
||||
|
||||
/**
|
||||
* The base URL to use while testing the application.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $baseUrl = 'http://localhost';
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
parent::setUp(); // Don't forget this!
|
||||
$this->redis = Redis::connection();
|
||||
$this->redis->flushall();
|
||||
$this->createApplication();
|
||||
}
|
||||
|
||||
public function testMeetingRoomsAvalableSlots(){
|
||||
$repository = EntityManager::getRepository(Summit::class);
|
||||
$summit = $repository->getBySlug('shanghai-2019');
|
||||
$rooms = $summit->getBookableRooms();
|
||||
$this->assertTrue(count($rooms) > 0);
|
||||
|
||||
$room = $rooms[0];
|
||||
|
||||
$room->getAvailableSlots(new \DateTime("2019-11-05"));
|
||||
}
|
||||
|
||||
}
|
@ -1350,4 +1350,181 @@ final class OAuth2SummitLocationsApiTest extends ProtectedApiTest
|
||||
$content = $response->getContent();
|
||||
$this->assertResponseStatus(204);
|
||||
}
|
||||
|
||||
// bookable rooms tests
|
||||
|
||||
public function testSummitGetBookableRoomsORFilter($summit_id = 27)
|
||||
{
|
||||
$params = [
|
||||
'id' => $summit_id,
|
||||
'page' => 1,
|
||||
'per_page' => 10,
|
||||
'order' => '-id',
|
||||
'expand' => 'venue,attribute_type',
|
||||
'filter' => [
|
||||
"attribute==Ocean,attribute==Microwave",
|
||||
"availability_day==1572912000",
|
||||
],
|
||||
];
|
||||
|
||||
$headers =
|
||||
[
|
||||
"HTTP_Authorization" => " Bearer " . $this->access_token,
|
||||
"CONTENT_TYPE" => "application/json"
|
||||
];
|
||||
|
||||
$response = $this->action
|
||||
(
|
||||
"GET",
|
||||
"OAuth2SummitLocationsApiController@getBookableVenueRooms",
|
||||
$params,
|
||||
[],
|
||||
[],
|
||||
[],
|
||||
$headers
|
||||
);
|
||||
|
||||
$content = $response->getContent();
|
||||
$this->assertResponseStatus(200);
|
||||
|
||||
$rooms = json_decode($content);
|
||||
$this->assertTrue(!is_null($rooms));
|
||||
}
|
||||
|
||||
public function testSummitGetBookableRoomAvailability($summit_id = 27, $room_id = 483, $day = 1572912000)
|
||||
{
|
||||
$params = [
|
||||
'id' => $summit_id,
|
||||
'room_id' => $room_id,
|
||||
'day' => $day,
|
||||
];
|
||||
|
||||
$headers =
|
||||
[
|
||||
"HTTP_Authorization" => " Bearer " . $this->access_token,
|
||||
"CONTENT_TYPE" => "application/json"
|
||||
];
|
||||
|
||||
$response = $this->action
|
||||
(
|
||||
"GET",
|
||||
"OAuth2SummitLocationsApiController@getBookableVenueRoomAvailability",
|
||||
$params,
|
||||
[],
|
||||
[],
|
||||
[],
|
||||
$headers
|
||||
);
|
||||
|
||||
$content = $response->getContent();
|
||||
$this->assertResponseStatus(200);
|
||||
|
||||
$slots = json_decode($content);
|
||||
$this->assertTrue(!is_null($slots));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $summit_id
|
||||
* @param int $room_id
|
||||
* @param int $start_date
|
||||
* @return mixed
|
||||
*/
|
||||
public function testBookableRoomReservation($summit_id =27, $room_id = 483, $start_date = 1572883200, $end_date = 1572886800){
|
||||
$params = [
|
||||
'id' => $summit_id,
|
||||
'room_id' => $room_id,
|
||||
];
|
||||
|
||||
$data = [
|
||||
'currency' => 'USD',
|
||||
'amount' => 325,
|
||||
'start_datetime' => $start_date,
|
||||
'end_datetime' => $end_date,
|
||||
];
|
||||
|
||||
$headers = [
|
||||
"HTTP_Authorization" => " Bearer " . $this->access_token,
|
||||
"CONTENT_TYPE" => "application/json"
|
||||
];
|
||||
|
||||
$response = $this->action(
|
||||
"POST",
|
||||
"OAuth2SummitLocationsApiController@createBookableVenueRoomReservation",
|
||||
$params,
|
||||
[],
|
||||
[],
|
||||
[],
|
||||
$headers,
|
||||
json_encode($data)
|
||||
);
|
||||
|
||||
$content = $response->getContent();
|
||||
$this->assertResponseStatus(201);
|
||||
$reservation = json_decode($content);
|
||||
$this->assertTrue(!is_null($reservation));
|
||||
return $reservation;
|
||||
}
|
||||
|
||||
public function testGetMyReservations($summit_id = 27)
|
||||
{
|
||||
$params = [
|
||||
'id' => $summit_id,
|
||||
'expand' => 'room'
|
||||
];
|
||||
|
||||
$headers =
|
||||
[
|
||||
"HTTP_Authorization" => " Bearer " . $this->access_token,
|
||||
"CONTENT_TYPE" => "application/json"
|
||||
];
|
||||
|
||||
$response = $this->action
|
||||
(
|
||||
"GET",
|
||||
"OAuth2SummitLocationsApiController@getMyBookableVenueRoomReservations",
|
||||
$params,
|
||||
[],
|
||||
[],
|
||||
[],
|
||||
$headers
|
||||
);
|
||||
|
||||
$content = $response->getContent();
|
||||
$this->assertResponseStatus(200);
|
||||
|
||||
$reservations = json_decode($content);
|
||||
$this->assertTrue(!is_null($reservations));
|
||||
}
|
||||
|
||||
public function testCancelMyReservations($summit_id = 27, $reservation_id = 4)
|
||||
{
|
||||
$params = [
|
||||
'id' => $summit_id,
|
||||
'reservation_id' => $reservation_id
|
||||
];
|
||||
|
||||
$headers =
|
||||
[
|
||||
"HTTP_Authorization" => " Bearer " . $this->access_token,
|
||||
"CONTENT_TYPE" => "application/json"
|
||||
];
|
||||
|
||||
$response = $this->action
|
||||
(
|
||||
"DELETE",
|
||||
"OAuth2SummitLocationsApiController@cancelMyBookableVenueRoomReservation",
|
||||
$params,
|
||||
[],
|
||||
[],
|
||||
[],
|
||||
$headers
|
||||
);
|
||||
|
||||
$content = $response->getContent();
|
||||
$this->assertResponseStatus(200);
|
||||
|
||||
$reservations = json_decode($content);
|
||||
$this->assertTrue(!is_null($reservations));
|
||||
}
|
||||
|
||||
}
|
@ -67,6 +67,8 @@ class AccessTokenServiceStub implements IAccessTokenService
|
||||
sprintf(OrganizationScopes::WriteOrganizationData, $url),
|
||||
sprintf(OrganizationScopes::ReadOrganizationData, $url),
|
||||
sprintf(SummitScopes::WritePresentationMaterialsData, $url),
|
||||
sprintf(SummitScopes::ReadMyBookableRoomsReservationData, $url),
|
||||
sprintf(SummitScopes::WriteMyBookableRoomsReservationData, $url),
|
||||
);
|
||||
|
||||
return AccessToken::createFromParams('123456789', implode(' ', $scopes), '1', $realm, '1','11624', 3600, 'WEB_APPLICATION', '', '');
|
||||
@ -119,6 +121,8 @@ class AccessTokenServiceStub2 implements IAccessTokenService
|
||||
sprintf(OrganizationScopes::WriteOrganizationData, $url),
|
||||
sprintf(OrganizationScopes::ReadOrganizationData, $url),
|
||||
sprintf(SummitScopes::WritePresentationMaterialsData, $url),
|
||||
sprintf(SummitScopes::ReadMyBookableRoomsReservationData, $url),
|
||||
sprintf(SummitScopes::WriteMyBookableRoomsReservationData, $url),
|
||||
);
|
||||
|
||||
return AccessToken::createFromParams('123456789', implode(' ', $scopes), '1', $realm, null,null, 3600, 'SERVICE', '', '');
|
||||
|
Loading…
x
Reference in New Issue
Block a user