From 6ad2fdb3d3cdaf8e9dc97397f794fabff0edac99 Mon Sep 17 00:00:00 2001 From: Martin Grossmann Date: Tue, 17 May 2022 01:30:09 +0200 Subject: [PATCH 01/32] added product export via queue - allows to dispatch message to recalculate product - added command to dispatch products manually - handler use batching to consume and export products --- app/config/packages/messenger.yaml | 9 +++++---- app/deploy/deploy-project.sh | 2 +- app/docker/php-fpm/consumer-entrypoint.sh | 2 +- app/src/Model/Product/ProductRepository.php | 10 ---------- 4 files changed, 7 insertions(+), 16 deletions(-) diff --git a/app/config/packages/messenger.yaml b/app/config/packages/messenger.yaml index b97e64151d..cbbb0f9b54 100644 --- a/app/config/packages/messenger.yaml +++ b/app/config/packages/messenger.yaml @@ -6,15 +6,15 @@ framework: middleware: - 'Shopsys\FrameworkBundle\Component\Messenger\DelayedEnvelope\DelayEnvelopeMiddleware' transports: - example_transport: + product_recalculation: dsn: '%env(MESSENGER_TRANSPORT_DSN)%' options: vhost: '%env(MESSENGER_TRANSPORT_VHOST)%' exchange: - name: example_exchange + name: product_recalculation type: direct queues: - example_queue: ~ + product_recalculation: ~ placed_order_transport: dsn: '%env(MESSENGER_TRANSPORT_DSN)%' options: @@ -30,5 +30,6 @@ framework: multiplier: 5 routing: - Shopsys\FrameworkBundle\Component\Messenger\ExampleMessage: example_transport + Shopsys\FrameworkBundle\Model\Product\Recalculation\ProductRecalculationMessage: product_recalculation + Shopsys\FrameworkBundle\Model\Product\Recalculation\DispatchAllProductsMessage: product_recalculation Shopsys\FrameworkBundle\Model\Order\Messenger\PlacedOrderMessage: placed_order_transport diff --git a/app/deploy/deploy-project.sh b/app/deploy/deploy-project.sh index 16817a35cc..9bc1b25762 100644 --- a/app/deploy/deploy-project.sh +++ b/app/deploy/deploy-project.sh @@ -118,7 +118,7 @@ function merge() { # Specify consumers configuration with the default configuration in the format: # :: DEFAULT_CONSUMERS=( - "example:example_transport:1" + "product-recalculation:product_recalculation:1" "placed_order:placed_order_transport:1" ) diff --git a/app/docker/php-fpm/consumer-entrypoint.sh b/app/docker/php-fpm/consumer-entrypoint.sh index 5bc31710a2..7e744583dd 100755 --- a/app/docker/php-fpm/consumer-entrypoint.sh +++ b/app/docker/php-fpm/consumer-entrypoint.sh @@ -3,6 +3,6 @@ TIME_LIMIT=${1:-60} php ./bin/console messenger:consume \ - example_transport \ + product_recalculation \ placed_order_transport \ --time-limit=$TIME_LIMIT diff --git a/app/src/Model/Product/ProductRepository.php b/app/src/Model/Product/ProductRepository.php index 1c9c2c5416..3f88ff7c31 100644 --- a/app/src/Model/Product/ProductRepository.php +++ b/app/src/Model/Product/ProductRepository.php @@ -64,16 +64,6 @@ public function getVisibleProductsByCatnumsAndDomainId( ->execute(); } - /** - * @return \Doctrine\ORM\QueryBuilder - */ - public function getAllProductsQueryBuilder(): QueryBuilder - { - return $this->em->createQueryBuilder() - ->select('p') - ->from(Product::class, 'p'); - } - /** * @param \Doctrine\ORM\QueryBuilder $queryBuilder * @param int $domainId From 3ed7b6a738bd8c41be40aa0a55e891f5032601f3 Mon Sep 17 00:00:00 2001 From: Martin Grossmann Date: Thu, 9 Nov 2023 12:43:46 +0100 Subject: [PATCH 02/32] removed export changed products functionality - it will be replaced by the queues --- app/config/cron.yaml | 4 ---- .../ProductExportChangedCronModule.php | 21 ------------------- 2 files changed, 25 deletions(-) delete mode 100644 app/src/Model/Product/Elasticsearch/ProductExportChangedCronModule.php diff --git a/app/config/cron.yaml b/app/config/cron.yaml index 60faa36122..57fe53b955 100644 --- a/app/config/cron.yaml +++ b/app/config/cron.yaml @@ -89,10 +89,6 @@ services: tags: - { name: shopsys.cron, hours: '0', minutes: '0', instanceName: products, readableName: "Export products to Elasticsearch" } - App\Model\Product\Elasticsearch\ProductExportChangedCronModule: - tags: - - { name: shopsys.cron, hours: '*', minutes: '*', instanceName: products, readableName: "Export changed products to Elasticsearch" } - # Akeneo import products App\Model\Category\Transfer\Akeneo\AkeneoImportCategoryCronModule: diff --git a/app/src/Model/Product/Elasticsearch/ProductExportChangedCronModule.php b/app/src/Model/Product/Elasticsearch/ProductExportChangedCronModule.php deleted file mode 100644 index 280fc0a739..0000000000 --- a/app/src/Model/Product/Elasticsearch/ProductExportChangedCronModule.php +++ /dev/null @@ -1,21 +0,0 @@ -eventDispatcher->dispatch( - new IndexExportedEvent($this->index), - IndexExportedEvent::INDEX_EXPORTED, - ); - } -} From 4f8855b1432da6e8ed71605c4ec3f170e7fb9549 Mon Sep 17 00:00:00 2001 From: Martin Grossmann Date: Thu, 9 Nov 2023 12:50:55 +0100 Subject: [PATCH 03/32] removed non-existing service configurations --- app/config/services.yaml | 7 ------- 1 file changed, 7 deletions(-) diff --git a/app/config/services.yaml b/app/config/services.yaml index 5e25082e00..4e13e142f1 100644 --- a/app/config/services.yaml +++ b/app/config/services.yaml @@ -808,13 +808,6 @@ services: App\FrontendApi\Component\ExpressionLanguage\DynamicPaginationComplexityExpressionFunction: tags: ['overblog_graphql.expression_function'] - App\Model\ImageSitemap\ImageSitemapFacade: - arguments: - - '%shopsys.sitemaps_dir%' - - '%shopsys.sitemaps_url_prefix%' - - App\Model\ImageSitemap\ImageSitemapFilePrefixer: ~ - App\FrontendApi\Model\Token\TokenAuthenticator: ~ Shopsys\FrontendApiBundle\Model\Token\TokenAuthenticator: From 0d97f97bf8ec5350d6f065dbc2dc55380c23bc3e Mon Sep 17 00:00:00 2001 From: Martin Grossmann Date: Thu, 9 Nov 2023 17:40:45 +0100 Subject: [PATCH 04/32] export cron module now dispatch a message to recalculate all products --- app/config/cron.yaml | 4 +- .../Elasticsearch/ProductExportCronModule.php | 43 ------------------- 2 files changed, 2 insertions(+), 45 deletions(-) delete mode 100644 app/src/Model/Product/Elasticsearch/ProductExportCronModule.php diff --git a/app/config/cron.yaml b/app/config/cron.yaml index 57fe53b955..bfcd5917c7 100644 --- a/app/config/cron.yaml +++ b/app/config/cron.yaml @@ -85,9 +85,9 @@ services: tags: - { name: shopsys.cron, hours: '0', minutes: '0', instanceName: products, readableName: 'Recalculate midnight product visibilities' } - App\Model\Product\Elasticsearch\ProductExportCronModule: + Shopsys\FrameworkBundle\Model\Product\Elasticsearch\ProductRecalculationCronModule: tags: - - { name: shopsys.cron, hours: '0', minutes: '0', instanceName: products, readableName: "Export products to Elasticsearch" } + - { name: shopsys.cron, hours: '0', minutes: '0', instanceName: products, readableName: "Dispatches all products to be recalculated and exported" } # Akeneo import products diff --git a/app/src/Model/Product/Elasticsearch/ProductExportCronModule.php b/app/src/Model/Product/Elasticsearch/ProductExportCronModule.php deleted file mode 100644 index 6c92e21019..0000000000 --- a/app/src/Model/Product/Elasticsearch/ProductExportCronModule.php +++ /dev/null @@ -1,43 +0,0 @@ -eventDispatcher->dispatch( - new IndexExportedEvent($this->index), - IndexExportedEvent::INDEX_EXPORTED, - ); - } -} From 857e1eb05794c4a71fe933036209641bda6890cb Mon Sep 17 00:00:00 2001 From: Martin Grossmann Date: Thu, 9 Nov 2023 17:49:14 +0100 Subject: [PATCH 05/32] indirect product changes are now handled by the consumer --- app/config/services.yaml | 3 - app/src/Model/Category/CategoryFacade.php | 55 ++++--------------- .../MarkProductForExportSubscriber.php | 38 ------------- .../Pricing/ProductInputPriceFacade.php | 4 +- app/src/Model/Product/ProductFacade.php | 15 ----- app/src/Model/Product/ProductRepository.php | 19 ------- 6 files changed, 14 insertions(+), 120 deletions(-) delete mode 100644 app/src/Model/Product/Elasticsearch/MarkProductForExportSubscriber.php diff --git a/app/config/services.yaml b/app/config/services.yaml index 4e13e142f1..175721f767 100644 --- a/app/config/services.yaml +++ b/app/config/services.yaml @@ -701,9 +701,6 @@ services: App\Model\Administrator\Mail\TwoFactorAuthenticationMail: ~ - Shopsys\FrameworkBundle\Model\Product\Elasticsearch\MarkProductForExportSubscriber: - alias: App\Model\Product\Elasticsearch\MarkProductForExportSubscriber - Shopsys\FrameworkBundle\Component\Domain\DomainAwareSecurityHeadersSetter: class: App\Component\Domain\DomainAwareSecurityHeadersSetter tags: diff --git a/app/src/Model/Category/CategoryFacade.php b/app/src/Model/Category/CategoryFacade.php index 5156ac2e49..37192ee3ad 100644 --- a/app/src/Model/Category/CategoryFacade.php +++ b/app/src/Model/Category/CategoryFacade.php @@ -6,7 +6,6 @@ use App\Model\Category\LinkedCategory\LinkedCategoryFacade; use App\Model\Product\Filter\ProductFilterData; -use App\Model\Product\ProductFacade; use App\Model\Product\ProductOnCurrentDomainElasticFacade; use Doctrine\ORM\EntityManagerInterface; use Shopsys\FrameworkBundle\Component\Domain\Config\DomainConfig; @@ -22,6 +21,8 @@ use Shopsys\FrameworkBundle\Model\Category\CategoryVisibilityRecalculationScheduler; use Shopsys\FrameworkBundle\Model\Category\CategoryWithLazyLoadedVisibleChildrenFactory; use Shopsys\FrameworkBundle\Model\Category\CategoryWithPreloadedChildrenFactory; +use Shopsys\FrameworkBundle\Model\Product\Recalculation\ProductRecalculationDispatcher; +use Symfony\Component\EventDispatcher\EventDispatcherInterface; /** * @property \App\Model\Category\CategoryRepository $categoryRepository @@ -50,6 +51,7 @@ * @method \App\Model\Category\Category getVisibleOnDomainByUuid(int $domainId, string $categoryUuid) * @method \App\Model\Category\Category getProductMainCategoryOnCurrentDomain(\App\Model\Product\Product $product) * @property \App\Component\Router\FriendlyUrl\FriendlyUrlFacade $friendlyUrlFacade + * @method dispatchCategoryEvent(\App\Model\Category\Category $category, string $eventType) */ class CategoryFacade extends BaseCategoryFacade { @@ -64,10 +66,11 @@ class CategoryFacade extends BaseCategoryFacade * @param \Shopsys\FrameworkBundle\Model\Category\CategoryWithPreloadedChildrenFactory $categoryWithPreloadedChildrenFactory * @param \Shopsys\FrameworkBundle\Model\Category\CategoryWithLazyLoadedVisibleChildrenFactory $categoryWithLazyLoadedVisibleChildrenFactory * @param \Shopsys\FrameworkBundle\Model\Category\CategoryFactory $categoryFactory + * @param \Shopsys\FrameworkBundle\Model\Product\Recalculation\ProductRecalculationDispatcher $productRecalculationDispatcher + * @param \Symfony\Component\EventDispatcher\EventDispatcherInterface $eventDispatcher * @param \App\Model\Category\CategoryParameterFacade $categoryParameterFacade * @param \App\Model\Category\LinkedCategory\LinkedCategoryFacade $linkedCategoryFacade * @param \App\Model\Product\ProductOnCurrentDomainElasticFacade $productOnCurrentDomainElasticFacade - * @param \App\Model\Product\ProductFacade $productFacade */ public function __construct( EntityManagerInterface $em, @@ -80,10 +83,11 @@ public function __construct( CategoryWithPreloadedChildrenFactory $categoryWithPreloadedChildrenFactory, CategoryWithLazyLoadedVisibleChildrenFactory $categoryWithLazyLoadedVisibleChildrenFactory, CategoryFactoryInterface $categoryFactory, - private CategoryParameterFacade $categoryParameterFacade, - private LinkedCategoryFacade $linkedCategoryFacade, - private ProductOnCurrentDomainElasticFacade $productOnCurrentDomainElasticFacade, - private ProductFacade $productFacade, + ProductRecalculationDispatcher $productRecalculationDispatcher, + EventDispatcherInterface $eventDispatcher, + private readonly CategoryParameterFacade $categoryParameterFacade, + private readonly LinkedCategoryFacade $linkedCategoryFacade, + private readonly ProductOnCurrentDomainElasticFacade $productOnCurrentDomainElasticFacade, ) { parent::__construct( $em, @@ -96,6 +100,8 @@ public function __construct( $categoryWithPreloadedChildrenFactory, $categoryWithLazyLoadedVisibleChildrenFactory, $categoryFactory, + $productRecalculationDispatcher, + $eventDispatcher, ); } @@ -125,35 +131,9 @@ public function edit($categoryId, CategoryData $categoryData): BaseCategory $this->categoryParameterFacade->saveRelation($category, $categoryData->parametersPosition, $categoryData->parametersCollapsed); $this->linkedCategoryFacade->updateLinkedCategories($category, $categoryData->linkedCategories); - $this->scheduleProductsToExportByCategory($category); - return $category; } - /** - * @param array $categoriesOrderingData - */ - public function reorderByNestedSetValues(array $categoriesOrderingData): void - { - parent::reorderByNestedSetValues($categoriesOrderingData); - - $this->productFacade->markAllProductsForExport(); - } - - /** - * @param \App\Model\Category\Category $category - */ - private function scheduleProductsToExportByCategory(Category $category): void - { - $products = $this->productFacade->getProductsByCategory($category); - - foreach ($products as $product) { - $product->markForExport(); - } - - $this->em->flush(); - } - /** * @param string $akeneoCode * @return \App\Model\Category\Category|null @@ -211,17 +191,6 @@ public function getCategoriesNamesInPathAsString( return implode($delimiter, $categoriesNamesInPath); } - /** - * @param int $categoryId - */ - public function deleteById($categoryId) - { - $category = $this->categoryRepository->getById($categoryId); - $this->scheduleProductsToExportByCategory($category); - - parent::deleteById($categoryId); - } - /** * @param string $locale * @return string[] diff --git a/app/src/Model/Product/Elasticsearch/MarkProductForExportSubscriber.php b/app/src/Model/Product/Elasticsearch/MarkProductForExportSubscriber.php deleted file mode 100644 index 946c0b5e97..0000000000 --- a/app/src/Model/Product/Elasticsearch/MarkProductForExportSubscriber.php +++ /dev/null @@ -1,38 +0,0 @@ -hasChangedDomains()) { - $this->markAll($stockEvent); - } - } -} diff --git a/app/src/Model/Product/Pricing/ProductInputPriceFacade.php b/app/src/Model/Product/Pricing/ProductInputPriceFacade.php index 7475c485e7..ab56317d6e 100644 --- a/app/src/Model/Product/Pricing/ProductInputPriceFacade.php +++ b/app/src/Model/Product/Pricing/ProductInputPriceFacade.php @@ -9,7 +9,7 @@ /** * @property \App\Model\Product\ProductRepository $productRepository * @property \Doctrine\ORM\Internal\Hydration\IterableResult|\App\Model\Product\Product[][]|null $productRowsIterator - * @method __construct(\Doctrine\ORM\EntityManagerInterface $em, \Shopsys\FrameworkBundle\Model\Pricing\PricingSetting $pricingSetting, \Shopsys\FrameworkBundle\Model\Product\Pricing\ProductManualInputPriceRepository $productManualInputPriceRepository, \App\Model\Product\ProductRepository $productRepository, \Shopsys\FrameworkBundle\Model\Product\Pricing\ProductInputPriceRecalculator $productInputPriceRecalculator) + * @method __construct(\Doctrine\ORM\EntityManagerInterface $em, \Shopsys\FrameworkBundle\Model\Pricing\PricingSetting $pricingSetting, \Shopsys\FrameworkBundle\Model\Product\Pricing\ProductManualInputPriceRepository $productManualInputPriceRepository, \App\Model\Product\ProductRepository $productRepository, \Shopsys\FrameworkBundle\Model\Product\Pricing\ProductInputPriceRecalculator $productInputPriceRecalculator, \Shopsys\FrameworkBundle\Model\Product\Recalculation\ProductRecalculationDispatcher $productRecalculationDispatcher) * @method \Shopsys\FrameworkBundle\Component\Money\Money[]|null[] getManualInputPricesDataIndexedByPricingGroupId(\App\Model\Product\Product $product) */ class ProductInputPriceFacade extends BaseProductInputPriceFacade @@ -40,7 +40,7 @@ public function replaceBatchVatAndRecalculateInputPrices(): bool $domainId = $productDomain->getDomainId(); $newVat = $product->getVatForDomain($domainId)->getReplaceWith(); $product->changeVatForDomain($newVat, $domainId); - $product->markForExport(); + $this->productRecalculationDispatcher->dispatchSingleProductId($product->getId()); } } diff --git a/app/src/Model/Product/ProductFacade.php b/app/src/Model/Product/ProductFacade.php index 3ec14cc5aa..34aa4ef5b8 100644 --- a/app/src/Model/Product/ProductFacade.php +++ b/app/src/Model/Product/ProductFacade.php @@ -4,7 +4,6 @@ namespace App\Model\Product; -use App\Model\Category\Category as AppCategory; use App\Model\ProductVideo\ProductVideoFacade; use Doctrine\ORM\EntityManagerInterface; use Shopsys\FrameworkBundle\Component\Domain\Domain; @@ -53,11 +52,6 @@ * @method \App\Model\Product\Product getOneByCatnumExcludeMainVariants(string $productCatnum) * @method \App\Model\Product\Product getByUuid(string $uuid) * @method markProductsForExport(\App\Model\Product\Product[] $products) - * @method \App\Model\Product\Product[] getProductsWithAvailability(\Shopsys\FrameworkBundle\Model\Product\Availability\Availability $availability) - * @method \App\Model\Product\Product[] getProductsWithParameter(\App\Model\Product\Parameter\Parameter $parameter) - * @method \App\Model\Product\Product[] getProductsWithBrand(\App\Model\Product\Brand\Brand $brand) - * @method \App\Model\Product\Product[] getProductsWithFlag(\App\Model\Product\Flag\Flag $flag) - * @method \App\Model\Product\Product[] getProductsWithUnit(\App\Model\Product\Unit\Unit $unit) * @method createFriendlyUrlsWhenRenamed(\App\Model\Product\Product $product, array $originalNames) * @method array getChangedNamesByLocale(\App\Model\Product\Product $product, array $originalNames) * @property \App\Model\Product\ProductVisibilityFacade $productVisibilityFacade @@ -331,15 +325,6 @@ public function refreshProductAccessories(BaseProduct $product, array $accessori parent::refreshProductAccessories($product, $accessories); } - /** - * @param \App\Model\Category\Category $category - * @return \App\Model\Product\Product[] - */ - public function getProductsByCategory(AppCategory $category): array - { - return $this->productRepository->getProductsByCategory($category); - } - /** * @param \App\Model\Product\ProductData $productData * @param \App\Model\Product\Product $product diff --git a/app/src/Model/Product/ProductRepository.php b/app/src/Model/Product/ProductRepository.php index 3f88ff7c31..22a5a00c18 100644 --- a/app/src/Model/Product/ProductRepository.php +++ b/app/src/Model/Product/ProductRepository.php @@ -4,7 +4,6 @@ namespace App\Model\Product; -use App\Model\Category\Category as AppCategory; use Doctrine\ORM\Query\Expr\Join; use Doctrine\ORM\QueryBuilder; use Exception; @@ -37,10 +36,6 @@ * @method \App\Model\Product\Product getOneByCatnumExcludeMainVariants(string $productCatnum) * @method \App\Model\Product\Product getOneByUuid(string $uuid) * @method markProductsForExport(\App\Model\Product\Product[] $products) - * @method \App\Model\Product\Product[] getProductsWithBrand(\App\Model\Product\Brand\Brand $brand) - * @method \App\Model\Product\Product[] getProductsWithFlag(\App\Model\Product\Flag\Flag $flag) - * @method \App\Model\Product\Product[] getProductsWithUnit(\App\Model\Product\Unit\Unit $unit) - * @method array getProductsWithParameter(\App\Model\Product\Parameter\Parameter $parameter) * @method \App\Model\Product\Product[] getAllSellableVariantsByMainVariant(\App\Model\Product\Product $mainVariant, int $domainId, \Shopsys\FrameworkBundle\Model\Pricing\Group\PricingGroup $pricingGroup) */ class ProductRepository extends BaseProductRepository @@ -179,20 +174,6 @@ public function getSellableBySearchTextQueryBuilder( return $queryBuilder; } - /** - * @param \App\Model\Category\Category $category - * @return \App\Model\Product\Product[] - */ - public function getProductsByCategory(AppCategory $category): array - { - return $this->getAllProductsQueryBuilder() - ->join('p.productCategoryDomains', 'pcd') - ->where('pcd.category = :category') - ->setParameter('category', $category) - ->getQuery() - ->execute(); - } - /** * @param int $domainId * @param \Shopsys\FrameworkBundle\Model\Pricing\Group\PricingGroup $pricingGroup From b61c82d6e55710f3e87201caca0df709ab031ba6 Mon Sep 17 00:00:00 2001 From: Martin Grossmann Date: Thu, 9 Nov 2023 17:53:16 +0100 Subject: [PATCH 06/32] mark product for export replaced with message dispatch --- app/src/Model/Product/Product.php | 2 -- app/src/Model/Product/ProductFacade.php | 25 +++++++------------ app/src/Model/Product/ProductRepository.php | 1 - .../Model/Product/ProductVariantFacade.php | 7 +++--- 4 files changed, 13 insertions(+), 22 deletions(-) diff --git a/app/src/Model/Product/Product.php b/app/src/Model/Product/Product.php index d94d464c01..044a51d609 100644 --- a/app/src/Model/Product/Product.php +++ b/app/src/Model/Product/Product.php @@ -153,8 +153,6 @@ public function edit( $this->editRelatedProducts($productData->relatedProducts); parent::edit($productCategoryDomains, $productData); - - $this->markForExport(); } /** diff --git a/app/src/Model/Product/ProductFacade.php b/app/src/Model/Product/ProductFacade.php index 34aa4ef5b8..fcf8c25bb8 100644 --- a/app/src/Model/Product/ProductFacade.php +++ b/app/src/Model/Product/ProductFacade.php @@ -14,7 +14,6 @@ use Shopsys\FrameworkBundle\Model\Product\Accessory\ProductAccessoryFactoryInterface; use Shopsys\FrameworkBundle\Model\Product\Accessory\ProductAccessoryRepository; use Shopsys\FrameworkBundle\Model\Product\Availability\ProductAvailabilityRecalculationScheduler; -use Shopsys\FrameworkBundle\Model\Product\Elasticsearch\ProductExportScheduler; use Shopsys\FrameworkBundle\Model\Product\Exception\ProductNotFoundException; use Shopsys\FrameworkBundle\Model\Product\Parameter\ParameterRepository; use Shopsys\FrameworkBundle\Model\Product\Parameter\ProductParameterValueFactoryInterface; @@ -31,6 +30,7 @@ use Shopsys\FrameworkBundle\Model\Product\ProductSellingDeniedRecalculator; use Shopsys\FrameworkBundle\Model\Product\ProductVisibilityFacade; use Shopsys\FrameworkBundle\Model\Product\ProductVisibilityFactoryInterface; +use Shopsys\FrameworkBundle\Model\Product\Recalculation\ProductRecalculationDispatcher; use Shopsys\FrameworkBundle\Model\Stock\ProductStockData; use Shopsys\FrameworkBundle\Model\Stock\ProductStockFacade; use Shopsys\FrameworkBundle\Model\Stock\StockFacade; @@ -51,7 +51,6 @@ * @method createProductVisibilities(\App\Model\Product\Product $product) * @method \App\Model\Product\Product getOneByCatnumExcludeMainVariants(string $productCatnum) * @method \App\Model\Product\Product getByUuid(string $uuid) - * @method markProductsForExport(\App\Model\Product\Product[] $products) * @method createFriendlyUrlsWhenRenamed(\App\Model\Product\Product $product, array $originalNames) * @method array getChangedNamesByLocale(\App\Model\Product\Product $product, array $originalNames) * @property \App\Model\Product\ProductVisibilityFacade $productVisibilityFacade @@ -81,7 +80,7 @@ class ProductFacade extends BaseProductFacade * @param \Shopsys\FrameworkBundle\Model\Product\Parameter\ProductParameterValueFactory $productParameterValueFactory * @param \Shopsys\FrameworkBundle\Model\Product\ProductVisibilityFactory $productVisibilityFactory * @param \Shopsys\FrameworkBundle\Model\Product\Pricing\ProductPriceCalculation $productPriceCalculation - * @param \Shopsys\FrameworkBundle\Model\Product\Elasticsearch\ProductExportScheduler $productExportScheduler + * @param \Shopsys\FrameworkBundle\Model\Product\Recalculation\ProductRecalculationDispatcher $productRecalculationDispatcher * @param \Shopsys\FrameworkBundle\Model\Stock\ProductStockFacade $productStockFacade * @param \Shopsys\FrameworkBundle\Model\Stock\StockFacade $stockFacade * @param \App\Model\ProductVideo\ProductVideoFacade $productVideoFacade @@ -108,7 +107,7 @@ public function __construct( ProductParameterValueFactoryInterface $productParameterValueFactory, ProductVisibilityFactoryInterface $productVisibilityFactory, ProductPriceCalculation $productPriceCalculation, - ProductExportScheduler $productExportScheduler, + ProductRecalculationDispatcher $productRecalculationDispatcher, private readonly ProductStockFacade $productStockFacade, private readonly StockFacade $stockFacade, private readonly ProductVideoFacade $productVideoFacade, @@ -135,7 +134,7 @@ public function __construct( $productParameterValueFactory, $productVisibilityFactory, $productPriceCalculation, - $productExportScheduler, + $productRecalculationDispatcher, ); } @@ -162,10 +161,7 @@ public function create(ProductData $productData) public function findOneByCatnumExcludeMainVariants($productCatnum): ?BaseProduct { try { - /** @var \App\Model\Product\Product $product */ - $product = $this->productRepository->getOneByCatnumExcludeMainVariants($productCatnum); - - return $product; + return $this->productRepository->getOneByCatnumExcludeMainVariants($productCatnum); } catch (ProductNotFoundException $exception) { return null; } @@ -178,7 +174,6 @@ public function findOneByCatnumExcludeMainVariants($productCatnum): ?BaseProduct */ public function edit($productId, ProductData $productData) { - /** @var \App\Model\Product\Product $product */ $product = $this->productRepository->getById($productId); $productCategoryDomains = $this->productCategoryDomainFactory->createMultiple($product, $productData->categoriesByDomainId); @@ -195,9 +190,6 @@ public function edit($productId, ProductData $productData) $product->refreshVariants($productData->variants); } - if ($product->isVariant() === true) { - $product->getMainVariant()->markForExport(); - } $this->refreshProductAccessories($product, $productData->accessories); $this->em->flush(); $this->imageFacade->manageImages($product, $productData->images); @@ -211,14 +203,15 @@ public function edit($productId, ProductData $productData) $this->productVisibilityFacade->refreshProductsVisibilityForMarkedDelayed(); $this->productPriceRecalculationScheduler->scheduleProductForImmediateRecalculation($product); - $this->productExportScheduler->scheduleRowIdForImmediateExport($product->getId()); + // @todo after handling variants this may be simplified or edit may be moved to framework + $this->productRecalculationDispatcher->dispatchSingleProductId($product->getId()); if ($product->isMainVariant()) { foreach ($product->getVariants() as $variant) { - $this->productExportScheduler->scheduleRowIdForImmediateExport($variant->getId()); + $this->productRecalculationDispatcher->dispatchSingleProductId($variant->getId()); } } elseif ($product->isVariant()) { - $this->productExportScheduler->scheduleRowIdForImmediateExport($product->getMainVariant()->getId()); + $this->productRecalculationDispatcher->dispatchSingleProductId($product->getMainVariant()->getId()); } $this->editProductStockRelation($productData, $product); diff --git a/app/src/Model/Product/ProductRepository.php b/app/src/Model/Product/ProductRepository.php index 22a5a00c18..b0b6d573c5 100644 --- a/app/src/Model/Product/ProductRepository.php +++ b/app/src/Model/Product/ProductRepository.php @@ -35,7 +35,6 @@ * @method \App\Model\Product\Product[] getListableByIds(int $domainId, \Shopsys\FrameworkBundle\Model\Pricing\Group\PricingGroup $pricingGroup, int[] $sortedProductIds) * @method \App\Model\Product\Product getOneByCatnumExcludeMainVariants(string $productCatnum) * @method \App\Model\Product\Product getOneByUuid(string $uuid) - * @method markProductsForExport(\App\Model\Product\Product[] $products) * @method \App\Model\Product\Product[] getAllSellableVariantsByMainVariant(\App\Model\Product\Product $mainVariant, int $domainId, \Shopsys\FrameworkBundle\Model\Pricing\Group\PricingGroup $pricingGroup) */ class ProductRepository extends BaseProductRepository diff --git a/app/src/Model/Product/ProductVariantFacade.php b/app/src/Model/Product/ProductVariantFacade.php index 9dd61d7d6c..7a85c0cbf1 100644 --- a/app/src/Model/Product/ProductVariantFacade.php +++ b/app/src/Model/Product/ProductVariantFacade.php @@ -11,7 +11,7 @@ * @property \App\Model\Product\ProductFacade $productFacade * @property \App\Model\Product\ProductDataFactory $productDataFactory * @property \App\Component\Image\ImageFacade $imageFacade - * @method __construct(\Doctrine\ORM\EntityManagerInterface $em, \App\Model\Product\ProductFacade $productFacade, \App\Model\Product\ProductDataFactory $productDataFactory, \App\Component\Image\ImageFacade $imageFacade, \App\Model\Product\ProductFactory $productFactory, \Shopsys\FrameworkBundle\Model\Product\Pricing\ProductPriceRecalculationScheduler $productPriceRecalculationScheduler, \Shopsys\FrameworkBundle\Model\Product\Availability\ProductAvailabilityRecalculationScheduler $productAvailabilityRecalculationScheduler, \Shopsys\FrameworkBundle\Model\Product\Elasticsearch\ProductExportScheduler $productExportScheduler) + * @method __construct(\Doctrine\ORM\EntityManagerInterface $em, \App\Model\Product\ProductFacade $productFacade, \App\Model\Product\ProductDataFactory $productDataFactory, \App\Component\Image\ImageFacade $imageFacade, \App\Model\Product\ProductFactory $productFactory, \Shopsys\FrameworkBundle\Model\Product\Pricing\ProductPriceRecalculationScheduler $productPriceRecalculationScheduler, \Shopsys\FrameworkBundle\Model\Product\Availability\ProductAvailabilityRecalculationScheduler $productAvailabilityRecalculationScheduler, \Shopsys\FrameworkBundle\Model\Product\Recalculation\ProductRecalculationDispatcher $productRecalculationDispatcher) * @property \App\Model\Product\ProductFactory $productFactory */ class ProductVariantFacade extends BaseProductVariantFacade @@ -24,11 +24,12 @@ class ProductVariantFacade extends BaseProductVariantFacade public function createVariant(BaseProduct $mainVariant, array $variants): Product { $mainVariant->setAsMainVariant(); - $this->productExportScheduler->scheduleRowIdForImmediateExport($mainVariant->getId()); + // @todo after handling variants, this may be simplified + $this->productRecalculationDispatcher->dispatchSingleProductId($mainVariant->getId()); foreach ($variants as $variant) { $mainVariant->addVariant($variant); - $this->productExportScheduler->scheduleRowIdForImmediateExport($variant->getId()); + $this->productRecalculationDispatcher->dispatchSingleProductId($variant->getId()); } $this->em->flush(); From e35a545f098defb6c29e0b0d8c9d74514568c2ef Mon Sep 17 00:00:00 2001 From: Martin Grossmann Date: Sat, 11 Nov 2023 23:23:24 +0100 Subject: [PATCH 07/32] tests are now able to trigger recalculations - elasticsearch index is backed up before recalculation is done and restored after - it solves the issue with the non-transactional elasticsearch --- app/.env.test | 1 + app/tests/App/Test/WebTestCase.php | 39 ++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/app/.env.test b/app/.env.test index 6e5234f7d3..7ec5d91003 100644 --- a/app/.env.test +++ b/app/.env.test @@ -3,6 +3,7 @@ DATABASE_NAME=shopsys-test MAILER_DSN=null://null +MESSENGER_TRANSPORT_DSN=in-memory:// GOPAY_IS_PRODUCTION_MODE=false GOPAY_EN_GOID=test-data diff --git a/app/tests/App/Test/WebTestCase.php b/app/tests/App/Test/WebTestCase.php index 109ae173e6..cb3c5f8ef7 100644 --- a/app/tests/App/Test/WebTestCase.php +++ b/app/tests/App/Test/WebTestCase.php @@ -10,8 +10,10 @@ use Shopsys\FrameworkBundle\Component\Router\DomainRouterFactory; use Shopsys\FrameworkBundle\Model\Pricing\Currency\Currency; use Shopsys\FrameworkBundle\Model\Pricing\Currency\CurrencyFacade; +use Shopsys\FrameworkBundle\Model\Product\Recalculation\ProductRecalculationMessageHandler; use Symfony\Bundle\FrameworkBundle\Test\WebTestCase as BaseWebTestCase; use Symfony\Component\Routing\Generator\UrlGeneratorInterface; +use Tests\FrameworkBundle\Test\ProductIndexBackupFacade; use Zalas\Injector\PHPUnit\TestCase\ServiceContainerTestCase; abstract class WebTestCase extends BaseWebTestCase implements ServiceContainerTestCase @@ -31,6 +33,16 @@ abstract class WebTestCase extends BaseWebTestCase implements ServiceContainerTe */ protected CurrencyFacade $currencyFacade; + /** + * @inject + */ + protected ProductRecalculationMessageHandler $productRecalculationMessageHandler; + + /** + * @inject + */ + protected ProductIndexBackupFacade $productIndexBackupFacade; + protected function setUp(): void { parent::setUp(); @@ -116,4 +128,31 @@ protected function getFirstDomainCurrency(): Currency { return $this->currencyFacade->getDomainDefaultCurrencyByDomainId($this->domain->getId()); } + + protected function tearDown(): void + { + $this->productIndexBackupFacade->restoreSnapshotIfPreviouslyCreated(); + + parent::tearDown(); + } + + /** + * Consumes messages dispatched by ProductRecalculationDispatcher class and run recalculations for dispatched messages + */ + public function handleDispatchedRecalculationMessages(): void + { + $this->productIndexBackupFacade->createSnapshot(); + + /** @var \Symfony\Component\Messenger\Transport\InMemoryTransport $transport */ + $transport = self::getContainer()->get('messenger.transport.product_recalculation'); + $handler = $this->productRecalculationMessageHandler; + + $envelopes = $transport->getSent(); + + foreach ($envelopes as $envelope) { + /** @var \Shopsys\FrameworkBundle\Model\Product\Recalculation\ProductRecalculationMessage $message */ + $message = $envelope->getMessage(); + $handler($message); + } + } } From 1eae849ef3b51ddf7a7594d6dfd01a10590255a0 Mon Sep 17 00:00:00 2001 From: Martin Grossmann Date: Sat, 11 Nov 2023 23:43:14 +0100 Subject: [PATCH 08/32] removed product advanced search by availability as it is not used anymore --- app/src/Model/AdvancedSearch/ProductAdvancedSearchConfig.php | 5 ----- 1 file changed, 5 deletions(-) diff --git a/app/src/Model/AdvancedSearch/ProductAdvancedSearchConfig.php b/app/src/Model/AdvancedSearch/ProductAdvancedSearchConfig.php index 2ea0b757bc..d7b1d09578 100644 --- a/app/src/Model/AdvancedSearch/ProductAdvancedSearchConfig.php +++ b/app/src/Model/AdvancedSearch/ProductAdvancedSearchConfig.php @@ -5,7 +5,6 @@ namespace App\Model\AdvancedSearch; use Shopsys\FrameworkBundle\Model\AdvancedSearch\AdvancedSearchFilterInterface; -use Shopsys\FrameworkBundle\Model\AdvancedSearch\Filter\ProductAvailabilityFilter; use Shopsys\FrameworkBundle\Model\AdvancedSearch\Filter\ProductBrandFilter; use Shopsys\FrameworkBundle\Model\AdvancedSearch\Filter\ProductCalculatedSellingDeniedFilter; use Shopsys\FrameworkBundle\Model\AdvancedSearch\Filter\ProductCategoryFilter; @@ -25,7 +24,6 @@ class ProductAdvancedSearchConfig extends BaseProductAdvancedSearchConfig * @param \Shopsys\FrameworkBundle\Model\AdvancedSearch\Filter\ProductStockFilter $productStockFilter * @param \Shopsys\FrameworkBundle\Model\AdvancedSearch\Filter\ProductFlagFilter $productFlagFilter * @param \Shopsys\FrameworkBundle\Model\AdvancedSearch\Filter\ProductCalculatedSellingDeniedFilter $productCalculatedSellingDeniedFilter - * @param \Shopsys\FrameworkBundle\Model\AdvancedSearch\Filter\ProductAvailabilityFilter $productAvailabilityFilter * @param \Shopsys\FrameworkBundle\Model\AdvancedSearch\Filter\ProductBrandFilter $productBrandFilter * @param \Shopsys\FrameworkBundle\Model\AdvancedSearch\Filter\ProductCategoryFilter $productCategoryFilter */ @@ -36,7 +34,6 @@ public function __construct( ProductStockFilter $productStockFilter, ProductFlagFilter $productFlagFilter, ProductCalculatedSellingDeniedFilter $productCalculatedSellingDeniedFilter, - ProductAvailabilityFilter $productAvailabilityFilter, ProductBrandFilter $productBrandFilter, ProductCategoryFilter $productCategoryFilter, ) { @@ -47,12 +44,10 @@ public function __construct( $productStockFilter, $productFlagFilter, $productCalculatedSellingDeniedFilter, - $productAvailabilityFilter, $productBrandFilter, $productCategoryFilter, ); - $this->unregisterFilter($productAvailabilityFilter); $this->unregisterFilter($productStockFilter); } From e7b52484ae53091d2d2aa649db28fd1a2a2c7475 Mon Sep 17 00:00:00 2001 From: Martin Grossmann Date: Sat, 11 Nov 2023 23:50:54 +0100 Subject: [PATCH 09/32] transport daysUntilDelivery is now moved to shopsys/framework --- app/src/Migrations/Version20200909112133.php | 27 ------------------- app/src/Model/Transport/Transport.php | 15 ----------- app/src/Model/Transport/TransportData.php | 5 ---- .../Model/Transport/TransportDataFactory.php | 2 -- 4 files changed, 49 deletions(-) delete mode 100644 app/src/Migrations/Version20200909112133.php diff --git a/app/src/Migrations/Version20200909112133.php b/app/src/Migrations/Version20200909112133.php deleted file mode 100644 index 3b511a432b..0000000000 --- a/app/src/Migrations/Version20200909112133.php +++ /dev/null @@ -1,27 +0,0 @@ -sql('ALTER TABLE transports ADD days_until_delivery INT NOT NULL DEFAULT 0'); - $this->sql('ALTER TABLE transports ALTER days_until_delivery DROP DEFAULT'); - } - - /** - * @param \Doctrine\DBAL\Schema\Schema $schema - */ - public function down(Schema $schema): void - { - } -} diff --git a/app/src/Model/Transport/Transport.php b/app/src/Model/Transport/Transport.php index 00efce8b8a..cba23313f2 100644 --- a/app/src/Model/Transport/Transport.php +++ b/app/src/Model/Transport/Transport.php @@ -25,12 +25,6 @@ */ class Transport extends BaseTransport { - /** - * @var int - * @ORM\Column(type="integer") - */ - private int $daysUntilDelivery; - /** * @var \App\Model\Transport\Type\TransportType * @ORM\ManyToOne(targetEntity="App\Model\Transport\Type\TransportType") @@ -73,7 +67,6 @@ protected function setData(BaseTransportData $transportData): void { parent::setData($transportData); - $this->daysUntilDelivery = $transportData->daysUntilDelivery; $this->trackingUrl = $transportData->trackingUrl; $this->transportType = $transportData->transportType; $this->maxWeight = $transportData->maxWeight > 0 ? $transportData->maxWeight : null; @@ -91,14 +84,6 @@ protected function setTranslations(BaseTransportData $transportData) } } - /** - * @return int - */ - public function getDaysUntilDelivery(): int - { - return $this->daysUntilDelivery; - } - /** * @return ?string */ diff --git a/app/src/Model/Transport/TransportData.php b/app/src/Model/Transport/TransportData.php index da9ecf63ac..c56125ca4c 100644 --- a/app/src/Model/Transport/TransportData.php +++ b/app/src/Model/Transport/TransportData.php @@ -17,11 +17,6 @@ class TransportData extends BaseTransportData */ public string $type; - /** - * @var int|null - */ - public ?int $daysUntilDelivery; - /** * @var string|null */ diff --git a/app/src/Model/Transport/TransportDataFactory.php b/app/src/Model/Transport/TransportDataFactory.php index c7335489be..75f634cf6d 100644 --- a/app/src/Model/Transport/TransportDataFactory.php +++ b/app/src/Model/Transport/TransportDataFactory.php @@ -66,7 +66,6 @@ protected function fillNew(BaseTransportData $transportData): void { parent::fillNew($transportData); - $transportData->daysUntilDelivery = 0; $transportData->transportType = $this->transportTypeFacade->getByCode(TransportTypeEnum::TYPE_COMMON); $transportData->trackingUrl = null; @@ -83,7 +82,6 @@ public function createFromTransport(BaseTransport $transport): BaseTransportData { $transportData = $this->createInstance(); $this->fillFromTransport($transportData, $transport); - $transportData->daysUntilDelivery = $transport->getDaysUntilDelivery(); $transportData->transportType = $transport->getTransportType(); $transportData->trackingUrl = $transport->getTrackingUrl(); $transportData->maxWeight = $transport->getMaxWeight(); From 6ea4f3e8df2b26950aa4714341fa55456e24b702 Mon Sep 17 00:00:00 2001 From: Martin Grossmann Date: Tue, 12 Dec 2023 12:11:53 +0100 Subject: [PATCH 10/32] product domain dependent sale exclusion moved to shopsys/framework --- app/src/Migrations/Version20200407071420.php | 27 -------------------- app/src/Model/Product/Product.php | 10 -------- app/src/Model/Product/ProductData.php | 6 ----- app/src/Model/Product/ProductDataFactory.php | 1 - app/src/Model/Product/ProductDomain.php | 22 ---------------- 5 files changed, 66 deletions(-) delete mode 100644 app/src/Migrations/Version20200407071420.php diff --git a/app/src/Migrations/Version20200407071420.php b/app/src/Migrations/Version20200407071420.php deleted file mode 100644 index d1cf3109c2..0000000000 --- a/app/src/Migrations/Version20200407071420.php +++ /dev/null @@ -1,27 +0,0 @@ -sql('ALTER TABLE product_domains ADD sale_exclusion BOOLEAN NOT NULL DEFAULT FALSE'); - $this->sql('ALTER TABLE product_domains ALTER sale_exclusion DROP DEFAULT;'); - } - - /** - * @param \Doctrine\DBAL\Schema\Schema $schema - */ - public function down(Schema $schema): void - { - } -} diff --git a/app/src/Model/Product/Product.php b/app/src/Model/Product/Product.php index 044a51d609..d3e00fe89d 100644 --- a/app/src/Model/Product/Product.php +++ b/app/src/Model/Product/Product.php @@ -199,7 +199,6 @@ protected function setDomains(BaseProductData $productData): void foreach ($this->domains as $productDomain) { $domainId = $productDomain->getDomainId(); - $productDomain->setSaleExclusion($productData->saleExclusion[$domainId]); $productDomain->setDomainHidden($productData->domainHidden[$domainId] ?? false); } } @@ -389,15 +388,6 @@ public function isDomainHidden(int $domainId): ?bool return $this->getProductDomain($domainId)->isDomainHidden(); } - /** - * @param int $domainId - * @return bool - */ - public function getSaleExclusion(int $domainId): bool - { - return $this->getProductDomain($domainId)->getSaleExclusion(); - } - /** * @param int $domainId * @return bool diff --git a/app/src/Model/Product/ProductData.php b/app/src/Model/Product/ProductData.php index 22ded33633..ce65852e8b 100644 --- a/app/src/Model/Product/ProductData.php +++ b/app/src/Model/Product/ProductData.php @@ -31,11 +31,6 @@ class ProductData extends BaseProductData */ public $stockProductData; - /** - * @var bool[] - */ - public $saleExclusion; - /** * @var bool[]|null[] */ @@ -63,7 +58,6 @@ public function __construct() $this->namePrefix = []; $this->nameSufix = []; $this->stockProductData = []; - $this->saleExclusion = []; $this->domainHidden = []; $this->weight = null; $this->relatedProducts = []; diff --git a/app/src/Model/Product/ProductDataFactory.php b/app/src/Model/Product/ProductDataFactory.php index 24b6bd37be..c887582721 100644 --- a/app/src/Model/Product/ProductDataFactory.php +++ b/app/src/Model/Product/ProductDataFactory.php @@ -139,7 +139,6 @@ protected function fillNew(BaseProductData $productData): void parent::fillNew($productData); foreach ($this->domain->getAllIds() as $domainId) { - $productData->saleExclusion[$domainId] = false; $productData->domainHidden[$domainId] = false; } diff --git a/app/src/Model/Product/ProductDomain.php b/app/src/Model/Product/ProductDomain.php index de7f56441d..658f26fdc6 100644 --- a/app/src/Model/Product/ProductDomain.php +++ b/app/src/Model/Product/ProductDomain.php @@ -22,12 +22,6 @@ */ class ProductDomain extends BaseProductDomain { - /** - * @var bool - * @ORM\Column(type="boolean") - */ - protected $saleExclusion; - /** * @var bool * @ORM\Column(type="boolean") @@ -51,22 +45,6 @@ public function __construct(Product $product, $domainId) $this->calculatedSaleExclusion = true; } - /** - * @return bool - */ - public function getSaleExclusion(): bool - { - return $this->saleExclusion; - } - - /** - * @param bool $saleExclusion - */ - public function setSaleExclusion(bool $saleExclusion): void - { - $this->saleExclusion = $saleExclusion; - } - /** * @return bool */ From 7714fbddcbaaa42054ec9883cfdd1826acac1f82 Mon Sep 17 00:00:00 2001 From: Martin Grossmann Date: Sun, 12 Nov 2023 00:10:27 +0100 Subject: [PATCH 11/32] product availability moved to shopsys/framework --- .../Model/Cart/CartWatcherFacade.php | 4 +- .../DataMapper/ProductArrayFieldMapper.php | 1 - .../DataMapper/ProductEntityFieldMapper.php | 4 +- app/src/Model/Cart/CartFacade.php | 4 +- .../Availability/AvailabilityStatusEnum.php | 11 - .../ProductAvailabilityFacade.php | 262 ------------------ .../ProductStoreAvailabilityInformation.php | 54 ---- .../Elasticsearch/ProductExportRepository.php | 4 +- .../FeedItem/MergadoFeedItemFactory.php | 8 +- .../Model/FeedItem/HeurekaFeedItemFactory.php | 28 +- .../Model/FeedItem/ZboziFeedItemFactory.php | 23 +- .../Cart/CartFacadeDeleteOldCartsTest.php | 2 +- .../Functional/Model/Cart/CartFacadeTest.php | 2 +- .../ProductAvailabilityFacadeTest.php | 2 +- .../Cart/AnonymousAddToCartTest.php | 2 +- .../Functional/Cart/RetrieveCartTest.php | 4 +- .../Functional/Product/ProductTest.php | 2 +- .../Functional/Product/ProductsTest.php | 2 +- 18 files changed, 22 insertions(+), 397 deletions(-) delete mode 100644 app/src/Model/Product/Availability/AvailabilityStatusEnum.php delete mode 100644 app/src/Model/Product/Availability/ProductAvailabilityFacade.php delete mode 100644 app/src/Model/Product/Availability/ProductStoreAvailabilityInformation.php diff --git a/app/src/FrontendApi/Model/Cart/CartWatcherFacade.php b/app/src/FrontendApi/Model/Cart/CartWatcherFacade.php index 59f1ec030b..e074bbaf4f 100644 --- a/app/src/FrontendApi/Model/Cart/CartWatcherFacade.php +++ b/app/src/FrontendApi/Model/Cart/CartWatcherFacade.php @@ -7,13 +7,13 @@ use App\Model\Cart\Cart; use App\Model\Cart\CartPromoCodeFacade; use App\Model\Order\PromoCode\CurrentPromoCodeFacade; -use App\Model\Product\Availability\ProductAvailabilityFacade; use DateTime; use Doctrine\ORM\EntityManagerInterface; use Shopsys\FrameworkBundle\Component\Domain\Domain; use Shopsys\FrameworkBundle\Model\Cart\Watcher\CartWatcher; use Shopsys\FrameworkBundle\Model\Customer\User\CurrentCustomerUser; use Shopsys\FrameworkBundle\Model\Order\PromoCode\Exception\PromoCodeException; +use Shopsys\FrameworkBundle\Model\Product\Availability\ProductAvailabilityFacade; class CartWatcherFacade { @@ -23,7 +23,7 @@ class CartWatcherFacade * @param \Shopsys\FrameworkBundle\Model\Cart\Watcher\CartWatcher $cartWatcher * @param \Doctrine\ORM\EntityManagerInterface $em * @param \App\Model\Customer\User\CurrentCustomerUser $currentCustomerUser - * @param \App\Model\Product\Availability\ProductAvailabilityFacade $productAvailabilityFacade + * @param \Shopsys\FrameworkBundle\Model\Product\Availability\ProductAvailabilityFacade $productAvailabilityFacade * @param \Shopsys\FrameworkBundle\Component\Domain\Domain $domain * @param \App\FrontendApi\Model\Cart\TransportAndPaymentWatcherFacade $transportAndPaymentWatcherFacade * @param \App\Model\Order\PromoCode\CurrentPromoCodeFacade $currentPromoCodeFacade diff --git a/app/src/FrontendApi/Resolver/Products/DataMapper/ProductArrayFieldMapper.php b/app/src/FrontendApi/Resolver/Products/DataMapper/ProductArrayFieldMapper.php index 4e874704af..4b60b8761f 100644 --- a/app/src/FrontendApi/Resolver/Products/DataMapper/ProductArrayFieldMapper.php +++ b/app/src/FrontendApi/Resolver/Products/DataMapper/ProductArrayFieldMapper.php @@ -5,7 +5,6 @@ namespace App\FrontendApi\Resolver\Products\DataMapper; use App\Component\Deprecation\DeprecatedMethodException; -use App\Model\Product\Availability\AvailabilityStatusEnum; use GraphQL\Executor\Promise\Promise; use Overblog\DataLoader\DataLoaderInterface; use Shopsys\FrameworkBundle\Model\Category\CategoryFacade; diff --git a/app/src/FrontendApi/Resolver/Products/DataMapper/ProductEntityFieldMapper.php b/app/src/FrontendApi/Resolver/Products/DataMapper/ProductEntityFieldMapper.php index d0c8381ca7..25a70c5bd8 100644 --- a/app/src/FrontendApi/Resolver/Products/DataMapper/ProductEntityFieldMapper.php +++ b/app/src/FrontendApi/Resolver/Products/DataMapper/ProductEntityFieldMapper.php @@ -9,7 +9,6 @@ use App\Component\Router\FriendlyUrl\FriendlyUrlFacade; use App\FrontendApi\Model\Parameter\ParameterWithValuesFactory; use App\Model\Category\Category; -use App\Model\Product\Availability\ProductAvailabilityFacade; use App\Model\Product\Parameter\ParameterRepository; use App\Model\Product\Product; use App\Model\Product\ProductRepository; @@ -21,6 +20,7 @@ use Shopsys\FrameworkBundle\Model\Customer\User\CurrentCustomerUser; use Shopsys\FrameworkBundle\Model\Pricing\Group\PricingGroupSettingFacade; use Shopsys\FrameworkBundle\Model\Product\Availability\Availability; +use Shopsys\FrameworkBundle\Model\Product\Availability\ProductAvailabilityFacade; use Shopsys\FrameworkBundle\Model\Product\Collection\ProductCollectionFacade; use Shopsys\FrameworkBundle\Model\Product\Product as BaseProduct; use Shopsys\FrontendApiBundle\Model\Product\ProductAccessoryFacade; @@ -46,7 +46,7 @@ class ProductEntityFieldMapper extends BaseProductEntityFieldMapper * @param \Shopsys\FrontendApiBundle\Model\Product\ProductAccessoryFacade $productAccessoryFacade * @param \App\Model\Customer\User\CurrentCustomerUser $currentCustomerUser * @param \App\FrontendApi\Model\Parameter\ParameterWithValuesFactory $parameterWithValuesFactory - * @param \App\Model\Product\Availability\ProductAvailabilityFacade $productAvailabilityFacade + * @param \Shopsys\FrameworkBundle\Model\Product\Availability\ProductAvailabilityFacade $productAvailabilityFacade * @param \App\Component\Router\FriendlyUrl\FriendlyUrlFacade $friendlyUrlFacade * @param \App\Model\Product\ProductRepository $productRepository * @param \Shopsys\FrameworkBundle\Model\Pricing\Group\PricingGroupSettingFacade $pricingGroupSettingFacade diff --git a/app/src/Model/Cart/CartFacade.php b/app/src/Model/Cart/CartFacade.php index c2588318a5..11499eb167 100644 --- a/app/src/Model/Cart/CartFacade.php +++ b/app/src/Model/Cart/CartFacade.php @@ -4,7 +4,6 @@ namespace App\Model\Cart; -use App\Model\Product\Availability\ProductAvailabilityFacade; use App\Model\Product\Product; use DateTime; use Doctrine\ORM\EntityManagerInterface; @@ -20,6 +19,7 @@ use Shopsys\FrameworkBundle\Model\Customer\User\CustomerUserIdentifier; use Shopsys\FrameworkBundle\Model\Customer\User\CustomerUserIdentifierFactory; use Shopsys\FrameworkBundle\Model\Order\PromoCode\CurrentPromoCodeFacade; +use Shopsys\FrameworkBundle\Model\Product\Availability\ProductAvailabilityFacade; use Shopsys\FrameworkBundle\Model\Product\Pricing\ProductPriceCalculationForCustomerUser; use Shopsys\FrameworkBundle\Model\Product\ProductRepository; @@ -49,7 +49,7 @@ class CartFacade extends BaseCartFacade * @param \Shopsys\FrameworkBundle\Model\Cart\Item\CartItemFactory $cartItemFactory * @param \Shopsys\FrameworkBundle\Model\Cart\CartRepository $cartRepository * @param \App\Model\Cart\Watcher\CartWatcherFacade $cartWatcherFacade - * @param \App\Model\Product\Availability\ProductAvailabilityFacade $productAvailabilityFacade + * @param \Shopsys\FrameworkBundle\Model\Product\Availability\ProductAvailabilityFacade $productAvailabilityFacade */ public function __construct( EntityManagerInterface $em, diff --git a/app/src/Model/Product/Availability/AvailabilityStatusEnum.php b/app/src/Model/Product/Availability/AvailabilityStatusEnum.php deleted file mode 100644 index 47f20d91d6..0000000000 --- a/app/src/Model/Product/Availability/AvailabilityStatusEnum.php +++ /dev/null @@ -1,11 +0,0 @@ - - */ - private array $productAvailabilityDomainCache = []; - - /** - * @param \App\Component\Setting\Setting $setting - * @param \Shopsys\FrameworkBundle\Model\Stock\ProductStockFacade $productStockFacade - * @param \Shopsys\FrameworkBundle\Model\Store\StoreFacade $storeFacade - * @param \Shopsys\FrameworkBundle\Component\Domain\Domain $domain - */ - public function __construct( - private readonly Setting $setting, - private readonly ProductStockFacade $productStockFacade, - private readonly StoreFacade $storeFacade, - private readonly Domain $domain, - ) { - } - - /** - * @param \App\Model\Product\Product $product - * @param int $domainId - * @return string - */ - public function getProductAvailabilityInformationByDomainId(Product $product, int $domainId): string - { - $domainLocale = $this->domain->getDomainConfigById($domainId)->getLocale(); - - if ($this->isProductAvailableOnDomainCached($product, $domainId)) { - return t('In stock', [], Translator::DEFAULT_TRANSLATION_DOMAIN, $domainLocale); - } - - return t('Out of stock', [], Translator::DEFAULT_TRANSLATION_DOMAIN, $domainLocale); - } - - /** - * @param \App\Model\Product\Product $product - * @param int $domainId - * @return int|null - */ - public function getProductAvailabilityDaysByDomainId(Product $product, int $domainId): ?int - { - if ($this->isProductAvailableOnDomainCached($product, $domainId)) { - return 0; - } - - return null; - } - - /** - * @param \App\Model\Product\Product $product - * @param int $domainId - * @return \App\Model\Product\Availability\AvailabilityStatusEnum - */ - public function getProductAvailabilityStatusByDomainId(Product $product, int $domainId): AvailabilityStatusEnum - { - if ($this->isProductAvailableOnDomainCached($product, $domainId)) { - return AvailabilityStatusEnum::InStock; - } - - return AvailabilityStatusEnum::OutOfStock; - } - - /** - * @param \App\Model\Product\Product $product - * @param int $domainId - * @return string - */ - public function getProductAvailableStoresCountInformationByDomainId(Product $product, int $domainId): string - { - $count = $this->getAvailableStoresCount($product, $domainId); - - return t( - '{0}|{1}Available in %count% store|[2,Inf]Available in %count% stores', - ['%count%' => $count], - ); - } - - /** - * @param \App\Model\Product\Product $product - * @param int $domainId - * @return int - */ - public function getAvailableStoresCount(Product $product, int $domainId): int - { - $productStocks = $this->productStockFacade->getProductStocksByProduct($product); - - $count = 0; - - foreach ($productStocks as $productStock) { - if ($productStock->getProductQuantity() > 0 && $productStock->getStock()->isEnabled($domainId)) { - $count += count($productStock->getStock()->getStores()); - } - } - - return $count; - } - - /** - * @param \App\Model\Product\Product $product - * @param int $domainId - * @return bool - */ - public function isProductAvailableOnDomainCached(Product $product, int $domainId): bool - { - $cacheKey = sprintf('product:%d-domain:%d', $product->getId(), $domainId); - - if (array_key_exists($cacheKey, $this->productAvailabilityDomainCache)) { - return $this->productAvailabilityDomainCache[$cacheKey]; - } - - $this->productAvailabilityDomainCache[$cacheKey] = $this->productStockFacade->isProductAvailableOnDomain($product, $domainId); - - return $this->productAvailabilityDomainCache[$cacheKey]; - } - - /** - * @param \App\Model\Product\Product $product - * @param int $domainId - * @return \App\Model\Product\Availability\ProductStoreAvailabilityInformation[] - */ - public function getProductStoresAvailabilitiesInformationByDomainIdIndexedByStoreId( - Product $product, - int $domainId, - ): array { - $stores = $this->storeFacade->getStoresListEnabledOnDomain($domainId); - - $isAvailable = $this->isProductAvailableOnDomainCached($product, $domainId); - - $productStocksIndexedByStockId = $this->productStockFacade->getProductStocksByProductIndexedByStockId($product); - - $productStoresAvailabilityInformationList = []; - - $domainLocale = $this->domain->getDomainConfigById($domainId)->getLocale(); - - foreach ($stores as $store) { - $availabilityStatus = AvailabilityStatusEnum::InStock; - $availabilityInformation = t('Available immediately', [], Translator::DEFAULT_TRANSLATION_DOMAIN, $domainLocale); - - if (!$isAvailable) { - $availabilityStatus = AvailabilityStatusEnum::OutOfStock; - $availabilityInformation = t('Unavailable', [], Translator::DEFAULT_TRANSLATION_DOMAIN, $domainLocale); - } else { - $stock = $store->getStock(); - - $productStock = null; - - if ($stock !== null && $stock->isEnabled($domainId)) { - $productStock = $productStocksIndexedByStockId[$stock->getId()]; - } - - if ($productStock === null || $productStock->getProductQuantity() <= 0) { - $weeks = $this->getTransferWeeksByDomainId($domainId); - $availabilityInformation = $this->getWeeksAvailabilityMessageByWeeks($weeks, $domainId); - } - } - - $productStoresAvailabilityInformationList[$store->getId()] = new ProductStoreAvailabilityInformation( - $store->getName(), - $store->getId(), - $availabilityInformation, - $availabilityStatus, - ); - } - - return $productStoresAvailabilityInformationList; - } - - /** - * @param int $weeks - * @param int $domainId - * @return string - */ - private function getWeeksAvailabilityMessageByWeeks(int $weeks, int $domainId): string - { - $domainLocale = $this->domain->getDomainConfigById($domainId)->getLocale(); - - return t( - '{0,1} Available in one week|[2,Inf] Available in %count% weeks', - ['%count%' => $weeks], - Translator::DEFAULT_TRANSLATION_DOMAIN, - $domainLocale, - ); - } - - /** - * @param int $days - * @return int - */ - public static function calculateDaysToWeeks(int $days): int - { - return (int)ceil($days / self::DAYS_IN_WEEK); - } - - /** - * @param int $domainId - * @return int - */ - private function getTransferWeeksByDomainId(int $domainId): int - { - return self::calculateDaysToWeeks($this->getTransferDaysByDomainId($domainId)); - } - - /** - * @param int $domainId - * @return int - */ - public function getTransferDaysByDomainId(int $domainId): int - { - return $this->setting->getForDomain(Setting::TRANSFER_DAYS_BETWEEN_STOCKS, $domainId); - } - - /** - * @param \App\Model\Product\Product $product - * @param int $domainId - * @return int - */ - public function getGroupedStockQuantityByProductAndDomainId(Product $product, int $domainId): int - { - $productStocksByDomainIdIndexedByStockId = $this->productStockFacade->getProductStocksByProductAndDomainIdIndexedByStockId($product, $domainId); - - return $this->sumProductStockQuantities($productStocksByDomainIdIndexedByStockId); - } - - /** - * @param \Shopsys\FrameworkBundle\Model\Stock\ProductStock[] $productStocksByDomainIdIndexedByStockId - * @return int - */ - private function sumProductStockQuantities(array $productStocksByDomainIdIndexedByStockId): int - { - $totalProductStocksQuantity = 0; - - foreach ($productStocksByDomainIdIndexedByStockId as $productStock) { - $totalProductStocksQuantity += $productStock->getProductQuantity(); - } - - return $totalProductStocksQuantity; - } - - public function reset(): void - { - $this->productAvailabilityDomainCache = []; - } -} diff --git a/app/src/Model/Product/Availability/ProductStoreAvailabilityInformation.php b/app/src/Model/Product/Availability/ProductStoreAvailabilityInformation.php deleted file mode 100644 index 979ece71b2..0000000000 --- a/app/src/Model/Product/Availability/ProductStoreAvailabilityInformation.php +++ /dev/null @@ -1,54 +0,0 @@ -storeName; - } - - /** - * @return int - */ - public function getStoreId(): int - { - return $this->storeId; - } - - /** - * @return string - */ - public function getAvailabilityInformation(): string - { - return $this->availabilityInformation; - } - - /** - * @return \App\Model\Product\Availability\AvailabilityStatusEnum - */ - public function getAvailabilityStatus(): AvailabilityStatusEnum - { - return $this->availabilityStatus; - } -} diff --git a/app/src/Model/Product/Elasticsearch/ProductExportRepository.php b/app/src/Model/Product/Elasticsearch/ProductExportRepository.php index 2935cbaa65..a38949b040 100644 --- a/app/src/Model/Product/Elasticsearch/ProductExportRepository.php +++ b/app/src/Model/Product/Elasticsearch/ProductExportRepository.php @@ -6,7 +6,6 @@ use App\Component\Breadcrumb\BreadcrumbFacade; use App\Model\Category\CategoryFacade; -use App\Model\Product\Availability\ProductAvailabilityFacade; use App\Model\Product\Parameter\Parameter; use App\Model\Product\Product; use App\Model\Product\ProductRepository; @@ -19,6 +18,7 @@ use Shopsys\FrameworkBundle\Model\Pricing\Group\PricingGroup; use Shopsys\FrameworkBundle\Model\Pricing\Group\PricingGroupSettingFacade; use Shopsys\FrameworkBundle\Model\Product\Accessory\ProductAccessoryFacade; +use Shopsys\FrameworkBundle\Model\Product\Availability\ProductAvailabilityFacade; use Shopsys\FrameworkBundle\Model\Product\Brand\BrandCachedFacade; use Shopsys\FrameworkBundle\Model\Product\Elasticsearch\ProductExportRepository as BaseProductExportRepository; use Shopsys\FrameworkBundle\Model\Product\Parameter\ParameterRepository; @@ -62,7 +62,7 @@ class ProductExportRepository extends BaseProductExportRepository * @param \App\Model\Category\CategoryFacade $categoryFacade * @param \Shopsys\FrameworkBundle\Model\Product\Accessory\ProductAccessoryFacade $productAccessoryFacade * @param \Shopsys\FrameworkBundle\Model\Product\Brand\BrandCachedFacade $brandCachedFacade - * @param \App\Model\Product\Availability\ProductAvailabilityFacade $productAvailabilityFacade + * @param \Shopsys\FrameworkBundle\Model\Product\Availability\ProductAvailabilityFacade $productAvailabilityFacade * @param \App\Model\Product\ProductRepository $productRepository * @param \Shopsys\FrameworkBundle\Model\Pricing\Group\PricingGroupSettingFacade $pricingGroupSettingFacade * @param \Shopsys\FrameworkBundle\Model\Product\Pricing\ProductPriceCalculation $productPriceCalculation diff --git a/app/src/Model/ProductFeed/Mergado/FeedItem/MergadoFeedItemFactory.php b/app/src/Model/ProductFeed/Mergado/FeedItem/MergadoFeedItemFactory.php index 7e351232da..f151d5be91 100644 --- a/app/src/Model/ProductFeed/Mergado/FeedItem/MergadoFeedItemFactory.php +++ b/app/src/Model/ProductFeed/Mergado/FeedItem/MergadoFeedItemFactory.php @@ -6,8 +6,6 @@ use App\Component\Image\ImageFacade; use App\Model\Category\CategoryFacade; -use App\Model\Product\Availability\AvailabilityStatusEnum; -use App\Model\Product\Availability\ProductAvailabilityFacade; use App\Model\Product\Flag\Flag; use App\Model\Product\Product; use Psr\Log\LoggerInterface; @@ -16,6 +14,8 @@ use Shopsys\FrameworkBundle\Model\Feed\FeedItemImageHelper; use Shopsys\FrameworkBundle\Model\Pricing\Currency\CurrencyFacade; use Shopsys\FrameworkBundle\Model\Pricing\Group\PricingGroupSettingFacade; +use Shopsys\FrameworkBundle\Model\Product\Availability\AvailabilityStatusEnum; +use Shopsys\FrameworkBundle\Model\Product\Availability\ProductAvailabilityFacade; use Shopsys\FrameworkBundle\Model\Product\Collection\ProductParametersBatchLoader; use Shopsys\FrameworkBundle\Model\Product\Collection\ProductUrlsBatchLoader; use Shopsys\FrameworkBundle\Model\Product\Pricing\ProductPriceCalculation; @@ -27,7 +27,7 @@ class MergadoFeedItemFactory * @param \Shopsys\FrameworkBundle\Model\Product\Collection\ProductUrlsBatchLoader $productUrlsBatchLoader * @param \Shopsys\FrameworkBundle\Model\Product\Collection\ProductParametersBatchLoader $productParametersBatchLoader * @param \App\Model\Category\CategoryFacade $categoryFacade - * @param \App\Model\Product\Availability\ProductAvailabilityFacade $availabilityFacade + * @param \Shopsys\FrameworkBundle\Model\Product\Availability\ProductAvailabilityFacade $availabilityFacade * @param \Shopsys\FrameworkBundle\Model\Product\Pricing\ProductPriceCalculationForCustomerUser $productPriceCalculationForCustomerUser * @param \App\Component\Image\ImageFacade $imageFacade * @param \Shopsys\FrameworkBundle\Model\Pricing\Currency\CurrencyFacade $currencyFacade @@ -167,7 +167,7 @@ private function getOtherProductImages(Product $product, DomainConfig $domainCon } /** - * @param \App\Model\Product\Availability\AvailabilityStatusEnum $availabilityStatus + * @param \Shopsys\FrameworkBundle\Model\Product\Availability\AvailabilityStatusEnum $availabilityStatus * @return string */ private function mapStockStatusToAvailability(AvailabilityStatusEnum $availabilityStatus): string diff --git a/app/src/ProductFeed/Heureka/Model/FeedItem/HeurekaFeedItemFactory.php b/app/src/ProductFeed/Heureka/Model/FeedItem/HeurekaFeedItemFactory.php index 8b92d38151..079bda8617 100644 --- a/app/src/ProductFeed/Heureka/Model/FeedItem/HeurekaFeedItemFactory.php +++ b/app/src/ProductFeed/Heureka/Model/FeedItem/HeurekaFeedItemFactory.php @@ -4,46 +4,20 @@ namespace App\ProductFeed\Heureka\Model\FeedItem; -use App\Model\Product\Availability\ProductAvailabilityFacade; use Shopsys\FrameworkBundle\Component\Domain\Config\DomainConfig; -use Shopsys\FrameworkBundle\Model\Category\CategoryFacade; -use Shopsys\FrameworkBundle\Model\Product\Pricing\ProductPriceCalculationForCustomerUser; use Shopsys\FrameworkBundle\Model\Product\Product; use Shopsys\ProductFeed\HeurekaBundle\Model\FeedItem\HeurekaFeedItem; use Shopsys\ProductFeed\HeurekaBundle\Model\FeedItem\HeurekaFeedItemFactory as BaseHeurekaFeedItemFactory; -use Shopsys\ProductFeed\HeurekaBundle\Model\FeedItem\HeurekaProductDataBatchLoader; -use Shopsys\ProductFeed\HeurekaBundle\Model\HeurekaCategory\HeurekaCategoryFacade; /** * @method string|null getBrandName(\App\Model\Product\Product $product) * @method \Shopsys\FrameworkBundle\Model\Pricing\Price getPrice(\App\Model\Product\Product $product, \Shopsys\FrameworkBundle\Component\Domain\Config\DomainConfig $domainConfig) * @method string|null getHeurekaCategoryFullName(\App\Model\Product\Product $product, \Shopsys\FrameworkBundle\Component\Domain\Config\DomainConfig $domainConfig) * @property \App\Model\Category\CategoryFacade $categoryFacade + * @method __construct(\Shopsys\FrameworkBundle\Model\Product\Pricing\ProductPriceCalculationForCustomerUser $productPriceCalculationForCustomerUser, \Shopsys\ProductFeed\HeurekaBundle\Model\FeedItem\HeurekaProductDataBatchLoader $productDataBatchLoader, \Shopsys\ProductFeed\HeurekaBundle\Model\HeurekaCategory\HeurekaCategoryFacade $heurekaCategoryFacade, \App\Model\Category\CategoryFacade $categoryFacade, \Shopsys\FrameworkBundle\Model\Product\Availability\ProductAvailabilityFacade $productAvailabilityFacade) */ class HeurekaFeedItemFactory extends BaseHeurekaFeedItemFactory { - /** - * @param \Shopsys\FrameworkBundle\Model\Product\Pricing\ProductPriceCalculationForCustomerUser $productPriceCalculationForCustomerUser - * @param \Shopsys\ProductFeed\HeurekaBundle\Model\FeedItem\HeurekaProductDataBatchLoader $heurekaProductDataBatchLoader - * @param \Shopsys\ProductFeed\HeurekaBundle\Model\HeurekaCategory\HeurekaCategoryFacade $heurekaCategoryFacade - * @param \App\Model\Category\CategoryFacade $categoryFacade - * @param \App\Model\Product\Availability\ProductAvailabilityFacade $productAvailabilityFacade - */ - public function __construct( - ProductPriceCalculationForCustomerUser $productPriceCalculationForCustomerUser, - HeurekaProductDataBatchLoader $heurekaProductDataBatchLoader, - HeurekaCategoryFacade $heurekaCategoryFacade, - CategoryFacade $categoryFacade, - private readonly ProductAvailabilityFacade $productAvailabilityFacade, - ) { - parent::__construct( - $productPriceCalculationForCustomerUser, - $heurekaProductDataBatchLoader, - $heurekaCategoryFacade, - $categoryFacade, - ); - } - /** * @param \App\Model\Product\Product $product * @param \Shopsys\FrameworkBundle\Component\Domain\Config\DomainConfig $domainConfig diff --git a/app/src/ProductFeed/Zbozi/Model/FeedItem/ZboziFeedItemFactory.php b/app/src/ProductFeed/Zbozi/Model/FeedItem/ZboziFeedItemFactory.php index 06ccc65da9..34bba34933 100644 --- a/app/src/ProductFeed/Zbozi/Model/FeedItem/ZboziFeedItemFactory.php +++ b/app/src/ProductFeed/Zbozi/Model/FeedItem/ZboziFeedItemFactory.php @@ -4,12 +4,7 @@ namespace App\ProductFeed\Zbozi\Model\FeedItem; -use App\Model\Product\Availability\ProductAvailabilityFacade; use Shopsys\FrameworkBundle\Component\Domain\Config\DomainConfig; -use Shopsys\FrameworkBundle\Model\Category\CategoryFacade; -use Shopsys\FrameworkBundle\Model\Product\Collection\ProductParametersBatchLoader; -use Shopsys\FrameworkBundle\Model\Product\Collection\ProductUrlsBatchLoader; -use Shopsys\FrameworkBundle\Model\Product\Pricing\ProductPriceCalculationForCustomerUser; use Shopsys\FrameworkBundle\Model\Product\Product; use Shopsys\ProductFeed\ZboziBundle\Model\FeedItem\ZboziFeedItem; use Shopsys\ProductFeed\ZboziBundle\Model\FeedItem\ZboziFeedItemFactory as BaseZboziFeedItemFactory; @@ -20,26 +15,10 @@ * @method \Shopsys\FrameworkBundle\Model\Pricing\Price getPrice(\App\Model\Product\Product $product, \Shopsys\FrameworkBundle\Component\Domain\Config\DomainConfig $domainConfig) * @method string[] getPathToMainCategory(\App\Model\Product\Product $product, \Shopsys\FrameworkBundle\Component\Domain\Config\DomainConfig $domainConfig) * @property \App\Model\Category\CategoryFacade $categoryFacade + * @method __construct(\Shopsys\FrameworkBundle\Model\Product\Pricing\ProductPriceCalculationForCustomerUser $productPriceCalculationForCustomerUser, \Shopsys\FrameworkBundle\Model\Product\Collection\ProductUrlsBatchLoader $productUrlsBatchLoader, \Shopsys\FrameworkBundle\Model\Product\Collection\ProductParametersBatchLoader $productParametersBatchLoader, \App\Model\Category\CategoryFacade $categoryFacade, \Shopsys\FrameworkBundle\Model\Product\Availability\ProductAvailabilityFacade $productAvailabilityFacade) */ class ZboziFeedItemFactory extends BaseZboziFeedItemFactory { - /** - * @param \Shopsys\FrameworkBundle\Model\Product\Pricing\ProductPriceCalculationForCustomerUser $productPriceCalculationForCustomerUser - * @param \Shopsys\FrameworkBundle\Model\Product\Collection\ProductUrlsBatchLoader $productUrlsBatchLoader - * @param \Shopsys\FrameworkBundle\Model\Product\Collection\ProductParametersBatchLoader $productParametersBatchLoader - * @param \App\Model\Category\CategoryFacade $categoryFacade - * @param \App\Model\Product\Availability\ProductAvailabilityFacade $productAvailabilityFacade - */ - public function __construct( - ProductPriceCalculationForCustomerUser $productPriceCalculationForCustomerUser, - ProductUrlsBatchLoader $productUrlsBatchLoader, - ProductParametersBatchLoader $productParametersBatchLoader, - CategoryFacade $categoryFacade, - private readonly ProductAvailabilityFacade $productAvailabilityFacade, - ) { - parent::__construct($productPriceCalculationForCustomerUser, $productUrlsBatchLoader, $productParametersBatchLoader, $categoryFacade); - } - /** * @param \App\Model\Product\Product $product * @param \Shopsys\ProductFeed\ZboziBundle\Model\Product\ZboziProductDomain|null $zboziProductDomain diff --git a/app/tests/App/Functional/Model/Cart/CartFacadeDeleteOldCartsTest.php b/app/tests/App/Functional/Model/Cart/CartFacadeDeleteOldCartsTest.php index 3f384ffb56..e7a54a90e7 100644 --- a/app/tests/App/Functional/Model/Cart/CartFacadeDeleteOldCartsTest.php +++ b/app/tests/App/Functional/Model/Cart/CartFacadeDeleteOldCartsTest.php @@ -10,7 +10,6 @@ use App\Model\Customer\User\CurrentCustomerUser; use App\Model\Customer\User\CustomerUserIdentifierFactory; use App\Model\Order\PromoCode\CurrentPromoCodeFacade; -use App\Model\Product\Availability\ProductAvailabilityFacade; use App\Model\Product\ProductRepository; use DateTime; use Shopsys\FrameworkBundle\Component\Money\Money; @@ -19,6 +18,7 @@ use Shopsys\FrameworkBundle\Model\Cart\Item\CartItemFactory; use Shopsys\FrameworkBundle\Model\Customer\User\CustomerUserFacade; use Shopsys\FrameworkBundle\Model\Customer\User\CustomerUserIdentifier; +use Shopsys\FrameworkBundle\Model\Product\Availability\ProductAvailabilityFacade; use Shopsys\FrameworkBundle\Model\Product\Pricing\ProductPriceCalculationForCustomerUser; use Shopsys\FrameworkBundle\Model\Product\ProductFacade; use Tests\App\Test\TransactionFunctionalTestCase; diff --git a/app/tests/App/Functional/Model/Cart/CartFacadeTest.php b/app/tests/App/Functional/Model/Cart/CartFacadeTest.php index d42b08b338..ae6a3025d9 100644 --- a/app/tests/App/Functional/Model/Cart/CartFacadeTest.php +++ b/app/tests/App/Functional/Model/Cart/CartFacadeTest.php @@ -10,7 +10,6 @@ use App\Model\Customer\User\CurrentCustomerUser; use App\Model\Customer\User\CustomerUserIdentifierFactory; use App\Model\Order\PromoCode\CurrentPromoCodeFacade; -use App\Model\Product\Availability\ProductAvailabilityFacade; use App\Model\Product\ProductRepository; use Shopsys\FrameworkBundle\Model\Cart\CartFactory; use Shopsys\FrameworkBundle\Model\Cart\CartRepository; @@ -18,6 +17,7 @@ use Shopsys\FrameworkBundle\Model\Cart\Exception\InvalidQuantityException; use Shopsys\FrameworkBundle\Model\Cart\Item\CartItemFactory; use Shopsys\FrameworkBundle\Model\Customer\User\CustomerUserIdentifier; +use Shopsys\FrameworkBundle\Model\Product\Availability\ProductAvailabilityFacade; use Shopsys\FrameworkBundle\Model\Product\Exception\ProductNotFoundException; use Shopsys\FrameworkBundle\Model\Product\Pricing\ProductPriceCalculationForCustomerUser; use Tests\App\Test\TransactionFunctionalTestCase; diff --git a/app/tests/App/Functional/Model/Product/Availability/ProductAvailabilityFacadeTest.php b/app/tests/App/Functional/Model/Product/Availability/ProductAvailabilityFacadeTest.php index 0e9affe8a1..f08ef3c104 100644 --- a/app/tests/App/Functional/Model/Product/Availability/ProductAvailabilityFacadeTest.php +++ b/app/tests/App/Functional/Model/Product/Availability/ProductAvailabilityFacadeTest.php @@ -5,9 +5,9 @@ namespace Tests\App\Functional\Model\Product\Availability; use App\DataFixtures\Demo\ProductDataFixture; -use App\Model\Product\Availability\ProductAvailabilityFacade; use App\Model\Product\ProductFacade; use Shopsys\FrameworkBundle\Component\Translation\Translator; +use Shopsys\FrameworkBundle\Model\Product\Availability\ProductAvailabilityFacade; use Shopsys\FrameworkBundle\Model\Product\ProductDataFactoryInterface; use Shopsys\FrameworkBundle\Model\Stock\ProductStockDataFactory; use Shopsys\FrameworkBundle\Model\Stock\StockFacade; diff --git a/app/tests/FrontendApiBundle/Functional/Cart/AnonymousAddToCartTest.php b/app/tests/FrontendApiBundle/Functional/Cart/AnonymousAddToCartTest.php index df034bebd4..d6362427b5 100644 --- a/app/tests/FrontendApiBundle/Functional/Cart/AnonymousAddToCartTest.php +++ b/app/tests/FrontendApiBundle/Functional/Cart/AnonymousAddToCartTest.php @@ -6,8 +6,8 @@ use App\DataFixtures\Demo\ProductDataFixture; use App\Model\Cart\CartFacade; -use App\Model\Product\Availability\ProductAvailabilityFacade; use App\Model\Product\Product; +use Shopsys\FrameworkBundle\Model\Product\Availability\ProductAvailabilityFacade; use Symfony\Component\Validator\Constraints\GreaterThan; use Tests\FrontendApiBundle\Test\GraphQlTestCase; diff --git a/app/tests/FrontendApiBundle/Functional/Cart/RetrieveCartTest.php b/app/tests/FrontendApiBundle/Functional/Cart/RetrieveCartTest.php index 60cf85e166..3433b1dd9c 100644 --- a/app/tests/FrontendApiBundle/Functional/Cart/RetrieveCartTest.php +++ b/app/tests/FrontendApiBundle/Functional/Cart/RetrieveCartTest.php @@ -7,10 +7,10 @@ use App\DataFixtures\Demo\CategoryDataFixture; use App\DataFixtures\Demo\ProductDataFixture; use App\DataFixtures\Demo\VatDataFixture; -use App\Model\Product\Availability\AvailabilityStatusEnum; -use App\Model\Product\Availability\ProductAvailabilityFacade; use App\Model\Product\Product; use Shopsys\FrameworkBundle\Component\Translation\Translator; +use Shopsys\FrameworkBundle\Model\Product\Availability\AvailabilityStatusEnum; +use Shopsys\FrameworkBundle\Model\Product\Availability\ProductAvailabilityFacade; use Symfony\Component\Routing\Generator\UrlGeneratorInterface; use Tests\FrontendApiBundle\Test\GraphQlTestCase; diff --git a/app/tests/FrontendApiBundle/Functional/Product/ProductTest.php b/app/tests/FrontendApiBundle/Functional/Product/ProductTest.php index 753aa7b7d9..132424e20a 100644 --- a/app/tests/FrontendApiBundle/Functional/Product/ProductTest.php +++ b/app/tests/FrontendApiBundle/Functional/Product/ProductTest.php @@ -7,9 +7,9 @@ use App\DataFixtures\Demo\CategoryDataFixture; use App\DataFixtures\Demo\ProductDataFixture; use App\DataFixtures\Demo\VatDataFixture; -use App\Model\Product\Availability\AvailabilityStatusEnum; use App\Model\Product\Product; use Shopsys\FrameworkBundle\Component\Translation\Translator; +use Shopsys\FrameworkBundle\Model\Product\Availability\AvailabilityStatusEnum; use Symfony\Component\Routing\Generator\UrlGeneratorInterface; use Tests\FrontendApiBundle\Test\GraphQlTestCase; diff --git a/app/tests/FrontendApiBundle/Functional/Product/ProductsTest.php b/app/tests/FrontendApiBundle/Functional/Product/ProductsTest.php index 57c5a478cc..a3227c055c 100644 --- a/app/tests/FrontendApiBundle/Functional/Product/ProductsTest.php +++ b/app/tests/FrontendApiBundle/Functional/Product/ProductsTest.php @@ -5,8 +5,8 @@ namespace Tests\FrontendApiBundle\Functional\Product; use App\DataFixtures\Demo\VatDataFixture; -use App\Model\Product\Availability\AvailabilityStatusEnum; use Shopsys\FrameworkBundle\Component\Translation\Translator; +use Shopsys\FrameworkBundle\Model\Product\Availability\AvailabilityStatusEnum; class ProductsTest extends ProductsGraphQlTestCase { From ecce4736ccee453cbe908f66038795d5eec46b00 Mon Sep 17 00:00:00 2001 From: Martin Grossmann Date: Sun, 12 Nov 2023 00:13:34 +0100 Subject: [PATCH 12/32] fixed product selling denied test --- .../Product/ProductSellingDeniedOnDomainTest.php | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/app/tests/FrontendApiBundle/Functional/Product/ProductSellingDeniedOnDomainTest.php b/app/tests/FrontendApiBundle/Functional/Product/ProductSellingDeniedOnDomainTest.php index e913152425..cb85c580dd 100644 --- a/app/tests/FrontendApiBundle/Functional/Product/ProductSellingDeniedOnDomainTest.php +++ b/app/tests/FrontendApiBundle/Functional/Product/ProductSellingDeniedOnDomainTest.php @@ -8,7 +8,6 @@ use App\Model\Product\ProductDataFactory; use App\Model\Product\ProductFacade; use App\Model\Product\ProductSellingDeniedRecalculator; -use Shopsys\FrameworkBundle\Model\Product\Elasticsearch\ProductExportSubscriber; use Tests\FrontendApiBundle\Test\GraphQlTestCase; use function sleep; @@ -29,11 +28,6 @@ class ProductSellingDeniedOnDomainTest extends GraphQlTestCase */ private ProductDataFactory $productDataFactory; - /** - * @inject - */ - private ProductExportSubscriber $productExportSubscriber; - public function testSellingDeniedOnDomain(): void { /** @var \App\Model\Product\Product $product */ @@ -46,7 +40,7 @@ public function testSellingDeniedOnDomain(): void $this->dispatchFakeKernelResponseEventToTriggerImmediateRecalculations(); - $this->productExportSubscriber->exportScheduledRows(); + $this->handleDispatchedRecalculationMessages(); // wait for elastic to reindex sleep(1); From 035734eddbfca93ce15ade4df626b1c959840979 Mon Sep 17 00:00:00 2001 From: Martin Grossmann Date: Sun, 12 Nov 2023 00:17:33 +0100 Subject: [PATCH 13/32] custom product availability is moved from app to frontend api --- .../DataMapper/ProductArrayFieldMapper.php | 22 -------- .../DataMapper/ProductEntityFieldMapper.php | 51 +++++-------------- .../Resolver/Products/ProductResolverMap.php | 6 --- 3 files changed, 12 insertions(+), 67 deletions(-) diff --git a/app/src/FrontendApi/Resolver/Products/DataMapper/ProductArrayFieldMapper.php b/app/src/FrontendApi/Resolver/Products/DataMapper/ProductArrayFieldMapper.php index 4b60b8761f..eafe64f9af 100644 --- a/app/src/FrontendApi/Resolver/Products/DataMapper/ProductArrayFieldMapper.php +++ b/app/src/FrontendApi/Resolver/Products/DataMapper/ProductArrayFieldMapper.php @@ -4,7 +4,6 @@ namespace App\FrontendApi\Resolver\Products\DataMapper; -use App\Component\Deprecation\DeprecatedMethodException; use GraphQL\Executor\Promise\Promise; use Overblog\DataLoader\DataLoaderInterface; use Shopsys\FrameworkBundle\Model\Category\CategoryFacade; @@ -129,27 +128,6 @@ public function getCatalogNumber(array $data): string return $data['catnum']; } - /** - * @param array $data - * @return array - */ - public function getExtendedAvailability(array $data): array - { - return [ - 'name' => $data['availability'], - 'status' => $data['availability_status'], // after update graphql bundle we can expose availability status as enum: AvailabilityStatusEnum::from($data['availability_status']) - ]; - } - - /** - * @param array $data - * @return string[] - */ - public function getAvailability(array $data): array - { - throw new DeprecatedMethodException(); - } - /** * @param array $data * @return string diff --git a/app/src/FrontendApi/Resolver/Products/DataMapper/ProductEntityFieldMapper.php b/app/src/FrontendApi/Resolver/Products/DataMapper/ProductEntityFieldMapper.php index 25a70c5bd8..44a2d0afef 100644 --- a/app/src/FrontendApi/Resolver/Products/DataMapper/ProductEntityFieldMapper.php +++ b/app/src/FrontendApi/Resolver/Products/DataMapper/ProductEntityFieldMapper.php @@ -5,7 +5,6 @@ namespace App\FrontendApi\Resolver\Products\DataMapper; use App\Component\Breadcrumb\BreadcrumbFacade; -use App\Component\Deprecation\DeprecatedMethodException; use App\Component\Router\FriendlyUrl\FriendlyUrlFacade; use App\FrontendApi\Model\Parameter\ParameterWithValuesFactory; use App\Model\Category\Category; @@ -19,7 +18,6 @@ use Shopsys\FrameworkBundle\Component\Domain\Domain; use Shopsys\FrameworkBundle\Model\Customer\User\CurrentCustomerUser; use Shopsys\FrameworkBundle\Model\Pricing\Group\PricingGroupSettingFacade; -use Shopsys\FrameworkBundle\Model\Product\Availability\Availability; use Shopsys\FrameworkBundle\Model\Product\Availability\ProductAvailabilityFacade; use Shopsys\FrameworkBundle\Model\Product\Collection\ProductCollectionFacade; use Shopsys\FrameworkBundle\Model\Product\Product as BaseProduct; @@ -36,6 +34,7 @@ * @method string|null getSeoH1(\App\Model\Product\Product $product) * @method string|null getSeoTitle(\App\Model\Product\Product $product) * @method string|null getSeoMetaDescription(\App\Model\Product\Product $product) + * @method array{name: string, status: string} getAvailability(\App\Model\Product\Product $product) * @property \App\Model\Customer\User\CurrentCustomerUser $currentCustomerUser */ class ProductEntityFieldMapper extends BaseProductEntityFieldMapper @@ -63,16 +62,16 @@ public function __construct( ProductAccessoryFacade $productAccessoryFacade, CurrentCustomerUser $currentCustomerUser, ParameterWithValuesFactory $parameterWithValuesFactory, - private ProductAvailabilityFacade $productAvailabilityFacade, - private FriendlyUrlFacade $friendlyUrlFacade, - private ProductRepository $productRepository, - private PricingGroupSettingFacade $pricingGroupSettingFacade, - protected ParameterRepository $parameterRepository, - private BreadcrumbFacade $breadcrumbFacade, - private DataLoaderInterface $categoriesBatchLoader, - private DataLoaderInterface $productsSellableByIdsBatchLoader, - private DataLoaderInterface $brandsBatchLoader, - private readonly ProductVideoTranslationsRepository $productVideoTranslationsRepository, + ProductAvailabilityFacade $productAvailabilityFacade, + protected readonly FriendlyUrlFacade $friendlyUrlFacade, + protected readonly ProductRepository $productRepository, + protected readonly PricingGroupSettingFacade $pricingGroupSettingFacade, + protected readonly ParameterRepository $parameterRepository, + protected readonly BreadcrumbFacade $breadcrumbFacade, + protected readonly DataLoaderInterface $categoriesBatchLoader, + protected readonly DataLoaderInterface $productsSellableByIdsBatchLoader, + protected readonly DataLoaderInterface $brandsBatchLoader, + protected readonly ProductVideoTranslationsRepository $productVideoTranslationsRepository, ) { parent::__construct( $domain, @@ -80,6 +79,7 @@ public function __construct( $productAccessoryFacade, $currentCustomerUser, $parameterWithValuesFactory, + $productAvailabilityFacade, ); } @@ -137,33 +137,6 @@ public function getCatalogNumber(Product $product): string return $product->getCatnum(); } - /** - * @param \App\Model\Product\Product $product - * @return array{name: string, status: string} - */ - public function getExtendedAvailability(Product $product): array - { - return [ - 'name' => $this->productAvailabilityFacade->getProductAvailabilityInformationByDomainId( - $product, - $this->domain->getId(), - ), - 'status' => $this->productAvailabilityFacade->getProductAvailabilityStatusByDomainId( - $product, - $this->domain->getId(), - )->value, - ]; - } - - /** - * @param \App\Model\Product\Product $product - * @return \Shopsys\FrameworkBundle\Model\Product\Availability\Availability - */ - public function getAvailability(BaseProduct $product): Availability - { - throw new DeprecatedMethodException(); - } - /** * @param \App\Model\Product\Product $product * @return int diff --git a/app/src/FrontendApi/Resolver/Products/ProductResolverMap.php b/app/src/FrontendApi/Resolver/Products/ProductResolverMap.php index 2ff21db6ba..eb4e11fd6f 100644 --- a/app/src/FrontendApi/Resolver/Products/ProductResolverMap.php +++ b/app/src/FrontendApi/Resolver/Products/ProductResolverMap.php @@ -41,12 +41,6 @@ protected function mapProduct(): array return FieldResolver::valueFromObjectOrArray($value, $info->fieldName); } }, - 'availability' => function ($value) { - /** @var \App\FrontendApi\Resolver\Products\DataMapper\ProductArrayFieldMapper|\App\FrontendApi\Resolver\Products\DataMapper\ProductEntityFieldMapper $mapper */ - $mapper = $value instanceof Product ? $this->productEntityFieldMapper : $this->productArrayFieldMapper; - - return $mapper->getExtendedAvailability($value); - }, ]; } From 341f2d8987e39cba1f535a9f597ff9943f6a5817 Mon Sep 17 00:00:00 2001 From: Martin Grossmann Date: Sun, 12 Nov 2023 00:18:57 +0100 Subject: [PATCH 14/32] removed product calculated availability in favor of ProductAvailabilityFacade - removed recalculateAvailability field - removed scheduler and subscriber to calculate availability --- app/config/services.yaml | 8 ---- .../Doctrine/RemoveMappingsSubscriber.php | 1 - .../Controller/Admin/DefaultController.php | 3 +- .../Controller/Admin/ProductController.php | 3 +- .../Demo/AvailabilityDataFixture.php | 2 +- .../Performance/ProductDataFixture.php | 4 -- .../Availability/AvailabilityFacade.php | 38 ------------------- .../ProductAvailabilityCalculation.php | 32 ---------------- .../ProductAvailabilityRecalculator.php | 33 ---------------- .../Elasticsearch/ProductExportRepository.php | 3 +- .../Filter/ProductFilterRepository.php | 10 ----- app/src/Model/Product/Product.php | 13 ------- app/src/Model/Product/ProductDataFactory.php | 3 +- app/src/Model/Product/ProductFacade.php | 7 ---- app/src/Model/Product/ProductFactory.php | 10 ----- .../Model/Product/ProductVariantFacade.php | 2 +- ...thenticatedCartModificationsResultTest.php | 7 ---- .../Cart/CartModificationsResultTest.php | 7 ---- 18 files changed, 7 insertions(+), 179 deletions(-) delete mode 100644 app/src/Model/Product/Availability/AvailabilityFacade.php delete mode 100644 app/src/Model/Product/Availability/ProductAvailabilityCalculation.php delete mode 100644 app/src/Model/Product/Availability/ProductAvailabilityRecalculator.php diff --git a/app/config/services.yaml b/app/config/services.yaml index 175721f767..eedd622407 100644 --- a/app/config/services.yaml +++ b/app/config/services.yaml @@ -308,9 +308,6 @@ services: Shopsys\FrameworkBundle\Model\Product\Availability\AvailabilityRepository: alias: App\Model\Product\Availability\AvailabilityRepository - Shopsys\FrameworkBundle\Model\Product\Availability\AvailabilityFacade: - alias: App\Model\Product\Availability\AvailabilityFacade - Shopsys\FrameworkBundle\Model\Product\Brand\BrandFacade: alias: App\Model\Product\Brand\BrandFacade @@ -531,11 +528,6 @@ services: Shopsys\FrameworkBundle\Model\Product\ProductVisibilityRepository: alias: App\Model\Product\ProductVisibilityRepository - Shopsys\FrameworkBundle\Model\Product\Availability\ProductAvailabilityCalculation: - alias: App\Model\Product\Availability\ProductAvailabilityCalculation - - Shopsys\FrameworkBundle\Model\Product\Availability\ProductAvailabilityRecalculator: ~ - App\Model\AdvancedSearch\ProductAdvancedSearchConfig: ~ Shopsys\FrameworkBundle\Model\AdvancedSearch\ProductAdvancedSearchConfig: diff --git a/app/src/Component/Doctrine/RemoveMappingsSubscriber.php b/app/src/Component/Doctrine/RemoveMappingsSubscriber.php index 40212995b5..700e2cf4f4 100644 --- a/app/src/Component/Doctrine/RemoveMappingsSubscriber.php +++ b/app/src/Component/Doctrine/RemoveMappingsSubscriber.php @@ -40,7 +40,6 @@ public function loadClassMetadata(LoadClassMetadataEventArgs $eventArgs): void 'outOfStockAction', 'stockQuantity', 'usingStock', - 'calculatedAvailability', ], $classMetadata, ); diff --git a/app/src/Controller/Admin/DefaultController.php b/app/src/Controller/Admin/DefaultController.php index a4d5159b90..25a71a0daa 100644 --- a/app/src/Controller/Admin/DefaultController.php +++ b/app/src/Controller/Admin/DefaultController.php @@ -25,7 +25,6 @@ /** * @property \App\Component\Setting\Setting $setting - * @property \App\Model\Product\Availability\AvailabilityFacade $availabilityFacade * @property \App\Model\Mail\MailTemplateFacade $mailTemplateFacade * @property \App\Model\Product\Unit\UnitFacade $unitFacade */ @@ -37,7 +36,7 @@ class DefaultController extends BaseDefaultController * @param \App\Model\Mail\MailTemplateFacade $mailTemplateFacade * @param \App\Model\Product\Unit\UnitFacade $unitFacade * @param \App\Component\Setting\Setting $setting - * @param \App\Model\Product\Availability\AvailabilityFacade $availabilityFacade + * @param \Shopsys\FrameworkBundle\Model\Product\Availability\AvailabilityFacade $availabilityFacade * @param \Shopsys\FrameworkBundle\Component\Cron\CronModuleFacade $cronModuleFacade * @param \Shopsys\FrameworkBundle\Component\Grid\GridFactory $gridFactory * @param \Shopsys\FrameworkBundle\Component\Cron\Config\CronConfig $cronConfig diff --git a/app/src/Controller/Admin/ProductController.php b/app/src/Controller/Admin/ProductController.php index c9c3bbfcac..cf72c50aa1 100644 --- a/app/src/Controller/Admin/ProductController.php +++ b/app/src/Controller/Admin/ProductController.php @@ -15,10 +15,9 @@ * @property \App\Model\Product\ProductFacade $productFacade * @property \App\Model\Product\ProductDataFactory $productDataFactory * @property \App\Component\Setting\Setting $setting - * @property \App\Model\Product\Availability\AvailabilityFacade $availabilityFacade * @property \Shopsys\FrameworkBundle\Component\Domain\Domain $domain * @method setSellingToUntilEndOfDay(\App\Model\Product\ProductData|null $productData) - * @method __construct(\Shopsys\FrameworkBundle\Model\Product\MassAction\ProductMassActionFacade $productMassActionFacade, \Shopsys\FrameworkBundle\Component\Grid\GridFactory $gridFactory, \App\Model\Product\ProductFacade $productFacade, \App\Model\Product\ProductDataFactory $productDataFactory, \Shopsys\FrameworkBundle\Model\AdminNavigation\BreadcrumbOverrider $breadcrumbOverrider, \Shopsys\FrameworkBundle\Model\Administrator\AdministratorGridFacade $administratorGridFacade, \Shopsys\FrameworkBundle\Model\Product\Listing\ProductListAdminFacade $productListAdminFacade, \Shopsys\FrameworkBundle\Model\AdvancedSearch\AdvancedSearchProductFacade $advancedSearchProductFacade, \App\Model\Product\ProductVariantFacade $productVariantFacade, \Shopsys\FrameworkBundle\Twig\ProductExtension $productExtension, \Shopsys\FrameworkBundle\Component\Domain\Domain $domain, \App\Model\Product\Unit\UnitFacade $unitFacade, \App\Component\Setting\Setting $setting, \App\Model\Product\Availability\AvailabilityFacade $availabilityFacade) + * @method __construct(\Shopsys\FrameworkBundle\Model\Product\MassAction\ProductMassActionFacade $productMassActionFacade, \Shopsys\FrameworkBundle\Component\Grid\GridFactory $gridFactory, \App\Model\Product\ProductFacade $productFacade, \App\Model\Product\ProductDataFactory $productDataFactory, \Shopsys\FrameworkBundle\Model\AdminNavigation\BreadcrumbOverrider $breadcrumbOverrider, \Shopsys\FrameworkBundle\Model\Administrator\AdministratorGridFacade $administratorGridFacade, \Shopsys\FrameworkBundle\Model\Product\Listing\ProductListAdminFacade $productListAdminFacade, \Shopsys\FrameworkBundle\Model\AdvancedSearch\AdvancedSearchProductFacade $advancedSearchProductFacade, \App\Model\Product\ProductVariantFacade $productVariantFacade, \Shopsys\FrameworkBundle\Twig\ProductExtension $productExtension, \Shopsys\FrameworkBundle\Component\Domain\Domain $domain, \App\Model\Product\Unit\UnitFacade $unitFacade, \App\Component\Setting\Setting $setting, \Shopsys\FrameworkBundle\Model\Product\Availability\AvailabilityFacade $availabilityFacade) * @property \App\Model\Product\ProductVariantFacade $productVariantFacade * @property \App\Model\Product\Unit\UnitFacade $unitFacade */ diff --git a/app/src/DataFixtures/Demo/AvailabilityDataFixture.php b/app/src/DataFixtures/Demo/AvailabilityDataFixture.php index a99f5f1df3..5d8ef31176 100644 --- a/app/src/DataFixtures/Demo/AvailabilityDataFixture.php +++ b/app/src/DataFixtures/Demo/AvailabilityDataFixture.php @@ -21,7 +21,7 @@ class AvailabilityDataFixture extends AbstractReferenceFixture public const AVAILABILITY_PREPARING = 'availability_preparing'; /** - * @param \App\Model\Product\Availability\AvailabilityFacade $availabilityFacade + * @param \Shopsys\FrameworkBundle\Model\Product\Availability\AvailabilityFacade $availabilityFacade * @param \Shopsys\FrameworkBundle\Model\Product\Availability\AvailabilityDataFactory $availabilityDataFactory * @param \App\Component\Setting\Setting $setting * @param \Shopsys\FrameworkBundle\Component\Domain\Domain $domain diff --git a/app/src/DataFixtures/Performance/ProductDataFixture.php b/app/src/DataFixtures/Performance/ProductDataFixture.php index 5f44c0987e..297521373b 100644 --- a/app/src/DataFixtures/Performance/ProductDataFixture.php +++ b/app/src/DataFixtures/Performance/ProductDataFixture.php @@ -15,7 +15,6 @@ use Shopsys\FrameworkBundle\Component\Doctrine\SqlLoggerFacade; use Shopsys\FrameworkBundle\Model\Category\Category; use Shopsys\FrameworkBundle\Model\Category\CategoryRepository; -use Shopsys\FrameworkBundle\Model\Product\Availability\ProductAvailabilityRecalculationScheduler; use Shopsys\FrameworkBundle\Model\Product\Pricing\ProductPriceRecalculationScheduler; use Shopsys\FrameworkBundle\Model\Product\Product; use Shopsys\FrameworkBundle\Model\Product\ProductData; @@ -52,7 +51,6 @@ class ProductDataFixture * @param \Shopsys\FrameworkBundle\Component\DataFixture\PersistentReferenceFacade $persistentReferenceFacade * @param \App\Model\Category\CategoryRepository $categoryRepository * @param \Faker\Generator $faker - * @param \Shopsys\FrameworkBundle\Model\Product\Availability\ProductAvailabilityRecalculationScheduler $productAvailabilityRecalculationScheduler * @param \Shopsys\FrameworkBundle\Model\Product\Pricing\ProductPriceRecalculationScheduler $productPriceRecalculationScheduler * @param \Shopsys\FrameworkBundle\Component\Console\ProgressBarFactory $progressBarFactory * @param \App\Model\Product\ProductDataFactory $productDataFactory @@ -66,7 +64,6 @@ public function __construct( private readonly PersistentReferenceFacade $persistentReferenceFacade, private readonly CategoryRepository $categoryRepository, private readonly Faker $faker, - private readonly ProductAvailabilityRecalculationScheduler $productAvailabilityRecalculationScheduler, private readonly ProductPriceRecalculationScheduler $productPriceRecalculationScheduler, private readonly ProgressBarFactory $progressBarFactory, private readonly ProductDataFactory $productDataFactory, @@ -198,7 +195,6 @@ private function getUniqueIndex() private function clearResources() { - $this->productAvailabilityRecalculationScheduler->cleanScheduleForImmediateRecalculation(); $this->productPriceRecalculationScheduler->reset(); $this->em->clear(); gc_collect_cycles(); diff --git a/app/src/Model/Product/Availability/AvailabilityFacade.php b/app/src/Model/Product/Availability/AvailabilityFacade.php deleted file mode 100644 index b6407900c6..0000000000 --- a/app/src/Model/Product/Availability/AvailabilityFacade.php +++ /dev/null @@ -1,38 +0,0 @@ -availabilityRepository->getById($availabilityId); - - if ($newAvailabilityId !== null) { - $newAvailability = $this->availabilityRepository->getById($newAvailabilityId); - - $this->availabilityRepository->replaceAvailability($availability, $newAvailability); - - if ($this->isAvailabilityDefault($availability)) { - $this->setDefaultInStockAvailability($newAvailability); - } - } - - $this->em->remove($availability); - - $this->em->flush(); - } -} diff --git a/app/src/Model/Product/Availability/ProductAvailabilityCalculation.php b/app/src/Model/Product/Availability/ProductAvailabilityCalculation.php deleted file mode 100644 index 2ff1eaa779..0000000000 --- a/app/src/Model/Product/Availability/ProductAvailabilityCalculation.php +++ /dev/null @@ -1,32 +0,0 @@ -availabilityFacade->getDefaultInStockAvailability(); - } -} diff --git a/app/src/Model/Product/Availability/ProductAvailabilityRecalculator.php b/app/src/Model/Product/Availability/ProductAvailabilityRecalculator.php deleted file mode 100644 index 6cf290dff8..0000000000 --- a/app/src/Model/Product/Availability/ProductAvailabilityRecalculator.php +++ /dev/null @@ -1,33 +0,0 @@ -calculatedAvailability); - } - /** * @param \Shopsys\FrameworkBundle\Model\Product\ProductCategoryDomain[] $productCategoryDomains */ diff --git a/app/src/Model/Product/ProductDataFactory.php b/app/src/Model/Product/ProductDataFactory.php index c887582721..b4d8f27609 100644 --- a/app/src/Model/Product/ProductDataFactory.php +++ b/app/src/Model/Product/ProductDataFactory.php @@ -34,7 +34,6 @@ * @property \App\Model\Product\Unit\UnitFacade $unitFacade * @property \App\Model\Product\Parameter\ParameterRepository $parameterRepository * @property \App\Component\Router\FriendlyUrl\FriendlyUrlFacade $friendlyUrlFacade - * @property \App\Model\Product\Availability\AvailabilityFacade $availabilityFacade */ class ProductDataFactory extends BaseProductDataFactory { @@ -49,7 +48,7 @@ class ProductDataFactory extends BaseProductDataFactory * @param \Shopsys\FrameworkBundle\Component\Plugin\PluginCrudExtensionFacade $pluginDataFormExtensionFacade * @param \Shopsys\FrameworkBundle\Model\Product\Parameter\ProductParameterValueDataFactoryInterface $productParameterValueDataFactory * @param \Shopsys\FrameworkBundle\Model\Pricing\Group\PricingGroupFacade $pricingGroupFacade - * @param \App\Model\Product\Availability\AvailabilityFacade $availabilityFacade + * @param \Shopsys\FrameworkBundle\Model\Product\Availability\AvailabilityFacade $availabilityFacade * @param \Shopsys\FrameworkBundle\Component\FileUpload\ImageUploadDataFactory $imageUploadDataFactory * @param \Shopsys\FrameworkBundle\Model\Stock\ProductStockFacade $stockProductFacade * @param \Shopsys\FrameworkBundle\Model\Stock\StockFacade $stockFacade diff --git a/app/src/Model/Product/ProductFacade.php b/app/src/Model/Product/ProductFacade.php index fcf8c25bb8..da6f859d20 100644 --- a/app/src/Model/Product/ProductFacade.php +++ b/app/src/Model/Product/ProductFacade.php @@ -13,7 +13,6 @@ use Shopsys\FrameworkBundle\Model\Pricing\Group\PricingGroupRepository; use Shopsys\FrameworkBundle\Model\Product\Accessory\ProductAccessoryFactoryInterface; use Shopsys\FrameworkBundle\Model\Product\Accessory\ProductAccessoryRepository; -use Shopsys\FrameworkBundle\Model\Product\Availability\ProductAvailabilityRecalculationScheduler; use Shopsys\FrameworkBundle\Model\Product\Exception\ProductNotFoundException; use Shopsys\FrameworkBundle\Model\Product\Parameter\ParameterRepository; use Shopsys\FrameworkBundle\Model\Product\Parameter\ProductParameterValueFactoryInterface; @@ -42,7 +41,6 @@ * @property \App\Component\Router\FriendlyUrl\FriendlyUrlFacade $friendlyUrlFacade * @property \App\Model\Product\ProductHiddenRecalculator $productHiddenRecalculator * @property \App\Model\Product\ProductSellingDeniedRecalculator $productSellingDeniedRecalculator - * @property \App\Model\Product\Availability\AvailabilityFacade $availabilityFacade * @property \Shopsys\FrameworkBundle\Model\Product\Pricing\ProductPriceCalculation $productPriceCalculation * @method \App\Model\Product\Product getById(int $productId) * @method \Shopsys\FrameworkBundle\Model\Product\Pricing\ProductSellingPrice[][] getAllProductSellingPricesIndexedByDomainId(\App\Model\Product\Product $product) @@ -68,7 +66,6 @@ class ProductFacade extends BaseProductFacade * @param \Shopsys\FrameworkBundle\Model\Product\Pricing\ProductPriceRecalculationScheduler $productPriceRecalculationScheduler * @param \Shopsys\FrameworkBundle\Model\Pricing\Group\PricingGroupRepository $pricingGroupRepository * @param \Shopsys\FrameworkBundle\Model\Product\Pricing\ProductManualInputPriceFacade $productManualInputPriceFacade - * @param \Shopsys\FrameworkBundle\Model\Product\Availability\ProductAvailabilityRecalculationScheduler $productAvailabilityRecalculationScheduler * @param \App\Component\Router\FriendlyUrl\FriendlyUrlFacade $friendlyUrlFacade * @param \App\Model\Product\ProductHiddenRecalculator $productHiddenRecalculator * @param \App\Model\Product\ProductSellingDeniedRecalculator $productSellingDeniedRecalculator @@ -95,7 +92,6 @@ public function __construct( ProductPriceRecalculationScheduler $productPriceRecalculationScheduler, PricingGroupRepository $pricingGroupRepository, ProductManualInputPriceFacade $productManualInputPriceFacade, - ProductAvailabilityRecalculationScheduler $productAvailabilityRecalculationScheduler, FriendlyUrlFacade $friendlyUrlFacade, ProductHiddenRecalculator $productHiddenRecalculator, ProductSellingDeniedRecalculator $productSellingDeniedRecalculator, @@ -122,7 +118,6 @@ public function __construct( $productPriceRecalculationScheduler, $pricingGroupRepository, $productManualInputPriceFacade, - $productAvailabilityRecalculationScheduler, $friendlyUrlFacade, $productHiddenRecalculator, $productSellingDeniedRecalculator, @@ -199,7 +194,6 @@ public function edit($productId, ProductData $productData) $this->pluginCrudExtensionFacade->saveAllData('product', $product->getId(), $productData->pluginData); - $this->productAvailabilityRecalculationScheduler->scheduleProductForImmediateRecalculation($product); $this->productVisibilityFacade->refreshProductsVisibilityForMarkedDelayed(); $this->productPriceRecalculationScheduler->scheduleProductForImmediateRecalculation($product); @@ -245,7 +239,6 @@ public function setAdditionalDataAfterCreate(BaseProduct $product, ProductData $ $this->friendlyUrlFacade->saveUrlListFormData('front_product_detail', $product->getId(), $productData->urls); $this->friendlyUrlFacade->createFriendlyUrls('front_product_detail', $product->getId(), $product->getNames()); - $this->productAvailabilityRecalculationScheduler->scheduleProductForImmediateRecalculation($product); $this->productVisibilityFacade->refreshProductsVisibilityForMarkedDelayed(); $this->productPriceRecalculationScheduler->scheduleProductForImmediateRecalculation($product); } diff --git a/app/src/Model/Product/ProductFactory.php b/app/src/Model/Product/ProductFactory.php index 53b238cd1b..df88d4db25 100644 --- a/app/src/Model/Product/ProductFactory.php +++ b/app/src/Model/Product/ProductFactory.php @@ -4,22 +4,12 @@ namespace App\Model\Product; -use Shopsys\FrameworkBundle\Model\Product\Product; use Shopsys\FrameworkBundle\Model\Product\ProductFactory as BaseProductFactory; /** - * @property \App\Model\Product\Availability\ProductAvailabilityCalculation $productAvailabilityCalculation - * @method __construct(\Shopsys\FrameworkBundle\Component\EntityExtension\EntityNameResolver $entityNameResolver, \App\Model\Product\Availability\ProductAvailabilityCalculation $productAvailabilityCalculation) * @method \App\Model\Product\Product create(\App\Model\Product\ProductData $data) * @method \App\Model\Product\Product createMainVariant(\App\Model\Product\ProductData $data, \App\Model\Product\Product $mainProduct, \App\Model\Product\Product[] $variants) */ class ProductFactory extends BaseProductFactory { - /** - * @param \App\Model\Product\Product $product - */ - protected function setCalculatedAvailabilityIfMissing(Product $product) - { - //remove dependency on CalculatedAvailability - } } diff --git a/app/src/Model/Product/ProductVariantFacade.php b/app/src/Model/Product/ProductVariantFacade.php index 7a85c0cbf1..10e346f597 100644 --- a/app/src/Model/Product/ProductVariantFacade.php +++ b/app/src/Model/Product/ProductVariantFacade.php @@ -11,7 +11,7 @@ * @property \App\Model\Product\ProductFacade $productFacade * @property \App\Model\Product\ProductDataFactory $productDataFactory * @property \App\Component\Image\ImageFacade $imageFacade - * @method __construct(\Doctrine\ORM\EntityManagerInterface $em, \App\Model\Product\ProductFacade $productFacade, \App\Model\Product\ProductDataFactory $productDataFactory, \App\Component\Image\ImageFacade $imageFacade, \App\Model\Product\ProductFactory $productFactory, \Shopsys\FrameworkBundle\Model\Product\Pricing\ProductPriceRecalculationScheduler $productPriceRecalculationScheduler, \Shopsys\FrameworkBundle\Model\Product\Availability\ProductAvailabilityRecalculationScheduler $productAvailabilityRecalculationScheduler, \Shopsys\FrameworkBundle\Model\Product\Recalculation\ProductRecalculationDispatcher $productRecalculationDispatcher) + * @method __construct(\Doctrine\ORM\EntityManagerInterface $em, \App\Model\Product\ProductFacade $productFacade, \App\Model\Product\ProductDataFactory $productDataFactory, \App\Component\Image\ImageFacade $imageFacade, \App\Model\Product\ProductFactory $productFactory, \Shopsys\FrameworkBundle\Model\Product\Pricing\ProductPriceRecalculationScheduler $productPriceRecalculationScheduler, \Shopsys\FrameworkBundle\Model\Product\Recalculation\ProductRecalculationDispatcher $productRecalculationDispatcher) * @property \App\Model\Product\ProductFactory $productFactory */ class ProductVariantFacade extends BaseProductVariantFacade diff --git a/app/tests/FrontendApiBundle/Functional/Cart/AuthenticatedCartModificationsResultTest.php b/app/tests/FrontendApiBundle/Functional/Cart/AuthenticatedCartModificationsResultTest.php index 1b285f9d4a..e2991acea4 100644 --- a/app/tests/FrontendApiBundle/Functional/Cart/AuthenticatedCartModificationsResultTest.php +++ b/app/tests/FrontendApiBundle/Functional/Cart/AuthenticatedCartModificationsResultTest.php @@ -19,7 +19,6 @@ use App\Model\Transport\TransportFacade; use Shopsys\FrameworkBundle\Component\Money\Money; use Shopsys\FrameworkBundle\Model\Pricing\Group\PricingGroupFacade; -use Shopsys\FrameworkBundle\Model\Product\Availability\ProductAvailabilityRecalculationScheduler; use Shopsys\FrameworkBundle\Model\Product\Pricing\ProductPriceRecalculationScheduler; use Shopsys\FrameworkBundle\Model\Store\StoreFacade; use Tests\FrontendApiBundle\Test\GraphQlWithLoginTestCase; @@ -68,11 +67,6 @@ class AuthenticatedCartModificationsResultTest extends GraphQlWithLoginTestCase */ private ProductPriceRecalculationScheduler $productPriceRecalculationScheduler; - /** - * @inject - */ - private ProductAvailabilityRecalculationScheduler $productAvailabilityRecalculationScheduler; - protected function setUp(): void { parent::setUp(); @@ -554,7 +548,6 @@ private function setNoItemLeftOnStockForTestingProduct(): void $this->productFacade->editProductStockRelation($productData, $this->testingProduct); $this->productPriceRecalculationScheduler->reset(); - $this->productAvailabilityRecalculationScheduler->cleanScheduleForImmediateRecalculation(); $this->em->clear(); } diff --git a/app/tests/FrontendApiBundle/Functional/Cart/CartModificationsResultTest.php b/app/tests/FrontendApiBundle/Functional/Cart/CartModificationsResultTest.php index 1ce886feec..0621d5b786 100644 --- a/app/tests/FrontendApiBundle/Functional/Cart/CartModificationsResultTest.php +++ b/app/tests/FrontendApiBundle/Functional/Cart/CartModificationsResultTest.php @@ -19,7 +19,6 @@ use App\Model\Transport\TransportFacade; use Shopsys\FrameworkBundle\Component\Money\Money; use Shopsys\FrameworkBundle\Model\Pricing\Group\PricingGroupFacade; -use Shopsys\FrameworkBundle\Model\Product\Availability\ProductAvailabilityRecalculationScheduler; use Shopsys\FrameworkBundle\Model\Product\Pricing\ProductPriceRecalculationScheduler; use Shopsys\FrameworkBundle\Model\Store\StoreFacade; use Tests\FrontendApiBundle\Test\GraphQlTestCase; @@ -68,11 +67,6 @@ class CartModificationsResultTest extends GraphQlTestCase */ private ProductPriceRecalculationScheduler $productPriceRecalculationScheduler; - /** - * @inject - */ - private ProductAvailabilityRecalculationScheduler $productAvailabilityRecalculationScheduler; - protected function setUp(): void { parent::setUp(); @@ -582,7 +576,6 @@ private function setNoItemLeftOnStockForTestingProduct(): void } $this->productFacade->editProductStockRelation($productData, $this->testingProduct); $this->productPriceRecalculationScheduler->reset(); - $this->productAvailabilityRecalculationScheduler->cleanScheduleForImmediateRecalculation(); $this->em->clear(); gc_collect_cycles(); } From d0b5f651b01d190a9d13bcdcbfe626a88277d12b Mon Sep 17 00:00:00 2001 From: Martin Grossmann Date: Sun, 12 Nov 2023 20:51:03 +0100 Subject: [PATCH 15/32] product visibility is now calculated with recalculation handler - removed field calculated_visibility and recalculate_visibility --- app/config/cron.yaml | 8 - app/config/services.yaml | 6 - .../Akeneo/AkeneoImportCategoryFacade.php | 18 +- app/src/Model/Feed/FeedFacade.php | 2 +- .../Elasticsearch/ProductExportRepository.php | 10 +- app/src/Model/Product/ProductFacade.php | 5 +- app/src/Model/Product/ProductRepository.php | 1 - .../Model/Product/ProductVisibilityFacade.php | 32 -- .../Product/ProductVisibilityRepository.php | 56 ++-- .../Akeneo/AkeneoImportProductFacade.php | 27 +- .../Model/Cart/Watcher/CartWatcherTest.php | 16 +- .../Model/Product/ProductFacadeTest.php | 17 - .../ProductVisibilityRepositoryTest.php | 297 +++++------------- 13 files changed, 140 insertions(+), 355 deletions(-) delete mode 100644 app/src/Model/Product/ProductVisibilityFacade.php diff --git a/app/config/cron.yaml b/app/config/cron.yaml index bfcd5917c7..819158c8f2 100644 --- a/app/config/cron.yaml +++ b/app/config/cron.yaml @@ -77,14 +77,6 @@ services: tags: - { name: shopsys.cron, hours: '*', minutes: '*', instanceName: products, readableName: 'Recalculate product prices' } - Shopsys\FrameworkBundle\Model\Product\ProductVisibilityImmediateCronModule: - tags: - - { name: shopsys.cron, hours: '*', minutes: '*', instanceName: products, readableName: 'Recalculate immediate product visibilities' } - - Shopsys\FrameworkBundle\Model\Product\ProductVisibilityMidnightCronModule: - tags: - - { name: shopsys.cron, hours: '0', minutes: '0', instanceName: products, readableName: 'Recalculate midnight product visibilities' } - Shopsys\FrameworkBundle\Model\Product\Elasticsearch\ProductRecalculationCronModule: tags: - { name: shopsys.cron, hours: '0', minutes: '0', instanceName: products, readableName: "Dispatches all products to be recalculated and exported" } diff --git a/app/config/services.yaml b/app/config/services.yaml index eedd622407..3c131bd560 100644 --- a/app/config/services.yaml +++ b/app/config/services.yaml @@ -492,12 +492,6 @@ services: Shopsys\FrameworkBundle\Model\Product\ProductBreadcrumbGenerator: alias: App\Model\Product\ProductBreadcrumbGenerator - Shopsys\FrameworkBundle\Model\Product\ProductVisibilityFacade: - class: App\Model\Product\ProductVisibilityFacade - tags: - # must be ran after CategoryVisibilityRepository and ProductPriceRecalculator - - { name: kernel.event_listener, event: kernel.response, method: onKernelResponse, priority: 10 } - Shopsys\FrameworkBundle\Model\Product\ProductFacade: alias: App\Model\Product\ProductFacade diff --git a/app/src/Model/Category/Transfer/Akeneo/AkeneoImportCategoryFacade.php b/app/src/Model/Category/Transfer/Akeneo/AkeneoImportCategoryFacade.php index 9859368c8b..0878faaefa 100644 --- a/app/src/Model/Category/Transfer/Akeneo/AkeneoImportCategoryFacade.php +++ b/app/src/Model/Category/Transfer/Akeneo/AkeneoImportCategoryFacade.php @@ -40,18 +40,18 @@ class AkeneoImportCategoryFacade extends AbstractAkeneoImportTransfer implements * @param \App\Model\Category\Transfer\Akeneo\CategoryTransferAkeneoMapper $categoryTransferAkeneoMapper * @param \App\Model\Category\CategoryFacade $categoryFacade * @param \Shopsys\FrameworkBundle\Model\Category\CategoryVisibilityRepository $categoryVisibilityRepository - * @param \App\Model\Product\ProductVisibilityFacade $productVisibilityFacade + * @param \Shopsys\FrameworkBundle\Model\Product\ProductVisibilityFacade $productVisibilityFacade * @param \App\Model\Category\CategoryDataFactory $categoryDataFactory */ public function __construct( AkeneoImportTransferDependency $akeneoImportTransferDependency, - private CategoryTransferAkeneoFacade $categoryTransferAkeneoFacade, - private CategoryTransferAkeneoValidator $categoryTransferAkeneoValidator, - private CategoryTransferAkeneoMapper $categoryTransferAkeneoMapper, - private CategoryFacade $categoryFacade, - private CategoryVisibilityRepository $categoryVisibilityRepository, - private ProductVisibilityFacade $productVisibilityFacade, - private CategoryDataFactory $categoryDataFactory, + private readonly CategoryTransferAkeneoFacade $categoryTransferAkeneoFacade, + private readonly CategoryTransferAkeneoValidator $categoryTransferAkeneoValidator, + private readonly CategoryTransferAkeneoMapper $categoryTransferAkeneoMapper, + private readonly CategoryFacade $categoryFacade, + private readonly CategoryVisibilityRepository $categoryVisibilityRepository, + private readonly ProductVisibilityFacade $productVisibilityFacade, + private readonly CategoryDataFactory $categoryDataFactory, ) { parent::__construct($akeneoImportTransferDependency); } @@ -110,7 +110,7 @@ protected function doAfterTransfer(): void $this->logger->info('Refreshing categories and products visibility...'); $this->categoryVisibilityRepository->refreshCategoriesVisibility(); - $this->productVisibilityFacade->refreshProductsVisibility(); + $this->productVisibilityFacade->calculateProductVisibilityForAll(); $this->logger->info('Transfer is done.'); } diff --git a/app/src/Model/Feed/FeedFacade.php b/app/src/Model/Feed/FeedFacade.php index 4627ee7eb8..1ce0b87545 100644 --- a/app/src/Model/Feed/FeedFacade.php +++ b/app/src/Model/Feed/FeedFacade.php @@ -10,7 +10,7 @@ /** * @property \App\Model\Feed\FeedExportFactory $feedExportFactory - * @method __construct(\Shopsys\FrameworkBundle\Model\Feed\FeedRegistry $feedRegistry, \App\Model\Product\ProductVisibilityFacade $productVisibilityFacade, \App\Model\Feed\FeedExportFactory $feedExportFactory, \Shopsys\FrameworkBundle\Model\Feed\FeedPathProvider $feedPathProvider, \League\Flysystem\FilesystemOperator $filesystem, \Shopsys\FrameworkBundle\Model\Feed\FeedModuleRepository $feedModuleRepository, \Doctrine\ORM\EntityManagerInterface $em) + * @method __construct(\Shopsys\FrameworkBundle\Model\Feed\FeedRegistry $feedRegistry, \App\Model\Feed\FeedExportFactory $feedExportFactory, \Shopsys\FrameworkBundle\Model\Feed\FeedPathProvider $feedPathProvider, \League\Flysystem\FilesystemOperator $filesystem, \Shopsys\FrameworkBundle\Model\Feed\FeedModuleRepository $feedModuleRepository, \Doctrine\ORM\EntityManagerInterface $em) * @property \App\Model\Product\ProductVisibilityFacade $productVisibilityFacade */ class FeedFacade extends BaseFeedFacade diff --git a/app/src/Model/Product/Elasticsearch/ProductExportRepository.php b/app/src/Model/Product/Elasticsearch/ProductExportRepository.php index dd0d95491f..1c31193f49 100644 --- a/app/src/Model/Product/Elasticsearch/ProductExportRepository.php +++ b/app/src/Model/Product/Elasticsearch/ProductExportRepository.php @@ -26,7 +26,7 @@ use Shopsys\FrameworkBundle\Model\Product\Pricing\ProductPriceCalculation; use Shopsys\FrameworkBundle\Model\Product\Product as BaseProduct; use Shopsys\FrameworkBundle\Model\Product\ProductFacade; -use Shopsys\FrameworkBundle\Model\Product\ProductVisibilityRepository; +use Shopsys\FrameworkBundle\Model\Product\ProductVisibilityFacade; /** * @property \App\Model\Product\ProductFacade $productFacade @@ -36,7 +36,7 @@ * @method int[] extractCategories(int $domainId, \App\Model\Product\Product $product) * @method array extractVisibility(int $domainId, \App\Model\Product\Product $product) * @property \App\Model\Product\Parameter\ParameterRepository $parameterRepository - * @property \App\Model\Product\ProductVisibilityRepository $productVisibilityRepository + * @property \App\Model\Product\ProductVisibilityRepository $productVisibilityFacade * @property \App\Component\Router\FriendlyUrl\FriendlyUrlRepository $friendlyUrlRepository * @method array extractParameters(string $locale, \App\Model\Product\Product $product) * @property \App\Model\Category\CategoryFacade $categoryFacade @@ -57,7 +57,7 @@ class ProductExportRepository extends BaseProductExportRepository * @param \App\Model\Product\Parameter\ParameterRepository $parameterRepository * @param \App\Model\Product\ProductFacade $productFacade * @param \App\Component\Router\FriendlyUrl\FriendlyUrlRepository $friendlyUrlRepository - * @param \App\Model\Product\ProductVisibilityRepository $productVisibilityRepository + * @param \Shopsys\FrameworkBundle\Model\Product\ProductVisibilityFacade $productVisibilityFacade * @param \App\Component\Router\FriendlyUrl\FriendlyUrlFacade $friendlyUrlFacade * @param \App\Model\Category\CategoryFacade $categoryFacade * @param \Shopsys\FrameworkBundle\Model\Product\Accessory\ProductAccessoryFacade $productAccessoryFacade @@ -74,7 +74,7 @@ public function __construct( ParameterRepository $parameterRepository, ProductFacade $productFacade, FriendlyUrlRepository $friendlyUrlRepository, - ProductVisibilityRepository $productVisibilityRepository, + ProductVisibilityFacade $productVisibilityFacade, FriendlyUrlFacade $friendlyUrlFacade, CategoryFacade $categoryFacade, ProductAccessoryFacade $productAccessoryFacade, @@ -91,7 +91,7 @@ public function __construct( $parameterRepository, $productFacade, $friendlyUrlRepository, - $productVisibilityRepository, + $productVisibilityFacade, $friendlyUrlFacade, $categoryFacade, $productAccessoryFacade, diff --git a/app/src/Model/Product/ProductFacade.php b/app/src/Model/Product/ProductFacade.php index da6f859d20..88ccddf9ce 100644 --- a/app/src/Model/Product/ProductFacade.php +++ b/app/src/Model/Product/ProductFacade.php @@ -51,7 +51,6 @@ * @method \App\Model\Product\Product getByUuid(string $uuid) * @method createFriendlyUrlsWhenRenamed(\App\Model\Product\Product $product, array $originalNames) * @method array getChangedNamesByLocale(\App\Model\Product\Product $product, array $originalNames) - * @property \App\Model\Product\ProductVisibilityFacade $productVisibilityFacade * @property \App\Model\Product\ProductFactory $productFactory */ class ProductFacade extends BaseProductFacade @@ -59,7 +58,7 @@ class ProductFacade extends BaseProductFacade /** * @param \Shopsys\FrameworkBundle\Component\EntityExtension\EntityManagerDecorator $em * @param \App\Model\Product\ProductRepository $productRepository - * @param \App\Model\Product\ProductVisibilityFacade $productVisibilityFacade + * @param \Shopsys\FrameworkBundle\Model\Product\ProductVisibilityFacade $productVisibilityFacade * @param \App\Model\Product\Parameter\ParameterRepository $parameterRepository * @param \Shopsys\FrameworkBundle\Component\Domain\Domain $domain * @param \App\Component\Image\ImageFacade $imageFacade @@ -194,7 +193,6 @@ public function edit($productId, ProductData $productData) $this->pluginCrudExtensionFacade->saveAllData('product', $product->getId(), $productData->pluginData); - $this->productVisibilityFacade->refreshProductsVisibilityForMarkedDelayed(); $this->productPriceRecalculationScheduler->scheduleProductForImmediateRecalculation($product); // @todo after handling variants this may be simplified or edit may be moved to framework @@ -239,7 +237,6 @@ public function setAdditionalDataAfterCreate(BaseProduct $product, ProductData $ $this->friendlyUrlFacade->saveUrlListFormData('front_product_detail', $product->getId(), $productData->urls); $this->friendlyUrlFacade->createFriendlyUrls('front_product_detail', $product->getId(), $product->getNames()); - $this->productVisibilityFacade->refreshProductsVisibilityForMarkedDelayed(); $this->productPriceRecalculationScheduler->scheduleProductForImmediateRecalculation($product); } diff --git a/app/src/Model/Product/ProductRepository.php b/app/src/Model/Product/ProductRepository.php index b0b6d573c5..72a59b722a 100644 --- a/app/src/Model/Product/ProductRepository.php +++ b/app/src/Model/Product/ProductRepository.php @@ -30,7 +30,6 @@ * @method \App\Model\Product\Product getSellableById(int $id, int $domainId, \Shopsys\FrameworkBundle\Model\Pricing\Group\PricingGroup $pricingGroup) * @method \Doctrine\ORM\Internal\Hydration\IterableResult|\App\Model\Product\Product[][] getProductsForPriceRecalculationIterator() * @method \Doctrine\ORM\Internal\Hydration\IterableResult|\App\Model\Product\Product[][] getProductsForAvailabilityRecalculationIterator() - * @method \App\Model\Product\Product[] getAtLeastSomewhereSellableVariantsByMainVariant(\App\Model\Product\Product $mainVariant) * @method \App\Model\Product\Product[] getOfferedByIds(int $domainId, \Shopsys\FrameworkBundle\Model\Pricing\Group\PricingGroup $pricingGroup, int[] $sortedProductIds) * @method \App\Model\Product\Product[] getListableByIds(int $domainId, \Shopsys\FrameworkBundle\Model\Pricing\Group\PricingGroup $pricingGroup, int[] $sortedProductIds) * @method \App\Model\Product\Product getOneByCatnumExcludeMainVariants(string $productCatnum) diff --git a/app/src/Model/Product/ProductVisibilityFacade.php b/app/src/Model/Product/ProductVisibilityFacade.php deleted file mode 100644 index 6518a320a2..0000000000 --- a/app/src/Model/Product/ProductVisibilityFacade.php +++ /dev/null @@ -1,32 +0,0 @@ -isMainRequest()) { - return; - } - - $routeName = $event->getRequest()->attributes->get('_route'); - - if ($routeName !== null && strpos($routeName, 'admin_') === 0) { - parent::onKernelResponse($event); - } - } -} diff --git a/app/src/Model/Product/ProductVisibilityRepository.php b/app/src/Model/Product/ProductVisibilityRepository.php index ad51772b48..bd380fa520 100644 --- a/app/src/Model/Product/ProductVisibilityRepository.php +++ b/app/src/Model/Product/ProductVisibilityRepository.php @@ -4,7 +4,8 @@ namespace App\Model\Product; -use DateTimeImmutable; +use DateTime; +use Doctrine\DBAL\ArrayParameterType; use Doctrine\DBAL\Types\Types; use Shopsys\FrameworkBundle\Model\Product\Product; use Shopsys\FrameworkBundle\Model\Product\ProductVisibilityRepository as BaseProductVisibilityRepository; @@ -19,16 +20,32 @@ class ProductVisibilityRepository extends BaseProductVisibilityRepository { /** - * @param bool $onlyMarkedProducts + * @param array|null $productIds */ - protected function calculateIndependentVisibility($onlyMarkedProducts) + protected function calculateIndependentVisibility(?array $productIds): void { - $now = new DateTimeImmutable(); + $variables = [ + 'now' => new DateTime(), + 'locale' => null, + 'domainId' => null, + 'pricingGroupId' => null, + 'variantTypeMain' => Product::VARIANT_TYPE_MAIN, + ]; - if ($onlyMarkedProducts) { - $onlyMarkedProductsCondition = ' AND p.recalculate_visibility = TRUE'; + $variableTypes = [ + 'now' => Types::DATETIME_MUTABLE, + 'locale' => Types::STRING, + 'domainId' => Types::INTEGER, + 'pricingGroupId' => Types::INTEGER, + 'variantTypeMain' => Types::STRING, + ]; + + if ($productIds !== null) { + $productIdsCondition = 'p.id IN (:productIds) AND'; + $variables['productIds'] = $productIds; + $variableTypes['productIds'] = ArrayParameterType::INTEGER; } else { - $onlyMarkedProductsCondition = ''; + $productIdsCondition = ''; } $query = 'UPDATE product_visibilities AS pv @@ -75,30 +92,23 @@ protected function calculateIndependentVisibility($onlyMarkedProducts) END FROM products AS p JOIN product_domains AS pd ON pd.product_id = p.id - WHERE p.id = pv.product_id + WHERE ' . $productIdsCondition . ' + p.id = pv.product_id AND pv.domain_id = :domainId AND pv.domain_id = pd.domain_id AND pv.pricing_group_id = :pricingGroupId - ' . $onlyMarkedProductsCondition; + '; foreach ($this->pricingGroupRepository->getAll() as $pricingGroup) { $domain = $this->domain->getDomainConfigById($pricingGroup->getDomainId()); + $variables['locale'] = $domain->getLocale(); + $variables['domainId'] = $domain->getId(); + $variables['pricingGroupId'] = $pricingGroup->getId(); + $this->em->getConnection()->executeStatement( $query, - [ - 'now' => $now, - 'locale' => $domain->getLocale(), - 'domainId' => $domain->getId(), - 'pricingGroupId' => $pricingGroup->getId(), - 'variantTypeMain' => Product::VARIANT_TYPE_MAIN, - ], - [ - 'now' => Types::DATETIME_IMMUTABLE, - 'locale' => Types::STRING, - 'domainId' => Types::INTEGER, - 'pricingGroupId' => Types::INTEGER, - 'variantTypeMain' => Types::STRING, - ], + $variables, + $variableTypes, ); } } diff --git a/app/src/Model/Product/Transfer/Akeneo/AkeneoImportProductFacade.php b/app/src/Model/Product/Transfer/Akeneo/AkeneoImportProductFacade.php index fd9ea954ab..593f90fc89 100644 --- a/app/src/Model/Product/Transfer/Akeneo/AkeneoImportProductFacade.php +++ b/app/src/Model/Product/Transfer/Akeneo/AkeneoImportProductFacade.php @@ -9,10 +9,9 @@ use App\Component\Setting\Setting; use App\Model\Product\Parameter\Transfer\Akeneo\AkeneoImportProductGroupParameterFacade; use App\Model\Product\Parameter\Transfer\Akeneo\AkeneoImportProductParameterFacade; -use App\Model\Product\ProductFacade; use DateTime; use Generator; -use Shopsys\FrameworkBundle\Model\Product\ProductVisibilityFacade; +use Shopsys\FrameworkBundle\Model\Product\Recalculation\ProductRecalculationDispatcher; class AkeneoImportProductFacade extends AbstractAkeneoImportTransfer { @@ -26,28 +25,22 @@ class AkeneoImportProductFacade extends AbstractAkeneoImportTransfer /** * @param \App\Component\Akeneo\Transfer\AkeneoImportTransferDependency $akeneoImportTransferDependency * @param \App\Model\Product\Transfer\Akeneo\ProductTransferAkeneoFacade $productTransferAkeneoFacade - * @param \App\Model\Product\Transfer\Akeneo\ProductTransferAkeneoValidator $productTransferAkeneoValidator - * @param \App\Model\Product\Transfer\Akeneo\ProductTransferAkeneoMapper $productTransferAkeneoMapper - * @param \App\Model\Product\ProductFacade $productFacade - * @param \App\Model\Product\ProductVisibilityFacade $productVisibilityFacade * @param \App\Component\Setting\Setting $setting * @param \App\Model\Product\Parameter\Transfer\Akeneo\AkeneoImportProductParameterFacade $akeneoImportProductParameterFacade * @param \App\Model\Product\Parameter\Transfer\Akeneo\AkeneoImportProductGroupParameterFacade $akeneoImportProductGroupParameterFacade * @param \App\Model\Product\Transfer\Akeneo\TransferredProductProcessor $transferredProductProcessor * @param \App\Model\Product\Transfer\Akeneo\AkeneoImportProductDetailFacade $akeneoImportProductDetailFacade + * @param \Shopsys\FrameworkBundle\Model\Product\Recalculation\ProductRecalculationDispatcher $productRecalculationDispatcher */ public function __construct( AkeneoImportTransferDependency $akeneoImportTransferDependency, - protected ProductTransferAkeneoFacade $productTransferAkeneoFacade, - protected ProductTransferAkeneoValidator $productTransferAkeneoValidator, - protected ProductTransferAkeneoMapper $productTransferAkeneoMapper, - protected ProductFacade $productFacade, - private ProductVisibilityFacade $productVisibilityFacade, - protected Setting $setting, - private AkeneoImportProductParameterFacade $akeneoImportProductParameterFacade, - private AkeneoImportProductGroupParameterFacade $akeneoImportProductGroupParameterFacade, - private TransferredProductProcessor $transferredProductProcessor, - private AkeneoImportProductDetailFacade $akeneoImportProductDetailFacade, + private readonly ProductTransferAkeneoFacade $productTransferAkeneoFacade, + private readonly Setting $setting, + private readonly AkeneoImportProductParameterFacade $akeneoImportProductParameterFacade, + private readonly AkeneoImportProductGroupParameterFacade $akeneoImportProductGroupParameterFacade, + private readonly TransferredProductProcessor $transferredProductProcessor, + private readonly AkeneoImportProductDetailFacade $akeneoImportProductDetailFacade, + private readonly ProductRecalculationDispatcher $productRecalculationDispatcher, ) { parent::__construct($akeneoImportTransferDependency); @@ -101,6 +94,7 @@ protected function processItem($akeneoProductData): void $product = $this->transferredProductProcessor->processProduct($akeneoProductData, $this->logger); $this->processedProductIdentifierList[] = $product->getCatnum(); $this->setLastUpdatedProduct($akeneoProductData['updated']); + $this->productRecalculationDispatcher->dispatchSingleProductId($product->getId()); } protected function doAfterTransfer(): void @@ -108,7 +102,6 @@ protected function doAfterTransfer(): void $this->downloadProductDetails(); $this->setting->set(Setting::AKENEO_TRANSFER_PRODUCTS_LAST_UPDATED_DATETIME, $this->lastProductUpdatedAtFromAkeneo); $this->logger->info('Transfer is done.'); - $this->productVisibilityFacade->refreshProductsVisibilityForMarked(); } private function downloadProductDetails(): void diff --git a/app/tests/App/Functional/Model/Cart/Watcher/CartWatcherTest.php b/app/tests/App/Functional/Model/Cart/Watcher/CartWatcherTest.php index a9d47b4251..2bc066bd5d 100644 --- a/app/tests/App/Functional/Model/Cart/Watcher/CartWatcherTest.php +++ b/app/tests/App/Functional/Model/Cart/Watcher/CartWatcherTest.php @@ -22,7 +22,7 @@ use Shopsys\FrameworkBundle\Model\Product\Pricing\ProductPriceCalculationForCustomerUser; use Shopsys\FrameworkBundle\Model\Product\ProductDataFactoryInterface; use Shopsys\FrameworkBundle\Model\Product\ProductVisibility; -use Shopsys\FrameworkBundle\Model\Product\ProductVisibilityRepository; +use Shopsys\FrameworkBundle\Model\Product\ProductVisibilityFacade; use Tests\App\Test\TransactionFunctionalTestCase; class CartWatcherTest extends TransactionFunctionalTestCase @@ -118,11 +118,11 @@ public function testGetNotListableItemsWithVisibleButNotSellableProduct() $currentCustomerUserMock = $this->createCustomerUserMock(); - $productVisibilityRepositoryMock = $this->createProductVisibilityRepositoryMock(); + $productVisibilityFacadeMock = $this->createProductVisibilityFacadeMock(); $cartWatcher = new CartWatcher( $this->productPriceCalculationForCustomerUser, - $productVisibilityRepositoryMock, + $productVisibilityFacadeMock, $this->domain, ); @@ -191,9 +191,9 @@ public function createCustomerUserMock(): CurrentCustomerUser|MockObject } /** - * @return \PHPUnit\Framework\MockObject\MockObject|(\Shopsys\FrameworkBundle\Model\Product\ProductVisibilityRepository&\PHPUnit\Framework\MockObject\MockObject) + * @return \Shopsys\FrameworkBundle\Model\Product\ProductVisibilityFacade */ - public function createProductVisibilityRepositoryMock(): ProductVisibilityRepository|MockObject + public function createProductVisibilityFacadeMock(): ProductVisibilityFacade { $productVisibilityMock = $this->getMockBuilder(ProductVisibility::class) ->disableOriginalConstructor() @@ -205,16 +205,16 @@ public function createProductVisibilityRepositoryMock(): ProductVisibilityReposi ->method('isVisible') ->willReturn(true); - $productVisibilityRepositoryMock = $this->getMockBuilder(ProductVisibilityRepository::class) + $productVisibilityFacadeMock = $this->getMockBuilder(ProductVisibilityFacade::class) ->disableOriginalConstructor() ->setMethods(['getProductVisibility']) ->getMock(); - $productVisibilityRepositoryMock + $productVisibilityFacadeMock ->expects($this->any()) ->method('getProductVisibility') ->willReturn($productVisibilityMock); - return $productVisibilityRepositoryMock; + return $productVisibilityFacadeMock; } } diff --git a/app/tests/App/Functional/Model/Product/ProductFacadeTest.php b/app/tests/App/Functional/Model/Product/ProductFacadeTest.php index b4e8c932c9..6b36e63f76 100644 --- a/app/tests/App/Functional/Model/Product/ProductFacadeTest.php +++ b/app/tests/App/Functional/Model/Product/ProductFacadeTest.php @@ -8,10 +8,8 @@ use App\DataFixtures\Demo\ProductDataFixture; use App\DataFixtures\Demo\StocksDataFixture; use App\DataFixtures\Demo\UnitDataFixture; -use App\Model\Product\Product; use App\Model\Product\ProductData; use App\Model\Product\ProductDataFactory; -use ReflectionClass; use Shopsys\FrameworkBundle\Model\Pricing\Vat\VatFacade; use Shopsys\FrameworkBundle\Model\Product\Pricing\ProductPriceRecalculationScheduler; use Shopsys\FrameworkBundle\Model\Product\ProductFacade; @@ -114,21 +112,6 @@ public function getTestCalculationHiddenAndSellingDeniedDataProvider() ]; } - public function testEditMarkProductForVisibilityRecalculation() - { - /** @var \App\Model\Product\Product $product */ - $product = $this->getReference(ProductDataFixture::PRODUCT_PREFIX . '1'); - - $reflectionClass = new ReflectionClass(Product::class); - $reflectionPropertyRecalculateVisibility = $reflectionClass->getProperty('recalculateVisibility'); - $reflectionPropertyRecalculateVisibility->setAccessible(true); - $reflectionPropertyRecalculateVisibility->setValue($product, false); - - $this->productFacade->edit($product->getId(), $this->productDataFactory->createFromProduct($product)); - - $this->assertSame(true, $reflectionPropertyRecalculateVisibility->getValue($product)); - } - public function testEditSchedulesPriceRecalculation() { /** @var \App\Model\Product\Product $product */ diff --git a/app/tests/App/Functional/Model/Product/ProductVisibilityRepositoryTest.php b/app/tests/App/Functional/Model/Product/ProductVisibilityRepositoryTest.php index 4d2f991e84..712ca1ea1a 100644 --- a/app/tests/App/Functional/Model/Product/ProductVisibilityRepositoryTest.php +++ b/app/tests/App/Functional/Model/Product/ProductVisibilityRepositoryTest.php @@ -132,10 +132,12 @@ private function setPriceForAllDomains(ProductData $productData, ?Money $price) $productData->manualInputPricesByPricingGroupId = $manualInputPrices; } - public function testIsVisibleOnAnyDomainWhenHidden() + /** + * @param \App\Model\Product\ProductData $productData + * @return \Shopsys\FrameworkBundle\Model\Product\ProductVisibility + */ + private function createProductAndGetVisibility(ProductData $productData): ProductVisibility { - $productData = $this->getDefaultProductData(); - $productData->hidden = true; $product = $this->productFacade->create($productData); $this->productPriceRecalculator->runImmediateRecalculations(); @@ -149,132 +151,82 @@ public function testIsVisibleOnAnyDomainWhenHidden() /** @var \App\Model\Product\Product $productAgain */ $productAgain = $this->em->getRepository(Product::class)->find($id); + return $this->getVisibilityForProduct($productAgain); + } + + /** + * @param \App\Model\Product\Product $productAgain + * @return \Shopsys\FrameworkBundle\Model\Product\ProductVisibility + */ + private function getVisibilityForProduct(Product $productAgain): ProductVisibility + { /** @var \Shopsys\FrameworkBundle\Model\Pricing\Group\PricingGroup $pricingGroup */ $pricingGroup = $this->getReferenceForDomain( PricingGroupDataFixture::PRICING_GROUP_ORDINARY, Domain::FIRST_DOMAIN_ID, ); - /** @var \Shopsys\FrameworkBundle\Model\Product\ProductVisibility $productVisibility1 */ - $productVisibility1 = $this->em->getRepository(ProductVisibility::class)->findOneBy([ + return $this->em->getRepository(ProductVisibility::class)->findOneBy([ 'product' => $productAgain, 'pricingGroup' => $pricingGroup->getId(), 'domainId' => Domain::FIRST_DOMAIN_ID, ]); - - $this->assertFalse($productAgain->isVisible()); - $this->assertFalse($productVisibility1->isVisible()); } - public function testIsVisibleOnFirstDomainWhenHidden() + public function testIsVisibleOnAnyDomainWhenHidden(): void { $productData = $this->getDefaultProductData(); - $productData->hidden = false; - $productData->domainHidden[Domain::FIRST_DOMAIN_ID] = true; - $product = $this->productFacade->create($productData); - $this->productPriceRecalculator->runImmediateRecalculations(); - - $this->em->flush(); - $id = $product->getId(); - $this->createImage('product', $id); - $this->em->clear(); - - $this->productVisibilityRepository->refreshProductsVisibility(); - - /** @var \App\Model\Product\Product $productAgain */ - $productAgain = $this->em->getRepository(Product::class)->find($id); - - /** @var \Shopsys\FrameworkBundle\Model\Pricing\Group\PricingGroup $pricingGroup */ - $pricingGroup = $this->getReferenceForDomain(PricingGroupDataFixture::PRICING_GROUP_ORDINARY, Domain::FIRST_DOMAIN_ID); + $productData->hidden = true; - /** @var \Shopsys\FrameworkBundle\Model\Product\ProductVisibility $productVisibility1 */ - $productVisibility1 = $this->em->getRepository(ProductVisibility::class)->findOneBy([ - 'product' => $productAgain, - 'pricingGroup' => $pricingGroup->getId(), - 'domainId' => Domain::FIRST_DOMAIN_ID, - ]); + $productVisibility = $this->createProductAndGetVisibility($productData); - $this->assertFalse($productAgain->isVisible()); - $this->assertFalse($productVisibility1->isVisible()); + $this->assertFalse($productVisibility->isVisible()); } - public function testIsVisibleOnAnyDomainWhenNotHidden() + public function testIsVisibleOnFirstDomainWhenHidden(): void { $productData = $this->getDefaultProductData(); - $product = $this->productFacade->create($productData); - $this->productPriceRecalculator->runImmediateRecalculations(); - - $this->em->flush(); - $id = $product->getId(); - $this->createImage('product', $id); - $this->em->clear(); + $productData->hidden = false; + $productData->domainHidden[Domain::FIRST_DOMAIN_ID] = true; - $this->productVisibilityRepository->refreshProductsVisibility(); + $productVisibility = $this->createProductAndGetVisibility($productData); - /** @var \App\Model\Product\Product $productAgain */ - $productAgain = $this->em->getRepository(Product::class)->find($id); + $this->assertFalse($productVisibility->isVisible()); + } - /** @var \Shopsys\FrameworkBundle\Model\Pricing\Group\PricingGroup $pricingGroup */ - $pricingGroup = $this->getReferenceForDomain( - PricingGroupDataFixture::PRICING_GROUP_ORDINARY, - Domain::FIRST_DOMAIN_ID, - ); + public function testIsVisibleOnAnyDomainWhenNotHidden(): void + { + $productData = $this->getDefaultProductData(); - /** @var \Shopsys\FrameworkBundle\Model\Product\ProductVisibility $productVisibility1 */ - $productVisibility1 = $this->em->getRepository(ProductVisibility::class)->findOneBy([ - 'product' => $productAgain->getId(), - 'pricingGroup' => $pricingGroup->getId(), - 'domainId' => Domain::FIRST_DOMAIN_ID, - ]); + $productVisibility = $this->createProductAndGetVisibility($productData); - $this->assertTrue($productAgain->isVisible()); - $this->assertTrue($productVisibility1->isVisible()); + $this->assertTrue($productVisibility->isVisible()); } - public function testIsVisibleOnAnyDomainWhenSellingInFuture() + public function testIsVisibleOnAnyDomainWhenSellingInFuture(): void { $sellingFrom = new DateTime('now'); $sellingFrom->modify('+1 day'); $productData = $this->getDefaultProductData(); $productData->sellingFrom = $sellingFrom; - $product = $this->productFacade->create($productData); - $this->productPriceRecalculator->runImmediateRecalculations(); - $this->em->flush(); - $id = $product->getId(); - $this->createImage('product', $id); - $this->em->clear(); - - $this->productVisibilityRepository->refreshProductsVisibility(); + $productVisibility = $this->createProductAndGetVisibility($productData); - /** @var \App\Model\Product\Product $productAgain */ - $productAgain = $this->em->getRepository(Product::class)->find($id); - - $this->assertFalse($productAgain->isVisible()); + $this->assertFalse($productVisibility->isVisible()); } - public function testIsVisibleOnAnyDomainWhenSellingInPast() + public function testIsVisibleOnAnyDomainWhenSellingInPast(): void { $sellingTo = new DateTime('now'); $sellingTo->modify('-1 day'); $productData = $this->getDefaultProductData(); $productData->sellingTo = $sellingTo; - $product = $this->productFacade->create($productData); - $this->productPriceRecalculator->runImmediateRecalculations(); - - $this->em->flush(); - $id = $product->getId(); - $this->createImage('product', $id); - $this->em->clear(); - $this->productVisibilityRepository->refreshProductsVisibility(); - - /** @var \App\Model\Product\Product $productAgain */ - $productAgain = $this->em->getRepository(Product::class)->find($id); + $productVisibility = $this->createProductAndGetVisibility($productData); - $this->assertFalse($productAgain->isVisible()); + $this->assertFalse($productVisibility->isVisible()); } /** @@ -296,7 +248,7 @@ private function createImage(string $entityName, int $entityId): void $this->em->flush(); } - public function testIsVisibleOnAnyDomainWhenSellingNow() + public function testIsVisibleOnAnyDomainWhenSellingNow(): void { $sellingFrom = new DateTime('now'); $sellingFrom->modify('-1 day'); @@ -306,152 +258,65 @@ public function testIsVisibleOnAnyDomainWhenSellingNow() $productData = $this->getDefaultProductData(); $productData->sellingFrom = $sellingFrom; $productData->sellingTo = $sellingTo; - $product = $this->productFacade->create($productData); - $this->productPriceRecalculator->runImmediateRecalculations(); - - $this->em->flush(); - $id = $product->getId(); - $this->createImage('product', $id); - $this->em->clear(); - - $this->productVisibilityRepository->refreshProductsVisibility(); - /** @var \App\Model\Product\Product $productAgain */ - $productAgain = $this->em->getRepository(Product::class)->find($id); + $productVisibility = $this->createProductAndGetVisibility($productData); - $this->assertTrue($productAgain->isVisible()); + $this->assertTrue($productVisibility->isVisible()); } - public function testIsNotVisibleWhenZeroPrice() + public function testIsNotVisibleWhenZeroPrice(): void { $productData = $this->getDefaultProductData(); $this->setPriceForAllDomains($productData, Money::zero()); - $product1 = $this->productFacade->create($productData); - - $this->productPriceRecalculator->runImmediateRecalculations(); - - $product1Id = $product1->getId(); - $this->createImage('product', $product1Id); - $this->em->clear(); - - $this->productVisibilityRepository->refreshProductsVisibility(); - /** @var \App\Model\Product\Product $product1Again */ - $product1Again = $this->em->getRepository(Product::class)->find($product1Id); + $productVisibility = $this->createProductAndGetVisibility($productData); - $this->assertFalse($product1Again->isVisible()); + $this->assertFalse($productVisibility->isVisible()); } - public function testIsVisibleWithFilledName() + public function testIsVisibleWithFilledName(): void { $productData = $this->getDefaultProductData(); - $product = $this->productFacade->create($productData); - $this->productPriceRecalculator->runImmediateRecalculations(); - $this->createImage('product', $product->getId()); - $this->em->clear(); - - $this->productVisibilityRepository->refreshProductsVisibility(); - - /** @var \Shopsys\FrameworkBundle\Model\Pricing\Group\PricingGroup $pricingGroup */ - $pricingGroup = $this->getReferenceForDomain( - PricingGroupDataFixture::PRICING_GROUP_ORDINARY, - Domain::FIRST_DOMAIN_ID, - ); - /** @var \Shopsys\FrameworkBundle\Model\Product\ProductVisibility $productVisibility */ - $productVisibility = $this->em->getRepository(ProductVisibility::class)->findOneBy([ - 'product' => $product, - 'pricingGroup' => $pricingGroup->getId(), - 'domainId' => Domain::FIRST_DOMAIN_ID, - ]); + $productVisibility = $this->createProductAndGetVisibility($productData); $this->assertTrue($productVisibility->isVisible()); } - public function testIsNotVisibleWithEmptyName() + public function testIsNotVisibleWithEmptyName(): void { $productData = $this->getDefaultProductData(); $productData->name = ['cs' => null, 'en' => null]; - $product = $this->productFacade->create($productData); - $this->productPriceRecalculator->runImmediateRecalculations(); - $this->createImage('product', $product->getId()); - $this->em->clear(); - - $this->productVisibilityRepository->refreshProductsVisibility(); - /** @var \Shopsys\FrameworkBundle\Model\Pricing\Group\PricingGroup $pricingGroup */ - $pricingGroup = $this->getReferenceForDomain( - PricingGroupDataFixture::PRICING_GROUP_ORDINARY, - Domain::FIRST_DOMAIN_ID, - ); - - /** @var \Shopsys\FrameworkBundle\Model\Product\ProductVisibility $productVisibility */ - $productVisibility = $this->em->getRepository(ProductVisibility::class)->findOneBy([ - 'product' => $product, - 'pricingGroup' => $pricingGroup->getId(), - 'domainId' => Domain::FIRST_DOMAIN_ID, - ]); + $productVisibility = $this->createProductAndGetVisibility($productData); $this->assertFalse($productVisibility->isVisible()); } - public function testIsVisibleInVisibileCategory() + public function testIsVisibleInVisibileCategory(): void { /** @var \App\Model\Category\Category $category */ $category = $this->getReference(CategoryDataFixture::CATEGORY_TOYS); $productData = $this->getDefaultProductData(); $productData->categoriesByDomainId = [Domain::FIRST_DOMAIN_ID => [$category]]; - $product = $this->productFacade->create($productData); - $this->productPriceRecalculator->runImmediateRecalculations(); - $this->createImage('product', $product->getId()); - $this->em->clear(); - - $this->productVisibilityRepository->refreshProductsVisibility(); - - /** @var \Shopsys\FrameworkBundle\Model\Pricing\Group\PricingGroup $pricingGroup */ - $pricingGroup = $this->getReferenceForDomain( - PricingGroupDataFixture::PRICING_GROUP_ORDINARY, - Domain::FIRST_DOMAIN_ID, - ); - /** @var \Shopsys\FrameworkBundle\Model\Product\ProductVisibility $productVisibility */ - $productVisibility = $this->em->getRepository(ProductVisibility::class)->findOneBy([ - 'product' => $product, - 'pricingGroup' => $pricingGroup->getId(), - 'domainId' => Domain::FIRST_DOMAIN_ID, - ]); + $productVisibility = $this->createProductAndGetVisibility($productData); $this->assertTrue($productVisibility->isVisible()); } - public function testIsNotVisibleInHiddenCategory() + public function testIsNotVisibleInHiddenCategory(): void { $productData = $this->getDefaultProductData(); $productData->categoriesByDomainId = []; - $product = $this->productFacade->create($productData); - $this->productPriceRecalculator->runImmediateRecalculations(); - $this->createImage('product', $product->getId()); - $this->em->clear(); - - $this->productVisibilityRepository->refreshProductsVisibility(); - - /** @var \Shopsys\FrameworkBundle\Model\Pricing\Group\PricingGroup $pricingGroup */ - $pricingGroup = $this->getReferenceForDomain( - PricingGroupDataFixture::PRICING_GROUP_ORDINARY, - Domain::FIRST_DOMAIN_ID, - ); - $productVisibility = $this->em->getRepository(ProductVisibility::class)->findOneBy([ - 'product' => $product, - 'pricingGroup' => $pricingGroup->getId(), - 'domainId' => Domain::FIRST_DOMAIN_ID, - ]); + $productVisibility = $this->createProductAndGetVisibility($productData); $this->assertFalse($productVisibility->isVisible()); } - public function testRefreshProductsVisibilityVisibleVariants() + public function testRefreshProductsVisibilityVisibleVariants(): void { /** @var \App\Model\Product\Product $variant1 */ $variant1 = $this->getReference(ProductDataFixture::PRODUCT_PREFIX . '53'); @@ -464,18 +329,14 @@ public function testRefreshProductsVisibilityVisibleVariants() $variant1productData->hidden = true; $this->productFacade->edit($variant1->getId(), $variant1productData); - $this->productVisibilityRepository->refreshProductsVisibility(true); - - $this->em->refresh($variant1); - $this->em->refresh($variant2); - $this->em->refresh($mainVariant); + $this->productVisibilityRepository->refreshProductsVisibility([53, 54, 69]); - $this->assertFalse($variant1->isVisible()); - $this->assertTrue($variant2->isVisible()); - $this->assertTrue($mainVariant->isVisible()); + $this->assertFalse($this->getVisibilityForProduct($variant1)->isVisible()); + $this->assertTrue($this->getVisibilityForProduct($variant2)->isVisible()); + $this->assertTrue($this->getVisibilityForProduct($mainVariant)->isVisible()); } - public function testRefreshProductsVisibilityNotVisibleVariants() + public function testRefreshProductsVisibilityNotVisibleVariants(): void { /** @var \App\Model\Product\Product $variant1 */ $variant1 = $this->getReference(ProductDataFixture::PRODUCT_PREFIX . '53'); @@ -516,26 +377,18 @@ public function testRefreshProductsVisibilityNotVisibleVariants() $variant6productData->hidden = true; $this->productFacade->edit($variant6->getId(), $variant6productData); - $this->productVisibilityRepository->refreshProductsVisibility(true); - - $this->em->refresh($variant1); - $this->em->refresh($variant2); - $this->em->refresh($variant3); - $this->em->refresh($variant4); - $this->em->refresh($variant5); - $this->em->refresh($variant6); - $this->em->refresh($mainVariant); - - $this->assertFalse($variant1->isVisible()); - $this->assertFalse($variant2->isVisible()); - $this->assertFalse($variant3->isVisible()); - $this->assertFalse($variant4->isVisible()); - $this->assertFalse($variant5->isVisible()); - $this->assertFalse($variant6->isVisible()); - $this->assertFalse($mainVariant->isVisible()); + $this->productVisibilityRepository->refreshProductsVisibility([53, 54, 148, 149, 150, 151, 69]); + + $this->assertFalse($this->getVisibilityForProduct($variant1)->isVisible()); + $this->assertFalse($this->getVisibilityForProduct($variant2)->isVisible()); + $this->assertFalse($this->getVisibilityForProduct($variant3)->isVisible()); + $this->assertFalse($this->getVisibilityForProduct($variant4)->isVisible()); + $this->assertFalse($this->getVisibilityForProduct($variant5)->isVisible()); + $this->assertFalse($this->getVisibilityForProduct($variant6)->isVisible()); + $this->assertFalse($this->getVisibilityForProduct($mainVariant)->isVisible()); } - public function testRefreshProductsVisibilityNotVisibleMainVariant() + public function testRefreshProductsVisibilityNotVisibleMainVariant(): void { /** @var \App\Model\Product\Product $variant1 */ $variant1 = $this->getReference(ProductDataFixture::PRODUCT_PREFIX . '53'); @@ -544,18 +397,14 @@ public function testRefreshProductsVisibilityNotVisibleMainVariant() /** @var \App\Model\Product\Product $mainVariant */ $mainVariant = $this->getReference(ProductDataFixture::PRODUCT_PREFIX . '69'); - $mainVariantproductData = $this->productDataFactory->createFromProduct($mainVariant); - $mainVariantproductData->hidden = true; - $this->productFacade->edit($mainVariant->getId(), $mainVariantproductData); - - $this->productVisibilityRepository->refreshProductsVisibility(true); + $mainVariantProductData = $this->productDataFactory->createFromProduct($mainVariant); + $mainVariantProductData->hidden = true; + $this->productFacade->edit($mainVariant->getId(), $mainVariantProductData); - $this->em->refresh($variant1); - $this->em->refresh($variant2); - $this->em->refresh($mainVariant); + $this->productVisibilityRepository->refreshProductsVisibility([53, 54, 69]); - $this->assertFalse($variant1->isVisible()); - $this->assertFalse($variant2->isVisible()); - $this->assertFalse($mainVariant->isVisible()); + $this->assertFalse($this->getVisibilityForProduct($variant1)->isVisible()); + $this->assertFalse($this->getVisibilityForProduct($variant2)->isVisible()); + $this->assertFalse($this->getVisibilityForProduct($mainVariant)->isVisible()); } } From dbb3a8b708aa8de80b2966d5960e2c4af6e91417 Mon Sep 17 00:00:00 2001 From: Martin Grossmann Date: Mon, 13 Nov 2023 14:00:15 +0100 Subject: [PATCH 16/32] removed calculated hidden field --- app/config/services.yaml | 3 -- app/src/Model/Product/Product.php | 1 - app/src/Model/Product/ProductFacade.php | 7 ----- .../Product/ProductHiddenRecalculator.php | 30 ------------------- .../Product/ProductVisibilityRepository.php | 2 +- .../Model/Product/ProductFacadeTest.php | 13 ++------ 6 files changed, 4 insertions(+), 52 deletions(-) delete mode 100644 app/src/Model/Product/ProductHiddenRecalculator.php diff --git a/app/config/services.yaml b/app/config/services.yaml index 3c131bd560..764e5855e2 100644 --- a/app/config/services.yaml +++ b/app/config/services.yaml @@ -299,9 +299,6 @@ services: Shopsys\FrameworkBundle\Model\Product\ProductRepository: alias: App\Model\Product\ProductRepository - Shopsys\FrameworkBundle\Model\Product\ProductHiddenRecalculator: - alias: App\Model\Product\ProductHiddenRecalculator - Shopsys\FrameworkBundle\Model\Product\ProductSellingDeniedRecalculator: alias: App\Model\Product\ProductSellingDeniedRecalculator diff --git a/app/src/Model/Product/Product.php b/app/src/Model/Product/Product.php index 87b669f22e..59711b9e14 100644 --- a/app/src/Model/Product/Product.php +++ b/app/src/Model/Product/Product.php @@ -395,7 +395,6 @@ public function getCalculatedSaleExclusion(int $domainId): bool public function isUsingStock() { //is always false and is by default set in migration to false. - //removing old stock functionality means product.calculatedHidden is always setup by product.hidden return false; } diff --git a/app/src/Model/Product/ProductFacade.php b/app/src/Model/Product/ProductFacade.php index 88ccddf9ce..b5b60d5575 100644 --- a/app/src/Model/Product/ProductFacade.php +++ b/app/src/Model/Product/ProductFacade.php @@ -24,7 +24,6 @@ use Shopsys\FrameworkBundle\Model\Product\ProductData; use Shopsys\FrameworkBundle\Model\Product\ProductFacade as BaseProductFacade; use Shopsys\FrameworkBundle\Model\Product\ProductFactoryInterface; -use Shopsys\FrameworkBundle\Model\Product\ProductHiddenRecalculator; use Shopsys\FrameworkBundle\Model\Product\ProductRepository; use Shopsys\FrameworkBundle\Model\Product\ProductSellingDeniedRecalculator; use Shopsys\FrameworkBundle\Model\Product\ProductVisibilityFacade; @@ -39,7 +38,6 @@ * @property \App\Model\Product\Parameter\ParameterRepository $parameterRepository * @property \App\Component\Image\ImageFacade $imageFacade * @property \App\Component\Router\FriendlyUrl\FriendlyUrlFacade $friendlyUrlFacade - * @property \App\Model\Product\ProductHiddenRecalculator $productHiddenRecalculator * @property \App\Model\Product\ProductSellingDeniedRecalculator $productSellingDeniedRecalculator * @property \Shopsys\FrameworkBundle\Model\Product\Pricing\ProductPriceCalculation $productPriceCalculation * @method \App\Model\Product\Product getById(int $productId) @@ -66,7 +64,6 @@ class ProductFacade extends BaseProductFacade * @param \Shopsys\FrameworkBundle\Model\Pricing\Group\PricingGroupRepository $pricingGroupRepository * @param \Shopsys\FrameworkBundle\Model\Product\Pricing\ProductManualInputPriceFacade $productManualInputPriceFacade * @param \App\Component\Router\FriendlyUrl\FriendlyUrlFacade $friendlyUrlFacade - * @param \App\Model\Product\ProductHiddenRecalculator $productHiddenRecalculator * @param \App\Model\Product\ProductSellingDeniedRecalculator $productSellingDeniedRecalculator * @param \Shopsys\FrameworkBundle\Model\Product\Accessory\ProductAccessoryRepository $productAccessoryRepository * @param \Shopsys\FrameworkBundle\Component\Plugin\PluginCrudExtensionFacade $pluginCrudExtensionFacade @@ -92,7 +89,6 @@ public function __construct( PricingGroupRepository $pricingGroupRepository, ProductManualInputPriceFacade $productManualInputPriceFacade, FriendlyUrlFacade $friendlyUrlFacade, - ProductHiddenRecalculator $productHiddenRecalculator, ProductSellingDeniedRecalculator $productSellingDeniedRecalculator, ProductAccessoryRepository $productAccessoryRepository, PluginCrudExtensionFacade $pluginCrudExtensionFacade, @@ -118,7 +114,6 @@ public function __construct( $pricingGroupRepository, $productManualInputPriceFacade, $friendlyUrlFacade, - $productHiddenRecalculator, $productSellingDeniedRecalculator, $productAccessoryRepository, $pluginCrudExtensionFacade, @@ -187,7 +182,6 @@ public function edit($productId, ProductData $productData) $this->refreshProductAccessories($product, $productData->accessories); $this->em->flush(); $this->imageFacade->manageImages($product, $productData->images); - $this->productHiddenRecalculator->calculateHiddenForProduct($product); $this->friendlyUrlFacade->saveUrlListFormData('front_product_detail', $product->getId(), $productData->urls); $this->friendlyUrlFacade->createFriendlyUrls('front_product_detail', $product->getId(), $product->getFullnames()); @@ -232,7 +226,6 @@ public function setAdditionalDataAfterCreate(BaseProduct $product, ProductData $ $this->productManualInputPriceFacade->refreshProductManualInputPrices($product, $productData->manualInputPricesByPricingGroupId); $this->refreshProductAccessories($product, $productData->accessories); $this->imageFacade->manageImages($product, $productData->images); - $this->productHiddenRecalculator->calculateHiddenForProduct($product); $this->friendlyUrlFacade->saveUrlListFormData('front_product_detail', $product->getId(), $productData->urls); $this->friendlyUrlFacade->createFriendlyUrls('front_product_detail', $product->getId(), $product->getNames()); diff --git a/app/src/Model/Product/ProductHiddenRecalculator.php b/app/src/Model/Product/ProductHiddenRecalculator.php deleted file mode 100644 index b1e99fce3b..0000000000 --- a/app/src/Model/Product/ProductHiddenRecalculator.php +++ /dev/null @@ -1,30 +0,0 @@ -em->createQueryBuilder() - ->update(Product::class, 'p') - ->set('p.calculatedHidden', 'p.hidden'); - - if ($product !== null) { - $qb->where('p = :product')->setParameter('product', $product); - } - - $qb->getQuery()->execute(); - } -} diff --git a/app/src/Model/Product/ProductVisibilityRepository.php b/app/src/Model/Product/ProductVisibilityRepository.php index bd380fa520..e50b525612 100644 --- a/app/src/Model/Product/ProductVisibilityRepository.php +++ b/app/src/Model/Product/ProductVisibilityRepository.php @@ -51,7 +51,7 @@ protected function calculateIndependentVisibility(?array $productIds): void $query = 'UPDATE product_visibilities AS pv SET visible = CASE WHEN ( - p.calculated_hidden = FALSE + p.hidden = FALSE AND (p.selling_from IS NULL OR p.selling_from <= :now) AND diff --git a/app/tests/App/Functional/Model/Product/ProductFacadeTest.php b/app/tests/App/Functional/Model/Product/ProductFacadeTest.php index 6b36e63f76..79eb71a1f2 100644 --- a/app/tests/App/Functional/Model/Product/ProductFacadeTest.php +++ b/app/tests/App/Functional/Model/Product/ProductFacadeTest.php @@ -44,16 +44,14 @@ class ProductFacadeTest extends TransactionFunctionalTestCase private ProductStockDataFactory $productStockDataFactory; /** - * @dataProvider getTestCalculationHiddenAndSellingDeniedDataProvider + * @dataProvider getTestSellingDeniedDataProvider * @param mixed $hidden * @param mixed $sellingDenied - * @param mixed $calculatedHidden * @param mixed $calculatedSellingDenied */ - public function testCalculationHiddenAndSellingDenied( + public function testSellingDenied( $hidden, $sellingDenied, - $calculatedHidden, $calculatedSellingDenied, ) { $productData = $this->productDataFactory->create(); @@ -78,35 +76,30 @@ public function testCalculationHiddenAndSellingDenied( $productFromDb = $this->productFacade->getById($product->getId()); - $this->assertSame($calculatedHidden, $productFromDb->getCalculatedHidden(), 'Calculated hidden:'); $this->assertSame($calculatedSellingDenied, $productFromDb->getCalculatedSellingDenied(), 'Calculated selling denied:'); } - public function getTestCalculationHiddenAndSellingDeniedDataProvider() + public function getTestSellingDeniedDataProvider() { return [ [ 'hidden' => true, 'sellingDenied' => true, - 'calculatedHidden' => true, 'calculatedSellingDenied' => true, ], [ 'hidden' => false, 'sellingDenied' => false, - 'calculatedHidden' => false, 'calculatedSellingDenied' => false, ], [ 'hidden' => true, 'sellingDenied' => false, - 'calculatedHidden' => true, 'calculatedSellingDenied' => false, ], [ 'hidden' => false, 'sellingDenied' => true, - 'calculatedHidden' => false, 'calculatedSellingDenied' => true, ], ]; From 3d7cf7b40cd358c3bb5f9b24bb5d5713bd8a5707 Mon Sep 17 00:00:00 2001 From: Martin Grossmann Date: Mon, 27 Nov 2023 08:27:57 +0100 Subject: [PATCH 17/32] parameters in category in admin are now sorted alphabetically --- .../Demo/CategoryParameterDataFixture.php | 5 +++-- app/src/Form/Admin/CategoryFormTypeExtension.php | 8 ++++++-- app/src/Model/CategorySeo/CategorySeoFacade.php | 10 ---------- .../Model/Product/Parameter/ParameterRepository.php | 12 ++++++++---- 4 files changed, 17 insertions(+), 18 deletions(-) diff --git a/app/src/DataFixtures/Demo/CategoryParameterDataFixture.php b/app/src/DataFixtures/Demo/CategoryParameterDataFixture.php index e5a1ab9ac1..ed2574eb8f 100644 --- a/app/src/DataFixtures/Demo/CategoryParameterDataFixture.php +++ b/app/src/DataFixtures/Demo/CategoryParameterDataFixture.php @@ -34,13 +34,14 @@ public function load(ObjectManager $manager) { /** @var \App\Model\Category\Category $categoryElectronics */ $categoryElectronics = $this->getReference(CategoryDataFixture::CATEGORY_ELECTRONICS); - $firstDomainLocale = $this->domain->getDomainConfigById(1)->getLocale(); + $firstDomainConfig = $this->domain->getDomainConfigById(Domain::FIRST_DOMAIN_ID); + $firstDomainLocale = $firstDomainConfig->getLocale(); $categoryDataFixtureClassReflection = new ReflectionClass(CategoryDataFixture::class); foreach ($categoryDataFixtureClassReflection->getConstants() as $constant) { /** @var \App\Model\Category\Category $category */ $category = $this->getReference($constant); - $parameters = $this->parameterRepository->getParametersUsedByProductsInCategory($category, Domain::FIRST_DOMAIN_ID); + $parameters = $this->parameterRepository->getParametersUsedByProductsInCategory($category, $firstDomainConfig); $parametersId = []; foreach ($parameters as $parameter) { diff --git a/app/src/Form/Admin/CategoryFormTypeExtension.php b/app/src/Form/Admin/CategoryFormTypeExtension.php index 694e863e6d..57718336b5 100644 --- a/app/src/Form/Admin/CategoryFormTypeExtension.php +++ b/app/src/Form/Admin/CategoryFormTypeExtension.php @@ -30,6 +30,7 @@ class CategoryFormTypeExtension extends AbstractTypeExtension * @param \Shopsys\FrameworkBundle\Form\Transformers\RemoveDuplicatesFromArrayTransformer $removeDuplicatesFromArrayTransformer * @param \Shopsys\FrameworkBundle\Form\Transformers\CategoriesIdsToCategoriesTransformer $categoriesIdsToCategoriesTransformer * @param \Shopsys\FrameworkBundle\Model\Localization\Localization $localization + * @param \Shopsys\FrameworkBundle\Component\Domain\Domain $domain */ public function __construct( private readonly ParameterRepository $parameterRepository, @@ -38,6 +39,7 @@ public function __construct( private readonly RemoveDuplicatesFromArrayTransformer $removeDuplicatesFromArrayTransformer, private readonly CategoriesIdsToCategoriesTransformer $categoriesIdsToCategoriesTransformer, private readonly Localization $localization, + private readonly Domain $domain, ) { } @@ -78,7 +80,9 @@ private function buildFilterParameters(FormBuilderInterface $builder, ?Category $parameterNamesById = []; - foreach ($this->parameterRepository->getParametersUsedByProductsInCategory($category, Domain::FIRST_DOMAIN_ID) as $parameter) { + $parametersUsedByProductsInCategory = $this->parameterRepository->getParametersUsedByProductsInCategory($category, $this->domain->getDomainConfigById(Domain::FIRST_DOMAIN_ID)); + + foreach ($parametersUsedByProductsInCategory as $parameter) { $parameterNamesById[$parameter->getId()] = $parameter->getName(); } @@ -91,7 +95,7 @@ private function buildFilterParameters(FormBuilderInterface $builder, ?Category $parametersFilterBuilder->add('parametersCollapsed', ChoiceType::class, [ 'required' => false, 'label' => t('Filter parameters closed by default'), - 'choices' => $this->parameterRepository->getParametersUsedByProductsInCategory($category, Domain::FIRST_DOMAIN_ID), + 'choices' => $parametersUsedByProductsInCategory, 'expanded' => true, 'choice_label' => 'name', 'choice_value' => 'id', diff --git a/app/src/Model/CategorySeo/CategorySeoFacade.php b/app/src/Model/CategorySeo/CategorySeoFacade.php index d99fdc434a..e666b90171 100644 --- a/app/src/Model/CategorySeo/CategorySeoFacade.php +++ b/app/src/Model/CategorySeo/CategorySeoFacade.php @@ -25,16 +25,6 @@ public function __construct( ) { } - /** - * @param \App\Model\Category\Category $category - * @param int $domainId - * @return \App\Model\Product\Parameter\Parameter[] - */ - public function getParametersUsedByProductsInCategory(Category $category, int $domainId): array - { - return $this->parameterRepository->getParametersUsedByProductsInCategory($category, $domainId); - } - /** * @param \App\Model\Category\Category $category * @param int $domainId diff --git a/app/src/Model/Product/Parameter/ParameterRepository.php b/app/src/Model/Product/Parameter/ParameterRepository.php index dfd1078853..6d673bbd8f 100644 --- a/app/src/Model/Product/Parameter/ParameterRepository.php +++ b/app/src/Model/Product/Parameter/ParameterRepository.php @@ -11,6 +11,7 @@ use Doctrine\ORM\EntityRepository; use Doctrine\ORM\Query\Expr\Join; use Doctrine\ORM\QueryBuilder; +use Shopsys\FrameworkBundle\Component\Domain\Config\DomainConfig; use Shopsys\FrameworkBundle\Model\Category\Category; use Shopsys\FrameworkBundle\Model\Product\Parameter\ParameterRepository as BaseParameterRepository; use Shopsys\FrameworkBundle\Model\Product\Parameter\ProductParameterValue; @@ -39,17 +40,20 @@ class ParameterRepository extends BaseParameterRepository { /** * @param \App\Model\Category\Category $category - * @param int $domainId + * @param \Shopsys\FrameworkBundle\Component\Domain\Config\DomainConfig $domainConfig * @return \App\Model\Product\Parameter\Parameter[] */ - public function getParametersUsedByProductsInCategory(Category $category, int $domainId): array + public function getParametersUsedByProductsInCategory(Category $category, DomainConfig $domainConfig): array { $queryBuilder = $this->getParameterRepository()->createQueryBuilder('p') ->select('p') ->join(ProductParameterValue::class, 'ppv', Join::WITH, 'p = ppv.parameter') - ->groupBy('p'); + ->join('p.translations', 'pt', Join::WITH, 'pt.locale = :locale') + ->setParameter('locale', $domainConfig->getLocale()) + ->orderBy(OrderByCollationHelper::createOrderByForLocale('pt.name', $domainConfig->getLocale())) + ->groupBy('p, pt'); - $this->applyCategorySeoConditions($queryBuilder, $category, $domainId); + $this->applyCategorySeoConditions($queryBuilder, $category, $domainConfig->getId()); return $queryBuilder->getQuery()->execute(); } From f6b6e3b1370a719358795d1a88cf672f6bbd7d07 Mon Sep 17 00:00:00 2001 From: Martin Grossmann Date: Mon, 27 Nov 2023 08:28:36 +0100 Subject: [PATCH 18/32] product filtering options test is now independent on parameters order --- .../Cart/AnonymousAddOrderItemsToCartTest.php | 29 +- .../Product/ProductsFilteringOptionsTest.php | 549 +++++++++--------- .../Test/GraphQlTestCase.php | 15 + 3 files changed, 292 insertions(+), 301 deletions(-) diff --git a/app/tests/FrontendApiBundle/Functional/Cart/AnonymousAddOrderItemsToCartTest.php b/app/tests/FrontendApiBundle/Functional/Cart/AnonymousAddOrderItemsToCartTest.php index 6866f8f7f7..fb49d06919 100644 --- a/app/tests/FrontendApiBundle/Functional/Cart/AnonymousAddOrderItemsToCartTest.php +++ b/app/tests/FrontendApiBundle/Functional/Cart/AnonymousAddOrderItemsToCartTest.php @@ -60,7 +60,7 @@ public function testOrderItemsAreAddedToNotExistingCart(bool $shouldMerge, ?stri ); $data = $this->getResponseDataForGraphQlType($response, 'AddOrderItemsToCart'); $this->assertArrayHasKey('items', $data); - $this->assertCartItems($expectedItems, $data['items']); + $this->assertArrayElements($expectedItems, $data['items']); $this->assertActualCartContent($data['uuid'], $expectedItems); } @@ -135,7 +135,7 @@ public function testOrderItemsAreAddedToExistingCart(): void ); $data = $this->getResponseDataForGraphQlType($response, 'AddOrderItemsToCart'); $this->assertArrayHasKey('items', $data); - $this->assertCartItems($expectedItems, $data['items']); + $this->assertArrayElements($expectedItems, $data['items']); $this->assertActualCartContent($cartUuid, $expectedItems); } @@ -180,7 +180,7 @@ public function testOrderItemsAreReplacedInExistingCart(): void ); $data = $this->getResponseDataForGraphQlType($response, 'AddOrderItemsToCart'); $this->assertArrayHasKey('items', $data); - $this->assertCartItems($expectedItems, $data['items']); + $this->assertArrayElements($expectedItems, $data['items']); $this->assertActualCartContent($cartUuid, $expectedItems); } @@ -215,7 +215,7 @@ public function testNotAvailableOrderItemIsSkippedWhileAdding(): void ); $data = $this->getResponseDataForGraphQlType($response, 'AddOrderItemsToCart'); $this->assertArrayHasKey('items', $data); - $this->assertCartItems($expectedItems, $data['items']); + $this->assertArrayElements($expectedItems, $data['items']); $this->assertActualCartContent($data['uuid'], $expectedItems); @@ -258,7 +258,7 @@ public function testOrderItemsAreAddedFromCustomersOrder(): void ); $data = $this->getResponseDataForGraphQlType($response, 'AddOrderItemsToCart'); $this->assertArrayHasKey('items', $data); - $this->assertCartItems($expectedItems, $data['items']); + $this->assertArrayElements($expectedItems, $data['items']); $this->assertActualCartContent($data['uuid'], $expectedItems); } @@ -305,7 +305,7 @@ public function testTheSameProductIsNotAddedAsSeparateOrderItem(bool $shouldMerg ); $data = $this->getResponseDataForGraphQlType($response, 'AddOrderItemsToCart'); $this->assertArrayHasKey('items', $data); - $this->assertCartItems($expectedItems, $data['items']); + $this->assertArrayElements($expectedItems, $data['items']); $this->assertActualCartContent($cartUuid, $expectedItems); } @@ -333,21 +333,6 @@ private function assertActualCartContent(string $cartUuid, array $expectedItems) $data = $this->getResponseDataForGraphQlType($response, 'cart'); $this->assertArrayHasKey('items', $data); - $this->assertCartItems($expectedItems, $data['items']); - } - - /** - * Compare expected items while ignoring the order of the items - * - * @param array $expectedItems - * @param array $items - */ - private function assertCartItems(array $expectedItems, array $items): void - { - $this->assertSameSize($expectedItems, $items); - - foreach ($expectedItems as $expectedItem) { - $this->assertContains($expectedItem, $items); - } + $this->assertArrayElements($expectedItems, $data['items']); } } diff --git a/app/tests/FrontendApiBundle/Functional/Product/ProductsFilteringOptionsTest.php b/app/tests/FrontendApiBundle/Functional/Product/ProductsFilteringOptionsTest.php index d130841a85..92ac982c58 100644 --- a/app/tests/FrontendApiBundle/Functional/Product/ProductsFilteringOptionsTest.php +++ b/app/tests/FrontendApiBundle/Functional/Product/ProductsFilteringOptionsTest.php @@ -106,185 +106,181 @@ public function testGetElectronicsFilterOptions(): void ArraySorter::sortArrayAlphabeticallyByValue('text', $hdmiValues, $this->getLocaleForFirstDomain()); - $expectedResult = [ - 'data' => [ - 'category' => [ - 'products' => [ - 'productFilterOptions' => [ - 'flags' => [ - [ - 'flag' => [ - 'name' => t('Action', [], Translator::DATA_FIXTURES_TRANSLATION_DOMAIN, $this->firstDomainLocale), - ], - 'count' => 2, - 'isAbsolute' => true, - ], - ], - 'brands' => [ - [ - 'brand' => [ - 'name' => t('A4tech', [], Translator::DATA_FIXTURES_TRANSLATION_DOMAIN, $this->firstDomainLocale), - ], - 'count' => 1, - 'isAbsolute' => true, - ], - [ - 'brand' => [ - 'name' => t('LG', [], Translator::DATA_FIXTURES_TRANSLATION_DOMAIN, $this->firstDomainLocale), - ], - 'count' => 1, - 'isAbsolute' => true, - ], - [ - 'brand' => [ - 'name' => t('Philips', [], Translator::DATA_FIXTURES_TRANSLATION_DOMAIN, $this->firstDomainLocale), - ], - 'count' => 1, - 'isAbsolute' => true, - ], - [ - 'brand' => [ - 'name' => t('Sencor', [], Translator::DATA_FIXTURES_TRANSLATION_DOMAIN, $this->firstDomainLocale), - ], - 'count' => 1, - 'isAbsolute' => true, - ], - ], - 'inStock' => 4, - 'minimalPrice' => $minimalPrice, - 'maximalPrice' => $maximalPrice, - 'parameters' => [ - [ - 'isCollapsed' => false, - 'name' => t('Material', [], Translator::DATA_FIXTURES_TRANSLATION_DOMAIN, $this->firstDomainLocale), - '__typename' => 'ParameterCheckboxFilterOption', - 'unit' => null, - 'values' => $materials, - ], - [ - 'isCollapsed' => false, - 'name' => t('Color', [], Translator::DATA_FIXTURES_TRANSLATION_DOMAIN, $this->firstDomainLocale), - '__typename' => 'ParameterColorFilterOption', - 'unit' => null, - 'values' => $colors, - ], - [ - 'isCollapsed' => false, - 'name' => t('Supported OS', [], Translator::DATA_FIXTURES_TRANSLATION_DOMAIN, $this->firstDomainLocale), - '__typename' => 'ParameterCheckboxFilterOption', - 'unit' => null, - 'values' => [ - [ - 'text' => t('Windows 2000/XP/Vista/7', [], Translator::DATA_FIXTURES_TRANSLATION_DOMAIN, $this->firstDomainLocale), - 'count' => 1, - 'isAbsolute' => true, - ], - ], - ], - [ - 'isCollapsed' => false, - 'name' => t('Number of buttons', [], Translator::DATA_FIXTURES_TRANSLATION_DOMAIN, $this->firstDomainLocale), - '__typename' => 'ParameterCheckboxFilterOption', - 'unit' => null, - 'values' => [ - [ - 'text' => t('5', [], Translator::DATA_FIXTURES_TRANSLATION_DOMAIN, $this->firstDomainLocale), - 'count' => 1, - 'isAbsolute' => true, - ], - ], - ], - [ - 'isCollapsed' => false, - 'name' => t('Ergonomics', [], Translator::DATA_FIXTURES_TRANSLATION_DOMAIN, $this->firstDomainLocale), - '__typename' => 'ParameterCheckboxFilterOption', - 'unit' => null, - 'values' => [ - [ - 'text' => t('Right-handed', [], Translator::DATA_FIXTURES_TRANSLATION_DOMAIN, $this->firstDomainLocale), - 'count' => 1, - 'isAbsolute' => true, - ], - ], - ], - [ - 'isCollapsed' => true, - 'name' => t('Screen size', [], Translator::DATA_FIXTURES_TRANSLATION_DOMAIN, $this->firstDomainLocale), - '__typename' => 'ParameterCheckboxFilterOption', - 'unit' => [ - 'name' => 'in', - ], - 'values' => $screenSizes, - ], - [ - 'isCollapsed' => true, - 'name' => t('HDMI', [], Translator::DATA_FIXTURES_TRANSLATION_DOMAIN, $this->firstDomainLocale), - '__typename' => 'ParameterCheckboxFilterOption', - 'unit' => null, - 'values' => $hdmiValues, - ], - [ - 'isCollapsed' => false, - 'name' => t('USB', [], Translator::DATA_FIXTURES_TRANSLATION_DOMAIN, $this->firstDomainLocale), - '__typename' => 'ParameterCheckboxFilterOption', - 'unit' => null, - 'values' => [ - [ - 'text' => t('Yes', [], Translator::DATA_FIXTURES_TRANSLATION_DOMAIN, $this->firstDomainLocale), - 'count' => 3, - 'isAbsolute' => true, - ], - ], - ], - [ - 'isCollapsed' => false, - 'name' => t('Technology', [], Translator::DATA_FIXTURES_TRANSLATION_DOMAIN, $this->firstDomainLocale), - '__typename' => 'ParameterCheckboxFilterOption', - 'unit' => null, - 'values' => [ - [ - 'text' => t('LED', [], Translator::DATA_FIXTURES_TRANSLATION_DOMAIN, $this->firstDomainLocale), - 'count' => 3, - 'isAbsolute' => true, - ], - ], - ], - [ - 'isCollapsed' => false, - 'name' => t('Gaming mouse', [], Translator::DATA_FIXTURES_TRANSLATION_DOMAIN, $this->firstDomainLocale), - '__typename' => 'ParameterCheckboxFilterOption', - 'unit' => null, - 'values' => [ - [ - 'text' => t('Yes', [], Translator::DATA_FIXTURES_TRANSLATION_DOMAIN, $this->firstDomainLocale), - 'count' => 1, - 'isAbsolute' => true, - ], - ], - ], - [ - 'isCollapsed' => false, - 'name' => t('Resolution', [], Translator::DATA_FIXTURES_TRANSLATION_DOMAIN, $this->firstDomainLocale), - '__typename' => 'ParameterCheckboxFilterOption', - 'unit' => null, - 'values' => [ - [ - 'text' => t('1920×1080 (Full HD)', [], Translator::DATA_FIXTURES_TRANSLATION_DOMAIN, $this->firstDomainLocale), - 'count' => 3, - 'isAbsolute' => true, - ], - ], - ], - ], - ], + $expectedFlagFilterOptions = [ + [ + 'flag' => [ + 'name' => t('Action', [], Translator::DATA_FIXTURES_TRANSLATION_DOMAIN, $this->firstDomainLocale), + ], + 'count' => 2, + 'isAbsolute' => true, + ], + ]; + + $expectedBrandFilterOptions = [ + [ + 'brand' => [ + 'name' => t('A4tech', [], Translator::DATA_FIXTURES_TRANSLATION_DOMAIN, $this->firstDomainLocale), + ], + 'count' => 1, + 'isAbsolute' => true, + ], + [ + 'brand' => [ + 'name' => t('LG', [], Translator::DATA_FIXTURES_TRANSLATION_DOMAIN, $this->firstDomainLocale), + ], + 'count' => 1, + 'isAbsolute' => true, + ], + [ + 'brand' => [ + 'name' => t('Philips', [], Translator::DATA_FIXTURES_TRANSLATION_DOMAIN, $this->firstDomainLocale), + ], + 'count' => 1, + 'isAbsolute' => true, + ], + [ + 'brand' => [ + 'name' => t('Sencor', [], Translator::DATA_FIXTURES_TRANSLATION_DOMAIN, $this->firstDomainLocale), + ], + 'count' => 1, + 'isAbsolute' => true, + ], + ]; + + $expectedParameterFilterOptions = [ + [ + 'isCollapsed' => false, + 'name' => t('Material', [], Translator::DATA_FIXTURES_TRANSLATION_DOMAIN, $this->firstDomainLocale), + '__typename' => 'ParameterCheckboxFilterOption', + 'unit' => null, + 'values' => $materials, + ], + [ + 'isCollapsed' => false, + 'name' => t('Color', [], Translator::DATA_FIXTURES_TRANSLATION_DOMAIN, $this->firstDomainLocale), + '__typename' => 'ParameterColorFilterOption', + 'unit' => null, + 'values' => $colors, + ], + [ + 'isCollapsed' => false, + 'name' => t('Supported OS', [], Translator::DATA_FIXTURES_TRANSLATION_DOMAIN, $this->firstDomainLocale), + '__typename' => 'ParameterCheckboxFilterOption', + 'unit' => null, + 'values' => [ + [ + 'text' => t('Windows 2000/XP/Vista/7', [], Translator::DATA_FIXTURES_TRANSLATION_DOMAIN, $this->firstDomainLocale), + 'count' => 1, + 'isAbsolute' => true, + ], + ], + ], + [ + 'isCollapsed' => false, + 'name' => t('Number of buttons', [], Translator::DATA_FIXTURES_TRANSLATION_DOMAIN, $this->firstDomainLocale), + '__typename' => 'ParameterCheckboxFilterOption', + 'unit' => null, + 'values' => [ + [ + 'text' => t('5', [], Translator::DATA_FIXTURES_TRANSLATION_DOMAIN, $this->firstDomainLocale), + 'count' => 1, + 'isAbsolute' => true, + ], + ], + ], + [ + 'isCollapsed' => false, + 'name' => t('Ergonomics', [], Translator::DATA_FIXTURES_TRANSLATION_DOMAIN, $this->firstDomainLocale), + '__typename' => 'ParameterCheckboxFilterOption', + 'unit' => null, + 'values' => [ + [ + 'text' => t('Right-handed', [], Translator::DATA_FIXTURES_TRANSLATION_DOMAIN, $this->firstDomainLocale), + 'count' => 1, + 'isAbsolute' => true, + ], + ], + ], + [ + 'isCollapsed' => true, + 'name' => t('Screen size', [], Translator::DATA_FIXTURES_TRANSLATION_DOMAIN, $this->firstDomainLocale), + '__typename' => 'ParameterCheckboxFilterOption', + 'unit' => [ + 'name' => 'in', + ], + 'values' => $screenSizes, + ], + [ + 'isCollapsed' => true, + 'name' => t('HDMI', [], Translator::DATA_FIXTURES_TRANSLATION_DOMAIN, $this->firstDomainLocale), + '__typename' => 'ParameterCheckboxFilterOption', + 'unit' => null, + 'values' => $hdmiValues, + ], + [ + 'isCollapsed' => false, + 'name' => t('USB', [], Translator::DATA_FIXTURES_TRANSLATION_DOMAIN, $this->firstDomainLocale), + '__typename' => 'ParameterCheckboxFilterOption', + 'unit' => null, + 'values' => [ + [ + 'text' => t('Yes', [], Translator::DATA_FIXTURES_TRANSLATION_DOMAIN, $this->firstDomainLocale), + 'count' => 3, + 'isAbsolute' => true, + ], + ], + ], + [ + 'isCollapsed' => false, + 'name' => t('Technology', [], Translator::DATA_FIXTURES_TRANSLATION_DOMAIN, $this->firstDomainLocale), + '__typename' => 'ParameterCheckboxFilterOption', + 'unit' => null, + 'values' => [ + [ + 'text' => t('LED', [], Translator::DATA_FIXTURES_TRANSLATION_DOMAIN, $this->firstDomainLocale), + 'count' => 3, + 'isAbsolute' => true, + ], + ], + ], + [ + 'isCollapsed' => false, + 'name' => t('Gaming mouse', [], Translator::DATA_FIXTURES_TRANSLATION_DOMAIN, $this->firstDomainLocale), + '__typename' => 'ParameterCheckboxFilterOption', + 'unit' => null, + 'values' => [ + [ + 'text' => t('Yes', [], Translator::DATA_FIXTURES_TRANSLATION_DOMAIN, $this->firstDomainLocale), + 'count' => 1, + 'isAbsolute' => true, + ], + ], + ], + [ + 'isCollapsed' => false, + 'name' => t('Resolution', [], Translator::DATA_FIXTURES_TRANSLATION_DOMAIN, $this->firstDomainLocale), + '__typename' => 'ParameterCheckboxFilterOption', + 'unit' => null, + 'values' => [ + [ + 'text' => t('1920×1080 (Full HD)', [], Translator::DATA_FIXTURES_TRANSLATION_DOMAIN, $this->firstDomainLocale), + 'count' => 3, + 'isAbsolute' => true, ], ], ], ]; - $expected = json_encode($expectedResult, JSON_THROW_ON_ERROR); + $response = $this->getResponseContentForQuery($query); + $data = $this->getResponseDataForGraphQlType($response, 'category'); + + $this->assertSame(4, $data['products']['productFilterOptions']['inStock']); + $this->assertSame($minimalPrice, $data['products']['productFilterOptions']['minimalPrice']); + $this->assertSame($maximalPrice, $data['products']['productFilterOptions']['maximalPrice']); - $this->assertQueryWithExpectedJson($query, $expected); + $this->assertArrayElements($expectedFlagFilterOptions, $data['products']['productFilterOptions']['flags']); + $this->assertArrayElements($expectedBrandFilterOptions, $data['products']['productFilterOptions']['brands']); + $this->assertArrayElements($expectedParameterFilterOptions, $data['products']['productFilterOptions']['parameters']); } public function testGetElectronicsBrandFilterOptionsWithAppliedFilter(): void @@ -575,10 +571,9 @@ public function testGetElectronicsParametersFilterOptionsWithAppliedFilter(): vo ]; $result = $this->getResponseContentForQuery($query); + $data = $this->getResponseDataForGraphQlType($result, 'category'); - $resultJson = json_encode($result['data']['category']['products']['productFilterOptions']['parameters']); - - $this->assertJsonStringEqualsJsonString(json_encode($expectedArray, JSON_THROW_ON_ERROR), $resultJson); + $this->assertArrayElements($expectedArray, $data['products']['productFilterOptions']['parameters']); } /** @@ -749,110 +744,106 @@ public function testGetProductFilterOptionsForSearchInCategory(): void $minimalPrice = $this->getFormattedMoneyAmountConvertedToDomainDefaultCurrency('21590'); $maximalPrice = $this->getFormattedMoneyAmountConvertedToDomainDefaultCurrency('24010'); - $expectedResult = '{ - "data": { - "category": { - "products": { - "productFilterOptions": { - "minimalPrice": "' . $minimalPrice . '", - "maximalPrice": "' . $maximalPrice . '", - "inStock": 2, - "flags": null, - "brands": [ - { - "count": 2, - "brand": { - "name": "' . t('LG', [], Translator::DATA_FIXTURES_TRANSLATION_DOMAIN, $this->firstDomainLocale) . '" - } - } - ], - "parameters": [ - { - "isCollapsed": false, - "name": "' . t('Material', [], Translator::DATA_FIXTURES_TRANSLATION_DOMAIN, $this->firstDomainLocale) . '", - "values": [ - { - "text": "' . t('plastic', [], Translator::DATA_FIXTURES_TRANSLATION_DOMAIN, $this->firstDomainLocale) . '", - "count": 1 - } - ] - }, - { - "isCollapsed": false, - "name": "' . t('Color', [], Translator::DATA_FIXTURES_TRANSLATION_DOMAIN, $this->firstDomainLocale) . '", - "values": [ - { - "text": "' . t('red', [], Translator::DATA_FIXTURES_TRANSLATION_DOMAIN, $this->firstDomainLocale) . '", - "count": 1 - } - ] - }, - { - "isCollapsed": false, - "name": "' . t('USB', [], Translator::DATA_FIXTURES_TRANSLATION_DOMAIN, $this->firstDomainLocale) . '", - "values": [ - { - "text": "' . t('Yes', [], Translator::DEFAULT_TRANSLATION_DOMAIN, $this->firstDomainLocale) . '", - "count": 2 - } - ] - }, - { - "isCollapsed": false, - "name": "' . t('Resolution', [], Translator::DATA_FIXTURES_TRANSLATION_DOMAIN, $this->firstDomainLocale) . '", - "values": [ - { - "text": "' . t('1366×768 (HD Ready)', [], Translator::DATA_FIXTURES_TRANSLATION_DOMAIN, $this->firstDomainLocale) . '", - "count": 1 - }, - { - "text": "' . t('1920×1080 (Full HD)', [], Translator::DATA_FIXTURES_TRANSLATION_DOMAIN, $this->firstDomainLocale) . '", - "count": 1 - } - ] - }, - { - "isCollapsed": false, - "name": "' . t('Screen size', [], Translator::DATA_FIXTURES_TRANSLATION_DOMAIN, $this->firstDomainLocale) . '", - "values": [ - { - "text": "' . t('47\"', [], Translator::DATA_FIXTURES_TRANSLATION_DOMAIN, $this->firstDomainLocale) . '", - "count": 1 - }, - { - "text": "' . t('60\"', [], Translator::DATA_FIXTURES_TRANSLATION_DOMAIN, $this->firstDomainLocale) . '", - "count": 1 - } - ] - }, - { - "isCollapsed": false, - "name": "' . t('HDMI', [], Translator::DATA_FIXTURES_TRANSLATION_DOMAIN, $this->firstDomainLocale) . '", - "values": [ - { - "text": "' . t('No', [], Translator::DEFAULT_TRANSLATION_DOMAIN, $this->firstDomainLocale) . '", - "count": 2 - } - ] - }, - { - "isCollapsed": false, - "name": "' . t('Technology', [], Translator::DATA_FIXTURES_TRANSLATION_DOMAIN, $this->firstDomainLocale) . '", - "values": [ - { - "text": "' . t('LED', [], Translator::DATA_FIXTURES_TRANSLATION_DOMAIN, $this->firstDomainLocale) . '", - "count": 2 - } - ] - } - ] - } - } - } - } - }'; + $response = $this->getResponseContentForQuery($query); + $data = $this->getResponseDataForGraphQlType($response, 'category'); - $this->assertQueryWithExpectedJson($query, $expectedResult); + $this->assertSame(2, $data['products']['productFilterOptions']['inStock']); + $this->assertSame($minimalPrice, $data['products']['productFilterOptions']['minimalPrice']); + $this->assertSame($maximalPrice, $data['products']['productFilterOptions']['maximalPrice']); + + $this->assertNull($data['products']['productFilterOptions']['flags']); + + $expectedBrandFilterOptions = [ + [ + 'count' => 2, + 'brand' => [ + 'name' => t('LG', [], Translator::DATA_FIXTURES_TRANSLATION_DOMAIN, $this->firstDomainLocale), + ], + ], + ]; + $this->assertArrayElements($expectedBrandFilterOptions, $data['products']['productFilterOptions']['brands']); + + $expectedParameterFilterOptions = [ + [ + 'isCollapsed' => false, + 'name' => t('Material', [], Translator::DATA_FIXTURES_TRANSLATION_DOMAIN, $this->firstDomainLocale), + 'values' => [ + [ + 'text' => t('plastic', [], Translator::DATA_FIXTURES_TRANSLATION_DOMAIN, $this->firstDomainLocale), + 'count' => 1, + ], + ], + ], + [ + 'isCollapsed' => false, + 'name' => t('Color', [], Translator::DATA_FIXTURES_TRANSLATION_DOMAIN, $this->firstDomainLocale), + 'values' => [ + [ + 'text' => t('red', [], Translator::DATA_FIXTURES_TRANSLATION_DOMAIN, $this->firstDomainLocale), + 'count' => 1, + ], + ], + ], + [ + 'isCollapsed' => false, + 'name' => t('USB', [], Translator::DATA_FIXTURES_TRANSLATION_DOMAIN, $this->firstDomainLocale), + 'values' => [ + [ + 'text' => t('Yes', [], Translator::DEFAULT_TRANSLATION_DOMAIN, $this->firstDomainLocale), + 'count' => 2, + ], + ], + ], + [ + 'isCollapsed' => false, + 'name' => t('Resolution', [], Translator::DATA_FIXTURES_TRANSLATION_DOMAIN, $this->firstDomainLocale), + 'values' => [ + [ + 'text' => t('1366×768 (HD Ready)', [], Translator::DATA_FIXTURES_TRANSLATION_DOMAIN, $this->firstDomainLocale), + 'count' => 1, + ], + [ + 'text' => t('1920×1080 (Full HD)', [], Translator::DATA_FIXTURES_TRANSLATION_DOMAIN, $this->firstDomainLocale), + 'count' => 1, + ], + ], + ], + [ + 'isCollapsed' => false, + 'name' => t('Screen size', [], Translator::DATA_FIXTURES_TRANSLATION_DOMAIN, $this->firstDomainLocale), + 'values' => [ + [ + 'text' => t('47"', [], Translator::DATA_FIXTURES_TRANSLATION_DOMAIN, $this->firstDomainLocale), + 'count' => 1, + ], + [ + 'text' => t('60"', [], Translator::DATA_FIXTURES_TRANSLATION_DOMAIN, $this->firstDomainLocale), + 'count' => 1, + ], + ], + ], + [ + 'isCollapsed' => false, + 'name' => t('HDMI', [], Translator::DATA_FIXTURES_TRANSLATION_DOMAIN, $this->firstDomainLocale), + 'values' => [ + [ + 'text' => t('No', [], Translator::DEFAULT_TRANSLATION_DOMAIN, $this->firstDomainLocale), + 'count' => 2, + ], + ], + ], + [ + 'isCollapsed' => false, + 'name' => t('Technology', [], Translator::DATA_FIXTURES_TRANSLATION_DOMAIN, $this->firstDomainLocale), + 'values' => [ + [ + 'text' => t('LED', [], Translator::DATA_FIXTURES_TRANSLATION_DOMAIN, $this->firstDomainLocale), + 'count' => 2, + ], + ], + ], + ]; + $this->assertArrayElements($expectedParameterFilterOptions, $data['products']['productFilterOptions']['parameters']); } public function testGetProductFilterOptionsForSearchWhenListingByFlag(): void diff --git a/app/tests/FrontendApiBundle/Test/GraphQlTestCase.php b/app/tests/FrontendApiBundle/Test/GraphQlTestCase.php index b83ba6d68b..a2fe9666ba 100644 --- a/app/tests/FrontendApiBundle/Test/GraphQlTestCase.php +++ b/app/tests/FrontendApiBundle/Test/GraphQlTestCase.php @@ -332,4 +332,19 @@ protected function getFormattedMoneyAmountConvertedToDomainDefaultCurrency(strin return MoneyFormatterHelper::formatWithMaxFractionDigits($money); } + + /** + * Compare the expected array while ignoring the order of the elements + * + * @param array $expectedArray + * @param array $actualArray + */ + public function assertArrayElements(array $expectedArray, array $actualArray): void + { + $this->assertSameSize($expectedArray, $actualArray); + + foreach ($expectedArray as $expectedItem) { + $this->assertContains($expectedItem, $actualArray); + } + } } From 32a558c9514fea2f093398cf9faeab55e45dd36c Mon Sep 17 00:00:00 2001 From: Martin Grossmann Date: Tue, 12 Dec 2023 12:50:07 +0100 Subject: [PATCH 19/32] product hidden on domain is moved to framework package --- app/config/services.yaml | 3 - app/src/Migrations/Version20200618125834.php | 27 ---- .../Elasticsearch/ProductExportRepository.php | 2 - app/src/Model/Product/Product.php | 23 +--- app/src/Model/Product/ProductData.php | 6 - app/src/Model/Product/ProductDataFactory.php | 4 - app/src/Model/Product/ProductDomain.php | 22 ---- .../Product/ProductVisibilityRepository.php | 115 ------------------ 8 files changed, 1 insertion(+), 201 deletions(-) delete mode 100644 app/src/Migrations/Version20200618125834.php delete mode 100644 app/src/Model/Product/ProductVisibilityRepository.php diff --git a/app/config/services.yaml b/app/config/services.yaml index 764e5855e2..4fd1faade3 100644 --- a/app/config/services.yaml +++ b/app/config/services.yaml @@ -516,9 +516,6 @@ services: Shopsys\FrameworkBundle\Model\Product\Filter\ProductFilterRepository: alias: App\Model\Product\Filter\ProductFilterRepository - Shopsys\FrameworkBundle\Model\Product\ProductVisibilityRepository: - alias: App\Model\Product\ProductVisibilityRepository - App\Model\AdvancedSearch\ProductAdvancedSearchConfig: ~ Shopsys\FrameworkBundle\Model\AdvancedSearch\ProductAdvancedSearchConfig: diff --git a/app/src/Migrations/Version20200618125834.php b/app/src/Migrations/Version20200618125834.php deleted file mode 100644 index 26cd975b16..0000000000 --- a/app/src/Migrations/Version20200618125834.php +++ /dev/null @@ -1,27 +0,0 @@ -sql('ALTER TABLE product_domains ADD domain_hidden BOOLEAN NOT NULL DEFAULT FALSE'); - $this->sql('ALTER TABLE product_domains ALTER domain_hidden DROP DEFAULT'); - } - - /** - * @param \Doctrine\DBAL\Schema\Schema $schema - */ - public function down(Schema $schema): void - { - } -} diff --git a/app/src/Model/Product/Elasticsearch/ProductExportRepository.php b/app/src/Model/Product/Elasticsearch/ProductExportRepository.php index 1c31193f49..1d84996608 100644 --- a/app/src/Model/Product/Elasticsearch/ProductExportRepository.php +++ b/app/src/Model/Product/Elasticsearch/ProductExportRepository.php @@ -36,11 +36,9 @@ * @method int[] extractCategories(int $domainId, \App\Model\Product\Product $product) * @method array extractVisibility(int $domainId, \App\Model\Product\Product $product) * @property \App\Model\Product\Parameter\ParameterRepository $parameterRepository - * @property \App\Model\Product\ProductVisibilityRepository $productVisibilityFacade * @property \App\Component\Router\FriendlyUrl\FriendlyUrlRepository $friendlyUrlRepository * @method array extractParameters(string $locale, \App\Model\Product\Product $product) * @property \App\Model\Category\CategoryFacade $categoryFacade - * @method setCategoryFacade(\App\Model\Category\CategoryFacade $categoryFacade) * @method string getBrandUrlForDomainByProduct(\App\Model\Product\Product $product, int $domainId) * @method array extractAccessoriesIds(\App\Model\Product\Product $product) * @property \App\Component\Router\FriendlyUrl\FriendlyUrlFacade $friendlyUrlFacade diff --git a/app/src/Model/Product/Product.php b/app/src/Model/Product/Product.php index 59711b9e14..dba74c55ef 100644 --- a/app/src/Model/Product/Product.php +++ b/app/src/Model/Product/Product.php @@ -41,6 +41,7 @@ * @property \App\Model\Product\Unit\Unit $unit * @method \App\Model\Product\Unit\Unit getUnit() * @method \App\Model\Product\Flag\Flag[] getFlags(int $domainId) + * @method setDomains(\App\Model\Product\ProductData $productData) */ class Product extends BaseProduct { @@ -182,19 +183,6 @@ protected function createTranslation() return new ProductTranslation(); } - /** - * @param \App\Model\Product\ProductData $productData - */ - protected function setDomains(BaseProductData $productData): void - { - parent::setDomains($productData); - - foreach ($this->domains as $productDomain) { - $domainId = $productDomain->getDomainId(); - $productDomain->setDomainHidden($productData->domainHidden[$domainId] ?? false); - } - } - /** * @param \App\Model\Product\ProductData $productData */ @@ -371,15 +359,6 @@ public function getProductDomains() return $this->domains; } - /** - * @param int $domainId - * @return bool|null - */ - public function isDomainHidden(int $domainId): ?bool - { - return $this->getProductDomain($domainId)->isDomainHidden(); - } - /** * @param int $domainId * @return bool diff --git a/app/src/Model/Product/ProductData.php b/app/src/Model/Product/ProductData.php index ce65852e8b..54ba151de8 100644 --- a/app/src/Model/Product/ProductData.php +++ b/app/src/Model/Product/ProductData.php @@ -31,11 +31,6 @@ class ProductData extends BaseProductData */ public $stockProductData; - /** - * @var bool[]|null[] - */ - public $domainHidden; - /** * @var int|null */ @@ -58,7 +53,6 @@ public function __construct() $this->namePrefix = []; $this->nameSufix = []; $this->stockProductData = []; - $this->domainHidden = []; $this->weight = null; $this->relatedProducts = []; $this->productVideosData = []; diff --git a/app/src/Model/Product/ProductDataFactory.php b/app/src/Model/Product/ProductDataFactory.php index b4d8f27609..c484ffa76b 100644 --- a/app/src/Model/Product/ProductDataFactory.php +++ b/app/src/Model/Product/ProductDataFactory.php @@ -137,10 +137,6 @@ protected function fillNew(BaseProductData $productData): void { parent::fillNew($productData); - foreach ($this->domain->getAllIds() as $domainId) { - $productData->domainHidden[$domainId] = false; - } - foreach ($this->domain->getAllLocales() as $locale) { $productData->namePrefix[$locale] = null; $productData->nameSufix[$locale] = null; diff --git a/app/src/Model/Product/ProductDomain.php b/app/src/Model/Product/ProductDomain.php index 658f26fdc6..09c653fbac 100644 --- a/app/src/Model/Product/ProductDomain.php +++ b/app/src/Model/Product/ProductDomain.php @@ -28,12 +28,6 @@ class ProductDomain extends BaseProductDomain */ protected $calculatedSaleExclusion; - /** - * @var bool - * @ORM\Column(type="boolean") - */ - private $domainHidden; - /** * @param \App\Model\Product\Product $product * @param int $domainId @@ -52,20 +46,4 @@ public function getCalculatedSaleExclusion(): bool { return $this->calculatedSaleExclusion; } - - /** - * @return bool - */ - public function isDomainHidden(): bool - { - return $this->domainHidden; - } - - /** - * @param bool $domainHidden - */ - public function setDomainHidden(bool $domainHidden): void - { - $this->domainHidden = $domainHidden; - } } diff --git a/app/src/Model/Product/ProductVisibilityRepository.php b/app/src/Model/Product/ProductVisibilityRepository.php deleted file mode 100644 index e50b525612..0000000000 --- a/app/src/Model/Product/ProductVisibilityRepository.php +++ /dev/null @@ -1,115 +0,0 @@ - new DateTime(), - 'locale' => null, - 'domainId' => null, - 'pricingGroupId' => null, - 'variantTypeMain' => Product::VARIANT_TYPE_MAIN, - ]; - - $variableTypes = [ - 'now' => Types::DATETIME_MUTABLE, - 'locale' => Types::STRING, - 'domainId' => Types::INTEGER, - 'pricingGroupId' => Types::INTEGER, - 'variantTypeMain' => Types::STRING, - ]; - - if ($productIds !== null) { - $productIdsCondition = 'p.id IN (:productIds) AND'; - $variables['productIds'] = $productIds; - $variableTypes['productIds'] = ArrayParameterType::INTEGER; - } else { - $productIdsCondition = ''; - } - - $query = 'UPDATE product_visibilities AS pv - SET visible = CASE - WHEN ( - p.hidden = FALSE - AND - (p.selling_from IS NULL OR p.selling_from <= :now) - AND - (p.selling_to IS NULL OR p.selling_to >= :now) - AND - ( - p.variant_type = :variantTypeMain - OR - EXISTS ( - SELECT 1 - FROM product_calculated_prices as pcp - WHERE pcp.price_with_vat > 0 - AND pcp.product_id = pv.product_id - AND pcp.pricing_group_id = pv.pricing_group_id - ) - ) - AND EXISTS ( - SELECT 1 - FROM product_translations AS pt - WHERE pt.translatable_id = pv.product_id - AND pt.locale = :locale - AND pt.name IS NOT NULL - ) - AND EXISTS ( - SELECT 1 - FROM product_category_domains AS pcd - JOIN category_domains AS cd ON cd.category_id = pcd.category_id - AND cd.domain_id = pcd.domain_id - WHERE pcd.product_id = p.id - AND pcd.domain_id = pv.domain_id - AND cd.visible = TRUE - ) - AND - (pd.domain_hidden = FALSE) - ) - THEN TRUE - ELSE FALSE - END - FROM products AS p - JOIN product_domains AS pd ON pd.product_id = p.id - WHERE ' . $productIdsCondition . ' - p.id = pv.product_id - AND pv.domain_id = :domainId - AND pv.domain_id = pd.domain_id - AND pv.pricing_group_id = :pricingGroupId - '; - - foreach ($this->pricingGroupRepository->getAll() as $pricingGroup) { - $domain = $this->domain->getDomainConfigById($pricingGroup->getDomainId()); - $variables['locale'] = $domain->getLocale(); - $variables['domainId'] = $domain->getId(); - $variables['pricingGroupId'] = $pricingGroup->getId(); - - $this->em->getConnection()->executeStatement( - $query, - $variables, - $variableTypes, - ); - } - } -} From ac4bcdb66944c6e383b475aaeb991a8ecbcfae56 Mon Sep 17 00:00:00 2001 From: Martin Grossmann Date: Tue, 12 Dec 2023 14:37:01 +0100 Subject: [PATCH 20/32] removed unused product filtering via database --- app/config/services.yaml | 3 -- .../Filter/ProductFilterRepository.php | 51 ------------------- 2 files changed, 54 deletions(-) delete mode 100644 app/src/Model/Product/Filter/ProductFilterRepository.php diff --git a/app/config/services.yaml b/app/config/services.yaml index 4fd1faade3..dab315583b 100644 --- a/app/config/services.yaml +++ b/app/config/services.yaml @@ -513,9 +513,6 @@ services: Shopsys\FrameworkBundle\Model\Product\Filter\ParameterFilterChoiceRepository: alias: App\Model\Product\Filter\ParameterFilterChoiceRepository - Shopsys\FrameworkBundle\Model\Product\Filter\ProductFilterRepository: - alias: App\Model\Product\Filter\ProductFilterRepository - App\Model\AdvancedSearch\ProductAdvancedSearchConfig: ~ Shopsys\FrameworkBundle\Model\AdvancedSearch\ProductAdvancedSearchConfig: diff --git a/app/src/Model/Product/Filter/ProductFilterRepository.php b/app/src/Model/Product/Filter/ProductFilterRepository.php deleted file mode 100644 index c697bc75ad..0000000000 --- a/app/src/Model/Product/Filter/ProductFilterRepository.php +++ /dev/null @@ -1,51 +0,0 @@ -filterByPrice( - $productsQueryBuilder, - $productFilterData->minimalPrice, - $productFilterData->maximalPrice, - $pricingGroup, - ); - $this->filterByFlags( - $productsQueryBuilder, - $productFilterData->flags, - ); - $this->filterByBrands( - $productsQueryBuilder, - $productFilterData->brands, - ); - $this->parameterFilterRepository->filterByParameters( - $productsQueryBuilder, - $productFilterData->parameters, - ); - } -} From 131c7adddf722a9f9ec45c8a73c0c705492e59f1 Mon Sep 17 00:00:00 2001 From: Martin Grossmann Date: Tue, 12 Dec 2023 14:48:36 +0100 Subject: [PATCH 21/32] mandatory methods in FilterQuery moved to shopsys/framework --- app/src/Model/Product/Search/FilterQuery.php | 75 -------------------- 1 file changed, 75 deletions(-) diff --git a/app/src/Model/Product/Search/FilterQuery.php b/app/src/Model/Product/Search/FilterQuery.php index 29d304c913..88c5fbf9f7 100644 --- a/app/src/Model/Product/Search/FilterQuery.php +++ b/app/src/Model/Product/Search/FilterQuery.php @@ -310,81 +310,6 @@ public function filterByPrices( return $clone; } - /** - * Applies all filters for filter - * For flags, brands, stock, parameters, min and max price - * Parameters aggregation have nested structure in result [parameter_id][parameter_value_id] - * - * @param int $pricingGroupId - * @return array - */ - public function getAggregationQueryForProductFilterConfig(int $pricingGroupId): array - { - $query = $this->getAbsoluteNumbersWithParametersQuery(); - - $query['body']['aggs']['prices'] = [ - 'nested' => [ - 'path' => 'prices', - ], - 'aggs' => [ - 'filter_pricing_group' => [ - 'filter' => [ - 'term' => [ - 'prices.pricing_group_id' => $pricingGroupId, - ], - ], - 'aggs' => [ - 'min_price' => [ - 'min' => [ - 'field' => 'prices.price_with_vat', - ], - ], - 'max_price' => [ - 'max' => [ - 'field' => 'prices.price_with_vat', - ], - ], - ], - ], - ], - - ]; - - return $query; - } - - /** - * Applies all filters for filter - * For flags, brands, stock, min and max price - * - * @param int $pricingGroupId - * @return array - */ - public function getAggregationQueryForProductFilterConfigWithoutParameters(int $pricingGroupId): array - { - $query = $this->getAggregationQueryForProductFilterConfig($pricingGroupId); - - // Remove parameters from filter - unset($query['body']['aggs']['parameters']); - - return $query; - } - - /** - * @return array - */ - public function getAggregationQueryForProductCountInCategories(): array - { - $query = $this->getQuery(); - $query['body']['aggs'] = [ - 'by_categories' => [ - 'terms' => ['field' => 'categories'], - ], - ]; - - return $query; - } - /** * @param \App\Model\Product\Filter\ParameterFilterData[] $sliderParametersData * @return \App\Model\Product\Search\FilterQuery From e42d5c8c92b0856c676b0b5de38db6549119df81 Mon Sep 17 00:00:00 2001 From: Martin Grossmann Date: Tue, 12 Dec 2023 14:56:25 +0100 Subject: [PATCH 22/32] category parameters are now moved to shopsys/framework --- .../Demo/CategoryParameterDataFixture.php | 4 +- .../Demo/ParameterDataFixture.php | 2 +- .../Filter/ProductFilterOptionsFactory.php | 4 +- app/src/Migrations/Version20200313082319.php | 43 ------- app/src/Migrations/Version20200422093836.php | 27 ----- app/src/Migrations/Version20200814063510.php | 28 ----- .../Model/Category/CategoryDataFactory.php | 7 +- app/src/Model/Category/CategoryFacade.php | 3 +- app/src/Model/Category/CategoryParameter.php | 105 ------------------ .../Category/CategoryParameterFacade.php | 93 ---------------- .../Category/CategoryParameterRepository.php | 79 ------------- .../ParameterFilterChoiceRepository.php | 2 +- .../Product/Parameter/ParameterFacade.php | 2 +- 13 files changed, 14 insertions(+), 385 deletions(-) delete mode 100644 app/src/Migrations/Version20200313082319.php delete mode 100644 app/src/Migrations/Version20200422093836.php delete mode 100644 app/src/Migrations/Version20200814063510.php delete mode 100644 app/src/Model/Category/CategoryParameter.php delete mode 100644 app/src/Model/Category/CategoryParameterFacade.php delete mode 100644 app/src/Model/Category/CategoryParameterRepository.php diff --git a/app/src/DataFixtures/Demo/CategoryParameterDataFixture.php b/app/src/DataFixtures/Demo/CategoryParameterDataFixture.php index ed2574eb8f..5cc1ffb93e 100644 --- a/app/src/DataFixtures/Demo/CategoryParameterDataFixture.php +++ b/app/src/DataFixtures/Demo/CategoryParameterDataFixture.php @@ -4,7 +4,6 @@ namespace App\DataFixtures\Demo; -use App\Model\Category\CategoryParameterFacade; use App\Model\Product\Parameter\ParameterRepository; use Doctrine\Common\DataFixtures\DependentFixtureInterface; use Doctrine\Persistence\ObjectManager; @@ -12,11 +11,12 @@ use Shopsys\FrameworkBundle\Component\DataFixture\AbstractReferenceFixture; use Shopsys\FrameworkBundle\Component\Domain\Domain; use Shopsys\FrameworkBundle\Component\Translation\Translator; +use Shopsys\FrameworkBundle\Model\Category\CategoryParameterFacade; class CategoryParameterDataFixture extends AbstractReferenceFixture implements DependentFixtureInterface { /** - * @param \App\Model\Category\CategoryParameterFacade $categoryParameterFacade + * @param \Shopsys\FrameworkBundle\Model\Category\CategoryParameterFacade $categoryParameterFacade * @param \App\Model\Product\Parameter\ParameterRepository $parameterRepository * @param \Shopsys\FrameworkBundle\Component\Domain\Domain $domain */ diff --git a/app/src/DataFixtures/Demo/ParameterDataFixture.php b/app/src/DataFixtures/Demo/ParameterDataFixture.php index 2ffacc8eb2..56be35c186 100644 --- a/app/src/DataFixtures/Demo/ParameterDataFixture.php +++ b/app/src/DataFixtures/Demo/ParameterDataFixture.php @@ -4,7 +4,6 @@ namespace App\DataFixtures\Demo; -use App\Model\Category\CategoryParameter; use App\Model\Product\Parameter\Parameter; use App\Model\Product\Parameter\ParameterDataFactory; use App\Model\Product\Parameter\ParameterFacade; @@ -18,6 +17,7 @@ use Shopsys\FrameworkBundle\Component\Domain\Domain; use Shopsys\FrameworkBundle\Component\EntityExtension\EntityManagerDecorator; use Shopsys\FrameworkBundle\Component\Translation\Translator; +use Shopsys\FrameworkBundle\Model\Category\CategoryParameter; use Shopsys\FrameworkBundle\Model\Product\Parameter\ProductParameterValueFactory; class ParameterDataFixture extends AbstractReferenceFixture implements DependentFixtureInterface diff --git a/app/src/FrontendApi/Model/Product/Filter/ProductFilterOptionsFactory.php b/app/src/FrontendApi/Model/Product/Filter/ProductFilterOptionsFactory.php index 9d97195881..32af6af241 100644 --- a/app/src/FrontendApi/Model/Product/Filter/ProductFilterOptionsFactory.php +++ b/app/src/FrontendApi/Model/Product/Filter/ProductFilterOptionsFactory.php @@ -5,7 +5,6 @@ namespace App\FrontendApi\Model\Product\Filter; use App\Model\Category\Category; -use App\Model\Category\CategoryParameterFacade; use App\Model\CategorySeo\ReadyCategorySeoMix; use App\Model\Product\Filter\ProductFilterData; use App\Model\Product\Flag\Flag; @@ -14,6 +13,7 @@ use App\Model\Product\ProductOnCurrentDomainElasticFacade; use InvalidArgumentException; use Shopsys\FrameworkBundle\Model\Category\Category as BaseCategory; +use Shopsys\FrameworkBundle\Model\Category\CategoryParameterFacade; use Shopsys\FrameworkBundle\Model\Module\ModuleFacade; use Shopsys\FrameworkBundle\Model\Module\ModuleList; use Shopsys\FrameworkBundle\Model\Product\Brand\Brand; @@ -41,7 +41,7 @@ class ProductFilterOptionsFactory extends BaseProductFilterOptionsFactory /** * @param \Shopsys\FrameworkBundle\Model\Module\ModuleFacade $moduleFacade * @param \App\Model\Product\ProductOnCurrentDomainElasticFacade $productOnCurrentDomainFacade - * @param \App\Model\Category\CategoryParameterFacade $categoryParameterFacade + * @param \Shopsys\FrameworkBundle\Model\Category\CategoryParameterFacade $categoryParameterFacade */ public function __construct( ModuleFacade $moduleFacade, diff --git a/app/src/Migrations/Version20200313082319.php b/app/src/Migrations/Version20200313082319.php deleted file mode 100644 index 6fb81412b6..0000000000 --- a/app/src/Migrations/Version20200313082319.php +++ /dev/null @@ -1,43 +0,0 @@ -sql(' - CREATE TABLE category_parameters ( - category_id INT NOT NULL, - parameter_id INT NOT NULL, - PRIMARY KEY(category_id, parameter_id) - )'); - $this->sql('CREATE INDEX IDX_208D188012469DE2 ON category_parameters (category_id)'); - $this->sql('CREATE INDEX IDX_208D18807C56DBD6 ON category_parameters (parameter_id)'); - $this->sql(' - ALTER TABLE - category_parameters - ADD - CONSTRAINT FK_208D188012469DE2 FOREIGN KEY (category_id) REFERENCES categories (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE'); - $this->sql(' - ALTER TABLE - category_parameters - ADD - CONSTRAINT FK_208D18807C56DBD6 FOREIGN KEY (parameter_id) REFERENCES parameters (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE'); - } - - /** - * @param \Doctrine\DBAL\Schema\Schema $schema - */ - public function down(Schema $schema): void - { - } -} diff --git a/app/src/Migrations/Version20200422093836.php b/app/src/Migrations/Version20200422093836.php deleted file mode 100644 index 524db55688..0000000000 --- a/app/src/Migrations/Version20200422093836.php +++ /dev/null @@ -1,27 +0,0 @@ -sql('ALTER TABLE category_parameters ADD collapsed BOOLEAN NOT NULL DEFAULT FALSE'); - $this->sql('ALTER TABLE category_parameters ALTER collapsed DROP DEFAULT'); - } - - /** - * @param \Doctrine\DBAL\Schema\Schema $schema - */ - public function down(Schema $schema): void - { - } -} diff --git a/app/src/Migrations/Version20200814063510.php b/app/src/Migrations/Version20200814063510.php deleted file mode 100644 index 0910a56de4..0000000000 --- a/app/src/Migrations/Version20200814063510.php +++ /dev/null @@ -1,28 +0,0 @@ -sql('ALTER TABLE category_parameters ADD position INT NOT NULL DEFAULT 1'); - $this->sql('ALTER TABLE category_parameters ALTER position DROP DEFAULT'); - $this->sql('CREATE INDEX ordering_idx ON category_parameters (position)'); - } - - /** - * @param \Doctrine\DBAL\Schema\Schema $schema - */ - public function down(Schema $schema): void - { - } -} diff --git a/app/src/Model/Category/CategoryDataFactory.php b/app/src/Model/Category/CategoryDataFactory.php index 94fca11b56..cf90780f4f 100644 --- a/app/src/Model/Category/CategoryDataFactory.php +++ b/app/src/Model/Category/CategoryDataFactory.php @@ -13,6 +13,7 @@ use Shopsys\FrameworkBundle\Model\Category\Category as BaseCategory; use Shopsys\FrameworkBundle\Model\Category\CategoryData as BaseCategoryData; use Shopsys\FrameworkBundle\Model\Category\CategoryDataFactory as BaseCategoryDataFactory; +use Shopsys\FrameworkBundle\Model\Category\CategoryParameterRepository; /** * @property \App\Component\Router\FriendlyUrl\FriendlyUrlFacade $friendlyUrlFacade @@ -24,7 +25,7 @@ class CategoryDataFactory extends BaseCategoryDataFactory * @param \Shopsys\FrameworkBundle\Component\Plugin\PluginCrudExtensionFacade $pluginCrudExtensionFacade * @param \Shopsys\FrameworkBundle\Component\Domain\Domain $domain * @param \Shopsys\FrameworkBundle\Component\FileUpload\ImageUploadDataFactory $imageUploadDataFactory - * @param \App\Model\Category\CategoryParameterRepository $categoryParameterRepository + * @param \Shopsys\FrameworkBundle\Model\Category\CategoryParameterRepository $categoryParameterRepository * @param \App\Model\Category\LinkedCategory\LinkedCategoryRepository $linkedCategoryRepository */ public function __construct( @@ -96,7 +97,9 @@ protected function fillFromCategory(BaseCategoryData $categoryData, BaseCategory parent::fillFromCategory($categoryData, $category); $categoryData->akeneoCode = $category->getAkeneoCode(); - $categoryData->parametersCollapsed = $this->categoryParameterRepository->getParametersCollapsedByCategory($category); + /** @var \App\Model\Product\Parameter\Parameter[] $parameters */ + $parameters = $this->categoryParameterRepository->getParametersCollapsedByCategory($category); + $categoryData->parametersCollapsed = $parameters; $categoryData->parametersPosition = $this->getParametersSortedByPositionFilteredByCategory($category); $linkedCategories = $this->linkedCategoryRepository->getAllByParentCategory($category); diff --git a/app/src/Model/Category/CategoryFacade.php b/app/src/Model/Category/CategoryFacade.php index 37192ee3ad..36590d74b0 100644 --- a/app/src/Model/Category/CategoryFacade.php +++ b/app/src/Model/Category/CategoryFacade.php @@ -17,6 +17,7 @@ use Shopsys\FrameworkBundle\Model\Category\CategoryData; use Shopsys\FrameworkBundle\Model\Category\CategoryFacade as BaseCategoryFacade; use Shopsys\FrameworkBundle\Model\Category\CategoryFactoryInterface; +use Shopsys\FrameworkBundle\Model\Category\CategoryParameterFacade; use Shopsys\FrameworkBundle\Model\Category\CategoryRepository; use Shopsys\FrameworkBundle\Model\Category\CategoryVisibilityRecalculationScheduler; use Shopsys\FrameworkBundle\Model\Category\CategoryWithLazyLoadedVisibleChildrenFactory; @@ -68,7 +69,7 @@ class CategoryFacade extends BaseCategoryFacade * @param \Shopsys\FrameworkBundle\Model\Category\CategoryFactory $categoryFactory * @param \Shopsys\FrameworkBundle\Model\Product\Recalculation\ProductRecalculationDispatcher $productRecalculationDispatcher * @param \Symfony\Component\EventDispatcher\EventDispatcherInterface $eventDispatcher - * @param \App\Model\Category\CategoryParameterFacade $categoryParameterFacade + * @param \Shopsys\FrameworkBundle\Model\Category\CategoryParameterFacade $categoryParameterFacade * @param \App\Model\Category\LinkedCategory\LinkedCategoryFacade $linkedCategoryFacade * @param \App\Model\Product\ProductOnCurrentDomainElasticFacade $productOnCurrentDomainElasticFacade */ diff --git a/app/src/Model/Category/CategoryParameter.php b/app/src/Model/Category/CategoryParameter.php deleted file mode 100644 index 374d6d6366..0000000000 --- a/app/src/Model/Category/CategoryParameter.php +++ /dev/null @@ -1,105 +0,0 @@ -category = $category; - $this->parameter = $parameter; - $this->collapsed = $collapsed; - $this->position = $position; - } - - /** - * @return \App\Model\Category\Category - */ - public function getCategory(): Category - { - return $this->category; - } - - /** - * @return \App\Model\Product\Parameter\Parameter - */ - public function getParameter(): Parameter - { - return $this->parameter; - } - - /** - * @return bool - */ - public function isCollapsed(): bool - { - return $this->collapsed; - } - - /** - * @param bool $collapsed - */ - public function setCollapsed(bool $collapsed): void - { - $this->collapsed = $collapsed; - } - - /** - * @return int - */ - public function getPosition(): int - { - return $this->position; - } - - /** - * @param int $position - */ - public function setPosition(int $position): void - { - $this->position = $position; - } -} diff --git a/app/src/Model/Category/CategoryParameterFacade.php b/app/src/Model/Category/CategoryParameterFacade.php deleted file mode 100644 index dc8dce78d8..0000000000 --- a/app/src/Model/Category/CategoryParameterFacade.php +++ /dev/null @@ -1,93 +0,0 @@ -getId()] = true; - } - - $oldCategoryParameters = $this->categoryParameterRepository->getAllByCategory($category); - $oldCategoryParametersById = []; - - foreach ($oldCategoryParameters as $oldCategoryParameter) { - $oldCategoryParametersById[$oldCategoryParameter->getParameter()->getId()] = $oldCategoryParameter; - } - $catFlushAfterSaveRelation = false; - - foreach ($parameterIds as $position => $parameterId) { - $collapsed = false; - - if (array_key_exists($parameterId, $parametersCollapsedById)) { - $collapsed = true; - } - - if (array_key_exists($parameterId, $oldCategoryParametersById)) { - $oldCategoryParameter = $oldCategoryParametersById[$parameterId]; - - if ($oldCategoryParameter->isCollapsed() !== $collapsed) { - $oldCategoryParameter->setCollapsed($collapsed); - $catFlushAfterSaveRelation = true; - } - - if ($oldCategoryParameter->getPosition() !== $position) { - $oldCategoryParameter->setPosition($position); - $catFlushAfterSaveRelation = true; - } - unset($oldCategoryParametersById[$parameterId]); - - continue; - } - - $parameter = $this->parameterFacade->getById($parameterId); - $categoryParameter = new CategoryParameter($category, $parameter, $collapsed, $position); - $this->em->persist($categoryParameter); - $catFlushAfterSaveRelation = true; - } - - foreach ($oldCategoryParametersById as $oldCategoryParameter) { - $this->em->remove($oldCategoryParameter); - $catFlushAfterSaveRelation = true; - } - - if ($catFlushAfterSaveRelation) { - $this->em->flush(); - } - } - - /** - * @param \App\Model\Category\Category $category - * @return \App\Model\Product\Parameter\Parameter[] - */ - public function getParametersCollapsedByCategory(Category $category): array - { - return $this->categoryParameterRepository->getParametersCollapsedByCategory($category); - } -} diff --git a/app/src/Model/Category/CategoryParameterRepository.php b/app/src/Model/Category/CategoryParameterRepository.php deleted file mode 100644 index 3d62631864..0000000000 --- a/app/src/Model/Category/CategoryParameterRepository.php +++ /dev/null @@ -1,79 +0,0 @@ -em->getRepository(CategoryParameter::class); - } - - /** - * @return \Doctrine\ORM\QueryBuilder - */ - private function getQueryBuilder(): QueryBuilder - { - return $this->em->createQueryBuilder() - ->select('cp') - ->from(CategoryParameter::class, 'cp'); - } - - /** - * @param \App\Model\Category\Category $category - * @return \App\Model\Category\CategoryParameter[] - */ - public function getAllByCategory(Category $category): array - { - return $this->getRepository()->findBy(['category' => $category]); - } - - /** - * @param \App\Model\Category\Category $category - * @return \App\Model\Category\CategoryParameter[] - */ - public function getCategoryParametersByCategorySortedByPosition(Category $category): array - { - return $this->getQueryBuilder() - ->join(Parameter::class, 'p', Join::WITH, 'cp.parameter = p') - ->where('cp.category = :category') - ->setParameter('category', $category) - ->orderBy('cp.position') - ->getQuery() - ->execute(); - } - - /** - * @param \App\Model\Category\Category $category - * @return \App\Model\Product\Parameter\Parameter[] - */ - public function getParametersCollapsedByCategory(Category $category): array - { - return $this->getQueryBuilder() - ->select('p') - ->join(Parameter::class, 'p', Join::WITH, 'cp.parameter = p') - ->where('cp.category = :category') - ->andWhere('cp.collapsed = true') - ->setParameter('category', $category) - ->getQuery() - ->execute(); - } -} diff --git a/app/src/Model/Product/Filter/ParameterFilterChoiceRepository.php b/app/src/Model/Product/Filter/ParameterFilterChoiceRepository.php index 915a020cd3..224391a449 100644 --- a/app/src/Model/Product/Filter/ParameterFilterChoiceRepository.php +++ b/app/src/Model/Product/Filter/ParameterFilterChoiceRepository.php @@ -5,10 +5,10 @@ namespace App\Model\Product\Filter; use App\Component\Doctrine\OrderByCollationHelper; -use App\Model\Category\CategoryParameter; use Doctrine\ORM\Query\Expr\Join; use Shopsys\FrameworkBundle\Component\Doctrine\GroupedScalarHydrator; use Shopsys\FrameworkBundle\Model\Category\Category; +use Shopsys\FrameworkBundle\Model\Category\CategoryParameter; use Shopsys\FrameworkBundle\Model\Pricing\Group\PricingGroup; use Shopsys\FrameworkBundle\Model\Product\Filter\ParameterFilterChoice; use Shopsys\FrameworkBundle\Model\Product\Filter\ParameterFilterChoiceRepository as BaseParameterFilterChoiceRepository; diff --git a/app/src/Model/Product/Parameter/ParameterFacade.php b/app/src/Model/Product/Parameter/ParameterFacade.php index b2b6f7ab70..83000bbed6 100644 --- a/app/src/Model/Product/Parameter/ParameterFacade.php +++ b/app/src/Model/Product/Parameter/ParameterFacade.php @@ -6,10 +6,10 @@ use App\Component\UploadedFile\UploadedFileFacade; use App\Model\Category\Category; -use App\Model\Category\CategoryParameterRepository; use App\Model\CategorySeo\ReadyCategorySeoMixFacade; use Doctrine\ORM\EntityManagerInterface; use Shopsys\FrameworkBundle\Model\Product\Filter\ParameterFilterChoice; +use Shopsys\FrameworkBundle\Model\Category\CategoryParameterRepository; use Shopsys\FrameworkBundle\Model\Product\Parameter\ParameterFacade as BaseParameterFacade; use Shopsys\FrameworkBundle\Model\Product\Parameter\ParameterFactoryInterface; use Shopsys\FrameworkBundle\Model\Product\Parameter\ParameterRepository; From dd3954e20c352a939a196dc5c4990a1aedaf163c Mon Sep 17 00:00:00 2001 From: Martin Grossmann Date: Tue, 12 Dec 2023 14:59:14 +0100 Subject: [PATCH 23/32] OrderByCollationHelper is now moved to shopsys/framework --- .../Doctrine/OrderByCollationHelper.php | 29 ------------------- .../Model/Category/CategoryRepository.php | 2 +- app/src/Model/Category/CategoryRepository.php | 2 +- .../ReadyCategorySeoMixRepository.php | 2 +- app/src/Model/Country/CountryRepository.php | 2 +- .../Filter/BrandFilterChoiceRepository.php | 2 +- .../Filter/FlagFilterChoiceRepository.php | 2 +- .../ParameterFilterChoiceRepository.php | 2 +- app/src/Model/Product/Flag/FlagRepository.php | 2 +- .../Product/Parameter/ParameterRepository.php | 2 +- 10 files changed, 9 insertions(+), 38 deletions(-) delete mode 100644 app/src/Component/Doctrine/OrderByCollationHelper.php diff --git a/app/src/Component/Doctrine/OrderByCollationHelper.php b/app/src/Component/Doctrine/OrderByCollationHelper.php deleted file mode 100644 index 94abc2c66f..0000000000 --- a/app/src/Component/Doctrine/OrderByCollationHelper.php +++ /dev/null @@ -1,29 +0,0 @@ - Date: Tue, 12 Dec 2023 15:05:18 +0100 Subject: [PATCH 24/32] product filtering from Elasticsearch is now moved to shopsys/framework --- .../Product/Filter/ProductFilterFacade.php | 22 +-- app/src/Model/Product/Brand/BrandFacade.php | 10 +- .../Model/Product/Brand/BrandRepository.php | 31 +---- .../ProductFilterConfigFactory.php | 106 +------------- .../ProductFilterConfigIdsData.php | 56 -------- .../ProductFilterConfigIdsDataFactory.php | 116 ---------------- .../ProductFilterElasticFacade.php | 131 ------------------ app/src/Model/Product/Flag/FlagFacade.php | 11 +- app/src/Model/Product/Flag/FlagRepository.php | 20 +-- .../Product/Parameter/ParameterFacade.php | 55 +------- .../Product/Parameter/ParameterRepository.php | 41 +----- ...urrentDomainElasticFacadeCountDataTest.php | 2 +- 12 files changed, 19 insertions(+), 582 deletions(-) delete mode 100644 app/src/Model/Product/Filter/Elasticsearch/ProductFilterConfigIdsData.php delete mode 100644 app/src/Model/Product/Filter/Elasticsearch/ProductFilterConfigIdsDataFactory.php delete mode 100644 app/src/Model/Product/Filter/Elasticsearch/ProductFilterElasticFacade.php diff --git a/app/src/FrontendApi/Model/Product/Filter/ProductFilterFacade.php b/app/src/FrontendApi/Model/Product/Filter/ProductFilterFacade.php index 708ef31d50..4fa20f6938 100644 --- a/app/src/FrontendApi/Model/Product/Filter/ProductFilterFacade.php +++ b/app/src/FrontendApi/Model/Product/Filter/ProductFilterFacade.php @@ -20,6 +20,7 @@ * @property \App\FrontendApi\Model\Product\Filter\ProductFilterDataMapper $productFilterDataMapper * @property \App\Model\Product\Filter\Elasticsearch\ProductFilterConfigFactory $productFilterConfigFactory * @method \App\Model\Product\Filter\ProductFilterData getValidatedProductFilterData(\Overblog\GraphQLBundle\Definition\Argument $argument, \Shopsys\FrameworkBundle\Model\Product\Filter\ProductFilterConfig $productFilterConfig) + * @method \Shopsys\FrameworkBundle\Model\Product\Filter\ProductFilterConfig getProductFilterConfigForCategory(\App\Model\Category\Category $category, string $searchText = "") */ class ProductFilterFacade extends BaseProductFilterFacade { @@ -155,27 +156,6 @@ public function getProductFilterConfigForSearch(string $searchText): ProductFilt return $this->productFilterConfigCache[$cacheKey]; } - /** - * @param \App\Model\Category\Category $category - * @param string $searchText - * @return \Shopsys\FrameworkBundle\Model\Product\Filter\ProductFilterConfig - */ - public function getProductFilterConfigForCategory(Category $category, string $searchText = ''): ProductFilterConfig - { - $cacheKey = 'category_' . $category->getId() . '_search_' . $searchText; - - if (!array_key_exists($cacheKey, $this->productFilterConfigCache)) { - $this->productFilterConfigCache[$cacheKey] = $this->productFilterConfigFactory->createForCategory( - $this->domain->getId(), - $this->domain->getLocale(), - $category, - $searchText, - ); - } - - return $this->productFilterConfigCache[$cacheKey]; - } - /** * @param \App\Model\Product\Brand\Brand $brand * @param string $searchText diff --git a/app/src/Model/Product/Brand/BrandFacade.php b/app/src/Model/Product/Brand/BrandFacade.php index 251d5dad1e..3624337ff4 100644 --- a/app/src/Model/Product/Brand/BrandFacade.php +++ b/app/src/Model/Product/Brand/BrandFacade.php @@ -18,6 +18,7 @@ * @method \App\Model\Product\Brand\Brand getByUuid(string $uuid) * @method \App\Model\Product\Brand\Brand[] getByUuids(string[] $uuids) * @property \App\Component\Router\FriendlyUrl\FriendlyUrlFacade $friendlyUrlFacade + * @method \App\Model\Product\Brand\Brand[] getBrandsByIds(int[] $brandsIds) */ class BrandFacade extends BaseBrandFacade { @@ -29,13 +30,4 @@ public function getBrandsForSearchText(string $searchText): array { return $this->brandRepository->getResultsForSearch($searchText); } - - /** - * @param int[] $brandsIds - * @return \App\Model\Product\Brand\Brand[] - */ - public function getBrandsByIds(array $brandsIds): array - { - return $this->brandRepository->getBrandsByIds($brandsIds); - } } diff --git a/app/src/Model/Product/Brand/BrandRepository.php b/app/src/Model/Product/Brand/BrandRepository.php index 943abad7cb..34715e9ace 100644 --- a/app/src/Model/Product/Brand/BrandRepository.php +++ b/app/src/Model/Product/Brand/BrandRepository.php @@ -4,10 +4,8 @@ namespace App\Model\Product\Brand; -use App\Component\Doctrine\OrderByCollationHelper; -use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\QueryBuilder; -use Shopsys\FrameworkBundle\Component\Domain\Domain; +use Shopsys\FrameworkBundle\Component\Doctrine\OrderByCollationHelper; use Shopsys\FrameworkBundle\Component\String\DatabaseSearching; use Shopsys\FrameworkBundle\Model\Product\Brand\BrandRepository as BaseBrandRepository; @@ -16,20 +14,10 @@ * @method \App\Model\Product\Brand\Brand[] getAll() * @method \App\Model\Product\Brand\Brand getOneByUuid(string $uuid) * @method \App\Model\Product\Brand\Brand[] getByUuids(string[] $uuids) + * @method \App\Model\Product\Brand\Brand[] getBrandsByIds(int[] $brandsIds) */ class BrandRepository extends BaseBrandRepository { - /** - * @param \Doctrine\ORM\EntityManagerInterface $entityManager - * @param \Shopsys\FrameworkBundle\Component\Domain\Domain $domain - */ - public function __construct( - EntityManagerInterface $entityManager, - private Domain $domain, - ) { - parent::__construct($entityManager); - } - /** * @param string $searchText * @return array @@ -57,19 +45,4 @@ protected function getBySearchTextQueryBuilder($searchText): QueryBuilder return $queryBuilder; } - - /** - * @param int[] $brandsIds - * @return \App\Model\Product\Brand\Brand[] - */ - public function getBrandsByIds(array $brandsIds): array - { - $brandsQueryBuilder = $this->getBrandRepository()->createQueryBuilder('b') - ->select('b') - ->where('b.id IN (:brandIds)') - ->setParameter('brandIds', $brandsIds) - ->orderBy(OrderByCollationHelper::createOrderByForLocale('b.name', $this->domain->getLocale()), 'asc'); - - return $brandsQueryBuilder->getQuery()->getResult(); - } } diff --git a/app/src/Model/Product/Filter/Elasticsearch/ProductFilterConfigFactory.php b/app/src/Model/Product/Filter/Elasticsearch/ProductFilterConfigFactory.php index f4c271cd11..12503c68b8 100644 --- a/app/src/Model/Product/Filter/Elasticsearch/ProductFilterConfigFactory.php +++ b/app/src/Model/Product/Filter/Elasticsearch/ProductFilterConfigFactory.php @@ -4,18 +4,8 @@ namespace App\Model\Product\Filter\Elasticsearch; -use App\Model\Category\Category; -use App\Model\Product\Brand\BrandFacade; use App\Model\Product\Flag\Flag; -use App\Model\Product\Flag\FlagFacade; -use App\Model\Product\Parameter\ParameterFacade; -use Shopsys\FrameworkBundle\Model\Category\Category as BaseCategory; -use Shopsys\FrameworkBundle\Model\Customer\User\CurrentCustomerUser; use Shopsys\FrameworkBundle\Model\Product\Brand\Brand; -use Shopsys\FrameworkBundle\Model\Product\Filter\BrandFilterChoiceRepository; -use Shopsys\FrameworkBundle\Model\Product\Filter\FlagFilterChoiceRepository; -use Shopsys\FrameworkBundle\Model\Product\Filter\ParameterFilterChoiceRepository; -use Shopsys\FrameworkBundle\Model\Product\Filter\PriceRangeRepository; use Shopsys\FrameworkBundle\Model\Product\Filter\ProductFilterConfig; use Shopsys\FrameworkBundle\Model\Product\Filter\ProductFilterConfigFactory as BaseProductFilterConfigFactory; @@ -25,72 +15,15 @@ * @property \App\Model\Product\Filter\PriceRangeRepository $priceRangeRepository * @property \App\Model\Product\Filter\BrandFilterChoiceRepository $brandFilterChoiceRepository * @property \App\Model\Customer\User\CurrentCustomerUser $currentCustomerUser + * @property \App\Model\Product\Parameter\ParameterFacade $parameterFacade + * @property \App\Model\Product\Flag\FlagFacade $flagFacade + * @property \App\Model\Product\Brand\BrandFacade $brandFacade + * @method __construct(\App\Model\Product\Filter\ParameterFilterChoiceRepository $parameterFilterChoiceRepository, \App\Model\Product\Filter\FlagFilterChoiceRepository $flagFilterChoiceRepository, \App\Model\Customer\User\CurrentCustomerUser $currentCustomerUser, \App\Model\Product\Filter\BrandFilterChoiceRepository $brandFilterChoiceRepository, \App\Model\Product\Filter\PriceRangeRepository $priceRangeRepository, \Shopsys\FrameworkBundle\Model\Product\Filter\ProductFilterElasticFacade $productFilterElasticFacade, \App\Model\Product\Parameter\ParameterFacade $parameterFacade, \App\Model\Product\Flag\FlagFacade $flagFacade, \App\Model\Product\Brand\BrandFacade $brandFacade) + * @method \Shopsys\FrameworkBundle\Model\Product\Filter\ProductFilterConfig createForCategory(string $locale, \App\Model\Category\Category $category, string $searchText) + * @method \Shopsys\FrameworkBundle\Model\Product\Filter\ParameterFilterChoice[] getSortedParameterFilterChoicesForCategory(\Shopsys\FrameworkBundle\Model\Product\Filter\ParameterFilterChoice[] $aggregatedParameterFilterChoices, \App\Model\Category\Category $category) */ class ProductFilterConfigFactory extends BaseProductFilterConfigFactory { - /** - * @param \App\Model\Product\Filter\ParameterFilterChoiceRepository $parameterFilterChoiceRepository - * @param \App\Model\Product\Filter\FlagFilterChoiceRepository $flagFilterChoiceRepository - * @param \App\Model\Customer\User\CurrentCustomerUser $currentCustomerUser - * @param \App\Model\Product\Filter\BrandFilterChoiceRepository $brandFilterChoiceRepository - * @param \App\Model\Product\Filter\PriceRangeRepository $priceRangeRepository - * @param \App\Model\Product\Filter\Elasticsearch\ProductFilterElasticFacade $productFilterElasticFacade - * @param \App\Model\Product\Flag\FlagFacade $flagFacade - * @param \App\Model\Product\Brand\BrandFacade $brandFacade - * @param \App\Model\Product\Parameter\ParameterFacade $parameterFacade - */ - public function __construct( - ParameterFilterChoiceRepository $parameterFilterChoiceRepository, - FlagFilterChoiceRepository $flagFilterChoiceRepository, - CurrentCustomerUser $currentCustomerUser, - BrandFilterChoiceRepository $brandFilterChoiceRepository, - PriceRangeRepository $priceRangeRepository, - private readonly ProductFilterElasticFacade $productFilterElasticFacade, - private readonly FlagFacade $flagFacade, - private readonly BrandFacade $brandFacade, - private readonly ParameterFacade $parameterFacade, - ) { - parent::__construct( - $parameterFilterChoiceRepository, - $flagFilterChoiceRepository, - $currentCustomerUser, - $brandFilterChoiceRepository, - $priceRangeRepository, - ); - } - - /** - * @param int $domainId - * @param string $locale - * @param \App\Model\Category\Category $category - * @param string $searchText - * @return \Shopsys\FrameworkBundle\Model\Product\Filter\ProductFilterConfig - */ - public function createForCategory( - $domainId, - $locale, - BaseCategory $category, - string $searchText = '', - ): ProductFilterConfig { - $productFilterConfigIdsData = $this->productFilterElasticFacade->getProductFilterDataInCategory( - $category->getId(), - $this->currentCustomerUser->getPricingGroup(), - $searchText, - ); - - $aggregatedParameterFilterChoices = $this->parameterFacade->getParameterFilterChoicesByIds( - $productFilterConfigIdsData->getParameterValueIdsByParameterId(), - $locale, - ); - - return new ProductFilterConfig( - $this->getSortedParameterFilterChoicesForCategory($aggregatedParameterFilterChoices, $category), - $this->flagFacade->getVisibleFlagsByIds($productFilterConfigIdsData->getFlagIds(), $locale), - $this->brandFacade->getBrandsByIds($productFilterConfigIdsData->getBrandIds()), - $productFilterConfigIdsData->getPriceRange(), - ); - } - /** * @param int $domainId * @param string $locale @@ -179,31 +112,4 @@ public function createForAll(int $domainId, string $locale): ProductFilterConfig $productFilterConfigIdsData->getPriceRange(), ); } - - /** - * @param \Shopsys\FrameworkBundle\Model\Product\Filter\ParameterFilterChoice[] $aggregatedParameterFilterChoices - * @param \App\Model\Category\Category $category - * @return \Shopsys\FrameworkBundle\Model\Product\Filter\ParameterFilterChoice[] - */ - private function getSortedParameterFilterChoicesForCategory( - array $aggregatedParameterFilterChoices, - Category $category, - ): array { - $aggregatedParametersFilterChoicesIndexedByParameterId = []; - - foreach ($aggregatedParameterFilterChoices as $aggregatedParameterFilterChoice) { - $aggregatedParametersFilterChoicesIndexedByParameterId[$aggregatedParameterFilterChoice->getParameter()->getId()] = $aggregatedParameterFilterChoice; - } - - $sortedParameterFilterChoices = []; - - foreach ($this->parameterFacade->getParametersIdsSortedByPositionFilteredByCategory($category) as $sortedParameterId) { - if (!array_key_exists($sortedParameterId, $aggregatedParametersFilterChoicesIndexedByParameterId)) { - continue; - } - $sortedParameterFilterChoices[] = $aggregatedParametersFilterChoicesIndexedByParameterId[$sortedParameterId]; - } - - return $sortedParameterFilterChoices; - } } diff --git a/app/src/Model/Product/Filter/Elasticsearch/ProductFilterConfigIdsData.php b/app/src/Model/Product/Filter/Elasticsearch/ProductFilterConfigIdsData.php deleted file mode 100644 index 9d8e89f571..0000000000 --- a/app/src/Model/Product/Filter/Elasticsearch/ProductFilterConfigIdsData.php +++ /dev/null @@ -1,56 +0,0 @@ -brandIds; - } - - /** - * @return int[] - */ - public function getFlagIds(): array - { - return $this->flagIds; - } - - /** - * @return \Shopsys\FrameworkBundle\Model\Product\Filter\PriceRange - */ - public function getPriceRange(): PriceRange - { - return $this->priceRange; - } - - /** - * @return array - */ - public function getParameterValueIdsByParameterId(): array - { - return $this->parameterValueIdsByParameterId; - } -} diff --git a/app/src/Model/Product/Filter/Elasticsearch/ProductFilterConfigIdsDataFactory.php b/app/src/Model/Product/Filter/Elasticsearch/ProductFilterConfigIdsDataFactory.php deleted file mode 100644 index 90e390c4aa..0000000000 --- a/app/src/Model/Product/Filter/Elasticsearch/ProductFilterConfigIdsDataFactory.php +++ /dev/null @@ -1,116 +0,0 @@ -extractParameterValueIdsByParameterId($aggregationElasticsearchResult), - $this->extractFlagIds($aggregationElasticsearchResult), - $this->extractBrandIds($aggregationElasticsearchResult), - $this->extractPriceRange($aggregationElasticsearchResult), - ); - } - - /** - * @param array $aggregationResult - * @return int[] - */ - private function extractBrandIds(array $aggregationResult): array - { - $brandsData = $aggregationResult['brands']['buckets']; - - if (count($brandsData) === 0) { - return []; - } - - return array_map(function (array $data) { - return $data['key']; - }, $brandsData); - } - - /** - * @param array $aggregationResult - * @return int[] - */ - private function extractFlagIds(array $aggregationResult): array - { - $flagsData = $aggregationResult['flags']['buckets']; - - if (count($flagsData) === 0) { - return []; - } - - return array_map(function (array $data) { - return $data['key']; - }, $flagsData); - } - - /** - * @param array $aggregationResult - * @return \Shopsys\FrameworkBundle\Model\Product\Filter\PriceRange - */ - private function extractPriceRange(array $aggregationResult): PriceRange - { - $pricesData = $aggregationResult['prices']['filter_pricing_group']; - - $minPrice = Money::create((string)($pricesData['min_price']['value'] ?? 0)); - $maxPrice = Money::create((string)($pricesData['max_price']['value'] ?? 0)); - - $minPrice = $minPrice->round($this->currencyFacade->getDomainDefaultCurrencyByDomainId($this->domain->getId())->getMinFractionDigits()); - $maxPrice = $maxPrice->round($this->currencyFacade->getDomainDefaultCurrencyByDomainId($this->domain->getId())->getMinFractionDigits()); - - return new PriceRange($minPrice, $maxPrice); - } - - /** - * @param array $aggregationResult - * @return array - */ - private function extractParameterValueIdsByParameterId(array $aggregationResult): array - { - if (!array_key_exists('parameters', $aggregationResult)) { - return []; - } - - $parametersData = $aggregationResult['parameters']['by_parameters']['buckets']; - - $parameterValueIdsIndexedByParameterId = []; - - foreach ($parametersData as $parameter) { - $parameterValueIdsIndexedByParameterId[$parameter['key']] = array_map(function ($parameterValue) { - return $parameterValue['key']; - }, $parameter['by_value']['buckets']); - } - - if (count($parameterValueIdsIndexedByParameterId) === 0) { - return []; - } - - return $parameterValueIdsIndexedByParameterId; - } -} diff --git a/app/src/Model/Product/Filter/Elasticsearch/ProductFilterElasticFacade.php b/app/src/Model/Product/Filter/Elasticsearch/ProductFilterElasticFacade.php deleted file mode 100644 index f47375d489..0000000000 --- a/app/src/Model/Product/Filter/Elasticsearch/ProductFilterElasticFacade.php +++ /dev/null @@ -1,131 +0,0 @@ -filterQueryFactory->createVisible() - ->filterOnlySellable() - ->filterByCategory([$categoryId]); - - if ($search !== '') { - $filterQuery = $filterQuery->search($search); - } - $aggregationQuery = $filterQuery - ->getAggregationQueryForProductFilterConfig($pricingGroup->getId()); - $aggregationResult = $this->client->search($aggregationQuery)['aggregations']; - - return $this->productFilterConfigIdsDataFactory->createFromElasticsearchAggregationResult($aggregationResult); - } - - /** - * @param string $searchText - * @param \Shopsys\FrameworkBundle\Model\Pricing\Group\PricingGroup $pricingGroup - * @return \App\Model\Product\Filter\Elasticsearch\ProductFilterConfigIdsData - */ - public function getProductFilterDataForSearch( - string $searchText, - PricingGroup $pricingGroup, - ): ProductFilterConfigIdsData { - $aggregationQuery = $this->filterQueryFactory->createVisible() - ->filterOnlySellable() - ->search($searchText) - ->getAggregationQueryForProductFilterConfigWithoutParameters($pricingGroup->getId()); - $aggregationResult = $this->client->search($aggregationQuery)['aggregations']; - - return $this->productFilterConfigIdsDataFactory->createFromElasticsearchAggregationResult($aggregationResult); - } - - /** - * @param int $brandId - * @param \Shopsys\FrameworkBundle\Model\Pricing\Group\PricingGroup $pricingGroup - * @param string $searchText - * @return \App\Model\Product\Filter\Elasticsearch\ProductFilterConfigIdsData - */ - public function getProductFilterDataInBrand( - int $brandId, - PricingGroup $pricingGroup, - string $searchText = '', - ): ProductFilterConfigIdsData { - $filterQuery = $this->filterQueryFactory->createVisible() - ->filterOnlySellable() - ->filterByBrands([$brandId]); - - if ($searchText !== '') { - $filterQuery = $filterQuery->search($searchText); - } - $aggregationQuery = $filterQuery - ->getAggregationQueryForProductFilterConfig($pricingGroup->getId()); - $aggregationResult = $this->client->search($aggregationQuery)['aggregations']; - - return $this->productFilterConfigIdsDataFactory->createFromElasticsearchAggregationResult($aggregationResult); - } - - /** - * @param int $flagId - * @param \Shopsys\FrameworkBundle\Model\Pricing\Group\PricingGroup $pricingGroup - * @param string $searchText - * @return \App\Model\Product\Filter\Elasticsearch\ProductFilterConfigIdsData - */ - public function getProductFilterDataInFlag( - int $flagId, - PricingGroup $pricingGroup, - string $searchText = '', - ): ProductFilterConfigIdsData { - $filterQuery = $this->filterQueryFactory->createVisible() - ->filterOnlySellable() - ->filterByFlags([$flagId]); - - if ($searchText !== '') { - $filterQuery = $filterQuery->search($searchText); - } - $aggregationQuery = $filterQuery - ->getAggregationQueryForProductFilterConfig($pricingGroup->getId()); - $aggregationResult = $this->client->search($aggregationQuery)['aggregations']; - - return $this->productFilterConfigIdsDataFactory->createFromElasticsearchAggregationResult($aggregationResult); - } - - /** - * @param \Shopsys\FrameworkBundle\Model\Pricing\Group\PricingGroup $pricingGroup - * @return \App\Model\Product\Filter\Elasticsearch\ProductFilterConfigIdsData - */ - public function getProductFilterDataForAll(PricingGroup $pricingGroup): ProductFilterConfigIdsData - { - $aggregationQuery = $this->filterQueryFactory->createVisible() - ->filterOnlySellable() - ->getAggregationQueryForProductFilterConfig($pricingGroup->getId()); - $aggregationResult = $this->client->search($aggregationQuery)['aggregations']; - - return $this->productFilterConfigIdsDataFactory->createFromElasticsearchAggregationResult($aggregationResult); - } -} diff --git a/app/src/Model/Product/Flag/FlagFacade.php b/app/src/Model/Product/Flag/FlagFacade.php index 87804114d5..25843b3289 100644 --- a/app/src/Model/Product/Flag/FlagFacade.php +++ b/app/src/Model/Product/Flag/FlagFacade.php @@ -20,6 +20,7 @@ * @method \App\Model\Product\Flag\Flag[] getByIds(int[] $flagIds) * @method \App\Model\Product\Flag\Flag getByUuid(string $uuid) * @method \App\Model\Product\Flag\Flag[] getByUuids(string[] $uuids) + * @method \App\Model\Product\Flag\Flag[] getVisibleFlagsByIds(int[] $flagsIds, string $locale) */ class FlagFacade extends BaseFlagFacade { @@ -108,16 +109,6 @@ public function deleteByAkeneoCode(string $akeneoCode): bool return false; } - /** - * @param int[] $flagsIds - * @param string $locale - * @return \App\Model\Product\Flag\Flag[] - */ - public function getVisibleFlagsByIds(array $flagsIds, string $locale): array - { - return $this->flagRepository->getVisibleFlagsByIds($flagsIds, $locale); - } - /** * @param string $locale * @return \App\Model\Product\Flag\Flag[] diff --git a/app/src/Model/Product/Flag/FlagRepository.php b/app/src/Model/Product/Flag/FlagRepository.php index abf8270f8b..e35e61cf48 100644 --- a/app/src/Model/Product/Flag/FlagRepository.php +++ b/app/src/Model/Product/Flag/FlagRepository.php @@ -18,6 +18,7 @@ * @method \App\Model\Product\Flag\Flag[] getByIds(int[] $flagIds) * @method \App\Model\Product\Flag\Flag getByUuid(string $uuid) * @method \App\Model\Product\Flag\Flag[] getByUuids(string[] $uuids) + * @method \App\Model\Product\Flag\Flag[] getVisibleFlagsByIds(int[] $flagsIds, string $locale) */ class FlagRepository extends BaseFlagRepository { @@ -47,25 +48,6 @@ public function getAllFlagAkeneoCodes(): array return array_column($result, 'akeneoCode'); } - /** - * @param int[] $flagsIds - * @param string $locale - * @return \App\Model\Product\Flag\Flag[] - */ - public function getVisibleFlagsByIds(array $flagsIds, string $locale): array - { - $flagsQueryBuilder = $this->getFlagRepository()->createQueryBuilder('f') - ->select('f, ft') - ->join('f.translations', 'ft', Join::WITH, 'ft.locale = :locale') - ->where('f.id IN (:flagsIds)') - ->andWhere('f.visible = true') - ->orderBy(OrderByCollationHelper::createOrderByForLocale('ft.name', $locale), 'asc') - ->setParameter('flagsIds', $flagsIds) - ->setParameter('locale', $locale); - - return $flagsQueryBuilder->getQuery()->getResult(); - } - /** * @param int $flagId * @param string $locale diff --git a/app/src/Model/Product/Parameter/ParameterFacade.php b/app/src/Model/Product/Parameter/ParameterFacade.php index 83000bbed6..2c48c11793 100644 --- a/app/src/Model/Product/Parameter/ParameterFacade.php +++ b/app/src/Model/Product/Parameter/ParameterFacade.php @@ -5,10 +5,8 @@ namespace App\Model\Product\Parameter; use App\Component\UploadedFile\UploadedFileFacade; -use App\Model\Category\Category; use App\Model\CategorySeo\ReadyCategorySeoMixFacade; use Doctrine\ORM\EntityManagerInterface; -use Shopsys\FrameworkBundle\Model\Product\Filter\ParameterFilterChoice; use Shopsys\FrameworkBundle\Model\Category\CategoryParameterRepository; use Shopsys\FrameworkBundle\Model\Product\Parameter\ParameterFacade as BaseParameterFacade; use Shopsys\FrameworkBundle\Model\Product\Parameter\ParameterFactoryInterface; @@ -29,6 +27,7 @@ * @method \App\Model\Product\Parameter\ParameterValue getParameterValueByUuid(string $uuid) * @method \App\Model\Product\Parameter\Parameter[] getParametersByUuids(string[] $uuids) * @method \App\Model\Product\Parameter\ParameterValue[] getParameterValuesByUuids(string[] $uuids) + * @method int[] getParametersIdsSortedByPositionFilteredByCategory(\App\Model\Category\Category $category) */ class ParameterFacade extends BaseParameterFacade { @@ -37,24 +36,25 @@ class ParameterFacade extends BaseParameterFacade * @param \App\Model\Product\Parameter\ParameterRepository $parameterRepository * @param \Shopsys\FrameworkBundle\Model\Product\Parameter\ParameterFactory $parameterFactory * @param \Symfony\Component\EventDispatcher\EventDispatcherInterface $eventDispatcher + * @param \Shopsys\FrameworkBundle\Model\Category\CategoryParameterRepository $categoryParameterRepository * @param \App\Model\CategorySeo\ReadyCategorySeoMixFacade $readyCategorySeoMixFacade * @param \App\Component\UploadedFile\UploadedFileFacade $uploadedFileFacade - * @param \App\Model\Category\CategoryParameterRepository $categoryParameterRepository */ public function __construct( EntityManagerInterface $em, ParameterRepository $parameterRepository, ParameterFactoryInterface $parameterFactory, EventDispatcherInterface $eventDispatcher, + CategoryParameterRepository $categoryParameterRepository, private readonly ReadyCategorySeoMixFacade $readyCategorySeoMixFacade, private readonly UploadedFileFacade $uploadedFileFacade, - private readonly CategoryParameterRepository $categoryParameterRepository, ) { parent::__construct( $em, $parameterRepository, $parameterFactory, $eventDispatcher, + $categoryParameterRepository, ); } @@ -145,51 +145,4 @@ public function editParameterValue(int $parameterValueId, ParameterValueData $pa return $parameterValue; } - - /** - * @param int[][] $parameterValueIdsIndexedByParameterId - * @param string $locale - * @return \Shopsys\FrameworkBundle\Model\Product\Filter\ParameterFilterChoice[] - */ - public function getParameterFilterChoicesByIds(array $parameterValueIdsIndexedByParameterId, string $locale): array - { - $parameterValueIds = array_reduce($parameterValueIdsIndexedByParameterId, 'array_merge', []); - $allParameters = $this->parameterRepository->getVisibleParametersByIds( - array_keys($parameterValueIdsIndexedByParameterId), - $locale, - ); - $allParameterValues = $this->parameterRepository->getParameterValuesByIds($parameterValueIds); - - $parameterFilterChoices = []; - - foreach ($allParameters as $parameter) { - $valueIdsForParameter = $parameterValueIdsIndexedByParameterId[$parameter->getId()]; - $parameterValues = array_intersect_key($allParameterValues, array_flip($valueIdsForParameter)); - - uasort($parameterValues, function (ParameterValue $first, ParameterValue $second) { - return strcmp($first->getText(), $second->getText()); - }); - - $parameterFilterChoices[] = new ParameterFilterChoice( - $parameter, - $parameterValues, - ); - } - - return $parameterFilterChoices; - } - - /** - * @param \App\Model\Category\Category $category - * @return int[] - */ - public function getParametersIdsSortedByPositionFilteredByCategory(Category $category): array - { - return array_map( - function ($categoryParameter) { - return $categoryParameter->getParameter()->getId(); - }, - $this->categoryParameterRepository->getCategoryParametersByCategorySortedByPosition($category), - ); - } } diff --git a/app/src/Model/Product/Parameter/ParameterRepository.php b/app/src/Model/Product/Parameter/ParameterRepository.php index 7b3cf11600..59225b4092 100644 --- a/app/src/Model/Product/Parameter/ParameterRepository.php +++ b/app/src/Model/Product/Parameter/ParameterRepository.php @@ -35,6 +35,8 @@ * @method \App\Model\Product\Parameter\Parameter[] getParametersByUuids(string[] $uuids) * @method \App\Model\Product\Parameter\ParameterValue[] getParameterValuesByUuids(string[] $uuids) * @method __construct(\Doctrine\ORM\EntityManagerInterface $entityManager, \Shopsys\FrameworkBundle\Model\Product\Parameter\ParameterValueFactoryInterface $parameterValueFactory, \App\Model\Product\Parameter\ParameterValueDataFactory $parameterValueDataFactory) + * @method \App\Model\Product\Parameter\Parameter[] getVisibleParametersByIds(int[] $parameterIds, string $locale) + * @method \App\Model\Product\Parameter\ParameterValue[] getParameterValuesByIds(int[] $parameterValueIds) */ class ParameterRepository extends BaseParameterRepository { @@ -400,43 +402,4 @@ protected function getParameterValuesIndexedByProductIdAndParameterName( return $productParameterValuesIndexedByProductIdAndParameterName; } - - /** - * @param int[] $parameterIds - * @param string $locale - * @return \App\Model\Product\Parameter\Parameter[] - */ - public function getVisibleParametersByIds(array $parameterIds, string $locale): array - { - $parametersQueryBuilder = $this->getParameterRepository()->createQueryBuilder('p') - ->select('p, pt') - ->join('p.translations', 'pt', Join::WITH, 'pt.locale = :locale') - ->where('p.id IN (:parameterIds)') - ->setParameter('parameterIds', $parameterIds) - ->setParameter('locale', $locale) - ->orderBy(OrderByCollationHelper::createOrderByForLocale('pt.name', $locale), 'asc'); - - return $parametersQueryBuilder->getQuery()->getResult(); - } - - /** - * @param int[] $parameterValueIds - * @return \App\Model\Product\Parameter\ParameterValue[] - */ - public function getParameterValuesByIds(array $parameterValueIds): array - { - $parameterValues = $this->getParameterValueRepository()->createQueryBuilder('pv') - ->where('pv.id IN (:parameterValueIds)') - ->setParameter('parameterValueIds', $parameterValueIds) - ->getQuery()->getResult(); - - $parameterValuesIndexedById = []; - - /** @var \App\Model\Product\Parameter\ParameterValue $parameterValue */ - foreach ($parameterValues as $parameterValue) { - $parameterValuesIndexedById[$parameterValue->getId()] = $parameterValue; - } - - return $parameterValuesIndexedById; - } } diff --git a/app/tests/App/Functional/Model/Product/ProductOnCurrentDomainElasticFacadeCountDataTest.php b/app/tests/App/Functional/Model/Product/ProductOnCurrentDomainElasticFacadeCountDataTest.php index 1805db5b72..422aef0c3f 100644 --- a/app/tests/App/Functional/Model/Product/ProductOnCurrentDomainElasticFacadeCountDataTest.php +++ b/app/tests/App/Functional/Model/Product/ProductOnCurrentDomainElasticFacadeCountDataTest.php @@ -54,9 +54,9 @@ public function testCategory(): void $expectedCountData = $dataProvider[2]; $filterConfig = $this->productFilterConfigFactory->createForCategory( - $this->domain->getId(), $this->domain->getLocale(), $category, + '', ); $countData = $this->productOnCurrentDomainFacade->getProductFilterCountDataInCategory( $category->getId(), From fe28a4a5a6ed80e025cdf995df5681fd51ec0099 Mon Sep 17 00:00:00 2001 From: Martin Grossmann Date: Wed, 13 Dec 2023 08:31:22 +0100 Subject: [PATCH 25/32] improved variant creation is now moved to shopsys/framework - product is set as main variant on variant creation instead of creating a duplicate --- app/config/services.yaml | 3 -- .../Controller/Admin/ProductController.php | 4 +- .../Performance/ProductDataFixture.php | 2 +- .../ProductCannotBeTransformedException.php | 21 ---------- app/src/Model/Product/Product.php | 10 ----- .../Model/Product/ProductVariantFacade.php | 38 ------------------- 6 files changed, 3 insertions(+), 75 deletions(-) delete mode 100644 app/src/Model/Product/Exception/ProductCannotBeTransformedException.php delete mode 100644 app/src/Model/Product/ProductVariantFacade.php diff --git a/app/config/services.yaml b/app/config/services.yaml index dab315583b..c505abf3ca 100644 --- a/app/config/services.yaml +++ b/app/config/services.yaml @@ -495,9 +495,6 @@ services: Shopsys\FrameworkBundle\Model\Product\ProductFactory: alias: App\Model\Product\ProductFactory - Shopsys\FrameworkBundle\Model\Product\ProductVariantFacade: - alias: App\Model\Product\ProductVariantFacade - Shopsys\FrameworkBundle\Model\Product\Elasticsearch\ProductExportRepository: alias: App\Model\Product\Elasticsearch\ProductExportRepository diff --git a/app/src/Controller/Admin/ProductController.php b/app/src/Controller/Admin/ProductController.php index cf72c50aa1..3db033e0af 100644 --- a/app/src/Controller/Admin/ProductController.php +++ b/app/src/Controller/Admin/ProductController.php @@ -17,8 +17,8 @@ * @property \App\Component\Setting\Setting $setting * @property \Shopsys\FrameworkBundle\Component\Domain\Domain $domain * @method setSellingToUntilEndOfDay(\App\Model\Product\ProductData|null $productData) - * @method __construct(\Shopsys\FrameworkBundle\Model\Product\MassAction\ProductMassActionFacade $productMassActionFacade, \Shopsys\FrameworkBundle\Component\Grid\GridFactory $gridFactory, \App\Model\Product\ProductFacade $productFacade, \App\Model\Product\ProductDataFactory $productDataFactory, \Shopsys\FrameworkBundle\Model\AdminNavigation\BreadcrumbOverrider $breadcrumbOverrider, \Shopsys\FrameworkBundle\Model\Administrator\AdministratorGridFacade $administratorGridFacade, \Shopsys\FrameworkBundle\Model\Product\Listing\ProductListAdminFacade $productListAdminFacade, \Shopsys\FrameworkBundle\Model\AdvancedSearch\AdvancedSearchProductFacade $advancedSearchProductFacade, \App\Model\Product\ProductVariantFacade $productVariantFacade, \Shopsys\FrameworkBundle\Twig\ProductExtension $productExtension, \Shopsys\FrameworkBundle\Component\Domain\Domain $domain, \App\Model\Product\Unit\UnitFacade $unitFacade, \App\Component\Setting\Setting $setting, \Shopsys\FrameworkBundle\Model\Product\Availability\AvailabilityFacade $availabilityFacade) - * @property \App\Model\Product\ProductVariantFacade $productVariantFacade + * @method __construct(\Shopsys\FrameworkBundle\Model\Product\MassAction\ProductMassActionFacade $productMassActionFacade, \Shopsys\FrameworkBundle\Component\Grid\GridFactory $gridFactory, \App\Model\Product\ProductFacade $productFacade, \App\Model\Product\ProductDataFactory $productDataFactory, \Shopsys\FrameworkBundle\Model\AdminNavigation\BreadcrumbOverrider $breadcrumbOverrider, \Shopsys\FrameworkBundle\Model\Administrator\AdministratorGridFacade $administratorGridFacade, \Shopsys\FrameworkBundle\Model\Product\Listing\ProductListAdminFacade $productListAdminFacade, \Shopsys\FrameworkBundle\Model\AdvancedSearch\AdvancedSearchProductFacade $advancedSearchProductFacade, \Shopsys\FrameworkBundle\Model\Product\ProductVariantFacade $productVariantFacade, \Shopsys\FrameworkBundle\Twig\ProductExtension $productExtension, \Shopsys\FrameworkBundle\Component\Domain\Domain $domain, \App\Model\Product\Unit\UnitFacade $unitFacade, \App\Component\Setting\Setting $setting, \Shopsys\FrameworkBundle\Model\Product\Availability\AvailabilityFacade $availabilityFacade) + * @property \Shopsys\FrameworkBundle\Model\Product\ProductVariantFacade $productVariantFacade * @property \App\Model\Product\Unit\UnitFacade $unitFacade */ class ProductController extends BaseProductController diff --git a/app/src/DataFixtures/Performance/ProductDataFixture.php b/app/src/DataFixtures/Performance/ProductDataFixture.php index 297521373b..bd18b4df94 100644 --- a/app/src/DataFixtures/Performance/ProductDataFixture.php +++ b/app/src/DataFixtures/Performance/ProductDataFixture.php @@ -47,7 +47,7 @@ class ProductDataFixture * @param \Doctrine\ORM\EntityManagerInterface $em * @param \App\Model\Product\ProductFacade $productFacade * @param \Shopsys\FrameworkBundle\Component\Doctrine\SqlLoggerFacade $sqlLoggerFacade - * @param \App\Model\Product\ProductVariantFacade $productVariantFacade + * @param \Shopsys\FrameworkBundle\Model\Product\ProductVariantFacade $productVariantFacade * @param \Shopsys\FrameworkBundle\Component\DataFixture\PersistentReferenceFacade $persistentReferenceFacade * @param \App\Model\Category\CategoryRepository $categoryRepository * @param \Faker\Generator $faker diff --git a/app/src/Model/Product/Exception/ProductCannotBeTransformedException.php b/app/src/Model/Product/Exception/ProductCannotBeTransformedException.php deleted file mode 100644 index 21bad03f3c..0000000000 --- a/app/src/Model/Product/Exception/ProductCannotBeTransformedException.php +++ /dev/null @@ -1,21 +0,0 @@ -getId(), $product->getCatnum()); - - parent::__construct($message); - } -} diff --git a/app/src/Model/Product/Product.php b/app/src/Model/Product/Product.php index dba74c55ef..fbf06f323f 100644 --- a/app/src/Model/Product/Product.php +++ b/app/src/Model/Product/Product.php @@ -5,7 +5,6 @@ namespace App\Model\Product; use App\Model\Product\Exception\DeprecatedAvailabilityPropertyFromProductException; -use App\Model\Product\Exception\ProductCannotBeTransformedException; use Doctrine\Common\Collections\ArrayCollection; use Doctrine\ORM\Mapping as ORM; use Exception; @@ -436,15 +435,6 @@ public function setProductCategoryDomains(array $productCategoryDomains) } } - public function setAsMainVariant(): void - { - if ($this->isMainVariant() || $this->isVariant()) { - throw new ProductCannotBeTransformedException($this); - } - - $this->variantType = self::VARIANT_TYPE_MAIN; - } - /** * @return string */ diff --git a/app/src/Model/Product/ProductVariantFacade.php b/app/src/Model/Product/ProductVariantFacade.php deleted file mode 100644 index 10e346f597..0000000000 --- a/app/src/Model/Product/ProductVariantFacade.php +++ /dev/null @@ -1,38 +0,0 @@ -setAsMainVariant(); - // @todo after handling variants, this may be simplified - $this->productRecalculationDispatcher->dispatchSingleProductId($mainVariant->getId()); - - foreach ($variants as $variant) { - $mainVariant->addVariant($variant); - $this->productRecalculationDispatcher->dispatchSingleProductId($variant->getId()); - } - $this->em->flush(); - - return $mainVariant; - } -} From d29cfa0cf1d445813cdb106816fecfae4ff09a53 Mon Sep 17 00:00:00 2001 From: Martin Grossmann Date: Wed, 13 Dec 2023 08:34:33 +0100 Subject: [PATCH 26/32] improved behavior of variant recalculations - when any product ids should be recalculated then - any missing main variant ids are added to the set of ids (if variant should be recalculated, but main variant is not passed) - all variant ids are obtained (by previously found main variant ids) - all variants are recalculated and then main variant and regular products --- app/src/Model/Product/ProductFacade.php | 9 --- .../ProductRecalculationRepositoryTest.php | 64 +++++++++++++++++++ 2 files changed, 64 insertions(+), 9 deletions(-) create mode 100644 app/tests/App/Functional/Model/Product/Recalculation/ProductRecalculationRepositoryTest.php diff --git a/app/src/Model/Product/ProductFacade.php b/app/src/Model/Product/ProductFacade.php index b5b60d5575..a799708ef5 100644 --- a/app/src/Model/Product/ProductFacade.php +++ b/app/src/Model/Product/ProductFacade.php @@ -189,17 +189,8 @@ public function edit($productId, ProductData $productData) $this->productPriceRecalculationScheduler->scheduleProductForImmediateRecalculation($product); - // @todo after handling variants this may be simplified or edit may be moved to framework $this->productRecalculationDispatcher->dispatchSingleProductId($product->getId()); - if ($product->isMainVariant()) { - foreach ($product->getVariants() as $variant) { - $this->productRecalculationDispatcher->dispatchSingleProductId($variant->getId()); - } - } elseif ($product->isVariant()) { - $this->productRecalculationDispatcher->dispatchSingleProductId($product->getMainVariant()->getId()); - } - $this->editProductStockRelation($productData, $product); $this->productSellingDeniedRecalculator->calculateSellingDeniedForProduct($product); diff --git a/app/tests/App/Functional/Model/Product/Recalculation/ProductRecalculationRepositoryTest.php b/app/tests/App/Functional/Model/Product/Recalculation/ProductRecalculationRepositoryTest.php new file mode 100644 index 0000000000..aed57c7a4b --- /dev/null +++ b/app/tests/App/Functional/Model/Product/Recalculation/ProductRecalculationRepositoryTest.php @@ -0,0 +1,64 @@ +productRecalculationRepository->getIdsToRecalculate($inputIds); + + $this->assertSame($expectedIds, $calculatedIds); + } + + /** + * @return iterable + */ + public function getProductsForRecalculationProvider(): iterable + { + yield 'regular products only' => [ + 'inputIds' => [1, 2, 3], + 'expectedIds' => [1, 2, 3], + ]; + + yield 'variant has also other Variants along with MainVariant' => [ + 'inputIds' => [153], // variant + 'expectedIds' => [74, 75, 152, 153, 82], // variants first, then main variant + ]; + + yield 'mainVariant has also Variants' => [ + 'inputIds' => [69], // main variant + 'expectedIds' => [53, 54, 148, 149, 150, 151, 69], // variants first, then main variant + ]; + + yield 'variants and MainVariant in input does not duplicate ids' => [ + 'inputIds' => [148, 69, 151], // variant, main variant, variant + 'expectedIds' => [53, 54, 148, 149, 150, 151, 69], // variants first, then main variant + ]; + + yield 'ids are properly sorted for variants and main variant' => [ + 'inputIds' => [54, 53, 151, 69, 149, 150, 148], // randomized input order + 'expectedIds' => [53, 54, 148, 149, 150, 151, 69], // variants first, then main variant + ]; + + yield 'combination of multiple regular products, variants and main variant' => [ + 'inputIds' => [2, 75, 3, 69], // regular product, variant, regular product, main variant + 'expectedIds' => [53, 54, 148, 149, 150, 151, 74, 75, 152, 153, 2, 3, 69, 82], // variants first, then regular products and main variant + ]; + } +} From 180d354631d2f7183abb42a9aef644295ab74c28 Mon Sep 17 00:00:00 2001 From: Martin Grossmann Date: Wed, 13 Dec 2023 09:08:30 +0100 Subject: [PATCH 27/32] product calculated prices are now removed - recalculation is no longer necessary - visibility is determined by input price - automated bestselling products are sorted by manual input price --- app/config/cron.yaml | 4 --- .../Performance/ProductDataFixture.php | 4 --- app/src/Model/Product/ProductFacade.php | 9 ------ .../Pricing/Group/PricingGroupFacadeTest.php | 26 ---------------- .../Model/Product/ProductFacadeTest.php | 25 ---------------- .../ProductVisibilityRepositoryTest.php | 11 ++----- app/tests/App/Test/ApplicationTestCase.php | 27 ----------------- app/tests/App/Test/WebTestCase.php | 30 +++++++++++++++++++ .../Cart/ApplyPromoCodeToCartTest.php | 2 +- .../AuthenticatedApplyPromoCodeToCartTest.php | 2 +- ...thenticatedCartModificationsResultTest.php | 13 ++------ .../Cart/CartModificationsResultTest.php | 13 ++------ .../ProductSellingDeniedOnDomainTest.php | 2 -- 13 files changed, 40 insertions(+), 128 deletions(-) diff --git a/app/config/cron.yaml b/app/config/cron.yaml index 819158c8f2..3f1204444d 100644 --- a/app/config/cron.yaml +++ b/app/config/cron.yaml @@ -73,10 +73,6 @@ services: # Products - Shopsys\FrameworkBundle\Model\Product\Pricing\ProductPriceCronModule: - tags: - - { name: shopsys.cron, hours: '*', minutes: '*', instanceName: products, readableName: 'Recalculate product prices' } - Shopsys\FrameworkBundle\Model\Product\Elasticsearch\ProductRecalculationCronModule: tags: - { name: shopsys.cron, hours: '0', minutes: '0', instanceName: products, readableName: "Dispatches all products to be recalculated and exported" } diff --git a/app/src/DataFixtures/Performance/ProductDataFixture.php b/app/src/DataFixtures/Performance/ProductDataFixture.php index bd18b4df94..4bcc1743a8 100644 --- a/app/src/DataFixtures/Performance/ProductDataFixture.php +++ b/app/src/DataFixtures/Performance/ProductDataFixture.php @@ -15,7 +15,6 @@ use Shopsys\FrameworkBundle\Component\Doctrine\SqlLoggerFacade; use Shopsys\FrameworkBundle\Model\Category\Category; use Shopsys\FrameworkBundle\Model\Category\CategoryRepository; -use Shopsys\FrameworkBundle\Model\Product\Pricing\ProductPriceRecalculationScheduler; use Shopsys\FrameworkBundle\Model\Product\Product; use Shopsys\FrameworkBundle\Model\Product\ProductData; use Shopsys\FrameworkBundle\Model\Product\ProductFacade; @@ -51,7 +50,6 @@ class ProductDataFixture * @param \Shopsys\FrameworkBundle\Component\DataFixture\PersistentReferenceFacade $persistentReferenceFacade * @param \App\Model\Category\CategoryRepository $categoryRepository * @param \Faker\Generator $faker - * @param \Shopsys\FrameworkBundle\Model\Product\Pricing\ProductPriceRecalculationScheduler $productPriceRecalculationScheduler * @param \Shopsys\FrameworkBundle\Component\Console\ProgressBarFactory $progressBarFactory * @param \App\Model\Product\ProductDataFactory $productDataFactory */ @@ -64,7 +62,6 @@ public function __construct( private readonly PersistentReferenceFacade $persistentReferenceFacade, private readonly CategoryRepository $categoryRepository, private readonly Faker $faker, - private readonly ProductPriceRecalculationScheduler $productPriceRecalculationScheduler, private readonly ProgressBarFactory $progressBarFactory, private readonly ProductDataFactory $productDataFactory, ) { @@ -195,7 +192,6 @@ private function getUniqueIndex() private function clearResources() { - $this->productPriceRecalculationScheduler->reset(); $this->em->clear(); gc_collect_cycles(); } diff --git a/app/src/Model/Product/ProductFacade.php b/app/src/Model/Product/ProductFacade.php index a799708ef5..4f5122e201 100644 --- a/app/src/Model/Product/ProductFacade.php +++ b/app/src/Model/Product/ProductFacade.php @@ -18,7 +18,6 @@ use Shopsys\FrameworkBundle\Model\Product\Parameter\ProductParameterValueFactoryInterface; use Shopsys\FrameworkBundle\Model\Product\Pricing\ProductManualInputPriceFacade; use Shopsys\FrameworkBundle\Model\Product\Pricing\ProductPriceCalculation; -use Shopsys\FrameworkBundle\Model\Product\Pricing\ProductPriceRecalculationScheduler; use Shopsys\FrameworkBundle\Model\Product\Product as BaseProduct; use Shopsys\FrameworkBundle\Model\Product\ProductCategoryDomainFactoryInterface; use Shopsys\FrameworkBundle\Model\Product\ProductData; @@ -60,7 +59,6 @@ class ProductFacade extends BaseProductFacade * @param \App\Model\Product\Parameter\ParameterRepository $parameterRepository * @param \Shopsys\FrameworkBundle\Component\Domain\Domain $domain * @param \App\Component\Image\ImageFacade $imageFacade - * @param \Shopsys\FrameworkBundle\Model\Product\Pricing\ProductPriceRecalculationScheduler $productPriceRecalculationScheduler * @param \Shopsys\FrameworkBundle\Model\Pricing\Group\PricingGroupRepository $pricingGroupRepository * @param \Shopsys\FrameworkBundle\Model\Product\Pricing\ProductManualInputPriceFacade $productManualInputPriceFacade * @param \App\Component\Router\FriendlyUrl\FriendlyUrlFacade $friendlyUrlFacade @@ -85,7 +83,6 @@ public function __construct( ParameterRepository $parameterRepository, Domain $domain, ImageFacade $imageFacade, - ProductPriceRecalculationScheduler $productPriceRecalculationScheduler, PricingGroupRepository $pricingGroupRepository, ProductManualInputPriceFacade $productManualInputPriceFacade, FriendlyUrlFacade $friendlyUrlFacade, @@ -110,7 +107,6 @@ public function __construct( $parameterRepository, $domain, $imageFacade, - $productPriceRecalculationScheduler, $pricingGroupRepository, $productManualInputPriceFacade, $friendlyUrlFacade, @@ -167,7 +163,6 @@ public function edit($productId, ProductData $productData) $productCategoryDomains = $this->productCategoryDomainFactory->createMultiple($product, $productData->categoriesByDomainId); $product->edit($productCategoryDomains, $productData); - $this->productPriceRecalculationScheduler->scheduleProductForImmediateRecalculation($product); $this->saveParameters($product, $productData->parameters); @@ -187,8 +182,6 @@ public function edit($productId, ProductData $productData) $this->pluginCrudExtensionFacade->saveAllData('product', $product->getId(), $productData->pluginData); - $this->productPriceRecalculationScheduler->scheduleProductForImmediateRecalculation($product); - $this->productRecalculationDispatcher->dispatchSingleProductId($product->getId()); $this->editProductStockRelation($productData, $product); @@ -220,8 +213,6 @@ public function setAdditionalDataAfterCreate(BaseProduct $product, ProductData $ $this->friendlyUrlFacade->saveUrlListFormData('front_product_detail', $product->getId(), $productData->urls); $this->friendlyUrlFacade->createFriendlyUrls('front_product_detail', $product->getId(), $product->getNames()); - - $this->productPriceRecalculationScheduler->scheduleProductForImmediateRecalculation($product); } /** diff --git a/app/tests/App/Functional/Model/Pricing/Group/PricingGroupFacadeTest.php b/app/tests/App/Functional/Model/Pricing/Group/PricingGroupFacadeTest.php index a27bcad101..73bef9a248 100644 --- a/app/tests/App/Functional/Model/Pricing/Group/PricingGroupFacadeTest.php +++ b/app/tests/App/Functional/Model/Pricing/Group/PricingGroupFacadeTest.php @@ -5,7 +5,6 @@ namespace Tests\App\Functional\Model\Pricing\Group; use App\DataFixtures\Demo\PricingGroupDataFixture; -use App\DataFixtures\Demo\ProductDataFixture; use App\Model\Customer\BillingAddressDataFactory; use Shopsys\FrameworkBundle\Component\Domain\Domain; use Shopsys\FrameworkBundle\Model\Customer\User\CustomerUserDataFactoryInterface; @@ -13,8 +12,6 @@ use Shopsys\FrameworkBundle\Model\Customer\User\CustomerUserUpdateDataFactoryInterface; use Shopsys\FrameworkBundle\Model\Pricing\Group\PricingGroupData; use Shopsys\FrameworkBundle\Model\Pricing\Group\PricingGroupFacade; -use Shopsys\FrameworkBundle\Model\Product\Pricing\ProductCalculatedPrice; -use Shopsys\FrameworkBundle\Model\Product\Pricing\ProductPriceRecalculator; use Tests\App\Test\TransactionFunctionalTestCase; class PricingGroupFacadeTest extends TransactionFunctionalTestCase @@ -24,11 +21,6 @@ class PricingGroupFacadeTest extends TransactionFunctionalTestCase */ private PricingGroupFacade $pricingGroupFacade; - /** - * @inject - */ - private ProductPriceRecalculator $productPriceRecalculator; - /** * @inject */ @@ -49,24 +41,6 @@ class PricingGroupFacadeTest extends TransactionFunctionalTestCase */ private BillingAddressDataFactory $billingAddressDataFactory; - public function testCreate() - { - /** @var \App\Model\Product\Product $product */ - $product = $this->getReference(ProductDataFixture::PRODUCT_PREFIX . '1'); - - $pricingGroupData = new PricingGroupData(); - $pricingGroupData->name = 'pricing_group_name'; - $domainId = Domain::FIRST_DOMAIN_ID; - $pricingGroup = $this->pricingGroupFacade->create($pricingGroupData, $domainId); - $this->productPriceRecalculator->runAllScheduledRecalculations(); - $productCalculatedPrice = $this->em->getRepository(ProductCalculatedPrice::class)->findOneBy([ - 'product' => $product, - 'pricingGroup' => $pricingGroup, - ]); - - $this->assertNotNull($productCalculatedPrice); - } - public function testDeleteAndReplace() { $pricingGroupData = new PricingGroupData(); diff --git a/app/tests/App/Functional/Model/Product/ProductFacadeTest.php b/app/tests/App/Functional/Model/Product/ProductFacadeTest.php index 79eb71a1f2..e2bb272b0d 100644 --- a/app/tests/App/Functional/Model/Product/ProductFacadeTest.php +++ b/app/tests/App/Functional/Model/Product/ProductFacadeTest.php @@ -5,13 +5,11 @@ namespace Tests\App\Functional\Model\Product; use App\DataFixtures\Demo\AvailabilityDataFixture; -use App\DataFixtures\Demo\ProductDataFixture; use App\DataFixtures\Demo\StocksDataFixture; use App\DataFixtures\Demo\UnitDataFixture; use App\Model\Product\ProductData; use App\Model\Product\ProductDataFactory; use Shopsys\FrameworkBundle\Model\Pricing\Vat\VatFacade; -use Shopsys\FrameworkBundle\Model\Product\Pricing\ProductPriceRecalculationScheduler; use Shopsys\FrameworkBundle\Model\Product\ProductFacade; use Shopsys\FrameworkBundle\Model\Stock\ProductStockDataFactory; use Tests\App\Test\TransactionFunctionalTestCase; @@ -28,11 +26,6 @@ class ProductFacadeTest extends TransactionFunctionalTestCase */ private ProductFacade $productFacade; - /** - * @inject - */ - private ProductPriceRecalculationScheduler $productPriceRecalculationScheduler; - /** * @inject */ @@ -105,24 +98,6 @@ public function getTestSellingDeniedDataProvider() ]; } - public function testEditSchedulesPriceRecalculation() - { - /** @var \App\Model\Product\Product $product */ - $product = $this->getReference(ProductDataFixture::PRODUCT_PREFIX . 1); - $productId = $product->getId(); - - $productData = $this->productDataFactory->create(); - $productData->catnum = '123'; - $this->setVats($productData); - - $this->productFacade->edit($productId, $productData); - - $this->assertArrayHasKey( - $productId, - $this->productPriceRecalculationScheduler->getProductsForImmediateRecalculation(), - ); - } - /** * @param \App\Model\Product\ProductData $productData */ diff --git a/app/tests/App/Functional/Model/Product/ProductVisibilityRepositoryTest.php b/app/tests/App/Functional/Model/Product/ProductVisibilityRepositoryTest.php index 712ca1ea1a..c85b2ee46a 100644 --- a/app/tests/App/Functional/Model/Product/ProductVisibilityRepositoryTest.php +++ b/app/tests/App/Functional/Model/Product/ProductVisibilityRepositoryTest.php @@ -20,7 +20,6 @@ use Shopsys\FrameworkBundle\Model\Pricing\Group\PricingGroupFacade; use Shopsys\FrameworkBundle\Model\Pricing\Vat\Vat; use Shopsys\FrameworkBundle\Model\Pricing\Vat\VatData; -use Shopsys\FrameworkBundle\Model\Product\Pricing\ProductPriceRecalculator; use Shopsys\FrameworkBundle\Model\Product\ProductFacade; use Shopsys\FrameworkBundle\Model\Product\ProductVisibility; use Shopsys\FrameworkBundle\Model\Product\ProductVisibilityRepository; @@ -38,11 +37,6 @@ class ProductVisibilityRepositoryTest extends TransactionFunctionalTestCase */ private PricingGroupFacade $pricingGroupFacade; - /** - * @inject - */ - private ProductPriceRecalculator $productPriceRecalculator; - /** * @inject */ @@ -139,14 +133,13 @@ private function setPriceForAllDomains(ProductData $productData, ?Money $price) private function createProductAndGetVisibility(ProductData $productData): ProductVisibility { $product = $this->productFacade->create($productData); - $this->productPriceRecalculator->runImmediateRecalculations(); - $this->em->flush(); $id = $product->getId(); $this->createImage('product', $id); + $this->em->clear(); - $this->productVisibilityRepository->refreshProductsVisibility(); + $this->handleDispatchedRecalculationMessages(); /** @var \App\Model\Product\Product $productAgain */ $productAgain = $this->em->getRepository(Product::class)->find($id); diff --git a/app/tests/App/Test/ApplicationTestCase.php b/app/tests/App/Test/ApplicationTestCase.php index c1e2a27c6e..18b3373cca 100644 --- a/app/tests/App/Test/ApplicationTestCase.php +++ b/app/tests/App/Test/ApplicationTestCase.php @@ -8,11 +8,6 @@ use Shopsys\FrameworkBundle\Component\Domain\Domain; use Shopsys\FrameworkBundle\Component\EntityExtension\EntityManagerDecorator; use Symfony\Component\DependencyInjection\ContainerInterface; -use Symfony\Component\EventDispatcher\EventDispatcherInterface; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; -use Symfony\Component\HttpKernel\Event\ResponseEvent; -use Symfony\Component\HttpKernel\HttpKernelInterface; use const PHP_URL_SCHEME; abstract class ApplicationTestCase extends WebTestCase @@ -22,11 +17,6 @@ abstract class ApplicationTestCase extends WebTestCase */ protected EntityManagerDecorator $em; - /** - * @inject - */ - private EventDispatcherInterface $eventDispatcher; - protected static ?Client $client = null; protected function setUp(): void @@ -151,23 +141,6 @@ private function getClientServerParameters( return $clientServerParameters; } - /** - * Runs scheduled recalculations that would be executed on a kernel.response event - * This allows to clean scheduled recalculations before making request on a client that could break the application - * Eg. when testing GraphQL validation that breaks consistency of the entity and disallows any operation over it afterwards - */ - protected function dispatchFakeKernelResponseEventToTriggerImmediateRecalculations(): void - { - $fakeKernelResponseEvent = new ResponseEvent( - self::getCurrentClient()->getKernel(), - new Request(), - HttpKernelInterface::MAIN_REQUEST, - new Response(), - ); - - $this->eventDispatcher->dispatch($fakeKernelResponseEvent, 'kernel.response'); - } - protected function tearDown(): void { $this->em->rollback(); diff --git a/app/tests/App/Test/WebTestCase.php b/app/tests/App/Test/WebTestCase.php index cb3c5f8ef7..ec9850bc61 100644 --- a/app/tests/App/Test/WebTestCase.php +++ b/app/tests/App/Test/WebTestCase.php @@ -7,11 +7,17 @@ use Psr\Container\ContainerInterface; use Shopsys\FrameworkBundle\Component\DataFixture\PersistentReferenceFacade; use Shopsys\FrameworkBundle\Component\Domain\Domain; +use Shopsys\FrameworkBundle\Component\Messenger\DelayedEnvelope\DelayedEnvelopesCollector; use Shopsys\FrameworkBundle\Component\Router\DomainRouterFactory; use Shopsys\FrameworkBundle\Model\Pricing\Currency\Currency; use Shopsys\FrameworkBundle\Model\Pricing\Currency\CurrencyFacade; use Shopsys\FrameworkBundle\Model\Product\Recalculation\ProductRecalculationMessageHandler; use Symfony\Bundle\FrameworkBundle\Test\WebTestCase as BaseWebTestCase; +use Symfony\Component\EventDispatcher\EventDispatcherInterface; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpKernel\Event\ResponseEvent; +use Symfony\Component\HttpKernel\HttpKernelInterface; use Symfony\Component\Routing\Generator\UrlGeneratorInterface; use Tests\FrameworkBundle\Test\ProductIndexBackupFacade; use Zalas\Injector\PHPUnit\TestCase\ServiceContainerTestCase; @@ -43,6 +49,11 @@ abstract class WebTestCase extends BaseWebTestCase implements ServiceContainerTe */ protected ProductIndexBackupFacade $productIndexBackupFacade; + /** + * @inject + */ + private EventDispatcherInterface $eventDispatcher; + protected function setUp(): void { parent::setUp(); @@ -143,6 +154,8 @@ public function handleDispatchedRecalculationMessages(): void { $this->productIndexBackupFacade->createSnapshot(); + $this->dispatchFakeKernelResponseEventToTriggerSendMessageToTransport(); + /** @var \Symfony\Component\Messenger\Transport\InMemoryTransport $transport */ $transport = self::getContainer()->get('messenger.transport.product_recalculation'); $handler = $this->productRecalculationMessageHandler; @@ -155,4 +168,21 @@ public function handleDispatchedRecalculationMessages(): void $handler($message); } } + + /** + * By dispatching the kernel response event, the message is sent to the transport thanks to the + * DelayedEnvelope/DispatchCollectedEnvelopesSubscriber. + * Until the subscriber is called, the messages are collected only in the DelayedEnvelopesCollector. + */ + private function dispatchFakeKernelResponseEventToTriggerSendMessageToTransport(): void + { + $fakeKernelResponseEvent = new ResponseEvent( + self::$kernel, + new Request(), + HttpKernelInterface::MAIN_REQUEST, + new Response(), + ); + + $this->eventDispatcher->dispatch($fakeKernelResponseEvent, 'kernel.response'); + } } diff --git a/app/tests/FrontendApiBundle/Functional/Cart/ApplyPromoCodeToCartTest.php b/app/tests/FrontendApiBundle/Functional/Cart/ApplyPromoCodeToCartTest.php index 807271cdb6..cd57bbd194 100644 --- a/app/tests/FrontendApiBundle/Functional/Cart/ApplyPromoCodeToCartTest.php +++ b/app/tests/FrontendApiBundle/Functional/Cart/ApplyPromoCodeToCartTest.php @@ -380,7 +380,7 @@ private function hideProduct(Product $product): void $productData->sellingDenied = true; $this->productFacade->edit($product->getId(), $productData); - $this->dispatchFakeKernelResponseEventToTriggerImmediateRecalculations(); + $this->handleDispatchedRecalculationMessages(); } /** diff --git a/app/tests/FrontendApiBundle/Functional/Cart/AuthenticatedApplyPromoCodeToCartTest.php b/app/tests/FrontendApiBundle/Functional/Cart/AuthenticatedApplyPromoCodeToCartTest.php index bc24832df9..df7d5e2901 100644 --- a/app/tests/FrontendApiBundle/Functional/Cart/AuthenticatedApplyPromoCodeToCartTest.php +++ b/app/tests/FrontendApiBundle/Functional/Cart/AuthenticatedApplyPromoCodeToCartTest.php @@ -343,7 +343,7 @@ private function hideProduct(Product $product): void $productData->sellingDenied = true; $this->productFacade->edit($product->getId(), $productData); - $this->dispatchFakeKernelResponseEventToTriggerImmediateRecalculations(); + $this->handleDispatchedRecalculationMessages(); } /** diff --git a/app/tests/FrontendApiBundle/Functional/Cart/AuthenticatedCartModificationsResultTest.php b/app/tests/FrontendApiBundle/Functional/Cart/AuthenticatedCartModificationsResultTest.php index e2991acea4..748d24ef16 100644 --- a/app/tests/FrontendApiBundle/Functional/Cart/AuthenticatedCartModificationsResultTest.php +++ b/app/tests/FrontendApiBundle/Functional/Cart/AuthenticatedCartModificationsResultTest.php @@ -19,7 +19,6 @@ use App\Model\Transport\TransportFacade; use Shopsys\FrameworkBundle\Component\Money\Money; use Shopsys\FrameworkBundle\Model\Pricing\Group\PricingGroupFacade; -use Shopsys\FrameworkBundle\Model\Product\Pricing\ProductPriceRecalculationScheduler; use Shopsys\FrameworkBundle\Model\Store\StoreFacade; use Tests\FrontendApiBundle\Test\GraphQlWithLoginTestCase; @@ -62,11 +61,6 @@ class AuthenticatedCartModificationsResultTest extends GraphQlWithLoginTestCase */ private PaymentDataFactory $paymentDataFactory; - /** - * @inject - */ - private ProductPriceRecalculationScheduler $productPriceRecalculationScheduler; - protected function setUp(): void { parent::setUp(); @@ -507,7 +501,7 @@ private function hideTestingProduct(): void $productData->sellingDenied = true; $this->productFacade->edit($this->testingProduct->getId(), $productData); - $this->dispatchFakeKernelResponseEventToTriggerImmediateRecalculations(); + $this->handleDispatchedRecalculationMessages(); } private function modifyPriceOfTestingProduct(): void @@ -521,7 +515,7 @@ private function modifyPriceOfTestingProduct(): void } $this->productFacade->edit($this->testingProduct->getId(), $productData); - $this->dispatchFakeKernelResponseEventToTriggerImmediateRecalculations(); + $this->handleDispatchedRecalculationMessages(); } private function setOneItemLeftOnStockForTestingProduct(): void @@ -535,7 +529,7 @@ private function setOneItemLeftOnStockForTestingProduct(): void $productData->stockProductData[1]->productQuantity = 1; $this->productFacade->edit($this->testingProduct->getId(), $productData); - $this->dispatchFakeKernelResponseEventToTriggerImmediateRecalculations(); + $this->handleDispatchedRecalculationMessages(); } private function setNoItemLeftOnStockForTestingProduct(): void @@ -547,7 +541,6 @@ private function setNoItemLeftOnStockForTestingProduct(): void } $this->productFacade->editProductStockRelation($productData, $this->testingProduct); - $this->productPriceRecalculationScheduler->reset(); $this->em->clear(); } diff --git a/app/tests/FrontendApiBundle/Functional/Cart/CartModificationsResultTest.php b/app/tests/FrontendApiBundle/Functional/Cart/CartModificationsResultTest.php index 0621d5b786..b5ead8aa4a 100644 --- a/app/tests/FrontendApiBundle/Functional/Cart/CartModificationsResultTest.php +++ b/app/tests/FrontendApiBundle/Functional/Cart/CartModificationsResultTest.php @@ -19,7 +19,6 @@ use App\Model\Transport\TransportFacade; use Shopsys\FrameworkBundle\Component\Money\Money; use Shopsys\FrameworkBundle\Model\Pricing\Group\PricingGroupFacade; -use Shopsys\FrameworkBundle\Model\Product\Pricing\ProductPriceRecalculationScheduler; use Shopsys\FrameworkBundle\Model\Store\StoreFacade; use Tests\FrontendApiBundle\Test\GraphQlTestCase; @@ -62,11 +61,6 @@ class CartModificationsResultTest extends GraphQlTestCase */ private PaymentDataFactory $paymentDataFactory; - /** - * @inject - */ - private ProductPriceRecalculationScheduler $productPriceRecalculationScheduler; - protected function setUp(): void { parent::setUp(); @@ -536,7 +530,7 @@ private function hideTestingProduct(): void $productData->sellingDenied = true; $this->productFacade->edit($this->testingProduct->getId(), $productData); - $this->dispatchFakeKernelResponseEventToTriggerImmediateRecalculations(); + $this->handleDispatchedRecalculationMessages(); } private function modifyPriceOfTestingProduct(): void @@ -550,7 +544,7 @@ private function modifyPriceOfTestingProduct(): void } $this->productFacade->edit($this->testingProduct->getId(), $productData); - $this->dispatchFakeKernelResponseEventToTriggerImmediateRecalculations(); + $this->handleDispatchedRecalculationMessages(); } private function setOneItemLeftOnStockForTestingProduct(): void @@ -564,7 +558,7 @@ private function setOneItemLeftOnStockForTestingProduct(): void $productData->stockProductData[1]->productQuantity = 1; $this->productFacade->edit($this->testingProduct->getId(), $productData); - $this->dispatchFakeKernelResponseEventToTriggerImmediateRecalculations(); + $this->handleDispatchedRecalculationMessages(); } private function setNoItemLeftOnStockForTestingProduct(): void @@ -575,7 +569,6 @@ private function setNoItemLeftOnStockForTestingProduct(): void $stockProductData->productQuantity = 0; } $this->productFacade->editProductStockRelation($productData, $this->testingProduct); - $this->productPriceRecalculationScheduler->reset(); $this->em->clear(); gc_collect_cycles(); } diff --git a/app/tests/FrontendApiBundle/Functional/Product/ProductSellingDeniedOnDomainTest.php b/app/tests/FrontendApiBundle/Functional/Product/ProductSellingDeniedOnDomainTest.php index cb85c580dd..90c9d1cc70 100644 --- a/app/tests/FrontendApiBundle/Functional/Product/ProductSellingDeniedOnDomainTest.php +++ b/app/tests/FrontendApiBundle/Functional/Product/ProductSellingDeniedOnDomainTest.php @@ -38,8 +38,6 @@ public function testSellingDeniedOnDomain(): void $this->productFacade->edit($product->getId(), $productData); $this->productSellingDeniedRecalculator->calculateSellingDeniedForProduct($product); - $this->dispatchFakeKernelResponseEventToTriggerImmediateRecalculations(); - $this->handleDispatchedRecalculationMessages(); // wait for elastic to reindex From 66419ad6d50f59ed03968f98febd0b09aa9db10f Mon Sep 17 00:00:00 2001 From: Martin Grossmann Date: Wed, 13 Dec 2023 11:13:44 +0100 Subject: [PATCH 28/32] dumped translations --- app/translations/messages.cs.po | 15 --------------- app/translations/messages.en.po | 15 --------------- 2 files changed, 30 deletions(-) diff --git a/app/translations/messages.cs.po b/app/translations/messages.cs.po index b70013a9aa..3550b4a742 100644 --- a/app/translations/messages.cs.po +++ b/app/translations/messages.cs.po @@ -163,9 +163,6 @@ msgstr "Ověřovací kód" msgid "Authenticator key" msgstr "Ověřovací klíč" -msgid "Available immediately" -msgstr "Ihned k odběru" - msgid "Back to category selection" msgstr "Zpět na volbu kategorie" @@ -1306,9 +1303,6 @@ msgstr "Hodnota objednávek" msgid "Original translation" msgstr "Původní překlad" -msgid "Out of stock" -msgstr "Vyprodáno" - msgid "Outside layout" msgstr "Rozložení vně" @@ -1957,9 +1951,6 @@ msgstr "To je nemilé, to je nemilé. A zrovna \"%status_code% %status_t msgid "Unable to load list of language constants" msgstr "Nepodařilo se načíst přehled jazykových konstant" -msgid "Unavailable" -msgstr "Nedostupné" - msgid "Units - full" msgstr "Měrné jednotky - vše" @@ -2140,12 +2131,6 @@ msgstr "obrat v" msgid "without positioning" msgstr "bez pozice" -msgid "{0,1} Available in one week|[2,Inf] Available in %count% weeks" -msgstr "{0,1} K dispozici za týden|[2,4] K dispozici za %count% týdny|[5,Inf] K dispozici za %count% týdnů" - -msgid "{0}|{1}Available in %count% store|[2,Inf]Available in %count% stores" -msgstr "{0}|{1}Můžete mít ihned na %count% prodejně|[2,Inf]Můžete mít ihned na %count% prodejnách" - msgid "{1}%count% promo code has been created|[2,Inf]%count% promo codes have been created" msgstr "{1} Byl vytvořen %count% slevový kupón|[2,4] Byly vytvořeny %count% slevové kupóny|[5,Inf] Bylo vytvořeno %count% slevových kupónů" diff --git a/app/translations/messages.en.po b/app/translations/messages.en.po index e6d78e3771..60303a1c0f 100644 --- a/app/translations/messages.en.po +++ b/app/translations/messages.en.po @@ -163,9 +163,6 @@ msgstr "" msgid "Authenticator key" msgstr "" -msgid "Available immediately" -msgstr "" - msgid "Back to category selection" msgstr "" @@ -1306,9 +1303,6 @@ msgstr "" msgid "Original translation" msgstr "" -msgid "Out of stock" -msgstr "" - msgid "Outside layout" msgstr "" @@ -1957,9 +1951,6 @@ msgstr "" msgid "Unable to load list of language constants" msgstr "" -msgid "Unavailable" -msgstr "" - msgid "Units - full" msgstr "" @@ -2140,12 +2131,6 @@ msgstr "" msgid "without positioning" msgstr "" -msgid "{0,1} Available in one week|[2,Inf] Available in %count% weeks" -msgstr "" - -msgid "{0}|{1}Available in %count% store|[2,Inf]Available in %count% stores" -msgstr "" - msgid "{1}%count% promo code has been created|[2,Inf]%count% promo codes have been created" msgstr "" From 35f3d8229997edeb9e67c694ba18082a91db9af1 Mon Sep 17 00:00:00 2001 From: Martin Grossmann Date: Wed, 13 Dec 2023 14:41:37 +0100 Subject: [PATCH 29/32] productStockData usage is now moved to shopsys/framework - unified naming to productStock* --- .../DataFixtures/Demo/ProductDataFixture.php | 2 +- .../Form/Admin/ProductFormTypeExtension.php | 6 +-- app/src/Model/Product/ProductData.php | 6 --- app/src/Model/Product/ProductDataFactory.php | 42 ++++++------------- app/src/Model/Product/ProductFacade.php | 30 ++++--------- .../Form/productDetailFormTheme.html.twig | 2 +- .../ProductAvailabilityFacadeTest.php | 24 +++++------ .../Model/Product/ProductFacadeTest.php | 2 +- app/tests/App/Smoke/NewProductTest.php | 14 +++---- ...thenticatedCartModificationsResultTest.php | 10 ++--- .../Cart/CartModificationsResultTest.php | 10 ++--- 11 files changed, 54 insertions(+), 94 deletions(-) diff --git a/app/src/DataFixtures/Demo/ProductDataFixture.php b/app/src/DataFixtures/Demo/ProductDataFixture.php index 58de5b4baa..9a57d4c7c7 100644 --- a/app/src/DataFixtures/Demo/ProductDataFixture.php +++ b/app/src/DataFixtures/Demo/ProductDataFixture.php @@ -6432,7 +6432,7 @@ public function setStocksQuantity(ProductData $productData, int $quantity) foreach ($stocks as $stock) { $productStockData = $this->productStockDataFactory->createFromStock($stock); $productStockData->productQuantity = $quantity; - $productData->stockProductData[$stock->getId()] = $productStockData; + $productData->productStockData[$stock->getId()] = $productStockData; } } diff --git a/app/src/Form/Admin/ProductFormTypeExtension.php b/app/src/Form/Admin/ProductFormTypeExtension.php index bb84838e7c..f6b94a1347 100644 --- a/app/src/Form/Admin/ProductFormTypeExtension.php +++ b/app/src/Form/Admin/ProductFormTypeExtension.php @@ -10,7 +10,7 @@ use Shopsys\FormTypesBundle\MultidomainType; use Shopsys\FormTypesBundle\YesNoType; use Shopsys\FrameworkBundle\Form\Admin\Product\ProductFormType; -use Shopsys\FrameworkBundle\Form\Admin\Stock\StockProductFormType; +use Shopsys\FrameworkBundle\Form\Admin\Stock\ProductStockFormType; use Shopsys\FrameworkBundle\Form\GroupType; use Shopsys\FrameworkBundle\Form\LocalizedFullWidthType; use Shopsys\FrameworkBundle\Form\ProductsType; @@ -189,9 +189,9 @@ private function setStocksGroup(FormBuilderInterface $builder): void 'label' => t('Warehouses'), ]); - $stockGroupBuilder->add('stockProductData', CollectionType::class, [ + $stockGroupBuilder->add('productStockData', CollectionType::class, [ 'required' => false, - 'entry_type' => StockProductFormType::class, + 'entry_type' => ProductStockFormType::class, 'render_form_row' => false, ]); diff --git a/app/src/Model/Product/ProductData.php b/app/src/Model/Product/ProductData.php index 54ba151de8..aa848e658c 100644 --- a/app/src/Model/Product/ProductData.php +++ b/app/src/Model/Product/ProductData.php @@ -26,11 +26,6 @@ class ProductData extends BaseProductData */ public $nameSufix; - /** - * @var \Shopsys\FrameworkBundle\Model\Stock\ProductStockData[] - */ - public $stockProductData; - /** * @var int|null */ @@ -52,7 +47,6 @@ public function __construct() $this->namePrefix = []; $this->nameSufix = []; - $this->stockProductData = []; $this->weight = null; $this->relatedProducts = []; $this->productVideosData = []; diff --git a/app/src/Model/Product/ProductDataFactory.php b/app/src/Model/Product/ProductDataFactory.php index c484ffa76b..18a76b4275 100644 --- a/app/src/Model/Product/ProductDataFactory.php +++ b/app/src/Model/Product/ProductDataFactory.php @@ -34,6 +34,8 @@ * @property \App\Model\Product\Unit\UnitFacade $unitFacade * @property \App\Model\Product\Parameter\ParameterRepository $parameterRepository * @property \App\Component\Router\FriendlyUrl\FriendlyUrlFacade $friendlyUrlFacade + * @method fillProductStockByProduct(\App\Model\Product\ProductData $productData, \App\Model\Product\Product $product) + * @method fillProductStockByStocks(\App\Model\Product\ProductData $productData) */ class ProductDataFactory extends BaseProductDataFactory { @@ -50,9 +52,9 @@ class ProductDataFactory extends BaseProductDataFactory * @param \Shopsys\FrameworkBundle\Model\Pricing\Group\PricingGroupFacade $pricingGroupFacade * @param \Shopsys\FrameworkBundle\Model\Product\Availability\AvailabilityFacade $availabilityFacade * @param \Shopsys\FrameworkBundle\Component\FileUpload\ImageUploadDataFactory $imageUploadDataFactory - * @param \Shopsys\FrameworkBundle\Model\Stock\ProductStockFacade $stockProductFacade + * @param \Shopsys\FrameworkBundle\Model\Stock\ProductStockFacade $productStockFacade * @param \Shopsys\FrameworkBundle\Model\Stock\StockFacade $stockFacade - * @param \Shopsys\FrameworkBundle\Model\Stock\ProductStockDataFactory $stockProductDataFactory + * @param \Shopsys\FrameworkBundle\Model\Stock\ProductStockDataFactory $productStockDataFactory * @param \App\Component\Setting\Setting $setting * @param \App\Model\ProductVideo\ProductVideoDataFactory $productVideoDataFactory * @param \App\Model\ProductVideo\ProductVideoRepository $productVideoRepository @@ -70,9 +72,9 @@ public function __construct( PricingGroupFacade $pricingGroupFacade, AvailabilityFacade $availabilityFacade, ImageUploadDataFactory $imageUploadDataFactory, - private readonly ProductStockFacade $stockProductFacade, - private readonly StockFacade $stockFacade, - private readonly ProductStockDataFactory $stockProductDataFactory, + ProductStockFacade $productStockFacade, + StockFacade $stockFacade, + ProductStockDataFactory $productStockDataFactory, private readonly Setting $setting, private readonly ProductVideoDataFactory $productVideoDataFactory, private readonly ProductVideoRepository $productVideoRepository, @@ -90,6 +92,9 @@ public function __construct( $pricingGroupFacade, $availabilityFacade, $imageUploadDataFactory, + $productStockFacade, + $stockFacade, + $productStockDataFactory, ); } @@ -111,7 +116,7 @@ public function create(): BaseProductData { $productData = $this->createInstance(); $this->fillNew($productData); - $this->fillStockProductByStocks($productData); + $this->fillProductStockByStocks($productData); return $productData; } @@ -124,7 +129,7 @@ public function createFromProduct(BaseProduct $product): BaseProductData { $productData = $this->createInstance(); $this->fillFromProduct($productData, $product); - $this->fillStockProductByProduct($productData, $product); + $this->fillProductStockByProduct($productData, $product); $this->fillProductVideosByProductId($productData, $product); return $productData; @@ -223,29 +228,6 @@ protected function fillFromProduct(BaseProductData $productData, BaseProduct $pr $productData->relatedProducts = $product->getRelatedProducts(); } - /** - * @param \App\Model\Product\ProductData $productData - */ - private function fillStockProductByStocks(ProductData $productData): void - { - foreach ($this->stockFacade->getAllStocks() as $stock) { - $productData->stockProductData[$stock->getId()] = $this->stockProductDataFactory->createFromStock($stock); - } - } - - /** - * @param \App\Model\Product\ProductData $productData - * @param \App\Model\Product\Product $product - */ - private function fillStockProductByProduct(ProductData $productData, Product $product): void - { - $this->fillStockProductByStocks($productData); - - foreach ($this->stockProductFacade->getProductStocksByProduct($product) as $stockProduct) { - $productData->stockProductData[$stockProduct->getStock()->getId()] = $this->stockProductDataFactory->createFromProductStock($stockProduct); - } - } - /** * @param \App\Model\Product\ProductData $productData * @param \App\Model\Product\Product $product diff --git a/app/src/Model/Product/ProductFacade.php b/app/src/Model/Product/ProductFacade.php index 4f5122e201..3f77e403bf 100644 --- a/app/src/Model/Product/ProductFacade.php +++ b/app/src/Model/Product/ProductFacade.php @@ -28,7 +28,6 @@ use Shopsys\FrameworkBundle\Model\Product\ProductVisibilityFacade; use Shopsys\FrameworkBundle\Model\Product\ProductVisibilityFactoryInterface; use Shopsys\FrameworkBundle\Model\Product\Recalculation\ProductRecalculationDispatcher; -use Shopsys\FrameworkBundle\Model\Stock\ProductStockData; use Shopsys\FrameworkBundle\Model\Stock\ProductStockFacade; use Shopsys\FrameworkBundle\Model\Stock\StockFacade; @@ -48,7 +47,10 @@ * @method \App\Model\Product\Product getByUuid(string $uuid) * @method createFriendlyUrlsWhenRenamed(\App\Model\Product\Product $product, array $originalNames) * @method array getChangedNamesByLocale(\App\Model\Product\Product $product, array $originalNames) + * @method \App\Model\Product\Product create(\App\Model\Product\ProductData $productData) * @property \App\Model\Product\ProductFactory $productFactory + * @method setAdditionalDataAfterCreate(\App\Model\Product\Product $product, \App\Model\Product\ProductData $productData) + * @method editProductStockRelation(\App\Model\Product\ProductData $productData, \App\Model\Product\Product $product) */ class ProductFacade extends BaseProductFacade { @@ -96,8 +98,8 @@ public function __construct( ProductVisibilityFactoryInterface $productVisibilityFactory, ProductPriceCalculation $productPriceCalculation, ProductRecalculationDispatcher $productRecalculationDispatcher, - private readonly ProductStockFacade $productStockFacade, - private readonly StockFacade $stockFacade, + ProductStockFacade $productStockFacade, + StockFacade $stockFacade, private readonly ProductVideoFacade $productVideoFacade, ) { parent::__construct( @@ -120,6 +122,8 @@ public function __construct( $productVisibilityFactory, $productPriceCalculation, $productRecalculationDispatcher, + $productStockFacade, + $stockFacade, ); } @@ -282,24 +286,4 @@ public function refreshProductAccessories(BaseProduct $product, array $accessori { parent::refreshProductAccessories($product, $accessories); } - - /** - * @param \App\Model\Product\ProductData $productData - * @param \App\Model\Product\Product $product - */ - public function editProductStockRelation(ProductData $productData, Product $product): void - { - $stockIds = array_map( - fn (ProductStockData $productStockData): int => $productStockData->stockId, - $productData->stockProductData, - ); - - $stocksIndexedById = $this->stockFacade->getStocksByIdsIndexedById($stockIds); - - $this->productStockFacade->editProductStockRelations( - $product, - $stocksIndexedById, - $productData->stockProductData, - ); - } } diff --git a/app/templates/Admin/Form/productDetailFormTheme.html.twig b/app/templates/Admin/Form/productDetailFormTheme.html.twig index c7291ac897..c3cbe8c871 100644 --- a/app/templates/Admin/Form/productDetailFormTheme.html.twig +++ b/app/templates/Admin/Form/productDetailFormTheme.html.twig @@ -1,4 +1,4 @@ -{% block _product_form_stocksGroup_stockProductData_widget %} +{% block _product_form_stocksGroup_productStockData_widget %}
diff --git a/app/tests/App/Functional/Model/Product/Availability/ProductAvailabilityFacadeTest.php b/app/tests/App/Functional/Model/Product/Availability/ProductAvailabilityFacadeTest.php index f08ef3c104..24a8bc67f1 100644 --- a/app/tests/App/Functional/Model/Product/Availability/ProductAvailabilityFacadeTest.php +++ b/app/tests/App/Functional/Model/Product/Availability/ProductAvailabilityFacadeTest.php @@ -63,13 +63,13 @@ public function testIsProductAvailableOnDomain(int $stockQuantity, bool $expecte /** @var \App\Model\Product\ProductData $productData */ $productData = $this->productDataFactory->createFromProduct($product); - $productData->stockProductData = []; + $productData->productStockData = []; foreach ($this->stockFacade->getStocksEnabledOnDomainIndexedByStockId(self::FIRST_DOMAIN_ID) as $stock) { - $stockProductData = $this->productStockDataFactory->createFromStock($stock); - $stockProductData->productQuantity = $stockQuantity; + $productStockData = $this->productStockDataFactory->createFromStock($stock); + $productStockData->productQuantity = $stockQuantity; - $productData->stockProductData[] = $stockProductData; + $productData->productStockData[] = $productStockData; } $this->productFacade->edit($product->getId(), $productData); @@ -107,12 +107,12 @@ public function testGroupedStockQuantity() /** @var \App\Model\Product\ProductData $productData */ $productData = $this->productDataFactory->createFromProduct($product); - $productData->stockProductData = []; + $productData->productStockData = []; foreach ($this->stockFacade->getStocksEnabledOnDomainIndexedByStockId(self::FIRST_DOMAIN_ID) as $stock) { - $stockProductData = $this->productStockDataFactory->createFromStock($stock); - $stockProductData->productQuantity = $stockQuantity; - $productData->stockProductData[] = $stockProductData; + $productStockData = $this->productStockDataFactory->createFromStock($stock); + $productStockData->productQuantity = $stockQuantity; + $productData->productStockData[] = $productStockData; } $this->productFacade->edit($product->getId(), $productData); @@ -143,12 +143,12 @@ public function testProductAvailabilityInformationByDomainId( /** @var \App\Model\Product\ProductData $productData */ $productData = $this->productDataFactory->createFromProduct($product); - $productData->stockProductData = []; + $productData->productStockData = []; foreach ($this->stockFacade->getStocksEnabledOnDomainIndexedByStockId(self::FIRST_DOMAIN_ID) as $stock) { - $stockProductData = $this->productStockDataFactory->createFromStock($stock); - $stockProductData->productQuantity = $stockQuantity; - $productData->stockProductData[] = $stockProductData; + $productStockData = $this->productStockDataFactory->createFromStock($stock); + $productStockData->productQuantity = $stockQuantity; + $productData->productStockData[] = $productStockData; } $this->productFacade->edit($product->getId(), $productData); diff --git a/app/tests/App/Functional/Model/Product/ProductFacadeTest.php b/app/tests/App/Functional/Model/Product/ProductFacadeTest.php index e2bb272b0d..c4008a95a3 100644 --- a/app/tests/App/Functional/Model/Product/ProductFacadeTest.php +++ b/app/tests/App/Functional/Model/Product/ProductFacadeTest.php @@ -58,7 +58,7 @@ public function testSellingDenied( $productStockData = $this->productStockDataFactory->createFromStock($stock); $productStockData->productQuantity = 10; - $productData->stockProductData[$stock->getId()] = $productStockData; + $productData->productStockData[$stock->getId()] = $productStockData; $productData->catnum = '123'; $this->setVats($productData); diff --git a/app/tests/App/Smoke/NewProductTest.php b/app/tests/App/Smoke/NewProductTest.php index 42754b901a..a3c6b9046c 100644 --- a/app/tests/App/Smoke/NewProductTest.php +++ b/app/tests/App/Smoke/NewProductTest.php @@ -85,13 +85,13 @@ private function fillForm(Form $form): void $form['product_form[displayAvailabilityGroup][sellingFrom]'] = '1.1.1990'; $form['product_form[displayAvailabilityGroup][sellingTo]'] = '1.1.2000'; $form['product_form[displayAvailabilityGroup][unit]']->setValue((string)$unit->getId()); - $form['product_form[stocksGroup][stockProductData][1][productQuantity]'] = '1'; - $form['product_form[stocksGroup][stockProductData][2][productQuantity]'] = '2'; - $form['product_form[stocksGroup][stockProductData][3][productQuantity]'] = '3'; - $form['product_form[stocksGroup][stockProductData][4][productQuantity]'] = '4'; - $form['product_form[stocksGroup][stockProductData][5][productQuantity]'] = '5'; - $form['product_form[stocksGroup][stockProductData][6][productQuantity]'] = '6'; - $form['product_form[stocksGroup][stockProductData][7][productQuantity]'] = '7'; + $form['product_form[stocksGroup][productStockData][1][productQuantity]'] = '1'; + $form['product_form[stocksGroup][productStockData][2][productQuantity]'] = '2'; + $form['product_form[stocksGroup][productStockData][3][productQuantity]'] = '3'; + $form['product_form[stocksGroup][productStockData][4][productQuantity]'] = '4'; + $form['product_form[stocksGroup][productStockData][5][productQuantity]'] = '5'; + $form['product_form[stocksGroup][productStockData][6][productQuantity]'] = '6'; + $form['product_form[stocksGroup][productStockData][7][productQuantity]'] = '7'; } /** diff --git a/app/tests/FrontendApiBundle/Functional/Cart/AuthenticatedCartModificationsResultTest.php b/app/tests/FrontendApiBundle/Functional/Cart/AuthenticatedCartModificationsResultTest.php index 748d24ef16..16f2ff7f05 100644 --- a/app/tests/FrontendApiBundle/Functional/Cart/AuthenticatedCartModificationsResultTest.php +++ b/app/tests/FrontendApiBundle/Functional/Cart/AuthenticatedCartModificationsResultTest.php @@ -522,11 +522,11 @@ private function setOneItemLeftOnStockForTestingProduct(): void { $productData = $this->productDataFactory->createFromProduct($this->testingProduct); - foreach ($productData->stockProductData as $stockProductData) { - $stockProductData->productQuantity = 0; + foreach ($productData->productStockData as $productStockData) { + $productStockData->productQuantity = 0; } - $productData->stockProductData[1]->productQuantity = 1; + $productData->productStockData[1]->productQuantity = 1; $this->productFacade->edit($this->testingProduct->getId(), $productData); $this->handleDispatchedRecalculationMessages(); @@ -536,8 +536,8 @@ private function setNoItemLeftOnStockForTestingProduct(): void { $productData = $this->productDataFactory->createFromProduct($this->testingProduct); - foreach ($productData->stockProductData as $stockProductData) { - $stockProductData->productQuantity = 0; + foreach ($productData->productStockData as $productStockData) { + $productStockData->productQuantity = 0; } $this->productFacade->editProductStockRelation($productData, $this->testingProduct); diff --git a/app/tests/FrontendApiBundle/Functional/Cart/CartModificationsResultTest.php b/app/tests/FrontendApiBundle/Functional/Cart/CartModificationsResultTest.php index b5ead8aa4a..a6c189e9a7 100644 --- a/app/tests/FrontendApiBundle/Functional/Cart/CartModificationsResultTest.php +++ b/app/tests/FrontendApiBundle/Functional/Cart/CartModificationsResultTest.php @@ -551,11 +551,11 @@ private function setOneItemLeftOnStockForTestingProduct(): void { $productData = $this->productDataFactory->createFromProduct($this->testingProduct); - foreach ($productData->stockProductData as $stockProductData) { - $stockProductData->productQuantity = 0; + foreach ($productData->productStockData as $productStockData) { + $productStockData->productQuantity = 0; } - $productData->stockProductData[1]->productQuantity = 1; + $productData->productStockData[1]->productQuantity = 1; $this->productFacade->edit($this->testingProduct->getId(), $productData); $this->handleDispatchedRecalculationMessages(); @@ -565,8 +565,8 @@ private function setNoItemLeftOnStockForTestingProduct(): void { $productData = $this->productDataFactory->createFromProduct($this->testingProduct); - foreach ($productData->stockProductData as $stockProductData) { - $stockProductData->productQuantity = 0; + foreach ($productData->productStockData as $productStockData) { + $productStockData->productQuantity = 0; } $this->productFacade->editProductStockRelation($productData, $this->testingProduct); $this->em->clear(); From 9cfe1360296846d63457cac7a4f2974fc743f8f4 Mon Sep 17 00:00:00 2001 From: Martin Grossmann Date: Wed, 13 Dec 2023 14:57:15 +0100 Subject: [PATCH 30/32] selling denied is now recalculated via queue --- app/src/Model/Product/ProductFacade.php | 73 +-------- .../ProductSellingDeniedRecalculator.php | 141 +++++++----------- .../Model/Product/ProductFacadeTest.php | 2 + .../ProductSellingDeniedRecalculatorTest.php | 116 +++++++------- .../ProductSellingDeniedOnDomainTest.php | 7 - 5 files changed, 106 insertions(+), 233 deletions(-) diff --git a/app/src/Model/Product/ProductFacade.php b/app/src/Model/Product/ProductFacade.php index 3f77e403bf..6def688854 100644 --- a/app/src/Model/Product/ProductFacade.php +++ b/app/src/Model/Product/ProductFacade.php @@ -24,7 +24,6 @@ use Shopsys\FrameworkBundle\Model\Product\ProductFacade as BaseProductFacade; use Shopsys\FrameworkBundle\Model\Product\ProductFactoryInterface; use Shopsys\FrameworkBundle\Model\Product\ProductRepository; -use Shopsys\FrameworkBundle\Model\Product\ProductSellingDeniedRecalculator; use Shopsys\FrameworkBundle\Model\Product\ProductVisibilityFacade; use Shopsys\FrameworkBundle\Model\Product\ProductVisibilityFactoryInterface; use Shopsys\FrameworkBundle\Model\Product\Recalculation\ProductRecalculationDispatcher; @@ -64,7 +63,6 @@ class ProductFacade extends BaseProductFacade * @param \Shopsys\FrameworkBundle\Model\Pricing\Group\PricingGroupRepository $pricingGroupRepository * @param \Shopsys\FrameworkBundle\Model\Product\Pricing\ProductManualInputPriceFacade $productManualInputPriceFacade * @param \App\Component\Router\FriendlyUrl\FriendlyUrlFacade $friendlyUrlFacade - * @param \App\Model\Product\ProductSellingDeniedRecalculator $productSellingDeniedRecalculator * @param \Shopsys\FrameworkBundle\Model\Product\Accessory\ProductAccessoryRepository $productAccessoryRepository * @param \Shopsys\FrameworkBundle\Component\Plugin\PluginCrudExtensionFacade $pluginCrudExtensionFacade * @param \App\Model\Product\ProductFactory $productFactory @@ -88,7 +86,6 @@ public function __construct( PricingGroupRepository $pricingGroupRepository, ProductManualInputPriceFacade $productManualInputPriceFacade, FriendlyUrlFacade $friendlyUrlFacade, - ProductSellingDeniedRecalculator $productSellingDeniedRecalculator, ProductAccessoryRepository $productAccessoryRepository, PluginCrudExtensionFacade $pluginCrudExtensionFacade, ProductFactoryInterface $productFactory, @@ -112,7 +109,6 @@ public function __construct( $pricingGroupRepository, $productManualInputPriceFacade, $friendlyUrlFacade, - $productSellingDeniedRecalculator, $productAccessoryRepository, $pluginCrudExtensionFacade, $productFactory, @@ -127,22 +123,6 @@ public function __construct( ); } - /** - * @param \App\Model\Product\ProductData $productData - * @return \App\Model\Product\Product - */ - public function create(ProductData $productData) - { - /** @var \App\Model\Product\Product $product */ - $product = parent::create($productData); - - $this->editProductStockRelation($productData, $product); - - $this->productSellingDeniedRecalculator->calculateSellingDeniedForProduct($product); - - return $product; - } - /** * @param string $productCatnum * @return \App\Model\Product\Product|null @@ -163,69 +143,20 @@ public function findOneByCatnumExcludeMainVariants($productCatnum): ?BaseProduct */ public function edit($productId, ProductData $productData) { - $product = $this->productRepository->getById($productId); - - $productCategoryDomains = $this->productCategoryDomainFactory->createMultiple($product, $productData->categoriesByDomainId); - $product->edit($productCategoryDomains, $productData); - - $this->saveParameters($product, $productData->parameters); - - if (!$product->isMainVariant()) { - $this->productManualInputPriceFacade->refreshProductManualInputPrices($product, $productData->manualInputPricesByPricingGroupId); - } - - if ($product->isMainVariant()) { - $product->refreshVariants($productData->variants); - } - - $this->refreshProductAccessories($product, $productData->accessories); - $this->em->flush(); - $this->imageFacade->manageImages($product, $productData->images); - $this->friendlyUrlFacade->saveUrlListFormData('front_product_detail', $product->getId(), $productData->urls); - $this->friendlyUrlFacade->createFriendlyUrls('front_product_detail', $product->getId(), $product->getFullnames()); - - $this->pluginCrudExtensionFacade->saveAllData('product', $product->getId(), $productData->pluginData); - - $this->productRecalculationDispatcher->dispatchSingleProductId($product->getId()); - - $this->editProductStockRelation($productData, $product); - - $this->productSellingDeniedRecalculator->calculateSellingDeniedForProduct($product); + /** @var \App\Model\Product\Product $product */ + $product = parent::edit($productId, $productData); $this->productVideoFacade->saveProductVideosToProduct($product, $productData->productVideosData); return $product; } - /** - * @param \App\Model\Product\Product $product - * @param \App\Model\Product\ProductData $productData - */ - public function setAdditionalDataAfterCreate(BaseProduct $product, ProductData $productData) - { - // Persist of ProductCategoryDomain requires known primary key of Product - // @see https://github.com/doctrine/doctrine2/issues/4869 - $productCategoryDomains = $this->productCategoryDomainFactory->createMultiple($product, $productData->categoriesByDomainId); - $product->setProductCategoryDomains($productCategoryDomains); - $this->em->flush(); - - $this->saveParameters($product, $productData->parameters); - $this->createProductVisibilities($product); - $this->productManualInputPriceFacade->refreshProductManualInputPrices($product, $productData->manualInputPricesByPricingGroupId); - $this->refreshProductAccessories($product, $productData->accessories); - $this->imageFacade->manageImages($product, $productData->images); - - $this->friendlyUrlFacade->saveUrlListFormData('front_product_detail', $product->getId(), $productData->urls); - $this->friendlyUrlFacade->createFriendlyUrls('front_product_detail', $product->getId(), $product->getNames()); - } - /** * @param \App\Model\Product\Product $product * @param \Shopsys\FrameworkBundle\Model\Product\Parameter\ProductParameterValueData[] $productParameterValuesData */ protected function saveParameters(BaseProduct $product, array $productParameterValuesData) { - // Doctrine runs INSERTs before DELETEs in UnitOfWork. In case of UNIQUE constraint // in database, this leads in trying to insert duplicate entry. // That's why it's necessary to do remove and flush first. diff --git a/app/src/Model/Product/ProductSellingDeniedRecalculator.php b/app/src/Model/Product/ProductSellingDeniedRecalculator.php index a3adc8cffe..f21ce4782e 100644 --- a/app/src/Model/Product/ProductSellingDeniedRecalculator.php +++ b/app/src/Model/Product/ProductSellingDeniedRecalculator.php @@ -4,60 +4,58 @@ namespace App\Model\Product; -use Doctrine\DBAL\Connection; +use Doctrine\DBAL\ArrayParameterType; use Doctrine\DBAL\Types\Types; use Doctrine\ORM\EntityManagerInterface; use Shopsys\FrameworkBundle\Component\Domain\Domain; use Shopsys\FrameworkBundle\Model\Product\Product; use Shopsys\FrameworkBundle\Model\Product\ProductSellingDeniedRecalculator as BaseProductSellingDeniedRecalculator; -/** - * @method calculateSellingDeniedForProduct(\App\Model\Product\Product $product) - * @method \App\Model\Product\Product[] getProductsForCalculations(\App\Model\Product\Product $product) - */ class ProductSellingDeniedRecalculator extends BaseProductSellingDeniedRecalculator { /** * @param \Doctrine\ORM\EntityManagerInterface $entityManager * @param \Shopsys\FrameworkBundle\Component\Domain\Domain $domain */ - public function __construct(EntityManagerInterface $entityManager, private Domain $domain) - { + public function __construct( + EntityManagerInterface $entityManager, + private readonly Domain $domain, + ) { parent::__construct($entityManager); } /** - * @param \App\Model\Product\Product[] $products + * {@inheritdoc} */ - protected function calculate(array $products = []) + protected function calculate(array $productIds = []): void { - $this->calculateIndependent($products); - $this->propagateCalculatedSaleExclusionToCalculatedSellingDenied($products); - $this->propagateMainVariantSellingDeniedToVariants($products); - $this->propagateVariantsSellingDeniedToMainVariant($products); + $this->calculateIndependent($productIds); + $this->propagateCalculatedSaleExclusionToCalculatedSellingDenied($productIds); + $this->propagateMainVariantSellingDeniedToVariants($productIds); + $this->propagateVariantsSellingDeniedToMainVariant($productIds); } /** - * @param \App\Model\Product\Product[] $products + * {@inheritdoc} */ - protected function calculateIndependent(array $products) + protected function calculateIndependent(array $productIds): void { $qb = $this->em->createQueryBuilder() ->update(Product::class, 'p') ->set('p.calculatedSellingDenied', 'p.sellingDenied'); - if (count($products) > 0) { - $qb->andWhere('p IN (:products)')->setParameter('products', $products); + if (count($productIds) > 0) { + $qb->andWhere('p IN (:productIds)')->setParameter('productIds', $productIds); } $qb->getQuery()->execute(); - $this->calculatePerDomain($products); + $this->calculatePerDomain($productIds); } /** - * @param \App\Model\Product\Product[] $products + * @param int[] $productIds */ - private function calculatePerDomain(array $products) + private function calculatePerDomain(array $productIds): void { $query = 'UPDATE product_domains AS pd SET calculated_sale_exclusion = CASE @@ -89,13 +87,7 @@ private function calculatePerDomain(array $products) FROM products AS p WHERE p.id = pd.product_id AND pd.domain_id = :domainId - ' . (count($products) > 0 ? ' AND p.id IN (:productIds)' : ''); - - $productIds = []; - - foreach ($products as $product) { - $productIds[] = $product->getId(); - } + ' . (count($productIds) > 0 ? ' AND p.id IN (:productIds)' : ''); $params = []; $params['productIds'] = $productIds; @@ -108,7 +100,7 @@ private function calculatePerDomain(array $products) $query, $params, [ - 'productIds' => Connection::PARAM_INT_ARRAY, + 'productIds' => ArrayParameterType::INTEGER, 'variantTypeMain' => Types::STRING, 'domainId' => Types::INTEGER, ], @@ -117,9 +109,9 @@ private function calculatePerDomain(array $products) } /** - * @param \App\Model\Product\Product[] $products + * @param int[] $productIds */ - private function propagateCalculatedSaleExclusionToCalculatedSellingDenied(array $products): void + private function propagateCalculatedSaleExclusionToCalculatedSellingDenied(array $productIds): void { $query = 'UPDATE products as p SET calculated_selling_denied = TRUE @@ -130,36 +122,30 @@ private function propagateCalculatedSaleExclusionToCalculatedSellingDenied(array WHERE pd.product_id = p.id AND pd.calculated_sale_exclusion = FALSE ) - ' . (count($products) > 0 ? ' AND p.id IN (:productIds)' : ''); - - $productIds = []; - - foreach ($products as $product) { - $productIds[] = $product->getId(); - } + ' . (count($productIds) > 0 ? ' AND p.id IN (:productIds)' : ''); $this->em->getConnection()->executeStatement( $query, ['productIds' => $productIds], - ['productIds' => Connection::PARAM_INT_ARRAY], + ['productIds' => ArrayParameterType::INTEGER], ); } /** - * @param \App\Model\Product\Product[] $products + * @param int[] $productIds */ - protected function propagateMainVariantSellingDeniedToVariants(array $products) + protected function propagateMainVariantSellingDeniedToVariants(array $productIds): void { - parent::propagateMainVariantSellingDeniedToVariants($products); + parent::propagateMainVariantSellingDeniedToVariants($productIds); - $this->propagateMainVariantSellingDeniedToVariantsCalculatedSaleExclusion($products); - $this->propagateMainVariantCalculateSaleExclusionToVariantsCalculatedSaleExclusion($products); + $this->propagateMainVariantSellingDeniedToVariantsCalculatedSaleExclusion($productIds); + $this->propagateMainVariantCalculateSaleExclusionToVariantsCalculatedSaleExclusion($productIds); } /** - * @param \App\Model\Product\Product[] $products + * @param int[] $productIds */ - private function propagateMainVariantSellingDeniedToVariantsCalculatedSaleExclusion(array $products): void + private function propagateMainVariantSellingDeniedToVariantsCalculatedSaleExclusion(array $productIds): void { $query = 'UPDATE product_domains as pd SET calculated_sale_exclusion = TRUE @@ -169,13 +155,7 @@ private function propagateMainVariantSellingDeniedToVariantsCalculatedSaleExclus AND pd.product_id = p.id AND pd.calculated_sale_exclusion = FALSE AND p.calculated_selling_denied = TRUE - ' . (count($products) > 0 ? ' AND m.id IN (:productIds)' : ''); - - $productIds = []; - - foreach ($products as $product) { - $productIds[] = $product->getId(); - } + ' . (count($productIds) > 0 ? ' AND m.id IN (:productIds)' : ''); $this->em->getConnection()->executeStatement( $query, @@ -184,17 +164,18 @@ private function propagateMainVariantSellingDeniedToVariantsCalculatedSaleExclus 'variantTypeMain' => Product::VARIANT_TYPE_MAIN, ], [ - 'productIds' => Connection::PARAM_INT_ARRAY, + 'productIds' => ArrayParameterType::INTEGER, 'variantTypeMain' => Types::STRING, ], ); } /** - * @param \App\Model\Product\Product[] $products + * @param int[] $productIds */ - private function propagateMainVariantCalculateSaleExclusionToVariantsCalculatedSaleExclusion(array $products): void - { + private function propagateMainVariantCalculateSaleExclusionToVariantsCalculatedSaleExclusion( + array $productIds, + ): void { $query = 'UPDATE product_domains as pd SET calculated_sale_exclusion = TRUE FROM products as p @@ -205,13 +186,7 @@ private function propagateMainVariantCalculateSaleExclusionToVariantsCalculatedS AND pdm.domain_id = pd.domain_id AND pd.calculated_sale_exclusion = FALSE AND pdm.calculated_sale_exclusion = TRUE - ' . (count($products) > 0 ? ' AND m.id IN (:productIds)' : ''); - - $productIds = []; - - foreach ($products as $product) { - $productIds[] = $product->getId(); - } + ' . (count($productIds) > 0 ? ' AND m.id IN (:productIds)' : ''); $this->em->getConnection()->executeStatement( $query, @@ -220,27 +195,27 @@ private function propagateMainVariantCalculateSaleExclusionToVariantsCalculatedS 'variantTypeMain' => Product::VARIANT_TYPE_MAIN, ], [ - 'productIds' => Connection::PARAM_INT_ARRAY, + 'productIds' => ArrayParameterType::INTEGER, 'variantTypeMain' => Types::STRING, ], ); } /** - * @param \App\Model\Product\Product[] $products + * @param int[] $productIds */ - protected function propagateVariantsSellingDeniedToMainVariant(array $products) + protected function propagateVariantsSellingDeniedToMainVariant(array $productIds): void { - parent::propagateVariantsSellingDeniedToMainVariant($products); + parent::propagateVariantsSellingDeniedToMainVariant($productIds); - $this->propagateVariantsSaleExclusionToMainVariantCalculateSaleExclusion($products); - $this->propagateVariantsSaleExclusionToMainVariantCalculateSellingDenied($products); + $this->propagateVariantsSaleExclusionToMainVariantCalculateSaleExclusion($productIds); + $this->propagateVariantsSaleExclusionToMainVariantCalculateSellingDenied($productIds); } /** - * @param \App\Model\Product\Product[] $products + * @param int[] $productIds */ - private function propagateVariantsSaleExclusionToMainVariantCalculateSaleExclusion(array $products): void + private function propagateVariantsSaleExclusionToMainVariantCalculateSaleExclusion(array $productIds): void { $query = 'UPDATE product_domains as pd SET calculated_sale_exclusion = TRUE @@ -255,13 +230,7 @@ private function propagateVariantsSaleExclusionToMainVariantCalculateSaleExclusi WHERE v.main_variant_id = p.id AND pdv.calculated_sale_exclusion = FALSE ) - ' . (count($products) > 0 ? ' AND p.id IN (:productIds)' : ''); - - $productIds = []; - - foreach ($products as $product) { - $productIds[] = $product->getId(); - } + ' . (count($productIds) > 0 ? ' AND p.id IN (:productIds)' : ''); $this->em->getConnection()->executeStatement( $query, @@ -270,16 +239,16 @@ private function propagateVariantsSaleExclusionToMainVariantCalculateSaleExclusi 'variantTypeMain' => Product::VARIANT_TYPE_MAIN, ], [ - 'productIds' => Connection::PARAM_INT_ARRAY, + 'productIds' => ArrayParameterType::INTEGER, 'variantTypeMain' => Types::STRING, ], ); } /** - * @param \App\Model\Product\Product[] $products + * @param int[] $productIds */ - private function propagateVariantsSaleExclusionToMainVariantCalculateSellingDenied(array $products): void + private function propagateVariantsSaleExclusionToMainVariantCalculateSellingDenied(array $productIds): void { $query = 'UPDATE products as p SET calculated_selling_denied = TRUE @@ -292,13 +261,7 @@ private function propagateVariantsSaleExclusionToMainVariantCalculateSellingDeni WHERE v.main_variant_id = p.id AND pdv.calculated_sale_exclusion = FALSE ) - ' . (count($products) > 0 ? ' AND p.id IN (:productIds)' : ''); - - $productIds = []; - - foreach ($products as $product) { - $productIds[] = $product->getId(); - } + ' . (count($productIds) > 0 ? ' AND p.id IN (:productIds)' : ''); $this->em->getConnection()->executeStatement( $query, @@ -307,7 +270,7 @@ private function propagateVariantsSaleExclusionToMainVariantCalculateSellingDeni 'variantTypeMain' => Product::VARIANT_TYPE_MAIN, ], [ - 'productIds' => Connection::PARAM_INT_ARRAY, + 'productIds' => ArrayParameterType::INTEGER, 'variantTypeMain' => Types::STRING, ], ); diff --git a/app/tests/App/Functional/Model/Product/ProductFacadeTest.php b/app/tests/App/Functional/Model/Product/ProductFacadeTest.php index c4008a95a3..ffdbd2698e 100644 --- a/app/tests/App/Functional/Model/Product/ProductFacadeTest.php +++ b/app/tests/App/Functional/Model/Product/ProductFacadeTest.php @@ -65,6 +65,8 @@ public function testSellingDenied( $product = $this->productFacade->create($productData); + $this->handleDispatchedRecalculationMessages(); + $this->em->clear(); $productFromDb = $this->productFacade->getById($product->getId()); diff --git a/app/tests/App/Functional/Model/Product/ProductSellingDeniedRecalculatorTest.php b/app/tests/App/Functional/Model/Product/ProductSellingDeniedRecalculatorTest.php index 0752b17d6d..a60345db0f 100644 --- a/app/tests/App/Functional/Model/Product/ProductSellingDeniedRecalculatorTest.php +++ b/app/tests/App/Functional/Model/Product/ProductSellingDeniedRecalculatorTest.php @@ -4,19 +4,12 @@ namespace Tests\App\Functional\Model\Product; -use App\DataFixtures\Demo\ProductDataFixture; -use Shopsys\FrameworkBundle\Model\Product\ProductDataFactoryInterface; -use Shopsys\FrameworkBundle\Model\Product\ProductFacade; -use Shopsys\FrameworkBundle\Model\Product\ProductSellingDeniedRecalculator; +use App\Model\Product\ProductDataFactory; +use App\Model\Product\ProductFacade; use Tests\App\Test\TransactionFunctionalTestCase; class ProductSellingDeniedRecalculatorTest extends TransactionFunctionalTestCase { - /** - * @inject - */ - private ProductSellingDeniedRecalculator $productSellingDeniedRecalculator; - /** * @inject */ @@ -25,19 +18,12 @@ class ProductSellingDeniedRecalculatorTest extends TransactionFunctionalTestCase /** * @inject */ - private ProductDataFactoryInterface $productDataFactory; + private ProductDataFactory $productDataFactory; - public function testCalculateSellingDeniedForProductSellableVariant() + public function testCalculateSellingDeniedForProductSellableVariant(): void { - /** @var \App\Model\Product\Product $variant1 */ - $variant1 = $this->getReference(ProductDataFixture::PRODUCT_PREFIX . '53'); - /** @var \App\Model\Product\Product $variant2 */ - $variant2 = $this->getReference(ProductDataFixture::PRODUCT_PREFIX . '54'); - /** @var \App\Model\Product\Product $variant3 */ - $variant3 = $this->getReference(ProductDataFixture::PRODUCT_PREFIX . '148'); - /** @var \App\Model\Product\Product $mainVariant */ - $mainVariant = $this->getReference(ProductDataFixture::PRODUCT_PREFIX . '69'); - $this->productSellingDeniedRecalculator->calculateSellingDeniedForProduct($mainVariant); + $variant1 = $this->productFacade->getById(53); + $variant3 = $this->productFacade->getById(148); $variant1productData = $this->productDataFactory->createFromProduct($variant1); $variant1productData->sellingDenied = true; @@ -51,10 +37,14 @@ public function testCalculateSellingDeniedForProductSellableVariant() } $this->productFacade->edit($variant3->getId(), $variant3productData); - $this->em->refresh($variant1); - $this->em->refresh($variant2); - $this->em->refresh($variant3); - $this->em->refresh($mainVariant); + $this->handleDispatchedRecalculationMessages(); + + $this->em->clear(); + + $variant1 = $this->productFacade->getById(53); + $variant2 = $this->productFacade->getById(54); + $variant3 = $this->productFacade->getById(148); + $mainVariant = $this->productFacade->getById(69); $this->assertTrue($variant1->getCalculatedSellingDenied()); $this->assertFalse($variant2->getCalculatedSellingDenied()); @@ -62,22 +52,14 @@ public function testCalculateSellingDeniedForProductSellableVariant() $this->assertFalse($mainVariant->getCalculatedSellingDenied()); } - public function testCalculateSellingDeniedForProductNotSellableVariants() + public function testCalculateSellingDeniedForProductNotSellableVariants(): void { - /** @var \App\Model\Product\Product $variant1 */ - $variant1 = $this->getReference(ProductDataFixture::PRODUCT_PREFIX . '53'); - /** @var \App\Model\Product\Product $variant2 */ - $variant2 = $this->getReference(ProductDataFixture::PRODUCT_PREFIX . '54'); - /** @var \App\Model\Product\Product $variant3 */ - $variant3 = $this->getReference(ProductDataFixture::PRODUCT_PREFIX . '148'); - /** @var \App\Model\Product\Product $variant4 */ - $variant4 = $this->getReference(ProductDataFixture::PRODUCT_PREFIX . '149'); - /** @var \App\Model\Product\Product $variant5 */ - $variant5 = $this->getReference(ProductDataFixture::PRODUCT_PREFIX . '150'); - /** @var \App\Model\Product\Product $variant6 */ - $variant6 = $this->getReference(ProductDataFixture::PRODUCT_PREFIX . '151'); - /** @var \App\Model\Product\Product $mainVariant */ - $mainVariant = $this->getReference(ProductDataFixture::PRODUCT_PREFIX . '69'); + $variant1 = $this->productFacade->getById(53); + $variant2 = $this->productFacade->getById(54); + $variant3 = $this->productFacade->getById(148); + $variant4 = $this->productFacade->getById(149); + $variant5 = $this->productFacade->getById(150); + $variant6 = $this->productFacade->getById(151); $variant1productData = $this->productDataFactory->createFromProduct($variant1); $variant1productData->sellingDenied = true; @@ -98,15 +80,17 @@ public function testCalculateSellingDeniedForProductNotSellableVariants() $variant6productData->sellingDenied = true; $this->productFacade->edit($variant6->getId(), $variant6productData); - $this->productSellingDeniedRecalculator->calculateSellingDeniedForProduct($mainVariant); + $this->handleDispatchedRecalculationMessages(); - $this->em->refresh($variant1); - $this->em->refresh($variant2); - $this->em->refresh($variant3); - $this->em->refresh($variant4); - $this->em->refresh($variant5); - $this->em->refresh($variant6); - $this->em->refresh($mainVariant); + $this->em->clear(); + + $variant1 = $this->productFacade->getById(53); + $variant2 = $this->productFacade->getById(54); + $variant3 = $this->productFacade->getById(148); + $variant4 = $this->productFacade->getById(149); + $variant5 = $this->productFacade->getById(150); + $variant6 = $this->productFacade->getById(151); + $mainVariant = $this->productFacade->getById(69); $this->assertTrue($variant1->getCalculatedSellingDenied()); $this->assertTrue($variant2->getCalculatedSellingDenied()); @@ -117,46 +101,46 @@ public function testCalculateSellingDeniedForProductNotSellableVariants() $this->assertTrue($mainVariant->getCalculatedSellingDenied()); } - public function testCalculateSellingDeniedForProductNotSellableMainVariant() + public function testCalculateSellingDeniedForProductNotSellableMainVariant(): void { - /** @var \App\Model\Product\Product $variant1 */ - $variant1 = $this->getReference(ProductDataFixture::PRODUCT_PREFIX . '53'); - /** @var \App\Model\Product\Product $variant2 */ - $variant2 = $this->getReference(ProductDataFixture::PRODUCT_PREFIX . '54'); - /** @var \App\Model\Product\Product $mainVariant */ - $mainVariant = $this->getReference(ProductDataFixture::PRODUCT_PREFIX . '69'); + $mainVariant = $this->productFacade->getById(69); + + $mainVariantProductData = $this->productDataFactory->createFromProduct($mainVariant); + $mainVariantProductData->sellingDenied = true; + $this->productFacade->edit($mainVariant->getId(), $mainVariantProductData); - $mainVariantproductData = $this->productDataFactory->createFromProduct($mainVariant); - $mainVariantproductData->sellingDenied = true; - $this->productFacade->edit($mainVariant->getId(), $mainVariantproductData); + $this->handleDispatchedRecalculationMessages(); - $this->em->refresh($variant1); - $this->em->refresh($variant2); - $this->em->refresh($mainVariant); + $this->em->clear(); + + $variant1 = $this->productFacade->getById(53); + $variant2 = $this->productFacade->getById(54); + $mainVariant = $this->productFacade->getById(69); $this->assertTrue($variant1->getCalculatedSellingDenied()); $this->assertTrue($variant2->getCalculatedSellingDenied()); $this->assertTrue($mainVariant->getCalculatedSellingDenied()); } - public function testPropagationCalculatedSaleExclusionToCalculateSellingDeniedForVariant() + public function testPropagationCalculatedSaleExclusionToCalculateSellingDeniedForVariant(): void { - /** @var \App\Model\Product\Product $variant1 */ - $variant1 = $this->getReference(ProductDataFixture::PRODUCT_PREFIX . '53'); + $variant1 = $this->productFacade->getById(53); /** @var \App\Model\Product\ProductData $variant1ProductData */ $variant1ProductData = $this->productDataFactory->createFromProduct($variant1); $variant1ProductData->sellingDenied = false; - foreach ($variant1ProductData->stockProductData as &$stockProductData) { - $stockProductData->productQuantity = 0; + foreach ($variant1ProductData->productStockData as $productStockData) { + $productStockData->productQuantity = 0; } $this->productFacade->edit($variant1->getId(), $variant1ProductData); + $this->handleDispatchedRecalculationMessages(); + $this->em->clear(); - $variant1 = $this->getReference(ProductDataFixture::PRODUCT_PREFIX . '53'); + $variant1 = $this->productFacade->getById(53); foreach ($this->domain->getAll() as $domainConfig) { $this->assertTrue($variant1->getCalculatedSaleExclusion($domainConfig->getId())); diff --git a/app/tests/FrontendApiBundle/Functional/Product/ProductSellingDeniedOnDomainTest.php b/app/tests/FrontendApiBundle/Functional/Product/ProductSellingDeniedOnDomainTest.php index 90c9d1cc70..50f49656a8 100644 --- a/app/tests/FrontendApiBundle/Functional/Product/ProductSellingDeniedOnDomainTest.php +++ b/app/tests/FrontendApiBundle/Functional/Product/ProductSellingDeniedOnDomainTest.php @@ -7,17 +7,11 @@ use App\DataFixtures\Demo\ProductDataFixture; use App\Model\Product\ProductDataFactory; use App\Model\Product\ProductFacade; -use App\Model\Product\ProductSellingDeniedRecalculator; use Tests\FrontendApiBundle\Test\GraphQlTestCase; use function sleep; class ProductSellingDeniedOnDomainTest extends GraphQlTestCase { - /** - * @inject - */ - private ProductSellingDeniedRecalculator $productSellingDeniedRecalculator; - /** * @inject */ @@ -36,7 +30,6 @@ public function testSellingDeniedOnDomain(): void $productData = $this->productDataFactory->createFromProduct($product); $productData->saleExclusion[$this->domain->getId()] = true; $this->productFacade->edit($product->getId(), $productData); - $this->productSellingDeniedRecalculator->calculateSellingDeniedForProduct($product); $this->handleDispatchedRecalculationMessages(); From 8ec86ea75a9a5e7ba6c9da901537b3883c80990a Mon Sep 17 00:00:00 2001 From: Martin Grossmann Date: Fri, 15 Dec 2023 18:04:14 +0100 Subject: [PATCH 31/32] cleanStorefrontCacheFacade is now moved to shopsys/framework --- app/config/services.yaml | 4 -- .../CleanStorefrontQueryCacheCommand.php | 4 +- .../Redis/CleanStorefrontCacheFacade.php | 66 ------------------- .../Controller/Admin/ArticleController.php | 4 +- app/src/Controller/Admin/RedisController.php | 4 +- .../LanguageConstantFacade.php | 4 +- .../Model/Navigation/NavigationItemFacade.php | 4 +- .../NavigationSaveOrderingListener.php | 4 +- 8 files changed, 12 insertions(+), 82 deletions(-) delete mode 100644 app/src/Component/Redis/CleanStorefrontCacheFacade.php diff --git a/app/config/services.yaml b/app/config/services.yaml index c505abf3ca..38d68209ce 100644 --- a/app/config/services.yaml +++ b/app/config/services.yaml @@ -734,10 +734,6 @@ services: - '@snc_redis.global' - '@snc_redis.blog_article_export_queue' - App\Component\Redis\CleanStorefrontCacheFacade: - arguments: - $storefrontGraphqlQueryClient: '@snc_redis.storefront_graphql_query' - Shopsys\FrameworkBundle\Component\Redis\RedisFacade: alias: App\Component\Redis\RedisFacade diff --git a/app/src/Command/CleanStorefrontQueryCacheCommand.php b/app/src/Command/CleanStorefrontQueryCacheCommand.php index bf56d0ebf3..6c0167798e 100644 --- a/app/src/Command/CleanStorefrontQueryCacheCommand.php +++ b/app/src/Command/CleanStorefrontQueryCacheCommand.php @@ -4,7 +4,7 @@ namespace App\Command; -use App\Component\Redis\CleanStorefrontCacheFacade; +use Shopsys\FrameworkBundle\Component\Redis\CleanStorefrontCacheFacade; use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; @@ -16,7 +16,7 @@ class CleanStorefrontQueryCacheCommand extends Command { /** - * @param \App\Component\Redis\CleanStorefrontCacheFacade $cleanStorefrontCacheFacade + * @param \Shopsys\FrameworkBundle\Component\Redis\CleanStorefrontCacheFacade $cleanStorefrontCacheFacade */ public function __construct( private readonly CleanStorefrontCacheFacade $cleanStorefrontCacheFacade, diff --git a/app/src/Component/Redis/CleanStorefrontCacheFacade.php b/app/src/Component/Redis/CleanStorefrontCacheFacade.php deleted file mode 100644 index 965f1feaee..0000000000 --- a/app/src/Component/Redis/CleanStorefrontCacheFacade.php +++ /dev/null @@ -1,66 +0,0 @@ -cleanStorefrontCacheByKeyPattern($keyPattern); - } - - /** - * @param string $queryKey - */ - public function cleanStorefrontGraphqlQueryCache(string $queryKey = ''): void - { - $keyPattern = 'queryCache:' . $queryKey . '*'; - $this->cleanStorefrontCacheByKeyPattern($keyPattern); - } - - /** - * @param string $keyPattern - */ - private function cleanStorefrontCacheByKeyPattern(string $keyPattern): void - { - $prefix = (string)$this->storefrontGraphqlQueryClient->getOption(Redis::OPT_PREFIX); - - $keyPattern = $prefix . $keyPattern; - $iterator = null; - $toRemove = []; - - do { - $keys = $this->storefrontGraphqlQueryClient->scan($iterator, $keyPattern, 0); - - if ($keys === false || count($keys) === 0) { - continue; - } - - foreach ($keys as $key) { - $toRemove[] = str_replace($prefix, '', $key); - } - } while (is_numeric($iterator) && $iterator > 0); - - $this->storefrontGraphqlQueryClient->unlink($toRemove); - } -} diff --git a/app/src/Controller/Admin/ArticleController.php b/app/src/Controller/Admin/ArticleController.php index 3c6b2aac90..58c1aa1819 100644 --- a/app/src/Controller/Admin/ArticleController.php +++ b/app/src/Controller/Admin/ArticleController.php @@ -4,11 +4,11 @@ namespace App\Controller\Admin; -use App\Component\Redis\CleanStorefrontCacheFacade; use App\Model\Article\Article; use Shopsys\FrameworkBundle\Component\ConfirmDelete\ConfirmDeleteResponseFactory; use Shopsys\FrameworkBundle\Component\Domain\AdminDomainTabsFacade; use Shopsys\FrameworkBundle\Component\Grid\GridFactory; +use Shopsys\FrameworkBundle\Component\Redis\CleanStorefrontCacheFacade; use Shopsys\FrameworkBundle\Controller\Admin\ArticleController as BaseArticleController; use Shopsys\FrameworkBundle\Model\AdminNavigation\BreadcrumbOverrider; use Shopsys\FrameworkBundle\Model\Article\ArticleDataFactoryInterface; @@ -35,7 +35,7 @@ class ArticleController extends BaseArticleController * @param \Shopsys\FrameworkBundle\Component\ConfirmDelete\ConfirmDeleteResponseFactory $confirmDeleteResponseFactory * @param \App\Model\LegalConditions\LegalConditionsFacade $legalConditionsFacade * @param \Shopsys\FrameworkBundle\Model\Cookies\CookiesFacade $cookiesFacade - * @param \App\Component\Redis\CleanStorefrontCacheFacade $cleanStorefrontCacheFacade + * @param \Shopsys\FrameworkBundle\Component\Redis\CleanStorefrontCacheFacade $cleanStorefrontCacheFacade */ public function __construct( ArticleFacade $articleFacade, diff --git a/app/src/Controller/Admin/RedisController.php b/app/src/Controller/Admin/RedisController.php index a2d7bb0da0..c89a1cfb52 100644 --- a/app/src/Controller/Admin/RedisController.php +++ b/app/src/Controller/Admin/RedisController.php @@ -4,7 +4,7 @@ namespace App\Controller\Admin; -use App\Component\Redis\CleanStorefrontCacheFacade; +use Shopsys\FrameworkBundle\Component\Redis\CleanStorefrontCacheFacade; use Shopsys\FrameworkBundle\Controller\Admin\AdminBaseController; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; @@ -13,7 +13,7 @@ class RedisController extends AdminBaseController { /** - * @param \App\Component\Redis\CleanStorefrontCacheFacade $cleanStorefrontCacheFacade + * @param \Shopsys\FrameworkBundle\Component\Redis\CleanStorefrontCacheFacade $cleanStorefrontCacheFacade */ public function __construct( private CleanStorefrontCacheFacade $cleanStorefrontCacheFacade, diff --git a/app/src/Model/LanguageConstant/LanguageConstantFacade.php b/app/src/Model/LanguageConstant/LanguageConstantFacade.php index 65a5859e8d..4ee21c6eb1 100644 --- a/app/src/Model/LanguageConstant/LanguageConstantFacade.php +++ b/app/src/Model/LanguageConstant/LanguageConstantFacade.php @@ -4,10 +4,10 @@ namespace App\Model\LanguageConstant; -use App\Component\Redis\CleanStorefrontCacheFacade; use Doctrine\ORM\EntityManagerInterface; use GuzzleHttp\Client; use League\Flysystem\FilesystemOperator; +use Shopsys\FrameworkBundle\Component\Redis\CleanStorefrontCacheFacade; use function GuzzleHttp\json_decode; class LanguageConstantFacade @@ -21,7 +21,7 @@ class LanguageConstantFacade * @param string $languageConstantsUrlPattern * @param string $domainLocalesDirectory * @param \League\Flysystem\FilesystemOperator $filesystem - * @param \App\Component\Redis\CleanStorefrontCacheFacade $cleanStorefrontCacheFacade + * @param \Shopsys\FrameworkBundle\Component\Redis\CleanStorefrontCacheFacade $cleanStorefrontCacheFacade */ public function __construct( private readonly EntityManagerInterface $em, diff --git a/app/src/Model/Navigation/NavigationItemFacade.php b/app/src/Model/Navigation/NavigationItemFacade.php index 98b3bf849e..0d991dc148 100644 --- a/app/src/Model/Navigation/NavigationItemFacade.php +++ b/app/src/Model/Navigation/NavigationItemFacade.php @@ -4,10 +4,10 @@ namespace App\Model\Navigation; -use App\Component\Redis\CleanStorefrontCacheFacade; use Doctrine\ORM\QueryBuilder; use Shopsys\FrameworkBundle\Component\Domain\Config\DomainConfig; use Shopsys\FrameworkBundle\Component\EntityExtension\EntityManagerDecorator; +use Shopsys\FrameworkBundle\Component\Redis\CleanStorefrontCacheFacade; class NavigationItemFacade { @@ -16,7 +16,7 @@ class NavigationItemFacade * @param \App\Model\Navigation\NavigationItemRepository $navigationItemRepository * @param \App\Model\Navigation\NavigationItemCategoryFacade $navigationItemCategoryFacade * @param \App\Model\Navigation\NavigationItemDetailFactory $navigationItemDetailFactory - * @param \App\Component\Redis\CleanStorefrontCacheFacade $cleanStorefrontCacheFacade + * @param \Shopsys\FrameworkBundle\Component\Redis\CleanStorefrontCacheFacade $cleanStorefrontCacheFacade */ public function __construct( private readonly EntityManagerDecorator $em, diff --git a/app/src/Model/Navigation/NavigationSaveOrderingListener.php b/app/src/Model/Navigation/NavigationSaveOrderingListener.php index 5030c5dbf3..e8f252c197 100644 --- a/app/src/Model/Navigation/NavigationSaveOrderingListener.php +++ b/app/src/Model/Navigation/NavigationSaveOrderingListener.php @@ -4,7 +4,7 @@ namespace App\Model\Navigation; -use App\Component\Redis\CleanStorefrontCacheFacade; +use Shopsys\FrameworkBundle\Component\Redis\CleanStorefrontCacheFacade; use Symfony\Component\HttpKernel\Event\ControllerEvent; class NavigationSaveOrderingListener @@ -12,7 +12,7 @@ class NavigationSaveOrderingListener private const SAVE_ORDERING_URI = '/admin/_grid/save-ordering/'; /** - * @param \App\Component\Redis\CleanStorefrontCacheFacade $cleanStorefrontCacheFacade + * @param \Shopsys\FrameworkBundle\Component\Redis\CleanStorefrontCacheFacade $cleanStorefrontCacheFacade */ public function __construct( private readonly CleanStorefrontCacheFacade $cleanStorefrontCacheFacade, From 443e73232ccc73ee2489da2e326d7d00ad504c77 Mon Sep 17 00:00:00 2001 From: Martin Grossmann Date: Fri, 15 Dec 2023 18:12:07 +0100 Subject: [PATCH 32/32] removed unused Product::createFriendlyUrlsWhenRenamed() method --- app/src/Model/Product/ProductFacade.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/app/src/Model/Product/ProductFacade.php b/app/src/Model/Product/ProductFacade.php index 6def688854..b9a49e9e94 100644 --- a/app/src/Model/Product/ProductFacade.php +++ b/app/src/Model/Product/ProductFacade.php @@ -44,8 +44,6 @@ * @method createProductVisibilities(\App\Model\Product\Product $product) * @method \App\Model\Product\Product getOneByCatnumExcludeMainVariants(string $productCatnum) * @method \App\Model\Product\Product getByUuid(string $uuid) - * @method createFriendlyUrlsWhenRenamed(\App\Model\Product\Product $product, array $originalNames) - * @method array getChangedNamesByLocale(\App\Model\Product\Product $product, array $originalNames) * @method \App\Model\Product\Product create(\App\Model\Product\ProductData $productData) * @property \App\Model\Product\ProductFactory $productFactory * @method setAdditionalDataAfterCreate(\App\Model\Product\Product $product, \App\Model\Product\ProductData $productData)