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

ChargeService::getChargeCount()   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 Lagdo\Facades\Logger;
10
use Siak\Tontine\Exception\MessageException;
11
use Siak\Tontine\Model\ChargeDef;
12
use Siak\Tontine\Model\Round;
13
use Siak\Tontine\Service\TenantService;
14
use Exception;
15
16
class ChargeService
17
{
18
    /**
19
     * @param TenantService $tenantService
20
     * @param BillSyncService $billSyncService
21
     */
22
    public function __construct(private TenantService $tenantService,
23
        private BillSyncService $billSyncService)
24
    {}
25
26
    /**
27
     * @param Round $round
28
     * @param bool $filter|null
29
     *
30
     * @return Relation
31
     */
32
    private function getQuery(Round $round, ?bool $filter): Relation
33
    {
34
        $onRoundFilter = fn(Builder $q) => $q->where('round_id', $round->id);
35
        return $round->guild->charges()
36
            ->when($filter === true, fn(Builder $query) => $query
37
                ->whereHas('charges', $onRoundFilter))
38
            ->when($filter === false, fn(Builder $query) => $query
39
                ->whereDoesntHave('charges', $onRoundFilter));
40
    }
41
42
    /**
43
     * Get a paginated list of charges.
44
     *
45
     * @param Round $round
46
     * @param int $page
47
     *
48
     * @return Collection
49
     */
50
    public function getChargeDefs(Round $round, ?bool $filter, int $page = 0): Collection
51
    {
52
        return $this->getQuery($round, $filter)
53
            ->withCount([
54
                'charges' => fn(Builder $q) => $q->where('round_id', $round->id),
55
            ])
56
            ->page($page, $this->tenantService->getLimit())
57
            ->orderBy('type', 'asc')
58
            ->orderBy('period', 'desc')
59
            ->orderBy('name', 'asc')
60
            ->get();
61
    }
62
63
    /**
64
     * Get the number of charges.
65
     *
66
     * @param Round $round
67
     *
68
     * @return int
69
     */
70
    public function getChargeDefCount(Round $round, ?bool $filter): int
71
    {
72
        return $this->getQuery($round, $filter)->count();
73
    }
74
75
    /**
76
     * Get a single charge.
77
     *
78
     * @param Round $round
79
     * @param int $chargeId
80
     *
81
     * @return ChargeDef|null
82
     */
83
    public function getChargeDef(Round $round, int $chargeId): ?ChargeDef
84
    {
85
        return $this->getQuery($round, null)->find($chargeId);
86
    }
87
88
    /**
89
     * Add new charge.
90
     *
91
     * @param Round $round
92
     * @param int $defId
93
     *
94
     * @return void
95
     */
96
    public function enableCharge(Round $round, int $defId): void
97
    {
98
        $def = $this->getChargeDef($round, $defId);
99
        if(!$def || $def->charges->count() > 0)
100
        {
101
            return;
102
        }
103
104
        DB::transaction(function() use($round, $def) {
105
            $charge = $def->charges()->create(['round_id' => $round->id]);
106
107
            $this->billSyncService->chargeEnabled($round, $charge);
108
        });
109
    }
110
111
    /**
112
     * Delete a charge.
113
     *
114
     * @param Round $round
115
     * @param int $defId
116
     *
117
     * @return void
118
     */
119
    public function disableCharge(Round $round, int $defId): void
120
    {
121
        $def = $this->getChargeDef($round, $defId);
122
        if(!$def || $def->charges->count() === 0)
123
        {
124
            return;
125
        }
126
127
        $charge = $def->charges->first();
128
        try
129
        {
130
            DB::transaction(function() use($round, $charge) {
131
                $this->billSyncService->chargeRemoved($round, $charge);
132
133
                $charge->delete();
134
            });
135
        }
136
        catch(Exception $e)
137
        {
138
            Logger::error('Error while disabling a charge.', [
139
                'message' => $e->getMessage(),
140
            ]);
141
            throw new MessageException(trans('tontine.charge.errors.cannot_remove'));
142
        }
143
    }
144
145
    /**
146
     * Get the number of active charges in the round.
147
     *
148
     * @param Round $round
149
     *
150
     * @return int
151
     */
152
    public function getChargeCount(Round $round): int
153
    {
154
        return $round->charges()->count();
155
    }
156
}
157