Skip to content

Commit e48578d

Browse files
authored
Feature: Export all answers (#422)
1 parent 1845d4d commit e48578d

File tree

75 files changed

+1634
-571
lines changed

Some content is hidden

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

75 files changed

+1634
-571
lines changed

backend/app/DomainObjects/QuestionAndAnswerViewDomainObject.php

Lines changed: 72 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,20 @@ class QuestionAndAnswerViewDomainObject extends AbstractDomainObject
1414
private ?string $product_title;
1515
private int $question_id;
1616
private ?int $order_id;
17+
private ?string $order_first_name;
18+
private ?string $order_last_name;
19+
private ?string $order_email;
20+
private ?string $order_public_id;
1721
private string $title;
1822
private bool $question_required;
1923
private ?string $question_description = null;
24+
private ?int $attendee_id = null;
25+
private ?string $attendee_public_id = null;
2026
private ?string $first_name = null;
2127
private ?string $last_name = null;
28+
private ?string $attendee_email = null;
2229
private array|string $answer;
2330
private string $belongs_to;
24-
private ?int $attendee_id = null;
25-
private ?string $attendee_public_id = null;
2631
private string $question_type;
2732
private int $event_id;
2833
private int $question_answer_id;
@@ -248,6 +253,66 @@ public function setAttendeePublicId(?string $attendee_public_id): QuestionAndAns
248253
return $this;
249254
}
250255

256+
public function getOrderFirstName(): ?string
257+
{
258+
return $this->order_first_name;
259+
}
260+
261+
public function setOrderFirstName(?string $order_first_name): QuestionAndAnswerViewDomainObject
262+
{
263+
$this->order_first_name = $order_first_name;
264+
265+
return $this;
266+
}
267+
268+
public function getOrderLastName(): ?string
269+
{
270+
return $this->order_last_name;
271+
}
272+
273+
public function setOrderLastName(?string $order_last_name): QuestionAndAnswerViewDomainObject
274+
{
275+
$this->order_last_name = $order_last_name;
276+
277+
return $this;
278+
}
279+
280+
public function getOrderEmail(): ?string
281+
{
282+
return $this->order_email;
283+
}
284+
285+
public function setOrderEmail(?string $order_email): QuestionAndAnswerViewDomainObject
286+
{
287+
$this->order_email = $order_email;
288+
289+
return $this;
290+
}
291+
292+
public function getOrderPublicId(): ?string
293+
{
294+
return $this->order_public_id;
295+
}
296+
297+
public function setOrderPublicId(?string $order_public_id): QuestionAndAnswerViewDomainObject
298+
{
299+
$this->order_public_id = $order_public_id;
300+
301+
return $this;
302+
}
303+
304+
public function getAttendeeEmail(): ?string
305+
{
306+
return $this->attendee_email;
307+
}
308+
309+
public function setAttendeeEmail(?string $attendee_email): QuestionAndAnswerViewDomainObject
310+
{
311+
$this->attendee_email = $attendee_email;
312+
313+
return $this;
314+
}
315+
251316
public function toArray(): array
252317
{
253318
return [
@@ -268,6 +333,11 @@ public function toArray(): array
268333
'product_title' => $this->product_title ?? null,
269334
'question_answer_id' => $this->question_answer_id ?? null,
270335
'question_options' => $this->question_options ?? null,
336+
'attendee_email' => $this->attendee_email ?? null,
337+
'order_first_name' => $this->order_first_name ?? null,
338+
'order_last_name' => $this->order_last_name ?? null,
339+
'order_email' => $this->order_email ?? null,
340+
'order_public_id' => $this->order_public_id ?? null,
271341
];
272342
}
273343
}
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
<?php
2+
3+
namespace HiEvents\Exports\AnswerExportSheets;
4+
5+
use HiEvents\DomainObjects\Enums\QuestionTypeEnum;
6+
use HiEvents\DomainObjects\QuestionAndAnswerViewDomainObject;
7+
use HiEvents\Helper\Url;
8+
use HiEvents\Services\Domain\Question\QuestionAnswerFormatter;
9+
use Illuminate\Support\Collection;
10+
use Maatwebsite\Excel\Concerns\FromCollection;
11+
use Maatwebsite\Excel\Concerns\ShouldAutoSize;
12+
use Maatwebsite\Excel\Concerns\WithColumnWidths;
13+
use Maatwebsite\Excel\Concerns\WithHeadings;
14+
use Maatwebsite\Excel\Concerns\WithMapping;
15+
use Maatwebsite\Excel\Concerns\WithStyles;
16+
use Maatwebsite\Excel\Concerns\WithTitle;
17+
use PhpOffice\PhpSpreadsheet\Style\Alignment;
18+
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
19+
20+
class AttendeeAnswersSheet implements
21+
FromCollection,
22+
WithHeadings,
23+
WithMapping,
24+
WithStyles,
25+
WithTitle,
26+
WithColumnWidths,
27+
ShouldAutoSize
28+
{
29+
public function __construct(
30+
private readonly Collection $answers,
31+
private readonly QuestionAnswerFormatter $questionAnswerFormatter,
32+
)
33+
{
34+
}
35+
36+
public function collection(): Collection
37+
{
38+
return $this->answers;
39+
}
40+
41+
public function headings(): array
42+
{
43+
return [
44+
__('Question'),
45+
__('Answer'),
46+
__('Order ID'),
47+
__('Order Email'),
48+
__('Attendee Name'),
49+
__('Attendee Email'),
50+
__('Product'),
51+
__('Order URL'),
52+
];
53+
}
54+
55+
/**
56+
* @param QuestionAndAnswerViewDomainObject $row
57+
*/
58+
public function map($row): array
59+
{
60+
$orderUrl = sprintf(
61+
Url::getFrontEndUrlFromConfig(Url::ORGANIZER_ORDER_SUMMARY),
62+
$row->getEventId(),
63+
$row->getOrderId(),
64+
);
65+
66+
$linkText = __('View Order');
67+
$hyperlink = '=HYPERLINK("' . $orderUrl . '","' . $linkText . '")';
68+
69+
return [
70+
$row->getTitle(),
71+
$this->questionAnswerFormatter->getAnswerAsText(
72+
$row->getAnswer(),
73+
QuestionTypeEnum::fromName($row->getQuestionType())
74+
),
75+
$row->getOrderPublicId() ?? '',
76+
$row->getOrderEmail() ?? '',
77+
trim($row->getFirstName() . ' ' . $row->getLastName()),
78+
$row->getAttendeeEmail() ?? '',
79+
$row->getProductTitle() ?? '',
80+
$hyperlink,
81+
];
82+
}
83+
84+
public function styles(Worksheet $sheet): array
85+
{
86+
$sheet->getStyle('A1:H1')->applyFromArray([
87+
'font' => ['bold' => true],
88+
]);
89+
90+
$highestRow = $sheet->getHighestRow();
91+
92+
if ($highestRow > 1) {
93+
$sheet->getStyle('H2:H' . $highestRow)->applyFromArray([
94+
'alignment' => [
95+
'horizontal' => Alignment::HORIZONTAL_CENTER,
96+
],
97+
'font' => [
98+
'bold' => true,
99+
'color' => ['rgb' => '0563C1'],
100+
],
101+
]);
102+
}
103+
104+
return [
105+
1 => ['font' => ['bold' => true]],
106+
];
107+
}
108+
109+
public function columnWidths(): array
110+
{
111+
return [
112+
'A' => 30, // Question
113+
'B' => 40, // Answer
114+
'C' => 15, // Order ID
115+
'D' => 25, // Order Email
116+
'E' => 25, // Attendee Name
117+
'F' => 25, // Attendee Email
118+
'G' => 25, // Product
119+
'H' => 15, // Order URL
120+
];
121+
}
122+
123+
/**
124+
* @return string
125+
*/
126+
public function title(): string
127+
{
128+
return __('Attendee Answers');
129+
}
130+
}
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
<?php
2+
3+
namespace HiEvents\Exports\AnswerExportSheets;
4+
5+
use HiEvents\DomainObjects\Enums\QuestionTypeEnum;
6+
use HiEvents\DomainObjects\QuestionAndAnswerViewDomainObject;
7+
use HiEvents\Helper\Url;
8+
use HiEvents\Services\Domain\Question\QuestionAnswerFormatter;
9+
use Illuminate\Support\Collection;
10+
use Maatwebsite\Excel\Concerns\FromCollection;
11+
use Maatwebsite\Excel\Concerns\ShouldAutoSize;
12+
use Maatwebsite\Excel\Concerns\WithColumnWidths;
13+
use Maatwebsite\Excel\Concerns\WithHeadings;
14+
use Maatwebsite\Excel\Concerns\WithMapping;
15+
use Maatwebsite\Excel\Concerns\WithStyles;
16+
use Maatwebsite\Excel\Concerns\WithTitle;
17+
use PhpOffice\PhpSpreadsheet\Style\Alignment;
18+
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
19+
20+
class OrderAnswersSheet implements
21+
FromCollection,
22+
WithHeadings,
23+
WithMapping,
24+
WithStyles,
25+
WithTitle,
26+
WithColumnWidths,
27+
ShouldAutoSize
28+
{
29+
public function __construct(
30+
private readonly Collection $answers,
31+
private readonly QuestionAnswerFormatter $questionAnswerFormatter,
32+
)
33+
{
34+
}
35+
36+
public function collection(): Collection
37+
{
38+
return $this->answers;
39+
}
40+
41+
public function headings(): array
42+
{
43+
return [
44+
__('Question'),
45+
__('Answer'),
46+
__('Order ID'),
47+
__('Order Name'),
48+
__('Order Email'),
49+
__('Order URL'),
50+
];
51+
}
52+
53+
/**
54+
* @param QuestionAndAnswerViewDomainObject $row
55+
*/
56+
public function map($row): array
57+
{
58+
$orderUrl = sprintf(
59+
Url::getFrontEndUrlFromConfig(Url::ORGANIZER_ORDER_SUMMARY),
60+
$row->getEventId(),
61+
$row->getOrderId(),
62+
);
63+
64+
$linkText = __('View Order');
65+
$hyperlink = '=HYPERLINK("' . $orderUrl . '","' . $linkText . '")';
66+
67+
return [
68+
$row->getTitle(),
69+
$this->questionAnswerFormatter->getAnswerAsText(
70+
$row->getAnswer(),
71+
QuestionTypeEnum::fromName($row->getQuestionType())
72+
),
73+
$row->getOrderPublicId() ?? '',
74+
trim($row->getOrderFirstName() . ' ' . $row->getOrderLastName()),
75+
$row->getOrderEmail() ?? '',
76+
$hyperlink,
77+
];
78+
}
79+
80+
public function styles(Worksheet $sheet): array
81+
{
82+
$sheet->getStyle('A1:F1')->applyFromArray([
83+
'font' => ['bold' => true],
84+
]);
85+
86+
$highestRow = $sheet->getHighestRow();
87+
88+
// Style the URL column cells but exclude the header row
89+
if ($highestRow > 1) {
90+
$sheet->getStyle('F2:F' . $highestRow)->applyFromArray([
91+
'alignment' => [
92+
'horizontal' => Alignment::HORIZONTAL_CENTER,
93+
],
94+
'font' => [
95+
'bold' => true,
96+
'color' => ['rgb' => '0563C1'],
97+
],
98+
]);
99+
}
100+
101+
return [
102+
1 => ['font' => ['bold' => true]],
103+
];
104+
}
105+
106+
public function columnWidths(): array
107+
{
108+
return [
109+
'A' => 30, // Question
110+
'B' => 40, // Answer
111+
'C' => 15, // Order ID
112+
'D' => 25, // Order Name
113+
'E' => 25, // Order Email
114+
'F' => 15, // Order URL
115+
];
116+
}
117+
118+
public function title(): string
119+
{
120+
return __('Order Answers');
121+
}
122+
}

0 commit comments

Comments
 (0)