Loan::scopeFixedInterest()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
c 0
b 0
f 0
nc 1
nop 1
dl 0
loc 4
rs 10
1
<?php
2
3
namespace Siak\Tontine\Model;
4
5
use Carbon\Carbon;
6
use Illuminate\Database\Eloquent\Builder;
7
use Illuminate\Database\Eloquent\Casts\Attribute;
8
use Illuminate\Database\Eloquent\Collection;
9
10
use function trans;
11
12
/**
13
 * @property string $interest_type
14
 * @property float $interest_rate
15
 * @property-read int $principal
16
 * @property-read int $interest
17
 * @property-read bool $fixed_interest
18
 * @property-read bool $simple_interest
19
 * @property-read bool $compound_interest
20
 * @property-read int $refunds_count
21
 * @property-read Session $session
22
 * @property-read Member $member
23
 * @property-read Fund $fund
24
 * @property-read Debt $principal_debt
25
 * @property-read Debt $interest_debt
26
 * @property-read Collection $debts
27
 * @property-read Collection $refunds
28
 */
29
class Loan extends Base
30
{
31
    use Traits\DateFormatter;
32
33
    /**
34
     * @const
35
     */
36
    const INTEREST_FIXED = 'f';
37
38
    /**
39
     * @const
40
     */
41
    const INTEREST_UNIQUE = 'u';
42
43
    /**
44
     * @const
45
     */
46
    const INTEREST_SIMPLE = 's';
47
48
    /**
49
     * @const
50
     */
51
    const INTEREST_COMPOUND = 'c';
52
53
    /**
54
     * Indicates if the model should be timestamped.
55
     *
56
     * @var bool
57
     */
58
    public $timestamps = false;
59
60
    /**
61
     * The attributes that are mass assignable.
62
     *
63
     * @var array
64
     */
65
    protected $fillable = [
66
        'interest_type',
67
        'interest_rate',
68
        'member_id',
69
        'session_id',
70
    ];
71
72
    /**
73
     * Get the attributes that should be cast.
74
     *
75
     * @return array<string, string>
76
     */
77
    protected function casts(): array
78
    {
79
        return [
80
            'deadline_date' => 'datetime:Y-m-d',
81
        ];
82
    }
83
84
    /**
85
     * @return Attribute
86
     */
87
    protected function principal(): Attribute
88
    {
89
        return Attribute::make(
90
            get: fn() => $this->principal_debt?->amount ?? 0,
91
        );
92
    }
93
94
    /**
95
     * @return Attribute
96
     */
97
    protected function interest(): Attribute
98
    {
99
        return Attribute::make(
100
            get: fn() => $this->interest_debt?->amount ?? 0,
101
        );
102
    }
103
104
    /**
105
     * @return Attribute
106
     */
107
    protected function fixedInterest(): Attribute
108
    {
109
        return Attribute::make(
110
            get: fn() => $this->interest_type === self::INTEREST_FIXED,
111
        );
112
    }
113
114
    /**
115
     * @return Attribute
116
     */
117
    protected function uniqueInterest(): Attribute
118
    {
119
        return Attribute::make(
120
            get: fn() => $this->interest_type === self::INTEREST_UNIQUE,
121
        );
122
    }
123
124
    /**
125
     * @return Attribute
126
     */
127
    protected function simpleInterest(): Attribute
128
    {
129
        return Attribute::make(
130
            get: fn() => $this->interest_type === self::INTEREST_SIMPLE,
131
        );
132
    }
133
134
    /**
135
     * @return Attribute
136
     */
137
    protected function compoundInterest(): Attribute
138
    {
139
        return Attribute::make(
140
            get: fn() => $this->interest_type === self::INTEREST_COMPOUND,
141
        );
142
    }
143
144
    /**
145
     * @return Attribute
146
     */
147
    protected function recurrentInterest(): Attribute
148
    {
149
        // Interests that grows after each session.
150
        return Attribute::make(
151
            get: fn() => $this->interest_type === self::INTEREST_SIMPLE ||
152
                $this->interest_type === self::INTEREST_COMPOUND,
153
        );
154
    }
155
156
    /**
157
     * @param  Builder  $query
158
     *
159
     * @return Builder
160
     */
161
    public function scopeFixedInterest(Builder $query): Builder
162
    {
163
        return $query->where('interest_type', self::INTEREST_FIXED)
164
            ->orWhere('interest_type', self::INTEREST_UNIQUE);
165
    }
166
167
    public function session()
168
    {
169
        return $this->belongsTo(Session::class);
170
    }
171
172
    public function member()
173
    {
174
        return $this->belongsTo(Member::class);
175
    }
176
177
    public function fund()
178
    {
179
        return $this->belongsTo(Fund::class);
180
    }
181
182
    public function debts()
183
    {
184
        return $this->hasMany(Debt::class);
185
    }
186
187
    public function refunds()
188
    {
189
        return $this->hasManyThrough(Refund::class, Debt::class)
190
            ->select('refunds.*');
191
    }
192
193
    public function principal_debt()
194
    {
195
        // Read from the database
196
        return $this->hasOne(Debt::class)->where('type', Debt::TYPE_PRINCIPAL);
197
    }
198
199
    public function interest_debt()
200
    {
201
        // Read from the database
202
        return $this->hasOne(Debt::class)->where('type', Debt::TYPE_INTEREST);
203
    }
204
205
    public function deadline_session()
206
    {
207
        return $this->belongsTo(Session::class, 'deadline_session_id');
208
    }
209
210
    /**
211
     * @return Attribute
212
     */
213
    protected function pDebt(): Attribute
214
    {
215
        // Read from the "debts" collection
216
        return Attribute::make(
217
            get: fn() => $this->debts->first(fn($debt) => $debt->type === Debt::TYPE_PRINCIPAL),
218
        );
219
    }
220
221
    /**
222
     * @return Attribute
223
     */
224
    protected function iDebt(): Attribute
225
    {
226
        // Read from the "debts" collection
227
        return Attribute::make(
228
            get: fn() => $this->debts->first(fn($debt) => $debt->type === Debt::TYPE_INTEREST),
229
        );
230
    }
231
232
    /**
233
     * @return Attribute
234
     */
235
    protected function allRefunds(): Attribute
236
    {
237
        return Attribute::make(
238
            get: fn() => !$this->i_debt ? $this->p_debt->all_refunds :
0 ignored issues
show
Bug introduced by
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...
Bug introduced by
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...
239
                $this->p_debt->all_refunds->concat($this->i_debt->all_refunds),
240
        );
241
    }
242
243
    /**
244
     * @return Attribute
245
     */
246
    protected function deadline(): Attribute
247
    {
248
        return Attribute::make(
249
            get: fn() => $this->deadline_session !== null ?
250
                trans('meeting.loan.deadline.session', [
251
                    'date' => $this->deadline_session->date('day_date', 'format_medium'),
252
                ]) :
253
                ($this->deadline_date !== null ?
254
                    trans('meeting.loan.deadline.date', [
255
                        'date' => $this->date('deadline_date', 'format_medium'),
256
                    ]) : '')
257
        );
258
    }
259
260
    /**
261
     * @return Attribute
262
     */
263
    protected function noDeadline(): Attribute
264
    {
265
        return Attribute::make(
266
            get: fn() => !$this->deadline_session && !$this->deadline_date,
267
        );
268
    }
269
270
271
    /**
272
     * @return Attribute
273
     */
274
    protected function deadlineExceeded(): Attribute
275
    {
276
        return Attribute::make(
277
            get: function() {
278
                if($this->no_deadline)
0 ignored issues
show
Bug introduced by
The property no_deadline 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...
279
                {
280
                    return false;
281
                }
282
283
                $date = $this->deadline_session !== null ?
284
                    $this->deadline_session->day_date : $this->deadline_date;
285
                return $date < Carbon::today();
286
            }
287
        );
288
    }
289
}
290