77
88use Magento \Catalog \Api \Data \ProductInterface ;
99use Magento \Catalog \Model \ResourceModel \Product \Indexer \Price \BasePriceModifier ;
10+ use Magento \Framework \DB \Select ;
1011use Magento \Framework \Indexer \DimensionalIndexerInterface ;
1112use Magento \Framework \EntityManager \MetadataPool ;
1213use Magento \Catalog \Model \Indexer \Product \Price \TableMaintainer ;
@@ -394,8 +395,8 @@ private function calculateBundleOptionPrice($priceTable, $dimensions)
394395 $ connection = $ this ->getConnection ();
395396
396397 $ this ->prepareBundleSelectionTable ();
397- $ this ->calculateBundleSelectionPrice ( $ dimensions , \ Magento \ Bundle \ Model \ Product \Price:: PRICE_TYPE_FIXED );
398- $ this ->calculateBundleSelectionPrice ($ dimensions, \ Magento \ Bundle \ Model \ Product \Price:: PRICE_TYPE_DYNAMIC );
398+ $ this ->calculateFixedBundleSelectionPrice ( );
399+ $ this ->calculateDynamicBundleSelectionPrice ($ dimensions );
399400
400401 $ this ->prepareBundleOptionTable ();
401402
@@ -426,84 +427,17 @@ private function calculateBundleOptionPrice($priceTable, $dimensions)
426427 }
427428
428429 /**
429- * Calculate bundle product selections price by product type
430+ * Get base select for bundle selection price
430431 *
431- * @param array $dimensions
432- * @param int $priceType
433- * @return void
432+ * @return Select
434433 * @throws \Exception
435- * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
436434 */
437- private function calculateBundleSelectionPrice ( $ dimensions , $ priceType )
435+ private function getBaseBundleSelectionPriceSelect (): Select
438436 {
439- $ connection = $ this ->getConnection ();
440-
441- if ($ priceType == \Magento \Bundle \Model \Product \Price::PRICE_TYPE_FIXED ) {
442- $ selectionPriceValue = $ connection ->getCheckSql (
443- 'bsp.selection_price_value IS NULL ' ,
444- 'bs.selection_price_value ' ,
445- 'bsp.selection_price_value '
446- );
447- $ selectionPriceType = $ connection ->getCheckSql (
448- 'bsp.selection_price_type IS NULL ' ,
449- 'bs.selection_price_type ' ,
450- 'bsp.selection_price_type '
451- );
452- $ priceExpr = new \Zend_Db_Expr (
453- $ connection ->getCheckSql (
454- $ selectionPriceType . ' = 1 ' ,
455- 'ROUND(i.price * ( ' . $ selectionPriceValue . ' / 100),4) ' ,
456- $ connection ->getCheckSql (
457- 'i.special_price > 0 AND i.special_price < 100 ' ,
458- 'ROUND( ' . $ selectionPriceValue . ' * (i.special_price / 100),4) ' ,
459- $ selectionPriceValue
460- )
461- ) . '* bs.selection_qty '
462- );
463-
464- $ tierExpr = $ connection ->getCheckSql (
465- 'i.base_tier IS NOT NULL ' ,
466- $ connection ->getCheckSql (
467- $ selectionPriceType . ' = 1 ' ,
468- 'ROUND(i.base_tier - (i.base_tier * ( ' . $ selectionPriceValue . ' / 100)),4) ' ,
469- $ connection ->getCheckSql (
470- 'i.tier_percent > 0 ' ,
471- 'ROUND((1 - i.tier_percent / 100) * ' . $ selectionPriceValue . ',4) ' ,
472- $ selectionPriceValue
473- )
474- ) . ' * bs.selection_qty ' ,
475- 'NULL '
476- );
477-
478- $ priceExpr = $ connection ->getLeastSql (
479- [
480- $ priceExpr ,
481- $ connection ->getIfNullSql ($ tierExpr , $ priceExpr ),
482- ]
483- );
484- } else {
485- $ price = 'idx.min_price * bs.selection_qty ' ;
486- $ specialExpr = $ connection ->getCheckSql (
487- 'i.special_price > 0 AND i.special_price < 100 ' ,
488- 'ROUND( ' . $ price . ' * (i.special_price / 100), 4) ' ,
489- $ price
490- );
491- $ tierExpr = $ connection ->getCheckSql (
492- 'i.tier_percent IS NOT NULL ' ,
493- 'ROUND((1 - i.tier_percent / 100) * ' . $ price . ', 4) ' ,
494- 'NULL '
495- );
496- $ priceExpr = $ connection ->getLeastSql (
497- [
498- $ specialExpr ,
499- $ connection ->getIfNullSql ($ tierExpr , $ price ),
500- ]
501- );
502- }
503-
504437 $ metadata = $ this ->metadataPool ->getMetadata (ProductInterface::class);
505438 $ linkField = $ metadata ->getLinkField ();
506- $ select = $ connection ->select ()->from (
439+
440+ $ select = $ this ->getConnection ()->select ()->from (
507441 ['i ' => $ this ->getBundlePriceTable ()],
508442 ['entity_id ' , 'customer_group_id ' , 'website_id ' ]
509443 )->join (
@@ -518,22 +452,173 @@ private function calculateBundleSelectionPrice($dimensions, $priceType)
518452 ['bs ' => $ this ->getTable ('catalog_product_bundle_selection ' )],
519453 'bs.option_id = bo.option_id ' ,
520454 ['selection_id ' ]
521- )->joinLeft (
455+ );
456+
457+ return $ select ;
458+ }
459+
460+ /**
461+ * Apply selections price for fixed bundles
462+ *
463+ * @return void
464+ * @throws \Exception
465+ */
466+ private function applyFixedBundleSelectionPrice ()
467+ {
468+ $ connection = $ this ->getConnection ();
469+
470+ $ selectionPriceValue = 'bsp.selection_price_value ' ;
471+ $ selectionPriceType = 'bsp.selection_price_type ' ;
472+ $ priceExpr = new \Zend_Db_Expr (
473+ $ connection ->getCheckSql (
474+ $ selectionPriceType . ' = 1 ' ,
475+ 'ROUND(i.price * ( ' . $ selectionPriceValue . ' / 100),4) ' ,
476+ $ connection ->getCheckSql (
477+ 'i.special_price > 0 AND i.special_price < 100 ' ,
478+ 'ROUND( ' . $ selectionPriceValue . ' * (i.special_price / 100),4) ' ,
479+ $ selectionPriceValue
480+ )
481+ ) . '* bs.selection_qty '
482+ );
483+ $ tierExpr = $ connection ->getCheckSql (
484+ 'i.base_tier IS NOT NULL ' ,
485+ $ connection ->getCheckSql (
486+ $ selectionPriceType . ' = 1 ' ,
487+ 'ROUND(i.base_tier - (i.base_tier * ( ' . $ selectionPriceValue . ' / 100)),4) ' ,
488+ $ connection ->getCheckSql (
489+ 'i.tier_percent > 0 ' ,
490+ 'ROUND((1 - i.tier_percent / 100) * ' . $ selectionPriceValue . ',4) ' ,
491+ $ selectionPriceValue
492+ )
493+ ) . ' * bs.selection_qty ' ,
494+ 'NULL '
495+ );
496+ $ priceExpr = $ connection ->getLeastSql (
497+ [
498+ $ priceExpr ,
499+ $ connection ->getIfNullSql ($ tierExpr , $ priceExpr ),
500+ ]
501+ );
502+
503+ $ select = $ this ->getBaseBundleSelectionPriceSelect ();
504+ $ select ->joinInner (
522505 ['bsp ' => $ this ->getTable ('catalog_product_bundle_selection_price ' )],
523506 'bs.selection_id = bsp.selection_id AND bsp.website_id = i.website_id ' ,
524- ['' ]
525- )->join (
507+ []
508+ )->where (
509+ 'i.price_type=? ' ,
510+ \Magento \Bundle \Model \Product \Price::PRICE_TYPE_FIXED
511+ )->columns (
512+ [
513+ 'group_type ' => $ connection ->getCheckSql ("bo.type = 'select' OR bo.type = 'radio' " , '0 ' , '1 ' ),
514+ 'is_required ' => 'bo.required ' ,
515+ 'price ' => $ priceExpr ,
516+ 'tier_price ' => $ tierExpr ,
517+ ]
518+ );
519+ $ query = $ select ->crossUpdateFromSelect ($ this ->getBundleSelectionTable ());
520+ $ connection ->query ($ query );
521+ }
522+
523+ /**
524+ * Calculate selections price for fixed bundles
525+ *
526+ * @return void
527+ * @throws \Exception
528+ */
529+ private function calculateFixedBundleSelectionPrice ()
530+ {
531+ $ connection = $ this ->getConnection ();
532+
533+ $ selectionPriceValue = 'bs.selection_price_value ' ;
534+ $ selectionPriceType = 'bs.selection_price_type ' ;
535+ $ priceExpr = new \Zend_Db_Expr (
536+ $ connection ->getCheckSql (
537+ $ selectionPriceType . ' = 1 ' ,
538+ 'ROUND(i.price * ( ' . $ selectionPriceValue . ' / 100),4) ' ,
539+ $ connection ->getCheckSql (
540+ 'i.special_price > 0 AND i.special_price < 100 ' ,
541+ 'ROUND( ' . $ selectionPriceValue . ' * (i.special_price / 100),4) ' ,
542+ $ selectionPriceValue
543+ )
544+ ) . '* bs.selection_qty '
545+ );
546+ $ tierExpr = $ connection ->getCheckSql (
547+ 'i.base_tier IS NOT NULL ' ,
548+ $ connection ->getCheckSql (
549+ $ selectionPriceType . ' = 1 ' ,
550+ 'ROUND(i.base_tier - (i.base_tier * ( ' . $ selectionPriceValue . ' / 100)),4) ' ,
551+ $ connection ->getCheckSql (
552+ 'i.tier_percent > 0 ' ,
553+ 'ROUND((1 - i.tier_percent / 100) * ' . $ selectionPriceValue . ',4) ' ,
554+ $ selectionPriceValue
555+ )
556+ ) . ' * bs.selection_qty ' ,
557+ 'NULL '
558+ );
559+ $ priceExpr = $ connection ->getLeastSql (
560+ [
561+ $ priceExpr ,
562+ $ connection ->getIfNullSql ($ tierExpr , $ priceExpr ),
563+ ]
564+ );
565+
566+ $ select = $ this ->getBaseBundleSelectionPriceSelect ();
567+ $ select ->where (
568+ 'i.price_type=? ' ,
569+ \Magento \Bundle \Model \Product \Price::PRICE_TYPE_FIXED
570+ )->columns (
571+ [
572+ 'group_type ' => $ connection ->getCheckSql ("bo.type = 'select' OR bo.type = 'radio' " , '0 ' , '1 ' ),
573+ 'is_required ' => 'bo.required ' ,
574+ 'price ' => $ priceExpr ,
575+ 'tier_price ' => $ tierExpr ,
576+ ]
577+ );
578+ $ query = $ select ->insertFromSelect ($ this ->getBundleSelectionTable ());
579+ $ connection ->query ($ query );
580+
581+ $ this ->applyFixedBundleSelectionPrice ();
582+ }
583+
584+ /**
585+ * Calculate selections price for dynamic bundles
586+ *
587+ * @param array $dimensions
588+ * @return void
589+ * @throws \Exception
590+ */
591+ private function calculateDynamicBundleSelectionPrice ($ dimensions )
592+ {
593+ $ connection = $ this ->getConnection ();
594+
595+ $ price = 'idx.min_price * bs.selection_qty ' ;
596+ $ specialExpr = $ connection ->getCheckSql (
597+ 'i.special_price > 0 AND i.special_price < 100 ' ,
598+ 'ROUND( ' . $ price . ' * (i.special_price / 100), 4) ' ,
599+ $ price
600+ );
601+ $ tierExpr = $ connection ->getCheckSql (
602+ 'i.tier_percent IS NOT NULL ' ,
603+ 'ROUND((1 - i.tier_percent / 100) * ' . $ price . ', 4) ' ,
604+ 'NULL '
605+ );
606+ $ priceExpr = $ connection ->getLeastSql (
607+ [
608+ $ specialExpr ,
609+ $ connection ->getIfNullSql ($ tierExpr , $ price ),
610+ ]
611+ );
612+
613+ $ select = $ this ->getBaseBundleSelectionPriceSelect ();
614+ $ select ->join (
526615 ['idx ' => $ this ->getMainTable ($ dimensions )],
527616 'bs.product_id = idx.entity_id AND i.customer_group_id = idx.customer_group_id ' .
528617 ' AND i.website_id = idx.website_id ' ,
529618 []
530- )->join (
531- ['e ' => $ this ->getTable ('catalog_product_entity ' )],
532- 'bs.product_id = e.entity_id AND e.required_options=0 ' ,
533- []
534619 )->where (
535620 'i.price_type=? ' ,
536- $ priceType
621+ \ Magento \ Bundle \ Model \ Product \Price:: PRICE_TYPE_DYNAMIC
537622 )->columns (
538623 [
539624 'group_type ' => $ connection ->getCheckSql ("bo.type = 'select' OR bo.type = 'radio' " , '0 ' , '1 ' ),
@@ -542,7 +627,6 @@ private function calculateBundleSelectionPrice($dimensions, $priceType)
542627 'tier_price ' => $ tierExpr ,
543628 ]
544629 );
545-
546630 $ query = $ select ->insertFromSelect ($ this ->getBundleSelectionTable ());
547631 $ connection ->query ($ query );
548632 }
0 commit comments