PaymentService::getPromoCodeFromPaymentTickets()   A
last analyzed

Complexity

Conditions 3
Paths 3

Size

Total Lines 11
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 5
dl 0
loc 11
rs 10
c 0
b 0
f 0
cc 3
nc 3
nop 1
1
<?php
2
3
namespace Application\Bundle\DefaultBundle\Service;
4
5
use Application\Bundle\DefaultBundle\Entity\TicketCost;
6
use Doctrine\Common\Collections\ArrayCollection;
7
use Doctrine\ORM\EntityManager;
8
use Symfony\Component\DependencyInjection\Container;
9
use Stfalcon\Bundle\EventBundle\Entity\Payment;
10
use Stfalcon\Bundle\EventBundle\Entity\Ticket;
11
use Stfalcon\Bundle\EventBundle\Entity\PromoCode;
12
use Stfalcon\Bundle\EventBundle\Entity\Event;
13
use Application\Bundle\UserBundle\Entity\User;
14
15
/**
16
 * Class PaymentService.
17
 */
18
class PaymentService
19
{
20
    /**
21
     * @var Container
22
     */
23
    protected $container;
24
    /** @var $em EntityManager */
0 ignored issues
show
Documentation Bug introduced by
The doc comment $em at position 0 could not be parsed: Unknown type name '$em' at position 0 in $em.
Loading history...
25
    protected $em;
26
27
    /**
28
     * @param Container $container
29
     */
30
    public function __construct($container)
31
    {
32
        $this->container = $container;
33
        $this->em = $container->get('doctrine.orm.default_entity_manager');
34
    }
35
36
    /**
37
     * Create payment for current user ticket.
38
     *
39
     * @param Ticket|null $ticket
40
     *
41
     * @return Payment
42
     */
43
    public function createPaymentForCurrentUserWithTicket($ticket)
44
    {
45
        /* @var  User $user */
46
        $user = $this->container->get('security.token_storage')->getToken()->getUser();
47
        $payment = new Payment();
48
        $payment->setUser($user);
49
50
        $this->em->persist($payment);
51
        if ($ticket instanceof Ticket) {
52
            if (($ticket->getPayment() && $this->removeTicketFromPayment($ticket->getPayment(), $ticket))
53
                || !$ticket->getPayment()) {
54
                $this->addTicketToPayment($payment, $ticket);
55
            }
56
        }
57
58
        $this->em->flush();
59
60
        return $payment;
61
    }
62
63
    /**
64
     * додаем тикет до оплати.
65
     *
66
     * @param Payment $payment
67
     * @param Ticket  $ticket
68
     */
69
    public function addTicketToPayment($payment, $ticket)
70
    {
71
        if (!$ticket->isPaid() && $payment->addTicket($ticket)) {
72
            $ticket->setPayment($payment);
73
            $this->em->persist($ticket);
74
            //$this->recalculatePaymentAmount($payment);
75
        }
76
    }
77
78
    /**
79
     * видаляем тикет з оплати.
80
     *
81
     * @param Payment $payment
82
     * @param Ticket  $ticket
83
     *
84
     * @return bool
85
     */
86
    public function removeTicketFromPayment($payment, $ticket)
87
    {
88
        if (!$ticket->isPaid() && $payment->removeTicket($ticket)) {
89
            $this->em->remove($ticket);
90
            $this->recalculatePaymentAmount($payment);
91
92
            return true;
93
        }
94
95
        return false;
96
    }
97
98
    /**
99
     * Recalculate amount of payment.
100
     *
101
     * @param Payment $payment
102
     */
103
    public function recalculatePaymentAmount($payment)
104
    {
105
        $paymentAmount = 0;
106
        $paymentAmountWithoutDiscount = 0;
107
        /** @var Ticket $ticket */
108
        foreach ($payment->getTickets() as $ticket) {
109
            $paymentAmount += $ticket->getAmount();
110
            $paymentAmountWithoutDiscount += $ticket->getAmountWithoutDiscount();
111
        }
112
        $payment->setAmount($paymentAmount);
113
        $payment->setBaseAmount($paymentAmountWithoutDiscount);
114
        $this->payByReferralMoney($payment);
115
        $this->em->flush();
116
    }
117
118
    /**
119
     * Get promo code from tickets if it have.
120
     *
121
     * @param Payment $payment
122
     *
123
     * @return null|PromoCode
124
     */
125
    public function getPromoCodeFromPaymentTickets($payment)
126
    {
127
        $promoCode = null;
128
        foreach ($payment->getTickets() as $ticket) {
129
            /** @var Ticket $ticket */
130
            if ($promoCode = $ticket->getPromoCode()) {
131
                return $promoCode;
132
            }
133
        }
134
135
        return $promoCode;
136
    }
137
138
    /**
139
     * Get ticket number for payment.
140
     *
141
     * @param Payment $payment
142
     *
143
     * @return int|void
144
     */
145
    public function getTicketNumberFromPayment($payment)
146
    {
147
        /** @var ArrayCollection $tickets */
148
        $tickets = $payment->getTickets();
149
150
        if (!$tickets->isEmpty()) {
151
            return $tickets->first()->getId();
152
        }
153
154
        return;
155
    }
156
157
    /**
158
     * Add promo code for all tickets in payment
159
     * if ticket already not have discount and
160
     * recalculate payment amount.
161
     *
162
     * @param Payment   $payment
163
     * @param PromoCode $promoCode
164
     *
165
     * @return array
166
     */
167
    public function addPromoCodeForTicketsInPayment($payment, $promoCode)
168
    {
169
        $notUsedPromoCode = [];
170
171
        $ticketService = $this->container->get('stfalcon_event.ticket.service');
172
        /** @var Ticket $ticket */
173
        foreach ($payment->getTickets() as $ticket) {
174
            if (!$promoCode->isCanBeTmpUsed()) {
175
                break;
176
            }
177
            if ($ticketService->isMustBeDiscount($ticket)) {
178
                $ticketService->setTicketBestDiscount($ticket, $promoCode);
179
            } else {
180
                $ticketService->setTicketPromoCode($ticket, $promoCode);
181
            }
182
            if (!$ticket->hasPromoCode()) {
183
                $notUsedPromoCode[] = $ticket->getUser()->getFullname();
184
            }
185
        }
186
        $this->recalculatePaymentAmount($payment);
187
188
        return $notUsedPromoCode;
189
    }
190
191
    /**
192
     * Пересчитываем итоговую сумму платежа по всем билетам
193
     * с учетом скидки.
194
     *
195
     * @param Payment $payment
196
     * @param Event   $event
197
     */
198
    public function checkTicketsPricesInPayment($payment, $event)
199
    {
200
        $ticketService = $this->container->get('stfalcon_event.ticket.service');
201
        /** @var Ticket $ticket */
202
        foreach ($payment->getTickets() as $ticket) {
203
            $currentTicketCost = $this->container->get('app.ticket_cost.service')->getCurrentEventTicketCost($event);
204
205
            if (null === $currentTicketCost) {
206
                $currentTicketCost = $event->getBiggestTicketCost();
207
            }
208
209
            $eventCost = $currentTicketCost->getAmountByTemporaryCount();
210
            $isMustBeDiscount = $ticketService->isMustBeDiscount($ticket);
211
212
            if (($ticket->getTicketCost() !== $currentTicketCost) ||
213
                ((int) $ticket->getAmountWithoutDiscount() !== (int) $eventCost) ||
214
                ($ticket->getHasDiscount() !== ($isMustBeDiscount || $ticket->hasPromoCode()))) {
215
                $ticketService->setTicketAmount($ticket, $eventCost, $isMustBeDiscount, $currentTicketCost);
216
            }
217
        }
218
        $this->recalculatePaymentAmount($payment);
219
    }
220
221
    /**
222
     * Check ticket costs as sold.
223
     *
224
     * @param Payment $payment
225
     */
226
    public function setTicketsCostAsSold($payment)
227
    {
228
        $ticketCostsRecalculate = [];
229
        if ($payment->isPaid()) {
230
            /** @var Ticket $ticket */
231
            foreach ($payment->getTickets() as $ticket) {
232
                $ticketCost = $ticket->getTicketCost();
233
                if ($ticketCost) {
234
                    $ticketCostsRecalculate[$ticketCost->getId()] = $ticketCost;
235
                }
236
            }
237
            /** @var TicketCost $ticketCost */
238
            foreach ($ticketCostsRecalculate as $ticketCost) {
239
                $ticketCost->recalculateSoldCount();
240
            }
241
            $this->em->flush();
242
        }
243
    }
244
245
    /**
246
     * Calculate using promocode.
247
     *
248
     * @param Payment $payment
249
     */
250
    public function calculateTicketsPromocode($payment)
251
    {
252
        if ($payment->isPaid()) {
253
            /** @var Ticket $ticket */
254
            foreach ($payment->getTickets() as $ticket) {
255
                if ($ticket->hasPromoCode()) {
256
                    $promoCode = $ticket->getPromoCode();
257
                    if ($promoCode) {
258
                        $promoCode->incUsedCount();
259
                    }
260
                }
261
            }
262
            $this->em->flush();
263
        }
264
    }
265
266
    /**
267
     * set payment paid if have referral money.
268
     *
269
     * @param Payment $payment
270
     * @param Event   $event
271
     *
272
     * @return bool
273
     */
274
    public function setPaidByBonusMoney(Payment $payment, Event $event)
275
    {
276
        $this->checkTicketsPricesInPayment($payment, $event);
277
        if ($payment->isPending() && 0 === (int) $payment->getAmount() && $payment->getFwdaysAmount() > 0) {
278
            $payment->setPaidWithGate(Payment::BONUS_GATE);
279
280
            $referralService = $this->container->get('stfalcon_event.referral.service');
281
            $referralService->utilizeBalance($payment);
282
283
            $this->em->flush();
284
285
            return true;
286
        }
287
288
        return false;
289
    }
290
291
    /**
292
     * set payment paid if have referral money.
293
     *
294
     * @param Payment $payment
295
     * @param Event   $event
296
     *
297
     * @return bool
298
     */
299
    public function setPaidByPromocode(Payment $payment, Event $event)
300
    {
301
        $this->checkTicketsPricesInPayment($payment, $event);
302
        if ($payment->isPending() && 0 === (int) $payment->getAmount() && 0 === (int) $payment->getFwdaysAmount()) {
303
            $payment->setPaidWithGate(Payment::PROMOCODE_GATE);
304
305
            $this->em->flush();
306
307
            return true;
308
        }
309
310
        return false;
311
    }
312
313
    /**
314
     * Correct pay amount by user referral money.
315
     *
316
     * @param Payment $payment
317
     */
318
    private function payByReferralMoney(Payment $payment)
319
    {
320
        /* @var  User $user */
321
        $user = $payment->getUser();
322
        if ($user instanceof User && $user->getBalance() > 0) {
323
            $amount = $user->getBalance() - $payment->getAmount();
324
            if ($amount < 0) {
325
                $payment->setAmount(-$amount);
326
                $payment->setFwdaysAmount($user->getBalance());
327
            } else {
328
                $payment->setFwdaysAmount($payment->getAmount());
329
                $payment->setAmount(0);
330
            }
331
        } else {
332
            $payment->setFwdaysAmount(0);
333
        }
334
    }
335
}
336