diff --git a/application/Espo/Core/Record/Defaults/DefaultPopulator.php b/application/Espo/Core/Record/Defaults/DefaultPopulator.php index ea8c8b447a..1a6b9384cc 100644 --- a/application/Espo/Core/Record/Defaults/DefaultPopulator.php +++ b/application/Espo/Core/Record/Defaults/DefaultPopulator.php @@ -33,11 +33,17 @@ use Espo\Core\Acl; use Espo\Core\Acl\Permission; use Espo\Core\Acl\Table as AclTable; use Espo\Core\Currency\ConfigDataProvider as CurrencyConfigDataProvider; +use Espo\Core\Field\Link; +use Espo\Core\Field\LinkMultiple; +use Espo\Core\Field\LinkMultipleItem; use Espo\Core\Name\Field; use Espo\Core\ORM\Entity as CoreEntity; use Espo\Core\ORM\Type\FieldType; use Espo\Core\Utils\FieldUtil; +use Espo\Core\Utils\Metadata; use Espo\Entities\User; +use Espo\Modules\Crm\Entities\Account; +use Espo\Modules\Crm\Entities\Contact; use Espo\ORM\Defs\Params\FieldParam; use Espo\ORM\Entity; use Espo\ORM\EntityManager; @@ -54,6 +60,7 @@ class DefaultPopulator implements Populator private FieldUtil $fieldUtil, private EntityManager $entityManager, private CurrencyConfigDataProvider $currencyConfig, + private Metadata $metadata, ) {} public function populate(Entity $entity): void @@ -61,6 +68,7 @@ class DefaultPopulator implements Populator $this->processAssignedUser($entity); $this->processDefaultTeam($entity); $this->processCurrency($entity); + $this->processPortal($entity); } /** @@ -136,11 +144,11 @@ class DefaultPopulator implements Populator foreach ($this->fieldUtil->getEntityTypeFieldList($entityType) as $field) { $type = $this->fieldUtil->getEntityTypeFieldParam($entityType, $field, FieldParam::TYPE); - if ( - $type === FieldType::CURRENCY && - $entity->get($field) && - !$entity->get($field . 'Currency') - ) { + if ($type !== FieldType::CURRENCY) { + continue; + } + + if ($entity->get($field) && !$entity->get($field . 'Currency')) { $entity->set($field . 'Currency', $this->currencyConfig->getDefaultCurrency()); } } @@ -180,4 +188,89 @@ class DefaultPopulator implements Populator $entity->set(Field::ASSIGNED_USER . 'Id', $this->user->getId()); $entity->set(Field::ASSIGNED_USER . 'Name', $this->user->getName()); } + + private function processPortal(Entity $entity): void + { + if (!$this->user->isPortal()) { + return; + } + + $this->processPortalAccount($entity); + $this->processPortalContact($entity); + } + + private function processPortalAccount(Entity $entity): void + { + /** @var ?string $link */ + $link = $this->metadata->get("aclDefs.{$entity->getEntityType()}.accountLink"); + + if (!$link) { + return; + } + + $account = $this->user->getContact()?->getAccount(); + + if (!$account) { + return; + } + + $this->processPortalRecord($entity, $link, $account); + } + + private function processPortalContact(Entity $entity): void + { + /** @var ?string $link */ + $link = $this->metadata->get("aclDefs.{$entity->getEntityType()}.contactLink"); + + if (!$link) { + return; + } + + $contact = $this->user->getContact(); + + if (!$contact) { + return; + } + + $this->processPortalRecord($entity, $link, $contact); + } + + private function processPortalRecord(Entity $entity, string $link, Account|Contact $record): void + { + if (!$entity instanceof CoreEntity) { + return; + } + + $fieldDefs = $this->entityManager + ->getDefs() + ->getEntity($entity->getEntityType()) + ->tryGetField($link); + + if (!$fieldDefs) { + return; + } + + if ( + $fieldDefs->getType() === FieldType::LINK || + $fieldDefs->getType() === FieldType::LINK_ONE + ) { + if ($entity->has($link . 'Id')) { + return; + } + + $entity->setValueObject($link, Link::create($record->getId(), $record->getName())); + + return; + } + + if ($fieldDefs->getType() === FieldType::LINK_MULTIPLE) { + if ($entity->has($link . 'Ids')) { + return; + } + + $linkMultiple = LinkMultiple::create([LinkMultipleItem::create($record->getId(), $record->getName())]); + + $entity->setValueObject($link, $linkMultiple); + } + } } diff --git a/tests/integration/Espo/Record/DefaultsPopulatorTest.php b/tests/integration/Espo/Record/DefaultsPopulatorTest.php new file mode 100644 index 0000000000..5212b4eef1 --- /dev/null +++ b/tests/integration/Espo/Record/DefaultsPopulatorTest.php @@ -0,0 +1,91 @@ +. + * + * The interactive user interfaces in modified source and object code versions + * of this program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU Affero General Public License version 3. + * + * In accordance with Section 7(b) of the GNU Affero General Public License version 3, + * these Appropriate Legal Notices must retain the display of the "EspoCRM" word. + ************************************************************************/ + +namespace tests\integration\Espo\Record; + +use Espo\Core\Acl\Table; +use Espo\Core\Exceptions\BadRequest; +use Espo\Core\Exceptions\Conflict; +use Espo\Core\Exceptions\Forbidden; +use Espo\Core\Record\CreateParams; +use Espo\Core\Record\ServiceContainer; +use Espo\Entities\Portal; +use Espo\Modules\Crm\Entities\Account; +use Espo\Modules\Crm\Entities\CaseObj; +use Espo\Modules\Crm\Entities\Contact; +use tests\integration\Core\BaseTestCase; + +class DefaultsPopulatorTest extends BaseTestCase +{ + /** + * @throws BadRequest + * @throws Forbidden + * @throws Conflict + */ + public function testPortal(): void + { + $em = $this->getEntityManager(); + + $account = $em->getRDBRepositoryByClass(Account::class)->getNew(); + $em->saveEntity($account); + + $contact = $em->getRDBRepositoryByClass(Contact::class)->getNew(); + $contact->setAccount($account); + $em->saveEntity($contact); + + $portal = $em->getRDBRepositoryByClass(Portal::class)->getNew(); + $em->saveEntity($portal); + + $this->createUser([ + 'userName' => 'tester', + 'portalsIds' => [$portal->getId()], + 'contactId' => $contact->getId(), + 'accountsIds' => [$account->getId()], + ], [ + 'data' => [ + 'Case' => [ + 'create' => Table::LEVEL_YES, + 'read' => 'contact', + ], + ], + ], true); + + $this->auth('tester', null, $portal->getId()); + $this->reCreateApplication();; + + $service = $this->getContainer()->getByClass(ServiceContainer::class)->getByClass(CaseObj::class); + + $case = $service->create((object) [ + 'name' => 'Test', + ], CreateParams::create()); + + $this->assertEquals($contact->getId(), $case->getContact()?->getId()); + $this->assertEquals($account->getId(), $case->getAccount()?->getId()); + } +}