Merge "Activate/Deactive Ticket"
This commit is contained in:
commit
d4b350a5ad
@ -900,7 +900,8 @@ final class OAuth2SummitOrdersApiController
|
||||
public function getTicketByHash($hash){
|
||||
try {
|
||||
$ticket = $this->service->getTicketByHash($hash);
|
||||
|
||||
if(is_null($ticket) || !$ticket->isActive())
|
||||
throw new EntityNotFoundException();
|
||||
return $this->ok(SerializerRegistry::getInstance()->getSerializer($ticket, ISummitAttendeeTicketSerializerTypes::PublicEdition)->serialize(Request::input('expand', '')));
|
||||
}
|
||||
catch (ValidationException $ex) {
|
||||
@ -1207,4 +1208,65 @@ final class OAuth2SummitOrdersApiController
|
||||
return $this->error500($ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $summit_id
|
||||
* @param $order_id
|
||||
* @param $ticket_id
|
||||
* @return \Illuminate\Http\JsonResponse|mixed
|
||||
*/
|
||||
public function activateTicket($summit_id, $order_id, $ticket_id){
|
||||
try {
|
||||
$summit = SummitFinderStrategyFactory::build($this->summit_repository, $this->getResourceServerContext())->find($summit_id);
|
||||
if (is_null($summit)) return $this->error404();
|
||||
|
||||
$ticket = $this->service->activateTicket($summit, intval($order_id), intval($ticket_id));
|
||||
return $this->updated(SerializerRegistry::getInstance()->getSerializer($ticket, ISummitAttendeeTicketSerializerTypes::AdminType)->serialize( Request::input('expand', '')));
|
||||
|
||||
}
|
||||
catch(\InvalidArgumentException $ex){
|
||||
Log::warning($ex);
|
||||
return $this->error400();
|
||||
}
|
||||
catch (ValidationException $ex) {
|
||||
Log::warning($ex);
|
||||
return $this->error412($ex->getMessages());
|
||||
}
|
||||
catch(EntityNotFoundException $ex)
|
||||
{
|
||||
Log::warning($ex);
|
||||
return $this->error404(array('message'=> $ex->getMessage()));
|
||||
}
|
||||
catch (Exception $ex) {
|
||||
Log::error($ex);
|
||||
return $this->error500($ex);
|
||||
}
|
||||
}
|
||||
|
||||
public function deActivateTicket($summit_id, $order_id, $ticket_id){
|
||||
try {
|
||||
$summit = SummitFinderStrategyFactory::build($this->summit_repository, $this->getResourceServerContext())->find($summit_id);
|
||||
if (is_null($summit)) return $this->error404();
|
||||
$ticket = $this->service->deActivateTicket($summit, intval($order_id), intval($ticket_id));
|
||||
return $this->updated(SerializerRegistry::getInstance()->getSerializer($ticket, ISummitAttendeeTicketSerializerTypes::AdminType)->serialize( Request::input('expand', '')));
|
||||
|
||||
}
|
||||
catch(\InvalidArgumentException $ex){
|
||||
Log::warning($ex);
|
||||
return $this->error400();
|
||||
}
|
||||
catch (ValidationException $ex) {
|
||||
Log::warning($ex);
|
||||
return $this->error412($ex->getMessages());
|
||||
}
|
||||
catch(EntityNotFoundException $ex)
|
||||
{
|
||||
Log::warning($ex);
|
||||
return $this->error404(array('message'=> $ex->getMessage()));
|
||||
}
|
||||
catch (Exception $ex) {
|
||||
Log::error($ex);
|
||||
return $this->error500($ex);
|
||||
}
|
||||
}
|
||||
}
|
@ -435,6 +435,7 @@ final class OAuth2SummitTicketApiController extends OAuth2ProtectedController
|
||||
function($filter) use($owner){
|
||||
if($filter instanceof Filter){
|
||||
$filter->addFilterCondition(FilterElement::makeEqual('member_id', $owner->getId()));
|
||||
$filter->addFilterCondition(FilterElement::makeEqual('is_active', true));
|
||||
}
|
||||
return $filter;
|
||||
},
|
||||
|
@ -886,6 +886,10 @@ Route::group([
|
||||
Route::post('', [ 'middleware' => 'auth.user', 'uses' =>'OAuth2SummitOrdersApiController@addTicket']);
|
||||
Route::group(['prefix' => '{ticket_id}'], function () {
|
||||
Route::put('', [ 'middleware' => 'auth.user', 'uses' =>'OAuth2SummitOrdersApiController@updateTicket']);
|
||||
Route::group(['prefix' => 'activate'], function () {
|
||||
Route::put('', [ 'middleware' => 'auth.user', 'uses' =>'OAuth2SummitOrdersApiController@activateTicket']);
|
||||
Route::delete('', [ 'middleware' => 'auth.user', 'uses' =>'OAuth2SummitOrdersApiController@deActivateTicket']);
|
||||
});
|
||||
Route::get('pdf', [ 'middleware' => 'auth.user', 'uses' =>'OAuth2SummitOrdersApiController@getTicketPDFBySummit']);
|
||||
});
|
||||
});
|
||||
|
@ -37,6 +37,7 @@ class BaseSummitAttendeeTicketSerializer extends SilverStripeSerializer
|
||||
'Discount' => 'discount:json_float',
|
||||
'RefundedAmount' => 'refunded_amount:json_float',
|
||||
'Currency' => 'currency:json_string',
|
||||
'Active' => 'is_active:json_bool',
|
||||
];
|
||||
|
||||
protected static $allowed_relations = [
|
||||
|
@ -46,6 +46,7 @@ final class SummitAttendeeTicketCSVSerializer extends SilverStripeSerializer
|
||||
'Currency' => 'currency:json_string',
|
||||
'BadgeTypeId' => 'badge_type_id:json_int',
|
||||
'BadgeTypeName' => 'badge_type_name:json_string',
|
||||
'Active' => 'is_active:json_bool',
|
||||
];
|
||||
|
||||
/**
|
||||
|
@ -1805,7 +1805,7 @@ LEFT JOIN Member ON Member.ID = SummitAttendee.MemberID
|
||||
WHERE
|
||||
( Member.ID = :member_id OR SummitAttendee.Email = :member_email) AND
|
||||
SummitAttendee.SummitID = :summit_id AND
|
||||
SummitAttendeeTicket.Status = :ticket_status
|
||||
SummitAttendeeTicket.Status = :ticket_status AND SummitAttendeeTicket.IsActive = 1
|
||||
SQL;
|
||||
|
||||
$stmt = $this->prepareRawSQL($sql);
|
||||
@ -1841,13 +1841,14 @@ SQL;
|
||||
JOIN o.summit su
|
||||
WHERE su.id = :summit_id
|
||||
and ( m.id = :member_id or o.email = :member_email)
|
||||
and t.status = :ticket_status");
|
||||
and t.status = :ticket_status and t.is_active = :active");
|
||||
|
||||
return $query
|
||||
->setParameter('member_id', $this->getId())
|
||||
->setParameter('member_email', $this->email)
|
||||
->setParameter('ticket_status', IOrderConstants::PaidStatus)
|
||||
->setParameter('summit_id', $summit->getId())
|
||||
->setParameter('active', true)
|
||||
->getResult();
|
||||
}
|
||||
|
||||
|
@ -369,6 +369,10 @@ class SummitAttendee extends SilverstripeBaseModel
|
||||
public function sendInvitationEmail(SummitAttendeeTicket $ticket, bool $overrideTicketOwnerIsSameAsOrderOwnerRule = false){
|
||||
Log::debug(sprintf("SummitAttendee::sendInvitationEmail attendee %s", $this->getEmail()));
|
||||
if($ticket->getOwnerEmail() != $this->getEmail()) return;
|
||||
if(!$ticket->isActive()){
|
||||
Log::warning(sprintf("SummitAttendee::sendInvitationEmail attendee %s ticket is not active", $this->getEmail()));
|
||||
return;
|
||||
}
|
||||
$this->updateStatus();
|
||||
if($this->isComplete()) {
|
||||
Log::debug(sprintf("SummitAttendee::sendInvitationEmail attendee %s is complete", $this->getEmail()));
|
||||
|
@ -159,6 +159,12 @@ class SummitAttendeeTicket extends SilverstripeBaseModel
|
||||
*/
|
||||
private $former_hashes;
|
||||
|
||||
/**
|
||||
* @ORM\Column(name="IsActive", type="boolean")
|
||||
* @var bool
|
||||
*/
|
||||
private $is_active;
|
||||
|
||||
/**
|
||||
* SummitAttendeeTicket constructor.
|
||||
*/
|
||||
@ -172,6 +178,7 @@ class SummitAttendeeTicket extends SilverstripeBaseModel
|
||||
$this->raw_cost = 0.0;
|
||||
$this->discount = 0.0;
|
||||
$this->refunded_amount = 0.0;
|
||||
$this->is_active = true;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -936,4 +943,23 @@ class SummitAttendeeTicket extends SilverstripeBaseModel
|
||||
// i am order owner
|
||||
if($this->order->getOwnerEmail() == $member->getEmail()) return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isActive(): bool
|
||||
{
|
||||
return $this->is_active;
|
||||
}
|
||||
|
||||
public function activate(): void
|
||||
{
|
||||
$this->is_active = true;
|
||||
}
|
||||
|
||||
public function deActivate(): void
|
||||
{
|
||||
$this->is_active = false;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -39,6 +39,7 @@ final class DoctrineSummitAttendeeTicketRepository
|
||||
{
|
||||
return [
|
||||
'number' => 'e.number:json_string',
|
||||
'is_active' => 'e.is_active',
|
||||
'order_number' => 'o.number:json_string',
|
||||
'owner_name' => [
|
||||
"concat(m.first_name, ' ', m.last_name) :operator :value",
|
||||
|
@ -113,6 +113,25 @@ interface ISummitOrderService extends IProcessPaymentService
|
||||
*/
|
||||
public function updateTicket(Summit $summit, int $order_id, int $ticket_id, array $payload):SummitAttendeeTicket;
|
||||
|
||||
/**
|
||||
* @param Summit $summit
|
||||
* @param int $order_id
|
||||
* @param int $ticket_id
|
||||
* @return SummitAttendeeTicket
|
||||
* @throws EntityNotFoundException
|
||||
* @throws ValidationException
|
||||
*/
|
||||
public function activateTicket(Summit $summit, int $order_id, int $ticket_id):SummitAttendeeTicket;
|
||||
|
||||
/**
|
||||
* @param Summit $summit
|
||||
* @param int $order_id
|
||||
* @param int $ticket_id
|
||||
* @return SummitAttendeeTicket
|
||||
* @throws EntityNotFoundException
|
||||
* @throws ValidationException
|
||||
*/
|
||||
public function deActivateTicket(Summit $summit, int $order_id, int $ticket_id):SummitAttendeeTicket;
|
||||
/**
|
||||
* @param Member $current_user
|
||||
* @param int $order_id
|
||||
|
@ -2473,7 +2473,7 @@ final class SummitOrderService
|
||||
|
||||
$ticket = $this->ticket_repository->getByHashExclusiveLock($hash);
|
||||
|
||||
if (is_null($ticket))
|
||||
if (is_null($ticket) && !$ticket->isActive())
|
||||
throw new EntityNotFoundException("ticket not found");
|
||||
|
||||
if (!$ticket->isPaid())
|
||||
@ -2532,7 +2532,7 @@ final class SummitOrderService
|
||||
return $this->tx_service->transaction(function () use ($current_user, $ticket_id, $payload) {
|
||||
$ticket = $this->ticket_repository->getByIdExclusiveLock($ticket_id);
|
||||
|
||||
if (is_null($ticket) || !$ticket instanceof SummitAttendeeTicket)
|
||||
if (is_null($ticket) || !$ticket instanceof SummitAttendeeTicket || !$ticket->isActive())
|
||||
throw new EntityNotFoundException("ticket not found");
|
||||
|
||||
if (!$ticket->canEditTicket($current_user)) {
|
||||
@ -2796,7 +2796,12 @@ final class SummitOrderService
|
||||
}
|
||||
|
||||
if (!is_null($ticket) && !$ticket->isPaid()) {
|
||||
Log::debug("SummitOrderService::processTicketData - ticket is not paid");
|
||||
Log::warning("SummitOrderService::processTicketData - ticket is not paid");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!is_null($ticket) && !$ticket->isActive()) {
|
||||
Log::warning("SummitOrderService::processTicketData - ticket is not active");
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -3063,6 +3068,10 @@ final class SummitOrderService
|
||||
}
|
||||
foreach ($order->getTickets() as $ticket) {
|
||||
try {
|
||||
if(!$ticket->isActive()){
|
||||
Log::warning(sprintf("SummitOrderService::processSummitOrderReminders - summit %s order %s skipping ticket %s ( not active)", $summit->getId(), $order->getId(), $ticket->getId()));
|
||||
continue;
|
||||
}
|
||||
$this->processTicketReminder($ticket);
|
||||
} catch (\Exception $ex) {
|
||||
Log::error($ex);
|
||||
@ -3097,6 +3106,10 @@ final class SummitOrderService
|
||||
$needs_action = false;
|
||||
|
||||
foreach ($order->getTickets() as $ticket) {
|
||||
if(!$ticket->isActive()){
|
||||
Log::warning(sprintf("SummitOrderService::processOrderReminder - order %s skipping ticket %s ( NOT ACTIVE ).", $order->getId(), $ticket->getId()));
|
||||
continue;
|
||||
}
|
||||
if (!$ticket->hasOwner()) {
|
||||
$needs_action = true;
|
||||
break;
|
||||
@ -3373,4 +3386,50 @@ final class SummitOrderService
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function activateTicket(Summit $summit, int $order_id, int $ticket_id): SummitAttendeeTicket
|
||||
{
|
||||
return $this->tx_service->transaction(function() use($summit, $order_id, $ticket_id){
|
||||
// lock and get the order
|
||||
$order = $this->order_repository->getByIdExclusiveLock($order_id);
|
||||
|
||||
if (is_null($order) || !$order instanceof SummitOrder)
|
||||
throw new EntityNotFoundException("order not found");
|
||||
|
||||
$ticket = $order->getTicketById($ticket_id);
|
||||
|
||||
if (is_null($ticket))
|
||||
throw new EntityNotFoundException("ticket not found");
|
||||
|
||||
$ticket->activate();
|
||||
|
||||
return $ticket;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function deActivateTicket(Summit $summit, int $order_id, int $ticket_id): SummitAttendeeTicket
|
||||
{
|
||||
return $this->tx_service->transaction(function() use($summit, $order_id, $ticket_id){
|
||||
// lock and get the order
|
||||
$order = $this->order_repository->getByIdExclusiveLock($order_id);
|
||||
|
||||
if (is_null($order) || !$order instanceof SummitOrder)
|
||||
throw new EntityNotFoundException("order not found");
|
||||
|
||||
$ticket = $order->getTicketById($ticket_id);
|
||||
|
||||
if (is_null($ticket))
|
||||
throw new EntityNotFoundException("ticket not found");
|
||||
|
||||
$ticket->deActivate();
|
||||
|
||||
return $ticket;
|
||||
});
|
||||
}
|
||||
}
|
50
database/migrations/model/Version20210422150202.php
Normal file
50
database/migrations/model/Version20210422150202.php
Normal file
@ -0,0 +1,50 @@
|
||||
<?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\Builder;
|
||||
use LaravelDoctrine\Migrations\Schema\Table;
|
||||
|
||||
/**
|
||||
* Class Version20210422150202
|
||||
* @package Database\Migrations\Model
|
||||
*/
|
||||
final class Version20210422150202 extends AbstractMigration
|
||||
{
|
||||
/**
|
||||
* @param Schema $schema
|
||||
*/
|
||||
public function up(Schema $schema):void
|
||||
{
|
||||
$builder = new Builder($schema);
|
||||
if($schema->hasTable("SummitAttendeeTicket")) {
|
||||
$builder->table('SummitAttendeeTicket', function (Table $table) {
|
||||
$table->boolean("IsActive")->setDefault(true)->setNotnull(true);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Schema $schema
|
||||
*/
|
||||
public function down(Schema $schema):void
|
||||
{
|
||||
$builder = new Builder($schema);
|
||||
if($schema->hasTable("SummitAttendeeTicket")) {
|
||||
$builder->table('SummitAttendeeTicket', function (Table $table) {
|
||||
$table->dropColumn("IsActive");
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
@ -615,6 +615,36 @@ class ApiEndpointsSeeder extends Seeder
|
||||
IGroup::SummitRegistrationAdmins
|
||||
]
|
||||
],
|
||||
[
|
||||
'name' => 'activate-ticket',
|
||||
'route' => '/api/v1/summits/{id}/orders/{order_id}/tickets/{ticket_id}/activate',
|
||||
'http_method' => 'PUT',
|
||||
'scopes' => [
|
||||
sprintf(SummitScopes::WriteSummitData, $current_realm),
|
||||
sprintf(SummitScopes::UpdateRegistrationOrders, $current_realm),
|
||||
],
|
||||
'authz_groups' => [
|
||||
IGroup::SuperAdmins,
|
||||
IGroup::Administrators,
|
||||
IGroup::SummitAdministrators,
|
||||
IGroup::SummitRegistrationAdmins
|
||||
]
|
||||
],
|
||||
[
|
||||
'name' => 'deactivate-ticket',
|
||||
'route' => '/api/v1/summits/{id}/orders/{order_id}/tickets/{ticket_id}/activate',
|
||||
'http_method' => 'DELETE',
|
||||
'scopes' => [
|
||||
sprintf(SummitScopes::WriteSummitData, $current_realm),
|
||||
sprintf(SummitScopes::UpdateRegistrationOrders, $current_realm),
|
||||
],
|
||||
'authz_groups' => [
|
||||
IGroup::SuperAdmins,
|
||||
IGroup::Administrators,
|
||||
IGroup::SummitAdministrators,
|
||||
IGroup::SummitRegistrationAdmins
|
||||
]
|
||||
],
|
||||
[
|
||||
'name' => 'add-ticket-2-order',
|
||||
'route' => '/api/v1/summits/{id}/orders/{order_id}/tickets',
|
||||
|
Loading…
Reference in New Issue
Block a user