From 9027917ea207836fff740cdd5eec9d976adea724 Mon Sep 17 00:00:00 2001 From: Matthieu Date: Mon, 11 May 2026 16:22:28 +0200 Subject: [PATCH] fix(custom-fields) : propage le renommage d'un champ dans la formule de reference auto --- config/services.yaml | 5 ++ src/Service/SkeletonStructureService.php | 39 ++++++++++ .../Service/SkeletonStructureServiceTest.php | 76 +++++++++++++++++++ 3 files changed, 120 insertions(+) create mode 100644 tests/Service/SkeletonStructureServiceTest.php diff --git a/config/services.yaml b/config/services.yaml index d811e2d..1b1b920 100644 --- a/config/services.yaml +++ b/config/services.yaml @@ -69,3 +69,8 @@ when@test: autowire: true autoconfigure: true public: true + + App\Service\SkeletonStructureService: + autowire: true + autoconfigure: true + public: true diff --git a/src/Service/SkeletonStructureService.php b/src/Service/SkeletonStructureService.php index 2f1cd9a..2218a39 100644 --- a/src/Service/SkeletonStructureService.php +++ b/src/Service/SkeletonStructureService.php @@ -226,6 +226,13 @@ class SkeletonStructureService } if ($existingField) { + // Propagate rename to the parent ModelType's reference formula and required-fields list + // so existing `{oldName}` placeholders keep resolving after the field is renamed. + $oldName = $existingField->getName(); + if ($oldName !== $normalized['name']) { + $this->propagateCustomFieldRename($modelType, $oldName, $normalized['name']); + } + // Update existing field $existingField->setName($normalized['name']); $existingField->setType($normalized['type']); @@ -264,6 +271,38 @@ class SkeletonStructureService } } + private function propagateCustomFieldRename(ModelType $modelType, string $oldName, string $newName): void + { + $formula = $modelType->getReferenceFormula(); + if (null !== $formula && '' !== $formula) { + $newFormula = preg_replace( + '/\{'.preg_quote($oldName, '/').'\}/', + '{'.$newName.'}', + $formula + ); + if (null !== $newFormula && $newFormula !== $formula) { + $modelType->setReferenceFormula($newFormula); + } + } + + $required = $modelType->getRequiredFieldsForReference(); + if ($required) { + $changed = false; + $newRequired = []; + foreach ($required as $fieldName) { + if ($fieldName === $oldName) { + $newRequired[] = $newName; + $changed = true; + } else { + $newRequired[] = $fieldName; + } + } + if ($changed) { + $modelType->setRequiredFieldsForReference($newRequired); + } + } + } + /** * Normalize frontend custom field data to a common shape. * diff --git a/tests/Service/SkeletonStructureServiceTest.php b/tests/Service/SkeletonStructureServiceTest.php new file mode 100644 index 0000000..3661271 --- /dev/null +++ b/tests/Service/SkeletonStructureServiceTest.php @@ -0,0 +1,76 @@ +createModelType('Roulement', 'ROUL-RENAME', ModelCategory::PIECE); + $mt->setReferenceFormula('{material}-{size}'); + $mt->setRequiredFieldsForReference(['material', 'size']); + + $em = $this->getEntityManager(); + $em->flush(); + + $cfMaterial = $this->createCustomField('material', 'text', typePiece: $mt, orderIndex: 0); + $cfSize = $this->createCustomField('size', 'text', typePiece: $mt, orderIndex: 1); + + /** @var SkeletonStructureService $service */ + $service = static::getContainer()->get(SkeletonStructureService::class); + + // Same fields, but `material` is renamed to `materiau` (matched by customFieldId) + $service->updateSkeletonRequirements($mt, [ + 'customFields' => [ + ['customFieldId' => $cfMaterial->getId(), 'name' => 'materiau', 'type' => 'text', 'orderIndex' => 0], + ['customFieldId' => $cfSize->getId(), 'name' => 'size', 'type' => 'text', 'orderIndex' => 1], + ], + ]); + + $em->flush(); + $em->refresh($mt); + $em->refresh($cfMaterial); + + self::assertSame('materiau', $cfMaterial->getName()); + self::assertSame('{materiau}-{size}', $mt->getReferenceFormula()); + self::assertSame(['materiau', 'size'], $mt->getRequiredFieldsForReference()); + } + + public function testRenameLeavesFormulaUnchangedWhenFieldNotInFormula(): void + { + $mt = $this->createModelType('Roulement2', 'ROUL-RENAME2', ModelCategory::PIECE); + $mt->setReferenceFormula('{material}'); + $mt->setRequiredFieldsForReference(['material']); + + $em = $this->getEntityManager(); + $em->flush(); + + $cfMaterial = $this->createCustomField('material', 'text', typePiece: $mt, orderIndex: 0); + $cfUnused = $this->createCustomField('unused', 'text', typePiece: $mt, orderIndex: 1); + + /** @var SkeletonStructureService $service */ + $service = static::getContainer()->get(SkeletonStructureService::class); + + $service->updateSkeletonRequirements($mt, [ + 'customFields' => [ + ['customFieldId' => $cfMaterial->getId(), 'name' => 'material', 'type' => 'text', 'orderIndex' => 0], + ['customFieldId' => $cfUnused->getId(), 'name' => 'renamed', 'type' => 'text', 'orderIndex' => 1], + ], + ]); + + $em->flush(); + $em->refresh($mt); + + self::assertSame('{material}', $mt->getReferenceFormula()); + self::assertSame(['material'], $mt->getRequiredFieldsForReference()); + } +}