mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-09-29 18:14:59 +00:00
Fixes
This commit is contained in:
@@ -12,202 +12,93 @@ declare(strict_types=1);
|
||||
namespace Chill\PersonBundle\Service\AccompanyingPeriodWork;
|
||||
|
||||
use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWork;
|
||||
use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWorkReferrerHistory;
|
||||
use Doctrine\DBAL\Exception;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Doctrine\ORM\Mapping\ClassMetadata;
|
||||
|
||||
/**
|
||||
* Service for merging two AccompanyingPeriodWork entities into a single entity.
|
||||
*/
|
||||
class AccompanyingPeriodWorkMergeService
|
||||
{
|
||||
public function __construct(private readonly EntityManagerInterface $em) {}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
* Merges two AccompanyingPeriodWork entities into one by transferring relevant data and removing the obsolete entity.
|
||||
*
|
||||
* @param AccompanyingPeriodWork $toKeep the entity to retain after the merge
|
||||
* @param AccompanyingPeriodWork $toDelete the entity to be removed after transferring data
|
||||
*
|
||||
* @return AccompanyingPeriodWork the kept accompanying period work
|
||||
*/
|
||||
public function merge(AccompanyingPeriodWork $toKeep, AccompanyingPeriodWork $toDelete): void
|
||||
public function merge(AccompanyingPeriodWork $toKeep, AccompanyingPeriodWork $toDelete): AccompanyingPeriodWork
|
||||
{
|
||||
$conn = $this->em->getConnection();
|
||||
$conn->beginTransaction();
|
||||
$this->em->wrapInTransaction(function (EntityManagerInterface $entityManager) use ($toKeep, $toDelete) {
|
||||
$this->alterStartDate($toKeep, $toDelete);
|
||||
$this->alterEndDate($toKeep, $toDelete);
|
||||
$this->concatenateComments($toKeep, $toDelete);
|
||||
$this->transferWorkflowsSQL($toKeep, $toDelete);
|
||||
$this->updateReferencesSQL($toKeep, $toDelete);
|
||||
$entityManager->remove($toDelete);
|
||||
});
|
||||
|
||||
try {
|
||||
$queries = array_merge(
|
||||
$this->updateReferencesSQL($toKeep, $toDelete),
|
||||
$this->transferWorkflowsSQL($toKeep, $toDelete),
|
||||
$this->generateStartDateSQL($toDelete, $toKeep),
|
||||
$this->generateEndDateSQL($toDelete, $toKeep),
|
||||
$this->generateCommentSQL($toDelete, $toKeep),
|
||||
$this->removeAccompanyingPeriodWork($toDelete)
|
||||
);
|
||||
|
||||
foreach ($queries as $query) {
|
||||
dump($query);
|
||||
$conn->executeStatement($query['sql'], $query['params']);
|
||||
}
|
||||
|
||||
$conn->commit();
|
||||
} catch (\Exception $e) {
|
||||
dump($e->getMessage());
|
||||
$conn->rollBack();
|
||||
throw $e;
|
||||
}
|
||||
return $toKeep;
|
||||
}
|
||||
|
||||
private function transferWorkflowsSQL(AccompanyingPeriodWork $toKeep, AccompanyingPeriodWork $toDelete): array
|
||||
private function transferWorkflowsSQL(AccompanyingPeriodWork $toKeep, AccompanyingPeriodWork $toDelete): void
|
||||
{
|
||||
$queries = [];
|
||||
$queries[] = [
|
||||
'sql' => "UPDATE chill_main_workflow_entity w
|
||||
$this->em->getConnection()->executeQuery(
|
||||
"UPDATE chill_main_workflow_entity w
|
||||
SET relatedentityid = :toKeepId
|
||||
WHERE w.relatedentityid = :toDeleteId
|
||||
AND w.relatedentityclass = 'Chill\\PersonBundle\\Entity\\AccompanyingPeriod\\AccompanyingPeriodWork'",
|
||||
'params' => ['toKeepId' => $toKeep->getId(), 'toDeleteId' => $toDelete->getId()],
|
||||
];
|
||||
|
||||
return $queries;
|
||||
['toKeepId' => $toKeep->getId(), 'toDeleteId' => $toDelete->getId()]
|
||||
);
|
||||
}
|
||||
|
||||
private function generateStartDateSQL(AccompanyingPeriodWork $toDelete, AccompanyingPeriodWork $toKeep): array
|
||||
private function alterStartDate(AccompanyingPeriodWork $toKeep, AccompanyingPeriodWork $toDelete): void
|
||||
{
|
||||
$queries = [];
|
||||
$queries[] = [
|
||||
'sql' => 'UPDATE chill_person_accompanying_period_work
|
||||
SET startdate = LEAST(
|
||||
COALESCE((SELECT startdate FROM chill_person_accompanying_period_work WHERE id = :toDelete), startdate),
|
||||
startdate
|
||||
)
|
||||
WHERE id = :toKeep',
|
||||
'params' => ['toDelete' => $toDelete->getId(), 'toKeep' => $toKeep->getId()],
|
||||
];
|
||||
|
||||
return $queries;
|
||||
$startDate = min($toKeep->getStartDate(), $toDelete->getStartDate());
|
||||
$toKeep->setStartDate($startDate);
|
||||
}
|
||||
|
||||
private function generateEndDateSQL(AccompanyingPeriodWork $toDelete, AccompanyingPeriodWork $toKeep): array
|
||||
private function alterEndDate(AccompanyingPeriodWork $toKeep, AccompanyingPeriodWork $toDelete): void
|
||||
{
|
||||
$queries = [];
|
||||
$queries[] = [
|
||||
'sql' => '
|
||||
UPDATE chill_person_accompanying_period_work
|
||||
SET enddate =
|
||||
CASE
|
||||
WHEN (SELECT enddate FROM chill_person_accompanying_period_work WHERE id = :toDelete) IS NULL
|
||||
OR enddate IS NULL
|
||||
THEN NULL
|
||||
ELSE GREATEST(
|
||||
COALESCE((SELECT enddate FROM chill_person_accompanying_period_work WHERE id = :toDelete), enddate),
|
||||
enddate
|
||||
)
|
||||
END
|
||||
WHERE id = :toKeep',
|
||||
'params' => ['toDelete' => $toDelete->getId(), 'toKeep' => $toKeep->getId()],
|
||||
if (null === $toKeep->getEndDate() || null === $toDelete->getEndDate()) {
|
||||
$toKeep->setEndDate(null);
|
||||
|
||||
];
|
||||
|
||||
return $queries;
|
||||
}
|
||||
|
||||
private function generateCommentSQL(AccompanyingPeriodWork $toDelete, AccompanyingPeriodWork $toKeep): array
|
||||
{
|
||||
$queries = [];
|
||||
$queries[] = [
|
||||
'sql' => "WITH updated_values AS (
|
||||
SELECT
|
||||
acpw1.id AS to_update,
|
||||
acpw1.note || ' ' || acpw2.note AS new_note,
|
||||
jsonb_set(
|
||||
acpw1.privatecomment_comments::jsonb,
|
||||
'{1}',
|
||||
to_jsonb((acpw1.privatecomment_comments::jsonb->>'1') || ' ' || (acpw2.privatecomment_comments::jsonb->>'1'))
|
||||
) AS new_privatecomment_comments
|
||||
FROM
|
||||
chill_person_accompanying_period_work acpw1,
|
||||
chill_person_accompanying_period_work acpw2
|
||||
WHERE
|
||||
acpw1.id = :toKeep AND
|
||||
acpw2.id = :toDelete
|
||||
)
|
||||
UPDATE chill_person_accompanying_period_work
|
||||
SET
|
||||
note = updated_values.new_note,
|
||||
privatecomment_comments = updated_values.new_privatecomment_comments
|
||||
FROM
|
||||
updated_values
|
||||
WHERE
|
||||
chill_person_accompanying_period_work.id = updated_values.to_update",
|
||||
'params' => ['toDelete' => $toDelete->getId(), 'toKeep' => $toKeep->getId()],
|
||||
];
|
||||
|
||||
return $queries;
|
||||
}
|
||||
|
||||
private function updateReferencesSQL(AccompanyingPeriodWork $toKeep, AccompanyingPeriodWork $toDelete): array
|
||||
{
|
||||
$queries = [];
|
||||
$allMeta = $this->em->getMetadataFactory()->getAllMetadata();
|
||||
|
||||
foreach ($allMeta as $meta) {
|
||||
if ($meta->isMappedSuperclass) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$tableName = $meta->getTableName();
|
||||
foreach ($meta->getAssociationMappings() as $assoc) {
|
||||
|
||||
if (AccompanyingPeriodWork::class !== $assoc['targetEntity'] && AccompanyingPeriodWork::class !== $assoc['sourceEntity']) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (($assoc['type'] & ClassMetadata::TO_ONE) !== 0) {
|
||||
$joinColumn = $meta->getSingleAssociationJoinColumnName($assoc['fieldName']);
|
||||
|
||||
if (AccompanyingPeriodWorkReferrerHistory::class === $assoc['sourceEntity']) {
|
||||
$queries[] = [
|
||||
'sql' => "DELETE FROM {$tableName} WHERE {$joinColumn} = :toDelete",
|
||||
'params' => ['toKeep' => $toKeep->getId(), 'toDelete' => $toDelete->getId()],
|
||||
];
|
||||
}
|
||||
|
||||
$queries[] = [
|
||||
'sql' => "UPDATE {$tableName} SET {$joinColumn} = :toKeep WHERE {$joinColumn} = :toDelete",
|
||||
'params' => ['toKeep' => $toKeep->getId(), 'toDelete' => $toDelete->getId()],
|
||||
];
|
||||
} elseif (8 === $assoc['type'] && isset($assoc['joinTable'])) {
|
||||
if ($assoc['isOwningSide']) {
|
||||
dump($assoc);
|
||||
$joinTable = $assoc['joinTable']['name'];
|
||||
$joinColumn = $assoc['joinTable']['joinColumns'][0]['name'];
|
||||
$relationColumn = $assoc['joinTable']['inverseJoinColumns'][0]['name'];
|
||||
$queries[] = [
|
||||
'sql' => "
|
||||
UPDATE {$joinTable} SET {$joinColumn} = :toKeep
|
||||
WHERE {$joinColumn} = :toDelete
|
||||
AND NOT EXISTS (
|
||||
SELECT 1
|
||||
FROM {$joinTable} AS t2
|
||||
WHERE t2.{$joinColumn} = :toKeep
|
||||
AND t2.{$relationColumn} = {$joinTable}.{$relationColumn}
|
||||
)
|
||||
",
|
||||
'params' => ['toDelete' => $toDelete->getId(), 'toKeep' => $toKeep->getId()],
|
||||
];
|
||||
|
||||
$queries[] = [
|
||||
'sql' => "DELETE FROM {$joinTable} WHERE {$joinColumn} = :toDelete",
|
||||
'params' => ['toDelete' => $toDelete->getId()],
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
return $queries;
|
||||
$endDate = max($toKeep->getEndDate(), $toDelete->getEndDate());
|
||||
$toKeep->setEndDate($endDate);
|
||||
}
|
||||
|
||||
public function removeAccompanyingPeriodWork(AccompanyingPeriodWork $toDelete): array
|
||||
private function concatenateComments(AccompanyingPeriodWork $toKeep, AccompanyingPeriodWork $toDelete): void
|
||||
{
|
||||
return [[
|
||||
'sql' => 'DELETE FROM chill_person_accompanying_period_work WHERE id = :toDelete',
|
||||
'params' => ['toDelete' => $toDelete->getId()],
|
||||
]];
|
||||
$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);
|
||||
}
|
||||
|
||||
foreach ($toDelete->getReferrers() as $referrer) {
|
||||
// we only keep the current referrer
|
||||
$toKeep->addReferrer($referrer);
|
||||
}
|
||||
|
||||
foreach ($toDelete->getPersons() as $person) {
|
||||
$toKeep->addPerson($person);
|
||||
}
|
||||
|
||||
if (null === $toKeep->getHandlingThierParty()) {
|
||||
$toKeep->setHandlingThierParty($toDelete->getHandlingThierParty());
|
||||
}
|
||||
|
||||
foreach ($toDelete->getThirdParties() as $thirdParty) {
|
||||
$toKeep->addThirdParty($thirdParty);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user