Passed
Push — main ( 34d123...876c9b )
by Thierry
05:11
created

LoanService::getFormattedAmountAvailable()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 1
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Siak\Tontine\Service\Meeting\Credit;
4
5
use Illuminate\Support\Collection;
6
use Illuminate\Support\Facades\DB;
7
use Siak\Tontine\Model\Debt;
8
use Siak\Tontine\Model\Fund;
9
use Siak\Tontine\Model\Loan;
10
use Siak\Tontine\Model\Member;
11
use Siak\Tontine\Model\Session;
12
use Siak\Tontine\Service\BalanceCalculator;
13
use Siak\Tontine\Service\Guild\FundService;
14
use Siak\Tontine\Service\Guild\MemberService;
15
use Siak\Tontine\Service\LocaleService;
16
use Siak\Tontine\Service\TenantService;
17
18
use function trans;
19
20
class LoanService
21
{
22
    /**
23
     * @param BalanceCalculator $balanceCalculator
24
     * @param LocaleService $localeService
25
     * @param TenantService $tenantService
26
     * @param FundService $fundService
27
     * @param MemberService $memberService
28
     */
29
    public function __construct(private BalanceCalculator $balanceCalculator,
30
        private LocaleService $localeService, private TenantService $tenantService,
31
        private FundService $fundService, private  MemberService $memberService)
32
    {}
33
34
    /**
35
     * @return array
36
     */
37
    public function getInterestTypes(): array
38
    {
39
        return [
40
            Loan::INTEREST_FIXED => trans('meeting.loan.interest.if'),
41
            Loan::INTEREST_UNIQUE => trans('meeting.loan.interest.iu'),
42
            Loan::INTEREST_SIMPLE => trans('meeting.loan.interest.is'),
43
            Loan::INTEREST_COMPOUND => trans('meeting.loan.interest.ic'),
44
        ];
45
    }
46
47
    /**
48
     * Get the amount available for loan.
49
     *
50
     * @param Session $session    The session
51
     *
52
     * @return int
53
     */
54
    public function getAmountAvailable(Session $session): int
55
    {
56
        return $this->balanceCalculator->getBalanceForLoan($session);
57
    }
58
59
    /**
60
     * Gett the number of loans for a given session.
61
     *
62
     * @param Session $session
63
     *
64
     * @return int
65
     */
66
    public function getSessionLoanCount(Session $session): int
67
    {
68
        return $session->loans()->count();
69
    }
70
71
    /**
72
     * Get the loans for a given session.
73
     *
74
     * @param Session $session
75
     * @param int $page
76
     *
77
     * @return Collection
78
     */
79
    public function getSessionLoans(Session $session, int $page = 0): Collection
80
    {
81
        return $session->loans()
82
            ->with(['member', 'fund'])
83
            ->page($page, $this->tenantService->getLimit())
84
            ->get();
85
    }
86
87
    /**
88
     * Get a loan for a given session.
89
     *
90
     * @param Session $session
91
     * @param int $loanId
92
     *
93
     * @return Loan|null
94
     */
95
    public function getSessionLoan(Session $session, int $loanId): ?Loan
96
    {
97
        return $session->loans()->with(['member', 'fund'])->withCount('refunds')->find($loanId);
98
    }
99
100
    /**
101
     * Create a loan.
102
     *
103
     * @param Session $session The session
104
     * @param Member $member
105
     * @param Fund $fund
106
     * @param array $values
107
     *
108
     * @return void
109
     */
110
    public function createLoan(Session $session, Member $member, Fund $fund, array $values): void
111
    {
112
        $loan = new Loan();
113
        $loan->interest_type = $values['interest_type'];
114
        $loan->interest_rate = $values['interest_rate'];
115
        $loan->session()->associate($session);
116
        $loan->member()->associate($member);
117
        $loan->fund()->associate($fund);
118
        DB::transaction(function() use($loan, $values) {
119
            $loan->save();
120
121
            $principal = $values['principal'];
122
            $interest = $values['interest'];
123
            // Create an entry for each type of debt
124
            if($principal > 0)
125
            {
126
                $loan->debts()->create(['type' => Debt::TYPE_PRINCIPAL, 'amount' => $principal]);
127
            }
128
            if($interest > 0)
129
            {
130
                $loan->debts()->create(['type' => Debt::TYPE_INTEREST, 'amount' => $interest]);
131
            }
132
        });
133
    }
134
135
    /**
136
     * Update a loan.
137
     *
138
     * @param Member $member
139
     * @param Fund $fund
140
     * @param Loan $loan
141
     * @param array $values
142
     *
143
     * @return void
144
     */
145
    public function updateLoan(Member $member, Fund $fund, Loan $loan, array $values): void
146
    {
147
        $loan->interest_type = $values['interest_type'];
148
        $loan->interest_rate = $values['interest_rate'];
149
        $loan->member()->associate($member);
150
        $loan->fund()->associate($fund);
151
        DB::transaction(function() use($loan, $values) {
152
            $loan->save();
153
154
            $principal = $values['principal'];
155
            $interest = $values['interest'];
156
            $loan->debts()->principal()->update(['amount' => $principal]);
157
            // The interest debt may need to be created or deleted.
158
            if($interest <= 0)
159
            {
160
                $loan->debts()->where('type', Debt::TYPE_INTEREST)->delete();
161
                return;
162
            }
163
            $loan->debts()->updateOrCreate(['type' => Debt::TYPE_INTEREST], ['amount' => $interest]);
164
        });
165
    }
166
167
    /**
168
     * Delete a loan.
169
     *
170
     * @param Session $session The session
171
     * @param int $loanId
172
     *
173
     * @return void
174
     */
175
    public function deleteLoan(Session $session, int $loanId): void
176
    {
177
        /** @var Loan|null */
178
        $loan = $session->loans()->find($loanId);
179
        if($loan !== null)
180
        {
181
            DB::transaction(function() use($loan) {
182
                $loan->refunds()->delete();
183
                $loan->debts()->delete();
184
                $loan->delete();
185
            });
186
        }
187
    }
188
}
189