Skip to content

Commit d9dadba

Browse files
authored
Feature: Add ticket lookup for attendees (#927)
1 parent 2c8a384 commit d9dadba

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

59 files changed

+2615
-312
lines changed
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
<?php
2+
3+
namespace HiEvents\DomainObjects\Generated;
4+
5+
/**
6+
* THIS FILE IS AUTOGENERATED - DO NOT EDIT IT DIRECTLY.
7+
* @package HiEvents\DomainObjects\Generated
8+
*/
9+
abstract class TicketLookupTokenDomainObjectAbstract extends \HiEvents\DomainObjects\AbstractDomainObject
10+
{
11+
final public const SINGULAR_NAME = 'ticket_lookup_token';
12+
final public const PLURAL_NAME = 'ticket_lookup_tokens';
13+
final public const ID = 'id';
14+
final public const EMAIL = 'email';
15+
final public const TOKEN = 'token';
16+
final public const EXPIRES_AT = 'expires_at';
17+
final public const CREATED_AT = 'created_at';
18+
final public const UPDATED_AT = 'updated_at';
19+
final public const DELETED_AT = 'deleted_at';
20+
21+
protected int $id;
22+
protected string $email;
23+
protected string $token;
24+
protected string $expires_at;
25+
protected ?string $created_at = null;
26+
protected ?string $updated_at = null;
27+
protected ?string $deleted_at = null;
28+
29+
public function toArray(): array
30+
{
31+
return [
32+
'id' => $this->id ?? null,
33+
'email' => $this->email ?? null,
34+
'token' => $this->token ?? null,
35+
'expires_at' => $this->expires_at ?? null,
36+
'created_at' => $this->created_at ?? null,
37+
'updated_at' => $this->updated_at ?? null,
38+
'deleted_at' => $this->deleted_at ?? null,
39+
];
40+
}
41+
42+
public function setId(int $id): self
43+
{
44+
$this->id = $id;
45+
return $this;
46+
}
47+
48+
public function getId(): int
49+
{
50+
return $this->id;
51+
}
52+
53+
public function setEmail(string $email): self
54+
{
55+
$this->email = $email;
56+
return $this;
57+
}
58+
59+
public function getEmail(): string
60+
{
61+
return $this->email;
62+
}
63+
64+
public function setToken(string $token): self
65+
{
66+
$this->token = $token;
67+
return $this;
68+
}
69+
70+
public function getToken(): string
71+
{
72+
return $this->token;
73+
}
74+
75+
public function setExpiresAt(string $expires_at): self
76+
{
77+
$this->expires_at = $expires_at;
78+
return $this;
79+
}
80+
81+
public function getExpiresAt(): string
82+
{
83+
return $this->expires_at;
84+
}
85+
86+
public function setCreatedAt(?string $created_at): self
87+
{
88+
$this->created_at = $created_at;
89+
return $this;
90+
}
91+
92+
public function getCreatedAt(): ?string
93+
{
94+
return $this->created_at;
95+
}
96+
97+
public function setUpdatedAt(?string $updated_at): self
98+
{
99+
$this->updated_at = $updated_at;
100+
return $this;
101+
}
102+
103+
public function getUpdatedAt(): ?string
104+
{
105+
return $this->updated_at;
106+
}
107+
108+
public function setDeletedAt(?string $deleted_at): self
109+
{
110+
$this->deleted_at = $deleted_at;
111+
return $this;
112+
}
113+
114+
public function getDeletedAt(): ?string
115+
{
116+
return $this->deleted_at;
117+
}
118+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<?php
2+
3+
namespace HiEvents\DomainObjects;
4+
5+
class TicketLookupTokenDomainObject extends Generated\TicketLookupTokenDomainObjectAbstract
6+
{
7+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?php
2+
3+
namespace HiEvents\Exceptions;
4+
5+
use Exception;
6+
7+
class InvalidTicketLookupTokenException extends Exception
8+
{
9+
10+
}

backend/app/Helper/Url.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ class Url
1414
public const ATTENDEE_TICKET = 'app.frontend_urls.attendee_product';
1515
public const ORDER_SUMMARY = 'app.frontend_urls.order_summary';
1616
public const ORGANIZER_ORDER_SUMMARY = 'app.frontend_urls.organizer_order_summary';
17+
public const TICKET_LOOKUP = 'app.frontend_urls.ticket_lookup';
1718

1819
public static function getFrontEndUrlFromConfig(string $key, array $queryParams = []): string
1920
{
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<?php
2+
3+
namespace HiEvents\Http\Actions\TicketLookup;
4+
5+
use HiEvents\Exceptions\InvalidTicketLookupTokenException;
6+
use HiEvents\Http\Actions\BaseAction;
7+
use HiEvents\Resources\Order\OrderResourcePublic;
8+
use HiEvents\Services\Application\Handlers\TicketLookup\DTO\GetOrdersByLookupTokenDTO;
9+
use HiEvents\Services\Application\Handlers\TicketLookup\GetOrdersByLookupTokenHandler;
10+
use Illuminate\Http\JsonResponse;
11+
12+
class GetOrdersByLookupTokenAction extends BaseAction
13+
{
14+
public function __construct(
15+
private readonly GetOrdersByLookupTokenHandler $getOrdersByLookupTokenHandler,
16+
) {
17+
}
18+
19+
public function __invoke(string $token): JsonResponse
20+
{
21+
try {
22+
$orders = $this->getOrdersByLookupTokenHandler->handle(
23+
new GetOrdersByLookupTokenDTO(
24+
token: $token,
25+
)
26+
);
27+
28+
return $this->resourceResponse(
29+
resource: OrderResourcePublic::class,
30+
data: $orders,
31+
);
32+
} catch (InvalidTicketLookupTokenException $e) {
33+
return $this->errorResponse(
34+
message: $e->getMessage(),
35+
);
36+
}
37+
}
38+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?php
2+
3+
namespace HiEvents\Http\Actions\TicketLookup;
4+
5+
use HiEvents\Http\Actions\BaseAction;
6+
use HiEvents\Http\Request\TicketLookup\SendTicketLookupEmailRequest;
7+
use HiEvents\Services\Application\Handlers\TicketLookup\DTO\SendTicketLookupEmailDTO;
8+
use HiEvents\Services\Application\Handlers\TicketLookup\SendTicketLookupEmailHandler;
9+
use Illuminate\Http\JsonResponse;
10+
11+
class SendTicketLookupEmailAction extends BaseAction
12+
{
13+
public function __construct(
14+
private readonly SendTicketLookupEmailHandler $sendTicketLookupEmailHandler,
15+
) {
16+
}
17+
18+
public function __invoke(SendTicketLookupEmailRequest $request): JsonResponse
19+
{
20+
$this->sendTicketLookupEmailHandler->handle(
21+
new SendTicketLookupEmailDTO(
22+
email: $request->validated('email'),
23+
)
24+
);
25+
26+
return $this->jsonResponse(
27+
data: [
28+
'message' => __('If you have tickets associated with this email, we will send you an email with the details.'),
29+
]
30+
);
31+
}
32+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?php
2+
3+
namespace HiEvents\Http\Request\TicketLookup;
4+
5+
use Illuminate\Foundation\Http\FormRequest;
6+
7+
class SendTicketLookupEmailRequest extends FormRequest
8+
{
9+
public function rules(): array
10+
{
11+
return [
12+
'email' => 'required|email',
13+
];
14+
}
15+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
<?php
2+
3+
namespace HiEvents\Mail\TicketLookup;
4+
5+
use HiEvents\Helper\Url;
6+
use HiEvents\Mail\BaseMail;
7+
use Illuminate\Mail\Mailables\Content;
8+
use Illuminate\Mail\Mailables\Envelope;
9+
10+
/**
11+
* @uses /backend/resources/views/emails/ticket-lookup/ticket-lookup.blade.php
12+
*/
13+
class TicketLookupEmail extends BaseMail
14+
{
15+
public function __construct(
16+
private readonly string $email,
17+
private readonly string $token,
18+
private readonly int $orderCount,
19+
) {
20+
parent::__construct();
21+
}
22+
23+
public function envelope(): Envelope
24+
{
25+
return new Envelope(
26+
subject: __('Your Tickets'),
27+
);
28+
}
29+
30+
public function content(): Content
31+
{
32+
return new Content(
33+
markdown: 'emails.ticket-lookup.ticket-lookup',
34+
with: [
35+
'email' => $this->email,
36+
'orderCount' => $this->orderCount,
37+
'ticketLookupUrl' => sprintf(
38+
Url::getFrontEndUrlFromConfig(Url::TICKET_LOOKUP),
39+
$this->token,
40+
),
41+
]
42+
);
43+
}
44+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?php
2+
3+
namespace HiEvents\Models;
4+
5+
use Illuminate\Database\Eloquent\SoftDeletes;
6+
7+
class TicketLookupToken extends BaseModel
8+
{
9+
use SoftDeletes;
10+
11+
protected $casts = [
12+
'expires_at' => 'datetime',
13+
];
14+
}

backend/app/Providers/RepositoryServiceProvider.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
use HiEvents\Repository\Eloquent\StripeCustomerRepository;
4242
use HiEvents\Repository\Eloquent\StripePaymentsRepository;
4343
use HiEvents\Repository\Eloquent\TaxAndFeeRepository;
44+
use HiEvents\Repository\Eloquent\TicketLookupTokenRepository;
4445
use HiEvents\Repository\Eloquent\UserRepository;
4546
use HiEvents\Repository\Eloquent\WebhookLogRepository;
4647
use HiEvents\Repository\Eloquent\WebhookRepository;
@@ -81,6 +82,7 @@
8182
use HiEvents\Repository\Interfaces\StripeCustomerRepositoryInterface;
8283
use HiEvents\Repository\Interfaces\StripePaymentsRepositoryInterface;
8384
use HiEvents\Repository\Interfaces\TaxAndFeeRepositoryInterface;
85+
use HiEvents\Repository\Interfaces\TicketLookupTokenRepositoryInterface;
8486
use HiEvents\Repository\Interfaces\UserRepositoryInterface;
8587
use HiEvents\Repository\Interfaces\WebhookLogRepositoryInterface;
8688
use HiEvents\Repository\Interfaces\WebhookRepositoryInterface;
@@ -132,6 +134,7 @@ class RepositoryServiceProvider extends ServiceProvider
132134
OrganizerSettingsRepositoryInterface::class => OrganizerSettingsRepository::class,
133135
EmailTemplateRepositoryInterface::class => EmailTemplateRepository::class,
134136
AccountStripePlatformRepositoryInterface::class => AccountStripePlatformRepository::class,
137+
TicketLookupTokenRepositoryInterface::class => TicketLookupTokenRepository::class,
135138
];
136139

137140
public function register(): void

0 commit comments

Comments
 (0)