ReportService   A
last analyzed

Complexity

Total Complexity 8

Size/Duplication

Total Lines 198
Duplicated Lines 0 %

Importance

Changes 12
Bugs 0 Features 0
Metric Value
eloc 97
dl 0
loc 198
rs 10
c 12
b 0
f 0
wmc 8

7 Methods

Rating   Name   Duplication   Size   Complexity  
A getCreditReport() 0 26 1
A __construct() 0 6 1
A setDebtAmount() 0 5 2
A getSavingsReport() 0 16 1
A getSessionEntry() 0 22 1
A getRoundReport() 0 19 1
A getSessionReport() 0 44 1
1
<?php
2
3
namespace Siak\Tontine\Service\Report;
4
5
use Siak\Tontine\Model\Loan;
6
use Siak\Tontine\Model\Round;
7
use Siak\Tontine\Model\Session;
8
use Siak\Tontine\Service\LocaleService;
9
use Siak\Tontine\Service\Meeting\Credit\DebtCalculator;
10
use Siak\Tontine\Service\Meeting\Pool\PoolService;
11
use Siak\Tontine\Service\Meeting\Saving\FundService;
12
use Siak\Tontine\Service\Meeting\Saving\ProfitService;
13
use Siak\Tontine\Service\Meeting\Session\SummaryService;
14
use Siak\Tontine\Service\Report\RoundService;
15
16
use function compact;
17
18
class ReportService
19
{
20
    /**
21
     * @param LocaleService $localeService
22
     * @param PoolService $poolService
23
     * @param SessionService $sessionService
24
     * @param MemberService $memberService
25
     * @param RoundService $roundService
26
     * @param FundService $fundService
27
     * @param SummaryService $summaryService
28
     * @param ProfitService $profitService
29
     * @param DebtCalculator $debtCalculator
30
     */
31
    public function __construct(protected LocaleService $localeService,
32
        protected PoolService $poolService, protected SessionService $sessionService,
33
        protected MemberService $memberService, protected RoundService $roundService,
34
        protected FundService $fundService, protected SummaryService $summaryService,
35
        protected ProfitService $profitService, protected DebtCalculator $debtCalculator)
36
    {}
37
38
    /**
39
     * @param Session $session
40
     *
41
     * @return array
42
     */
43
    public function getSessionReport(Session $session): array
44
    {
45
        $guild = $session->round->guild;
46
        [$country] = $this->localeService->getNameFromGuild($guild);
47
48
        return [
49
            'guild' => $guild,
50
            'session' => $session,
51
            'country' => $country,
52
            'deposits' => [
53
                'session' => $session,
54
                'pools' => $this->poolService->getPoolsWithReceivables($session),
55
                'receivables' => $this->memberService->getReceivables($session),
56
                'extras' => $this->memberService->getExtraDeposits($session),
57
            ],
58
            'remitments' => [
59
                'session' => $session,
60
                'pools' => $this->sessionService->getPayables($session),
61
                'payables' => $this->memberService->getPayables($session),
62
                'auctions' => $this->memberService->getAuctions($session),
63
            ],
64
            'bills' => [
65
                'bills' => $this->memberService->getBills($session),
66
                'charges' => [
67
                    'session' => $this->sessionService->getSessionCharges($session),
68
                    'total' => $this->sessionService->getTotalCharges($session),
69
                ],
70
            ],
71
            'loans' => [
72
                'loans' => $this->memberService->getLoans($session),
73
                'total' => $this->sessionService->getLoan($session),
74
            ],
75
            'refunds' => [
76
                'refunds' => $this->memberService->getRefunds($session),
77
                'total' => $this->sessionService->getRefund($session),
78
            ],
79
            'savings' => [
80
                'savings' => $this->memberService->getSavings($session),
81
                'funds' => $this->fundService->getSessionFundList($session),
82
                'total' => $this->sessionService->getSaving($session),
83
            ],
84
            'outflows' => [
85
                'outflows' => $this->memberService->getOutflows($session),
86
                'total' => $this->sessionService->getOutflow($session),
87
            ],
88
        ];
89
    }
90
91
    /**
92
     * @param Session $session
93
     *
94
     * @return array
95
     */
96
    public function getSessionEntry(Session $session): array
97
    {
98
        $guild = $session->round->guild;
99
        [$country] = $this->localeService->getNameFromGuild($guild);
100
101
        return [
102
            'guild' => $guild,
103
            'session' => $session,
104
            'country' => $country,
105
            'deposits' => [
106
                'session' => $session,
107
                'receivables' => $this->memberService->getReceivables($session),
108
                'pools' => $this->sessionService->getReceivables($session),
109
            ],
110
            'remitments' => [
111
                'session' => $session,
112
                'payables' => $this->memberService->getPayables($session),
113
                'pools' => $this->sessionService->getPayables($session),
114
            ],
115
            'bills' => [
116
                'bills' => $this->memberService->getBills($session),
117
                'charges' => $session->round->charges()->fixed()->get(),
118
            ],
119
        ];
120
    }
121
122
    /**
123
     * @param Session $session
124
     *
125
     * @return array
126
     */
127
    public function getSavingsReport(Session $session): array
128
    {
129
        $guild = $session->round->guild;
130
        [$country] = $this->localeService->getNameFromGuild($guild);
131
        $funds = $this->fundService->getSessionFunds($session);
132
        $profits = $session->funds->keyBy('id')->map(fn($fund) => $fund->profit_amount);
133
134
        $funds = $funds
135
            ->map(fn($fund) => [
136
                'fund' => $fund,
137
                'distribution' => $this->profitService->getDistribution($session,
138
                    $fund, $profits[$fund->id] ?? 0),
139
            ])
140
            ->filter(fn($report) => $report['distribution']->savings->count() > 0);
141
142
        return compact('guild', 'session', 'country', 'funds');
143
    }
144
145
    /**
146
     * @param Loan $loan
147
     * @param Session $session
148
     *
149
     * @return void
150
     */
151
    private function setDebtAmount(Loan $loan, Session $session)
152
    {
153
        if(($debt = $loan->i_debt) !== null)
0 ignored issues
show
Bug introduced by
The property i_debt does not seem to exist on Siak\Tontine\Model\Loan. 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...
154
        {
155
            $loan->iDebtAmount = $this->debtCalculator->getDebtAmount($debt, $session);
0 ignored issues
show
Bug introduced by
The property iDebtAmount does not seem to exist on Siak\Tontine\Model\Loan. 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...
156
        }
157
    }
158
159
    /**
160
     * @param Session $session
161
     *
162
     * @return array
163
     */
164
    public function getCreditReport(Session $session): array
165
    {
166
        $round = $session->round;
167
        $guild = $round->guild;
168
        [$country, $currency] = $this->localeService->getNameFromGuild($guild);
169
170
        $funds = $this->fundService->getSessionFunds($session)
171
            ->each(function($fund) use($session) {
172
                $sessionIds = $this->fundService->getFundSessionIds($fund, $session);
173
                $fund->loans = Loan::select('loans.*')
174
                    ->join('sessions', 'loans.session_id', '=', 'sessions.id')
175
                    ->where(fn($query) => $query->where('fund_id', $fund->id))
176
                    ->whereIn('loans.session_id', $sessionIds)
177
                    ->with(['member', 'session', 'debts.refund', 'debts.refund.session',
178
                        'debts.partial_refunds' => function($query) use($sessionIds) {
179
                            $query->whereIn('session_id', $sessionIds);
180
                        },
181
                        'debts.partial_refunds.session'])
182
                    ->orderBy('sessions.day_date')
0 ignored issues
show
Bug introduced by
'sessions.day_date' of type string is incompatible with the type Closure|Illuminate\Datab...\Database\Query\Builder expected by parameter $column of Illuminate\Database\Query\Builder::orderBy(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

182
                    ->orderBy(/** @scrutinizer ignore-type */ 'sessions.day_date')
Loading history...
183
                    ->get()
184
                    ->each(fn(Loan $loan) => $this->setDebtAmount($loan, $session))
185
                    ->groupBy('member.id');
186
            })
187
            ->filter(fn($fund) => $fund->loans->count() > 0);
188
189
        return compact('guild', 'round', 'session', 'country', 'currency', 'funds');
190
    }
191
192
    /**
193
     * @param Round $round
194
     *
195
     * @return array
196
     */
197
    public function getRoundReport(Round $round): array
198
    {
199
        [$country, $currency] = $this->localeService->getNameFromGuild($round->guild);
200
201
        $figures = $this->summaryService->getFigures($round);
202
      
203
        $sessions = $this->roundService->getRoundSessions($round);
204
        $sessionIds = $sessions->pluck('id');
205
        $balance = [
206
            'sessions' => $sessions,
207
            'settlements' => $this->roundService->getSettlementAmounts($sessionIds),
208
            'loans' => $this->roundService->getLoanAmounts($sessionIds),
209
            'refunds' => $this->roundService->getRefundAmounts($sessionIds),
210
            'savings' => $this->roundService->getSavingAmounts($sessionIds),
211
            'outflows' => $this->roundService->getOutflowAmounts($sessionIds),
212
            'pools' => $this->summaryService->getPoolsBalance($figures),
213
        ];
214
215
        return compact('round', 'country', 'currency', 'figures', 'balance');
216
    }
217
}
218