commerce_funds-8.x-1.7/src/ProductManager.php
src/ProductManager.php
<?php
namespace Drupal\commerce_funds;
use Drupal\Core\Database\Connection;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\commerce_funds\Entity\Transaction;
use Drupal\commerce_order\Entity\Order;
use Drupal\commerce_order\Entity\OrderItem;
use Drupal\commerce_price\Price;
use Drupal\commerce_product\Entity\Product;
use Drupal\commerce_product\Entity\ProductVariation;
use Drupal\commerce_product\Entity\ProductVariationInterface;
/**
* Product manager class for funds products.
*/
class ProductManager implements ProductManagerInterface {
/**
* The entity type manager.
*
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
protected $entityTypeManager;
/**
* The db connection.
*
* @var \Drupal\Core\Database\Connection
*/
protected $connection;
/**
* Class constructor.
*/
public function __construct(EntityTypeManagerInterface $entity_type_manager, Connection $connection) {
$this->entityTypeManager = $entity_type_manager;
$this->connection = $connection;
}
/**
* {@inheritdoc}
*/
public function createProduct($type, $amount, $currency_code): ProductVariationInterface {
$title = ucfirst($type) . ' ' . $amount;
// If deposit product already exist we load it and check for variations.
$product_exist = $this->connection->query("SELECT product_id FROM {commerce_product_field_data} WHERE title = :title", [
':title' => $title,
])->fetchObject();
// Prepare the variation for further steps.
$sku = $type . '_' . $amount . '_' . $currency_code;
$price = new Price($amount, $currency_code);
$variation = [
'type' => $type,
'amount' => $amount,
'currency_code' => $currency_code,
'sku' => $sku,
'price' => $price,
];
// In case we have a multicurency website,
// we want to add a variation to the product
// of that amount.
if ($product_exist) {
$product = Product::load($product_exist->product_id);
$product_variations = array_filter($product->getVariations(), function ($product_variation) use ($sku) {
$variation_sku = $product_variation->getSku();
return $variation_sku === $sku;
});
$product_variation = reset($product_variations);
if (!$product_variation) {
$product_variation = $this->createVariation($product, $variation);
}
return $product_variation;
}
// Otherwise we create a new deposit product.
$product = Product::create([
'type' => $type,
'title' => ucfirst($type) . ' ' . $amount,
'status' => 1,
]);
$product->save();
// Create a new variation and add it to the product.
$product_variation = $this->createVariation($product, $variation);
return $product_variation;
}
/**
* Helper function to create a product variation.
*
* @param Drupal\commerce_product\Entity\Product $product
* A product entity.
* @param array $variation
* An associative array containing the type, amount,
* currency_code, sku and price.
*
* @see FundsProductManager::createProduct()
*
* @return Drupal\commerce_product\Entity\ProductVariation
* The product variation, deposit or fee, of the amount.
*/
protected function createVariation(Product $product, array $variation): ProductVariationInterface {
$product_variation = ProductVariation::create([
'title' => ucfirst($variation['type']) . ' ' . $variation['amount'] . ' ' . $variation['currency_code'],
'type' => $variation['type'],
'product_id' => $product->id(),
'sku' => $variation['sku'],
'price' => $variation['price'],
]);
$product_variation->save();
// Add the variation to the product.
$product->addVariation($product_variation);
return $product_variation;
}
/**
* {@inheritdoc}
*/
public function createOrder(ProductVariation $product_variation, ?Transaction $transaction = NULL) {
$store = $this->entityTypeManager->getStorage('commerce_store')->loadDefault();
// Create a new order item.
$order_item = OrderItem::create([
'type' => 'deposit',
'purchased_entity' => $product_variation,
'quantity' => 1,
'unit_price' => $product_variation->getPrice(),
]);
$order_item->save();
// Add the product variation to a new order.
$order = Order::create([
'type' => 'deposit',
'order_items' => [$order_item],
'store_id' => $store->id(),
'checkout_flow' => 'deposit',
'checkout_step' => 'order_information',
]);
$order->save();
// Add the deposit order item.
$order->addItem($order_item);
// Add the transaction if created
// via a field.
if ($transaction) {
$order->set('field_transaction', $transaction->id());
}
$order->save();
return $order;
}
/**
* {@inheritdoc}
*/
public function updateOrder(Order $order, ProductVariation $product_variation) {
// Get order items.
$order_items = $order->getItems();
// Remove previous fee product variation if exist.
if (isset($order_items[1])) {
$order->removeItem($order_items[1]);
}
// Create a new order item.
$order_item = OrderItem::create([
'type' => 'fee',
'purchased_entity' => $product_variation,
'quantity' => 1,
'unit_price' => $product_variation->getPrice(),
]);
$order_item->save();
// Add the deposit order item.
$order->addItem($order_item);
$order->save();
return $order;
}
}
