Passed
Pull Request — main (#62)
by Thierry
05:23
created

RefundService::canDeleteRefund()   A

Complexity

Conditions 6
Paths 3

Size

Total Lines 14
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 6
eloc 5
nc 3
nop 2
dl 0
loc 14
rs 9.2222
c 2
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 Illuminate\Support\Facades\Log;
8
use Siak\Tontine\Exception\MessageException;
9
use Siak\Tontine\Model\Debt;
10
use Siak\Tontine\Model\Fund;
11
use Siak\Tontine\Model\Refund;
12
use Siak\Tontine\Model\Session;
13
use Siak\Tontine\Service\LocaleService;
14
use Siak\Tontine\Service\Meeting\PaymentServiceInterface;
15
use Siak\Tontine\Service\TenantService;
16
use Siak\Tontine\Service\Tontine\FundService;
17
18
use function trans;
19
20
class RefundService
21
{
22
    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, $start_at, $partial_refunds, $recurrent_interest, $session, $is_interest
Loading history...
23
24
    /**
25
     * @param DebtCalculator $debtCalculator
26
     * @param TenantService $tenantService
27
     * @param LocaleService $localeService
28
     * @param FundService $fundService
29
     * @param PaymentServiceInterface $paymentService;
30
     */
31
    public function __construct(private DebtCalculator $debtCalculator,
32
        TenantService $tenantService, private LocaleService $localeService,
33
        FundService $fundService, private PaymentServiceInterface $paymentService)
34
    {
35
        $this->tenantService = $tenantService;
36
        $this->fundService = $fundService;
37
    }
38
39
    /**
40
     * Get the number of debts.
41
     *
42
     * @param Session $session The session
43
     * @param Fund $fund
44
     * @param bool|null $onlyPaid
45
     *
46
     * @return int
47
     */
48
    public function getDebtCount(Session $session, Fund $fund, ?bool $onlyPaid): int
49
    {
50
        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...
51
    }
52
53
    /**
54
     * Get the debts.
55
     *
56
     * @param Session $session The session
57
     * @param Fund $fund
58
     * @param bool|null $onlyPaid
59
     * @param int $page
60
     *
61
     * @return Collection
62
     */
63
    public function getDebts(Session $session, Fund $fund,
64
        ?bool $onlyPaid, int $page = 0): Collection
65
    {
66
        return $this->getDebtsQuery($session, $fund, $onlyPaid, true)
67
            ->page($page, $this->tenantService->getLimit())
68
            ->get()
69
            ->each(fn(Debt $debt) => $this->fillDebt($debt, $session))
70
            ->sortBy('loan.member.name', SORT_LOCALE_STRING)
71
            ->values();
72
    }
73
74
    /**
75
     * Get the refunds for a given session.
76
     *
77
     * @param Session $session The session
78
     * @param int $page
79
     *
80
     * @return Collection
81
     */
82
    public function getRefunds(Session $session, int $page = 0): Collection
83
    {
84
        return $session->refunds()
85
            ->page($page, $this->tenantService->getLimit())
86
            ->with('debt.loan.member')
87
            ->get();
88
    }
89
90
    /**
91
     * Create a refund.
92
     *
93
     * @param Debt $debt
94
     * @param Session $session The session
95
     *
96
     * @return void
97
     */
98
    public function createRefund(Debt $debt, Session $session): void
99
    {
100
        if(!$this->canCreateRefund($debt, $session))
101
        {
102
            throw new MessageException(trans('meeting.refund.errors.cannot_refund'));
103
        }
104
105
        $refund = new Refund();
106
        $refund->debt()->associate($debt);
107
        $refund->session()->associate($session);
108
        DB::transaction(function() use($debt, $session, $refund) {
109
            $refund->save();
110
            // For simple or compound interest, also save the final amount.
111
            if($debt->is_interest && $debt->loan->recurrent_interest)
0 ignored issues
show
Bug introduced by
The property recurrent_interest does not exist on Siak\Tontine\Model\Loan. Did you mean interest?
Loading history...
112
            {
113
                $debt->amount = $this->debtCalculator->getDebtDueAmount($debt, $session, true);
114
                $debt->save();
115
            }
116
        });
117
    }
118
119
    /**
120
     * Delete a refund.
121
     *
122
     * @param Debt $debt
123
     * @param Session $session The session
124
     *
125
     * @return void
126
     */
127
    public function deleteRefund(Debt $debt, Session $session): void
128
    {
129
        if(!$this->canDeleteRefund($debt, $session))
130
        {
131
            throw new MessageException(trans('meeting.refund.errors.cannot_refund'));
132
        }
133
        if(!$this->paymentService->isEditable($debt->refund))
134
        {
135
            throw new MessageException(trans('meeting.refund.errors.cannot_delete'));
136
        }
137
        $debt->refund->delete();
138
    }
139
}
140