View source
<?php
namespace Drupal\commerce_stock_local;
use Drupal\commerce\PurchasableEntityInterface;
use Drupal\commerce_stock\StockCheckInterface;
use Drupal\Core\Database\Connection;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
class LocalStockChecker implements StockCheckInterface {
protected $database;
protected $locationStorage;
public function __construct(Connection $database, EntityTypeManagerInterface $entity_type_manager) {
$this->database = $database;
$this->locationStorage = $entity_type_manager
->getStorage('commerce_stock_location');
}
public static function create(ContainerInterface $container) {
return new static($container
->get('database'), $container
->get('entity_type.manager'));
}
public function getLocationStockLevel($location_id, PurchasableEntityInterface $entity) {
$result = $this->database
->select('commerce_stock_location_level', 'll')
->fields('ll')
->condition('location_id', $location_id)
->condition('entity_id', $entity
->id())
->condition('entity_type', $entity
->getEntityTypeId())
->execute()
->fetch();
return [
'qty' => $result ? $result->qty : 0,
'last_transaction' => $result ? $result->last_transaction_id : 0,
];
}
public function getLocationStockTransactionLatest($location_id, PurchasableEntityInterface $entity) {
$query = $this->database
->select('commerce_stock_transaction')
->condition('location_id', $location_id)
->condition('entity_id', $entity
->id())
->condition('entity_type', $entity
->getEntityTypeId());
$query
->addExpression('MAX(id)', 'max_id');
$result = $query
->execute()
->fetch();
return $result && $result->max_id ? $result->max_id : 0;
}
public function getLocationStockTransactionSum($location_id, PurchasableEntityInterface $entity, $min, $max) {
$query = $this->database
->select('commerce_stock_transaction', 'txn')
->fields('txn', [
'location_id',
])
->condition('location_id', $location_id)
->condition('entity_id', $entity
->id())
->condition('entity_type', $entity
->getEntityTypeId())
->condition('id', $min, '>');
if ($max) {
$query
->condition('id', $max, '<=');
}
$query
->addExpression('SUM(qty)', 'qty');
$query
->groupBy('location_id');
$result = $query
->execute()
->fetch();
return $result ? $result->qty : 0;
}
public function getTotalStockLevel(PurchasableEntityInterface $entity, array $locations) {
$location_info = $this
->getLocationsStockLevels($entity, $locations);
$total = 0;
foreach ($location_info as $location) {
$total += $location['qty'] + $location['transactions_qty'];
}
return $total;
}
public function getLocationsStockLevels(PurchasableEntityInterface $entity, array $locations) {
$location_levels = [];
foreach ($locations as $location) {
$location_id = $location
->getId();
$location_level = $this
->getLocationStockLevel($location_id, $entity);
$latest_txn = $this
->getLocationStockTransactionLatest($location_id, $entity);
$transactions_qty = $this
->getLocationStockTransactionSum($location_id, $entity, $location_level['last_transaction'], $latest_txn);
$location_levels[$location_id] = [
'qty' => $location_level['qty'],
'transactions_qty' => $transactions_qty,
];
}
return $location_levels;
}
public function getIsInStock(PurchasableEntityInterface $entity, array $locations) {
return $this
->getTotalStockLevel($entity, $locations) > 0;
}
public function getIsAlwaysInStock(PurchasableEntityInterface $entity) {
return $entity
->get('commerce_stock_always_in_stock') && $entity
->get('commerce_stock_always_in_stock')->value == TRUE;
}
public function getLocationList($return_active_only = TRUE) {
$locations = $this->locationStorage
->loadMultiple();
if ($return_active_only) {
$active = [];
foreach ($locations as $location) {
if ($location
->isActive()) {
$active[] = $location;
}
}
return $active;
}
return $locations;
}
}