Skip to content

Commit ca0e7ca

Browse files
authored
main <- develop (#401)
* Fix promo code input styles (#395) * Homepage design tweaks (#399) * Update deprecated timezones (#400) * Update deprecated timezones * remove comments * Allow editing of Order questions (#398) * Allow editing of Order questions * Update designs
1 parent 43e1a38 commit ca0e7ca

Some content is hidden

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

43 files changed

+1166
-232
lines changed

backend/app/DomainObjects/Enums/QuestionTypeEnum.php

+8
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,12 @@ enum QuestionTypeEnum
1616
case DROPDOWN;
1717
case MULTI_SELECT_DROPDOWN;
1818
case DATE;
19+
20+
public static function getMultipleChoiceTypes(): array
21+
{
22+
return [
23+
self::CHECKBOX,
24+
self::MULTI_SELECT_DROPDOWN,
25+
];
26+
}
1927
}

backend/app/DomainObjects/QuestionAndAnswerViewDomainObject.php

+72
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,18 @@ class QuestionAndAnswerViewDomainObject extends AbstractDomainObject
1515
private int $question_id;
1616
private ?int $order_id;
1717
private string $title;
18+
private bool $question_required;
19+
private ?string $question_description = null;
1820
private ?string $first_name = null;
1921
private ?string $last_name = null;
2022
private array|string $answer;
2123
private string $belongs_to;
2224
private ?int $attendee_id = null;
25+
private ?string $attendee_public_id = null;
2326
private string $question_type;
2427
private int $event_id;
28+
private int $question_answer_id;
29+
private ?array $question_options = null;
2530

2631
private ?AttendeeDomainObject $attendee = null;
2732

@@ -183,19 +188,86 @@ public function setQuestion(?QuestionDomainObject $question): static
183188
return $this;
184189
}
185190

191+
public function getQuestionAnswerId(): int
192+
{
193+
return $this->question_answer_id;
194+
}
195+
196+
public function setQuestionAnswerId(int $question_answer_id): QuestionAndAnswerViewDomainObject
197+
{
198+
$this->question_answer_id = $question_answer_id;
199+
200+
return $this;
201+
}
202+
203+
public function getQuestionDescription(): ?string
204+
{
205+
return $this->question_description;
206+
}
207+
208+
public function setQuestionDescription(?string $question_description): QuestionAndAnswerViewDomainObject
209+
{
210+
$this->question_description = $question_description;
211+
212+
return $this;
213+
}
214+
215+
public function getQuestionRequired(): bool
216+
{
217+
return $this->question_required;
218+
}
219+
220+
public function setQuestionRequired(bool $question_required): QuestionAndAnswerViewDomainObject
221+
{
222+
$this->question_required = $question_required;
223+
224+
return $this;
225+
}
226+
227+
public function getQuestionOptions(): ?array
228+
{
229+
return $this->question_options;
230+
}
231+
232+
public function setQuestionOptions(?array $question_options): QuestionAndAnswerViewDomainObject
233+
{
234+
$this->question_options = $question_options;
235+
236+
return $this;
237+
}
238+
239+
public function getAttendeePublicId(): ?string
240+
{
241+
return $this->attendee_public_id;
242+
}
243+
244+
public function setAttendeePublicId(?string $attendee_public_id): QuestionAndAnswerViewDomainObject
245+
{
246+
$this->attendee_public_id = $attendee_public_id;
247+
248+
return $this;
249+
}
250+
186251
public function toArray(): array
187252
{
188253
return [
189254
'question_id' => $this->question_id ?? null,
190255
'order_id' => $this->order_id ?? null,
191256
'title' => $this->title ?? null,
257+
'question_description' => $this->question_description ?? null,
258+
'question_required' => $this->question_required ?? null,
192259
'last_name' => $this->last_name ?? null,
193260
'answer' => $this->answer ?? null,
194261
'belongs_to' => $this->belongs_to ?? null,
195262
'attendee_id' => $this->attendee_id ?? null,
263+
'attendee_public_id' => $this->attendee_public_id ?? null,
196264
'question_type' => $this->question_type ?? null,
197265
'first_name' => $this->first_name ?? null,
198266
'event_id' => $this->event_id ?? null,
267+
'product_id' => $this->product_id ?? null,
268+
'product_title' => $this->product_title ?? null,
269+
'question_answer_id' => $this->question_answer_id ?? null,
270+
'question_options' => $this->question_options ?? null,
199271
];
200272
}
201273
}

backend/app/DomainObjects/QuestionAnswerDomainObject.php

+29
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,35 @@
22

33
namespace HiEvents\DomainObjects;
44

5+
use HiEvents\DomainObjects\Generated\OrderDomainObjectAbstract;
6+
57
class QuestionAnswerDomainObject extends Generated\QuestionAnswerDomainObjectAbstract
68
{
9+
private ?OrderDomainObjectAbstract $order = null;
10+
11+
private ?QuestionDomainObject $question = null;
12+
13+
public function setOrder(?OrderDomainObjectAbstract $order): QuestionAnswerDomainObject
14+
{
15+
$this->order = $order;
16+
17+
return $this;
18+
}
19+
20+
public function getOrder(): ?OrderDomainObjectAbstract
21+
{
22+
return $this->order;
23+
}
24+
25+
public function setQuestion(?QuestionDomainObject $question): QuestionAnswerDomainObject
26+
{
27+
$this->question = $question;
28+
29+
return $this;
30+
}
31+
32+
public function getQuestion(): ?QuestionDomainObject
33+
{
34+
return $this->question;
35+
}
736
}

backend/app/DomainObjects/QuestionDomainObject.php

+16
Original file line numberDiff line numberDiff line change
@@ -40,4 +40,20 @@ public function setOptions(array|string|null $options): self
4040
return $this;
4141
}
4242

43+
public function isAnswerValid(mixed $answer): bool
44+
{
45+
if (!isset($answer)) {
46+
return false;
47+
}
48+
49+
if (!$this->isPreDefinedChoice()) {
50+
return true;
51+
}
52+
53+
if (is_string($answer)) {
54+
return in_array($answer, $this->getOptions(), true);
55+
}
56+
57+
return array_diff((array)$answer, $this->getOptions()) === [];
58+
}
4359
}

backend/app/Http/Actions/Auth/LoginAction.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ public function __invoke(LoginRequest $request): JsonResponse
2626
$loginResponse = $this->loginHandler->handle(new LoginCredentialsDTO(
2727
email: strtolower($request->validated('email')),
2828
password: $request->validated('password'),
29-
accountId: $request->validated('account_id'),
29+
accountId: (int)$request->validated('account_id'),
3030
));
3131
} catch (UnauthorizedException $e) {
3232
return $this->errorResponse(

backend/app/Http/Actions/Auth/RefreshTokenAction.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,6 @@ class RefreshTokenAction extends BaseAuthAction
88
{
99
public function __invoke(): JsonResponse
1010
{
11-
return $this->respondWithToken(auth()->refresh(), auth()->user()->accounts);
11+
return $this->respondWithToken(auth()->refresh(), $this->getAuthenticatedUser()->accounts ?? collect());
1212
}
1313
}

backend/app/Http/Actions/Orders/GetOrderAction.php

+5-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
use HiEvents\DomainObjects\OrderItemDomainObject;
88
use HiEvents\DomainObjects\QuestionAndAnswerViewDomainObject;
99
use HiEvents\Http\Actions\BaseAction;
10+
use HiEvents\Repository\Eloquent\Value\OrderAndDirection;
11+
use HiEvents\Repository\Eloquent\Value\Relationship;
1012
use HiEvents\Repository\Interfaces\OrderRepositoryInterface;
1113
use HiEvents\Resources\Order\OrderResource;
1214
use Illuminate\Http\JsonResponse;
@@ -27,7 +29,9 @@ public function __invoke(int $eventId, int $orderId): JsonResponse
2729
$order = $this->orderRepository
2830
->loadRelation(OrderItemDomainObject::class)
2931
->loadRelation(AttendeeDomainObject::class)
30-
->loadRelation(QuestionAndAnswerViewDomainObject::class)
32+
->loadRelation(new Relationship(domainObject: QuestionAndAnswerViewDomainObject::class, orderAndDirections: [
33+
new OrderAndDirection(order: 'question_id'),
34+
]))
3135
->findById($orderId);
3236

3337
return $this->resourceResponse(OrderResource::class, $order);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<?php
2+
3+
namespace HiEvents\Http\Actions\Questions;
4+
5+
use HiEvents\DomainObjects\EventDomainObject;
6+
use HiEvents\Http\Actions\BaseAction;
7+
use HiEvents\Http\Request\Questions\EditQuestionAnswerRequest;
8+
use HiEvents\Services\Application\Handlers\Question\DTO\EditQuestionAnswerDTO;
9+
use HiEvents\Services\Application\Handlers\Question\EditQuestionAnswerHandler;
10+
use HiEvents\Services\Domain\Question\Exception\InvalidAnswerException;
11+
use Illuminate\Http\Response;
12+
use Illuminate\Validation\ValidationException;
13+
14+
class EditQuestionAnswerAction extends BaseAction
15+
{
16+
public function __construct(
17+
private readonly EditQuestionAnswerHandler $editQuestionAnswerHandler,
18+
)
19+
{
20+
}
21+
22+
public function __invoke(
23+
int $eventId,
24+
int $questionId,
25+
int $questionAnswerId,
26+
EditQuestionAnswerRequest $request,
27+
): Response
28+
{
29+
$this->isActionAuthorized($eventId, EventDomainObject::class);
30+
31+
try {
32+
$this->editQuestionAnswerHandler->handle(new EditQuestionAnswerDTO(
33+
questionAnswerId: $questionAnswerId,
34+
eventId: $eventId,
35+
answer: $request->validated('answer'),
36+
));
37+
} catch (InvalidAnswerException $e) {
38+
throw ValidationException::withMessages(['answer.answer' => $e->getMessage()]);
39+
}
40+
41+
return $this->noContentResponse();
42+
}
43+
}

backend/app/Http/Actions/Users/DeactivateUsersAction.php

-39
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?php
2+
3+
namespace HiEvents\Http\Request\Questions;
4+
5+
use HiEvents\Http\Request\BaseRequest;
6+
7+
class EditQuestionAnswerRequest extends BaseRequest
8+
{
9+
public function rules(): array
10+
{
11+
return [
12+
'answer' => [
13+
'nullable',
14+
function ($attribute, $value, $fail) {
15+
if (!is_string($value) && !is_array($value)) {
16+
$fail("The {$attribute} must be a string or an array.");
17+
}
18+
}
19+
],
20+
];
21+
}
22+
}

backend/app/Models/QuestionAndAnswerView.php

+1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ class QuestionAndAnswerView extends Model
1414

1515
protected $casts = [
1616
'answer' => 'array',
17+
'question_options' => 'array',
1718
];
1819

1920
public function attendee(): BelongsTo

backend/app/Models/QuestionAnswer.php

+11
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace HiEvents\Models;
44

55
use HiEvents\DomainObjects\Generated\QuestionAnswerDomainObjectAbstract;
6+
use Illuminate\Database\Eloquent\Relations\BelongsTo;
67

78
class QuestionAnswer extends BaseModel
89
{
@@ -23,4 +24,14 @@ protected function getFillableFields(): array
2324
QuestionAnswerDomainObjectAbstract::ANSWER,
2425
];
2526
}
27+
28+
public function order(): BelongsTo
29+
{
30+
return $this->belongsTo(Order::class);
31+
}
32+
33+
public function question(): BelongsTo
34+
{
35+
return $this->belongsTo(Question::class);
36+
}
2637
}

backend/app/Repository/Interfaces/RepositoryInterface.php

+3
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
use Exception;
66
use HiEvents\DomainObjects\Interfaces\DomainObjectInterface;
77
use HiEvents\Repository\Eloquent\Value\OrderAndDirection;
8+
use HiEvents\Repository\Eloquent\Value\Relationship;
89
use Illuminate\Contracts\Pagination\Paginator;
910
use Illuminate\Database\Eloquent\Relations\Relation;
1011
use Illuminate\Pagination\LengthAwarePaginator;
@@ -198,4 +199,6 @@ public function decrementEach(array $where, array $columns, array $extra = []):
198199
public function incrementEach(array $columns, array $additionalUpdates = [], ?array $where = null);
199200

200201
public function includeDeleted(): static;
202+
203+
public function loadRelation(string|Relationship $relationship): static;
201204
}

backend/app/Resources/Question/QuestionAnswerViewResource.php

+6
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ public function toArray(Request $request): array
2020
'product_title' => $this->getProductTitle(),
2121
'question_id' => $this->getQuestionId(),
2222
'title' => $this->getTitle(),
23+
'question_required' => $this->getQuestionRequired(),
24+
'question_description' => $this->getQuestionDescription(),
2325
'answer' => $this->getAnswer(),
2426
'text_answer' => app(QuestionAnswerFormatter::class)->getAnswerAsText(
2527
$this->getAnswer(),
@@ -28,13 +30,17 @@ public function toArray(Request $request): array
2830
'order_id' => $this->getOrderId(),
2931
'belongs_to' => $this->getBelongsTo(),
3032
'question_type' => $this->getQuestionType(),
33+
'event_id' => $this->getEventId(),
34+
'question_answer_id' => $this->getQuestionAnswerId(),
35+
'question_options' => $this->getQuestionOptions(),
3136

3237
$this->mergeWhen(
3338
$this->getAttendeeId() !== null,
3439
fn() => [
3540
'attendee_id' => $this->getAttendeeId(),
3641
'first_name' => $this->getFirstName(),
3742
'last_name' => $this->getLastName(),
43+
'attendee_public_id' => $this->getAttendeePublicId(),
3844
]
3945
),
4046
];

0 commit comments

Comments
 (0)