diff --git a/application/Espo/Core/Entities/Person.php b/application/Espo/Core/Entities/Person.php index ad24b58416..6ab165a5e4 100644 --- a/application/Espo/Core/Entities/Person.php +++ b/application/Espo/Core/Entities/Person.php @@ -36,6 +36,7 @@ use Espo\Core\ORM\Entity; use Espo\Core\ORM\Helper; use Espo\ORM\EntityManager; +use Espo\ORM\Relation\Relations; use Espo\ORM\Value\ValueAccessorFactory; class Person extends Entity @@ -47,9 +48,16 @@ class Person extends Entity array $defs, EntityManager $entityManager, Helper $helper, - ?ValueAccessorFactory $valueAccessorFactory = null + ?ValueAccessorFactory $valueAccessorFactory = null, + ?Relations $relations = null, ) { - parent::__construct($entityType, $defs, $entityManager, $valueAccessorFactory); + parent::__construct( + $entityType, + $defs, + $entityManager, + $valueAccessorFactory, + $relations + ); $this->helper = $helper; } diff --git a/application/Espo/Core/ORM/Repositories/RDB.php b/application/Espo/Core/ORM/Repositories/RDB.php index 84bb9568e9..1fc38a71b2 100644 --- a/application/Espo/Core/ORM/Repositories/RDB.php +++ b/application/Espo/Core/ORM/Repositories/RDB.php @@ -37,6 +37,7 @@ use Espo\Core\HookManager; use Espo\Core\Utils\Id\RecordIdGenerator; use Espo\Core\Utils\Metadata; use Espo\Core\Utils\SystemUser; +use Espo\ORM\Relation\RelationsMap; /** * @deprecated As of v6.0. Not to be extended. Extend Espo\Core\Repositories\Database, or better @@ -97,7 +98,8 @@ class RDB extends \Espo\Core\Repositories\Database implements Injectable /** @ph HookManager $hookManager, ApplicationState $applicationState, RecordIdGenerator $recordIdGenerator, - SystemUser $systemUser + SystemUser $systemUser, + ?RelationsMap $relationsMap, ) { parent::__construct( $entityType, @@ -107,7 +109,8 @@ class RDB extends \Espo\Core\Repositories\Database implements Injectable /** @ph $hookManager, $applicationState, $recordIdGenerator, - $systemUser + $systemUser, + $relationsMap ); $this->init(); diff --git a/application/Espo/Core/Repositories/Database.php b/application/Espo/Core/Repositories/Database.php index a9cde87a1b..b840119585 100644 --- a/application/Espo/Core/Repositories/Database.php +++ b/application/Espo/Core/Repositories/Database.php @@ -33,6 +33,7 @@ use Espo\Core\ORM\Repository\Option\SaveOption; use Espo\Core\Utils\SystemUser; use Espo\ORM\BaseEntity; use Espo\ORM\Entity; +use Espo\ORM\Relation\RelationsMap; use Espo\ORM\Repository\RDBRepository; use Espo\Core\ORM\EntityFactory; use Espo\Core\ORM\EntityManager; @@ -84,7 +85,8 @@ class Database extends RDBRepository HookManager $hookManager, ApplicationState $applicationState, RecordIdGenerator $recordIdGenerator, - private SystemUser $systemUser + private SystemUser $systemUser, + ?RelationsMap $relationsMap, ) { $this->metadata = $metadata; $this->hookManager = $hookManager; @@ -99,7 +101,7 @@ class Database extends RDBRepository $hookMediator = new HookMediator($hookManager); } - parent::__construct($entityType, $entityManager, $entityFactory, $hookMediator); + parent::__construct($entityType, $entityManager, $entityFactory, $hookMediator, $relationsMap); } /** diff --git a/application/Espo/Modules/Crm/Entities/Call.php b/application/Espo/Modules/Crm/Entities/Call.php index dddc021caf..179853ee2d 100644 --- a/application/Espo/Modules/Crm/Entities/Call.php +++ b/application/Espo/Modules/Crm/Entities/Call.php @@ -32,6 +32,7 @@ namespace Espo\Modules\Crm\Entities; use Espo\Core\Field\DateTime; use Espo\Core\Field\Link; use Espo\Core\Field\LinkMultiple; +use Espo\Core\Field\LinkParent; use Espo\Core\ORM\Entity; class Call extends Entity @@ -126,4 +127,17 @@ class Call extends Entity /** @var LinkMultiple */ return $this->getValueObject('leads'); } + + public function setParent(Entity|LinkParent|null $parent): self + { + if ($parent instanceof LinkParent) { + $this->setValueObject('parent', $parent); + + return $this; + } + + $this->relations->set('parent', $parent); + + return $this; + } } diff --git a/application/Espo/Modules/Crm/Entities/Lead.php b/application/Espo/Modules/Crm/Entities/Lead.php index 410a3c04ed..5e89b76239 100644 --- a/application/Espo/Modules/Crm/Entities/Lead.php +++ b/application/Espo/Modules/Crm/Entities/Lead.php @@ -143,4 +143,11 @@ class Lead extends \Espo\Core\Entities\Person return $this; } + + public function setCreatedAccount(Account|null $createdAccount): self + { + $this->relations->set('createdAccount', $createdAccount); + + return $this; + } } diff --git a/application/Espo/Modules/Crm/Entities/Meeting.php b/application/Espo/Modules/Crm/Entities/Meeting.php index ac78a1d867..2a02f6b4e5 100644 --- a/application/Espo/Modules/Crm/Entities/Meeting.php +++ b/application/Espo/Modules/Crm/Entities/Meeting.php @@ -32,6 +32,7 @@ namespace Espo\Modules\Crm\Entities; use Espo\Core\Field\DateTimeOptional; use Espo\Core\Field\Link; use Espo\Core\Field\LinkMultiple; +use Espo\Core\Field\LinkParent; use Espo\Core\ORM\Entity; class Meeting extends Entity @@ -131,4 +132,17 @@ class Meeting extends Entity /** @var LinkMultiple */ return $this->getValueObject('leads'); } + + public function setParent(Entity|LinkParent|null $parent): self + { + if ($parent instanceof LinkParent) { + $this->setValueObject('parent', $parent); + + return $this; + } + + $this->relations->set('parent', $parent); + + return $this; + } } diff --git a/application/Espo/Modules/Crm/Entities/Opportunity.php b/application/Espo/Modules/Crm/Entities/Opportunity.php index 686aa10ee2..f2fac77072 100644 --- a/application/Espo/Modules/Crm/Entities/Opportunity.php +++ b/application/Espo/Modules/Crm/Entities/Opportunity.php @@ -137,4 +137,17 @@ class Opportunity extends Entity /** @var LinkMultiple */ return $this->getValueObject('teams'); } + + public function setAccount(Account|Link|null $account): self + { + if ($account instanceof Link) { + $this->setValueObject('account', $account); + + return $this; + } + + $this->relations->set('account', $account); + + return $this; + } } diff --git a/application/Espo/Modules/Crm/Entities/Task.php b/application/Espo/Modules/Crm/Entities/Task.php index 2c67e3e302..faf6af7c6e 100644 --- a/application/Espo/Modules/Crm/Entities/Task.php +++ b/application/Espo/Modules/Crm/Entities/Task.php @@ -32,6 +32,7 @@ namespace Espo\Modules\Crm\Entities; use Espo\Core\Field\DateTimeOptional; use Espo\Core\Field\Link; use Espo\Core\Field\LinkMultiple; +use Espo\Core\Field\LinkParent; use Espo\Core\ORM\Entity; class Task extends Entity @@ -91,4 +92,17 @@ class Task extends Entity /** @var string[] */ return $this->getLinkMultipleIdList('attachments'); } + + public function setParent(Entity|LinkParent|null $parent): self + { + if ($parent instanceof LinkParent) { + $this->setValueObject('parent', $parent); + + return $this; + } + + $this->relations->set('parent', $parent); + + return $this; + } } diff --git a/tests/integration/Espo/ORM/RelationsTest.php b/tests/integration/Espo/ORM/RelationsTest.php index cb92d3207f..d729915051 100644 --- a/tests/integration/Espo/ORM/RelationsTest.php +++ b/tests/integration/Espo/ORM/RelationsTest.php @@ -29,9 +29,12 @@ namespace tests\integration\Espo\ORM; +use Espo\Modules\Crm\Entities\Lead; +use Espo\Modules\Crm\Entities\Task; use Espo\ORM\EntityCollection; use Espo\Modules\Crm\Entities\Account; use Espo\Modules\Crm\Entities\Opportunity; +use Espo\ORM\Repository\Option\SaveOption; use tests\integration\Core\BaseTestCase; use tests\integration\testClasses\Entities\Account as AccountExtended; use tests\integration\testClasses\Entities\Opportunity as OpportunityExtended; @@ -113,4 +116,80 @@ class RelationsTest extends BaseTestCase $this->assertCount(2, $items); } + + public function testSet(): void + { + $metadata = $this->getMetadata(); + $metadata->set('entityDefs', Account::ENTITY_TYPE, [ + 'entityClassName' => AccountExtended::class, + ]); + $metadata->save(); + + $this->reCreateApplication(); + + $em = $this->getEntityManager(); + + /** @var Account $account */ + $account = $em->createEntity(Account::ENTITY_TYPE); + + // belongsTo + + $opp = $em->getRDBRepositoryByClass(Opportunity::class)->getNew(); + $opp->setAccount($account); + $em->saveEntity($opp, [SaveOption::SKIP_ALL => true]); + $em->refreshEntity($opp); + + $this->assertEquals($account->getId(), $opp->getAccount()->getId()); + + $opp->setAccount(null); + $em->saveEntity($opp, [SaveOption::SKIP_ALL => true]); + $em->refreshEntity($opp); + + $this->assertNull($opp->getAccount()); + + // belongsToParent + + $task = $em->getRDBRepositoryByClass(Task::class)->getNew(); + $task->setParent($account); + $em->saveEntity($task, [SaveOption::SKIP_ALL => true]); + $em->refreshEntity($task); + + $this->assertEquals($account->getId(), $task->get('parentId')); + $this->assertEquals($account->getEntityType(), $task->get('parentType')); + + $task = $em->getRDBRepositoryByClass(Task::class)->getNew(); + $task->setParent(null); + $em->saveEntity($task, [SaveOption::SKIP_ALL => true]); + $em->refreshEntity($task); + + $this->assertNull($task->get('parentId')); + $this->assertNull($task->get('parentType')); + + // belongsTo hasOne + + $lead1 = $em->getRDBRepositoryByClass(Lead::class)->getNew(); + $lead1->setCreatedAccount($account); + $em->saveEntity($lead1, [SaveOption::SKIP_ALL => true]); + $em->refreshEntity($lead1); + + $this->assertEquals($account->getId(), $lead1->get('createdAccountId')); + + $lead2 = $em->getRDBRepositoryByClass(Lead::class)->getNew(); + $lead2->setCreatedAccount($account); + $em->saveEntity($lead2, [SaveOption::SKIP_ALL => true]); + $em->refreshEntity($lead2); + + $this->assertEquals($account->getId(), $lead2->get('createdAccountId')); + + $em->refreshEntity($lead1); + + $this->assertEquals(null, $lead1->get('createdAccountId')); + + $lead2->setCreatedAccount(null); + $em->saveEntity($lead2); + + // hasOne + + + } } diff --git a/tests/integration/testClasses/Entities/Account.php b/tests/integration/testClasses/Entities/Account.php index 16b7561f4c..b792fe328b 100644 --- a/tests/integration/testClasses/Entities/Account.php +++ b/tests/integration/testClasses/Entities/Account.php @@ -29,6 +29,7 @@ namespace tests\integration\testClasses\Entities; +use Espo\Modules\Crm\Entities\Lead; use Espo\ORM\EntityCollection; class Account extends \Espo\Modules\Crm\Entities\Account @@ -37,4 +38,9 @@ class Account extends \Espo\Modules\Crm\Entities\Account { return $this->relations->getMany('opportunities'); } + + public function setRelatedOriginalLead(?Lead $lead): void + { + $this->relations->set('originalLead', $lead); + } }