PriceCalculator.php in Commerce Core 8.2
File
modules/order/src/PriceCalculator.php
View source
<?php
namespace Drupal\commerce_order;
use Drupal\commerce\Context;
use Drupal\commerce\PurchasableEntityInterface;
use Drupal\commerce_order\Resolver\ChainOrderTypeResolverInterface;
use Drupal\commerce_price\Resolver\ChainPriceResolverInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Symfony\Component\HttpFoundation\RequestStack;
class PriceCalculator implements PriceCalculatorInterface {
protected $adjustmentTransformer;
protected $chainOrderTypeResolver;
protected $chainPriceResolver;
protected $entityTypeManager;
protected $requestStack;
protected $processors = [];
protected $orders = [];
public function __construct(AdjustmentTransformerInterface $adjustment_transformer, ChainOrderTypeResolverInterface $chain_order_type_resolver, ChainPriceResolverInterface $chain_price_resolver, EntityTypeManagerInterface $entity_type_manager, RequestStack $request_stack) {
$this->adjustmentTransformer = $adjustment_transformer;
$this->chainOrderTypeResolver = $chain_order_type_resolver;
$this->chainPriceResolver = $chain_price_resolver;
$this->entityTypeManager = $entity_type_manager;
$this->requestStack = $request_stack;
}
public function addProcessor(OrderProcessorInterface $processor, $adjustment_type) {
$this->processors[$adjustment_type][] = $processor;
}
public function getProcessors($adjustment_type) {
if (!isset($this->processors[$adjustment_type])) {
return [];
}
return $this->processors[$adjustment_type];
}
public function calculate(PurchasableEntityInterface $purchasable_entity, $quantity, Context $context, array $adjustment_types = []) {
$resolved_price = $this->chainPriceResolver
->resolve($purchasable_entity, $quantity, $context);
$processors = [];
foreach ($adjustment_types as $adjustment_type) {
$processors = array_merge($processors, $this
->getProcessors($adjustment_type));
}
if (empty($adjustment_types) || empty($processors)) {
return new PriceCalculatorResult($resolved_price, $resolved_price);
}
$order_item_storage = $this->entityTypeManager
->getStorage('commerce_order_item');
$order_item = $order_item_storage
->createFromPurchasableEntity($purchasable_entity);
$order_item
->setUnitPrice($resolved_price);
$order_item
->setQuantity($quantity);
$order_type_id = $this->chainOrderTypeResolver
->resolve($order_item);
$order = $this
->prepareOrder($order_type_id, $context);
$order_item->order_id = $order;
$order
->setItems([
$order_item,
]);
foreach ($processors as $processor) {
$processor
->process($order);
}
$calculated_price = $order_item
->getAdjustedTotalPrice();
$adjustments = $order_item
->getAdjustments();
$adjustments = $this->adjustmentTransformer
->processAdjustments($adjustments);
return new PriceCalculatorResult($calculated_price, $resolved_price, $adjustments);
}
protected function prepareOrder($order_type_id, Context $context) {
if (!isset($this->orders[$order_type_id])) {
$order_storage = $this->entityTypeManager
->getStorage('commerce_order');
$this->orders[$order_type_id] = $order_storage
->create([
'type' => $order_type_id,
'ip_address' => $this->requestStack
->getCurrentRequest()
->getClientIp(),
'data' => [
'provider' => 'order_price_calculator',
],
]);
}
$order = $this->orders[$order_type_id];
$order
->setStoreId($context
->getStore()
->id());
$order
->setCustomerId($context
->getCustomer()
->id());
$order
->setEmail($context
->getCustomer()
->getEmail());
$order
->clearAdjustments();
return $order;
}
}