PaymentController::addPromoCodeAction()   A
last analyzed

Complexity

Conditions 6
Paths 6

Size

Total Lines 31
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

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