From 8b5f5e0d9df8d252eb88172b1195453fe1faf7d2 Mon Sep 17 00:00:00 2001 From: KarlsonComplete Date: Sat, 22 Feb 2025 22:04:47 +0300 Subject: [PATCH 01/49] =?UTF-8?q?-=20=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8?= =?UTF-8?q?=D0=BB=20=D1=81=D1=83=D1=89=D0=BD=D0=BE=D1=81=D1=82=D1=8C=20App?= =?UTF-8?q?licationInstallation.php?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Entity/ApplicationInstallation.php | 179 ++++++++++++++++++ 1 file changed, 179 insertions(+) create mode 100644 src/ApplicationInstallations/Entity/ApplicationInstallation.php diff --git a/src/ApplicationInstallations/Entity/ApplicationInstallation.php b/src/ApplicationInstallations/Entity/ApplicationInstallation.php new file mode 100644 index 0000000..7cc06fb --- /dev/null +++ b/src/ApplicationInstallations/Entity/ApplicationInstallation.php @@ -0,0 +1,179 @@ +id; + } + + #[\Override] + public function getCreatedAt(): CarbonImmutable + { + return $this->createdAt; + } + + #[\Override] + public function getUpdatedAt(): CarbonImmutable + { + return $this->updatedAt; + } + + #[\Override] + public function getBitrix24AccountId(): Uuid + { + return $this->bitrix24AccountId; + } + + #[\Override] + public function getContactPersonId(): ?Uuid + { + return $this->contactPersonId; + } + + #[\Override] + public function changeContactPerson(?Uuid $uuid): void + { + // TODO: Implement changeContactPerson() method. + } + + #[\Override] + public function getBitrix24PartnerContactPersonId(): ?Uuid + { + return $this->bitrix24PartnerContactPersonId; + } + + #[\Override] + public function changeBitrix24PartnerContactPerson(?Uuid $uuid): void + { + // TODO: Implement changeBitrix24PartnerContactPerson() method. + } + + #[\Override] + public function getBitrix24PartnerId(): ?Uuid + { + return $this->bitrix24PartnerId; + } + + #[\Override] + public function changeBitrix24Partner(?Uuid $uuid): void + { + // TODO: Implement changeBitrix24Partner() method. + } + + #[\Override] + public function getExternalId(): ?string + { + return $this->externalId; + } + + #[\Override] + public function setExternalId(?string $externalId): void + { + $this->externalId = $externalId; + } + + #[\Override] + public function getStatus(): ApplicationInstallationStatus + { + return $this->status; + } + + #[\Override] + public function applicationInstalled(): void + { + // TODO: Implement applicationInstalled() method. + } + + #[\Override] + public function applicationUninstalled(): void + { + // TODO: Implement applicationUninstalled() method. + } + + #[\Override] + public function markAsActive(?string $comment): void + { + // TODO: Implement markAsActive() method. + } + + #[\Override] + public function markAsBlocked(?string $comment): void + { + // TODO: Implement markAsBlocked() method. + } + + #[\Override] + public function getApplicationStatus(): ApplicationStatus + { + return $this->applicationStatus; + } + + #[\Override] + public function changeApplicationStatus(ApplicationStatus $applicationStatus): void + { + // TODO: Implement changeApplicationStatus() method. + } + + #[\Override] + public function getPortalLicenseFamily(): PortalLicenseFamily + { + // TODO: Implement getPortalLicenseFamily() method. + } + + #[\Override] + public function changePortalLicenseFamily(PortalLicenseFamily $portalLicenseFamily): void + { + // TODO: Implement changePortalLicenseFamily() method. + } + + #[\Override] + public function getPortalUsersCount(): ?int + { + // TODO: Implement getPortalUsersCount() method. + } + + #[\Override] + public function changePortalUsersCount(int $usersCount): void + { + // TODO: Implement changePortalUsersCount() method. + } + + #[\Override] + public function getComment(): ?string + { + return $this->comment; + } +} \ No newline at end of file From de8b7fa51a1d6e62043a6c2b332af002f06d1775 Mon Sep 17 00:00:00 2001 From: KarlsonComplete Date: Mon, 24 Feb 2025 23:46:22 +0300 Subject: [PATCH 02/49] =?UTF-8?q?-=20=D0=A0=D0=B5=D0=B0=D0=BB=D0=B8=D0=B7?= =?UTF-8?q?=D0=BE=D0=B2=D0=B0=D0=BB=20=D0=B1=D0=BE=D0=BB=D1=8C=D1=88=D0=B8?= =?UTF-8?q?=D0=BD=D1=81=D1=82=D0=B2=D0=BE=20=D0=BC=D0=B5=D1=82=D0=BE=D0=B4?= =?UTF-8?q?=D0=BE=D0=B2=20=D0=B4=D0=BB=D1=8F=20=D1=81=D1=83=D1=89=D0=BD?= =?UTF-8?q?=D0=BE=D1=81=D1=82=D0=B8=20ApplicationInstallation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Entity/ApplicationInstallation.php | 120 ++++++++++++++++-- 1 file changed, 109 insertions(+), 11 deletions(-) diff --git a/src/ApplicationInstallations/Entity/ApplicationInstallation.php b/src/ApplicationInstallations/Entity/ApplicationInstallation.php index 7cc06fb..975f3ab 100644 --- a/src/ApplicationInstallations/Entity/ApplicationInstallation.php +++ b/src/ApplicationInstallations/Entity/ApplicationInstallation.php @@ -4,14 +4,17 @@ namespace Bitrix24\Lib\ApplicationInstallations\Entity;; +use Bitrix24\Lib\AggregateRoot; use Bitrix24\SDK\Application\ApplicationStatus; use Bitrix24\SDK\Application\Contracts\ApplicationInstallations\Entity\ApplicationInstallationInterface; use Bitrix24\SDK\Application\Contracts\ApplicationInstallations\Entity\ApplicationInstallationStatus; use Bitrix24\SDK\Application\PortalLicenseFamily; use Carbon\CarbonImmutable; use Symfony\Component\Uid\Uuid; +use Bitrix24\SDK\Application\Contracts\ApplicationInstallations\Events; -class ApplicationInstallation implements ApplicationInstallationInterface + +class ApplicationInstallation extends AggregateRoot implements ApplicationInstallationInterface { private ?string $comment = null; @@ -22,13 +25,15 @@ public function __construct( private CarbonImmutable $updatedAt, // Он должен быть readonly? Я думаю да т.к это связано с установкой и мы не должны менять это свойство. private readonly Uuid $bitrix24AccountId, - // Думаю это тоже readonly т.к связано с установкой - private readonly Uuid $contactPersonId, + // Думаю это тоже readonly т.к связано с установкой, хотя если у нас есть метод changeContactPerson значит мы должны иметь возможность изменить это свойство + private Uuid $contactPersonId, private Uuid $bitrix24PartnerContactPersonId, private ?Uuid $bitrix24PartnerId, private string $externalId, private ApplicationInstallationStatus $status, private ApplicationStatus $applicationStatus, + private PortalLicenseFamily $portalLicenseFamily, + private int $portalUsersCount ) { } @@ -66,7 +71,26 @@ public function getContactPersonId(): ?Uuid #[\Override] public function changeContactPerson(?Uuid $uuid): void { - // TODO: Implement changeContactPerson() method. + //Параметр необязательный, то есть мы можем пустоту занести ? + + if ($uuid === $this->contactPersonId) { + throw new \InvalidArgumentException( + sprintf( + 'new contactPersonId %s must not match the old contactPersonId %s.', + $uuid, + $this->contactPersonId + ) + ); + } + + $this->updatedAt = new CarbonImmutable(); + $this->events[] = new Events\ApplicationInstallationContactPersonChangedEvent( + $this->id, + $this->updatedAt, + $this->contactPersonId, + $uuid + ); + } #[\Override] @@ -78,7 +102,25 @@ public function getBitrix24PartnerContactPersonId(): ?Uuid #[\Override] public function changeBitrix24PartnerContactPerson(?Uuid $uuid): void { - // TODO: Implement changeBitrix24PartnerContactPerson() method. + //Параметр необязательный, то есть мы можем пустоту занести ? + + if ($uuid === $this->bitrix24PartnerContactPersonId) { + throw new \InvalidArgumentException( + sprintf( + 'new bitrix24PartnerContactPersonId %s must not match the old bitrix24PartnerContactPersonId %s.', + $uuid, + $this->bitrix24PartnerContactPersonId + ) + ); + } + + $this->updatedAt = new CarbonImmutable(); + $this->events[] = new Events\ApplicationInstallationBitrix24PartnerContactPersonChangedEvent( + $this->id, + $this->updatedAt, + $this->bitrix24PartnerContactPersonId, + $uuid + ); } #[\Override] @@ -90,7 +132,25 @@ public function getBitrix24PartnerId(): ?Uuid #[\Override] public function changeBitrix24Partner(?Uuid $uuid): void { - // TODO: Implement changeBitrix24Partner() method. + //Параметр необязательный, то есть мы можем пустоту занести ? + + if ($uuid === $this->bitrix24PartnerId) { + throw new \InvalidArgumentException( + sprintf( + 'new bitrix24PartnerId %s must not match the old bitrix24PartnerId %s.', + $uuid, + $this->bitrix24PartnerId + ) + ); + } + + $this->updatedAt = new CarbonImmutable(); + $this->events[] = new Events\ApplicationInstallationBitrix24PartnerChangedEvent( + $this->id, + $this->updatedAt, + $this->bitrix24PartnerId, + $uuid + ); } #[\Override] @@ -144,31 +204,69 @@ public function getApplicationStatus(): ApplicationStatus #[\Override] public function changeApplicationStatus(ApplicationStatus $applicationStatus): void { - // TODO: Implement changeApplicationStatus() method. + if ($this->applicationStatus === $applicationStatus) { + throw new \InvalidArgumentException( + sprintf('new applicationStatus identical with old applicationStatus') + ); + } + + $this->updatedAt = new CarbonImmutable(); + $this->events[] = new Events\ApplicationInstallationApplicationStatusChangedEvent( + $this->id, + $this->updatedAt, + $applicationStatus + ); } #[\Override] public function getPortalLicenseFamily(): PortalLicenseFamily { - // TODO: Implement getPortalLicenseFamily() method. + return $this->portalLicenseFamily; } #[\Override] public function changePortalLicenseFamily(PortalLicenseFamily $portalLicenseFamily): void { - // TODO: Implement changePortalLicenseFamily() method. + if ($this->portalLicenseFamily === $portalLicenseFamily) { + throw new \InvalidArgumentException( + sprintf('new portalLicenseFamily identical with old portalLicenseFamily') + ); + } + + $this->updatedAt = new CarbonImmutable(); + $this->events[] = new Events\ApplicationInstallationPortalLicenseFamilyChangedEvent( + $this->id, + $this->updatedAt, + $this->portalLicenseFamily, + $portalLicenseFamily + ); } #[\Override] public function getPortalUsersCount(): ?int { - // TODO: Implement getPortalUsersCount() method. + return $this->portalUsersCount; } #[\Override] public function changePortalUsersCount(int $usersCount): void { - // TODO: Implement changePortalUsersCount() method. + if ($this->portalUsersCount === $usersCount) { + throw new \InvalidArgumentException( + sprintf('new usersCount %s identical with old portalUsersCount %s', + $usersCount, + $this->portalUsersCount + ) + ); + } + + $this->updatedAt = new CarbonImmutable(); + $this->events[] = new Events\ApplicationInstallationPortalUsersCountChangedEvent( + $this->id, + $this->updatedAt, + $this->portalUsersCount, + $usersCount + ); } #[\Override] From 235f52a26ed531953102256a55707b3bd5ac5854 Mon Sep 17 00:00:00 2001 From: KarlsonComplete Date: Tue, 25 Feb 2025 23:54:10 +0300 Subject: [PATCH 03/49] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8?= =?UTF-8?q?=D0=BB=20=D1=80=D0=B5=D0=BF=D0=BE=D0=B7=D0=B8=D1=82=D0=BE=D1=80?= =?UTF-8?q?=D0=B8=D0=B9=20=D0=B8=20=D0=BD=D0=B0=D0=BF=D0=B8=D1=81=D0=B0?= =?UTF-8?q?=D0=BB=20=D0=BC=D0=B5=D1=82=D0=BE=D0=B4=D1=8B=20=D0=B4=D0=BB?= =?UTF-8?q?=D1=8F=20ApplicationInstall?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ApplicationInstallationsRepository.php | 105 ++++++++++++++++++ 1 file changed, 105 insertions(+) create mode 100644 src/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationsRepository.php diff --git a/src/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationsRepository.php b/src/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationsRepository.php new file mode 100644 index 0000000..7b05258 --- /dev/null +++ b/src/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationsRepository.php @@ -0,0 +1,105 @@ +getClassMetadata(ApplicationInstallation::class)); + } + + public function save(ApplicationInstallationInterface $applicationInstallation): void + { + $this->getEntityManager()->persist($applicationInstallation); + } + + public function getById(Uuid $uuid): ApplicationInstallationInterface + { + + // $applicationInstallation = $this->find($uuid); + + $applicationInstallation = $this->getEntityManager()->getRepository(ApplicationInstallation::class) + ->createQueryBuilder('appInstallation') + ->where('appInstallation.UUID = :uuid') + ->andWhere('appInstallation.status != :status') + ->setParameter('uuid', $uuid) + ->setParameter('status', ApplicationInstallationStatus::deleted) + ->getQuery() + ->getOneOrNullResult(); + + if (null === $applicationInstallation) { + throw new ApplicationInstallationNotFoundException( + sprintf('application installed not found by id %s', $uuid->toRfc4122()) + ); + } + + return $applicationInstallation; + } + + public function delete(Uuid $uuid): void + { + $applicationInstallation = $this->getEntityManager()->getRepository(ApplicationInstallation::class)->find($uuid); + + if (null === $applicationInstallation) { + throw new ApplicationInstallationNotFoundException( + sprintf('application installed not found by id %s', $uuid->toRfc4122()) + ); + } + + if ($applicationInstallation->getStatus() !== ApplicationInstallationStatus::deleted) { + throw new ApplicationInstallationNotFoundException( + sprintf('you cannot delete application installed because you status must be deleted your status %s', $applicationInstallation->getStatus()->name) + ); + } + + $this->save($applicationInstallation); + } + + public function findByBitrix24AccountId(Uuid $uuid): array + { + $applicationInstallations = $this->getEntityManager()->getRepository(ApplicationInstallation::class) + ->createQueryBuilder('appInstallation') + ->where('appInstallation.bitrix24AccountId = :bitrix24AccountId') + ->setParameter('bitrix24AccountId', $uuid) + ->getQuery() + ->getOneOrNullResult(); + + if (null === $applicationInstallations) { + throw new ApplicationInstallationNotFoundException( + sprintf('application installed not found by bitrix24AccountId %s', $uuid->toRfc4122()) + ); + } + + return $applicationInstallations; + } + + public function findByExternalId(string $externalId): array + { + $applicationInstallations = $this->getEntityManager()->getRepository(ApplicationInstallation::class) + ->createQueryBuilder('appInstallation') + ->where('appInstallation.externalId = :externalId') + ->setParameter('externalId', $externalId) + ->getQuery() + ->getOneOrNullResult(); + + if (null === $applicationInstallations) { + throw new ApplicationInstallationNotFoundException( + sprintf('application installed not found by externalId %s', $externalId) + ); + } + + return $applicationInstallations; + } +} \ No newline at end of file From 848b1a20c44ca6371702fed5839b6bad559a9258 Mon Sep 17 00:00:00 2001 From: KarlsonComplete Date: Sun, 2 Mar 2025 17:37:24 +0300 Subject: [PATCH 04/49] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8?= =?UTF-8?q?=D0=BB=203=20=D0=BC=D0=B5=D1=82=D0=BA=D1=83=20=D0=B2=20=D0=B4?= =?UTF-8?q?=D0=BE=D0=BC=D0=B5=D0=BD=20=D0=A4=D1=83=D0=BD=D0=BA=D1=86=D0=B8?= =?UTF-8?q?=D0=B8=20=D0=B4=D0=BB=D1=8F=20=D1=81=D1=83=D1=89=D0=BD=D0=BE?= =?UTF-8?q?=D1=81=D1=82=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Entity/ApplicationInstallation.php | 59 +++++++++++++++++-- .../ApplicationInstallationsRepository.php | 5 +- src/Bitrix24Accounts/ValueObjects/Domain.php | 2 +- 3 files changed, 59 insertions(+), 7 deletions(-) diff --git a/src/ApplicationInstallations/Entity/ApplicationInstallation.php b/src/ApplicationInstallations/Entity/ApplicationInstallation.php index 975f3ab..1826267 100644 --- a/src/ApplicationInstallations/Entity/ApplicationInstallation.php +++ b/src/ApplicationInstallations/Entity/ApplicationInstallation.php @@ -8,11 +8,13 @@ use Bitrix24\SDK\Application\ApplicationStatus; use Bitrix24\SDK\Application\Contracts\ApplicationInstallations\Entity\ApplicationInstallationInterface; use Bitrix24\SDK\Application\Contracts\ApplicationInstallations\Entity\ApplicationInstallationStatus; +use Bitrix24\SDK\Application\Contracts\ApplicationInstallations\Events\ApplicationInstallationBlockedEvent; +use Bitrix24\SDK\Application\Contracts\ApplicationInstallations\Events\ApplicationInstallationUninstalledEvent; use Bitrix24\SDK\Application\PortalLicenseFamily; use Carbon\CarbonImmutable; use Symfony\Component\Uid\Uuid; use Bitrix24\SDK\Application\Contracts\ApplicationInstallations\Events; - +use Bitrix24\SDK\Core\Exceptions\InvalidArgumentException; class ApplicationInstallation extends AggregateRoot implements ApplicationInstallationInterface { @@ -174,25 +176,72 @@ public function getStatus(): ApplicationInstallationStatus #[\Override] public function applicationInstalled(): void { - // TODO: Implement applicationInstalled() method. + if (ApplicationInstallationStatus::new !== $this->status) { + throw new InvalidArgumentException( + sprintf( + 'for finish application installation must be in status «new», current status - «%s»', + $this->status->name + ) + ); + } + + $this->status = ApplicationInstallationStatus::active; + $this->updatedAt = new CarbonImmutable(); + // Тут событие должно быть ? + } #[\Override] public function applicationUninstalled(): void { - // TODO: Implement applicationUninstalled() method. + + $this->status = ApplicationInstallationStatus::deleted; + $this->updatedAt = new CarbonImmutable(); + $this->events[] = new ApplicationInstallationUninstalledEvent( + $this->id, + new CarbonImmutable(), + $this->bitrix24AccountId, + $this->contactPersonId, + $this->bitrix24PartnerId, + $this->bitrix24PartnerId, + $this->externalId + ); + } #[\Override] public function markAsActive(?string $comment): void { - // TODO: Implement markAsActive() method. + if (ApplicationInstallationStatus::blocked !== $this->status) { + throw new InvalidArgumentException( + sprintf( + 'you can activate application install only in status «blocked», now status «%s»', + $this->status->name + ) + ); + } + + $this->status = ApplicationInstallationStatus::active; + $this->comment = $comment; + $this->updatedAt = new CarbonImmutable(); } #[\Override] public function markAsBlocked(?string $comment): void { - // TODO: Implement markAsBlocked() method. + if (ApplicationInstallationStatus::deleted === $this->status) { + throw new InvalidArgumentException('you cannot block application install in status «deleted»'); + } + // Когда происходит блокировка ? И как из нее выйти ? + + $this->status = ApplicationInstallationStatus::blocked; + $this->comment = $comment; + $this->updatedAt = new CarbonImmutable(); + $this->events[] = new ApplicationInstallationBlockedEvent( + $this->id, + new CarbonImmutable(), + $this->comment + ); } #[\Override] diff --git a/src/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationsRepository.php b/src/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationsRepository.php index 7b05258..13fcbb0 100644 --- a/src/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationsRepository.php +++ b/src/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationsRepository.php @@ -12,7 +12,7 @@ use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityRepository; use Symfony\Component\Uid\Uuid; - +use Bitrix24\SDK\Core\Exceptions\InvalidArgumentException; class ApplicationInstallationsRepository extends EntityRepository implements ApplicationInstallationRepositoryInterface { public function __construct(EntityManagerInterface $entityManager) @@ -87,6 +87,9 @@ public function findByBitrix24AccountId(Uuid $uuid): array public function findByExternalId(string $externalId): array { + if ('' == $externalId) { + throw new InvalidArgumentException('external id cannot be empty'); + } $applicationInstallations = $this->getEntityManager()->getRepository(ApplicationInstallation::class) ->createQueryBuilder('appInstallation') ->where('appInstallation.externalId = :externalId') diff --git a/src/Bitrix24Accounts/ValueObjects/Domain.php b/src/Bitrix24Accounts/ValueObjects/Domain.php index a399ee7..9f72eb3 100644 --- a/src/Bitrix24Accounts/ValueObjects/Domain.php +++ b/src/Bitrix24Accounts/ValueObjects/Domain.php @@ -23,7 +23,7 @@ private function validate(string $domain): void $patternLengthCheck = '/^.{1,253}$/'; // Проверка длины каждой метки (1-63 символа, включая кириллицу) - $patternLengthEachLabel = '/^[A-Za-zА-Яа-яЁё0-9-]{1,63}(\.[A-Za-zА-Яа-яЁё0-9-]{1,63})*$/u'; + $patternLengthEachLabel = '/^[A-Za-zА-Яа-яЁё0-9-]{1,63}(\.[A-Za-zА-Яа-яЁё0-9-]{1,63}){0,2}$/u'; if ( in_array(preg_match($patternValidChars, $domain), [0, false], true) || in_array(preg_match($patternLengthCheck, $domain), [0, false], true) From a943adc3b43441e40c90260033924758d3e518ed Mon Sep 17 00:00:00 2001 From: KarlsonComplete Date: Wed, 5 Mar 2025 22:37:46 +0300 Subject: [PATCH 05/49] =?UTF-8?q?=D0=9F=D0=BE=D0=BF=D1=80=D0=B0=D0=B2?= =?UTF-8?q?=D0=B8=D0=BB=20=D1=81=D1=83=D1=89=D0=BD=D0=BE=D1=81=D1=82=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...x24Accounts.Entity.Bitrix24Account.dcm.xml | 2 + .../Entity/ApplicationInstallation.php | 193 ++++++++---------- .../ApplicationInstallationsRepository.php | 2 - .../Entity/Bitrix24Account.php | 3 +- 4 files changed, 90 insertions(+), 110 deletions(-) diff --git a/config/xml/Bitrix24.Lib.Bitrix24Accounts.Entity.Bitrix24Account.dcm.xml b/config/xml/Bitrix24.Lib.Bitrix24Accounts.Entity.Bitrix24Account.dcm.xml index c2e57d9..74b6231 100644 --- a/config/xml/Bitrix24.Lib.Bitrix24Accounts.Entity.Bitrix24Account.dcm.xml +++ b/config/xml/Bitrix24.Lib.Bitrix24Accounts.Entity.Bitrix24Account.dcm.xml @@ -24,6 +24,8 @@ + + diff --git a/src/ApplicationInstallations/Entity/ApplicationInstallation.php b/src/ApplicationInstallations/Entity/ApplicationInstallation.php index 1826267..671478a 100644 --- a/src/ApplicationInstallations/Entity/ApplicationInstallation.php +++ b/src/ApplicationInstallations/Entity/ApplicationInstallation.php @@ -2,13 +2,16 @@ declare(strict_types=1); -namespace Bitrix24\Lib\ApplicationInstallations\Entity;; +namespace Bitrix24\Lib\ApplicationInstallations\Entity; +; use Bitrix24\Lib\AggregateRoot; use Bitrix24\SDK\Application\ApplicationStatus; use Bitrix24\SDK\Application\Contracts\ApplicationInstallations\Entity\ApplicationInstallationInterface; use Bitrix24\SDK\Application\Contracts\ApplicationInstallations\Entity\ApplicationInstallationStatus; use Bitrix24\SDK\Application\Contracts\ApplicationInstallations\Events\ApplicationInstallationBlockedEvent; +use Bitrix24\SDK\Application\Contracts\ApplicationInstallations\Events\ApplicationInstallationFinishedEvent; +use Bitrix24\SDK\Application\Contracts\ApplicationInstallations\Events\ApplicationInstallationUnblockedEvent; use Bitrix24\SDK\Application\Contracts\ApplicationInstallations\Events\ApplicationInstallationUninstalledEvent; use Bitrix24\SDK\Application\PortalLicenseFamily; use Carbon\CarbonImmutable; @@ -19,24 +22,24 @@ class ApplicationInstallation extends AggregateRoot implements ApplicationInstallationInterface { - private ?string $comment = null; - public function __construct( - private readonly Uuid $id, - private readonly CarbonImmutable $createdAt, - private CarbonImmutable $updatedAt, + private readonly Uuid $id, + private readonly CarbonImmutable $createdAt, + private CarbonImmutable $updatedAt, // Он должен быть readonly? Я думаю да т.к это связано с установкой и мы не должны менять это свойство. - private readonly Uuid $bitrix24AccountId, + private readonly Uuid $bitrix24AccountId, // Думаю это тоже readonly т.к связано с установкой, хотя если у нас есть метод changeContactPerson значит мы должны иметь возможность изменить это свойство - private Uuid $contactPersonId, - private Uuid $bitrix24PartnerContactPersonId, - private ?Uuid $bitrix24PartnerId, - private string $externalId, + private Uuid $contactPersonId, + private Uuid $bitrix24PartnerContactPersonId, + private ?Uuid $bitrix24PartnerId, + private string $externalId, private ApplicationInstallationStatus $status, - private ApplicationStatus $applicationStatus, - private PortalLicenseFamily $portalLicenseFamily, - private int $portalUsersCount - ) { + private ApplicationStatus $applicationStatus, + private PortalLicenseFamily $portalLicenseFamily, + private int $portalUsersCount, + private ?string $comment = null + ) + { } @@ -73,24 +76,13 @@ public function getContactPersonId(): ?Uuid #[\Override] public function changeContactPerson(?Uuid $uuid): void { - //Параметр необязательный, то есть мы можем пустоту занести ? - - if ($uuid === $this->contactPersonId) { - throw new \InvalidArgumentException( - sprintf( - 'new contactPersonId %s must not match the old contactPersonId %s.', - $uuid, - $this->contactPersonId - ) - ); - } - $this->updatedAt = new CarbonImmutable(); + $this->events[] = new Events\ApplicationInstallationContactPersonChangedEvent( - $this->id, - $this->updatedAt, - $this->contactPersonId, - $uuid + $this->id, + $this->updatedAt, + $this->contactPersonId, + $uuid ); } @@ -104,19 +96,8 @@ public function getBitrix24PartnerContactPersonId(): ?Uuid #[\Override] public function changeBitrix24PartnerContactPerson(?Uuid $uuid): void { - //Параметр необязательный, то есть мы можем пустоту занести ? - - if ($uuid === $this->bitrix24PartnerContactPersonId) { - throw new \InvalidArgumentException( - sprintf( - 'new bitrix24PartnerContactPersonId %s must not match the old bitrix24PartnerContactPersonId %s.', - $uuid, - $this->bitrix24PartnerContactPersonId - ) - ); - } - $this->updatedAt = new CarbonImmutable(); + $this->events[] = new Events\ApplicationInstallationBitrix24PartnerContactPersonChangedEvent( $this->id, $this->updatedAt, @@ -128,25 +109,14 @@ public function changeBitrix24PartnerContactPerson(?Uuid $uuid): void #[\Override] public function getBitrix24PartnerId(): ?Uuid { - return $this->bitrix24PartnerId; + return $this->bitrix24PartnerId; } #[\Override] public function changeBitrix24Partner(?Uuid $uuid): void { - //Параметр необязательный, то есть мы можем пустоту занести ? - - if ($uuid === $this->bitrix24PartnerId) { - throw new \InvalidArgumentException( - sprintf( - 'new bitrix24PartnerId %s must not match the old bitrix24PartnerId %s.', - $uuid, - $this->bitrix24PartnerId - ) - ); - } - $this->updatedAt = new CarbonImmutable(); + $this->events[] = new Events\ApplicationInstallationBitrix24PartnerChangedEvent( $this->id, $this->updatedAt, @@ -176,30 +146,42 @@ public function getStatus(): ApplicationInstallationStatus #[\Override] public function applicationInstalled(): void { - if (ApplicationInstallationStatus::new !== $this->status) { - throw new InvalidArgumentException( + if ( + ApplicationInstallationStatus::new !== $this->status + && ApplicationInstallationStatus::blocked !== $this->status + ) { + throw new \LogicException( sprintf( - 'for finish application installation must be in status «new», current status - «%s»', - $this->status->name + 'installation was interrupted because status must be in new or blocked,but your status is %s', + $this->status->value ) ); } $this->status = ApplicationInstallationStatus::active; $this->updatedAt = new CarbonImmutable(); - // Тут событие должно быть ? + + $this->events[] = new ApplicationInstallationFinishedEvent( + $this->id, + $this->updatedAt, + $this->bitrix24PartnerId, + $this->portalLicenseFamily, + $this->contactPersonId, + $this->bitrix24PartnerContactPersonId, + $this->bitrix24PartnerId + ); } #[\Override] public function applicationUninstalled(): void { - $this->status = ApplicationInstallationStatus::deleted; $this->updatedAt = new CarbonImmutable(); + $this->events[] = new ApplicationInstallationUninstalledEvent( $this->id, - new CarbonImmutable(), + $this->updatedAt, $this->bitrix24AccountId, $this->contactPersonId, $this->bitrix24PartnerId, @@ -213,10 +195,10 @@ public function applicationUninstalled(): void public function markAsActive(?string $comment): void { if (ApplicationInstallationStatus::blocked !== $this->status) { - throw new InvalidArgumentException( + throw new \LogicException( sprintf( - 'you can activate application install only in status «blocked», now status «%s»', - $this->status->name + 'you must be in status blocked to complete the installation, now status is «%s»', + $this->status->value ) ); } @@ -224,19 +206,30 @@ public function markAsActive(?string $comment): void $this->status = ApplicationInstallationStatus::active; $this->comment = $comment; $this->updatedAt = new CarbonImmutable(); + + $this->events[] = new ApplicationInstallationUnblockedEvent( + $this->id, + $this->updatedAt, + $this->comment + ); } #[\Override] public function markAsBlocked(?string $comment): void { - if (ApplicationInstallationStatus::deleted === $this->status) { - throw new InvalidArgumentException('you cannot block application install in status «deleted»'); + if ( + ApplicationInstallationStatus::new !== $this->status + && ApplicationInstallationStatus::active !== $this->status + ) { + throw new \LogicException(sprintf('You can block application installation only in status new or active,but your status is «%s»', + $this->status->value + )); } - // Когда происходит блокировка ? И как из нее выйти ? $this->status = ApplicationInstallationStatus::blocked; $this->comment = $comment; $this->updatedAt = new CarbonImmutable(); + $this->events[] = new ApplicationInstallationBlockedEvent( $this->id, new CarbonImmutable(), @@ -247,24 +240,21 @@ public function markAsBlocked(?string $comment): void #[\Override] public function getApplicationStatus(): ApplicationStatus { - return $this->applicationStatus; + return $this->applicationStatus; } #[\Override] public function changeApplicationStatus(ApplicationStatus $applicationStatus): void { - if ($this->applicationStatus === $applicationStatus) { - throw new \InvalidArgumentException( - sprintf('new applicationStatus identical with old applicationStatus') + if ($this->applicationStatus !== $applicationStatus) { + $this->updatedAt = new CarbonImmutable(); + + $this->events[] = new Events\ApplicationInstallationApplicationStatusChangedEvent( + $this->id, + $this->updatedAt, + $applicationStatus ); } - - $this->updatedAt = new CarbonImmutable(); - $this->events[] = new Events\ApplicationInstallationApplicationStatusChangedEvent( - $this->id, - $this->updatedAt, - $applicationStatus - ); } #[\Override] @@ -276,46 +266,37 @@ public function getPortalLicenseFamily(): PortalLicenseFamily #[\Override] public function changePortalLicenseFamily(PortalLicenseFamily $portalLicenseFamily): void { - if ($this->portalLicenseFamily === $portalLicenseFamily) { - throw new \InvalidArgumentException( - sprintf('new portalLicenseFamily identical with old portalLicenseFamily') + if ($this->portalLicenseFamily !== $portalLicenseFamily) { + $this->updatedAt = new CarbonImmutable(); + + $this->events[] = new Events\ApplicationInstallationPortalLicenseFamilyChangedEvent( + $this->id, + $this->updatedAt, + $this->portalLicenseFamily, + $portalLicenseFamily ); } - - $this->updatedAt = new CarbonImmutable(); - $this->events[] = new Events\ApplicationInstallationPortalLicenseFamilyChangedEvent( - $this->id, - $this->updatedAt, - $this->portalLicenseFamily, - $portalLicenseFamily - ); } #[\Override] public function getPortalUsersCount(): ?int { - return $this->portalUsersCount; + return $this->portalUsersCount; } #[\Override] public function changePortalUsersCount(int $usersCount): void { - if ($this->portalUsersCount === $usersCount) { - throw new \InvalidArgumentException( - sprintf('new usersCount %s identical with old portalUsersCount %s', - $usersCount, - $this->portalUsersCount - ) + if ($this->portalUsersCount !== $usersCount) { + $this->updatedAt = new CarbonImmutable(); + + $this->events[] = new Events\ApplicationInstallationPortalUsersCountChangedEvent( + $this->id, + $this->updatedAt, + $this->portalUsersCount, + $usersCount ); } - - $this->updatedAt = new CarbonImmutable(); - $this->events[] = new Events\ApplicationInstallationPortalUsersCountChangedEvent( - $this->id, - $this->updatedAt, - $this->portalUsersCount, - $usersCount - ); } #[\Override] diff --git a/src/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationsRepository.php b/src/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationsRepository.php index 13fcbb0..71fca2b 100644 --- a/src/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationsRepository.php +++ b/src/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationsRepository.php @@ -28,8 +28,6 @@ public function save(ApplicationInstallationInterface $applicationInstallation): public function getById(Uuid $uuid): ApplicationInstallationInterface { - // $applicationInstallation = $this->find($uuid); - $applicationInstallation = $this->getEntityManager()->getRepository(ApplicationInstallation::class) ->createQueryBuilder('appInstallation') ->where('appInstallation.UUID = :uuid') diff --git a/src/Bitrix24Accounts/Entity/Bitrix24Account.php b/src/Bitrix24Accounts/Entity/Bitrix24Account.php index 616f75d..1c8897c 100644 --- a/src/Bitrix24Accounts/Entity/Bitrix24Account.php +++ b/src/Bitrix24Accounts/Entity/Bitrix24Account.php @@ -33,8 +33,6 @@ class Bitrix24Account extends AggregateRoot implements Bitrix24AccountInterface { private ?string $applicationToken = null; - private ?string $comment = null; - public function __construct( private readonly Uuid $id, private readonly int $bitrix24UserId, @@ -49,6 +47,7 @@ public function __construct( private int $applicationVersion, private Scope $applicationScope, bool $isEmitBitrix24AccountCreatedEvent = false, + private ?string $comment = null ) { $this->addAccountCreatedEventIfNeeded($isEmitBitrix24AccountCreatedEvent); } From ae6dde29dba5223cff766f5a5bd4567c087bbbf3 Mon Sep 17 00:00:00 2001 From: KarlsonComplete Date: Wed, 5 Mar 2025 23:02:19 +0300 Subject: [PATCH 06/49] =?UTF-8?q?=D0=9C=D0=B0=D0=BF=D0=BF=D0=B8=D0=BD?= =?UTF-8?q?=D0=B3=20=D1=81=D1=83=D1=89=D0=BD=D0=BE=D1=81=D1=82=D0=B8=20app?= =?UTF-8?q?licationInstallation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...ons.Entity.ApplicationInstallation.dcm.xml | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 config/xml/Bitrix24.Lib.ApplicationInstallations.Entity.ApplicationInstallation.dcm.xml diff --git a/config/xml/Bitrix24.Lib.ApplicationInstallations.Entity.ApplicationInstallation.dcm.xml b/config/xml/Bitrix24.Lib.ApplicationInstallations.Entity.ApplicationInstallation.dcm.xml new file mode 100644 index 0000000..025b7f9 --- /dev/null +++ b/config/xml/Bitrix24.Lib.ApplicationInstallations.Entity.ApplicationInstallation.dcm.xml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From e12cf66ed9bb8e8c24bbb2ded23dec810d6e1a25 Mon Sep 17 00:00:00 2001 From: KarlsonComplete Date: Sun, 9 Mar 2025 13:25:51 +0300 Subject: [PATCH 07/49] =?UTF-8?q?-=20=D0=9F=D0=BE=D0=BF=D1=80=D0=B0=D0=B2?= =?UTF-8?q?=D0=B8=D0=BB=20=D1=81=D1=83=D1=89=D0=BD=D0=BE=D1=81=D1=82=D1=8C?= =?UTF-8?q?=20=D0=B8=D0=BD=D1=81=D1=82=D0=B0=D0=BB=D1=8F=D1=86=D0=B8=D0=B8?= =?UTF-8?q?=20-=20=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8=D0=BB=20=D0=B1?= =?UTF-8?q?=D0=B8=D0=BB=D0=B4=D0=B5=D1=80=20-=20=D0=98=20=D1=82=D0=B5?= =?UTF-8?q?=D1=81=D1=82=D1=8B=20=D0=BD=D0=B0=20=D1=80=D0=B5=D0=BF=D0=BE?= =?UTF-8?q?=D0=B7=D0=B8=D1=82=D0=BE=D1=80=D0=B8=D0=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Entity/ApplicationInstallation.php | 14 ++++++-------- ...y.php => ApplicationInstallationRepository.php} | 2 +- .../Builders/Bitrix24AccountBuilder.php | 2 -- 3 files changed, 7 insertions(+), 11 deletions(-) rename src/ApplicationInstallations/Infrastructure/Doctrine/{ApplicationInstallationsRepository.php => ApplicationInstallationRepository.php} (97%) diff --git a/src/ApplicationInstallations/Entity/ApplicationInstallation.php b/src/ApplicationInstallations/Entity/ApplicationInstallation.php index 671478a..a0f519c 100644 --- a/src/ApplicationInstallations/Entity/ApplicationInstallation.php +++ b/src/ApplicationInstallations/Entity/ApplicationInstallation.php @@ -24,19 +24,17 @@ class ApplicationInstallation extends AggregateRoot implements ApplicationInstal public function __construct( private readonly Uuid $id, + private ApplicationInstallationStatus $status, private readonly CarbonImmutable $createdAt, private CarbonImmutable $updatedAt, - // Он должен быть readonly? Я думаю да т.к это связано с установкой и мы не должны менять это свойство. private readonly Uuid $bitrix24AccountId, - // Думаю это тоже readonly т.к связано с установкой, хотя если у нас есть метод changeContactPerson значит мы должны иметь возможность изменить это свойство - private Uuid $contactPersonId, - private Uuid $bitrix24PartnerContactPersonId, - private ?Uuid $bitrix24PartnerId, - private string $externalId, - private ApplicationInstallationStatus $status, private ApplicationStatus $applicationStatus, private PortalLicenseFamily $portalLicenseFamily, - private int $portalUsersCount, + private ?int $portalUsersCount, + private ?Uuid $contactPersonId, + private ?Uuid $bitrix24PartnerContactPersonId, + private ?Uuid $bitrix24PartnerId, + private ?string $externalId, private ?string $comment = null ) { diff --git a/src/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationsRepository.php b/src/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationRepository.php similarity index 97% rename from src/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationsRepository.php rename to src/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationRepository.php index 71fca2b..b0781f1 100644 --- a/src/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationsRepository.php +++ b/src/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationRepository.php @@ -13,7 +13,7 @@ use Doctrine\ORM\EntityRepository; use Symfony\Component\Uid\Uuid; use Bitrix24\SDK\Core\Exceptions\InvalidArgumentException; -class ApplicationInstallationsRepository extends EntityRepository implements ApplicationInstallationRepositoryInterface +class ApplicationInstallationRepository extends EntityRepository implements ApplicationInstallationRepositoryInterface { public function __construct(EntityManagerInterface $entityManager) { diff --git a/tests/Functional/Bitrix24Accounts/Builders/Bitrix24AccountBuilder.php b/tests/Functional/Bitrix24Accounts/Builders/Bitrix24AccountBuilder.php index bff547e..7944908 100644 --- a/tests/Functional/Bitrix24Accounts/Builders/Bitrix24AccountBuilder.php +++ b/tests/Functional/Bitrix24Accounts/Builders/Bitrix24AccountBuilder.php @@ -14,9 +14,7 @@ namespace Bitrix24\Lib\Tests\Functional\Bitrix24Accounts\Builders; use Bitrix24\Lib\Bitrix24Accounts\Entity\Bitrix24Account; -use Bitrix24\SDK\Application\Contracts\Bitrix24Accounts\Entity\Bitrix24AccountInterface; use Bitrix24\SDK\Application\Contracts\Bitrix24Accounts\Entity\Bitrix24AccountStatus; -use Bitrix24\SDK\Application\Contracts\Events\AggregateRootEventsEmitterInterface; use Bitrix24\SDK\Core\Credentials\AuthToken; use Bitrix24\SDK\Core\Credentials\Scope; use Carbon\CarbonImmutable; From 34d49c0b576aa684fafcb734658c91adebdcf161 Mon Sep 17 00:00:00 2001 From: KarlsonComplete Date: Mon, 10 Mar 2025 21:25:48 +0300 Subject: [PATCH 08/49] =?UTF-8?q?-=20=D0=A2=D0=B5=D1=81=D1=82=D1=8B=20?= =?UTF-8?q?=D0=BD=D0=B0=20=D1=80=D0=B5=D0=BF=D0=BE=D0=B7=D0=B8=D1=82=D0=BE?= =?UTF-8?q?=D1=80=D0=B8=D0=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Entity/ApplicationInstallation.php | 2 +- .../ApplicationInstallationRepository.php | 2 +- .../ApplicationInstallationBuilder.php | 99 +++++++++++++++++++ .../ApplicationInstallationRepositoryTest.php | 81 +++++++++++++++ 4 files changed, 182 insertions(+), 2 deletions(-) create mode 100644 tests/Functional/ApplicationInstallations/Builders/ApplicationInstallationBuilder.php create mode 100644 tests/Functional/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationRepositoryTest.php diff --git a/src/ApplicationInstallations/Entity/ApplicationInstallation.php b/src/ApplicationInstallations/Entity/ApplicationInstallation.php index a0f519c..aa15c07 100644 --- a/src/ApplicationInstallations/Entity/ApplicationInstallation.php +++ b/src/ApplicationInstallations/Entity/ApplicationInstallation.php @@ -162,7 +162,7 @@ public function applicationInstalled(): void $this->events[] = new ApplicationInstallationFinishedEvent( $this->id, $this->updatedAt, - $this->bitrix24PartnerId, + $this->bitrix24AccountId, $this->portalLicenseFamily, $this->contactPersonId, $this->bitrix24PartnerContactPersonId, diff --git a/src/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationRepository.php b/src/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationRepository.php index b0781f1..ce067fc 100644 --- a/src/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationRepository.php +++ b/src/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationRepository.php @@ -30,7 +30,7 @@ public function getById(Uuid $uuid): ApplicationInstallationInterface $applicationInstallation = $this->getEntityManager()->getRepository(ApplicationInstallation::class) ->createQueryBuilder('appInstallation') - ->where('appInstallation.UUID = :uuid') + ->where('appInstallation.id = :uuid') ->andWhere('appInstallation.status != :status') ->setParameter('uuid', $uuid) ->setParameter('status', ApplicationInstallationStatus::deleted) diff --git a/tests/Functional/ApplicationInstallations/Builders/ApplicationInstallationBuilder.php b/tests/Functional/ApplicationInstallations/Builders/ApplicationInstallationBuilder.php new file mode 100644 index 0000000..77bf5e8 --- /dev/null +++ b/tests/Functional/ApplicationInstallations/Builders/ApplicationInstallationBuilder.php @@ -0,0 +1,99 @@ +id = Uuid::v7(); + $this->createdAt = CarbonImmutable::now(); + $this->updatedAt = CarbonImmutable::now(); + $this->bitrix24AccountId = Uuid::v7(); + $this->bitrix24PartnerContactPersonId = Uuid::v7(); + $this->contactPersonId = Uuid::v7(); + $this->bitrix24PartnerId = Uuid::v7(); + $this->portalUsersCount = random_int(1, 1_000_000); + } + + public function withExternalId(string $externalId): self + { + $this->externalId = $externalId; + + return $this; + } + + public function withApplicationStatusInstallation(ApplicationInstallationStatus $status): self + { + $this->status = $status; + + return $this; + } + + public function withApplicationStatus(ApplicationStatus $applicationStatus): self + { + $this->applicationStatus = $applicationStatus; + + return $this; + } + + public function withPortalLicenseFamily(PortalLicenseFamily $portalLicenseFamily): self + { + $this->portalLicenseFamily = $portalLicenseFamily; + + return $this; + } + + public function build(): ApplicationInstallation + { + $applicationInstallation = new ApplicationInstallation( + $this->id, + $this->status, + $this->createdAt, + $this->updatedAt, + $this->bitrix24AccountId, + $this->applicationStatus, + $this->portalLicenseFamily, + $this->portalUsersCount, + $this->contactPersonId, + $this->bitrix24PartnerContactPersonId, + $this->bitrix24PartnerId, + $this->externalId, + $this->comment + ); + + return $applicationInstallation; + } + + + + + + + + +} \ No newline at end of file diff --git a/tests/Functional/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationRepositoryTest.php b/tests/Functional/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationRepositoryTest.php new file mode 100644 index 0000000..2eb5b0d --- /dev/null +++ b/tests/Functional/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationRepositoryTest.php @@ -0,0 +1,81 @@ + Date: Sun, 16 Mar 2025 14:01:08 +0300 Subject: [PATCH 09/49] =?UTF-8?q?-=20=D0=9F=D0=BE=D0=BF=D1=80=D0=B0=D0=B2?= =?UTF-8?q?=D0=B8=D0=BB=20=D0=B4=D0=BE=D0=BC=D0=B5=D0=BD=20=D0=B8=20=D0=BF?= =?UTF-8?q?=D1=80=D0=BE=D0=B2=D0=B5=D0=BB=20=D0=BF=D1=80=D0=B0=D0=B2=D0=BA?= =?UTF-8?q?=D0=B8=20=D0=BF=D0=BE=20=D0=BA=D0=BE=D0=BC=D0=BC=D0=B5=D0=BD?= =?UTF-8?q?=D1=82=D0=B0=D0=BC.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Doctrine/ApplicationInstallationRepository.php | 14 +------------- src/Bitrix24Accounts/Entity/Bitrix24Account.php | 4 ++-- src/Bitrix24Accounts/ValueObjects/Domain.php | 6 +++--- 3 files changed, 6 insertions(+), 18 deletions(-) diff --git a/src/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationRepository.php b/src/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationRepository.php index ce067fc..72b5ed2 100644 --- a/src/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationRepository.php +++ b/src/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationRepository.php @@ -74,18 +74,12 @@ public function findByBitrix24AccountId(Uuid $uuid): array ->getQuery() ->getOneOrNullResult(); - if (null === $applicationInstallations) { - throw new ApplicationInstallationNotFoundException( - sprintf('application installed not found by bitrix24AccountId %s', $uuid->toRfc4122()) - ); - } - return $applicationInstallations; } public function findByExternalId(string $externalId): array { - if ('' == $externalId) { + if ('' === trim($externalId)) { throw new InvalidArgumentException('external id cannot be empty'); } $applicationInstallations = $this->getEntityManager()->getRepository(ApplicationInstallation::class) @@ -95,12 +89,6 @@ public function findByExternalId(string $externalId): array ->getQuery() ->getOneOrNullResult(); - if (null === $applicationInstallations) { - throw new ApplicationInstallationNotFoundException( - sprintf('application installed not found by externalId %s', $externalId) - ); - } - return $applicationInstallations; } } \ No newline at end of file diff --git a/src/Bitrix24Accounts/Entity/Bitrix24Account.php b/src/Bitrix24Accounts/Entity/Bitrix24Account.php index 1c8897c..bcea202 100644 --- a/src/Bitrix24Accounts/Entity/Bitrix24Account.php +++ b/src/Bitrix24Accounts/Entity/Bitrix24Account.php @@ -46,10 +46,10 @@ public function __construct( private CarbonImmutable $updatedAt, private int $applicationVersion, private Scope $applicationScope, - bool $isEmitBitrix24AccountCreatedEvent = false, + private $isEmitBitrix24AccountCreatedEvent = false, private ?string $comment = null ) { - $this->addAccountCreatedEventIfNeeded($isEmitBitrix24AccountCreatedEvent); + $this->addAccountCreatedEventIfNeeded($this->isEmitBitrix24AccountCreatedEvent); } #[\Override] diff --git a/src/Bitrix24Accounts/ValueObjects/Domain.php b/src/Bitrix24Accounts/ValueObjects/Domain.php index 9f72eb3..1ad69b5 100644 --- a/src/Bitrix24Accounts/ValueObjects/Domain.php +++ b/src/Bitrix24Accounts/ValueObjects/Domain.php @@ -19,11 +19,11 @@ private function validate(string $domain): void // Регулярное выражение для проверки допустимых символов (латиница и кириллица) $patternValidChars = '/^((?!-)[A-Za-zА-Яа-яЁё0-9-]{1,63}(? Date: Wed, 19 Mar 2025 00:08:32 +0300 Subject: [PATCH 10/49] =?UTF-8?q?-=20=D0=9F=D0=BE=D0=BF=D1=80=D0=B0=D0=B2?= =?UTF-8?q?=D0=B8=D0=BB=20=D1=82=D0=B5=D1=81=D1=82=D1=8B=20=D0=BD=D0=B0=20?= =?UTF-8?q?=D1=80=D0=B5=D0=BF=D0=BE=D0=B7=D0=B8=D1=82=D0=BE=D1=80=D0=B8?= =?UTF-8?q?=D0=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...ations.Entity.ApplicationInstallation.dcm.xml | 16 ++++++++-------- .../ApplicationInstallationRepository.php | 6 +++--- .../ApplicationInstallationRepositoryTest.php | 4 ++-- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/config/xml/Bitrix24.Lib.ApplicationInstallations.Entity.ApplicationInstallation.dcm.xml b/config/xml/Bitrix24.Lib.ApplicationInstallations.Entity.ApplicationInstallation.dcm.xml index 025b7f9..b128b62 100644 --- a/config/xml/Bitrix24.Lib.ApplicationInstallations.Entity.ApplicationInstallation.dcm.xml +++ b/config/xml/Bitrix24.Lib.ApplicationInstallations.Entity.ApplicationInstallation.dcm.xml @@ -7,29 +7,29 @@ + + - + + nullable="true"/> - - - - - + - + + + \ No newline at end of file diff --git a/src/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationRepository.php b/src/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationRepository.php index 72b5ed2..8a51dff 100644 --- a/src/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationRepository.php +++ b/src/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationRepository.php @@ -57,7 +57,7 @@ public function delete(Uuid $uuid): void } if ($applicationInstallation->getStatus() !== ApplicationInstallationStatus::deleted) { - throw new ApplicationInstallationNotFoundException( + throw new InvalidArgumentException( sprintf('you cannot delete application installed because you status must be deleted your status %s', $applicationInstallation->getStatus()->name) ); } @@ -72,7 +72,7 @@ public function findByBitrix24AccountId(Uuid $uuid): array ->where('appInstallation.bitrix24AccountId = :bitrix24AccountId') ->setParameter('bitrix24AccountId', $uuid) ->getQuery() - ->getOneOrNullResult(); + ->getResult(); return $applicationInstallations; } @@ -87,7 +87,7 @@ public function findByExternalId(string $externalId): array ->where('appInstallation.externalId = :externalId') ->setParameter('externalId', $externalId) ->getQuery() - ->getOneOrNullResult(); + ->getResult(); return $applicationInstallations; } diff --git a/tests/Functional/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationRepositoryTest.php b/tests/Functional/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationRepositoryTest.php index 2eb5b0d..f4df59f 100644 --- a/tests/Functional/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationRepositoryTest.php +++ b/tests/Functional/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationRepositoryTest.php @@ -68,14 +68,14 @@ protected function createApplicationInstallationRepositoryImplementation(): Appl return new ApplicationInstallationRepository($entityManager); } - /* #[\Override] + #[\Override] protected function createRepositoryFlusherImplementation(): TestRepositoryFlusherInterface { $entityManager = EntityManagerFactory::get(); $eventDispatcher = new EventDispatcher(); return new FlusherDecorator(new Flusher($entityManager, $eventDispatcher)); - }*/ + } } From da750c534c6aa7ff71313a3e4adb3546d8957c49 Mon Sep 17 00:00:00 2001 From: KarlsonComplete Date: Sun, 23 Mar 2025 11:24:44 +0300 Subject: [PATCH 11/49] =?UTF-8?q?-=20=D0=9F=D0=BE=D0=BF=D1=80=D0=B0=D0=B2?= =?UTF-8?q?=D0=B8=D0=BB=20=D1=82=D0=B5=D1=81=D1=82=D1=8B=20=D0=BD=D0=B0=20?= =?UTF-8?q?=D1=80=D0=B5=D0=BF=D0=BE=D0=B7=D0=B8=D1=82=D0=BE=D1=80=D0=B8?= =?UTF-8?q?=D0=B9=20-=20=D0=94=D0=BE=D0=BF=D0=B8=D1=81=D0=B0=D0=BB=20?= =?UTF-8?q?=D0=BE=D0=BF=D0=B8=D1=81=D0=B0=D0=BD=D0=B8=D0=B5=20=D0=BA=20?= =?UTF-8?q?=D0=BC=D0=B5=D1=82=D0=BE=D0=B4=D1=83=20validate=20=D0=B4=D0=BB?= =?UTF-8?q?=D1=8F=20=D0=B4=D0=BE=D0=BC=D0=B5=D0=BD=D0=B0=20-=20=D0=AE?= =?UTF-8?q?=D0=B7=D0=B0=D0=BD=D1=83=D0=BB=20cs-fixer=20-=20=D0=AE=D0=B7?= =?UTF-8?q?=D0=B0=D0=BD=D1=83=D0=BB=20=D1=80=D0=B5=D0=BA=D1=82=D0=BE=D1=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ....SDK.Application.ApplicationStatus.dcm.xml | 7 +++ .../Entity/ApplicationInstallation.php | 48 ++++++++----------- .../ApplicationInstallationRepository.php | 33 +++++++------ src/Bitrix24Accounts/ValueObjects/Domain.php | 30 +++++++++++- .../ApplicationInstallationBuilder.php | 32 ++++++++----- .../ApplicationInstallationRepositoryTest.php | 2 +- 6 files changed, 97 insertions(+), 55 deletions(-) create mode 100644 config/xml/Bitrix24.SDK.Application.ApplicationStatus.dcm.xml diff --git a/config/xml/Bitrix24.SDK.Application.ApplicationStatus.dcm.xml b/config/xml/Bitrix24.SDK.Application.ApplicationStatus.dcm.xml new file mode 100644 index 0000000..2a89139 --- /dev/null +++ b/config/xml/Bitrix24.SDK.Application.ApplicationStatus.dcm.xml @@ -0,0 +1,7 @@ + + + + + \ No newline at end of file diff --git a/src/ApplicationInstallations/Entity/ApplicationInstallation.php b/src/ApplicationInstallations/Entity/ApplicationInstallation.php index aa15c07..727a83d 100644 --- a/src/ApplicationInstallations/Entity/ApplicationInstallation.php +++ b/src/ApplicationInstallations/Entity/ApplicationInstallation.php @@ -3,12 +3,12 @@ declare(strict_types=1); namespace Bitrix24\Lib\ApplicationInstallations\Entity; -; use Bitrix24\Lib\AggregateRoot; use Bitrix24\SDK\Application\ApplicationStatus; use Bitrix24\SDK\Application\Contracts\ApplicationInstallations\Entity\ApplicationInstallationInterface; use Bitrix24\SDK\Application\Contracts\ApplicationInstallations\Entity\ApplicationInstallationStatus; +use Bitrix24\SDK\Application\Contracts\ApplicationInstallations\Events; use Bitrix24\SDK\Application\Contracts\ApplicationInstallations\Events\ApplicationInstallationBlockedEvent; use Bitrix24\SDK\Application\Contracts\ApplicationInstallations\Events\ApplicationInstallationFinishedEvent; use Bitrix24\SDK\Application\Contracts\ApplicationInstallations\Events\ApplicationInstallationUnblockedEvent; @@ -16,30 +16,24 @@ use Bitrix24\SDK\Application\PortalLicenseFamily; use Carbon\CarbonImmutable; use Symfony\Component\Uid\Uuid; -use Bitrix24\SDK\Application\Contracts\ApplicationInstallations\Events; -use Bitrix24\SDK\Core\Exceptions\InvalidArgumentException; class ApplicationInstallation extends AggregateRoot implements ApplicationInstallationInterface { - public function __construct( - private readonly Uuid $id, + private readonly Uuid $id, private ApplicationInstallationStatus $status, - private readonly CarbonImmutable $createdAt, - private CarbonImmutable $updatedAt, - private readonly Uuid $bitrix24AccountId, - private ApplicationStatus $applicationStatus, - private PortalLicenseFamily $portalLicenseFamily, - private ?int $portalUsersCount, - private ?Uuid $contactPersonId, - private ?Uuid $bitrix24PartnerContactPersonId, - private ?Uuid $bitrix24PartnerId, - private ?string $externalId, - private ?string $comment = null - ) - { - - } + private readonly CarbonImmutable $createdAt, + private CarbonImmutable $updatedAt, + private readonly Uuid $bitrix24AccountId, + private readonly ApplicationStatus $applicationStatus, + private readonly PortalLicenseFamily $portalLicenseFamily, + private readonly ?int $portalUsersCount, + private readonly ?Uuid $contactPersonId, + private readonly ?Uuid $bitrix24PartnerContactPersonId, + private readonly ?Uuid $bitrix24PartnerId, + private ?string $externalId, + private ?string $comment = null + ) {} #[\Override] public function getId(): Uuid @@ -82,7 +76,6 @@ public function changeContactPerson(?Uuid $uuid): void $this->contactPersonId, $uuid ); - } #[\Override] @@ -168,7 +161,6 @@ public function applicationInstalled(): void $this->bitrix24PartnerContactPersonId, $this->bitrix24PartnerId ); - } #[\Override] @@ -186,7 +178,6 @@ public function applicationUninstalled(): void $this->bitrix24PartnerId, $this->externalId ); - } #[\Override] @@ -219,7 +210,8 @@ public function markAsBlocked(?string $comment): void ApplicationInstallationStatus::new !== $this->status && ApplicationInstallationStatus::active !== $this->status ) { - throw new \LogicException(sprintf('You can block application installation only in status new or active,but your status is «%s»', + throw new \LogicException(sprintf( + 'You can block application installation only in status new or active,but your status is «%s»', $this->status->value )); } @@ -247,7 +239,7 @@ public function changeApplicationStatus(ApplicationStatus $applicationStatus): v if ($this->applicationStatus !== $applicationStatus) { $this->updatedAt = new CarbonImmutable(); - $this->events[] = new Events\ApplicationInstallationApplicationStatusChangedEvent( + $this->events[] = new Events\ApplicationInstallationApplicationStatusChangedEvent( $this->id, $this->updatedAt, $applicationStatus @@ -267,7 +259,7 @@ public function changePortalLicenseFamily(PortalLicenseFamily $portalLicenseFami if ($this->portalLicenseFamily !== $portalLicenseFamily) { $this->updatedAt = new CarbonImmutable(); - $this->events[] = new Events\ApplicationInstallationPortalLicenseFamilyChangedEvent( + $this->events[] = new Events\ApplicationInstallationPortalLicenseFamilyChangedEvent( $this->id, $this->updatedAt, $this->portalLicenseFamily, @@ -288,7 +280,7 @@ public function changePortalUsersCount(int $usersCount): void if ($this->portalUsersCount !== $usersCount) { $this->updatedAt = new CarbonImmutable(); - $this->events[] = new Events\ApplicationInstallationPortalUsersCountChangedEvent( + $this->events[] = new Events\ApplicationInstallationPortalUsersCountChangedEvent( $this->id, $this->updatedAt, $this->portalUsersCount, @@ -302,4 +294,4 @@ public function getComment(): ?string { return $this->comment; } -} \ No newline at end of file +} diff --git a/src/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationRepository.php b/src/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationRepository.php index 8a51dff..ea8b9da 100644 --- a/src/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationRepository.php +++ b/src/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationRepository.php @@ -9,10 +9,11 @@ use Bitrix24\SDK\Application\Contracts\ApplicationInstallations\Entity\ApplicationInstallationStatus; use Bitrix24\SDK\Application\Contracts\ApplicationInstallations\Exceptions\ApplicationInstallationNotFoundException; use Bitrix24\SDK\Application\Contracts\ApplicationInstallations\Repository\ApplicationInstallationRepositoryInterface; +use Bitrix24\SDK\Core\Exceptions\InvalidArgumentException; use Doctrine\ORM\EntityManagerInterface; -use Doctrine\ORM\EntityRepository; +use Doctrine\ORM\EntityRepository; use Symfony\Component\Uid\Uuid; -use Bitrix24\SDK\Core\Exceptions\InvalidArgumentException; + class ApplicationInstallationRepository extends EntityRepository implements ApplicationInstallationRepositoryInterface { public function __construct(EntityManagerInterface $entityManager) @@ -20,14 +21,15 @@ public function __construct(EntityManagerInterface $entityManager) parent::__construct($entityManager, $entityManager->getClassMetadata(ApplicationInstallation::class)); } + #[\Override] public function save(ApplicationInstallationInterface $applicationInstallation): void { $this->getEntityManager()->persist($applicationInstallation); } + #[\Override] public function getById(Uuid $uuid): ApplicationInstallationInterface { - $applicationInstallation = $this->getEntityManager()->getRepository(ApplicationInstallation::class) ->createQueryBuilder('appInstallation') ->where('appInstallation.id = :uuid') @@ -35,7 +37,8 @@ public function getById(Uuid $uuid): ApplicationInstallationInterface ->setParameter('uuid', $uuid) ->setParameter('status', ApplicationInstallationStatus::deleted) ->getQuery() - ->getOneOrNullResult(); + ->getOneOrNullResult() + ; if (null === $applicationInstallation) { throw new ApplicationInstallationNotFoundException( @@ -46,6 +49,7 @@ public function getById(Uuid $uuid): ApplicationInstallationInterface return $applicationInstallation; } + #[\Override] public function delete(Uuid $uuid): void { $applicationInstallation = $this->getEntityManager()->getRepository(ApplicationInstallation::class)->find($uuid); @@ -56,7 +60,7 @@ public function delete(Uuid $uuid): void ); } - if ($applicationInstallation->getStatus() !== ApplicationInstallationStatus::deleted) { + if (ApplicationInstallationStatus::deleted !== $applicationInstallation->getStatus()) { throw new InvalidArgumentException( sprintf('you cannot delete application installed because you status must be deleted your status %s', $applicationInstallation->getStatus()->name) ); @@ -65,30 +69,31 @@ public function delete(Uuid $uuid): void $this->save($applicationInstallation); } + #[\Override] public function findByBitrix24AccountId(Uuid $uuid): array { - $applicationInstallations = $this->getEntityManager()->getRepository(ApplicationInstallation::class) + return $this->getEntityManager()->getRepository(ApplicationInstallation::class) ->createQueryBuilder('appInstallation') ->where('appInstallation.bitrix24AccountId = :bitrix24AccountId') ->setParameter('bitrix24AccountId', $uuid) ->getQuery() - ->getResult(); - - return $applicationInstallations; + ->getResult() + ; } + #[\Override] public function findByExternalId(string $externalId): array { if ('' === trim($externalId)) { throw new InvalidArgumentException('external id cannot be empty'); } - $applicationInstallations = $this->getEntityManager()->getRepository(ApplicationInstallation::class) + + return $this->getEntityManager()->getRepository(ApplicationInstallation::class) ->createQueryBuilder('appInstallation') ->where('appInstallation.externalId = :externalId') ->setParameter('externalId', $externalId) ->getQuery() - ->getResult(); - - return $applicationInstallations; + ->getResult() + ; } -} \ No newline at end of file +} diff --git a/src/Bitrix24Accounts/ValueObjects/Domain.php b/src/Bitrix24Accounts/ValueObjects/Domain.php index 1ad69b5..86b3fe9 100644 --- a/src/Bitrix24Accounts/ValueObjects/Domain.php +++ b/src/Bitrix24Accounts/ValueObjects/Domain.php @@ -14,6 +14,34 @@ public function __construct(string $domain) $this->value = $domain; } + /* + * @return void + * + * Validates a domain name based on three main criteria: + * 1. **Allowed characters**: + * - Latin, Cyrillic, digits, and hyphens. + * - Hyphens are prohibited at the start/end of each label (regex: `$patternValidChars`). + * - Supports IDN (Internationalized Domain Names). + * 2. **Overall domain length**: + * - Not more than 255 characters (regex: `$patternLengthCheck`). + * 3. **Length of each label**: + * - From 1 to 63 characters (regex: `$patternLengthEachLabel`). + * - Maximum number of labels: 127 (as per RFC 1035). + * + * Complies with the requirements of: + * - RFC 1035 (basic domain name rules) [1]. + * - RFC 5891 (IDN) [2]. + * + * Examples of valid domains: + * - `example.com` + * - `кириллический-домен.рф` + * + * Composed of three patterns for simplicity and clarity. + * @throws \InvalidArgumentException If the domain fails any of the checks. + * + * [1] https://www.rfc-editor.org/rfc/rfc1035 + * [2] https://www.rfc-editor.org/rfc/rfc5891 + */ private function validate(string $domain): void { // Регулярное выражение для проверки допустимых символов (латиница и кириллица) @@ -23,7 +51,7 @@ private function validate(string $domain): void $patternLengthCheck = '/^.{1,255}$/'; // Проверка длины каждой метки (1-63 символа, включая кириллицу) - $patternLengthEachLabel = '/^[A-Za-zА-Яа-яЁё0-9-]{1,63}(\.[A-Za-zА-Яа-яЁё0-9-]{1,63}){0,4}$/u'; + $patternLengthEachLabel = '/^[A-Za-zА-Яа-яЁё0-9-]{1,63}(\.[A-Za-zА-Яа-яЁё0-9-]{1,63}){0,126}$/u'; if ( in_array(preg_match($patternValidChars, $domain), [0, false], true) || in_array(preg_match($patternLengthCheck, $domain), [0, false], true) diff --git a/tests/Functional/ApplicationInstallations/Builders/ApplicationInstallationBuilder.php b/tests/Functional/ApplicationInstallations/Builders/ApplicationInstallationBuilder.php index 77bf5e8..c286abb 100644 --- a/tests/Functional/ApplicationInstallations/Builders/ApplicationInstallationBuilder.php +++ b/tests/Functional/ApplicationInstallations/Builders/ApplicationInstallationBuilder.php @@ -14,17 +14,29 @@ class ApplicationInstallationBuilder { private readonly Uuid $id; + private readonly CarbonImmutable $createdAt; - private CarbonImmutable $updatedAt; + + private readonly CarbonImmutable $updatedAt; + private readonly Uuid $bitrix24AccountId; - private ?Uuid $contactPersonId; - private ?Uuid $bitrix24PartnerContactPersonId; - private ?Uuid $bitrix24PartnerId; - private ?string $externalId; + + private readonly ?Uuid $contactPersonId; + + private readonly ?Uuid $bitrix24PartnerContactPersonId; + + private readonly ?Uuid $bitrix24PartnerId; + + private ?string $externalId = null; + private ApplicationInstallationStatus $status; + private ApplicationStatus $applicationStatus; + private PortalLicenseFamily $portalLicenseFamily; - private ?int $portalUsersCount; + + private readonly ?int $portalUsersCount; + private ?string $comment = null; @@ -47,9 +59,9 @@ public function withExternalId(string $externalId): self return $this; } - public function withApplicationStatusInstallation(ApplicationInstallationStatus $status): self + public function withApplicationStatusInstallation(ApplicationInstallationStatus $applicationInstallationStatus): self { - $this->status = $status; + $this->status = $applicationInstallationStatus; return $this; } @@ -70,7 +82,7 @@ public function withPortalLicenseFamily(PortalLicenseFamily $portalLicenseFamily public function build(): ApplicationInstallation { - $applicationInstallation = new ApplicationInstallation( + return new ApplicationInstallation( $this->id, $this->status, $this->createdAt, @@ -85,8 +97,6 @@ public function build(): ApplicationInstallation $this->externalId, $this->comment ); - - return $applicationInstallation; } diff --git a/tests/Functional/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationRepositoryTest.php b/tests/Functional/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationRepositoryTest.php index f4df59f..e332b53 100644 --- a/tests/Functional/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationRepositoryTest.php +++ b/tests/Functional/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationRepositoryTest.php @@ -11,7 +11,6 @@ use Bitrix24\SDK\Application\Contracts\ApplicationInstallations\Entity\ApplicationInstallationStatus; use Bitrix24\SDK\Application\Contracts\ApplicationInstallations\Repository\ApplicationInstallationRepositoryInterface; use Bitrix24\SDK\Application\PortalLicenseFamily; -use Bitrix24\SDK\Tests\Application\Contracts\ApplicationInstallations\Entity\ApplicationInstallationInterfaceTest; use Bitrix24\SDK\Tests\Application\Contracts\ApplicationInstallations\Repository\ApplicationInstallationRepositoryInterfaceTest; use Bitrix24\SDK\Tests\Application\Contracts\TestRepositoryFlusherInterface; use Carbon\CarbonImmutable; @@ -29,6 +28,7 @@ class ApplicationInstallationRepositoryTest extends ApplicationInstallationRepositoryInterfaceTest { + #[\Override] protected function createApplicationInstallationImplementation( Uuid $uuid, ApplicationInstallationStatus $applicationInstallationStatus, From cb71267a4e18d59089a061566afd540eec68abf7 Mon Sep 17 00:00:00 2001 From: KarlsonComplete Date: Sun, 23 Mar 2025 20:34:44 +0300 Subject: [PATCH 12/49] =?UTF-8?q?-=20=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8?= =?UTF-8?q?=D0=BB=20=D1=8E=D0=BD=D0=B8=D1=82=20=D1=82=D0=B5=D1=81=D1=82?= =?UTF-8?q?=D1=8B=20=D0=B8=D0=B7=20sdk=20-=20=D0=9F=D0=BE=D0=BF=D1=80?= =?UTF-8?q?=D0=B0=D0=B2=D0=B8=D0=BB=20=D1=81=D1=83=D1=89=D0=BD=D0=BE=D1=81?= =?UTF-8?q?=D1=82=D1=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Entity/ApplicationInstallation.php | 43 ++++++++++++--- .../Entity/ApplicationInstallationTest.php | 53 +++++++++++++++++++ 2 files changed, 90 insertions(+), 6 deletions(-) create mode 100644 tests/Unit/ApplicationInstallations/Entity/ApplicationInstallationTest.php diff --git a/src/ApplicationInstallations/Entity/ApplicationInstallation.php b/src/ApplicationInstallations/Entity/ApplicationInstallation.php index 727a83d..cac917c 100644 --- a/src/ApplicationInstallations/Entity/ApplicationInstallation.php +++ b/src/ApplicationInstallations/Entity/ApplicationInstallation.php @@ -16,6 +16,7 @@ use Bitrix24\SDK\Application\PortalLicenseFamily; use Carbon\CarbonImmutable; use Symfony\Component\Uid\Uuid; +use Bitrix24\SDK\Core\Exceptions\InvalidArgumentException; class ApplicationInstallation extends AggregateRoot implements ApplicationInstallationInterface { @@ -25,12 +26,12 @@ public function __construct( private readonly CarbonImmutable $createdAt, private CarbonImmutable $updatedAt, private readonly Uuid $bitrix24AccountId, - private readonly ApplicationStatus $applicationStatus, - private readonly PortalLicenseFamily $portalLicenseFamily, - private readonly ?int $portalUsersCount, - private readonly ?Uuid $contactPersonId, - private readonly ?Uuid $bitrix24PartnerContactPersonId, - private readonly ?Uuid $bitrix24PartnerId, + private ApplicationStatus $applicationStatus, + private PortalLicenseFamily $portalLicenseFamily, + private ?int $portalUsersCount, + private ?Uuid $contactPersonId, + private ?Uuid $bitrix24PartnerContactPersonId, + private ?Uuid $bitrix24PartnerId, private ?string $externalId, private ?string $comment = null ) {} @@ -70,6 +71,8 @@ public function changeContactPerson(?Uuid $uuid): void { $this->updatedAt = new CarbonImmutable(); + $this->contactPersonId = $uuid; + $this->events[] = new Events\ApplicationInstallationContactPersonChangedEvent( $this->id, $this->updatedAt, @@ -89,6 +92,8 @@ public function changeBitrix24PartnerContactPerson(?Uuid $uuid): void { $this->updatedAt = new CarbonImmutable(); + $this->bitrix24PartnerContactPersonId = $uuid; + $this->events[] = new Events\ApplicationInstallationBitrix24PartnerContactPersonChangedEvent( $this->id, $this->updatedAt, @@ -108,6 +113,8 @@ public function changeBitrix24Partner(?Uuid $uuid): void { $this->updatedAt = new CarbonImmutable(); + $this->bitrix24PartnerId = $uuid; + $this->events[] = new Events\ApplicationInstallationBitrix24PartnerChangedEvent( $this->id, $this->updatedAt, @@ -125,6 +132,9 @@ public function getExternalId(): ?string #[\Override] public function setExternalId(?string $externalId): void { + if ($externalId === '') { + throw new InvalidArgumentException('ExternalId cannot be empty string'); + } $this->externalId = $externalId; } @@ -166,6 +176,19 @@ public function applicationInstalled(): void #[\Override] public function applicationUninstalled(): void { + + if ( + ApplicationInstallationStatus::active !== $this->status + && ApplicationInstallationStatus::blocked !== $this->status + ) { + throw new \LogicException( + sprintf( + 'installation was interrupted because status must be in active or blocked, but your status is %s', + $this->status->value + ) + ); + } + $this->status = ApplicationInstallationStatus::deleted; $this->updatedAt = new CarbonImmutable(); @@ -237,6 +260,7 @@ public function getApplicationStatus(): ApplicationStatus public function changeApplicationStatus(ApplicationStatus $applicationStatus): void { if ($this->applicationStatus !== $applicationStatus) { + $this->applicationStatus = $applicationStatus; $this->updatedAt = new CarbonImmutable(); $this->events[] = new Events\ApplicationInstallationApplicationStatusChangedEvent( @@ -258,6 +282,7 @@ public function changePortalLicenseFamily(PortalLicenseFamily $portalLicenseFami { if ($this->portalLicenseFamily !== $portalLicenseFamily) { $this->updatedAt = new CarbonImmutable(); + $this->portalLicenseFamily = $portalLicenseFamily; $this->events[] = new Events\ApplicationInstallationPortalLicenseFamilyChangedEvent( $this->id, @@ -277,7 +302,13 @@ public function getPortalUsersCount(): ?int #[\Override] public function changePortalUsersCount(int $usersCount): void { + if ($usersCount < 0) { + throw new \InvalidArgumentException('Users count can not be negative'); + } + if ($this->portalUsersCount !== $usersCount) { + + $this->portalUsersCount = $usersCount; $this->updatedAt = new CarbonImmutable(); $this->events[] = new Events\ApplicationInstallationPortalUsersCountChangedEvent( diff --git a/tests/Unit/ApplicationInstallations/Entity/ApplicationInstallationTest.php b/tests/Unit/ApplicationInstallations/Entity/ApplicationInstallationTest.php new file mode 100644 index 0000000..f103667 --- /dev/null +++ b/tests/Unit/ApplicationInstallations/Entity/ApplicationInstallationTest.php @@ -0,0 +1,53 @@ + Date: Mon, 24 Mar 2025 23:05:25 +0300 Subject: [PATCH 13/49] =?UTF-8?q?-=20=D0=9F=D1=80=D0=BE=D1=82=D0=B5=D1=81?= =?UTF-8?q?=D1=82=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BB=20unit=20=D1=82?= =?UTF-8?q?=D0=B5=D1=81=D1=82=D1=8B.=20-=20=D0=9F=D0=BE=D0=BF=D1=80=D0=B0?= =?UTF-8?q?=D0=B2=D0=B8=D0=BB=20=D0=B4=D0=BE=D0=BC=D0=B5=D0=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Bitrix24Accounts/ValueObjects/Domain.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Bitrix24Accounts/ValueObjects/Domain.php b/src/Bitrix24Accounts/ValueObjects/Domain.php index 86b3fe9..e172b22 100644 --- a/src/Bitrix24Accounts/ValueObjects/Domain.php +++ b/src/Bitrix24Accounts/ValueObjects/Domain.php @@ -44,13 +44,13 @@ public function __construct(string $domain) */ private function validate(string $domain): void { - // Регулярное выражение для проверки допустимых символов (латиница и кириллица) + // Regular expression for checking available symbol (Latin and Cyrillic) $patternValidChars = '/^((?!-)[A-Za-zА-Яа-яЁё0-9-]{1,63}(? Date: Mon, 24 Mar 2025 23:17:32 +0300 Subject: [PATCH 14/49] =?UTF-8?q?-=20=D0=AE=D0=B7=D0=B0=D0=BD=D1=83=D0=BB?= =?UTF-8?q?=20=D1=80=D0=B5=D0=BA=D1=82=D0=BE=D1=80=20=D0=B8=20cs-fixer?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Entity/ApplicationInstallation.php | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/ApplicationInstallations/Entity/ApplicationInstallation.php b/src/ApplicationInstallations/Entity/ApplicationInstallation.php index cac917c..acf8a51 100644 --- a/src/ApplicationInstallations/Entity/ApplicationInstallation.php +++ b/src/ApplicationInstallations/Entity/ApplicationInstallation.php @@ -14,9 +14,9 @@ use Bitrix24\SDK\Application\Contracts\ApplicationInstallations\Events\ApplicationInstallationUnblockedEvent; use Bitrix24\SDK\Application\Contracts\ApplicationInstallations\Events\ApplicationInstallationUninstalledEvent; use Bitrix24\SDK\Application\PortalLicenseFamily; +use Bitrix24\SDK\Core\Exceptions\InvalidArgumentException; use Carbon\CarbonImmutable; use Symfony\Component\Uid\Uuid; -use Bitrix24\SDK\Core\Exceptions\InvalidArgumentException; class ApplicationInstallation extends AggregateRoot implements ApplicationInstallationInterface { @@ -132,9 +132,10 @@ public function getExternalId(): ?string #[\Override] public function setExternalId(?string $externalId): void { - if ($externalId === '') { + if ('' === $externalId) { throw new InvalidArgumentException('ExternalId cannot be empty string'); } + $this->externalId = $externalId; } @@ -176,7 +177,6 @@ public function applicationInstalled(): void #[\Override] public function applicationUninstalled(): void { - if ( ApplicationInstallationStatus::active !== $this->status && ApplicationInstallationStatus::blocked !== $this->status @@ -307,7 +307,6 @@ public function changePortalUsersCount(int $usersCount): void } if ($this->portalUsersCount !== $usersCount) { - $this->portalUsersCount = $usersCount; $this->updatedAt = new CarbonImmutable(); From edb04f3d9b594122778435cca5b04ee30a649502 Mon Sep 17 00:00:00 2001 From: KarlsonComplete Date: Sun, 30 Mar 2025 13:06:40 +0300 Subject: [PATCH 15/49] =?UTF-8?q?-=20=D0=AE=D0=B7=D0=B0=D0=BD=D1=83=D0=BB?= =?UTF-8?q?=20=D1=80=D0=B5=D0=BA=D1=82=D0=BE=D1=80=20=D0=B8=20cs-fixer=20-?= =?UTF-8?q?=20=D0=9D=D0=B0=D0=BF=D0=B8=D1=81=D0=B0=D0=BB=20UseCase=20?= =?UTF-8?q?=D0=BD=D0=B0=20=D1=83=D1=81=D1=82=D0=B0=D0=BD=D0=BE=D0=B2=D0=BA?= =?UTF-8?q?=D1=83=20=D0=BF=D1=80=D0=B8=D0=BB=D0=BE=D0=B6=D0=B5=D0=BD=D0=B8?= =?UTF-8?q?=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../UseCase/InstallStart/Command.php | 42 ++++++++ .../UseCase/InstallStart/Handler.php | 54 ++++++++++ .../ApplicationInstallationBuilder.php | 2 +- .../UseCase/InstallStart/HandlerTest.php | 100 ++++++++++++++++++ 4 files changed, 197 insertions(+), 1 deletion(-) create mode 100644 src/ApplicationInstallations/UseCase/InstallStart/Command.php create mode 100644 src/ApplicationInstallations/UseCase/InstallStart/Handler.php create mode 100644 tests/Functional/ApplicationInstallations/UseCase/InstallStart/HandlerTest.php diff --git a/src/ApplicationInstallations/UseCase/InstallStart/Command.php b/src/ApplicationInstallations/UseCase/InstallStart/Command.php new file mode 100644 index 0000000..c736239 --- /dev/null +++ b/src/ApplicationInstallations/UseCase/InstallStart/Command.php @@ -0,0 +1,42 @@ +validate(); + } + + private function validate(): void + { + if ($this->portalUsersCount <= 0) { + throw new \InvalidArgumentException('Bitrix24 User ID must be a positive integer.'); + } + + if ('' === $this->externalId) { + throw new \InvalidArgumentException('Member ID must be a non-empty string.'); + } + + if ('' === $this->comment) { + throw new \InvalidArgumentException('Member ID must be a non-empty string.'); + } + } +} diff --git a/src/ApplicationInstallations/UseCase/InstallStart/Handler.php b/src/ApplicationInstallations/UseCase/InstallStart/Handler.php new file mode 100644 index 0000000..8c6ec7a --- /dev/null +++ b/src/ApplicationInstallations/UseCase/InstallStart/Handler.php @@ -0,0 +1,54 @@ +logger->info('ApplicationInstallations.InstallStart.start', [ + 'id' => $command->uuid->toRfc4122(), + ]); + + $applicationInstallation = new ApplicationInstallation( + $command->uuid, + ApplicationInstallationStatus::new, + new CarbonImmutable(), + new CarbonImmutable(), + $command->bitrix24AccountId, + $command->applicationStatus, + $command->portalLicenseFamily, + $command->portalUsersCount, + $command->contactPersonId, + $command->bitrix24PartnerContactPersonId, + $command->bitrix24PartnerId, + $command->externalId, + $command->comment + ); + + $this->applicationInstallationRepository->save($applicationInstallation); + $this->flusher->flush(); + + $this->logger->info( + 'Bitrix24Accounts.InstallStart.Finish', + [ + 'id' => $command->uuid->toRfc4122(), + ] + ); + } +} diff --git a/tests/Functional/ApplicationInstallations/Builders/ApplicationInstallationBuilder.php b/tests/Functional/ApplicationInstallations/Builders/ApplicationInstallationBuilder.php index c286abb..72f3c82 100644 --- a/tests/Functional/ApplicationInstallations/Builders/ApplicationInstallationBuilder.php +++ b/tests/Functional/ApplicationInstallations/Builders/ApplicationInstallationBuilder.php @@ -29,7 +29,7 @@ class ApplicationInstallationBuilder private ?string $externalId = null; - private ApplicationInstallationStatus $status; + private ApplicationInstallationStatus $status = ApplicationInstallationStatus::active; private ApplicationStatus $applicationStatus; diff --git a/tests/Functional/ApplicationInstallations/UseCase/InstallStart/HandlerTest.php b/tests/Functional/ApplicationInstallations/UseCase/InstallStart/HandlerTest.php new file mode 100644 index 0000000..aa3db9b --- /dev/null +++ b/tests/Functional/ApplicationInstallations/UseCase/InstallStart/HandlerTest.php @@ -0,0 +1,100 @@ + + * + * For the full copyright and license information, please view the MIT-LICENSE.txt + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace Bitrix24\Lib\Tests\Functional\ApplicationInstallations\UseCase\InstallStart; + + +use Bitrix24\Lib\Bitrix24Accounts; + +use Bitrix24\Lib\Services\Flusher; +use Bitrix24\Lib\ApplicationInstallations; +use Bitrix24\Lib\Tests\EntityManagerFactory; + +use Bitrix24\Lib\Tests\Functional\ApplicationInstallations\Builders\ApplicationInstallationBuilder; +use Bitrix24\SDK\Application\ApplicationStatus; +use Bitrix24\SDK\Application\Contracts\ApplicationInstallations\Entity\ApplicationInstallationStatus; +use Bitrix24\SDK\Application\PortalLicenseFamily; +use Bitrix24\SDK\Core\Exceptions\InvalidArgumentException; + +use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\Attributes\Test; +use PHPUnit\Framework\TestCase; +use Psr\Log\NullLogger; +use Bitrix24\SDK\Application\Contracts\ApplicationInstallations\Exceptions\ApplicationInstallationNotFoundException; +use Symfony\Component\EventDispatcher\Debug\TraceableEventDispatcher; +use Symfony\Component\EventDispatcher\EventDispatcher; +use Symfony\Component\Stopwatch\Stopwatch; + +use Bitrix24\Lib\ApplicationInstallations\Infrastructure\Doctrine\ApplicationInstallationRepository; +use Bitrix24\Lib\ApplicationInstallations\UseCase\InstallStart\Handler; + +/** + * @internal + */ +#[CoversClass(ApplicationInstallations\UseCase\InstallStart\Handler::class)] +class HandlerTest extends TestCase +{ + private Handler $handler; + + private Flusher $flusher; + + private ApplicationInstallationRepository $repository; + + private TraceableEventDispatcher $eventDispatcher; + + #[\Override] + protected function setUp(): void + { + $entityManager = EntityManagerFactory::get(); + $this->eventDispatcher = new TraceableEventDispatcher(new EventDispatcher(), new Stopwatch()); + $this->repository = new ApplicationInstallationRepository($entityManager); + $this->flusher = new Flusher($entityManager, $this->eventDispatcher); + $this->handler = new Handler( + $this->repository, + $this->flusher, + new NullLogger() + ); + } + + /** + * @throws InvalidArgumentException + * @throws ApplicationInstallationNotFoundException + */ + #[Test] + public function testInstallNewApplicationInstallation(): void + { + $applicationInstallationBuilder = (new ApplicationInstallationBuilder()) + ->withApplicationStatus(new ApplicationStatus('F')) + ->withPortalLicenseFamily(PortalLicenseFamily::free) + ->build(); + + $this->handler->handle( + new ApplicationInstallations\UseCase\InstallStart\Command( + $applicationInstallationBuilder->getId(), + $applicationInstallationBuilder->getBitrix24AccountId(), + $applicationInstallationBuilder->getApplicationStatus(), + $applicationInstallationBuilder->getPortalLicenseFamily(), + $applicationInstallationBuilder->getPortalUsersCount(), + $applicationInstallationBuilder->getContactPersonId(), + $applicationInstallationBuilder->getBitrix24PartnerContactPersonId(), + $applicationInstallationBuilder->getBitrix24PartnerId(), + $applicationInstallationBuilder->getExternalId(), + $applicationInstallationBuilder->getComment() + ) + ); + + $applicationInstallation = $this->repository->getById($applicationInstallationBuilder->getId()); + + $this->assertEquals(ApplicationInstallationStatus::new, $applicationInstallation->getStatus()); + } +} From 5eef8732fe1939cd6dd4c6b8b729527e53b66c94 Mon Sep 17 00:00:00 2001 From: KarlsonComplete Date: Tue, 1 Apr 2025 00:49:06 +0300 Subject: [PATCH 16/49] =?UTF-8?q?-=20=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8?= =?UTF-8?q?=D0=BB=20=D0=B2=20=D1=81=D1=83=D1=89=D0=BD=D0=BE=D1=81=D1=82?= =?UTF-8?q?=D1=8C=20=D0=BC=D0=B5=D1=82=D0=BE=D0=B4=20=D0=B4=D0=BB=D1=8F=20?= =?UTF-8?q?=D0=B2=D1=8B=D0=B1=D1=80=D0=BE=D1=81=D0=B0=20=D1=81=D0=BE=D0=B1?= =?UTF-8?q?=D1=8B=D1=82=D0=B8=D1=8F=20=D1=83=D1=81=D1=82=D0=B0=D0=BD=D0=BE?= =?UTF-8?q?=D0=B2=D0=BA=D0=B8=20-=20=D0=9F=D0=BE=D0=BF=D1=80=D0=B0=D0=B2?= =?UTF-8?q?=D0=B8=D0=BB=20handler=20=D0=B4=D0=BB=D1=8F=20=D1=83=D1=81?= =?UTF-8?q?=D1=82=D0=B0=D0=BD=D0=BE=D0=B2=D0=BA=D0=B8=20=D0=BF=D1=80=D0=B8?= =?UTF-8?q?=D0=BB=D0=BE=D0=B6=D0=B5=D0=BD=D0=B8=D1=8F=20-=20=D0=A2=D0=B5?= =?UTF-8?q?=D1=81=D1=82=20=D0=BD=D0=B0=20=D1=83=D1=81=D1=82=D0=B0=D0=BD?= =?UTF-8?q?=D0=BE=D0=B2=D0=BA=D1=83=20(=D0=B2=D0=BA=D0=BB=D1=8E=D1=87?= =?UTF-8?q?=D0=B0=D1=8E=D1=89=D0=B8=D0=B9=20=D0=B2=20=D1=81=D0=B5=D0=B1?= =?UTF-8?q?=D1=8F=20=D0=B0=D0=BA=D0=BA=D0=B0=D1=83=D0=BD=D1=82=20=D0=B1?= =?UTF-8?q?=D0=B8=D1=82=D1=80=D0=B8=D0=BA=D1=81=2024)=20-=D0=A2=D0=B5?= =?UTF-8?q?=D1=81=D1=82=20=D0=BD=D0=B0=20=D0=BC=D0=B5=D1=82=D0=BE=D0=B4=20?= =?UTF-8?q?ChangePortalLicenseFamily?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Entity/ApplicationInstallation.php | 21 +++++- .../UseCase/InstallStart/Handler.php | 5 +- .../UseCase/InstallStart/HandlerTest.php | 64 ++++++++++++++++--- .../ChangePortalLicenseFamily.php | 33 ++++++++++ 4 files changed, 110 insertions(+), 13 deletions(-) create mode 100644 tests/Unit/ApplicationInstallations/MethodValidation/ChangePortalLicenseFamily.php diff --git a/src/ApplicationInstallations/Entity/ApplicationInstallation.php b/src/ApplicationInstallations/Entity/ApplicationInstallation.php index acf8a51..90c8478 100644 --- a/src/ApplicationInstallations/Entity/ApplicationInstallation.php +++ b/src/ApplicationInstallations/Entity/ApplicationInstallation.php @@ -10,6 +10,7 @@ use Bitrix24\SDK\Application\Contracts\ApplicationInstallations\Entity\ApplicationInstallationStatus; use Bitrix24\SDK\Application\Contracts\ApplicationInstallations\Events; use Bitrix24\SDK\Application\Contracts\ApplicationInstallations\Events\ApplicationInstallationBlockedEvent; +use Bitrix24\SDK\Application\Contracts\ApplicationInstallations\Events\ApplicationInstallationCreatedEvent; use Bitrix24\SDK\Application\Contracts\ApplicationInstallations\Events\ApplicationInstallationFinishedEvent; use Bitrix24\SDK\Application\Contracts\ApplicationInstallations\Events\ApplicationInstallationUnblockedEvent; use Bitrix24\SDK\Application\Contracts\ApplicationInstallations\Events\ApplicationInstallationUninstalledEvent; @@ -33,8 +34,11 @@ public function __construct( private ?Uuid $bitrix24PartnerContactPersonId, private ?Uuid $bitrix24PartnerId, private ?string $externalId, - private ?string $comment = null - ) {} + private ?string $comment = null, + private $isEmitApplicationInstallationCreatedEvent = false, + ) { + $this->addApplicationCreatedEventIfNeeded($this->isEmitApplicationInstallationCreatedEvent); + } #[\Override] public function getId(): Uuid @@ -324,4 +328,17 @@ public function getComment(): ?string { return $this->comment; } + + private function addApplicationCreatedEventIfNeeded(bool $isEmitCreatedEvent): void + { + + if ($isEmitCreatedEvent) { + // Создание события и добавление его в массив событий + $this->events[] = new ApplicationInstallationCreatedEvent( + $this->id, + $this->createdAt, + $this->bitrix24AccountId + ); + } + } } diff --git a/src/ApplicationInstallations/UseCase/InstallStart/Handler.php b/src/ApplicationInstallations/UseCase/InstallStart/Handler.php index 8c6ec7a..7b1e474 100644 --- a/src/ApplicationInstallations/UseCase/InstallStart/Handler.php +++ b/src/ApplicationInstallations/UseCase/InstallStart/Handler.php @@ -38,11 +38,12 @@ public function handle(Command $command): void $command->bitrix24PartnerContactPersonId, $command->bitrix24PartnerId, $command->externalId, - $command->comment + $command->comment, + true ); $this->applicationInstallationRepository->save($applicationInstallation); - $this->flusher->flush(); + $this->flusher->flush($applicationInstallation); $this->logger->info( 'Bitrix24Accounts.InstallStart.Finish', diff --git a/tests/Functional/ApplicationInstallations/UseCase/InstallStart/HandlerTest.php b/tests/Functional/ApplicationInstallations/UseCase/InstallStart/HandlerTest.php index aa3db9b..242fdd6 100644 --- a/tests/Functional/ApplicationInstallations/UseCase/InstallStart/HandlerTest.php +++ b/tests/Functional/ApplicationInstallations/UseCase/InstallStart/HandlerTest.php @@ -16,14 +16,19 @@ use Bitrix24\Lib\Bitrix24Accounts; +use Bitrix24\Lib\Bitrix24Accounts\ValueObjects\Domain; use Bitrix24\Lib\Services\Flusher; use Bitrix24\Lib\ApplicationInstallations; use Bitrix24\Lib\Tests\EntityManagerFactory; use Bitrix24\Lib\Tests\Functional\ApplicationInstallations\Builders\ApplicationInstallationBuilder; +use Bitrix24\Lib\Tests\Functional\Bitrix24Accounts\Builders\Bitrix24AccountBuilder; use Bitrix24\SDK\Application\ApplicationStatus; use Bitrix24\SDK\Application\Contracts\ApplicationInstallations\Entity\ApplicationInstallationStatus; +use Bitrix24\SDK\Application\Contracts\Bitrix24Accounts\Events\Bitrix24AccountCreatedEvent; +use Bitrix24\SDK\Application\Contracts\Bitrix24Accounts\Exceptions\Bitrix24AccountNotFoundException; use Bitrix24\SDK\Application\PortalLicenseFamily; +use Bitrix24\SDK\Core\Credentials\Scope; use Bitrix24\SDK\Core\Exceptions\InvalidArgumentException; use PHPUnit\Framework\Attributes\CoversClass; @@ -38,17 +43,21 @@ use Bitrix24\Lib\ApplicationInstallations\Infrastructure\Doctrine\ApplicationInstallationRepository; use Bitrix24\Lib\ApplicationInstallations\UseCase\InstallStart\Handler; +use Bitrix24\Lib\Bitrix24Accounts\Infrastructure\Doctrine\Bitrix24AccountRepository; /** * @internal */ #[CoversClass(ApplicationInstallations\UseCase\InstallStart\Handler::class)] class HandlerTest extends TestCase { - private Handler $handler; + private Handler $handlerApplicationInstallation; + private Bitrix24Accounts\UseCase\InstallStart\Handler $handlerBitrix24Account; private Flusher $flusher; - private ApplicationInstallationRepository $repository; + private ApplicationInstallationRepository $applicationInstallationRepository; + + private Bitrix24AccountRepository $bitrix24AccountRepository; private TraceableEventDispatcher $eventDispatcher; @@ -57,31 +66,63 @@ protected function setUp(): void { $entityManager = EntityManagerFactory::get(); $this->eventDispatcher = new TraceableEventDispatcher(new EventDispatcher(), new Stopwatch()); - $this->repository = new ApplicationInstallationRepository($entityManager); + $this->applicationInstallationRepository = new ApplicationInstallationRepository($entityManager); + $this->bitrix24AccountRepository = new Bitrix24AccountRepository($entityManager); $this->flusher = new Flusher($entityManager, $this->eventDispatcher); - $this->handler = new Handler( - $this->repository, + + $this->handlerApplicationInstallation = new Handler( + $this->applicationInstallationRepository, $this->flusher, new NullLogger() ); + + $this->handlerBitrix24Account = new Bitrix24Accounts\UseCase\InstallStart\Handler( + $this->bitrix24AccountRepository, + $this->flusher, + new NullLogger() + ); + } /** * @throws InvalidArgumentException - * @throws ApplicationInstallationNotFoundException + * @throws Bitrix24AccountNotFoundException|ApplicationInstallationNotFoundException */ #[Test] public function testInstallNewApplicationInstallation(): void { + + $bitrix24AccountBuilder = (new Bitrix24AccountBuilder()) + ->withApplicationScope(new Scope(['crm'])) + ->build(); + + $this->handlerBitrix24Account->handle( + new Bitrix24Accounts\UseCase\InstallStart\Command( + $bitrix24AccountBuilder->getId(), + $bitrix24AccountBuilder->getBitrix24UserId(), + $bitrix24AccountBuilder->isBitrix24UserAdmin(), + $bitrix24AccountBuilder->getMemberId(), + new Domain($bitrix24AccountBuilder->getDomainUrl()), + $bitrix24AccountBuilder->getAuthToken(), + $bitrix24AccountBuilder->getApplicationVersion(), + $bitrix24AccountBuilder->getApplicationScope() + ) + ); + + $bitrix24Account = $this->bitrix24AccountRepository->getById($bitrix24AccountBuilder->getId()); + + $this->assertEquals($bitrix24Account->getId(), $bitrix24AccountBuilder->getId()); + + $applicationInstallationBuilder = (new ApplicationInstallationBuilder()) ->withApplicationStatus(new ApplicationStatus('F')) ->withPortalLicenseFamily(PortalLicenseFamily::free) ->build(); - $this->handler->handle( + $this->handlerApplicationInstallation->handle( new ApplicationInstallations\UseCase\InstallStart\Command( $applicationInstallationBuilder->getId(), - $applicationInstallationBuilder->getBitrix24AccountId(), + $bitrix24AccountBuilder->getId(), $applicationInstallationBuilder->getApplicationStatus(), $applicationInstallationBuilder->getPortalLicenseFamily(), $applicationInstallationBuilder->getPortalUsersCount(), @@ -93,8 +134,13 @@ public function testInstallNewApplicationInstallation(): void ) ); - $applicationInstallation = $this->repository->getById($applicationInstallationBuilder->getId()); + $applicationInstallation = $this->applicationInstallationRepository->getById($applicationInstallationBuilder->getId()); + + $dispatchedEvents = $this->eventDispatcher->getOrphanedEvents(); + print_r($dispatchedEvents); // Выводит список событий + $this->assertContains('Bitrix24\SDK\Application\Contracts\Bitrix24Accounts\Events\Bitrix24AccountCreatedEvent', $dispatchedEvents); + $this->assertContains('Bitrix24\SDK\Application\Contracts\ApplicationInstallations\Events\ApplicationInstallationCreatedEvent', $dispatchedEvents); $this->assertEquals(ApplicationInstallationStatus::new, $applicationInstallation->getStatus()); } } diff --git a/tests/Unit/ApplicationInstallations/MethodValidation/ChangePortalLicenseFamily.php b/tests/Unit/ApplicationInstallations/MethodValidation/ChangePortalLicenseFamily.php new file mode 100644 index 0000000..1e94ace --- /dev/null +++ b/tests/Unit/ApplicationInstallations/MethodValidation/ChangePortalLicenseFamily.php @@ -0,0 +1,33 @@ +withPortalLicenseFamily(PortalLicenseFamily::free) + ->withApplicationStatus(new ApplicationStatus('F')) + ->build(); + $applicationInstallation->changePortalLicenseFamily(PortalLicenseFamily::basic); + $this->assertEquals(PortalLicenseFamily::basic, $applicationInstallation->getPortalLicenseFamily()); + } + + public function testNotEqualsChangePortalLicenseFamily(): void + { + $applicationInstallation = (new ApplicationInstallationBuilder) + ->withPortalLicenseFamily(PortalLicenseFamily::free) + ->withApplicationStatus(new ApplicationStatus('F')) + ->build(); + $initialUpdatedAt = $applicationInstallation->getUpdatedAt(); + $applicationInstallation->changePortalLicenseFamily(PortalLicenseFamily::free); + $this->assertEquals($initialUpdatedAt, $applicationInstallation->getUpdatedAt()); + } +} From 50e64f4e29d9022c047b167bba93c85164bc337d Mon Sep 17 00:00:00 2001 From: KarlsonComplete Date: Thu, 3 Apr 2025 21:33:39 +0300 Subject: [PATCH 17/49] =?UTF-8?q?-=20=D0=9F=D0=BE=D0=BF=D1=80=D0=B0=D0=B2?= =?UTF-8?q?=D0=B8=D0=BB=20=D1=82=D0=B5=D1=81=D1=82=20=D0=BD=D0=B0=20=D1=83?= =?UTF-8?q?=D1=81=D1=82=D0=B0=D0=BD=D0=BE=D0=B2=D0=BA=D1=83=20(=D0=B2?= =?UTF-8?q?=D0=BA=D0=BB=D1=8E=D1=87=D0=B0=D1=8E=D1=89=D0=B8=D0=B9=20=D0=B2?= =?UTF-8?q?=20=D1=81=D0=B5=D0=B1=D1=8F=20=D0=B0=D0=BA=D0=BA=D0=B0=D1=83?= =?UTF-8?q?=D0=BD=D1=82=20=D0=B1=D0=B8=D1=82=D1=80=D0=B8=D0=BA=D1=81=2024)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../UseCase/InstallStart/Command.php | 30 +++++++++- .../UseCase/InstallStart/Handler.php | 22 +++++++ .../UseCase/InstallStart/HandlerTest.php | 58 +++++++------------ 3 files changed, 69 insertions(+), 41 deletions(-) diff --git a/src/ApplicationInstallations/UseCase/InstallStart/Command.php b/src/ApplicationInstallations/UseCase/InstallStart/Command.php index c736239..79be3a9 100644 --- a/src/ApplicationInstallations/UseCase/InstallStart/Command.php +++ b/src/ApplicationInstallations/UseCase/InstallStart/Command.php @@ -4,8 +4,11 @@ namespace Bitrix24\Lib\ApplicationInstallations\UseCase\InstallStart; +use Bitrix24\Lib\Bitrix24Accounts\ValueObjects\Domain; use Bitrix24\SDK\Application\ApplicationStatus; use Bitrix24\SDK\Application\PortalLicenseFamily; +use Bitrix24\SDK\Core\Credentials\AuthToken; +use Bitrix24\SDK\Core\Credentials\Scope; use Symfony\Component\Uid\Uuid; readonly class Command @@ -20,23 +23,44 @@ public function __construct( public ?Uuid $bitrix24PartnerContactPersonId, public ?Uuid $bitrix24PartnerId, public ?string $externalId, - public ?string $comment + public ?string $comment, + public Uuid $bitrix24AccountUuid, + public int $bitrix24UserId, + public bool $isBitrix24UserAdmin, + public string $memberId, + public Domain $domain, + public AuthToken $authToken, + public int $applicationVersion, + public Scope $applicationScope ) { $this->validate(); } + private function validate(): void { if ($this->portalUsersCount <= 0) { - throw new \InvalidArgumentException('Bitrix24 User ID must be a positive integer.'); + throw new \InvalidArgumentException('Portal Users count must be a positive integer.'); } if ('' === $this->externalId) { - throw new \InvalidArgumentException('Member ID must be a non-empty string.'); + throw new \InvalidArgumentException('External ID must be a non-empty string.'); } if ('' === $this->comment) { + throw new \InvalidArgumentException('Comment must be a non-empty string.'); + } + + if ($this->bitrix24UserId <= 0) { + throw new \InvalidArgumentException('Bitrix24 User ID must be a positive integer.'); + } + + if ('' === $this->memberId) { throw new \InvalidArgumentException('Member ID must be a non-empty string.'); } + + if ($this->applicationVersion <= 0) { + throw new \InvalidArgumentException('Application version must be a positive integer.'); + } } } diff --git a/src/ApplicationInstallations/UseCase/InstallStart/Handler.php b/src/ApplicationInstallations/UseCase/InstallStart/Handler.php index 7b1e474..0ae2ada 100644 --- a/src/ApplicationInstallations/UseCase/InstallStart/Handler.php +++ b/src/ApplicationInstallations/UseCase/InstallStart/Handler.php @@ -6,14 +6,18 @@ use Bitrix24\Lib\ApplicationInstallations\Entity\ApplicationInstallation; use Bitrix24\Lib\ApplicationInstallations\Infrastructure\Doctrine\ApplicationInstallationRepository; +use Bitrix24\Lib\Bitrix24Accounts\Entity\Bitrix24Account; +use Bitrix24\Lib\Bitrix24Accounts\Infrastructure\Doctrine\Bitrix24AccountRepository; use Bitrix24\Lib\Services\Flusher; use Bitrix24\SDK\Application\Contracts\ApplicationInstallations\Entity\ApplicationInstallationStatus; +use Bitrix24\SDK\Application\Contracts\Bitrix24Accounts\Entity\Bitrix24AccountStatus; use Carbon\CarbonImmutable; use Psr\Log\LoggerInterface; readonly class Handler { public function __construct( + private Bitrix24AccountRepository $bitrix24AccountRepository, private ApplicationInstallationRepository $applicationInstallationRepository, private Flusher $flusher, private LoggerInterface $logger @@ -25,6 +29,24 @@ public function handle(Command $command): void 'id' => $command->uuid->toRfc4122(), ]); + $bitrix24Account = new Bitrix24Account( + $command->bitrix24AccountUuid, + $command->bitrix24UserId, + $command->isBitrix24UserAdmin, + $command->memberId, + $command->domain->value, + Bitrix24AccountStatus::new, + $command->authToken, + new CarbonImmutable(), + new CarbonImmutable(), + $command->applicationVersion, + $command->applicationScope, + true + ); + + $this->bitrix24AccountRepository->save($bitrix24Account); + $this->flusher->flush($bitrix24Account); + $applicationInstallation = new ApplicationInstallation( $command->uuid, ApplicationInstallationStatus::new, diff --git a/tests/Functional/ApplicationInstallations/UseCase/InstallStart/HandlerTest.php b/tests/Functional/ApplicationInstallations/UseCase/InstallStart/HandlerTest.php index 242fdd6..d80eddc 100644 --- a/tests/Functional/ApplicationInstallations/UseCase/InstallStart/HandlerTest.php +++ b/tests/Functional/ApplicationInstallations/UseCase/InstallStart/HandlerTest.php @@ -25,8 +25,6 @@ use Bitrix24\Lib\Tests\Functional\Bitrix24Accounts\Builders\Bitrix24AccountBuilder; use Bitrix24\SDK\Application\ApplicationStatus; use Bitrix24\SDK\Application\Contracts\ApplicationInstallations\Entity\ApplicationInstallationStatus; -use Bitrix24\SDK\Application\Contracts\Bitrix24Accounts\Events\Bitrix24AccountCreatedEvent; -use Bitrix24\SDK\Application\Contracts\Bitrix24Accounts\Exceptions\Bitrix24AccountNotFoundException; use Bitrix24\SDK\Application\PortalLicenseFamily; use Bitrix24\SDK\Core\Credentials\Scope; use Bitrix24\SDK\Core\Exceptions\InvalidArgumentException; @@ -50,14 +48,13 @@ #[CoversClass(ApplicationInstallations\UseCase\InstallStart\Handler::class)] class HandlerTest extends TestCase { - private Handler $handlerApplicationInstallation; - private Bitrix24Accounts\UseCase\InstallStart\Handler $handlerBitrix24Account; + private Handler $handler; private Flusher $flusher; - private ApplicationInstallationRepository $applicationInstallationRepository; + private ApplicationInstallationRepository $repository; - private Bitrix24AccountRepository $bitrix24AccountRepository; + private Bitrix24AccountRepository $bitrix24accountRepository; private TraceableEventDispatcher $eventDispatcher; @@ -66,18 +63,12 @@ protected function setUp(): void { $entityManager = EntityManagerFactory::get(); $this->eventDispatcher = new TraceableEventDispatcher(new EventDispatcher(), new Stopwatch()); - $this->applicationInstallationRepository = new ApplicationInstallationRepository($entityManager); - $this->bitrix24AccountRepository = new Bitrix24AccountRepository($entityManager); + $this->repository = new ApplicationInstallationRepository($entityManager); $this->flusher = new Flusher($entityManager, $this->eventDispatcher); - - $this->handlerApplicationInstallation = new Handler( - $this->applicationInstallationRepository, - $this->flusher, - new NullLogger() - ); - - $this->handlerBitrix24Account = new Bitrix24Accounts\UseCase\InstallStart\Handler( - $this->bitrix24AccountRepository, + $this->bitrix24accountRepository = new Bitrix24AccountRepository($entityManager); + $this->handler = new Handler( + $this->bitrix24accountRepository, + $this->repository, $this->flusher, new NullLogger() ); @@ -86,7 +77,7 @@ protected function setUp(): void /** * @throws InvalidArgumentException - * @throws Bitrix24AccountNotFoundException|ApplicationInstallationNotFoundException + * @throws ApplicationInstallationNotFoundException */ #[Test] public function testInstallNewApplicationInstallation(): void @@ -96,30 +87,13 @@ public function testInstallNewApplicationInstallation(): void ->withApplicationScope(new Scope(['crm'])) ->build(); - $this->handlerBitrix24Account->handle( - new Bitrix24Accounts\UseCase\InstallStart\Command( - $bitrix24AccountBuilder->getId(), - $bitrix24AccountBuilder->getBitrix24UserId(), - $bitrix24AccountBuilder->isBitrix24UserAdmin(), - $bitrix24AccountBuilder->getMemberId(), - new Domain($bitrix24AccountBuilder->getDomainUrl()), - $bitrix24AccountBuilder->getAuthToken(), - $bitrix24AccountBuilder->getApplicationVersion(), - $bitrix24AccountBuilder->getApplicationScope() - ) - ); - - $bitrix24Account = $this->bitrix24AccountRepository->getById($bitrix24AccountBuilder->getId()); - - $this->assertEquals($bitrix24Account->getId(), $bitrix24AccountBuilder->getId()); - $applicationInstallationBuilder = (new ApplicationInstallationBuilder()) ->withApplicationStatus(new ApplicationStatus('F')) ->withPortalLicenseFamily(PortalLicenseFamily::free) ->build(); - $this->handlerApplicationInstallation->handle( + $this->handler->handle( new ApplicationInstallations\UseCase\InstallStart\Command( $applicationInstallationBuilder->getId(), $bitrix24AccountBuilder->getId(), @@ -130,11 +104,19 @@ public function testInstallNewApplicationInstallation(): void $applicationInstallationBuilder->getBitrix24PartnerContactPersonId(), $applicationInstallationBuilder->getBitrix24PartnerId(), $applicationInstallationBuilder->getExternalId(), - $applicationInstallationBuilder->getComment() + $applicationInstallationBuilder->getComment(), + $bitrix24AccountBuilder->getId(), + $bitrix24AccountBuilder->getBitrix24UserId(), + $bitrix24AccountBuilder->isBitrix24UserAdmin(), + $bitrix24AccountBuilder->getMemberId(), + new Domain($bitrix24AccountBuilder->getDomainUrl()), + $bitrix24AccountBuilder->getAuthToken(), + $bitrix24AccountBuilder->getApplicationVersion(), + $bitrix24AccountBuilder->getApplicationScope() ) ); - $applicationInstallation = $this->applicationInstallationRepository->getById($applicationInstallationBuilder->getId()); + $applicationInstallation = $this->repository->getById($applicationInstallationBuilder->getId()); $dispatchedEvents = $this->eventDispatcher->getOrphanedEvents(); print_r($dispatchedEvents); // Выводит список событий From 6fe5e1671d834de73df604c9079f313497b5eb4f Mon Sep 17 00:00:00 2001 From: KarlsonComplete Date: Sat, 5 Apr 2025 10:08:25 +0300 Subject: [PATCH 18/49] =?UTF-8?q?-=20=D0=9E=D0=B1=D0=BD=D0=BE=D0=B2=D0=B8?= =?UTF-8?q?=D0=BB=20=D1=82=D0=B5=D1=81=D1=82=20=D0=BD=D0=B0=20=D1=83=D1=81?= =?UTF-8?q?=D1=82=D0=B0=D0=BD=D0=BE=D0=B2=D0=BA=D1=83=20(=D0=B2=D0=BA?= =?UTF-8?q?=D0=BB=D1=8E=D1=87=D0=B0=D1=8E=D1=89=D0=B8=D0=B9=20=D0=B2=20?= =?UTF-8?q?=D1=81=D0=B5=D0=B1=D1=8F=20=D0=B0=D0=BA=D0=BA=D0=B0=D1=83=D0=BD?= =?UTF-8?q?=D1=82=20=D0=B1=D0=B8=D1=82=D1=80=D0=B8=D0=BA=D1=81=2024)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../UseCase/InstallStart/Handler.php | 12 +++++++++++- .../UseCase/InstallStart/HandlerTest.php | 6 ++++-- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/ApplicationInstallations/UseCase/InstallStart/Handler.php b/src/ApplicationInstallations/UseCase/InstallStart/Handler.php index 0ae2ada..782886e 100644 --- a/src/ApplicationInstallations/UseCase/InstallStart/Handler.php +++ b/src/ApplicationInstallations/UseCase/InstallStart/Handler.php @@ -13,7 +13,7 @@ use Bitrix24\SDK\Application\Contracts\Bitrix24Accounts\Entity\Bitrix24AccountStatus; use Carbon\CarbonImmutable; use Psr\Log\LoggerInterface; - +use Symfony\Component\Uid\Uuid; readonly class Handler { public function __construct( @@ -47,6 +47,11 @@ public function handle(Command $command): void $this->bitrix24AccountRepository->save($bitrix24Account); $this->flusher->flush($bitrix24Account); + $applicationToken = Uuid::v7()->toRfc4122(); + $bitrix24Account->applicationInstalled($applicationToken); + $this->bitrix24AccountRepository->save($bitrix24Account); + $this->flusher->flush($bitrix24Account); + $applicationInstallation = new ApplicationInstallation( $command->uuid, ApplicationInstallationStatus::new, @@ -67,6 +72,11 @@ public function handle(Command $command): void $this->applicationInstallationRepository->save($applicationInstallation); $this->flusher->flush($applicationInstallation); + $applicationInstallation->applicationInstalled(); + + $this->applicationInstallationRepository->save($applicationInstallation); + $this->flusher->flush($applicationInstallation); + $this->logger->info( 'Bitrix24Accounts.InstallStart.Finish', [ diff --git a/tests/Functional/ApplicationInstallations/UseCase/InstallStart/HandlerTest.php b/tests/Functional/ApplicationInstallations/UseCase/InstallStart/HandlerTest.php index d80eddc..cfb066d 100644 --- a/tests/Functional/ApplicationInstallations/UseCase/InstallStart/HandlerTest.php +++ b/tests/Functional/ApplicationInstallations/UseCase/InstallStart/HandlerTest.php @@ -119,10 +119,12 @@ public function testInstallNewApplicationInstallation(): void $applicationInstallation = $this->repository->getById($applicationInstallationBuilder->getId()); $dispatchedEvents = $this->eventDispatcher->getOrphanedEvents(); - print_r($dispatchedEvents); // Выводит список событий $this->assertContains('Bitrix24\SDK\Application\Contracts\Bitrix24Accounts\Events\Bitrix24AccountCreatedEvent', $dispatchedEvents); $this->assertContains('Bitrix24\SDK\Application\Contracts\ApplicationInstallations\Events\ApplicationInstallationCreatedEvent', $dispatchedEvents); - $this->assertEquals(ApplicationInstallationStatus::new, $applicationInstallation->getStatus()); + $this->assertContains('Bitrix24\SDK\Application\Contracts\Bitrix24Accounts\Events\Bitrix24AccountApplicationInstalledEvent', $dispatchedEvents); + $this->assertContains('Bitrix24\SDK\Application\Contracts\ApplicationInstallations\Events\ApplicationInstallationFinishedEvent', $dispatchedEvents); + $this->assertEquals(ApplicationInstallationStatus::active, $applicationInstallation->getStatus()); + $this->assertEquals($bitrix24AccountBuilder->getId(), $applicationInstallation->getBitrix24AccountId()); } } From bb672978cb15b82362a98a6fe1d28609339747c7 Mon Sep 17 00:00:00 2001 From: KarlsonComplete Date: Sun, 6 Apr 2025 11:50:28 +0300 Subject: [PATCH 19/49] =?UTF-8?q?-=20=D0=9D=D0=B0=D1=87=D0=B0=D0=BB=20?= =?UTF-8?q?=D0=BF=D0=B8=D1=81=D0=B0=D1=82=D1=8C=20=D1=82=D0=B5=D1=81=D1=82?= =?UTF-8?q?=20=D0=BF=D0=B5=D1=80=D0=B5=D1=83=D1=81=D1=82=D0=B0=D0=BD=D0=BE?= =?UTF-8?q?=D0=B2=D0=BA=D0=B8=20=D0=BF=D1=80=D0=B8=D0=BB=D0=BE=D0=B6=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ApplicationInstallationRepository.php | 11 ++ .../{InstallStart => Install}/Command.php | 2 +- .../{InstallStart => Install}/Handler.php | 2 +- .../UseCase/Reinstall/Command.php | 66 ++++++++ .../UseCase/Reinstall/Handler.php | 134 ++++++++++++++++ .../ApplicationInstallationBuilder.php | 9 +- .../{InstallStart => Install}/HandlerTest.php | 8 +- .../UseCase/Reinstall/HandlerTest.php | 144 ++++++++++++++++++ 8 files changed, 369 insertions(+), 7 deletions(-) rename src/ApplicationInstallations/UseCase/{InstallStart => Install}/Command.php (96%) rename src/ApplicationInstallations/UseCase/{InstallStart => Install}/Handler.php (97%) create mode 100644 src/ApplicationInstallations/UseCase/Reinstall/Command.php create mode 100644 src/ApplicationInstallations/UseCase/Reinstall/Handler.php rename tests/Functional/ApplicationInstallations/UseCase/{InstallStart => Install}/HandlerTest.php (95%) create mode 100644 tests/Functional/ApplicationInstallations/UseCase/Reinstall/HandlerTest.php diff --git a/src/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationRepository.php b/src/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationRepository.php index ea8b9da..f459607 100644 --- a/src/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationRepository.php +++ b/src/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationRepository.php @@ -81,6 +81,17 @@ public function findByBitrix24AccountId(Uuid $uuid): array ; } + public function findActiveApplicationInstallations(): array + { + return $this->getEntityManager()->getRepository(ApplicationInstallation::class) + ->createQueryBuilder('appInstallation') + ->where('appInstallation.status IN (:statuses)') + ->setParameter('statuses', [ApplicationInstallationStatus::active,ApplicationInstallationStatus::new]) + ->getQuery() + ->getResult() + ; + } + #[\Override] public function findByExternalId(string $externalId): array { diff --git a/src/ApplicationInstallations/UseCase/InstallStart/Command.php b/src/ApplicationInstallations/UseCase/Install/Command.php similarity index 96% rename from src/ApplicationInstallations/UseCase/InstallStart/Command.php rename to src/ApplicationInstallations/UseCase/Install/Command.php index 79be3a9..dc27cb3 100644 --- a/src/ApplicationInstallations/UseCase/InstallStart/Command.php +++ b/src/ApplicationInstallations/UseCase/Install/Command.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace Bitrix24\Lib\ApplicationInstallations\UseCase\InstallStart; +namespace Bitrix24\Lib\ApplicationInstallations\UseCase\Install; use Bitrix24\Lib\Bitrix24Accounts\ValueObjects\Domain; use Bitrix24\SDK\Application\ApplicationStatus; diff --git a/src/ApplicationInstallations/UseCase/InstallStart/Handler.php b/src/ApplicationInstallations/UseCase/Install/Handler.php similarity index 97% rename from src/ApplicationInstallations/UseCase/InstallStart/Handler.php rename to src/ApplicationInstallations/UseCase/Install/Handler.php index 782886e..401a5ac 100644 --- a/src/ApplicationInstallations/UseCase/InstallStart/Handler.php +++ b/src/ApplicationInstallations/UseCase/Install/Handler.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace Bitrix24\Lib\ApplicationInstallations\UseCase\InstallStart; +namespace Bitrix24\Lib\ApplicationInstallations\UseCase\Install; use Bitrix24\Lib\ApplicationInstallations\Entity\ApplicationInstallation; use Bitrix24\Lib\ApplicationInstallations\Infrastructure\Doctrine\ApplicationInstallationRepository; diff --git a/src/ApplicationInstallations/UseCase/Reinstall/Command.php b/src/ApplicationInstallations/UseCase/Reinstall/Command.php new file mode 100644 index 0000000..f03f984 --- /dev/null +++ b/src/ApplicationInstallations/UseCase/Reinstall/Command.php @@ -0,0 +1,66 @@ +validate(); + } + + + private function validate(): void + { + if ($this->portalUsersCount <= 0) { + throw new \InvalidArgumentException('Portal Users count must be a positive integer.'); + } + + if ('' === $this->externalId) { + throw new \InvalidArgumentException('External ID must be a non-empty string.'); + } + + if ('' === $this->comment) { + throw new \InvalidArgumentException('Comment must be a non-empty string.'); + } + + if ($this->bitrix24UserId <= 0) { + throw new \InvalidArgumentException('Bitrix24 User ID must be a positive integer.'); + } + + if ('' === $this->memberId) { + throw new \InvalidArgumentException('Member ID must be a non-empty string.'); + } + + if ($this->applicationVersion <= 0) { + throw new \InvalidArgumentException('Application version must be a positive integer.'); + } + } +} diff --git a/src/ApplicationInstallations/UseCase/Reinstall/Handler.php b/src/ApplicationInstallations/UseCase/Reinstall/Handler.php new file mode 100644 index 0000000..b44ecff --- /dev/null +++ b/src/ApplicationInstallations/UseCase/Reinstall/Handler.php @@ -0,0 +1,134 @@ +logger->info('ApplicationInstallations.InstallStart.start', [ + 'id' => $command->uuid->toRfc4122(), + ]); + + /** @var $activeApplicationInstallation */ + $activeApplicationInstallation = $this->getActiveApplicationInstallation(); + $bitrix24AccountId = $activeApplicationInstallation->getBitrix24AccountId(); + + /* + В документации написано, что нужно деактивировать аккаунтЫ связанные с приложением. Но у нас связь у приложения идет только с 1 аккаунтом. + Отсюда вопрос у нас аккаунт у приложения один ? Или если несколько то как их получить ? + */ + + /* + * Еще вопрос написано деактивация приложения и аккаунтов связанных с приложением это soft delete ? + */ + + $activeApplicationInstallation->applicationUninstalled(); + $this->applicationInstallationRepository->save($activeApplicationInstallation); + $this->flusher->flush(); + + + $oldBitrix24Account = $this->bitrix24AccountRepository->getById($bitrix24AccountId); + // Тут возникает вопрос. Для деинсталяции(если деактивация означает это) нам нужно токен прокидывать в команду, мне кажется бредово. + // Так как мы ходим запустить хендлер с параметрами нового приложения и чтобы там под капотом все что нужно деактивировалось, а что нужно установилось. + // Может добавить метод получения токена ? Или он уже должен быть и мы просто проморгали ? + $oldBitrix24Account->applicationUninstalled(); + + + //Ниже пока что можно не смотреть + $bitrix24Account = new Bitrix24Account( + $command->bitrix24AccountUuid, + $command->bitrix24UserId, + $command->isBitrix24UserAdmin, + $command->memberId, + $command->domain->value, + Bitrix24AccountStatus::new, + $command->authToken, + new CarbonImmutable(), + new CarbonImmutable(), + $command->applicationVersion, + $command->applicationScope, + true + ); + + $this->bitrix24AccountRepository->save($bitrix24Account); + $this->flusher->flush($bitrix24Account); + + $applicationToken = Uuid::v7()->toRfc4122(); + $bitrix24Account->applicationInstalled($applicationToken); + $this->bitrix24AccountRepository->save($bitrix24Account); + $this->flusher->flush($bitrix24Account); + + $applicationInstallation = new ApplicationInstallation( + $command->uuid, + ApplicationInstallationStatus::new, + new CarbonImmutable(), + new CarbonImmutable(), + $command->bitrix24AccountId, + $command->applicationStatus, + $command->portalLicenseFamily, + $command->portalUsersCount, + $command->contactPersonId, + $command->bitrix24PartnerContactPersonId, + $command->bitrix24PartnerId, + $command->externalId, + $command->comment, + true + ); + + $this->applicationInstallationRepository->save($applicationInstallation); + $this->flusher->flush($applicationInstallation); + + $applicationInstallation->applicationInstalled(); + + $this->applicationInstallationRepository->save($applicationInstallation); + $this->flusher->flush($applicationInstallation); + + $this->logger->info( + 'Bitrix24Accounts.InstallStart.Finish', + [ + 'id' => $command->uuid->toRfc4122(), + ] + ); + } + + private function getActiveApplicationInstallation(): ApplicationInstallationInterface + { + $activeApplicationInstallations = $this->applicationInstallationRepository->findActiveApplicationInstallations(); + + /* + У нас вообще может быть приложений больше чем одно активных или в статусе new ? Мне кажется это значит что что-то не сработало в прошлый раз. + Так как приложение у нас по факту же только одно ? + */ + if (!empty($activeApplicationInstallations)){ + if (count($activeApplicationInstallations) > 1) { + //Тут может добавить исключение для приложения ? По подобию MultipleBitrix24AccountsFoundException + throw new \InvalidArgumentException( + 'multiple application installations with active or new status' + ); + } + } + + return $activeApplicationInstallations[0]; + } +} diff --git a/tests/Functional/ApplicationInstallations/Builders/ApplicationInstallationBuilder.php b/tests/Functional/ApplicationInstallations/Builders/ApplicationInstallationBuilder.php index 72f3c82..cfe5f5a 100644 --- a/tests/Functional/ApplicationInstallations/Builders/ApplicationInstallationBuilder.php +++ b/tests/Functional/ApplicationInstallations/Builders/ApplicationInstallationBuilder.php @@ -19,7 +19,7 @@ class ApplicationInstallationBuilder private readonly CarbonImmutable $updatedAt; - private readonly Uuid $bitrix24AccountId; + private Uuid $bitrix24AccountId; private readonly ?Uuid $contactPersonId; @@ -73,6 +73,13 @@ public function withApplicationStatus(ApplicationStatus $applicationStatus): sel return $this; } + public function withBitrix24AccountId(Uuid $bitrix24AccountId): self + { + $this->bitrix24AccountId = $bitrix24AccountId; + + return $this; + } + public function withPortalLicenseFamily(PortalLicenseFamily $portalLicenseFamily): self { $this->portalLicenseFamily = $portalLicenseFamily; diff --git a/tests/Functional/ApplicationInstallations/UseCase/InstallStart/HandlerTest.php b/tests/Functional/ApplicationInstallations/UseCase/Install/HandlerTest.php similarity index 95% rename from tests/Functional/ApplicationInstallations/UseCase/InstallStart/HandlerTest.php rename to tests/Functional/ApplicationInstallations/UseCase/Install/HandlerTest.php index cfb066d..8a64d76 100644 --- a/tests/Functional/ApplicationInstallations/UseCase/InstallStart/HandlerTest.php +++ b/tests/Functional/ApplicationInstallations/UseCase/Install/HandlerTest.php @@ -11,7 +11,7 @@ declare(strict_types=1); -namespace Bitrix24\Lib\Tests\Functional\ApplicationInstallations\UseCase\InstallStart; +namespace Bitrix24\Lib\Tests\Functional\ApplicationInstallations\UseCase\Install; use Bitrix24\Lib\Bitrix24Accounts; @@ -39,13 +39,13 @@ use Symfony\Component\Stopwatch\Stopwatch; use Bitrix24\Lib\ApplicationInstallations\Infrastructure\Doctrine\ApplicationInstallationRepository; -use Bitrix24\Lib\ApplicationInstallations\UseCase\InstallStart\Handler; +use Bitrix24\Lib\ApplicationInstallations\UseCase\Install\Handler; use Bitrix24\Lib\Bitrix24Accounts\Infrastructure\Doctrine\Bitrix24AccountRepository; /** * @internal */ -#[CoversClass(ApplicationInstallations\UseCase\InstallStart\Handler::class)] +#[CoversClass(ApplicationInstallations\UseCase\Install\Handler::class)] class HandlerTest extends TestCase { private Handler $handler; @@ -94,7 +94,7 @@ public function testInstallNewApplicationInstallation(): void ->build(); $this->handler->handle( - new ApplicationInstallations\UseCase\InstallStart\Command( + new ApplicationInstallations\UseCase\Install\Command( $applicationInstallationBuilder->getId(), $bitrix24AccountBuilder->getId(), $applicationInstallationBuilder->getApplicationStatus(), diff --git a/tests/Functional/ApplicationInstallations/UseCase/Reinstall/HandlerTest.php b/tests/Functional/ApplicationInstallations/UseCase/Reinstall/HandlerTest.php new file mode 100644 index 0000000..ea31b36 --- /dev/null +++ b/tests/Functional/ApplicationInstallations/UseCase/Reinstall/HandlerTest.php @@ -0,0 +1,144 @@ + + * + * For the full copyright and license information, please view the MIT-LICENSE.txt + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace Bitrix24\Lib\Tests\Functional\ApplicationInstallations\UseCase\Reinstall; + + +use Bitrix24\Lib\Bitrix24Accounts; + +use Bitrix24\Lib\Bitrix24Accounts\ValueObjects\Domain; +use Bitrix24\Lib\Services\Flusher; +use Bitrix24\Lib\ApplicationInstallations; +use Bitrix24\Lib\Tests\EntityManagerFactory; + +use Bitrix24\Lib\Tests\Functional\ApplicationInstallations\Builders\ApplicationInstallationBuilder; +use Bitrix24\Lib\Tests\Functional\Bitrix24Accounts\Builders\Bitrix24AccountBuilder; +use Bitrix24\SDK\Application\ApplicationStatus; +use Bitrix24\SDK\Application\Contracts\ApplicationInstallations\Entity\ApplicationInstallationStatus; +use Bitrix24\SDK\Application\Contracts\Bitrix24Accounts\Entity\Bitrix24AccountStatus; +use Bitrix24\SDK\Application\PortalLicenseFamily; +use Bitrix24\SDK\Core\Credentials\Scope; +use Bitrix24\SDK\Core\Exceptions\InvalidArgumentException; + +use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\Attributes\Test; +use PHPUnit\Framework\TestCase; +use Psr\Log\NullLogger; +use Bitrix24\SDK\Application\Contracts\ApplicationInstallations\Exceptions\ApplicationInstallationNotFoundException; +use Symfony\Component\EventDispatcher\Debug\TraceableEventDispatcher; +use Symfony\Component\EventDispatcher\EventDispatcher; +use Symfony\Component\Stopwatch\Stopwatch; + +use Bitrix24\Lib\ApplicationInstallations\Infrastructure\Doctrine\ApplicationInstallationRepository; +use Bitrix24\Lib\ApplicationInstallations\UseCase\Reinstall\Handler; + +use Bitrix24\Lib\Bitrix24Accounts\Infrastructure\Doctrine\Bitrix24AccountRepository; +use Symfony\Component\Uid\Uuid; + +/** + * @internal + */ +#[CoversClass(ApplicationInstallations\UseCase\Reinstall\Handler::class)] +class HandlerTest extends TestCase +{ + private Handler $handler; + + private Flusher $flusher; + + private ApplicationInstallationRepository $repository; + + private Bitrix24AccountRepository $bitrix24accountRepository; + + private TraceableEventDispatcher $eventDispatcher; + + #[\Override] + protected function setUp(): void + { + $entityManager = EntityManagerFactory::get(); + $this->eventDispatcher = new TraceableEventDispatcher(new EventDispatcher(), new Stopwatch()); + $this->repository = new ApplicationInstallationRepository($entityManager); + $this->flusher = new Flusher($entityManager, $this->eventDispatcher); + $this->bitrix24accountRepository = new Bitrix24AccountRepository($entityManager); + $this->handler = new Handler( + $this->bitrix24accountRepository, + $this->repository, + $this->flusher, + new NullLogger() + ); + + } + + /** + * @throws InvalidArgumentException + * @throws ApplicationInstallationNotFoundException + */ + #[Test] + public function testReinstallApplicationInstallation(): void + { + + $applicationToken = Uuid::v7()->toRfc4122(); + $bitrix24AccountBuilder = (new Bitrix24AccountBuilder()) + ->withApplicationScope(new Scope(['crm'])) + ->withStatus(Bitrix24AccountStatus::new) + ->withApplicationToken($applicationToken) + ->build(); + + $this->bitrix24accountRepository->save($bitrix24AccountBuilder); + $this->flusher->flush(); + + $applicationInstallationBuilder = (new ApplicationInstallationBuilder()) + ->withApplicationStatus(new ApplicationStatus('F')) + ->withPortalLicenseFamily(PortalLicenseFamily::free) + ->withBitrix24AccountId($bitrix24AccountBuilder->getId()) + ->withApplicationStatusInstallation(ApplicationInstallationStatus::active) + ->build(); + + $this->repository->save($applicationInstallationBuilder); + $this->flusher->flush(); + + + $this->handler->handle( + new ApplicationInstallations\UseCase\Reinstall\Command( + $applicationInstallationBuilder->getId(), + $bitrix24AccountBuilder->getId(), + $applicationInstallationBuilder->getApplicationStatus(), + $applicationInstallationBuilder->getPortalLicenseFamily(), + $applicationInstallationBuilder->getPortalUsersCount(), + $applicationInstallationBuilder->getContactPersonId(), + $applicationInstallationBuilder->getBitrix24PartnerContactPersonId(), + $applicationInstallationBuilder->getBitrix24PartnerId(), + $applicationInstallationBuilder->getExternalId(), + $applicationInstallationBuilder->getComment(), + $bitrix24AccountBuilder->getId(), + $bitrix24AccountBuilder->getBitrix24UserId(), + $bitrix24AccountBuilder->isBitrix24UserAdmin(), + $bitrix24AccountBuilder->getMemberId(), + new Domain($bitrix24AccountBuilder->getDomainUrl()), + $bitrix24AccountBuilder->getAuthToken(), + $bitrix24AccountBuilder->getApplicationVersion(), + $bitrix24AccountBuilder->getApplicationScope() + ) + ); + + $applicationInstallation = $this->repository->getById($applicationInstallationBuilder->getId()); + + $dispatchedEvents = $this->eventDispatcher->getOrphanedEvents(); + + $this->assertContains('Bitrix24\SDK\Application\Contracts\Bitrix24Accounts\Events\Bitrix24AccountCreatedEvent', $dispatchedEvents); + $this->assertContains('Bitrix24\SDK\Application\Contracts\ApplicationInstallations\Events\ApplicationInstallationCreatedEvent', $dispatchedEvents); + $this->assertContains('Bitrix24\SDK\Application\Contracts\Bitrix24Accounts\Events\Bitrix24AccountApplicationInstalledEvent', $dispatchedEvents); + $this->assertContains('Bitrix24\SDK\Application\Contracts\ApplicationInstallations\Events\ApplicationInstallationFinishedEvent', $dispatchedEvents); + $this->assertEquals(ApplicationInstallationStatus::active, $applicationInstallation->getStatus()); + $this->assertEquals($bitrix24AccountBuilder->getId(), $applicationInstallation->getBitrix24AccountId()); + } +} From a42d3a182bf36d60ec96532b3f621e627639efda Mon Sep 17 00:00:00 2001 From: KarlsonComplete Date: Sun, 13 Apr 2025 11:13:04 +0300 Subject: [PATCH 20/49] =?UTF-8?q?-=20=D0=9F=D1=80=D0=B0=D0=B2=D0=BA=D0=B8?= =?UTF-8?q?=20=D0=B4=D0=BB=D1=8F=20=D1=82=D0=B5=D1=81=D1=82=D0=B0=20=D0=BF?= =?UTF-8?q?=D0=B5=D1=80=D0=B5=D1=83=D1=81=D1=82=D0=B0=D0=BD=D0=BE=D0=B2?= =?UTF-8?q?=D0=BA=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Entity/ApplicationInstallation.php | 1 - .../ApplicationInstallationRepository.php | 4 +- .../UseCase/Install/Command.php | 1 - .../UseCase/Install/Handler.php | 1 + .../UseCase/Reinstall/Command.php | 8 +++- .../UseCase/Reinstall/Handler.php | 48 +++++++++---------- .../ApplicationInstallationBuilder.php | 4 +- .../UseCase/Install/HandlerTest.php | 8 ++-- .../UseCase/Reinstall/HandlerTest.php | 44 ++++++++++++----- 9 files changed, 69 insertions(+), 50 deletions(-) diff --git a/src/ApplicationInstallations/Entity/ApplicationInstallation.php b/src/ApplicationInstallations/Entity/ApplicationInstallation.php index 90c8478..77312f7 100644 --- a/src/ApplicationInstallations/Entity/ApplicationInstallation.php +++ b/src/ApplicationInstallations/Entity/ApplicationInstallation.php @@ -331,7 +331,6 @@ public function getComment(): ?string private function addApplicationCreatedEventIfNeeded(bool $isEmitCreatedEvent): void { - if ($isEmitCreatedEvent) { // Создание события и добавление его в массив событий $this->events[] = new ApplicationInstallationCreatedEvent( diff --git a/src/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationRepository.php b/src/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationRepository.php index f459607..926ec82 100644 --- a/src/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationRepository.php +++ b/src/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationRepository.php @@ -86,10 +86,10 @@ public function findActiveApplicationInstallations(): array return $this->getEntityManager()->getRepository(ApplicationInstallation::class) ->createQueryBuilder('appInstallation') ->where('appInstallation.status IN (:statuses)') - ->setParameter('statuses', [ApplicationInstallationStatus::active,ApplicationInstallationStatus::new]) + ->setParameter('statuses', [ApplicationInstallationStatus::active, ApplicationInstallationStatus::new]) ->getQuery() ->getResult() - ; + ; } #[\Override] diff --git a/src/ApplicationInstallations/UseCase/Install/Command.php b/src/ApplicationInstallations/UseCase/Install/Command.php index dc27cb3..22b8f33 100644 --- a/src/ApplicationInstallations/UseCase/Install/Command.php +++ b/src/ApplicationInstallations/UseCase/Install/Command.php @@ -36,7 +36,6 @@ public function __construct( $this->validate(); } - private function validate(): void { if ($this->portalUsersCount <= 0) { diff --git a/src/ApplicationInstallations/UseCase/Install/Handler.php b/src/ApplicationInstallations/UseCase/Install/Handler.php index 401a5ac..5b3e2de 100644 --- a/src/ApplicationInstallations/UseCase/Install/Handler.php +++ b/src/ApplicationInstallations/UseCase/Install/Handler.php @@ -14,6 +14,7 @@ use Carbon\CarbonImmutable; use Psr\Log\LoggerInterface; use Symfony\Component\Uid\Uuid; + readonly class Handler { public function __construct( diff --git a/src/ApplicationInstallations/UseCase/Reinstall/Command.php b/src/ApplicationInstallations/UseCase/Reinstall/Command.php index f03f984..302c163 100644 --- a/src/ApplicationInstallations/UseCase/Reinstall/Command.php +++ b/src/ApplicationInstallations/UseCase/Reinstall/Command.php @@ -6,6 +6,8 @@ use Bitrix24\Lib\Bitrix24Accounts\ValueObjects\Domain; use Bitrix24\SDK\Application\ApplicationStatus; +use Bitrix24\SDK\Application\Contracts\ApplicationInstallations\Entity\ApplicationInstallationStatus; +use Bitrix24\SDK\Application\Contracts\Bitrix24Accounts\Entity\Bitrix24AccountStatus; use Bitrix24\SDK\Application\PortalLicenseFamily; use Bitrix24\SDK\Core\Credentials\AuthToken; use Bitrix24\SDK\Core\Credentials\Scope; @@ -15,6 +17,7 @@ { public function __construct( public Uuid $uuid, + public ApplicationInstallationStatus $applicationInstallationStatus, public Uuid $bitrix24AccountId, public ApplicationStatus $applicationStatus, public PortalLicenseFamily $portalLicenseFamily, @@ -25,18 +28,19 @@ public function __construct( public ?string $externalId, public ?string $comment, public Uuid $bitrix24AccountUuid, + public Bitrix24AccountStatus $bitrix24AccountStatus, public int $bitrix24UserId, public bool $isBitrix24UserAdmin, public string $memberId, public Domain $domain, public AuthToken $authToken, public int $applicationVersion, - public Scope $applicationScope + public Scope $applicationScope, + public ?string $applicationToken ) { $this->validate(); } - private function validate(): void { if ($this->portalUsersCount <= 0) { diff --git a/src/ApplicationInstallations/UseCase/Reinstall/Handler.php b/src/ApplicationInstallations/UseCase/Reinstall/Handler.php index b44ecff..05fab4a 100644 --- a/src/ApplicationInstallations/UseCase/Reinstall/Handler.php +++ b/src/ApplicationInstallations/UseCase/Reinstall/Handler.php @@ -10,11 +10,11 @@ use Bitrix24\Lib\Bitrix24Accounts\Infrastructure\Doctrine\Bitrix24AccountRepository; use Bitrix24\Lib\Services\Flusher; use Bitrix24\SDK\Application\Contracts\ApplicationInstallations\Entity\ApplicationInstallationInterface; -use Bitrix24\SDK\Application\Contracts\ApplicationInstallations\Entity\ApplicationInstallationStatus; -use Bitrix24\SDK\Application\Contracts\Bitrix24Accounts\Entity\Bitrix24AccountStatus; +use Bitrix24\SDK\Application\Contracts\Events\AggregateRootEventsEmitterInterface; use Carbon\CarbonImmutable; use Psr\Log\LoggerInterface; use Symfony\Component\Uid\Uuid; + readonly class Handler { public function __construct( @@ -30,39 +30,39 @@ public function handle(Command $command): void 'id' => $command->uuid->toRfc4122(), ]); - /** @var $activeApplicationInstallation */ + /** @var AggregateRootEventsEmitterInterface|ApplicationInstallationInterface $activeApplicationInstallation */ $activeApplicationInstallation = $this->getActiveApplicationInstallation(); - $bitrix24AccountId = $activeApplicationInstallation->getBitrix24AccountId(); /* В документации написано, что нужно деактивировать аккаунтЫ связанные с приложением. Но у нас связь у приложения идет только с 1 аккаунтом. Отсюда вопрос у нас аккаунт у приложения один ? Или если несколько то как их получить ? */ - /* - * Еще вопрос написано деактивация приложения и аккаунтов связанных с приложением это soft delete ? - */ - - $activeApplicationInstallation->applicationUninstalled(); - $this->applicationInstallationRepository->save($activeApplicationInstallation); - $this->flusher->flush(); - + // Еще вопрос написано деактивация приложения и аккаунтов связанных с приложением это soft delete ? + + if (!empty($activeApplicationInstallation)) { + $bitrix24AccountId = $activeApplicationInstallation->getBitrix24AccountId(); + $oldBitrix24Account = $this->bitrix24AccountRepository->getById($bitrix24AccountId); + $activeApplicationInstallation->applicationUninstalled(); + $this->applicationInstallationRepository->save($activeApplicationInstallation); + $this->flusher->flush($activeApplicationInstallation); + $oldBitrix24Account->applicationUninstalled($command->applicationToken); + $this->bitrix24AccountRepository->save($oldBitrix24Account); + $this->flusher->flush($oldBitrix24Account); + } - $oldBitrix24Account = $this->bitrix24AccountRepository->getById($bitrix24AccountId); // Тут возникает вопрос. Для деинсталяции(если деактивация означает это) нам нужно токен прокидывать в команду, мне кажется бредово. // Так как мы ходим запустить хендлер с параметрами нового приложения и чтобы там под капотом все что нужно деактивировалось, а что нужно установилось. // Может добавить метод получения токена ? Или он уже должен быть и мы просто проморгали ? - $oldBitrix24Account->applicationUninstalled(); - - //Ниже пока что можно не смотреть + // Ниже пока что можно не смотреть $bitrix24Account = new Bitrix24Account( $command->bitrix24AccountUuid, $command->bitrix24UserId, $command->isBitrix24UserAdmin, $command->memberId, $command->domain->value, - Bitrix24AccountStatus::new, + $command->bitrix24AccountStatus, $command->authToken, new CarbonImmutable(), new CarbonImmutable(), @@ -81,7 +81,7 @@ public function handle(Command $command): void $applicationInstallation = new ApplicationInstallation( $command->uuid, - ApplicationInstallationStatus::new, + $command->applicationInstallationStatus, new CarbonImmutable(), new CarbonImmutable(), $command->bitrix24AccountId, @@ -120,13 +120,11 @@ private function getActiveApplicationInstallation(): ApplicationInstallationInte У нас вообще может быть приложений больше чем одно активных или в статусе new ? Мне кажется это значит что что-то не сработало в прошлый раз. Так как приложение у нас по факту же только одно ? */ - if (!empty($activeApplicationInstallations)){ - if (count($activeApplicationInstallations) > 1) { - //Тут может добавить исключение для приложения ? По подобию MultipleBitrix24AccountsFoundException - throw new \InvalidArgumentException( - 'multiple application installations with active or new status' - ); - } + if (!([] === $activeApplicationInstallations) && count($activeApplicationInstallations) > 1) { + // Тут может добавить исключение для приложения ? По подобию MultipleBitrix24AccountsFoundException + throw new \InvalidArgumentException( + 'multiple application installations with active or new status' + ); } return $activeApplicationInstallations[0]; diff --git a/tests/Functional/ApplicationInstallations/Builders/ApplicationInstallationBuilder.php b/tests/Functional/ApplicationInstallations/Builders/ApplicationInstallationBuilder.php index cfe5f5a..0a88f86 100644 --- a/tests/Functional/ApplicationInstallations/Builders/ApplicationInstallationBuilder.php +++ b/tests/Functional/ApplicationInstallations/Builders/ApplicationInstallationBuilder.php @@ -73,9 +73,9 @@ public function withApplicationStatus(ApplicationStatus $applicationStatus): sel return $this; } - public function withBitrix24AccountId(Uuid $bitrix24AccountId): self + public function withBitrix24AccountId(Uuid $uuid): self { - $this->bitrix24AccountId = $bitrix24AccountId; + $this->bitrix24AccountId = $uuid; return $this; } diff --git a/tests/Functional/ApplicationInstallations/UseCase/Install/HandlerTest.php b/tests/Functional/ApplicationInstallations/UseCase/Install/HandlerTest.php index 8a64d76..e6fbc61 100644 --- a/tests/Functional/ApplicationInstallations/UseCase/Install/HandlerTest.php +++ b/tests/Functional/ApplicationInstallations/UseCase/Install/HandlerTest.php @@ -120,10 +120,10 @@ public function testInstallNewApplicationInstallation(): void $dispatchedEvents = $this->eventDispatcher->getOrphanedEvents(); - $this->assertContains('Bitrix24\SDK\Application\Contracts\Bitrix24Accounts\Events\Bitrix24AccountCreatedEvent', $dispatchedEvents); - $this->assertContains('Bitrix24\SDK\Application\Contracts\ApplicationInstallations\Events\ApplicationInstallationCreatedEvent', $dispatchedEvents); - $this->assertContains('Bitrix24\SDK\Application\Contracts\Bitrix24Accounts\Events\Bitrix24AccountApplicationInstalledEvent', $dispatchedEvents); - $this->assertContains('Bitrix24\SDK\Application\Contracts\ApplicationInstallations\Events\ApplicationInstallationFinishedEvent', $dispatchedEvents); + $this->assertContains(\Bitrix24\SDK\Application\Contracts\Bitrix24Accounts\Events\Bitrix24AccountCreatedEvent::class, $dispatchedEvents); + $this->assertContains(\Bitrix24\SDK\Application\Contracts\ApplicationInstallations\Events\ApplicationInstallationCreatedEvent::class, $dispatchedEvents); + $this->assertContains(\Bitrix24\SDK\Application\Contracts\Bitrix24Accounts\Events\Bitrix24AccountApplicationInstalledEvent::class, $dispatchedEvents); + $this->assertContains(\Bitrix24\SDK\Application\Contracts\ApplicationInstallations\Events\ApplicationInstallationFinishedEvent::class, $dispatchedEvents); $this->assertEquals(ApplicationInstallationStatus::active, $applicationInstallation->getStatus()); $this->assertEquals($bitrix24AccountBuilder->getId(), $applicationInstallation->getBitrix24AccountId()); } diff --git a/tests/Functional/ApplicationInstallations/UseCase/Reinstall/HandlerTest.php b/tests/Functional/ApplicationInstallations/UseCase/Reinstall/HandlerTest.php index ea31b36..272cb7d 100644 --- a/tests/Functional/ApplicationInstallations/UseCase/Reinstall/HandlerTest.php +++ b/tests/Functional/ApplicationInstallations/UseCase/Reinstall/HandlerTest.php @@ -87,30 +87,43 @@ public function testReinstallApplicationInstallation(): void { $applicationToken = Uuid::v7()->toRfc4122(); - $bitrix24AccountBuilder = (new Bitrix24AccountBuilder()) + $bitrix24Account = (new Bitrix24AccountBuilder()) ->withApplicationScope(new Scope(['crm'])) ->withStatus(Bitrix24AccountStatus::new) ->withApplicationToken($applicationToken) ->build(); - $this->bitrix24accountRepository->save($bitrix24AccountBuilder); + $this->bitrix24accountRepository->save($bitrix24Account); $this->flusher->flush(); - $applicationInstallationBuilder = (new ApplicationInstallationBuilder()) + $oldApplicationInstallationBuilder = (new ApplicationInstallationBuilder()) ->withApplicationStatus(new ApplicationStatus('F')) ->withPortalLicenseFamily(PortalLicenseFamily::free) - ->withBitrix24AccountId($bitrix24AccountBuilder->getId()) + ->withBitrix24AccountId($bitrix24Account->getId()) ->withApplicationStatusInstallation(ApplicationInstallationStatus::active) ->build(); - $this->repository->save($applicationInstallationBuilder); + $this->repository->save($oldApplicationInstallationBuilder); $this->flusher->flush(); + $bitrix24AccountBuilder = (new Bitrix24AccountBuilder()) + ->withApplicationScope(new Scope(['crm'])) + ->withStatus(Bitrix24AccountStatus::new) + ->build(); + + $applicationInstallationBuilder = (new ApplicationInstallationBuilder()) + ->withApplicationStatus(new ApplicationStatus('F')) + ->withPortalLicenseFamily(PortalLicenseFamily::free) + ->withBitrix24AccountId($bitrix24Account->getId()) + ->withApplicationStatusInstallation(ApplicationInstallationStatus::new) + ->build(); + $this->handler->handle( new ApplicationInstallations\UseCase\Reinstall\Command( $applicationInstallationBuilder->getId(), - $bitrix24AccountBuilder->getId(), + $applicationInstallationBuilder->getStatus(), + $applicationInstallationBuilder->getBitrix24AccountId(), $applicationInstallationBuilder->getApplicationStatus(), $applicationInstallationBuilder->getPortalLicenseFamily(), $applicationInstallationBuilder->getPortalUsersCount(), @@ -120,25 +133,30 @@ public function testReinstallApplicationInstallation(): void $applicationInstallationBuilder->getExternalId(), $applicationInstallationBuilder->getComment(), $bitrix24AccountBuilder->getId(), + $bitrix24AccountBuilder->getStatus(), $bitrix24AccountBuilder->getBitrix24UserId(), $bitrix24AccountBuilder->isBitrix24UserAdmin(), $bitrix24AccountBuilder->getMemberId(), new Domain($bitrix24AccountBuilder->getDomainUrl()), $bitrix24AccountBuilder->getAuthToken(), $bitrix24AccountBuilder->getApplicationVersion(), - $bitrix24AccountBuilder->getApplicationScope() + $bitrix24AccountBuilder->getApplicationScope(), + $applicationToken ) ); $applicationInstallation = $this->repository->getById($applicationInstallationBuilder->getId()); $dispatchedEvents = $this->eventDispatcher->getOrphanedEvents(); - - $this->assertContains('Bitrix24\SDK\Application\Contracts\Bitrix24Accounts\Events\Bitrix24AccountCreatedEvent', $dispatchedEvents); - $this->assertContains('Bitrix24\SDK\Application\Contracts\ApplicationInstallations\Events\ApplicationInstallationCreatedEvent', $dispatchedEvents); - $this->assertContains('Bitrix24\SDK\Application\Contracts\Bitrix24Accounts\Events\Bitrix24AccountApplicationInstalledEvent', $dispatchedEvents); - $this->assertContains('Bitrix24\SDK\Application\Contracts\ApplicationInstallations\Events\ApplicationInstallationFinishedEvent', $dispatchedEvents); + var_dump($dispatchedEvents); + $this->assertContains(\Bitrix24\SDK\Application\Contracts\Bitrix24Accounts\Events\Bitrix24AccountCreatedEvent::class, $dispatchedEvents); + $this->assertContains(\Bitrix24\SDK\Application\Contracts\Bitrix24Accounts\Events\Bitrix24AccountApplicationInstalledEvent::class, $dispatchedEvents); + $this->assertContains(\Bitrix24\SDK\Application\Contracts\Bitrix24Accounts\Events\Bitrix24AccountApplicationUninstalledEvent::class, $dispatchedEvents); + + $this->assertContains(\Bitrix24\SDK\Application\Contracts\ApplicationInstallations\Events\ApplicationInstallationCreatedEvent::class, $dispatchedEvents); + $this->assertContains(\Bitrix24\SDK\Application\Contracts\ApplicationInstallations\Events\ApplicationInstallationFinishedEvent::class, $dispatchedEvents); + $this->assertContains(\Bitrix24\SDK\Application\Contracts\ApplicationInstallations\Events\ApplicationInstallationUninstalledEvent::class, $dispatchedEvents); $this->assertEquals(ApplicationInstallationStatus::active, $applicationInstallation->getStatus()); - $this->assertEquals($bitrix24AccountBuilder->getId(), $applicationInstallation->getBitrix24AccountId()); + $this->assertEquals($applicationInstallationBuilder->getBitrix24AccountId(), $applicationInstallation->getBitrix24AccountId()); } } From 231526f1649cfcd0a5e8e9e70bf4133f5d31baf1 Mon Sep 17 00:00:00 2001 From: KarlsonComplete Date: Thu, 17 Apr 2025 00:33:07 +0300 Subject: [PATCH 21/49] =?UTF-8?q?-=20=D0=9F=D1=80=D0=B0=D0=B2=D0=BA=D0=B8?= =?UTF-8?q?=20=D0=BF=D0=BE=20=D0=B1=D0=B8=D1=82=D1=80=D0=B8=D0=BA=D1=81=20?= =?UTF-8?q?24=20=D0=B0=D0=BA=D0=BA=D0=B0=D1=83=D0=BD=D1=82=D1=83=20=D1=83?= =?UTF-8?q?=D0=B1=D1=80=D0=B0=D0=BB=D0=B8=20(=D0=B4=D0=B0=D1=82=D1=83=20?= =?UTF-8?q?=D1=81=D0=BE=D0=B7=D0=B4=D0=B0=D0=BD=D0=B8=D1=8F=20/=20=D0=B4?= =?UTF-8?q?=D0=B0=D1=82=D1=83=20=D0=BE=D0=B1=D0=BD=D0=BE=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D1=8F=20/=20=D1=81=D1=82=D0=B0=D1=82=D1=83=D1=81)?= =?UTF-8?q?=20=D0=B8=D0=B7=20=D0=BA=D0=BE=D0=BD=D1=81=D1=82=D1=80=D1=83?= =?UTF-8?q?=D0=BA=D1=82=D0=BE=D1=80=D0=B0=20.=20=D0=9E=D0=B1=D1=8A=D1=8F?= =?UTF-8?q?=D0=B2=D0=BB=D1=8F=D0=B5=D0=BC=20=D1=82=D0=B5=D0=BF=D0=B5=D1=80?= =?UTF-8?q?=D1=8C=20=D0=BF=D1=80=D0=B8=20=D1=81=D0=BE=D0=B7=D0=B4=D0=B0?= =?UTF-8?q?=D0=BD=D0=B8=D0=B8.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../UseCase/Install/Command.php | 3 -- .../UseCase/Install/Handler.php | 40 +++++++++++++------ .../Entity/Bitrix24Account.php | 13 ++++-- .../UseCase/InstallStart/Handler.php | 3 -- .../UseCase/Install/HandlerTest.php | 3 -- .../Builders/Bitrix24AccountBuilder.php | 11 +---- .../Bitrix24AccountRepositoryTest.php | 3 -- .../UseCase/RenewAuthToken/HandlerTest.php | 5 +++ .../UseCase/UpdateVersion/HandlerTest.php | 8 ++-- .../Entity/Bitrix24AccountTest.php | 3 -- .../UseCase/ChangeDomainUrl/CommandTest.php | 10 ----- 11 files changed, 49 insertions(+), 53 deletions(-) diff --git a/src/ApplicationInstallations/UseCase/Install/Command.php b/src/ApplicationInstallations/UseCase/Install/Command.php index 22b8f33..64d67f0 100644 --- a/src/ApplicationInstallations/UseCase/Install/Command.php +++ b/src/ApplicationInstallations/UseCase/Install/Command.php @@ -14,8 +14,6 @@ readonly class Command { public function __construct( - public Uuid $uuid, - public Uuid $bitrix24AccountId, public ApplicationStatus $applicationStatus, public PortalLicenseFamily $portalLicenseFamily, public ?int $portalUsersCount, @@ -24,7 +22,6 @@ public function __construct( public ?Uuid $bitrix24PartnerId, public ?string $externalId, public ?string $comment, - public Uuid $bitrix24AccountUuid, public int $bitrix24UserId, public bool $isBitrix24UserAdmin, public string $memberId, diff --git a/src/ApplicationInstallations/UseCase/Install/Handler.php b/src/ApplicationInstallations/UseCase/Install/Handler.php index 5b3e2de..87d8f20 100644 --- a/src/ApplicationInstallations/UseCase/Install/Handler.php +++ b/src/ApplicationInstallations/UseCase/Install/Handler.php @@ -18,28 +18,44 @@ readonly class Handler { public function __construct( - private Bitrix24AccountRepository $bitrix24AccountRepository, + private Bitrix24AccountRepository $bitrix24AccountRepository, private ApplicationInstallationRepository $applicationInstallationRepository, - private Flusher $flusher, - private LoggerInterface $logger - ) {} + private Flusher $flusher, + private LoggerInterface $logger + ) + { + } public function handle(Command $command): void { $this->logger->info('ApplicationInstallations.InstallStart.start', [ - 'id' => $command->uuid->toRfc4122(), + 'applicationStatus' => $command->applicationStatus, + 'portalLicenseFamily' => $command->portalLicenseFamily, + 'portalUsersCount' => $command->portalUsersCount, + 'contactPersonId' => $command->contactPersonId, + 'bitrix24PartnerContactPersonId' => $command->bitrix24PartnerContactPersonId, + 'bitrix24PartnerId' => $command->bitrix24PartnerId, + 'externalId' => $command->externalId, + 'comment' => $command->comment, + 'bitrix24UserId' => $command->bitrix24UserId, + 'isBitrix24UserAdmin' => $command->isBitrix24UserAdmin, + 'memberId' => $command->memberId, + 'domain' => $command->domain, + 'authToken' => $command->authToken, + 'applicationVersion' => $command->applicationVersion, + 'applicationScope' => $command->applicationScope ]); + $bitrix24AccountId = Uuid::v7(); + $applicationInstallationId = Uuid::v7(); + $bitrix24Account = new Bitrix24Account( - $command->bitrix24AccountUuid, + $bitrix24AccountId, $command->bitrix24UserId, $command->isBitrix24UserAdmin, $command->memberId, $command->domain->value, - Bitrix24AccountStatus::new, $command->authToken, - new CarbonImmutable(), - new CarbonImmutable(), $command->applicationVersion, $command->applicationScope, true @@ -54,11 +70,11 @@ public function handle(Command $command): void $this->flusher->flush($bitrix24Account); $applicationInstallation = new ApplicationInstallation( - $command->uuid, + $applicationInstallationId, ApplicationInstallationStatus::new, new CarbonImmutable(), new CarbonImmutable(), - $command->bitrix24AccountId, + $bitrix24AccountId, $command->applicationStatus, $command->portalLicenseFamily, $command->portalUsersCount, @@ -79,7 +95,7 @@ public function handle(Command $command): void $this->flusher->flush($applicationInstallation); $this->logger->info( - 'Bitrix24Accounts.InstallStart.Finish', + 'ApplicationInstallations.InstallStart.Finish', [ 'id' => $command->uuid->toRfc4122(), ] diff --git a/src/Bitrix24Accounts/Entity/Bitrix24Account.php b/src/Bitrix24Accounts/Entity/Bitrix24Account.php index bcea202..b809066 100644 --- a/src/Bitrix24Accounts/Entity/Bitrix24Account.php +++ b/src/Bitrix24Accounts/Entity/Bitrix24Account.php @@ -23,6 +23,7 @@ use Bitrix24\SDK\Application\Contracts\Bitrix24Accounts\Events\Bitrix24AccountCreatedEvent; use Bitrix24\SDK\Application\Contracts\Bitrix24Accounts\Events\Bitrix24AccountDomainUrlChangedEvent; use Bitrix24\SDK\Core\Credentials\AuthToken; +use Bitrix24\SDK\Core\Credentials\Credentials; use Bitrix24\SDK\Core\Credentials\Scope; use Bitrix24\SDK\Core\Exceptions\InvalidArgumentException; use Bitrix24\SDK\Core\Response\DTO\RenewedAuthToken; @@ -33,6 +34,12 @@ class Bitrix24Account extends AggregateRoot implements Bitrix24AccountInterface { private ?string $applicationToken = null; + private readonly CarbonImmutable $createdAt; + + private CarbonImmutable $updatedAt; + + private Bitrix24AccountStatus $status; + public function __construct( private readonly Uuid $id, private readonly int $bitrix24UserId, @@ -40,15 +47,15 @@ public function __construct( /** bitrix24 portal unique id */ private readonly string $memberId, private string $domainUrl, - private Bitrix24AccountStatus $status, private AuthToken $authToken, - private readonly CarbonImmutable $createdAt, - private CarbonImmutable $updatedAt, private int $applicationVersion, private Scope $applicationScope, private $isEmitBitrix24AccountCreatedEvent = false, private ?string $comment = null ) { + $this->createdAt = new CarbonImmutable(); + $this->updatedAt = new CarbonImmutable(); + $this->status = Bitrix24AccountStatus::new; $this->addAccountCreatedEventIfNeeded($this->isEmitBitrix24AccountCreatedEvent); } diff --git a/src/Bitrix24Accounts/UseCase/InstallStart/Handler.php b/src/Bitrix24Accounts/UseCase/InstallStart/Handler.php index 01e7ee0..d8bf7d1 100644 --- a/src/Bitrix24Accounts/UseCase/InstallStart/Handler.php +++ b/src/Bitrix24Accounts/UseCase/InstallStart/Handler.php @@ -34,10 +34,7 @@ public function handle(Command $command): void $command->isBitrix24UserAdmin, $command->memberId, $command->domain->value, - Bitrix24AccountStatus::new, $command->authToken, - new CarbonImmutable(), - new CarbonImmutable(), $command->applicationVersion, $command->applicationScope, true diff --git a/tests/Functional/ApplicationInstallations/UseCase/Install/HandlerTest.php b/tests/Functional/ApplicationInstallations/UseCase/Install/HandlerTest.php index e6fbc61..9a03e03 100644 --- a/tests/Functional/ApplicationInstallations/UseCase/Install/HandlerTest.php +++ b/tests/Functional/ApplicationInstallations/UseCase/Install/HandlerTest.php @@ -95,8 +95,6 @@ public function testInstallNewApplicationInstallation(): void $this->handler->handle( new ApplicationInstallations\UseCase\Install\Command( - $applicationInstallationBuilder->getId(), - $bitrix24AccountBuilder->getId(), $applicationInstallationBuilder->getApplicationStatus(), $applicationInstallationBuilder->getPortalLicenseFamily(), $applicationInstallationBuilder->getPortalUsersCount(), @@ -105,7 +103,6 @@ public function testInstallNewApplicationInstallation(): void $applicationInstallationBuilder->getBitrix24PartnerId(), $applicationInstallationBuilder->getExternalId(), $applicationInstallationBuilder->getComment(), - $bitrix24AccountBuilder->getId(), $bitrix24AccountBuilder->getBitrix24UserId(), $bitrix24AccountBuilder->isBitrix24UserAdmin(), $bitrix24AccountBuilder->getMemberId(), diff --git a/tests/Functional/Bitrix24Accounts/Builders/Bitrix24AccountBuilder.php b/tests/Functional/Bitrix24Accounts/Builders/Bitrix24AccountBuilder.php index 7944908..aa2ba95 100644 --- a/tests/Functional/Bitrix24Accounts/Builders/Bitrix24AccountBuilder.php +++ b/tests/Functional/Bitrix24Accounts/Builders/Bitrix24AccountBuilder.php @@ -33,14 +33,10 @@ class Bitrix24AccountBuilder private string $domainUrl; - private Bitrix24AccountStatus $status = Bitrix24AccountStatus::active; + private Bitrix24AccountStatus $status; private readonly AuthToken $authToken; - private readonly CarbonImmutable $createdAt; - - private readonly CarbonImmutable $updatedAt; - private readonly int $applicationVersion; private Scope $applicationScope; @@ -55,8 +51,6 @@ public function __construct() $this->memberId = Uuid::v4()->toRfc4122(); $this->domainUrl = Uuid::v4()->toRfc4122().'-example.com'; $this->authToken = new AuthToken('old_1', 'old_2', 3600); - $this->createdAt = CarbonImmutable::now(); - $this->updatedAt = CarbonImmutable::now(); $this->applicationVersion = 1; $this->applicationScope = new Scope(); } @@ -104,10 +98,7 @@ public function build(): Bitrix24Account $this->isBitrix24UserAdmin, $this->memberId, $this->domainUrl, - $this->status, $this->authToken, - $this->createdAt, - $this->updatedAt, $this->applicationVersion, $this->applicationScope ); diff --git a/tests/Functional/Bitrix24Accounts/Infrastructure/Doctrine/Bitrix24AccountRepositoryTest.php b/tests/Functional/Bitrix24Accounts/Infrastructure/Doctrine/Bitrix24AccountRepositoryTest.php index 4736e55..bba49d5 100644 --- a/tests/Functional/Bitrix24Accounts/Infrastructure/Doctrine/Bitrix24AccountRepositoryTest.php +++ b/tests/Functional/Bitrix24Accounts/Infrastructure/Doctrine/Bitrix24AccountRepositoryTest.php @@ -56,10 +56,7 @@ protected function createBitrix24AccountImplementation( $isBitrix24UserAdmin, $memberId, $domainUrl, - $bitrix24AccountStatus, $authToken, - $createdAt, - $updatedAt, $applicationVersion, $applicationScope ); diff --git a/tests/Functional/Bitrix24Accounts/UseCase/RenewAuthToken/HandlerTest.php b/tests/Functional/Bitrix24Accounts/UseCase/RenewAuthToken/HandlerTest.php index 31a5855..87000e8 100644 --- a/tests/Functional/Bitrix24Accounts/UseCase/RenewAuthToken/HandlerTest.php +++ b/tests/Functional/Bitrix24Accounts/UseCase/RenewAuthToken/HandlerTest.php @@ -20,6 +20,7 @@ use Bitrix24\Lib\Tests\EntityManagerFactory; use Bitrix24\Lib\Tests\Functional\Bitrix24Accounts\Builders\Bitrix24AccountBuilder; use Bitrix24\SDK\Application\ApplicationStatus; +use Bitrix24\SDK\Application\Contracts\Bitrix24Accounts\Entity\Bitrix24AccountStatus; use Bitrix24\SDK\Application\Contracts\Bitrix24Accounts\Repository\Bitrix24AccountRepositoryInterface; use Bitrix24\SDK\Core\Credentials\AuthToken; use Bitrix24\SDK\Core\Response\DTO\RenewedAuthToken; @@ -30,6 +31,7 @@ use Symfony\Component\EventDispatcher\Debug\TraceableEventDispatcher; use Symfony\Component\EventDispatcher\EventDispatcher; use Symfony\Component\Stopwatch\Stopwatch; +use Symfony\Component\Uid\Uuid; /** * @internal @@ -64,7 +66,10 @@ protected function setUp(): void #[Test] public function testRenewAuthTokenWithoutBitrix24UserId(): void { + $applicationToken = Uuid::v7()->toRfc4122(); $bitrix24Account = (new Bitrix24AccountBuilder()) + ->withStatus(Bitrix24AccountStatus::new) + ->withApplicationToken($applicationToken) ->build(); $this->repository->save($bitrix24Account); $this->flusher->flush(); diff --git a/tests/Functional/Bitrix24Accounts/UseCase/UpdateVersion/HandlerTest.php b/tests/Functional/Bitrix24Accounts/UseCase/UpdateVersion/HandlerTest.php index 8147815..c80d27e 100644 --- a/tests/Functional/Bitrix24Accounts/UseCase/UpdateVersion/HandlerTest.php +++ b/tests/Functional/Bitrix24Accounts/UseCase/UpdateVersion/HandlerTest.php @@ -69,7 +69,7 @@ public function testSuccessUpdateVersion(): void $applicationToken = Uuid::v7()->toRfc4122(); $bitrix24Account = (new Bitrix24AccountBuilder()) - ->withStatus(Bitrix24AccountStatus::active) + ->withStatus(Bitrix24AccountStatus::new) ->withApplicationToken($applicationToken) ->build(); @@ -98,7 +98,7 @@ public function testNotFoundBitrix24AccountForUpdateVersion(): void $applicationToken = Uuid::v7()->toRfc4122(); $bitrix24Account = (new Bitrix24AccountBuilder()) - ->withStatus(Bitrix24AccountStatus::active) + ->withStatus(Bitrix24AccountStatus::new) ->withApplicationToken($applicationToken) ->build(); @@ -126,8 +126,10 @@ public function testNotFoundBitrix24AccountForUpdateVersion(): void #[Test] public function testNotValidVersionForUpdateVersion(): void { + $applicationToken = Uuid::v7()->toRfc4122(); $bitrix24Account = (new Bitrix24AccountBuilder()) - ->withStatus(Bitrix24AccountStatus::active) + ->withStatus(Bitrix24AccountStatus::new) + ->withApplicationToken($applicationToken) ->build(); diff --git a/tests/Unit/Bitrix24Accounts/Entity/Bitrix24AccountTest.php b/tests/Unit/Bitrix24Accounts/Entity/Bitrix24AccountTest.php index 3671674..fa20efc 100644 --- a/tests/Unit/Bitrix24Accounts/Entity/Bitrix24AccountTest.php +++ b/tests/Unit/Bitrix24Accounts/Entity/Bitrix24AccountTest.php @@ -49,10 +49,7 @@ protected function createBitrix24AccountImplementation( $isBitrix24UserAdmin, $memberId, $domainUrl, - $bitrix24AccountStatus, $authToken, - $createdAt, - $updatedAt, $applicationVersion, $applicationScope ); diff --git a/tests/Unit/Bitrix24Accounts/UseCase/ChangeDomainUrl/CommandTest.php b/tests/Unit/Bitrix24Accounts/UseCase/ChangeDomainUrl/CommandTest.php index bb3646f..d5d023a 100644 --- a/tests/Unit/Bitrix24Accounts/UseCase/ChangeDomainUrl/CommandTest.php +++ b/tests/Unit/Bitrix24Accounts/UseCase/ChangeDomainUrl/CommandTest.php @@ -54,16 +54,6 @@ public function testValidateInvalidDomain( public static function dataForValidateValidDomain(): \Generator { - // Примеры допустимых доменов - /*$arrValidDomains = [ - ['oldDomain' => 'example.com', 'newDomain' => 'example.org'], - ['oldDomain' => 'пример.рф', 'newDomain' => 'пример.рус'], - ['oldDomain' => 'test-site.org', 'newDomain' => 'test-site.ru'], - ['oldDomain' => 'valid-domain.co.uk', 'newDomain' => 'valid-domain.net'], - ['oldDomain' => 'subdomain.example.com', 'newDomain' => 'subdomain2.example.com'], - ['oldDomain' => 'тест.рус', 'newDomain' => 'тест2.рус'], // Пример с кириллицей - ];*/ - yield 'validDomain1' => [ 'example.com', 'example.org', From 12c486ef34e475e467d6cd623dd5b8407da78815 Mon Sep 17 00:00:00 2001 From: KarlsonComplete Date: Sun, 20 Apr 2025 18:02:43 +0300 Subject: [PATCH 22/49] =?UTF-8?q?=D0=9F=D1=80=D0=B0=D0=B2=D0=BA=D0=B8=20?= =?UTF-8?q?=D1=83=D1=81=D1=82=D0=B0=D0=BD=D0=BE=D0=B2=D0=BA=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../UseCase/Install/Handler.php | 58 ++++++++++++--- .../UseCase/Reinstall/Handler.php | 4 -- .../UseCase/Install/HandlerTest.php | 70 +++++++++++++++++-- 3 files changed, 113 insertions(+), 19 deletions(-) diff --git a/src/ApplicationInstallations/UseCase/Install/Handler.php b/src/ApplicationInstallations/UseCase/Install/Handler.php index 87d8f20..e50d94a 100644 --- a/src/ApplicationInstallations/UseCase/Install/Handler.php +++ b/src/ApplicationInstallations/UseCase/Install/Handler.php @@ -9,8 +9,11 @@ use Bitrix24\Lib\Bitrix24Accounts\Entity\Bitrix24Account; use Bitrix24\Lib\Bitrix24Accounts\Infrastructure\Doctrine\Bitrix24AccountRepository; use Bitrix24\Lib\Services\Flusher; +use Bitrix24\SDK\Application\Contracts\ApplicationInstallations\Entity\ApplicationInstallationInterface; use Bitrix24\SDK\Application\Contracts\ApplicationInstallations\Entity\ApplicationInstallationStatus; +use Bitrix24\SDK\Application\Contracts\Bitrix24Accounts\Entity\Bitrix24AccountInterface; use Bitrix24\SDK\Application\Contracts\Bitrix24Accounts\Entity\Bitrix24AccountStatus; +use Bitrix24\SDK\Application\Contracts\Events\AggregateRootEventsEmitterInterface; use Carbon\CarbonImmutable; use Psr\Log\LoggerInterface; use Symfony\Component\Uid\Uuid; @@ -46,6 +49,30 @@ public function handle(Command $command): void 'applicationScope' => $command->applicationScope ]); + $accountsCount = 0; + + /** @var AggregateRootEventsEmitterInterface|ApplicationInstallationInterface $activeApplicationInstallation */ + $activeApplicationInstallation = $this->getActiveApplicationInstallation(); + //Решили 13 апреля расширить контракт установки и добавить получения токена + $activeApplicationToken = $activeApplicationInstallation->getApplicationToken(); + if (!empty($activeApplicationInstallation)) { + + $oldBitrix24AccountId = $activeApplicationInstallation->getBitrix24AccountId(); + $oldBitrix24Account = $this->bitrix24AccountRepository->getById($oldBitrix24AccountId); + /** @var AggregateRootEventsEmitterInterface[]|Bitrix24AccountInterface[] $accounts */ + $accounts = $this->bitrix24AccountRepository->findByMemberId($oldBitrix24Account->getMemberId()); + $accountsCount = count($accounts); + foreach ($accounts as $account) { + //Сюда пробрасываем токен полученный выше + $account->applicationUninstalled($activeApplicationToken); + $this->bitrix24AccountRepository->save($account); + } + + $activeApplicationInstallation->applicationUninstalled(); + + $this->flusher->flush(...$accounts); + } + $bitrix24AccountId = Uuid::v7(); $applicationInstallationId = Uuid::v7(); @@ -61,13 +88,8 @@ public function handle(Command $command): void true ); - $this->bitrix24AccountRepository->save($bitrix24Account); - $this->flusher->flush($bitrix24Account); - $applicationToken = Uuid::v7()->toRfc4122(); $bitrix24Account->applicationInstalled($applicationToken); - $this->bitrix24AccountRepository->save($bitrix24Account); - $this->flusher->flush($bitrix24Account); $applicationInstallation = new ApplicationInstallation( $applicationInstallationId, @@ -86,19 +108,35 @@ public function handle(Command $command): void true ); - $this->applicationInstallationRepository->save($applicationInstallation); - $this->flusher->flush($applicationInstallation); - $applicationInstallation->applicationInstalled(); + $this->bitrix24AccountRepository->save($bitrix24Account); $this->applicationInstallationRepository->save($applicationInstallation); - $this->flusher->flush($applicationInstallation); + $this->flusher->flush($applicationInstallation,$bitrix24Account); $this->logger->info( 'ApplicationInstallations.InstallStart.Finish', [ - 'id' => $command->uuid->toRfc4122(), + 'applicationId' => $applicationInstallationId, + 'bitrix24AccountId' => $bitrix24AccountId, + 'applicationToken' => $applicationToken, + 'memberId' => $command->memberId, + 'domain' => $command->domain, + 'accountsUninstalledCount' => $accountsCount, ] ); } + private function getActiveApplicationInstallation(): ApplicationInstallationInterface + { + $activeApplicationInstallations = $this->applicationInstallationRepository->findActiveApplicationInstallations(); + + if (!([] === $activeApplicationInstallations) && count($activeApplicationInstallations) > 1) { + // Тут может добавить исключение для приложения ? По подобию MultipleBitrix24AccountsFoundException + throw new \InvalidArgumentException( + 'multiple application installations with active or new status' + ); + } + + return $activeApplicationInstallations[0]; + } } diff --git a/src/ApplicationInstallations/UseCase/Reinstall/Handler.php b/src/ApplicationInstallations/UseCase/Reinstall/Handler.php index 05fab4a..d82120b 100644 --- a/src/ApplicationInstallations/UseCase/Reinstall/Handler.php +++ b/src/ApplicationInstallations/UseCase/Reinstall/Handler.php @@ -116,10 +116,6 @@ private function getActiveApplicationInstallation(): ApplicationInstallationInte { $activeApplicationInstallations = $this->applicationInstallationRepository->findActiveApplicationInstallations(); - /* - У нас вообще может быть приложений больше чем одно активных или в статусе new ? Мне кажется это значит что что-то не сработало в прошлый раз. - Так как приложение у нас по факту же только одно ? - */ if (!([] === $activeApplicationInstallations) && count($activeApplicationInstallations) > 1) { // Тут может добавить исключение для приложения ? По подобию MultipleBitrix24AccountsFoundException throw new \InvalidArgumentException( diff --git a/tests/Functional/ApplicationInstallations/UseCase/Install/HandlerTest.php b/tests/Functional/ApplicationInstallations/UseCase/Install/HandlerTest.php index 9a03e03..e30ea77 100644 --- a/tests/Functional/ApplicationInstallations/UseCase/Install/HandlerTest.php +++ b/tests/Functional/ApplicationInstallations/UseCase/Install/HandlerTest.php @@ -25,6 +25,7 @@ use Bitrix24\Lib\Tests\Functional\Bitrix24Accounts\Builders\Bitrix24AccountBuilder; use Bitrix24\SDK\Application\ApplicationStatus; use Bitrix24\SDK\Application\Contracts\ApplicationInstallations\Entity\ApplicationInstallationStatus; +use Bitrix24\SDK\Application\Contracts\Bitrix24Accounts\Entity\Bitrix24AccountStatus; use Bitrix24\SDK\Application\PortalLicenseFamily; use Bitrix24\SDK\Core\Credentials\Scope; use Bitrix24\SDK\Core\Exceptions\InvalidArgumentException; @@ -42,6 +43,8 @@ use Bitrix24\Lib\ApplicationInstallations\UseCase\Install\Handler; use Bitrix24\Lib\Bitrix24Accounts\Infrastructure\Doctrine\Bitrix24AccountRepository; +use Symfony\Component\Uid\Uuid; + /** * @internal */ @@ -77,12 +80,10 @@ protected function setUp(): void /** * @throws InvalidArgumentException - * @throws ApplicationInstallationNotFoundException */ #[Test] public function testInstallNewApplicationInstallation(): void { - $bitrix24AccountBuilder = (new Bitrix24AccountBuilder()) ->withApplicationScope(new Scope(['crm'])) ->build(); @@ -113,7 +114,68 @@ public function testInstallNewApplicationInstallation(): void ) ); - $applicationInstallation = $this->repository->getById($applicationInstallationBuilder->getId()); + $dispatchedEvents = $this->eventDispatcher->getOrphanedEvents(); + + $this->assertContains(\Bitrix24\SDK\Application\Contracts\Bitrix24Accounts\Events\Bitrix24AccountCreatedEvent::class, $dispatchedEvents); + $this->assertContains(\Bitrix24\SDK\Application\Contracts\ApplicationInstallations\Events\ApplicationInstallationCreatedEvent::class, $dispatchedEvents); + $this->assertContains(\Bitrix24\SDK\Application\Contracts\Bitrix24Accounts\Events\Bitrix24AccountApplicationInstalledEvent::class, $dispatchedEvents); + $this->assertContains(\Bitrix24\SDK\Application\Contracts\ApplicationInstallations\Events\ApplicationInstallationFinishedEvent::class, $dispatchedEvents); + } + + /** + * @throws InvalidArgumentException + */ + #[Test] + public function testReinstallApplicationInstallation(): void + { + //Загружаем в базу данных аккаунт и установку приложения для тестирования переустановки. + $applicationToken = Uuid::v7()->toRfc4122(); + $bitrix24Account = (new Bitrix24AccountBuilder()) + ->withApplicationScope(new Scope(['crm'])) + ->withStatus(Bitrix24AccountStatus::new) + ->withApplicationToken($applicationToken) + ->build(); + + + $oldApplicationInstallationBuilder = (new ApplicationInstallationBuilder()) + ->withApplicationStatus(new ApplicationStatus('F')) + ->withPortalLicenseFamily(PortalLicenseFamily::free) + ->withBitrix24AccountId($bitrix24Account->getId()) + ->withApplicationStatusInstallation(ApplicationInstallationStatus::active) + ->build(); + + $this->bitrix24accountRepository->save($bitrix24Account); + $this->repository->save($oldApplicationInstallationBuilder); + $this->flusher->flush(); + + $bitrix24AccountBuilder = (new Bitrix24AccountBuilder()) + ->withApplicationScope(new Scope(['crm'])) + ->build(); + + $applicationInstallationBuilder = (new ApplicationInstallationBuilder()) + ->withApplicationStatus(new ApplicationStatus('F')) + ->withPortalLicenseFamily(PortalLicenseFamily::free) + ->build(); + + $this->handler->handle( + new ApplicationInstallations\UseCase\Install\Command( + $applicationInstallationBuilder->getApplicationStatus(), + $applicationInstallationBuilder->getPortalLicenseFamily(), + $applicationInstallationBuilder->getPortalUsersCount(), + $applicationInstallationBuilder->getContactPersonId(), + $applicationInstallationBuilder->getBitrix24PartnerContactPersonId(), + $applicationInstallationBuilder->getBitrix24PartnerId(), + $applicationInstallationBuilder->getExternalId(), + $applicationInstallationBuilder->getComment(), + $bitrix24AccountBuilder->getBitrix24UserId(), + $bitrix24AccountBuilder->isBitrix24UserAdmin(), + $bitrix24AccountBuilder->getMemberId(), + new Domain($bitrix24AccountBuilder->getDomainUrl()), + $bitrix24AccountBuilder->getAuthToken(), + $bitrix24AccountBuilder->getApplicationVersion(), + $bitrix24AccountBuilder->getApplicationScope() + ) + ); $dispatchedEvents = $this->eventDispatcher->getOrphanedEvents(); @@ -121,7 +183,5 @@ public function testInstallNewApplicationInstallation(): void $this->assertContains(\Bitrix24\SDK\Application\Contracts\ApplicationInstallations\Events\ApplicationInstallationCreatedEvent::class, $dispatchedEvents); $this->assertContains(\Bitrix24\SDK\Application\Contracts\Bitrix24Accounts\Events\Bitrix24AccountApplicationInstalledEvent::class, $dispatchedEvents); $this->assertContains(\Bitrix24\SDK\Application\Contracts\ApplicationInstallations\Events\ApplicationInstallationFinishedEvent::class, $dispatchedEvents); - $this->assertEquals(ApplicationInstallationStatus::active, $applicationInstallation->getStatus()); - $this->assertEquals($bitrix24AccountBuilder->getId(), $applicationInstallation->getBitrix24AccountId()); } } From 68f4056707416bc58e92a8673343fe7a57c3d43e Mon Sep 17 00:00:00 2001 From: KarlsonComplete Date: Sat, 26 Apr 2025 15:20:52 +0300 Subject: [PATCH 23/49] =?UTF-8?q?=D0=9F=D1=80=D0=B0=D0=B2=D0=BA=D0=B8=20?= =?UTF-8?q?=D0=B4=D0=BB=D1=8F=20=D1=83=D1=81=D1=82=D0=B0=D0=BD=D0=BE=D0=B2?= =?UTF-8?q?=D0=BA=D0=B8=20=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8=D0=BB=20app?= =?UTF-8?q?licationToken=20=D0=B2=20=D1=81=D1=83=D1=89=D0=BD=D0=BE=D1=81?= =?UTF-8?q?=D1=82=D1=8C=20=D1=83=D1=81=D1=82=D0=B0=D0=BD=D0=BE=D0=B2=D0=BA?= =?UTF-8?q?=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...ons.Entity.ApplicationInstallation.dcm.xml | 3 +++ .../Entity/ApplicationInstallation.php | 18 +++++++++++----- .../ApplicationInstallationRepository.php | 6 ------ .../UseCase/Install/Command.php | 6 ++++++ .../UseCase/Install/Handler.php | 21 ++++++++++--------- .../ApplicationInstallationBuilder.php | 12 +++++++++++ .../UseCase/Install/HandlerTest.php | 10 ++++++--- .../Bitrix24AccountRepositoryTest.php | 3 --- .../Entity/Bitrix24AccountTest.php | 3 --- 9 files changed, 52 insertions(+), 30 deletions(-) diff --git a/config/xml/Bitrix24.Lib.ApplicationInstallations.Entity.ApplicationInstallation.dcm.xml b/config/xml/Bitrix24.Lib.ApplicationInstallations.Entity.ApplicationInstallation.dcm.xml index b128b62..bb793a6 100644 --- a/config/xml/Bitrix24.Lib.ApplicationInstallations.Entity.ApplicationInstallation.dcm.xml +++ b/config/xml/Bitrix24.Lib.ApplicationInstallations.Entity.ApplicationInstallation.dcm.xml @@ -28,8 +28,11 @@ + + + \ No newline at end of file diff --git a/src/ApplicationInstallations/Entity/ApplicationInstallation.php b/src/ApplicationInstallations/Entity/ApplicationInstallation.php index 77312f7..8fa1407 100644 --- a/src/ApplicationInstallations/Entity/ApplicationInstallation.php +++ b/src/ApplicationInstallations/Entity/ApplicationInstallation.php @@ -18,6 +18,7 @@ use Bitrix24\SDK\Core\Exceptions\InvalidArgumentException; use Carbon\CarbonImmutable; use Symfony\Component\Uid\Uuid; +use Bitrix24\SDK\Core\Exceptions\LogicException; class ApplicationInstallation extends AggregateRoot implements ApplicationInstallationInterface { @@ -34,8 +35,9 @@ public function __construct( private ?Uuid $bitrix24PartnerContactPersonId, private ?Uuid $bitrix24PartnerId, private ?string $externalId, + private readonly string $applicationToken, private ?string $comment = null, - private $isEmitApplicationInstallationCreatedEvent = false, + private $isEmitApplicationInstallationCreatedEvent = false ) { $this->addApplicationCreatedEventIfNeeded($this->isEmitApplicationInstallationCreatedEvent); } @@ -70,6 +72,12 @@ public function getContactPersonId(): ?Uuid return $this->contactPersonId; } + public function getApplicationToken(): string + { + return $this->applicationToken; + } + + #[\Override] public function changeContactPerson(?Uuid $uuid): void { @@ -156,7 +164,7 @@ public function applicationInstalled(): void ApplicationInstallationStatus::new !== $this->status && ApplicationInstallationStatus::blocked !== $this->status ) { - throw new \LogicException( + throw new LogicException( sprintf( 'installation was interrupted because status must be in new or blocked,but your status is %s', $this->status->value @@ -185,7 +193,7 @@ public function applicationUninstalled(): void ApplicationInstallationStatus::active !== $this->status && ApplicationInstallationStatus::blocked !== $this->status ) { - throw new \LogicException( + throw new LogicException( sprintf( 'installation was interrupted because status must be in active or blocked, but your status is %s', $this->status->value @@ -211,7 +219,7 @@ public function applicationUninstalled(): void public function markAsActive(?string $comment): void { if (ApplicationInstallationStatus::blocked !== $this->status) { - throw new \LogicException( + throw new LogicException( sprintf( 'you must be in status blocked to complete the installation, now status is «%s»', $this->status->value @@ -237,7 +245,7 @@ public function markAsBlocked(?string $comment): void ApplicationInstallationStatus::new !== $this->status && ApplicationInstallationStatus::active !== $this->status ) { - throw new \LogicException(sprintf( + throw new LogicException(sprintf( 'You can block application installation only in status new or active,but your status is «%s»', $this->status->value )); diff --git a/src/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationRepository.php b/src/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationRepository.php index 926ec82..ae95e03 100644 --- a/src/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationRepository.php +++ b/src/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationRepository.php @@ -54,12 +54,6 @@ public function delete(Uuid $uuid): void { $applicationInstallation = $this->getEntityManager()->getRepository(ApplicationInstallation::class)->find($uuid); - if (null === $applicationInstallation) { - throw new ApplicationInstallationNotFoundException( - sprintf('application installed not found by id %s', $uuid->toRfc4122()) - ); - } - if (ApplicationInstallationStatus::deleted !== $applicationInstallation->getStatus()) { throw new InvalidArgumentException( sprintf('you cannot delete application installed because you status must be deleted your status %s', $applicationInstallation->getStatus()->name) diff --git a/src/ApplicationInstallations/UseCase/Install/Command.php b/src/ApplicationInstallations/UseCase/Install/Command.php index 64d67f0..ebefa4b 100644 --- a/src/ApplicationInstallations/UseCase/Install/Command.php +++ b/src/ApplicationInstallations/UseCase/Install/Command.php @@ -14,6 +14,7 @@ readonly class Command { public function __construct( + public string $applicationToken, public ApplicationStatus $applicationStatus, public PortalLicenseFamily $portalLicenseFamily, public ?int $portalUsersCount, @@ -35,6 +36,11 @@ public function __construct( private function validate(): void { + + if ('' === $this->applicationToken) { + throw new \InvalidArgumentException('applicationToken must be a non-empty string.'); + } + if ($this->portalUsersCount <= 0) { throw new \InvalidArgumentException('Portal Users count must be a positive integer.'); } diff --git a/src/ApplicationInstallations/UseCase/Install/Handler.php b/src/ApplicationInstallations/UseCase/Install/Handler.php index e50d94a..c533294 100644 --- a/src/ApplicationInstallations/UseCase/Install/Handler.php +++ b/src/ApplicationInstallations/UseCase/Install/Handler.php @@ -12,7 +12,6 @@ use Bitrix24\SDK\Application\Contracts\ApplicationInstallations\Entity\ApplicationInstallationInterface; use Bitrix24\SDK\Application\Contracts\ApplicationInstallations\Entity\ApplicationInstallationStatus; use Bitrix24\SDK\Application\Contracts\Bitrix24Accounts\Entity\Bitrix24AccountInterface; -use Bitrix24\SDK\Application\Contracts\Bitrix24Accounts\Entity\Bitrix24AccountStatus; use Bitrix24\SDK\Application\Contracts\Events\AggregateRootEventsEmitterInterface; use Carbon\CarbonImmutable; use Psr\Log\LoggerInterface; @@ -53,10 +52,12 @@ public function handle(Command $command): void /** @var AggregateRootEventsEmitterInterface|ApplicationInstallationInterface $activeApplicationInstallation */ $activeApplicationInstallation = $this->getActiveApplicationInstallation(); - //Решили 13 апреля расширить контракт установки и добавить получения токена - $activeApplicationToken = $activeApplicationInstallation->getApplicationToken(); + if (!empty($activeApplicationInstallation)) { + //Решили 13 апреля расширить контракт установки и добавить получения токена + $activeApplicationToken = $activeApplicationInstallation->getApplicationToken(); + $oldBitrix24AccountId = $activeApplicationInstallation->getBitrix24AccountId(); $oldBitrix24Account = $this->bitrix24AccountRepository->getById($oldBitrix24AccountId); /** @var AggregateRootEventsEmitterInterface[]|Bitrix24AccountInterface[] $accounts */ @@ -88,8 +89,8 @@ public function handle(Command $command): void true ); - $applicationToken = Uuid::v7()->toRfc4122(); - $bitrix24Account->applicationInstalled($applicationToken); + + $bitrix24Account->applicationInstalled($command->applicationToken); $applicationInstallation = new ApplicationInstallation( $applicationInstallationId, @@ -104,6 +105,7 @@ public function handle(Command $command): void $command->bitrix24PartnerContactPersonId, $command->bitrix24PartnerId, $command->externalId, + $command->applicationToken, $command->comment, true ); @@ -119,24 +121,23 @@ public function handle(Command $command): void [ 'applicationId' => $applicationInstallationId, 'bitrix24AccountId' => $bitrix24AccountId, - 'applicationToken' => $applicationToken, + 'applicationToken' => $command->applicationToken, 'memberId' => $command->memberId, 'domain' => $command->domain, 'accountsUninstalledCount' => $accountsCount, ] ); } - private function getActiveApplicationInstallation(): ApplicationInstallationInterface + private function getActiveApplicationInstallation(): ApplicationInstallationInterface|null { $activeApplicationInstallations = $this->applicationInstallationRepository->findActiveApplicationInstallations(); - if (!([] === $activeApplicationInstallations) && count($activeApplicationInstallations) > 1) { - // Тут может добавить исключение для приложения ? По подобию MultipleBitrix24AccountsFoundException + if (count($activeApplicationInstallations) > 1) { throw new \InvalidArgumentException( 'multiple application installations with active or new status' ); } - return $activeApplicationInstallations[0]; + return $activeApplicationInstallations[0] ?? null; } } diff --git a/tests/Functional/ApplicationInstallations/Builders/ApplicationInstallationBuilder.php b/tests/Functional/ApplicationInstallations/Builders/ApplicationInstallationBuilder.php index 0a88f86..79346a0 100644 --- a/tests/Functional/ApplicationInstallations/Builders/ApplicationInstallationBuilder.php +++ b/tests/Functional/ApplicationInstallations/Builders/ApplicationInstallationBuilder.php @@ -39,6 +39,8 @@ class ApplicationInstallationBuilder private ?string $comment = null; + private string $applicationToken; + public function __construct() { @@ -50,6 +52,8 @@ public function __construct() $this->contactPersonId = Uuid::v7(); $this->bitrix24PartnerId = Uuid::v7(); $this->portalUsersCount = random_int(1, 1_000_000); + //Токен который будет прилетать при событии установки в битриксе + $this->applicationToken = Uuid::v7()->toRfc4122(); } public function withExternalId(string $externalId): self @@ -73,6 +77,13 @@ public function withApplicationStatus(ApplicationStatus $applicationStatus): sel return $this; } + public function withApplicationToken(string $applicationToken): self + { + $this->applicationToken = $applicationToken; + + return $this; + } + public function withBitrix24AccountId(Uuid $uuid): self { $this->bitrix24AccountId = $uuid; @@ -102,6 +113,7 @@ public function build(): ApplicationInstallation $this->bitrix24PartnerContactPersonId, $this->bitrix24PartnerId, $this->externalId, + $this->applicationToken, $this->comment ); } diff --git a/tests/Functional/ApplicationInstallations/UseCase/Install/HandlerTest.php b/tests/Functional/ApplicationInstallations/UseCase/Install/HandlerTest.php index e30ea77..61c506f 100644 --- a/tests/Functional/ApplicationInstallations/UseCase/Install/HandlerTest.php +++ b/tests/Functional/ApplicationInstallations/UseCase/Install/HandlerTest.php @@ -94,8 +94,10 @@ public function testInstallNewApplicationInstallation(): void ->withPortalLicenseFamily(PortalLicenseFamily::free) ->build(); + $this->handler->handle( new ApplicationInstallations\UseCase\Install\Command( + $applicationInstallationBuilder->getApplicationToken(), $applicationInstallationBuilder->getApplicationStatus(), $applicationInstallationBuilder->getPortalLicenseFamily(), $applicationInstallationBuilder->getPortalUsersCount(), @@ -130,7 +132,7 @@ public function testReinstallApplicationInstallation(): void { //Загружаем в базу данных аккаунт и установку приложения для тестирования переустановки. $applicationToken = Uuid::v7()->toRfc4122(); - $bitrix24Account = (new Bitrix24AccountBuilder()) + $oldBitrix24Account = (new Bitrix24AccountBuilder()) ->withApplicationScope(new Scope(['crm'])) ->withStatus(Bitrix24AccountStatus::new) ->withApplicationToken($applicationToken) @@ -140,11 +142,12 @@ public function testReinstallApplicationInstallation(): void $oldApplicationInstallationBuilder = (new ApplicationInstallationBuilder()) ->withApplicationStatus(new ApplicationStatus('F')) ->withPortalLicenseFamily(PortalLicenseFamily::free) - ->withBitrix24AccountId($bitrix24Account->getId()) + ->withBitrix24AccountId($oldBitrix24Account->getId()) ->withApplicationStatusInstallation(ApplicationInstallationStatus::active) + ->withApplicationToken($applicationToken) ->build(); - $this->bitrix24accountRepository->save($bitrix24Account); + $this->bitrix24accountRepository->save($oldBitrix24Account); $this->repository->save($oldApplicationInstallationBuilder); $this->flusher->flush(); @@ -159,6 +162,7 @@ public function testReinstallApplicationInstallation(): void $this->handler->handle( new ApplicationInstallations\UseCase\Install\Command( + $applicationInstallationBuilder->getApplicationToken(), $applicationInstallationBuilder->getApplicationStatus(), $applicationInstallationBuilder->getPortalLicenseFamily(), $applicationInstallationBuilder->getPortalUsersCount(), diff --git a/tests/Functional/Bitrix24Accounts/Infrastructure/Doctrine/Bitrix24AccountRepositoryTest.php b/tests/Functional/Bitrix24Accounts/Infrastructure/Doctrine/Bitrix24AccountRepositoryTest.php index bba49d5..b33b88a 100644 --- a/tests/Functional/Bitrix24Accounts/Infrastructure/Doctrine/Bitrix24AccountRepositoryTest.php +++ b/tests/Functional/Bitrix24Accounts/Infrastructure/Doctrine/Bitrix24AccountRepositoryTest.php @@ -43,10 +43,7 @@ protected function createBitrix24AccountImplementation( bool $isBitrix24UserAdmin, string $memberId, string $domainUrl, - Bitrix24AccountStatus $bitrix24AccountStatus, AuthToken $authToken, - CarbonImmutable $createdAt, - CarbonImmutable $updatedAt, int $applicationVersion, Scope $applicationScope ): Bitrix24AccountInterface { diff --git a/tests/Unit/Bitrix24Accounts/Entity/Bitrix24AccountTest.php b/tests/Unit/Bitrix24Accounts/Entity/Bitrix24AccountTest.php index fa20efc..f0fd0a0 100644 --- a/tests/Unit/Bitrix24Accounts/Entity/Bitrix24AccountTest.php +++ b/tests/Unit/Bitrix24Accounts/Entity/Bitrix24AccountTest.php @@ -36,10 +36,7 @@ protected function createBitrix24AccountImplementation( bool $isBitrix24UserAdmin, string $memberId, string $domainUrl, - Bitrix24AccountStatus $bitrix24AccountStatus, AuthToken $authToken, - CarbonImmutable $createdAt, - CarbonImmutable $updatedAt, int $applicationVersion, Scope $applicationScope ): Bitrix24AccountInterface { From f5f72c373806d1ab678e97175cebf6548df8f186 Mon Sep 17 00:00:00 2001 From: KarlsonComplete Date: Sun, 27 Apr 2025 10:39:37 +0300 Subject: [PATCH 24/49] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8?= =?UTF-8?q?=D0=BB=20=D0=B4=D0=B5=D0=B8=D0=BD=D1=81=D1=82=D0=B0=D0=BB=D1=8F?= =?UTF-8?q?=D1=86=D0=B8=D1=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../UseCase/Uninstall/Command.php | 23 ++++ .../UseCase/Uninstall/Handler.php | 81 ++++++++++++ .../UseCase/Install/HandlerTest.php | 2 +- .../UseCase/Uninstall/HandlerTest.php | 118 ++++++++++++++++++ 4 files changed, 223 insertions(+), 1 deletion(-) create mode 100644 src/ApplicationInstallations/UseCase/Uninstall/Command.php create mode 100644 src/ApplicationInstallations/UseCase/Uninstall/Handler.php create mode 100644 tests/Functional/ApplicationInstallations/UseCase/Uninstall/HandlerTest.php diff --git a/src/ApplicationInstallations/UseCase/Uninstall/Command.php b/src/ApplicationInstallations/UseCase/Uninstall/Command.php new file mode 100644 index 0000000..f4a0624 --- /dev/null +++ b/src/ApplicationInstallations/UseCase/Uninstall/Command.php @@ -0,0 +1,23 @@ +validate(); + } + + private function validate(): void + { + if ('' === $this->applicationToken) { + throw new \InvalidArgumentException('applicationToken must be a non-empty string.'); + } + + } +} \ No newline at end of file diff --git a/src/ApplicationInstallations/UseCase/Uninstall/Handler.php b/src/ApplicationInstallations/UseCase/Uninstall/Handler.php new file mode 100644 index 0000000..c5a9d9c --- /dev/null +++ b/src/ApplicationInstallations/UseCase/Uninstall/Handler.php @@ -0,0 +1,81 @@ +logger->info('ApplicationInstallations.Uninstall.start', [ + 'applicationToken' => $command->applicationToken, + ]); + + /** @var AggregateRootEventsEmitterInterface|ApplicationInstallationInterface $activeApplicationInstallation */ + $activeApplicationInstallation = $this->getActiveApplicationInstallation(); + + if (!empty($activeApplicationInstallation)) { + + //Решили 13 апреля расширить контракт установки и добавить получения токена + $activeApplicationToken = $activeApplicationInstallation->getApplicationToken(); + + $oldBitrix24AccountId = $activeApplicationInstallation->getBitrix24AccountId(); + $oldBitrix24Account = $this->bitrix24AccountRepository->getById($oldBitrix24AccountId); + /** @var AggregateRootEventsEmitterInterface[]|Bitrix24AccountInterface[] $accounts */ + $accounts = $this->bitrix24AccountRepository->findByMemberId($oldBitrix24Account->getMemberId()); + $accountsCount = count($accounts); + foreach ($accounts as $account) { + //Сюда пробрасываем токен полученный выше + $account->applicationUninstalled($activeApplicationToken); + $this->bitrix24AccountRepository->save($account); + } + + $activeApplicationInstallation->applicationUninstalled(); + + $this->flusher->flush(...$accounts); + } + + $this->logger->info( + 'ApplicationInstallations.Uninstall.Finish', + [ + 'applicationInstallationId' => $activeApplicationInstallation->getId(), + 'applicationToken' => $command->applicationToken, + 'bitrix24AccountId' => $activeApplicationInstallation->getBitrix24AccountId(), + 'accountsUninstalledCount' => $accountsCount, + ] + ); + } + + private function getActiveApplicationInstallation(): ApplicationInstallationInterface|null + { + $activeApplicationInstallations = $this->applicationInstallationRepository->findActiveApplicationInstallations(); + + if (count($activeApplicationInstallations) > 1) { + throw new \InvalidArgumentException( + 'multiple application installations with active or new status' + ); + } + + return $activeApplicationInstallations[0] ?? null; + } +} diff --git a/tests/Functional/ApplicationInstallations/UseCase/Install/HandlerTest.php b/tests/Functional/ApplicationInstallations/UseCase/Install/HandlerTest.php index 61c506f..927fc5e 100644 --- a/tests/Functional/ApplicationInstallations/UseCase/Install/HandlerTest.php +++ b/tests/Functional/ApplicationInstallations/UseCase/Install/HandlerTest.php @@ -34,7 +34,7 @@ use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\TestCase; use Psr\Log\NullLogger; -use Bitrix24\SDK\Application\Contracts\ApplicationInstallations\Exceptions\ApplicationInstallationNotFoundException; + use Symfony\Component\EventDispatcher\Debug\TraceableEventDispatcher; use Symfony\Component\EventDispatcher\EventDispatcher; use Symfony\Component\Stopwatch\Stopwatch; diff --git a/tests/Functional/ApplicationInstallations/UseCase/Uninstall/HandlerTest.php b/tests/Functional/ApplicationInstallations/UseCase/Uninstall/HandlerTest.php new file mode 100644 index 0000000..df44fbf --- /dev/null +++ b/tests/Functional/ApplicationInstallations/UseCase/Uninstall/HandlerTest.php @@ -0,0 +1,118 @@ + + * + * For the full copyright and license information, please view the MIT-LICENSE.txt + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace Bitrix24\Lib\Tests\Functional\ApplicationInstallations\UseCase\Uninstall; + + +use Bitrix24\Lib\Bitrix24Accounts; + +use Bitrix24\Lib\Bitrix24Accounts\ValueObjects\Domain; +use Bitrix24\Lib\Services\Flusher; +use Bitrix24\Lib\ApplicationInstallations; +use Bitrix24\Lib\Tests\EntityManagerFactory; + +use Bitrix24\Lib\Tests\Functional\ApplicationInstallations\Builders\ApplicationInstallationBuilder; +use Bitrix24\Lib\Tests\Functional\Bitrix24Accounts\Builders\Bitrix24AccountBuilder; +use Bitrix24\SDK\Application\ApplicationStatus; +use Bitrix24\SDK\Application\Contracts\ApplicationInstallations\Entity\ApplicationInstallationStatus; +use Bitrix24\SDK\Application\Contracts\Bitrix24Accounts\Entity\Bitrix24AccountStatus; +use Bitrix24\SDK\Application\PortalLicenseFamily; +use Bitrix24\SDK\Core\Credentials\Scope; +use Bitrix24\SDK\Core\Exceptions\InvalidArgumentException; + +use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\Attributes\Test; +use PHPUnit\Framework\TestCase; +use Psr\Log\NullLogger; + +use Symfony\Component\EventDispatcher\Debug\TraceableEventDispatcher; +use Symfony\Component\EventDispatcher\EventDispatcher; +use Symfony\Component\Stopwatch\Stopwatch; + +use Bitrix24\Lib\ApplicationInstallations\Infrastructure\Doctrine\ApplicationInstallationRepository; +use Bitrix24\Lib\ApplicationInstallations\UseCase\Uninstall\Handler; + +use Bitrix24\Lib\Bitrix24Accounts\Infrastructure\Doctrine\Bitrix24AccountRepository; +use Symfony\Component\Uid\Uuid; + +/** + * @internal + */ +#[CoversClass(ApplicationInstallations\UseCase\Uninstall\Handler::class)] +class HandlerTest extends TestCase +{ + private Handler $handler; + + private Flusher $flusher; + + private ApplicationInstallationRepository $repository; + + private Bitrix24AccountRepository $bitrix24accountRepository; + + private TraceableEventDispatcher $eventDispatcher; + + #[\Override] + protected function setUp(): void + { + $entityManager = EntityManagerFactory::get(); + $this->eventDispatcher = new TraceableEventDispatcher(new EventDispatcher(), new Stopwatch()); + $this->repository = new ApplicationInstallationRepository($entityManager); + $this->flusher = new Flusher($entityManager, $this->eventDispatcher); + $this->bitrix24accountRepository = new Bitrix24AccountRepository($entityManager); + $this->handler = new Handler( + $this->bitrix24accountRepository, + $this->repository, + $this->flusher, + new NullLogger() + ); + } + + /** + * @throws InvalidArgumentException + */ + #[Test] + public function testUninstallApplicationInstallation(): void + { + //Загружаем в базу данных аккаунт и установку приложения для тестирования переустановки. + $applicationToken = Uuid::v7()->toRfc4122(); + $oldBitrix24Account = (new Bitrix24AccountBuilder()) + ->withApplicationScope(new Scope(['crm'])) + ->withStatus(Bitrix24AccountStatus::new) + ->withApplicationToken($applicationToken) + ->build(); + + + $oldApplicationInstallationBuilder = (new ApplicationInstallationBuilder()) + ->withApplicationStatus(new ApplicationStatus('F')) + ->withPortalLicenseFamily(PortalLicenseFamily::free) + ->withBitrix24AccountId($oldBitrix24Account->getId()) + ->withApplicationStatusInstallation(ApplicationInstallationStatus::active) + ->withApplicationToken($applicationToken) + ->build(); + + $this->bitrix24accountRepository->save($oldBitrix24Account); + $this->repository->save($oldApplicationInstallationBuilder); + $this->flusher->flush(); + + $this->handler->handle( + new ApplicationInstallations\UseCase\Uninstall\Command( + $applicationToken, + ) + ); + + $dispatchedEvents = $this->eventDispatcher->getOrphanedEvents(); + + $this->assertContains(\Bitrix24\SDK\Application\Contracts\Bitrix24Accounts\Events\Bitrix24AccountApplicationUninstalledEvent::class, $dispatchedEvents); + + } +} \ No newline at end of file From 1aef0f8a2efb0af07f5e8213fe4789e4c7b646e7 Mon Sep 17 00:00:00 2001 From: KarlsonComplete Date: Mon, 28 Apr 2025 23:13:49 +0300 Subject: [PATCH 25/49] =?UTF-8?q?=D0=9F=D1=80=D0=B0=D0=B2=D0=BA=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...ons.Entity.ApplicationInstallation.dcm.xml | 2 +- .../Entity/ApplicationInstallation.php | 14 +- .../UseCase/Install/Command.php | 23 ++- .../UseCase/Install/Handler.php | 25 +-- .../UseCase/Reinstall/Command.php | 70 -------- .../UseCase/Reinstall/Handler.php | 128 -------------- .../ApplicationInstallationBuilder.php | 34 ++-- .../UseCase/Install/HandlerTest.php | 2 - .../UseCase/Reinstall/HandlerTest.php | 162 ------------------ 9 files changed, 39 insertions(+), 421 deletions(-) delete mode 100644 src/ApplicationInstallations/UseCase/Reinstall/Command.php delete mode 100644 src/ApplicationInstallations/UseCase/Reinstall/Handler.php delete mode 100644 tests/Functional/ApplicationInstallations/UseCase/Reinstall/HandlerTest.php diff --git a/config/xml/Bitrix24.Lib.ApplicationInstallations.Entity.ApplicationInstallation.dcm.xml b/config/xml/Bitrix24.Lib.ApplicationInstallations.Entity.ApplicationInstallation.dcm.xml index bb793a6..3ba6b71 100644 --- a/config/xml/Bitrix24.Lib.ApplicationInstallations.Entity.ApplicationInstallation.dcm.xml +++ b/config/xml/Bitrix24.Lib.ApplicationInstallations.Entity.ApplicationInstallation.dcm.xml @@ -28,7 +28,7 @@ - + diff --git a/src/ApplicationInstallations/Entity/ApplicationInstallation.php b/src/ApplicationInstallations/Entity/ApplicationInstallation.php index 8fa1407..327cd7c 100644 --- a/src/ApplicationInstallations/Entity/ApplicationInstallation.php +++ b/src/ApplicationInstallations/Entity/ApplicationInstallation.php @@ -22,11 +22,14 @@ class ApplicationInstallation extends AggregateRoot implements ApplicationInstallationInterface { + + private ?string $applicationToken = null; + private CarbonImmutable $createdAt; + private CarbonImmutable $updatedAt; + private ApplicationInstallationStatus $status; + public function __construct( private readonly Uuid $id, - private ApplicationInstallationStatus $status, - private readonly CarbonImmutable $createdAt, - private CarbonImmutable $updatedAt, private readonly Uuid $bitrix24AccountId, private ApplicationStatus $applicationStatus, private PortalLicenseFamily $portalLicenseFamily, @@ -35,10 +38,12 @@ public function __construct( private ?Uuid $bitrix24PartnerContactPersonId, private ?Uuid $bitrix24PartnerId, private ?string $externalId, - private readonly string $applicationToken, private ?string $comment = null, private $isEmitApplicationInstallationCreatedEvent = false ) { + $this->createdAt = new CarbonImmutable(); + $this->updatedAt = new CarbonImmutable(); + $this->status = ApplicationInstallationStatus::new; $this->addApplicationCreatedEventIfNeeded($this->isEmitApplicationInstallationCreatedEvent); } @@ -77,7 +82,6 @@ public function getApplicationToken(): string return $this->applicationToken; } - #[\Override] public function changeContactPerson(?Uuid $uuid): void { diff --git a/src/ApplicationInstallations/UseCase/Install/Command.php b/src/ApplicationInstallations/UseCase/Install/Command.php index ebefa4b..f37ad70 100644 --- a/src/ApplicationInstallations/UseCase/Install/Command.php +++ b/src/ApplicationInstallations/UseCase/Install/Command.php @@ -14,7 +14,6 @@ readonly class Command { public function __construct( - public string $applicationToken, public ApplicationStatus $applicationStatus, public PortalLicenseFamily $portalLicenseFamily, public ?int $portalUsersCount, @@ -34,12 +33,26 @@ public function __construct( $this->validate(); } - private function validate(): void + public function __toString(): string { + return sprintf( + " portalUsersCount: %s, contactPersonId: %s, bitrix24PartnerContactPersonId: %s, + bitrix24PartnerId: %s, externalId: %s, comment: %s, bitrix24UserId: %d, + isBitrix24UserAdmin: %s, memberId: %s", + $this->portalUsersCount ?? 'null', + $this->contactPersonId ?? 'null', + $this->bitrix24PartnerContactPersonId ?? 'null', + $this->bitrix24PartnerId ?? 'null', + $this->externalId ?? 'null', + $this->comment ?? 'null', + $this->bitrix24UserId, + $this->isBitrix24UserAdmin ? 'true' : 'false', + $this->memberId + ); + } - if ('' === $this->applicationToken) { - throw new \InvalidArgumentException('applicationToken must be a non-empty string.'); - } + private function validate(): void + { if ($this->portalUsersCount <= 0) { throw new \InvalidArgumentException('Portal Users count must be a positive integer.'); diff --git a/src/ApplicationInstallations/UseCase/Install/Handler.php b/src/ApplicationInstallations/UseCase/Install/Handler.php index c533294..204c924 100644 --- a/src/ApplicationInstallations/UseCase/Install/Handler.php +++ b/src/ApplicationInstallations/UseCase/Install/Handler.php @@ -10,10 +10,8 @@ use Bitrix24\Lib\Bitrix24Accounts\Infrastructure\Doctrine\Bitrix24AccountRepository; use Bitrix24\Lib\Services\Flusher; use Bitrix24\SDK\Application\Contracts\ApplicationInstallations\Entity\ApplicationInstallationInterface; -use Bitrix24\SDK\Application\Contracts\ApplicationInstallations\Entity\ApplicationInstallationStatus; use Bitrix24\SDK\Application\Contracts\Bitrix24Accounts\Entity\Bitrix24AccountInterface; use Bitrix24\SDK\Application\Contracts\Events\AggregateRootEventsEmitterInterface; -use Carbon\CarbonImmutable; use Psr\Log\LoggerInterface; use Symfony\Component\Uid\Uuid; @@ -31,21 +29,7 @@ public function __construct( public function handle(Command $command): void { $this->logger->info('ApplicationInstallations.InstallStart.start', [ - 'applicationStatus' => $command->applicationStatus, - 'portalLicenseFamily' => $command->portalLicenseFamily, - 'portalUsersCount' => $command->portalUsersCount, - 'contactPersonId' => $command->contactPersonId, - 'bitrix24PartnerContactPersonId' => $command->bitrix24PartnerContactPersonId, - 'bitrix24PartnerId' => $command->bitrix24PartnerId, - 'externalId' => $command->externalId, - 'comment' => $command->comment, - 'bitrix24UserId' => $command->bitrix24UserId, - 'isBitrix24UserAdmin' => $command->isBitrix24UserAdmin, - 'memberId' => $command->memberId, - 'domain' => $command->domain, - 'authToken' => $command->authToken, - 'applicationVersion' => $command->applicationVersion, - 'applicationScope' => $command->applicationScope + (string)$command ]); $accountsCount = 0; @@ -94,9 +78,6 @@ public function handle(Command $command): void $applicationInstallation = new ApplicationInstallation( $applicationInstallationId, - ApplicationInstallationStatus::new, - new CarbonImmutable(), - new CarbonImmutable(), $bitrix24AccountId, $command->applicationStatus, $command->portalLicenseFamily, @@ -105,7 +86,6 @@ public function handle(Command $command): void $command->bitrix24PartnerContactPersonId, $command->bitrix24PartnerId, $command->externalId, - $command->applicationToken, $command->comment, true ); @@ -121,9 +101,6 @@ public function handle(Command $command): void [ 'applicationId' => $applicationInstallationId, 'bitrix24AccountId' => $bitrix24AccountId, - 'applicationToken' => $command->applicationToken, - 'memberId' => $command->memberId, - 'domain' => $command->domain, 'accountsUninstalledCount' => $accountsCount, ] ); diff --git a/src/ApplicationInstallations/UseCase/Reinstall/Command.php b/src/ApplicationInstallations/UseCase/Reinstall/Command.php deleted file mode 100644 index 302c163..0000000 --- a/src/ApplicationInstallations/UseCase/Reinstall/Command.php +++ /dev/null @@ -1,70 +0,0 @@ -validate(); - } - - private function validate(): void - { - if ($this->portalUsersCount <= 0) { - throw new \InvalidArgumentException('Portal Users count must be a positive integer.'); - } - - if ('' === $this->externalId) { - throw new \InvalidArgumentException('External ID must be a non-empty string.'); - } - - if ('' === $this->comment) { - throw new \InvalidArgumentException('Comment must be a non-empty string.'); - } - - if ($this->bitrix24UserId <= 0) { - throw new \InvalidArgumentException('Bitrix24 User ID must be a positive integer.'); - } - - if ('' === $this->memberId) { - throw new \InvalidArgumentException('Member ID must be a non-empty string.'); - } - - if ($this->applicationVersion <= 0) { - throw new \InvalidArgumentException('Application version must be a positive integer.'); - } - } -} diff --git a/src/ApplicationInstallations/UseCase/Reinstall/Handler.php b/src/ApplicationInstallations/UseCase/Reinstall/Handler.php deleted file mode 100644 index d82120b..0000000 --- a/src/ApplicationInstallations/UseCase/Reinstall/Handler.php +++ /dev/null @@ -1,128 +0,0 @@ -logger->info('ApplicationInstallations.InstallStart.start', [ - 'id' => $command->uuid->toRfc4122(), - ]); - - /** @var AggregateRootEventsEmitterInterface|ApplicationInstallationInterface $activeApplicationInstallation */ - $activeApplicationInstallation = $this->getActiveApplicationInstallation(); - - /* - В документации написано, что нужно деактивировать аккаунтЫ связанные с приложением. Но у нас связь у приложения идет только с 1 аккаунтом. - Отсюда вопрос у нас аккаунт у приложения один ? Или если несколько то как их получить ? - */ - - // Еще вопрос написано деактивация приложения и аккаунтов связанных с приложением это soft delete ? - - if (!empty($activeApplicationInstallation)) { - $bitrix24AccountId = $activeApplicationInstallation->getBitrix24AccountId(); - $oldBitrix24Account = $this->bitrix24AccountRepository->getById($bitrix24AccountId); - $activeApplicationInstallation->applicationUninstalled(); - $this->applicationInstallationRepository->save($activeApplicationInstallation); - $this->flusher->flush($activeApplicationInstallation); - $oldBitrix24Account->applicationUninstalled($command->applicationToken); - $this->bitrix24AccountRepository->save($oldBitrix24Account); - $this->flusher->flush($oldBitrix24Account); - } - - // Тут возникает вопрос. Для деинсталяции(если деактивация означает это) нам нужно токен прокидывать в команду, мне кажется бредово. - // Так как мы ходим запустить хендлер с параметрами нового приложения и чтобы там под капотом все что нужно деактивировалось, а что нужно установилось. - // Может добавить метод получения токена ? Или он уже должен быть и мы просто проморгали ? - - // Ниже пока что можно не смотреть - $bitrix24Account = new Bitrix24Account( - $command->bitrix24AccountUuid, - $command->bitrix24UserId, - $command->isBitrix24UserAdmin, - $command->memberId, - $command->domain->value, - $command->bitrix24AccountStatus, - $command->authToken, - new CarbonImmutable(), - new CarbonImmutable(), - $command->applicationVersion, - $command->applicationScope, - true - ); - - $this->bitrix24AccountRepository->save($bitrix24Account); - $this->flusher->flush($bitrix24Account); - - $applicationToken = Uuid::v7()->toRfc4122(); - $bitrix24Account->applicationInstalled($applicationToken); - $this->bitrix24AccountRepository->save($bitrix24Account); - $this->flusher->flush($bitrix24Account); - - $applicationInstallation = new ApplicationInstallation( - $command->uuid, - $command->applicationInstallationStatus, - new CarbonImmutable(), - new CarbonImmutable(), - $command->bitrix24AccountId, - $command->applicationStatus, - $command->portalLicenseFamily, - $command->portalUsersCount, - $command->contactPersonId, - $command->bitrix24PartnerContactPersonId, - $command->bitrix24PartnerId, - $command->externalId, - $command->comment, - true - ); - - $this->applicationInstallationRepository->save($applicationInstallation); - $this->flusher->flush($applicationInstallation); - - $applicationInstallation->applicationInstalled(); - - $this->applicationInstallationRepository->save($applicationInstallation); - $this->flusher->flush($applicationInstallation); - - $this->logger->info( - 'Bitrix24Accounts.InstallStart.Finish', - [ - 'id' => $command->uuid->toRfc4122(), - ] - ); - } - - private function getActiveApplicationInstallation(): ApplicationInstallationInterface - { - $activeApplicationInstallations = $this->applicationInstallationRepository->findActiveApplicationInstallations(); - - if (!([] === $activeApplicationInstallations) && count($activeApplicationInstallations) > 1) { - // Тут может добавить исключение для приложения ? По подобию MultipleBitrix24AccountsFoundException - throw new \InvalidArgumentException( - 'multiple application installations with active or new status' - ); - } - - return $activeApplicationInstallations[0]; - } -} diff --git a/tests/Functional/ApplicationInstallations/Builders/ApplicationInstallationBuilder.php b/tests/Functional/ApplicationInstallations/Builders/ApplicationInstallationBuilder.php index 79346a0..63d6a05 100644 --- a/tests/Functional/ApplicationInstallations/Builders/ApplicationInstallationBuilder.php +++ b/tests/Functional/ApplicationInstallations/Builders/ApplicationInstallationBuilder.php @@ -15,10 +15,6 @@ class ApplicationInstallationBuilder { private readonly Uuid $id; - private readonly CarbonImmutable $createdAt; - - private readonly CarbonImmutable $updatedAt; - private Uuid $bitrix24AccountId; private readonly ?Uuid $contactPersonId; @@ -29,7 +25,7 @@ class ApplicationInstallationBuilder private ?string $externalId = null; - private ApplicationInstallationStatus $status = ApplicationInstallationStatus::active; + private ApplicationInstallationStatus $status; private ApplicationStatus $applicationStatus; @@ -39,21 +35,14 @@ class ApplicationInstallationBuilder private ?string $comment = null; - private string $applicationToken; - - public function __construct() { $this->id = Uuid::v7(); - $this->createdAt = CarbonImmutable::now(); - $this->updatedAt = CarbonImmutable::now(); $this->bitrix24AccountId = Uuid::v7(); $this->bitrix24PartnerContactPersonId = Uuid::v7(); $this->contactPersonId = Uuid::v7(); $this->bitrix24PartnerId = Uuid::v7(); $this->portalUsersCount = random_int(1, 1_000_000); - //Токен который будет прилетать при событии установки в битриксе - $this->applicationToken = Uuid::v7()->toRfc4122(); } public function withExternalId(string $externalId): self @@ -77,13 +66,6 @@ public function withApplicationStatus(ApplicationStatus $applicationStatus): sel return $this; } - public function withApplicationToken(string $applicationToken): self - { - $this->applicationToken = $applicationToken; - - return $this; - } - public function withBitrix24AccountId(Uuid $uuid): self { $this->bitrix24AccountId = $uuid; @@ -100,11 +82,8 @@ public function withPortalLicenseFamily(PortalLicenseFamily $portalLicenseFamily public function build(): ApplicationInstallation { - return new ApplicationInstallation( + $applicationInstallation = new ApplicationInstallation( $this->id, - $this->status, - $this->createdAt, - $this->updatedAt, $this->bitrix24AccountId, $this->applicationStatus, $this->portalLicenseFamily, @@ -113,9 +92,16 @@ public function build(): ApplicationInstallation $this->bitrix24PartnerContactPersonId, $this->bitrix24PartnerId, $this->externalId, - $this->applicationToken, $this->comment ); + + if (!empty($this->status)) { + if ($this->status == ApplicationInstallationStatus::active) { + $applicationInstallation->applicationInstalled(); + } + } + + return $applicationInstallation; } diff --git a/tests/Functional/ApplicationInstallations/UseCase/Install/HandlerTest.php b/tests/Functional/ApplicationInstallations/UseCase/Install/HandlerTest.php index 927fc5e..0a66874 100644 --- a/tests/Functional/ApplicationInstallations/UseCase/Install/HandlerTest.php +++ b/tests/Functional/ApplicationInstallations/UseCase/Install/HandlerTest.php @@ -144,7 +144,6 @@ public function testReinstallApplicationInstallation(): void ->withPortalLicenseFamily(PortalLicenseFamily::free) ->withBitrix24AccountId($oldBitrix24Account->getId()) ->withApplicationStatusInstallation(ApplicationInstallationStatus::active) - ->withApplicationToken($applicationToken) ->build(); $this->bitrix24accountRepository->save($oldBitrix24Account); @@ -162,7 +161,6 @@ public function testReinstallApplicationInstallation(): void $this->handler->handle( new ApplicationInstallations\UseCase\Install\Command( - $applicationInstallationBuilder->getApplicationToken(), $applicationInstallationBuilder->getApplicationStatus(), $applicationInstallationBuilder->getPortalLicenseFamily(), $applicationInstallationBuilder->getPortalUsersCount(), diff --git a/tests/Functional/ApplicationInstallations/UseCase/Reinstall/HandlerTest.php b/tests/Functional/ApplicationInstallations/UseCase/Reinstall/HandlerTest.php deleted file mode 100644 index 272cb7d..0000000 --- a/tests/Functional/ApplicationInstallations/UseCase/Reinstall/HandlerTest.php +++ /dev/null @@ -1,162 +0,0 @@ - - * - * For the full copyright and license information, please view the MIT-LICENSE.txt - * file that was distributed with this source code. - */ - -declare(strict_types=1); - -namespace Bitrix24\Lib\Tests\Functional\ApplicationInstallations\UseCase\Reinstall; - - -use Bitrix24\Lib\Bitrix24Accounts; - -use Bitrix24\Lib\Bitrix24Accounts\ValueObjects\Domain; -use Bitrix24\Lib\Services\Flusher; -use Bitrix24\Lib\ApplicationInstallations; -use Bitrix24\Lib\Tests\EntityManagerFactory; - -use Bitrix24\Lib\Tests\Functional\ApplicationInstallations\Builders\ApplicationInstallationBuilder; -use Bitrix24\Lib\Tests\Functional\Bitrix24Accounts\Builders\Bitrix24AccountBuilder; -use Bitrix24\SDK\Application\ApplicationStatus; -use Bitrix24\SDK\Application\Contracts\ApplicationInstallations\Entity\ApplicationInstallationStatus; -use Bitrix24\SDK\Application\Contracts\Bitrix24Accounts\Entity\Bitrix24AccountStatus; -use Bitrix24\SDK\Application\PortalLicenseFamily; -use Bitrix24\SDK\Core\Credentials\Scope; -use Bitrix24\SDK\Core\Exceptions\InvalidArgumentException; - -use PHPUnit\Framework\Attributes\CoversClass; -use PHPUnit\Framework\Attributes\Test; -use PHPUnit\Framework\TestCase; -use Psr\Log\NullLogger; -use Bitrix24\SDK\Application\Contracts\ApplicationInstallations\Exceptions\ApplicationInstallationNotFoundException; -use Symfony\Component\EventDispatcher\Debug\TraceableEventDispatcher; -use Symfony\Component\EventDispatcher\EventDispatcher; -use Symfony\Component\Stopwatch\Stopwatch; - -use Bitrix24\Lib\ApplicationInstallations\Infrastructure\Doctrine\ApplicationInstallationRepository; -use Bitrix24\Lib\ApplicationInstallations\UseCase\Reinstall\Handler; - -use Bitrix24\Lib\Bitrix24Accounts\Infrastructure\Doctrine\Bitrix24AccountRepository; -use Symfony\Component\Uid\Uuid; - -/** - * @internal - */ -#[CoversClass(ApplicationInstallations\UseCase\Reinstall\Handler::class)] -class HandlerTest extends TestCase -{ - private Handler $handler; - - private Flusher $flusher; - - private ApplicationInstallationRepository $repository; - - private Bitrix24AccountRepository $bitrix24accountRepository; - - private TraceableEventDispatcher $eventDispatcher; - - #[\Override] - protected function setUp(): void - { - $entityManager = EntityManagerFactory::get(); - $this->eventDispatcher = new TraceableEventDispatcher(new EventDispatcher(), new Stopwatch()); - $this->repository = new ApplicationInstallationRepository($entityManager); - $this->flusher = new Flusher($entityManager, $this->eventDispatcher); - $this->bitrix24accountRepository = new Bitrix24AccountRepository($entityManager); - $this->handler = new Handler( - $this->bitrix24accountRepository, - $this->repository, - $this->flusher, - new NullLogger() - ); - - } - - /** - * @throws InvalidArgumentException - * @throws ApplicationInstallationNotFoundException - */ - #[Test] - public function testReinstallApplicationInstallation(): void - { - - $applicationToken = Uuid::v7()->toRfc4122(); - $bitrix24Account = (new Bitrix24AccountBuilder()) - ->withApplicationScope(new Scope(['crm'])) - ->withStatus(Bitrix24AccountStatus::new) - ->withApplicationToken($applicationToken) - ->build(); - - $this->bitrix24accountRepository->save($bitrix24Account); - $this->flusher->flush(); - - $oldApplicationInstallationBuilder = (new ApplicationInstallationBuilder()) - ->withApplicationStatus(new ApplicationStatus('F')) - ->withPortalLicenseFamily(PortalLicenseFamily::free) - ->withBitrix24AccountId($bitrix24Account->getId()) - ->withApplicationStatusInstallation(ApplicationInstallationStatus::active) - ->build(); - - $this->repository->save($oldApplicationInstallationBuilder); - $this->flusher->flush(); - - $bitrix24AccountBuilder = (new Bitrix24AccountBuilder()) - ->withApplicationScope(new Scope(['crm'])) - ->withStatus(Bitrix24AccountStatus::new) - ->build(); - - $applicationInstallationBuilder = (new ApplicationInstallationBuilder()) - ->withApplicationStatus(new ApplicationStatus('F')) - ->withPortalLicenseFamily(PortalLicenseFamily::free) - ->withBitrix24AccountId($bitrix24Account->getId()) - ->withApplicationStatusInstallation(ApplicationInstallationStatus::new) - ->build(); - - - $this->handler->handle( - new ApplicationInstallations\UseCase\Reinstall\Command( - $applicationInstallationBuilder->getId(), - $applicationInstallationBuilder->getStatus(), - $applicationInstallationBuilder->getBitrix24AccountId(), - $applicationInstallationBuilder->getApplicationStatus(), - $applicationInstallationBuilder->getPortalLicenseFamily(), - $applicationInstallationBuilder->getPortalUsersCount(), - $applicationInstallationBuilder->getContactPersonId(), - $applicationInstallationBuilder->getBitrix24PartnerContactPersonId(), - $applicationInstallationBuilder->getBitrix24PartnerId(), - $applicationInstallationBuilder->getExternalId(), - $applicationInstallationBuilder->getComment(), - $bitrix24AccountBuilder->getId(), - $bitrix24AccountBuilder->getStatus(), - $bitrix24AccountBuilder->getBitrix24UserId(), - $bitrix24AccountBuilder->isBitrix24UserAdmin(), - $bitrix24AccountBuilder->getMemberId(), - new Domain($bitrix24AccountBuilder->getDomainUrl()), - $bitrix24AccountBuilder->getAuthToken(), - $bitrix24AccountBuilder->getApplicationVersion(), - $bitrix24AccountBuilder->getApplicationScope(), - $applicationToken - ) - ); - - $applicationInstallation = $this->repository->getById($applicationInstallationBuilder->getId()); - - $dispatchedEvents = $this->eventDispatcher->getOrphanedEvents(); - var_dump($dispatchedEvents); - $this->assertContains(\Bitrix24\SDK\Application\Contracts\Bitrix24Accounts\Events\Bitrix24AccountCreatedEvent::class, $dispatchedEvents); - $this->assertContains(\Bitrix24\SDK\Application\Contracts\Bitrix24Accounts\Events\Bitrix24AccountApplicationInstalledEvent::class, $dispatchedEvents); - $this->assertContains(\Bitrix24\SDK\Application\Contracts\Bitrix24Accounts\Events\Bitrix24AccountApplicationUninstalledEvent::class, $dispatchedEvents); - - $this->assertContains(\Bitrix24\SDK\Application\Contracts\ApplicationInstallations\Events\ApplicationInstallationCreatedEvent::class, $dispatchedEvents); - $this->assertContains(\Bitrix24\SDK\Application\Contracts\ApplicationInstallations\Events\ApplicationInstallationFinishedEvent::class, $dispatchedEvents); - $this->assertContains(\Bitrix24\SDK\Application\Contracts\ApplicationInstallations\Events\ApplicationInstallationUninstalledEvent::class, $dispatchedEvents); - $this->assertEquals(ApplicationInstallationStatus::active, $applicationInstallation->getStatus()); - $this->assertEquals($applicationInstallationBuilder->getBitrix24AccountId(), $applicationInstallation->getBitrix24AccountId()); - } -} From 1782b40b53d6a4a4b51f8ee3536d822f15647167 Mon Sep 17 00:00:00 2001 From: KarlsonComplete Date: Sun, 4 May 2025 10:01:54 +0300 Subject: [PATCH 26/49] =?UTF-8?q?-=D0=A3=D1=88=D0=BB=D0=B8=20=D0=B2=20?= =?UTF-8?q?=D0=B0=D0=BA=D0=BA=D0=B0=D1=83=D0=BD=D1=82=D0=B5=20=D0=BE=D1=82?= =?UTF-8?q?=20applicationToken=20=D0=B2=20=D0=BC=D0=B5=D1=82=D0=BE=D0=B4?= =?UTF-8?q?=D0=B0=D1=85=20installed/uninstalled=20-=20=D0=94=D0=BE=D0=B1?= =?UTF-8?q?=D0=B0=D0=B2=D0=B8=D0=BB=D0=B8=20setToken=20-=20=D0=9F=D0=BE?= =?UTF-8?q?=D0=BF=D1=80=D0=B0=D0=B2=D0=B8=D0=BB=D0=B8=20=D1=82=D0=B5=D1=81?= =?UTF-8?q?=D1=82=20=D1=83=D1=81=D1=82=D0=B0=D0=BD=D0=BE=D0=B2=D0=BA=D0=B8?= =?UTF-8?q?=20=D0=BF=D1=80=D0=B8=D0=BB=D0=BE=D0=B6=D0=B5=D0=BD=D0=B8=D1=8F?= =?UTF-8?q?=20-=20=D0=9F=D0=BE=D0=BF=D1=80=D0=B0=D0=B2=D0=B8=D0=BB=D0=B8?= =?UTF-8?q?=20=D0=BE=D0=B1=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D1=87=D0=B8=D0=BA?= =?UTF-8?q?=D0=B8=20=D0=BF=D0=BE=D1=81=D0=BB=D0=B5=20=D0=BF=D1=80=D0=B0?= =?UTF-8?q?=D0=B2=D0=BE=D0=BA=20=D0=BC=D0=B5=D1=82=D0=BE=D0=B4=D0=BE=D0=B2?= =?UTF-8?q?=20=D0=B2=20=D0=B0=D0=BA=D0=BA=D0=B0=D1=83=D0=BD=D1=82=D0=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ApplicationInstallationRepository.php | 27 +++++++- .../UseCase/Install/Handler.php | 61 +++++++------------ .../Entity/Bitrix24Account.php | 26 ++++---- .../Doctrine/Bitrix24AccountRepository.php | 24 ++++++++ .../UseCase/InstallFinish/Handler.php | 5 +- .../UseCase/Uninstall/Handler.php | 2 +- .../UseCase/Install/HandlerTest.php | 16 +++-- .../UseCase/Uninstall/HandlerTest.php | 1 - .../Builders/Bitrix24AccountBuilder.php | 3 +- .../UseCase/InstallFinish/HandlerTest.php | 8 --- 10 files changed, 100 insertions(+), 73 deletions(-) diff --git a/src/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationRepository.php b/src/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationRepository.php index ae95e03..42b0621 100644 --- a/src/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationRepository.php +++ b/src/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationRepository.php @@ -75,12 +75,14 @@ public function findByBitrix24AccountId(Uuid $uuid): array ; } - public function findActiveApplicationInstallations(): array + public function findActiveApplicationInstallations(string $memberId): array { return $this->getEntityManager()->getRepository(ApplicationInstallation::class) ->createQueryBuilder('appInstallation') ->where('appInstallation.status IN (:statuses)') + ->andWhere('appInstallation.memberId = :memberId') ->setParameter('statuses', [ApplicationInstallationStatus::active, ApplicationInstallationStatus::new]) + ->setParameter('memberId', $memberId) ->getQuery() ->getResult() ; @@ -101,4 +103,27 @@ public function findByExternalId(string $externalId): array ->getResult() ; } + + public function findActiveByAccountIds(array $accountIds): array + { + if (empty($accountIds)) { + return []; + } + + $activeStatuses = [ + ApplicationInstallationStatus::new, + ApplicationInstallationStatus::active, + ]; + + $installations = $this->getEntityManager()->getRepository(ApplicationInstallation::class) + ->createQueryBuilder('applicationInstallation') + ->where('applicationInstallation.bitrix24AccountId IN (:accountIds)') + ->andWhere('applicationInstallation.status IN (:statuses)') + ->setParameter('accountIds', $accountIds) + ->setParameter('statuses', $activeStatuses) + ->getQuery() + ->getResult(); + + return $installations; + } } diff --git a/src/ApplicationInstallations/UseCase/Install/Handler.php b/src/ApplicationInstallations/UseCase/Install/Handler.php index 204c924..f10e9bd 100644 --- a/src/ApplicationInstallations/UseCase/Install/Handler.php +++ b/src/ApplicationInstallations/UseCase/Install/Handler.php @@ -9,9 +9,6 @@ use Bitrix24\Lib\Bitrix24Accounts\Entity\Bitrix24Account; use Bitrix24\Lib\Bitrix24Accounts\Infrastructure\Doctrine\Bitrix24AccountRepository; use Bitrix24\Lib\Services\Flusher; -use Bitrix24\SDK\Application\Contracts\ApplicationInstallations\Entity\ApplicationInstallationInterface; -use Bitrix24\SDK\Application\Contracts\Bitrix24Accounts\Entity\Bitrix24AccountInterface; -use Bitrix24\SDK\Application\Contracts\Events\AggregateRootEventsEmitterInterface; use Psr\Log\LoggerInterface; use Symfony\Component\Uid\Uuid; @@ -28,34 +25,33 @@ public function __construct( public function handle(Command $command): void { - $this->logger->info('ApplicationInstallations.InstallStart.start', [ + $this->logger->info('ApplicationInstallations.Install.start', [ (string)$command ]); - $accountsCount = 0; - - /** @var AggregateRootEventsEmitterInterface|ApplicationInstallationInterface $activeApplicationInstallation */ - $activeApplicationInstallation = $this->getActiveApplicationInstallation(); - - if (!empty($activeApplicationInstallation)) { - - //Решили 13 апреля расширить контракт установки и добавить получения токена - $activeApplicationToken = $activeApplicationInstallation->getApplicationToken(); + //Проверяем есть ли активные аккаунты если есть значит деактивируем аккаунты и установщики + // 1. Получаем все аккаунты с этим memberId + $accounts = $this->bitrix24AccountRepository->findActiveByMemberId($command->memberId); + if (!empty($accounts)) { + $accountIds = array_map(fn($acc) => $acc->getId(), $accounts); + // 2. Получаем все активные установки для этих аккаунтов + $activeInstallations = $this->applicationInstallationRepository->findActiveByAccountIds($accountIds); + + // 3. Деактивируем все активные установки и связанные аккаунты + foreach ($activeInstallations as $installation) { + $installation->applicationUninstalled(); + $this->applicationInstallationRepository->save($installation); + } - $oldBitrix24AccountId = $activeApplicationInstallation->getBitrix24AccountId(); - $oldBitrix24Account = $this->bitrix24AccountRepository->getById($oldBitrix24AccountId); - /** @var AggregateRootEventsEmitterInterface[]|Bitrix24AccountInterface[] $accounts */ - $accounts = $this->bitrix24AccountRepository->findByMemberId($oldBitrix24Account->getMemberId()); - $accountsCount = count($accounts); foreach ($accounts as $account) { - //Сюда пробрасываем токен полученный выше - $account->applicationUninstalled($activeApplicationToken); + //Нужна правка в контракте ушли от обязательного параметра токена!!! + $account->applicationUninstalled(); $this->bitrix24AccountRepository->save($account); } - $activeApplicationInstallation->applicationUninstalled(); - - $this->flusher->flush(...$accounts); + // Здесь сразу флашим так как это условие не всегда работает , и лучше сначало разобраться с аккаунтами и установщиками + // которые нужно деактивировать , а после уже работаем с новыми сущностями. + $this->flusher->flush(...$activeInstallations, ...$accounts); } $bitrix24AccountId = Uuid::v7(); @@ -74,7 +70,7 @@ public function handle(Command $command): void ); - $bitrix24Account->applicationInstalled($command->applicationToken); + $bitrix24Account->applicationInstalled(); $applicationInstallation = new ApplicationInstallation( $applicationInstallationId, @@ -97,24 +93,11 @@ public function handle(Command $command): void $this->flusher->flush($applicationInstallation,$bitrix24Account); $this->logger->info( - 'ApplicationInstallations.InstallStart.Finish', + 'ApplicationInstallations.Install.Finish', [ 'applicationId' => $applicationInstallationId, - 'bitrix24AccountId' => $bitrix24AccountId, - 'accountsUninstalledCount' => $accountsCount, + 'bitrix24AccountId' => $bitrix24AccountId ] ); } - private function getActiveApplicationInstallation(): ApplicationInstallationInterface|null - { - $activeApplicationInstallations = $this->applicationInstallationRepository->findActiveApplicationInstallations(); - - if (count($activeApplicationInstallations) > 1) { - throw new \InvalidArgumentException( - 'multiple application installations with active or new status' - ); - } - - return $activeApplicationInstallations[0] ?? null; - } } diff --git a/src/Bitrix24Accounts/Entity/Bitrix24Account.php b/src/Bitrix24Accounts/Entity/Bitrix24Account.php index b809066..c623d30 100644 --- a/src/Bitrix24Accounts/Entity/Bitrix24Account.php +++ b/src/Bitrix24Accounts/Entity/Bitrix24Account.php @@ -176,7 +176,7 @@ public function changeDomainUrl(string $newDomainUrl): void * @throws InvalidArgumentException */ #[\Override] - public function applicationInstalled(string $applicationToken): void + public function applicationInstalled(): void { if (Bitrix24AccountStatus::new !== $this->status) { throw new InvalidArgumentException( @@ -187,12 +187,7 @@ public function applicationInstalled(string $applicationToken): void ); } - if ('' === $applicationToken) { - throw new InvalidArgumentException('application token cannot be empty'); - } - $this->status = Bitrix24AccountStatus::active; - $this->applicationToken = $applicationToken; $this->updatedAt = new CarbonImmutable(); $this->events[] = new Bitrix24AccountApplicationInstalledEvent( $this->id, @@ -200,15 +195,10 @@ public function applicationInstalled(string $applicationToken): void ); } - /** - * @throws InvalidArgumentException - */ + #[\Override] - public function applicationUninstalled(string $applicationToken): void + public function applicationUninstalled(): void { - $this->guardEmptyToken($applicationToken); - $this->guardTokenMismatch($applicationToken); - $this->guardApplicationIsActive(); $this->status = Bitrix24AccountStatus::deleted; $this->updatedAt = new CarbonImmutable(); $this->events[] = new Bitrix24AccountApplicationUninstalledEvent( @@ -359,4 +349,14 @@ private function addAccountCreatedEventIfNeeded(bool $isEmitCreatedEvent): void ); } } + + public function setToken(string $applicationToken): void + { + if ('' === $applicationToken) { + throw new InvalidArgumentException('application token cannot be empty'); + } + + $this->updatedAt = new CarbonImmutable(); + $this->applicationToken = $applicationToken; + } } diff --git a/src/Bitrix24Accounts/Infrastructure/Doctrine/Bitrix24AccountRepository.php b/src/Bitrix24Accounts/Infrastructure/Doctrine/Bitrix24AccountRepository.php index 5fb37ad..996281d 100644 --- a/src/Bitrix24Accounts/Infrastructure/Doctrine/Bitrix24AccountRepository.php +++ b/src/Bitrix24Accounts/Infrastructure/Doctrine/Bitrix24AccountRepository.php @@ -105,6 +105,30 @@ public function findByMemberId( return $this->findBy($criteria); } + public function findActiveByMemberId(string $memberId): array + { + if ('' === trim($memberId)) { + throw new InvalidArgumentException('memberId cannot be empty'); + } + + $activeStatuses = [ + Bitrix24AccountStatus::new, + Bitrix24AccountStatus::active, + ]; + + $accounts = $this->getEntityManager()->getRepository(Bitrix24Account::class) + ->createQueryBuilder('b24') + ->where('b24.memberId = :memberId') + ->andWhere('b24.status IN (:statuses)') + ->setParameter('memberId', $memberId) + ->setParameter('statuses', $activeStatuses) + ->getQuery() + ->getResult() + ; + + return $accounts; + } + #[\Override] public function delete(Uuid $uuid): void { diff --git a/src/Bitrix24Accounts/UseCase/InstallFinish/Handler.php b/src/Bitrix24Accounts/UseCase/InstallFinish/Handler.php index e5b805d..826f3d2 100644 --- a/src/Bitrix24Accounts/UseCase/InstallFinish/Handler.php +++ b/src/Bitrix24Accounts/UseCase/InstallFinish/Handler.php @@ -39,7 +39,7 @@ public function handle(Command $command): void /** @var AggregateRootEventsEmitterInterface|Bitrix24AccountInterface $bitrix24Account */ $bitrix24Account = $this->getSingleAccountByMemberId($command->domain->value, $command->memberId, $command->bitrix24UserId); - $bitrix24Account->applicationInstalled($command->applicationToken); + $bitrix24Account->applicationInstalled(); $this->bitrix24AccountRepository->save($bitrix24Account); $this->flusher->flush($bitrix24Account); @@ -49,8 +49,7 @@ public function handle(Command $command): void [ 'b24_domain_url' => $command->domain, 'b24_member_id' => $command->memberId, - 'b24_application_id' => $command->applicationToken, - 'b24_user_id' => $command->bitrix24UserId, + 'b24_user_id' => $command->bitrix24UserId ] ); } diff --git a/src/Bitrix24Accounts/UseCase/Uninstall/Handler.php b/src/Bitrix24Accounts/UseCase/Uninstall/Handler.php index 516126b..9c672de 100644 --- a/src/Bitrix24Accounts/UseCase/Uninstall/Handler.php +++ b/src/Bitrix24Accounts/UseCase/Uninstall/Handler.php @@ -32,7 +32,7 @@ public function handle(Command $command): void $accounts = $this->bitrix24AccountRepository->findByApplicationToken($command->applicationToken); $accountsCount = count($accounts); foreach ($accounts as $account) { - $account->applicationUninstalled($command->applicationToken); + $account->applicationUninstalled(); $this->bitrix24AccountRepository->save($account); } diff --git a/tests/Functional/ApplicationInstallations/UseCase/Install/HandlerTest.php b/tests/Functional/ApplicationInstallations/UseCase/Install/HandlerTest.php index 0a66874..fa7112b 100644 --- a/tests/Functional/ApplicationInstallations/UseCase/Install/HandlerTest.php +++ b/tests/Functional/ApplicationInstallations/UseCase/Install/HandlerTest.php @@ -97,7 +97,6 @@ public function testInstallNewApplicationInstallation(): void $this->handler->handle( new ApplicationInstallations\UseCase\Install\Command( - $applicationInstallationBuilder->getApplicationToken(), $applicationInstallationBuilder->getApplicationStatus(), $applicationInstallationBuilder->getPortalLicenseFamily(), $applicationInstallationBuilder->getPortalUsersCount(), @@ -130,28 +129,33 @@ public function testInstallNewApplicationInstallation(): void #[Test] public function testReinstallApplicationInstallation(): void { + + $memberId = Uuid::v4()->toRfc4122(); + //Загружаем в базу данных аккаунт и установку приложения для тестирования переустановки. $applicationToken = Uuid::v7()->toRfc4122(); - $oldBitrix24Account = (new Bitrix24AccountBuilder()) + $currentBitrix24Account = (new Bitrix24AccountBuilder()) ->withApplicationScope(new Scope(['crm'])) ->withStatus(Bitrix24AccountStatus::new) ->withApplicationToken($applicationToken) + ->withMemberId($memberId) ->build(); - $oldApplicationInstallationBuilder = (new ApplicationInstallationBuilder()) + $currentApplicationInstallationBuilder = (new ApplicationInstallationBuilder()) ->withApplicationStatus(new ApplicationStatus('F')) ->withPortalLicenseFamily(PortalLicenseFamily::free) - ->withBitrix24AccountId($oldBitrix24Account->getId()) + ->withBitrix24AccountId($currentBitrix24Account->getId()) ->withApplicationStatusInstallation(ApplicationInstallationStatus::active) ->build(); - $this->bitrix24accountRepository->save($oldBitrix24Account); - $this->repository->save($oldApplicationInstallationBuilder); + $this->bitrix24accountRepository->save($currentBitrix24Account); + $this->repository->save($currentApplicationInstallationBuilder); $this->flusher->flush(); $bitrix24AccountBuilder = (new Bitrix24AccountBuilder()) ->withApplicationScope(new Scope(['crm'])) + ->withMemberId($memberId) ->build(); $applicationInstallationBuilder = (new ApplicationInstallationBuilder()) diff --git a/tests/Functional/ApplicationInstallations/UseCase/Uninstall/HandlerTest.php b/tests/Functional/ApplicationInstallations/UseCase/Uninstall/HandlerTest.php index df44fbf..3d14ebf 100644 --- a/tests/Functional/ApplicationInstallations/UseCase/Uninstall/HandlerTest.php +++ b/tests/Functional/ApplicationInstallations/UseCase/Uninstall/HandlerTest.php @@ -97,7 +97,6 @@ public function testUninstallApplicationInstallation(): void ->withPortalLicenseFamily(PortalLicenseFamily::free) ->withBitrix24AccountId($oldBitrix24Account->getId()) ->withApplicationStatusInstallation(ApplicationInstallationStatus::active) - ->withApplicationToken($applicationToken) ->build(); $this->bitrix24accountRepository->save($oldBitrix24Account); diff --git a/tests/Functional/Bitrix24Accounts/Builders/Bitrix24AccountBuilder.php b/tests/Functional/Bitrix24Accounts/Builders/Bitrix24AccountBuilder.php index aa2ba95..6e6efb8 100644 --- a/tests/Functional/Bitrix24Accounts/Builders/Bitrix24AccountBuilder.php +++ b/tests/Functional/Bitrix24Accounts/Builders/Bitrix24AccountBuilder.php @@ -104,7 +104,8 @@ public function build(): Bitrix24Account ); if ($this->applicationToken !== null && Bitrix24AccountStatus::new == $this->status) { - $bitrix24Account->applicationInstalled($this->applicationToken); + $bitrix24Account->applicationInstalled(); + $bitrix24Account->setToken($this->applicationToken); } return $bitrix24Account; diff --git a/tests/Functional/Bitrix24Accounts/UseCase/InstallFinish/HandlerTest.php b/tests/Functional/Bitrix24Accounts/UseCase/InstallFinish/HandlerTest.php index f0d1ac0..5d84d7e 100644 --- a/tests/Functional/Bitrix24Accounts/UseCase/InstallFinish/HandlerTest.php +++ b/tests/Functional/Bitrix24Accounts/UseCase/InstallFinish/HandlerTest.php @@ -86,14 +86,6 @@ public function testFinishInstallationApplication(): void $updated = $this->repository->getById($bitrix24Account->getId()); $this->assertEquals(Bitrix24AccountStatus::active, $updated->getStatus(), 'expected status is active'); - $this->assertTrue( - $updated->isApplicationTokenValid($applicationToken), - sprintf( - 'failed application token «%s» validation for bitrix24 account with id «%s»', - $applicationToken, - $bitrix24Account->getId()->toString() - ) - ); $this->assertTrue( in_array(Bitrix24AccountApplicationInstalledEvent::class, $this->eventDispatcher->getOrphanedEvents(), true), sprintf( From 0f6d191dc98b21f5c06683c322d66b6a8a278691 Mon Sep 17 00:00:00 2001 From: KarlsonComplete Date: Sun, 4 May 2025 11:44:00 +0300 Subject: [PATCH 27/49] =?UTF-8?q?-=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8?= =?UTF-8?q?=D0=BB=D0=B8=20=D0=BE=D0=B1=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=BA?= =?UTF-8?q?=D1=83=20=D1=81=D0=BE=D0=B1=D1=8B=D1=82=D0=B8=D1=8F=20OnAppInst?= =?UTF-8?q?all=20-=D0=9D=D0=B0=D0=BF=D0=B8=D1=81=D0=B0=D0=BB=D0=B8=20?= =?UTF-8?q?=D1=82=D0=B5=D1=81=D1=82=20=D0=BA=20=D1=81=D0=BE=D0=B1=D1=8B?= =?UTF-8?q?=D1=82=D0=B8=D1=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../UseCase/Install/Handler.php | 4 + .../UseCase/OnAppInstall/Command.php | 35 +++++ .../UseCase/OnAppInstall/Handler.php | 81 +++++++++++ .../UseCase/OnAppInstall/HandlerTest.php | 127 ++++++++++++++++++ .../Builders/Bitrix24AccountBuilder.php | 25 +++- 5 files changed, 271 insertions(+), 1 deletion(-) create mode 100644 src/ApplicationInstallations/UseCase/OnAppInstall/Command.php create mode 100644 src/ApplicationInstallations/UseCase/OnAppInstall/Handler.php create mode 100644 tests/Functional/ApplicationInstallations/UseCase/OnAppInstall/HandlerTest.php diff --git a/src/ApplicationInstallations/UseCase/Install/Handler.php b/src/ApplicationInstallations/UseCase/Install/Handler.php index f10e9bd..2c38055 100644 --- a/src/ApplicationInstallations/UseCase/Install/Handler.php +++ b/src/ApplicationInstallations/UseCase/Install/Handler.php @@ -31,6 +31,10 @@ public function handle(Command $command): void //Проверяем есть ли активные аккаунты если есть значит деактивируем аккаунты и установщики // 1. Получаем все аккаунты с этим memberId + /* (В идеале же у нас только один аккаунт должен быть с memberId, но я думаю лучше все таки возвращать массив мало ли)!!!!! + одновременно придет несколько событий установки. или при миграции задублируются строки + Поэтому я добавлю еще условие в котором если больше чем один аккаунт будем удалять но еще + записывать в лог + */ $accounts = $this->bitrix24AccountRepository->findActiveByMemberId($command->memberId); if (!empty($accounts)) { $accountIds = array_map(fn($acc) => $acc->getId(), $accounts); diff --git a/src/ApplicationInstallations/UseCase/OnAppInstall/Command.php b/src/ApplicationInstallations/UseCase/OnAppInstall/Command.php new file mode 100644 index 0000000..b145d81 --- /dev/null +++ b/src/ApplicationInstallations/UseCase/OnAppInstall/Command.php @@ -0,0 +1,35 @@ +validate(); + } + + private function validate(): void + { + + if ('' === $this->memberId) { + throw new \InvalidArgumentException('Member ID must be a non-empty string.'); + } + + if ('' === $this->domainUrl) { + throw new \InvalidArgumentException('Domain url must be a non-empty string.'); + } + + if ('' === $this->applicationToken) { + throw new \InvalidArgumentException('ApplicationToken must be a non-empty string.'); + } + + } +} diff --git a/src/ApplicationInstallations/UseCase/OnAppInstall/Handler.php b/src/ApplicationInstallations/UseCase/OnAppInstall/Handler.php new file mode 100644 index 0000000..9756779 --- /dev/null +++ b/src/ApplicationInstallations/UseCase/OnAppInstall/Handler.php @@ -0,0 +1,81 @@ +logger->info('ApplicationInstallation.OnAppInstall.start', [ + 'b24_domain_url' => $command->domainUrl, + 'b24_member_id' => $command->memberId, + 'b24_application_id' => $command->applicationToken, + ]); + /* + Если при установке мы можем деактивировать аккаунты если их больше 1 по каким то причинам, + то тут наверно лучше выдавать эксепшен , хотя с другой стороны это стоит обработать как то, + но не хотелось бы этого делать здесь. Как лучше ???? + */ + + /* + * И еще вопрос токен будем в установку заносить все таки ? Потому что впринципи все разрулилось и без токена в установке. + */ + /** @var AggregateRootEventsEmitterInterface|Bitrix24AccountInterface $bitrix24Account */ + $bitrix24Account = $this->getSingleAccountByMemberId($command->domainUrl, $command->memberId,); + + $bitrix24Account->setToken($command->applicationToken); + + $this->bitrix24AccountRepository->save($bitrix24Account); + $this->flusher->flush($bitrix24Account); + $this->logger->info('ApplicationInstallation.OnAppInstall.finish'); + } + + private function getSingleAccountByMemberId(string $domainUrl, string $memberId): Bitrix24AccountInterface + { + $accounts = $this->bitrix24AccountRepository->findByMemberId( + $memberId, + Bitrix24AccountStatus::active, + ); + + if ([] === $accounts) { + throw new Bitrix24AccountNotFoundException( + sprintf( + 'bitrix24 account for domain %s with member id %s in status «new» not found', + $domainUrl, + $memberId + ) + ); + } + + if (count($accounts) > 1) { + throw new MultipleBitrix24AccountsFoundException( + sprintf( + 'multiple bitrix24 accounts for domain %s with member id %s in status «new» found', + $domainUrl, + $memberId + ) + ); + } + + return $accounts[0]; + } +} \ No newline at end of file diff --git a/tests/Functional/ApplicationInstallations/UseCase/OnAppInstall/HandlerTest.php b/tests/Functional/ApplicationInstallations/UseCase/OnAppInstall/HandlerTest.php new file mode 100644 index 0000000..791af07 --- /dev/null +++ b/tests/Functional/ApplicationInstallations/UseCase/OnAppInstall/HandlerTest.php @@ -0,0 +1,127 @@ + + * + * For the full copyright and license information, please view the MIT-LICENSE.txt + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace Bitrix24\Lib\Tests\Functional\ApplicationInstallations\UseCase\OnAppInstall; + + +use Bitrix24\Lib\Bitrix24Accounts; + +use Bitrix24\Lib\Bitrix24Accounts\ValueObjects\Domain; +use Bitrix24\Lib\Services\Flusher; +use Bitrix24\Lib\ApplicationInstallations; +use Bitrix24\Lib\Tests\EntityManagerFactory; + +use Bitrix24\Lib\Tests\Functional\ApplicationInstallations\Builders\ApplicationInstallationBuilder; +use Bitrix24\Lib\Tests\Functional\Bitrix24Accounts\Builders\Bitrix24AccountBuilder; +use Bitrix24\SDK\Application\ApplicationStatus; +use Bitrix24\SDK\Application\Contracts\ApplicationInstallations\Entity\ApplicationInstallationStatus; +use Bitrix24\SDK\Application\Contracts\Bitrix24Accounts\Entity\Bitrix24AccountStatus; +use Bitrix24\SDK\Application\PortalLicenseFamily; +use Bitrix24\SDK\Core\Credentials\Scope; +use Bitrix24\SDK\Core\Exceptions\InvalidArgumentException; + +use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\Attributes\Test; +use PHPUnit\Framework\TestCase; +use Psr\Log\NullLogger; + +use Symfony\Component\EventDispatcher\Debug\TraceableEventDispatcher; +use Symfony\Component\EventDispatcher\EventDispatcher; +use Symfony\Component\Stopwatch\Stopwatch; + +use Bitrix24\Lib\ApplicationInstallations\Infrastructure\Doctrine\ApplicationInstallationRepository; +use Bitrix24\Lib\ApplicationInstallations\UseCase\OnAppInstall\Handler; + +use Bitrix24\Lib\Bitrix24Accounts\Infrastructure\Doctrine\Bitrix24AccountRepository; +use Symfony\Component\Uid\Uuid; + +/** + * @internal + */ +#[CoversClass(ApplicationInstallations\UseCase\OnAppInstall\Handler::class)] +class HandlerTest extends TestCase +{ + private Handler $handler; + + private Flusher $flusher; + + private ApplicationInstallationRepository $repository; + + private Bitrix24AccountRepository $bitrix24accountRepository; + + private TraceableEventDispatcher $eventDispatcher; + + #[\Override] + protected function setUp(): void + { + $entityManager = EntityManagerFactory::get(); + $this->eventDispatcher = new TraceableEventDispatcher(new EventDispatcher(), new Stopwatch()); + $this->repository = new ApplicationInstallationRepository($entityManager); + $this->flusher = new Flusher($entityManager, $this->eventDispatcher); + $this->bitrix24accountRepository = new Bitrix24AccountRepository($entityManager); + $this->handler = new Handler( + $this->bitrix24accountRepository, + $this->flusher, + new NullLogger() + ); + + } + + /** + * @throws InvalidArgumentException + */ + #[Test] + public function testEventOnAppInstall(): void + { + $memberId = Uuid::v4()->toRfc4122(); + $domainUrl = Uuid::v4()->toRfc4122().'-example.com'; + $applicationToken = Uuid::v7()->toRfc4122(); + + $bitrix24Account = (new Bitrix24AccountBuilder()) + ->withApplicationScope(new Scope(['crm'])) + ->withStatus(Bitrix24AccountStatus::new) + ->withMemberId($memberId) + ->withDomainUrl($domainUrl) + ->withInstalled() + ->build(); + + $applicationInstallationBuilder = (new ApplicationInstallationBuilder()) + ->withApplicationStatus(new ApplicationStatus('F')) + ->withPortalLicenseFamily(PortalLicenseFamily::free) + ->withBitrix24AccountId($bitrix24Account->getId()) + ->withApplicationStatusInstallation(ApplicationInstallationStatus::active) + ->build(); + + $this->bitrix24accountRepository->save($bitrix24Account); + $this->repository->save($applicationInstallationBuilder); + $this->flusher->flush(); + + $this->handler->handle( + new ApplicationInstallations\UseCase\OnAppInstall\Command( + $memberId, + $domainUrl, + $applicationToken, + ) + ); + + $updated = $this->bitrix24accountRepository->getById($bitrix24Account->getId()); + $this->assertTrue( + $updated->isApplicationTokenValid($applicationToken), + sprintf( + 'failed application token «%s» validation for bitrix24 account with id «%s»', + $applicationToken, + $bitrix24Account->getId()->toString() + ) + ); + } +} diff --git a/tests/Functional/Bitrix24Accounts/Builders/Bitrix24AccountBuilder.php b/tests/Functional/Bitrix24Accounts/Builders/Bitrix24AccountBuilder.php index 6e6efb8..e92b81d 100644 --- a/tests/Functional/Bitrix24Accounts/Builders/Bitrix24AccountBuilder.php +++ b/tests/Functional/Bitrix24Accounts/Builders/Bitrix24AccountBuilder.php @@ -43,6 +43,10 @@ class Bitrix24AccountBuilder private ?string $applicationToken = null; + private bool $isSetToken = false; + + private bool $isInstalled = false; + public function __construct() { $this->id = Uuid::v7(); @@ -90,6 +94,20 @@ public function withStatus(Bitrix24AccountStatus $bitrix24AccountStatus): self return $this; } + public function withSetToken(): self + { + $this->isSetToken = true; + + return $this; + } + + public function withInstalled(): self + { + $this->isInstalled = true; + + return $this; + } + public function build(): Bitrix24Account { $bitrix24Account = new Bitrix24Account( @@ -103,11 +121,16 @@ public function build(): Bitrix24Account $this->applicationScope ); - if ($this->applicationToken !== null && Bitrix24AccountStatus::new == $this->status) { + if ($this->isInstalled && Bitrix24AccountStatus::new == $this->status) { $bitrix24Account->applicationInstalled(); + } + + if ($this->isSetToken && $this->applicationToken !== null) { $bitrix24Account->setToken($this->applicationToken); } + + return $bitrix24Account; } } From d0b6d5c261f1ffadb3cb6165dfbd20eee4bdb4db Mon Sep 17 00:00:00 2001 From: KarlsonComplete Date: Sat, 17 May 2025 11:12:59 +0300 Subject: [PATCH 28/49] . --- .../Entity/ApplicationInstallation.php | 10 +++ .../ApplicationInstallationRepository.php | 10 +-- .../UseCase/Install/Handler.php | 55 ++++++++-------- .../UseCase/OnAppInstall/Command.php | 7 ++- .../UseCase/OnAppInstall/Handler.php | 62 +++++++++---------- .../Doctrine/Bitrix24AccountRepository.php | 8 ++- .../UseCase/OnAppInstall/HandlerTest.php | 7 ++- 7 files changed, 86 insertions(+), 73 deletions(-) diff --git a/src/ApplicationInstallations/Entity/ApplicationInstallation.php b/src/ApplicationInstallations/Entity/ApplicationInstallation.php index 327cd7c..b815517 100644 --- a/src/ApplicationInstallations/Entity/ApplicationInstallation.php +++ b/src/ApplicationInstallations/Entity/ApplicationInstallation.php @@ -161,6 +161,16 @@ public function getStatus(): ApplicationInstallationStatus return $this->status; } + public function setToken(string $applicationToken): void + { + if ('' === $applicationToken) { + throw new InvalidArgumentException('application token cannot be empty'); + } + + $this->updatedAt = new CarbonImmutable(); + $this->applicationToken = $applicationToken; + } + #[\Override] public function applicationInstalled(): void { diff --git a/src/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationRepository.php b/src/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationRepository.php index 42b0621..1111a6d 100644 --- a/src/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationRepository.php +++ b/src/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationRepository.php @@ -104,12 +104,8 @@ public function findByExternalId(string $externalId): array ; } - public function findActiveByAccountIds(array $accountIds): array + public function findActiveByAccountId(Uuid $b24AccountId): array { - if (empty($accountIds)) { - return []; - } - $activeStatuses = [ ApplicationInstallationStatus::new, ApplicationInstallationStatus::active, @@ -117,9 +113,9 @@ public function findActiveByAccountIds(array $accountIds): array $installations = $this->getEntityManager()->getRepository(ApplicationInstallation::class) ->createQueryBuilder('applicationInstallation') - ->where('applicationInstallation.bitrix24AccountId IN (:accountIds)') + ->where('applicationInstallation.bitrix24AccountId = :b24AccountId') ->andWhere('applicationInstallation.status IN (:statuses)') - ->setParameter('accountIds', $accountIds) + ->setParameter('b24AccountId', $b24AccountId) ->setParameter('statuses', $activeStatuses) ->getQuery() ->getResult(); diff --git a/src/ApplicationInstallations/UseCase/Install/Handler.php b/src/ApplicationInstallations/UseCase/Install/Handler.php index 2c38055..1705caa 100644 --- a/src/ApplicationInstallations/UseCase/Install/Handler.php +++ b/src/ApplicationInstallations/UseCase/Install/Handler.php @@ -9,6 +9,9 @@ use Bitrix24\Lib\Bitrix24Accounts\Entity\Bitrix24Account; use Bitrix24\Lib\Bitrix24Accounts\Infrastructure\Doctrine\Bitrix24AccountRepository; use Bitrix24\Lib\Services\Flusher; +use Bitrix24\SDK\Application\Contracts\ApplicationInstallations\Entity\ApplicationInstallationInterface; +use Bitrix24\SDK\Application\Contracts\Bitrix24Accounts\Entity\Bitrix24AccountInterface; +use Bitrix24\SDK\Application\Contracts\Events\AggregateRootEventsEmitterInterface; use Psr\Log\LoggerInterface; use Symfony\Component\Uid\Uuid; @@ -29,33 +32,24 @@ public function handle(Command $command): void (string)$command ]); - //Проверяем есть ли активные аккаунты если есть значит деактивируем аккаунты и установщики - // 1. Получаем все аккаунты с этим memberId - /* (В идеале же у нас только один аккаунт должен быть с memberId, но я думаю лучше все таки возвращать массив мало ли)!!!!! - одновременно придет несколько событий установки. или при миграции задублируются строки - Поэтому я добавлю еще условие в котором если больше чем один аккаунт будем удалять но еще + записывать в лог - */ - $accounts = $this->bitrix24AccountRepository->findActiveByMemberId($command->memberId); - if (!empty($accounts)) { - $accountIds = array_map(fn($acc) => $acc->getId(), $accounts); - // 2. Получаем все активные установки для этих аккаунтов - $activeInstallations = $this->applicationInstallationRepository->findActiveByAccountIds($accountIds); - - // 3. Деактивируем все активные установки и связанные аккаунты - foreach ($activeInstallations as $installation) { - $installation->applicationUninstalled(); - $this->applicationInstallationRepository->save($installation); - } - - foreach ($accounts as $account) { - //Нужна правка в контракте ушли от обязательного параметра токена!!! - $account->applicationUninstalled(); - $this->bitrix24AccountRepository->save($account); - } - - // Здесь сразу флашим так как это условие не всегда работает , и лучше сначало разобраться с аккаунтами и установщиками - // которые нужно деактивировать , а после уже работаем с новыми сущностями. - $this->flusher->flush(...$activeInstallations, ...$accounts); + + /** @var AggregateRootEventsEmitterInterface|Bitrix24AccountInterface $b24Account */ + $b24Account = $this->bitrix24AccountRepository->findActiveByMemberId($command->memberId); + + if ($b24Account !== null) { + + /** @var AggregateRootEventsEmitterInterface|ApplicationInstallationInterface $activeInstallation */ + $activeInstallation = $this->getActiveApplicationInstallations($b24Account->getId()); + + $activeInstallation->applicationUninstalled(); + $this->applicationInstallationRepository->save($activeInstallation); + + $b24Account->applicationUninstalled(); + $this->bitrix24AccountRepository->save($b24Account); + + /* Здесь сразу флашим так как это условие не всегда работает , и лучше сначало разобраться с аккаунтами и установщиками + которые нужно деактивировать , а после уже работаем с новыми сущностями. */ + $this->flusher->flush($b24Account, $activeInstallation); } $bitrix24AccountId = Uuid::v7(); @@ -104,4 +98,11 @@ public function handle(Command $command): void ] ); } + + private function getActiveApplicationInstallations(Uuid $b24AccountId): ApplicationInstallationInterface + { + $activeInstallations = $this->applicationInstallationRepository->findActiveByAccountId($b24AccountId); + + return $activeInstallations[0]; + } } diff --git a/src/ApplicationInstallations/UseCase/OnAppInstall/Command.php b/src/ApplicationInstallations/UseCase/OnAppInstall/Command.php index b145d81..5f7ac7c 100644 --- a/src/ApplicationInstallations/UseCase/OnAppInstall/Command.php +++ b/src/ApplicationInstallations/UseCase/OnAppInstall/Command.php @@ -5,13 +5,13 @@ namespace Bitrix24\Lib\ApplicationInstallations\UseCase\OnAppInstall; - readonly class Command { public function __construct( public string $memberId, public string $domainUrl, - public string $applicationToken + public string $applicationToken, + public string $applicationStatus, ) { $this->validate(); } @@ -31,5 +31,8 @@ private function validate(): void throw new \InvalidArgumentException('ApplicationToken must be a non-empty string.'); } + if ('' === $this->applicationStatus) { + throw new \InvalidArgumentException('ApplicationStatus must be a non-empty string.'); + } } } diff --git a/src/ApplicationInstallations/UseCase/OnAppInstall/Handler.php b/src/ApplicationInstallations/UseCase/OnAppInstall/Handler.php index 9756779..883c680 100644 --- a/src/ApplicationInstallations/UseCase/OnAppInstall/Handler.php +++ b/src/ApplicationInstallations/UseCase/OnAppInstall/Handler.php @@ -4,19 +4,22 @@ namespace Bitrix24\Lib\ApplicationInstallations\UseCase\OnAppInstall; +use Bitrix24\Lib\ApplicationInstallations\Infrastructure\Doctrine\ApplicationInstallationRepository; use Bitrix24\Lib\Bitrix24Accounts\Infrastructure\Doctrine\Bitrix24AccountRepository; use Bitrix24\Lib\Services\Flusher; +use Bitrix24\SDK\Application\ApplicationStatus; +use Bitrix24\SDK\Application\Contracts\ApplicationInstallations\Entity\ApplicationInstallationInterface; use Bitrix24\SDK\Application\Contracts\Bitrix24Accounts\Entity\Bitrix24AccountInterface; use Bitrix24\SDK\Application\Contracts\Bitrix24Accounts\Entity\Bitrix24AccountStatus; -use Bitrix24\SDK\Application\Contracts\Bitrix24Accounts\Exceptions\Bitrix24AccountNotFoundException; -use Bitrix24\SDK\Application\Contracts\Bitrix24Accounts\Exceptions\MultipleBitrix24AccountsFoundException; use Bitrix24\SDK\Application\Contracts\Events\AggregateRootEventsEmitterInterface; +use Symfony\Component\Uid\Uuid; use Psr\Log\LoggerInterface; readonly class Handler { public function __construct( private Bitrix24AccountRepository $bitrix24AccountRepository, + private ApplicationInstallationRepository $applicationInstallationRepository, private Flusher $flusher, private LoggerInterface $logger ) @@ -29,53 +32,44 @@ public function handle(Command $command): void 'b24_domain_url' => $command->domainUrl, 'b24_member_id' => $command->memberId, 'b24_application_id' => $command->applicationToken, + 'application_status' => $command->applicationStatus, ]); - /* - Если при установке мы можем деактивировать аккаунты если их больше 1 по каким то причинам, - то тут наверно лучше выдавать эксепшен , хотя с другой стороны это стоит обработать как то, - но не хотелось бы этого делать здесь. Как лучше ???? - */ - - /* - * И еще вопрос токен будем в установку заносить все таки ? Потому что впринципи все разрулилось и без токена в установке. - */ + /** @var AggregateRootEventsEmitterInterface|Bitrix24AccountInterface $bitrix24Account */ - $bitrix24Account = $this->getSingleAccountByMemberId($command->domainUrl, $command->memberId,); + $bitrix24Account = $this->getAccountByMemberId($command->memberId); + + /** @var AggregateRootEventsEmitterInterface|ApplicationInstallationInterface $applicationInstallation */ + $applicationInstallation = $this->getApplicationInstallationByAccountId($bitrix24Account->getId()); + + $applicationStatus = new ApplicationStatus($command->applicationStatus); + $applicationInstallation->changeApplicationStatus($applicationStatus); + + $applicationInstallation->setToken($command->applicationToken); $bitrix24Account->setToken($command->applicationToken); $this->bitrix24AccountRepository->save($bitrix24Account); - $this->flusher->flush($bitrix24Account); + $this->applicationInstallationRepository->save($applicationInstallation); + + $this->flusher->flush($applicationInstallation,$bitrix24Account); + $this->logger->info('ApplicationInstallation.OnAppInstall.finish'); } - private function getSingleAccountByMemberId(string $domainUrl, string $memberId): Bitrix24AccountInterface + private function getAccountByMemberId(string $memberId): Bitrix24AccountInterface { $accounts = $this->bitrix24AccountRepository->findByMemberId( $memberId, Bitrix24AccountStatus::active, ); - if ([] === $accounts) { - throw new Bitrix24AccountNotFoundException( - sprintf( - 'bitrix24 account for domain %s with member id %s in status «new» not found', - $domainUrl, - $memberId - ) - ); - } - - if (count($accounts) > 1) { - throw new MultipleBitrix24AccountsFoundException( - sprintf( - 'multiple bitrix24 accounts for domain %s with member id %s in status «new» found', - $domainUrl, - $memberId - ) - ); - } - return $accounts[0]; } + + private function getApplicationInstallationByAccountId(Uuid $b24AccountId): ApplicationInstallationInterface + { + $applicationInstallations = $this->applicationInstallationRepository->findByBitrix24AccountId($b24AccountId); + + return $applicationInstallations[0]; + } } \ No newline at end of file diff --git a/src/Bitrix24Accounts/Infrastructure/Doctrine/Bitrix24AccountRepository.php b/src/Bitrix24Accounts/Infrastructure/Doctrine/Bitrix24AccountRepository.php index 996281d..9d5030c 100644 --- a/src/Bitrix24Accounts/Infrastructure/Doctrine/Bitrix24AccountRepository.php +++ b/src/Bitrix24Accounts/Infrastructure/Doctrine/Bitrix24AccountRepository.php @@ -105,7 +105,7 @@ public function findByMemberId( return $this->findBy($criteria); } - public function findActiveByMemberId(string $memberId): array + public function findActiveByMemberId(string $memberId): Bitrix24AccountInterface|null { if ('' === trim($memberId)) { throw new InvalidArgumentException('memberId cannot be empty'); @@ -126,7 +126,11 @@ public function findActiveByMemberId(string $memberId): array ->getResult() ; - return $accounts; + if (empty($accounts)){ + return null; + } + + return $accounts[0]; } #[\Override] diff --git a/tests/Functional/ApplicationInstallations/UseCase/OnAppInstall/HandlerTest.php b/tests/Functional/ApplicationInstallations/UseCase/OnAppInstall/HandlerTest.php index 791af07..95f5e67 100644 --- a/tests/Functional/ApplicationInstallations/UseCase/OnAppInstall/HandlerTest.php +++ b/tests/Functional/ApplicationInstallations/UseCase/OnAppInstall/HandlerTest.php @@ -26,6 +26,7 @@ use Bitrix24\SDK\Application\ApplicationStatus; use Bitrix24\SDK\Application\Contracts\ApplicationInstallations\Entity\ApplicationInstallationStatus; use Bitrix24\SDK\Application\Contracts\Bitrix24Accounts\Entity\Bitrix24AccountStatus; +use Bitrix24\SDK\Application\Contracts\Bitrix24Accounts\Exceptions\Bitrix24AccountNotFoundException; use Bitrix24\SDK\Application\PortalLicenseFamily; use Bitrix24\SDK\Core\Credentials\Scope; use Bitrix24\SDK\Core\Exceptions\InvalidArgumentException; @@ -69,8 +70,10 @@ protected function setUp(): void $this->repository = new ApplicationInstallationRepository($entityManager); $this->flusher = new Flusher($entityManager, $this->eventDispatcher); $this->bitrix24accountRepository = new Bitrix24AccountRepository($entityManager); + $this->applicationInstallationRepository = new ApplicationInstallationRepository($entityManager); $this->handler = new Handler( $this->bitrix24accountRepository, + $this->applicationInstallationRepository, $this->flusher, new NullLogger() ); @@ -78,7 +81,7 @@ protected function setUp(): void } /** - * @throws InvalidArgumentException + * @throws InvalidArgumentException|Bitrix24AccountNotFoundException */ #[Test] public function testEventOnAppInstall(): void @@ -86,6 +89,7 @@ public function testEventOnAppInstall(): void $memberId = Uuid::v4()->toRfc4122(); $domainUrl = Uuid::v4()->toRfc4122().'-example.com'; $applicationToken = Uuid::v7()->toRfc4122(); + $applicationStatus = 'T'; $bitrix24Account = (new Bitrix24AccountBuilder()) ->withApplicationScope(new Scope(['crm'])) @@ -111,6 +115,7 @@ public function testEventOnAppInstall(): void $memberId, $domainUrl, $applicationToken, + $applicationStatus ) ); From db8872388f44ccad844728c7ea03a29fad4cc165 Mon Sep 17 00:00:00 2001 From: KarlsonComplete Date: Thu, 29 May 2025 23:29:39 +0300 Subject: [PATCH 29/49] . --- ...ons.Entity.ApplicationInstallation.dcm.xml | 2 +- ...x24Accounts.Entity.Bitrix24Account.dcm.xml | 2 + .../ApplicationInstallationRepository.php | 8 +-- .../UseCase/Install/Handler.php | 52 ++++++++------- .../Entity/Bitrix24Account.php | 6 ++ .../Doctrine/Bitrix24AccountRepository.php | 8 +-- .../UseCase/Install/HandlerTest.php | 64 +++++++++++++++++++ .../Builders/Bitrix24AccountBuilder.php | 12 +++- 8 files changed, 119 insertions(+), 35 deletions(-) diff --git a/config/xml/Bitrix24.Lib.ApplicationInstallations.Entity.ApplicationInstallation.dcm.xml b/config/xml/Bitrix24.Lib.ApplicationInstallations.Entity.ApplicationInstallation.dcm.xml index 3ba6b71..9e8c92c 100644 --- a/config/xml/Bitrix24.Lib.ApplicationInstallations.Entity.ApplicationInstallation.dcm.xml +++ b/config/xml/Bitrix24.Lib.ApplicationInstallations.Entity.ApplicationInstallation.dcm.xml @@ -13,7 +13,7 @@ - + diff --git a/config/xml/Bitrix24.Lib.Bitrix24Accounts.Entity.Bitrix24Account.dcm.xml b/config/xml/Bitrix24.Lib.Bitrix24Accounts.Entity.Bitrix24Account.dcm.xml index 74b6231..7aca058 100644 --- a/config/xml/Bitrix24.Lib.Bitrix24Accounts.Entity.Bitrix24Account.dcm.xml +++ b/config/xml/Bitrix24.Lib.Bitrix24Accounts.Entity.Bitrix24Account.dcm.xml @@ -12,6 +12,8 @@ + + diff --git a/src/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationRepository.php b/src/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationRepository.php index 1111a6d..7b4110d 100644 --- a/src/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationRepository.php +++ b/src/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationRepository.php @@ -104,22 +104,22 @@ public function findByExternalId(string $externalId): array ; } - public function findActiveByAccountId(Uuid $b24AccountId): array + public function findActiveByAccountId(Uuid $b24AccountId): ApplicationInstallationInterface { $activeStatuses = [ ApplicationInstallationStatus::new, ApplicationInstallationStatus::active, ]; - $installations = $this->getEntityManager()->getRepository(ApplicationInstallation::class) + $installation = $this->getEntityManager()->getRepository(ApplicationInstallation::class) ->createQueryBuilder('applicationInstallation') ->where('applicationInstallation.bitrix24AccountId = :b24AccountId') ->andWhere('applicationInstallation.status IN (:statuses)') ->setParameter('b24AccountId', $b24AccountId) ->setParameter('statuses', $activeStatuses) ->getQuery() - ->getResult(); + ->getOneOrNullResult(); - return $installations; + return $installation; } } diff --git a/src/ApplicationInstallations/UseCase/Install/Handler.php b/src/ApplicationInstallations/UseCase/Install/Handler.php index 1705caa..57ce71f 100644 --- a/src/ApplicationInstallations/UseCase/Install/Handler.php +++ b/src/ApplicationInstallations/UseCase/Install/Handler.php @@ -12,6 +12,8 @@ use Bitrix24\SDK\Application\Contracts\ApplicationInstallations\Entity\ApplicationInstallationInterface; use Bitrix24\SDK\Application\Contracts\Bitrix24Accounts\Entity\Bitrix24AccountInterface; use Bitrix24\SDK\Application\Contracts\Events\AggregateRootEventsEmitterInterface; +use Bitrix24\SDK\Core\Exceptions\InvalidArgumentException; +use Bitrix24\SDK\Core\Exceptions\LogicException; use Psr\Log\LoggerInterface; use Symfony\Component\Uid\Uuid; @@ -26,30 +28,42 @@ public function __construct( { } + /** + * @throws LogicException + * @throws InvalidArgumentException + */ public function handle(Command $command): void { $this->logger->info('ApplicationInstallations.Install.start', [ (string)$command ]); - - /** @var AggregateRootEventsEmitterInterface|Bitrix24AccountInterface $b24Account */ - $b24Account = $this->bitrix24AccountRepository->findActiveByMemberId($command->memberId); - - if ($b24Account !== null) { - - /** @var AggregateRootEventsEmitterInterface|ApplicationInstallationInterface $activeInstallation */ - $activeInstallation = $this->getActiveApplicationInstallations($b24Account->getId()); - - $activeInstallation->applicationUninstalled(); - $this->applicationInstallationRepository->save($activeInstallation); - - $b24Account->applicationUninstalled(); - $this->bitrix24AccountRepository->save($b24Account); + /* + * Аккаунтов может быть несколько , но установку на портал проводят только 1 раз , то есть есть мастер аккаунт который нужно получать. + * У остальных аккаунтов установок быть не может это просто (доступы/авторизации). + * Решить какое поле для мастера добавить в аккаунт. + */ + /** @var AggregateRootEventsEmitterInterface|Bitrix24AccountInterface[] $b24Accounts */ + $b24Accounts = $this->bitrix24AccountRepository->findActiveByMemberId($command->memberId); + + if ($b24Accounts !== []) { + $entitiesToFlush = []; + foreach ($b24Accounts as $b24Account) { + $isMaster = $b24Account->isMaster(); + if ($isMaster) { + $activeInstallation = $this->applicationInstallationRepository->findActiveByAccountId($b24Account->getId()); + $activeInstallation->applicationUninstalled(); + $this->applicationInstallationRepository->save($activeInstallation); + $entitiesToFlush[] = $activeInstallation; + } + $b24Account->applicationUninstalled(); + $this->bitrix24AccountRepository->save($b24Account); + $entitiesToFlush[] = $b24Account; + } /* Здесь сразу флашим так как это условие не всегда работает , и лучше сначало разобраться с аккаунтами и установщиками которые нужно деактивировать , а после уже работаем с новыми сущностями. */ - $this->flusher->flush($b24Account, $activeInstallation); + $this->flusher->flush(...$entitiesToFlush); } $bitrix24AccountId = Uuid::v7(); @@ -64,6 +78,7 @@ public function handle(Command $command): void $command->authToken, $command->applicationVersion, $command->applicationScope, + true, true ); @@ -98,11 +113,4 @@ public function handle(Command $command): void ] ); } - - private function getActiveApplicationInstallations(Uuid $b24AccountId): ApplicationInstallationInterface - { - $activeInstallations = $this->applicationInstallationRepository->findActiveByAccountId($b24AccountId); - - return $activeInstallations[0]; - } } diff --git a/src/Bitrix24Accounts/Entity/Bitrix24Account.php b/src/Bitrix24Accounts/Entity/Bitrix24Account.php index c623d30..9021c6c 100644 --- a/src/Bitrix24Accounts/Entity/Bitrix24Account.php +++ b/src/Bitrix24Accounts/Entity/Bitrix24Account.php @@ -50,6 +50,7 @@ public function __construct( private AuthToken $authToken, private int $applicationVersion, private Scope $applicationScope, + private bool $isMaster = false, private $isEmitBitrix24AccountCreatedEvent = false, private ?string $comment = null ) { @@ -77,6 +78,11 @@ public function isBitrix24UserAdmin(): bool return $this->isBitrix24UserAdmin; } + public function isMaster(): bool + { + return $this->isMaster; + } + #[\Override] public function getMemberId(): string { diff --git a/src/Bitrix24Accounts/Infrastructure/Doctrine/Bitrix24AccountRepository.php b/src/Bitrix24Accounts/Infrastructure/Doctrine/Bitrix24AccountRepository.php index 9d5030c..996281d 100644 --- a/src/Bitrix24Accounts/Infrastructure/Doctrine/Bitrix24AccountRepository.php +++ b/src/Bitrix24Accounts/Infrastructure/Doctrine/Bitrix24AccountRepository.php @@ -105,7 +105,7 @@ public function findByMemberId( return $this->findBy($criteria); } - public function findActiveByMemberId(string $memberId): Bitrix24AccountInterface|null + public function findActiveByMemberId(string $memberId): array { if ('' === trim($memberId)) { throw new InvalidArgumentException('memberId cannot be empty'); @@ -126,11 +126,7 @@ public function findActiveByMemberId(string $memberId): Bitrix24AccountInterface ->getResult() ; - if (empty($accounts)){ - return null; - } - - return $accounts[0]; + return $accounts; } #[\Override] diff --git a/tests/Functional/ApplicationInstallations/UseCase/Install/HandlerTest.php b/tests/Functional/ApplicationInstallations/UseCase/Install/HandlerTest.php index fa7112b..f4793df 100644 --- a/tests/Functional/ApplicationInstallations/UseCase/Install/HandlerTest.php +++ b/tests/Functional/ApplicationInstallations/UseCase/Install/HandlerTest.php @@ -139,6 +139,7 @@ public function testReinstallApplicationInstallation(): void ->withStatus(Bitrix24AccountStatus::new) ->withApplicationToken($applicationToken) ->withMemberId($memberId) + ->withMaster(true) ->build(); @@ -190,4 +191,67 @@ public function testReinstallApplicationInstallation(): void $this->assertContains(\Bitrix24\SDK\Application\Contracts\Bitrix24Accounts\Events\Bitrix24AccountApplicationInstalledEvent::class, $dispatchedEvents); $this->assertContains(\Bitrix24\SDK\Application\Contracts\ApplicationInstallations\Events\ApplicationInstallationFinishedEvent::class, $dispatchedEvents); } + + /** + * @throws InvalidArgumentException + */ + #[Test] + public function testFewInstallationsOnOneAccount(): void + { + + $memberId = Uuid::v4()->toRfc4122(); + + //Загружаем в базу данных аккаунт и установку приложения для тестирования переустановки. + $applicationToken = Uuid::v7()->toRfc4122(); + $currentBitrix24Account = (new Bitrix24AccountBuilder()) + ->withApplicationScope(new Scope(['crm'])) + ->withStatus(Bitrix24AccountStatus::new) + ->withApplicationToken($applicationToken) + ->withMemberId($memberId) + ->build(); + + + $currentApplicationInstallationBuilder = (new ApplicationInstallationBuilder()) + ->withApplicationStatus(new ApplicationStatus('F')) + ->withPortalLicenseFamily(PortalLicenseFamily::free) + ->withBitrix24AccountId($currentBitrix24Account->getId()) + ->withApplicationStatusInstallation(ApplicationInstallationStatus::active) + ->build(); + + $this->bitrix24accountRepository->save($currentBitrix24Account); + $this->repository->save($currentApplicationInstallationBuilder); + $this->flusher->flush(); + + $applicationInstallationBuilder = (new ApplicationInstallationBuilder()) + ->withApplicationStatus(new ApplicationStatus('F')) + ->withPortalLicenseFamily(PortalLicenseFamily::free) + ->build(); + + $this->handler->handle( + new ApplicationInstallations\UseCase\Install\Command( + $applicationInstallationBuilder->getApplicationStatus(), + $applicationInstallationBuilder->getPortalLicenseFamily(), + $applicationInstallationBuilder->getPortalUsersCount(), + $applicationInstallationBuilder->getContactPersonId(), + $applicationInstallationBuilder->getBitrix24PartnerContactPersonId(), + $applicationInstallationBuilder->getBitrix24PartnerId(), + $applicationInstallationBuilder->getExternalId(), + $applicationInstallationBuilder->getComment(), + $currentBitrix24Account->getBitrix24UserId(), + $currentBitrix24Account->isBitrix24UserAdmin(), + $currentBitrix24Account->getMemberId(), + new Domain($currentBitrix24Account->getDomainUrl()), + $currentBitrix24Account->getAuthToken(), + $currentBitrix24Account->getApplicationVersion(), + $currentBitrix24Account->getApplicationScope() + ) + ); + + $dispatchedEvents = $this->eventDispatcher->getOrphanedEvents(); + + $this->assertContains(\Bitrix24\SDK\Application\Contracts\Bitrix24Accounts\Events\Bitrix24AccountCreatedEvent::class, $dispatchedEvents); + $this->assertContains(\Bitrix24\SDK\Application\Contracts\ApplicationInstallations\Events\ApplicationInstallationCreatedEvent::class, $dispatchedEvents); + $this->assertContains(\Bitrix24\SDK\Application\Contracts\Bitrix24Accounts\Events\Bitrix24AccountApplicationInstalledEvent::class, $dispatchedEvents); + $this->assertContains(\Bitrix24\SDK\Application\Contracts\ApplicationInstallations\Events\ApplicationInstallationFinishedEvent::class, $dispatchedEvents); + } } diff --git a/tests/Functional/Bitrix24Accounts/Builders/Bitrix24AccountBuilder.php b/tests/Functional/Bitrix24Accounts/Builders/Bitrix24AccountBuilder.php index e92b81d..d93e837 100644 --- a/tests/Functional/Bitrix24Accounts/Builders/Bitrix24AccountBuilder.php +++ b/tests/Functional/Bitrix24Accounts/Builders/Bitrix24AccountBuilder.php @@ -42,7 +42,7 @@ class Bitrix24AccountBuilder private Scope $applicationScope; private ?string $applicationToken = null; - + private bool $isMaster = false; private bool $isSetToken = false; private bool $isInstalled = false; @@ -101,6 +101,13 @@ public function withSetToken(): self return $this; } + public function withMaster(bool $isMaster): self + { + $this->isMaster = $isMaster; + + return $this; + } + public function withInstalled(): self { $this->isInstalled = true; @@ -118,7 +125,8 @@ public function build(): Bitrix24Account $this->domainUrl, $this->authToken, $this->applicationVersion, - $this->applicationScope + $this->applicationScope, + $this->isMaster ); if ($this->isInstalled && Bitrix24AccountStatus::new == $this->status) { From ff436cdf0974ba790aec1c42a50a55b64799a9f4 Mon Sep 17 00:00:00 2001 From: KarlsonComplete Date: Sun, 1 Jun 2025 13:42:29 +0300 Subject: [PATCH 30/49] . --- ...x24Accounts.Entity.Bitrix24Account.dcm.xml | 2 +- .../Entity/ApplicationInstallation.php | 28 ++++++--- .../ApplicationInstallationRepository.php | 5 +- .../UseCase/Install/Handler.php | 6 +- .../UseCase/OnAppInstall/Handler.php | 34 ++++------ .../Entity/Bitrix24Account.php | 62 +++++++++++-------- .../Doctrine/Bitrix24AccountRepository.php | 34 ++++++++++ .../UseCase/OnAppInstall/HandlerTest.php | 9 +-- .../Builders/Bitrix24AccountBuilder.php | 10 +-- 9 files changed, 120 insertions(+), 70 deletions(-) diff --git a/config/xml/Bitrix24.Lib.Bitrix24Accounts.Entity.Bitrix24Account.dcm.xml b/config/xml/Bitrix24.Lib.Bitrix24Accounts.Entity.Bitrix24Account.dcm.xml index 7aca058..d4baa42 100644 --- a/config/xml/Bitrix24.Lib.Bitrix24Accounts.Entity.Bitrix24Account.dcm.xml +++ b/config/xml/Bitrix24.Lib.Bitrix24Accounts.Entity.Bitrix24Account.dcm.xml @@ -12,7 +12,7 @@ - + diff --git a/src/ApplicationInstallations/Entity/ApplicationInstallation.php b/src/ApplicationInstallations/Entity/ApplicationInstallation.php index b815517..e37cce8 100644 --- a/src/ApplicationInstallations/Entity/ApplicationInstallation.php +++ b/src/ApplicationInstallations/Entity/ApplicationInstallation.php @@ -163,16 +163,11 @@ public function getStatus(): ApplicationInstallationStatus public function setToken(string $applicationToken): void { - if ('' === $applicationToken) { - throw new InvalidArgumentException('application token cannot be empty'); - } - $this->updatedAt = new CarbonImmutable(); - $this->applicationToken = $applicationToken; } #[\Override] - public function applicationInstalled(): void + public function applicationInstalled(?string $applicationToken = null): void { if ( ApplicationInstallationStatus::new !== $this->status @@ -186,6 +181,10 @@ public function applicationInstalled(): void ); } + if ('' !== $applicationToken) { + $this->applicationToken = $applicationToken; + } + $this->status = ApplicationInstallationStatus::active; $this->updatedAt = new CarbonImmutable(); @@ -201,7 +200,7 @@ public function applicationInstalled(): void } #[\Override] - public function applicationUninstalled(): void + public function applicationUninstalled(?string $applicationToken = null): void { if ( ApplicationInstallationStatus::active !== $this->status @@ -362,4 +361,19 @@ private function addApplicationCreatedEventIfNeeded(bool $isEmitCreatedEvent): v ); } } + + public function isApplicationTokenValid(string $applicationToken): bool + { + return $this->applicationToken === $applicationToken; + } + + public function setApplicationToken(string $applicationToken): void + { + if ('' === $applicationToken) { + throw new InvalidArgumentException('application token cannot be empty'); + } + + $this->updatedAt = new CarbonImmutable(); + $this->applicationToken = $applicationToken; + } } diff --git a/src/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationRepository.php b/src/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationRepository.php index 7b4110d..f287fcb 100644 --- a/src/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationRepository.php +++ b/src/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationRepository.php @@ -64,14 +64,15 @@ public function delete(Uuid $uuid): void } #[\Override] - public function findByBitrix24AccountId(Uuid $uuid): array + //У нас в установке аккаунтId это констрейнт, так что возращать мы должны сущность. + public function findByBitrix24AccountId(Uuid $uuid): ApplicationInstallationInterface { return $this->getEntityManager()->getRepository(ApplicationInstallation::class) ->createQueryBuilder('appInstallation') ->where('appInstallation.bitrix24AccountId = :bitrix24AccountId') ->setParameter('bitrix24AccountId', $uuid) ->getQuery() - ->getResult() + ->getOneOrNullResult() ; } diff --git a/src/ApplicationInstallations/UseCase/Install/Handler.php b/src/ApplicationInstallations/UseCase/Install/Handler.php index 57ce71f..c9fb2da 100644 --- a/src/ApplicationInstallations/UseCase/Install/Handler.php +++ b/src/ApplicationInstallations/UseCase/Install/Handler.php @@ -49,14 +49,14 @@ public function handle(Command $command): void if ($b24Accounts !== []) { $entitiesToFlush = []; foreach ($b24Accounts as $b24Account) { - $isMaster = $b24Account->isMaster(); + $isMaster = $b24Account->isMasterAccount(); if ($isMaster) { $activeInstallation = $this->applicationInstallationRepository->findActiveByAccountId($b24Account->getId()); $activeInstallation->applicationUninstalled(); $this->applicationInstallationRepository->save($activeInstallation); $entitiesToFlush[] = $activeInstallation; } - $b24Account->applicationUninstalled(); + $b24Account->applicationUninstalled(null); $this->bitrix24AccountRepository->save($b24Account); $entitiesToFlush[] = $b24Account; } @@ -83,7 +83,7 @@ public function handle(Command $command): void ); - $bitrix24Account->applicationInstalled(); + $bitrix24Account->applicationInstalled(null); $applicationInstallation = new ApplicationInstallation( $applicationInstallationId, diff --git a/src/ApplicationInstallations/UseCase/OnAppInstall/Handler.php b/src/ApplicationInstallations/UseCase/OnAppInstall/Handler.php index 883c680..6977e55 100644 --- a/src/ApplicationInstallations/UseCase/OnAppInstall/Handler.php +++ b/src/ApplicationInstallations/UseCase/OnAppInstall/Handler.php @@ -12,6 +12,7 @@ use Bitrix24\SDK\Application\Contracts\Bitrix24Accounts\Entity\Bitrix24AccountInterface; use Bitrix24\SDK\Application\Contracts\Bitrix24Accounts\Entity\Bitrix24AccountStatus; use Bitrix24\SDK\Application\Contracts\Events\AggregateRootEventsEmitterInterface; +use Bitrix24\SDK\Core\Exceptions\InvalidArgumentException; use Symfony\Component\Uid\Uuid; use Psr\Log\LoggerInterface; @@ -26,6 +27,9 @@ public function __construct( { } + /** + * @throws InvalidArgumentException + */ public function handle(Command $command): void { $this->logger->info('ApplicationInstallation.OnAppInstall.start', [ @@ -35,18 +39,23 @@ public function handle(Command $command): void 'application_status' => $command->applicationStatus, ]); + //Тут нужно получить аккаунт мастера , так как если я не ошибаюсь , события установки могут приходить не сразу. + //И за это время на портале могут появится несколько других авторизаций. /** @var AggregateRootEventsEmitterInterface|Bitrix24AccountInterface $bitrix24Account */ - $bitrix24Account = $this->getAccountByMemberId($command->memberId); + $bitrix24Account = $this->bitrix24AccountRepository->findMasterByMemberId( + $command->memberId, + Bitrix24AccountStatus::active, + ); /** @var AggregateRootEventsEmitterInterface|ApplicationInstallationInterface $applicationInstallation */ - $applicationInstallation = $this->getApplicationInstallationByAccountId($bitrix24Account->getId()); + $applicationInstallation = $this->applicationInstallationRepository->findByBitrix24AccountId($bitrix24Account->getId()); $applicationStatus = new ApplicationStatus($command->applicationStatus); $applicationInstallation->changeApplicationStatus($applicationStatus); - $applicationInstallation->setToken($command->applicationToken); - $bitrix24Account->setToken($command->applicationToken); + $applicationInstallation->setApplicationToken($command->applicationToken); + $bitrix24Account->setApplicationToken($command->applicationToken); $this->bitrix24AccountRepository->save($bitrix24Account); $this->applicationInstallationRepository->save($applicationInstallation); @@ -55,21 +64,4 @@ public function handle(Command $command): void $this->logger->info('ApplicationInstallation.OnAppInstall.finish'); } - - private function getAccountByMemberId(string $memberId): Bitrix24AccountInterface - { - $accounts = $this->bitrix24AccountRepository->findByMemberId( - $memberId, - Bitrix24AccountStatus::active, - ); - - return $accounts[0]; - } - - private function getApplicationInstallationByAccountId(Uuid $b24AccountId): ApplicationInstallationInterface - { - $applicationInstallations = $this->applicationInstallationRepository->findByBitrix24AccountId($b24AccountId); - - return $applicationInstallations[0]; - } } \ No newline at end of file diff --git a/src/Bitrix24Accounts/Entity/Bitrix24Account.php b/src/Bitrix24Accounts/Entity/Bitrix24Account.php index 9021c6c..9207ef3 100644 --- a/src/Bitrix24Accounts/Entity/Bitrix24Account.php +++ b/src/Bitrix24Accounts/Entity/Bitrix24Account.php @@ -23,7 +23,6 @@ use Bitrix24\SDK\Application\Contracts\Bitrix24Accounts\Events\Bitrix24AccountCreatedEvent; use Bitrix24\SDK\Application\Contracts\Bitrix24Accounts\Events\Bitrix24AccountDomainUrlChangedEvent; use Bitrix24\SDK\Core\Credentials\AuthToken; -use Bitrix24\SDK\Core\Credentials\Credentials; use Bitrix24\SDK\Core\Credentials\Scope; use Bitrix24\SDK\Core\Exceptions\InvalidArgumentException; use Bitrix24\SDK\Core\Response\DTO\RenewedAuthToken; @@ -41,18 +40,18 @@ class Bitrix24Account extends AggregateRoot implements Bitrix24AccountInterface private Bitrix24AccountStatus $status; public function __construct( - private readonly Uuid $id, - private readonly int $bitrix24UserId, - private readonly bool $isBitrix24UserAdmin, + private readonly Uuid $id, + private readonly int $bitrix24UserId, + private readonly bool $isBitrix24UserAdmin, /** bitrix24 portal unique id */ private readonly string $memberId, - private string $domainUrl, - private AuthToken $authToken, - private int $applicationVersion, - private Scope $applicationScope, - private bool $isMaster = false, - private $isEmitBitrix24AccountCreatedEvent = false, - private ?string $comment = null + private string $domainUrl, + private AuthToken $authToken, + private int $applicationVersion, + private Scope $applicationScope, + private readonly bool $isMasterAccount = false, + private $isEmitBitrix24AccountCreatedEvent = false, + private ?string $comment = null ) { $this->createdAt = new CarbonImmutable(); $this->updatedAt = new CarbonImmutable(); @@ -78,11 +77,6 @@ public function isBitrix24UserAdmin(): bool return $this->isBitrix24UserAdmin; } - public function isMaster(): bool - { - return $this->isMaster; - } - #[\Override] public function getMemberId(): string { @@ -179,10 +173,11 @@ public function changeDomainUrl(string $newDomainUrl): void } /** + * @param string|null $applicationToken * @throws InvalidArgumentException */ #[\Override] - public function applicationInstalled(): void + public function applicationInstalled(?string $applicationToken): void { if (Bitrix24AccountStatus::new !== $this->status) { throw new InvalidArgumentException( @@ -193,6 +188,10 @@ public function applicationInstalled(): void ); } + if ('' !== $applicationToken) { + $this->applicationToken = $applicationToken; + } + $this->status = Bitrix24AccountStatus::active; $this->updatedAt = new CarbonImmutable(); $this->events[] = new Bitrix24AccountApplicationInstalledEvent( @@ -203,7 +202,7 @@ public function applicationInstalled(): void #[\Override] - public function applicationUninstalled(): void + public function applicationUninstalled(?string $applicationToken): void { $this->status = Bitrix24AccountStatus::deleted; $this->updatedAt = new CarbonImmutable(); @@ -216,6 +215,8 @@ public function applicationUninstalled(): void #[\Override] public function isApplicationTokenValid(string $applicationToken): bool { + $this->guardTokenMismatch($applicationToken); + return $this->applicationToken === $applicationToken; } @@ -285,6 +286,22 @@ public function markAsActive(?string $comment): void $this->updatedAt = new CarbonImmutable(); } + + #[\Override] + public function isMasterAccount(): bool + { + return $this->isMasterAccount; + } + + #[\Override] + public function setApplicationToken(string $applicationToken): void + { + $this->guardEmptyToken($applicationToken); + + $this->updatedAt = new CarbonImmutable(); + $this->applicationToken = $applicationToken; + } + /** * @throws InvalidArgumentException */ @@ -356,13 +373,4 @@ private function addAccountCreatedEventIfNeeded(bool $isEmitCreatedEvent): void } } - public function setToken(string $applicationToken): void - { - if ('' === $applicationToken) { - throw new InvalidArgumentException('application token cannot be empty'); - } - - $this->updatedAt = new CarbonImmutable(); - $this->applicationToken = $applicationToken; - } } diff --git a/src/Bitrix24Accounts/Infrastructure/Doctrine/Bitrix24AccountRepository.php b/src/Bitrix24Accounts/Infrastructure/Doctrine/Bitrix24AccountRepository.php index 996281d..9db5194 100644 --- a/src/Bitrix24Accounts/Infrastructure/Doctrine/Bitrix24AccountRepository.php +++ b/src/Bitrix24Accounts/Infrastructure/Doctrine/Bitrix24AccountRepository.php @@ -105,6 +105,40 @@ public function findByMemberId( return $this->findBy($criteria); } + /** + * @phpstan-return Bitrix24AccountInterface + * @throws InvalidArgumentException + */ + public function findMasterByMemberId( + string $memberId, + ?Bitrix24AccountStatus $bitrix24AccountStatus = null, + ?int $bitrix24UserId = null, + ?bool $isAdmin = null + ): Bitrix24AccountInterface { + if ('' === trim($memberId)) { + throw new InvalidArgumentException('memberId cannot be empty'); + } + + $criteria = [ + 'memberId' => $memberId, + 'isMasterAccount' => true + ]; + + if ($bitrix24AccountStatus instanceof Bitrix24AccountStatus) { + $criteria['status'] = $bitrix24AccountStatus->name; + } + + if (null !== $bitrix24UserId) { + $criteria['bitrix24UserId'] = $bitrix24UserId; + } + + if (null !== $isAdmin) { + $criteria['isBitrix24UserAdmin'] = $isAdmin; + } + + return $this->findOneBy($criteria); + } + public function findActiveByMemberId(string $memberId): array { if ('' === trim($memberId)) { diff --git a/tests/Functional/ApplicationInstallations/UseCase/OnAppInstall/HandlerTest.php b/tests/Functional/ApplicationInstallations/UseCase/OnAppInstall/HandlerTest.php index 95f5e67..6df8dd5 100644 --- a/tests/Functional/ApplicationInstallations/UseCase/OnAppInstall/HandlerTest.php +++ b/tests/Functional/ApplicationInstallations/UseCase/OnAppInstall/HandlerTest.php @@ -56,7 +56,7 @@ class HandlerTest extends TestCase private Flusher $flusher; - private ApplicationInstallationRepository $repository; + private ApplicationInstallationRepository $applicationInstallationRepository; private Bitrix24AccountRepository $bitrix24accountRepository; @@ -67,10 +67,9 @@ protected function setUp(): void { $entityManager = EntityManagerFactory::get(); $this->eventDispatcher = new TraceableEventDispatcher(new EventDispatcher(), new Stopwatch()); - $this->repository = new ApplicationInstallationRepository($entityManager); + $this->applicationInstallationRepository = new ApplicationInstallationRepository($entityManager); $this->flusher = new Flusher($entityManager, $this->eventDispatcher); $this->bitrix24accountRepository = new Bitrix24AccountRepository($entityManager); - $this->applicationInstallationRepository = new ApplicationInstallationRepository($entityManager); $this->handler = new Handler( $this->bitrix24accountRepository, $this->applicationInstallationRepository, @@ -97,6 +96,7 @@ public function testEventOnAppInstall(): void ->withMemberId($memberId) ->withDomainUrl($domainUrl) ->withInstalled() + ->withMaster(true) ->build(); $applicationInstallationBuilder = (new ApplicationInstallationBuilder()) @@ -107,7 +107,7 @@ public function testEventOnAppInstall(): void ->build(); $this->bitrix24accountRepository->save($bitrix24Account); - $this->repository->save($applicationInstallationBuilder); + $this->applicationInstallationRepository->save($applicationInstallationBuilder); $this->flusher->flush(); $this->handler->handle( @@ -120,6 +120,7 @@ public function testEventOnAppInstall(): void ); $updated = $this->bitrix24accountRepository->getById($bitrix24Account->getId()); + $this->assertTrue( $updated->isApplicationTokenValid($applicationToken), sprintf( diff --git a/tests/Functional/Bitrix24Accounts/Builders/Bitrix24AccountBuilder.php b/tests/Functional/Bitrix24Accounts/Builders/Bitrix24AccountBuilder.php index d93e837..5b55b6c 100644 --- a/tests/Functional/Bitrix24Accounts/Builders/Bitrix24AccountBuilder.php +++ b/tests/Functional/Bitrix24Accounts/Builders/Bitrix24AccountBuilder.php @@ -42,7 +42,7 @@ class Bitrix24AccountBuilder private Scope $applicationScope; private ?string $applicationToken = null; - private bool $isMaster = false; + private bool $isMasterAccount = false; private bool $isSetToken = false; private bool $isInstalled = false; @@ -103,7 +103,7 @@ public function withSetToken(): self public function withMaster(bool $isMaster): self { - $this->isMaster = $isMaster; + $this->isMasterAccount = $isMaster; return $this; } @@ -126,15 +126,15 @@ public function build(): Bitrix24Account $this->authToken, $this->applicationVersion, $this->applicationScope, - $this->isMaster + $this->isMasterAccount ); if ($this->isInstalled && Bitrix24AccountStatus::new == $this->status) { - $bitrix24Account->applicationInstalled(); + $bitrix24Account->applicationInstalled(null); } if ($this->isSetToken && $this->applicationToken !== null) { - $bitrix24Account->setToken($this->applicationToken); + $bitrix24Account->setApplicationToken($this->applicationToken); } From 93bf8a37342b1fa42bfa6355395734a0552c2062 Mon Sep 17 00:00:00 2001 From: KarlsonComplete Date: Tue, 3 Jun 2025 23:08:23 +0300 Subject: [PATCH 31/49] . --- .../Entity/ApplicationInstallation.php | 11 +++-------- .../Doctrine/ApplicationInstallationRepository.php | 4 ++-- .../UseCase/OnAppInstall/Handler.php | 2 +- .../Doctrine/Bitrix24AccountRepository.php | 4 ++-- 4 files changed, 8 insertions(+), 13 deletions(-) diff --git a/src/ApplicationInstallations/Entity/ApplicationInstallation.php b/src/ApplicationInstallations/Entity/ApplicationInstallation.php index e37cce8..17a3399 100644 --- a/src/ApplicationInstallations/Entity/ApplicationInstallation.php +++ b/src/ApplicationInstallations/Entity/ApplicationInstallation.php @@ -83,7 +83,7 @@ public function getApplicationToken(): string } #[\Override] - public function changeContactPerson(?Uuid $uuid): void + public function changeContactPerson(Uuid $uuid): void { $this->updatedAt = new CarbonImmutable(); @@ -104,7 +104,7 @@ public function getBitrix24PartnerContactPersonId(): ?Uuid } #[\Override] - public function changeBitrix24PartnerContactPerson(?Uuid $uuid): void + public function changeBitrix24PartnerContactPerson(Uuid $uuid): void { $this->updatedAt = new CarbonImmutable(); @@ -125,7 +125,7 @@ public function getBitrix24PartnerId(): ?Uuid } #[\Override] - public function changeBitrix24Partner(?Uuid $uuid): void + public function changeBitrix24Partner(Uuid $uuid): void { $this->updatedAt = new CarbonImmutable(); @@ -161,11 +161,6 @@ public function getStatus(): ApplicationInstallationStatus return $this->status; } - public function setToken(string $applicationToken): void - { - - } - #[\Override] public function applicationInstalled(?string $applicationToken = null): void { diff --git a/src/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationRepository.php b/src/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationRepository.php index f287fcb..ec7b1eb 100644 --- a/src/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationRepository.php +++ b/src/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationRepository.php @@ -65,7 +65,7 @@ public function delete(Uuid $uuid): void #[\Override] //У нас в установке аккаунтId это констрейнт, так что возращать мы должны сущность. - public function findByBitrix24AccountId(Uuid $uuid): ApplicationInstallationInterface + public function findByBitrix24AccountId(Uuid $uuid): ApplicationInstallationInterface|null { return $this->getEntityManager()->getRepository(ApplicationInstallation::class) ->createQueryBuilder('appInstallation') @@ -105,7 +105,7 @@ public function findByExternalId(string $externalId): array ; } - public function findActiveByAccountId(Uuid $b24AccountId): ApplicationInstallationInterface + public function findActiveByAccountId(Uuid $b24AccountId): ApplicationInstallationInterface|null { $activeStatuses = [ ApplicationInstallationStatus::new, diff --git a/src/ApplicationInstallations/UseCase/OnAppInstall/Handler.php b/src/ApplicationInstallations/UseCase/OnAppInstall/Handler.php index 6977e55..ca62b68 100644 --- a/src/ApplicationInstallations/UseCase/OnAppInstall/Handler.php +++ b/src/ApplicationInstallations/UseCase/OnAppInstall/Handler.php @@ -47,7 +47,7 @@ public function handle(Command $command): void Bitrix24AccountStatus::active, ); - /** @var AggregateRootEventsEmitterInterface|ApplicationInstallationInterface $applicationInstallation */ + /** @var AggregateRootEventsEmitterInterface|ApplicationInstallationInterface|null $applicationInstallation */ $applicationInstallation = $this->applicationInstallationRepository->findByBitrix24AccountId($bitrix24Account->getId()); $applicationStatus = new ApplicationStatus($command->applicationStatus); diff --git a/src/Bitrix24Accounts/Infrastructure/Doctrine/Bitrix24AccountRepository.php b/src/Bitrix24Accounts/Infrastructure/Doctrine/Bitrix24AccountRepository.php index 9db5194..1e5e9a7 100644 --- a/src/Bitrix24Accounts/Infrastructure/Doctrine/Bitrix24AccountRepository.php +++ b/src/Bitrix24Accounts/Infrastructure/Doctrine/Bitrix24AccountRepository.php @@ -106,7 +106,7 @@ public function findByMemberId( } /** - * @phpstan-return Bitrix24AccountInterface + * @phpstan-return Bitrix24AccountInterface|null * @throws InvalidArgumentException */ public function findMasterByMemberId( @@ -114,7 +114,7 @@ public function findMasterByMemberId( ?Bitrix24AccountStatus $bitrix24AccountStatus = null, ?int $bitrix24UserId = null, ?bool $isAdmin = null - ): Bitrix24AccountInterface { + ): Bitrix24AccountInterface|null { if ('' === trim($memberId)) { throw new InvalidArgumentException('memberId cannot be empty'); } From d454f711ada40dd48dc240b9015534bb0e072664 Mon Sep 17 00:00:00 2001 From: KarlsonComplete Date: Thu, 5 Jun 2025 00:08:59 +0300 Subject: [PATCH 32/49] . --- .../Entity/ApplicationInstallation.php | 2 +- src/Bitrix24Accounts/Entity/Bitrix24Account.php | 14 +------------- .../ApplicationInstallationRepositoryTest.php | 3 --- .../Doctrine/Bitrix24AccountRepositoryTest.php | 4 +++- 4 files changed, 5 insertions(+), 18 deletions(-) diff --git a/src/ApplicationInstallations/Entity/ApplicationInstallation.php b/src/ApplicationInstallations/Entity/ApplicationInstallation.php index 17a3399..fa4d878 100644 --- a/src/ApplicationInstallations/Entity/ApplicationInstallation.php +++ b/src/ApplicationInstallations/Entity/ApplicationInstallation.php @@ -176,7 +176,7 @@ public function applicationInstalled(?string $applicationToken = null): void ); } - if ('' !== $applicationToken) { + if (!empty($applicationToken)) { $this->applicationToken = $applicationToken; } diff --git a/src/Bitrix24Accounts/Entity/Bitrix24Account.php b/src/Bitrix24Accounts/Entity/Bitrix24Account.php index 9207ef3..e8c5029 100644 --- a/src/Bitrix24Accounts/Entity/Bitrix24Account.php +++ b/src/Bitrix24Accounts/Entity/Bitrix24Account.php @@ -188,7 +188,7 @@ public function applicationInstalled(?string $applicationToken): void ); } - if ('' !== $applicationToken) { + if (!empty($applicationToken)) { $this->applicationToken = $applicationToken; } @@ -350,18 +350,6 @@ private function guardTokenMismatch(string $applicationToken): void } } - private function guardApplicationIsActive(): void - { - if (Bitrix24AccountStatus::active !== $this->status) { - throw new InvalidArgumentException( - sprintf( - 'for uninstall account must be in status «active», current status - «%s»', - $this->status->name - ) - ); - } - } - private function addAccountCreatedEventIfNeeded(bool $isEmitCreatedEvent): void { if ($isEmitCreatedEvent) { diff --git a/tests/Functional/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationRepositoryTest.php b/tests/Functional/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationRepositoryTest.php index e332b53..b3f985c 100644 --- a/tests/Functional/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationRepositoryTest.php +++ b/tests/Functional/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationRepositoryTest.php @@ -46,9 +46,6 @@ protected function createApplicationInstallationImplementation( { return new ApplicationInstallation( $uuid, - $applicationInstallationStatus, - $createdAt, - $updatedAt, $bitrix24AccountUuid, $applicationStatus, $portalLicenseFamily, diff --git a/tests/Functional/Bitrix24Accounts/Infrastructure/Doctrine/Bitrix24AccountRepositoryTest.php b/tests/Functional/Bitrix24Accounts/Infrastructure/Doctrine/Bitrix24AccountRepositoryTest.php index b33b88a..6d4c1ac 100644 --- a/tests/Functional/Bitrix24Accounts/Infrastructure/Doctrine/Bitrix24AccountRepositoryTest.php +++ b/tests/Functional/Bitrix24Accounts/Infrastructure/Doctrine/Bitrix24AccountRepositoryTest.php @@ -41,6 +41,7 @@ protected function createBitrix24AccountImplementation( Uuid $uuid, int $bitrix24UserId, bool $isBitrix24UserAdmin, + bool $isMasterAccount, string $memberId, string $domainUrl, AuthToken $authToken, @@ -55,7 +56,8 @@ protected function createBitrix24AccountImplementation( $domainUrl, $authToken, $applicationVersion, - $applicationScope + $applicationScope, + $isMasterAccount ); } From 559a52f9b548a052d76d533328643ba458ac531a Mon Sep 17 00:00:00 2001 From: KarlsonComplete Date: Sat, 7 Jun 2025 12:57:19 +0300 Subject: [PATCH 33/49] =?UTF-8?q?=D0=9F=D0=BE=D0=BF=D1=80=D0=B0=D0=B2?= =?UTF-8?q?=D0=B8=D0=BB=20=D1=82=D0=B5=D1=81=D1=82=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Entity/ApplicationInstallation.php | 5 ----- .../ApplicationInstallationRepository.php | 18 ++++++++++-------- .../UseCase/InstallFinish/Handler.php | 2 +- .../UseCase/InstallStart/Handler.php | 1 + .../UseCase/Uninstall/Handler.php | 2 +- .../UseCase/RenewAuthToken/HandlerTest.php | 1 + .../UseCase/Uninstall/HandlerTest.php | 1 + .../UseCase/UpdateVersion/HandlerTest.php | 2 ++ 8 files changed, 17 insertions(+), 15 deletions(-) diff --git a/src/ApplicationInstallations/Entity/ApplicationInstallation.php b/src/ApplicationInstallations/Entity/ApplicationInstallation.php index fa4d878..4cdcbe4 100644 --- a/src/ApplicationInstallations/Entity/ApplicationInstallation.php +++ b/src/ApplicationInstallations/Entity/ApplicationInstallation.php @@ -77,11 +77,6 @@ public function getContactPersonId(): ?Uuid return $this->contactPersonId; } - public function getApplicationToken(): string - { - return $this->applicationToken; - } - #[\Override] public function changeContactPerson(Uuid $uuid): void { diff --git a/src/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationRepository.php b/src/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationRepository.php index ec7b1eb..f07d000 100644 --- a/src/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationRepository.php +++ b/src/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationRepository.php @@ -37,8 +37,7 @@ public function getById(Uuid $uuid): ApplicationInstallationInterface ->setParameter('uuid', $uuid) ->setParameter('status', ApplicationInstallationStatus::deleted) ->getQuery() - ->getOneOrNullResult() - ; + ->getOneOrNullResult(); if (null === $applicationInstallation) { throw new ApplicationInstallationNotFoundException( @@ -54,6 +53,12 @@ public function delete(Uuid $uuid): void { $applicationInstallation = $this->getEntityManager()->getRepository(ApplicationInstallation::class)->find($uuid); + if ($applicationInstallation == null) { + throw new ApplicationInstallationNotFoundException( + sprintf('Application installation with uuid %s not found', $uuid->toRfc4122()) + ); + } + if (ApplicationInstallationStatus::deleted !== $applicationInstallation->getStatus()) { throw new InvalidArgumentException( sprintf('you cannot delete application installed because you status must be deleted your status %s', $applicationInstallation->getStatus()->name) @@ -72,8 +77,7 @@ public function findByBitrix24AccountId(Uuid $uuid): ApplicationInstallationInte ->where('appInstallation.bitrix24AccountId = :bitrix24AccountId') ->setParameter('bitrix24AccountId', $uuid) ->getQuery() - ->getOneOrNullResult() - ; + ->getOneOrNullResult(); } public function findActiveApplicationInstallations(string $memberId): array @@ -85,8 +89,7 @@ public function findActiveApplicationInstallations(string $memberId): array ->setParameter('statuses', [ApplicationInstallationStatus::active, ApplicationInstallationStatus::new]) ->setParameter('memberId', $memberId) ->getQuery() - ->getResult() - ; + ->getResult(); } #[\Override] @@ -101,8 +104,7 @@ public function findByExternalId(string $externalId): array ->where('appInstallation.externalId = :externalId') ->setParameter('externalId', $externalId) ->getQuery() - ->getResult() - ; + ->getResult(); } public function findActiveByAccountId(Uuid $b24AccountId): ApplicationInstallationInterface|null diff --git a/src/Bitrix24Accounts/UseCase/InstallFinish/Handler.php b/src/Bitrix24Accounts/UseCase/InstallFinish/Handler.php index 826f3d2..896bca7 100644 --- a/src/Bitrix24Accounts/UseCase/InstallFinish/Handler.php +++ b/src/Bitrix24Accounts/UseCase/InstallFinish/Handler.php @@ -39,7 +39,7 @@ public function handle(Command $command): void /** @var AggregateRootEventsEmitterInterface|Bitrix24AccountInterface $bitrix24Account */ $bitrix24Account = $this->getSingleAccountByMemberId($command->domain->value, $command->memberId, $command->bitrix24UserId); - $bitrix24Account->applicationInstalled(); + $bitrix24Account->applicationInstalled(null); $this->bitrix24AccountRepository->save($bitrix24Account); $this->flusher->flush($bitrix24Account); diff --git a/src/Bitrix24Accounts/UseCase/InstallStart/Handler.php b/src/Bitrix24Accounts/UseCase/InstallStart/Handler.php index d8bf7d1..76fe880 100644 --- a/src/Bitrix24Accounts/UseCase/InstallStart/Handler.php +++ b/src/Bitrix24Accounts/UseCase/InstallStart/Handler.php @@ -37,6 +37,7 @@ public function handle(Command $command): void $command->authToken, $command->applicationVersion, $command->applicationScope, + false, true ); diff --git a/src/Bitrix24Accounts/UseCase/Uninstall/Handler.php b/src/Bitrix24Accounts/UseCase/Uninstall/Handler.php index 9c672de..1a8bde6 100644 --- a/src/Bitrix24Accounts/UseCase/Uninstall/Handler.php +++ b/src/Bitrix24Accounts/UseCase/Uninstall/Handler.php @@ -32,7 +32,7 @@ public function handle(Command $command): void $accounts = $this->bitrix24AccountRepository->findByApplicationToken($command->applicationToken); $accountsCount = count($accounts); foreach ($accounts as $account) { - $account->applicationUninstalled(); + $account->applicationUninstalled(null); $this->bitrix24AccountRepository->save($account); } diff --git a/tests/Functional/Bitrix24Accounts/UseCase/RenewAuthToken/HandlerTest.php b/tests/Functional/Bitrix24Accounts/UseCase/RenewAuthToken/HandlerTest.php index 87000e8..479f2cb 100644 --- a/tests/Functional/Bitrix24Accounts/UseCase/RenewAuthToken/HandlerTest.php +++ b/tests/Functional/Bitrix24Accounts/UseCase/RenewAuthToken/HandlerTest.php @@ -70,6 +70,7 @@ public function testRenewAuthTokenWithoutBitrix24UserId(): void $bitrix24Account = (new Bitrix24AccountBuilder()) ->withStatus(Bitrix24AccountStatus::new) ->withApplicationToken($applicationToken) + ->withInstalled() ->build(); $this->repository->save($bitrix24Account); $this->flusher->flush(); diff --git a/tests/Functional/Bitrix24Accounts/UseCase/Uninstall/HandlerTest.php b/tests/Functional/Bitrix24Accounts/UseCase/Uninstall/HandlerTest.php index a902791..53f08b4 100644 --- a/tests/Functional/Bitrix24Accounts/UseCase/Uninstall/HandlerTest.php +++ b/tests/Functional/Bitrix24Accounts/UseCase/Uninstall/HandlerTest.php @@ -75,6 +75,7 @@ public function testUninstallApplication(): void $bitrix24Account = (new Bitrix24AccountBuilder()) ->withStatus(Bitrix24AccountStatus::new) ->withApplicationToken($applicationToken) + ->withInstalled() ->build(); $this->repository->save($bitrix24Account); diff --git a/tests/Functional/Bitrix24Accounts/UseCase/UpdateVersion/HandlerTest.php b/tests/Functional/Bitrix24Accounts/UseCase/UpdateVersion/HandlerTest.php index c80d27e..12412d7 100644 --- a/tests/Functional/Bitrix24Accounts/UseCase/UpdateVersion/HandlerTest.php +++ b/tests/Functional/Bitrix24Accounts/UseCase/UpdateVersion/HandlerTest.php @@ -71,6 +71,7 @@ public function testSuccessUpdateVersion(): void $bitrix24Account = (new Bitrix24AccountBuilder()) ->withStatus(Bitrix24AccountStatus::new) ->withApplicationToken($applicationToken) + ->withInstalled() ->build(); $this->repository->save($bitrix24Account); @@ -130,6 +131,7 @@ public function testNotValidVersionForUpdateVersion(): void $bitrix24Account = (new Bitrix24AccountBuilder()) ->withStatus(Bitrix24AccountStatus::new) ->withApplicationToken($applicationToken) + ->withInstalled() ->build(); From 77c4196d00e7fe5785bc30e6e9776e29fcdb024e Mon Sep 17 00:00:00 2001 From: KarlsonComplete Date: Sun, 8 Jun 2025 17:42:43 +0300 Subject: [PATCH 34/49] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8?= =?UTF-8?q?=D0=BB=20=D0=B4=D0=BE=D0=BA=20=D0=B1=D0=BB=D0=BE=D0=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Entity/ApplicationInstallation.php | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/ApplicationInstallations/Entity/ApplicationInstallation.php b/src/ApplicationInstallations/Entity/ApplicationInstallation.php index 4cdcbe4..7216c1b 100644 --- a/src/ApplicationInstallations/Entity/ApplicationInstallation.php +++ b/src/ApplicationInstallations/Entity/ApplicationInstallation.php @@ -20,6 +20,19 @@ use Symfony\Component\Uid\Uuid; use Bitrix24\SDK\Core\Exceptions\LogicException; +/** + * Установка может происходить по 2 сценриям. + * 1) UI - Пользователь запускает установку через интерфейс. + * Bitrix24 отправляет первичный запрос на /install.php с параметрами: + * AUTH_ID, REFRESH_ID, member_id в теле запроса. Без application_token + * Система создаёт Bitrix24Account в статусе new. + * Bitrix24 отправляет событие ONAPPINSTALL на /event-handler.php и передает application_token + * Вызывается applicationInstalled($applicationToken) с полученным токеном. + * 2) Без UI - Установка инициируется прямым POST-запросом с полным набором credentials. + * Сразу создается Bitrix24Account. У установщика и у аккаунта вызывается метод с переданыым токеном: + * $bitrix24Account->applicationInstalled($applicationToken); + * $applicationInstallation->applicationInstalled($applicationToken); + */ class ApplicationInstallation extends AggregateRoot implements ApplicationInstallationInterface { From c8a882c2f4bb0d4f4f30854aca0b60e2edace930 Mon Sep 17 00:00:00 2001 From: KarlsonComplete Date: Sat, 14 Jun 2025 22:10:30 +0300 Subject: [PATCH 35/49] . --- .../Doctrine/ApplicationInstallationRepository.php | 2 ++ src/Bitrix24Accounts/Entity/Bitrix24Account.php | 2 +- .../Infrastructure/Doctrine/Bitrix24AccountRepository.php | 2 ++ src/Bitrix24Accounts/UseCase/Uninstall/Handler.php | 1 + .../Bitrix24Accounts/UseCase/Uninstall/HandlerTest.php | 2 +- 5 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationRepository.php b/src/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationRepository.php index f07d000..a2067e3 100644 --- a/src/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationRepository.php +++ b/src/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationRepository.php @@ -75,6 +75,7 @@ public function findByBitrix24AccountId(Uuid $uuid): ApplicationInstallationInte return $this->getEntityManager()->getRepository(ApplicationInstallation::class) ->createQueryBuilder('appInstallation') ->where('appInstallation.bitrix24AccountId = :bitrix24AccountId') + ->orderBy('appInstallation.createdAt', 'DESC') ->setParameter('bitrix24AccountId', $uuid) ->getQuery() ->getOneOrNullResult(); @@ -102,6 +103,7 @@ public function findByExternalId(string $externalId): array return $this->getEntityManager()->getRepository(ApplicationInstallation::class) ->createQueryBuilder('appInstallation') ->where('appInstallation.externalId = :externalId') + ->orderBy('appInstallation.createdAt', 'DESC') ->setParameter('externalId', $externalId) ->getQuery() ->getResult(); diff --git a/src/Bitrix24Accounts/Entity/Bitrix24Account.php b/src/Bitrix24Accounts/Entity/Bitrix24Account.php index e8c5029..fea5dbf 100644 --- a/src/Bitrix24Accounts/Entity/Bitrix24Account.php +++ b/src/Bitrix24Accounts/Entity/Bitrix24Account.php @@ -205,7 +205,7 @@ public function applicationInstalled(?string $applicationToken): void public function applicationUninstalled(?string $applicationToken): void { $this->status = Bitrix24AccountStatus::deleted; - $this->updatedAt = new CarbonImmutable(); + $this->updatedAt = new CarbonImmutable();; $this->events[] = new Bitrix24AccountApplicationUninstalledEvent( $this->id, new CarbonImmutable() diff --git a/src/Bitrix24Accounts/Infrastructure/Doctrine/Bitrix24AccountRepository.php b/src/Bitrix24Accounts/Infrastructure/Doctrine/Bitrix24AccountRepository.php index 1e5e9a7..fd9c24d 100644 --- a/src/Bitrix24Accounts/Infrastructure/Doctrine/Bitrix24AccountRepository.php +++ b/src/Bitrix24Accounts/Infrastructure/Doctrine/Bitrix24AccountRepository.php @@ -56,6 +56,7 @@ public function existsById(Uuid $uuid): bool ->createQueryBuilder('b24') ->where('b24.id = :id') ->andWhere('b24.status != :status') + ->orderBy('b24.createdAt', 'DESC') ->setParameter('id', $uuid) ->setParameter('status', Bitrix24AccountStatus::deleted) ->getQuery() @@ -154,6 +155,7 @@ public function findActiveByMemberId(string $memberId): array ->createQueryBuilder('b24') ->where('b24.memberId = :memberId') ->andWhere('b24.status IN (:statuses)') + ->orderBy('b24.createdAt', 'DESC') ->setParameter('memberId', $memberId) ->setParameter('statuses', $activeStatuses) ->getQuery() diff --git a/src/Bitrix24Accounts/UseCase/Uninstall/Handler.php b/src/Bitrix24Accounts/UseCase/Uninstall/Handler.php index 1a8bde6..b2e0182 100644 --- a/src/Bitrix24Accounts/UseCase/Uninstall/Handler.php +++ b/src/Bitrix24Accounts/UseCase/Uninstall/Handler.php @@ -30,6 +30,7 @@ public function handle(Command $command): void /** @var AggregateRootEventsEmitterInterface[]|Bitrix24AccountInterface[] $accounts */ $accounts = $this->bitrix24AccountRepository->findByApplicationToken($command->applicationToken); + $accountsCount = count($accounts); foreach ($accounts as $account) { $account->applicationUninstalled(null); diff --git a/tests/Functional/Bitrix24Accounts/UseCase/Uninstall/HandlerTest.php b/tests/Functional/Bitrix24Accounts/UseCase/Uninstall/HandlerTest.php index 53f08b4..d761e60 100644 --- a/tests/Functional/Bitrix24Accounts/UseCase/Uninstall/HandlerTest.php +++ b/tests/Functional/Bitrix24Accounts/UseCase/Uninstall/HandlerTest.php @@ -76,11 +76,11 @@ public function testUninstallApplication(): void ->withStatus(Bitrix24AccountStatus::new) ->withApplicationToken($applicationToken) ->withInstalled() + ->withSetToken() ->build(); $this->repository->save($bitrix24Account); $this->flusher->flush(); - $this->handler->handle(new Bitrix24Accounts\UseCase\Uninstall\Command($applicationToken)); $this->expectException(Bitrix24AccountNotFoundException::class); From 595dab78664b1da2e4d952b9742dc844443ceda0 Mon Sep 17 00:00:00 2001 From: KarlsonComplete Date: Sun, 22 Jun 2025 18:04:13 +0300 Subject: [PATCH 36/49] =?UTF-8?q?=D0=9E=D0=B1=D0=BD=D0=BE=D0=B2=D0=B8?= =?UTF-8?q?=D0=BB=D0=B8=20=D0=BC=D0=B5=D1=82=D0=BE=D0=B4=D1=8B=20=D0=B2=20?= =?UTF-8?q?=D1=83=D1=81=D1=82=D0=B0=D0=BD=D0=BE=D0=B2=D1=89=D0=B8=D0=BA?= =?UTF-8?q?=D0=B5.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Entity/ApplicationInstallation.php | 83 +++++++++---------- 1 file changed, 38 insertions(+), 45 deletions(-) diff --git a/src/ApplicationInstallations/Entity/ApplicationInstallation.php b/src/ApplicationInstallations/Entity/ApplicationInstallation.php index 7216c1b..7407170 100644 --- a/src/ApplicationInstallations/Entity/ApplicationInstallation.php +++ b/src/ApplicationInstallations/Entity/ApplicationInstallation.php @@ -90,63 +90,18 @@ public function getContactPersonId(): ?Uuid return $this->contactPersonId; } - #[\Override] - public function changeContactPerson(Uuid $uuid): void - { - $this->updatedAt = new CarbonImmutable(); - - $this->contactPersonId = $uuid; - - $this->events[] = new Events\ApplicationInstallationContactPersonChangedEvent( - $this->id, - $this->updatedAt, - $this->contactPersonId, - $uuid - ); - } - #[\Override] public function getBitrix24PartnerContactPersonId(): ?Uuid { return $this->bitrix24PartnerContactPersonId; } - #[\Override] - public function changeBitrix24PartnerContactPerson(Uuid $uuid): void - { - $this->updatedAt = new CarbonImmutable(); - - $this->bitrix24PartnerContactPersonId = $uuid; - - $this->events[] = new Events\ApplicationInstallationBitrix24PartnerContactPersonChangedEvent( - $this->id, - $this->updatedAt, - $this->bitrix24PartnerContactPersonId, - $uuid - ); - } - #[\Override] public function getBitrix24PartnerId(): ?Uuid { return $this->bitrix24PartnerId; } - #[\Override] - public function changeBitrix24Partner(Uuid $uuid): void - { - $this->updatedAt = new CarbonImmutable(); - - $this->bitrix24PartnerId = $uuid; - - $this->events[] = new Events\ApplicationInstallationBitrix24PartnerChangedEvent( - $this->id, - $this->updatedAt, - $this->bitrix24PartnerId, - $uuid - ); - } - #[\Override] public function getExternalId(): ?string { @@ -365,11 +320,13 @@ private function addApplicationCreatedEventIfNeeded(bool $isEmitCreatedEvent): v } } + #[\Override] public function isApplicationTokenValid(string $applicationToken): bool { return $this->applicationToken === $applicationToken; } + #[\Override] public function setApplicationToken(string $applicationToken): void { if ('' === $applicationToken) { @@ -379,4 +336,40 @@ public function setApplicationToken(string $applicationToken): void $this->updatedAt = new CarbonImmutable(); $this->applicationToken = $applicationToken; } + + #[\Override] + public function linkContactPerson(Uuid $uuid): void + { + // TODO: Implement linkContactPerson() method. + } + + #[\Override] + public function unlinkContactPerson(): void + { + // TODO: Implement unlinkContactPerson() method. + } + + #[\Override] + public function linkBitrix24PartnerContactPerson(Uuid $uuid): void + { + // TODO: Implement linkBitrix24PartnerContactPerson() method. + } + + #[\Override] + public function unlinkBitrix24PartnerContactPerson(): void + { + // TODO: Implement unlinkBitrix24PartnerContactPerson() method. + } + + #[\Override] + public function linkBitrix24Partner(Uuid $uuid): void + { + // TODO: Implement linkBitrix24Partner() method. + } + + #[\Override] + public function unlinkBitrix24Partner(): void + { + // TODO: Implement unlinkBitrix24Partner() method. + } } From 12dde1390a75d6599cc8d98fd67cad56462412d5 Mon Sep 17 00:00:00 2001 From: KarlsonComplete Date: Tue, 24 Jun 2025 23:39:47 +0300 Subject: [PATCH 37/49] =?UTF-8?q?=D0=9E=D0=B1=D0=BD=D0=BE=D0=B2=D0=B8?= =?UTF-8?q?=D0=BB=D0=B8=20=D0=BC=D0=B5=D1=82=D0=BE=D0=B4=D1=8B=20=D0=B2=20?= =?UTF-8?q?=D1=83=D1=81=D1=82=D0=B0=D0=BD=D0=BE=D0=B2=D1=89=D0=B8=D0=BA?= =?UTF-8?q?=D0=B5.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Entity/ApplicationInstallation.php | 82 +++++++++++++++---- .../ApplicationInstallationRepository.php | 12 --- 2 files changed, 65 insertions(+), 29 deletions(-) diff --git a/src/ApplicationInstallations/Entity/ApplicationInstallation.php b/src/ApplicationInstallations/Entity/ApplicationInstallation.php index 7407170..61e9818 100644 --- a/src/ApplicationInstallations/Entity/ApplicationInstallation.php +++ b/src/ApplicationInstallations/Entity/ApplicationInstallation.php @@ -10,6 +10,7 @@ use Bitrix24\SDK\Application\Contracts\ApplicationInstallations\Entity\ApplicationInstallationStatus; use Bitrix24\SDK\Application\Contracts\ApplicationInstallations\Events; use Bitrix24\SDK\Application\Contracts\ApplicationInstallations\Events\ApplicationInstallationBlockedEvent; +use Bitrix24\SDK\Application\Contracts\ApplicationInstallations\Events\ApplicationInstallationContactPersonLinkedEvent; use Bitrix24\SDK\Application\Contracts\ApplicationInstallations\Events\ApplicationInstallationCreatedEvent; use Bitrix24\SDK\Application\Contracts\ApplicationInstallations\Events\ApplicationInstallationFinishedEvent; use Bitrix24\SDK\Application\Contracts\ApplicationInstallations\Events\ApplicationInstallationUnblockedEvent; @@ -42,18 +43,19 @@ class ApplicationInstallation extends AggregateRoot implements ApplicationInstal private ApplicationInstallationStatus $status; public function __construct( - private readonly Uuid $id, - private readonly Uuid $bitrix24AccountId, - private ApplicationStatus $applicationStatus, + private readonly Uuid $id, + private readonly Uuid $bitrix24AccountId, + private ApplicationStatus $applicationStatus, private PortalLicenseFamily $portalLicenseFamily, - private ?int $portalUsersCount, - private ?Uuid $contactPersonId, - private ?Uuid $bitrix24PartnerContactPersonId, - private ?Uuid $bitrix24PartnerId, - private ?string $externalId, - private ?string $comment = null, - private $isEmitApplicationInstallationCreatedEvent = false - ) { + private ?int $portalUsersCount, + private ?Uuid $contactPersonId, + private ?Uuid $bitrix24PartnerContactPersonId, + private ?Uuid $bitrix24PartnerId, + private ?string $externalId, + private ?string $comment = null, + private $isEmitApplicationInstallationCreatedEvent = false + ) + { $this->createdAt = new CarbonImmutable(); $this->updatedAt = new CarbonImmutable(); $this->status = ApplicationInstallationStatus::new; @@ -340,36 +342,82 @@ public function setApplicationToken(string $applicationToken): void #[\Override] public function linkContactPerson(Uuid $uuid): void { - // TODO: Implement linkContactPerson() method. + $this->updatedAt = new CarbonImmutable(); + $this->contactPersonId = $uuid; + + $this->events[] = new ApplicationInstallationContactPersonLinkedEvent( + $this->id, + $this->updatedAt, + $this->contactPersonId + ); } #[\Override] public function unlinkContactPerson(): void { - // TODO: Implement unlinkContactPerson() method. + $this->updatedAt = new CarbonImmutable(); + + $this->events[] = new Events\ApplicationInstallationContactPersonUnlinkedEvent( + $this->id, + $this->updatedAt, + $this->contactPersonId + ); + + $this->contactPersonId = null; } #[\Override] public function linkBitrix24PartnerContactPerson(Uuid $uuid): void { - // TODO: Implement linkBitrix24PartnerContactPerson() method. + $this->updatedAt = new CarbonImmutable(); + $this->bitrix24PartnerContactPersonId = $uuid; + + $this->events[] = new Events\ApplicationInstallationBitrix24PartnerContactPersonLinkedEvent( + $this->id, + $this->updatedAt, + $this->bitrix24PartnerContactPersonId + ); } #[\Override] public function unlinkBitrix24PartnerContactPerson(): void { - // TODO: Implement unlinkBitrix24PartnerContactPerson() method. + $this->updatedAt = new CarbonImmutable(); + + $this->events[] = new Events\ApplicationInstallationBitrix24PartnerContactPersonUnlinkedEvent( + $this->id, + $this->updatedAt, + $this->bitrix24PartnerContactPersonId + ); + + $this->bitrix24PartnerContactPersonId = null; } #[\Override] public function linkBitrix24Partner(Uuid $uuid): void { - // TODO: Implement linkBitrix24Partner() method. + $this->updatedAt = new CarbonImmutable(); + $this->bitrix24PartnerId = $uuid; + + $this->events[] = new Events\ApplicationInstallationBitrix24PartnerLinkedEvent( + $this->id, + $this->updatedAt, + $this->bitrix24PartnerId + ); } #[\Override] public function unlinkBitrix24Partner(): void { - // TODO: Implement unlinkBitrix24Partner() method. + $this->updatedAt = new CarbonImmutable(); + + $this->events[] = new Events\ApplicationInstallationBitrix24PartnerUnlinkedEvent( + $this->id, + $this->updatedAt, + $this->bitrix24PartnerId + ); + + $this->bitrix24PartnerId = null; + } } diff --git a/src/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationRepository.php b/src/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationRepository.php index a2067e3..79d08d1 100644 --- a/src/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationRepository.php +++ b/src/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationRepository.php @@ -81,18 +81,6 @@ public function findByBitrix24AccountId(Uuid $uuid): ApplicationInstallationInte ->getOneOrNullResult(); } - public function findActiveApplicationInstallations(string $memberId): array - { - return $this->getEntityManager()->getRepository(ApplicationInstallation::class) - ->createQueryBuilder('appInstallation') - ->where('appInstallation.status IN (:statuses)') - ->andWhere('appInstallation.memberId = :memberId') - ->setParameter('statuses', [ApplicationInstallationStatus::active, ApplicationInstallationStatus::new]) - ->setParameter('memberId', $memberId) - ->getQuery() - ->getResult(); - } - #[\Override] public function findByExternalId(string $externalId): array { From 7e4eb8f6abc092166d21415784c75c2d70fa6edd Mon Sep 17 00:00:00 2001 From: KarlsonComplete Date: Sat, 28 Jun 2025 19:13:26 +0300 Subject: [PATCH 38/49] . --- .../UseCase/Uninstall/Command.php | 9 ++- .../UseCase/Uninstall/Handler.php | 57 ++++++++++--------- .../ApplicationInstallationBuilder.php | 15 ++++- .../UseCase/Uninstall/HandlerTest.php | 10 +++- 4 files changed, 59 insertions(+), 32 deletions(-) diff --git a/src/ApplicationInstallations/UseCase/Uninstall/Command.php b/src/ApplicationInstallations/UseCase/Uninstall/Command.php index f4a0624..6d68fcd 100644 --- a/src/ApplicationInstallations/UseCase/Uninstall/Command.php +++ b/src/ApplicationInstallations/UseCase/Uninstall/Command.php @@ -4,10 +4,14 @@ namespace Bitrix24\Lib\ApplicationInstallations\UseCase\Uninstall; +use Bitrix24\Lib\Bitrix24Accounts\ValueObjects\Domain; + readonly class Command { public function __construct( - public string $applicationToken, + public Domain $domainUrl, + public string $memberId, + public string $applicationToken ) { $this->validate(); @@ -19,5 +23,8 @@ private function validate(): void throw new \InvalidArgumentException('applicationToken must be a non-empty string.'); } + if ('' === $this->memberId) { + throw new \InvalidArgumentException('Member ID must be a non-empty string.'); + } } } \ No newline at end of file diff --git a/src/ApplicationInstallations/UseCase/Uninstall/Handler.php b/src/ApplicationInstallations/UseCase/Uninstall/Handler.php index c5a9d9c..57afe3a 100644 --- a/src/ApplicationInstallations/UseCase/Uninstall/Handler.php +++ b/src/ApplicationInstallations/UseCase/Uninstall/Handler.php @@ -28,41 +28,42 @@ public function __construct( public function handle(Command $command): void { $this->logger->info('ApplicationInstallations.Uninstall.start', [ - 'applicationToken' => $command->applicationToken, + 'domainUrl' => $command->domainUrl, + 'memberId' => $command->memberId, + 'applicationToken' => $command->applicationToken ]); - /** @var AggregateRootEventsEmitterInterface|ApplicationInstallationInterface $activeApplicationInstallation */ - $activeApplicationInstallation = $this->getActiveApplicationInstallation(); - - if (!empty($activeApplicationInstallation)) { - - //Решили 13 апреля расширить контракт установки и добавить получения токена - $activeApplicationToken = $activeApplicationInstallation->getApplicationToken(); - - $oldBitrix24AccountId = $activeApplicationInstallation->getBitrix24AccountId(); - $oldBitrix24Account = $this->bitrix24AccountRepository->getById($oldBitrix24AccountId); - /** @var AggregateRootEventsEmitterInterface[]|Bitrix24AccountInterface[] $accounts */ - $accounts = $this->bitrix24AccountRepository->findByMemberId($oldBitrix24Account->getMemberId()); - $accountsCount = count($accounts); - foreach ($accounts as $account) { - //Сюда пробрасываем токен полученный выше - $account->applicationUninstalled($activeApplicationToken); - $this->bitrix24AccountRepository->save($account); + /* + * Аккаунтов может быть несколько , но деинсталяция на портале проводится только 1 раз , то есть есть мастер аккаунт который нужно получать. + * У остальных аккаунтов деинсталяции быть не может это просто (доступы/авторизации). + */ + /** @var AggregateRootEventsEmitterInterface|Bitrix24AccountInterface[] $b24Accounts */ + $b24Accounts = $this->bitrix24AccountRepository->findActiveByMemberId($command->memberId); + + if ($b24Accounts !== []) { + $entitiesToFlush = []; + foreach ($b24Accounts as $b24Account) { + $isMaster = $b24Account->isMasterAccount(); + if ($isMaster) { + $activeInstallation = $this->applicationInstallationRepository->findActiveByAccountId($b24Account->getId()); + $isTokenValid = $activeInstallation->isApplicationTokenValid($command->applicationToken); + if ($isTokenValid) { + $activeInstallation->applicationUninstalled($command->applicationToken); + $this->applicationInstallationRepository->save($activeInstallation); + $entitiesToFlush[] = $activeInstallation; + } + } + // Тут нужно в методе что то делать с токеном ? Удалять же его по идеи не надо . + $b24Account->applicationUninstalled(null); + $this->bitrix24AccountRepository->save($b24Account); + $entitiesToFlush[] = $b24Account; } - $activeApplicationInstallation->applicationUninstalled(); - - $this->flusher->flush(...$accounts); + $this->flusher->flush(...$entitiesToFlush); } $this->logger->info( - 'ApplicationInstallations.Uninstall.Finish', - [ - 'applicationInstallationId' => $activeApplicationInstallation->getId(), - 'applicationToken' => $command->applicationToken, - 'bitrix24AccountId' => $activeApplicationInstallation->getBitrix24AccountId(), - 'accountsUninstalledCount' => $accountsCount, - ] + 'ApplicationInstallations.Uninstall.Finish' ); } diff --git a/tests/Functional/ApplicationInstallations/Builders/ApplicationInstallationBuilder.php b/tests/Functional/ApplicationInstallations/Builders/ApplicationInstallationBuilder.php index 63d6a05..496a769 100644 --- a/tests/Functional/ApplicationInstallations/Builders/ApplicationInstallationBuilder.php +++ b/tests/Functional/ApplicationInstallations/Builders/ApplicationInstallationBuilder.php @@ -35,6 +35,8 @@ class ApplicationInstallationBuilder private ?string $comment = null; + private ?string $applicationToken = null; + public function __construct() { $this->id = Uuid::v7(); @@ -52,6 +54,13 @@ public function withExternalId(string $externalId): self return $this; } + public function withApplicationToken(string $applicationToken): self + { + $this->applicationToken = $applicationToken; + + return $this; + } + public function withApplicationStatusInstallation(ApplicationInstallationStatus $applicationInstallationStatus): self { $this->status = $applicationInstallationStatus; @@ -97,7 +106,11 @@ public function build(): ApplicationInstallation if (!empty($this->status)) { if ($this->status == ApplicationInstallationStatus::active) { - $applicationInstallation->applicationInstalled(); + if (!empty($this->applicationToken)) { + $applicationInstallation->applicationInstalled($this->applicationToken); + }else{ + $applicationInstallation->applicationInstalled(); + } } } diff --git a/tests/Functional/ApplicationInstallations/UseCase/Uninstall/HandlerTest.php b/tests/Functional/ApplicationInstallations/UseCase/Uninstall/HandlerTest.php index 3d14ebf..1aaf7e2 100644 --- a/tests/Functional/ApplicationInstallations/UseCase/Uninstall/HandlerTest.php +++ b/tests/Functional/ApplicationInstallations/UseCase/Uninstall/HandlerTest.php @@ -44,6 +44,7 @@ use Bitrix24\Lib\Bitrix24Accounts\Infrastructure\Doctrine\Bitrix24AccountRepository; use Symfony\Component\Uid\Uuid; +use function Symfony\Component\Translation\t; /** * @internal @@ -83,12 +84,14 @@ protected function setUp(): void #[Test] public function testUninstallApplicationInstallation(): void { - //Загружаем в базу данных аккаунт и установку приложения для тестирования переустановки. + //Загружаем в базу данных аккаунт и установку приложения для их деинсталяции. $applicationToken = Uuid::v7()->toRfc4122(); $oldBitrix24Account = (new Bitrix24AccountBuilder()) ->withApplicationScope(new Scope(['crm'])) ->withStatus(Bitrix24AccountStatus::new) ->withApplicationToken($applicationToken) + ->withMaster(true) + ->withSetToken() ->build(); @@ -97,6 +100,7 @@ public function testUninstallApplicationInstallation(): void ->withPortalLicenseFamily(PortalLicenseFamily::free) ->withBitrix24AccountId($oldBitrix24Account->getId()) ->withApplicationStatusInstallation(ApplicationInstallationStatus::active) + ->withApplicationToken($applicationToken) ->build(); $this->bitrix24accountRepository->save($oldBitrix24Account); @@ -105,7 +109,9 @@ public function testUninstallApplicationInstallation(): void $this->handler->handle( new ApplicationInstallations\UseCase\Uninstall\Command( - $applicationToken, + new Domain($oldBitrix24Account->getDomainUrl()), + $oldBitrix24Account->getMemberId(), + $applicationToken ) ); From b854025ca4fb61bc28f79ec213c5c2fd77ce795a Mon Sep 17 00:00:00 2001 From: KarlsonComplete Date: Sun, 29 Jun 2025 10:42:56 +0300 Subject: [PATCH 39/49] . --- src/Bitrix24Accounts/Entity/Bitrix24Account.php | 2 -- .../Entity/ApplicationInstallationTest.php | 6 ++---- tests/Unit/Bitrix24Accounts/Entity/Bitrix24AccountTest.php | 4 +++- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/Bitrix24Accounts/Entity/Bitrix24Account.php b/src/Bitrix24Accounts/Entity/Bitrix24Account.php index fea5dbf..d7dd332 100644 --- a/src/Bitrix24Accounts/Entity/Bitrix24Account.php +++ b/src/Bitrix24Accounts/Entity/Bitrix24Account.php @@ -215,8 +215,6 @@ public function applicationUninstalled(?string $applicationToken): void #[\Override] public function isApplicationTokenValid(string $applicationToken): bool { - $this->guardTokenMismatch($applicationToken); - return $this->applicationToken === $applicationToken; } diff --git a/tests/Unit/ApplicationInstallations/Entity/ApplicationInstallationTest.php b/tests/Unit/ApplicationInstallations/Entity/ApplicationInstallationTest.php index f103667..e7de8fe 100644 --- a/tests/Unit/ApplicationInstallations/Entity/ApplicationInstallationTest.php +++ b/tests/Unit/ApplicationInstallations/Entity/ApplicationInstallationTest.php @@ -37,9 +37,6 @@ protected function createApplicationInstallationImplementation( ApplicationInstallationInterface { return new ApplicationInstallation( $uuid, - $applicationInstallationStatus, - $createdAt, - $updatedAt, $bitrix24AccountUuid, $applicationStatus, $portalLicenseFamily, @@ -47,7 +44,8 @@ protected function createApplicationInstallationImplementation( $clientContactPersonUuid, $partnerContactPersonUuid, $partnerUuid, - $externalId + $externalId, + null ); } } diff --git a/tests/Unit/Bitrix24Accounts/Entity/Bitrix24AccountTest.php b/tests/Unit/Bitrix24Accounts/Entity/Bitrix24AccountTest.php index f0fd0a0..66d5bf3 100644 --- a/tests/Unit/Bitrix24Accounts/Entity/Bitrix24AccountTest.php +++ b/tests/Unit/Bitrix24Accounts/Entity/Bitrix24AccountTest.php @@ -34,6 +34,7 @@ protected function createBitrix24AccountImplementation( Uuid $uuid, int $bitrix24UserId, bool $isBitrix24UserAdmin, + bool $isMasterAccount, string $memberId, string $domainUrl, AuthToken $authToken, @@ -48,7 +49,8 @@ protected function createBitrix24AccountImplementation( $domainUrl, $authToken, $applicationVersion, - $applicationScope + $applicationScope, + $isMasterAccount ); } } From 93169efea4f4d16a1d6cc25f0374610857675270 Mon Sep 17 00:00:00 2001 From: KarlsonComplete Date: Tue, 1 Jul 2025 00:27:16 +0300 Subject: [PATCH 40/49] . --- .../Entity/ApplicationInstallation.php | 19 ++++ .../UseCase/Uninstall/Handler.php | 34 +++---- .../Entity/Bitrix24Account.php | 24 +++-- .../UseCase/Uninstall/HandlerTest.php | 93 ++++++++++++++++++- 4 files changed, 140 insertions(+), 30 deletions(-) diff --git a/src/ApplicationInstallations/Entity/ApplicationInstallation.php b/src/ApplicationInstallations/Entity/ApplicationInstallation.php index 61e9818..bb99ff4 100644 --- a/src/ApplicationInstallations/Entity/ApplicationInstallation.php +++ b/src/ApplicationInstallations/Entity/ApplicationInstallation.php @@ -174,6 +174,11 @@ public function applicationUninstalled(?string $applicationToken = null): void ); } + // Это проверка для мастер аккаунтов чтобы удостовериться что передан верный токен для деинсталяции. + if ($applicationToken !== null){ + $this->guardTokenMismatch($applicationToken); + } + $this->status = ApplicationInstallationStatus::deleted; $this->updatedAt = new CarbonImmutable(); @@ -420,4 +425,18 @@ public function unlinkBitrix24Partner(): void $this->bitrix24PartnerId = null; } + + private function guardTokenMismatch(string $applicationToken): void + { + if (!$this->isApplicationTokenValid($applicationToken)) { + throw new InvalidArgumentException( + sprintf( + 'application token «%s» mismatch with application token «%s» for application installation «%s»', + $applicationToken, + $this->applicationToken, + $this->id->toRfc4122() + ) + ); + } + } } diff --git a/src/ApplicationInstallations/UseCase/Uninstall/Handler.php b/src/ApplicationInstallations/UseCase/Uninstall/Handler.php index 57afe3a..701d8ce 100644 --- a/src/ApplicationInstallations/UseCase/Uninstall/Handler.php +++ b/src/ApplicationInstallations/UseCase/Uninstall/Handler.php @@ -6,10 +6,11 @@ use Bitrix24\Lib\ApplicationInstallations\Infrastructure\Doctrine\ApplicationInstallationRepository; +use Bitrix24\Lib\Bitrix24Accounts\Entity\Bitrix24Account; use Bitrix24\Lib\Bitrix24Accounts\Infrastructure\Doctrine\Bitrix24AccountRepository; use Bitrix24\Lib\Services\Flusher; -use Bitrix24\SDK\Application\Contracts\ApplicationInstallations\Entity\ApplicationInstallationInterface; use Bitrix24\SDK\Application\Contracts\Bitrix24Accounts\Entity\Bitrix24AccountInterface; +use Bitrix24\SDK\Application\Contracts\Bitrix24Accounts\Entity\Bitrix24AccountStatus; use Bitrix24\SDK\Application\Contracts\Events\AggregateRootEventsEmitterInterface; use Psr\Log\LoggerInterface; @@ -34,11 +35,13 @@ public function handle(Command $command): void ]); /* - * Аккаунтов может быть несколько , но деинсталяция на портале проводится только 1 раз , то есть есть мастер аккаунт который нужно получать. - * У остальных аккаунтов деинсталяции быть не может это просто (доступы/авторизации). + * 1)Аккаунтов может быть несколько , но деинсталяция на портале проводится только 1 раз , то есть есть мастер аккаунт который нужно получать. + * 2)У остальных аккаунтов деинсталяции быть не может это просто (доступы/авторизации). + * 3)Может быть такой сценарий что при увольнении сотрудника особенно админа у которого была активная установка. Установка может зависнуть , + * таким образом нужно пробегаться по всем аккаунтам и установкам и проверять нету ли активных, если что деактивировать. */ /** @var AggregateRootEventsEmitterInterface|Bitrix24AccountInterface[] $b24Accounts */ - $b24Accounts = $this->bitrix24AccountRepository->findActiveByMemberId($command->memberId); + $b24Accounts = $this->bitrix24AccountRepository->findByMemberId($command->memberId); if ($b24Accounts !== []) { $entitiesToFlush = []; @@ -46,15 +49,17 @@ public function handle(Command $command): void $isMaster = $b24Account->isMasterAccount(); if ($isMaster) { $activeInstallation = $this->applicationInstallationRepository->findActiveByAccountId($b24Account->getId()); - $isTokenValid = $activeInstallation->isApplicationTokenValid($command->applicationToken); - if ($isTokenValid) { + if ($activeInstallation !== null) { $activeInstallation->applicationUninstalled($command->applicationToken); $this->applicationInstallationRepository->save($activeInstallation); $entitiesToFlush[] = $activeInstallation; } + // Тут тоже спорно получается , а если установка была по событию, а событие не произошло и токен не записался. ??? + $b24Account->applicationUninstalled($command->applicationToken); + }else{ + $b24Account->applicationUninstalled(null); } - // Тут нужно в методе что то делать с токеном ? Удалять же его по идеи не надо . - $b24Account->applicationUninstalled(null); + $this->bitrix24AccountRepository->save($b24Account); $entitiesToFlush[] = $b24Account; } @@ -66,17 +71,4 @@ public function handle(Command $command): void 'ApplicationInstallations.Uninstall.Finish' ); } - - private function getActiveApplicationInstallation(): ApplicationInstallationInterface|null - { - $activeApplicationInstallations = $this->applicationInstallationRepository->findActiveApplicationInstallations(); - - if (count($activeApplicationInstallations) > 1) { - throw new \InvalidArgumentException( - 'multiple application installations with active or new status' - ); - } - - return $activeApplicationInstallations[0] ?? null; - } } diff --git a/src/Bitrix24Accounts/Entity/Bitrix24Account.php b/src/Bitrix24Accounts/Entity/Bitrix24Account.php index d7dd332..b15a7fd 100644 --- a/src/Bitrix24Accounts/Entity/Bitrix24Account.php +++ b/src/Bitrix24Accounts/Entity/Bitrix24Account.php @@ -52,7 +52,8 @@ public function __construct( private readonly bool $isMasterAccount = false, private $isEmitBitrix24AccountCreatedEvent = false, private ?string $comment = null - ) { + ) + { $this->createdAt = new CarbonImmutable(); $this->updatedAt = new CarbonImmutable(); $this->status = Bitrix24AccountStatus::new; @@ -204,12 +205,21 @@ public function applicationInstalled(?string $applicationToken): void #[\Override] public function applicationUninstalled(?string $applicationToken): void { - $this->status = Bitrix24AccountStatus::deleted; - $this->updatedAt = new CarbonImmutable();; - $this->events[] = new Bitrix24AccountApplicationUninstalledEvent( - $this->id, - new CarbonImmutable() - ); + if ( + Bitrix24AccountStatus::new == $this->status + || Bitrix24AccountStatus::active == $this->status + ) { + if ($applicationToken !== null) { + $this->guardTokenMismatch($applicationToken); + } + + $this->status = Bitrix24AccountStatus::deleted; + $this->updatedAt = new CarbonImmutable();; + $this->events[] = new Bitrix24AccountApplicationUninstalledEvent( + $this->id, + new CarbonImmutable() + ); + } } #[\Override] diff --git a/tests/Functional/ApplicationInstallations/UseCase/Uninstall/HandlerTest.php b/tests/Functional/ApplicationInstallations/UseCase/Uninstall/HandlerTest.php index 1aaf7e2..424e95a 100644 --- a/tests/Functional/ApplicationInstallations/UseCase/Uninstall/HandlerTest.php +++ b/tests/Functional/ApplicationInstallations/UseCase/Uninstall/HandlerTest.php @@ -44,7 +44,7 @@ use Bitrix24\Lib\Bitrix24Accounts\Infrastructure\Doctrine\Bitrix24AccountRepository; use Symfony\Component\Uid\Uuid; -use function Symfony\Component\Translation\t; + /** * @internal @@ -82,7 +82,7 @@ protected function setUp(): void * @throws InvalidArgumentException */ #[Test] - public function testUninstallApplicationInstallation(): void + public function testUninstall(): void { //Загружаем в базу данных аккаунт и установку приложения для их деинсталяции. $applicationToken = Uuid::v7()->toRfc4122(); @@ -118,6 +118,95 @@ public function testUninstallApplicationInstallation(): void $dispatchedEvents = $this->eventDispatcher->getOrphanedEvents(); $this->assertContains(\Bitrix24\SDK\Application\Contracts\Bitrix24Accounts\Events\Bitrix24AccountApplicationUninstalledEvent::class, $dispatchedEvents); + } + + /** + * @throws InvalidArgumentException + */ + #[Test] + public function testUninstallWithNotValidToken() + { + //Загружаем в базу данных аккаунт и установку приложения для их деинсталяции. + $applicationToken = Uuid::v7()->toRfc4122(); + $oldBitrix24Account = (new Bitrix24AccountBuilder()) + ->withApplicationScope(new Scope(['crm'])) + ->withStatus(Bitrix24AccountStatus::new) + ->withApplicationToken($applicationToken) + ->withMaster(true) + ->withSetToken() + ->build(); + + $oldApplicationInstallationBuilder = (new ApplicationInstallationBuilder()) + ->withApplicationStatus(new ApplicationStatus('F')) + ->withPortalLicenseFamily(PortalLicenseFamily::free) + ->withBitrix24AccountId($oldBitrix24Account->getId()) + ->withApplicationStatusInstallation(ApplicationInstallationStatus::active) + ->withApplicationToken($applicationToken) + ->build(); + + $this->bitrix24accountRepository->save($oldBitrix24Account); + $this->repository->save($oldApplicationInstallationBuilder); + $this->flusher->flush(); + + $this->expectException(InvalidArgumentException::class); + $this->expectExceptionMessage('application token «testNotValidToken» mismatch with application token «'. $applicationToken .'» for application installation «'.$oldApplicationInstallationBuilder->getId()->toRfc4122() .'»'); + $this->handler->handle( + new ApplicationInstallations\UseCase\Uninstall\Command( + new Domain($oldBitrix24Account->getDomainUrl()), + $oldBitrix24Account->getMemberId(), + 'testNotValidToken' + ) + ); } + + public function testUninstallWithFewAccount() + { + $memberId = Uuid::v4()->toRfc4122(); + //Загружаем в базу данных аккаунт и установку приложения для их деинсталяции. + $applicationToken = Uuid::v7()->toRfc4122(); + $oldBitrix24Account = (new Bitrix24AccountBuilder()) + ->withApplicationScope(new Scope(['crm'])) + ->withStatus(Bitrix24AccountStatus::new) + ->withApplicationToken($applicationToken) + ->withMaster(true) + ->withMemberId($memberId) + ->withSetToken() + ->build(); + + + $oldBitrix24Account2 = (new Bitrix24AccountBuilder()) + ->withApplicationScope(new Scope(['crm'])) + ->withStatus(Bitrix24AccountStatus::new) + ->withMemberId($memberId) + ->build(); + + $oldApplicationInstallationBuilder = (new ApplicationInstallationBuilder()) + ->withApplicationStatus(new ApplicationStatus('F')) + ->withPortalLicenseFamily(PortalLicenseFamily::free) + ->withBitrix24AccountId($oldBitrix24Account->getId()) + ->withApplicationStatusInstallation(ApplicationInstallationStatus::active) + ->withApplicationToken($applicationToken) + ->build(); + + $this->bitrix24accountRepository->save($oldBitrix24Account); + $this->bitrix24accountRepository->save($oldBitrix24Account2); + + $this->repository->save($oldApplicationInstallationBuilder); + $this->flusher->flush(); + + $this->handler->handle( + new ApplicationInstallations\UseCase\Uninstall\Command( + new Domain($oldBitrix24Account->getDomainUrl()), + $oldBitrix24Account->getMemberId(), + $applicationToken + ) + ); + + $dispatchedEvents = $this->eventDispatcher->getOrphanedEvents(); + + $this->assertContains(\Bitrix24\SDK\Application\Contracts\Bitrix24Accounts\Events\Bitrix24AccountApplicationUninstalledEvent::class, $dispatchedEvents); + } + + } \ No newline at end of file From 76b386b26b7e3291cd6f669463b7f36d1a92cf1b Mon Sep 17 00:00:00 2001 From: KarlsonComplete Date: Sun, 6 Jul 2025 12:40:58 +0300 Subject: [PATCH 41/49] =?UTF-8?q?=D0=A0=D0=B5=D0=BA=D1=82=D0=BE=D1=80=20+?= =?UTF-8?q?=20=D0=A4=D0=B8=D0=BA=D1=81=D0=B5=D1=80.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Entity/ApplicationInstallation.php | 63 +++++++++---------- .../ApplicationInstallationRepository.php | 23 +++---- .../UseCase/Install/Command.php | 8 +-- .../UseCase/Install/Handler.php | 27 ++++---- .../UseCase/OnAppInstall/Command.php | 2 - .../UseCase/OnAppInstall/Handler.php | 22 +++---- .../UseCase/Uninstall/Command.php | 5 +- .../UseCase/Uninstall/Handler.php | 31 +++++---- .../Entity/Bitrix24Account.php | 36 +++++------ .../Doctrine/Bitrix24AccountRepository.php | 9 ++- .../UseCase/InstallFinish/Handler.php | 2 +- .../UseCase/InstallStart/Handler.php | 2 - .../ApplicationInstallationBuilder.php | 30 ++++----- .../UseCase/Install/HandlerTest.php | 8 +-- .../UseCase/Uninstall/HandlerTest.php | 22 +++---- .../Builders/Bitrix24AccountBuilder.php | 2 + 16 files changed, 134 insertions(+), 158 deletions(-) diff --git a/src/ApplicationInstallations/Entity/ApplicationInstallation.php b/src/ApplicationInstallations/Entity/ApplicationInstallation.php index bb99ff4..f625a03 100644 --- a/src/ApplicationInstallations/Entity/ApplicationInstallation.php +++ b/src/ApplicationInstallations/Entity/ApplicationInstallation.php @@ -17,9 +17,9 @@ use Bitrix24\SDK\Application\Contracts\ApplicationInstallations\Events\ApplicationInstallationUninstalledEvent; use Bitrix24\SDK\Application\PortalLicenseFamily; use Bitrix24\SDK\Core\Exceptions\InvalidArgumentException; +use Bitrix24\SDK\Core\Exceptions\LogicException; use Carbon\CarbonImmutable; use Symfony\Component\Uid\Uuid; -use Bitrix24\SDK\Core\Exceptions\LogicException; /** * Установка может происходить по 2 сценриям. @@ -32,33 +32,33 @@ * 2) Без UI - Установка инициируется прямым POST-запросом с полным набором credentials. * Сразу создается Bitrix24Account. У установщика и у аккаунта вызывается метод с переданыым токеном: * $bitrix24Account->applicationInstalled($applicationToken); - * $applicationInstallation->applicationInstalled($applicationToken); + * $applicationInstallation->applicationInstalled($applicationToken);. */ class ApplicationInstallation extends AggregateRoot implements ApplicationInstallationInterface { - private ?string $applicationToken = null; - private CarbonImmutable $createdAt; + + private readonly CarbonImmutable $createdAt; + private CarbonImmutable $updatedAt; - private ApplicationInstallationStatus $status; + + private ApplicationInstallationStatus $status = ApplicationInstallationStatus::new; public function __construct( - private readonly Uuid $id, - private readonly Uuid $bitrix24AccountId, - private ApplicationStatus $applicationStatus, + private readonly Uuid $id, + private readonly Uuid $bitrix24AccountId, + private ApplicationStatus $applicationStatus, private PortalLicenseFamily $portalLicenseFamily, - private ?int $portalUsersCount, - private ?Uuid $contactPersonId, - private ?Uuid $bitrix24PartnerContactPersonId, - private ?Uuid $bitrix24PartnerId, - private ?string $externalId, - private ?string $comment = null, - private $isEmitApplicationInstallationCreatedEvent = false - ) - { + private ?int $portalUsersCount, + private ?Uuid $contactPersonId, + private ?Uuid $bitrix24PartnerContactPersonId, + private ?Uuid $bitrix24PartnerId, + private ?string $externalId, + private ?string $comment = null, + private $isEmitApplicationInstallationCreatedEvent = false + ) { $this->createdAt = new CarbonImmutable(); $this->updatedAt = new CarbonImmutable(); - $this->status = ApplicationInstallationStatus::new; $this->addApplicationCreatedEventIfNeeded($this->isEmitApplicationInstallationCreatedEvent); } @@ -141,7 +141,7 @@ public function applicationInstalled(?string $applicationToken = null): void ); } - if (!empty($applicationToken)) { + if (null !== $applicationToken && '' !== $applicationToken && '0' !== $applicationToken) { $this->applicationToken = $applicationToken; } @@ -175,7 +175,7 @@ public function applicationUninstalled(?string $applicationToken = null): void } // Это проверка для мастер аккаунтов чтобы удостовериться что передан верный токен для деинсталяции. - if ($applicationToken !== null){ + if (null !== $applicationToken) { $this->guardTokenMismatch($applicationToken); } @@ -315,18 +315,6 @@ public function getComment(): ?string return $this->comment; } - private function addApplicationCreatedEventIfNeeded(bool $isEmitCreatedEvent): void - { - if ($isEmitCreatedEvent) { - // Создание события и добавление его в массив событий - $this->events[] = new ApplicationInstallationCreatedEvent( - $this->id, - $this->createdAt, - $this->bitrix24AccountId - ); - } - } - #[\Override] public function isApplicationTokenValid(string $applicationToken): bool { @@ -423,7 +411,18 @@ public function unlinkBitrix24Partner(): void ); $this->bitrix24PartnerId = null; + } + private function addApplicationCreatedEventIfNeeded(bool $isEmitCreatedEvent): void + { + if ($isEmitCreatedEvent) { + // Создание события и добавление его в массив событий + $this->events[] = new ApplicationInstallationCreatedEvent( + $this->id, + $this->createdAt, + $this->bitrix24AccountId + ); + } } private function guardTokenMismatch(string $applicationToken): void diff --git a/src/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationRepository.php b/src/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationRepository.php index 79d08d1..e7b13b0 100644 --- a/src/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationRepository.php +++ b/src/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationRepository.php @@ -37,7 +37,8 @@ public function getById(Uuid $uuid): ApplicationInstallationInterface ->setParameter('uuid', $uuid) ->setParameter('status', ApplicationInstallationStatus::deleted) ->getQuery() - ->getOneOrNullResult(); + ->getOneOrNullResult() + ; if (null === $applicationInstallation) { throw new ApplicationInstallationNotFoundException( @@ -53,7 +54,7 @@ public function delete(Uuid $uuid): void { $applicationInstallation = $this->getEntityManager()->getRepository(ApplicationInstallation::class)->find($uuid); - if ($applicationInstallation == null) { + if (null == $applicationInstallation) { throw new ApplicationInstallationNotFoundException( sprintf('Application installation with uuid %s not found', $uuid->toRfc4122()) ); @@ -69,8 +70,8 @@ public function delete(Uuid $uuid): void } #[\Override] - //У нас в установке аккаунтId это констрейнт, так что возращать мы должны сущность. - public function findByBitrix24AccountId(Uuid $uuid): ApplicationInstallationInterface|null + // У нас в установке аккаунтId это констрейнт, так что возращать мы должны сущность. + public function findByBitrix24AccountId(Uuid $uuid): ?ApplicationInstallationInterface { return $this->getEntityManager()->getRepository(ApplicationInstallation::class) ->createQueryBuilder('appInstallation') @@ -78,7 +79,8 @@ public function findByBitrix24AccountId(Uuid $uuid): ApplicationInstallationInte ->orderBy('appInstallation.createdAt', 'DESC') ->setParameter('bitrix24AccountId', $uuid) ->getQuery() - ->getOneOrNullResult(); + ->getOneOrNullResult() + ; } #[\Override] @@ -94,25 +96,24 @@ public function findByExternalId(string $externalId): array ->orderBy('appInstallation.createdAt', 'DESC') ->setParameter('externalId', $externalId) ->getQuery() - ->getResult(); + ->getResult() + ; } - public function findActiveByAccountId(Uuid $b24AccountId): ApplicationInstallationInterface|null + public function findActiveByAccountId(Uuid $uuid): ?ApplicationInstallationInterface { $activeStatuses = [ ApplicationInstallationStatus::new, ApplicationInstallationStatus::active, ]; - $installation = $this->getEntityManager()->getRepository(ApplicationInstallation::class) + return $this->getEntityManager()->getRepository(ApplicationInstallation::class) ->createQueryBuilder('applicationInstallation') ->where('applicationInstallation.bitrix24AccountId = :b24AccountId') ->andWhere('applicationInstallation.status IN (:statuses)') - ->setParameter('b24AccountId', $b24AccountId) + ->setParameter('b24AccountId', $uuid) ->setParameter('statuses', $activeStatuses) ->getQuery() ->getOneOrNullResult(); - - return $installation; } } diff --git a/src/ApplicationInstallations/UseCase/Install/Command.php b/src/ApplicationInstallations/UseCase/Install/Command.php index f37ad70..aaa5896 100644 --- a/src/ApplicationInstallations/UseCase/Install/Command.php +++ b/src/ApplicationInstallations/UseCase/Install/Command.php @@ -11,7 +11,7 @@ use Bitrix24\SDK\Core\Credentials\Scope; use Symfony\Component\Uid\Uuid; -readonly class Command +readonly class Command implements \Stringable { public function __construct( public ApplicationStatus $applicationStatus, @@ -33,12 +33,13 @@ public function __construct( $this->validate(); } + #[\Override] public function __toString(): string { return sprintf( - " portalUsersCount: %s, contactPersonId: %s, bitrix24PartnerContactPersonId: %s, + ' portalUsersCount: %s, contactPersonId: %s, bitrix24PartnerContactPersonId: %s, bitrix24PartnerId: %s, externalId: %s, comment: %s, bitrix24UserId: %d, - isBitrix24UserAdmin: %s, memberId: %s", + isBitrix24UserAdmin: %s, memberId: %s', $this->portalUsersCount ?? 'null', $this->contactPersonId ?? 'null', $this->bitrix24PartnerContactPersonId ?? 'null', @@ -53,7 +54,6 @@ public function __toString(): string private function validate(): void { - if ($this->portalUsersCount <= 0) { throw new \InvalidArgumentException('Portal Users count must be a positive integer.'); } diff --git a/src/ApplicationInstallations/UseCase/Install/Handler.php b/src/ApplicationInstallations/UseCase/Install/Handler.php index c9fb2da..164e72c 100644 --- a/src/ApplicationInstallations/UseCase/Install/Handler.php +++ b/src/ApplicationInstallations/UseCase/Install/Handler.php @@ -20,13 +20,11 @@ readonly class Handler { public function __construct( - private Bitrix24AccountRepository $bitrix24AccountRepository, + private Bitrix24AccountRepository $bitrix24AccountRepository, private ApplicationInstallationRepository $applicationInstallationRepository, - private Flusher $flusher, - private LoggerInterface $logger - ) - { - } + private Flusher $flusher, + private LoggerInterface $logger + ) {} /** * @throws LogicException @@ -35,7 +33,7 @@ public function __construct( public function handle(Command $command): void { $this->logger->info('ApplicationInstallations.Install.start', [ - (string)$command + (string) $command, ]); /* @@ -46,16 +44,18 @@ public function handle(Command $command): void /** @var AggregateRootEventsEmitterInterface|Bitrix24AccountInterface[] $b24Accounts */ $b24Accounts = $this->bitrix24AccountRepository->findActiveByMemberId($command->memberId); - if ($b24Accounts !== []) { + if ([] !== $b24Accounts) { $entitiesToFlush = []; foreach ($b24Accounts as $b24Account) { $isMaster = $b24Account->isMasterAccount(); if ($isMaster) { + /** @var AggregateRootEventsEmitterInterface|ApplicationInstallationInterface $activeInstallation */ $activeInstallation = $this->applicationInstallationRepository->findActiveByAccountId($b24Account->getId()); $activeInstallation->applicationUninstalled(); $this->applicationInstallationRepository->save($activeInstallation); $entitiesToFlush[] = $activeInstallation; } + $b24Account->applicationUninstalled(null); $this->bitrix24AccountRepository->save($b24Account); $entitiesToFlush[] = $b24Account; @@ -66,11 +66,11 @@ public function handle(Command $command): void $this->flusher->flush(...$entitiesToFlush); } - $bitrix24AccountId = Uuid::v7(); + $uuidV7 = Uuid::v7(); $applicationInstallationId = Uuid::v7(); $bitrix24Account = new Bitrix24Account( - $bitrix24AccountId, + $uuidV7, $command->bitrix24UserId, $command->isBitrix24UserAdmin, $command->memberId, @@ -82,12 +82,11 @@ public function handle(Command $command): void true ); - $bitrix24Account->applicationInstalled(null); $applicationInstallation = new ApplicationInstallation( $applicationInstallationId, - $bitrix24AccountId, + $uuidV7, $command->applicationStatus, $command->portalLicenseFamily, $command->portalUsersCount, @@ -103,13 +102,13 @@ public function handle(Command $command): void $this->bitrix24AccountRepository->save($bitrix24Account); $this->applicationInstallationRepository->save($applicationInstallation); - $this->flusher->flush($applicationInstallation,$bitrix24Account); + $this->flusher->flush($applicationInstallation, $bitrix24Account); $this->logger->info( 'ApplicationInstallations.Install.Finish', [ 'applicationId' => $applicationInstallationId, - 'bitrix24AccountId' => $bitrix24AccountId + 'bitrix24AccountId' => $uuidV7, ] ); } diff --git a/src/ApplicationInstallations/UseCase/OnAppInstall/Command.php b/src/ApplicationInstallations/UseCase/OnAppInstall/Command.php index 5f7ac7c..64a1e60 100644 --- a/src/ApplicationInstallations/UseCase/OnAppInstall/Command.php +++ b/src/ApplicationInstallations/UseCase/OnAppInstall/Command.php @@ -1,6 +1,5 @@ memberId) { throw new \InvalidArgumentException('Member ID must be a non-empty string.'); } diff --git a/src/ApplicationInstallations/UseCase/OnAppInstall/Handler.php b/src/ApplicationInstallations/UseCase/OnAppInstall/Handler.php index ca62b68..553c14e 100644 --- a/src/ApplicationInstallations/UseCase/OnAppInstall/Handler.php +++ b/src/ApplicationInstallations/UseCase/OnAppInstall/Handler.php @@ -13,19 +13,16 @@ use Bitrix24\SDK\Application\Contracts\Bitrix24Accounts\Entity\Bitrix24AccountStatus; use Bitrix24\SDK\Application\Contracts\Events\AggregateRootEventsEmitterInterface; use Bitrix24\SDK\Core\Exceptions\InvalidArgumentException; -use Symfony\Component\Uid\Uuid; use Psr\Log\LoggerInterface; readonly class Handler { public function __construct( - private Bitrix24AccountRepository $bitrix24AccountRepository, + private Bitrix24AccountRepository $bitrix24AccountRepository, private ApplicationInstallationRepository $applicationInstallationRepository, - private Flusher $flusher, - private LoggerInterface $logger - ) - { - } + private Flusher $flusher, + private LoggerInterface $logger + ) {} /** * @throws InvalidArgumentException @@ -39,15 +36,15 @@ public function handle(Command $command): void 'application_status' => $command->applicationStatus, ]); - //Тут нужно получить аккаунт мастера , так как если я не ошибаюсь , события установки могут приходить не сразу. - //И за это время на портале могут появится несколько других авторизаций. + // Тут нужно получить аккаунт мастера , так как если я не ошибаюсь , события установки могут приходить не сразу. + // И за это время на портале могут появится несколько других авторизаций. /** @var AggregateRootEventsEmitterInterface|Bitrix24AccountInterface $bitrix24Account */ $bitrix24Account = $this->bitrix24AccountRepository->findMasterByMemberId( $command->memberId, Bitrix24AccountStatus::active, ); - /** @var AggregateRootEventsEmitterInterface|ApplicationInstallationInterface|null $applicationInstallation */ + /** @var null|AggregateRootEventsEmitterInterface|ApplicationInstallationInterface $applicationInstallation */ $applicationInstallation = $this->applicationInstallationRepository->findByBitrix24AccountId($bitrix24Account->getId()); $applicationStatus = new ApplicationStatus($command->applicationStatus); @@ -55,13 +52,14 @@ public function handle(Command $command): void $applicationInstallation->changeApplicationStatus($applicationStatus); $applicationInstallation->setApplicationToken($command->applicationToken); + $bitrix24Account->setApplicationToken($command->applicationToken); $this->bitrix24AccountRepository->save($bitrix24Account); $this->applicationInstallationRepository->save($applicationInstallation); - $this->flusher->flush($applicationInstallation,$bitrix24Account); + $this->flusher->flush($applicationInstallation, $bitrix24Account); $this->logger->info('ApplicationInstallation.OnAppInstall.finish'); } -} \ No newline at end of file +} diff --git a/src/ApplicationInstallations/UseCase/Uninstall/Command.php b/src/ApplicationInstallations/UseCase/Uninstall/Command.php index 6d68fcd..84debaa 100644 --- a/src/ApplicationInstallations/UseCase/Uninstall/Command.php +++ b/src/ApplicationInstallations/UseCase/Uninstall/Command.php @@ -12,8 +12,7 @@ public function __construct( public Domain $domainUrl, public string $memberId, public string $applicationToken - ) - { + ) { $this->validate(); } @@ -27,4 +26,4 @@ private function validate(): void throw new \InvalidArgumentException('Member ID must be a non-empty string.'); } } -} \ No newline at end of file +} diff --git a/src/ApplicationInstallations/UseCase/Uninstall/Handler.php b/src/ApplicationInstallations/UseCase/Uninstall/Handler.php index 701d8ce..8374f31 100644 --- a/src/ApplicationInstallations/UseCase/Uninstall/Handler.php +++ b/src/ApplicationInstallations/UseCase/Uninstall/Handler.php @@ -4,34 +4,29 @@ namespace Bitrix24\Lib\ApplicationInstallations\UseCase\Uninstall; - use Bitrix24\Lib\ApplicationInstallations\Infrastructure\Doctrine\ApplicationInstallationRepository; -use Bitrix24\Lib\Bitrix24Accounts\Entity\Bitrix24Account; use Bitrix24\Lib\Bitrix24Accounts\Infrastructure\Doctrine\Bitrix24AccountRepository; use Bitrix24\Lib\Services\Flusher; +use Bitrix24\SDK\Application\Contracts\ApplicationInstallations\Entity\ApplicationInstallationInterface; use Bitrix24\SDK\Application\Contracts\Bitrix24Accounts\Entity\Bitrix24AccountInterface; -use Bitrix24\SDK\Application\Contracts\Bitrix24Accounts\Entity\Bitrix24AccountStatus; use Bitrix24\SDK\Application\Contracts\Events\AggregateRootEventsEmitterInterface; use Psr\Log\LoggerInterface; readonly class Handler { public function __construct( - private Bitrix24AccountRepository $bitrix24AccountRepository, + private Bitrix24AccountRepository $bitrix24AccountRepository, private ApplicationInstallationRepository $applicationInstallationRepository, - private Flusher $flusher, - private LoggerInterface $logger - ) - { - - } + private Flusher $flusher, + private LoggerInterface $logger + ) {} public function handle(Command $command): void { $this->logger->info('ApplicationInstallations.Uninstall.start', [ 'domainUrl' => $command->domainUrl, 'memberId' => $command->memberId, - 'applicationToken' => $command->applicationToken + 'applicationToken' => $command->applicationToken, ]); /* @@ -43,21 +38,23 @@ public function handle(Command $command): void /** @var AggregateRootEventsEmitterInterface|Bitrix24AccountInterface[] $b24Accounts */ $b24Accounts = $this->bitrix24AccountRepository->findByMemberId($command->memberId); - if ($b24Accounts !== []) { + if ([] !== $b24Accounts) { $entitiesToFlush = []; foreach ($b24Accounts as $b24Account) { $isMaster = $b24Account->isMasterAccount(); if ($isMaster) { + /** @var AggregateRootEventsEmitterInterface|ApplicationInstallationInterface $activeInstallation */ $activeInstallation = $this->applicationInstallationRepository->findActiveByAccountId($b24Account->getId()); - if ($activeInstallation !== null) { + if (null !== $activeInstallation) { $activeInstallation->applicationUninstalled($command->applicationToken); $this->applicationInstallationRepository->save($activeInstallation); $entitiesToFlush[] = $activeInstallation; } - // Тут тоже спорно получается , а если установка была по событию, а событие не произошло и токен не записался. ??? - $b24Account->applicationUninstalled($command->applicationToken); - }else{ - $b24Account->applicationUninstalled(null); + + // Тут тоже спорно получается , а если установка была по событию, а событие не произошло и токен не записался. ??? + $b24Account->applicationUninstalled($command->applicationToken); + } else { + $b24Account->applicationUninstalled(null); } $this->bitrix24AccountRepository->save($b24Account); diff --git a/src/Bitrix24Accounts/Entity/Bitrix24Account.php b/src/Bitrix24Accounts/Entity/Bitrix24Account.php index b15a7fd..abf521a 100644 --- a/src/Bitrix24Accounts/Entity/Bitrix24Account.php +++ b/src/Bitrix24Accounts/Entity/Bitrix24Account.php @@ -37,26 +37,24 @@ class Bitrix24Account extends AggregateRoot implements Bitrix24AccountInterface private CarbonImmutable $updatedAt; - private Bitrix24AccountStatus $status; + private Bitrix24AccountStatus $status = Bitrix24AccountStatus::new; public function __construct( - private readonly Uuid $id, - private readonly int $bitrix24UserId, - private readonly bool $isBitrix24UserAdmin, + private readonly Uuid $id, + private readonly int $bitrix24UserId, + private readonly bool $isBitrix24UserAdmin, /** bitrix24 portal unique id */ private readonly string $memberId, - private string $domainUrl, - private AuthToken $authToken, - private int $applicationVersion, - private Scope $applicationScope, - private readonly bool $isMasterAccount = false, - private $isEmitBitrix24AccountCreatedEvent = false, - private ?string $comment = null - ) - { + private string $domainUrl, + private AuthToken $authToken, + private int $applicationVersion, + private Scope $applicationScope, + private readonly bool $isMasterAccount = false, + private $isEmitBitrix24AccountCreatedEvent = false, + private ?string $comment = null + ) { $this->createdAt = new CarbonImmutable(); $this->updatedAt = new CarbonImmutable(); - $this->status = Bitrix24AccountStatus::new; $this->addAccountCreatedEventIfNeeded($this->isEmitBitrix24AccountCreatedEvent); } @@ -174,7 +172,6 @@ public function changeDomainUrl(string $newDomainUrl): void } /** - * @param string|null $applicationToken * @throws InvalidArgumentException */ #[\Override] @@ -189,7 +186,7 @@ public function applicationInstalled(?string $applicationToken): void ); } - if (!empty($applicationToken)) { + if (null !== $applicationToken && '' !== $applicationToken && '0' !== $applicationToken) { $this->applicationToken = $applicationToken; } @@ -201,7 +198,6 @@ public function applicationInstalled(?string $applicationToken): void ); } - #[\Override] public function applicationUninstalled(?string $applicationToken): void { @@ -209,12 +205,12 @@ public function applicationUninstalled(?string $applicationToken): void Bitrix24AccountStatus::new == $this->status || Bitrix24AccountStatus::active == $this->status ) { - if ($applicationToken !== null) { + if (null !== $applicationToken) { $this->guardTokenMismatch($applicationToken); } $this->status = Bitrix24AccountStatus::deleted; - $this->updatedAt = new CarbonImmutable();; + $this->updatedAt = new CarbonImmutable(); $this->events[] = new Bitrix24AccountApplicationUninstalledEvent( $this->id, new CarbonImmutable() @@ -294,7 +290,6 @@ public function markAsActive(?string $comment): void $this->updatedAt = new CarbonImmutable(); } - #[\Override] public function isMasterAccount(): bool { @@ -368,5 +363,4 @@ private function addAccountCreatedEventIfNeeded(bool $isEmitCreatedEvent): void ); } } - } diff --git a/src/Bitrix24Accounts/Infrastructure/Doctrine/Bitrix24AccountRepository.php b/src/Bitrix24Accounts/Infrastructure/Doctrine/Bitrix24AccountRepository.php index fd9c24d..8477799 100644 --- a/src/Bitrix24Accounts/Infrastructure/Doctrine/Bitrix24AccountRepository.php +++ b/src/Bitrix24Accounts/Infrastructure/Doctrine/Bitrix24AccountRepository.php @@ -108,6 +108,7 @@ public function findByMemberId( /** * @phpstan-return Bitrix24AccountInterface|null + * * @throws InvalidArgumentException */ public function findMasterByMemberId( @@ -115,14 +116,14 @@ public function findMasterByMemberId( ?Bitrix24AccountStatus $bitrix24AccountStatus = null, ?int $bitrix24UserId = null, ?bool $isAdmin = null - ): Bitrix24AccountInterface|null { + ): ?Bitrix24AccountInterface { if ('' === trim($memberId)) { throw new InvalidArgumentException('memberId cannot be empty'); } $criteria = [ 'memberId' => $memberId, - 'isMasterAccount' => true + 'isMasterAccount' => true, ]; if ($bitrix24AccountStatus instanceof Bitrix24AccountStatus) { @@ -151,7 +152,7 @@ public function findActiveByMemberId(string $memberId): array Bitrix24AccountStatus::active, ]; - $accounts = $this->getEntityManager()->getRepository(Bitrix24Account::class) + return $this->getEntityManager()->getRepository(Bitrix24Account::class) ->createQueryBuilder('b24') ->where('b24.memberId = :memberId') ->andWhere('b24.status IN (:statuses)') @@ -161,8 +162,6 @@ public function findActiveByMemberId(string $memberId): array ->getQuery() ->getResult() ; - - return $accounts; } #[\Override] diff --git a/src/Bitrix24Accounts/UseCase/InstallFinish/Handler.php b/src/Bitrix24Accounts/UseCase/InstallFinish/Handler.php index 896bca7..f8518cf 100644 --- a/src/Bitrix24Accounts/UseCase/InstallFinish/Handler.php +++ b/src/Bitrix24Accounts/UseCase/InstallFinish/Handler.php @@ -49,7 +49,7 @@ public function handle(Command $command): void [ 'b24_domain_url' => $command->domain, 'b24_member_id' => $command->memberId, - 'b24_user_id' => $command->bitrix24UserId + 'b24_user_id' => $command->bitrix24UserId, ] ); } diff --git a/src/Bitrix24Accounts/UseCase/InstallStart/Handler.php b/src/Bitrix24Accounts/UseCase/InstallStart/Handler.php index 76fe880..ece0c7d 100644 --- a/src/Bitrix24Accounts/UseCase/InstallStart/Handler.php +++ b/src/Bitrix24Accounts/UseCase/InstallStart/Handler.php @@ -6,10 +6,8 @@ use Bitrix24\Lib\Bitrix24Accounts\Entity\Bitrix24Account; use Bitrix24\Lib\Services\Flusher; -use Bitrix24\SDK\Application\Contracts\Bitrix24Accounts\Entity\Bitrix24AccountStatus; use Bitrix24\SDK\Application\Contracts\Bitrix24Accounts\Exceptions\Bitrix24AccountNotFoundException; use Bitrix24\SDK\Application\Contracts\Bitrix24Accounts\Repository\Bitrix24AccountRepositoryInterface; -use Carbon\CarbonImmutable; use Psr\Log\LoggerInterface; readonly class Handler diff --git a/tests/Functional/ApplicationInstallations/Builders/ApplicationInstallationBuilder.php b/tests/Functional/ApplicationInstallations/Builders/ApplicationInstallationBuilder.php index 496a769..fb2788b 100644 --- a/tests/Functional/ApplicationInstallations/Builders/ApplicationInstallationBuilder.php +++ b/tests/Functional/ApplicationInstallations/Builders/ApplicationInstallationBuilder.php @@ -15,7 +15,7 @@ class ApplicationInstallationBuilder { private readonly Uuid $id; - private Uuid $bitrix24AccountId; + private Uuid $bitrix24AccountId; private readonly ?Uuid $contactPersonId; @@ -91,7 +91,7 @@ public function withPortalLicenseFamily(PortalLicenseFamily $portalLicenseFamily public function build(): ApplicationInstallation { - $applicationInstallation = new ApplicationInstallation( + $applicationInstallation = new ApplicationInstallation( $this->id, $this->bitrix24AccountId, $this->applicationStatus, @@ -104,24 +104,16 @@ public function build(): ApplicationInstallation $this->comment ); - if (!empty($this->status)) { - if ($this->status == ApplicationInstallationStatus::active) { - if (!empty($this->applicationToken)) { - $applicationInstallation->applicationInstalled($this->applicationToken); - }else{ - $applicationInstallation->applicationInstalled(); - } - } - } - - return $applicationInstallation; - } - - - - - + if (!empty($this->status) && $this->status == ApplicationInstallationStatus::active) { + if ($this->applicationToken !== null && $this->applicationToken !== '' && $this->applicationToken !== '0') { + $applicationInstallation->applicationInstalled($this->applicationToken); + } else { + $applicationInstallation->applicationInstalled(); + } + } + return $applicationInstallation; + } } \ No newline at end of file diff --git a/tests/Functional/ApplicationInstallations/UseCase/Install/HandlerTest.php b/tests/Functional/ApplicationInstallations/UseCase/Install/HandlerTest.php index f4793df..f0d219f 100644 --- a/tests/Functional/ApplicationInstallations/UseCase/Install/HandlerTest.php +++ b/tests/Functional/ApplicationInstallations/UseCase/Install/HandlerTest.php @@ -143,7 +143,7 @@ public function testReinstallApplicationInstallation(): void ->build(); - $currentApplicationInstallationBuilder = (new ApplicationInstallationBuilder()) + $applicationInstallation = (new ApplicationInstallationBuilder()) ->withApplicationStatus(new ApplicationStatus('F')) ->withPortalLicenseFamily(PortalLicenseFamily::free) ->withBitrix24AccountId($currentBitrix24Account->getId()) @@ -151,7 +151,7 @@ public function testReinstallApplicationInstallation(): void ->build(); $this->bitrix24accountRepository->save($currentBitrix24Account); - $this->repository->save($currentApplicationInstallationBuilder); + $this->repository->save($applicationInstallation); $this->flusher->flush(); $bitrix24AccountBuilder = (new Bitrix24AccountBuilder()) @@ -211,7 +211,7 @@ public function testFewInstallationsOnOneAccount(): void ->build(); - $currentApplicationInstallationBuilder = (new ApplicationInstallationBuilder()) + $applicationInstallation = (new ApplicationInstallationBuilder()) ->withApplicationStatus(new ApplicationStatus('F')) ->withPortalLicenseFamily(PortalLicenseFamily::free) ->withBitrix24AccountId($currentBitrix24Account->getId()) @@ -219,7 +219,7 @@ public function testFewInstallationsOnOneAccount(): void ->build(); $this->bitrix24accountRepository->save($currentBitrix24Account); - $this->repository->save($currentApplicationInstallationBuilder); + $this->repository->save($applicationInstallation); $this->flusher->flush(); $applicationInstallationBuilder = (new ApplicationInstallationBuilder()) diff --git a/tests/Functional/ApplicationInstallations/UseCase/Uninstall/HandlerTest.php b/tests/Functional/ApplicationInstallations/UseCase/Uninstall/HandlerTest.php index 424e95a..251ab8f 100644 --- a/tests/Functional/ApplicationInstallations/UseCase/Uninstall/HandlerTest.php +++ b/tests/Functional/ApplicationInstallations/UseCase/Uninstall/HandlerTest.php @@ -95,7 +95,7 @@ public function testUninstall(): void ->build(); - $oldApplicationInstallationBuilder = (new ApplicationInstallationBuilder()) + $applicationInstallation = (new ApplicationInstallationBuilder()) ->withApplicationStatus(new ApplicationStatus('F')) ->withPortalLicenseFamily(PortalLicenseFamily::free) ->withBitrix24AccountId($oldBitrix24Account->getId()) @@ -104,7 +104,7 @@ public function testUninstall(): void ->build(); $this->bitrix24accountRepository->save($oldBitrix24Account); - $this->repository->save($oldApplicationInstallationBuilder); + $this->repository->save($applicationInstallation); $this->flusher->flush(); $this->handler->handle( @@ -124,7 +124,7 @@ public function testUninstall(): void * @throws InvalidArgumentException */ #[Test] - public function testUninstallWithNotValidToken() + public function testUninstallWithNotValidToken(): void { //Загружаем в базу данных аккаунт и установку приложения для их деинсталяции. $applicationToken = Uuid::v7()->toRfc4122(); @@ -137,7 +137,7 @@ public function testUninstallWithNotValidToken() ->build(); - $oldApplicationInstallationBuilder = (new ApplicationInstallationBuilder()) + $applicationInstallation = (new ApplicationInstallationBuilder()) ->withApplicationStatus(new ApplicationStatus('F')) ->withPortalLicenseFamily(PortalLicenseFamily::free) ->withBitrix24AccountId($oldBitrix24Account->getId()) @@ -146,11 +146,11 @@ public function testUninstallWithNotValidToken() ->build(); $this->bitrix24accountRepository->save($oldBitrix24Account); - $this->repository->save($oldApplicationInstallationBuilder); + $this->repository->save($applicationInstallation); $this->flusher->flush(); $this->expectException(InvalidArgumentException::class); - $this->expectExceptionMessage('application token «testNotValidToken» mismatch with application token «'. $applicationToken .'» for application installation «'.$oldApplicationInstallationBuilder->getId()->toRfc4122() .'»'); + $this->expectExceptionMessage('application token «testNotValidToken» mismatch with application token «'. $applicationToken .'» for application installation «'.$applicationInstallation->getId()->toRfc4122() .'»'); $this->handler->handle( new ApplicationInstallations\UseCase\Uninstall\Command( new Domain($oldBitrix24Account->getDomainUrl()), @@ -160,7 +160,7 @@ public function testUninstallWithNotValidToken() ); } - public function testUninstallWithFewAccount() + public function testUninstallWithFewAccount(): void { $memberId = Uuid::v4()->toRfc4122(); //Загружаем в базу данных аккаунт и установку приложения для их деинсталяции. @@ -175,13 +175,13 @@ public function testUninstallWithFewAccount() ->build(); - $oldBitrix24Account2 = (new Bitrix24AccountBuilder()) + $bitrix24Account = (new Bitrix24AccountBuilder()) ->withApplicationScope(new Scope(['crm'])) ->withStatus(Bitrix24AccountStatus::new) ->withMemberId($memberId) ->build(); - $oldApplicationInstallationBuilder = (new ApplicationInstallationBuilder()) + $applicationInstallation = (new ApplicationInstallationBuilder()) ->withApplicationStatus(new ApplicationStatus('F')) ->withPortalLicenseFamily(PortalLicenseFamily::free) ->withBitrix24AccountId($oldBitrix24Account->getId()) @@ -190,9 +190,9 @@ public function testUninstallWithFewAccount() ->build(); $this->bitrix24accountRepository->save($oldBitrix24Account); - $this->bitrix24accountRepository->save($oldBitrix24Account2); + $this->bitrix24accountRepository->save($bitrix24Account); - $this->repository->save($oldApplicationInstallationBuilder); + $this->repository->save($applicationInstallation); $this->flusher->flush(); $this->handler->handle( diff --git a/tests/Functional/Bitrix24Accounts/Builders/Bitrix24AccountBuilder.php b/tests/Functional/Bitrix24Accounts/Builders/Bitrix24AccountBuilder.php index 5b55b6c..77b6bed 100644 --- a/tests/Functional/Bitrix24Accounts/Builders/Bitrix24AccountBuilder.php +++ b/tests/Functional/Bitrix24Accounts/Builders/Bitrix24AccountBuilder.php @@ -42,7 +42,9 @@ class Bitrix24AccountBuilder private Scope $applicationScope; private ?string $applicationToken = null; + private bool $isMasterAccount = false; + private bool $isSetToken = false; private bool $isInstalled = false; From cdfc42a6c352a3e521568cdfbc2288845c289455 Mon Sep 17 00:00:00 2001 From: KarlsonComplete Date: Tue, 8 Jul 2025 00:20:56 +0300 Subject: [PATCH 42/49] =?UTF-8?q?-=D0=9F=D0=BE=D0=BF=D1=80=D0=B0=D0=B2?= =?UTF-8?q?=D0=B8=D0=BB=20handler=20=D0=B4=D0=B5=D0=B8=D0=BD=D1=81=D1=82?= =?UTF-8?q?=D0=B0=D0=BB=D1=8F=D1=86=D0=B8=D0=B8.=20-=D0=94=D0=BE=D0=BF?= =?UTF-8?q?=D0=BE=D0=BB=D0=BD=D0=B8=D0=BB=20=D1=82=D0=B5=D1=81=D1=82=D0=B0?= =?UTF-8?q?=D0=BC=D0=B8=20=D0=B4=D0=B5=D0=B8=D0=BD=D1=81=D1=82=D0=B0=D0=BB?= =?UTF-8?q?=D1=8F=D1=86=D0=B8=D1=8E.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Entity/ApplicationInstallation.php | 9 ++- .../ApplicationInstallationRepository.php | 17 +++++ .../UseCase/Install/Handler.php | 5 +- .../UseCase/Uninstall/Handler.php | 73 +++++++++++-------- .../Entity/Bitrix24Account.php | 1 + .../UseCase/Uninstall/HandlerTest.php | 68 ++++++++++++----- 6 files changed, 121 insertions(+), 52 deletions(-) diff --git a/src/ApplicationInstallations/Entity/ApplicationInstallation.php b/src/ApplicationInstallations/Entity/ApplicationInstallation.php index f625a03..09a1384 100644 --- a/src/ApplicationInstallations/Entity/ApplicationInstallation.php +++ b/src/ApplicationInstallations/Entity/ApplicationInstallation.php @@ -174,8 +174,8 @@ public function applicationUninstalled(?string $applicationToken = null): void ); } - // Это проверка для мастер аккаунтов чтобы удостовериться что передан верный токен для деинсталяции. if (null !== $applicationToken) { + $this->guardEmptyToken($applicationToken); $this->guardTokenMismatch($applicationToken); } @@ -438,4 +438,11 @@ private function guardTokenMismatch(string $applicationToken): void ); } } + + private function guardEmptyToken(string $applicationToken): void + { + if ('' === $applicationToken) { + throw new InvalidArgumentException('application token cannot be empty'); + } + } } diff --git a/src/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationRepository.php b/src/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationRepository.php index e7b13b0..4d3f4a1 100644 --- a/src/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationRepository.php +++ b/src/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationRepository.php @@ -116,4 +116,21 @@ public function findActiveByAccountId(Uuid $uuid): ?ApplicationInstallationInter ->getQuery() ->getOneOrNullResult(); } + + public function findActiveByApplicationToken(string $applicationToken): ?ApplicationInstallationInterface + { + $activeStatuses = [ + ApplicationInstallationStatus::new, + ApplicationInstallationStatus::active + ]; + + return $this->getEntityManager()->getRepository(ApplicationInstallation::class) + ->createQueryBuilder('applicationInstallation') + ->where('applicationInstallation.applicationToken = :applicationToken') + ->andWhere('applicationInstallation.status IN (:statuses)') + ->setParameter('applicationToken', $applicationToken) + ->setParameter('statuses', $activeStatuses) + ->getQuery() + ->getOneOrNullResult(); + } } diff --git a/src/ApplicationInstallations/UseCase/Install/Handler.php b/src/ApplicationInstallations/UseCase/Install/Handler.php index 164e72c..a68f582 100644 --- a/src/ApplicationInstallations/UseCase/Install/Handler.php +++ b/src/ApplicationInstallations/UseCase/Install/Handler.php @@ -84,6 +84,8 @@ public function handle(Command $command): void $bitrix24Account->applicationInstalled(null); + $this->bitrix24AccountRepository->save($bitrix24Account); + $applicationInstallation = new ApplicationInstallation( $applicationInstallationId, $uuidV7, @@ -99,9 +101,8 @@ public function handle(Command $command): void ); $applicationInstallation->applicationInstalled(); - - $this->bitrix24AccountRepository->save($bitrix24Account); $this->applicationInstallationRepository->save($applicationInstallation); + $this->flusher->flush($applicationInstallation, $bitrix24Account); $this->logger->info( diff --git a/src/ApplicationInstallations/UseCase/Uninstall/Handler.php b/src/ApplicationInstallations/UseCase/Uninstall/Handler.php index 8374f31..73f2b79 100644 --- a/src/ApplicationInstallations/UseCase/Uninstall/Handler.php +++ b/src/ApplicationInstallations/UseCase/Uninstall/Handler.php @@ -12,14 +12,30 @@ use Bitrix24\SDK\Application\Contracts\Events\AggregateRootEventsEmitterInterface; use Psr\Log\LoggerInterface; +/** + * + * Обработчик сценария деинсталляции приложения. + * + * Важно: Сценарий рассчитан на идеальные условия и может не учитывать случаи, когда: + * 1) В базе данных кто-то вручную удалил или деактивировал запись о деинсталляции, а затем вызвал этот обработчик. + * 2) Токен удаления поступает с задержкой (например, при быстрой установке и удалении приложения). + * 3) В системе может существовать несколько аккаунтов, однако деинсталляция на портале выполняется только один раз. + * 4) Для остальных аккаунтов деинсталляция невозможна — они используются только для авторизации и доступа. + * + * Возможные ограничения: + * 1) Если установка приложения производилась по событию, которое не произошло, токен может не сохраниться, что приведет к спорным ситуациям при деинсталляции. + * 2) Используйте этот обработчик только при уверенности в целостности данных и корректности порядка событий. + */ readonly class Handler { public function __construct( - private Bitrix24AccountRepository $bitrix24AccountRepository, + private Bitrix24AccountRepository $bitrix24AccountRepository, private ApplicationInstallationRepository $applicationInstallationRepository, - private Flusher $flusher, - private LoggerInterface $logger - ) {} + private Flusher $flusher, + private LoggerInterface $logger + ) + { + } public function handle(Command $command): void { @@ -29,39 +45,36 @@ public function handle(Command $command): void 'applicationToken' => $command->applicationToken, ]); - /* - * 1)Аккаунтов может быть несколько , но деинсталяция на портале проводится только 1 раз , то есть есть мастер аккаунт который нужно получать. - * 2)У остальных аккаунтов деинсталяции быть не может это просто (доступы/авторизации). - * 3)Может быть такой сценарий что при увольнении сотрудника особенно админа у которого была активная установка. Установка может зависнуть , - * таким образом нужно пробегаться по всем аккаунтам и установкам и проверять нету ли активных, если что деактивировать. - */ - /** @var AggregateRootEventsEmitterInterface|Bitrix24AccountInterface[] $b24Accounts */ - $b24Accounts = $this->bitrix24AccountRepository->findByMemberId($command->memberId); + /** @var AggregateRootEventsEmitterInterface|ApplicationInstallationInterface $activeInstallation */ + $activeInstallation = $this->applicationInstallationRepository->findActiveByApplicationToken($command->applicationToken); - if ([] !== $b24Accounts) { + if (null !== $activeInstallation) { $entitiesToFlush = []; - foreach ($b24Accounts as $b24Account) { - $isMaster = $b24Account->isMasterAccount(); - if ($isMaster) { - /** @var AggregateRootEventsEmitterInterface|ApplicationInstallationInterface $activeInstallation */ - $activeInstallation = $this->applicationInstallationRepository->findActiveByAccountId($b24Account->getId()); - if (null !== $activeInstallation) { - $activeInstallation->applicationUninstalled($command->applicationToken); - $this->applicationInstallationRepository->save($activeInstallation); - $entitiesToFlush[] = $activeInstallation; + + $activeInstallation->applicationUninstalled($command->applicationToken); + + $this->applicationInstallationRepository->save($activeInstallation); + + $entitiesToFlush[] = $activeInstallation; + + /** @var AggregateRootEventsEmitterInterface|Bitrix24AccountInterface[] $b24Accounts */ + $b24Accounts = $this->bitrix24AccountRepository->findByMemberId($command->memberId); + + if ([] !== $b24Accounts) { + foreach ($b24Accounts as $b24Account) { + $isMaster = $b24Account->isMasterAccount(); + if ($isMaster) { + $b24Account->applicationUninstalled($command->applicationToken); + } else { + $b24Account->applicationUninstalled(null); } - // Тут тоже спорно получается , а если установка была по событию, а событие не произошло и токен не записался. ??? - $b24Account->applicationUninstalled($command->applicationToken); - } else { - $b24Account->applicationUninstalled(null); + $this->bitrix24AccountRepository->save($b24Account); + $entitiesToFlush[] = $b24Account; } - - $this->bitrix24AccountRepository->save($b24Account); - $entitiesToFlush[] = $b24Account; } - $this->flusher->flush(...$entitiesToFlush); + } $this->logger->info( diff --git a/src/Bitrix24Accounts/Entity/Bitrix24Account.php b/src/Bitrix24Accounts/Entity/Bitrix24Account.php index abf521a..a0f8b04 100644 --- a/src/Bitrix24Accounts/Entity/Bitrix24Account.php +++ b/src/Bitrix24Accounts/Entity/Bitrix24Account.php @@ -206,6 +206,7 @@ public function applicationUninstalled(?string $applicationToken): void || Bitrix24AccountStatus::active == $this->status ) { if (null !== $applicationToken) { + $this->guardEmptyToken($applicationToken); $this->guardTokenMismatch($applicationToken); } diff --git a/tests/Functional/ApplicationInstallations/UseCase/Uninstall/HandlerTest.php b/tests/Functional/ApplicationInstallations/UseCase/Uninstall/HandlerTest.php index 251ab8f..142397b 100644 --- a/tests/Functional/ApplicationInstallations/UseCase/Uninstall/HandlerTest.php +++ b/tests/Functional/ApplicationInstallations/UseCase/Uninstall/HandlerTest.php @@ -25,7 +25,9 @@ use Bitrix24\Lib\Tests\Functional\Bitrix24Accounts\Builders\Bitrix24AccountBuilder; use Bitrix24\SDK\Application\ApplicationStatus; use Bitrix24\SDK\Application\Contracts\ApplicationInstallations\Entity\ApplicationInstallationStatus; +use Bitrix24\SDK\Application\Contracts\ApplicationInstallations\Exceptions\ApplicationInstallationNotFoundException; use Bitrix24\SDK\Application\Contracts\Bitrix24Accounts\Entity\Bitrix24AccountStatus; +use Bitrix24\SDK\Application\Contracts\Bitrix24Accounts\Exceptions\Bitrix24AccountNotFoundException; use Bitrix24\SDK\Application\PortalLicenseFamily; use Bitrix24\SDK\Core\Credentials\Scope; use Bitrix24\SDK\Core\Exceptions\InvalidArgumentException; @@ -92,10 +94,12 @@ public function testUninstall(): void ->withApplicationToken($applicationToken) ->withMaster(true) ->withSetToken() + ->withInstalled() ->build(); + $this->bitrix24accountRepository->save($oldBitrix24Account); - $applicationInstallation = (new ApplicationInstallationBuilder()) + $oldApplicationInstallation = (new ApplicationInstallationBuilder()) ->withApplicationStatus(new ApplicationStatus('F')) ->withPortalLicenseFamily(PortalLicenseFamily::free) ->withBitrix24AccountId($oldBitrix24Account->getId()) @@ -103,21 +107,23 @@ public function testUninstall(): void ->withApplicationToken($applicationToken) ->build(); - $this->bitrix24accountRepository->save($oldBitrix24Account); - $this->repository->save($applicationInstallation); + $this->repository->save($oldApplicationInstallation); + $this->flusher->flush(); $this->handler->handle( - new ApplicationInstallations\UseCase\Uninstall\Command( - new Domain($oldBitrix24Account->getDomainUrl()), - $oldBitrix24Account->getMemberId(), - $applicationToken - ) + new ApplicationInstallations\UseCase\Uninstall\Command( + new Domain($oldBitrix24Account->getDomainUrl()), + $oldBitrix24Account->getMemberId(), + $applicationToken + ) ); $dispatchedEvents = $this->eventDispatcher->getOrphanedEvents(); - $this->assertContains(\Bitrix24\SDK\Application\Contracts\Bitrix24Accounts\Events\Bitrix24AccountApplicationUninstalledEvent::class, $dispatchedEvents); + + $this->expectException(ApplicationInstallationNotFoundException::class); + $this->repository->getById($oldApplicationInstallation->getId()); } /** @@ -126,7 +132,6 @@ public function testUninstall(): void #[Test] public function testUninstallWithNotValidToken(): void { - //Загружаем в базу данных аккаунт и установку приложения для их деинсталяции. $applicationToken = Uuid::v7()->toRfc4122(); $oldBitrix24Account = (new Bitrix24AccountBuilder()) ->withApplicationScope(new Scope(['crm'])) @@ -134,10 +139,12 @@ public function testUninstallWithNotValidToken(): void ->withApplicationToken($applicationToken) ->withMaster(true) ->withSetToken() + ->withInstalled() ->build(); + $this->bitrix24accountRepository->save($oldBitrix24Account); - $applicationInstallation = (new ApplicationInstallationBuilder()) + $oldApplicationInstallation = (new ApplicationInstallationBuilder()) ->withApplicationStatus(new ApplicationStatus('F')) ->withPortalLicenseFamily(PortalLicenseFamily::free) ->withBitrix24AccountId($oldBitrix24Account->getId()) @@ -145,12 +152,10 @@ public function testUninstallWithNotValidToken(): void ->withApplicationToken($applicationToken) ->build(); - $this->bitrix24accountRepository->save($oldBitrix24Account); - $this->repository->save($applicationInstallation); + $this->repository->save($oldApplicationInstallation); + $this->flusher->flush(); - $this->expectException(InvalidArgumentException::class); - $this->expectExceptionMessage('application token «testNotValidToken» mismatch with application token «'. $applicationToken .'» for application installation «'.$applicationInstallation->getId()->toRfc4122() .'»'); $this->handler->handle( new ApplicationInstallations\UseCase\Uninstall\Command( new Domain($oldBitrix24Account->getDomainUrl()), @@ -158,6 +163,16 @@ public function testUninstallWithNotValidToken(): void 'testNotValidToken' ) ); + + $applicationInstallation = $this->repository->getById($oldApplicationInstallation->getId()); + + $this->assertEquals(ApplicationInstallationStatus::active, $applicationInstallation->getStatus()); + $this->assertEquals($oldApplicationInstallation->getUpdatedAt(), $applicationInstallation->getUpdatedAt()); + + $bitrix24Account = $this->bitrix24accountRepository->getById($oldBitrix24Account->getId()); + + $this->assertEquals(Bitrix24AccountStatus::active, $bitrix24Account->getStatus()); + $this->assertEquals($oldBitrix24Account->getUpdatedAt(), $bitrix24Account->getUpdatedAt()); } public function testUninstallWithFewAccount(): void @@ -174,6 +189,7 @@ public function testUninstallWithFewAccount(): void ->withSetToken() ->build(); + $this->bitrix24accountRepository->save($oldBitrix24Account); $bitrix24Account = (new Bitrix24AccountBuilder()) ->withApplicationScope(new Scope(['crm'])) @@ -181,7 +197,9 @@ public function testUninstallWithFewAccount(): void ->withMemberId($memberId) ->build(); - $applicationInstallation = (new ApplicationInstallationBuilder()) + $this->bitrix24accountRepository->save($bitrix24Account); + + $oldApplicationInstallation = (new ApplicationInstallationBuilder()) ->withApplicationStatus(new ApplicationStatus('F')) ->withPortalLicenseFamily(PortalLicenseFamily::free) ->withBitrix24AccountId($oldBitrix24Account->getId()) @@ -189,10 +207,8 @@ public function testUninstallWithFewAccount(): void ->withApplicationToken($applicationToken) ->build(); - $this->bitrix24accountRepository->save($oldBitrix24Account); - $this->bitrix24accountRepository->save($bitrix24Account); + $this->repository->save($oldApplicationInstallation); - $this->repository->save($applicationInstallation); $this->flusher->flush(); $this->handler->handle( @@ -206,6 +222,20 @@ public function testUninstallWithFewAccount(): void $dispatchedEvents = $this->eventDispatcher->getOrphanedEvents(); $this->assertContains(\Bitrix24\SDK\Application\Contracts\Bitrix24Accounts\Events\Bitrix24AccountApplicationUninstalledEvent::class, $dispatchedEvents); + + $applicationInstallation = $this->repository->find($oldApplicationInstallation->getId()); + + $this->assertEquals(ApplicationInstallationStatus::deleted, $applicationInstallation->getStatus()); + + $bitrix24Accounts = $this->bitrix24accountRepository->findByMemberId($memberId); + + foreach ($bitrix24Accounts as $account) { + $this->assertSame( + Bitrix24AccountStatus::deleted, + $account->getStatus(), + sprintf('Account %s не в статусе "удалён"', $account->getId()) + ); + } } From dace51abeea14f360d675bc75e7bf7238d1c6646 Mon Sep 17 00:00:00 2001 From: KarlsonComplete Date: Wed, 9 Jul 2025 23:23:07 +0300 Subject: [PATCH 43/49] . --- .../Entity/ApplicationInstallation.php | 7 +++---- .../UseCase/Install/Command.php | 21 +------------------ .../UseCase/Install/Handler.php | 18 +++++++--------- .../UseCase/OnAppInstall/Command.php | 8 +++---- .../UseCase/OnAppInstall/Handler.php | 9 ++++---- .../Entity/Bitrix24Account.php | 3 ++- .../ApplicationInstallationBuilder.php | 2 +- .../UseCase/OnAppInstall/HandlerTest.php | 2 +- 8 files changed, 23 insertions(+), 47 deletions(-) diff --git a/src/ApplicationInstallations/Entity/ApplicationInstallation.php b/src/ApplicationInstallations/Entity/ApplicationInstallation.php index 09a1384..3aba323 100644 --- a/src/ApplicationInstallations/Entity/ApplicationInstallation.php +++ b/src/ApplicationInstallations/Entity/ApplicationInstallation.php @@ -141,7 +141,8 @@ public function applicationInstalled(?string $applicationToken = null): void ); } - if (null !== $applicationToken && '' !== $applicationToken && '0' !== $applicationToken) { + if (null !== $applicationToken) { + $this->guardEmptyToken($applicationToken); $this->applicationToken = $applicationToken; } @@ -324,9 +325,7 @@ public function isApplicationTokenValid(string $applicationToken): bool #[\Override] public function setApplicationToken(string $applicationToken): void { - if ('' === $applicationToken) { - throw new InvalidArgumentException('application token cannot be empty'); - } + $this->guardEmptyToken($applicationToken); $this->updatedAt = new CarbonImmutable(); $this->applicationToken = $applicationToken; diff --git a/src/ApplicationInstallations/UseCase/Install/Command.php b/src/ApplicationInstallations/UseCase/Install/Command.php index aaa5896..64d67f0 100644 --- a/src/ApplicationInstallations/UseCase/Install/Command.php +++ b/src/ApplicationInstallations/UseCase/Install/Command.php @@ -11,7 +11,7 @@ use Bitrix24\SDK\Core\Credentials\Scope; use Symfony\Component\Uid\Uuid; -readonly class Command implements \Stringable +readonly class Command { public function __construct( public ApplicationStatus $applicationStatus, @@ -33,25 +33,6 @@ public function __construct( $this->validate(); } - #[\Override] - public function __toString(): string - { - return sprintf( - ' portalUsersCount: %s, contactPersonId: %s, bitrix24PartnerContactPersonId: %s, - bitrix24PartnerId: %s, externalId: %s, comment: %s, bitrix24UserId: %d, - isBitrix24UserAdmin: %s, memberId: %s', - $this->portalUsersCount ?? 'null', - $this->contactPersonId ?? 'null', - $this->bitrix24PartnerContactPersonId ?? 'null', - $this->bitrix24PartnerId ?? 'null', - $this->externalId ?? 'null', - $this->comment ?? 'null', - $this->bitrix24UserId, - $this->isBitrix24UserAdmin ? 'true' : 'false', - $this->memberId - ); - } - private function validate(): void { if ($this->portalUsersCount <= 0) { diff --git a/src/ApplicationInstallations/UseCase/Install/Handler.php b/src/ApplicationInstallations/UseCase/Install/Handler.php index a68f582..db97d77 100644 --- a/src/ApplicationInstallations/UseCase/Install/Handler.php +++ b/src/ApplicationInstallations/UseCase/Install/Handler.php @@ -27,20 +27,17 @@ public function __construct( ) {} /** - * @throws LogicException * @throws InvalidArgumentException */ public function handle(Command $command): void { $this->logger->info('ApplicationInstallations.Install.start', [ - (string) $command, + 'externalId' => $command->externalId, + 'bitrix24UserId' => $command->bitrix24UserId, + 'isBitrix24UserAdmin' => $command->isBitrix24UserAdmin, + 'memberId' => $command->memberId, ]); - /* - * Аккаунтов может быть несколько , но установку на портал проводят только 1 раз , то есть есть мастер аккаунт который нужно получать. - * У остальных аккаунтов установок быть не может это просто (доступы/авторизации). - * Решить какое поле для мастера добавить в аккаунт. - */ /** @var AggregateRootEventsEmitterInterface|Bitrix24AccountInterface[] $b24Accounts */ $b24Accounts = $this->bitrix24AccountRepository->findActiveByMemberId($command->memberId); @@ -61,8 +58,10 @@ public function handle(Command $command): void $entitiesToFlush[] = $b24Account; } - /* Здесь сразу флашим так как это условие не всегда работает , и лучше сначало разобраться с аккаунтами и установщиками - которые нужно деактивировать , а после уже работаем с новыми сущностями. */ + /* + Здесь сразу флашим так как это условие не всегда работает , и лучше сначало разобраться с аккаунтами и установщиками + которые нужно деактивировать , а после уже работаем с новыми сущностями. + */ $this->flusher->flush(...$entitiesToFlush); } @@ -83,7 +82,6 @@ public function handle(Command $command): void ); $bitrix24Account->applicationInstalled(null); - $this->bitrix24AccountRepository->save($bitrix24Account); $applicationInstallation = new ApplicationInstallation( diff --git a/src/ApplicationInstallations/UseCase/OnAppInstall/Command.php b/src/ApplicationInstallations/UseCase/OnAppInstall/Command.php index 64a1e60..403a251 100644 --- a/src/ApplicationInstallations/UseCase/OnAppInstall/Command.php +++ b/src/ApplicationInstallations/UseCase/OnAppInstall/Command.php @@ -4,11 +4,13 @@ namespace Bitrix24\Lib\ApplicationInstallations\UseCase\OnAppInstall; +use Bitrix24\Lib\Bitrix24Accounts\ValueObjects\Domain; + readonly class Command { public function __construct( public string $memberId, - public string $domainUrl, + public Domain $domainUrl, public string $applicationToken, public string $applicationStatus, ) { @@ -21,10 +23,6 @@ private function validate(): void throw new \InvalidArgumentException('Member ID must be a non-empty string.'); } - if ('' === $this->domainUrl) { - throw new \InvalidArgumentException('Domain url must be a non-empty string.'); - } - if ('' === $this->applicationToken) { throw new \InvalidArgumentException('ApplicationToken must be a non-empty string.'); } diff --git a/src/ApplicationInstallations/UseCase/OnAppInstall/Handler.php b/src/ApplicationInstallations/UseCase/OnAppInstall/Handler.php index 553c14e..fe9feea 100644 --- a/src/ApplicationInstallations/UseCase/OnAppInstall/Handler.php +++ b/src/ApplicationInstallations/UseCase/OnAppInstall/Handler.php @@ -36,14 +36,16 @@ public function handle(Command $command): void 'application_status' => $command->applicationStatus, ]); - // Тут нужно получить аккаунт мастера , так как если я не ошибаюсь , события установки могут приходить не сразу. - // И за это время на портале могут появится несколько других авторизаций. /** @var AggregateRootEventsEmitterInterface|Bitrix24AccountInterface $bitrix24Account */ $bitrix24Account = $this->bitrix24AccountRepository->findMasterByMemberId( $command->memberId, Bitrix24AccountStatus::active, ); + $bitrix24Account->setApplicationToken($command->applicationToken); + + $this->bitrix24AccountRepository->save($bitrix24Account); + /** @var null|AggregateRootEventsEmitterInterface|ApplicationInstallationInterface $applicationInstallation */ $applicationInstallation = $this->applicationInstallationRepository->findByBitrix24AccountId($bitrix24Account->getId()); @@ -53,9 +55,6 @@ public function handle(Command $command): void $applicationInstallation->setApplicationToken($command->applicationToken); - $bitrix24Account->setApplicationToken($command->applicationToken); - - $this->bitrix24AccountRepository->save($bitrix24Account); $this->applicationInstallationRepository->save($applicationInstallation); $this->flusher->flush($applicationInstallation, $bitrix24Account); diff --git a/src/Bitrix24Accounts/Entity/Bitrix24Account.php b/src/Bitrix24Accounts/Entity/Bitrix24Account.php index a0f8b04..ec1f651 100644 --- a/src/Bitrix24Accounts/Entity/Bitrix24Account.php +++ b/src/Bitrix24Accounts/Entity/Bitrix24Account.php @@ -186,7 +186,8 @@ public function applicationInstalled(?string $applicationToken): void ); } - if (null !== $applicationToken && '' !== $applicationToken && '0' !== $applicationToken) { + if (null !== $applicationToken) { + $this->guardEmptyToken($applicationToken); $this->applicationToken = $applicationToken; } diff --git a/tests/Functional/ApplicationInstallations/Builders/ApplicationInstallationBuilder.php b/tests/Functional/ApplicationInstallations/Builders/ApplicationInstallationBuilder.php index fb2788b..264a03a 100644 --- a/tests/Functional/ApplicationInstallations/Builders/ApplicationInstallationBuilder.php +++ b/tests/Functional/ApplicationInstallations/Builders/ApplicationInstallationBuilder.php @@ -105,7 +105,7 @@ public function build(): ApplicationInstallation ); if (!empty($this->status) && $this->status == ApplicationInstallationStatus::active) { - if ($this->applicationToken !== null && $this->applicationToken !== '' && $this->applicationToken !== '0') { + if ($this->applicationToken !== null && $this->applicationToken !== '') { $applicationInstallation->applicationInstalled($this->applicationToken); } else { $applicationInstallation->applicationInstalled(); diff --git a/tests/Functional/ApplicationInstallations/UseCase/OnAppInstall/HandlerTest.php b/tests/Functional/ApplicationInstallations/UseCase/OnAppInstall/HandlerTest.php index 6df8dd5..ea179a5 100644 --- a/tests/Functional/ApplicationInstallations/UseCase/OnAppInstall/HandlerTest.php +++ b/tests/Functional/ApplicationInstallations/UseCase/OnAppInstall/HandlerTest.php @@ -113,7 +113,7 @@ public function testEventOnAppInstall(): void $this->handler->handle( new ApplicationInstallations\UseCase\OnAppInstall\Command( $memberId, - $domainUrl, + new Domain($domainUrl), $applicationToken, $applicationStatus ) From bbf598e27c8c91797a57a9f60435cabd17b96c0b Mon Sep 17 00:00:00 2001 From: KarlsonComplete Date: Fri, 11 Jul 2025 00:18:21 +0300 Subject: [PATCH 44/49] . --- .../UseCase/Install/Command.php | 22 ++-- .../UseCase/Install/Handler.php | 16 +-- .../UseCase/Install/HandlerTest.php | 96 +++++++++++++++- .../UseCase/Uninstall/HandlerTest.php | 1 - .../UseCase/Install/CommandTest.php | 108 ++++++++++++++++++ .../UseCase/OnAppInstall/CommandTest.php | 21 ++++ .../UseCase/Uninstall/CommandTest.php | 21 ++++ 7 files changed, 268 insertions(+), 17 deletions(-) create mode 100644 tests/Unit/ApplicationInstallations/UseCase/Install/CommandTest.php create mode 100644 tests/Unit/ApplicationInstallations/UseCase/OnAppInstall/CommandTest.php create mode 100644 tests/Unit/ApplicationInstallations/UseCase/Uninstall/CommandTest.php diff --git a/src/ApplicationInstallations/UseCase/Install/Command.php b/src/ApplicationInstallations/UseCase/Install/Command.php index 64d67f0..1c6bdfc 100644 --- a/src/ApplicationInstallations/UseCase/Install/Command.php +++ b/src/ApplicationInstallations/UseCase/Install/Command.php @@ -10,6 +10,7 @@ use Bitrix24\SDK\Core\Credentials\AuthToken; use Bitrix24\SDK\Core\Credentials\Scope; use Symfony\Component\Uid\Uuid; +use Bitrix24\SDK\Core\Exceptions\InvalidArgumentException; readonly class Command { @@ -28,7 +29,8 @@ public function __construct( public Domain $domain, public AuthToken $authToken, public int $applicationVersion, - public Scope $applicationScope + public Scope $applicationScope, + public ?string $applicationToken = null, ) { $this->validate(); } @@ -36,27 +38,33 @@ public function __construct( private function validate(): void { if ($this->portalUsersCount <= 0) { - throw new \InvalidArgumentException('Portal Users count must be a positive integer.'); + throw new InvalidArgumentException('Portal Users count must be a positive integer.'); } if ('' === $this->externalId) { - throw new \InvalidArgumentException('External ID must be a non-empty string.'); + throw new InvalidArgumentException('External ID must be a non-empty string.'); } if ('' === $this->comment) { - throw new \InvalidArgumentException('Comment must be a non-empty string.'); + throw new InvalidArgumentException('Comment must be a non-empty string.'); } if ($this->bitrix24UserId <= 0) { - throw new \InvalidArgumentException('Bitrix24 User ID must be a positive integer.'); + throw new InvalidArgumentException('Bitrix24 User ID must be a positive integer.'); } if ('' === $this->memberId) { - throw new \InvalidArgumentException('Member ID must be a non-empty string.'); + throw new InvalidArgumentException('Member ID must be a non-empty string.'); } if ($this->applicationVersion <= 0) { - throw new \InvalidArgumentException('Application version must be a positive integer.'); + throw new InvalidArgumentException('Application version must be a positive integer.'); + } + + if ($this->applicationToken !== null) { + if ($this->applicationToken == '') { + throw new InvalidArgumentException('Application token must be a non-empty string.'); + } } } } diff --git a/src/ApplicationInstallations/UseCase/Install/Handler.php b/src/ApplicationInstallations/UseCase/Install/Handler.php index db97d77..7c05ccc 100644 --- a/src/ApplicationInstallations/UseCase/Install/Handler.php +++ b/src/ApplicationInstallations/UseCase/Install/Handler.php @@ -20,11 +20,13 @@ readonly class Handler { public function __construct( - private Bitrix24AccountRepository $bitrix24AccountRepository, + private Bitrix24AccountRepository $bitrix24AccountRepository, private ApplicationInstallationRepository $applicationInstallationRepository, - private Flusher $flusher, - private LoggerInterface $logger - ) {} + private Flusher $flusher, + private LoggerInterface $logger + ) + { + } /** * @throws InvalidArgumentException @@ -36,6 +38,7 @@ public function handle(Command $command): void 'bitrix24UserId' => $command->bitrix24UserId, 'isBitrix24UserAdmin' => $command->isBitrix24UserAdmin, 'memberId' => $command->memberId, + 'applicationToken' => $command->applicationToken, ]); /** @var AggregateRootEventsEmitterInterface|Bitrix24AccountInterface[] $b24Accounts */ @@ -52,7 +55,6 @@ public function handle(Command $command): void $this->applicationInstallationRepository->save($activeInstallation); $entitiesToFlush[] = $activeInstallation; } - $b24Account->applicationUninstalled(null); $this->bitrix24AccountRepository->save($b24Account); $entitiesToFlush[] = $b24Account; @@ -81,7 +83,7 @@ public function handle(Command $command): void true ); - $bitrix24Account->applicationInstalled(null); + $bitrix24Account->applicationInstalled($command->applicationToken); $this->bitrix24AccountRepository->save($bitrix24Account); $applicationInstallation = new ApplicationInstallation( @@ -98,7 +100,7 @@ public function handle(Command $command): void true ); - $applicationInstallation->applicationInstalled(); + $applicationInstallation->applicationInstalled($command->applicationToken); $this->applicationInstallationRepository->save($applicationInstallation); $this->flusher->flush($applicationInstallation, $bitrix24Account); diff --git a/tests/Functional/ApplicationInstallations/UseCase/Install/HandlerTest.php b/tests/Functional/ApplicationInstallations/UseCase/Install/HandlerTest.php index f0d219f..9da3891 100644 --- a/tests/Functional/ApplicationInstallations/UseCase/Install/HandlerTest.php +++ b/tests/Functional/ApplicationInstallations/UseCase/Install/HandlerTest.php @@ -24,8 +24,10 @@ use Bitrix24\Lib\Tests\Functional\ApplicationInstallations\Builders\ApplicationInstallationBuilder; use Bitrix24\Lib\Tests\Functional\Bitrix24Accounts\Builders\Bitrix24AccountBuilder; use Bitrix24\SDK\Application\ApplicationStatus; +use Bitrix24\SDK\Application\Contracts\ApplicationInstallations\Entity\ApplicationInstallationInterface; use Bitrix24\SDK\Application\Contracts\ApplicationInstallations\Entity\ApplicationInstallationStatus; use Bitrix24\SDK\Application\Contracts\Bitrix24Accounts\Entity\Bitrix24AccountStatus; +use Bitrix24\SDK\Application\Contracts\Events\AggregateRootEventsEmitterInterface; use Bitrix24\SDK\Application\PortalLicenseFamily; use Bitrix24\SDK\Core\Credentials\Scope; use Bitrix24\SDK\Core\Exceptions\InvalidArgumentException; @@ -82,7 +84,7 @@ protected function setUp(): void * @throws InvalidArgumentException */ #[Test] - public function testInstallNewApplicationInstallation(): void + public function testNewInstallation(): void { $bitrix24AccountBuilder = (new Bitrix24AccountBuilder()) ->withApplicationScope(new Scope(['crm'])) @@ -127,7 +129,96 @@ public function testInstallNewApplicationInstallation(): void * @throws InvalidArgumentException */ #[Test] - public function testReinstallApplicationInstallation(): void + public function testNewInstallationWithToken(): void + { + $bitrix24AccountBuilder = (new Bitrix24AccountBuilder()) + ->withApplicationScope(new Scope(['crm'])) + ->build(); + + + $applicationInstallationBuilder = (new ApplicationInstallationBuilder()) + ->withApplicationStatus(new ApplicationStatus('F')) + ->withPortalLicenseFamily(PortalLicenseFamily::free) + ->build(); + + $newApplicationToken = Uuid::v7()->toRfc4122(); + + $this->handler->handle( + new ApplicationInstallations\UseCase\Install\Command( + $applicationInstallationBuilder->getApplicationStatus(), + $applicationInstallationBuilder->getPortalLicenseFamily(), + $applicationInstallationBuilder->getPortalUsersCount(), + $applicationInstallationBuilder->getContactPersonId(), + $applicationInstallationBuilder->getBitrix24PartnerContactPersonId(), + $applicationInstallationBuilder->getBitrix24PartnerId(), + $applicationInstallationBuilder->getExternalId(), + $applicationInstallationBuilder->getComment(), + $bitrix24AccountBuilder->getBitrix24UserId(), + $bitrix24AccountBuilder->isBitrix24UserAdmin(), + $bitrix24AccountBuilder->getMemberId(), + new Domain($bitrix24AccountBuilder->getDomainUrl()), + $bitrix24AccountBuilder->getAuthToken(), + $bitrix24AccountBuilder->getApplicationVersion(), + $bitrix24AccountBuilder->getApplicationScope(), + $newApplicationToken + ) + ); + + $activeInstallation = $this->repository->findActiveByApplicationToken($newApplicationToken); + $this->assertNotNull($activeInstallation); + + $dispatchedEvents = $this->eventDispatcher->getOrphanedEvents(); + + $this->assertContains(\Bitrix24\SDK\Application\Contracts\Bitrix24Accounts\Events\Bitrix24AccountCreatedEvent::class, $dispatchedEvents); + $this->assertContains(\Bitrix24\SDK\Application\Contracts\ApplicationInstallations\Events\ApplicationInstallationCreatedEvent::class, $dispatchedEvents); + $this->assertContains(\Bitrix24\SDK\Application\Contracts\Bitrix24Accounts\Events\Bitrix24AccountApplicationInstalledEvent::class, $dispatchedEvents); + $this->assertContains(\Bitrix24\SDK\Application\Contracts\ApplicationInstallations\Events\ApplicationInstallationFinishedEvent::class, $dispatchedEvents); + } + + /** + * @throws InvalidArgumentException + */ + #[Test] + public function testNewInstallationWithEmptyToken(): void + { + $bitrix24AccountBuilder = (new Bitrix24AccountBuilder()) + ->withApplicationScope(new Scope(['crm'])) + ->build(); + + + $applicationInstallationBuilder = (new ApplicationInstallationBuilder()) + ->withApplicationStatus(new ApplicationStatus('F')) + ->withPortalLicenseFamily(PortalLicenseFamily::free) + ->build(); + + $this->expectException(InvalidArgumentException::class); + $this->handler->handle( + new ApplicationInstallations\UseCase\Install\Command( + $applicationInstallationBuilder->getApplicationStatus(), + $applicationInstallationBuilder->getPortalLicenseFamily(), + $applicationInstallationBuilder->getPortalUsersCount(), + $applicationInstallationBuilder->getContactPersonId(), + $applicationInstallationBuilder->getBitrix24PartnerContactPersonId(), + $applicationInstallationBuilder->getBitrix24PartnerId(), + $applicationInstallationBuilder->getExternalId(), + $applicationInstallationBuilder->getComment(), + $bitrix24AccountBuilder->getBitrix24UserId(), + $bitrix24AccountBuilder->isBitrix24UserAdmin(), + $bitrix24AccountBuilder->getMemberId(), + new Domain($bitrix24AccountBuilder->getDomainUrl()), + $bitrix24AccountBuilder->getAuthToken(), + $bitrix24AccountBuilder->getApplicationVersion(), + $bitrix24AccountBuilder->getApplicationScope(), + '' + ) + ); + } + + /** + * @throws InvalidArgumentException + */ + #[Test] + public function testReinstallInstallation(): void { $memberId = Uuid::v4()->toRfc4122(); @@ -254,4 +345,5 @@ public function testFewInstallationsOnOneAccount(): void $this->assertContains(\Bitrix24\SDK\Application\Contracts\Bitrix24Accounts\Events\Bitrix24AccountApplicationInstalledEvent::class, $dispatchedEvents); $this->assertContains(\Bitrix24\SDK\Application\Contracts\ApplicationInstallations\Events\ApplicationInstallationFinishedEvent::class, $dispatchedEvents); } + } diff --git a/tests/Functional/ApplicationInstallations/UseCase/Uninstall/HandlerTest.php b/tests/Functional/ApplicationInstallations/UseCase/Uninstall/HandlerTest.php index 142397b..28310cb 100644 --- a/tests/Functional/ApplicationInstallations/UseCase/Uninstall/HandlerTest.php +++ b/tests/Functional/ApplicationInstallations/UseCase/Uninstall/HandlerTest.php @@ -27,7 +27,6 @@ use Bitrix24\SDK\Application\Contracts\ApplicationInstallations\Entity\ApplicationInstallationStatus; use Bitrix24\SDK\Application\Contracts\ApplicationInstallations\Exceptions\ApplicationInstallationNotFoundException; use Bitrix24\SDK\Application\Contracts\Bitrix24Accounts\Entity\Bitrix24AccountStatus; -use Bitrix24\SDK\Application\Contracts\Bitrix24Accounts\Exceptions\Bitrix24AccountNotFoundException; use Bitrix24\SDK\Application\PortalLicenseFamily; use Bitrix24\SDK\Core\Credentials\Scope; use Bitrix24\SDK\Core\Exceptions\InvalidArgumentException; diff --git a/tests/Unit/ApplicationInstallations/UseCase/Install/CommandTest.php b/tests/Unit/ApplicationInstallations/UseCase/Install/CommandTest.php new file mode 100644 index 0000000..e9eb462 --- /dev/null +++ b/tests/Unit/ApplicationInstallations/UseCase/Install/CommandTest.php @@ -0,0 +1,108 @@ +expectException($expectedException); + } + + new Install\Command( + $applicationStatus, + $portalLicenseFamily, + $portalUsersCount, + $contactPersonId, + $bitrix24PartnerContactPersonId, + $bitrix24PartnerId, + $externalId, + $comment, + $bitrix24UserId, + $isBitrix24UserAdmin, + $memberId, + $domain, + $authToken, + $applicationVersion, + $applicationScope, + $applicationToken, + ); + } + + public static function dataForCommand(): \Generator + { + $applicationInstallationBuilder = (new ApplicationInstallationBuilder()) + ->withApplicationStatus(new ApplicationStatus('F')) + ->withPortalLicenseFamily(PortalLicenseFamily::free) + ->build(); + + $bitrix24AccountBuilder = (new Bitrix24AccountBuilder()) + ->withApplicationScope(new Scope(['crm'])) + ->build(); + + + yield '' => [ + $applicationInstallationBuilder->getApplicationStatus(), + $applicationInstallationBuilder->getPortalLicenseFamily(), + $applicationInstallationBuilder->getPortalUsersCount(), + $applicationInstallationBuilder->getContactPersonId(), + $applicationInstallationBuilder->getBitrix24PartnerContactPersonId(), + $applicationInstallationBuilder->getBitrix24PartnerId(), + $applicationInstallationBuilder->getExternalId(), + $applicationInstallationBuilder->getComment(), + $applicationInstallationBuilder->getBitrix24AccountId(), + $bitrix24AccountBuilder->getBitrix24UserId(), + $bitrix24AccountBuilder->isBitrix24UserAdmin(), + $bitrix24AccountBuilder->getMemberId(), + $bitrix24AccountBuilder->getDomainUrl(), + $bitrix24AccountBuilder->getAuthToken(), + $bitrix24AccountBuilder->getApplicationVersion(), + $bitrix24AccountBuilder->getApplicationScope(), + ]; + + } +} \ No newline at end of file diff --git a/tests/Unit/ApplicationInstallations/UseCase/OnAppInstall/CommandTest.php b/tests/Unit/ApplicationInstallations/UseCase/OnAppInstall/CommandTest.php new file mode 100644 index 0000000..da88df1 --- /dev/null +++ b/tests/Unit/ApplicationInstallations/UseCase/OnAppInstall/CommandTest.php @@ -0,0 +1,21 @@ + Date: Sun, 13 Jul 2025 13:49:19 +0300 Subject: [PATCH 45/49] =?UTF-8?q?=D0=94=D0=BE=D0=BF=D0=B8=D1=81=D0=B0?= =?UTF-8?q?=D0=BB=20=D1=8E=D0=BD=D0=B8=D1=82=20=D1=82=D0=B5=D1=81=D1=82?= =?UTF-8?q?=D1=8B=20=D0=B4=D0=BB=D1=8F=20=D1=83=D1=81=D1=82=D0=B0=D0=BD?= =?UTF-8?q?=D0=BE=D0=B2=D1=89=D0=B8=D0=BA=D0=B0.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../UseCase/Install/CommandTest.php | 160 +++++++++++++++++- .../UseCase/OnAppInstall/CommandTest.php | 92 +++++++++- .../UseCase/Uninstall/CommandTest.php | 66 +++++++- .../UseCase/InstallStart/CommandTest.php | 6 +- 4 files changed, 311 insertions(+), 13 deletions(-) diff --git a/tests/Unit/ApplicationInstallations/UseCase/Install/CommandTest.php b/tests/Unit/ApplicationInstallations/UseCase/Install/CommandTest.php index e9eb462..aae26c7 100644 --- a/tests/Unit/ApplicationInstallations/UseCase/Install/CommandTest.php +++ b/tests/Unit/ApplicationInstallations/UseCase/Install/CommandTest.php @@ -5,18 +5,18 @@ namespace Bitrix24\Lib\Tests\Unit\ApplicationInstallations\UseCase\Install; -use Bitrix24\Lib\Bitrix24Accounts\UseCase\ChangeDomainUrl\Command; use Bitrix24\Lib\Bitrix24Accounts\ValueObjects\Domain; use Bitrix24\Lib\Tests\Functional\Bitrix24Accounts\Builders\Bitrix24AccountBuilder; use Bitrix24\SDK\Application\ApplicationStatus; use Bitrix24\SDK\Application\PortalLicenseFamily; use Bitrix24\SDK\Core\Credentials\AuthToken; use Bitrix24\SDK\Core\Credentials\Scope; +use Bitrix24\SDK\Core\Exceptions\InvalidArgumentException; use PHPUnit\Framework\Attributes\CoversClass; use PHPUnit\Framework\TestCase; use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\Attributes\Test; -use Bitrix24\Lib\ApplicationInstallations\UseCase\Install; +use Bitrix24\Lib\ApplicationInstallations\UseCase\Install\Command; use Symfony\Component\Uid\Uuid; use Bitrix24\Lib\Tests\Functional\ApplicationInstallations\Builders\ApplicationInstallationBuilder; @@ -53,7 +53,7 @@ public function testValidCommand( $this->expectException($expectedException); } - new Install\Command( + $command = new Command( $applicationStatus, $portalLicenseFamily, $portalUsersCount, @@ -71,6 +71,11 @@ public function testValidCommand( $applicationScope, $applicationToken, ); + + if (null === $expectedException) { + // Проверяем, что объект создан и является экземпляром нужного класса + $this->assertInstanceOf(Command::class, $command); + } } public static function dataForCommand(): \Generator @@ -84,8 +89,150 @@ public static function dataForCommand(): \Generator ->withApplicationScope(new Scope(['crm'])) ->build(); + yield 'validCommand' => [ + $applicationInstallationBuilder->getApplicationStatus(), + $applicationInstallationBuilder->getPortalLicenseFamily(), + $applicationInstallationBuilder->getPortalUsersCount(), + $applicationInstallationBuilder->getContactPersonId(), + $applicationInstallationBuilder->getBitrix24PartnerContactPersonId(), + $applicationInstallationBuilder->getBitrix24PartnerId(), + $applicationInstallationBuilder->getExternalId(), + $applicationInstallationBuilder->getComment(), + $bitrix24AccountBuilder->getBitrix24UserId(), + $bitrix24AccountBuilder->isBitrix24UserAdmin(), + $bitrix24AccountBuilder->getMemberId(), + new Domain($bitrix24AccountBuilder->getDomainUrl()), + $bitrix24AccountBuilder->getAuthToken(), + $bitrix24AccountBuilder->getApplicationVersion(), + $bitrix24AccountBuilder->getApplicationScope(), + null, + null, + ]; + + yield 'invalidPortalUsersCount' => [ + $applicationInstallationBuilder->getApplicationStatus(), + $applicationInstallationBuilder->getPortalLicenseFamily(), + 0, + $applicationInstallationBuilder->getContactPersonId(), + $applicationInstallationBuilder->getBitrix24PartnerContactPersonId(), + $applicationInstallationBuilder->getBitrix24PartnerId(), + $applicationInstallationBuilder->getExternalId(), + $applicationInstallationBuilder->getComment(), + $bitrix24AccountBuilder->getBitrix24UserId(), + $bitrix24AccountBuilder->isBitrix24UserAdmin(), + $bitrix24AccountBuilder->getMemberId(), + new Domain($bitrix24AccountBuilder->getDomainUrl()), + $bitrix24AccountBuilder->getAuthToken(), + $bitrix24AccountBuilder->getApplicationVersion(), + $bitrix24AccountBuilder->getApplicationScope(), + null, + InvalidArgumentException::class, + ]; + + yield 'emptyExternalId' => [ + $applicationInstallationBuilder->getApplicationStatus(), + $applicationInstallationBuilder->getPortalLicenseFamily(), + $applicationInstallationBuilder->getPortalUsersCount(), + $applicationInstallationBuilder->getContactPersonId(), + $applicationInstallationBuilder->getBitrix24PartnerContactPersonId(), + $applicationInstallationBuilder->getBitrix24PartnerId(), + '', + $applicationInstallationBuilder->getComment(), + $bitrix24AccountBuilder->getBitrix24UserId(), + $bitrix24AccountBuilder->isBitrix24UserAdmin(), + $bitrix24AccountBuilder->getMemberId(), + new Domain($bitrix24AccountBuilder->getDomainUrl()), + $bitrix24AccountBuilder->getAuthToken(), + $bitrix24AccountBuilder->getApplicationVersion(), + $bitrix24AccountBuilder->getApplicationScope(), + null, + InvalidArgumentException::class, + ]; + + yield 'emptyComment' => [ + $applicationInstallationBuilder->getApplicationStatus(), + $applicationInstallationBuilder->getPortalLicenseFamily(), + $applicationInstallationBuilder->getPortalUsersCount(), + $applicationInstallationBuilder->getContactPersonId(), + $applicationInstallationBuilder->getBitrix24PartnerContactPersonId(), + $applicationInstallationBuilder->getBitrix24PartnerId(), + $applicationInstallationBuilder->getExternalId(), + '', + $bitrix24AccountBuilder->getBitrix24UserId(), + $bitrix24AccountBuilder->isBitrix24UserAdmin(), + $bitrix24AccountBuilder->getMemberId(), + new Domain($bitrix24AccountBuilder->getDomainUrl()), + $bitrix24AccountBuilder->getAuthToken(), + $bitrix24AccountBuilder->getApplicationVersion(), + $bitrix24AccountBuilder->getApplicationScope(), + null, + InvalidArgumentException::class, + ]; + + + yield 'invalidBitrix24UserId' => [ + $applicationInstallationBuilder->getApplicationStatus(), + $applicationInstallationBuilder->getPortalLicenseFamily(), + $applicationInstallationBuilder->getPortalUsersCount(), + $applicationInstallationBuilder->getContactPersonId(), + $applicationInstallationBuilder->getBitrix24PartnerContactPersonId(), + $applicationInstallationBuilder->getBitrix24PartnerId(), + $applicationInstallationBuilder->getExternalId(), + $applicationInstallationBuilder->getComment(), + 0, + $bitrix24AccountBuilder->isBitrix24UserAdmin(), + $bitrix24AccountBuilder->getMemberId(), + new Domain($bitrix24AccountBuilder->getDomainUrl()), + $bitrix24AccountBuilder->getAuthToken(), + $bitrix24AccountBuilder->getApplicationVersion(), + $bitrix24AccountBuilder->getApplicationScope(), + null, + InvalidArgumentException::class, + ]; + + // Пустой memberId + yield 'emptyMemberId' => [ + $applicationInstallationBuilder->getApplicationStatus(), + $applicationInstallationBuilder->getPortalLicenseFamily(), + $applicationInstallationBuilder->getPortalUsersCount(), + $applicationInstallationBuilder->getContactPersonId(), + $applicationInstallationBuilder->getBitrix24PartnerContactPersonId(), + $applicationInstallationBuilder->getBitrix24PartnerId(), + $applicationInstallationBuilder->getExternalId(), + $applicationInstallationBuilder->getComment(), + $bitrix24AccountBuilder->getBitrix24UserId(), + $bitrix24AccountBuilder->isBitrix24UserAdmin(), + '', + new Domain($bitrix24AccountBuilder->getDomainUrl()), + $bitrix24AccountBuilder->getAuthToken(), + $bitrix24AccountBuilder->getApplicationVersion(), + $bitrix24AccountBuilder->getApplicationScope(), + null, + InvalidArgumentException::class, + ]; + + // Некорректная версия приложения + yield 'invalidApplicationVersion' => [ + $applicationInstallationBuilder->getApplicationStatus(), + $applicationInstallationBuilder->getPortalLicenseFamily(), + $applicationInstallationBuilder->getPortalUsersCount(), + $applicationInstallationBuilder->getContactPersonId(), + $applicationInstallationBuilder->getBitrix24PartnerContactPersonId(), + $applicationInstallationBuilder->getBitrix24PartnerId(), + $applicationInstallationBuilder->getExternalId(), + $applicationInstallationBuilder->getComment(), + $bitrix24AccountBuilder->getBitrix24UserId(), + $bitrix24AccountBuilder->isBitrix24UserAdmin(), + $bitrix24AccountBuilder->getMemberId(), + new Domain($bitrix24AccountBuilder->getDomainUrl()), + $bitrix24AccountBuilder->getAuthToken(), + 0, + $bitrix24AccountBuilder->getApplicationScope(), + null, + InvalidArgumentException::class, + ]; - yield '' => [ + yield 'emptyApplicationToken' => [ $applicationInstallationBuilder->getApplicationStatus(), $applicationInstallationBuilder->getPortalLicenseFamily(), $applicationInstallationBuilder->getPortalUsersCount(), @@ -94,14 +241,15 @@ public static function dataForCommand(): \Generator $applicationInstallationBuilder->getBitrix24PartnerId(), $applicationInstallationBuilder->getExternalId(), $applicationInstallationBuilder->getComment(), - $applicationInstallationBuilder->getBitrix24AccountId(), $bitrix24AccountBuilder->getBitrix24UserId(), $bitrix24AccountBuilder->isBitrix24UserAdmin(), $bitrix24AccountBuilder->getMemberId(), - $bitrix24AccountBuilder->getDomainUrl(), + new Domain($bitrix24AccountBuilder->getDomainUrl()), $bitrix24AccountBuilder->getAuthToken(), $bitrix24AccountBuilder->getApplicationVersion(), $bitrix24AccountBuilder->getApplicationScope(), + '', + InvalidArgumentException::class ]; } diff --git a/tests/Unit/ApplicationInstallations/UseCase/OnAppInstall/CommandTest.php b/tests/Unit/ApplicationInstallations/UseCase/OnAppInstall/CommandTest.php index da88df1..6e45f49 100644 --- a/tests/Unit/ApplicationInstallations/UseCase/OnAppInstall/CommandTest.php +++ b/tests/Unit/ApplicationInstallations/UseCase/OnAppInstall/CommandTest.php @@ -1,15 +1,23 @@ expectException($expectedException); + } + + $command = new Command( + $memberId, + $domain, + $applicationToken, + $applicationStatus + ); + + if (null === $expectedException) { + $this->assertInstanceOf(Command::class, $command); + } + } + + public static function dataForCommand(): \Generator + { + $applicationToken = Uuid::v7()->toRfc4122(); + $applicationStatus = 'T'; + + $applicationInstallationBuilder = (new ApplicationInstallationBuilder()) + ->withApplicationStatus(new ApplicationStatus('F')) + ->withPortalLicenseFamily(PortalLicenseFamily::free) + ->withApplicationToken($applicationToken) + ->withApplicationStatusInstallation(ApplicationInstallationStatus::active) + ->build(); + + $bitrix24AccountBuilder = (new Bitrix24AccountBuilder()) + ->withApplicationScope(new Scope(['crm'])) + ->withInstalled() + ->withApplicationToken($applicationToken) + ->withStatus(Bitrix24AccountStatus::active) + ->build(); + + // Валидный кейс + yield 'validCommand' => [ + $bitrix24AccountBuilder->getMemberId(), + new Domain($bitrix24AccountBuilder->getDomainUrl()), + $applicationToken, + $applicationStatus, + null, + ]; + + // Пустой memberId + yield 'emptyMemberId' => [ + '', + new Domain($bitrix24AccountBuilder->getDomainUrl()), + $applicationToken, + $applicationStatus, + \InvalidArgumentException::class, + ]; + + // Пустой applicationToken + yield 'emptyApplicationToken' => [ + $bitrix24AccountBuilder->getMemberId(), + new Domain($bitrix24AccountBuilder->getDomainUrl()), + '', + $applicationStatus, + \InvalidArgumentException::class, + ]; + // Пустой applicationStatus + yield 'emptyApplicationStatus' => [ + $bitrix24AccountBuilder->getMemberId(), + new Domain($bitrix24AccountBuilder->getDomainUrl()), + $applicationToken, + '', + \InvalidArgumentException::class, + ]; + } } \ No newline at end of file diff --git a/tests/Unit/ApplicationInstallations/UseCase/Uninstall/CommandTest.php b/tests/Unit/ApplicationInstallations/UseCase/Uninstall/CommandTest.php index 1991c47..97fd0d7 100644 --- a/tests/Unit/ApplicationInstallations/UseCase/Uninstall/CommandTest.php +++ b/tests/Unit/ApplicationInstallations/UseCase/Uninstall/CommandTest.php @@ -1,15 +1,19 @@ expectException($expectedException); + } + + $command = new Command( + $domain, + $memberId, + $applicationToken + ); + + if (null === $expectedException) { + $this->assertInstanceOf(Command::class, $command); + } + } + + public static function dataForCommand(): \Generator + { + $applicationToken = Uuid::v7()->toRfc4122(); + + $bitrix24AccountBuilder = (new Bitrix24AccountBuilder()) + ->withApplicationScope(new Scope(['crm'])) + ->withInstalled() + ->withApplicationToken($applicationToken) + ->withStatus(Bitrix24AccountStatus::active) + ->build(); + + // Валидный кейс + yield 'validCommand' => [ + $bitrix24AccountBuilder->getMemberId(), + new Domain($bitrix24AccountBuilder->getDomainUrl()), + $applicationToken, + null, + ]; + + // Пустой memberId + yield 'emptyMemberId' => [ + '', + new Domain($bitrix24AccountBuilder->getDomainUrl()), + $applicationToken, + \InvalidArgumentException::class, + ]; + // Пустой applicationToken + yield 'emptyApplicationToken' => [ + $bitrix24AccountBuilder->getMemberId(), + new Domain($bitrix24AccountBuilder->getDomainUrl()), + '', + \InvalidArgumentException::class, + ]; + } } \ No newline at end of file diff --git a/tests/Unit/Bitrix24Accounts/UseCase/InstallStart/CommandTest.php b/tests/Unit/Bitrix24Accounts/UseCase/InstallStart/CommandTest.php index 3369550..d9d3b05 100644 --- a/tests/Unit/Bitrix24Accounts/UseCase/InstallStart/CommandTest.php +++ b/tests/Unit/Bitrix24Accounts/UseCase/InstallStart/CommandTest.php @@ -80,7 +80,7 @@ public static function dataForCommand(): \Generator 'Member ID must be a non-empty string.' ]; - yield 'validDomainUrl' => [ + yield 'emptyDomainUrl' => [ $bitrix24Account->getId(), $bitrix24Account->getBitrix24UserId(), $bitrix24Account->isBitrix24UserAdmin(), @@ -93,7 +93,7 @@ public static function dataForCommand(): \Generator sprintf('Invalid domain: %s', '') ]; - yield 'validBitrix24UserId' => [ + yield 'invalidBitrix24UserId' => [ $bitrix24Account->getId(), 0, $bitrix24Account->isBitrix24UserAdmin(), @@ -106,7 +106,7 @@ public static function dataForCommand(): \Generator 'Bitrix24 User ID must be a positive integer.' ]; - yield 'validApplicationToken' => [ + yield 'invalidApplicationVersion' => [ $bitrix24Account->getId(), $bitrix24Account->getBitrix24UserId(), $bitrix24Account->isBitrix24UserAdmin(), From 1e13af873e74e3ab7b3b2f76614fcc94e007a14a Mon Sep 17 00:00:00 2001 From: KarlsonComplete Date: Sun, 13 Jul 2025 14:14:03 +0300 Subject: [PATCH 46/49] =?UTF-8?q?=D0=A0=D0=B5=D0=BA=D1=82=D0=BE=D1=80=20+?= =?UTF-8?q?=20=D0=A4=D0=B8=D0=BA=D1=81=D0=B5=D1=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Doctrine/ApplicationInstallationRepository.php | 8 +++++--- .../UseCase/Install/Command.php | 8 +++----- .../UseCase/Install/Handler.php | 14 +++++++------- .../UseCase/Uninstall/Handler.php | 13 +++++-------- .../Doctrine/Bitrix24AccountRepository.php | 8 ++++---- .../UseCase/Uninstall/HandlerTest.php | 6 +++--- .../UseCase/OnAppInstall/CommandTest.php | 2 +- 7 files changed, 28 insertions(+), 31 deletions(-) diff --git a/src/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationRepository.php b/src/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationRepository.php index 4d3f4a1..aaecd8c 100644 --- a/src/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationRepository.php +++ b/src/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationRepository.php @@ -114,14 +114,15 @@ public function findActiveByAccountId(Uuid $uuid): ?ApplicationInstallationInter ->setParameter('b24AccountId', $uuid) ->setParameter('statuses', $activeStatuses) ->getQuery() - ->getOneOrNullResult(); + ->getOneOrNullResult() + ; } public function findActiveByApplicationToken(string $applicationToken): ?ApplicationInstallationInterface { $activeStatuses = [ ApplicationInstallationStatus::new, - ApplicationInstallationStatus::active + ApplicationInstallationStatus::active, ]; return $this->getEntityManager()->getRepository(ApplicationInstallation::class) @@ -131,6 +132,7 @@ public function findActiveByApplicationToken(string $applicationToken): ?Applica ->setParameter('applicationToken', $applicationToken) ->setParameter('statuses', $activeStatuses) ->getQuery() - ->getOneOrNullResult(); + ->getOneOrNullResult() + ; } } diff --git a/src/ApplicationInstallations/UseCase/Install/Command.php b/src/ApplicationInstallations/UseCase/Install/Command.php index 1c6bdfc..8e84750 100644 --- a/src/ApplicationInstallations/UseCase/Install/Command.php +++ b/src/ApplicationInstallations/UseCase/Install/Command.php @@ -9,8 +9,8 @@ use Bitrix24\SDK\Application\PortalLicenseFamily; use Bitrix24\SDK\Core\Credentials\AuthToken; use Bitrix24\SDK\Core\Credentials\Scope; -use Symfony\Component\Uid\Uuid; use Bitrix24\SDK\Core\Exceptions\InvalidArgumentException; +use Symfony\Component\Uid\Uuid; readonly class Command { @@ -61,10 +61,8 @@ private function validate(): void throw new InvalidArgumentException('Application version must be a positive integer.'); } - if ($this->applicationToken !== null) { - if ($this->applicationToken == '') { - throw new InvalidArgumentException('Application token must be a non-empty string.'); - } + if (null !== $this->applicationToken && '' === $this->applicationToken) { + throw new InvalidArgumentException('Application token must be a non-empty string.'); } } } diff --git a/src/ApplicationInstallations/UseCase/Install/Handler.php b/src/ApplicationInstallations/UseCase/Install/Handler.php index 7c05ccc..9ebde87 100644 --- a/src/ApplicationInstallations/UseCase/Install/Handler.php +++ b/src/ApplicationInstallations/UseCase/Install/Handler.php @@ -13,20 +13,17 @@ use Bitrix24\SDK\Application\Contracts\Bitrix24Accounts\Entity\Bitrix24AccountInterface; use Bitrix24\SDK\Application\Contracts\Events\AggregateRootEventsEmitterInterface; use Bitrix24\SDK\Core\Exceptions\InvalidArgumentException; -use Bitrix24\SDK\Core\Exceptions\LogicException; use Psr\Log\LoggerInterface; use Symfony\Component\Uid\Uuid; readonly class Handler { public function __construct( - private Bitrix24AccountRepository $bitrix24AccountRepository, + private Bitrix24AccountRepository $bitrix24AccountRepository, private ApplicationInstallationRepository $applicationInstallationRepository, - private Flusher $flusher, - private LoggerInterface $logger - ) - { - } + private Flusher $flusher, + private LoggerInterface $logger + ) {} /** * @throws InvalidArgumentException @@ -55,6 +52,7 @@ public function handle(Command $command): void $this->applicationInstallationRepository->save($activeInstallation); $entitiesToFlush[] = $activeInstallation; } + $b24Account->applicationUninstalled(null); $this->bitrix24AccountRepository->save($b24Account); $entitiesToFlush[] = $b24Account; @@ -84,6 +82,7 @@ public function handle(Command $command): void ); $bitrix24Account->applicationInstalled($command->applicationToken); + $this->bitrix24AccountRepository->save($bitrix24Account); $applicationInstallation = new ApplicationInstallation( @@ -101,6 +100,7 @@ public function handle(Command $command): void ); $applicationInstallation->applicationInstalled($command->applicationToken); + $this->applicationInstallationRepository->save($applicationInstallation); $this->flusher->flush($applicationInstallation, $bitrix24Account); diff --git a/src/ApplicationInstallations/UseCase/Uninstall/Handler.php b/src/ApplicationInstallations/UseCase/Uninstall/Handler.php index 73f2b79..231680e 100644 --- a/src/ApplicationInstallations/UseCase/Uninstall/Handler.php +++ b/src/ApplicationInstallations/UseCase/Uninstall/Handler.php @@ -13,7 +13,6 @@ use Psr\Log\LoggerInterface; /** - * * Обработчик сценария деинсталляции приложения. * * Важно: Сценарий рассчитан на идеальные условия и может не учитывать случаи, когда: @@ -29,13 +28,11 @@ readonly class Handler { public function __construct( - private Bitrix24AccountRepository $bitrix24AccountRepository, + private Bitrix24AccountRepository $bitrix24AccountRepository, private ApplicationInstallationRepository $applicationInstallationRepository, - private Flusher $flusher, - private LoggerInterface $logger - ) - { - } + private Flusher $flusher, + private LoggerInterface $logger + ) {} public function handle(Command $command): void { @@ -73,8 +70,8 @@ public function handle(Command $command): void $entitiesToFlush[] = $b24Account; } } - $this->flusher->flush(...$entitiesToFlush); + $this->flusher->flush(...$entitiesToFlush); } $this->logger->info( diff --git a/src/Bitrix24Accounts/Infrastructure/Doctrine/Bitrix24AccountRepository.php b/src/Bitrix24Accounts/Infrastructure/Doctrine/Bitrix24AccountRepository.php index 8477799..6f71eae 100644 --- a/src/Bitrix24Accounts/Infrastructure/Doctrine/Bitrix24AccountRepository.php +++ b/src/Bitrix24Accounts/Infrastructure/Doctrine/Bitrix24AccountRepository.php @@ -222,9 +222,9 @@ public function findByApplicationToken(string $applicationToken): array } /** - * @throws InvalidArgumentException - * * @phpstan-return Bitrix24AccountInterface&AggregateRootEventsEmitterInterface + * + * @throws InvalidArgumentException */ #[\Override] public function findOneAdminByMemberId(string $memberId): ?Bitrix24AccountInterface @@ -243,10 +243,10 @@ public function findOneAdminByMemberId(string $memberId): ?Bitrix24AccountInterf } /** - * @phpstan-return array - * * @return array * + * @phpstan-return array + * * @throws InvalidArgumentException */ #[\Override] diff --git a/tests/Functional/ApplicationInstallations/UseCase/Uninstall/HandlerTest.php b/tests/Functional/ApplicationInstallations/UseCase/Uninstall/HandlerTest.php index 28310cb..8cbad0a 100644 --- a/tests/Functional/ApplicationInstallations/UseCase/Uninstall/HandlerTest.php +++ b/tests/Functional/ApplicationInstallations/UseCase/Uninstall/HandlerTest.php @@ -228,11 +228,11 @@ public function testUninstallWithFewAccount(): void $bitrix24Accounts = $this->bitrix24accountRepository->findByMemberId($memberId); - foreach ($bitrix24Accounts as $account) { + foreach ($bitrix24Accounts as $bitrix24Account) { $this->assertSame( Bitrix24AccountStatus::deleted, - $account->getStatus(), - sprintf('Account %s не в статусе "удалён"', $account->getId()) + $bitrix24Account->getStatus(), + sprintf('Account %s не в статусе "удалён"', $bitrix24Account->getId()) ); } } diff --git a/tests/Unit/ApplicationInstallations/UseCase/OnAppInstall/CommandTest.php b/tests/Unit/ApplicationInstallations/UseCase/OnAppInstall/CommandTest.php index 6e45f49..fcf556b 100644 --- a/tests/Unit/ApplicationInstallations/UseCase/OnAppInstall/CommandTest.php +++ b/tests/Unit/ApplicationInstallations/UseCase/OnAppInstall/CommandTest.php @@ -56,7 +56,7 @@ public static function dataForCommand(): \Generator $applicationToken = Uuid::v7()->toRfc4122(); $applicationStatus = 'T'; - $applicationInstallationBuilder = (new ApplicationInstallationBuilder()) + (new ApplicationInstallationBuilder()) ->withApplicationStatus(new ApplicationStatus('F')) ->withPortalLicenseFamily(PortalLicenseFamily::free) ->withApplicationToken($applicationToken) From d273379508c90467310d7de094097a28032b9cae Mon Sep 17 00:00:00 2001 From: KarlsonComplete Date: Fri, 1 Aug 2025 00:12:43 +0300 Subject: [PATCH 47/49] =?UTF-8?q?=D0=9F=D1=80=D0=B0=D0=B2=D0=BA=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ApplicationInstallationRepository.php | 41 +++++++++++---- .../UseCase/Install/Command.php | 22 +++++++- .../UseCase/Install/Handler.php | 51 ++++++++++++------- .../UseCase/OnAppInstall/Command.php | 5 ++ .../UseCase/OnAppInstall/Handler.php | 22 ++++---- .../UseCase/Uninstall/Handler.php | 19 +++++++ 6 files changed, 119 insertions(+), 41 deletions(-) diff --git a/src/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationRepository.php b/src/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationRepository.php index aaecd8c..85d688c 100644 --- a/src/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationRepository.php +++ b/src/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationRepository.php @@ -12,6 +12,7 @@ use Bitrix24\SDK\Core\Exceptions\InvalidArgumentException; use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityRepository; +use Doctrine\ORM\Query\Expr\Join; use Symfony\Component\Uid\Uuid; class ApplicationInstallationRepository extends EntityRepository implements ApplicationInstallationRepositoryInterface @@ -37,8 +38,7 @@ public function getById(Uuid $uuid): ApplicationInstallationInterface ->setParameter('uuid', $uuid) ->setParameter('status', ApplicationInstallationStatus::deleted) ->getQuery() - ->getOneOrNullResult() - ; + ->getOneOrNullResult(); if (null === $applicationInstallation) { throw new ApplicationInstallationNotFoundException( @@ -79,8 +79,7 @@ public function findByBitrix24AccountId(Uuid $uuid): ?ApplicationInstallationInt ->orderBy('appInstallation.createdAt', 'DESC') ->setParameter('bitrix24AccountId', $uuid) ->getQuery() - ->getOneOrNullResult() - ; + ->getOneOrNullResult(); } #[\Override] @@ -96,8 +95,7 @@ public function findByExternalId(string $externalId): array ->orderBy('appInstallation.createdAt', 'DESC') ->setParameter('externalId', $externalId) ->getQuery() - ->getResult() - ; + ->getResult(); } public function findActiveByAccountId(Uuid $uuid): ?ApplicationInstallationInterface @@ -114,8 +112,7 @@ public function findActiveByAccountId(Uuid $uuid): ?ApplicationInstallationInter ->setParameter('b24AccountId', $uuid) ->setParameter('statuses', $activeStatuses) ->getQuery() - ->getOneOrNullResult() - ; + ->getOneOrNullResult(); } public function findActiveByApplicationToken(string $applicationToken): ?ApplicationInstallationInterface @@ -132,7 +129,31 @@ public function findActiveByApplicationToken(string $applicationToken): ?Applica ->setParameter('applicationToken', $applicationToken) ->setParameter('statuses', $activeStatuses) ->getQuery() - ->getOneOrNullResult() - ; + ->getOneOrNullResult(); + } + + /** + * Получаем активную установку приложения с помощью аккаунта. + * + * @param string $memberId + * @return ApplicationInstallation|null + */ + public function findActiveInstallationWithAccountByMemberId(string $memberId): ?ApplicationInstallationInterface + { + $qb = $this->createQueryBuilder('ai'); + + return $qb->leftJoin( + 'Bitrix24\Lib\Bitrix24Accounts\Entity\Bitrix24Account', + 'b24', + Join::WITH, + 'ai.bitrix24AccountId = b24.id AND b24.isMasterAccount = true' + ) + ->where('b24.memberId = :memberId') + ->andWhere('b24.isMasterAccount = true') + ->andWhere('ai.status != :status') + ->setParameter('memberId', $memberId) + ->setParameter('status', ApplicationInstallationStatus::deleted) + ->getQuery() + ->getOneOrNullResult(); } } diff --git a/src/ApplicationInstallations/UseCase/Install/Command.php b/src/ApplicationInstallations/UseCase/Install/Command.php index 8e84750..db177ee 100644 --- a/src/ApplicationInstallations/UseCase/Install/Command.php +++ b/src/ApplicationInstallations/UseCase/Install/Command.php @@ -12,6 +12,22 @@ use Bitrix24\SDK\Core\Exceptions\InvalidArgumentException; use Symfony\Component\Uid\Uuid; +/** + * Установка может происходить по 2 сценриям. + * Если в эту команду передается $applicationToken значит это установка без UI. + * Иначе это установка с UI и $applicationToken передаваться не должен. + * + * 1) UI - Пользователь запускает установку через интерфейс. + * Bitrix24 отправляет первичный запрос на /install.php с параметрами: + * AUTH_ID, REFRESH_ID, member_id в теле запроса. Без application_token + * Система создаёт Bitrix24Account в статусе new. + * Bitrix24 отправляет событие ONAPPINSTALL на /event-handler.php и передает application_token + * Вызывается applicationInstalled($applicationToken) с полученным токеном. + * 2) Без UI - Установка инициируется прямым POST-запросом с полным набором credentials. + * Сразу создается Bitrix24Account. У установщика и у аккаунта вызывается метод с переданыым токеном: + * $bitrix24Account->applicationInstalled($applicationToken); + * $applicationInstallation->applicationInstalled($applicationToken);. + */ readonly class Command { public function __construct( @@ -61,8 +77,10 @@ private function validate(): void throw new InvalidArgumentException('Application version must be a positive integer.'); } - if (null !== $this->applicationToken && '' === $this->applicationToken) { - throw new InvalidArgumentException('Application token must be a non-empty string.'); + if (null !== $this->applicationToken) { + if ('' === trim($this->applicationToken)) { + throw new InvalidArgumentException('Application token must be a non-empty string.'); + } } } } diff --git a/src/ApplicationInstallations/UseCase/Install/Handler.php b/src/ApplicationInstallations/UseCase/Install/Handler.php index 9ebde87..a9de0f6 100644 --- a/src/ApplicationInstallations/UseCase/Install/Handler.php +++ b/src/ApplicationInstallations/UseCase/Install/Handler.php @@ -26,6 +26,11 @@ public function __construct( ) {} /** + * На данный момент могут быть не обработаны несколько сценариев. + * Например : + * 1) По какой-то причине мы пропустили событие от Б24 с токеном, о том, что надо удалить приложение (удален портал, мы были не доступны и запрос пропущен или еще как-то) + * 2) Надо вручную или еще как-то удалить приложение зная только его member_id (может что-то еще для валидации) + * * @throws InvalidArgumentException */ public function handle(Command $command): void @@ -38,33 +43,43 @@ public function handle(Command $command): void 'applicationToken' => $command->applicationToken, ]); - /** @var AggregateRootEventsEmitterInterface|Bitrix24AccountInterface[] $b24Accounts */ - $b24Accounts = $this->bitrix24AccountRepository->findActiveByMemberId($command->memberId); + /** @var null|AggregateRootEventsEmitterInterface|ApplicationInstallationInterface $activeInstallation */ + $activeInstallation = $this->applicationInstallationRepository->findActiveInstallationWithAccountByMemberId($command->memberId); - if ([] !== $b24Accounts) { + if (null !== $activeInstallation) { $entitiesToFlush = []; - foreach ($b24Accounts as $b24Account) { - $isMaster = $b24Account->isMasterAccount(); - if ($isMaster) { - /** @var AggregateRootEventsEmitterInterface|ApplicationInstallationInterface $activeInstallation */ - $activeInstallation = $this->applicationInstallationRepository->findActiveByAccountId($b24Account->getId()); - $activeInstallation->applicationUninstalled(); - $this->applicationInstallationRepository->save($activeInstallation); - $entitiesToFlush[] = $activeInstallation; - } - $b24Account->applicationUninstalled(null); - $this->bitrix24AccountRepository->save($b24Account); - $entitiesToFlush[] = $b24Account; + $activeInstallation->applicationUninstalled(); + + $this->applicationInstallationRepository->save($activeInstallation); + + $entitiesToFlush[] = $activeInstallation; + + /** @var AggregateRootEventsEmitterInterface|Bitrix24AccountInterface[] $b24Accounts */ + $b24Accounts = $this->bitrix24AccountRepository->findByMemberId($command->memberId); + + if ([] !== $b24Accounts) { + foreach ($b24Accounts as $b24Account) { + $isMaster = $b24Account->isMasterAccount(); + if ($isMaster) { + $b24Account->applicationUninstalled(null); + } else { + $b24Account->applicationUninstalled(null); + } + + $this->bitrix24AccountRepository->save($b24Account); + $entitiesToFlush[] = $b24Account; + } } /* - Здесь сразу флашим так как это условие не всегда работает , и лучше сначало разобраться с аккаунтами и установщиками - которые нужно деактивировать , а после уже работаем с новыми сущностями. - */ + Здесь сразу флашим так как это условие не всегда работает , и лучше сначало разобраться с аккаунтами и установщиками + которые нужно деактивировать , а после уже работаем с новыми сущностями. + */ $this->flusher->flush(...$entitiesToFlush); } + $uuidV7 = Uuid::v7(); $applicationInstallationId = Uuid::v7(); diff --git a/src/ApplicationInstallations/UseCase/OnAppInstall/Command.php b/src/ApplicationInstallations/UseCase/OnAppInstall/Command.php index 403a251..2658e2f 100644 --- a/src/ApplicationInstallations/UseCase/OnAppInstall/Command.php +++ b/src/ApplicationInstallations/UseCase/OnAppInstall/Command.php @@ -6,6 +6,11 @@ use Bitrix24\Lib\Bitrix24Accounts\ValueObjects\Domain; +/** + * Команда вызывается в тех случаях если установка происходит с помощью UI. + * Bitrix24 отправляет событие ONAPPINSTALL на /event-handler.php и передает application_token. + * Цель этого события донести токен приложения. + */ readonly class Command { public function __construct( diff --git a/src/ApplicationInstallations/UseCase/OnAppInstall/Handler.php b/src/ApplicationInstallations/UseCase/OnAppInstall/Handler.php index fe9feea..667a5c2 100644 --- a/src/ApplicationInstallations/UseCase/OnAppInstall/Handler.php +++ b/src/ApplicationInstallations/UseCase/OnAppInstall/Handler.php @@ -36,18 +36,8 @@ public function handle(Command $command): void 'application_status' => $command->applicationStatus, ]); - /** @var AggregateRootEventsEmitterInterface|Bitrix24AccountInterface $bitrix24Account */ - $bitrix24Account = $this->bitrix24AccountRepository->findMasterByMemberId( - $command->memberId, - Bitrix24AccountStatus::active, - ); - - $bitrix24Account->setApplicationToken($command->applicationToken); - - $this->bitrix24AccountRepository->save($bitrix24Account); - /** @var null|AggregateRootEventsEmitterInterface|ApplicationInstallationInterface $applicationInstallation */ - $applicationInstallation = $this->applicationInstallationRepository->findByBitrix24AccountId($bitrix24Account->getId()); + $applicationInstallation = $this->applicationInstallationRepository->findActiveInstallationWithAccountByMemberId($command->memberId); $applicationStatus = new ApplicationStatus($command->applicationStatus); @@ -57,6 +47,16 @@ public function handle(Command $command): void $this->applicationInstallationRepository->save($applicationInstallation); + /** @var AggregateRootEventsEmitterInterface|Bitrix24AccountInterface $bitrix24Account */ + $bitrix24Account = $this->bitrix24AccountRepository->findMasterByMemberId( + $command->memberId, + Bitrix24AccountStatus::active, + ); + + $bitrix24Account->setApplicationToken($command->applicationToken); + + $this->bitrix24AccountRepository->save($bitrix24Account); + $this->flusher->flush($applicationInstallation, $bitrix24Account); $this->logger->info('ApplicationInstallation.OnAppInstall.finish'); diff --git a/src/ApplicationInstallations/UseCase/Uninstall/Handler.php b/src/ApplicationInstallations/UseCase/Uninstall/Handler.php index 231680e..55b7de5 100644 --- a/src/ApplicationInstallations/UseCase/Uninstall/Handler.php +++ b/src/ApplicationInstallations/UseCase/Uninstall/Handler.php @@ -46,6 +46,11 @@ public function handle(Command $command): void $activeInstallation = $this->applicationInstallationRepository->findActiveByApplicationToken($command->applicationToken); if (null !== $activeInstallation) { + + $this->logger->info( + 'ApplicationInstallations.Uninstall.Start' + ); + $entitiesToFlush = []; $activeInstallation->applicationUninstalled($command->applicationToken); @@ -72,6 +77,20 @@ public function handle(Command $command): void } $this->flusher->flush(...$entitiesToFlush); + + $this->logger->info('ApplicationInstallations.Uninstall.completed', [ + 'installationId' => $activeInstallation->getId(), + 'applicationToken' => $command->applicationToken, + 'flushedEntitiesCount' => count($entitiesToFlush), + ]); + + }else{ + $this->logger->info('ApplicationInstallations.Uninstall.false_request', [ + 'applicationToken' => $command->applicationToken, + 'memberId' => $command->memberId, + 'domainUrl' => $command->domainUrl, + 'message' => 'No active installation found for uninstall request', + ]); } $this->logger->info( From ded8f7a215997cdb334140a1352a9c08f0395742 Mon Sep 17 00:00:00 2001 From: KarlsonComplete Date: Sat, 2 Aug 2025 02:07:18 +0300 Subject: [PATCH 48/49] . --- .../ApplicationInstallationRepository.php | 25 +++++++++++-------- .../UseCase/Install/Command.php | 6 ++--- .../UseCase/Install/Handler.php | 13 +++------- .../UseCase/Uninstall/Handler.php | 4 +-- .../ApplicationInstallationRepositoryTest.php | 2 -- .../Entity/ApplicationInstallationTest.php | 2 -- 6 files changed, 21 insertions(+), 31 deletions(-) diff --git a/src/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationRepository.php b/src/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationRepository.php index 85d688c..2f7effc 100644 --- a/src/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationRepository.php +++ b/src/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationRepository.php @@ -5,6 +5,7 @@ namespace Bitrix24\Lib\ApplicationInstallations\Infrastructure\Doctrine; use Bitrix24\Lib\ApplicationInstallations\Entity\ApplicationInstallation; +use Bitrix24\Lib\Bitrix24Accounts\Entity\Bitrix24Account; use Bitrix24\SDK\Application\Contracts\ApplicationInstallations\Entity\ApplicationInstallationInterface; use Bitrix24\SDK\Application\Contracts\ApplicationInstallations\Entity\ApplicationInstallationStatus; use Bitrix24\SDK\Application\Contracts\ApplicationInstallations\Exceptions\ApplicationInstallationNotFoundException; @@ -38,7 +39,8 @@ public function getById(Uuid $uuid): ApplicationInstallationInterface ->setParameter('uuid', $uuid) ->setParameter('status', ApplicationInstallationStatus::deleted) ->getQuery() - ->getOneOrNullResult(); + ->getOneOrNullResult() + ; if (null === $applicationInstallation) { throw new ApplicationInstallationNotFoundException( @@ -79,7 +81,8 @@ public function findByBitrix24AccountId(Uuid $uuid): ?ApplicationInstallationInt ->orderBy('appInstallation.createdAt', 'DESC') ->setParameter('bitrix24AccountId', $uuid) ->getQuery() - ->getOneOrNullResult(); + ->getOneOrNullResult() + ; } #[\Override] @@ -95,7 +98,8 @@ public function findByExternalId(string $externalId): array ->orderBy('appInstallation.createdAt', 'DESC') ->setParameter('externalId', $externalId) ->getQuery() - ->getResult(); + ->getResult() + ; } public function findActiveByAccountId(Uuid $uuid): ?ApplicationInstallationInterface @@ -112,7 +116,8 @@ public function findActiveByAccountId(Uuid $uuid): ?ApplicationInstallationInter ->setParameter('b24AccountId', $uuid) ->setParameter('statuses', $activeStatuses) ->getQuery() - ->getOneOrNullResult(); + ->getOneOrNullResult() + ; } public function findActiveByApplicationToken(string $applicationToken): ?ApplicationInstallationInterface @@ -129,21 +134,21 @@ public function findActiveByApplicationToken(string $applicationToken): ?Applica ->setParameter('applicationToken', $applicationToken) ->setParameter('statuses', $activeStatuses) ->getQuery() - ->getOneOrNullResult(); + ->getOneOrNullResult() + ; } /** * Получаем активную установку приложения с помощью аккаунта. * - * @param string $memberId - * @return ApplicationInstallation|null + * @return null|ApplicationInstallation */ public function findActiveInstallationWithAccountByMemberId(string $memberId): ?ApplicationInstallationInterface { - $qb = $this->createQueryBuilder('ai'); + $queryBuilder = $this->createQueryBuilder('ai'); - return $qb->leftJoin( - 'Bitrix24\Lib\Bitrix24Accounts\Entity\Bitrix24Account', + return $queryBuilder->leftJoin( + Bitrix24Account::class, 'b24', Join::WITH, 'ai.bitrix24AccountId = b24.id AND b24.isMasterAccount = true' diff --git a/src/ApplicationInstallations/UseCase/Install/Command.php b/src/ApplicationInstallations/UseCase/Install/Command.php index db177ee..120f803 100644 --- a/src/ApplicationInstallations/UseCase/Install/Command.php +++ b/src/ApplicationInstallations/UseCase/Install/Command.php @@ -77,10 +77,8 @@ private function validate(): void throw new InvalidArgumentException('Application version must be a positive integer.'); } - if (null !== $this->applicationToken) { - if ('' === trim($this->applicationToken)) { - throw new InvalidArgumentException('Application token must be a non-empty string.'); - } + if (null !== $this->applicationToken && '' === trim($this->applicationToken)) { + throw new InvalidArgumentException('Application token must be a non-empty string.'); } } } diff --git a/src/ApplicationInstallations/UseCase/Install/Handler.php b/src/ApplicationInstallations/UseCase/Install/Handler.php index a9de0f6..1000e54 100644 --- a/src/ApplicationInstallations/UseCase/Install/Handler.php +++ b/src/ApplicationInstallations/UseCase/Install/Handler.php @@ -29,7 +29,7 @@ public function __construct( * На данный момент могут быть не обработаны несколько сценариев. * Например : * 1) По какой-то причине мы пропустили событие от Б24 с токеном, о том, что надо удалить приложение (удален портал, мы были не доступны и запрос пропущен или еще как-то) - * 2) Надо вручную или еще как-то удалить приложение зная только его member_id (может что-то еще для валидации) + * 2) Надо вручную или еще как-то удалить приложение зная только его member_id (может что-то еще для валидации). * * @throws InvalidArgumentException */ @@ -44,7 +44,7 @@ public function handle(Command $command): void ]); /** @var null|AggregateRootEventsEmitterInterface|ApplicationInstallationInterface $activeInstallation */ - $activeInstallation = $this->applicationInstallationRepository->findActiveInstallationWithAccountByMemberId($command->memberId); + $activeInstallation = $this->applicationInstallationRepository->findActiveInstallationWithAccountByMemberId($command->memberId); if (null !== $activeInstallation) { $entitiesToFlush = []; @@ -60,13 +60,7 @@ public function handle(Command $command): void if ([] !== $b24Accounts) { foreach ($b24Accounts as $b24Account) { - $isMaster = $b24Account->isMasterAccount(); - if ($isMaster) { - $b24Account->applicationUninstalled(null); - } else { - $b24Account->applicationUninstalled(null); - } - + $b24Account->applicationUninstalled(null); $this->bitrix24AccountRepository->save($b24Account); $entitiesToFlush[] = $b24Account; } @@ -79,7 +73,6 @@ public function handle(Command $command): void $this->flusher->flush(...$entitiesToFlush); } - $uuidV7 = Uuid::v7(); $applicationInstallationId = Uuid::v7(); diff --git a/src/ApplicationInstallations/UseCase/Uninstall/Handler.php b/src/ApplicationInstallations/UseCase/Uninstall/Handler.php index 55b7de5..45f3e97 100644 --- a/src/ApplicationInstallations/UseCase/Uninstall/Handler.php +++ b/src/ApplicationInstallations/UseCase/Uninstall/Handler.php @@ -46,7 +46,6 @@ public function handle(Command $command): void $activeInstallation = $this->applicationInstallationRepository->findActiveByApplicationToken($command->applicationToken); if (null !== $activeInstallation) { - $this->logger->info( 'ApplicationInstallations.Uninstall.Start' ); @@ -83,8 +82,7 @@ public function handle(Command $command): void 'applicationToken' => $command->applicationToken, 'flushedEntitiesCount' => count($entitiesToFlush), ]); - - }else{ + } else { $this->logger->info('ApplicationInstallations.Uninstall.false_request', [ 'applicationToken' => $command->applicationToken, 'memberId' => $command->memberId, diff --git a/tests/Functional/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationRepositoryTest.php b/tests/Functional/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationRepositoryTest.php index b3f985c..925d0ac 100644 --- a/tests/Functional/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationRepositoryTest.php +++ b/tests/Functional/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationRepositoryTest.php @@ -32,8 +32,6 @@ class ApplicationInstallationRepositoryTest extends ApplicationInstallationRepos protected function createApplicationInstallationImplementation( Uuid $uuid, ApplicationInstallationStatus $applicationInstallationStatus, - CarbonImmutable $createdAt, - CarbonImmutable $updatedAt, Uuid $bitrix24AccountUuid, ApplicationStatus $applicationStatus, PortalLicenseFamily $portalLicenseFamily, diff --git a/tests/Unit/ApplicationInstallations/Entity/ApplicationInstallationTest.php b/tests/Unit/ApplicationInstallations/Entity/ApplicationInstallationTest.php index e7de8fe..98a4f27 100644 --- a/tests/Unit/ApplicationInstallations/Entity/ApplicationInstallationTest.php +++ b/tests/Unit/ApplicationInstallations/Entity/ApplicationInstallationTest.php @@ -24,8 +24,6 @@ class ApplicationInstallationTest extends ApplicationInstallationInterfaceTest protected function createApplicationInstallationImplementation( Uuid $uuid, ApplicationInstallationStatus $applicationInstallationStatus, - CarbonImmutable $createdAt, - CarbonImmutable $updatedAt, Uuid $bitrix24AccountUuid, ApplicationStatus $applicationStatus, PortalLicenseFamily $portalLicenseFamily, From 6fc9d0a6eeeb70c08f0b46aff1c848f561c6329d Mon Sep 17 00:00:00 2001 From: KarlsonComplete Date: Mon, 4 Aug 2025 21:46:46 +0300 Subject: [PATCH 49/49] =?UTF-8?q?=D0=9F=D1=80=D0=B0=D0=B2=D0=BA=D0=B8.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Doctrine/ApplicationInstallationRepository.php | 3 ++- .../UseCase/Uninstall/Handler.php | 8 +------- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/src/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationRepository.php b/src/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationRepository.php index 2f7effc..df950b4 100644 --- a/src/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationRepository.php +++ b/src/ApplicationInstallations/Infrastructure/Doctrine/ApplicationInstallationRepository.php @@ -159,6 +159,7 @@ public function findActiveInstallationWithAccountByMemberId(string $memberId): ? ->setParameter('memberId', $memberId) ->setParameter('status', ApplicationInstallationStatus::deleted) ->getQuery() - ->getOneOrNullResult(); + ->getOneOrNullResult() + ; } } diff --git a/src/ApplicationInstallations/UseCase/Uninstall/Handler.php b/src/ApplicationInstallations/UseCase/Uninstall/Handler.php index 45f3e97..273c2ba 100644 --- a/src/ApplicationInstallations/UseCase/Uninstall/Handler.php +++ b/src/ApplicationInstallations/UseCase/Uninstall/Handler.php @@ -63,13 +63,7 @@ public function handle(Command $command): void if ([] !== $b24Accounts) { foreach ($b24Accounts as $b24Account) { - $isMaster = $b24Account->isMasterAccount(); - if ($isMaster) { - $b24Account->applicationUninstalled($command->applicationToken); - } else { - $b24Account->applicationUninstalled(null); - } - + $b24Account->applicationUninstalled(null); $this->bitrix24AccountRepository->save($b24Account); $entitiesToFlush[] = $b24Account; }