FundService::disableFund()   A
last analyzed

Complexity

Conditions 4
Paths 3

Size

Total Lines 16
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 4
eloc 7
c 1
b 0
f 0
nc 3
nop 2
dl 0
loc 16
rs 10
1
<?php
2
3
namespace Siak\Tontine\Service\Planning;
4
5
use Illuminate\Database\Eloquent\Builder;
6
use Illuminate\Database\Eloquent\Relations\Relation;
7
use Illuminate\Support\Collection;
8
use Siak\Tontine\Exception\MessageException;
9
use Siak\Tontine\Model\Fund;
10
use Siak\Tontine\Model\FundDef;
11
use Siak\Tontine\Model\Round;
12
use Siak\Tontine\Service\TenantService;
13
use Exception;
14
15
class FundService
16
{
17
    use SessionTrait;
0 ignored issues
show
introduced by
The trait Siak\Tontine\Service\Planning\SessionTrait requires some properties which are not provided by Siak\Tontine\Service\Planning\FundService: $end, $start, $day_date
Loading history...
18
19
    /**
20
     * @param TenantService $tenantService
21
     */
22
    public function __construct(protected TenantService $tenantService)
23
    {}
24
25
    /**
26
     * @param Round $round
27
     * @param bool $filter|null
28
     *
29
     * @return Relation
30
     */
31
    private function getQuery(Round $round, ?bool $filter): Relation
32
    {
33
        $onRoundFilter = fn(Builder|Relation $q) => $q->ofRound($round);
34
        return $round->guild->funds()
35
            ->when($filter === true, fn(Builder|Relation $query) => $query
36
                ->whereHas('funds', $onRoundFilter))
37
            ->when($filter === false, fn(Builder|Relation $query) => $query
38
                ->whereDoesntHave('funds', $onRoundFilter));
39
    }
40
41
    /**
42
     * Get a paginated list of funds.
43
     *
44
     * @param Round $round
45
     * @param bool $filter|null
46
     * @param int $page
47
     *
48
     * @return Collection
49
     */
50
    public function getFundDefs(Round $round, ?bool $filter, int $page = 0): Collection
51
    {
52
        return $this->getQuery($round, $filter)
53
            ->with([
54
                'funds' => fn(Builder|Relation $q) =>
55
                    $q->where('round_id', $round->id),
56
            ])
57
            ->withCount([
58
                'funds as funds_in_round_count' =>
59
                    fn(Builder|Relation $q) => $q->ofRound($round),
60
            ])
61
            ->page($page, $this->tenantService->getLimit())
62
            ->get();
63
    }
64
65
    /**
66
     * Get the number of funds.
67
     *
68
     * @param Round $round
69
     * @param bool $filter|null
70
     *
71
     * @return int
72
     */
73
    public function getFundDefCount(Round $round, ?bool $filter): int
74
    {
75
        return $this->getQuery($round, $filter)->count();
76
    }
77
78
    /**
79
     * Get a fund.
80
     *
81
     * @param Round $round
82
     * @param int $fundId
83
     *
84
     * @return Fund|null
85
     */
86
    public function getFund(Round $round, int $fundId): ?Fund
87
    {
88
        return Fund::ofRound($round)->with(['sessions'])->find($fundId);
89
    }
90
91
    /**
92
     * @param Round $round
93
     * @param int $defId
94
     *
95
     * @return FundDef|null
96
     */
97
    public function getFundDef(Round $round, int $defId): ?FundDef
98
    {
99
        return $round->guild->funds()
100
            // ->user()
101
            ->withCount([
102
                'funds' => fn(Builder|Relation $q) =>
103
                    $q->where('round_id', $round->id),
104
            ])
105
            ->find($defId);
106
    }
107
108
    /**
109
     * @param Round $round
110
     * @param int $defId
111
     *
112
     * @return void
113
     */
114
    public function enableFund(Round $round, int $defId): void
115
    {
116
        $def = $this->getFundDef($round, $defId);
117
        if(!$def || $def->funds_count > 0)
0 ignored issues
show
Bug introduced by
The property funds_count does not exist on Siak\Tontine\Model\FundDef. Did you mean funds?
Loading history...
118
        {
119
            return; // Todo: throw an exception
120
        }
121
122
        $itemQuery = Fund::withoutGlobalScopes()->where('def_id', $defId);
123
        $startSession = $this->getStartSession($round, $itemQuery);
0 ignored issues
show
Bug introduced by
It seems like $itemQuery can also be of type Illuminate\Database\Eloq...gHasThroughRelationship; however, parameter $itemQuery of Siak\Tontine\Service\Pla...vice::getStartSession() does only seem to accept Illuminate\Database\Eloquent\Builder, 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

123
        $startSession = $this->getStartSession($round, /** @scrutinizer ignore-type */ $itemQuery);
Loading history...
124
        $endSession = $this->getEndSession($round, $itemQuery);
0 ignored issues
show
Bug introduced by
It seems like $itemQuery can also be of type Illuminate\Database\Eloq...gHasThroughRelationship; however, parameter $itemQuery of Siak\Tontine\Service\Pla...ervice::getEndSession() does only seem to accept Illuminate\Database\Eloquent\Builder, 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

124
        $endSession = $this->getEndSession($round, /** @scrutinizer ignore-type */ $itemQuery);
Loading history...
125
        if($endSession->day_date <= $startSession->day_date)
126
        {
127
            return; // Todo: throw an exception
128
        }
129
130
        // Create the fund
131
        $def->funds()->create([
132
            'round_id' => $round->id,
133
            'start_sid' => $startSession->id,
134
            'end_sid' => $endSession->id,
135
            'interest_sid' => $endSession->id,
136
        ]);
137
    }
138
139
    /**
140
     * @param Round $round
141
     * @param int $defId
142
     *
143
     * @return void
144
     */
145
    public function disableFund(Round $round, int $defId): void
146
    {
147
        $def = $this->getFundDef($round, $defId);
148
        if(!$def || $def->funds_count === 0)
0 ignored issues
show
Bug introduced by
The property funds_count does not exist on Siak\Tontine\Model\FundDef. Did you mean funds?
Loading history...
149
        {
150
            return;
151
        }
152
153
        try
154
        {
155
            // Delete the fund
156
            $def->funds()->where('round_id', $round->id)->delete();
157
        }
158
        catch(Exception $e)
159
        {
160
            throw new MessageException(trans('tontine.fund.errors.cannot_remove'));
161
        }
162
    }
163
164
    /**
165
     * Save the fund sessions.
166
     *
167
     * @param Fund $fund
168
     * @param array $values
169
     *
170
     * @return void
171
     */
172
    public function saveSessions(Fund $fund, array $values)
173
    {
174
        $fund->update($values);
175
    }
176
177
    /**
178
     * Get the number of active funds in the round.
179
     *
180
     * @param Round $round
181
     *
182
     * @return int
183
     */
184
    public function getFundCount(Round $round): int
185
    {
186
        return $round->funds()->real()/*->user()*/->count();
187
    }
188
}
189