commerce_product_bundles-8.x-1.0/src/Plugin/Field/FieldWidget/BundleVariationPriceWidget.php

src/Plugin/Field/FieldWidget/BundleVariationPriceWidget.php
<?php

namespace Drupal\commerce_product_bundles\Plugin\Field\FieldWidget;

use CommerceGuys\Intl\Formatter\CurrencyFormatterInterface;
use Drupal\commerce\Context;
use Drupal\commerce_order\AdjustmentTypeManager;
use Drupal\commerce_order\PriceCalculatorInterface;
use Drupal\commerce_order\PriceCalculatorResult;
use Drupal\commerce_store\CurrentStoreInterface;
use Drupal\Core\Cache\Cache;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Field\EntityReferenceFieldItemList;
use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Field\WidgetBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Language\LanguageInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\commerce_product_bundles\Entity\ProductBundleVariation;
use Drupal\commerce_product_bundles\Service\ProductBundleVariationServiceInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\RequestStack;

/**
 * Plugin implementation of the 'bundle_variation_price' widget.
 *
 * This is not widget but 'Formatter' to display bundle price in bundle variation form.
 *
 * @FieldWidget(
 *   id = "bundle_variation_price",
 *   label = @Translation("Bundle variation price"),
 *   field_types = {
 *     "commerce_price",
 *   }
 * )
 */
class BundleVariationPriceWidget extends WidgetBase implements ContainerFactoryPluginInterface {

  /**
   * The adjustment type manager.
   *
   * @var \Drupal\commerce_order\AdjustmentTypeManager
   */
  protected $adjustmentTypeManager;

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

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

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

  /**
   * The currency formatter.
   *
   * @var \CommerceGuys\Intl\Formatter\CurrencyFormatterInterface
   */
  protected $currencyFormatter;

  /**
   * The commerce product bundle service.
   *
   * @var \Drupal\commerce_product_bundles\service\ProductBundleVariationServiceInterface
   */
  protected $commerceProductBundleService;

  /**
   * The module handler.
   *
   * @var \Drupal\Core\Extension\ModuleHandlerInterface
   */
  protected $moduleHandler;

  /**
   * @var \Drupal\Core\Entity\EntityTypeManager|\Drupal\Core\Entity\EntityTypeManagerInterface
   */
  protected $entityTypeManager;

  /**
   * Request stack service.
   *
   * @var RequestStack
   */
  protected $requestStack;

  /**
   * BundleVariationPriceWidget constructor.
   *
   * @param $plugin_id
   * @param $plugin_definition
   * @param \Drupal\Core\Field\FieldDefinitionInterface $field_definition
   * @param array $settings
   * @param array $third_party_settings
   * @param \CommerceGuys\Intl\Formatter\CurrencyFormatterInterface $currency_formatter
   * @param \Drupal\commerce_order\AdjustmentTypeManager $adjustment_type_manager
   * @param \Drupal\commerce_store\CurrentStoreInterface $current_store
   * @param \Drupal\Core\Session\AccountInterface $current_user
   * @param \Drupal\commerce_order\PriceCalculatorInterface $price_calculator
   * @param \Drupal\commerce_product_bundles\Service\ProductBundleVariationServiceInterface $commerce_product_bundles_service
   * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
   * @param \Symfony\Component\HttpFoundation\RequestStack $request_stack
   */
  public function __construct($plugin_id, $plugin_definition, FieldDefinitionInterface $field_definition, array $settings, array $third_party_settings,
                              CurrencyFormatterInterface $currency_formatter, AdjustmentTypeManager $adjustment_type_manager,
                              CurrentStoreInterface $current_store, AccountInterface $current_user, PriceCalculatorInterface $price_calculator,
                              ProductBundleVariationServiceInterface $commerce_product_bundles_service, ModuleHandlerInterface $module_handler,
                              EntityTypeManagerInterface $entity_type_manager, RequestStack $request_stack) {
    parent::__construct($plugin_id, $plugin_definition, $field_definition, $settings, $third_party_settings);

    $this->currencyFormatter = $currency_formatter;
    $this->adjustmentTypeManager = $adjustment_type_manager;
    $this->currentStore = $current_store;
    $this->currentUser = $current_user;
    $this->priceCalculator = $price_calculator;
    $this->commerceProductBundleService = $commerce_product_bundles_service;
    $this->moduleHandler = $module_handler;
    $this->entityTypeManager = $entity_type_manager;
    $this->requestStack = $request_stack;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
    return new static(
      $plugin_id,
      $plugin_definition,
      $configuration['field_definition'],
      $configuration['settings'],
      $configuration['third_party_settings'],
      $container->get('commerce_price.currency_formatter'),
      $container->get('plugin.manager.commerce_adjustment_type'),
      $container->get('commerce_store.current_store'),
      $container->get('current_user'),
      $container->get('commerce_order.price_calculator'),
      $container->get('commerce_product_bundles.bundle_variation_service'),
      $container->get('module_handler'),
      $container->get('entity_type.manager'),
      $container->get('request_stack')
    );
  }

  /**
   * {@inheritdoc}
   */
  public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state) {
    $element = [];
    /** @var \Drupal\commerce_order\Entity\OrderItemInterface $order_item */
    $order_item = $items[$delta]->getEntity();

    // Get storage.
    $storage = $form_state->getStorage();

    if (!$items[$delta]->isEmpty()) {
      if ($order_item->getFields()['purchased_entity'] instanceof EntityReferenceFieldItemList) {
        $variation_id = $storage['selected_bundle_variation'] ?? '';
        // Get all data.
        $bundle_variation_id = !empty($variation_id) ? $variation_id : $order_item->getFields()['purchased_entity']->getString();

        $bundle_variation = ProductBundleVariation::load($bundle_variation_id);
        $context = new Context($this->currentUser, $this->currentStore->getStore(), NULL, []);

        /** @var \Drupal\commerce\PurchasableEntityInterface $purchasable_entity */
        $purchasable_entity = $bundle_variation;
        // Get calculated price > include promotions.
        $result = $this->priceCalculator->calculate($purchasable_entity, 1, $context, ['promotion' => 'promotion']);
        $calculated_price = $result->getCalculatedPrice();
        $base_price = $result->getBasePrice();
        $number = $calculated_price->getNumber();
        $base_number = $result->getBasePrice()->getNumber();
        $currency_code = $calculated_price->getCurrencyCode();
        $options = $this->getFormattingOptions();

        $markup = [
          '#theme' => 'commerce_bundle_bundle_price_calculated',
          '#result' => $result,
          '#calculated_price' => $this->currencyFormatter->format($number, $currency_code, $options),
          '#base_price' => $this->currencyFormatter->format($base_number, $currency_code, $options),
          '#adjustments' => $result->getAdjustments(),
          '#cache' => [
            'tags' => $purchasable_entity->getCacheTags(),
            'contexts' => Cache::mergeContexts($purchasable_entity->getCacheContexts(), [
              'languages:' . LanguageInterface::TYPE_INTERFACE,
              'country',
            ]),
          ],
        ];

        // Set bundle price tpl..
        $element = [
          '#theme' => 'commerce_bundle_price_calculated',
          '#bundle_price' => $markup,
          '#original_price' => NULL,
          '#savings_price' => NULL
        ];

        // Get original price.
        $purchased_entity = [];
        $selected_vars = $form_state->getValue('purchased_entity');
        if(empty($selected_vars)) {
          $user_input = $form_state->getUserInput();
          $selected_vars = isset($user_input['purchased_entity']) ? $user_input['purchased_entity'] : NULL;
        }
        if(isset($selected_vars[0]['bundle_variations_ref_options']) && !empty($selected_vars[0]['bundle_variations_ref_options'])){
          $purchased_entity[0]['bundle_variations_ref_options'] = $selected_vars[0]['bundle_variations_ref_options'] ?? '';
        }
        if(isset($selected_vars[0]['quantity']) && !empty($selected_vars[0]['quantity'])){
          $purchased_entity[0]['quantity'] = $selected_vars[0]['quantity'] ?? '';
        }

        // Show original price only if we do not have discount on bundle.
        if(!$base_price->greaterThan($calculated_price)){
          $calculated_original_value = $this->commerceProductBundleService->calculateOriginalPrice($purchased_entity, $bundle_variation);

          // Show original price only if it is greater than bundle price.
          if($calculated_original_value->greaterThan($calculated_price)){
            $calculated_price_result = new PriceCalculatorResult($calculated_original_value, $calculated_original_value);

            $cal_original_price = $calculated_price_result->getCalculatedPrice();
            $cal_original_number = $cal_original_price->getNumber();
            $calc_base_number = $calculated_price_result->getBasePrice()->getNumber();
            $calc_currency_code = $cal_original_price->getCurrencyCode();

            $original_price_markup = [
              '#theme' => 'commerce_original_price_calculated',
              '#result' => $calculated_price_result,
              '#calculated_price' => $this->currencyFormatter->format($cal_original_number, $calc_currency_code, $options),
              '#base_price' => $this->currencyFormatter->format($calc_base_number, $calc_currency_code, $options),
              '#adjustments' => $calculated_price_result->getAdjustments(),
              '#cache' => [
                'tags' => $purchasable_entity->getCacheTags(),
                'contexts' => Cache::mergeContexts($purchasable_entity->getCacheContexts(), [
                  'languages:' . LanguageInterface::TYPE_INTERFACE,
                  'country',
                ]),
              ],
            ];

            $element['#original_price'] = $original_price_markup;
          }
        }

        // Calculate savings price.
        $savings = $this->commerceProductBundleService->calculateSavings($selected_vars, $bundle_variation);
        // Show savings only if it is higher that 0.
        if($savings->isPositive() && !$savings->isZero()) {
          $calculated_savings_result = new PriceCalculatorResult($savings, $savings);

          $cal_savings_price = $calculated_savings_result->getCalculatedPrice();
          $cal_savings_original_number = $cal_savings_price->getNumber();
          $calc_savings_base_number = $calculated_savings_result->getBasePrice()->getNumber();
          $calc_savings_currency_code = $cal_savings_price->getCurrencyCode();

          $savings_price_markup = [
            '#theme' => 'commerce_savings_price_calculated',
            '#result' => $calculated_savings_result,
            '#calculated_price' => $this->currencyFormatter->format($cal_savings_original_number, $calc_savings_currency_code, $options),
            '#base_price' => $this->currencyFormatter->format($calc_savings_base_number, $calc_savings_currency_code, $options),
            '#adjustments' => $calculated_savings_result->getAdjustments(),
            '#cache' => [
              'tags' => $purchasable_entity->getCacheTags(),
              'contexts' => Cache::mergeContexts($purchasable_entity->getCacheContexts(), [
                'languages:' . LanguageInterface::TYPE_INTERFACE,
                'country',
              ]),
            ],
          ];

          $element['#savings_price'] = $savings_price_markup;
        }
      }
    }

    return $element;
  }

  /**
   * Gets the formatting options for the currency formatter.
   *
   * @return array
   *   The formatting options.
   */
  protected function getFormattingOptions() {
    return [
      'currency_display' => 'symbol',
      'minimum_fraction_digits' => 0,
    ];
  }

  /**
   * {@inheritdoc}
   */
  public static function isApplicable(FieldDefinitionInterface $field_definition) {
    $entity_type = $field_definition->getTargetEntityTypeId();
    $field_name = $field_definition->getName();
    return $entity_type === 'commerce_order_item' && $field_name === 'unit_price';
  }

}

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

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