diff --git a/CHANGELOG.md b/CHANGELOG.md
index abaeb96f..38a0e55e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
### Added
- Retrieve, create and delete SongArrangement comments ([PR187](https://github.com/5pm-HDH/churchtools-api/pull/187))
+- Get GroupTypes ([PR188](https://github.com/5pm-HDH/churchtools-api/pull/188))
### Changed
diff --git a/README.md b/README.md
index 413bbf47..8c1ec9e2 100644
--- a/README.md
+++ b/README.md
@@ -7,7 +7,7 @@
![integarion-test workflow](https://github.com/5pm-HDH/churchtools-api/actions/workflows/integration-tests.yml/badge.svg)
The ChurchTools-API Client is a PHP-based wrapper for the ChurchTools API and has been tested with ChurchTools
-version 3.104.0.
+version 3.104.3.
> [!NOTE]
> Version 2 has been launched, featuring a restructured code base and numerous new features. If you're upgrading from version 1 to 2, please consult the [Upgrade Guide](https://github.com/5pm-HDH/churchtools-api/blob/master/CHANGELOG.md#upgrade-guide---upgrading-from-v1-to-v2).
diff --git a/docs/out/GroupAPI.md b/docs/out/GroupAPI.md
index e578e730..ad92b206 100644
--- a/docs/out/GroupAPI.md
+++ b/docs/out/GroupAPI.md
@@ -512,4 +512,62 @@
// Output: []
+```
+
+## Group-Types
+
+```php
+ use CTApi\Models\Groups\Group\GroupType;
+ use CTApi\Models\Groups\Group\GroupTypeRequest;
+
+ $groupTypes = GroupTypeRequest::all();
+
+ $groupTypeNames = array_map(function (GroupType $groupType) {
+ return $groupType->getName();
+ }, $groupTypes);
+
+ $groupTypeNameList = implode("/", $groupTypeNames);
+ var_dump( $groupTypeNameList);
+ // Output: "Dienst/Kleingruppe/Maßnahme/Merkmal"
+
+
+```
+
+```php
+ use CTApi\Models\Groups\Group\GroupType;
+ use CTApi\Models\Groups\Group\GroupTypeRequest;
+
+ $groupType = GroupTypeRequest::find(2);
+
+ var_dump( $groupType?->getName());
+ // Output: "Dienst"
+
+ var_dump( $groupType?->getNameTranslated());
+ // Output: "Dienst"
+
+ var_dump( $groupType?->getNamePlural());
+ // Output: "Dienste"
+
+ var_dump( $groupType?->getNamePluralTranslated());
+ // Output: "Dienste"
+
+ var_dump( $groupType?->getShorty());
+ // Output: "DT"
+
+ var_dump( $groupType?->getDescription());
+ // Output: ""
+
+ var_dump( $groupType?->getIsLeaderNecessary());
+ // Output: false
+
+ var_dump( $groupType?->getAvailableForNewPerson());
+ // Output: false
+
+ var_dump( $groupType?->getPermissionDepth());
+ // Output: 1
+
+ var_dump( $groupType?->getSortKey());
+ // Output: 0
+
+
```
\ No newline at end of file
diff --git a/docs/src/ressources/GroupAPI.md b/docs/src/ressources/GroupAPI.md
index 8100d793..a98e7b1d 100644
--- a/docs/src/ressources/GroupAPI.md
+++ b/docs/src/ressources/GroupAPI.md
@@ -16,4 +16,10 @@
## GroupMemberFields
-{{ \CTApi\Test\Unit\Docs\GroupMemberFieldsTest.testGetFields }}
\ No newline at end of file
+{{ \CTApi\Test\Unit\Docs\GroupMemberFieldsTest.testGetFields }}
+
+## Group-Types
+
+{{ \CTApi\Test\Unit\Docs\GroupTypeRequestTest.testGetAll }}
+
+{{ \CTApi\Test\Unit\Docs\GroupTypeRequestTest.testFind }}
\ No newline at end of file
diff --git a/src/Models/Groups/Group/GroupType.php b/src/Models/Groups/Group/GroupType.php
new file mode 100644
index 00000000..1ba6e21a
--- /dev/null
+++ b/src/Models/Groups/Group/GroupType.php
@@ -0,0 +1,144 @@
+id = $id;
+ return $this;
+ }
+
+ public function getAvailableForNewPerson(): ?bool
+ {
+ return $this->availableForNewPerson;
+ }
+
+ public function setAvailableForNewPerson(?bool $availableForNewPerson): static
+ {
+ $this->availableForNewPerson = $availableForNewPerson;
+ return $this;
+ }
+
+ public function getIsLeaderNecessary(): ?bool
+ {
+ return $this->isLeaderNecessary;
+ }
+
+ public function setIsLeaderNecessary(?bool $isLeaderNecessary): static
+ {
+ $this->isLeaderNecessary = $isLeaderNecessary;
+ return $this;
+ }
+
+ public function getName(): ?string
+ {
+ return $this->name;
+ }
+
+ public function setName(?string $name): static
+ {
+ $this->name = $name;
+ return $this;
+ }
+
+ public function getNamePlural(): ?string
+ {
+ return $this->namePlural;
+ }
+
+ public function setNamePlural(?string $namePlural): static
+ {
+ $this->namePlural = $namePlural;
+ return $this;
+ }
+
+ public function getNamePluralTranslated(): ?string
+ {
+ return $this->namePluralTranslated;
+ }
+
+ public function setNamePluralTranslated(?string $namePluralTranslated): static
+ {
+ $this->namePluralTranslated = $namePluralTranslated;
+ return $this;
+ }
+
+ public function getNameTranslated(): ?string
+ {
+ return $this->nameTranslated;
+ }
+
+ public function setNameTranslated(?string $nameTranslated): static
+ {
+ $this->nameTranslated = $nameTranslated;
+ return $this;
+ }
+
+ public function getPermissionDepth(): ?int
+ {
+ return $this->permissionDepth;
+ }
+
+ public function setPermissionDepth(?int $permissionDepth): static
+ {
+ $this->permissionDepth = $permissionDepth;
+ return $this;
+ }
+
+ public function getShorty(): ?string
+ {
+ return $this->shorty;
+ }
+
+ public function setShorty(?string $shorty): static
+ {
+ $this->shorty = $shorty;
+ return $this;
+ }
+
+ public function getSortKey(): ?int
+ {
+ return $this->sortKey;
+ }
+
+ public function setSortKey(?int $sortKey): static
+ {
+ $this->sortKey = $sortKey;
+ return $this;
+ }
+
+ public function getDescription(): ?string
+ {
+ return $this->description;
+ }
+
+ public function setDescription(?string $description): GroupType
+ {
+ $this->description = $description;
+ return $this;
+ }
+}
diff --git a/src/Models/Groups/Group/GroupTypeRequest.php b/src/Models/Groups/Group/GroupTypeRequest.php
new file mode 100644
index 00000000..9df2ed57
--- /dev/null
+++ b/src/Models/Groups/Group/GroupTypeRequest.php
@@ -0,0 +1,33 @@
+all();
+ }
+
+ public static function where(string $key, $value): GroupTypeRequestBuilder
+ {
+ return (new GroupTypeRequestBuilder())->where($key, $value);
+ }
+
+ public static function orderBy(string $key, $orderAscending = true): GroupTypeRequestBuilder
+ {
+ return (new GroupTypeRequestBuilder())->orderBy($key, $orderAscending);
+ }
+
+ public static function findOrFail(int $id): GroupType
+ {
+ return (new GroupTypeRequestBuilder())->findOrFail($id);
+ }
+
+ public static function find(int $id): ?GroupType
+ {
+ return (new GroupTypeRequestBuilder())->find($id);
+ }
+
+}
diff --git a/src/Models/Groups/Group/GroupTypeRequestBuilder.php b/src/Models/Groups/Group/GroupTypeRequestBuilder.php
new file mode 100644
index 00000000..d64e3694
--- /dev/null
+++ b/src/Models/Groups/Group/GroupTypeRequestBuilder.php
@@ -0,0 +1,18 @@
+groupTypeId1 = IntegrationTestData::getResultAsInt("group_types", "any_group_type_1.id");
+ $this->groupTypeId2 = IntegrationTestData::getResultAsInt("group_types", "any_group_type_2.id");
+ }
+
+ public function testGetAll()
+ {
+ $groupTypes = GroupTypeRequest::all();
+
+ $groupType1 = null;
+ $groupType2 = null;
+ foreach ($groupTypes as $groupType) {
+ if ($groupType->getIdAsInteger() === $this->groupTypeId1) {
+ $groupType1 = $groupType;
+ }
+ if ($groupType->getIdAsInteger() === $this->groupTypeId2) {
+ $groupType2 = $groupType;
+ }
+ }
+ $this->assertNotNull($groupType1);
+ $this->assertNotNull($groupType2);
+
+ $this->assertEqualsTestData("group_types", "any_group_type_1.name", $groupType1->getName());
+ $this->assertEqualsTestData("group_types", "any_group_type_1.namePlural", $groupType1->getNamePlural());
+ $this->assertEqualsTestData("group_types", "any_group_type_1.permissionDepth", $groupType1->getPermissionDepth());
+ $this->assertEqualsTestData("group_types", "any_group_type_1.shorty", $groupType1->getShorty());
+
+ $this->assertEqualsTestData("group_types", "any_group_type_2.name", $groupType2->getName());
+ $this->assertEqualsTestData("group_types", "any_group_type_2.namePlural", $groupType2->getNamePlural());
+ $this->assertEqualsTestData("group_types", "any_group_type_2.permissionDepth", $groupType2->getPermissionDepth());
+ $this->assertEqualsTestData("group_types", "any_group_type_2.shorty", $groupType2->getShorty());
+ }
+
+ public function testFind()
+ {
+ $groupType1 = GroupTypeRequest::find($this->groupTypeId1);
+ $this->assertEqualsTestData("group_types", "any_group_type_1.name", $groupType1->getName());
+ $this->assertEqualsTestData("group_types", "any_group_type_1.namePlural", $groupType1->getNamePlural());
+ $this->assertEqualsTestData("group_types", "any_group_type_1.permissionDepth", $groupType1->getPermissionDepth());
+ $this->assertEqualsTestData("group_types", "any_group_type_1.shorty", $groupType1->getShorty());
+ }
+
+ public function testFindOrFail()
+ {
+ $groupType1 = GroupTypeRequest::findOrFail($this->groupTypeId1);
+ $this->assertEqualsTestData("group_types", "any_group_type_1.name", $groupType1->getName());
+ $this->assertEqualsTestData("group_types", "any_group_type_1.namePlural", $groupType1->getNamePlural());
+ $this->assertEqualsTestData("group_types", "any_group_type_1.permissionDepth", $groupType1->getPermissionDepth());
+ $this->assertEqualsTestData("group_types", "any_group_type_1.shorty", $groupType1->getShorty());
+ }
+
+
+ public function testFindOrFail_Failing()
+ {
+ $this->expectException(CTRequestException::class);
+ $groupType1 = GroupTypeRequest::findOrFail(999999);
+ }
+
+ public function testGetOrderBy()
+ {
+ $orderedById = GroupTypeRequest::orderBy("id")->get();
+
+ $indexGroupType1 = null;
+ $indexGroupType2 = null;
+
+ $index = 0;
+ foreach ($orderedById as $groupType) {
+ if ($groupType->getIdAsInteger() === $this->groupTypeId1) {
+ $indexGroupType1 = $index;
+ }
+ if ($groupType->getIdAsInteger() === $this->groupTypeId2) {
+ $indexGroupType2 = $index;
+ }
+ $index++;
+ }
+
+ $this->assertNotNull($indexGroupType1);
+ $this->assertNotNull($indexGroupType2);
+
+ $this->assertTrue($indexGroupType1 < $indexGroupType2);
+ }
+
+ public function testGetOrderBy_DESC()
+ {
+ $orderedById = GroupTypeRequest::orderBy("id", false)->get();
+
+ $indexGroupType1 = null;
+ $indexGroupType2 = null;
+
+ $index = 0;
+ foreach ($orderedById as $groupType) {
+ if ($groupType->getIdAsInteger() === $this->groupTypeId1) {
+ $indexGroupType1 = $index;
+ }
+ if ($groupType->getIdAsInteger() === $this->groupTypeId2) {
+ $indexGroupType2 = $index;
+ }
+ $index++;
+ }
+
+ $this->assertNotNull($indexGroupType1);
+ $this->assertNotNull($indexGroupType2);
+
+ $this->assertTrue($indexGroupType1 > $indexGroupType2);
+ }
+
+ public function testGetOrderBy_Name()
+ {
+ $orderedByName = GroupTypeRequest::orderBy("name")->get();
+
+ $indexGroupType1 = null;
+ $indexGroupType2 = null;
+
+ $index = 0;
+ foreach ($orderedByName as $groupType) {
+ if ($groupType->getIdAsInteger() === $this->groupTypeId1) {
+ $indexGroupType1 = $index;
+ }
+ if ($groupType->getIdAsInteger() === $this->groupTypeId2) {
+ $indexGroupType2 = $index;
+ }
+ $index++;
+ }
+
+ $this->assertNotNull($indexGroupType1);
+ $this->assertNotNull($indexGroupType2);
+
+ $this->assertTrue($indexGroupType1 > $indexGroupType2);
+ }
+}
\ No newline at end of file
diff --git a/tests/Integration/integration-test-data.json b/tests/Integration/integration-test-data.json
index bee1a2ed..fda634a9 100644
--- a/tests/Integration/integration-test-data.json
+++ b/tests/Integration/integration-test-data.json
@@ -94,6 +94,25 @@
"child_group_name": "Lobpreisteam"
}
},
+ "group_types": {
+ "description": "Get defined group types.",
+ "result": {
+ "any_group_type_1": {
+ "id": 1,
+ "name": "Kleingruppe",
+ "namePlural": "Kleingruppen",
+ "permissionDepth": 1,
+ "shorty": "KG"
+ },
+ "any_group_type_2": {
+ "id": 2,
+ "name": "Dienst",
+ "namePlural": "Dienste",
+ "permissionDepth": 1,
+ "shorty": "DT"
+ }
+ }
+ },
"update_group_member": {
"description": "Add person to group and remove them again.",
"filter": {
diff --git a/tests/Unit/Docs/GroupTypeRequestTest.php b/tests/Unit/Docs/GroupTypeRequestTest.php
new file mode 100644
index 00000000..1a9f6b59
--- /dev/null
+++ b/tests/Unit/Docs/GroupTypeRequestTest.php
@@ -0,0 +1,40 @@
+getName();
+ }, $groupTypes);
+
+ $groupTypeNameList = implode("/", $groupTypeNames);
+ $this->assertEquals("Dienst/Kleingruppe/Maßnahme/Merkmal", $groupTypeNameList);
+ }
+
+ public function testFind()
+ {
+ $groupType = GroupTypeRequest::find(2);
+
+ $this->assertEquals("Dienst", $groupType?->getName());
+ $this->assertEquals("Dienst", $groupType?->getNameTranslated());
+ $this->assertEquals("Dienste", $groupType?->getNamePlural());
+ $this->assertEquals("Dienste", $groupType?->getNamePluralTranslated());
+ $this->assertEquals("DT", $groupType?->getShorty());
+ $this->assertEquals("", $groupType?->getDescription());
+ $this->assertEquals(false, $groupType?->getIsLeaderNecessary());
+ $this->assertEquals(false, $groupType?->getAvailableForNewPerson());
+ $this->assertEquals(1, $groupType?->getPermissionDepth());
+ $this->assertEquals(0, $groupType?->getSortKey());
+ }
+
+}
\ No newline at end of file
diff --git a/tests/Unit/HttpMock/data/api_group_grouptypes.json b/tests/Unit/HttpMock/data/api_group_grouptypes.json
new file mode 100644
index 00000000..d473f2e9
--- /dev/null
+++ b/tests/Unit/HttpMock/data/api_group_grouptypes.json
@@ -0,0 +1,59 @@
+{
+ "data": [
+ {
+ "id": 2,
+ "name": "Dienst",
+ "nameTranslated": "Dienst",
+ "namePlural": "Dienste",
+ "namePluralTranslated": "Dienste",
+ "shorty": "DT",
+ "description": null,
+ "isLeaderNecessary": false,
+ "availableForNewPerson": false,
+ "permissionDepth": 1,
+ "sortKey": 0
+ },
+ {
+ "id": 1,
+ "name": "Kleingruppe",
+ "nameTranslated": "Kleingruppe",
+ "namePlural": "Kleingruppen",
+ "namePluralTranslated": "Kleingruppen",
+ "shorty": "KG",
+ "description": null,
+ "isLeaderNecessary": true,
+ "availableForNewPerson": false,
+ "permissionDepth": 1,
+ "sortKey": 0
+ },
+ {
+ "id": 3,
+ "name": "Ma\u00dfnahme",
+ "nameTranslated": "Ma\u00dfnahme",
+ "namePlural": "Ma\u00dfnahmen",
+ "namePluralTranslated": "Ma\u00dfnahmen",
+ "shorty": "MN",
+ "description": null,
+ "isLeaderNecessary": false,
+ "availableForNewPerson": true,
+ "permissionDepth": 1,
+ "sortKey": 0
+ },
+ {
+ "id": 4,
+ "name": "Merkmal",
+ "nameTranslated": "Merkmal",
+ "namePlural": "Merkmale",
+ "namePluralTranslated": "Merkmale",
+ "shorty": "MM",
+ "description": null,
+ "isLeaderNecessary": false,
+ "availableForNewPerson": true,
+ "permissionDepth": 1,
+ "sortKey": 0
+ }
+ ],
+ "meta": {
+ "count": 4
+ }
+}
\ No newline at end of file
diff --git a/tests/Unit/HttpMock/data/api_group_grouptypes_2.json b/tests/Unit/HttpMock/data/api_group_grouptypes_2.json
new file mode 100644
index 00000000..ff7c8099
--- /dev/null
+++ b/tests/Unit/HttpMock/data/api_group_grouptypes_2.json
@@ -0,0 +1,18 @@
+{
+ "data": {
+ "id": 2,
+ "name": "Dienst",
+ "nameTranslated": "Dienst",
+ "namePlural": "Dienste",
+ "namePluralTranslated": "Dienste",
+ "shorty": "DT",
+ "description": null,
+ "isLeaderNecessary": false,
+ "availableForNewPerson": false,
+ "permissionDepth": 1,
+ "sortKey": 0
+ },
+ "meta": {
+ "count": 4
+ }
+}
\ No newline at end of file