diff --git a/vendor/magento/module-catalog-permissions/Model/Plugin/RecollectQuoteWithCatalogPermission.php b/vendor/magento/module-catalog-permissions/Model/Plugin/RecollectQuoteWithCatalogPermission.php
new file mode 100644
index 00000000000..0c211cbc05c
--- /dev/null
+++ b/vendor/magento/module-catalog-permissions/Model/Plugin/RecollectQuoteWithCatalogPermission.php
@@ -0,0 +1,138 @@
+getId() ?: $customer->getEntityId();
+ $previousCustomerData = [];
+ /** @var Customer $customer */
+ if ($customerId && empty($customer->getTaxvat())) {
+ try {
+ $prevCustomerData = $this->customerRepository->getById($customerId);
+ $previousCustomerData = $prevCustomerData->__toArray();
+ // phpcs:ignore Magento2.CodeAnalysis.EmptyBlock
+ } catch (NoSuchEntityException $e) {
+ }
+ }
+
+ $result = $proceed($customer);
+
+ if (!empty($previousCustomerData)
+ && $previousCustomerData['group_id'] !== null
+ && $previousCustomerData['group_id'] !== $customer->getGroupId()
+ && empty($previousCustomerData['taxvat'])) {
+ try {
+ $customerAccountShareScope = $this->scopeConfig->getValue(
+ Share::XML_PATH_CUSTOMER_ACCOUNT_SHARE,
+ ScopeConfigInterface::SCOPE_TYPE_DEFAULT
+ );
+ if ($customerAccountShareScope === Share::SHARE_WEBSITE) {
+ /** @var Quote $quote */
+ $quote = $this->cartRepository->getActiveForCustomer($customer->getId());
+ if ($quote) {
+ $quote->setCustomerGroupId($customer->getGroupId());
+ $this->verifyPermission->verify($quote, $customer);
+ $quote->collectTotals();
+ $this->cartRepository->save($quote);
+ }
+ } else {
+ $this->collectTotalsForCustomer($customer);
+ }
+ // phpcs:ignore Magento2.CodeAnalysis.EmptyBlock
+ } catch (NoSuchEntityException $e) {
+ }
+ }
+
+ return $result;
+ }
+
+ /**
+ * Re-collect totals for customer group change
+ *
+ * @param Customer|AbstractModel $customer
+ * @return void
+ * @throws NoSuchEntityException
+ */
+ private function collectTotalsForCustomer(Customer|AbstractModel $customer): void
+ {
+ $allStores = $this->storeManager->getStores();
+ foreach ($allStores as $store) {
+ /** @var Quote $quote */
+ $quote = $this->cartRepository->getActiveForCustomer($customer->getId(), [$store->getId()]);
+ if ($quote) {
+ $this->verifyPermission->verify($quote, $customer);
+ $quote->collectTotals();
+ $this->cartRepository->save($quote);
+ }
+ }
+ }
+}
diff --git a/vendor/magento/module-catalog-permissions/Model/VerifyQuoteItemPermissionAfterGroupChange.php b/vendor/magento/module-catalog-permissions/Model/VerifyQuoteItemPermissionAfterGroupChange.php
new file mode 100644
index 00000000000..fb812c19b71
--- /dev/null
+++ b/vendor/magento/module-catalog-permissions/Model/VerifyQuoteItemPermissionAfterGroupChange.php
@@ -0,0 +1,156 @@
+getStoreId();
+ $customerGroupId = $customer->getGroupId();
+ $canCustomerAddToCart = $this->isConfigSettingsCanAddToCart($customerGroupId, $storeId);
+
+ if ($this->canCheckoutGeneralConfigPermissions($customerGroupId, $storeId) &&
+ $canCustomerAddToCart) {
+ return;
+ }
+
+ $websiteId = $this->storeRepository->getById($storeId)->getWebsiteId();
+ foreach ($quote->getAllItems() as $item) {
+ $categoryIds = $item->getProduct()->getCategoryIds();
+
+ if (empty($categoryIds)) {
+ $item->setDisableAddToCart(true);
+ continue;
+ }
+
+ $categoryPermissionIndex = $this->permissionIndex->getIndexForCategory(
+ $categoryIds,
+ $customerGroupId,
+ $websiteId
+ );
+ $permissions = [];
+ foreach ($categoryPermissionIndex as $permission) {
+ $permissions[] = (int)$permission['grant_checkout_items'];
+ }
+
+ if ((!empty($permissions) && !in_array(Permission::PERMISSION_ALLOW, $permissions, true)) ||
+ (!$canCustomerAddToCart && empty($permissions))) {
+ $item->setDisableAddToCart(true);
+ }
+ }
+ $this->verifyQuoteItems($quote);
+ }
+
+ /**
+ * Get Checkout Permissions from general config by Customer Group Id
+ *
+ * @param int $customerGroupId
+ * @param int $storeId
+ * @return bool
+ */
+ private function canCheckoutGeneralConfigPermissions(int $customerGroupId, int $storeId) : bool
+ {
+ if ((int)$this->permissionsConfig->getCheckoutItemsMode($storeId) === ConfigInterface::GRANT_CUSTOMER_GROUP) {
+ $grantCategoryView = in_array(
+ $customerGroupId,
+ $this->permissionsConfig->getCatalogCategoryViewGroups($storeId)
+ );
+ } else {
+ $viewMode = (int)$this->permissionsConfig->getCatalogCategoryViewMode($storeId);
+ $grantCategoryView = $viewMode === ConfigInterface::GRANT_ALL;
+ }
+
+ return $grantCategoryView;
+ }
+
+ /**
+ * Check if current customer group can add product to cart
+ *
+ * @param int $customerGroupId
+ * @param int $storeId
+ * @return bool
+ */
+ private function isConfigSettingsCanAddToCart(int $customerGroupId, int $storeId) : bool
+ {
+ $canAddToCart = true;
+ if ((int) $this->permissionsConfig->getCheckoutItemsMode($storeId) === ConfigInterface::GRANT_CUSTOMER_GROUP) {
+ $canAddToCart = in_array(
+ $customerGroupId,
+ $this->permissionsConfig->getCheckoutItemsGroups($storeId)
+ );
+ }
+ return $canAddToCart;
+ }
+
+ /**
+ * Verify quote items for customer
+ *
+ * @param Quote $quote
+ * @return void
+ */
+ private function verifyQuoteItems(Quote $quote): void
+ {
+ $allQuoteItems = $quote->getAllItems();
+ foreach ($allQuoteItems as $quoteItem) {
+ /** @var Item $quoteItem */
+ if ($quoteItem->getParentItem()) {
+ continue;
+ }
+
+ if ($quoteItem->getDisableAddToCart() && !$quoteItem->isDeleted()) {
+ $quote->removeItem($quoteItem->getQuoteId());
+ $quote->deleteItem($quoteItem);
+ }
+ }
+ }
+}
diff --git a/vendor/magento/module-catalog-permissions/Observer/CheckQuotePermissionsAfterCustomerLoginObserver.php b/vendor/magento/module-catalog-permissions/Observer/CheckQuotePermissionsAfterCustomerLoginObserver.php
new file mode 100644
index 00000000000..a617441b2f4
--- /dev/null
+++ b/vendor/magento/module-catalog-permissions/Observer/CheckQuotePermissionsAfterCustomerLoginObserver.php
@@ -0,0 +1,85 @@
+permissionsConfig->isEnabled()) {
+ return $this;
+ }
+
+ $customer = $this->customerSession->getCustomer();
+ if (!$customer || !$customer->getId()) {
+ return $this;
+ }
+
+ $customerId = $customer->getId() ?: $customer->getEntityId();
+
+ $quote = $this->cartRepository->getActiveForCustomer($customerId) ?? null;
+
+ if ($quote) {
+ $this->verifyPermission->verify($quote, $customer);
+ $quote->collectTotals();
+ $this->cartRepository->save($quote);
+ }
+ return $this;
+ }
+}
diff --git a/vendor/magento/module-catalog-permissions/Observer/CheckQuotePermissionsObserver.php b/vendor/magento/module-catalog-permissions/Observer/CheckQuotePermissionsObserver.php
index 0a19732e98a..ff039d5e4b7 100644
--- a/vendor/magento/module-catalog-permissions/Observer/CheckQuotePermissionsObserver.php
+++ b/vendor/magento/module-catalog-permissions/Observer/CheckQuotePermissionsObserver.php
@@ -123,7 +123,11 @@ class CheckQuotePermissionsObserver implements ObserverInterface
protected function _initPermissionsOnQuoteItems(Quote $quote)
{
$storeId = $quote->getStoreId();
- $customerGroupId = $this->_customerSession->getCustomerGroupId();
+
+ $customer = $this->_customerSession->getCustomer();
+ $customerGroupId = ($customer && $customer->getId()) ?
+ (int)$customer->getGroupId() :
+ (int)$this->_customerSession->getCustomerGroupId();
$canCustomerAddToCart = $this->isConfigSettingsCanAddToCart($customerGroupId, $storeId);
if ($this->canCheckoutGeneralConfigPermissions($customerGroupId, $storeId) &&
diff --git a/vendor/magento/module-catalog-permissions/etc/adminhtml/di.xml b/vendor/magento/module-catalog-permissions/etc/adminhtml/di.xml
index 6133b54bbc0..74949517095 100644
--- a/vendor/magento/module-catalog-permissions/etc/adminhtml/di.xml
+++ b/vendor/magento/module-catalog-permissions/etc/adminhtml/di.xml
@@ -1,8 +1,19 @@
@@ -10,4 +21,7 @@
+
+
+
diff --git a/vendor/magento/module-catalog-permissions/etc/frontend/events.xml b/vendor/magento/module-catalog-permissions/etc/frontend/events.xml
index cc1de1319ff..9ed9d1e7c11 100644
--- a/vendor/magento/module-catalog-permissions/etc/frontend/events.xml
+++ b/vendor/magento/module-catalog-permissions/etc/frontend/events.xml
@@ -1,8 +1,19 @@
@@ -60,4 +71,7 @@
+
+
+