Passed
Push — main ( 59b813...6e4e13 )
by Thierry
05:31
created

MemberService::getMemberCount()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
c 0
b 0
f 0
nc 1
nop 1
dl 0
loc 3
rs 10
1
<?php
2
3
namespace Siak\Tontine\Service\Planning;
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 Siak\Tontine\Exception\MessageException;
10
use Siak\Tontine\Model\MemberDef;
11
use Siak\Tontine\Model\Round;
12
use Siak\Tontine\Service\TenantService;
13
use Siak\Tontine\Service\Traits\WithTrait;
14
use Siak\Tontine\Validation\SearchSanitizer;
15
16
class MemberService
17
{
18
    use WithTrait;
19
20
    /**
21
     * @param TenantService $tenantService
22
     * @param BillSyncService $billSyncService
23
     * @param SearchSanitizer $searchSanitizer
24
     */
25
    public function __construct(private TenantService $tenantService,
26
        private BillSyncService $billSyncService, private SearchSanitizer $searchSanitizer)
27
    {}
28
29
    /**
30
     * @param Round $round
31
     * @param string $search
32
     * @param bool $filter|null
33
     *
34
     * @return Relation
35
     */
36
    private function getQuery(Round $round, string $search, ?bool $filter): Relation
37
    {
38
        $onRoundFilter = fn(Builder $q) => $q->where('round_id', $round->id);
39
        return $round->guild->members()
40
            ->search($this->searchSanitizer->sanitize($search))
41
            ->when($filter === true, fn(Builder $query) => $query
42
                ->whereHas('members', $onRoundFilter))
43
            ->when($filter === false, fn(Builder $query) => $query
44
                ->whereDoesntHave('members', $onRoundFilter));
45
    }
46
47
    /**
48
     * Get a paginated list of members.
49
     *
50
     * @param Round $round
51
     * @param string $search
52
     * @param bool $filter|null
53
     * @param int $page
54
     *
55
     * @return Collection
56
     */
57
    public function getMemberDefs(Round $round, string $search, ?bool $filter, int $page = 0): Collection
58
    {
59
        return $this->getQuery($round, $search, $filter)
60
            ->withCount([
61
                'members' => fn(Builder $q) => $q->where('round_id', $round->id),
62
            ])
63
            ->page($page, $this->tenantService->getLimit())
64
            ->orderBy('name', 'asc')
65
            ->get();
66
    }
67
68
    /**
69
     * Get the number of members.
70
     *
71
     * @param Round $round
72
     * @param string $search
73
     * @param bool $filter|null
74
     *
75
     * @return int
76
     */
77
    public function getMemberDefCount(Round $round, string $search, ?bool $filter): int
78
    {
79
        return $this->getQuery($round, $search, $filter)->count();
80
    }
81
82
    /**
83
     * Get a single member.
84
     *
85
     * @param Round $round
86
     * @param int $memberId
87
     *
88
     * @return MemberDef|null
89
     */
90
    public function getMemberDef(Round $round, int $memberId): ?MemberDef
91
    {
92
        return $this->getQuery($round, '', null)->find($memberId);
93
    }
94
95
    /**
96
     * Add a new member.
97
     *
98
     * @param Round $round
99
     * @param int $defId
100
     *
101
     * @return void
102
     */
103
    public function enableMember(Round $round, int $defId): void
104
    {
105
        $def = $this->getMemberDef($round, $defId);
106
        if(!$def || $def->members->count() > 0)
107
        {
108
            return;
109
        }
110
111
        DB::transaction(function() use($round, $def) {
112
            $member = $def->members()->create(['round_id' => $round->id]);
113
114
            $this->billSyncService->memberEnabled($round, $member);
115
        });
116
    }
117
118
    /**
119
     * Delete a member.
120
     *
121
     * @param Round $round
122
     * @param int $defId
123
     *
124
     * @return void
125
     */
126
    public function disableMember(Round $round, int $defId): void
127
    {
128
        $def = $this->getMemberDef($round, $defId);
129
        if(!$def || $def->members->count() === 0)
130
        {
131
            return;
132
        }
133
134
        $member = $def->members->first();
135
        try
136
        {
137
            DB::transaction(function() use($round, $member) {
138
                $this->billSyncService->memberRemoved($round, $member);
139
140
                $member->delete();
141
            });
142
        }
143
        catch(Exception)
0 ignored issues
show
Bug introduced by
The type Siak\Tontine\Service\Planning\Exception was not found. Did you mean Exception? If so, make sure to prefix the type with \.
Loading history...
144
        {
145
            throw new MessageException(trans('tontine.member.errors.cannot_remove'));
146
        }
147
    }
148
149
    /**
150
     * Get the number of active members in the round.
151
     *
152
     * @param Round $round
153
     *
154
     * @return int
155
     */
156
    public function getMemberCount(Round $round): int
157
    {
158
        return $round->members()->count();
159
    }
160
}
161