BookingRepositoryTest::insertTestData()   B
last analyzed

Complexity

Conditions 6
Paths 10

Size

Total Lines 45
Code Lines 28

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 6
eloc 28
nc 10
nop 1
dl 0
loc 45
rs 8.8497
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace ApplicationTest\Repository;
6
7
use Application\Enum\BookingStatus;
8
use Application\Enum\BookingType;
9
use Application\Enum\UserStatus;
10
use Application\Model\Booking;
11
use Application\Model\User;
12
use Application\Repository\BookingRepository;
13
use Cake\Chronos\Chronos;
14
use Ecodev\Felix\Utility;
15
16
class BookingRepositoryTest extends AbstractRepositoryTest
17
{
18
    private BookingRepository $repository;
19
20
    protected function setUp(): void
21
    {
22
        parent::setUp();
23
        $this->repository = $this->getEntityManager()->getRepository(Booking::class);
24
        Chronos::setTestNow(new Chronos('2020-01-01'));
25
    }
26
27
    protected function tearDown(): void
28
    {
29
        Chronos::setTestNow(null);
30
        parent::tearDown();
31
    }
32
33
    public function testGetAllToInvoice(): void
34
    {
35
        $bookings = $this->repository->getAllToInvoice();
36
        $actual = Utility::modelToId($bookings);
37
38
        $expected = [
39
            4004,
40
            4005,
41
            4015,
42
            4007,
43
            4017,
44
        ];
45
46
        self::assertSame($expected, $actual);
47
    }
48
49
    public function testGetAllToInvoiceForUser(): void
50
    {
51
        $user = $this->getEntityManager()->getRepository(User::class)->getOneById(1005);
52
53
        $bookings = $this->repository->getAllToInvoice($user);
54
        $actual = Utility::modelToId($bookings);
55
56
        $expected = [
57
            4007,
58
        ];
59
60
        self::assertSame($expected, $actual);
61
    }
62
63
    private function insertTestData(array $data): void
64
    {
65
        $connection = $this->getEntityManager()->getConnection();
66
        $connection->executeQuery('DELETE FROM booking');
67
68
        foreach ($data as $user) {
69
            $bookings = $user['bookings'] ?? [];
70
            $account = $user['account'] ?? null;
71
72
            unset($user['bookings'], $user['account']);
73
            $connection->insert('user', $user);
74
            $userId = $connection->lastInsertId();
75
76
            foreach ($bookings as $booking) {
77
                $booking['owner_id'] = $userId;
78
79
                $bookable = $booking['bookable'] ?? null;
80
                unset($booking['bookable']);
81
82
                if ($bookable) {
83
                    $connection->insert('bookable', $bookable);
84
                    $bookableId = $connection->lastInsertId();
85
                    $booking['bookable_id'] = $bookableId;
86
                }
87
88
                $connection->insert('booking', $booking);
89
            }
90
91
            if ($account) {
92
                $connection->insert('account', [
93
                    'owner_id' => $userId,
94
                ]);
95
                $accountId = $connection->lastInsertId();
96
97
                $connection->insert('transaction', []);
98
                $transactionId = $connection->lastInsertId();
99
100
                foreach ($account['transaction_lines'] as $line) {
101
                    $line['transaction_id'] = $transactionId;
102
                    $line['debit_id'] = $accountId;
103
104
                    // Automatically link to last bookable created
105
                    $line['bookable_id'] = $bookableId ?? null;
106
107
                    $connection->insert('transaction_line', $line);
108
                }
109
            }
110
        }
111
    }
112
113
    /**
114
     * @dataProvider providerGetAllToInvoice
115
     */
116
    public function testGetAllToInvoiceAllCases(array $data, array $expected): void
117
    {
118
        $this->insertTestData($data);
119
        $bookings = $this->repository->getAllToInvoice();
120
121
        $actual = [];
122
        foreach ($bookings as $a) {
123
            $actual[] = $a->getBookable()->getName();
124
        }
125
126
        self::assertSame($expected, $actual);
127
    }
128
129
    public function providerGetAllToInvoice(): iterable
130
    {
131
        $normal = [
132
            [
133
                'role' => User::ROLE_MEMBER,
134
                'status' => UserStatus::Active->value,
135
                'bookings' => [
136
                    [
137
                        'start_date' => '2019-02-25',
138
                        'end_date' => null,
139
                        'status' => BookingStatus::Booked->value,
140
                        'bookable' => [
141
                            'name' => 'cotisation',
142
                            'booking_type' => BookingType::Mandatory->value,
143
                            'is_active' => true,
144
                            'periodic_price' => '25.00',
145
                        ],
146
                    ],
147
                    [
148
                        'start_date' => '2020-01-01',
149
                        'end_date' => null,
150
                        'status' => BookingStatus::Booked->value,
151
                        'bookable' => [
152
                            'name' => 'casier',
153
                            'booking_type' => BookingType::AdminAssigned->value,
154
                            'is_active' => true,
155
                            'periodic_price' => '25.00',
156
                        ],
157
                    ],
158
                ],
159
                'account' => [
160
                    'transaction_lines' => [
161
                        [
162
                            'balance' => '5.00',
163
                            'transaction_date' => '2019-02-25',
164
                        ],
165
                    ],
166
                ],
167
            ],
168
        ];
169
170
        $inactiveUser = $normal;
171
        $inactiveUser[0]['status'] = UserStatus::Inactive->value;
172
173
        $archivedUser = $normal;
174
        $archivedUser[0]['status'] = UserStatus::Archived->value;
175
176
        $newUser = $normal;
177
        $newUser[0]['status'] = UserStatus::New->value;
178
179
        $bookingOnlyUser = $normal;
180
        $bookingOnlyUser[0]['role'] = User::ROLE_BOOKING_ONLY;
181
182
        $individualUser = $normal;
183
        $individualUser[0]['role'] = User::ROLE_INDIVIDUAL;
184
185
        $trainerUser = $normal;
186
        $trainerUser[0]['role'] = User::ROLE_TRAINER;
187
188
        $responsibleUser = $normal;
189
        $responsibleUser[0]['role'] = User::ROLE_RESPONSIBLE;
190
191
        $administratorUser = $normal;
192
        $administratorUser[0]['role'] = User::ROLE_ADMINISTRATOR;
193
194
        $futureBookingThisYear = $normal;
195
        $futureBookingThisYear[0]['bookings'][0]['start_date'] = '2019-12-31';
196
197
        $futureBookingNextYear = $normal;
198
        $futureBookingNextYear[0]['bookings'][0]['start_date'] = '2021-01-01';
199
200
        $terminatedBooking = $normal;
201
        $terminatedBooking[0]['bookings'][0]['end_date'] = '2019-01-01';
202
203
        $terminatedBooking = $normal;
204
        $terminatedBooking[0]['bookings'][0]['end_date'] = '2019-01-01';
205
206
        $terminatedBookingNextYear = $normal;
207
        $terminatedBookingNextYear[0]['bookings'][0]['end_date'] = '2021-01-01';
208
209
        $applicationBooking = $normal;
210
        $applicationBooking[0]['bookings'][0]['status'] = BookingStatus::Application->value;
211
212
        $processedBooking = $normal;
213
        $processedBooking[0]['bookings'][0]['status'] = BookingStatus::Processed->value;
214
215
        $selfApprovedBookable = $normal;
216
        $selfApprovedBookable[0]['bookings'][0]['bookable']['booking_type'] = BookingType::SelfApproved->value;
217
218
        $applicationBookable = $normal;
219
        $applicationBookable[0]['bookings'][0]['bookable']['booking_type'] = BookingType::Application->value;
220
221
        $inactiveBookable = $normal;
222
        $inactiveBookable[0]['bookings'][0]['bookable']['is_active'] = false;
223
224
        $freeBookable = $normal;
225
        $freeBookable[0]['bookings'][0]['bookable']['periodic_price'] = 0;
226
227
        $negativeBookable = $normal;
228
        $negativeBookable[0]['bookings'][0]['bookable']['periodic_price'] = -10;
229
230
        $existingTransactionThisYear = $normal;
231
        $existingTransactionThisYear[0]['account']['transaction_lines'][0]['transaction_date'] = '2020-02-01';
232
233
        $existingTransactionNextYear = $normal;
234
        $existingTransactionNextYear[0]['account']['transaction_lines'][0]['transaction_date'] = '2021-02-01';
235
        yield 'normal user get casier and cotisation' => [
236
            $normal,
237
            ['casier', 'cotisation'],
238
        ];
239
        yield 'inactive user get casier and cotisation' => [
240
            $inactiveUser,
241
            ['casier', 'cotisation'],
242
        ];
243
        yield 'archived user get nothing' => [
244
            $archivedUser,
245
            [],
246
        ];
247
        yield 'new user get casier and cotisation' => [
248
            $newUser,
249
            ['casier', 'cotisation'],
250
        ];
251
        yield 'bookingOnly user get nothing' => [
252
            $bookingOnlyUser,
253
            [],
254
        ];
255
        yield 'individual user get casier and cotisation so it can be invoiced to family owner' => [
256
            $individualUser,
257
            ['casier', 'cotisation'],
258
        ];
259
        yield 'trainer user get casier and cotisation' => [
260
            $trainerUser,
261
            ['casier', 'cotisation'],
262
        ];
263
        yield 'responsible user get casier and cotisation' => [
264
            $responsibleUser,
265
            ['casier', 'cotisation'],
266
        ];
267
        yield 'administrator user get casier and cotisation' => [
268
            $administratorUser,
269
            ['casier', 'cotisation'],
270
        ];
271
        yield 'future booking this year are still counted' => [
272
            $futureBookingThisYear,
273
            ['casier', 'cotisation'],
274
        ];
275
        yield 'future booking next year are not yet counted' => [
276
            $futureBookingNextYear,
277
            ['casier'],
278
        ];
279
        yield 'terminated booking are not counted anymore' => [
280
            $terminatedBooking,
281
            ['casier'],
282
        ];
283
        yield 'terminated booking next year are not yet terminated so must be counted' => [
284
            $terminatedBookingNextYear,
285
            ['casier', 'cotisation'],
286
        ];
287
        yield 'application booking is ignored' => [
288
            $applicationBooking,
289
            ['casier'],
290
        ];
291
        yield 'processsed booking is ignored' => [
292
            $processedBooking,
293
            ['casier'],
294
        ];
295
        yield 'self approved bookable is not counted' => [
296
            $selfApprovedBookable,
297
            ['casier'],
298
        ];
299
        yield 'application bookable is not counted' => [
300
            $applicationBookable,
301
            ['casier'],
302
        ];
303
        yield 'inactive bookable is not counted' => [
304
            $inactiveBookable,
305
            ['casier'],
306
        ];
307
        yield 'free bookable is not counted' => [
308
            $freeBookable,
309
            ['casier'],
310
        ];
311
        yield 'negative bookable is counted' => [
312
            $negativeBookable,
313
            ['casier', 'cotisation'],
314
        ];
315
        yield 'existing transaction for this year should not be re-created' => [
316
            $existingTransactionThisYear,
317
            ['cotisation'],
318
        ];
319
        yield 'existing transaction for next year have no impact' => [
320
            $existingTransactionNextYear,
321
            ['casier', 'cotisation'],
322
        ];
323
    }
324
}
325