diff --git a/CHANGELOG.md b/CHANGELOG.md index cd6ddd7..5a154b5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,22 @@ # Changelog +## [1.8.1] - 2026-03-05 + +### Refactoring +- **Suppression du systeme TypeMachine (squelettes machines)** : les entites `TypeMachine`, `TypeMachineComponentRequirement`, `TypeMachinePieceRequirement`, `TypeMachineProductRequirement` sont supprimees. Les champs personnalises machines sont desormais lies directement a chaque machine (relation `CustomField → Machine`). +- **Suppression des pages squelettes machines** : pages `/machine-skeleton`, `/type/[id]`, `/type/edit/[id]` et tous les composants associes (`TypeEditForm`, `MachineSkeletonSummary`, `MachineCreatePreview`, selectors de requirements). +- **Simplification de la creation de machines** : plus besoin de selectionner un squelette, ajout direct de composants/pieces/produits. + +### Corrections +- **Fix affichage categorie sur les pages edit** : les categories (produit, composant, piece) s'affichent correctement sur les pages d'edition au lieu de "Categorie inconnue". Cause : import `Serializer\Annotation\Groups` obsolete dans `ModelType` (remplace par `Attribute\Groups` pour Symfony 8) + groupes de serialisation manquants (`product:read`, `composant:read`, `piece:read`). +- Fix import `Serializer\Annotation\Groups` → `Attribute\Groups` dans `Profile`. +- Fix filtre `SearchFilter` : `partial` → `ipartial` sur `Comment.entityName` et `Document.name`/`Document.filename` pour recherche insensible a la casse. + +### Migration requise +```bash +docker compose exec web php bin/console doctrine:migrations:migrate +``` + ## [1.8.0] - 2026-03-03 ### Ajouts diff --git a/Inventory_frontend b/Inventory_frontend index 6f1bac3..32d03b4 160000 --- a/Inventory_frontend +++ b/Inventory_frontend @@ -1 +1 @@ -Subproject commit 6f1bac381d65f1dbe228c1055bf922154c4e95d3 +Subproject commit 32d03b480de9af3cdebc6b23053e8f863184540d diff --git a/migrations/Version20260304120000.php b/migrations/Version20260304120000.php new file mode 100644 index 0000000..25fa65c --- /dev/null +++ b/migrations/Version20260304120000.php @@ -0,0 +1,158 @@ +addSql('ALTER TABLE machine_component_links DROP COLUMN IF EXISTS typemachinecomponentrequirementid'); + $this->addSql('ALTER TABLE machine_piece_links DROP COLUMN IF EXISTS typemachinepiecerequirementid'); + $this->addSql('ALTER TABLE machine_product_links DROP COLUMN IF EXISTS typemachineproductrequirementid'); + + // 2. Add machineid column to custom_fields (new direct FK to machines) + $this->addSql('ALTER TABLE custom_fields ADD COLUMN IF NOT EXISTS machineid VARCHAR(36) DEFAULT NULL'); + $this->addSql(<<<'SQL' + DO $$ BEGIN + IF NOT EXISTS ( + SELECT 1 FROM information_schema.table_constraints + WHERE constraint_name = 'fk_custom_fields_machine' AND table_name = 'custom_fields' + ) THEN + ALTER TABLE custom_fields ADD CONSTRAINT fk_custom_fields_machine + FOREIGN KEY (machineid) REFERENCES machines(id) ON DELETE CASCADE; + END IF; + END $$; + SQL); + + // 3. Enable pgcrypto for gen_random_bytes (needed for CUID generation) + $this->addSql('CREATE EXTENSION IF NOT EXISTS pgcrypto'); + + // 4. Migrate existing custom fields: copy from TypeMachine to each linked Machine + $this->addSql(<<<'SQL' + INSERT INTO custom_fields (id, name, type, required, defaultvalue, options, orderindex, machineid, createdat, updatedat) + SELECT + 'cl' || encode(gen_random_bytes(12), 'hex'), + cf.name, cf.type, cf.required, cf.defaultvalue, cf.options, cf.orderindex, + m.id, + NOW(), NOW() + FROM custom_fields cf + JOIN machines m ON m.typemachineid = cf.typemachineid + WHERE cf.typemachineid IS NOT NULL + AND NOT EXISTS ( + SELECT 1 FROM custom_fields existing + WHERE existing.machineid = m.id AND existing.name = cf.name + ) + SQL); + + // 4. Delete original TypeMachine-linked custom fields (now migrated) + $this->addSql('DELETE FROM custom_fields WHERE typemachineid IS NOT NULL'); + + // 5. Drop typemachineid column from custom_fields + $this->addSql('ALTER TABLE custom_fields DROP COLUMN IF EXISTS typemachineid'); + + // 6. Drop typemachineid column from machines + $this->addSql('ALTER TABLE machines DROP COLUMN IF EXISTS typemachineid'); + + // 7. Drop requirement tables (order matters: these reference type_machines) + $this->addSql('DROP TABLE IF EXISTS type_machine_component_requirements'); + $this->addSql('DROP TABLE IF EXISTS type_machine_piece_requirements'); + $this->addSql('DROP TABLE IF EXISTS type_machine_product_requirements'); + + // 8. Drop type_machines table + $this->addSql('DROP TABLE IF EXISTS type_machines'); + } + + public function down(Schema $schema): void + { + // Recreate type_machines table + $this->addSql(<<<'SQL' + CREATE TABLE IF NOT EXISTS type_machines ( + id VARCHAR(36) NOT NULL PRIMARY KEY, + name VARCHAR(255) NOT NULL UNIQUE, + description TEXT DEFAULT NULL, + category VARCHAR(255) DEFAULT NULL, + maintenancefrequency VARCHAR(255) DEFAULT NULL, + components JSON DEFAULT NULL, + criticalparts JSON DEFAULT NULL, + machinepieces JSON DEFAULT NULL, + specifications JSON DEFAULT NULL, + createdat TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL, + updatedat TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL + ) + SQL); + + // Recreate requirement tables + $this->addSql(<<<'SQL' + CREATE TABLE IF NOT EXISTS type_machine_component_requirements ( + id VARCHAR(36) NOT NULL PRIMARY KEY, + typemachineid VARCHAR(36) NOT NULL REFERENCES type_machines(id) ON DELETE CASCADE, + typecomposantid VARCHAR(36) NOT NULL REFERENCES model_types(id), + label VARCHAR(255) DEFAULT NULL, + mincount INTEGER DEFAULT 1, + maxcount INTEGER DEFAULT NULL, + required BOOLEAN DEFAULT true, + allownewmodels BOOLEAN DEFAULT true, + orderindex INTEGER DEFAULT 0, + createdat TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL, + updatedat TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL + ) + SQL); + + $this->addSql(<<<'SQL' + CREATE TABLE IF NOT EXISTS type_machine_piece_requirements ( + id VARCHAR(36) NOT NULL PRIMARY KEY, + typemachineid VARCHAR(36) NOT NULL REFERENCES type_machines(id) ON DELETE CASCADE, + typepieceid VARCHAR(36) NOT NULL REFERENCES model_types(id), + label VARCHAR(255) DEFAULT NULL, + mincount INTEGER DEFAULT 0, + maxcount INTEGER DEFAULT NULL, + required BOOLEAN DEFAULT false, + allownewmodels BOOLEAN DEFAULT true, + orderindex INTEGER DEFAULT 0, + createdat TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL, + updatedat TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL + ) + SQL); + + $this->addSql(<<<'SQL' + CREATE TABLE IF NOT EXISTS type_machine_product_requirements ( + id VARCHAR(36) NOT NULL PRIMARY KEY, + typemachineid VARCHAR(36) NOT NULL REFERENCES type_machines(id) ON DELETE CASCADE, + typeproductid VARCHAR(36) NOT NULL REFERENCES model_types(id), + label VARCHAR(255) DEFAULT NULL, + mincount INTEGER DEFAULT 0, + maxcount INTEGER DEFAULT NULL, + required BOOLEAN DEFAULT false, + allownewmodels BOOLEAN DEFAULT true, + orderindex INTEGER DEFAULT 0, + createdat TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL, + updatedat TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL + ) + SQL); + + // Re-add typemachineid to machines + $this->addSql('ALTER TABLE machines ADD COLUMN IF NOT EXISTS typemachineid VARCHAR(36) DEFAULT NULL'); + + // Re-add typemachineid to custom_fields + $this->addSql('ALTER TABLE custom_fields ADD COLUMN IF NOT EXISTS typemachineid VARCHAR(36) DEFAULT NULL'); + + // Re-add requirement FK columns to link tables + $this->addSql('ALTER TABLE machine_component_links ADD COLUMN IF NOT EXISTS typemachinecomponentrequirementid VARCHAR(36) DEFAULT NULL'); + $this->addSql('ALTER TABLE machine_piece_links ADD COLUMN IF NOT EXISTS typemachinepiecerequirementid VARCHAR(36) DEFAULT NULL'); + $this->addSql('ALTER TABLE machine_product_links ADD COLUMN IF NOT EXISTS typemachineproductrequirementid VARCHAR(36) DEFAULT NULL'); + + // Drop machine FK on custom_fields + $this->addSql('ALTER TABLE custom_fields DROP COLUMN IF EXISTS machineid'); + } +} diff --git a/src/Controller/MachineCustomFieldsController.php b/src/Controller/MachineCustomFieldsController.php index 39303d3..9b25032 100644 --- a/src/Controller/MachineCustomFieldsController.php +++ b/src/Controller/MachineCustomFieldsController.php @@ -33,12 +33,7 @@ class MachineCustomFieldsController extends AbstractController return $this->json(['success' => false, 'error' => 'Machine not found.'], 404); } - $typeMachine = $machine->getTypeMachine(); - if (!$typeMachine) { - return $this->json(['success' => true, 'machineId' => $machine->getId(), 'customFieldValues' => []]); - } - - foreach ($typeMachine->getCustomFields() as $customField) { + foreach ($machine->getCustomFields() as $customField) { if (!$customField instanceof CustomField) { continue; } diff --git a/src/Controller/MachineSkeletonController.php b/src/Controller/MachineStructureController.php similarity index 59% rename from src/Controller/MachineSkeletonController.php rename to src/Controller/MachineStructureController.php index 027aeeb..d046a06 100644 --- a/src/Controller/MachineSkeletonController.php +++ b/src/Controller/MachineStructureController.php @@ -6,6 +6,7 @@ namespace App\Controller; use App\Entity\Composant; use App\Entity\CustomField; +use App\Entity\CustomFieldValue; use App\Entity\Machine; use App\Entity\MachineComponentLink; use App\Entity\MachinePieceLink; @@ -13,9 +14,6 @@ use App\Entity\MachineProductLink; use App\Entity\ModelType; use App\Entity\Piece; use App\Entity\Product; -use App\Entity\TypeMachineComponentRequirement; -use App\Entity\TypeMachinePieceRequirement; -use App\Entity\TypeMachineProductRequirement; use App\Repository\ComposantRepository; use App\Repository\MachineComponentLinkRepository; use App\Repository\MachinePieceLinkRepository; @@ -23,9 +21,6 @@ use App\Repository\MachineProductLinkRepository; use App\Repository\MachineRepository; use App\Repository\PieceRepository; use App\Repository\ProductRepository; -use App\Repository\TypeMachineComponentRequirementRepository; -use App\Repository\TypeMachinePieceRequirementRepository; -use App\Repository\TypeMachineProductRequirementRepository; use Doctrine\Common\Collections\Collection; use Doctrine\ORM\EntityManagerInterface; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; @@ -34,7 +29,7 @@ use Symfony\Component\HttpFoundation\Request; use Symfony\Component\Routing\Attribute\Route; #[Route('/api/machines')] -class MachineSkeletonController extends AbstractController +class MachineStructureController extends AbstractController { public function __construct( private readonly EntityManagerInterface $entityManager, @@ -45,13 +40,10 @@ class MachineSkeletonController extends AbstractController private readonly ComposantRepository $composantRepository, private readonly PieceRepository $pieceRepository, private readonly ProductRepository $productRepository, - private readonly TypeMachineComponentRequirementRepository $componentRequirementRepository, - private readonly TypeMachinePieceRequirementRepository $pieceRequirementRepository, - private readonly TypeMachineProductRequirementRepository $productRequirementRepository, ) {} - #[Route('/{id}/skeleton', name: 'machine_skeleton_get', methods: ['GET'])] - public function getSkeleton(string $id): JsonResponse + #[Route('/{id}/structure', name: 'machine_structure_get', methods: ['GET'])] + public function getStructure(string $id): JsonResponse { $this->denyAccessUnlessGranted('ROLE_VIEWER'); @@ -64,7 +56,7 @@ class MachineSkeletonController extends AbstractController $pieceLinks = $this->machinePieceLinkRepository->findBy(['machine' => $machine]); $productLinks = $this->machineProductLinkRepository->findBy(['machine' => $machine]); - return $this->json($this->normalizeMachineSkeletonResponse( + return $this->json($this->normalizeStructureResponse( $machine, $componentLinks, $pieceLinks, @@ -72,8 +64,8 @@ class MachineSkeletonController extends AbstractController )); } - #[Route('/{id}/skeleton', name: 'machine_skeleton_update', methods: ['PATCH'])] - public function updateSkeleton(string $id, Request $request): JsonResponse + #[Route('/{id}/structure', name: 'machine_structure_update', methods: ['PATCH'])] + public function updateStructure(string $id, Request $request): JsonResponse { $this->denyAccessUnlessGranted('ROLE_GESTIONNAIRE'); @@ -108,7 +100,7 @@ class MachineSkeletonController extends AbstractController $this->entityManager->flush(); - return $this->json($this->normalizeMachineSkeletonResponse( + return $this->json($this->normalizeStructureResponse( $machine, $componentLinks, $pieceLinks, @@ -116,6 +108,194 @@ class MachineSkeletonController extends AbstractController )); } + #[Route('/{id}/clone', name: 'machine_clone', methods: ['POST'])] + public function cloneMachine(string $id, Request $request): JsonResponse + { + $this->denyAccessUnlessGranted('ROLE_GESTIONNAIRE'); + + $source = $this->machineRepository->find($id); + if (!$source instanceof Machine) { + return $this->json(['success' => false, 'error' => 'Machine source introuvable.'], 404); + } + + $payload = json_decode($request->getContent(), true); + if (!is_array($payload) || empty($payload['name']) || empty($payload['siteId'])) { + return $this->json(['success' => false, 'error' => 'name et siteId sont requis.'], 400); + } + + $site = $this->entityManager->getRepository(\App\Entity\Site::class)->find($payload['siteId']); + if (!$site) { + return $this->json(['success' => false, 'error' => 'Site introuvable.'], 404); + } + + // Create new machine + $newMachine = new Machine(); + $newMachine->setName($payload['name']); + $newMachine->setSite($site); + if (!empty($payload['reference'])) { + $newMachine->setReference($payload['reference']); + } + $newMachine->setPrix($source->getPrix()); + + // Copy constructeurs + foreach ($source->getConstructeurs() as $constructeur) { + $newMachine->getConstructeurs()->add($constructeur); + } + + $this->entityManager->persist($newMachine); + + // Copy custom fields and values + $this->cloneCustomFields($source, $newMachine); + + // Copy component links (preserving hierarchy) + $componentLinkMap = $this->cloneComponentLinks($source, $newMachine); + + // Copy piece links + $pieceLinkMap = $this->clonePieceLinks($source, $newMachine, $componentLinkMap); + + // Copy product links + $this->cloneProductLinks($source, $newMachine, $componentLinkMap, $pieceLinkMap); + + $this->entityManager->flush(); + + $componentLinks = $this->machineComponentLinkRepository->findBy(['machine' => $newMachine]); + $pieceLinks = $this->machinePieceLinkRepository->findBy(['machine' => $newMachine]); + $productLinks = $this->machineProductLinkRepository->findBy(['machine' => $newMachine]); + + return $this->json($this->normalizeStructureResponse( + $newMachine, + $componentLinks, + $pieceLinks, + $productLinks + ), 201); + } + + private function cloneCustomFields(Machine $source, Machine $target): void + { + foreach ($source->getCustomFields() as $cf) { + $newCf = new CustomField(); + $newCf->setName($cf->getName()); + $newCf->setType($cf->getType()); + $newCf->setRequired($cf->isRequired()); + $newCf->setDefaultValue($cf->getDefaultValue()); + $newCf->setOptions($cf->getOptions()); + $newCf->setOrderIndex($cf->getOrderIndex()); + $newCf->setMachine($target); + $this->entityManager->persist($newCf); + } + + foreach ($source->getCustomFieldValues() as $cfv) { + $newValue = new CustomFieldValue(); + $newValue->setMachine($target); + $newValue->setCustomField($cfv->getCustomField()); + $newValue->setValue($cfv->getValue()); + $this->entityManager->persist($newValue); + } + } + + /** + * @return array Map of old link ID → new link + */ + private function cloneComponentLinks(Machine $source, Machine $target): array + { + $sourceLinks = $this->machineComponentLinkRepository->findBy(['machine' => $source]); + $linkMap = []; + + // First pass: create all links without parent relationships + foreach ($sourceLinks as $link) { + $newLink = new MachineComponentLink(); + $newLink->setMachine($target); + $newLink->setComposant($link->getComposant()); + $newLink->setNameOverride($link->getNameOverride()); + $newLink->setReferenceOverride($link->getReferenceOverride()); + $newLink->setPrixOverride($link->getPrixOverride()); + $this->entityManager->persist($newLink); + $linkMap[$link->getId()] = $newLink; + } + + // Second pass: set parent relationships + foreach ($sourceLinks as $link) { + $parent = $link->getParentLink(); + if ($parent && isset($linkMap[$parent->getId()])) { + $linkMap[$link->getId()]->setParentLink($linkMap[$parent->getId()]); + } + } + + return $linkMap; + } + + /** + * @param array $componentLinkMap + * + * @return array Map of old link ID → new link + */ + private function clonePieceLinks(Machine $source, Machine $target, array $componentLinkMap): array + { + $sourceLinks = $this->machinePieceLinkRepository->findBy(['machine' => $source]); + $linkMap = []; + + foreach ($sourceLinks as $link) { + $newLink = new MachinePieceLink(); + $newLink->setMachine($target); + $newLink->setPiece($link->getPiece()); + $newLink->setNameOverride($link->getNameOverride()); + $newLink->setReferenceOverride($link->getReferenceOverride()); + $newLink->setPrixOverride($link->getPrixOverride()); + + $parent = $link->getParentLink(); + if ($parent && isset($componentLinkMap[$parent->getId()])) { + $newLink->setParentLink($componentLinkMap[$parent->getId()]); + } + + $this->entityManager->persist($newLink); + $linkMap[$link->getId()] = $newLink; + } + + return $linkMap; + } + + /** + * @param array $componentLinkMap + * @param array $pieceLinkMap + */ + private function cloneProductLinks( + Machine $source, + Machine $target, + array $componentLinkMap, + array $pieceLinkMap, + ): void { + $sourceLinks = $this->machineProductLinkRepository->findBy(['machine' => $source]); + $linkMap = []; + + // First pass: create all links + foreach ($sourceLinks as $link) { + $newLink = new MachineProductLink(); + $newLink->setMachine($target); + $newLink->setProduct($link->getProduct()); + + $parentComponent = $link->getParentComponentLink(); + if ($parentComponent && isset($componentLinkMap[$parentComponent->getId()])) { + $newLink->setParentComponentLink($componentLinkMap[$parentComponent->getId()]); + } + + $parentPiece = $link->getParentPieceLink(); + if ($parentPiece && isset($pieceLinkMap[$parentPiece->getId()])) { + $newLink->setParentPieceLink($pieceLinkMap[$parentPiece->getId()]); + } + + $this->entityManager->persist($newLink); + $linkMap[$link->getId()] = $newLink; + } + + // Second pass: set parent product link relationships + foreach ($sourceLinks as $link) { + $parent = $link->getParentLink(); + if ($parent && isset($linkMap[$parent->getId()])) { + $linkMap[$link->getId()]->setParentLink($linkMap[$parent->getId()]); + } + } + } + private function normalizePayloadList(mixed $value): array { if (!is_array($value)) { @@ -144,7 +324,7 @@ class MachineSkeletonController extends AbstractController $composantId = $this->resolveIdentifier($entry, ['composantId', 'componentId', 'idComposant']); if (!$composantId) { - return $this->json(['success' => false, 'error' => 'Composant requis pour le squelette.'], 400); + return $this->json(['success' => false, 'error' => 'Composant requis.'], 400); } $composant = $this->composantRepository->find($composantId); if (!$composant instanceof Composant) { @@ -154,14 +334,6 @@ class MachineSkeletonController extends AbstractController $link->setMachine($machine); $link->setComposant($composant); - $requirementId = $this->resolveIdentifier($entry, ['requirementId', 'typeMachineComponentRequirementId']); - if ($requirementId) { - $requirement = $this->componentRequirementRepository->find($requirementId); - if ($requirement instanceof TypeMachineComponentRequirement) { - $link->setTypeMachineComponentRequirement($requirement); - } - } - $this->applyOverrides($link, $entry['overrides'] ?? null); $pendingParents[$linkId] = $this->resolveIdentifier($entry, [ @@ -176,10 +348,7 @@ class MachineSkeletonController extends AbstractController } foreach ($pendingParents as $linkId => $parentId) { - if (!$parentId) { - continue; - } - if (!isset($links[$linkId])) { + if (!$parentId || !isset($links[$linkId])) { continue; } $parent = $links[$parentId] ?? $existing[$parentId] ?? null; @@ -213,7 +382,7 @@ class MachineSkeletonController extends AbstractController $pieceId = $this->resolveIdentifier($entry, ['pieceId']); if (!$pieceId) { - return $this->json(['success' => false, 'error' => 'Pièce requise pour le squelette.'], 400); + return $this->json(['success' => false, 'error' => 'Pièce requise.'], 400); } $piece = $this->pieceRepository->find($pieceId); if (!$piece instanceof Piece) { @@ -223,14 +392,6 @@ class MachineSkeletonController extends AbstractController $link->setMachine($machine); $link->setPiece($piece); - $requirementId = $this->resolveIdentifier($entry, ['requirementId', 'typeMachinePieceRequirementId']); - if ($requirementId) { - $requirement = $this->pieceRequirementRepository->find($requirementId); - if ($requirement instanceof TypeMachinePieceRequirement) { - $link->setTypeMachinePieceRequirement($requirement); - } - } - $this->applyOverrides($link, $entry['overrides'] ?? null); $pendingParents[$linkId] = $this->resolveIdentifier($entry, [ @@ -245,10 +406,7 @@ class MachineSkeletonController extends AbstractController } foreach ($pendingParents as $linkId => $parentId) { - if (!$parentId) { - continue; - } - if (!isset($links[$linkId])) { + if (!$parentId || !isset($links[$linkId])) { continue; } $parent = $componentIndex[$parentId] ?? null; @@ -287,7 +445,7 @@ class MachineSkeletonController extends AbstractController $productId = $this->resolveIdentifier($entry, ['productId']); if (!$productId) { - return $this->json(['success' => false, 'error' => 'Produit requis pour le squelette.'], 400); + return $this->json(['success' => false, 'error' => 'Produit requis.'], 400); } $product = $this->productRepository->find($productId); if (!$product instanceof Product) { @@ -297,14 +455,6 @@ class MachineSkeletonController extends AbstractController $link->setMachine($machine); $link->setProduct($product); - $requirementId = $this->resolveIdentifier($entry, ['requirementId', 'typeMachineProductRequirementId']); - if ($requirementId) { - $requirement = $this->productRequirementRepository->find($requirementId); - if ($requirement instanceof TypeMachineProductRequirement) { - $link->setTypeMachineProductRequirement($requirement); - } - } - $pendingParents[$linkId] = [ 'parentComponentLinkId' => $this->resolveIdentifier($entry, ['parentComponentLinkId']), 'parentPieceLinkId' => $this->resolveIdentifier($entry, ['parentPieceLinkId']), @@ -336,7 +486,7 @@ class MachineSkeletonController extends AbstractController return array_values($links); } - private function normalizeMachineSkeletonResponse( + private function normalizeStructureResponse( Machine $machine, array $componentLinks, array $pieceLinks, @@ -346,7 +496,6 @@ class MachineSkeletonController extends AbstractController $componentIndex = $this->indexNormalizedLinks($normalizedComponentLinks); $normalizedPieceLinks = $this->normalizePieceLinks($pieceLinks); - // Build component hierarchy – track which IDs are children $childIds = []; foreach ($normalizedComponentLinks as $link) { $parentId = $link['parentComponentLinkId'] ?? null; @@ -356,10 +505,8 @@ class MachineSkeletonController extends AbstractController } } - // Add pieces to components recursively $this->attachPiecesToComponents($componentIndex, $normalizedPieceLinks); - // Only return root-level components (exclude children already nested) $rootComponents = array_filter( $componentIndex, static fn (array $link) => !isset($childIds[$link['id']]), @@ -382,7 +529,6 @@ class MachineSkeletonController extends AbstractController } } - // Recursively attach to child components foreach ($componentIndex as &$component) { if (!empty($component['childLinks'])) { $this->attachPiecesToChildComponents($component['childLinks'], $pieceLinks); @@ -403,7 +549,6 @@ class MachineSkeletonController extends AbstractController } } - // Recursively process nested children if (!empty($child['childLinks'])) { $this->attachPiecesToChildComponents($child['childLinks'], $pieceLinks); } @@ -412,8 +557,7 @@ class MachineSkeletonController extends AbstractController private function normalizeMachine(Machine $machine): array { - $site = $machine->getSite(); - $typeMachine = $machine->getTypeMachine(); + $site = $machine->getSite(); return [ 'id' => $machine->getId(), @@ -425,24 +569,8 @@ class MachineSkeletonController extends AbstractController 'id' => $site->getId(), 'name' => $site->getName(), ], - 'typeMachineId' => $typeMachine?->getId(), - 'typeMachine' => $typeMachine ? [ - 'id' => $typeMachine->getId(), - 'name' => $typeMachine->getName(), - 'category' => $typeMachine->getCategory(), - 'description' => $typeMachine->getDescription(), - 'customFields' => $this->normalizeCustomFields($typeMachine->getCustomFields()), - 'componentRequirements' => $typeMachine->getComponentRequirements() - ->map(fn (TypeMachineComponentRequirement $req) => $this->normalizeComponentRequirement($req)) - ->toArray(), - 'pieceRequirements' => $typeMachine->getPieceRequirements() - ->map(fn (TypeMachinePieceRequirement $req) => $this->normalizePieceRequirement($req)) - ->toArray(), - 'productRequirements' => $typeMachine->getProductRequirements() - ->map(fn (TypeMachineProductRequirement $req) => $this->normalizeProductRequirement($req)) - ->toArray(), - ] : null, 'constructeurs' => $this->normalizeConstructeurs($machine->getConstructeurs()), + 'customFields' => $this->normalizeCustomFields($machine->getCustomFields()), 'documents' => null, 'customFieldValues' => null, ]; @@ -472,26 +600,21 @@ class MachineSkeletonController extends AbstractController private function normalizeComponentLinks(array $links): array { return array_map(function (MachineComponentLink $link): array { - $composant = $link->getComposant(); - $requirement = $link->getTypeMachineComponentRequirement(); - $parentLink = $link->getParentLink(); - $parentRequirementId = $parentLink?->getTypeMachineComponentRequirement()?->getId(); + $composant = $link->getComposant(); + $parentLink = $link->getParentLink(); return [ - 'id' => $link->getId(), - 'linkId' => $link->getId(), - 'machineId' => $link->getMachine()->getId(), - 'composantId' => $composant->getId(), - 'composant' => $this->normalizeComposant($composant), - 'typeMachineComponentRequirementId' => $requirement?->getId(), - 'typeMachineComponentRequirement' => $requirement ? $this->normalizeComponentRequirement($requirement) : null, - 'parentLinkId' => $parentLink?->getId(), - 'parentComponentLinkId' => $parentLink?->getId(), - 'parentComponentId' => $parentLink?->getComposant()->getId(), - 'parentMachineComponentRequirementId' => $parentRequirementId, - 'overrides' => $this->normalizeOverrides($link), - 'childLinks' => [], - 'pieceLinks' => [], + 'id' => $link->getId(), + 'linkId' => $link->getId(), + 'machineId' => $link->getMachine()->getId(), + 'composantId' => $composant->getId(), + 'composant' => $this->normalizeComposant($composant), + 'parentLinkId' => $parentLink?->getId(), + 'parentComponentLinkId' => $parentLink?->getId(), + 'parentComponentId' => $parentLink?->getComposant()->getId(), + 'overrides' => $this->normalizeOverrides($link), + 'childLinks' => [], + 'pieceLinks' => [], ]; }, $links); } @@ -499,24 +622,19 @@ class MachineSkeletonController extends AbstractController private function normalizePieceLinks(array $links): array { return array_map(function (MachinePieceLink $link): array { - $piece = $link->getPiece(); - $requirement = $link->getTypeMachinePieceRequirement(); - $parentLink = $link->getParentLink(); - $parentRequirementId = $parentLink?->getTypeMachineComponentRequirement()?->getId(); + $piece = $link->getPiece(); + $parentLink = $link->getParentLink(); return [ - 'id' => $link->getId(), - 'linkId' => $link->getId(), - 'machineId' => $link->getMachine()->getId(), - 'pieceId' => $piece->getId(), - 'piece' => $this->normalizePiece($piece), - 'typeMachinePieceRequirementId' => $requirement?->getId(), - 'typeMachinePieceRequirement' => $requirement ? $this->normalizePieceRequirement($requirement) : null, - 'parentLinkId' => $parentLink?->getId(), - 'parentComponentLinkId' => $parentLink?->getId(), - 'parentComponentId' => $parentLink?->getComposant()->getId(), - 'parentMachineComponentRequirementId' => $parentRequirementId, - 'overrides' => $this->normalizeOverrides($link), + 'id' => $link->getId(), + 'linkId' => $link->getId(), + 'machineId' => $link->getMachine()->getId(), + 'pieceId' => $piece->getId(), + 'piece' => $this->normalizePiece($piece), + 'parentLinkId' => $parentLink?->getId(), + 'parentComponentLinkId' => $parentLink?->getId(), + 'parentComponentId' => $parentLink?->getComposant()->getId(), + 'overrides' => $this->normalizeOverrides($link), ]; }, $links); } @@ -524,55 +642,58 @@ class MachineSkeletonController extends AbstractController private function normalizeProductLinks(array $links): array { return array_map(function (MachineProductLink $link): array { - $product = $link->getProduct(); - $requirement = $link->getTypeMachineProductRequirement(); + $product = $link->getProduct(); return [ - 'id' => $link->getId(), - 'linkId' => $link->getId(), - 'machineId' => $link->getMachine()->getId(), - 'productId' => $product->getId(), - 'product' => $this->normalizeProduct($product), - 'typeMachineProductRequirementId' => $requirement?->getId(), - 'typeMachineProductRequirement' => $requirement ? $this->normalizeProductRequirement($requirement) : null, - 'parentLinkId' => $link->getParentLink()?->getId(), - 'parentComponentLinkId' => $link->getParentComponentLink()?->getId(), - 'parentPieceLinkId' => $link->getParentPieceLink()?->getId(), + 'id' => $link->getId(), + 'linkId' => $link->getId(), + 'machineId' => $link->getMachine()->getId(), + 'productId' => $product->getId(), + 'product' => $this->normalizeProduct($product), + 'parentLinkId' => $link->getParentLink()?->getId(), + 'parentComponentLinkId' => $link->getParentComponentLink()?->getId(), + 'parentPieceLinkId' => $link->getParentPieceLink()?->getId(), ]; }, $links); } private function normalizeComposant(Composant $composant): array { + $type = $composant->getTypeComposant(); + return [ - 'id' => $composant->getId(), - 'name' => $composant->getName(), - 'reference' => $composant->getReference(), - 'prix' => $composant->getPrix(), - 'typeComposantId' => $composant->getTypeComposant()?->getId(), - 'typeComposant' => $this->normalizeModelType($composant->getTypeComposant()), - 'productId' => $composant->getProduct()?->getId(), - 'product' => $composant->getProduct() ? $this->normalizeProduct($composant->getProduct()) : null, - 'constructeurs' => $this->normalizeConstructeurs($composant->getConstructeurs()), - 'documents' => [], - 'customFields' => [], + 'id' => $composant->getId(), + 'name' => $composant->getName(), + 'reference' => $composant->getReference(), + 'prix' => $composant->getPrix(), + 'typeComposantId' => $type?->getId(), + 'typeComposant' => $this->normalizeModelType($type), + 'productId' => $composant->getProduct()?->getId(), + 'product' => $composant->getProduct() ? $this->normalizeProduct($composant->getProduct()) : null, + 'constructeurs' => $this->normalizeConstructeurs($composant->getConstructeurs()), + 'documents' => [], + 'customFields' => $type ? $this->normalizeCustomFieldDefinitions($type->getComponentCustomFields()) : [], + 'customFieldValues' => $this->normalizeCustomFieldValues($composant->getCustomFieldValues()), ]; } private function normalizePiece(Piece $piece): array { + $type = $piece->getTypePiece(); + return [ - 'id' => $piece->getId(), - 'name' => $piece->getName(), - 'reference' => $piece->getReference(), - 'prix' => $piece->getPrix(), - 'typePieceId' => $piece->getTypePiece()?->getId(), - 'typePiece' => $this->normalizeModelType($piece->getTypePiece()), - 'productId' => $piece->getProduct()?->getId(), - 'product' => $piece->getProduct() ? $this->normalizeProduct($piece->getProduct()) : null, - 'constructeurs' => $this->normalizeConstructeurs($piece->getConstructeurs()), - 'documents' => [], - 'customFields' => [], + 'id' => $piece->getId(), + 'name' => $piece->getName(), + 'reference' => $piece->getReference(), + 'prix' => $piece->getPrix(), + 'typePieceId' => $type?->getId(), + 'typePiece' => $this->normalizeModelType($type), + 'productId' => $piece->getProduct()?->getId(), + 'product' => $piece->getProduct() ? $this->normalizeProduct($piece->getProduct()) : null, + 'constructeurs' => $this->normalizeConstructeurs($piece->getConstructeurs()), + 'documents' => [], + 'customFields' => $type ? $this->normalizeCustomFieldDefinitions($type->getPieceCustomFields()) : [], + 'customFieldValues' => $this->normalizeCustomFieldValues($piece->getCustomFieldValues()), ]; } @@ -598,49 +719,11 @@ class MachineSkeletonController extends AbstractController } return [ - 'id' => $type->getId(), - 'name' => $type->getName(), - 'code' => $type->getCode(), - 'category' => $type->getCategory()->value, - ]; - } - - private function normalizeComponentRequirement(TypeMachineComponentRequirement $requirement): array - { - return [ - 'id' => $requirement->getId(), - 'label' => $requirement->getLabel(), - 'minCount' => $requirement->getMinCount(), - 'maxCount' => $requirement->getMaxCount(), - 'required' => $requirement->isRequired(), - 'typeComposantId' => $requirement->getTypeComposant()->getId(), - 'typeComposant' => $this->normalizeModelType($requirement->getTypeComposant()), - ]; - } - - private function normalizePieceRequirement(TypeMachinePieceRequirement $requirement): array - { - return [ - 'id' => $requirement->getId(), - 'label' => $requirement->getLabel(), - 'minCount' => $requirement->getMinCount(), - 'maxCount' => $requirement->getMaxCount(), - 'required' => $requirement->isRequired(), - 'typePieceId' => $requirement->getTypePiece()->getId(), - 'typePiece' => $this->normalizeModelType($requirement->getTypePiece()), - ]; - } - - private function normalizeProductRequirement(TypeMachineProductRequirement $requirement): array - { - return [ - 'id' => $requirement->getId(), - 'label' => $requirement->getLabel(), - 'minCount' => $requirement->getMinCount(), - 'maxCount' => $requirement->getMaxCount(), - 'required' => $requirement->isRequired(), - 'typeProductId' => $requirement->getTypeProduct()->getId(), - 'typeProduct' => $this->normalizeModelType($requirement->getTypeProduct()), + 'id' => $type->getId(), + 'name' => $type->getName(), + 'code' => $type->getCode(), + 'category' => $type->getCategory()->value, + 'structure' => $type->getStructure(), ]; } @@ -659,6 +742,55 @@ class MachineSkeletonController extends AbstractController return $items; } + private function normalizeCustomFieldDefinitions(Collection $customFields): array + { + $items = []; + foreach ($customFields as $cf) { + if (!$cf instanceof CustomField) { + continue; + } + $items[] = [ + 'id' => $cf->getId(), + 'name' => $cf->getName(), + 'type' => $cf->getType(), + 'required' => $cf->isRequired(), + 'options' => $cf->getOptions(), + 'defaultValue' => $cf->getDefaultValue(), + 'orderIndex' => $cf->getOrderIndex(), + ]; + } + + usort($items, static fn (array $a, array $b) => $a['orderIndex'] <=> $b['orderIndex']); + + return $items; + } + + private function normalizeCustomFieldValues(Collection $customFieldValues): array + { + $items = []; + foreach ($customFieldValues as $cfv) { + if (!$cfv instanceof CustomFieldValue) { + continue; + } + $cf = $cfv->getCustomField(); + $items[] = [ + 'id' => $cfv->getId(), + 'value' => $cfv->getValue(), + 'customField' => [ + 'id' => $cf->getId(), + 'name' => $cf->getName(), + 'type' => $cf->getType(), + 'required' => $cf->isRequired(), + 'options' => $cf->getOptions(), + 'defaultValue' => $cf->getDefaultValue(), + 'orderIndex' => $cf->getOrderIndex(), + ], + ]; + } + + return $items; + } + private function normalizeOverrides(object $link): ?array { $name = method_exists($link, 'getNameOverride') ? $link->getNameOverride() : null; diff --git a/src/Entity/Comment.php b/src/Entity/Comment.php index 3af2f67..547c805 100644 --- a/src/Entity/Comment.php +++ b/src/Entity/Comment.php @@ -20,7 +20,7 @@ use Doctrine\ORM\Mapping as ORM; #[ORM\Table(name: 'comments')] #[ORM\Index(columns: ['entity_type', 'entity_id', 'status'], name: 'idx_comment_entity_status')] #[ORM\HasLifecycleCallbacks] -#[ApiFilter(SearchFilter::class, properties: ['entityType' => 'exact', 'entityId' => 'exact', 'status' => 'exact', 'entityName' => 'partial'])] +#[ApiFilter(SearchFilter::class, properties: ['entityType' => 'exact', 'entityId' => 'exact', 'status' => 'exact', 'entityName' => 'ipartial'])] #[ApiFilter(OrderFilter::class, properties: ['createdAt', 'authorName', 'status'])] #[ApiResource( operations: [ diff --git a/src/Entity/CustomField.php b/src/Entity/CustomField.php index 4c95170..e721e6d 100644 --- a/src/Entity/CustomField.php +++ b/src/Entity/CustomField.php @@ -62,9 +62,9 @@ class CustomField #[Groups(['composant:read', 'piece:read', 'product:read', 'machine:read'])] private int $orderIndex = 0; - #[ORM\ManyToOne(targetEntity: TypeMachine::class, inversedBy: 'customFields')] - #[ORM\JoinColumn(name: 'typeMachineId', referencedColumnName: 'id', nullable: true, onDelete: 'CASCADE')] - private ?TypeMachine $typeMachine = null; + #[ORM\ManyToOne(targetEntity: Machine::class, inversedBy: 'customFields')] + #[ORM\JoinColumn(name: 'machineId', referencedColumnName: 'id', nullable: true, onDelete: 'CASCADE')] + private ?Machine $machine = null; #[ORM\ManyToOne(targetEntity: ModelType::class, inversedBy: 'customFields')] #[ORM\JoinColumn(name: 'typeComposantId', referencedColumnName: 'id', nullable: true, onDelete: 'CASCADE')] @@ -197,14 +197,14 @@ class CustomField return $this; } - public function getTypeMachine(): ?TypeMachine + public function getMachine(): ?Machine { - return $this->typeMachine; + return $this->machine; } - public function setTypeMachine(?TypeMachine $typeMachine): static + public function setMachine(?Machine $machine): static { - $this->typeMachine = $typeMachine; + $this->machine = $machine; return $this; } diff --git a/src/Entity/Document.php b/src/Entity/Document.php index bdaafcd..cb541ce 100644 --- a/src/Entity/Document.php +++ b/src/Entity/Document.php @@ -24,7 +24,7 @@ use Symfony\Component\Serializer\Attribute\Groups; #[ORM\Entity(repositoryClass: DocumentRepository::class)] #[ORM\Table(name: 'documents')] #[ORM\HasLifecycleCallbacks] -#[ApiFilter(SearchFilter::class, properties: ['name' => 'partial', 'filename' => 'partial'])] +#[ApiFilter(SearchFilter::class, properties: ['name' => 'ipartial', 'filename' => 'ipartial'])] #[ApiFilter(ExistsFilter::class, properties: ['site', 'machine', 'composant', 'piece', 'product'])] #[ApiFilter(OrderFilter::class, properties: ['createdAt', 'name', 'size'])] #[ApiResource( diff --git a/src/Entity/Machine.php b/src/Entity/Machine.php index 32687aa..8210980 100644 --- a/src/Entity/Machine.php +++ b/src/Entity/Machine.php @@ -53,10 +53,6 @@ class Machine #[ORM\JoinColumn(name: 'siteId', referencedColumnName: 'id', nullable: false, onDelete: 'CASCADE')] private Site $site; - #[ORM\ManyToOne(targetEntity: TypeMachine::class, inversedBy: 'machines')] - #[ORM\JoinColumn(name: 'typeMachineId', referencedColumnName: 'id', nullable: true)] - private ?TypeMachine $typeMachine = null; - /** * @var Collection */ @@ -92,6 +88,12 @@ class Machine #[ORM\OneToMany(mappedBy: 'machine', targetEntity: Document::class)] private Collection $documents; + /** + * @var Collection + */ + #[ORM\OneToMany(mappedBy: 'machine', targetEntity: CustomField::class, cascade: ['persist', 'remove'])] + private Collection $customFields; + /** * @var Collection */ @@ -111,6 +113,7 @@ class Machine $this->pieceLinks = new ArrayCollection(); $this->productLinks = new ArrayCollection(); $this->documents = new ArrayCollection(); + $this->customFields = new ArrayCollection(); $this->customFieldValues = new ArrayCollection(); } @@ -192,14 +195,31 @@ class Machine return $this; } - public function getTypeMachine(): ?TypeMachine + /** + * @return Collection + */ + public function getCustomFields(): Collection { - return $this->typeMachine; + return $this->customFields; } - public function setTypeMachine(?TypeMachine $typeMachine): static + public function addCustomField(CustomField $customField): static { - $this->typeMachine = $typeMachine; + if (!$this->customFields->contains($customField)) { + $this->customFields->add($customField); + $customField->setMachine($this); + } + + return $this; + } + + public function removeCustomField(CustomField $customField): static + { + if ($this->customFields->removeElement($customField)) { + if ($customField->getMachine() === $this) { + $customField->setMachine(null); + } + } return $this; } diff --git a/src/Entity/MachineComponentLink.php b/src/Entity/MachineComponentLink.php index af7fb47..f907850 100644 --- a/src/Entity/MachineComponentLink.php +++ b/src/Entity/MachineComponentLink.php @@ -55,10 +55,6 @@ class MachineComponentLink #[ORM\OneToMany(mappedBy: 'parentLink', targetEntity: MachineComponentLink::class)] private Collection $childLinks; - #[ORM\ManyToOne(targetEntity: TypeMachineComponentRequirement::class, inversedBy: 'machineComponentLinks')] - #[ORM\JoinColumn(name: 'typeMachineComponentRequirementId', referencedColumnName: 'id', nullable: true, onDelete: 'SET NULL')] - private ?TypeMachineComponentRequirement $typeMachineComponentRequirement = null; - /** * @var Collection */ @@ -159,18 +155,6 @@ class MachineComponentLink return $this; } - public function getTypeMachineComponentRequirement(): ?TypeMachineComponentRequirement - { - return $this->typeMachineComponentRequirement; - } - - public function setTypeMachineComponentRequirement(?TypeMachineComponentRequirement $requirement): static - { - $this->typeMachineComponentRequirement = $requirement; - - return $this; - } - public function getNameOverride(): ?string { return $this->nameOverride; diff --git a/src/Entity/MachinePieceLink.php b/src/Entity/MachinePieceLink.php index 5d94561..19b3b47 100644 --- a/src/Entity/MachinePieceLink.php +++ b/src/Entity/MachinePieceLink.php @@ -49,10 +49,6 @@ class MachinePieceLink #[ORM\JoinColumn(name: 'parentLinkId', referencedColumnName: 'id', nullable: true, onDelete: 'CASCADE')] private ?MachineComponentLink $parentLink = null; - #[ORM\ManyToOne(targetEntity: TypeMachinePieceRequirement::class, inversedBy: 'machinePieceLinks')] - #[ORM\JoinColumn(name: 'typeMachinePieceRequirementId', referencedColumnName: 'id', nullable: true, onDelete: 'SET NULL')] - private ?TypeMachinePieceRequirement $typeMachinePieceRequirement = null; - /** * @var Collection */ @@ -145,18 +141,6 @@ class MachinePieceLink return $this; } - public function getTypeMachinePieceRequirement(): ?TypeMachinePieceRequirement - { - return $this->typeMachinePieceRequirement; - } - - public function setTypeMachinePieceRequirement(?TypeMachinePieceRequirement $requirement): static - { - $this->typeMachinePieceRequirement = $requirement; - - return $this; - } - public function getNameOverride(): ?string { return $this->nameOverride; diff --git a/src/Entity/MachineProductLink.php b/src/Entity/MachineProductLink.php index e54da40..db11867 100644 --- a/src/Entity/MachineProductLink.php +++ b/src/Entity/MachineProductLink.php @@ -45,10 +45,6 @@ class MachineProductLink #[ORM\JoinColumn(name: 'productId', referencedColumnName: 'id', nullable: false, onDelete: 'CASCADE')] private Product $product; - #[ORM\ManyToOne(targetEntity: TypeMachineProductRequirement::class, inversedBy: 'machineProductLinks')] - #[ORM\JoinColumn(name: 'typeMachineProductRequirementId', referencedColumnName: 'id', nullable: true, onDelete: 'SET NULL')] - private ?TypeMachineProductRequirement $typeMachineProductRequirement = null; - #[ORM\ManyToOne(targetEntity: MachineProductLink::class, inversedBy: 'childLinks')] #[ORM\JoinColumn(name: 'parentLinkId', referencedColumnName: 'id', nullable: true, onDelete: 'CASCADE')] private ?MachineProductLink $parentLink = null; @@ -132,18 +128,6 @@ class MachineProductLink return $this; } - public function getTypeMachineProductRequirement(): ?TypeMachineProductRequirement - { - return $this->typeMachineProductRequirement; - } - - public function setTypeMachineProductRequirement(?TypeMachineProductRequirement $requirement): static - { - $this->typeMachineProductRequirement = $requirement; - - return $this; - } - public function getParentLink(): ?MachineProductLink { return $this->parentLink; diff --git a/src/Entity/ModelType.php b/src/Entity/ModelType.php index 90e9f51..ac54467 100644 --- a/src/Entity/ModelType.php +++ b/src/Entity/ModelType.php @@ -21,7 +21,7 @@ use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\Collection; use Doctrine\DBAL\Types\Types; use Doctrine\ORM\Mapping as ORM; -use Symfony\Component\Serializer\Annotation\Groups; +use Symfony\Component\Serializer\Attribute\Groups; #[ORM\Entity(repositoryClass: ModelTypeRepository::class)] #[ORM\Table(name: 'model_types')] @@ -45,11 +45,11 @@ class ModelType { #[ORM\Id] #[ORM\Column(type: Types::STRING, length: 36)] - #[Groups(['type_machine:read', 'model_type:read'])] + #[Groups(['type_machine:read', 'model_type:read', 'product:read', 'composant:read', 'piece:read'])] private ?string $id = null; #[ORM\Column(type: Types::STRING, length: 120)] - #[Groups(['type_machine:read', 'model_type:read', 'model_type:write'])] + #[Groups(['type_machine:read', 'model_type:read', 'model_type:write', 'product:read', 'composant:read', 'piece:read'])] private string $name; #[ORM\Column(type: Types::STRING, length: 60, unique: true)] @@ -69,15 +69,15 @@ class ModelType private ?string $description = null; #[ORM\Column(type: Types::JSON, nullable: true, name: 'componentSkeleton')] - #[Groups(['model_type:read'])] + #[Groups(['model_type:read', 'composant:read'])] private ?array $componentSkeleton = null; #[ORM\Column(type: Types::JSON, nullable: true, name: 'pieceSkeleton')] - #[Groups(['model_type:read'])] + #[Groups(['model_type:read', 'piece:read'])] private ?array $pieceSkeleton = null; #[ORM\Column(type: Types::JSON, nullable: true, name: 'productSkeleton')] - #[Groups(['model_type:read'])] + #[Groups(['model_type:read', 'product:read'])] private ?array $productSkeleton = null; #[ORM\Column(type: Types::DATETIME_IMMUTABLE, name: 'createdAt')] @@ -108,24 +108,6 @@ class ModelType #[ORM\OneToMany(mappedBy: 'typeProduct', targetEntity: Product::class)] private Collection $products; - /** - * @var Collection - */ - #[ORM\OneToMany(mappedBy: 'typeComposant', targetEntity: TypeMachineComponentRequirement::class)] - private Collection $componentRequirements; - - /** - * @var Collection - */ - #[ORM\OneToMany(mappedBy: 'typePiece', targetEntity: TypeMachinePieceRequirement::class)] - private Collection $pieceRequirements; - - /** - * @var Collection - */ - #[ORM\OneToMany(mappedBy: 'typeProduct', targetEntity: TypeMachineProductRequirement::class)] - private Collection $productRequirements; - /** * @var Collection */ @@ -146,15 +128,12 @@ class ModelType public function __construct() { - $this->composants = new ArrayCollection(); - $this->pieces = new ArrayCollection(); - $this->products = new ArrayCollection(); - $this->componentRequirements = new ArrayCollection(); - $this->pieceRequirements = new ArrayCollection(); - $this->productRequirements = new ArrayCollection(); - $this->customFields = new ArrayCollection(); - $this->pieceCustomFields = new ArrayCollection(); - $this->productCustomFields = new ArrayCollection(); + $this->composants = new ArrayCollection(); + $this->pieces = new ArrayCollection(); + $this->products = new ArrayCollection(); + $this->customFields = new ArrayCollection(); + $this->pieceCustomFields = new ArrayCollection(); + $this->productCustomFields = new ArrayCollection(); } #[ORM\PrePersist] @@ -288,7 +267,7 @@ class ModelType return $this; } - #[Groups(['model_type:read'])] + #[Groups(['model_type:read', 'product:read', 'composant:read', 'piece:read'])] public function getStructure(): ?array { return match ($this->category) { @@ -312,6 +291,30 @@ class ModelType return $this; } + /** + * @return Collection + */ + public function getComponentCustomFields(): Collection + { + return $this->customFields; + } + + /** + * @return Collection + */ + public function getPieceCustomFields(): Collection + { + return $this->pieceCustomFields; + } + + /** + * @return Collection + */ + public function getProductCustomFields(): Collection + { + return $this->productCustomFields; + } + public function getCreatedAt(): DateTimeImmutable { return $this->createdAt; diff --git a/src/Entity/Profile.php b/src/Entity/Profile.php index dad9747..7316a32 100644 --- a/src/Entity/Profile.php +++ b/src/Entity/Profile.php @@ -17,7 +17,7 @@ use DateTimeImmutable; use Doctrine\ORM\Mapping as ORM; use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface; use Symfony\Component\Security\Core\User\UserInterface; -use Symfony\Component\Serializer\Annotation\Groups; +use Symfony\Component\Serializer\Attribute\Groups; use Symfony\Component\Validator\Constraints as Assert; #[ORM\Entity(repositoryClass: ProfileRepository::class)] diff --git a/src/Entity/TypeMachine.php b/src/Entity/TypeMachine.php deleted file mode 100644 index b8795fb..0000000 --- a/src/Entity/TypeMachine.php +++ /dev/null @@ -1,390 +0,0 @@ - - */ - #[ORM\OneToMany(targetEntity: Machine::class, mappedBy: 'typeMachine')] - private Collection $machines; - - /** - * @var Collection - */ - #[ORM\OneToMany(targetEntity: CustomField::class, mappedBy: 'typeMachine', cascade: ['persist', 'remove'])] - #[ApiProperty(readableLink: true, writableLink: true)] - private Collection $customFields; - - /** - * @var Collection - */ - #[ORM\OneToMany(targetEntity: TypeMachineComponentRequirement::class, mappedBy: 'typeMachine', cascade: ['persist', 'remove'], orphanRemoval: true)] - #[ApiProperty(readableLink: true, writableLink: true)] - private Collection $componentRequirements; - - /** - * @var Collection - */ - #[ORM\OneToMany(targetEntity: TypeMachinePieceRequirement::class, mappedBy: 'typeMachine', cascade: ['persist', 'remove'], orphanRemoval: true)] - #[ApiProperty(readableLink: true, writableLink: true)] - private Collection $pieceRequirements; - - /** - * @var Collection - */ - #[ORM\OneToMany(targetEntity: TypeMachineProductRequirement::class, mappedBy: 'typeMachine', cascade: ['persist', 'remove'], orphanRemoval: true)] - #[ApiProperty(readableLink: true, writableLink: true)] - private Collection $productRequirements; - - public function __construct() - { - $this->id = 'cl'.bin2hex(random_bytes(12)); - $this->createdAt = new DateTimeImmutable(); - $this->updatedAt = new DateTimeImmutable(); - $this->machines = new ArrayCollection(); - $this->customFields = new ArrayCollection(); - $this->componentRequirements = new ArrayCollection(); - $this->pieceRequirements = new ArrayCollection(); - $this->productRequirements = new ArrayCollection(); - } - - public function getId(): ?string - { - return $this->id; - } - - public function getName(): string - { - return $this->name; - } - - public function setName(string $name): static - { - $this->name = $name; - - return $this; - } - - public function getDescription(): ?string - { - return $this->description; - } - - public function setDescription(?string $description): static - { - $this->description = $description; - - return $this; - } - - public function getCategory(): ?string - { - return $this->category; - } - - public function setCategory(?string $category): static - { - $this->category = $category; - - return $this; - } - - public function getMaintenanceFrequency(): ?string - { - return $this->maintenanceFrequency; - } - - public function setMaintenanceFrequency(?string $maintenanceFrequency): static - { - $this->maintenanceFrequency = $maintenanceFrequency; - - return $this; - } - - public function getComponents(): ?array - { - return $this->components; - } - - public function setComponents(?array $components): static - { - $this->components = $components; - - return $this; - } - - public function getCriticalParts(): ?array - { - return $this->criticalParts; - } - - public function setCriticalParts(?array $criticalParts): static - { - $this->criticalParts = $criticalParts; - - return $this; - } - - public function getMachinePieces(): ?array - { - return $this->machinePieces; - } - - public function setMachinePieces(?array $machinePieces): static - { - $this->machinePieces = $machinePieces; - - return $this; - } - - public function getSpecifications(): ?array - { - return $this->specifications; - } - - public function setSpecifications(?array $specifications): static - { - $this->specifications = $specifications; - - return $this; - } - - public function getCreatedAt(): DateTimeImmutable - { - return $this->createdAt; - } - - public function getUpdatedAt(): DateTimeImmutable - { - return $this->updatedAt; - } - - /** - * @return Collection - */ - public function getMachines(): Collection - { - return $this->machines; - } - - public function addMachine(Machine $machine): static - { - if (!$this->machines->contains($machine)) { - $this->machines->add($machine); - $machine->setTypeMachine($this); - } - - return $this; - } - - public function removeMachine(Machine $machine): static - { - if ($this->machines->removeElement($machine)) { - if ($machine->getTypeMachine() === $this) { - $machine->setTypeMachine(null); - } - } - - return $this; - } - - /** - * @return Collection - */ - public function getCustomFields(): Collection - { - return $this->customFields; - } - - public function addCustomField(CustomField $customField): static - { - if (!$this->customFields->contains($customField)) { - $this->customFields->add($customField); - $customField->setTypeMachine($this); - } - - return $this; - } - - public function removeCustomField(CustomField $customField): static - { - if ($this->customFields->removeElement($customField)) { - if ($customField->getTypeMachine() === $this) { - $customField->setTypeMachine(null); - } - } - - return $this; - } - - /** - * @return Collection - */ - public function getComponentRequirements(): Collection - { - return $this->componentRequirements; - } - - public function addComponentRequirement(TypeMachineComponentRequirement $componentRequirement): static - { - if (!$this->componentRequirements->contains($componentRequirement)) { - $this->componentRequirements->add($componentRequirement); - $componentRequirement->setTypeMachine($this); - } - - return $this; - } - - public function removeComponentRequirement(TypeMachineComponentRequirement $componentRequirement): static - { - $this->componentRequirements->removeElement($componentRequirement); - - return $this; - } - - /** - * @return Collection - */ - public function getPieceRequirements(): Collection - { - return $this->pieceRequirements; - } - - public function addPieceRequirement(TypeMachinePieceRequirement $pieceRequirement): static - { - if (!$this->pieceRequirements->contains($pieceRequirement)) { - $this->pieceRequirements->add($pieceRequirement); - $pieceRequirement->setTypeMachine($this); - } - - return $this; - } - - public function removePieceRequirement(TypeMachinePieceRequirement $pieceRequirement): static - { - $this->pieceRequirements->removeElement($pieceRequirement); - - return $this; - } - - /** - * @return Collection - */ - public function getProductRequirements(): Collection - { - return $this->productRequirements; - } - - public function addProductRequirement(TypeMachineProductRequirement $productRequirement): static - { - if (!$this->productRequirements->contains($productRequirement)) { - $this->productRequirements->add($productRequirement); - $productRequirement->setTypeMachine($this); - } - - return $this; - } - - public function removeProductRequirement(TypeMachineProductRequirement $productRequirement): static - { - $this->productRequirements->removeElement($productRequirement); - - return $this; - } - - #[ORM\PrePersist] - public function setCreatedAtValue(): void - { - $this->createdAt = new DateTimeImmutable(); - $this->updatedAt = new DateTimeImmutable(); - } - - #[ORM\PreUpdate] - public function setUpdatedAtValue(): void - { - $this->updatedAt = new DateTimeImmutable(); - } -} diff --git a/src/Entity/TypeMachineComponentRequirement.php b/src/Entity/TypeMachineComponentRequirement.php deleted file mode 100644 index 80b87a5..0000000 --- a/src/Entity/TypeMachineComponentRequirement.php +++ /dev/null @@ -1,224 +0,0 @@ - 1], name: 'minCount')] - #[Groups(['type_machine:read'])] - private int $minCount = 1; - - #[ORM\Column(type: Types::INTEGER, nullable: true, name: 'maxCount')] - #[Groups(['type_machine:read'])] - private ?int $maxCount = null; - - #[ORM\Column(type: Types::BOOLEAN, options: ['default' => true], name: 'required')] - #[Groups(['type_machine:read'])] - private bool $required = true; - - #[ORM\Column(type: Types::BOOLEAN, options: ['default' => true], name: 'allowNewModels')] - #[Groups(['type_machine:read'])] - private bool $allowNewModels = true; - - #[ORM\Column(type: Types::INTEGER, options: ['default' => 0], name: 'orderIndex')] - #[Groups(['type_machine:read'])] - private int $orderIndex = 0; - - #[ORM\ManyToOne(targetEntity: TypeMachine::class, inversedBy: 'componentRequirements')] - #[ORM\JoinColumn(name: 'typeMachineId', referencedColumnName: 'id', nullable: false, onDelete: 'CASCADE')] - private TypeMachine $typeMachine; - - #[ORM\ManyToOne(targetEntity: ModelType::class, inversedBy: 'componentRequirements')] - #[ORM\JoinColumn(name: 'typeComposantId', referencedColumnName: 'id', nullable: false)] - #[ApiProperty(readableLink: true)] - #[Groups(['type_machine:read'])] - private ModelType $typeComposant; - - /** - * @var Collection - */ - #[ORM\OneToMany(mappedBy: 'typeMachineComponentRequirement', targetEntity: MachineComponentLink::class)] - private Collection $machineComponentLinks; - - #[ORM\Column(type: Types::DATETIME_IMMUTABLE, name: 'createdAt')] - private DateTimeImmutable $createdAt; - - #[ORM\Column(type: Types::DATETIME_IMMUTABLE, name: 'updatedAt')] - private DateTimeImmutable $updatedAt; - - public function __construct() - { - $this->machineComponentLinks = new ArrayCollection(); - } - - #[ORM\PrePersist] - public function setCreatedAtValue(): void - { - $now = new DateTimeImmutable(); - $this->createdAt = $now; - $this->updatedAt = $now; - - if (null === $this->id) { - $this->id = $this->generateCuid(); - } - } - - #[ORM\PreUpdate] - public function setUpdatedAtValue(): void - { - $this->updatedAt = new DateTimeImmutable(); - } - - public function getId(): ?string - { - return $this->id; - } - - public function setId(string $id): static - { - $this->id = $id; - - return $this; - } - - public function getLabel(): ?string - { - return $this->label; - } - - public function setLabel(?string $label): static - { - $this->label = $label; - - return $this; - } - - public function getMinCount(): int - { - return $this->minCount; - } - - public function setMinCount(int $minCount): static - { - $this->minCount = $minCount; - - return $this; - } - - public function getMaxCount(): ?int - { - return $this->maxCount; - } - - public function setMaxCount(?int $maxCount): static - { - $this->maxCount = $maxCount; - - return $this; - } - - public function isRequired(): bool - { - return $this->required; - } - - public function setRequired(bool $required): static - { - $this->required = $required; - - return $this; - } - - public function isAllowNewModels(): bool - { - return $this->allowNewModels; - } - - public function setAllowNewModels(bool $allowNewModels): static - { - $this->allowNewModels = $allowNewModels; - - return $this; - } - - public function getOrderIndex(): int - { - return $this->orderIndex; - } - - public function setOrderIndex(int $orderIndex): static - { - $this->orderIndex = $orderIndex; - - return $this; - } - - public function getTypeMachine(): TypeMachine - { - return $this->typeMachine; - } - - public function setTypeMachine(TypeMachine $typeMachine): static - { - $this->typeMachine = $typeMachine; - - return $this; - } - - public function getTypeComposant(): ModelType - { - return $this->typeComposant; - } - - public function setTypeComposant(ModelType $typeComposant): static - { - $this->typeComposant = $typeComposant; - - return $this; - } - - private function generateCuid(): string - { - return 'cl'.bin2hex(random_bytes(12)); - } -} diff --git a/src/Entity/TypeMachinePieceRequirement.php b/src/Entity/TypeMachinePieceRequirement.php deleted file mode 100644 index d76bc83..0000000 --- a/src/Entity/TypeMachinePieceRequirement.php +++ /dev/null @@ -1,224 +0,0 @@ - 0], name: 'minCount')] - #[Groups(['type_machine:read'])] - private int $minCount = 0; - - #[ORM\Column(type: Types::INTEGER, nullable: true, name: 'maxCount')] - #[Groups(['type_machine:read'])] - private ?int $maxCount = null; - - #[ORM\Column(type: Types::BOOLEAN, options: ['default' => false])] - #[Groups(['type_machine:read'])] - private bool $required = false; - - #[ORM\Column(type: Types::BOOLEAN, options: ['default' => true], name: 'allowNewModels')] - #[Groups(['type_machine:read'])] - private bool $allowNewModels = true; - - #[ORM\Column(type: Types::INTEGER, options: ['default' => 0], name: 'orderIndex')] - #[Groups(['type_machine:read'])] - private int $orderIndex = 0; - - #[ORM\ManyToOne(targetEntity: TypeMachine::class, inversedBy: 'pieceRequirements')] - #[ORM\JoinColumn(name: 'typeMachineId', referencedColumnName: 'id', nullable: false, onDelete: 'CASCADE')] - private TypeMachine $typeMachine; - - #[ORM\ManyToOne(targetEntity: ModelType::class, inversedBy: 'pieceRequirements')] - #[ORM\JoinColumn(name: 'typePieceId', referencedColumnName: 'id', nullable: false)] - #[ApiProperty(readableLink: true)] - #[Groups(['type_machine:read'])] - private ModelType $typePiece; - - /** - * @var Collection - */ - #[ORM\OneToMany(mappedBy: 'typeMachinePieceRequirement', targetEntity: MachinePieceLink::class)] - private Collection $machinePieceLinks; - - #[ORM\Column(type: Types::DATETIME_IMMUTABLE, name: 'createdAt')] - private DateTimeImmutable $createdAt; - - #[ORM\Column(type: Types::DATETIME_IMMUTABLE, name: 'updatedAt')] - private DateTimeImmutable $updatedAt; - - public function __construct() - { - $this->machinePieceLinks = new ArrayCollection(); - } - - #[ORM\PrePersist] - public function setCreatedAtValue(): void - { - $now = new DateTimeImmutable(); - $this->createdAt = $now; - $this->updatedAt = $now; - - if (null === $this->id) { - $this->id = $this->generateCuid(); - } - } - - #[ORM\PreUpdate] - public function setUpdatedAtValue(): void - { - $this->updatedAt = new DateTimeImmutable(); - } - - public function getId(): ?string - { - return $this->id; - } - - public function setId(string $id): static - { - $this->id = $id; - - return $this; - } - - public function getLabel(): ?string - { - return $this->label; - } - - public function setLabel(?string $label): static - { - $this->label = $label; - - return $this; - } - - public function getMinCount(): int - { - return $this->minCount; - } - - public function setMinCount(int $minCount): static - { - $this->minCount = $minCount; - - return $this; - } - - public function getMaxCount(): ?int - { - return $this->maxCount; - } - - public function setMaxCount(?int $maxCount): static - { - $this->maxCount = $maxCount; - - return $this; - } - - public function isRequired(): bool - { - return $this->required; - } - - public function setRequired(bool $required): static - { - $this->required = $required; - - return $this; - } - - public function isAllowNewModels(): bool - { - return $this->allowNewModels; - } - - public function setAllowNewModels(bool $allowNewModels): static - { - $this->allowNewModels = $allowNewModels; - - return $this; - } - - public function getOrderIndex(): int - { - return $this->orderIndex; - } - - public function setOrderIndex(int $orderIndex): static - { - $this->orderIndex = $orderIndex; - - return $this; - } - - public function getTypeMachine(): TypeMachine - { - return $this->typeMachine; - } - - public function setTypeMachine(TypeMachine $typeMachine): static - { - $this->typeMachine = $typeMachine; - - return $this; - } - - public function getTypePiece(): ModelType - { - return $this->typePiece; - } - - public function setTypePiece(ModelType $typePiece): static - { - $this->typePiece = $typePiece; - - return $this; - } - - private function generateCuid(): string - { - return 'cl'.bin2hex(random_bytes(12)); - } -} diff --git a/src/Entity/TypeMachineProductRequirement.php b/src/Entity/TypeMachineProductRequirement.php deleted file mode 100644 index 5b56a5a..0000000 --- a/src/Entity/TypeMachineProductRequirement.php +++ /dev/null @@ -1,224 +0,0 @@ - 0], name: 'minCount')] - #[Groups(['type_machine:read'])] - private int $minCount = 0; - - #[ORM\Column(type: Types::INTEGER, nullable: true, name: 'maxCount')] - #[Groups(['type_machine:read'])] - private ?int $maxCount = null; - - #[ORM\Column(type: Types::BOOLEAN, options: ['default' => false])] - #[Groups(['type_machine:read'])] - private bool $required = false; - - #[ORM\Column(type: Types::BOOLEAN, options: ['default' => true], name: 'allowNewModels')] - #[Groups(['type_machine:read'])] - private bool $allowNewModels = true; - - #[ORM\Column(type: Types::INTEGER, options: ['default' => 0], name: 'orderIndex')] - #[Groups(['type_machine:read'])] - private int $orderIndex = 0; - - #[ORM\ManyToOne(targetEntity: TypeMachine::class, inversedBy: 'productRequirements')] - #[ORM\JoinColumn(name: 'typeMachineId', referencedColumnName: 'id', nullable: false, onDelete: 'CASCADE')] - private TypeMachine $typeMachine; - - #[ORM\ManyToOne(targetEntity: ModelType::class, inversedBy: 'productRequirements')] - #[ORM\JoinColumn(name: 'typeProductId', referencedColumnName: 'id', nullable: false)] - #[ApiProperty(readableLink: true)] - #[Groups(['type_machine:read'])] - private ModelType $typeProduct; - - /** - * @var Collection - */ - #[ORM\OneToMany(mappedBy: 'typeMachineProductRequirement', targetEntity: MachineProductLink::class)] - private Collection $machineProductLinks; - - #[ORM\Column(type: Types::DATETIME_IMMUTABLE, name: 'createdAt')] - private DateTimeImmutable $createdAt; - - #[ORM\Column(type: Types::DATETIME_IMMUTABLE, name: 'updatedAt')] - private DateTimeImmutable $updatedAt; - - public function __construct() - { - $this->machineProductLinks = new ArrayCollection(); - } - - #[ORM\PrePersist] - public function setCreatedAtValue(): void - { - $now = new DateTimeImmutable(); - $this->createdAt = $now; - $this->updatedAt = $now; - - if (null === $this->id) { - $this->id = $this->generateCuid(); - } - } - - #[ORM\PreUpdate] - public function setUpdatedAtValue(): void - { - $this->updatedAt = new DateTimeImmutable(); - } - - public function getId(): ?string - { - return $this->id; - } - - public function setId(string $id): static - { - $this->id = $id; - - return $this; - } - - public function getLabel(): ?string - { - return $this->label; - } - - public function setLabel(?string $label): static - { - $this->label = $label; - - return $this; - } - - public function getMinCount(): int - { - return $this->minCount; - } - - public function setMinCount(int $minCount): static - { - $this->minCount = $minCount; - - return $this; - } - - public function getMaxCount(): ?int - { - return $this->maxCount; - } - - public function setMaxCount(?int $maxCount): static - { - $this->maxCount = $maxCount; - - return $this; - } - - public function isRequired(): bool - { - return $this->required; - } - - public function setRequired(bool $required): static - { - $this->required = $required; - - return $this; - } - - public function isAllowNewModels(): bool - { - return $this->allowNewModels; - } - - public function setAllowNewModels(bool $allowNewModels): static - { - $this->allowNewModels = $allowNewModels; - - return $this; - } - - public function getOrderIndex(): int - { - return $this->orderIndex; - } - - public function setOrderIndex(int $orderIndex): static - { - $this->orderIndex = $orderIndex; - - return $this; - } - - public function getTypeMachine(): TypeMachine - { - return $this->typeMachine; - } - - public function setTypeMachine(TypeMachine $typeMachine): static - { - $this->typeMachine = $typeMachine; - - return $this; - } - - public function getTypeProduct(): ModelType - { - return $this->typeProduct; - } - - public function setTypeProduct(ModelType $typeProduct): static - { - $this->typeProduct = $typeProduct; - - return $this; - } - - private function generateCuid(): string - { - return 'cl'.bin2hex(random_bytes(12)); - } -} diff --git a/src/EventSubscriber/MachineAuditSubscriber.php b/src/EventSubscriber/MachineAuditSubscriber.php index 8d0a89f..42dbe9c 100644 --- a/src/EventSubscriber/MachineAuditSubscriber.php +++ b/src/EventSubscriber/MachineAuditSubscriber.php @@ -11,7 +11,6 @@ use App\Entity\ModelType; use App\Entity\Product; use App\Entity\Profile; use App\Entity\Site; -use App\Entity\TypeMachine; use DateTimeInterface; use Doctrine\Bundle\DoctrineBundle\Attribute\AsDoctrineListener; use Doctrine\Common\Collections\Collection; @@ -286,7 +285,6 @@ final class MachineAuditSubscriber implements EventSubscriber 'reference' => $machine->getReference(), 'prix' => $machine->getPrix(), 'site' => $this->normalizeValue($machine->getSite()), - 'typeMachine' => $this->normalizeValue($machine->getTypeMachine()), 'constructeurIds' => $this->normalizeCollection($machine->getConstructeurs()), ]; } @@ -335,13 +333,6 @@ final class MachineAuditSubscriber implements EventSubscriber ]; } - if ($value instanceof TypeMachine) { - return [ - 'id' => $value->getId(), - 'name' => $value->getName(), - ]; - } - if ($value instanceof ModelType) { return [ 'id' => $value->getId(), diff --git a/src/Repository/TypeMachineComponentRequirementRepository.php b/src/Repository/TypeMachineComponentRequirementRepository.php deleted file mode 100644 index 56bccd3..0000000 --- a/src/Repository/TypeMachineComponentRequirementRepository.php +++ /dev/null @@ -1,20 +0,0 @@ - - */ -class TypeMachineComponentRequirementRepository extends ServiceEntityRepository -{ - public function __construct(ManagerRegistry $registry) - { - parent::__construct($registry, TypeMachineComponentRequirement::class); - } -} diff --git a/src/Repository/TypeMachinePieceRequirementRepository.php b/src/Repository/TypeMachinePieceRequirementRepository.php deleted file mode 100644 index 4f510b6..0000000 --- a/src/Repository/TypeMachinePieceRequirementRepository.php +++ /dev/null @@ -1,20 +0,0 @@ - - */ -class TypeMachinePieceRequirementRepository extends ServiceEntityRepository -{ - public function __construct(ManagerRegistry $registry) - { - parent::__construct($registry, TypeMachinePieceRequirement::class); - } -} diff --git a/src/Repository/TypeMachineProductRequirementRepository.php b/src/Repository/TypeMachineProductRequirementRepository.php deleted file mode 100644 index de8721c..0000000 --- a/src/Repository/TypeMachineProductRequirementRepository.php +++ /dev/null @@ -1,20 +0,0 @@ - - */ -class TypeMachineProductRequirementRepository extends ServiceEntityRepository -{ - public function __construct(ManagerRegistry $registry) - { - parent::__construct($registry, TypeMachineProductRequirement::class); - } -} diff --git a/src/Repository/TypeMachineRepository.php b/src/Repository/TypeMachineRepository.php deleted file mode 100644 index 8a6bfa6..0000000 --- a/src/Repository/TypeMachineRepository.php +++ /dev/null @@ -1,38 +0,0 @@ - - */ -class TypeMachineRepository extends ServiceEntityRepository -{ - public function __construct(ManagerRegistry $registry) - { - parent::__construct($registry, TypeMachine::class); - } - - public function save(TypeMachine $entity, bool $flush = false): void - { - $this->getEntityManager()->persist($entity); - - if ($flush) { - $this->getEntityManager()->flush(); - } - } - - public function remove(TypeMachine $entity, bool $flush = false): void - { - $this->getEntityManager()->remove($entity); - - if ($flush) { - $this->getEntityManager()->flush(); - } - } -} diff --git a/src/Service/ModelTypeCategoryConversionService.php b/src/Service/ModelTypeCategoryConversionService.php index 1125be8..8c8a372 100644 --- a/src/Service/ModelTypeCategoryConversionService.php +++ b/src/Service/ModelTypeCategoryConversionService.php @@ -137,16 +137,6 @@ final class ModelTypeCategoryConversionService $blockers[] = sprintf('%d pièce(s) liée(s) à des machines.', $machineLinked); } - // Check type machine requirements - $requirementCount = (int) $this->connection->fetchOne( - 'SELECT COUNT(*) FROM type_machine_piece_requirements WHERE typepieceid = :id', - ['id' => $modelTypeId], - ); - - if ($requirementCount > 0) { - $blockers[] = sprintf('Utilisé dans %d modèle(s) de type de machine.', $requirementCount); - } - // Check name collision with existing composants $collisions = $this->connection->fetchFirstColumn( 'SELECT p.name FROM pieces p @@ -210,16 +200,6 @@ final class ModelTypeCategoryConversionService $blockers[] = sprintf('%d composant(s) lié(s) à des machines.', $machineLinked); } - // Check type machine requirements - $requirementCount = (int) $this->connection->fetchOne( - 'SELECT COUNT(*) FROM type_machine_component_requirements WHERE typecomposantid = :id', - ['id' => $modelTypeId], - ); - - if ($requirementCount > 0) { - $blockers[] = sprintf('Utilisé dans %d modèle(s) de type de machine.', $requirementCount); - } - // Check if any composant has pieces or sub-components in structure $withStructure = $this->connection->fetchAllAssociative( 'SELECT name, structure FROM composants WHERE typecomposantid = :id AND structure IS NOT NULL', diff --git a/src/State/TypeMachinePutProcessor.php b/src/State/TypeMachinePutProcessor.php deleted file mode 100644 index 8147d13..0000000 --- a/src/State/TypeMachinePutProcessor.php +++ /dev/null @@ -1,211 +0,0 @@ - $uriVariables - * @param array $context - */ - public function process(mixed $data, Operation $operation, array $uriVariables = [], array $context = []): TypeMachine - { - $typeMachine = $this->em->getRepository(TypeMachine::class)->find($uriVariables['id']); - - if (!$typeMachine) { - throw new NotFoundHttpException('Type de machine non trouvé.'); - } - - // Guard: cannot edit if machines are linked - if (!$typeMachine->getMachines()->isEmpty()) { - throw new HttpException(422, 'Ce type de machine ne peut pas être modifié car des machines y sont rattachées.'); - } - - $request = $this->requestStack->getCurrentRequest(); - $payload = json_decode($request->getContent(), true) ?? []; - - $this->updateScalarProperties($typeMachine, $payload); - - if (array_key_exists('customFields', $payload)) { - $this->replaceCustomFields($typeMachine, $payload['customFields'] ?? []); - } - - if (array_key_exists('componentRequirements', $payload)) { - $this->replaceComponentRequirements($typeMachine, $payload['componentRequirements'] ?? []); - } - - if (array_key_exists('pieceRequirements', $payload)) { - $this->replacePieceRequirements($typeMachine, $payload['pieceRequirements'] ?? []); - } - - if (array_key_exists('productRequirements', $payload)) { - $this->replaceProductRequirements($typeMachine, $payload['productRequirements'] ?? []); - } - - $this->em->flush(); - - return $typeMachine; - } - - private function updateScalarProperties(TypeMachine $typeMachine, array $payload): void - { - if (isset($payload['name'])) { - $typeMachine->setName($payload['name']); - } - - if (array_key_exists('description', $payload)) { - $typeMachine->setDescription($payload['description']); - } - - if (array_key_exists('category', $payload)) { - $typeMachine->setCategory($payload['category']); - } - - if (array_key_exists('maintenanceFrequency', $payload)) { - $typeMachine->setMaintenanceFrequency($payload['maintenanceFrequency']); - } - - if (array_key_exists('components', $payload)) { - $typeMachine->setComponents($payload['components']); - } - - if (array_key_exists('criticalParts', $payload)) { - $typeMachine->setCriticalParts($payload['criticalParts']); - } - - if (array_key_exists('machinePieces', $payload)) { - $typeMachine->setMachinePieces($payload['machinePieces']); - } - - if (array_key_exists('specifications', $payload)) { - $typeMachine->setSpecifications($payload['specifications']); - } - } - - private function replaceCustomFields(TypeMachine $typeMachine, array $fieldsData): void - { - foreach ($typeMachine->getCustomFields()->toArray() as $old) { - $typeMachine->removeCustomField($old); - } - - foreach ($fieldsData as $index => $data) { - $field = new CustomField(); - $field->setName($data['name'] ?? ''); - $field->setType($data['type'] ?? 'text'); - $field->setRequired($data['required'] ?? false); - $field->setOptions($data['options'] ?? null); - $field->setOrderIndex($data['orderIndex'] ?? $index); - $typeMachine->addCustomField($field); - } - } - - private function replaceComponentRequirements(TypeMachine $typeMachine, array $requirementsData): void - { - foreach ($typeMachine->getComponentRequirements()->toArray() as $old) { - $typeMachine->removeComponentRequirement($old); - } - - foreach ($requirementsData as $index => $data) { - $req = new TypeMachineComponentRequirement(); - $req->setLabel($data['label'] ?? null); - $req->setMinCount($data['minCount'] ?? 1); - $req->setMaxCount($data['maxCount'] ?? null); - $req->setRequired($data['required'] ?? true); - $req->setAllowNewModels($data['allowNewModels'] ?? true); - $req->setOrderIndex($data['orderIndex'] ?? $index); - - $modelType = $this->resolveModelType($data['typeComposant'] ?? null); - if ($modelType) { - $req->setTypeComposant($modelType); - } - - $typeMachine->addComponentRequirement($req); - } - } - - private function replacePieceRequirements(TypeMachine $typeMachine, array $requirementsData): void - { - foreach ($typeMachine->getPieceRequirements()->toArray() as $old) { - $typeMachine->removePieceRequirement($old); - } - - foreach ($requirementsData as $index => $data) { - $req = new TypeMachinePieceRequirement(); - $req->setLabel($data['label'] ?? null); - $req->setMinCount($data['minCount'] ?? 0); - $req->setMaxCount($data['maxCount'] ?? null); - $req->setRequired($data['required'] ?? false); - $req->setAllowNewModels($data['allowNewModels'] ?? true); - $req->setOrderIndex($data['orderIndex'] ?? $index); - - $modelType = $this->resolveModelType($data['typePiece'] ?? null); - if ($modelType) { - $req->setTypePiece($modelType); - } - - $typeMachine->addPieceRequirement($req); - } - } - - private function replaceProductRequirements(TypeMachine $typeMachine, array $requirementsData): void - { - foreach ($typeMachine->getProductRequirements()->toArray() as $old) { - $typeMachine->removeProductRequirement($old); - } - - foreach ($requirementsData as $index => $data) { - $req = new TypeMachineProductRequirement(); - $req->setLabel($data['label'] ?? null); - $req->setMinCount($data['minCount'] ?? 0); - $req->setMaxCount($data['maxCount'] ?? null); - $req->setRequired($data['required'] ?? false); - $req->setAllowNewModels($data['allowNewModels'] ?? true); - $req->setOrderIndex($data['orderIndex'] ?? $index); - - $modelType = $this->resolveModelType($data['typeProduct'] ?? null); - if ($modelType) { - $req->setTypeProduct($modelType); - } - - $typeMachine->addProductRequirement($req); - } - } - - private function resolveModelType(mixed $value): ?ModelType - { - if (!$value) { - return null; - } - - $id = $value; - - if (is_string($value) && preg_match('#/api/model_types/(.+)$#', $value, $matches)) { - $id = $matches[1]; - } - - return $this->em->getReference(ModelType::class, $id); - } -}