• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

klinge / sl-webapp / 18972069596

31 Oct 2025 12:08PM UTC coverage: 74.73% (+11.1%) from 63.602%
18972069596

Pull #115

github

web-flow
Merge c283235e4 into 63f7c79ae
Pull Request #115: 106 refactor controllers

677 of 783 new or added lines in 31 files covered. (86.46%)

80 existing lines in 4 files now uncovered.

1662 of 2224 relevant lines covered (74.73%)

3.82 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

98.59
/App/Services/SeglingService.php
1
<?php
2

3
declare(strict_types=1);
4

5
namespace App\Services;
6

7
use Exception;
8
use App\Models\SeglingRepository;
9
use App\Models\BetalningRepository;
10
use App\Models\MedlemRepository;
11
use App\Models\Roll;
12
use App\Utils\Sanitizer;
13
use App\Utils\Session;
14
use Monolog\Logger;
15
use PDOException;
16

17
class SeglingService
18
{
19
    public function __construct(
20
        private SeglingRepository $seglingRepo,
21
        private BetalningRepository $betalningRepo,
22
        private MedlemRepository $medlemRepo,
23
        private Roll $roll,
24
        private Logger $logger
25
    ) {
26
    }
17✔
27

28
    public function getAllSeglingar(): array
29
    {
30
        return $this->seglingRepo->getAllWithDeltagare();
1✔
31
    }
32

33
    public function getSeglingEditData(int $id): array
34
    {
35
        $segling = $this->seglingRepo->getByIdWithDeltagare($id);
2✔
36
        if (!$segling) {
2✔
37
            throw new Exception('Segling not found');
1✔
38
        }
39

40
        // Get deltagare with payment status
41
        $year = (int) substr($segling->start_dat, 0, 4);
1✔
42
        $deltagareWithBetalning = [];
1✔
43

44
        foreach ($segling->deltagare as $deltagare) {
1✔
45
            $hasPayed = $this->betalningRepo->memberHasPayed($deltagare['medlem_id'], $year);
1✔
46
            $deltagare['har_betalt'] = $hasPayed;
1✔
47
            $deltagareWithBetalning[] = $deltagare;
1✔
48
        }
49

50
        $segling->deltagare = $deltagareWithBetalning;
1✔
51

52
        return [
1✔
53
            'segling' => $segling,
1✔
54
            'roles' => $this->roll->getAll(),
1✔
55
            'allaSkeppare' => $this->medlemRepo->getMembersByRollName('Skeppare'),
1✔
56
            'allaBatsman' => $this->medlemRepo->getMembersByRollName('Båtsman'),
1✔
57
            'allaKockar' => $this->medlemRepo->getMembersByRollName('Kock')
1✔
58
        ];
1✔
59
    }
60

61
    public function updateSegling(int $id, array $postData): SeglingServiceResult
62
    {
63
        $sanitizer = new Sanitizer();
2✔
64
        $rules = [
2✔
65
            'startdat' => ['date', 'Y-m-d'],
2✔
66
            'slutdat' => ['date', 'Y-m-d'],
2✔
67
            'skeppslag' => 'string',
2✔
68
            'kommentar' => 'string',
2✔
69
        ];
2✔
70
        $cleanValues = $sanitizer->sanitize($postData, $rules);
2✔
71

72
        if ($this->seglingRepo->update($id, $cleanValues)) {
2✔
73
            return new SeglingServiceResult(true, 'Segling uppdaterad!', 'segling-list');
1✔
74
        } else {
75
            return new SeglingServiceResult(false, 'Kunde inte uppdatera seglingen. Försök igen.');
1✔
76
        }
77
    }
78

79
    public function deleteSegling(int $id): SeglingServiceResult
80
    {
81
        if ($this->seglingRepo->delete($id)) {
2✔
82
            $this->logger->info('Segling was deleted: ' . $id . ' by user: ' . Session::get('user_id'));
1✔
83
            return new SeglingServiceResult(true, 'Seglingen är nu borttagen!', 'segling-list');
1✔
84
        } else {
85
            $this->logger->warning('Failed to delete segling: ' . $id . ' User: ' . Session::get('user_id'));
1✔
86
            return new SeglingServiceResult(false, 'Kunde inte ta bort seglingen. Försök igen.', 'segling-list');
1✔
87
        }
88
    }
89

90
    public function createSegling(array $postData): SeglingServiceResult
91
    {
92
        $sanitizer = new Sanitizer();
3✔
93
        $rules = [
3✔
94
            'startdat' => ['date', 'Y-m-d'],
3✔
95
            'slutdat' => ['date', 'Y-m-d'],
3✔
96
            'skeppslag' => 'string',
3✔
97
            'kommentar' => 'string',
3✔
98
        ];
3✔
99
        $cleanValues = $sanitizer->sanitize($postData, $rules);
3✔
100

101
        // Validate required fields
102
        if (empty($cleanValues['startdat']) || empty($cleanValues['slutdat']) || empty($cleanValues['skeppslag'])) {
3✔
103
            return new SeglingServiceResult(false, 'Indata saknades. Kunde inte spara seglingen. Försök igen.', 'segling-show-create');
1✔
104
        }
105

106
        $result = $this->seglingRepo->create($cleanValues);
2✔
107

108
        if ($result) {
2✔
109
            return new SeglingServiceResult(true, 'Seglingen är nu skapad!', 'segling-edit', $result);
1✔
110
        } else {
111
            return new SeglingServiceResult(false, 'Kunde inte spara till databas. Försök igen.', 'segling-show-create');
1✔
112
        }
113
    }
114

115
    public function addMemberToSegling(array $postData): SeglingServiceResult
116
    {
117
        if (!isset($postData['segling_id']) || !isset($postData['segling_person'])) {
4✔
118
            return new SeglingServiceResult(false, 'Missing input');
1✔
119
        }
120

121
        $seglingId = (int) $postData['segling_id'];
3✔
122
        $memberId = (int) $postData['segling_person'];
3✔
123
        $roleId = isset($postData['segling_roll']) ? (int) $postData['segling_roll'] : null;
3✔
124

125
        if ($this->seglingRepo->isMemberOnSegling($seglingId, $memberId)) {
3✔
126
            return new SeglingServiceResult(false, 'Medlemmen är redan tillagd på seglingen.');
1✔
127
        }
128

129
        try {
130
            if ($this->seglingRepo->addMemberToSegling($seglingId, $memberId, $roleId)) {
2✔
131
                return new SeglingServiceResult(true, 'Medlem tillagd på segling');
1✔
132
            } else {
NEW
133
                return new SeglingServiceResult(false, 'Failed to insert row');
×
134
            }
135
        } catch (PDOException $e) {
1✔
136
            return new SeglingServiceResult(false, 'PDO error: ' . $e->getMessage());
1✔
137
        }
138
    }
139

140
    public function removeMemberFromSegling(array $data): SeglingServiceResult
141
    {
142
        $seglingId = $data['segling_id'] ?? null;
3✔
143
        $medlemId = $data['medlem_id'] ?? null;
3✔
144

145
        if (!$seglingId || !$medlemId) {
3✔
146
            $this->logger->warning("Failed to delete medlem from segling. Invalid data. Medlem: " . $medlemId . " Segling: " . $seglingId);
1✔
147
            return new SeglingServiceResult(false, 'Invalid data');
1✔
148
        }
149

150
        if ($this->seglingRepo->removeMemberFromSegling((int) $seglingId, (int) $medlemId)) {
2✔
151
            $this->logger->info("Delete medlem from segling. Medlem: " . $medlemId . " Segling: " . $seglingId . " User: " . Session::get('user_id'));
1✔
152
            return new SeglingServiceResult(true, 'Member removed successfully');
1✔
153
        } else {
154
            $this->logger->warning("Failed to delete medlem from segling. Medlem: " . $medlemId . " Segling: " . $seglingId);
1✔
155
            return new SeglingServiceResult(false, 'Deletion failed');
1✔
156
        }
157
    }
158
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc