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 @@ {{ item.quantity }} {{ item.unit }} {{ item.article }} - {{ item.materialList ? item.materialList()?.name : '' }} + {{ item.materialList().name }} @@ -25,8 +25,9 @@ export default { }, computed: { sortedMaterialItems() { - return sortBy(this.contentNode.materialItems().items, (item) => - item.materialList ? item.materialList()?.name : '' + return sortBy( + this.contentNode.materialItems().items, + (item) => item.materialList().name ) }, }, diff --git a/print/components/scheduleEntry/contentNode/Material.vue b/print/components/scheduleEntry/contentNode/Material.vue index bf3b524af1..3668f2a51a 100644 --- a/print/components/scheduleEntry/contentNode/Material.vue +++ b/print/components/scheduleEntry/contentNode/Material.vue @@ -11,7 +11,7 @@ {{ item.article }} - {{ item.materialList ? item.materialList()?.name : '' }} + {{ item.materialList().name }}