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\Exception\MessageException; |
||||
10 | use Siak\Tontine\Model\Pool; |
||||
11 | use Siak\Tontine\Model\PoolDef; |
||||
12 | use Siak\Tontine\Model\Round; |
||||
13 | use Siak\Tontine\Model\Session; |
||||
14 | use Siak\Tontine\Service\TenantService; |
||||
15 | use Exception; |
||||
16 | |||||
17 | class PoolService |
||||
18 | { |
||||
19 | use SessionTrait; |
||||
0 ignored issues
–
show
introduced
by
![]() |
|||||
20 | |||||
21 | /** |
||||
22 | * @param TenantService $tenantService |
||||
23 | * @param PoolSyncService $poolSyncService |
||||
24 | * @param FundSyncService $fundSyncService |
||||
25 | */ |
||||
26 | public function __construct(protected TenantService $tenantService, |
||||
27 | private PoolSyncService $poolSyncService, private FundSyncService $fundSyncService) |
||||
28 | {} |
||||
29 | |||||
30 | /** |
||||
31 | * @param Round $round |
||||
32 | * @param bool $filter|null |
||||
33 | * |
||||
34 | * @return Builder|Relation |
||||
35 | */ |
||||
36 | public function getQuery(Round $round, ?bool $filter): Builder|Relation |
||||
37 | { |
||||
38 | $onRoundFilter = fn(Builder|Relation $q) => $q->ofRound($round); |
||||
39 | return $round->guild->pools() |
||||
40 | ->when($filter === true, fn(Builder|Relation $query) => $query |
||||
41 | ->whereHas('pools', $onRoundFilter)) |
||||
42 | ->when($filter === false, fn(Builder|Relation $query) => $query |
||||
43 | ->whereDoesntHave('pools', $onRoundFilter)); |
||||
44 | } |
||||
45 | |||||
46 | /** |
||||
47 | * Get a paginated list of pools. |
||||
48 | * |
||||
49 | * @param Round $round |
||||
50 | * @param bool $filter|null |
||||
51 | * @param int $page |
||||
52 | * |
||||
53 | * @return Collection |
||||
54 | */ |
||||
55 | public function getPoolDefs(Round $round, ?bool $filter, int $page = 0): Collection |
||||
56 | { |
||||
57 | return $this->getQuery($round, $filter) |
||||
58 | ->with([ |
||||
59 | 'pools' => fn(Builder|Relation $q) => $q->where('round_id', $round->id), |
||||
60 | ]) |
||||
61 | ->withCount([ |
||||
62 | 'pools as pools_in_round_count' => fn(Builder|Relation $q) => $q->ofRound($round), |
||||
63 | ]) |
||||
64 | ->page($page, $this->tenantService->getLimit()) |
||||
65 | ->get(); |
||||
66 | } |
||||
67 | |||||
68 | /** |
||||
69 | * Get the number of pools. |
||||
70 | * |
||||
71 | * @param Round $round |
||||
72 | * @param bool $filter|null |
||||
73 | * |
||||
74 | * @return int |
||||
75 | */ |
||||
76 | public function getPoolDefCount(Round $round, ?bool $filter): int |
||||
77 | { |
||||
78 | return $this->getQuery($round, $filter)->count(); |
||||
0 ignored issues
–
show
|
|||||
79 | } |
||||
80 | |||||
81 | /** |
||||
82 | * @param Round $round |
||||
83 | * @param int $defId |
||||
84 | * |
||||
85 | * @return PoolDef|null |
||||
86 | */ |
||||
87 | public function getPoolDef(Round $round, int $defId): ?PoolDef |
||||
88 | { |
||||
89 | return $round->guild->pools() |
||||
90 | ->with([ |
||||
91 | 'pools' => fn(Builder|Relation $q) => $q->where('round_id', $round->id), |
||||
92 | ]) |
||||
93 | ->find($defId); |
||||
94 | } |
||||
95 | |||||
96 | /** |
||||
97 | * @param Round $round |
||||
98 | * @param int $defId |
||||
99 | * |
||||
100 | * @return void |
||||
101 | */ |
||||
102 | public function enablePool(Round $round, int $defId): void |
||||
103 | { |
||||
104 | $def = $this->getPoolDef($round, $defId); |
||||
105 | if(!$def || $def->pools->count() > 0) |
||||
106 | { |
||||
107 | return; // Todo: throw an exception |
||||
108 | } |
||||
109 | |||||
110 | $itemQuery = Pool::withoutGlobalScopes()->where('def_id', $defId); |
||||
111 | $startSession = $this->getStartSession($round, $itemQuery); |
||||
0 ignored issues
–
show
It seems like
$itemQuery can also be of type Illuminate\Database\Eloq...gHasThroughRelationship ; however, parameter $itemQuery of Siak\Tontine\Service\Pla...vice::getStartSession() does only seem to accept Illuminate\Database\Eloquent\Builder , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||
112 | $endSession = $this->getEndSession($round, $itemQuery); |
||||
0 ignored issues
–
show
It seems like
$itemQuery can also be of type Illuminate\Database\Eloq...gHasThroughRelationship ; however, parameter $itemQuery of Siak\Tontine\Service\Pla...ervice::getEndSession() does only seem to accept Illuminate\Database\Eloquent\Builder , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||
113 | if($endSession->day_date <= $startSession->day_date) |
||||
114 | { |
||||
115 | return; // Todo: throw an exception |
||||
116 | } |
||||
117 | |||||
118 | // Create the pool |
||||
119 | DB::transaction(function() use($def, $round, $startSession, $endSession) { |
||||
120 | $pool = $def->pools()->create([ |
||||
121 | 'title' => $def->title, |
||||
122 | 'amount' => $def->amount, |
||||
123 | 'deposit_fixed' => $def->deposit_fixed, |
||||
0 ignored issues
–
show
|
|||||
124 | 'deposit_lendable' => $def->deposit_lendable, |
||||
0 ignored issues
–
show
|
|||||
125 | 'remit_planned' => $def->remit_planned, |
||||
0 ignored issues
–
show
|
|||||
126 | 'remit_auction' => $def->remit_auction, |
||||
0 ignored issues
–
show
|
|||||
127 | 'round_id' => $round->id, |
||||
128 | 'start_sid' => $startSession->id, |
||||
129 | 'end_sid' => $endSession->id, |
||||
130 | ]); |
||||
131 | |||||
132 | $this->fundSyncService->poolEnabled($round, $pool); |
||||
133 | }); |
||||
134 | } |
||||
135 | |||||
136 | /** |
||||
137 | * @param Round $round |
||||
138 | * @param int $defId |
||||
139 | * |
||||
140 | * @return void |
||||
141 | */ |
||||
142 | public function disablePool(Round $round, int $defId): void |
||||
143 | { |
||||
144 | $def = $this->getPoolDef($round, $defId); |
||||
145 | if(!$def || $def->pools->count() === 0) |
||||
146 | { |
||||
147 | return; |
||||
148 | } |
||||
149 | |||||
150 | try |
||||
151 | { |
||||
152 | // Delete the pool |
||||
153 | DB::transaction(function() use($def, $round) { |
||||
154 | $pool = $def->pools->first(); |
||||
155 | $this->fundSyncService->poolDisabled($round, $pool); |
||||
156 | |||||
157 | DB::table('pool_session_disabled') |
||||
158 | ->where('pool_id', $pool->id) |
||||
159 | ->delete(); |
||||
160 | $pool->delete(); |
||||
161 | }); |
||||
162 | } |
||||
163 | catch(Exception $e) |
||||
164 | { |
||||
165 | throw new MessageException(trans('tontine.pool.errors.cannot_remove')); |
||||
166 | } |
||||
167 | } |
||||
168 | |||||
169 | /** |
||||
170 | * Get a paginated list of pools. |
||||
171 | * |
||||
172 | * @param Round $round |
||||
173 | * @param int $page |
||||
174 | * |
||||
175 | * @return Collection |
||||
176 | */ |
||||
177 | public function getPools(Round $round, int $page = 0): Collection |
||||
178 | { |
||||
179 | return Pool::ofRound($round) |
||||
180 | ->page($page, $this->tenantService->getLimit()) |
||||
181 | ->get(); |
||||
182 | } |
||||
183 | |||||
184 | /** |
||||
185 | * Get a pool. |
||||
186 | * |
||||
187 | * @param Round $round |
||||
188 | * @param int $poolId |
||||
189 | * |
||||
190 | * @return Pool|null |
||||
191 | */ |
||||
192 | public function getPool(Round $round, int $poolId): ?Pool |
||||
193 | { |
||||
194 | return Pool::ofRound($round) |
||||
195 | ->with(['sessions', 'disabled_sessions']) |
||||
196 | ->find($poolId); |
||||
197 | } |
||||
198 | |||||
199 | /** |
||||
200 | * Get the sessions enabled for a pool. |
||||
201 | * |
||||
202 | * @param Pool $pool |
||||
203 | * |
||||
204 | * @return Collection |
||||
205 | */ |
||||
206 | public function getActiveSessions(Pool $pool): Collection |
||||
207 | { |
||||
208 | return $pool->sessions()->orderBy('day_date')->get(); |
||||
209 | } |
||||
210 | |||||
211 | /** |
||||
212 | * Get the number of sessions enabled for a pool. |
||||
213 | * |
||||
214 | * @param Pool $pool |
||||
215 | * |
||||
216 | * @return int |
||||
217 | */ |
||||
218 | public function getActiveSessionCount(Pool $pool): int |
||||
219 | { |
||||
220 | return $pool->sessions()->count(); |
||||
221 | } |
||||
222 | |||||
223 | /** |
||||
224 | * Save the pool sessions. |
||||
225 | * |
||||
226 | * @param Pool $pool |
||||
227 | * @param array $values |
||||
228 | * |
||||
229 | * @return void |
||||
230 | */ |
||||
231 | public function saveSessions(Pool $pool, array $values) |
||||
232 | { |
||||
233 | DB::transaction(function() use($pool, $values) { |
||||
234 | $pool->update($values); |
||||
235 | |||||
236 | $this->poolSyncService->sessionsChanged($pool); |
||||
237 | }); |
||||
238 | } |
||||
239 | |||||
240 | /** |
||||
241 | * Enable or disable a session for a pool. |
||||
242 | * |
||||
243 | * @param Pool $pool |
||||
244 | * @param Session $session |
||||
245 | * |
||||
246 | * @return void |
||||
247 | */ |
||||
248 | public function enableSession(Pool $pool, Session $session) |
||||
249 | { |
||||
250 | // Enable the session for the pool. |
||||
251 | DB::transaction(function() use($pool, $session) { |
||||
252 | DB::table('pool_session_disabled') |
||||
253 | ->where('pool_id', $pool->id) |
||||
254 | ->where('session_id', $session->id) |
||||
255 | ->delete(); |
||||
256 | |||||
257 | $this->poolSyncService->sessionEnabled($pool, $session); |
||||
258 | }); |
||||
259 | } |
||||
260 | |||||
261 | /** |
||||
262 | * Enable or disable a session for a pool. |
||||
263 | * |
||||
264 | * @param Pool $pool |
||||
265 | * @param Session $session |
||||
266 | * |
||||
267 | * @return void |
||||
268 | */ |
||||
269 | public function disableSession(Pool $pool, Session $session) |
||||
270 | { |
||||
271 | try |
||||
272 | { |
||||
273 | // Disable the session for the pool. |
||||
274 | DB::transaction(function() use($pool, $session) { |
||||
275 | DB::table('pool_session_disabled') |
||||
276 | ->updateOrInsert([ |
||||
277 | 'pool_id' => $pool->id, |
||||
278 | 'session_id' => $session->id, |
||||
279 | ]); |
||||
280 | |||||
281 | $this->poolSyncService->sessionDisabled($pool, $session); |
||||
282 | }); |
||||
283 | } |
||||
284 | catch(Exception $e) |
||||
285 | { |
||||
286 | throw new MessageException(trans('tontine.session.errors.cannot_disable')); |
||||
287 | } |
||||
288 | } |
||||
289 | |||||
290 | /** |
||||
291 | * Get the number of active pools in the round. |
||||
292 | * |
||||
293 | * @param Round $round |
||||
294 | * |
||||
295 | * @return int |
||||
296 | */ |
||||
297 | public function getPoolCount(Round $round): int |
||||
298 | { |
||||
299 | return $round->pools()->count(); |
||||
300 | } |
||||
301 | } |
||||
302 |