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

ReportService   A

Complexity

Total Complexity 11

Size/Duplication

Total Lines 228
Duplicated Lines 0 %

Importance

Changes 12
Bugs 0 Features 0
Metric Value
eloc 87
dl 0
loc 228
rs 10
c 12
b 0
f 0
wmc 11

10 Methods

Rating   Name   Duplication   Size   Complexity  
A getPools() 0 28 1
A getRoundReport() 0 27 2
A getClosings() 0 5 1
A __construct() 0 7 1
A getRoundReportFilename() 0 3 1
A getSessionReportFilename() 0 3 1
A getSessionReport() 0 43 1
A getProfitsReportFilename() 0 3 1
A getFundClosings() 0 4 1
A getProfitsReport() 0 13 1
1
<?php
2
3
namespace Siak\Tontine\Service\Report;
4
5
use Illuminate\Support\Arr;
6
use Illuminate\Support\Collection;
7
use Illuminate\Support\Str;
8
use Siak\Tontine\Model\Round;
9
use Siak\Tontine\Model\Session;
10
use Siak\Tontine\Service\LocaleService;
11
use Siak\Tontine\Service\TenantService;
12
use Siak\Tontine\Service\Meeting\Saving\SavingService;
13
use Siak\Tontine\Service\Meeting\Saving\ProfitService;
14
use Siak\Tontine\Service\Meeting\SummaryService;
15
use Siak\Tontine\Service\Planning\SubscriptionService;
16
use Siak\Tontine\Service\Report\RoundService;
17
use Siak\Tontine\Service\Tontine\FundService;
18
19
use function compact;
20
use function strtolower;
21
use function trans;
22
23
class ReportService
24
{
25
    /**
26
     * @var int
27
     */
28
    private $depositsAmount;
29
30
    /**
31
     * @var int
32
     */
33
    private $remitmentsAmount;
34
35
    /**
36
     * @param LocaleService $localeService
37
     * @param TenantService $tenantService
38
     * @param SessionService $sessionService
39
     * @param MemberService $memberService
40
     * @param RoundService $roundService
41
     * @param FundService $fundService
42
     * @param SavingService $savingService
43
     * @param SummaryService $summaryService
44
     * @param ReportService $reportService
45
     * @param SubscriptionService $subscriptionService
46
     */
47
    public function __construct(protected LocaleService $localeService,
48
        protected TenantService $tenantService, protected SessionService $sessionService,
49
        protected MemberService $memberService, protected RoundService $roundService,
50
        protected FundService $fundService, protected SavingService $savingService,
51
        protected SummaryService $summaryService, protected ProfitService $profitService,
52
        protected SubscriptionService $subscriptionService)
53
    {}
54
55
    /**
56
     * Get pools with receivables and payables.
57
     *
58
     * @param Session $session
59
     *
60
     * @return Collection
61
     */
62
    public function getPools(Session $session): Collection
63
    {
64
        $this->depositsAmount = 0;
65
        $this->remitmentsAmount = 0;
66
        $pools = $this->tenantService->round()->pools;
67
68
        return $pools->each(function($pool) use($session) {
69
            $subscriptionCount = $pool->subscriptions()->count();
70
            $subscriptionIds = $pool->subscriptions()->pluck('id');
71
            // Receivables
72
            $query = $session->receivables()->whereIn('subscription_id', $subscriptionIds);
73
            // Expected
74
            $pool->receivables_count = $query->count();
75
            // Paid
76
            $pool->deposits_count = $query->whereHas('deposit')->count();
77
            // Amount
78
            $pool->deposits_amount = $pool->deposits_count * $pool->amount;
79
            $this->depositsAmount += $pool->deposits_amount;
80
81
            // Payables
82
            $query = $session->payables()->whereIn('subscription_id', $subscriptionIds);
83
            // Expected
84
            $pool->payables_count = $this->summaryService->getSessionRemitmentCount($pool, $session);
85
            // Paid
86
            $pool->remitments_count = $query->whereHas('remitment')->count();
87
            // Amount
88
            $pool->remitments_amount = $pool->remitments_count * $pool->amount * $subscriptionCount;
89
            $this->remitmentsAmount += $pool->remitments_amount;
90
        });
91
    }
92
93
    /**
94
     * @param Session $session
95
     * @param Collection $funds
96
     *
97
     * @return array
98
     */
99
    private function getFundClosings(Session $session, Collection $funds): array
100
    {
101
        $closings = $this->savingService->getSessionClosings($session);
102
        return Arr::only($closings, $funds->keys()->all());
103
    }
104
105
    /**
106
     * @param Session $session
107
     *
108
     * @return array
109
     */
110
    public function getClosings(Session $session): array
111
    {
112
        $closings = $this->savingService->getSessionClosings($session);
113
        $funds = $this->fundService->getFundList();
114
        return Arr::only($closings, $funds->keys()->all());
115
    }
116
117
    /**
118
     * @param Session $session
119
     *
120
     * @return array
121
     */
122
    public function getSessionReport(Session $session): array
123
    {
124
        $tontine = $this->tenantService->tontine();
125
        [$country] = $this->localeService->getNameFromTontine($tontine);
0 ignored issues
show
Bug introduced by
It seems like $tontine can also be of type null; however, parameter $tontine of Siak\Tontine\Service\Loc...e::getNameFromTontine() does only seem to accept Siak\Tontine\Model\Tontine, 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 ignore-type  annotation

125
        [$country] = $this->localeService->getNameFromTontine(/** @scrutinizer ignore-type */ $tontine);
Loading history...
126
127
        return [
128
            'tontine' => $tontine,
129
            'session' => $session,
130
            'country' => $country,
131
            'deposits' => [
132
                'session' => $session,
133
                'receivables' => $this->memberService->getReceivables($session),
134
                'pools' => $this->sessionService->getReceivables($session),
135
            ],
136
            'remitments' => [
137
                'session' => $session,
138
                'payables' => $this->memberService->getPayables($session),
139
                'pools' => $this->sessionService->getPayables($session),
140
                'auctions' => $this->memberService->getAuctions($session),
141
            ],
142
            'bills' => [
143
                'bills' => $this->memberService->getBills($session),
144
                'charges' => [
145
                    'session' => $this->sessionService->getSessionCharges($session),
146
                    'total' => $this->sessionService->getTotalCharges($session),
147
                ],
148
            ],
149
            'loans' => [
150
                'loans' => $this->memberService->getLoans($session),
151
                'total' => $this->sessionService->getLoan($session),
152
            ],
153
            'refunds' => [
154
                'refunds' => $this->memberService->getRefunds($session),
155
                'total' => $this->sessionService->getRefund($session),
156
            ],
157
            'savings' => [
158
                'savings' => $this->memberService->getSavings($session),
159
                'funds' => $this->fundService->getFundList(),
160
                'total' => $this->sessionService->getSaving($session),
161
            ],
162
            'disbursements' => [
163
                'disbursements' => $this->memberService->getDisbursements($session),
164
                'total' => $this->sessionService->getDisbursement($session),
165
            ],
166
        ];
167
    }
168
169
    /**
170
     * @param Session $session
171
     *
172
     * @return array
173
     */
174
    public function getProfitsReport(Session $session): array
175
    {
176
        $tontine = $this->tenantService->tontine();
177
        [$country] = $this->localeService->getNameFromTontine($tontine);
0 ignored issues
show
Bug introduced by
It seems like $tontine can also be of type null; however, parameter $tontine of Siak\Tontine\Service\Loc...e::getNameFromTontine() does only seem to accept Siak\Tontine\Model\Tontine, 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 ignore-type  annotation

177
        [$country] = $this->localeService->getNameFromTontine(/** @scrutinizer ignore-type */ $tontine);
Loading history...
178
        $funds = $this->fundService->getFundList();
179
        $closings = $this->getFundClosings($session, $funds);
180
        $profits = Arr::map($closings, fn($amount, $fundId) => [
181
            'fund' => $funds[$fundId],
182
            'profitAmount' => $amount,
183
            'savings' => $this->profitService->getDistributions($session, $fundId, $amount),
184
        ]);
185
186
        return compact('tontine', 'session', 'country', 'profits');
187
    }
188
189
    /**
190
     * @param Round $round
191
     *
192
     * @return array
193
     */
194
    public function getRoundReport(Round $round): array
195
    {
196
        $tontine = $this->tenantService->tontine();
197
        [$country, $currency] = $this->localeService->getNameFromTontine($tontine);
0 ignored issues
show
Bug introduced by
It seems like $tontine can also be of type null; however, parameter $tontine of Siak\Tontine\Service\Loc...e::getNameFromTontine() does only seem to accept Siak\Tontine\Model\Tontine, 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 ignore-type  annotation

197
        [$country, $currency] = $this->localeService->getNameFromTontine(/** @scrutinizer ignore-type */ $tontine);
Loading history...
198
199
        $pools = $this->subscriptionService->getPools(false)
200
            ->each(function($pool) {
201
                $pool->figures = $this->summaryService->getFigures($pool);
202
            });
203
204
        $sessions = $round->sessions()->orderBy('start_at', 'asc')->get();
205
        // Sessions with data
206
        $sessionIds = $sessions->filter(function($session) {
207
            return $session->status === Session::STATUS_CLOSED ||
208
                $session->status === Session::STATUS_OPENED;
209
        })->pluck('id');
210
        $amounts = [
211
            'sessions' => $sessions,
212
            'auctions' => $this->roundService->getAuctionAmounts($sessionIds),
213
            'settlements' => $this->roundService->getSettlementAmounts($sessionIds),
214
            'loans' => $this->roundService->getLoanAmounts($sessionIds),
215
            'refunds' => $this->roundService->getRefundAmounts($sessionIds),
216
            'savings' => $this->roundService->getSavingAmounts($sessionIds),
217
            'disbursements' => $this->roundService->getDisbursementAmounts($sessionIds),
218
        ];
219
220
        return compact('tontine', 'round', 'country', 'currency', 'pools', 'amounts');
221
    }
222
223
    /**
224
     * @param Session $session
225
     *
226
     * @return string
227
     */
228
    public function getSessionReportFilename(Session $session): string
229
    {
230
        return strtolower(trans('meeting.titles.report')) . '-' . Str::slug($session->title) . '.pdf';
231
    }
232
233
    /**
234
     * @param Session $session
235
     *
236
     * @return string
237
     */
238
    public function getProfitsReportFilename(Session $session): string
239
    {
240
        return Str::slug(trans('meeting.titles.profits')) . '-' . Str::slug($session->title) . '.pdf';
241
    }
242
243
    /**
244
     * @param Round $round
245
     *
246
     * @return string
247
     */
248
    public function getRoundReportFilename(Round $round): string
249
    {
250
        return strtolower(trans('meeting.titles.report')) . '-' . Str::slug($round->title) . '.pdf';
251
    }
252
}
253