Passed
Push — main ( ef0742...4e298b )
by Thierry
11:40
created

FundService::getFirstFund()   A

Complexity

Conditions 2
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 2
nc 1
nop 1
dl 0
loc 4
rs 10
c 1
b 0
f 0
1
<?php
2
3
namespace Siak\Tontine\Service\Meeting\Saving;
4
5
use Illuminate\Database\Eloquent\Builder;
6
use Illuminate\Database\Eloquent\Relations\Relation;
7
use Illuminate\Support\Collection;
8
use Siak\Tontine\Model\Fund;
9
use Siak\Tontine\Model\Round;
10
use Siak\Tontine\Model\Session;
11
use Siak\Tontine\Service\TenantService;
12
13
class FundService
14
{
15
    /**
16
     * @param TenantService $tenantService
17
     */
18
    public function __construct(protected TenantService $tenantService)
19
    {}
20
21
    /**
22
     * @param Session $session
23
     * @param bool $onlyReal
24
     *
25
     * @return Relation|Builder
26
     */
27
    private function getSessionQuery(Session $session, bool $onlyReal): Relation|Builder
28
    {
29
        return $session->funds()
30
            ->join('fund_defs', 'fund_defs.id', '=', 'funds.def_id')
31
            ->when($onlyReal, fn(Builder $query) => $query->real())
32
            ->with(['pool'])
33
            ->orderBy('fund_defs.type') // The default fund is first in the list.
34
            ->orderBy('funds.id');
35
    }
36
37
    /**
38
     * Get the active funds of a session.
39
     *
40
     * @param Session $session
41
     * @param bool $onlyReal
42
     *
43
     * @return Collection
44
     */
45
    public function getSessionFunds(Session $session, bool $onlyReal = true): Collection
46
    {
47
        return $this->getSessionQuery($session, $onlyReal)->get();
48
    }
49
50
    /**
51
     * @param Session $session
52
     *
53
     * @return Collection
54
     */
55
    public function getStartingFunds(Session $session): Collection
56
    {
57
        return $this->getSessionFunds($session, true)
58
            ->filter(fn($fund) => $fund->start_sid === $session->id && $fund->start_amount > 0);
59
    }
60
61
    /**
62
     * @param Session $session
63
     *
64
     * @return Collection
65
     */
66
    public function getEndingFunds(Session $session): Collection
67
    {
68
        return $this->getSessionFunds($session, true)
69
            ->filter(fn($fund) => $fund->end_sid === $session->id && $fund->end_amount > 0);
70
    }
71
72
    /**
73
     * Get a list of funds for the dropdown select component.
74
     *
75
     * @param Session $session
76
     * @param bool $onlyReal
77
     *
78
     * @return Collection
79
     */
80
    public function getSessionFundList(Session $session, bool $onlyReal = true): Collection
81
    {
82
        return $this->getSessionQuery($session, $onlyReal)
83
            ->select(['funds.id'])
84
            // Since the "title" field is defined in the model and not in the database,
85
            // we need to get the data before we call the pluck() method.
86
            ->get()
87
            ->pluck('title', 'id');
88
    }
89
90
    /**
91
     * Get the default fund.
92
     *
93
     * @param Round $round
94
     *
95
     * @return Fund|null
96
     */
97
    public function getDefaultFund(Round $round): ?Fund
98
    {
99
        return $round->guild->default_fund
100
            ->funds()->real()->where('round_id', $round->id)->first();
101
    }
102
103
    /**
104
     * @param Session $session
105
     *
106
     * @return Fund|null
107
     */
108
    public function getFirstFund(Session $session): ?Fund
109
    {
110
        return $this->getDefaultFund($session->round) ?:
111
            $this->getSessionQuery($session, onlyReal: true)->first();
112
    }
113
114
    /**
115
     * Get an active fund of a session.
116
     *
117
     * @param Session $session
118
     * @param int $fundId
119
     * @param bool $onlyReal
120
     *
121
     * @return Fund|null
122
     */
123
    public function getSessionFund(Session $session, int $fundId, bool $onlyReal = true): ?Fund
124
    {
125
        if($fundId === 0)
126
        {
127
            return $this->getDefaultFund($session->round);
128
        }
129
130
        $fund = $session->funds()
131
            ->when($onlyReal, fn(Builder $query) => $query->real())
132
            ->with(['pool'])
133
            ->find($fundId);
134
        return $fund ?? $this->getDefaultFund($session->round);
135
    }
136
137
    /**
138
     * @param Fund $fund
139
     * @param Session $session
140
     *
141
     * @return Builder|Relation
142
     */
143
    private function getFundSessionsQuery(Fund $fund, Session $session): Builder|Relation
144
    {
145
        return $fund->sessions()
146
            ->where('day_date', '<=', $session->day_date)
147
            ->where('day_date', '<=', $fund->interest->day_date);
148
    }
149
150
    /**
151
     * Get the sessions to be used for profit calculation.
152
     *
153
     * @param Fund $fund
154
     * @param Session $session
155
     *
156
     * @return Collection
157
     */
158
    public function getFundSessions(Fund $fund, Session $session): Collection
159
    {
160
        return $this->getFundSessionsQuery($fund, $session)->get();
161
    }
162
163
    /**
164
     * Get the id of sessions to be used for profit calculation.
165
     *
166
     * @param Fund $fund
167
     * @param Session $session
168
     *
169
     * @return Collection
170
     */
171
    public function getFundSessionIds(Fund $fund, Session $session): Collection
172
    {
173
        return $this->getFundSessionsQuery($fund, $session)->pluck('id');
174
    }
175
}
176