Passed
Push — main ( 1c458a...5a987a )
by Thierry
10:56 queued 05:26
created

ChargeService::getChargeDef()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
c 1
b 0
f 0
nc 1
nop 2
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\ChargeDef;
11
use Siak\Tontine\Model\Round;
12
use Siak\Tontine\Service\TenantService;
13
use Exception;
14
15
class ChargeService
16
{
17
    /**
18
     * @param TenantService $tenantService
19
     * @param BillSyncService $billSyncService
20
     */
21
    public function __construct(private TenantService $tenantService,
22
        private BillSyncService $billSyncService)
23
    {}
24
25
    /**
26
     * @param Round $round
27
     * @param bool $filter|null
28
     *
29
     * @return Relation
30
     */
31
    private function getQuery(Round $round, ?bool $filter): Relation
32
    {
33
        $chargeCallback = fn($q) => $q->where('round_id', $round->id);
34
        return $round->guild->charges()
35
            ->with(['charges' => $chargeCallback])
36
            ->when($filter === true, fn(Builder $query) => $query
37
                ->whereHas('charges', $chargeCallback))
38
            ->when($filter === false, fn(Builder $query) => $query
39
                ->whereDoesntHave('charges', $chargeCallback));
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
            ->page($page, $this->tenantService->getLimit())
54
            ->orderBy('type', 'asc')
55
            ->orderBy('period', 'desc')
56
            ->orderBy('name', 'asc')
57
            ->get();
58
    }
59
60
    /**
61
     * Get the number of charges.
62
     *
63
     * @param Round $round
64
     *
65
     * @return int
66
     */
67
    public function getChargeDefCount(Round $round, ?bool $filter): int
68
    {
69
        return $this->getQuery($round, $filter)->count();
70
    }
71
72
    /**
73
     * Get a single charge.
74
     *
75
     * @param Round $round
76
     * @param int $chargeId
77
     *
78
     * @return ChargeDef|null
79
     */
80
    public function getChargeDef(Round $round, int $chargeId): ?ChargeDef
81
    {
82
        return $this->getQuery($round, null)->find($chargeId);
83
    }
84
85
    /**
86
     * Add new charge.
87
     *
88
     * @param Round $round
89
     * @param int $defId
90
     *
91
     * @return void
92
     */
93
    public function enableCharge(Round $round, int $defId): void
94
    {
95
        $def = $this->getChargeDef($round, $defId);
96
        if(!$def || $def->charges->count() > 0)
97
        {
98
            return;
99
        }
100
101
        DB::transaction(function() use($round, $def) {
102
            $charge = $def->charges()->create(['round_id' => $round->id]);
103
104
            $this->billSyncService->chargeEnabled($round, $charge);
105
        });
106
    }
107
108
    /**
109
     * Delete a charge.
110
     *
111
     * @param Round $round
112
     * @param int $defId
113
     *
114
     * @return void
115
     */
116
    public function disableCharge(Round $round, int $defId): void
117
    {
118
        $def = $this->getChargeDef($round, $defId);
119
        if(!$def || $def->charges->count() === 0)
120
        {
121
            return;
122
        }
123
124
        $charge = $def->charges->first();
125
        try
126
        {
127
            DB::transaction(function() use($round, $charge) {
128
                $this->billSyncService->chargeRemoved($round, $charge);
129
130
                $charge->delete();
131
            });
132
        }
133
        catch(Exception)
134
        {
135
            throw new MessageException(trans('tontine.charge.errors.cannot_remove'));
136
        }
137
    }
138
}
139