Failed Conditions
Push — master ( 5c622e...91b182 )
by Adrien
07:46
created

Invoicer::invoiceOne()   A

Complexity

Conditions 5
Paths 4

Size

Total Lines 22
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 12
CRAP Score 5.0113

Importance

Changes 0
Metric Value
cc 5
eloc 13
nc 4
nop 2
dl 0
loc 22
rs 9.5222
c 0
b 0
f 0
ccs 12
cts 13
cp 0.9231
crap 5.0113
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Application\Service;
6
7
use Application\Model\Account;
8
use Application\Model\Booking;
9
use Application\Model\Transaction;
10
use Application\Model\TransactionLine;
11
use Application\Model\User;
12
use Cake\Chronos\Date;
13
use Doctrine\ORM\EntityManager;
14
15
class Invoicer
16
{
17
    /**
18
     * @var EntityManager
19
     */
20
    private $entityManager;
21
22
    /**
23
     * @var int
24
     */
25
    private $count = 0;
26
27 1
    public function __construct(EntityManager $entityManager)
28
    {
29 1
        $this->entityManager = $entityManager;
30 1
    }
31
32 2
    public function invoice(?User $user = null): int
33
    {
34 2
        $this->count = 0;
35 2
        $bookings = $this->entityManager->getRepository(Booking::class)->getAllToInvoice($user);
36
37 2
        $user = null;
38 2
        $bookingPerUser = [];
39
40
        /** @var Booking $booking */
41 2
        foreach ($bookings as $booking) {
42 2
            if ($user !== $booking->getOwner()) {
43 2
                $this->createTransaction($user, $bookingPerUser);
44
45 2
                $user = $booking->getOwner();
46 2
                $bookingPerUser = [];
47
            }
48
49 2
            $bookingPerUser[] = $booking;
50
        }
51 2
        $this->createTransaction($user, $bookingPerUser);
52
53 2
        return $this->count;
54
    }
55
56
    /**
57
     * @param null|User $user
58
     * @param Booking[] $bookings
59
     */
60 2
    private function createTransaction(?User $user, array $bookings): void
61
    {
62 2
        if (!$user || !$bookings) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $bookings of type Application\Model\Booking[] is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
63 2
            return;
64
        }
65
66 2
        $account = $this->entityManager->getRepository(Account::class)->getOrCreate($user);
67 2
        $transaction = new Transaction();
68 2
        $transaction->setTransactionDate(Date::today());
69 2
        $transaction->setName('Cotisation et services ' . Date::today()->format('Y'));
70 2
        $this->entityManager->persist($transaction);
71
72 2
        foreach ($bookings as $booking) {
73 2
            $bookable = $booking->getBookable();
74 2
            $transactionLine = new TransactionLine();
75 2
            $this->entityManager->persist($transactionLine);
76
77 2
            $transactionLine->setName('Paiement depuis crédit MyIchtus');
78 2
            $transactionLine->setBookable($bookable);
79 2
            $transactionLine->setDebit($account);
80 2
            $transactionLine->setCredit($bookable->getCreditAccount());
81 2
            $transactionLine->setBalance($this->calculateBalance($booking));
82 2
            $transactionLine->setTransaction($transaction);
83 2
            $transactionLine->setTransactionDate(Date::today());
84
        }
85
86 2
        ++$this->count;
87 2
    }
88
89
    /**
90
     * @param Booking $booking
91
     *
92
     * @return string
93
     */
94 2
    private function calculateBalance(Booking $booking): string
95
    {
96 2
        $bookable = $booking->getBookable();
97 2
        $simultaneous = $bookable->getSimultaneousBookingMaximum();
98
99
        // If infinite booking, pay full price
100 2
        if (!($simultaneous > 1)) {
101 2
            $simultaneous = 1;
102
        }
103
104 2
        $price = (string) ($bookable->getPeriodicPrice() / $simultaneous);
105
106 2
        return $price;
107
    }
108
}
109