7
7
8
8
use Magento \Catalog \Api \Data \ProductInterface ;
9
9
use Magento \Catalog \Model \ResourceModel \Product \Indexer \Price \BasePriceModifier ;
10
+ use Magento \Framework \DB \Select ;
10
11
use Magento \Framework \Indexer \DimensionalIndexerInterface ;
11
12
use Magento \Framework \EntityManager \MetadataPool ;
12
13
use Magento \Catalog \Model \Indexer \Product \Price \TableMaintainer ;
@@ -394,8 +395,8 @@ private function calculateBundleOptionPrice($priceTable, $dimensions)
394
395
$ connection = $ this ->getConnection ();
395
396
396
397
$ 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 );
399
400
400
401
$ this ->prepareBundleOptionTable ();
401
402
@@ -426,84 +427,17 @@ private function calculateBundleOptionPrice($priceTable, $dimensions)
426
427
}
427
428
428
429
/**
429
- * Calculate bundle product selections price by product type
430
+ * Get base select for bundle selection price
430
431
*
431
- * @param array $dimensions
432
- * @param int $priceType
433
- * @return void
432
+ * @return Select
434
433
* @throws \Exception
435
- * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
436
434
*/
437
- private function calculateBundleSelectionPrice ( $ dimensions , $ priceType )
435
+ private function getBaseBundleSelectionPriceSelect (): Select
438
436
{
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
-
504
437
$ metadata = $ this ->metadataPool ->getMetadata (ProductInterface::class);
505
438
$ linkField = $ metadata ->getLinkField ();
506
- $ select = $ connection ->select ()->from (
439
+
440
+ $ select = $ this ->getConnection ()->select ()->from (
507
441
['i ' => $ this ->getBundlePriceTable ()],
508
442
['entity_id ' , 'customer_group_id ' , 'website_id ' ]
509
443
)->join (
@@ -518,22 +452,173 @@ private function calculateBundleSelectionPrice($dimensions, $priceType)
518
452
['bs ' => $ this ->getTable ('catalog_product_bundle_selection ' )],
519
453
'bs.option_id = bo.option_id ' ,
520
454
['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 (
522
505
['bsp ' => $ this ->getTable ('catalog_product_bundle_selection_price ' )],
523
506
'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 (
526
615
['idx ' => $ this ->getMainTable ($ dimensions )],
527
616
'bs.product_id = idx.entity_id AND i.customer_group_id = idx.customer_group_id ' .
528
617
' AND i.website_id = idx.website_id ' ,
529
618
[]
530
- )->join (
531
- ['e ' => $ this ->getTable ('catalog_product_entity ' )],
532
- 'bs.product_id = e.entity_id AND e.required_options=0 ' ,
533
- []
534
619
)->where (
535
620
'i.price_type=? ' ,
536
- $ priceType
621
+ \ Magento \ Bundle \ Model \ Product \Price:: PRICE_TYPE_DYNAMIC
537
622
)->columns (
538
623
[
539
624
'group_type ' => $ connection ->getCheckSql ("bo.type = 'select' OR bo.type = 'radio' " , '0 ' , '1 ' ),
@@ -542,7 +627,6 @@ private function calculateBundleSelectionPrice($dimensions, $priceType)
542
627
'tier_price ' => $ tierExpr ,
543
628
]
544
629
);
545
-
546
630
$ query = $ select ->insertFromSelect ($ this ->getBundleSelectionTable ());
547
631
$ connection ->query ($ query );
548
632
}
0 commit comments