Passed
Push — main ( 171f61...5bf549 )
by Thierry
06:20
created

OutflowService::getSessionOutflowCount()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
c 1
b 0
f 0
nc 1
nop 1
dl 0
loc 3
rs 10
1
<?php
2
3
namespace Siak\Tontine\Service\Meeting\Cash;
4
5
use Illuminate\Support\Collection;
6
use Siak\Tontine\Exception\MessageException;
7
use Siak\Tontine\Model\Category;
8
use Siak\Tontine\Model\Charge;
9
use Siak\Tontine\Model\Outflow;
10
use Siak\Tontine\Model\Member;
11
use Siak\Tontine\Model\Session;
12
use Siak\Tontine\Service\BalanceCalculator;
13
use Siak\Tontine\Service\LocaleService;
14
use Siak\Tontine\Service\TenantService;
15
16
use function trans;
17
use function trim;
18
19
class OutflowService
20
{
21
    /**
22
     * @param LocaleService $localeService
23
     * @param TenantService $tenantService
24
     * @param BalanceCalculator $balanceCalculator
25
     */
26
    public function __construct(protected LocaleService $localeService,
27
        protected TenantService $tenantService, protected BalanceCalculator $balanceCalculator)
28
    {}
29
30
    /**
31
     * Get a list of members for the dropdown select component.
32
     *
33
     * @return Collection
34
     */
35
    public function getMembers(): Collection
36
    {
37
        return $this->tenantService->guild()->members()->active()
38
            ->orderBy('name', 'asc')->pluck('name', 'id')->prepend('', 0);
39
    }
40
41
    /**
42
     * Find a member.
43
     *
44
     * @param int $memberId
45
     *
46
     * @return Member|null
47
     */
48
    public function getMember(int $memberId): ?Member
49
    {
50
        return $this->tenantService->guild()->members()->active()->find($memberId);
51
    }
52
53
    /**
54
     * Get a list of charges for the dropdown select component.
55
     *
56
     * @return Collection
57
     */
58
    public function getCharges(): Collection
59
    {
60
        return $this->tenantService->guild()->charges()->fee()->active()
61
            ->orderBy('name', 'asc')->pluck('name', 'id')->prepend('', 0);
62
    }
63
64
    /**
65
     * Find a charge.
66
     *
67
     * @param int $chargeId
68
     *
69
     * @return Charge|null
70
     */
71
    public function getCharge(int $chargeId): ?Charge
72
    {
73
        return $this->tenantService->guild()->charges()->fee()->find($chargeId);
74
    }
75
76
    /**
77
     * Get the outflow categories for the dropdown select component.
78
     *
79
     * @return Collection
80
     */
81
    public function getAccounts(): Collection
82
    {
83
        // It is important to call get() before pluck() so the name field is translated.
84
        $globalCategories = Category::outflow()->get();
85
        // We need to move the "other" category to the end of the list.
86
        // getAttributes()['name'] returns the name field, without calling the getter.
87
        [$otherCategory, $globalCategories] = $globalCategories->partition(fn($category) =>
88
            $category->getAttributes()['name'] === 'other');
89
90
        $guildCategories = $this->tenantService->guild()->categories()->outflow()
91
            ->active()->get();
92
        return $globalCategories->concat($guildCategories)->concat($otherCategory)
93
            ->pluck('name', 'id');
94
    }
95
96
    /**
97
     * Find a cash outflow category.
98
     *
99
     * @param int $categoryId
100
     *
101
     * @return Category|null
102
     */
103
    public function getAccount(int $categoryId): ?Category
104
    {
105
        return Category::outflow()->find($categoryId);
106
    }
107
108
    /**
109
     * Get the amount available for outflow.
110
     *
111
     * @param Session $session    The session
112
     *
113
     * @return int
114
     */
115
    public function getAmountAvailable(Session $session): int
116
    {
117
        return $this->balanceCalculator->getTotalBalance($session);
118
    }
119
120
    /**
121
     * Get the amount available for outflow.
122
     *
123
     * @param Session $session    The session
124
     *
125
     * @return float
126
     */
127
    public function getAmountAvailableValue(Session $session): float
128
    {
129
        return $this->localeService->getMoneyValue($this->getAmountAvailable($session));
130
    }
131
132
    /**
133
     * Get the amount available for outflow.
134
     *
135
     * @param Session $session    The session
136
     *
137
     * @return string
138
     */
139
    public function getFormattedAmountAvailable(Session $session): string
140
    {
141
        return $this->localeService->formatMoney($this->getAmountAvailable($session));
142
    }
143
144
    /**
145
     * Get the outflows.
146
     *
147
     * @param int $page
148
     *
149
     * @return Collection
150
     */
151
    public function getOutflows(int $page = 0): Collection
152
    {
153
        return Outflow::with(['member', 'charge', 'category', 'session'])
154
            ->page($page, $this->tenantService->getLimit())->get();
155
    }
156
157
    /**
158
     * Count the outflows for a given session.
159
     *
160
     * @param Session $session
161
     *
162
     * @return int
163
     */
164
    public function getSessionOutflowCount(Session $session): int
165
    {
166
        return $session->outflows()->count();
167
    }
168
169
    /**
170
     * Get the outflows for a given session.
171
     *
172
     * @param Session $session
173
     * @param int $page
174
     *
175
     * @return Collection
176
     */
177
    public function getSessionOutflows(Session $session, int $page = 0): Collection
178
    {
179
        return $session->outflows()
180
            ->with(['member', 'charge', 'category'])
181
            ->page($page, $this->tenantService->getLimit())
182
            ->get();
183
    }
184
185
    /**
186
     * Get a cash outflow for a given session.
187
     *
188
     * @param Session $session
189
     * @param int $outflowId
190
     *
191
     * @return Outflow|null
192
     */
193
    public function getSessionOutflow(Session $session, int $outflowId): ?Outflow
194
    {
195
        return $session->outflows()->find($outflowId);
196
    }
197
198
    /**
199
     * Create a cash outflow.
200
     *
201
     * @param Session $session The session
202
     * @param array $values
203
     *
204
     * @return void
205
     */
206
    public function createOutflow(Session $session, array $values): void
207
    {
208
        $member = $this->getMember($values['member']);
209
        $charge = $this->getCharge($values['charge']);
210
        $category = $this->getAccount($values['category']);
211
        if(!$category)
0 ignored issues
show
introduced by
$category is of type Siak\Tontine\Model\Category, thus it always evaluated to true.
Loading history...
212
        {
213
            throw new MessageException(trans('meeting.category.errors.not_found'));
214
        }
215
216
        $outflow = new Outflow();
217
        $outflow->amount = $values['amount'];
218
        $outflow->comment = trim($values['comment']);
219
        if(($member))
220
        {
221
            $outflow->member()->associate($member);
222
        }
223
        if(($charge))
224
        {
225
            $outflow->charge_lendable = $charge->lendable;
226
            $outflow->charge()->associate($charge);
227
        }
228
        else
229
        {
230
            $outflow->charge_lendable = true;
231
        }
232
        $outflow->category()->associate($category);
233
        $outflow->session()->associate($session);
234
        $outflow->save();
235
    }
236
237
    /**
238
     * Update a cash outflow.
239
     *
240
     * @param Session $session The session
241
     * @param int $outflowId
242
     * @param array $values
243
     *
244
     * @return void
245
     */
246
    public function updateOutflow(Session $session, int $outflowId, array $values): void
247
    {
248
        $member = $this->getMember($values['member']);
249
        $charge = $this->getCharge($values['charge']);
250
        $category = $this->getAccount($values['category']);
251
        if(!$category)
0 ignored issues
show
introduced by
$category is of type Siak\Tontine\Model\Category, thus it always evaluated to true.
Loading history...
252
        {
253
            throw new MessageException(trans('meeting.category.errors.not_found'));
254
        }
255
        $outflow = $session->outflows()->find($outflowId);
256
        if(!$outflow)
257
        {
258
            throw new MessageException(trans('meeting.outflow.errors.not_found'));
259
        }
260
261
        $outflow->amount = $values['amount'];
262
        $outflow->comment = trim($values['comment']);
263
        if(($member))
264
        {
265
            $outflow->member()->associate($member);
266
        }
267
        else
268
        {
269
            $outflow->member()->dissociate();
270
        }
271
        if(($charge))
272
        {
273
            $outflow->charge_lendable = $charge->lendable;
274
            $outflow->charge()->associate($charge);
275
        }
276
        else
277
        {
278
            $outflow->charge_lendable = true;
279
            $outflow->charge()->dissociate();
280
        }
281
        $outflow->category()->associate($category);
282
        $outflow->save();
283
    }
284
285
    /**
286
     * Delete a cash outflow.
287
     *
288
     * @param Session $session The session
289
     * @param int $outflowId
290
     *
291
     * @return void
292
     */
293
    public function deleteOutflow(Session $session, int $outflowId): void
294
    {
295
        $session->outflows()->where('id', $outflowId)->delete();
296
    }
297
}
298