Failed Conditions
Push — master ( b089ad...aace03 )
by Adrien
07:24
created

Invoicer::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 2
dl 0
loc 4
ccs 0
cts 4
cp 0
crap 2
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Application\Service;
6
7
use Application\Model\Account;
8
use Application\Model\Bookable;
9
use Application\Model\Booking;
10
use Application\Model\Transaction;
11
use Application\Model\TransactionLine;
12
use Application\Model\User;
13
use Cake\Chronos\Date;
14
use Doctrine\ORM\EntityManager;
15
16
class Invoicer
17
{
18
    /**
19
     * @var EntityManager
20
     */
21
    private $entityManager;
22
23
    /**
24
     * @var Mailer
25
     */
26
    private $mailer;
27
28
    public function __construct(EntityManager $entityManager, Mailer $mailer)
29
    {
30
        $this->entityManager = $entityManager;
31
        $this->mailer = $mailer;
32
    }
33
34
    public function invoice(): void
35
    {
36
        $bookings = $this->entityManager->getRepository(Booking::class)->getAllToInvoice();
37
        $user = null;
38
        $bookables = [];
39
40
        /** @var Booking $booking */
41
        foreach ($bookings as $booking) {
42
            if ($user !== $booking->getOwner()) {
43
                if ($user) {
44
                    $transaction = $this->createTransaction($user, $bookables);
1 ignored issue
show
Bug introduced by
$user of type void is incompatible with the type Application\Model\User expected by parameter $user of Application\Service\Invoicer::createTransaction(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

44
                    $transaction = $this->createTransaction(/** @scrutinizer ignore-type */ $user, $bookables);
Loading history...
45
46
                    $this->entityManager->flush();
47
                    $this->entityManager->refresh($user->getAccount());
48
49
                    if ($user->getEmail()) {
50
                        $this->mailer->queueInvoice($user, $transaction);
1 ignored issue
show
Bug introduced by
$user of type void is incompatible with the type Application\Model\User expected by parameter $user of Application\Service\Mailer::queueInvoice(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

50
                        $this->mailer->queueInvoice(/** @scrutinizer ignore-type */ $user, $transaction);
Loading history...
51
                    }
52
                }
53
54
                $user = $booking->getOwner();
55
                $bookables = [];
56
            }
57
58
            $bookables[] = $booking->getBookable();
59
        }
60
    }
61
62
    /**
63
     * @param User $user
64
     * @param Bookable[] $bookables
65
     *
66
     * @return Transaction
67
     */
68
    private function createTransaction(User $user, array $bookables): Transaction
69
    {
70
        $account = $this->entityManager->getRepository(Account::class)->getOrCreate($user);
71
        $transaction = new Transaction();
72
        $this->entityManager->persist($transaction);
73
74
        foreach ($bookables as $bookable) {
75
            $transactionLine = new TransactionLine();
76
            $this->entityManager->persist($transactionLine);
77
78
            $transactionLine->setBookable($bookable);
79
            $transactionLine->setDebit($account);
80
            $transactionLine->setCredit($bookable->getCreditAccount());
81
            $transactionLine->setBalance($this->calculateBalance($bookable));
82
            $transactionLine->setTransaction($transaction);
83
            $transactionLine->setTransactionDate(Date::today());
84
        }
85
86
        return $transaction;
87
    }
88
89
    /**
90
     * @param Bookable $bookable
91
     *
92
     * @return string
93
     */
94
    private function calculateBalance(Bookable $bookable): string
95
    {
96
        $simultaneous = $bookable->getSimultaneousBookingMaximum();
97
98
        // If infinite booking, pay full price
99
        if (!($simultaneous > 1)) {
100
            $simultaneous = 1;
101
        }
102
103
        $price = (string) ($bookable->getPeriodicPrice() / $simultaneous);
104
105
        return $price;
106
    }
107
}
108