Skip to content

Commit f07e763

Browse files
romanetarsmarcet
andauthored
feat: managed tickets (#281)
* 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 <roman_ag@hotmail.com> * 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 <roman_ag@hotmail.com> Co-authored-by: smarcet@gmail.com <smarcet@gmail.com>
1 parent 7e13a8f commit f07e763

36 files changed

Lines changed: 974 additions & 83 deletions

app/Http/Controllers/Apis/Protected/Summit/Factories/Registration/PromoCodesValidationRulesFactory.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
* See the License for the specific language governing permissions and
1212
* limitations under the License.
1313
**/
14-
1514
use App\Http\ValidationRulesFactories\AbstractValidationRulesFactory;
1615
use App\Models\Foundation\Summit\PromoCodes\PromoCodesConstants;
1716
use models\exceptions\ValidationException;
@@ -60,6 +59,7 @@ public static function buildForAdd(array $payload = []): array
6059
'valid_until_date' => 'nullable|required_with:valid_since_date|date_format:U|epoch_seconds|after:valid_since_date',
6160
'allowed_ticket_types' => 'sometimes|int_array',
6261
'badge_features' => 'sometimes|int_array',
62+
'allows_to_delegate' => 'sometimes|boolean',
6363
];
6464

6565
$specific_rules = [];
@@ -174,6 +174,7 @@ public static function buildForUpdate(array $payload = []): array
174174
'badge_features' => 'sometimes|int_array',
175175
'badge_features_apply_to_all_tix_retroactively' => 'sometimes|boolean',
176176
'tags' => 'sometimes|string_array',
177+
'allows_to_delegate' => 'sometimes|boolean',
177178
];
178179

179180
$specific_rules = [];

app/Http/Controllers/Apis/Protected/Summit/Factories/Registration/SummitTicketTypeValidationRulesFactory.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
11
<?php namespace App\Http\Controllers;
2-
use App\Http\ValidationRulesFactories\AbstractValidationRulesFactory;
3-
use models\summit\SummitTicketType;
4-
52
/**
63
* Copyright 2018 OpenStack Foundation
74
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -14,7 +11,8 @@
1411
* See the License for the specific language governing permissions and
1512
* limitations under the License.
1613
**/
17-
14+
use App\Http\ValidationRulesFactories\AbstractValidationRulesFactory;
15+
use models\summit\SummitTicketType;
1816
/**
1917
* Class SummitTicketTypeValidationRulesFactory
2018
* @package App\Http\Controllers
@@ -39,6 +37,7 @@ public static function buildForAdd(array $payload = []): array
3937
'external_id' => 'sometimes|string|max:255',
4038
'badge_type_id' => 'sometimes|integer',
4139
'audience' => 'sometimes|string|in:'.implode(',', SummitTicketType::AllowedAudience),
40+
'allows_to_delegate' => 'sometimes|boolean',
4241
];
4342
}
4443

@@ -60,6 +59,7 @@ public static function buildForUpdate(array $payload = []): array
6059
'sales_end_date' => 'nullable:sales_start_date|date_format:U|epoch_seconds|after:sales_start_date',
6160
'cost' => 'sometimes|numeric|greater_than_or_equal:0',
6261
'audience' => 'sometimes|string|in:'.implode(',', SummitTicketType::AllowedAudience),
62+
'allows_to_delegate' => 'sometimes|boolean',
6363
];
6464
}
6565
}

app/Http/Controllers/Apis/Protected/Summit/OAuth2SummitAttendeesApiController.php

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -390,6 +390,7 @@ public function getAttendeesBySummit($summit_id)
390390
'tags_id' => ['=='],
391391
'notes' => ['=@', '@@'],
392392
'has_notes' => ['=='],
393+
'has_manager' => ['=='],
393394
];
394395

395396
if (Request::has('filter')) {
@@ -453,6 +454,7 @@ function () {
453454
'tags_id' => 'sometimes|integer',
454455
'notes' => 'sometimes|string',
455456
'has_notes' => ['sometimes', new Boolean()],
457+
'has_manager' => ['sometimes', new Boolean()],
456458
];
457459
},
458460
function () {
@@ -532,6 +534,7 @@ function () {
532534
'tags_id' => ['=='],
533535
'notes' => ['=@', '@@'],
534536
'has_notes' => ['=='],
537+
'has_manager' => ['=='],
535538
];
536539
},
537540
function () {
@@ -566,6 +569,7 @@ function () {
566569
'tags_id' => 'sometimes|integer',
567570
'notes' => 'sometimes|string',
568571
'has_notes' => ['sometimes', new Boolean()],
572+
'has_manager' => ['sometimes', new Boolean()],
569573
];
570574
},
571575
function () {
@@ -629,10 +633,11 @@ public function addAttendee($summit_id)
629633
'surname' => 'required_without:member_id|string|max:255',
630634
'admin_notes' => 'nullable|sometimes|string|max:1024',
631635
'company' => 'nullable|sometimes|string|max:255',
632-
'email' => 'required_without:member_id|string|max:255|email',
633-
'member_id' => 'required_without:email|integer',
636+
'email' => 'sometimes|string|max:255|email',
637+
'member_id' => 'sometimes|integer',
634638
'extra_questions' => 'sometimes|extra_question_dto_array',
635639
'tags' => 'sometimes|string_array',
640+
'manager_id' => 'sometimes|integer',
636641
];
637642

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

721727
// Creates a Validator instance and validates the data.
@@ -980,6 +986,7 @@ public function send($summit_id)
980986
'tags_id' => ['=='],
981987
'notes' => ['=@', '@@'],
982988
'has_notes' => ['=='],
989+
'has_manager' => ['=='],
983990
]);
984991
}
985992

@@ -1020,6 +1027,7 @@ public function send($summit_id)
10201027
'tags_id' => 'sometimes|integer',
10211028
'notes' => 'sometimes|string',
10221029
'has_notes' => ['sometimes', new Boolean()],
1030+
'has_manager' => ['sometimes', new Boolean()],
10231031
]);
10241032

10251033
$this->attendee_service->triggerSend($summit, $payload, FiltersParams::getFilterParam());

app/Http/Controllers/Apis/Protected/Summit/OAuth2SummitOrdersApiController.php

Lines changed: 57 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
use App\ModelSerializers\SerializerUtils;
2121
use App\Rules\Boolean;
2222
use App\Services\Model\ISummitOrderService;
23+
use Illuminate\Support\Facades\Log;
2324
use models\exceptions\EntityNotFoundException;
2425
use models\oauth2\IResourceServerContext;
2526
use models\summit\IOrderConstants;
@@ -478,18 +479,33 @@ public function getMyTicketById($order_id, $ticket_id)
478479
$isOrderOwner = false;
479480

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

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

488+
$isTicketOwner = true;
487489
$ticketOwnerEmail = $ticket->getOwnerEmail();
490+
Log::debug
491+
(
492+
sprintf
493+
(
494+
"OAuth2SummitOrdersApiController::getMyTicketById ticketOwnerEmail %s current email %s",
495+
$ticketOwnerEmail,
496+
$current_user->getEmail()
497+
)
498+
);
488499

489-
$isTicketOwner = true;
490-
if(!empty($ticketOwnerEmail) && $ticketOwnerEmail != $current_user->getEmail() )
500+
if(!empty($ticketOwnerEmail) && $ticketOwnerEmail != $current_user->getEmail())
491501
$isTicketOwner = false;
492502

503+
if(!$isTicketOwner){
504+
// check if we are the manager
505+
$isTicketOwner = $ticket->hasOwner() && $ticket->getOwner()->isManagedBy($current_user);
506+
Log::debug(sprintf("OAuth2SummitOrdersApiController::getMyTicketById isTicketOwner %b (manager)" , $isTicketOwner));
507+
}
508+
493509
if(!$isOrderOwner && !$isTicketOwner)
494510
throw new EntityNotFoundException("Ticket not found.");
495511

@@ -1257,4 +1273,42 @@ function ($page, $per_page, $filter, $order, $applyExtraFilters) use ($summit) {
12571273
},
12581274
);
12591275
}
1276+
1277+
/**
1278+
* @param $summit_id
1279+
* @param $order_id
1280+
* @param $ticket_id
1281+
* @return mixed
1282+
*/
1283+
public function delegateTicket($summit_id, $order_id, $ticket_id)
1284+
{
1285+
return $this->processRequest(function () use ($summit_id, $order_id, $ticket_id) {
1286+
$summit = SummitFinderStrategyFactory::build($this->summit_repository, $this->getResourceServerContext())->find($summit_id);
1287+
if (is_null($summit)) return $this->error404();
1288+
1289+
$current_user = $this->getResourceServerContext()->getCurrentUser();
1290+
if (is_null($current_user))
1291+
return $this->error403();
1292+
1293+
$payload = $this->getJsonPayload([
1294+
'attendee_first_name' => 'required|string|max:255',
1295+
'attendee_last_name' => 'required|string|max:255',
1296+
'attendee_email' => 'sometimes|string|max:255|email',
1297+
'attendee_company' => 'nullable|string|max:255',
1298+
'attendee_company_id' => 'nullable|sometimes|integer',
1299+
'extra_questions' => 'sometimes|extra_question_dto_array',
1300+
'disclaimer_accepted' => 'nullable|boolean',
1301+
]);
1302+
1303+
$ticket = $this->service->delegateTicket($summit, intval($order_id), intval($ticket_id), $current_user, $payload);
1304+
1305+
return $this->updated(SerializerRegistry::getInstance()
1306+
->getSerializer($ticket, ISummitAttendeeTicketSerializerTypes::AdminType)
1307+
->serialize(
1308+
SerializerUtils::getExpand(),
1309+
SerializerUtils::getFields(),
1310+
SerializerUtils::getRelations()
1311+
));
1312+
});
1313+
}
12601314
}

app/Http/Controllers/Apis/Protected/Summit/OAuth2SummitPromoCodesApiController.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ function () {
142142
'contact_email' => ['@@', '=@', '=='],
143143
'tier_name' => ['@@', '=@', '=='],
144144
'email_sent' => ['=='],
145+
'allows_to_delegate' => ['=='],
145146
];
146147
},
147148
function () {
@@ -164,6 +165,7 @@ function () {
164165
'sponsor_id' => 'sometimes|integer',
165166
'tier_name' => 'sometimes|string',
166167
'email_sent' => ['sometimes', new Boolean()],
168+
'allows_to_delegate' => ['sometimes', new Boolean()],
167169
];
168170
},
169171
function () {
@@ -231,6 +233,7 @@ function () {
231233
'contact_email' => ['@@', '=@', '=='],
232234
'tier_name' => ['@@', '=@', '=='],
233235
'email_sent' => ['=='],
236+
'allows_to_delegate' => ['=='],
234237
];
235238
},
236239
function () {
@@ -245,6 +248,7 @@ function () {
245248
'sponsor_id' => 'sometimes|integer',
246249
'tier_name' => 'sometimes|string',
247250
'email_sent' => ['sometimes', new Boolean()],
251+
'allows_to_delegate' => ['sometimes', new Boolean()],
248252
];
249253
},
250254
function () {
@@ -319,6 +323,7 @@ function () {
319323
'contact_email' => ['@@', '=@', '=='],
320324
'tier_name' => ['@@', '=@', '=='],
321325
'email_sent' => ['=='],
326+
'allows_to_delegate' => ['=='],
322327
];
323328
},
324329
function () {
@@ -341,6 +346,7 @@ function () {
341346
'contact_email' => 'sometimes|string',
342347
'tier_name' => 'sometimes|string',
343348
'email_sent' => ['sometimes', new Boolean()],
349+
'allows_to_delegate' => ['sometimes', new Boolean()],
344350
];
345351
},
346352
function () {
@@ -425,6 +431,7 @@ function () {
425431
'contact_email' => ['@@', '=@', '=='],
426432
'tier_name' => ['@@', '=@', '=='],
427433
'email_sent' => ['=='],
434+
'allows_to_delegate' => ['=='],
428435
];
429436
},
430437
function () {
@@ -438,6 +445,7 @@ function () {
438445
'contact_email' => 'sometimes|string',
439446
'tier_name' => 'sometimes|string',
440447
'email_sent' => ['sometimes', new Boolean()],
448+
'allows_to_delegate' => ['sometimes', new Boolean()],
441449
];
442450
},
443451
function () {
@@ -1034,6 +1042,7 @@ public function sendSponsorPromoCodes($summit_id)
10341042
'contact_email' => ['@@', '=@', '=='],
10351043
'tier_name' => ['@@', '=@', '=='],
10361044
'email_sent' => ['=='],
1045+
'allows_to_delegate' => ['=='],
10371046
]);
10381047
}
10391048

@@ -1053,6 +1062,7 @@ public function sendSponsorPromoCodes($summit_id)
10531062
'sponsor_id' => 'sometimes|integer',
10541063
'tier_name' => 'sometimes|string',
10551064
'email_sent' => ['sometimes', new Boolean()],
1065+
'allows_to_delegate' => ['sometimes', new Boolean()],
10561066
]);
10571067

10581068
$this->promo_code_service->triggerSendSponsorPromoCodes($summit, $payload, FiltersParams::getFilterParam());

app/Http/Controllers/Apis/Protected/Summit/OAuth2SummitsTicketTypesApiController.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
**/
1414
use App\Http\Utils\EpochCellFormatter;
1515
use App\ModelSerializers\SerializerUtils;
16+
use App\Rules\Boolean;
1617
use App\Services\Model\ISummitTicketTypeService;
1718
use Illuminate\Support\Facades\Log;
1819
use models\exceptions\ValidationException;
@@ -92,6 +93,7 @@ function () {
9293
'sales_end_date'=> ['>', '<', '<=', '>=', '==','[]'],
9394
'created'=> ['>', '<', '<=', '>=', '==','[]'],
9495
'last_edited'=> ['>', '<', '<=', '>=', '==','[]'],
96+
'allows_to_delegate' => ['=='],
9597
];
9698
},
9799
function () {
@@ -106,6 +108,7 @@ function () {
106108
'sales_end_date' => 'sometimes|required|date_format:U|epoch_seconds',
107109
'created' => 'sometimes|required|date_format:U|epoch_seconds',
108110
'last_edited' => 'sometimes|required|date_format:U|epoch_seconds',
111+
'allows_to_delegate' => ['sometimes', new Boolean()],
109112
];
110113
},
111114
function () {
@@ -162,6 +165,7 @@ function () {
162165
'sales_end_date'=> ['>', '<', '<=', '>=', '==','[]'],
163166
'created'=> ['>', '<', '<=', '>=', '==','[]'],
164167
'last_edited'=> ['>', '<', '<=', '>=', '==','[]'],
168+
'allows_to_delegate' => ['=='],
165169
];
166170
},
167171
function () {
@@ -176,6 +180,7 @@ function () {
176180
'sales_end_date' => 'sometimes|required|date_format:U|epoch_seconds',
177181
'created' => 'sometimes|required|date_format:U|epoch_seconds',
178182
'last_edited' => 'sometimes|required|date_format:U|epoch_seconds',
183+
'allows_to_delegate' => ['sometimes', new Boolean()],
179184
];
180185
},
181186
function () {
@@ -237,6 +242,7 @@ function () {
237242
'sales_end_date'=> ['>', '<', '<=', '>=', '==','[]'],
238243
'created'=> ['>', '<', '<=', '>=', '==','[]'],
239244
'last_edited'=> ['>', '<', '<=', '>=', '==','[]'],
245+
'allows_to_delegate' => ['=='],
240246
];
241247
},
242248
function () {
@@ -251,6 +257,7 @@ function () {
251257
'sales_end_date' => 'sometimes|required|date_format:U|epoch_seconds',
252258
'created' => 'sometimes|required|date_format:U|epoch_seconds',
253259
'last_edited' => 'sometimes|required|date_format:U|epoch_seconds',
260+
'allows_to_delegate' => ['sometimes', new Boolean()],
254261
];
255262
},
256263
function () {

app/Jobs/Emails/Registration/Attendees/InviteAttendeeTicketEditionMail.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,6 @@ protected function getEmailEventSlug(): string
193193
{
194194
return self::EVENT_SLUG;
195195
}
196-
197196
public function handle
198197
(
199198
IMailApi $api

app/Jobs/Emails/Registration/Attendees/ProcessAttendeesEmailRequestJob.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,8 @@ public function handle(IAttendeeService $service){
9696
'tags' => ['=@', '==', '@@'],
9797
'tags_id' => ['=='],
9898
'notes' => ['=@', '@@'],
99-
'has_notes' => ['==']
99+
'has_notes' => ['=='],
100+
'has_manager' => ['==']
100101
]) : null;
101102

102103
$service->send($this->summit_id, $this->payload, $filter);

app/Jobs/Emails/Registration/Attendees/SummitAttendeeTicketEmail.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,6 @@ public static function getEmailTemplateSchema(): array{
211211
return $payload;
212212
}
213213

214-
215214
public function handle
216215
(
217216
IMailApi $api
@@ -237,4 +236,5 @@ public function handle
237236
Cache::forever($summit_attendee_ticket_email_sent_key, $now->getTimestamp());
238237
parent::handle($api);
239238
}
239+
240240
}

app/ModelSerializers/Summit/Registration/PromoCodes/SummitRegistrationPromoCodeSerializer.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ class SummitRegistrationPromoCodeSerializer extends SilverStripeSerializer
3636
'ClassName' => 'class_name:json_string',
3737
'Description' => 'description:json_string',
3838
'Notes' => 'notes:json_string',
39+
'AllowsToDelegate' => 'allows_to_delegate:json_boolean',
3940
];
4041

4142
protected static $allowed_relations = [

0 commit comments

Comments
 (0)