Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Controller/Getconfig/Index.php
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ public function execute()
'PRODUCT_SYNCHRONIZATION_ADDITIONAL_FIELDS_HEAVY_QUERY' => $this->scopeConfig->getValue(Config::XML_PATH_PRODUCT_SYNCHRONIZATION_ADDITIONAL_FIELDS_HEAVY_QUERY, $scope, $scopeID),
'PRODUCT_SYNCHRONIZATION_SALABLE_ONLY' => $this->scopeConfig->getValue(Config::XML_PATH_PRODUCT_SYNCHRONIZATION_SALABLE_ONLY, $scope, $scopeID),
'PRODUCT_SYNCHRONIZATION_VISIBILITY' => $this->scopeConfig->getValue(Config::XML_PATH_PRODUCT_SYNCHRONIZATION_VISIBILITY, $scope, $scopeID),
'PRODUCT_SYNCHRONIZATION_EXCLUDE_DISABLED_PRODUCTS' => $this->scopeConfig->getValue(Config::XML_PATH_PRODUCT_SYNCHRONIZATION_EXCLUDE_DISABLED_PRODUCTS, $scope, $scopeID),
'PRODUCT_SYNCHRONIZATION_DISABLE_ORDER_SYNCHRONIZATION' => $this->scopeConfig->getValue(Config::XML_PATH_PRODUCT_SYNCHRONIZATION_DISABLE_ORDER_SYNCHRONIZATION, $scope, $scopeID),
'PRODUCT_SYNCHRONIZATION_ENABLE_ORDER_RETURN_SYNCHRONIZATION' => $this->scopeConfig->getValue(Config::XML_PATH_PRODUCT_SYNCHRONIZATION_ENABLE_ORDER_RETURN_SYNCHRONIZATION, $scope, $scopeID),
'PRODUCT_SYNCHRONIZATION_IMAGE_TYPE' => $this->scopeConfig->getValue(Config::XML_PATH_PRODUCT_SYNCHRONIZATION_IMAGE_TYPE, $scope, $scopeID),
Expand Down
96 changes: 96 additions & 0 deletions Model/Adapter/Product.php
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,11 @@ protected function prepareCollection($page, $limit, $orderBy, $order, $scope, $s
break;
}

// Filter out disabled products and their children if configuration is enabled
if ($this->scopeConfig->getValue(Config::XML_PATH_PRODUCT_SYNCHRONIZATION_EXCLUDE_DISABLED_PRODUCTS, $scope, $scopeid)) {
$this->filterDisabledProducts($collection, $scopeid);
}

$collection->setPageSize($limit)->setCurPage($page)->addOrder($orderBy, $order);

$this->eventManager->dispatch('clerk_' . $this->eventPrefix . '_get_collection_after', [
Expand All @@ -274,6 +279,97 @@ protected function prepareCollection($page, $limit, $orderBy, $order, $scope, $s
}
}

/**
* Filter out disabled products and their children from the collection
*
* @param $collection
* @param $scopeid
* @return void
*/
protected function filterDisabledProducts($collection, $scopeid)
{
try {
// First, filter out disabled products directly
$collection->addAttributeToFilter('status', \Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED);

// Get all disabled configurable products to exclude their children
$disabledConfigurableProducts = $this->collectionFactory->create()
->addStoreFilter($scopeid)
->addAttributeToFilter('type_id', self::PRODUCT_TYPE_CONFIGURABLE)
->addAttributeToFilter('status', \Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_DISABLED)
->getAllIds();

if (!empty($disabledConfigurableProducts)) {
// Get all child products of disabled configurable products
$childProductIds = [];
foreach ($disabledConfigurableProducts as $parentId) {
try {
$parentProduct = $this->_productRepository->getById($parentId, false, $scopeid);
if ($parentProduct->getTypeId() === self::PRODUCT_TYPE_CONFIGURABLE) {
$childProducts = $parentProduct->getTypeInstance()->getUsedProducts($parentProduct);
foreach ($childProducts as $childProduct) {
$childProductIds[] = $childProduct->getId();
}
}
} catch (Exception $e) {
$this->clerk_logger->error('Error getting child products for disabled parent', [
'parent_id' => $parentId,
'error' => $e->getMessage()
]);
}
}

// Exclude child products of disabled configurable products
if (!empty($childProductIds)) {
$collection->addFieldToFilter('entity_id', ['nin' => $childProductIds]);
$this->clerk_logger->log('Excluded child products of disabled configurable products', [
'disabled_parent_count' => count($disabledConfigurableProducts),
'excluded_child_count' => count($childProductIds)
]);
}
}

// Also handle grouped products
$disabledGroupedProducts = $this->collectionFactory->create()
->addStoreFilter($scopeid)
->addAttributeToFilter('type_id', self::PRODUCT_TYPE_GROUPED)
->addAttributeToFilter('status', \Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_DISABLED)
->getAllIds();

if (!empty($disabledGroupedProducts)) {
$associatedProductIds = [];
foreach ($disabledGroupedProducts as $parentId) {
try {
$parentProduct = $this->_productRepository->getById($parentId, false, $scopeid);
if ($parentProduct->getTypeId() === self::PRODUCT_TYPE_GROUPED) {
$associatedProducts = $parentProduct->getTypeInstance()->getAssociatedProducts($parentProduct);
foreach ($associatedProducts as $associatedProduct) {
$associatedProductIds[] = $associatedProduct->getId();
}
}
} catch (Exception $e) {
$this->clerk_logger->error('Error getting associated products for disabled grouped parent', [
'parent_id' => $parentId,
'error' => $e->getMessage()
]);
}
}

// Exclude associated products of disabled grouped products
if (!empty($associatedProductIds)) {
$collection->addFieldToFilter('entity_id', ['nin' => $associatedProductIds]);
$this->clerk_logger->log('Excluded associated products of disabled grouped products', [
'disabled_parent_count' => count($disabledGroupedProducts),
'excluded_associated_count' => count($associatedProductIds)
]);
}
}

} catch (Exception $e) {
$this->clerk_logger->error('Error filtering disabled products', ['error' => $e->getMessage()]);
}
}

/**
* Add field handlers for products
*/
Expand Down
1 change: 1 addition & 0 deletions Model/Config.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ class Config
const XML_PATH_PRODUCT_SYNCHRONIZATION_ADDITIONAL_FIELDS_HEAVY_QUERY = 'clerk/product_synchronization/additional_fields_heavy_query';
const XML_PATH_PRODUCT_SYNCHRONIZATION_SALABLE_ONLY = 'clerk/product_synchronization/saleable_only';
const XML_PATH_PRODUCT_SYNCHRONIZATION_VISIBILITY = 'clerk/product_synchronization/visibility';
const XML_PATH_PRODUCT_SYNCHRONIZATION_EXCLUDE_DISABLED_PRODUCTS = 'clerk/product_synchronization/exclude_disabled_products';
const XML_PATH_PRODUCT_SYNCHRONIZATION_DISABLE_ORDER_SYNCHRONIZATION = 'clerk/product_synchronization/disable_order_synchronization';
const XML_PATH_PRODUCT_SYNCHRONIZATION_IMAGE_TYPE = 'clerk/product_synchronization/image_type';
const XML_PATH_PRODUCT_SYNCHRONIZATION_ENABLE_ORDER_RETURN_SYNCHRONIZATION = 'clerk/product_synchronization/return_order_synchronization';
Expand Down
5 changes: 5 additions & 0 deletions etc/adminhtml/system.xml
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,11 @@
<label>Only synchronize product with visibility</label>
<source_model>Clerk\Clerk\Model\Config\Source\Visibility</source_model>
</field>
<field id="exclude_disabled_products" translate="label comment" type="select" sortOrder="42" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Exclude disabled products and their children</label>
<comment>When enabled, disabled parent products and their children will not be imported to Clerk</comment>
<source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
</field>
<field id="return_order_synchronization" translate="label" type="select" sortOrder="45" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Track returned orders</label>
<source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
Expand Down
1 change: 1 addition & 0 deletions etc/config.xml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
<additional_fields></additional_fields>
<saleable_only>1</saleable_only>
<visibility>4</visibility>
<exclude_disabled_products>1</exclude_disabled_products>
<disable_order_synchronization>0</disable_order_synchronization>
</product_synchronization>
<search>
Expand Down