Skip to content
Closed
Show file tree
Hide file tree
Changes from all 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: 2 additions & 2 deletions modules/order/src/Entity/Order.php
Original file line number Diff line number Diff line change
Expand Up @@ -387,9 +387,9 @@ public function preSave(EntityStorageInterface $storage) {
}

/**
* Recalculates the line item total price.
* {@inheritdoc}
*/
protected function recalculateTotalPrice() {
public function recalculateTotalPrice() {
$total_price = $this->getTotalPrice();
if ($total_price) {
$currency_code = $total_price->getCurrencyCode();
Expand Down
5 changes: 5 additions & 0 deletions modules/order/src/Entity/OrderInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -233,4 +233,9 @@ public function getPlacedTime();
*/
public function setPlacedTime($timestamp);

/**
* Recalculates the line item total price.
*/
public function recalculateTotalPrice();

}
3 changes: 3 additions & 0 deletions modules/promotion/commerce_promotion.services.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,6 @@ services:
plugin.manager.commerce_promotion_condition:
class: Drupal\commerce_promotion\PromotionConditionManager
arguments: ['@container.namespaces', '@cache.discovery', '@module_handler', '@entity_type.manager']
commerce_promotion.promotion_application_service:
class: Drupal\commerce_promotion\PromotionApplicationService
arguments: ['@entity_type.manager']
77 changes: 77 additions & 0 deletions modules/promotion/src/PromotionApplicationService.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
<?php

namespace Drupal\commerce_promotion;

use Drupal\commerce_order\Entity\OrderInterface;
use Drupal\commerce_order\Entity\OrderType;
use Drupal\commerce_order\EntityAdjustableInterface;
use Drupal\commerce_promotion\Entity\PromotionInterface;
use Drupal\Component\Plugin\Exception\ContextException;
use Drupal\Core\Entity\EntityTypeManagerInterface;

/**
* @todo Docblock
* @todo Bikeshed name
*/
class PromotionApplicationService implements PromotionApplicationServiceInterface {

/**
* The promotion storage.
*
* @var \Drupal\commerce_promotion\PromotionStorageInterface
*/
protected $promotionStorage;

/**
* Constructs a new PromotionApplicationService object.
*
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
* The entity type manager.
*/
public function __construct(EntityTypeManagerInterface $entity_type_manager) {
$this->promotionStorage = $entity_type_manager->getStorage('commerce_promotion');
}

/**
* {@inheritdoc}
*/
public function apply(OrderInterface $order) {
// Load the valid promotions for the order type and store.
$promotions = $this->promotionStorage->loadValid($order->bundle(), $order->getStore());

foreach ($order->getLineItems() as $line_item) {
$this->applyToEntity($line_item, $promotions);
}

// Recalculate the order's total, after line item promotions applied.
$order->recalculateTotalPrice();
$this->applyToEntity($order, $promotions);
// @todo only save if a promotion was applied.
$order->save();
}

/**
* Helper to apply promotions to an entity.
*
* @param \Drupal\commerce_order\EntityAdjustableInterface $entity
* The adjuatable entity.
* @param \Drupal\commerce_promotion\Entity\PromotionInterface[] $promotions
* The array of possible promotions.
*/
protected function applyToEntity(EntityAdjustableInterface $entity, array $promotions) {
foreach ($promotions as $promotion) {
try {
// @todo When conditions land: if ($promotion->applies($entity) {
$promotion->apply($entity);
// @todo When conditions land: }
}
catch (ContextException $e) {
// @todo We need the promotion to check if the entity applies to offer.
continue;
}
}
// @todo only save when promotion applied.
$entity->save();
}

}
21 changes: 21 additions & 0 deletions modules/promotion/src/PromotionApplicationServiceInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php

namespace Drupal\commerce_promotion;

use Drupal\commerce_order\Entity\OrderInterface;
use Drupal\commerce_order\EntityAdjustableInterface;

/**
* @todo Docblock
*/
interface PromotionApplicationServiceInterface {

/**
* Applies promotions to an order.
*
* @param \Drupal\commerce_order\Entity\OrderInterface $order
* The order.
*/
public function apply(OrderInterface $order);

}
10 changes: 5 additions & 5 deletions modules/promotion/src/PromotionStorage.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,23 +15,23 @@ class PromotionStorage extends CommerceContentEntityStorage implements Promotion
/**
* Helper method to return base query for valid promotions.
*
* @param \Drupal\commerce_order\Entity\OrderTypeInterface $order_type
* @param string $order_type
* The order type.
* @param \Drupal\commerce_store\Entity\StoreInterface $store
* The store.
*
* @return \Drupal\Core\Entity\Query\QueryInterface
* The entity query.
*/
protected function loadValidQuery(OrderTypeInterface $order_type, StoreInterface $store) {
protected function loadValidQuery($order_type, StoreInterface $store) {
$query = $this->getQuery();

$or_condition = $query->orConditionGroup()
->condition('end_date', gmdate('Y-m-d'), '>=')
->notExists('end_date', gmdate('Y-m-d'));
$query
->condition('stores', [$store->id()], 'IN')
->condition('order_types', [$order_type->id()], 'IN')
->condition('order_types', [$order_type], 'IN')
->condition('start_date', gmdate('Y-m-d'), '<=')
->condition('status', TRUE)
->condition($or_condition);
Expand All @@ -41,7 +41,7 @@ protected function loadValidQuery(OrderTypeInterface $order_type, StoreInterface
/**
* {@inheritdoc}
*/
public function loadValid(OrderTypeInterface $order_type, StoreInterface $store) {
public function loadValid($order_type, StoreInterface $store) {
$query = $this->loadValidQuery($order_type, $store);
$result = $query->execute();
if (empty($result)) {
Expand All @@ -55,7 +55,7 @@ public function loadValid(OrderTypeInterface $order_type, StoreInterface $store)
/**
* {@inheritdoc}
*/
public function loadByCoupon(OrderTypeInterface $order_type, StoreInterface $store, CouponInterface $coupon) {
public function loadByCoupon($order_type, StoreInterface $store, CouponInterface $coupon) {
$query = $this->loadValidQuery($order_type, $store);
$query->condition('coupons', $coupon->id());
$result = $query->execute();
Expand Down
11 changes: 6 additions & 5 deletions modules/promotion/src/PromotionStorageInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,29 +5,30 @@
use Drupal\commerce_order\Entity\OrderTypeInterface;
use Drupal\commerce_promotion\Entity\CouponInterface;
use Drupal\commerce_store\Entity\StoreInterface;
use Drupal\Core\Entity\EntityStorageInterface;

/**
* Defines the interface for promotion storage.
*/
interface PromotionStorageInterface {
interface PromotionStorageInterface extends EntityStorageInterface {

/**
* Loads the valid promotions for the given order type and store.
*
* @param \Drupal\commerce_order\Entity\OrderTypeInterface $order_type
* @param string $order_type
* The order type.
* @param \Drupal\commerce_store\Entity\StoreInterface $store
* The store.
*
* @return \Drupal\commerce_promotion\Entity\PromotionInterface[]
* The valid promotions.
*/
public function loadValid(OrderTypeInterface $order_type, StoreInterface $store);
public function loadValid($order_type, StoreInterface $store);

/**
* Loads the valid promotions for the given coupon.
*
* @param \Drupal\commerce_order\Entity\OrderTypeInterface $order_type
* @param string $order_type
* The order type.
* @param \Drupal\commerce_store\Entity\StoreInterface $store
* The store.
Expand All @@ -37,6 +38,6 @@ public function loadValid(OrderTypeInterface $order_type, StoreInterface $store)
* @return \Drupal\commerce_promotion\Entity\PromotionInterface
* The valid promotions.
*/
public function loadByCoupon(OrderTypeInterface $order_type, StoreInterface $store, CouponInterface $coupon);
public function loadByCoupon($order_type, StoreInterface $store, CouponInterface $coupon);

}
Loading