Passed
Pull Request — main (#51)
by Thierry
13:39
created

SettlementTargetService   A

Complexity

Total Complexity 13

Size/Duplication

Total Lines 183
Duplicated Lines 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 63
dl 0
loc 183
rs 10
c 2
b 0
f 0
wmc 13

10 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 3 1
A deleteTarget() 0 3 1
A getMembersWithSettlements() 0 22 2
A getMembersSettlements() 0 18 2
A getMemberCount() 0 3 1
A getTarget() 0 10 2
A getDeadlineSessions() 0 7 1
A updateTarget() 0 8 1
A getMembersQuery() 0 6 1
A createTarget() 0 10 1
1
<?php
2
3
namespace Siak\Tontine\Service\Meeting\Charge;
4
5
use Illuminate\Support\Collection;
6
use Illuminate\Support\Facades\DB;
7
use Illuminate\Support\Facades\Log;
8
use Siak\Tontine\Model\Charge;
9
use Siak\Tontine\Model\Session;
10
use Siak\Tontine\Model\SettlementTarget;
11
use Siak\Tontine\Service\TenantService;
12
13
class SettlementTargetService
14
{
15
    /**
16
     * @var TenantService
17
     */
18
    protected TenantService $tenantService;
19
20
    /**
21
     * @param TenantService $tenantService
22
     */
23
    public function __construct(TenantService $tenantService)
24
    {
25
        $this->tenantService = $tenantService;
26
    }
27
28
    /**
29
     * Get the sessions after the current.
30
     *
31
     * @param Session $currentSession
32
     *
33
     * @return Collection
34
     */
35
    public function getDeadlineSessions(Session $currentSession): Collection
36
    {
37
        return $this->tenantService->getSessions()
38
            ->filter(function($session) use($currentSession) {
39
                return $session->start_at > $currentSession->start_at;
40
            })
41
            ->pluck('title', 'id');
42
    }
43
44
    /**
45
     * @param Charge $charge
46
     * @param Session $session
47
     *
48
     * @return SettlementTarget|null
49
     */
50
    public function getTarget(Charge $charge, Session $session): ?SettlementTarget
51
    {
52
        return $charge->targets()
53
            ->with(['session', 'deadline'])
54
            ->get()
55
            ->filter(function($target) use($session) {
56
                return $session->start_at >= $target->session->start_at &&
57
                    $session->start_at <= $target->deadline->start_at;
58
            })
59
            ->first();
60
    }
61
62
    /**
63
     * @param string $search
64
     *
65
     * @return mixed
66
     */
67
    private function getMembersQuery(string $search = '')
68
    {
69
        return $this->tenantService->tontine()->members()->active()
70
            ->when($search !== '', function($query) use($search) {
71
                return $query->where(DB::raw('lower(members.name)'),
72
                    'like', '%' . strtolower($search) . '%');
73
            });
74
    }
75
76
    /**
77
     * @param Charge $charge
78
     * @param SettlementTarget $target
79
     * @param Collection $members
80
     *
81
     * @return Collection
82
     */
83
    public function getMembersSettlements(Charge $charge, SettlementTarget $target,
84
        Collection $members): Collection
85
    {
86
        $sessions = $this->tenantService->round()->sessions
87
            ->filter(function($session) use($target) {
88
                return $session->start_at >= $target->session->start_at &&
89
                    $session->start_at <= $target->deadline->start_at;
90
            });
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(function($session) use($target) {
116
                return $session->start_at >= $target->session->start_at &&
117
                    $session->start_at <= $target->deadline->start_at;
118
            });
119
        return $this->getMembersQuery($search)
120
            ->select('members.id', 'members.name')
121
            ->addSelect([
122
                'paid' => DB::table('settlements')
123
                    ->join('bills', 'settlements.bill_id', '=', 'bills.id')
124
                    ->join('libre_bills', 'libre_bills.bill_id', '=', 'bills.id')
125
                    ->whereColumn('libre_bills.member_id', 'members.id')
126
                    ->where('libre_bills.charge_id', $charge->id)
127
                    ->whereIn('settlements.session_id', $sessions->pluck('id'))
128
                    ->select(DB::raw('SUM(bills.amount)'))
129
            ])
130
            ->page($page, $this->tenantService->getLimit())
131
            ->orderBy('members.name', 'asc')
132
            ->get();
133
    }
134
135
    /**
136
     * @param Charge $charge
137
     * @param Session $session
138
     * @param string $search
139
     * @param bool $filter|null
140
     *
141
     * @return int
142
     */
143
    public function getMemberCount(string $search = ''): int
144
    {
145
        return $this->getMembersQuery($search)->count();
146
    }
147
148
    /**
149
     * @param Charge $charge
150
     * @param Session $session
151
     * @param Session $deadline
152
     * @param float $amount
153
     * @param bool $global
154
     *
155
     * @return void
156
     */
157
    public function createTarget(Charge $charge, Session $session,
158
        Session $deadline, float $amount, bool $global): void
159
    {
160
        $target = new SettlementTarget();
161
        $target->amount = $amount;
162
        $target->global = $global;
163
        $target->charge()->associate($charge);
164
        $target->session()->associate($session);
165
        $target->deadline()->associate($deadline);
166
        $target->save();
167
    }
168
169
    /**
170
     * @param SettlementTarget $target
171
     * @param Session $session
172
     * @param Session $deadline
173
     * @param float $amount
174
     * @param bool $global
175
     *
176
     * @return void
177
     */
178
    public function updateTarget(SettlementTarget $target, Session $session,
179
        Session $deadline, float $amount, bool $global): void
180
    {
181
        $target->amount = $amount;
182
        $target->global = $global;
183
        $target->session()->associate($session);
184
        $target->deadline()->associate($deadline);
185
        $target->save();
186
    }
187
188
    /**
189
     * @param SettlementTarget $target
190
     *
191
     * @return void
192
     */
193
    public function deleteTarget(SettlementTarget $target): void
194
    {
195
        $target->delete();
196
    }
197
}
198