Passed
Push — main ( 2f3e46...485e61 )
by Thierry
05:35
created

PoolService::getActiveSessionCount()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 5
nc 1
nop 1
dl 0
loc 7
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Siak\Tontine\Service\Planning;
4
5
use Illuminate\Database\Eloquent\Builder;
6
use Illuminate\Database\Eloquent\Relations\Relation;
7
use Illuminate\Support\Collection;
8
use Illuminate\Support\Facades\DB;
9
use Siak\Tontine\Model\Pool;
10
use Siak\Tontine\Model\Session;
11
use Siak\Tontine\Service\TenantService;
12
13
class PoolService
14
{
15
    /**
16
     * @param TenantService $tenantService
17
     * @param DataSyncService $dataSyncService
18
     */
19
    public function __construct(protected TenantService $tenantService,
20
        private DataSyncService $dataSyncService)
21
    {}
22
23
    /**
24
     * @return Builder|Relation
25
     */
26
    private function getQuery(): Builder|Relation
27
    {
28
        return Pool::ofRound($this->tenantService->round());
29
    }
30
31
    /**
32
     * Get a paginated list of pools.
33
     *
34
     * @param int $page
35
     *
36
     * @return Collection
37
     */
38
    public function getPools(int $page = 0): Collection
39
    {
40
        return $this->getQuery()
41
            ->page($page, $this->tenantService->getLimit())
42
            ->get();
43
    }
44
45
    /**
46
     * Get the number of pools.
47
     *
48
     * @return int
49
     */
50
    public function getPoolCount(): int
51
    {
52
        return $this->getQuery()->count();
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->getQuery()->count() could return the type Illuminate\Database\Eloquent\Builder which is incompatible with the type-hinted return integer. Consider adding an additional type-check to rule them out.
Loading history...
53
    }
54
55
    /**
56
     * Get a single pool.
57
     *
58
     * @param int $poolId    The pool id
59
     *
60
     * @return Pool|null
61
     */
62
    public function getPool(int $poolId): ?Pool
63
    {
64
        return $this->getQuery()->with('counter')->find($poolId);
65
    }
66
67
    /**
68
     * Get the pools in the current round.
69
     *
70
     * @return Collection
71
     */
72
    public function getRoundPools(): Collection
73
    {
74
        return $this->tenantService->round()->pools()->get();
75
    }
76
77
    /**
78
     * Add a new pool.
79
     *
80
     * @param array $values
81
     *
82
     * @return bool
83
     */
84
    public function createPool(array $values): bool
85
    {
86
        $this->tenantService->round()->pools()->create($values);
87
88
        return true;
89
    }
90
91
    /**
92
     * Update a pool.
93
     *
94
     * @param Pool $pool
95
     * @param array $values
96
     *
97
     * @return bool
98
     */
99
    public function updatePool(Pool $pool, array $values): bool
100
    {
101
        return $pool->update($values);
102
    }
103
104
    /**
105
     * Delete a pool.
106
     *
107
     * @param Pool $pool
108
     *
109
     * @return void
110
     */
111
    public function deletePool(Pool $pool)
112
    {
113
        DB::transaction(function() use($pool) {
114
            $this->dataSyncService->syncPool($pool, false);
115
116
            $pool->pool_round()->delete();
117
            $pool->subscriptions()->delete();
118
            $pool->delete();
119
        });
120
    }
121
122
    /**
123
     * @param int $count
124
     *
125
     * @return Collection
126
     */
127
    public function getFakePools(int $count): Collection
128
    {
129
        return Pool::factory()->count($count)->make([
130
            'round_id' => $this->tenantService->round(),
131
        ]);
132
    }
133
134
    /**
135
     * Save the pool start and/or end session.
136
     *
137
     * @param Pool $pool
138
     * @param array $values
139
     *
140
     * @return void
141
     */
142
    private function _saveSessions(Pool $pool, array $values)
143
    {
144
        if($pool->pool_round !== null)
145
        {
146
            $pool->pool_round()->update($values);
147
            return;
148
        }
149
150
        // The initial value is the same for start and end sessions.
151
        if(!isset($values['start_session_id']))
152
        {
153
            $values['start_session_id'] = $this
154
                ->getPoolStartSession($pool)?->id ?? $values['end_session_id'];
155
        }
156
        if(!isset($values['end_session_id']))
157
        {
158
            $values['end_session_id'] = $this
159
                ->getPoolEndSession($pool)?->id ?? $values['start_session_id'];
160
        }
161
        $pool->pool_round()->create($values);
162
    }
163
164
    /**
165
     * Save the pool start and/or end session.
166
     *
167
     * @param Pool $pool
168
     * @param array $values
169
     *
170
     * @return void
171
     */
172
    public function saveSessions(Pool $pool, array $values)
173
    {
174
        DB::transaction(function() use($pool, $values) {
175
            $this->_saveSessions($pool, $values);
176
177
            $this->dataSyncService->syncPool($pool, true);
178
        });
179
    }
180
181
    /**
182
     * Delete the pool round.
183
     *
184
     * @param Pool $pool
185
     *
186
     * @return void
187
     */
188
    public function deleteRound(Pool $pool)
189
    {
190
        DB::transaction(function() use($pool) {
191
            $pool->pool_round()->delete();
192
193
            $this->dataSyncService->syncPool($pool, true);
194
        });
195
    }
196
197
    /**
198
     * Get the first session of the pool.
199
     *
200
     * @param Pool $pool
201
     *
202
     * @return Session|null
203
     */
204
    public function getPoolStartSession(Pool $pool): ?Session
205
    {
206
        return $pool->pool_round?->start_session ??
207
            $pool->round->sessions()->orderBy('start_at', 'asc')->first();
208
    }
209
210
    /**
211
     * Get the last session of the pool.
212
     *
213
     * @param Pool $pool
214
     *
215
     * @return Session|null
216
     */
217
    public function getPoolEndSession(Pool $pool): ?Session
218
    {
219
        return $pool->pool_round?->end_session ??
220
            $pool->round->sessions()->orderBy('start_at', 'desc')->first();
221
    }
222
223
    /**
224
     * Enable or disable a session for a pool.
225
     *
226
     * @param Pool $pool
227
     * @param int $sessionId    The session id
228
     *
229
     * @return void
230
     */
231
    public function enableSession(Pool $pool, int $sessionId)
232
    {
233
        // When the remitments are planned, don't enable or disable a session
234
        // if receivables already exist on the pool.
235
        // if($pool->remit_planned &&
236
        //     $pool->subscriptions()->whereHas('receivables')->count() > 0)
237
        // {
238
        //     return;
239
        // }
240
        $session = $this->tenantService->tontine()
241
            ->sessions()
242
            ->ofPool($pool)
243
            ->disabled($pool)
244
            ->find($sessionId);
245
        if(!$session)
246
        {
247
            return;
248
        }
249
250
        // Enable the session for the pool.
251
        $pool->disabled_sessions()->detach($session->id);
252
    }
253
254
    /**
255
     * Enable or disable a session for a pool.
256
     *
257
     * @param Pool $pool
258
     * @param int $sessionId    The session id
259
     *
260
     * @return void
261
     */
262
    public function disableSession(Pool $pool, int $sessionId)
263
    {
264
        // When the remitments are planned, don't enable or disable a session
265
        // if receivables already exist on the pool.
266
        // if($pool->remit_planned &&
267
        //     $pool->subscriptions()->whereHas('receivables')->count() > 0)
268
        // {
269
        //     return;
270
        // }
271
        $session = $this->tenantService->tontine()
272
            ->sessions()
273
            ->ofPool($pool)
274
            ->enabled($pool)
275
            ->find($sessionId);
276
        if(!$session)
277
        {
278
            return;
279
        }
280
281
        // Disable the session for the pool.
282
        DB::transaction(function() use($pool, $session) {
283
            $pool->disabled_sessions()->attach($session->id);
284
285
            $this->dataSyncService->syncPool($pool, true);
286
        });
287
    }
288
289
    /**
290
     * @param Pool $pool
291
     * @param Session $session
292
     *
293
     * @return bool
294
     */
295
    public function enabled(Pool $pool, Session $session): bool
296
    {
297
        return $session->disabled_pools->find($pool->id) === null;
298
    }
299
300
    /**
301
     * @param Pool $pool
302
     * @param Session $session
303
     *
304
     * @return bool
305
     */
306
    public function disabled(Pool $pool, Session $session): bool
307
    {
308
        return $session->disabled_pools->find($pool->id) !== null;
309
    }
310
311
    /**
312
     * @param Pool $pool
313
     * @param Session $session
314
     *
315
     * @return bool
316
     */
317
    public function active(Pool $pool, Session $session): int
318
    {
319
        return $this->tenantService->tontine()
320
            ->sessions()
321
            ->ofPool($pool)
322
            ->enabled($pool)
323
            ->where('sessions.id', $session->id)
324
            ->exists();
325
    }
326
327
    /**
328
     * Get the sessions enabled for a pool.
329
     *
330
     * @param Pool $pool
331
     *
332
     * @return Collection
333
     */
334
    public function getActiveSessions(Pool $pool): Collection
335
    {
336
        return $this->tenantService->tontine()
337
            ->sessions()
338
            ->ofPool($pool)
339
            ->enabled($pool)
340
            ->orderBy('start_at')
341
            ->get();
342
    }
343
344
    /**
345
     * Get the number of sessions enabled for a pool.
346
     *
347
     * @param Pool $pool
348
     *
349
     * @return int
350
     */
351
    public function getActiveSessionCount(Pool $pool): int
352
    {
353
        return $this->tenantService->tontine()
354
            ->sessions()
355
            ->ofPool($pool)
356
            ->enabled($pool)
357
            ->count();
358
    }
359
}
360