From 246546b313c8eb66311fa692315d201033a0b684 Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Tue, 20 May 2025 12:38:24 +0200 Subject: [PATCH 1/4] Retrieve schema to form full tablename and construct sql statements correctly in thirdparty merge service --- .../Service/ThirdpartyMergeService.php | 38 +++++++++++++++---- 1 file changed, 31 insertions(+), 7 deletions(-) diff --git a/src/Bundle/ChillThirdPartyBundle/Service/ThirdpartyMergeService.php b/src/Bundle/ChillThirdPartyBundle/Service/ThirdpartyMergeService.php index 6c0014a2d..ec8a134e6 100644 --- a/src/Bundle/ChillThirdPartyBundle/Service/ThirdpartyMergeService.php +++ b/src/Bundle/ChillThirdPartyBundle/Service/ThirdpartyMergeService.php @@ -52,32 +52,33 @@ class ThirdpartyMergeService } $tableName = $meta->getTableName(); + $schema = $meta->getSchemaName(); + $fullTableName = $this->getFullTableName($tableName, $schema); + foreach ($meta->getAssociationMappings() as $assoc) { if (ThirdParty::class !== $assoc['targetEntity']) { continue; } - // phpstan wants boolean for if condition if (($assoc['type'] & ClassMetadata::TO_ONE) !== 0) { $joinColumn = $meta->getSingleAssociationJoinColumnName($assoc['fieldName']); - $suffix = (ThirdParty::class === $assoc['sourceEntity']) ? 'chill_3party.' : ''; - $queries[] = [ - 'sql' => "UPDATE {$suffix}{$tableName} SET {$joinColumn} = :toKeep WHERE {$joinColumn} = :toDelete", + 'sql' => "UPDATE {$fullTableName} SET {$joinColumn} = :toKeep WHERE {$joinColumn} = :toDelete", 'params' => ['toKeep' => $toKeep->getId(), 'toDelete' => $toDelete->getId()], ]; } elseif (ClassMetadata::MANY_TO_MANY === $assoc['type'] && isset($assoc['joinTable'])) { $joinTable = $assoc['joinTable']['name']; - $prefix = null !== ($assoc['joinTable']['schema'] ?? null) ? $assoc['joinTable']['schema'].'.' : ''; + $joinSchema = $assoc['joinTable']['schema'] ?? null; + $fullJoinTable = $this->getFullTableName($joinTable, $joinSchema); $joinColumn = $assoc['joinTable']['inverseJoinColumns'][0]['name']; $queries[] = [ - 'sql' => "UPDATE {$prefix}{$joinTable} SET {$joinColumn} = :toKeep WHERE {$joinColumn} = :toDelete AND NOT EXISTS (SELECT 1 FROM {$prefix}{$joinTable} WHERE {$joinColumn} = :toKeep)", + 'sql' => "UPDATE {$fullJoinTable} SET {$joinColumn} = :toKeep WHERE {$joinColumn} = :toDelete AND NOT EXISTS (SELECT 1 FROM {$fullJoinTable} WHERE {$joinColumn} = :toKeep)", 'params' => ['toDelete' => $toDelete->getId(), 'toKeep' => $toKeep->getId()], ]; $queries[] = [ - 'sql' => "DELETE FROM {$joinTable} WHERE {$joinColumn} = :toDelete", + 'sql' => "DELETE FROM {$fullJoinTable} WHERE {$joinColumn} = :toDelete", 'params' => ['toDelete' => $toDelete->getId()], ]; } @@ -104,4 +105,27 @@ class ThirdpartyMergeService ], ]; } + + // Helper method to retrieve full table name of the different associations + // (e.g. "chill_3party.third_party" or "public.chill_3party.third_party") + // + // If the table name is already schema-qualified, it is returned as-is. + // + // If the table name is not schema-qualified, it is prefixed with the + // schema name of the target entity (e.g. "public.chill_3party.third_party"). + // + // If the table name is not schema-qualified and the target entity has no + // schema name, the table name is prefixed with "public". + private function getFullTableName(string $tableName, ?string $schema): string + { + if ($schema !== null) { + return "{$schema}.{$tableName}"; + } + + if (str_contains($tableName, '.')) { + return $tableName; + } + + return "public.{$tableName}"; + } } From 2c01516f719189d65a7a94088c4431d653f44bc6 Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Tue, 20 May 2025 14:00:34 +0200 Subject: [PATCH 2/4] add changie --- .changes/unreleased/Fixed-20250520-140008.yaml | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .changes/unreleased/Fixed-20250520-140008.yaml diff --git a/.changes/unreleased/Fixed-20250520-140008.yaml b/.changes/unreleased/Fixed-20250520-140008.yaml new file mode 100644 index 000000000..695e86e1a --- /dev/null +++ b/.changes/unreleased/Fixed-20250520-140008.yaml @@ -0,0 +1,6 @@ +kind: Fixed +body: Fix retrieve schema to form full tablename and construct sql statements correctly in Thirdparty merger. +time: 2025-05-20T14:00:08.987229634+02:00 +custom: + Issue: "" + SchemaChange: No schema change From 9a3fef862e82072ad6d9a9c2eaa92e39efc8da3b Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Tue, 20 May 2025 14:05:02 +0200 Subject: [PATCH 3/4] Add missing translation accompanying period work duplicate controller --- .changes/unreleased/Fixed-20250520-140433.yaml | 6 ++++++ src/Bundle/ChillPersonBundle/translations/messages.fr.yml | 1 + 2 files changed, 7 insertions(+) create mode 100644 .changes/unreleased/Fixed-20250520-140433.yaml diff --git a/.changes/unreleased/Fixed-20250520-140433.yaml b/.changes/unreleased/Fixed-20250520-140433.yaml new file mode 100644 index 000000000..2dafa1d0e --- /dev/null +++ b/.changes/unreleased/Fixed-20250520-140433.yaml @@ -0,0 +1,6 @@ +kind: Fixed +body: Fix add missing translation +time: 2025-05-20T14:04:33.612140549+02:00 +custom: + Issue: "" + SchemaChange: No schema change diff --git a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml index a4f8ec33f..11ef65c6c 100644 --- a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml @@ -1509,3 +1509,4 @@ acpw_duplicate: to keep: Action d'accompagnement à conserver to delete: Action d'accompagnement à supprimer Successfully merged: Action d'accompagnement fusionnée avec succès. + You cannot merge a accompanying period work with itself. Please choose a different one: Vous ne pouvez pas fusionner un action d'accompagnement avec lui-même. Veuillez en choisir un autre. From 26fd16ab07ca6992c2620ea4b7ff5faf47b4aa75 Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Tue, 20 May 2025 16:43:39 +0200 Subject: [PATCH 4/4] Transfer evaluations (and related documents) during merge --- .../unreleased/Fixed-20250520-164429.yaml | 6 ++++ .../AccompanyingPeriodWorkMergeService.php | 34 +++++++++++++------ 2 files changed, 29 insertions(+), 11 deletions(-) create mode 100644 .changes/unreleased/Fixed-20250520-164429.yaml diff --git a/.changes/unreleased/Fixed-20250520-164429.yaml b/.changes/unreleased/Fixed-20250520-164429.yaml new file mode 100644 index 000000000..453094763 --- /dev/null +++ b/.changes/unreleased/Fixed-20250520-164429.yaml @@ -0,0 +1,6 @@ +kind: Fixed +body: Fix the transfer of evaluations and documents during of accompanyingperiodwork +time: 2025-05-20T16:44:29.093304653+02:00 +custom: + Issue: "" + SchemaChange: No schema change diff --git a/src/Bundle/ChillPersonBundle/Service/AccompanyingPeriodWork/AccompanyingPeriodWorkMergeService.php b/src/Bundle/ChillPersonBundle/Service/AccompanyingPeriodWork/AccompanyingPeriodWorkMergeService.php index ba0f93ce3..490798171 100644 --- a/src/Bundle/ChillPersonBundle/Service/AccompanyingPeriodWork/AccompanyingPeriodWorkMergeService.php +++ b/src/Bundle/ChillPersonBundle/Service/AccompanyingPeriodWork/AccompanyingPeriodWorkMergeService.php @@ -17,9 +17,9 @@ use Doctrine\ORM\EntityManagerInterface; /** * Service for merging two AccompanyingPeriodWork entities into a single entity. */ -class AccompanyingPeriodWorkMergeService +readonly class AccompanyingPeriodWorkMergeService { - public function __construct(private readonly EntityManagerInterface $em) {} + public function __construct(private EntityManagerInterface $em) {} /** * Merges two AccompanyingPeriodWork entities into one by transferring relevant data and removing the obsolete entity. @@ -35,8 +35,9 @@ class AccompanyingPeriodWorkMergeService $this->alterStartDate($toKeep, $toDelete); $this->alterEndDate($toKeep, $toDelete); $this->concatenateComments($toKeep, $toDelete); + $this->transferEvaluationsSQL($toKeep, $toDelete); $this->transferWorkflowsSQL($toKeep, $toDelete); - $this->updateReferencesSQL($toKeep, $toDelete); + $this->updateReferences($toKeep, $toDelete); $entityManager->remove($toDelete); }); @@ -54,6 +55,16 @@ class AccompanyingPeriodWorkMergeService ); } + private function transferEvaluationsSQL(AccompanyingPeriodWork $toKeep, AccompanyingPeriodWork $toDelete): void + { + $this->em->getConnection()->executeQuery( + "UPDATE chill_person_accompanying_period_work_evaluation cpapwe + SET accompanyingperiodwork_id = :toKeepId + WHERE cpapwe.accompanyingperiodwork_id = :toDeleteId", + ['toKeepId' => $toKeep->getId(), 'toDeleteId' => $toDelete->getId()] + ); + } + private function alterStartDate(AccompanyingPeriodWork $toKeep, AccompanyingPeriodWork $toDelete): void { $startDate = min($toKeep->getStartDate(), $toDelete->getStartDate()); @@ -74,16 +85,17 @@ class AccompanyingPeriodWorkMergeService private function concatenateComments(AccompanyingPeriodWork $toKeep, AccompanyingPeriodWork $toDelete): void { - $toKeep->setNote($toKeep->getNote()."\n\n-----------------\n\n".$toDelete->getNote()); - $toKeep->getPrivateComment()->concatenateComments($toDelete->getPrivateComment()); - } - - private function updateReferencesSQL(AccompanyingPeriodWork $toKeep, AccompanyingPeriodWork $toDelete): void - { - foreach ($toDelete->getAccompanyingPeriodWorkEvaluations() as $evaluation) { - $toKeep->addAccompanyingPeriodWorkEvaluation($evaluation); + if ($toDelete->getNote() !== '') { + $toKeep->setNote($toKeep->getNote()."\n\n-----------------\n\n".$toDelete->getNote()); } + if (count($toDelete->getPrivateComment()->getComments()) > 0) { + $toKeep->getPrivateComment()->concatenateComments($toDelete->getPrivateComment()); + } + } + + private function updateReferences(AccompanyingPeriodWork $toKeep, AccompanyingPeriodWork $toDelete): void + { foreach ($toDelete->getReferrers() as $referrer) { // we only keep the current referrer $toKeep->addReferrer($referrer);