diff --git a/vendor/magento/module-shared-catalog/Observer/Controller/SaveProduct.php b/vendor/magento/module-shared-catalog/Observer/Controller/SaveProduct.php
deleted file mode 100644
index 09781c239090..000000000000
--- a/vendor/magento/module-shared-catalog/Observer/Controller/SaveProduct.php
+++ /dev/null
@@ -1,135 +0,0 @@
-productSharedCatalogManagement = $productSharedCatalogManagement;
- $this->sharedCatalogRepository = $sharedCatalogRepository;
- $this->searchCriteriaBuilder = $searchCriteriaBuilder;
- $this->productSharedCatalogsLoader = $productSharedCatalogsLoader;
- }
-
- /**
- * Add product to the selected shared catalogs after saving.
- *
- * @param Observer $observer
- * @return void
- */
- public function execute(Observer $observer)
- {
- /** @var \Magento\Catalog\Model\Product $product */
- $product = $observer->getEvent()->getProduct();
-
- $customerGroupIds = $this->retrieveCustomerGroupIds((array)$product->getData('tier_price'));
- $sharedCatalogIds = $this->prepareSharedCatalogIds(
- (array)$product->getData('shared_catalog'),
- (array)$customerGroupIds
- );
- $assignedSharedCatalogs = $this->productSharedCatalogsLoader->getAssignedSharedCatalogs($product->getSku());
- $assignedSharedCatalogIds = array_keys($assignedSharedCatalogs);
-
- $forCreate = array_diff($sharedCatalogIds, $assignedSharedCatalogIds);
- foreach ($forCreate as $sharedCatalogId) {
- $this->productSharedCatalogManagement->assignProducts($sharedCatalogId, [$product]);
- }
-
- $forDelete = array_diff($assignedSharedCatalogIds, $sharedCatalogIds);
- foreach ($forDelete as $sharedCatalogId) {
- $this->productSharedCatalogManagement->unassignProducts($sharedCatalogId, [$product]);
- }
- }
-
- /**
- * Prepare list of shared catalog ids.
- *
- * @param array $sharedCatalogsIds
- * @param array $customerGroupIds
- * @return array
- */
- private function prepareSharedCatalogIds(array $sharedCatalogsIds, array $customerGroupIds): array
- {
- if ($customerGroupIds) {
- $this->searchCriteriaBuilder->addFilter(
- SharedCatalogInterface::CUSTOMER_GROUP_ID,
- $customerGroupIds,
- 'in'
- );
- $searchCriteria = $this->searchCriteriaBuilder->create();
- $sharedCatalogs = $this->sharedCatalogRepository->getList($searchCriteria)->getItems();
-
- foreach ($sharedCatalogs as $sharedCatalog) {
- if (!in_array($sharedCatalog->getId(), $sharedCatalogsIds)) {
- $sharedCatalogsIds[] = $sharedCatalog->getId();
- }
- }
- }
-
- return $sharedCatalogsIds;
- }
-
- /**
- * Retrieve customer group ids list from tier prices data.
- *
- * @param array $tierPricesData
- * @return array
- */
- private function retrieveCustomerGroupIds(array $tierPricesData): array
- {
- $customerGroups = [];
-
- foreach ($tierPricesData as $tierPrice) {
- if (!isset($tierPrice['delete']) && !empty($tierPrice['cust_group'])) {
- $customerGroups[] = $tierPrice['cust_group'];
- }
- }
-
- return $customerGroups;
- }
-}
diff --git a/vendor/magento/module-shared-catalog/Plugin/Catalog/Controller/Adminhtml/Product/Save.php b/vendor/magento/module-shared-catalog/Plugin/Catalog/Controller/Adminhtml/Product/Save.php
new file mode 100644
index 000000000000..63c398d18d53
--- /dev/null
+++ b/vendor/magento/module-shared-catalog/Plugin/Catalog/Controller/Adminhtml/Product/Save.php
@@ -0,0 +1,229 @@
+productRepository = $productRepository;
+ $this->searchCriteriaBuilder = $searchCriteriaBuilder;
+ $this->sharedCatalogRepository = $sharedCatalogRepository;
+ $this->productSharedCatalogsLoader = $productSharedCatalogsLoader;
+ $this->productSharedCatalogManagement = $productSharedCatalogManagement;
+ }
+
+ /**
+ * Intercepts product save action and performs shared catalog adjustments
+ *
+ * @param ProductSave $subject
+ * @param callable $proceed
+ * @return mixed
+ * @throws LocalizedException
+ * @throws NoSuchEntityException
+ */
+ public function aroundExecute(ProductSave $subject, callable $proceed): mixed
+ {
+ try {
+ $oldProduct = $this->getProductBeforeSave((int)$subject->getRequest()->getParam('id'));
+ } catch (\Throwable) {
+ return $proceed();
+ }
+ $returnValue = $proceed();
+ $productRequestData = $subject->getRequest()->getParam('product');
+ try {
+ $product = $this->productRepository->get($productRequestData['sku']);
+ } catch (\Throwable) {
+ return $returnValue;
+ }
+
+ $sharedCatalogIds = $this->getSharedCatalogIds($productRequestData, $oldProduct);
+
+ $assignedSharedCatalogs = $this->productSharedCatalogsLoader->getAssignedSharedCatalogs($product->getSku());
+ $assignedSharedCatalogIds = array_keys($assignedSharedCatalogs);
+
+ $forCreate = array_diff($sharedCatalogIds, $assignedSharedCatalogIds);
+ foreach ($forCreate as $sharedCatalogId) {
+ $this->productSharedCatalogManagement->assignProducts($sharedCatalogId, [$product]);
+ }
+
+ $forDelete = array_diff($assignedSharedCatalogIds, $sharedCatalogIds);
+ foreach ($forDelete as $sharedCatalogId) {
+ $this->productSharedCatalogManagement->unassignProducts($sharedCatalogId, [$product]);
+ }
+
+ return $returnValue;
+ }
+
+ /**
+ * Get product details before save action is processed
+ *
+ * @param int $productId
+ * @return ProductInterface|null
+ * @throws NoSuchEntityException
+ */
+ private function getProductBeforeSave(int $productId): ?ProductInterface
+ {
+ $oldProduct = null;
+ if ($productId) {
+ $oldProduct = clone($this->productRepository->getById($productId));
+ }
+
+ return $oldProduct;
+ }
+
+ /**
+ * Prepare list of shared catalog ids.
+ *
+ * @param array $sharedCatalogsIds
+ * @param array $customerGroupIds
+ * @return array
+ * @throws LocalizedException
+ */
+ private function prepareSharedCatalogIds(array $sharedCatalogsIds, array $customerGroupIds): array
+ {
+ if ($customerGroupIds) {
+ $this->searchCriteriaBuilder->addFilter(
+ SharedCatalogInterface::CUSTOMER_GROUP_ID,
+ $customerGroupIds,
+ 'in'
+ );
+ $searchCriteria = $this->searchCriteriaBuilder->create();
+ $sharedCatalogs = $this->sharedCatalogRepository->getList($searchCriteria)->getItems();
+ $sharedCatalogsIds = [];
+ foreach ($sharedCatalogs as $sharedCatalog) {
+ $sharedCatalogsIds[] = $sharedCatalog->getId();
+ }
+ }
+
+ return $sharedCatalogsIds;
+ }
+
+ /**
+ * Retrieve customer group ids list from tier prices data.
+ *
+ * @param array $tierPricesData
+ * @return array
+ */
+ private function retrieveCustomerGroupIds(array $tierPricesData): array
+ {
+ $customerGroups = [];
+
+ foreach ($tierPricesData as $tierPrice) {
+ if (!isset($tierPrice['delete']) && !empty($tierPrice['cust_group'])) {
+ $customerGroups[] = $tierPrice['cust_group'];
+ }
+ }
+
+ return $customerGroups;
+ }
+
+ /**
+ * Generate Shared Catalog ids taking into account configured tier prices
+ *
+ * @param mixed $productRequestData
+ * @param ProductInterface|null $oldProduct
+ * @return array
+ * @throws LocalizedException
+ */
+ public function getSharedCatalogIds(mixed $productRequestData, ?ProductInterface $oldProduct): array
+ {
+ $currentCustomerGroupIds = $this->retrieveCustomerGroupIds(
+ !empty($productRequestData['tier_price']) ? (array)$productRequestData['tier_price'] : []
+ );
+ if ($oldProduct) {
+ $oldTierPrices = [];
+ foreach ($oldProduct->getTierPrices() as $tierPrice) {
+ $oldTierPrices [] = [
+ 'cust_group' => $tierPrice->getCustomerGroupId()
+ ];
+ }
+ $previousCustomerGroupIds = $this->retrieveCustomerGroupIds($oldTierPrices);
+ } else {
+ $previousCustomerGroupIds = [];
+ }
+
+ $sharedCatalogIds = (
+ !empty($productRequestData['shared_catalog']) ?
+ (array)$productRequestData['shared_catalog'] :
+ []
+ );
+ if ($addedCustomerGroupIds = array_diff($currentCustomerGroupIds, $previousCustomerGroupIds)) {
+ $addedCatalogIds = $this->prepareSharedCatalogIds(
+ $sharedCatalogIds,
+ $addedCustomerGroupIds
+ );
+
+ $sharedCatalogIds = array_unique(array_merge($sharedCatalogIds, $addedCatalogIds));
+ }
+
+ return $sharedCatalogIds;
+ }
+}
diff --git a/vendor/magento/module-shared-catalog/etc/adminhtml/di.xml b/vendor/magento/module-shared-catalog/etc/adminhtml/di.xml
index f8e0e0182c0c..1afbfe53caf9 100644
--- a/vendor/magento/module-shared-catalog/etc/adminhtml/di.xml
+++ b/vendor/magento/module-shared-catalog/etc/adminhtml/di.xml
@@ -144,4 +144,10 @@
+
+
+
diff --git a/vendor/magento/module-shared-catalog/etc/adminhtml/events.xml b/vendor/magento/module-shared-catalog/etc/adminhtml/events.xml
index 117ae7e99615..67af14df7d3a 100644
--- a/vendor/magento/module-shared-catalog/etc/adminhtml/events.xml
+++ b/vendor/magento/module-shared-catalog/etc/adminhtml/events.xml
@@ -12,7 +12,4 @@
-
-
-