From f656b7fd590da2ef4627ac141387bfe2c805adc0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Valentino=20Me=C4=91imorec?= <43341-valic@users.noreply.drupalcode.org> Date: Mon, 9 Oct 2023 11:21:20 +0000 Subject: [PATCH] Issue #3381018: Add price field formatter to display converted price --- config/schema/commerce_exchanger.schema.yml | 14 ++ .../PriceExchangerFormatter.php | 150 ++++++++++++++++++ 2 files changed, 164 insertions(+) create mode 100644 src/Plugin/Field/FieldFormatter/PriceExchangerFormatter.php diff --git a/config/schema/commerce_exchanger.schema.yml b/config/schema/commerce_exchanger.schema.yml index e42556c..58b966c 100644 --- a/config/schema/commerce_exchanger.schema.yml +++ b/config/schema/commerce_exchanger.schema.yml @@ -82,3 +82,17 @@ commerce_exchanger.latest_exchange_rates.*: sync: type: integer label: 'Sync' + +field.formatter.settings.commerce_price_exchanger: + type: mapping + label: 'Exchanger price formatter settings' + mapping: + strip_trailing_zeroes: + type: boolean + label: 'Strip trailing zeroes after the decimal point' + currency_display: + type: string + label: 'Currency display' + target_currency: + type: string + label: 'Target currency' diff --git a/src/Plugin/Field/FieldFormatter/PriceExchangerFormatter.php b/src/Plugin/Field/FieldFormatter/PriceExchangerFormatter.php new file mode 100644 index 0000000..69b129d --- /dev/null +++ b/src/Plugin/Field/FieldFormatter/PriceExchangerFormatter.php @@ -0,0 +1,150 @@ +<?php + +namespace Drupal\commerce_exchanger\Plugin\Field\FieldFormatter; + +use CommerceGuys\Intl\Formatter\CurrencyFormatterInterface; +use Drupal\commerce_exchanger\ExchangerCalculatorInterface; +use Drupal\commerce_price\Plugin\Field\FieldFormatter\PriceDefaultFormatter; +use Drupal\Core\Entity\EntityTypeManagerInterface; +use Drupal\Core\Field\FieldDefinitionInterface; +use Drupal\Core\Field\FieldItemListInterface; +use Drupal\Core\Form\FormStateInterface; +use Drupal\Core\Language\LanguageInterface; +use Symfony\Component\DependencyInjection\ContainerInterface; + +/** + * Plugin implementation of the 'commerce_price_exchanger' formatter. + * + * @FieldFormatter( + * id = "commerce_price_exchanger", + * label = @Translation("Currency converter price"), + * field_types = { + * "commerce_price" + * } + * ) + */ +class PriceExchangerFormatter extends PriceDefaultFormatter { + + /** + * The price exchanger. + * + * @var \Drupal\commerce_exchanger\ExchangerCalculatorInterface + */ + protected $priceExchanger; + + /** + * The entity type manager. + * + * @var \Drupal\Core\Entity\EntityTypeManagerInterface + */ + protected $entityTypeManager; + + /** + * Constructs a new PriceConvertedFormatter object. + * + * @param string $plugin_id + * The plugin_id for the formatter. + * @param mixed $plugin_definition + * The plugin implementation definition. + * @param \Drupal\Core\Field\FieldDefinitionInterface $field_definition + * The definition of the field to which the formatter is associated. + * @param array $settings + * The formatter settings. + * @param string $label + * The formatter label display setting. + * @param string $view_mode + * The view mode. + * @param array $third_party_settings + * Any third party settings. + * @param \CommerceGuys\Intl\Formatter\CurrencyFormatterInterface $currency_formatter + * The currency formatter. + * @param \Drupal\commerce_exchanger\ExchangerCalculatorInterface $price_exchanger + * The price exchanger. + * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager + * The entity type manager. + */ + public function __construct($plugin_id, $plugin_definition, FieldDefinitionInterface $field_definition, array $settings, $label, $view_mode, array $third_party_settings, CurrencyFormatterInterface $currency_formatter, ExchangerCalculatorInterface $price_exchanger, EntityTypeManagerInterface $entity_type_manager) { + parent::__construct($plugin_id, $plugin_definition, $field_definition, $settings, $label, $view_mode, $third_party_settings, $currency_formatter); + $this->priceExchanger = $price_exchanger; + $this->entityTypeManager = $entity_type_manager; + } + + /** + * {@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['label'], + $configuration['view_mode'], + $configuration['third_party_settings'], + $container->get('commerce_price.currency_formatter'), + $container->get('commerce_exchanger.calculate'), + $container->get('entity_type.manager')); + } + + /** + * {@inheritdoc} + */ + public static function defaultSettings() { + return ['target_currency' => 'USD'] + parent::defaultSettings(); + } + + /** + * {@inheritdoc} + */ + public function settingsForm(array $form, FormStateInterface $form_state) { + $elements = parent::settingsForm($form, $form_state); + $currency_storage = $this->entityTypeManager->getStorage('commerce_currency'); + // Get all active currencies. + /** @var \Drupal\commerce_price\Entity\CurrencyInterface[] $active_currencies */ + $active_currencies = $currency_storage->loadByProperties(['status' => 1]); + $options = []; + foreach ($active_currencies as $active_currency) { + $options[$active_currency->getCurrencyCode()] = $active_currency->getName(); + } + + $elements['target_currency'] = [ + '#type' => 'radios', + '#title' => $this->t('Target currency'), + '#options' => $options, + '#default_value' => $this->getSetting('target_currency'), + ]; + return $elements; + } + + /** + * {@inheritdoc} + */ + public function settingsSummary() { + $summary = parent::settingsSummary(); + $target_currency = $this->getSetting('target_currency'); + $summary[] = $this->t('Target currency: @target_currency.', ['@target_currency' => $target_currency]); + return $summary; + } + + /** + * {@inheritdoc} + */ + public function viewElements(FieldItemListInterface $items, $langcode) { + $options = $this->getFormattingOptions(); + $elements = []; + foreach ($items as $delta => $item) { + $price = $item->toPrice(); + $converted_price = $this->priceExchanger->priceConversion($price, $this->getSetting('target_currency')); + $elements[$delta] = [ + '#markup' => $this->currencyFormatter->format($converted_price->getNumber(), $converted_price->getCurrencyCode(), $options), + '#cache' => [ + 'contexts' => [ + 'languages:' . LanguageInterface::TYPE_INTERFACE, + 'country', + ], + ], + ]; + } + return $elements; + } + +} -- GitLab