|
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
|
|
|
|