Issues (202)

src/Model/Loan.php (2 issues)

Labels
Severity
1
<?php
2
3
namespace Siak\Tontine\Model;
4
5
use Illuminate\Database\Eloquent\Builder;
6
use Illuminate\Database\Eloquent\Casts\Attribute;
7
use Illuminate\Database\Eloquent\Collection;
8
9
/**
10
 * @property string $interest_type
11
 * @property float $interest_rate
12
 * @property-read int $principal
13
 * @property-read int $interest
14
 * @property-read bool $fixed_interest
15
 * @property-read bool $simple_interest
16
 * @property-read bool $compound_interest
17
 * @property-read int $refunds_count
18
 * @property-read Session $session
19
 * @property-read Member $member
20
 * @property-read Fund $fund
21
 * @property-read Debt $principal_debt
22
 * @property-read Debt $interest_debt
23
 * @property-read Collection $debts
24
 * @property-read Collection $refunds
25
 */
26
class Loan extends Base
27
{
28
    /**
29
     * @const
30
     */
31
    const INTEREST_FIXED = 'f';
32
33
    /**
34
     * @const
35
     */
36
    const INTEREST_UNIQUE = 'u';
37
38
    /**
39
     * @const
40
     */
41
    const INTEREST_SIMPLE = 's';
42
43
    /**
44
     * @const
45
     */
46
    const INTEREST_COMPOUND = 'c';
47
48
    /**
49
     * Indicates if the model should be timestamped.
50
     *
51
     * @var bool
52
     */
53
    public $timestamps = false;
54
55
    /**
56
     * The attributes that are mass assignable.
57
     *
58
     * @var array
59
     */
60
    protected $fillable = [
61
        'interest_type',
62
        'interest_rate',
63
        'member_id',
64
        'session_id',
65
    ];
66
67
    /**
68
     * @return Attribute
69
     */
70
    protected function principal(): Attribute
71
    {
72
        return Attribute::make(
73
            get: fn() => $this->principal_debt?->amount ?? 0,
74
        );
75
    }
76
77
    /**
78
     * @return Attribute
79
     */
80
    protected function interest(): Attribute
81
    {
82
        return Attribute::make(
83
            get: fn() => $this->interest_debt?->amount ?? 0,
84
        );
85
    }
86
87
    /**
88
     * @return Attribute
89
     */
90
    protected function fixedInterest(): Attribute
91
    {
92
        return Attribute::make(
93
            get: fn() => $this->interest_type === self::INTEREST_FIXED,
94
        );
95
    }
96
97
    /**
98
     * @return Attribute
99
     */
100
    protected function uniqueInterest(): Attribute
101
    {
102
        return Attribute::make(
103
            get: fn() => $this->interest_type === self::INTEREST_UNIQUE,
104
        );
105
    }
106
107
    /**
108
     * @return Attribute
109
     */
110
    protected function simpleInterest(): Attribute
111
    {
112
        return Attribute::make(
113
            get: fn() => $this->interest_type === self::INTEREST_SIMPLE,
114
        );
115
    }
116
117
    /**
118
     * @return Attribute
119
     */
120
    protected function compoundInterest(): Attribute
121
    {
122
        return Attribute::make(
123
            get: fn() => $this->interest_type === self::INTEREST_COMPOUND,
124
        );
125
    }
126
127
    /**
128
     * @return Attribute
129
     */
130
    protected function recurrentInterest(): Attribute
131
    {
132
        // Interests that grows after each session.
133
        return Attribute::make(
134
            get: fn() => $this->interest_type === self::INTEREST_SIMPLE ||
135
                $this->interest_type === self::INTEREST_COMPOUND,
136
        );
137
    }
138
139
    /**
140
     * @param  Builder  $query
141
     *
142
     * @return Builder
143
     */
144
    public function scopeFixedInterest(Builder $query): Builder
145
    {
146
        return $query->where('interest_type', self::INTEREST_FIXED)
147
            ->orWhere('interest_type', self::INTEREST_UNIQUE);
148
    }
149
150
    public function session()
151
    {
152
        return $this->belongsTo(Session::class);
153
    }
154
155
    public function member()
156
    {
157
        return $this->belongsTo(Member::class);
158
    }
159
160
    public function fund()
161
    {
162
        return $this->belongsTo(Fund::class);
163
    }
164
165
    public function debts()
166
    {
167
        return $this->hasMany(Debt::class);
168
    }
169
170
    public function refunds()
171
    {
172
        return $this->hasManyThrough(Refund::class, Debt::class)
173
            ->select('refunds.*');
174
    }
175
176
    public function principal_debt()
177
    {
178
        // Read from the database
179
        return $this->hasOne(Debt::class)->where('type', Debt::TYPE_PRINCIPAL);
180
    }
181
182
    public function interest_debt()
183
    {
184
        // Read from the database
185
        return $this->hasOne(Debt::class)->where('type', Debt::TYPE_INTEREST);
186
    }
187
188
    /**
189
     * @return Attribute
190
     */
191
    protected function pDebt(): Attribute
192
    {
193
        // Read from the "debts" collection
194
        return Attribute::make(
195
            get: fn() => $this->debts->first(fn($debt) => $debt->type === Debt::TYPE_PRINCIPAL),
196
        );
197
    }
198
199
    /**
200
     * @return Attribute
201
     */
202
    protected function iDebt(): Attribute
203
    {
204
        // Read from the "debts" collection
205
        return Attribute::make(
206
            get: fn() => $this->debts->first(fn($debt) => $debt->type === Debt::TYPE_INTEREST),
207
        );
208
    }
209
210
    /**
211
     * @return Attribute
212
     */
213
    protected function allRefunds(): Attribute
214
    {
215
        return Attribute::make(
216
            get: fn() => !$this->i_debt ? $this->p_debt->all_refunds :
0 ignored issues
show
The property i_debt does not seem to exist on Siak\Tontine\Model\Loan. Are you sure there is no database migration missing?

Checks if undeclared accessed properties appear in database migrations and if the creating migration is correct.

Loading history...
The property p_debt does not seem to exist on Siak\Tontine\Model\Loan. Are you sure there is no database migration missing?

Checks if undeclared accessed properties appear in database migrations and if the creating migration is correct.

Loading history...
217
                $this->p_debt->all_refunds->concat($this->i_debt->all_refunds),
218
        );
219
    }
220
}
221