merge relationship columns

This commit is contained in:
Yuri Kuznetsov
2025-02-06 10:40:49 +02:00
parent bdf81780f1
commit b35efdaec5
2 changed files with 87 additions and 2 deletions
@@ -46,6 +46,7 @@ use Espo\ORM\Entity;
use Espo\Entities\EmailAddress;
use Espo\Entities\PhoneNumber;
use Espo\ORM\Type\RelationType;
use stdClass;
class Merger
@@ -255,14 +256,24 @@ class Merger
private function updateRelations(Entity $sourceEntity, Entity $targetEntity, string $link): void
{
$entityType = $sourceEntity->getEntityType();
$columnAttributeMap = $this->getLinkColumnAttributeMap($entityType, $link);
$collection = $this->entityManager
->getRelation($sourceEntity, $link)
->find();
foreach ($collection as $relatedEntity) {
$map = null;
if ($columnAttributeMap) {
$map = array_map(fn ($attribute) => $relatedEntity->get($attribute), $columnAttributeMap);
}
$this->entityManager
->getRelation($targetEntity, $link)
->relate($relatedEntity);
->relate($relatedEntity, $map);
}
}
@@ -385,4 +396,35 @@ class Merger
}
}
}
/**
* @return ?array<string, string>
*/
private function getLinkColumnAttributeMap(string $entityType, string $link): ?array
{
$entityDefs = $this->entityManager
->getDefs()
->getEntity($entityType);
$columnAttributeMap = null;
$relationDefs = $entityDefs->tryGetRelation($link);
if (
$relationDefs &&
$relationDefs->getType() === RelationType::MANY_MANY &&
$relationDefs->hasForeignEntityType() &&
$relationDefs->hasForeignRelationName()
) {
$foreignRelationDefs = $this->entityManager
->getDefs()
->getEntity($relationDefs->getForeignEntityType())
->getRelation($relationDefs->getForeignRelationName());
/** ?@var array<string, string> $columnAttributeMap */
$columnAttributeMap = $foreignRelationDefs->getParam('columnAttributeMap');
}
return $columnAttributeMap;
}
}
+44 -1
View File
@@ -38,9 +38,11 @@ use Espo\Core\Field\EmailAddress;
use Espo\Core\Field\PhoneNumber;
use Espo\Core\ORM\EntityManager;
use Espo\Modules\Crm\Entities\Account;
use Espo\Modules\Crm\Entities\Contact;
use tests\integration\Core\BaseTestCase;
class ActionTest extends \tests\integration\Core\BaseTestCase
class ActionTest extends BaseTestCase
{
/** @var Application */
private $app;
@@ -273,6 +275,47 @@ class ActionTest extends \tests\integration\Core\BaseTestCase
);
}
public function testMergeRelationshipColumns(): void
{
$em = $this->getEntityManager();
$account = $em->getRDBRepositoryByClass(Account::class)->getNew();
$accountSource = $em->getRDBRepositoryByClass(Account::class)->getNew();
$contact = $em->getRDBRepositoryByClass(Contact::class)->getNew();
$em->saveEntity($account);
$em->saveEntity($accountSource);
$em->saveEntity($contact);
$em->getRelation($accountSource, 'contacts')
->relate($contact, [
'role' => 'Tester',
'isInactive' => true,
]);
$merger = $this->getInjectableFactory()->create(Merger::class);
/** @noinspection PhpUnhandledExceptionInspection */
$merger->process(
new Params(Account::ENTITY_TYPE, $account->getId()),
[$accountSource->getId()],
(object) []
);
$em->refreshEntity($account);
$relation = $em->getRelation($account, 'contacts');
$this->assertEquals(
'Tester',
$relation->getColumn($contact, 'role')
);
$this->assertTrue(
$relation->getColumn($contact, 'isInactive')
);
}
public function testMergeNoEditAccess(): void
{
$this->createUser('tester', [