PluginProbe ʕ •ᴥ•ʔ
Booking for Appointments and Events Calendar – Amelia / 2.0.2
Booking for Appointments and Events Calendar – Amelia v2.0.2
2.4.4 2.4.3 2.4.2 2.4.1 2.4 trunk 1.2.1 1.2.10 1.2.11 1.2.12 1.2.13 1.2.14 1.2.15 1.2.16 1.2.17 1.2.18 1.2.19 1.2.2 1.2.20 1.2.21 1.2.22 1.2.23 1.2.24 1.2.25 1.2.26 1.2.27 1.2.28 1.2.29 1.2.3 1.2.30 1.2.31 1.2.32 1.2.33 1.2.34 1.2.35 1.2.36 1.2.37 1.2.38 1.2.4 1.2.5 1.2.6 1.2.7 1.2.8 1.2.9 2.0 2.0.1 2.0.2 2.1 2.1.1 2.1.2 2.1.3 2.2 2.2.1 2.3
ameliabooking / src / Application / Commands / QrCode / ScanQrCodeCommandHandler.php
ameliabooking / src / Application / Commands / QrCode Last commit date
GetQrCodeCommand.php 6 months ago GetQrCodeCommandHandler.php 6 months ago ScanQrCodeCommand.php 8 months ago ScanQrCodeCommandHandler.php 8 months ago
ScanQrCodeCommandHandler.php
274 lines
1 <?php
2
3 namespace AmeliaBooking\Application\Commands\QrCode;
4
5 use AmeliaBooking\Application\Commands\CommandHandler;
6 use AmeliaBooking\Application\Commands\CommandResult;
7 use AmeliaBooking\Application\Common\Exceptions\AccessDeniedException;
8 use AmeliaBooking\Application\Services\User\UserApplicationService;
9 use AmeliaBooking\Domain\Common\Exceptions\InvalidArgumentException;
10 use AmeliaBooking\Domain\Entity\Booking\Appointment\CustomerBooking;
11 use AmeliaBooking\Domain\Entity\User\AbstractUser;
12 use AmeliaBooking\Infrastructure\Common\Exceptions\QueryExecutionException;
13 use AmeliaBooking\Infrastructure\Repository\Booking\Appointment\CustomerBookingRepository;
14 use AmeliaBooking\Domain\Entity\Entities;
15 use AmeliaBooking\Infrastructure\Repository\Booking\Event\EventRepository;
16 use Interop\Container\Exception\ContainerException;
17 use Slim\Exception\ContainerValueNotFoundException;
18
19 /**
20 * Class ScanQrCodeCommandHandler
21 *
22 * @package AmeliaBooking\Application\Command\QrCode
23 */
24 class ScanQrCodeCommandHandler extends CommandHandler
25 {
26 /**
27 * @var array
28 */
29 public $mandatoryFields = [
30 'ticketManualCode',
31 'scannedAt',
32 ];
33
34 /**
35 * @param ScanQrCodeCommand $command
36 *
37 * @return CommandResult
38 * @throws AccessDeniedException
39 * @throws InvalidArgumentException
40 * @throws QueryExecutionException
41 * @throws ContainerException
42 * @throws ContainerValueNotFoundException
43 */
44 public function handle(ScanQrCodeCommand $command)
45 {
46 $result = new CommandResult();
47
48 /** @var UserApplicationService $userAS */
49 $userAS = $this->container->get('application.user.service');
50
51 if (!$command->getPermissionService()->currentUserCanWrite(Entities::BOOKINGS)) {
52 $user = $userAS->getAuthenticatedUser($command->getToken(), false, 'providerCabinet');
53
54 if ($user === null) {
55 $result->setResult(CommandResult::RESULT_ERROR);
56 $result->setMessage('Could not retrieve user');
57 $result->setData(
58 [
59 'reauthorize' => true
60 ]
61 );
62
63 return $result;
64 }
65 }
66
67 $this->checkMandatoryFields($command);
68
69 /** @var CustomerBookingRepository $bookingRepository */
70 $bookingRepository = $this->container->get('domain.booking.customerBooking.repository');
71 $ticketManualCode = $command->getField('ticketManualCode');
72
73 $ticketData = $bookingRepository->getQrTicketNumber($ticketManualCode);
74 if (!$ticketData) {
75 $result->setResult(CommandResult::RESULT_ERROR);
76 $result->setMessage('Ticket not found');
77 $result->setData([
78 'messageType' => 'error',
79 'message' => 'ticket_not_found',
80 ]);
81
82 return $result;
83 }
84
85 $qrCodes = json_decode($ticketData['qrCodes'], true);
86 $bookingId = $ticketData['id'];
87
88 $scannedAt = $command->getField('scannedAt');
89
90 /** @var CustomerBooking $booking */
91 $booking = $bookingRepository->getById($bookingId);
92
93 if (!$booking) {
94 $result->setResult(CommandResult::RESULT_ERROR);
95 $result->setMessage('Booking not found');
96 $result->setData([
97 'messageType' => 'error',
98 'message' => 'booking_not_found',
99 ]);
100 return $result;
101 }
102
103 $bookingStatus = $booking->getStatus()->getValue();
104 if ($bookingStatus === 'rejected' || $bookingStatus === 'canceled') {
105 $result->setResult(CommandResult::RESULT_ERROR);
106 $result->setMessage('Booking is canceled');
107 $result->setData([
108 'messageType' => 'error',
109 'message' => 'booking_canceled',
110 ]);
111
112 return $result;
113 }
114
115 /** @var EventRepository $eventRepository */
116 $eventRepository = $this->container->get('domain.booking.event.repository');
117 $event = $eventRepository->getByBookingId($bookingId);
118
119 if ($event && $event->getStatus()->getValue() === 'rejected') {
120 $result->setResult(CommandResult::RESULT_ERROR);
121 $result->setMessage('Event is canceled');
122 $result->setData([
123 'messageType' => 'error',
124 'message' => 'event_canceled',
125 ]);
126
127 return $result;
128 }
129
130 $updated = false;
131
132 $type = 'ticket';
133 foreach ($qrCodes as $qrCodeItem) {
134 if ($qrCodeItem['ticketManualCode'] == $ticketManualCode) {
135 $type = $qrCodeItem['type'];
136 break;
137 }
138 }
139
140 if ($type === 'ticket') {
141 foreach ($qrCodes as &$qrCode) {
142 if (
143 $qrCode['type'] === 'ticket' &&
144 isset($qrCode['ticketManualCode']) &&
145 hash_equals($qrCode['ticketManualCode'], $ticketManualCode)
146 ) {
147 if (!array_key_exists($scannedAt, $qrCode['dates'])) {
148 $result->setResult(CommandResult::RESULT_ERROR);
149 $result->setMessage('Ticket cannot be scanned for this date');
150 $result->setData([
151 'messageType' => 'error',
152 'message' => 'ticket_not_valid_for_date',
153 ]);
154
155 return $result;
156 }
157
158 if ($qrCode['dates'][$scannedAt] === true) {
159 $result->setResult(CommandResult::RESULT_ERROR);
160 $result->setMessage('Ticket has already been scanned');
161 $result->setData([
162 'messageType' => 'error',
163 'message' => 'ticket_already_scanned',
164 ]);
165
166 return $result;
167 }
168
169 $qrCode['dates'][$scannedAt] = true;
170 $updated = true;
171 break;
172 }
173 }
174 }
175
176 $ticketsControl = 0;
177
178 if ($type === 'booking') {
179 foreach ($qrCodes as &$qrCode) {
180 if (
181 $qrCode['type'] === 'booking' &&
182 isset($qrCode['ticketManualCode']) &&
183 hash_equals($qrCode['ticketManualCode'], $ticketManualCode)
184 ) {
185 if (!array_key_exists($scannedAt, $qrCode['dates'])) {
186 $result->setResult(CommandResult::RESULT_ERROR);
187 $result->setMessage('Ticket cannot be scanned for this date');
188 $result->setData([
189 'messageType' => 'error',
190 'message' => 'ticket_not_valid_for_date',
191 ]);
192
193 return $result;
194 }
195
196 if ($qrCode['dates'][$scannedAt] === true) {
197 $result->setResult(CommandResult::RESULT_ERROR);
198 $result->setMessage('Group ticket has already been scanned');
199 $result->setData([
200 'messageType' => 'error',
201 'message' => 'group_ticket_already_scanned',
202 ]);
203
204 return $result;
205 }
206
207 $qrCode['dates'][$scannedAt] = true;
208 $updated = true;
209 break;
210 }
211 }
212
213 // Check if any ticket is already scanned for this date
214 foreach ($qrCodes as $qrCodeItem) {
215 if (array_key_exists($scannedAt, $qrCodeItem['dates']) && $qrCodeItem['dates'][$scannedAt] === true) {
216 $ticketsControl++;
217 }
218 }
219
220 if ($ticketsControl === count($qrCodes)) {
221 $result->setResult(CommandResult::RESULT_ERROR);
222 $result->setMessage('All tickets have already been scanned');
223 $result->setData([
224 'messageType' => 'error',
225 'message' => 'all_already_scanned',
226 ]);
227
228 return $result;
229 }
230
231 $ticketsControl = 0;
232 // Mark all as scanned for this date
233 foreach ($qrCodes as &$qr) {
234 if (array_key_exists($scannedAt, $qr['dates'])) {
235 if ($qr['dates'][$scannedAt] === false) {
236 $ticketsControl++;
237 $qr['dates'][$scannedAt] = true;
238 }
239 }
240 }
241 }
242
243 if (!$updated) {
244 $result->setResult(CommandResult::RESULT_ERROR);
245 $result->setMessage('Ticket not found');
246 $result->setData([
247 'messageType' => 'error',
248 'message' => 'ticket_not_found',
249 ]);
250
251 return $result;
252 }
253
254 $encoded = json_encode($qrCodes, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
255 $bookingRepository->updateFieldById($bookingId, $encoded, 'qrCodes');
256
257 $result->setResult(CommandResult::RESULT_SUCCESS);
258 $result->setMessage('Ticket is valid');
259 $result->setData([
260 'bookingId' => $bookingId,
261 'ticketManualCode' => $ticketManualCode,
262 'type' => $type,
263 'scannedAt' => $scannedAt,
264 'qrCodes' => $qrCodes,
265 'ticketControl' => $type === 'ticket' ? 1 : $ticketsControl,
266 'eventName' => $event ? $event->getName()->getValue() : '',
267 'messageType' => 'success',
268 'message' => 'ticket_is_valid',
269 ]);
270
271 return $result;
272 }
273 }
274