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

RefundService::getDebtsByIds()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 5
c 0
b 0
f 0
nc 1
nop 2
dl 0
loc 7
rs 10
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\FundService;
15
use Siak\Tontine\Service\Meeting\PaymentServiceInterface;
16
use Siak\Tontine\Service\TenantService;
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, $partial_refunds, $recurrent_interest, $session, $day_date, $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|null $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|null $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
            ->orderBy('members.name')
68
            ->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

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