BookingRepository   A
last analyzed

Complexity

Total Complexity 3

Size/Duplication

Total Lines 60
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 3
eloc 21
c 0
b 0
f 0
dl 0
loc 60
rs 10
ccs 22
cts 22
cp 1

1 Method

Rating   Name   Duplication   Size   Complexity  
A getAllToInvoice() 0 48 3
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Application\Repository;
6
7
use Application\Enum\BookableStatus;
8
use Application\Enum\BookingStatus;
9
use Application\Enum\BookingType;
10
use Application\Enum\UserStatus;
11
use Application\Model\Bookable;
12
use Application\Model\Booking;
13
use Application\Model\User;
14
use Cake\Chronos\ChronosDate;
15
use Doctrine\DBAL\ArrayParameterType;
16
use Doctrine\ORM\Query\ResultSetMappingBuilder;
17
18
/**
19
 * @extends AbstractRepository<Booking>
20
 */
21
class BookingRepository extends AbstractRepository
22
{
23
    /**
24
     * All non-terminated bookings
25
     *     for active, periodic bookable
26
     *     for non-archived user
27
     *     but that do not already have an existing transaction_line in the user account for this year.
28
     *
29
     * @param null|User $user if given will filter only for that user
30
     *
31
     * @return Booking[]
32
     */
33 25
    public function getAllToInvoice(?User $user = null): array
34
    {
35 25
        $rsm = new ResultSetMappingBuilder($this->getEntityManager(), ResultSetMappingBuilder::COLUMN_RENAMING_INCREMENT);
36 25
        $rsm->addRootEntityFromClassMetadata(Booking::class, 'booking');
37 25
        $rsm->addJoinedEntityFromClassMetadata(Bookable::class, 'bookable', 'booking', 'bookable');
38 25
        $selectClause = $rsm->generateSelectClause();
39
40 25
        $userFilter = $user ? 'AND user.id = :user' : '';
41
42 25
        $sql = "
43 25
            SELECT $selectClause FROM booking
44
            JOIN bookable ON booking.bookable_id = bookable.id
45
            JOIN user ON booking.owner_id = user.id AND user.role NOT IN (:roles)
46
            LEFT JOIN account ON user.id = account.owner_id
47
            LEFT JOIN transaction_line ON
48
                account.id = transaction_line.debit_id
49
                AND transaction_line.bookable_id = bookable.id
50
                AND transaction_line.transaction_date >= :currentYear
51
                AND transaction_line.transaction_date < :nextYear
52
            WHERE
53
            user.status != :userStatus
54 25
            $userFilter
55
            AND bookable.booking_type IN (:bookingType)
56
            AND booking.status = :bookingStatus
57
            AND booking.start_date < :nextYear
58
            AND (booking.end_date IS NULL OR booking.end_date >= :nextYear)
59
            AND bookable.status = :bookableStatus
60
            AND bookable.periodic_price != 0
61
            AND transaction_line.id IS NULL
62
            ORDER BY booking.owner_id ASC, bookable.name ASC
63 25
        ";
64
65 25
        $query = $this->getEntityManager()->createNativeQuery($sql, $rsm)
66 25
            ->setParameter('bookingType', [BookingType::Mandatory->value, BookingType::AdminAssigned->value, BookingType::AdminApproved->value], ArrayParameterType::STRING)
67 25
            ->setParameter('bookingStatus', BookingStatus::Booked->value)
68 25
            ->setParameter('bookableStatus', BookableStatus::Active->value)
69 25
            ->setParameter('userStatus', UserStatus::Archived->value)
70 25
            ->setParameter('currentYear', ChronosDate::now()->firstOfYear()->toDateString())
71 25
            ->setParameter('nextYear', ChronosDate::now()->firstOfYear()->addYears(1)->toDateString())
72 25
            ->setParameter('roles', [User::ROLE_BOOKING_ONLY], ArrayParameterType::STRING);
73
74 25
        if ($user) {
75 1
            $query->setParameter('user', $user->getId());
76
        }
77
78 25
        $result = $query->getResult();
79
80 25
        return $result;
81
    }
82
}
83