mirror of
https://github.com/farmOS/farmOS.git
synced 2024-02-23 11:37:38 +01:00
Add a getAssetsByLocation() method to the asset.location service.
This commit is contained in:
parent
2c0cd65b77
commit
cc9e0a8a6c
3 changed files with 85 additions and 3 deletions
|
@ -2,7 +2,7 @@ services:
|
|||
asset.location:
|
||||
class: Drupal\farm_location\AssetLocation
|
||||
arguments:
|
||||
[ '@log.location', '@farm.log_query', '@entity_type.manager', '@datetime.time' ]
|
||||
[ '@log.location', '@farm.log_query', '@entity_type.manager', '@datetime.time' , '@database']
|
||||
log.location:
|
||||
class: Drupal\farm_location\LogLocation
|
||||
farm_location.log_presave:
|
||||
|
|
|
@ -4,6 +4,7 @@ namespace Drupal\farm_location;
|
|||
|
||||
use Drupal\asset\Entity\AssetInterface;
|
||||
use Drupal\Component\Datetime\TimeInterface;
|
||||
use Drupal\Core\Database\Connection;
|
||||
use Drupal\Core\Entity\EntityTypeManagerInterface;
|
||||
use Drupal\farm_log\LogQueryFactoryInterface;
|
||||
use Drupal\log\Entity\LogInterface;
|
||||
|
@ -56,6 +57,13 @@ class AssetLocation implements AssetLocationInterface {
|
|||
*/
|
||||
protected $time;
|
||||
|
||||
/**
|
||||
* The database service.
|
||||
*
|
||||
* @var \Drupal\Core\Database\Connection
|
||||
*/
|
||||
protected $database;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
|
@ -67,12 +75,15 @@ class AssetLocation implements AssetLocationInterface {
|
|||
* Entity type manager.
|
||||
* @param \Drupal\Component\Datetime\TimeInterface $time
|
||||
* The time service.
|
||||
* @param \Drupal\Core\Database\Connection $database
|
||||
* The database service.
|
||||
*/
|
||||
public function __construct(LogLocationInterface $log_location, LogQueryFactoryInterface $log_query_factory, EntityTypeManagerInterface $entity_type_manager, TimeInterface $time) {
|
||||
public function __construct(LogLocationInterface $log_location, LogQueryFactoryInterface $log_query_factory, EntityTypeManagerInterface $entity_type_manager, TimeInterface $time, Connection $database) {
|
||||
$this->logLocation = $log_location;
|
||||
$this->logQueryFactory = $log_query_factory;
|
||||
$this->entityTypeManager = $entity_type_manager;
|
||||
$this->time = $time;
|
||||
$this->database = $database;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -83,7 +94,8 @@ class AssetLocation implements AssetLocationInterface {
|
|||
$container->get('log.location'),
|
||||
$container->get('farm.log_query'),
|
||||
$container->get('entity_type.manager'),
|
||||
$container->get('datetime.time')
|
||||
$container->get('datetime.time'),
|
||||
$container->get('database')
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -196,4 +208,63 @@ class AssetLocation implements AssetLocationInterface {
|
|||
$asset->{static::ASSET_FIELD_GEOMETRY} = $wkt;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getAssetsByLocation(AssetInterface $location): array {
|
||||
if (empty($location->id())) {
|
||||
return [];
|
||||
}
|
||||
$query = "
|
||||
-- Select asset IDs from the asset base table.
|
||||
SELECT a.id
|
||||
FROM {asset} a
|
||||
|
||||
-- Inner join logs that reference the assets.
|
||||
INNER JOIN {asset_field_data} afd ON afd.id = a.id
|
||||
INNER JOIN {log__asset} la ON a.id = la.asset_target_id AND la.deleted = 0
|
||||
INNER JOIN {log_field_data} lfd ON lfd.id = la.entity_id
|
||||
|
||||
-- Inner join location assets referenced by the logs.
|
||||
INNER JOIN {log__location} ll ON ll.entity_id = lfd.id AND ll.deleted = 0
|
||||
|
||||
-- Left join ANY future movement logs for the same asset.
|
||||
-- In the WHERE clause we'll exclude all records that have future logs,
|
||||
-- leaving only the 'current' log entry.
|
||||
LEFT JOIN (
|
||||
{log_field_data} lfd2
|
||||
INNER JOIN {log__asset} la2 ON la2.entity_id = lfd2.id AND la2.deleted = 0
|
||||
) ON lfd2.is_movement = 1 AND la2.asset_target_id = a.id
|
||||
|
||||
-- Future log entries have either a higher timestamp, or an equal timestamp and higher log ID.
|
||||
AND (lfd2.timestamp > lfd.timestamp OR (lfd2.timestamp = lfd.timestamp AND lfd2.id > lfd.id))
|
||||
|
||||
-- Don't include future logs beyond the given timestamp.
|
||||
-- These conditions should match the values in the WHERE clause.
|
||||
AND (lfd2.status = 'done') AND (lfd2.timestamp <= :timestamp)
|
||||
|
||||
-- Only include assets that are not archived.
|
||||
WHERE (afd.status != 'archived')
|
||||
|
||||
-- Limit results to completed movement logs to the desired location that
|
||||
-- took place before the given timestamp.
|
||||
WHERE (lfd.is_movement = 1) AND (lfd.status = 'done') AND (lfd.timestamp <= :timestamp) AND (ll.location_target_id = :location_id)
|
||||
|
||||
-- Exclude records with future log entries.
|
||||
AND lfd2.id IS NULL";
|
||||
$args = [
|
||||
':timestamp' => $this->time->getRequestTime(),
|
||||
':location_id' => $location->id(),
|
||||
];
|
||||
$result = $this->database->query($query, $args)->fetchAll();
|
||||
$asset_ids = [];
|
||||
foreach ($result as $row) {
|
||||
if (!empty($row->id)) {
|
||||
$asset_ids[] = $row->id;
|
||||
}
|
||||
}
|
||||
$asset_ids = array_unique($asset_ids);
|
||||
return $this->entityTypeManager->getStorage('asset')->loadMultiple($asset_ids);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -86,4 +86,15 @@ interface AssetLocationInterface {
|
|||
*/
|
||||
public function setIntrinsicGeometry(AssetInterface $asset, string $wkt): void;
|
||||
|
||||
/**
|
||||
* Get assets that are in a location.
|
||||
*
|
||||
* @param \Drupal\asset\Entity\AssetInterface $location
|
||||
* The location asset entity.
|
||||
*
|
||||
* @return array
|
||||
* Returns an array of assets.
|
||||
*/
|
||||
public function getAssetsByLocation(AssetInterface $location): array;
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue