diff --git a/api/migrations/schema/Version20250412165829.php b/api/migrations/schema/Version20250412165829.php
deleted file mode 100644
index 97d2497350..0000000000
--- a/api/migrations/schema/Version20250412165829.php
+++ /dev/null
@@ -1,31 +0,0 @@
-addSql(<<<'SQL'
- ALTER TABLE material_item ALTER materialListId DROP NOT NULL
- SQL);
- }
-
- public function down(Schema $schema): void {
- // this down() migration is auto-generated, please modify it to your needs
- $this->addSql(<<<'SQL'
- ALTER TABLE material_item ALTER materiallistid SET NOT NULL
- SQL);
- }
-}
diff --git a/api/src/Entity/ContentNode.php b/api/src/Entity/ContentNode.php
index 5c80a12c08..5b66cbe19f 100644
--- a/api/src/Entity/ContentNode.php
+++ b/api/src/Entity/ContentNode.php
@@ -53,7 +53,7 @@
#[ORM\InheritanceType('SINGLE_TABLE')]
#[ORM\DiscriminatorColumn(name: 'strategy', type: 'string')]
#[ORM\UniqueConstraint(name: 'contentnode_parentid_slot_position_unique', columns: ['parentid', 'slot', 'position'])]
-abstract class ContentNode extends BaseEntity implements BelongsToCampInterface, BelongsToContentNodeTreeInterface, CopyFromPrototypeInterface, HasParentInterface {
+abstract class ContentNode extends BaseEntity implements BelongsToContentNodeTreeInterface, CopyFromPrototypeInterface, HasParentInterface {
use ClassInfoTrait;
/**
@@ -193,17 +193,6 @@ public function setParent(?ContentNode $parent) {
$this->root ??= $parent?->root;
}
- public function getCamp(): ?Camp {
- if (null == $this->getRoot()) {
- return null;
- }
- if ($this->getRoot()->campRootContentNodes->count() > 0) {
- return $this->getRoot()->campRootContentNodes[0]->camp;
- }
-
- return null;
- }
-
/**
* Holds the actual data of the content node.
*/
diff --git a/api/src/Entity/MaterialItem.php b/api/src/Entity/MaterialItem.php
index 97f10de041..dafa0084cb 100644
--- a/api/src/Entity/MaterialItem.php
+++ b/api/src/Entity/MaterialItem.php
@@ -23,7 +23,6 @@
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Serializer\Annotation\Groups;
-use Symfony\Component\Serializer\Attribute\SerializedName;
use Symfony\Component\Validator\Constraints as Assert;
/**
@@ -45,7 +44,6 @@
security: 'is_authenticated()'
),
new Post(
- denormalizationContext: ['groups' => ['write', 'create']],
securityPostDenormalize: 'is_granted("CAMP_MEMBER", object) or is_granted("CAMP_MANAGER", object) or object.materialList === null'
),
],
@@ -60,12 +58,11 @@ class MaterialItem extends BaseEntity implements BelongsToCampInterface, CopyFro
* The list to which this item belongs. Lists are used to keep track of who is
* responsible to prepare and bring the item to the camp.
*/
- #[Assert\NotNull]
- #[AssertBelongsToSameCamp]
+ #[AssertBelongsToSameCamp(compareToPrevious: true, groups: ['update'])]
#[ApiProperty(example: '/material_lists/1a2b3c4d')]
#[Groups(['read', 'write'])]
#[ORM\ManyToOne(targetEntity: MaterialList::class, inversedBy: 'materialItems')]
- #[ORM\JoinColumn(nullable: true, onDelete: 'cascade')]
+ #[ORM\JoinColumn(nullable: false, onDelete: 'cascade')]
public ?MaterialList $materialList = null;
/**
@@ -134,13 +131,9 @@ public function __construct() {
$this->periodMaterialItems = new ArrayCollection();
}
- #[ApiProperty]
- #[SerializedName('camp')]
- #[Groups(['read'])]
+ #[ApiProperty(readable: false)]
public function getCamp(): ?Camp {
- return $this->period?->getCamp()
- ?? $this->materialNode?->getCamp()
- ?? $this->materialList?->getCamp();
+ return $this->materialList?->getCamp();
}
/**
@@ -150,14 +143,9 @@ public function getCamp(): ?Camp {
public function copyFromPrototype($prototype, $entityMap): void {
$entityMap->add($prototype, $this);
- if (null != $prototype->materialList) {
- /** @var MaterialList $materialList */
- $materialList = $entityMap->get($prototype->materialList);
-
- if ($entityMap->belongsToTargetCamp($materialList)) {
- $materialList->addMaterialItem($this);
- }
- }
+ /** @var MaterialList $materialList */
+ $materialList = $entityMap->get($prototype->materialList);
+ $materialList->addMaterialItem($this);
$this->article = $prototype->article;
$this->quantity = $prototype->quantity;
diff --git a/api/src/Repository/MaterialItemRepository.php b/api/src/Repository/MaterialItemRepository.php
index eaa4f6cb7c..5a0dda44ee 100644
--- a/api/src/Repository/MaterialItemRepository.php
+++ b/api/src/Repository/MaterialItemRepository.php
@@ -24,8 +24,7 @@ public function __construct(ManagerRegistry $registry) {
}
public function filterByUser(QueryBuilder $queryBuilder, QueryNameGeneratorInterface $queryNameGenerator, User $user): void {
- $periodMaterialItems = QueryBuilderHelper::findOrAddInnerRootJoinAlias($queryBuilder, $queryNameGenerator, 'periodMaterialItems');
- $period = QueryBuilderHelper::findOrAddInnerJoinAlias($queryBuilder, $queryNameGenerator, $periodMaterialItems, 'period');
- $this->filterByCampCollaboration($queryBuilder, $user, "{$period}.camp");
+ $materialList = QueryBuilderHelper::findOrAddInnerRootJoinAlias($queryBuilder, $queryNameGenerator, 'materialList');
+ $this->filterByCampCollaboration($queryBuilder, $user, "{$materialList}.camp");
}
}
diff --git a/api/src/State/ActivityCreateProcessor.php b/api/src/State/ActivityCreateProcessor.php
index a1f19bb8af..c5204cb303 100644
--- a/api/src/State/ActivityCreateProcessor.php
+++ b/api/src/State/ActivityCreateProcessor.php
@@ -34,7 +34,6 @@ public function onBefore($data, Operation $operation, array $uriVariables = [],
throw new \UnexpectedValueException('Property rootContentNode of provided category is of wrong type. Object of type '.ColumnLayout::class.' expected.');
}
- $targetCamp = $data->category->camp;
$data->camp = $data->category->camp;
$rootContentNodePrototype = $data->category->rootContentNode;
@@ -51,7 +50,7 @@ public function onBefore($data, Operation $operation, array $uriVariables = [],
$data->setRootContentNode($rootContentNode);
// deep copy from category root node
- $entityMap = new EntityMap($targetCamp);
+ $entityMap = new EntityMap();
$rootContentNode->copyFromPrototype($rootContentNodePrototype, $entityMap);
return $data;
diff --git a/api/src/State/CampCreateProcessor.php b/api/src/State/CampCreateProcessor.php
index cf33080406..89a9e3060b 100644
--- a/api/src/State/CampCreateProcessor.php
+++ b/api/src/State/CampCreateProcessor.php
@@ -37,7 +37,7 @@ public function onBefore($data, Operation $operation, array $uriVariables = [],
// copy from prototype, if given
if (isset($data->campPrototype)) {
- $entityMap = new EntityMap($data);
+ $entityMap = new EntityMap();
$data->copyFromPrototype($data->campPrototype, $entityMap);
}
diff --git a/api/src/State/CategoryCreateProcessor.php b/api/src/State/CategoryCreateProcessor.php
index 60e3edbc84..305b7422ba 100644
--- a/api/src/State/CategoryCreateProcessor.php
+++ b/api/src/State/CategoryCreateProcessor.php
@@ -38,7 +38,7 @@ public function onBefore($data, Operation $operation, array $uriVariables = [],
if (isset($data->copyCategorySource)) {
// CopyActivity Source is set -> copy it's content (rootContentNode)
- $entityMap = new EntityMap($data->camp);
+ $entityMap = new EntityMap();
$rootContentNode->copyFromPrototype($data->copyCategorySource->getRootContentNode(), $entityMap);
}
diff --git a/api/src/State/ChecklistCreateProcessor.php b/api/src/State/ChecklistCreateProcessor.php
index 0e477ab22f..bbac6635f5 100644
--- a/api/src/State/ChecklistCreateProcessor.php
+++ b/api/src/State/ChecklistCreateProcessor.php
@@ -22,7 +22,7 @@ public function __construct(ProcessorInterface $decorated) {
public function onBefore($data, Operation $operation, array $uriVariables = [], array $context = []): Checklist {
if (isset($data->copyChecklistSource)) {
// CopyChecklist Source is set -> copy it's content
- $entityMap = new EntityMap($data->camp);
+ $entityMap = new EntityMap();
$data->copyFromPrototype($data->copyChecklistSource, $entityMap);
}
diff --git a/api/src/Util/EntityMap.php b/api/src/Util/EntityMap.php
index 9091fe2d7e..d6bfdf07dc 100644
--- a/api/src/Util/EntityMap.php
+++ b/api/src/Util/EntityMap.php
@@ -3,16 +3,12 @@
namespace App\Util;
use App\Entity\BaseEntity;
-use App\Entity\BelongsToCampInterface;
-use App\Entity\Camp;
class EntityMap {
use ClassInfoTrait;
private $map = [];
- public function __construct(private Camp $targetCamp) {}
-
public function add(BaseEntity $prototype, BaseEntity $entity) {
$key = $this->getObjectClass($prototype).'#'.$prototype->getId();
$this->map[$key] = $entity;
@@ -24,8 +20,4 @@ public function get(BaseEntity $prototype): BaseEntity {
return $keyExists ? $this->map[$key] : $prototype;
}
-
- public function belongsToTargetCamp(BelongsToCampInterface $entity) {
- return $entity->getCamp() == $this->targetCamp;
- }
}
diff --git a/api/tests/Api/Activities/CreateActivityTest.php b/api/tests/Api/Activities/CreateActivityTest.php
index 8c17c96787..1f54d509d5 100644
--- a/api/tests/Api/Activities/CreateActivityTest.php
+++ b/api/tests/Api/Activities/CreateActivityTest.php
@@ -519,7 +519,7 @@ public function testCreateActivityFromCopySourceWithinSameCamp() {
}
public function testCreateActivityFromCopySourceAcrossCamp() {
- $response = static::createClientWithCredentials()->request(
+ static::createClientWithCredentials()->request(
'POST',
'/activities',
['json' => $this->getExampleWritePayload(
@@ -540,21 +540,6 @@ public function testCreateActivityFromCopySourceAcrossCamp() {
// Activity created
$this->assertResponseStatusCodeSame(201);
-
- // Embedded MaterialNode -> MaterialItems
- // Test MaterialList is nulled
- $responseArray = $response->toArray();
- $contentNodes = $responseArray['_embedded']['contentNodes'];
-
- $materialNodes = array_filter($contentNodes, fn ($cn) => 'Material' == $cn['contentTypeName']);
- $this->assertCount(1, $materialNodes);
-
- $materialNode = reset($materialNodes);
- $materialItems = $materialNode['_embedded']['materialItems'];
- $this->assertCount(1, $materialItems);
-
- $materailItem = reset($materialItems);
- $this->assertNull($materailItem['_links']['materialList']);
}
/**
diff --git a/api/tests/Api/MaterialItems/CreateMaterialItemTest.php b/api/tests/Api/MaterialItems/CreateMaterialItemTest.php
index 1bb5dc4c56..8224ab0176 100644
--- a/api/tests/Api/MaterialItems/CreateMaterialItemTest.php
+++ b/api/tests/Api/MaterialItems/CreateMaterialItemTest.php
@@ -205,7 +205,7 @@ public function testCreateMaterialItemValidatesPeriodFromDifferentCamp() {
$this->assertJsonContains([
'violations' => [
[
- 'propertyPath' => 'materialList',
+ 'propertyPath' => 'period',
'message' => 'Must belong to the same camp.',
],
],
@@ -222,7 +222,7 @@ public function testCreateMaterialItemValidatesMaterialNodeFromDifferentCamp() {
$this->assertJsonContains([
'violations' => [
[
- 'propertyPath' => 'materialList',
+ 'propertyPath' => 'materialNode',
'message' => 'Must belong to the same camp.',
],
],
diff --git a/api/tests/Api/MaterialItems/UpdateMaterialItemTest.php b/api/tests/Api/MaterialItems/UpdateMaterialItemTest.php
index 82b3eceaa8..7d072793bb 100644
--- a/api/tests/Api/MaterialItems/UpdateMaterialItemTest.php
+++ b/api/tests/Api/MaterialItems/UpdateMaterialItemTest.php
@@ -151,9 +151,9 @@ public function testPatchMaterialItemValidatesMissingMaterialList() {
'materialList' => null,
], 'headers' => ['Content-Type' => 'application/merge-patch+json']]);
- $this->assertResponseStatusCodeSame(422);
+ $this->assertResponseStatusCodeSame(400);
$this->assertJsonContains([
- 'detail' => 'materialList: This value should not be null.',
+ 'detail' => 'The type of the "materialList" attribute must be "array" (nested document) or "string" (IRI), "NULL" given.',
]);
}
@@ -244,7 +244,7 @@ public function testPatchMaterialItemValidatesPeriodFromDifferentCamp() {
$this->assertJsonContains([
'violations' => [
[
- 'propertyPath' => 'materialList',
+ 'propertyPath' => 'period',
'message' => 'Must belong to the same camp.',
],
],
@@ -261,7 +261,7 @@ public function testPatchMaterialItemValidatesMaterialNodeFromDifferentCamp() {
$this->assertJsonContains([
'violations' => [
[
- 'propertyPath' => 'materialList',
+ 'propertyPath' => 'materialNode',
'message' => 'Must belong to the same camp.',
],
],
diff --git a/api/tests/Api/SnapshotTests/EndpointPerformanceTest.php b/api/tests/Api/SnapshotTests/EndpointPerformanceTest.php
index 92f4138caa..46e474c2d9 100644
--- a/api/tests/Api/SnapshotTests/EndpointPerformanceTest.php
+++ b/api/tests/Api/SnapshotTests/EndpointPerformanceTest.php
@@ -186,9 +186,9 @@ protected function getSnapshotId(): string {
private static function getContentNodeEndpointQueryCountRanges(): array {
return [
- '/content_nodes' => [10, 12],
+ '/content_nodes' => [8, 11],
'/content_node/column_layouts' => [6, 6],
- '/content_node/column_layouts/item' => [9, 9],
+ '/content_node/column_layouts/item' => [10, 10],
'/content_node/checklist_nodes' => [6, 7],
'/content_node/checklist_nodes/item' => [9, 9],
'/content_node/material_nodes' => [6, 7],
diff --git a/api/tests/Api/SnapshotTests/__snapshots__/ResponseSnapshotTest__testGetCollectionMatchesStructure with data set content_nodematerial_nodes__1.json b/api/tests/Api/SnapshotTests/__snapshots__/ResponseSnapshotTest__testGetCollectionMatchesStructure with data set content_nodematerial_nodes__1.json
index eb28f3fab4..57f3dd809a 100644
--- a/api/tests/Api/SnapshotTests/__snapshots__/ResponseSnapshotTest__testGetCollectionMatchesStructure with data set content_nodematerial_nodes__1.json
+++ b/api/tests/Api/SnapshotTests/__snapshots__/ResponseSnapshotTest__testGetCollectionMatchesStructure with data set content_nodematerial_nodes__1.json
@@ -35,9 +35,6 @@
"materialItems": [
{
"_links": {
- "camp": {
- "href": "escaped_value"
- },
"materialList": {
"href": "escaped_value"
},
diff --git a/api/tests/Api/SnapshotTests/__snapshots__/ResponseSnapshotTest__testGetCollectionMatchesStructure with data set content_nodes__1.json b/api/tests/Api/SnapshotTests/__snapshots__/ResponseSnapshotTest__testGetCollectionMatchesStructure with data set content_nodes__1.json
index f473304eb9..2088e60717 100644
--- a/api/tests/Api/SnapshotTests/__snapshots__/ResponseSnapshotTest__testGetCollectionMatchesStructure with data set content_nodes__1.json
+++ b/api/tests/Api/SnapshotTests/__snapshots__/ResponseSnapshotTest__testGetCollectionMatchesStructure with data set content_nodes__1.json
@@ -35,9 +35,6 @@
"materialItems": [
{
"_links": {
- "camp": {
- "href": "escaped_value"
- },
"materialList": {
"href": "escaped_value"
},
diff --git a/api/tests/Api/SnapshotTests/__snapshots__/ResponseSnapshotTest__testGetCollectionMatchesStructure with data set material_items__1.json b/api/tests/Api/SnapshotTests/__snapshots__/ResponseSnapshotTest__testGetCollectionMatchesStructure with data set material_items__1.json
index 1223d1b54a..e47a32dc20 100644
--- a/api/tests/Api/SnapshotTests/__snapshots__/ResponseSnapshotTest__testGetCollectionMatchesStructure with data set material_items__1.json
+++ b/api/tests/Api/SnapshotTests/__snapshots__/ResponseSnapshotTest__testGetCollectionMatchesStructure with data set material_items__1.json
@@ -3,9 +3,6 @@
"items": [
{
"_links": {
- "camp": {
- "href": "escaped_value"
- },
"materialList": {
"href": "escaped_value"
},
@@ -24,9 +21,6 @@
},
{
"_links": {
- "camp": {
- "href": "escaped_value"
- },
"materialList": {
"href": "escaped_value"
},
@@ -45,9 +39,6 @@
},
{
"_links": {
- "camp": {
- "href": "escaped_value"
- },
"materialList": {
"href": "escaped_value"
},
@@ -66,9 +57,6 @@
},
{
"_links": {
- "camp": {
- "href": "escaped_value"
- },
"materialList": {
"href": "escaped_value"
},
diff --git a/api/tests/Api/SnapshotTests/__snapshots__/ResponseSnapshotTest__testGetItemMatchesStructure with data set activities__1.json b/api/tests/Api/SnapshotTests/__snapshots__/ResponseSnapshotTest__testGetItemMatchesStructure with data set activities__1.json
index 810a52ed1f..893d0b0e8c 100644
--- a/api/tests/Api/SnapshotTests/__snapshots__/ResponseSnapshotTest__testGetItemMatchesStructure with data set activities__1.json
+++ b/api/tests/Api/SnapshotTests/__snapshots__/ResponseSnapshotTest__testGetItemMatchesStructure with data set activities__1.json
@@ -46,9 +46,6 @@
"materialItems": [
{
"_links": {
- "camp": {
- "href": "escaped_value"
- },
"materialList": {
"href": "escaped_value"
},
diff --git a/api/tests/Api/SnapshotTests/__snapshots__/ResponseSnapshotTest__testGetItemMatchesStructure with data set material_items__1.json b/api/tests/Api/SnapshotTests/__snapshots__/ResponseSnapshotTest__testGetItemMatchesStructure with data set material_items__1.json
index 1c7206980e..5c1fd1b585 100644
--- a/api/tests/Api/SnapshotTests/__snapshots__/ResponseSnapshotTest__testGetItemMatchesStructure with data set material_items__1.json
+++ b/api/tests/Api/SnapshotTests/__snapshots__/ResponseSnapshotTest__testGetItemMatchesStructure with data set material_items__1.json
@@ -1,8 +1,5 @@
{
"_links": {
- "camp": {
- "href": "escaped_value"
- },
"materialList": {
"href": "escaped_value"
},
diff --git a/api/tests/Api/SnapshotTests/__snapshots__/ResponseSnapshotTest__testOpenApiSpecMatchesSnapshot__1.yml b/api/tests/Api/SnapshotTests/__snapshots__/ResponseSnapshotTest__testOpenApiSpecMatchesSnapshot__1.yml
index f62c201826..095f4f5ee9 100644
--- a/api/tests/Api/SnapshotTests/__snapshots__/ResponseSnapshotTest__testOpenApiSpecMatchesSnapshot__1.yml
+++ b/api/tests/Api/SnapshotTests/__snapshots__/ResponseSnapshotTest__testOpenApiSpecMatchesSnapshot__1.yml
@@ -12771,13 +12771,6 @@ components:
example: Volleyball
maxLength: 64
type: string
- camp:
- example: 'https://example.com/'
- format: iri-reference
- readOnly: true
- type:
- - 'null'
- - string
id:
description: 'An internal, unique, randomly generated identifier of this entity.'
example: 1a2b3c4d
@@ -12790,9 +12783,7 @@ components:
responsible to prepare and bring the item to the camp.
example: /material_lists/1a2b3c4d
format: iri-reference
- type:
- - 'null'
- - string
+ type: string
materialNode:
description: 'The content node to which this item belongs, if it does not belong to a period.'
example: /content_node/material_nodes/1a2b3c4d
@@ -12839,54 +12830,7 @@ components:
responsible to prepare and bring the item to the camp.
example: /material_lists/1a2b3c4d
format: iri-reference
- type:
- - 'null'
- - string
- materialNode:
- description: 'The content node to which this item belongs, if it does not belong to a period.'
- example: /content_node/material_nodes/1a2b3c4d
- format: iri-reference
- type:
- - 'null'
- - string
- period:
- description: 'The period to which this item belongs, if it does not belong to a content node.'
- example: /periods/1a2b3c4d
- format: iri-reference
- type:
- - 'null'
- - string
- quantity:
- description: 'The number of items or the amount in the unit of items that are required.'
- example: 1.5
- type:
- - 'null'
- - number
- unit:
- description: 'An optional unit for measuring the amount of items required.'
- example: kg
- type:
- - 'null'
- - string
- type: object
- MaterialItem-write_create:
- deprecated: false
- description: 'A physical item that is needed for carrying out a programme or camp.'
- properties:
- article:
- description: 'The name of the item that is required.'
- example: Volleyball
- maxLength: 64
type: string
- materialList:
- description: |-
- The list to which this item belongs. Lists are used to keep track of who is
- responsible to prepare and bring the item to the camp.
- example: /material_lists/1a2b3c4d
- format: iri-reference
- type:
- - 'null'
- - string
materialNode:
description: 'The content node to which this item belongs, if it does not belong to a period.'
example: /content_node/material_nodes/1a2b3c4d
@@ -12904,20 +12848,15 @@ components:
quantity:
description: 'The number of items or the amount in the unit of items that are required.'
example: 1.5
- exclusiveMinimum: 0
type:
- 'null'
- number
unit:
description: 'An optional unit for measuring the amount of items required.'
example: kg
- maxLength: 32
type:
- 'null'
- string
- required:
- - article
- - materialList
type: object
MaterialItem.jsonapi:
deprecated: false
@@ -12955,8 +12894,6 @@ components:
type: string
relationships:
properties:
- camp:
- properties: { data: { properties: { id: { format: iri-reference, type: string }, type: { type: string } }, type: object } }
materialList:
properties: { data: { properties: { id: { format: iri-reference, type: string }, type: { type: string } }, type: object } }
materialNode:
@@ -12984,8 +12921,6 @@ components:
$ref: '#/components/schemas/MaterialList.jsonapi'
-
$ref: '#/components/schemas/MaterialList.jsonapi'
- -
- $ref: '#/components/schemas/MaterialList.jsonapi'
readOnly: true
type: array
type: object
@@ -13007,13 +12942,6 @@ components:
example: Volleyball
maxLength: 64
type: string
- camp:
- example: 'https://example.com/'
- format: iri-reference
- readOnly: true
- type:
- - 'null'
- - string
id:
description: 'An internal, unique, randomly generated identifier of this entity.'
example: 1a2b3c4d
@@ -13026,9 +12954,7 @@ components:
responsible to prepare and bring the item to the camp.
example: /material_lists/1a2b3c4d
format: iri-reference
- type:
- - 'null'
- - string
+ type: string
materialNode:
description: 'The content node to which this item belongs, if it does not belong to a period.'
example: /content_node/material_nodes/1a2b3c4d
@@ -13061,7 +12987,7 @@ components:
- article
- materialList
type: object
- MaterialItem.jsonhal-write_create:
+ MaterialItem.jsonhal-write:
deprecated: false
description: 'A physical item that is needed for carrying out a programme or camp.'
properties:
@@ -13085,9 +13011,7 @@ components:
responsible to prepare and bring the item to the camp.
example: /material_lists/1a2b3c4d
format: iri-reference
- type:
- - 'null'
- - string
+ type: string
materialNode:
description: 'The content node to which this item belongs, if it does not belong to a period.'
example: /content_node/material_nodes/1a2b3c4d
@@ -13152,13 +13076,6 @@ components:
example: Volleyball
maxLength: 64
type: string
- camp:
- example: 'https://example.com/'
- format: iri-reference
- readOnly: true
- type:
- - 'null'
- - string
id:
description: 'An internal, unique, randomly generated identifier of this entity.'
example: 1a2b3c4d
@@ -13171,9 +13088,7 @@ components:
responsible to prepare and bring the item to the camp.
example: /material_lists/1a2b3c4d
format: iri-reference
- type:
- - 'null'
- - string
+ type: string
materialNode:
description: 'The content node to which this item belongs, if it does not belong to a period.'
example: /content_node/material_nodes/1a2b3c4d
@@ -13206,7 +13121,7 @@ components:
- article
- materialList
type: object
- MaterialItem.jsonld-write_create:
+ MaterialItem.jsonld-write:
deprecated: false
description: 'A physical item that is needed for carrying out a programme or camp.'
properties:
@@ -13221,9 +13136,7 @@ components:
responsible to prepare and bring the item to the camp.
example: /material_lists/1a2b3c4d
format: iri-reference
- type:
- - 'null'
- - string
+ type: string
materialNode:
description: 'The content node to which this item belongs, if it does not belong to a period.'
example: /content_node/material_nodes/1a2b3c4d
@@ -30773,19 +30686,19 @@ paths:
content:
application/hal+json:
schema:
- $ref: '#/components/schemas/MaterialItem.jsonhal-write_create'
+ $ref: '#/components/schemas/MaterialItem.jsonhal-write'
application/json:
schema:
- $ref: '#/components/schemas/MaterialItem-write_create'
+ $ref: '#/components/schemas/MaterialItem-write'
application/ld+json:
schema:
- $ref: '#/components/schemas/MaterialItem.jsonld-write_create'
+ $ref: '#/components/schemas/MaterialItem.jsonld-write'
application/vnd.api+json:
schema:
$ref: '#/components/schemas/MaterialItem.jsonapi'
text/html:
schema:
- $ref: '#/components/schemas/MaterialItem-write_create'
+ $ref: '#/components/schemas/MaterialItem-write'
description: 'The new MaterialItem resource'
required: true
responses:
diff --git a/api/tests/Api/SnapshotTests/__snapshots__/test_EndpointPerformanceTest__testPerformanceDidNotChangeForStableEndpoints__1.yml b/api/tests/Api/SnapshotTests/__snapshots__/test_EndpointPerformanceTest__testPerformanceDidNotChangeForStableEndpoints__1.yml
index af819ecde2..a36a795d0c 100644
--- a/api/tests/Api/SnapshotTests/__snapshots__/test_EndpointPerformanceTest__testPerformanceDidNotChangeForStableEndpoints__1.yml
+++ b/api/tests/Api/SnapshotTests/__snapshots__/test_EndpointPerformanceTest__testPerformanceDidNotChangeForStableEndpoints__1.yml
@@ -1,5 +1,5 @@
/activities: 21
-/activities/item: 38
+/activities/item: 37
/activity_progress_labels: 6
/activity_progress_labels/item: 7
/activity_responsibles: 6
@@ -20,8 +20,8 @@
/days/item: 12
/day_responsibles: 6
/day_responsibles/item: 9
-/material_items: 9
-/material_items/item: 11
+/material_items: 7
+/material_items/item: 9
/material_lists: 6
/material_lists/item: 7
/periods: 6
@@ -39,9 +39,9 @@
'/categories?camp=': 9
'/content_types?categories=': 6
'/day_responsibles?day.period=': 6
-'/material_items?materialList=': 9
-'/material_items?materialNode=': 9
-'/material_items?period=': 10
+'/material_items?materialList=': 7
+'/material_items?materialNode=': 7
+'/material_items?period=': 8
'/material_lists?camp=': 6
'/profiles?user.collaboration.camp=': 6
'/schedule_entries?period=': 13
diff --git a/api/tests/Entity/CampTest.php b/api/tests/Entity/CampTest.php
index 8909dee23b..b228b48fcf 100644
--- a/api/tests/Entity/CampTest.php
+++ b/api/tests/Entity/CampTest.php
@@ -55,7 +55,7 @@ public function setUp(): void {
public function testCopyFromPrototype() {
$camp = new Camp();
- $camp->copyFromPrototype($this->campPrototype, new EntityMap($camp));
+ $camp->copyFromPrototype($this->campPrototype, new EntityMap());
$this->assertEquals($this->campPrototype->getId(), $camp->campPrototypeId);
diff --git a/api/tests/Security/Voter/CampIsPrototypeVoterTest.php b/api/tests/Security/Voter/CampIsPrototypeVoterTest.php
index 1ab66746d4..529fd767e8 100644
--- a/api/tests/Security/Voter/CampIsPrototypeVoterTest.php
+++ b/api/tests/Security/Voter/CampIsPrototypeVoterTest.php
@@ -4,7 +4,6 @@
use App\Entity\Activity;
use App\Entity\BaseEntity;
-use App\Entity\BelongsToContentNodeTreeInterface;
use App\Entity\Camp;
use App\Entity\ContentNode\ColumnLayout;
use App\Entity\Period;
@@ -123,9 +122,8 @@ public function testGrantsAccessViaBelongsToContentNodeTreeInterface() {
$camp->isPrototype = true;
$activity = $this->createMock(Activity::class);
$activity->method('getCamp')->willReturn($camp);
- $root = $this->createMock(ColumnLayout::class);
- $subject = $this->createMock(ContentNodeTreeDummy1::class);
- $subject->method('getRoot')->willReturn($root);
+ $subject = $this->createMock(ColumnLayout::class);
+ $subject->method('getRoot')->willReturn($subject);
$repository = $this->createMock(EntityRepository::class);
$this->em->method('getRepository')->willReturn($repository);
$repository->method('findOneBy')->willReturn($activity);
@@ -139,9 +137,3 @@ public function testGrantsAccessViaBelongsToContentNodeTreeInterface() {
}
class CampIsPrototypeVoterTestDummy extends BaseEntity {}
-
-class ContentNodeTreeDummy1 implements BelongsToContentNodeTreeInterface {
- public function getRoot(): ?ColumnLayout {
- return null;
- }
-}
diff --git a/api/tests/Security/Voter/CampRoleVoterTest.php b/api/tests/Security/Voter/CampRoleVoterTest.php
index 21a2660b92..4b5fa5eedf 100644
--- a/api/tests/Security/Voter/CampRoleVoterTest.php
+++ b/api/tests/Security/Voter/CampRoleVoterTest.php
@@ -4,7 +4,6 @@
use App\Entity\Activity;
use App\Entity\BaseEntity;
-use App\Entity\BelongsToContentNodeTreeInterface;
use App\Entity\Camp;
use App\Entity\CampCollaboration;
use App\Entity\ContentNode\ColumnLayout;
@@ -251,9 +250,8 @@ public function testGrantsAccessViaBelongsToContentNodeTreeInterface() {
$camp->collaborations->add($collaboration);
$activity = $this->createMock(Activity::class);
$activity->method('getCamp')->willReturn($camp);
- $root = $this->createMock(ColumnLayout::class);
- $subject = $this->createMock(ContentNodeTreeDummy2::class);
- $subject->method('getRoot')->willReturn($root);
+ $subject = $this->createMock(ColumnLayout::class);
+ $subject->method('getRoot')->willReturn($subject);
$repository = $this->createMock(EntityRepository::class);
$this->em->method('getRepository')->willReturn($repository);
$repository->method('findOneBy')->willReturn($activity);
@@ -267,9 +265,3 @@ public function testGrantsAccessViaBelongsToContentNodeTreeInterface() {
}
class CampRoleVoterTestDummy extends BaseEntity {}
-
-class ContentNodeTreeDummy2 implements BelongsToContentNodeTreeInterface {
- public function getRoot(): ?ColumnLayout {
- return null;
- }
-}
diff --git a/frontend/src/components/material/DialogMaterialItemEdit.vue b/frontend/src/components/material/DialogMaterialItemEdit.vue
index c47530a7fd..9cca2132f5 100644
--- a/frontend/src/components/material/DialogMaterialItemEdit.vue
+++ b/frontend/src/components/material/DialogMaterialItemEdit.vue
@@ -56,7 +56,7 @@ export default {
return this.api.get(this.materialItemUri)
},
camp() {
- return this.materialItem.camp()
+ return this.materialItem.materialList().camp()
},
},
watch: {
diff --git a/frontend/src/components/material/MaterialTable.vue b/frontend/src/components/material/MaterialTable.vue
index a14cba7a30..632ab8ed32 100644
--- a/frontend/src/components/material/MaterialTable.vue
+++ b/frontend/src/components/material/MaterialTable.vue
@@ -349,7 +349,7 @@ export default {
unit: item.unit,
combinedQuantity: this.renderQuantity(item),
article: item.article,
- listName: item.materialList ? item.materialList()?.name : '',
+ listName: item.materialList().name,
entityObject: item,
readonly: this.disabled || (this.period && item.materialNode), // if complete component is in period overview, disable editing of material that belongs to materialNodes (Activity material)
rowClass: 'readonly',
diff --git a/pdf/src/campPrint/scheduleEntry/contentNode/Material.vue b/pdf/src/campPrint/scheduleEntry/contentNode/Material.vue
index 0dd0f5ddbd..e0dbb15909 100644
--- a/pdf/src/campPrint/scheduleEntry/contentNode/Material.vue
+++ b/pdf/src/campPrint/scheduleEntry/contentNode/Material.vue
@@ -6,7 +6,7 @@