RefundService   A
last analyzed

Complexity

Total Complexity 12

Size/Duplication

Total Lines 133
Duplicated Lines 0 %

Importance

Changes 6
Bugs 0 Features 0
Metric Value
eloc 33
c 6
b 0
f 0
dl 0
loc 133
rs 10
wmc 12

7 Methods

Rating   Name   Duplication   Size   Complexity  
A getDebtsByIds() 0 7 1
A __construct() 0 6 1
A createRefund() 0 17 4
A getDebtCount() 0 3 1
A deleteRefund() 0 9 3
A getRefunds() 0 6 1
A getDebts() 0 9 1
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\Exception\MessageException;
8
use Siak\Tontine\Model\Debt;
9
use Siak\Tontine\Model\Fund;
10
use Siak\Tontine\Model\Refund;
11
use Siak\Tontine\Model\Session;
12
use Siak\Tontine\Service\LocaleService;
13
use Siak\Tontine\Service\Meeting\Saving\FundService;
14
use Siak\Tontine\Service\Payment\PaymentServiceInterface;
15
use Siak\Tontine\Service\TenantService;
16
17
use function trans;
18
19
class RefundService
20
{
21
    use RefundTrait;
0 ignored issues
show
introduced by
The trait Siak\Tontine\Service\Meeting\Credit\RefundTrait requires some properties which are not provided by Siak\Tontine\Service\Meeting\Credit\RefundService: $principal_debt, $is_principal, $session_id, $refund, $opened, $loan, $interest_debt, $id, $partial_refunds, $recurrent_interest, $session, $day_date, $is_interest
Loading history...
22
23
    /**
24
     * @param DebtCalculator $debtCalculator
25
     * @param TenantService $tenantService
26
     * @param LocaleService $localeService
27
     * @param FundService $fundService
28
     * @param PaymentServiceInterface $paymentService;
29
     */
30
    public function __construct(private DebtCalculator $debtCalculator,
31
        TenantService $tenantService, private LocaleService $localeService,
32
        FundService $fundService, private PaymentServiceInterface $paymentService)
33
    {
34
        $this->tenantService = $tenantService;
35
        $this->fundService = $fundService;
36
    }
37
38
    /**
39
     * Get the number of debts.
40
     *
41
     * @param Session $session The session
42
     * @param Fund|null $fund
43
     * @param bool|null $onlyPaid
44
     *
45
     * @return int
46
     */
47
    public function getDebtCount(Session $session, ?Fund $fund, ?bool $onlyPaid): int
48
    {
49
        return $this->getDebtsQuery($session, $fund, $onlyPaid, false)->count();
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->getDebtsQu...lyPaid, false)->count() could return the type Illuminate\Database\Eloq...uent\Relations\Relation which is incompatible with the type-hinted return integer. Consider adding an additional type-check to rule them out.
Loading history...
50
    }
51
52
    /**
53
     * Get the debts.
54
     *
55
     * @param Session $session The session
56
     * @param Fund|null $fund
57
     * @param bool|null $onlyPaid
58
     * @param int $page
59
     *
60
     * @return Collection
61
     */
62
    public function getDebts(Session $session, ?Fund $fund,
63
        ?bool $onlyPaid, int $page = 0): Collection
64
    {
65
        return $this->getDebtsQuery($session, $fund, $onlyPaid, true)
66
            ->orderBy('member_defs.name')
67
            ->orderBy('debts.id')
0 ignored issues
show
Bug introduced by
'debts.id' of type string is incompatible with the type Closure|Illuminate\Datab...\Database\Query\Builder expected by parameter $column of Illuminate\Database\Query\Builder::orderBy(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

67
            ->orderBy(/** @scrutinizer ignore-type */ 'debts.id')
Loading history...
68
            ->page($page, $this->tenantService->getLimit())
69
            ->get()
70
            ->each(fn(Debt $debt) => $this->fillDebt($debt, $session));
71
    }
72
73
    /**
74
     * Get the debts.
75
     *
76
     * @param Session $session The session
77
     * @param array $ids
78
     *
79
     * @return Collection
80
     */
81
    public function getDebtsByIds(Session $session, array $ids): Collection
82
    {
83
        return $this->getDebtsQuery($session, null, false, true)
84
            ->whereIn('id', $ids)
85
            ->get()
86
            ->each(fn(Debt $debt) => $this->fillDebt($debt, $session))
87
            ->keyBy('id');
88
    }
89
90
    /**
91
     * Get the refunds for a given session.
92
     *
93
     * @param Session $session The session
94
     * @param int $page
95
     *
96
     * @return Collection
97
     */
98
    public function getRefunds(Session $session, int $page = 0): Collection
99
    {
100
        return $session->refunds()
101
            ->page($page, $this->tenantService->getLimit())
102
            ->with('debt.loan.member')
103
            ->get();
104
    }
105
106
    /**
107
     * Create a refund.
108
     *
109
     * @param Debt $debt
110
     * @param Session $session The session
111
     *
112
     * @return void
113
     */
114
    public function createRefund(Debt $debt, Session $session): void
115
    {
116
        if(!$this->canCreateRefund($debt, $session))
117
        {
118
            throw new MessageException(trans('meeting.refund.errors.cannot_create'));
119
        }
120
121
        $refund = new Refund();
122
        $refund->debt()->associate($debt);
123
        $refund->session()->associate($session);
124
        DB::transaction(function() use($debt, $session, $refund) {
125
            $refund->save();
126
            // For simple or compound interest, also save the final amount.
127
            if($debt->is_interest && $debt->loan->recurrent_interest)
0 ignored issues
show
Bug introduced by
The property is_interest does not seem to exist on Siak\Tontine\Model\Debt. 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 recurrent_interest does not exist on Siak\Tontine\Model\Loan. Did you mean interest?
Loading history...
128
            {
129
                $debt->amount = $this->debtCalculator->getDebtDueAmount($debt, $session, true);
130
                $debt->save();
131
            }
132
        });
133
    }
134
135
    /**
136
     * Delete a refund.
137
     *
138
     * @param Debt $debt
139
     * @param Session $session The session
140
     *
141
     * @return void
142
     */
143
    public function deleteRefund(Debt $debt, Session $session): void
144
    {
145
        if(!$this->canDeleteRefund($debt, $session) ||
146
            !$this->paymentService->isEditable($debt->refund))
147
        {
148
            throw new MessageException(trans('meeting.refund.errors.cannot_delete'));
149
        }
150
151
        $debt->refund->delete();
152
    }
153
}
154