Passed
Pull Request — master (#489)
by Andrew
05:39
created

PaymentController::getPromoCodeFromQuery()   A

Complexity

Conditions 5
Paths 3

Size

Total Lines 13
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 8
dl 0
loc 13
rs 9.6111
c 0
b 0
f 0
cc 5
nc 3
nop 3
1
<?php
2
3
namespace Application\Bundle\DefaultBundle\Controller;
4
5
use Application\Bundle\UserBundle\Entity\User;
6
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
7
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
8
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
9
use Stfalcon\Bundle\EventBundle\Entity\Event;
10
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
11
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
12
use Stfalcon\Bundle\EventBundle\Entity\PromoCode;
13
use Stfalcon\Bundle\EventBundle\Entity\Payment;
14
use Stfalcon\Bundle\EventBundle\Entity\Ticket;
15
use Symfony\Component\HttpFoundation\JsonResponse;
16
use Symfony\Component\HttpFoundation\Response;
17
use Symfony\Component\Security\Core\Exception\BadCredentialsException;
18
19
/**
20
 * Class PaymentController.
21
 */
22
class PaymentController extends Controller
23
{
24
    /**
25
     * Event pay.
26
     *
27
     * @Route("/event/{eventSlug}/pay", name="event_pay",
28
     *     options = {"expose"=true},
29
     *     condition="request.isXmlHttpRequest()")
30
     * @Security("has_role('ROLE_USER')")
31
     *
32
     * @ParamConverter("event", options={"mapping": {"eventSlug": "slug"}})
33
     *
34
     * @param Event $event
35
     *
36
     * @return JsonResponse
37
     */
38
    public function payAction(Event $event)
39
    {
40
        $html = '';
41
        if (!$event->getReceivePayments() || !$event->isHaveFreeTickets()) {
42
            return new JsonResponse(
43
                [
44
                    'result' => false,
45
                    'error_code' => 1,
46
                    'error' => "Оплата за участие в {$event->getName()} не принимается.",
47
                    'html' => $html,
48
                ]
49
            );
50
        }
51
        /* @var  User $user */
52
        $user = $this->getUser();
53
54
        /* @var Ticket|null $ticket  */
55
        $ticket = $this->getDoctrine()->getManager()
56
            ->getRepository('StfalconEventBundle:Ticket')
57
            ->findOneBy(['user' => $user->getId(), 'event' => $event->getId()]);
58
59
        $paymentService = $this->get('stfalcon_event.payment.service');
60
61
        /** @var Payment|null $payment */
62
        $payment = $this->getDoctrine()->getManager()->getRepository('StfalconEventBundle:Payment')
63
            ->findPaymentByUserAndEvent($user, $event);
64
        $em = $this->getDoctrine()->getManager();
65
        if (!$ticket && !$payment) {
66
            $ticket = $this->get('stfalcon_event.ticket.service')->createTicket($event, $user);
67
            $user->addWantsToVisitEvents($event);
68
            $em->flush();
69
        }
70
71
        if (!$payment && $ticket->getPayment() && !$ticket->getPayment()->isReturned()) {
72
            $payment = $ticket->getPayment();
73
            $payment->setUser($ticket->getUser());
74
            $em->flush();
75
        }
76
77
        if ($ticket && !$payment) {
78
            $payment = $paymentService->createPaymentForCurrentUserWithTicket($ticket);
79
        } elseif ($ticket && $payment->isPaid()) {
80
            $payment = $paymentService->createPaymentForCurrentUserWithTicket(null);
81
        }
82
83
        if (!$payment) {
84
            return new JsonResponse(
85
                [
86
                    'result' => false,
87
                    'error_code' => 2,
88
                    'error' => 'Payment not found!',
89
                    'html' => $html,
90
                ]
91
            );
92
        }
93
94
        if ($payment->isPaid()) {
95
            return new JsonResponse(
96
                [
97
                    'result' => false,
98
                    'error_code' => 3,
99
                    'error' => 'Payment is paid',
100
                    'html' => $html,
101
                ]
102
            );
103
        }
104
105
        if ($payment->isPending()) {
106
            $paymentService->checkTicketsPricesInPayment($payment, $event);
107
        }
108
109
        $this->get('session')->set('active_payment_id', $payment->getId());
110
111
        $promoCode = null;
112
        $request = $this->get('request_stack')->getCurrentRequest();
113
        if ($request && $code = $request->query->get('promoCode')) {
114
            $promoCode = $this->getPromoCodeFromQuery($event, $payment, $code);
115
        }
116
117
        return $this->getPaymentHtml($event, $payment, $promoCode);
118
    }
119
120
    /**
121
     * @Route(path="/addPromoCode/{code}/{eventSlug}", name="add_promo_code",
122
     *     methods={"POST"},
123
     *     options = {"expose"=true},
124
     *     condition="request.isXmlHttpRequest()")
125
     * @ParamConverter("event", options={"mapping": {"eventSlug": "slug"}})
126
     *
127
     * @Security("has_role('ROLE_USER')")
128
     *
129
     * @param string $code
130
     * @param Event  $event
131
     *
132
     * @return JsonResponse
133
     */
134
    public function addPromoCodeAction($code, Event $event)
135
    {
136
        $payment = $this->getPaymentIfAccess();
137
        $translator = $this->get('translator');
138
        if (!$payment) {
139
            return new JsonResponse(['result' => false, 'error' => 'Payment not found or access denied!', 'html' => '']);
140
        }
141
142
        if ($payment->isPaid()) {
143
            return new JsonResponse(['result' => false, 'error' => 'Payment paid!', 'html' => '']);
144
        }
145
146
        $em = $this->getDoctrine()->getManager();
147
        /** @var PromoCode|null $promoCode */
148
        $promoCode = $em->getRepository('StfalconEventBundle:PromoCode')
149
            ->findActivePromoCodeByCodeAndEvent($code, $event);
150
151
        if (!$promoCode) {
152
            return new JsonResponse(['result' => false, 'error' => $translator->trans('error.promocode.not_found'), 'html' => '']);
153
        }
154
155
        if (!$promoCode->isCanBeUsed()) {
156
            return new JsonResponse(['result' => false, 'error' => $translator->trans('error.promocode.used'), 'html' => '']);
157
        }
158
159
        if ($payment->isPending()) {
160
            $paymentService = $this->get('stfalcon_event.payment.service');
161
            $paymentService->checkTicketsPricesInPayment($payment, $event);
162
        }
163
164
        return $this->getPaymentHtml($event, $payment, $promoCode);
165
    }
166
167
    /**
168
     * static payment.
169
     *
170
     * @Route("/static-payment/{eventSlug}")
171
     *
172
     * @Security("has_role('ROLE_USER')")
173
     *
174
     * @ParamConverter("event", options={"mapping": {"eventSlug": "slug"}})
175
     *
176
     * @param Event $event
177
     *
178
     * @Template("@ApplicationDefault/Redesign/Payment/payment.html.twig")
179
     *
180
     * @return array|Response
181
     */
182
    public function staticPaymentAction(Event $event)
183
    {
184
        if (!$event->getReceivePayments() || !$event->isHaveFreeTickets()) {
185
            return $this->render(
186
                '@ApplicationDefault/Redesign/static.page.html.twig',
187
                ['text' => $this->get('translator')->trans('error.payment.closed', ['%event%' => $event->getName()])]
188
            );
189
        }
190
191
        return ['event' => $event];
192
    }
193
194
    /**
195
     * Add user to payment.
196
     *
197
     * @Route("/event/{eventSlug}/payment/participant/add/{name}/{surname}/{email}", name="add_participant_to_payment",
198
     *     methods={"POST"},
199
     *     options={"expose"=true},
200
     *     condition="request.isXmlHttpRequest()")
201
     *
202
     * @Security("has_role('ROLE_USER')")
203
     *
204
     * @ParamConverter("event", options={"mapping": {"eventSlug": "slug"}})
205
     *
206
     * @param Event  $event
207
     * @param string $name
208
     * @param string $surname
209
     * @param string $email
210
     *
211
     * @return JsonResponse
212
     */
213
    public function addParticipantToPaymentAction(Event $event, $name, $surname, $email)
214
    {
215
        if (!$event->getReceivePayments() || !$event->isHaveFreeTickets()) {
216
            return new JsonResponse(
217
                [
218
                    'result' => false,
219
                    'error' => "Оплата за участие в {$event->getName()} не принимается.",
220
                    'html' => '',
221
                ]
222
            );
223
        }
224
225
        $payment = $this->getPaymentIfAccess();
226
227
        if (!$payment) {
228
            return new JsonResponse(['result' => false, 'error' => 'Payment not found or access denied!', 'html' => '']);
229
        }
230
231
        if ($payment->isPaid()) {
232
            return new JsonResponse(['result' => false, 'error' => 'Payment paid!', 'html' => '']);
233
        }
234
        /** @var User|null $user */
235
        $user = $this->get('fos_user.user_manager')->findUserBy(['email' => $email]);
236
237
        if (!$user) {
238
            try {
239
                $user = $this->get('fos_user.user_manager')->autoRegistration(['name' => $name, 'surname' => $surname, 'email' => $email]);
240
            } catch (BadCredentialsException $e) {
241
                $this->get('logger')->addError('autoRegistration with bad params');
242
243
                return new JsonResponse(['result' => false, 'error' => 'Bad credentials!', 'html' => '']);
244
            }
245
        }
246
247
        if (!$user) {
248
            return new JsonResponse(['result' => false, 'error' => 'Cant create user!', 'html' => '']);
249
        }
250
251
        $em = $this->getDoctrine()->getManager();
252
253
        /** @var Ticket|null $ticket */
254
        $ticket = $em->getRepository('StfalconEventBundle:Ticket')
255
            ->findOneBy(['event' => $event->getId(), 'user' => $user->getId()]);
256
257
        if (!$ticket) {
258
            $ticket = $this->get('stfalcon_event.ticket.service')->createTicket($event, $user);
259
            $user->addWantsToVisitEvents($event);
260
            $em->flush();
261
        }
262
263
        if (!$ticket->isPaid()) {
264
            $paymentService = $this->get('stfalcon_event.payment.service');
265
            $paymentService->addTicketToPayment($payment, $ticket);
266
            $paymentService->checkTicketsPricesInPayment($payment, $event);
267
        } else {
268
            return new JsonResponse(
269
                [
270
                    'result' => false,
271
                    'error' => $this->get('translator')->trans('error.user.already.paid', ['%email%' => $user->getEmail()]),
272
                    'html' => '',
273
                ]
274
            );
275
        }
276
277
        return $this->getPaymentHtml($event, $payment);
278
    }
279
280
    /**
281
     * Remove user/ticket from payment.
282
     *
283
     * @Route("/event/{eventSlug}/ticket/{id}/remove", name="remove_ticket_from_payment",
284
     *     methods={"POST"},
285
     *     options={"expose"=true},
286
     *     condition="request.isXmlHttpRequest()")
287
     * @Security("has_role('ROLE_USER')")
288
     *
289
     * @ParamConverter("event", options={"mapping": {"eventSlug": "slug"}})
290
     *
291
     * @param Event  $event
292
     * @param Ticket $ticket
293
     *
294
     * @return JsonResponse
295
     */
296
    public function removeTicketFromPaymentAction(Event $event, Ticket $ticket)
297
    {
298
        $payment = $this->getPaymentIfAccess($ticket);
299
300
        if (!$payment) {
301
            return new JsonResponse(['result' => false, 'error' => 'Payment not found or access denied!', 'html' => '']);
302
        }
303
304
        if (!$ticket->isPaid() && $payment->getTickets()->count() > 1) {
305
            $paymentService = $this->get('stfalcon_event.payment.service');
306
            $paymentService->removeTicketFromPayment($payment, $ticket);
307
            $paymentService->checkTicketsPricesInPayment($payment, $event);
308
        } else {
309
            return new JsonResponse(['result' => false, 'error' => 'Already paid ticket!', 'html' => '']);
310
        }
311
312
        return $this->getPaymentHtml($event, $payment);
313
    }
314
315
    /**
316
     * Pay for payment by bonus money.
317
     *
318
     * @Route("/event/{eventSlug}/pay-by-bonus", name="event_pay_by_bonus")
319
     *
320
     * @Security("has_role('ROLE_USER')")
321
     *
322
     * @ParamConverter("event", options={"mapping": {"eventSlug": "slug"}})
323
     *
324
     * @param Event $event
325
     *
326
     * @return Response
327
     */
328
    public function setPaidByBonusMoneyAction(Event $event)
329
    {
330
        $result = false;
331
        $payment = $this->getPaymentIfAccess();
332
333
        if ($payment && $payment->isPending() && 0 === (int) $payment->getAmount()) {
334
            $paymentService = $this->get('stfalcon_event.payment.service');
335
            $result = $paymentService->setPaidByBonusMoney($payment, $event);
336
        }
337
338
        $redirectUrl = $result ? $this->generateUrl('show_success') : $this->generateUrl('payment_fail');
339
340
        return $this->redirect($redirectUrl);
341
    }
342
343
    /**
344
     * Pay for payment by promocode (100% discount).
345
     *
346
     * @Route("/event/{eventSlug}/pay-by-promocode", name="event_pay_by_promocode")
347
     *
348
     * @Security("has_role('ROLE_USER')")
349
     *
350
     * @ParamConverter("event", options={"mapping": {"eventSlug": "slug"}})
351
     *
352
     * @param Event $event
353
     *
354
     * @return Response
355
     */
356
    public function setPaidByPromocodeAction(Event $event)
357
    {
358
        $result = false;
359
        $payment = $this->getPaymentIfAccess();
360
361
        if ($payment && $payment->isPending() && 0 === (int) $payment->getAmount()) {
362
            $paymentService = $this->get('stfalcon_event.payment.service');
363
            $result = $paymentService->setPaidByPromocode($payment, $event);
364
        }
365
366
        $redirectUrl = $result ? $this->generateUrl('show_success') : $this->generateUrl('payment_fail');
367
368
        return $this->redirect($redirectUrl);
369
    }
370
371
    /**
372
     * Get payment html for popup.
373
     *
374
     * @param Event          $event
375
     * @param Payment        $payment
376
     * @param Promocode|null $promoCode
377
     *
378
     * @return JsonResponse
379
     */
380
    private function getPaymentHtml(Event $event, Payment $payment, PromoCode $promoCode = null)
381
    {
382
        $paymentsConfig = $this->container->getParameter('stfalcon_event.config');
383
        $discountAmount = 100 * (float) $paymentsConfig['discount'];
384
385
        $notUsedPromoCode = [];
386
        $paymentService = $this->get('stfalcon_event.payment.service');
387
388
        if (!$promoCode) {
389
            $promoCode = $paymentService->getPromoCodeFromPaymentTickets($payment);
390
        }
391
        if ($promoCode) {
392
            $notUsedPromoCode = $paymentService->addPromoCodeForTicketsInPayment($payment, $promoCode);
393
        }
394
395
        $paySystemData = $this->get('app.way_for_pay.service')->getData($payment, $event);
396
397
        $formAction = null;
398
        $payType = null;
399
400
        $paymentSums = $this->renderView('@ApplicationDefault/Redesign/Payment/payment.sums.html.twig', ['payment' => $payment]);
401
        $byeBtnCaption = $this->get('translator')->trans('ticket.status.pay');
402
        /** @var User */
403
        $user = $this->getUser();
404
        if ($payment->getTickets()->count() > 0) {
405
            if (0 === (int) $payment->getAmount()) {
406
                $formAction = $payment->getFwdaysAmount() > 0 ?
407
                    $this->generateUrl('event_pay_by_bonus', ['eventSlug' => $event->getSlug()]) :
408
                    $this->generateUrl('event_pay_by_promocode', ['eventSlug' => $event->getSlug()]);
409
                $byeBtnCaption = $this->get('translator')->trans('ticket.status.get');
410
            } else {
411
                $payType = 'wayforpay';
412
            }
413
        }
414
415
        $html = $this->renderView('@ApplicationDefault/Redesign/Payment/wayforpay.html.twig', [
416
            'params' => $paySystemData,
417
            'event' => $event,
418
            'payment' => $payment,
419
            'discountAmount' => $discountAmount,
420
            'pay_type' => $payType,
421
        ]);
422
423
        if ('wayforpay' === $payType) {
424
            $this->get('session')->set('way_for_pay_payment', $payment->getId());
425
        }
426
427
        return new JsonResponse([
428
            'result' => true,
429
            'error' => '',
430
            'html' => $html,
431
            'paymentSums' => $paymentSums,
432
            'notUsedPromoCode' => $notUsedPromoCode,
433
            'phoneNumber' => $user->getPhone(),
434
            'is_user_create_payment' => $user === $payment->getUser(),
435
            'form_action' => $formAction,
436
            'pay_type' => $payType,
437
            'tickets_count' => $payment->getTickets()->count(),
438
            'byeBtnCaption' => $byeBtnCaption,
439
        ]);
440
    }
441
442
    /**
443
     * Check if payment correct and give it by id.
444
     *
445
     * @param Ticket $removeTicket
446
     *
447
     * @return Payment|null $payment
448
     */
449
    private function getPaymentIfAccess($removeTicket = null)
450
    {
451
        $em = $this->getDoctrine()->getManager();
452
        $payment = null;
453
        if ($this->get('session')->has('active_payment_id')) {
454
            $paymentId = $this->get('session')->get('active_payment_id');
455
            $payment = $em->getRepository('StfalconEventBundle:Payment')->find($paymentId);
456
        }
457
458
        if ($removeTicket instanceof Ticket) {
459
            $payment = $payment && ($removeTicket->getUser() === $this->getUser() ||
460
                $payment->getUser() === $this->getUser()) ? $payment : null;
461
        } else {
462
            $payment = $payment && $payment->getUser() === $this->getUser() ? $payment : null;
463
        }
464
465
        return $payment;
466
    }
467
468
    /**
469
     * @param Event   $event
470
     * @param Payment $payment
471
     * @param string  $code
472
     *
473
     * @return PromoCode|null
474
     */
475
    private function getPromoCodeFromQuery(Event $event, Payment $payment, $code)
476
    {
477
        $promoCode = null;
478
        if (!$payment->isPaid()) {
479
            $em = $this->getDoctrine()->getManager();
480
            $promoCode = $em->getRepository('StfalconEventBundle:PromoCode')
481
                ->findActivePromoCodeByCodeAndEvent($code, $event);
482
            if (($promoCode && !$promoCode->isCanBeUsed()) || is_array($promoCode)) {
483
                $promoCode = null;
484
            }
485
        }
486
487
        return $promoCode;
488
    }
489
}
490