Skip to content

Commit

Permalink
feat: managed tickets (#281)
Browse files Browse the repository at this point in the history
* fix: submitters query for media upload condition

* fix: avoid REGISTRATION_INVITE_ATTENDEE_TICKET_EDITION and SUMMIT_REGISTRATION_ATTENDEE_TICKET_EMIT overlaps

* feat: model mapping

Signed-off-by: romanetar <[email protected]>

* feat: added new endpoint

PUT api/v1/summits/{summit_id}/orders/{order_id}/tickets/{ticket_id}/delegate

Payload

attendee_first_name : string | mandatory
attendee_last_name:: string | mandatory
attendee_email: string | email| optional
attendee_company: string | optional
extra_questions: [] | optional

feature: updated ticket endpoints to retrieve managed tickets

feature: add new filter for attendees endpoints

?filter=has_manager==1|0

* fix: update attendee

* fix: null exception

* fix: attendees CRUD endpoints - manager setting

* chore: add debug info

* fix: get ticket by id

* fix: missing  validation on delegate

* fix: email overriding on delegation

* fix: validation rules

* chore: add debug info

* fix: refactor attendee factory to include manager logic

* fix: refactoring

* fix: delegate to manager email

* chore: refactor

* fix: has_manager filter

---------

Signed-off-by: romanetar <[email protected]>
Co-authored-by: [email protected] <[email protected]>
  • Loading branch information
romanetar and smarcet authored Aug 27, 2024
1 parent 7e13a8f commit f07e763
Show file tree
Hide file tree
Showing 36 changed files with 974 additions and 83 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
**/

use App\Http\ValidationRulesFactories\AbstractValidationRulesFactory;
use App\Models\Foundation\Summit\PromoCodes\PromoCodesConstants;
use models\exceptions\ValidationException;
Expand Down Expand Up @@ -60,6 +59,7 @@ public static function buildForAdd(array $payload = []): array
'valid_until_date' => 'nullable|required_with:valid_since_date|date_format:U|epoch_seconds|after:valid_since_date',
'allowed_ticket_types' => 'sometimes|int_array',
'badge_features' => 'sometimes|int_array',
'allows_to_delegate' => 'sometimes|boolean',
];

$specific_rules = [];
Expand Down Expand Up @@ -174,6 +174,7 @@ public static function buildForUpdate(array $payload = []): array
'badge_features' => 'sometimes|int_array',
'badge_features_apply_to_all_tix_retroactively' => 'sometimes|boolean',
'tags' => 'sometimes|string_array',
'allows_to_delegate' => 'sometimes|boolean',
];

$specific_rules = [];
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
<?php namespace App\Http\Controllers;
use App\Http\ValidationRulesFactories\AbstractValidationRulesFactory;
use models\summit\SummitTicketType;

/**
* Copyright 2018 OpenStack Foundation
* Licensed under the Apache License, Version 2.0 (the "License");
Expand All @@ -14,7 +11,8 @@
* See the License for the specific language governing permissions and
* limitations under the License.
**/

use App\Http\ValidationRulesFactories\AbstractValidationRulesFactory;
use models\summit\SummitTicketType;
/**
* Class SummitTicketTypeValidationRulesFactory
* @package App\Http\Controllers
Expand All @@ -39,6 +37,7 @@ public static function buildForAdd(array $payload = []): array
'external_id' => 'sometimes|string|max:255',
'badge_type_id' => 'sometimes|integer',
'audience' => 'sometimes|string|in:'.implode(',', SummitTicketType::AllowedAudience),
'allows_to_delegate' => 'sometimes|boolean',
];
}

Expand All @@ -60,6 +59,7 @@ public static function buildForUpdate(array $payload = []): array
'sales_end_date' => 'nullable:sales_start_date|date_format:U|epoch_seconds|after:sales_start_date',
'cost' => 'sometimes|numeric|greater_than_or_equal:0',
'audience' => 'sometimes|string|in:'.implode(',', SummitTicketType::AllowedAudience),
'allows_to_delegate' => 'sometimes|boolean',
];
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,7 @@ public function getAttendeesBySummit($summit_id)
'tags_id' => ['=='],
'notes' => ['=@', '@@'],
'has_notes' => ['=='],
'has_manager' => ['=='],
];

if (Request::has('filter')) {
Expand Down Expand Up @@ -453,6 +454,7 @@ function () {
'tags_id' => 'sometimes|integer',
'notes' => 'sometimes|string',
'has_notes' => ['sometimes', new Boolean()],
'has_manager' => ['sometimes', new Boolean()],
];
},
function () {
Expand Down Expand Up @@ -532,6 +534,7 @@ function () {
'tags_id' => ['=='],
'notes' => ['=@', '@@'],
'has_notes' => ['=='],
'has_manager' => ['=='],
];
},
function () {
Expand Down Expand Up @@ -566,6 +569,7 @@ function () {
'tags_id' => 'sometimes|integer',
'notes' => 'sometimes|string',
'has_notes' => ['sometimes', new Boolean()],
'has_manager' => ['sometimes', new Boolean()],
];
},
function () {
Expand Down Expand Up @@ -629,10 +633,11 @@ public function addAttendee($summit_id)
'surname' => 'required_without:member_id|string|max:255',
'admin_notes' => 'nullable|sometimes|string|max:1024',
'company' => 'nullable|sometimes|string|max:255',
'email' => 'required_without:member_id|string|max:255|email',
'member_id' => 'required_without:email|integer',
'email' => 'sometimes|string|max:255|email',
'member_id' => 'sometimes|integer',
'extra_questions' => 'sometimes|extra_question_dto_array',
'tags' => 'sometimes|string_array',
'manager_id' => 'sometimes|integer',
];

// Creates a Validator instance and validates the data.
Expand Down Expand Up @@ -716,6 +721,7 @@ public function updateAttendee($summit_id, $attendee_id)
'extra_questions' => 'sometimes|extra_question_dto_array',
'admin_notes' => 'nullable|sometimes|string|max:1024',
'tags' => 'sometimes|string_array',
'manager_id' => 'sometimes|integer',
];

// Creates a Validator instance and validates the data.
Expand Down Expand Up @@ -980,6 +986,7 @@ public function send($summit_id)
'tags_id' => ['=='],
'notes' => ['=@', '@@'],
'has_notes' => ['=='],
'has_manager' => ['=='],
]);
}

Expand Down Expand Up @@ -1020,6 +1027,7 @@ public function send($summit_id)
'tags_id' => 'sometimes|integer',
'notes' => 'sometimes|string',
'has_notes' => ['sometimes', new Boolean()],
'has_manager' => ['sometimes', new Boolean()],
]);

$this->attendee_service->triggerSend($summit, $payload, FiltersParams::getFilterParam());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
use App\ModelSerializers\SerializerUtils;
use App\Rules\Boolean;
use App\Services\Model\ISummitOrderService;
use Illuminate\Support\Facades\Log;
use models\exceptions\EntityNotFoundException;
use models\oauth2\IResourceServerContext;
use models\summit\IOrderConstants;
Expand Down Expand Up @@ -478,18 +479,33 @@ public function getMyTicketById($order_id, $ticket_id)
$isOrderOwner = false;

$ticket = $order->getTicketById(intval($ticket_id));
if (is_null($ticket))
if (!$ticket instanceof SummitAttendeeTicket)
throw new EntityNotFoundException("Ticket not found.");

if(!$ticket->hasOwner() && !$isOrderOwner)
throw new EntityNotFoundException("Order not found.");

$isTicketOwner = true;
$ticketOwnerEmail = $ticket->getOwnerEmail();
Log::debug
(
sprintf
(
"OAuth2SummitOrdersApiController::getMyTicketById ticketOwnerEmail %s current email %s",
$ticketOwnerEmail,
$current_user->getEmail()
)
);

$isTicketOwner = true;
if(!empty($ticketOwnerEmail) && $ticketOwnerEmail != $current_user->getEmail() )
if(!empty($ticketOwnerEmail) && $ticketOwnerEmail != $current_user->getEmail())
$isTicketOwner = false;

if(!$isTicketOwner){
// check if we are the manager
$isTicketOwner = $ticket->hasOwner() && $ticket->getOwner()->isManagedBy($current_user);
Log::debug(sprintf("OAuth2SummitOrdersApiController::getMyTicketById isTicketOwner %b (manager)" , $isTicketOwner));
}

if(!$isOrderOwner && !$isTicketOwner)
throw new EntityNotFoundException("Ticket not found.");

Expand Down Expand Up @@ -1257,4 +1273,42 @@ function ($page, $per_page, $filter, $order, $applyExtraFilters) use ($summit) {
},
);
}

/**
* @param $summit_id
* @param $order_id
* @param $ticket_id
* @return mixed
*/
public function delegateTicket($summit_id, $order_id, $ticket_id)
{
return $this->processRequest(function () use ($summit_id, $order_id, $ticket_id) {
$summit = SummitFinderStrategyFactory::build($this->summit_repository, $this->getResourceServerContext())->find($summit_id);
if (is_null($summit)) return $this->error404();

$current_user = $this->getResourceServerContext()->getCurrentUser();
if (is_null($current_user))
return $this->error403();

$payload = $this->getJsonPayload([
'attendee_first_name' => 'required|string|max:255',
'attendee_last_name' => 'required|string|max:255',
'attendee_email' => 'sometimes|string|max:255|email',
'attendee_company' => 'nullable|string|max:255',
'attendee_company_id' => 'nullable|sometimes|integer',
'extra_questions' => 'sometimes|extra_question_dto_array',
'disclaimer_accepted' => 'nullable|boolean',
]);

$ticket = $this->service->delegateTicket($summit, intval($order_id), intval($ticket_id), $current_user, $payload);

return $this->updated(SerializerRegistry::getInstance()
->getSerializer($ticket, ISummitAttendeeTicketSerializerTypes::AdminType)
->serialize(
SerializerUtils::getExpand(),
SerializerUtils::getFields(),
SerializerUtils::getRelations()
));
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ function () {
'contact_email' => ['@@', '=@', '=='],
'tier_name' => ['@@', '=@', '=='],
'email_sent' => ['=='],
'allows_to_delegate' => ['=='],
];
},
function () {
Expand All @@ -164,6 +165,7 @@ function () {
'sponsor_id' => 'sometimes|integer',
'tier_name' => 'sometimes|string',
'email_sent' => ['sometimes', new Boolean()],
'allows_to_delegate' => ['sometimes', new Boolean()],
];
},
function () {
Expand Down Expand Up @@ -231,6 +233,7 @@ function () {
'contact_email' => ['@@', '=@', '=='],
'tier_name' => ['@@', '=@', '=='],
'email_sent' => ['=='],
'allows_to_delegate' => ['=='],
];
},
function () {
Expand All @@ -245,6 +248,7 @@ function () {
'sponsor_id' => 'sometimes|integer',
'tier_name' => 'sometimes|string',
'email_sent' => ['sometimes', new Boolean()],
'allows_to_delegate' => ['sometimes', new Boolean()],
];
},
function () {
Expand Down Expand Up @@ -319,6 +323,7 @@ function () {
'contact_email' => ['@@', '=@', '=='],
'tier_name' => ['@@', '=@', '=='],
'email_sent' => ['=='],
'allows_to_delegate' => ['=='],
];
},
function () {
Expand All @@ -341,6 +346,7 @@ function () {
'contact_email' => 'sometimes|string',
'tier_name' => 'sometimes|string',
'email_sent' => ['sometimes', new Boolean()],
'allows_to_delegate' => ['sometimes', new Boolean()],
];
},
function () {
Expand Down Expand Up @@ -425,6 +431,7 @@ function () {
'contact_email' => ['@@', '=@', '=='],
'tier_name' => ['@@', '=@', '=='],
'email_sent' => ['=='],
'allows_to_delegate' => ['=='],
];
},
function () {
Expand All @@ -438,6 +445,7 @@ function () {
'contact_email' => 'sometimes|string',
'tier_name' => 'sometimes|string',
'email_sent' => ['sometimes', new Boolean()],
'allows_to_delegate' => ['sometimes', new Boolean()],
];
},
function () {
Expand Down Expand Up @@ -1034,6 +1042,7 @@ public function sendSponsorPromoCodes($summit_id)
'contact_email' => ['@@', '=@', '=='],
'tier_name' => ['@@', '=@', '=='],
'email_sent' => ['=='],
'allows_to_delegate' => ['=='],
]);
}

Expand All @@ -1053,6 +1062,7 @@ public function sendSponsorPromoCodes($summit_id)
'sponsor_id' => 'sometimes|integer',
'tier_name' => 'sometimes|string',
'email_sent' => ['sometimes', new Boolean()],
'allows_to_delegate' => ['sometimes', new Boolean()],
]);

$this->promo_code_service->triggerSendSponsorPromoCodes($summit, $payload, FiltersParams::getFilterParam());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
**/
use App\Http\Utils\EpochCellFormatter;
use App\ModelSerializers\SerializerUtils;
use App\Rules\Boolean;
use App\Services\Model\ISummitTicketTypeService;
use Illuminate\Support\Facades\Log;
use models\exceptions\ValidationException;
Expand Down Expand Up @@ -92,6 +93,7 @@ function () {
'sales_end_date'=> ['>', '<', '<=', '>=', '==','[]'],
'created'=> ['>', '<', '<=', '>=', '==','[]'],
'last_edited'=> ['>', '<', '<=', '>=', '==','[]'],
'allows_to_delegate' => ['=='],
];
},
function () {
Expand All @@ -106,6 +108,7 @@ function () {
'sales_end_date' => 'sometimes|required|date_format:U|epoch_seconds',
'created' => 'sometimes|required|date_format:U|epoch_seconds',
'last_edited' => 'sometimes|required|date_format:U|epoch_seconds',
'allows_to_delegate' => ['sometimes', new Boolean()],
];
},
function () {
Expand Down Expand Up @@ -162,6 +165,7 @@ function () {
'sales_end_date'=> ['>', '<', '<=', '>=', '==','[]'],
'created'=> ['>', '<', '<=', '>=', '==','[]'],
'last_edited'=> ['>', '<', '<=', '>=', '==','[]'],
'allows_to_delegate' => ['=='],
];
},
function () {
Expand All @@ -176,6 +180,7 @@ function () {
'sales_end_date' => 'sometimes|required|date_format:U|epoch_seconds',
'created' => 'sometimes|required|date_format:U|epoch_seconds',
'last_edited' => 'sometimes|required|date_format:U|epoch_seconds',
'allows_to_delegate' => ['sometimes', new Boolean()],
];
},
function () {
Expand Down Expand Up @@ -237,6 +242,7 @@ function () {
'sales_end_date'=> ['>', '<', '<=', '>=', '==','[]'],
'created'=> ['>', '<', '<=', '>=', '==','[]'],
'last_edited'=> ['>', '<', '<=', '>=', '==','[]'],
'allows_to_delegate' => ['=='],
];
},
function () {
Expand All @@ -251,6 +257,7 @@ function () {
'sales_end_date' => 'sometimes|required|date_format:U|epoch_seconds',
'created' => 'sometimes|required|date_format:U|epoch_seconds',
'last_edited' => 'sometimes|required|date_format:U|epoch_seconds',
'allows_to_delegate' => ['sometimes', new Boolean()],
];
},
function () {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,6 @@ protected function getEmailEventSlug(): string
{
return self::EVENT_SLUG;
}

public function handle
(
IMailApi $api
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,8 @@ public function handle(IAttendeeService $service){
'tags' => ['=@', '==', '@@'],
'tags_id' => ['=='],
'notes' => ['=@', '@@'],
'has_notes' => ['==']
'has_notes' => ['=='],
'has_manager' => ['==']
]) : null;

$service->send($this->summit_id, $this->payload, $filter);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,6 @@ public static function getEmailTemplateSchema(): array{
return $payload;
}


public function handle
(
IMailApi $api
Expand All @@ -237,4 +236,5 @@ public function handle
Cache::forever($summit_attendee_ticket_email_sent_key, $now->getTimestamp());
parent::handle($api);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ class SummitRegistrationPromoCodeSerializer extends SilverStripeSerializer
'ClassName' => 'class_name:json_string',
'Description' => 'description:json_string',
'Notes' => 'notes:json_string',
'AllowsToDelegate' => 'allows_to_delegate:json_boolean',
];

protected static $allowed_relations = [
Expand Down
Loading

0 comments on commit f07e763

Please sign in to comment.