Skip to content
Closed
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion v2/recipes/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,6 @@ These recipes are all designed to work off of each other, so try it out - you ca

[Products](products.md) - Products and types.

[Orders](orders.md) - Orders, order items, and their types.
[Multiprice](multiprice.md) - Multiprice and multicurrency.

[Orders](orders.md) - Orders, order items, and their types.
138 changes: 138 additions & 0 deletions v2/recipes/multiprice.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
# Multiprice and multicurrency

We want to define a specific price and currency for each language.

We need a new multiple commerce_price field in product variation in place of default price field.

Add following field in a custom module or add your own multiple commerce_price field to product variation.

## Creating field
```yaml
# config/install/field.field.commerce_product_variation.default.multiprice.yml
langcode: en
status: true
dependencies:
config:
- commerce_product.commerce_product_variation_type.default
- field.storage.commerce_product_variation.multiprice
module:
- commerce_price
id: commerce_product_variation.default.multiprice
field_name: multiprice
entity_type: commerce_product_variation
bundle: default
label: Multiprice
description: 'Define differents prices depending of currency'
required: true
translatable: false
default_value: { }
default_value_callback: ''
settings: { }
field_type: commerce_price
```

```yaml
# config/install/field.storage.commerce_product_variation.multiprice.yml
langcode: en
status: true
dependencies:
module:
- commerce_price
- commerce_product
id: commerce_product_variation.multiprice
field_name: multiprice
entity_type: commerce_product_variation
type: commerce_price
settings: { }
module: commerce_price
locked: false
cardinality: -1
translatable: true
indexes: { }
persist_with_no_fields: false
custom_storage: false
```

* Hide default price field from product variation form display and display mode.
* Display multiprice field in form display and display mode.

## Creating resolver

### Add resolver to services

```yaml
services:
commerce_multiprice_example.commerce_multicurrency_resolver:
class: Drupal\commerce_multiprice_example\Resolvers\CommerceMulticurrencyResolver
arguments: ['@request_stack']
tags:
- { name: commerce_price.price_resolver, priority: 600 }
```

### Creating resolver

Replace multiprice field name by your own field if needed.

```php
<?php
namespace Drupal\commerce_multiprice_example\Resolvers;

use Drupal\commerce\Context;
use Drupal\commerce\PurchasableEntityInterface;
use Drupal\commerce_price\Price;
use Drupal\commerce_price\Resolver\PriceResolverInterface;

/**
* Returns a price and currency depending of language.
*/
class CommerceMulticurrencyResolver implements PriceResolverInterface {

/**
* The language manager.
*
* @var \Drupal\Core\Language\LanguageManagerInterface
*/
protected $languageManager;

/**
* Constructs a new CommerceMulticurrencyResolver object.
*
* @param \Drupal\Core\Language\LanguageManagerInterface $language_manager
* The language manager.
*/
public function __construct(LanguageManagerInterface $language_manager) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Working on https://www.drupal.org/node/2831954#comment-11906059
and using the implementation suggested here, the tests won't work with $language_manager construct argument.

Please check my PR for the issue drupalcommerce/commerce#626
And maybe we could get the right solution for how this CommerceMulticurrencyResolver should be done

$this->languageManager = $language_manager;
}

/**
* {@inheritdoc}
*/
public function resolve(PurchasableEntityInterface $entity, $quantity, Context $context) {
// Define mapping between language and currency.
$currency_by_language = ['en' => 'USD', 'fr' => 'EUR', 'ja' => 'JPY'];

// Get current language.
$language = $this->languageManager->getCurrentLanguage()->getId();

// Get default language.
$default_language = $this->languageManager->getDefaultLanguage()->getId();

// Set default price to null. Default price will be used to return currency
// of default language if no currency has been found for current language.
$default_price = NULL;

// Find price for current language depending of its currency.
foreach ($entity->get('multiprice') as $price) {
if ($price->get('currency_code')->getValue() == $currency_by_language[$language]) {
return new Price($price->get('number')->getValue(), $price->get('currency_code')->getValue());
}
elseif ($price->get('currency_code')->getValue() == $currency_by_language[$default_language]) {
$default_price = new Price($price->get('number')->getValue(), $price->get('currency_code')->getValue());
}
}

return $default_price;
}
}
```