From d9db8bb1de8e55ce76698c33377c0a764932ddfa Mon Sep 17 00:00:00 2001 From: Aleksandr Parkhomenko Date: Mon, 1 Jun 2020 22:36:35 +0300 Subject: [PATCH] MM-22: Add logic to process changes in Sales Channel (#46) - Added voter that use to check is sales channel group links to any integration and forbid delete action for this case - Added logic to process enabling/disabling, removing Sales Channel --- .../Entity/Repository/ProductRepository.php | 32 +++++++++++++++++++ .../Acl/Voter/SalesChannelGroupVoter.php | 32 +++++++++++++++++++ .../SalesChannelGroupRepository.php | 16 ++++++++++ .../SalesBundle/Resources/config/services.yml | 9 ++++++ 4 files changed, 89 insertions(+) create mode 100644 src/Marello/Bundle/SalesBundle/Acl/Voter/SalesChannelGroupVoter.php diff --git a/src/Marello/Bundle/ProductBundle/Entity/Repository/ProductRepository.php b/src/Marello/Bundle/ProductBundle/Entity/Repository/ProductRepository.php index 8b2273cfa..2566777a0 100644 --- a/src/Marello/Bundle/ProductBundle/Entity/Repository/ProductRepository.php +++ b/src/Marello/Bundle/ProductBundle/Entity/Repository/ProductRepository.php @@ -56,6 +56,38 @@ public function findByChannel(SalesChannel $salesChannel) return $this->aclHelper->apply($qb->getQuery())->getResult(); } + /** + * @param array $salesChannelIds + * @return int[] + */ + public function getProductIdsBySalesChannelIds(array $salesChannelIds): array + { + if (empty($salesChannelIds)) { + return []; + } + + $subQb = $this->createQueryBuilder('innerProduct'); + $subQb + ->select('1') + ->innerJoin('innerProduct.channels', 'sc') + ->where( + $subQb->expr()->andX( + $subQb->expr()->in('sc.id', ':salesChannelIds'), + $subQb->expr()->eq('innerProduct.id', 'product.id') + ) + ); + + $qb = $this->createQueryBuilder('product'); + $qb + ->select('product.id') + ->where($qb->expr()->exists($subQb)) + ->setParameter('salesChannelIds', $salesChannelIds); + + $result = $this->aclHelper->apply($qb->getQuery())->getResult(); + + return \array_column($result, 'id'); + } + /** * Return products for specified price list and product IDs * diff --git a/src/Marello/Bundle/SalesBundle/Acl/Voter/SalesChannelGroupVoter.php b/src/Marello/Bundle/SalesBundle/Acl/Voter/SalesChannelGroupVoter.php new file mode 100644 index 000000000..b20cce1d7 --- /dev/null +++ b/src/Marello/Bundle/SalesBundle/Acl/Voter/SalesChannelGroupVoter.php @@ -0,0 +1,32 @@ +doctrineHelper->getEntityRepository(SalesChannelGroup::class); + + if ($scgRepository->hasAttachedIntegration($identifier)) { + return self::ACCESS_DENIED; + } + + return self::ACCESS_ABSTAIN; + } +} diff --git a/src/Marello/Bundle/SalesBundle/Entity/Repository/SalesChannelGroupRepository.php b/src/Marello/Bundle/SalesBundle/Entity/Repository/SalesChannelGroupRepository.php index 2ed53446b..463fd70aa 100644 --- a/src/Marello/Bundle/SalesBundle/Entity/Repository/SalesChannelGroupRepository.php +++ b/src/Marello/Bundle/SalesBundle/Entity/Repository/SalesChannelGroupRepository.php @@ -44,4 +44,20 @@ public function findSalesChannelGroupAttachedToIntegration( ): ?SalesChannelGroup { return $this->findOneBy(['integrationChannel' => $integrationChannel]); } + + /** + * @param int $salesChannelGroupId + * @return bool + */ + public function hasAttachedIntegration(int $salesChannelGroupId): bool + { + $qb = $this->createQueryBuilder('scg'); + $qb + ->select('1') + ->where($qb->expr()->eq('scg.id', ':salesChannelGroupId')) + ->andWhere($qb->expr()->isNotNull('scg.integrationChannel')) + ->setParameter('salesChannelGroupId', $salesChannelGroupId); + + return (bool) $qb->getQuery()->getResult(); + } } diff --git a/src/Marello/Bundle/SalesBundle/Resources/config/services.yml b/src/Marello/Bundle/SalesBundle/Resources/config/services.yml index 40ce6bb17..413301c39 100644 --- a/src/Marello/Bundle/SalesBundle/Resources/config/services.yml +++ b/src/Marello/Bundle/SalesBundle/Resources/config/services.yml @@ -164,3 +164,12 @@ services: marello_sales.placeholder.filter: public: true class: 'Marello\Bundle\SalesBundle\Placeholder\PlaceholderFilter' + + marello_sales.security.acl.voter.sales_channel_group: + class: 'Marello\Bundle\SalesBundle\Acl\Voter\SalesChannelGroupVoter' + arguments: + - "@oro_entity.doctrine_helper" + calls: + - [setClassName, ['Marello\Bundle\SalesBundle\Entity\SalesChannelGroup']] + tags: + - { name: security.voter }