Passed
Push — main ( c89920...e11349 )
by Thierry
05:00
created

DepositService::countDeposits()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
nc 1
nop 2
dl 0
loc 3
rs 10
c 1
b 0
f 0
1
<?php
2
3
namespace Siak\Tontine\Service\Meeting\Pool;
4
5
use Illuminate\Support\Facades\DB;
6
use Illuminate\Support\Collection;
7
use Siak\Tontine\Exception\MessageException;
8
use Siak\Tontine\Model\Deposit;
9
use Siak\Tontine\Model\Pool;
10
use Siak\Tontine\Model\Receivable;
11
use Siak\Tontine\Model\Session;
12
use Siak\Tontine\Service\TenantService;
13
14
use function trans;
15
16
class DepositService
17
{
18
    /**
19
     * @var TenantService
20
     */
21
    protected TenantService $tenantService;
22
23
    /**
24
     * @param TenantService $tenantService
25
     */
26
    public function __construct(TenantService $tenantService)
27
    {
28
        $this->tenantService = $tenantService;
29
    }
30
31
    /**
32
     * Get a single session.
33
     *
34
     * @param int $sessionId    The session id
35
     *
36
     * @return Session|null
37
     */
38
    public function getSession(int $sessionId): ?Session
39
    {
40
        return $this->tenantService->getSession($sessionId);
41
    }
42
43
    /**
44
     * Get a single pool.
45
     *
46
     * @param int $poolId    The pool id
47
     *
48
     * @return Pool|null
49
     */
50
    public function getPool(int $poolId): ?Pool
51
    {
52
        return $this->tenantService->round()->pools()->find($poolId);
53
    }
54
55
    /**
56
     * @param Pool $pool
57
     * @param Session $session
58
     *
59
     * @return mixed
60
     */
61
    private function getQuery(Pool $pool, Session $session)
62
    {
63
        return $session->receivables()->whereIn('subscription_id', $pool->subscriptions()->pluck('id'));
64
    }
65
66
    /**
67
     * @param Pool $pool
68
     * @param Session $session
69
     * @param int $page
70
     *
71
     * @return Collection
72
     */
73
    public function getReceivables(Pool $pool, Session $session, int $page = 0): Collection
74
    {
75
        // The jointure with the subscriptions and members tables is needed,
76
        // so the final records can be ordered by member name.
77
        return $this->getQuery($pool, $session)
78
            ->select('receivables.*')
79
            ->join('subscriptions', 'subscriptions.id', '=', 'receivables.subscription_id')
80
            ->join('members', 'members.id', '=', 'subscriptions.member_id')
81
            ->with(['subscription.member', 'deposit'])
82
            ->page($page, $this->tenantService->getLimit())
83
            ->orderBy('members.name', 'asc')
84
            ->get();
85
    }
86
87
    /**
88
     * Get the number of receivables in the selected round.
89
     *
90
     * @param Pool $pool
91
     * @param Session $session
92
     *
93
     * @return int
94
     */
95
    public function getReceivableCount(Pool $pool, Session $session): int
96
    {
97
        return $this->getQuery($pool, $session)->count();
98
    }
99
100
    /**
101
     * Find the unique receivable for a pool and a session.
102
     *
103
     * @param Pool $pool The pool
104
     * @param Session $session The session
105
     * @param int $receivableId
106
     *
107
     * @return Receivable|null
108
     */
109
    public function getReceivable(Pool $pool, Session $session, int $receivableId): ?Receivable
110
    {
111
        return $this->getQuery($pool, $session)->find($receivableId);
112
    }
113
114
    /**
115
     * Create a deposit.
116
     *
117
     * @param Pool $pool The pool
118
     * @param Session $session The session
119
     * @param int $receivableId
120
     *
121
     * @return void
122
     */
123
    public function createDeposit(Pool $pool, Session $session, int $receivableId): void
124
    {
125
        $receivable = $this->getReceivable($pool, $session, $receivableId);
126
        if(!$receivable || $receivable->deposit || !$pool->deposit_fixed)
127
        {
128
            throw new MessageException(trans('tontine.subscription.errors.not_found'));
129
        }
130
131
        $deposit = new Deposit();
132
        $deposit->receivable()->associate($receivable);
133
        $deposit->session()->associate($session);
134
        $deposit->save();
135
    }
136
137
    /**
138
     * Create a deposit.
139
     *
140
     * @param Pool $pool The pool
141
     * @param Session $session The session
142
     * @param int $receivableId
143
     * @param int $amount
144
     *
145
     * @return void
146
     */
147
    public function saveDepositAmount(Pool $pool, Session $session, int $receivableId, int $amount): void
148
    {
149
        $receivable = $this->getReceivable($pool, $session, $receivableId);
150
        if(!$receivable || $pool->deposit_fixed)
151
        {
152
            throw new MessageException(trans('tontine.subscription.errors.not_found'));
153
        }
154
155
        if($receivable->deposit !== null)
156
        {
157
            $receivable->deposit->amount = $amount;
158
            $receivable->deposit->save();
159
            return;
160
        }
161
162
        $deposit = new Deposit();
163
        $deposit->amount = $amount;
164
        $deposit->receivable()->associate($receivable);
165
        $deposit->session()->associate($session);
166
        $deposit->save();
167
    }
168
169
    /**
170
     * Delete a deposit.
171
     *
172
     * @param Pool $pool The pool
173
     * @param Session $session The session
174
     * @param int $receivableId
175
     *
176
     * @return void
177
     */
178
    public function deleteDeposit(Pool $pool, Session $session, int $receivableId): void
179
    {
180
        $receivable = $this->getReceivable($pool, $session, $receivableId);
181
        if(!$receivable || !$receivable->deposit)
182
        {
183
            throw new MessageException(trans('tontine.subscription.errors.not_found'));
184
        }
185
        if(($receivable->deposit->online))
186
        {
187
            throw new MessageException(trans('tontine.subscription.errors.online'));
188
        }
189
        $receivable->deposit()->delete();
190
    }
191
192
    /**
193
     * Create all deposits for a pool.
194
     *
195
     * @param Pool $pool The pool
196
     * @param Session $session The session
197
     *
198
     * @return void
199
     */
200
    public function createAllDeposits(Pool $pool, Session $session): void
201
    {
202
        $receivables = $this->getQuery($pool, $session)->whereDoesntHave('deposit')->get();
203
        if($receivables->count() === 0)
204
        {
205
            return;
206
        }
207
208
        DB::transaction(function() use($session, $receivables) {
209
            foreach($receivables as $receivable)
210
            {
211
                $deposit = new Deposit();
212
                $deposit->receivable()->associate($receivable);
213
                $deposit->session()->associate($session);
214
                $deposit->save();
215
            }
216
        });
217
    }
218
219
    /**
220
     * Delete all deposits for a pool.
221
     *
222
     * @param Pool $pool The pool
223
     * @param Session $session The session
224
     *
225
     * @return void
226
     */
227
    public function deleteAllDeposits(Pool $pool, Session $session): void
228
    {
229
        $receivables = $this->getQuery($pool, $session)->whereHas('deposit')->get();
230
        if($receivables->count() === 0)
231
        {
232
            return;
233
        }
234
235
        DB::transaction(function() use($session, $receivables) {
236
            foreach($receivables as $receivable)
237
            {
238
                $receivable->deposit()->where('session_id', $session->id)->delete();
239
            }
240
        });
241
    }
242
243
    /**
244
     * Delete all deposits for a pool.
245
     *
246
     * @param Pool $pool The pool
247
     * @param Session $session The session
248
     *
249
     * @return int
250
     */
251
    public function countDeposits(Pool $pool, Session $session): int
252
    {
253
        return $this->getQuery($pool, $session)->whereHas('deposit')->count();
254
    }
255
}
256