Passed
Push — main ( 9da855...5626b3 )
by Thierry
12:12 queued 05:12
created

LateDepositService::getPoolDepositNumbers()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 10
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 8
c 1
b 0
f 0
nc 1
nop 2
dl 0
loc 10
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 LateDepositService
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...Pool\LateDepositService: $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 bool|null $filter
32
     *
33
     * @return Builder|Relation
34
     */
35
    private function getReceivableQuery(Pool $pool, Session $session,
36
        ?bool $filter = null): Builder|Relation
37
    {
38
        $filterQuery = match($filter) {
39
            true => fn(Builder $query) => $query->paid(),
40
            false => fn(Builder $query) => $query->unpaid(),
41
            default => null,
42
        };
43
44
        return $session->round->receivables()
45
            ->join('subscriptions', 'subscriptions.id', '=', 'receivables.subscription_id')
46
            ->where('subscriptions.pool_id', $pool->id)
47
            ->late($session)
48
            ->when($filterQuery !== null, $filterQuery);
49
    }
50
51
    /**
52
     * @param Pool $pool The pool
53
     * @param Session $session The session
54
     * @param bool|null $filter
55
     *
56
     * @return int
57
     */
58
    public function getReceivableCount(Pool $pool, Session $session,
59
        ?bool $filter = null): int
60
    {
61
        return $this->getReceivableQuery($pool, $session, $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...
62
    }
63
64
    /**
65
     * @param Pool $pool The pool
66
     * @param Session $session The session
67
     * @param bool|null $filter
68
     * @param int $page
69
     *
70
     * @return Collection
71
     */
72
    public function getReceivables(Pool $pool, Session $session,
73
        ?bool $filter = null, int $page = 0): Collection
74
    {
75
        $query = $this->getReceivableQuery($pool, $session, $filter);
76
        return $this->getReceivableDetailsQuery($query, $page)->get();
77
    }
78
79
    /**
80
     * Find the unique receivable for a pool and a session.
81
     *
82
     * @param Pool $pool The pool
83
     * @param Session $session The session
84
     * @param int $receivableId
85
     *
86
     * @return Receivable|null
87
     */
88
    public function getReceivable(Pool $pool, Session $session, int $receivableId): ?Receivable
89
    {
90
        return $this->getReceivableQuery($pool, $session)
91
            ->with(['deposit'])
92
            ->find($receivableId);
93
    }
94
95
    /**
96
     * Create a deposit.
97
     *
98
     * @param Pool $pool The pool
99
     * @param Session $session The session
100
     * @param int $receivableId
101
     * @param int $amount
102
     *
103
     * @return void
104
     */
105
    public function createDeposit(Pool $pool, Session $session,
106
        int $receivableId, int $amount = 0): void
107
    {
108
        $receivable = $this->getReceivable($pool, $session, $receivableId);
109
        $this->checkDepositCreation($pool, $receivable, $amount);
110
111
        $this->saveDeposit($receivable, $session, $amount);
112
    }
113
114
    /**
115
     * Delete a deposit.
116
     *
117
     * @param Pool $pool The pool
118
     * @param Session $session The session
119
     * @param int $receivableId
120
     *
121
     * @return void
122
     */
123
    public function deleteDeposit(Pool $pool, Session $session, int $receivableId): void
124
    {
125
        $receivable = $this->getReceivable($pool, $session, $receivableId);
126
        $this->_deleteDeposit($receivable);
127
    }
128
129
    /**
130
     * @param Pool $pool The pool
131
     * @param Session $session The session
132
     *
133
     * @return array
134
     */
135
    public function getPoolDepositNumbers(Pool $pool, Session $session): array
136
    {
137
        $deposit = Deposit::where('pool_id', $pool->id)
138
            ->where('session_id', $session->id)
139
            ->whereHas('receivable', fn(Builder $qr) => $qr
140
                ->late($session))
141
            ->select(DB::raw('count(*) as count'),
142
                DB::raw('sum(amount) as amount'))
143
            ->first();
144
        return [$deposit?->amount ?? 0, $deposit?->count ?? 0];
145
    }
146
}
147