|
6 | 6 | namespace Magento\Bundle\Model\ResourceModel\Indexer;
|
7 | 7 |
|
8 | 8 | use Magento\Catalog\Api\Data\ProductInterface;
|
9 |
| -use Magento\Catalog\Model\ResourceModel\Product\Indexer\Price\BasePriceModifier; |
10 |
| -use Magento\Framework\DB\Select; |
11 |
| -use Magento\Framework\Indexer\DimensionalIndexerInterface; |
12 |
| -use Magento\Framework\EntityManager\MetadataPool; |
13 | 9 | use Magento\Catalog\Model\Indexer\Product\Price\TableMaintainer;
|
14 |
| -use Magento\Catalog\Model\ResourceModel\Product\Indexer\Price\IndexTableStructureFactory; |
| 10 | +use Magento\Catalog\Model\Product\Attribute\Source\Status; |
| 11 | +use Magento\Catalog\Model\ResourceModel\Product\Indexer\Price\BasePriceModifier; |
15 | 12 | use Magento\Catalog\Model\ResourceModel\Product\Indexer\Price\IndexTableStructure;
|
| 13 | +use Magento\Catalog\Model\ResourceModel\Product\Indexer\Price\IndexTableStructureFactory; |
16 | 14 | use Magento\Catalog\Model\ResourceModel\Product\Indexer\Price\Query\JoinAttributeProcessor;
|
| 15 | +use Magento\CatalogInventory\Model\Stock; |
17 | 16 | use Magento\Customer\Model\Indexer\CustomerGroupDimensionProvider;
|
| 17 | +use Magento\Framework\DB\Select; |
| 18 | +use Magento\Framework\EntityManager\MetadataPool; |
| 19 | +use Magento\Framework\Indexer\DimensionalIndexerInterface; |
18 | 20 | use Magento\Store\Model\Indexer\WebsiteDimensionProvider;
|
19 |
| -use Magento\Catalog\Model\Product\Attribute\Source\Status; |
20 |
| -use Magento\CatalogInventory\Model\Stock; |
21 | 21 |
|
22 | 22 | /**
|
23 | 23 | * Bundle products Price indexer resource model
|
@@ -671,53 +671,78 @@ private function calculateFixedBundleSelectionPrice()
|
671 | 671 | * @return void
|
672 | 672 | * @throws \Exception
|
673 | 673 | */
|
674 |
| - private function calculateDynamicBundleSelectionPrice($dimensions) |
| 674 | + private function calculateDynamicBundleSelectionPrice(array $dimensions): void |
675 | 675 | {
|
676 | 676 | $connection = $this->getConnection();
|
677 |
| - |
678 |
| - $price = 'idx.min_price * bs.selection_qty'; |
679 |
| - $specialExpr = $connection->getCheckSql( |
680 |
| - 'i.special_price > 0 AND i.special_price < 100', |
681 |
| - 'ROUND(' . $price . ' * (i.special_price / 100), 4)', |
682 |
| - $price |
683 |
| - ); |
684 |
| - $tierExpr = $connection->getCheckSql( |
685 |
| - 'i.tier_percent IS NOT NULL', |
686 |
| - 'ROUND((1 - i.tier_percent / 100) * ' . $price . ', 4)', |
687 |
| - 'NULL' |
688 |
| - ); |
689 |
| - $priceExpr = $connection->getLeastSql( |
690 |
| - [ |
691 |
| - $specialExpr, |
692 |
| - $connection->getIfNullSql($tierExpr, $price), |
693 |
| - ] |
694 |
| - ); |
695 |
| - |
696 |
| - $select = $this->getBaseBundleSelectionPriceSelect(); |
697 |
| - $select->join( |
698 |
| - ['idx' => $this->getMainTable($dimensions)], |
699 |
| - 'bs.product_id = idx.entity_id AND i.customer_group_id = idx.customer_group_id' . |
700 |
| - ' AND i.website_id = idx.website_id', |
701 |
| - [] |
702 |
| - )->where( |
703 |
| - 'i.price_type=?', |
704 |
| - \Magento\Bundle\Model\Product\Price::PRICE_TYPE_DYNAMIC |
705 |
| - )->columns( |
706 |
| - [ |
707 |
| - 'group_type' => $connection->getCheckSql("bo.type = 'select' OR bo.type = 'radio'", '0', '1'), |
708 |
| - 'is_required' => 'bo.required', |
709 |
| - 'price' => $priceExpr, |
710 |
| - 'tier_price' => $tierExpr, |
711 |
| - ] |
712 |
| - ); |
713 |
| - $select->join( |
714 |
| - ['si' => $this->getTable('cataloginventory_stock_status')], |
715 |
| - 'si.product_id = bs.product_id', |
716 |
| - [] |
| 677 | + $insertColumns = [ |
| 678 | + 'entity_id', |
| 679 | + 'customer_group_id', |
| 680 | + 'website_id', |
| 681 | + 'option_id', |
| 682 | + 'selection_id', |
| 683 | + 'group_type', |
| 684 | + 'is_required', |
| 685 | + 'price', |
| 686 | + 'tier_price' |
| 687 | + ]; |
| 688 | + $insertColumns = array_map(function ($item) use ($connection) { |
| 689 | + return $connection->quoteIdentifier($item); |
| 690 | + }, $insertColumns); |
| 691 | + $updateValues = []; |
| 692 | + foreach ($insertColumns as $column) { |
| 693 | + $updateValues[] = sprintf("%s = VALUES(%s)", $column, $column); |
| 694 | + } |
| 695 | + $selectColumns = [ |
| 696 | + '`i`.`entity_id`', |
| 697 | + '`i`.`customer_group_id`', |
| 698 | + '`i`.`website_id`', |
| 699 | + '`bo`.`option_id`', |
| 700 | + '`bs`.`selection_id`', |
| 701 | + "IF(bo.type = 'select' OR bo.type = 'radio', 0, 1) AS `group_type`", |
| 702 | + "`bo`.`required` AS `is_required`", |
| 703 | + 'LEAST(IF(i.special_price > 0 AND i.special_price < 100, |
| 704 | + ROUND(idx.min_price * bs.selection_qty * (i.special_price / 100), 4), idx.min_price * bs.selection_qty), |
| 705 | + IFNULL((IF(i.tier_percent IS NOT NULL, |
| 706 | + ROUND((1 - i.tier_percent / 100) * idx.min_price * bs.selection_qty, 4), NULL)), |
| 707 | + idx.min_price * bs.selection_qty)) AS `price`', |
| 708 | + 'IF(i.tier_percent IS NOT NULL, ROUND((1 - i.tier_percent / 100) * idx.min_price * bs.selection_qty, 4), |
| 709 | + NULL) AS `tier_price`' |
| 710 | + ]; |
| 711 | + $selectFrom = [ |
| 712 | + '`' . $this->getBundlePriceTable() . '` AS `i`', |
| 713 | + 'INNER JOIN `' . $this->getTable('catalog_product_entity') . |
| 714 | + '` AS `parent_product` ON parent_product.entity_id = i.entity_id AND |
| 715 | + (parent_product.created_in <= 1 AND parent_product.updated_in > 1)', |
| 716 | + 'INNER JOIN `' . $this->getTable('catalog_product_bundle_option') . '` AS `bo` |
| 717 | + ON bo.parent_id = parent_product.row_id', |
| 718 | + 'INNER JOIN `' . $this->getTable('catalog_product_bundle_selection') . '` AS `bs` |
| 719 | + ON bs.option_id = bo.option_id', |
| 720 | + 'INNER JOIN `' . $this->getMainTable($dimensions) . '` AS `idx` USE INDEX (PRIMARY) |
| 721 | + ON bs.product_id = idx.entity_id AND i.customer_group_id = idx.customer_group_id AND |
| 722 | + i.website_id = idx.website_id', |
| 723 | + 'INNER JOIN `' . $this->getTable('cataloginventory_stock_status') . '` AS `si` |
| 724 | + ON si.product_id = bs.product_id' |
| 725 | + ]; |
| 726 | + $selectWhere = [ |
| 727 | + $connection->quoteInto('si.stock_status = ?', Stock::STOCK_IN_STOCK, \Zend_Db::INT_TYPE), |
| 728 | + $connection->quoteInto( |
| 729 | + 'i.price_type = ?', |
| 730 | + \Magento\Bundle\Model\Product\Price::PRICE_TYPE_DYNAMIC, |
| 731 | + \Zend_Db::INT_TYPE |
| 732 | + ) |
| 733 | + ]; |
| 734 | + $select = sprintf( |
| 735 | + "SELECT %s FROM %s WHERE %s", |
| 736 | + implode(",", $selectColumns), |
| 737 | + implode("\n", $selectFrom), |
| 738 | + implode(" AND ", $selectWhere) |
717 | 739 | );
|
718 |
| - $select->where('si.stock_status = ?', Stock::STOCK_IN_STOCK); |
719 |
| - |
720 |
| - $this->tableMaintainer->insertFromSelect($select, $this->getBundleSelectionTable(), []); |
| 740 | + $connection->query(sprintf( |
| 741 | + "INSERT INTO `catalog_product_index_price_bundle_sel_temp` (%s) %s ON DUPLICATE KEY UPDATE %s", |
| 742 | + implode(",", $insertColumns), |
| 743 | + $select, |
| 744 | + implode(",", $updateValues) |
| 745 | + )); |
721 | 746 | }
|
722 | 747 |
|
723 | 748 | /**
|
|
0 commit comments