Passed
Pull Request — main (#49)
by Thierry
14:14
created

FixedFeeService   A

Complexity

Total Complexity 10

Size/Duplication

Total Lines 221
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 101
c 0
b 0
f 0
dl 0
loc 221
rs 10
wmc 10

10 Methods

Rating   Name   Duplication   Size   Complexity  
A getBills() 0 8 1
A getSettlements() 0 12 1
A getFees() 0 5 1
A __construct() 0 4 1
A getSession() 0 3 1
A getCurrentSessionSettlements() 0 24 1
A getCurrentSessionBills() 0 22 1
A getPreviousSessionsSettlements() 0 27 1
A getFeeCount() 0 3 1
A getPreviousSessionsBills() 0 24 1
1
<?php
2
3
namespace Siak\Tontine\Service\Meeting\Charge;
4
5
use Illuminate\Support\Collection;
6
use Illuminate\Support\Facades\DB;
7
use Siak\Tontine\Model\Session;
8
use Siak\Tontine\Service\LocaleService;
9
use Siak\Tontine\Service\TenantService;
10
11
class FixedFeeService
12
{
13
    /**
14
     * @var LocaleService
15
     */
16
    protected LocaleService $localeService;
17
18
    /**
19
     * @var TenantService
20
     */
21
    protected TenantService $tenantService;
22
23
    /**
24
     * @param LocaleService $localeService
25
     * @param TenantService $tenantService
26
     */
27
    public function __construct(LocaleService $localeService, TenantService $tenantService)
28
    {
29
        $this->localeService = $localeService;
30
        $this->tenantService = $tenantService;
31
    }
32
33
    /**
34
     * Get a single session.
35
     *
36
     * @param int $sessionId    The session id
37
     *
38
     * @return Session|null
39
     */
40
    public function getSession(int $sessionId): ?Session
41
    {
42
        return $this->tenantService->getSession($sessionId);
43
    }
44
45
    /**
46
     * Get a paginated list of fees.
47
     *
48
     * @param int $page
49
     *
50
     * @return Collection
51
     */
52
    public function getFees(int $page = 0): Collection
53
    {
54
        return $this->tenantService->tontine()->charges()
55
            ->fixed()->orderBy('id', 'desc')
56
            ->page($page, $this->tenantService->getLimit())->get();
57
    }
58
59
    /**
60
     * Get the number of fees.
61
     *
62
     * @return int
63
     */
64
    public function getFeeCount(): int
65
    {
66
        return $this->tenantService->tontine()->charges()->fixed()->count();
67
    }
68
69
    /**
70
     * @param Session $session
71
     *
72
     * @return Collection
73
     */
74
    private function getCurrentSessionBills(Session $session): Collection
75
    {
76
        // Count the session bills
77
        $sessionQuery = DB::table('session_bills')
78
            ->select('charge_id', DB::raw('count(*) as total'), DB::raw('sum(amount) as amount'))
79
            ->join('bills', 'session_bills.bill_id', '=', 'bills.id')
80
            ->where('session_bills.session_id', $session->id)
81
            ->groupBy('charge_id');
82
        // Count the round bills
83
        $roundQuery = DB::table('round_bills')
84
            ->select('charge_id', DB::raw('count(*) as total'), DB::raw('sum(amount) as amount'))
85
            ->join('bills', 'round_bills.bill_id', '=', 'bills.id')
86
            ->where('round_bills.round_id', $session->round_id)
87
            ->groupBy('charge_id');
88
        // Count the tontine bills only for active members
89
        $memberIds = $this->tenantService->tontine()->members()->active()->pluck('id');
90
        $tontineQuery = DB::table('tontine_bills')
91
            ->select('charge_id', DB::raw('count(*) as total'), DB::raw('sum(amount) as amount'))
92
            ->join('bills', 'tontine_bills.bill_id', '=', 'bills.id')
93
            ->whereIn('tontine_bills.member_id', $memberIds)
94
            ->groupBy('charge_id');
95
        return $sessionQuery->union($roundQuery)->union($tontineQuery)->get();
96
    }
97
98
    /**
99
     * @param Session $session
100
     *
101
     * @return Collection
102
     */
103
    private function getPreviousSessionsBills(Session $session): Collection
104
    {
105
        // Count the session bills.
106
        $sessionIds = $this->tenantService->round()->sessions()
107
            ->where('start_at', '<', $session->start_at)->pluck('id');
108
        $sessionQuery = DB::table('session_bills')
109
            ->select('charge_id', DB::raw('count(*) as total'), DB::raw('sum(amount) as amount'))
110
            ->join('bills', 'session_bills.bill_id', '=', 'bills.id')
111
            ->whereIn('session_bills.session_id', $sessionIds)
112
            ->groupBy('charge_id');
113
        // Count the round bills.
114
        $roundQuery = DB::table('round_bills')
115
            ->select('charge_id', DB::raw('count(*) as total'), DB::raw('sum(amount) as amount'))
116
            ->join('bills', 'round_bills.bill_id', '=', 'bills.id')
117
            ->where('round_bills.round_id', $session->round_id)
118
            ->groupBy('charge_id');
119
        // Count the tontine bills only for active members.
120
        $memberIds = $this->tenantService->tontine()->members()->active()->pluck('id');
121
        $tontineQuery = DB::table('tontine_bills')
122
            ->select('charge_id', DB::raw('count(*) as total'), DB::raw('sum(amount) as amount'))
123
            ->join('bills', 'tontine_bills.bill_id', '=', 'bills.id')
124
            ->whereIn('tontine_bills.member_id', $memberIds)
125
            ->groupBy('charge_id');
126
        return $sessionQuery->union($roundQuery)->union($tontineQuery)->get();
127
    }
128
129
    /**
130
     * @param Session $session
131
     *
132
     * @return Collection
133
     */
134
    private function getCurrentSessionSettlements(Session $session): Collection
135
    {
136
        // Count the session bills settlements.
137
        $sessionQuery = DB::table('settlements')
138
            ->select('charge_id', DB::raw('count(*) as total'), DB::raw('sum(amount) as amount'))
139
            ->join('bills', 'settlements.bill_id', '=', 'bills.id')
140
            ->join('session_bills', 'session_bills.bill_id', '=', 'bills.id')
141
            ->where('settlements.session_id', $session->id)
142
            ->groupBy('charge_id');
143
        // Count the round bills settlements.
144
        $roundQuery = DB::table('settlements')
145
            ->select('charge_id', DB::raw('count(*) as total'), DB::raw('sum(amount) as amount'))
146
            ->join('bills', 'settlements.bill_id', '=', 'bills.id')
147
            ->join('round_bills', 'round_bills.bill_id', '=', 'bills.id')
148
            ->where('settlements.session_id', $session->id)
149
            ->groupBy('charge_id');
150
        // Count the tontine bills settlements.
151
        $tontineQuery = DB::table('settlements')
152
            ->select('charge_id', DB::raw('count(*) as total'), DB::raw('sum(amount) as amount'))
153
            ->join('bills', 'settlements.bill_id', '=', 'bills.id')
154
            ->join('tontine_bills', 'tontine_bills.bill_id', '=', 'bills.id')
155
            ->where('settlements.session_id', $session->id)
156
            ->groupBy('charge_id');
157
        return $sessionQuery->union($roundQuery)->union($tontineQuery)->get();
158
    }
159
160
    /**
161
     * @param Session $session
162
     *
163
     * @return Collection
164
     */
165
    private function getPreviousSessionsSettlements(Session $session): Collection
166
    {
167
        // The current and future sessions ids.
168
        $sessionIds = $this->tenantService->sessions()
169
            ->where('start_at', '>=', $session->start_at)->pluck('id');
170
        // Count the session bills settlements.
171
        $sessionQuery = DB::table('settlements')
172
            ->select('charge_id', DB::raw('count(*) as total'), DB::raw('sum(amount) as amount'))
173
            ->join('bills', 'settlements.bill_id', '=', 'bills.id')
174
            ->join('session_bills', 'session_bills.bill_id', '=', 'bills.id')
175
            ->whereNotIn('settlements.session_id', $sessionIds)
176
            ->groupBy('charge_id');
177
        // Count the round bills settlements.
178
        $roundQuery = DB::table('settlements')
179
            ->select('charge_id', DB::raw('count(*) as total'), DB::raw('sum(amount) as amount'))
180
            ->join('bills', 'settlements.bill_id', '=', 'bills.id')
181
            ->join('round_bills', 'round_bills.bill_id', '=', 'bills.id')
182
            ->whereNotIn('settlements.session_id', $sessionIds)
183
            ->groupBy('charge_id');
184
        // Count the tontine bills settlements.
185
        $tontineQuery = DB::table('settlements')
186
            ->select('charge_id', DB::raw('count(*) as total'), DB::raw('sum(amount) as amount'))
187
            ->join('bills', 'settlements.bill_id', '=', 'bills.id')
188
            ->join('tontine_bills', 'tontine_bills.bill_id', '=', 'bills.id')
189
            ->whereNotIn('settlements.session_id', $sessionIds)
190
            ->groupBy('charge_id');
191
        return $sessionQuery->union($roundQuery)->union($tontineQuery)->get();
192
    }
193
194
    /**
195
     * Get the report of bills
196
     *
197
     * @param Session $session
198
     *
199
     * @return array
200
     */
201
    public function getBills(Session $session): array
202
    {
203
        $currentBills = $this->getCurrentSessionBills($session);
204
        $previousBills = $this->getPreviousSessionsBills($session);
205
        return [
206
            'total' => [
207
                'current' => $currentBills->pluck('total', 'charge_id'),
208
                'previous' => $previousBills->pluck('total', 'charge_id'),
209
            ],
210
        ];
211
    }
212
213
    /**
214
     * Get the report of settlements
215
     *
216
     * @param Session $session
217
     *
218
     * @return array
219
     */
220
    public function getSettlements(Session $session): array
221
    {
222
        $currentSettlements = $this->getCurrentSessionSettlements($session);
223
        $previousSettlements = $this->getPreviousSessionsSettlements($session);
224
        return [
225
            'total' => [
226
                'current' => $currentSettlements->pluck('total', 'charge_id'),
227
                'previous' => $previousSettlements->pluck('total', 'charge_id'),
228
            ],
229
            'amount' => [
230
                'current' => $currentSettlements->pluck('amount', 'charge_id'),
231
                'previous' => $previousSettlements->pluck('amount', 'charge_id'),
232
            ],
233
        ];
234
    }
235
}
236