Passed
Pull Request — main (#67)
by Thierry
06:31
created

EarlyDepositService::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 0

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 0
c 1
b 0
f 0
nc 1
nop 2
dl 0
loc 3
rs 10
1
<?php
2
3
namespace Siak\Tontine\Service\Meeting\Pool;
4
5
use Illuminate\Database\Eloquent\Builder;
6
use Illuminate\Database\Eloquent\Relations\Relation;
7
use Illuminate\Support\Facades\DB;
8
use Illuminate\Support\Collection;
9
use Siak\Tontine\Model\Deposit;
10
use Siak\Tontine\Model\Pool;
11
use Siak\Tontine\Model\Receivable;
12
use Siak\Tontine\Model\Session;
13
use Siak\Tontine\Service\Payment\PaymentServiceInterface;
14
use Siak\Tontine\Service\TenantService;
15
16
class EarlyDepositService
17
{
18
    use DepositServiceTrait;
0 ignored issues
show
introduced by
The trait Siak\Tontine\Service\Mee...ool\DepositServiceTrait requires some properties which are not provided by Siak\Tontine\Service\Mee...ool\EarlyDepositService: $deposit_fixed, $id, $deposit
Loading history...
19
20
    /**
21
     * @param TenantService $tenantService
22
     * @param PaymentServiceInterface $paymentService
23
     */
24
    public function __construct(protected TenantService $tenantService,
25
        protected PaymentServiceInterface $paymentService)
26
    {}
27
28
    /**
29
     * @param Pool $pool
30
     * @param Session $session
31
     * @param Session|null $nextSession
32
     * @param bool|null $filter
33
     *
34
     * @return Builder|Relation
35
     */
36
    private function getReceivableQuery(Pool $pool, Session $session,
37
        ?Session $nextSession, ?bool $filter = null): Builder|Relation
38
    {
39
        $filterQuery = match($filter) {
40
            true => fn(Builder $query) => $query->paid(),
41
            false => fn(Builder $query) => $query->unpaid(),
42
            default => null,
43
        };
44
45
        return $session->round->receivables()
46
            ->join('subscriptions', 'subscriptions.id', '=', 'receivables.subscription_id')
47
            ->where('subscriptions.pool_id', $pool->id)
48
            ->early($session)
49
            ->when($nextSession !== null,
50
                fn(Builder $query) => $query->whereSession($nextSession))
51
            ->when($filterQuery !== null, $filterQuery);
52
    }
53
54
    /**
55
     * @param Pool $pool The pool
56
     * @param Session $session The session
57
     * @param Session|null $nextSession
58
     * @param bool|null $filter
59
     *
60
     * @return int
61
     */
62
    public function getReceivableCount(Pool $pool, Session $session,
63
        ?Session $nextSession, ?bool $filter = null): int
64
    {
65
        return $this->getReceivableQuery($pool, $session, $nextSession, $filter)->count();
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->getReceiva...sion, $filter)->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...
66
    }
67
68
    /**
69
     * @param Pool $pool The pool
70
     * @param Session $session The session
71
     * @param Session|null $nextSession
72
     * @param bool|null $filter
73
     * @param int $page
74
     *
75
     * @return Collection
76
     */
77
    public function getReceivables(Pool $pool, Session $session,
78
        ?Session $nextSession, ?bool $filter = null, int $page = 0): Collection
79
    {
80
        $query = $this->getReceivableQuery($pool, $session, $nextSession, $filter);
81
        return $this->getReceivableDetailsQuery($query, $page)->get();
82
    }
83
84
    /**
85
     * @param Pool $pool The pool
86
     * @param Session $session The session
87
     * @param Session|null $nextSession
88
     *
89
     * @return array
90
     */
91
    public function getPoolDepositNumbers(Pool $pool, Session $session, ?Session $nextSession): array
92
    {
93
        $deposit = Deposit::where('pool_id', $pool->id)
94
            ->where('session_id', $session->id)
95
            ->whereHas('receivable', fn(Builder $qr) => $qr
96
                ->early($session)
97
                ->when($nextSession !== null,
98
                    fn(Builder $query) => $query->whereSession($nextSession)))
99
            ->select(DB::raw('count(*) as count'),
100
                DB::raw('sum(amount) as amount'))
101
            ->first();
102
        return [$deposit?->amount ?? 0, $deposit?->count ?? 0];
103
    }
104
105
    /**
106
     * Find the unique receivable for a pool and a session.
107
     *
108
     * @param Pool $pool The pool
109
     * @param Session $session The session
110
     * @param Session $nextSession
111
     * @param int $receivableId
112
     *
113
     * @return Receivable|null
114
     */
115
    public function getReceivable(Pool $pool, Session $session,
116
        Session $nextSession, int $receivableId): ?Receivable
117
    {
118
        return $this->getReceivableQuery($pool, $session, $nextSession)
119
            ->with(['deposit'])
120
            ->find($receivableId);
121
    }
122
123
    /**
124
     * Create a deposit.
125
     *
126
     * @param Pool $pool The pool
127
     * @param Session $session The session
128
     * @param Session $nextSession
129
     * @param int $receivableId
130
     * @param int $amount
131
     *
132
     * @return void
133
     */
134
    public function createDeposit(Pool $pool, Session $session,
135
        Session $nextSession, int $receivableId, int $amount = 0): void
136
    {
137
        $receivable = $this->getReceivable($pool, $session, $nextSession, $receivableId);
138
        $this->checkDepositCreation($pool, $receivable, $amount);
139
140
        $this->saveDeposit($receivable, $session, $amount);
141
    }
142
143
    /**
144
     * Delete a deposit.
145
     *
146
     * @param Pool $pool The pool
147
     * @param Session $session The session
148
     * @param Session $nextSession
149
     * @param int $receivableId
150
     *
151
     * @return void
152
     */
153
    public function deleteDeposit(Pool $pool, Session $session,
154
        Session $nextSession, int $receivableId): void
155
    {
156
        $receivable = $this->getReceivable($pool, $session, $nextSession, $receivableId);
157
        $this->_deleteDeposit($receivable);
158
    }
159
}
160