commerce_product_bundles-8.x-1.0/src/Service/ProductBundleVariationService.php

src/Service/ProductBundleVariationService.php
<?php

namespace Drupal\commerce_product_bundles\Service;

use Drupal\commerce\Context;
use Drupal\commerce_order\PriceCalculatorInterface;
use Drupal\commerce_price\Price;
use Drupal\commerce_price\Resolver\ChainPriceResolverInterface;
use Drupal\commerce_product\Entity\ProductVariation;
use Drupal\commerce_product\Entity\ProductVariationInterface;
use Drupal\commerce_store\CurrentStoreInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\commerce_product_bundles\Entity\ProductBundleVariation;
use Drupal\commerce_product_bundles\Entity\ProductBundleVariationInterface;

/**
 * Class ProductBundleVariationService
 *
 * @package Drupal\commerce_product_bundles\Service
 */
class ProductBundleVariationService implements ProductBundleVariationServiceInterface {

  /**
   * The BundleVaritionFieldMapper.
   *
   * @var \Drupal\commerce_product_bundles\Service\ProductBundleVariationFieldRendererInterface
   */
  protected $bundleVariationFieldMapper;

  /**
   * The current user.
   *
   * @var \Drupal\Core\Session\AccountInterface
   */
  protected $currentUser;

  /**
   * The current store.
   *
   * @var \Drupal\commerce_store\CurrentStoreInterface
   */
  protected $currentStore;

  /**
   * The chain base price resolver.
   *
   * @var \Drupal\commerce_price\Resolver\ChainPriceResolverInterface
   */
  protected $chainPriceResolver;

  /**
   * The price calculator.
   *
   * @var \Drupal\commerce_order\PriceCalculatorInterface
   */
  protected $priceCalculator;

  /**
   * ProductBundleVariationService constructor.
   *
   * @param \Drupal\commerce_product_bundles\Service\ProductBundleVariationFieldManagerInterface $bundle_variation_field_mapper
   * @param \Drupal\commerce_store\CurrentStoreInterface $current_store
   * @param \Drupal\Core\Session\AccountInterface $current_user
   * @param \Drupal\commerce_price\Resolver\ChainPriceResolverInterface $chain_price_resolver
   * @param \Drupal\commerce_order\PriceCalculatorInterface $price_calculator
   */
  public function __construct(ProductBundleVariationFieldManagerInterface $bundle_variation_field_mapper, CurrentStoreInterface $current_store, AccountInterface $current_user,
                              ChainPriceResolverInterface $chain_price_resolver, PriceCalculatorInterface $price_calculator) {
    $this->bundleVariationFieldMapper = $bundle_variation_field_mapper;
    $this->currentStore = $current_store;
    $this->currentUser = $current_user;
    $this->chainPriceResolver = $chain_price_resolver;
    $this->priceCalculator = $price_calculator;
  }

  /**
   * {@inheritDoc}
   */
  public function calculateSavings($form_values, $bundle_variation, $check_access = TRUE) {
    $values = $this->getRefVariationsPrice($form_values, $bundle_variation, $check_access);
    $price = $values['price'];
    $variations_calculated_price = $values['variations_calculated_price'];

    return $variations_calculated_price->subtract($price);
  }

  /**
   * {@inheritDoc}
   */
  public function calculateOriginalPrice($form_values, $bundle_variation) {
    $values = $this->getRefVariationsPrice($form_values, $bundle_variation);

    return $values['variations_calculated_price'];
  }

  /**
   * Calculates referenced variations price.
   *
   * @param $form_values
   * @param $bundle_variation
   * @param bool $check_access
   *
   * @return array
   */
  private function getRefVariationsPrice($form_values, $bundle_variation, $check_access = TRUE) {
    // Set fallback price for add new eck -> this is for edit form only!
    if($bundle_variation->isNew()){
      $fallback_price = new Price(0, 'USD');
      return [
        'price' => $fallback_price,
        'variations_calculated_price' => $fallback_price
      ];
    }

    $context = new Context($this->currentUser, $this->currentStore->getStore(), NULL, []);
    // Get calculated price > include promotions.
    $bundle_price = $this->priceCalculator->calculate($bundle_variation, 1, $context, ['promotion' => 'promotion']);
    $price = $bundle_price->getCalculatedPrice();
    $variations_calculated_price = new Price(0, $price->getCurrencyCode());
    $bundle_ref_values = [];
    $quantities = [];

    if(isset($form_values[0]['bundle_variations_ref_options'])) {
      $bundle_ref_values = $form_values[0]['bundle_variations_ref_options'];
      $quantities = $form_values[0]['quantity'];
    } elseif (isset($form_values[0]['bundle_variations_options'])) {
      $bundle_var = ProductBundleVariation::load($form_values[0]['bundle_variations_options']);
      if($bundle_var instanceof ProductBundleVariationInterface) {
        $bundle_var_ref = $this->bundleVariationFieldMapper->prepareBundleVariations($bundle_variation);

        // Loop through all ref product to get correct price.
        if(!empty($bundle_var_ref)) {
          foreach ($bundle_var_ref as $ref_key => $product_ref){
            $variations_ref = $product_ref->getRefVariations();
            // Select only first variation.
            if(!empty($variations_ref)){
              $variation_ref = reset($variations_ref);
              $bundle_ref_values[$ref_key] = $variation_ref;
              $quantities[$ref_key] = $product_ref->getQuantity();
            }
          }
        }
      }
    } else {
      $bundle_var_ref = $this->bundleVariationFieldMapper->prepareBundleVariations($bundle_variation, $check_access);

      // Loop through all ref product to get correct price.
      if(!empty($bundle_var_ref)) {
        foreach ($bundle_var_ref as $ref_key => $product_ref) {
          $variations_ref = $product_ref->getRefVariations($check_access);
          // Select only first variation.
          if(!empty($variations_ref)) {
            $variation_ref = reset($variations_ref);
            $bundle_ref_values[$ref_key] = $variation_ref;
            $quantities[$ref_key] = $product_ref->getQuantity();
          }
        }
      }
    }

    // Loop through selected variations.
    foreach ($bundle_ref_values as $product_id => $variation_id) {
      $variation = NULL;
      if(is_numeric($variation_id)){
        $variation = ProductVariation::load($variation_id);
      } elseif($variation_id instanceof ProductVariationInterface){
        // Use only first variation for calculation.
        $variation = $variation_id;
      }

      // Double check if variation is loaded.
      if($variation instanceof ProductVariationInterface) {
        $variation_price = $variation->getPrice();
        // Resolve price.
        if ($variation_price->getCurrencyCode() !== $price->getCurrencyCode()) {
          $context = new Context($this->currentUser, $this->currentStore->getStore(), NULL, []);
          $variation_price = $this->chainPriceResolver->resolve($variation, 1, $context);
        }
        // Defaults to one.
        $multiply = 1;
        if (isset($quantities[$product_id])) {
          $multiply = $quantities[$product_id];
        }
        $multiplied = $variation_price->multiply($multiply);
        $variations_calculated_price = $variations_calculated_price->add($multiplied);
      }
    }

    return [
      'price' => $price,
      'variations_calculated_price' => $variations_calculated_price
    ];
  }

}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc