Passed
Push — main ( 9b7af3...eeb558 )
by Thierry
05:55
created

SettlementTargetService::filterTarget()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 2
nc 2
nop 2
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Siak\Tontine\Service\Meeting\Charge;
4
5
use Illuminate\Database\Eloquent\Builder;
6
use Illuminate\Database\Eloquent\Relations\Relation;
7
use Illuminate\Support\Collection;
8
use Illuminate\Support\Facades\DB;
9
use Illuminate\Support\Facades\Log;
10
use Siak\Tontine\Model\Charge;
11
use Siak\Tontine\Model\Session;
12
use Siak\Tontine\Model\SettlementTarget;
13
use Siak\Tontine\Service\TenantService;
14
use Siak\Tontine\Validation\SearchSanitizer;
15
16
class SettlementTargetService
17
{
18
    /**
19
     * @param TenantService $tenantService
20
     */
21
    public function __construct(protected TenantService $tenantService,
22
        private SearchSanitizer $searchSanitizer)
23
    {}
24
25
    /**
26
     * Get the sessions after the current.
27
     *
28
     * @param Session $currentSession
29
     *
30
     * @return Collection
31
     */
32
    public function getDeadlineSessions(Session $currentSession): Collection
33
    {
34
        return $this->tenantService->guild()->sessions()
35
            ->where('day_date', '>', $currentSession->day_date)
36
            ->pluck('title', 'id');
37
    }
38
39
    /**
40
     * @param Session $session
41
     * @param SettlementTarget $target
42
     *
43
     * @return bool
44
     */
45
    private function filterTarget(Session $session, SettlementTarget $target): bool
46
    {
47
        return $session->day_date >= $target->session->day_date &&
48
            $session->day_date <= $target->deadline->day_date;
49
    }
50
51
    /**
52
     * @param Charge $charge
53
     * @param Session $session
54
     *
55
     * @return SettlementTarget|null
56
     */
57
    public function getTarget(Charge $charge, Session $session): ?SettlementTarget
58
    {
59
        return $charge->targets()
60
            ->with(['session', 'deadline'])
61
            ->get()
62
            ->filter(fn($target) => $this->filterTarget($session, $target))
63
            ->first();
64
    }
65
66
    /**
67
     * @param string $search
68
     *
69
     * @return Builder|Relation
70
     */
71
    private function getMembersQuery(string $search = ''): Builder|Relation
72
    {
73
        return $this->tenantService->guild()
74
            ->members()
75
            ->active()
76
            ->search($this->searchSanitizer->sanitize($search));
77
    }
78
79
    /**
80
     * @param Charge $charge
81
     * @param SettlementTarget $target
82
     * @param Collection $members
83
     *
84
     * @return Collection
85
     */
86
    public function getMembersSettlements(Charge $charge, SettlementTarget $target,
87
        Collection $members): Collection
88
    {
89
        $sessions = $this->tenantService->round()->sessions
90
            ->filter(fn($session) => $this->filterTarget($session, $target));
91
        return DB::table('settlements')
92
            ->join('bills', 'settlements.bill_id', '=', 'bills.id')
93
            ->join('libre_bills', 'libre_bills.bill_id', '=', 'bills.id')
94
            ->whereIn('libre_bills.member_id', $members->pluck('id'))
95
            ->where('libre_bills.charge_id', $charge->id)
96
            ->whereIn('settlements.session_id', $sessions->pluck('id'))
97
            ->select('libre_bills.member_id', DB::raw('sum(bills.amount) as amount'))
98
            ->groupBy('libre_bills.member_id')
99
            ->get()
100
            ->pluck('amount', 'member_id');
101
    }
102
103
    /**
104
     * @param Charge $charge
105
     * @param SettlementTarget $target
106
     * @param string $search
107
     * @param int $page
108
     *
109
     * @return Collection
110
     */
111
    public function getMembersWithSettlements(Charge $charge, SettlementTarget $target,
112
        string $search = '', int $page = 0): Collection
113
    {
114
        $sessions = $this->tenantService->round()->sessions
115
            ->filter(fn($session) => $this->filterTarget($session, $target));
116
        return $this->getMembersQuery($search)
117
            ->select('members.id', 'members.name')
118
            ->addSelect([
119
                'paid' => DB::table('settlements')
120
                    ->join('bills', 'settlements.bill_id', '=', 'bills.id')
121
                    ->join('libre_bills', 'libre_bills.bill_id', '=', 'bills.id')
122
                    ->whereColumn('libre_bills.member_id', 'members.id')
123
                    ->where('libre_bills.charge_id', $charge->id)
124
                    ->whereIn('settlements.session_id', $sessions->pluck('id'))
125
                    ->select(DB::raw('sum(bills.amount)'))
126
            ])
127
            ->page($page, $this->tenantService->getLimit())
128
            ->orderBy('members.name', 'asc')
0 ignored issues
show
Bug introduced by
'members.name' 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

128
            ->orderBy(/** @scrutinizer ignore-type */ 'members.name', 'asc')
Loading history...
129
            ->get();
130
    }
131
132
    /**
133
     * @param Charge $charge
134
     * @param Session $session
135
     * @param string $search
136
     * @param bool $filter|null
137
     *
138
     * @return int
139
     */
140
    public function getMemberCount(string $search = ''): int
141
    {
142
        return $this->getMembersQuery($search)->count();
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->getMembersQuery($search)->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...
143
    }
144
145
    /**
146
     * @param Charge $charge
147
     * @param Session $session
148
     * @param Session $deadline
149
     * @param float $amount
150
     * @param bool $global
151
     *
152
     * @return void
153
     */
154
    public function createTarget(Charge $charge, Session $session,
155
        Session $deadline, float $amount, bool $global): void
156
    {
157
        $target = new SettlementTarget();
158
        $target->amount = $amount;
159
        $target->global = $global;
160
        $target->charge()->associate($charge);
161
        $target->session()->associate($session);
162
        $target->deadline()->associate($deadline);
163
        $target->save();
164
    }
165
166
    /**
167
     * @param SettlementTarget $target
168
     * @param Session $session
169
     * @param Session $deadline
170
     * @param float $amount
171
     * @param bool $global
172
     *
173
     * @return void
174
     */
175
    public function updateTarget(SettlementTarget $target, Session $session,
176
        Session $deadline, float $amount, bool $global): void
177
    {
178
        $target->amount = $amount;
179
        $target->global = $global;
180
        $target->session()->associate($session);
181
        $target->deadline()->associate($deadline);
182
        $target->save();
183
    }
184
185
    /**
186
     * @param SettlementTarget $target
187
     *
188
     * @return void
189
     */
190
    public function deleteTarget(SettlementTarget $target): void
191
    {
192
        $target->delete();
193
    }
194
}
195