feat(skeleton) : expose skeleton relations via API and create SkeletonStructureService

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Matthieu
2026-03-12 17:58:18 +01:00
parent 100e24725c
commit e2326064ba
2 changed files with 106 additions and 3 deletions

View File

@@ -271,9 +271,9 @@ class ModelType
public function getStructure(): ?array
{
return match ($this->category) {
ModelCategory::COMPONENT => $this->componentSkeleton,
ModelCategory::PIECE => $this->pieceSkeleton,
ModelCategory::PRODUCT => $this->productSkeleton,
ModelCategory::COMPONENT => $this->getComponentStructureFromRelations(),
ModelCategory::PIECE => $this->getPieceStructureFromRelations(),
ModelCategory::PRODUCT => ['customFields' => []],
};
}
@@ -390,6 +390,45 @@ class ModelType
return $this;
}
private function getComponentStructureFromRelations(): array
{
$structure = ['customFields' => [], 'pieces' => [], 'products' => [], 'subcomponents' => []];
foreach ($this->skeletonPieceRequirements as $req) {
$structure['pieces'][] = [
'typePieceId' => $req->getTypePiece()->getId(),
];
}
foreach ($this->skeletonProductRequirements as $req) {
$structure['products'][] = [
'typeProductId' => $req->getTypeProduct()->getId(),
'familyCode' => $req->getFamilyCode(),
];
}
foreach ($this->skeletonSubcomponentRequirements as $req) {
$structure['subcomponents'][] = [
'alias' => $req->getAlias(),
'familyCode' => $req->getFamilyCode(),
'typeComposantId' => $req->getTypeComposant()?->getId(),
];
}
return $structure;
}
private function getPieceStructureFromRelations(): array
{
return [
'customFields' => [],
'products' => array_map(fn (SkeletonProductRequirement $req) => [
'typeProductId' => $req->getTypeProduct()->getId(),
'familyCode' => $req->getFamilyCode(),
], $this->skeletonProductRequirements->toArray()),
];
}
private function applyStructureForCategory(?array $structure, ModelCategory $category): void
{
if (ModelCategory::COMPONENT === $category) {

View File

@@ -0,0 +1,64 @@
<?php
declare(strict_types=1);
namespace App\Service;
use App\Entity\ModelType;
use App\Entity\SkeletonPieceRequirement;
use App\Entity\SkeletonProductRequirement;
use App\Entity\SkeletonSubcomponentRequirement;
use Doctrine\ORM\EntityManagerInterface;
class SkeletonStructureService
{
public function __construct(private EntityManagerInterface $em) {}
public function updateSkeletonRequirements(ModelType $modelType, array $structure): void
{
// Clear existing requirements
foreach ($modelType->getSkeletonPieceRequirements() as $req) {
$modelType->removeSkeletonPieceRequirement($req);
}
foreach ($modelType->getSkeletonProductRequirements() as $req) {
$modelType->removeSkeletonProductRequirement($req);
}
foreach ($modelType->getSkeletonSubcomponentRequirements() as $req) {
$modelType->removeSkeletonSubcomponentRequirement($req);
}
// Create piece requirements
foreach (($structure['pieces'] ?? []) as $i => $pieceData) {
$req = new SkeletonPieceRequirement();
$req->setModelType($modelType);
$req->setTypePiece($this->em->getReference(ModelType::class, $pieceData['typePieceId']));
$req->setPosition($i);
$modelType->addSkeletonPieceRequirement($req);
}
// Create product requirements (shared by component + piece types)
foreach (($structure['products'] ?? []) as $i => $prodData) {
$req = new SkeletonProductRequirement();
$req->setModelType($modelType);
$req->setTypeProduct($this->em->getReference(ModelType::class, $prodData['typeProductId']));
$req->setFamilyCode($prodData['familyCode'] ?? null);
$req->setPosition($i);
$modelType->addSkeletonProductRequirement($req);
}
// Create subcomponent requirements (component types only)
foreach (($structure['subcomponents'] ?? []) as $i => $subData) {
$req = new SkeletonSubcomponentRequirement();
$req->setModelType($modelType);
$req->setAlias($subData['alias'] ?? '');
$req->setFamilyCode($subData['familyCode'] ?? '');
if (!empty($subData['typeComposantId'])) {
$req->setTypeComposant($this->em->getReference(ModelType::class, $subData['typeComposantId']));
}
$req->setPosition($i);
$modelType->addSkeletonSubcomponentRequirement($req);
}
}
}