Passed
Pull Request — main (#48)
by Thierry
13:20
created

MemberService::getFines()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 34
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 21
nc 1
nop 2
dl 0
loc 34
rs 9.584
c 0
b 0
f 0

1 Method

Rating   Name   Duplication   Size   Complexity  
A MemberService::getLoans() 0 11 1
1
<?php
2
3
namespace Siak\Tontine\Service\Report;
4
5
use Illuminate\Database\Eloquent\Builder;
6
use Illuminate\Support\Collection;
7
use Siak\Tontine\Model\Auction;
8
use Siak\Tontine\Model\Bill;
9
use Siak\Tontine\Model\Debt;
10
use Siak\Tontine\Model\Member;
11
use Siak\Tontine\Model\Session;
12
use Siak\Tontine\Service\BalanceCalculator;
13
use Siak\Tontine\Service\TenantService;
14
15
class MemberService
16
{
17
    /**
18
     * @var TenantService
19
     */
20
    protected TenantService $tenantService;
21
22
    /**
23
     * @var BalanceCalculator
24
     */
25
    protected BalanceCalculator $balanceCalculator;
26
27
    /**
28
     * @param TenantService $tenantService
29
     * @param BalanceCalculator $balanceCalculator
30
     */
31
    public function __construct(TenantService $tenantService, BalanceCalculator $balanceCalculator)
32
    {
33
        $this->tenantService = $tenantService;
34
        $this->balanceCalculator = $balanceCalculator;
35
    }
36
37
    /**
38
     * Get a paginated list of members.
39
     *
40
     * @param int $page
41
     *
42
     * @return Collection
43
     */
44
    public function getMembers(int $page = 0): Collection
45
    {
46
        return $this->tenantService->tontine()->members()->active()
47
            ->page($page, $this->tenantService->getLimit())
48
            ->orderBy('name', 'asc')->get();
49
    }
50
51
    /**
52
     * Get the number of members.
53
     *
54
     * @return int
55
     */
56
    public function getMemberCount(): int
57
    {
58
        return $this->tenantService->tontine()->members()->active()->count();
59
    }
60
61
    /**
62
     * @param Session $session
63
     * @param Member $member|null
64
     *
65
     * @return Collection
66
     */
67
    public function getReceivables(Session $session, ?Member $member = null): Collection
68
    {
69
        return $session->receivables()
70
            ->when($member !== null, function($query) use($member) {
71
                return $query->whereHas('subscription', function(Builder $query) use($member) {
72
                    $query->where('member_id', $member->id);
73
                });
74
            })
75
            ->with(['deposit', 'subscription.pool', 'subscription.member'])
76
            ->get()
77
            ->each(function($receivable) {
78
                $receivable->pool = $receivable->subscription->pool;
79
                $receivable->member = $receivable->subscription->member;
80
                $receivable->paid = ($receivable->deposit !== null);
81
                $receivable->amount = $this->balanceCalculator->getReceivableAmount($receivable);
82
            })
83
            // Sort by member name
84
            ->when($member === null, function($collection) {
85
                return $collection->sortBy('member.name', SORT_LOCALE_STRING)->values();
86
            });
87
    }
88
89
    /**
90
     * @param Session $session
91
     * @param Member $member|null
92
     *
93
     * @return Collection
94
     */
95
    public function getPayables(Session $session, ?Member $member = null): Collection
96
    {
97
        return $session->payables()
98
            ->when($member !== null, function($query) use($member) {
99
                return $query->whereHas('subscription', function(Builder $query) use($member) {
100
                    $query->where('member_id', $member->id);
101
                });
102
            })
103
            ->with(['remitment', 'subscription.pool', 'subscription.member'])
104
            ->get()
105
            ->each(function($payable) use($session) {
106
                $payable->pool = $payable->subscription->pool;
107
                $payable->member = $payable->subscription->member;
108
                $payable->paid = ($payable->remitment !== null);
109
                $payable->amount = $this->balanceCalculator->getPayableAmount($payable, $session);
110
            })
111
            // Sort by member name
112
            ->when($member === null, function($collection) {
113
                return $collection->sortBy('member.name', SORT_LOCALE_STRING)->values();
114
            });
115
    }
116
117
    /**
118
     * @param Session $session
119
     * @param Member $member|null
120
     *
121
     * @return Collection
122
     */
123
    public function getAuctions(Session $session, ?Member $member = null): Collection
124
    {
125
        return $session->auctions()
126
            ->when($member !== null, function($query) use($member) {
127
                return $query->whereHas('remitment', function($query) use($member) {
128
                    $query->whereHas('payable', function($query) use($member) {
129
                        $query->whereHas('subscription', function($query) use($member) {
130
                            $query->where('member_id', $member->id);
131
                        });
132
                    });
133
                });
134
            })
135
            ->with(['remitment.payable.subscription.pool',
136
                'remitment.payable.subscription.member'])
137
            ->get()
138
            ->each(function(Auction $auction) {
139
                $subscription = $auction->remitment->payable->subscription;
140
                $auction->member = $subscription->member;
0 ignored issues
show
Bug introduced by
The property member does not seem to exist on Siak\Tontine\Model\Auction. Are you sure there is no database migration missing?

Checks if undeclared accessed properties appear in database migrations and if the creating migration is correct.

Loading history...
141
                $auction->pool = $subscription->pool;
0 ignored issues
show
Bug introduced by
The property pool does not seem to exist on Siak\Tontine\Model\Auction. Are you sure there is no database migration missing?

Checks if undeclared accessed properties appear in database migrations and if the creating migration is correct.

Loading history...
142
            })
143
            ->keyBy('remitment.payable.id')
144
            // Sort by member name
145
            ->when($member === null, function($collection) {
146
                return $collection->sortBy('member.name', SORT_LOCALE_STRING)->values();
147
            });
148
    }
149
150
    /**
151
     * @param Session $session
152
     * @param Member $member|null
153
     *
154
     * @return Collection
155
     */
156
    public function getBills(Session $session, ?Member $member = null): Collection
157
    {
158
        return Bill::with(['settlement', 'tontine_bill.member', 'round_bill.member',
159
            'session_bill.member', 'session_bill.session',
160
            'fine_bill.session', 'fine_bill.member'])
161
            ->where(function($query) use($session) {
162
                return $query
163
                    // Unsettled bills.
164
                    ->orWhereDoesntHave('settlement')
165
                    // Bills settled on this session.
166
                    ->orWhereHas('settlement', function(Builder $query) use($session) {
167
                        $query->where('session_id', $session->id);
168
                    });
169
            })
170
            ->where(function($query) use($session, $member) {
171
                return $query
172
                    // Tontine bills.
173
                    ->orWhereHas('tontine_bill', function(Builder $query) use($member) {
174
                        return $query->when($member !== null, function($query) use($member) {
175
                                return $query->where('member_id', $member->id);
176
                            })
177
                            ->when($member === null, function($query) {
178
                                $memberIds = $this->tenantService->tontine()
179
                                    ->members()->active()->pluck('id');
180
                                return $query->whereIn('member_id', $memberIds);
181
                            });
182
                    })
183
                    // Round bills.
184
                    ->orWhereHas('round_bill', function(Builder $query) use($session, $member) {
185
                        return $query->where('round_id', $session->round_id)
186
                            ->when($member !== null, function($query) use($member) {
187
                                return $query->where('member_id', $member->id);
188
                            });
189
                    })
190
                    // Session bills.
191
                    ->orWhereHas('session_bill', function(Builder $query) use($session, $member) {
192
                        return $query->where('session_id', $session->id)
193
                            ->when($member !== null, function($query) use($member) {
194
                                return $query->where('member_id', $member->id);
195
                            });
196
                    })
197
                    // Fine bills, all up to this session.
198
                    ->orWhereHas('fine_bill', function(Builder $query) use($session, $member) {
199
                        $sessionIds = $this->tenantService->getSessionIds($session);
200
                        return $query->whereIn('session_id', $sessionIds)
201
                            ->when($member !== null, function($query) use($member) {
202
                                return $query->where('member_id', $member->id);
203
                            });
204
                    });
205
            })
206
            ->get()
207
            ->each(function($bill) {
208
                // Take the only value which is not null
209
                $_bill = $bill->session_bill ?? $bill->round_bill ??
210
                    $bill->tontine_bill ?? $bill->fine_bill;
211
212
                $bill->paid = $bill->settlement !== null;
213
                $bill->session = $bill->fine_bill ? $_bill->session : null;
214
                $bill->member = $_bill->member;
215
                $bill->charge_id = $_bill->charge_id;
216
            })
217
            // Sort by member name
218
            ->when($member === null, function($collection) {
219
                return $collection->sortBy('member.name', SORT_LOCALE_STRING)->values();
220
            });
221
    }
222
223
    /**
224
     * @param Session $session
225
     * @param Member $member|null
226
     *
227
     * @return Collection
228
     */
229
    public function getLoans(Session $session, ?Member $member = null): Collection
230
    {
231
        return $session->loans()
232
            ->when($member !== null, function($query) use($member) {
233
                return $query->where('member_id', $member->id);
234
            })
235
            ->with(['member', 'principal_debt.refund', 'interest_debt.refund'])
236
            ->get()
237
            // Sort by member name
238
            ->when($member === null, function($collection) {
239
                return $collection->sortBy('member.name', SORT_LOCALE_STRING)->values();
240
            });
241
    }
242
243
    /**
244
     * @param Session $session
245
     * @param Member $member|null
246
     *
247
     * @return Collection
248
     */
249
    public function getDebts(Session $session, ?Member $member = null): Collection
250
    {
251
        return Debt::with(['loan.session', 'loan.member'])
252
            // Member debts
253
            ->when($member !== null, function($query) use($member) {
254
                return $query->whereHas('loan', function(Builder $query) use($member) {
255
                    $query->where('member_id', $member->id);
256
                });
257
            })
258
            // Debts refunded on this session.
259
            ->whereHas('refund', function(Builder $query) use($session) {
260
                $query->where('session_id', $session->id);
261
            })
262
            ->get()
263
            ->each(function($debt) {
264
                $debt->session = $debt->loan->session;
265
                $debt->member = $debt->loan->member;
266
            })
267
            // Sort by member name
268
            ->when($member === null, function($collection) {
269
                return $collection->sortBy('member.name', SORT_LOCALE_STRING)->values();
270
            });
271
    }
272
273
    /**
274
     * @param Session $session
275
     * @param Member $member|null
276
     *
277
     * @return Collection
278
     */
279
    public function getFundings(Session $session, ?Member $member = null): Collection
280
    {
281
        return $session->fundings()->with(['member'])
282
            ->when($member !== null, function($query) use($member) {
283
                return $query->where('member_id', $member->id);
284
            })
285
            ->get()
286
            // Sort by member name
287
            ->when($member === null, function($collection) {
288
                return $collection->sortBy('member.name', SORT_LOCALE_STRING)->values();
289
            });
290
    }
291
292
    /**
293
     * @param Session $session
294
     * @param Member $member|null
295
     *
296
     * @return Collection
297
     */
298
    public function getDisbursements(Session $session, ?Member $member = null): Collection
299
    {
300
        return $session->disbursements()->with(['member', 'category'])
301
            ->when($member !== null, function($query) use($member) {
302
                return $query->where('member_id', $member->id);
303
            })
304
            ->get()
305
            // Sort by member name
306
            ->when($member === null, function($collection) {
307
                return $collection->sortBy('member.name', SORT_LOCALE_STRING)->values();
308
            });
309
    }
310
}
311