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
30 changes: 27 additions & 3 deletions src/controllers/InventoryController.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@
use craft\helpers\ArrayHelper;
use craft\helpers\Cp;
use craft\helpers\Html;
use craft\db\Query;
use craft\db\Table as CraftTable;
use craft\web\assets\htmx\HtmxAsset;
use craft\web\CpScreenResponseBehavior;
use yii\base\InvalidConfigException;
Expand Down Expand Up @@ -224,12 +226,12 @@
$inventoryLevelsManagerContainerId = $this->request->getRequiredParam('containerId');
$inventoryItemId = $this->request->getParam('inventoryItemId'); // Used for quick link to manage stock
$page = $this->request->getParam('page', 1);
$limit = $this->request->getParam('per_page', 25);
$limit = $this->request->getParam('per_page', 15);
$offset = ($page - 1) * $limit;
$inventoryLocationId = (int)Craft::$app->getRequest()->getParam('inventoryLocationId');
$search = $this->request->getParam('search');

$inventoryQuery = Plugin::getInstance()->getInventory()->getInventoryLevelQuery(limit: $limit, offset: $offset)
$inventoryQuery = Plugin::getInstance()->getInventory()->getInventoryLevelQuery(limit: $limit, offset: $offset, inventoryLocationId: $inventoryLocationId)
->andWhere(['inventoryLocationId' => $inventoryLocationId]);

if ($inventoryItemId) {
Expand Down Expand Up @@ -288,12 +290,34 @@
->offset(null)
->count();

// Batch-load all purchasables for this page in one query per element type,
// rather than one getElementById call per row.
$requestedSite = Cp::requestedSite();
$purchasableIds = array_unique(array_filter(array_column($inventoryTableData, 'purchasableId')));
$purchasablesMap = [];
if ($purchasableIds) {
$elementTypes = (new Query())
->select(['id', 'type'])
->from(CraftTable::ELEMENTS)
->where(['id' => $purchasableIds])
->pairs();
$byType = [];
foreach ($elementTypes as $id => $type) {
$byType[$type][] = $id;
}
foreach ($byType as $type => $ids) {
foreach ($type::find()->id($ids)->siteId($requestedSite->id)->all() as $element) {

Check failure on line 309 in src/controllers/InventoryController.php

View workflow job for this annotation

GitHub Actions / ci / Code Quality / PHPStan / PHPStan

Cannot call static method find() on (int|string).
$purchasablesMap[$element->id] = $element;
}
}
}

$view = Craft::$app->getView();
$time = microtime(true);
foreach ($inventoryTableData as $key => &$inventoryLevel) {
$id = $inventoryLevel['inventoryItemId'];
/** @var ?Purchasable $purchasable */
$purchasable = \Craft::$app->getElements()->getElementById($inventoryLevel['purchasableId'], siteId: Cp::requestedSite()->id);
$purchasable = $purchasablesMap[$inventoryLevel['purchasableId']] ?? null;
$inventoryItemDomId = sprintf("edit-$id-link-%s", mt_rand());
if ($purchasable) {
// When providing the `labelHtml` option we need to encode it ourselves
Expand Down
12 changes: 9 additions & 3 deletions src/services/Inventory.php
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ public function getInventoryLevel(InventoryItem|int $inventoryItem, InventoryLoc
$inventoryItemId = $inventoryItem instanceof InventoryItem ? $inventoryItem->id : $inventoryItem;
$inventoryLocationId = $inventoryLocation instanceof InventoryLocation ? $inventoryLocation->id : $inventoryLocation;

$result = $this->getInventoryLevelQuery(withTrashed: $withTrashed)
$result = $this->getInventoryLevelQuery(withTrashed: $withTrashed, inventoryLocationId: $inventoryLocationId)
->andWhere([
'inventoryLocationId' => $inventoryLocationId,
'inventoryItemId' => $inventoryItemId,
Expand Down Expand Up @@ -310,7 +310,7 @@ private function _populateInventoryFulfillmentLevel(array $data): InventoryFulfi
*/
public function getInventoryLocationLevels(InventoryLocation $inventoryLocation, bool $withTrashed = false): Collection
{
$levels = $this->getInventoryLevelQuery(withTrashed: $withTrashed)
$levels = $this->getInventoryLevelQuery(withTrashed: $withTrashed, inventoryLocationId: $inventoryLocation->id)
->andWhere(['inventoryLocationId' => $inventoryLocation->id])
->andWhere(['not', ['elements.id' => null]])
->collect();
Expand All @@ -333,7 +333,7 @@ public function getInventoryLocationLevels(InventoryLocation $inventoryLocation,
* @param bool $withTrashed
* @return Query
*/
public function getInventoryLevelQuery(?int $limit = null, ?int $offset = null, bool $withTrashed = false): Query
public function getInventoryLevelQuery(?int $limit = null, ?int $offset = null, bool $withTrashed = false, ?int $inventoryLocationId = null): Query
{
$inventoryTotals = (new Query())
->select([
Expand All @@ -347,6 +347,12 @@ public function getInventoryLevelQuery(?int $limit = null, ?int $offset = null,
->leftJoin(['it' => Table::INVENTORYTRANSACTIONS], "[[il.id]] = [[it.inventoryLocationId]] AND [[ii.id]] = [[it.inventoryItemId]]")
->groupBy(['[[il.id]]', '[[ii.id]]', '[[it.type]]']);

// Scoping the location in the subquery prevents the CROSS JOIN from expanding
// to all locations × all items before the outer WHERE can filter it down.
if ($inventoryLocationId !== null) {
$inventoryTotals->andWhere(['il.id' => $inventoryLocationId]);
}

$query = (new Query())
->select([
'[[ii.id]] as inventoryItemId',
Expand Down
2 changes: 2 additions & 0 deletions src/translations/en/commerce.php
Original file line number Diff line number Diff line change
Expand Up @@ -1101,6 +1101,7 @@
'Switch plan' => 'Switch plan',
'Switch' => 'Switch',
'System' => 'System',
'Table Columns' => 'Table Columns',
'Target - The category relationship field is on the purchasable' => 'Target - The category relationship field is on the purchasable',
'Tax & Shipping' => 'Tax & Shipping',
'Tax (inc)' => 'Tax (inc)',
Expand Down Expand Up @@ -1300,6 +1301,7 @@
'Variants not restored.' => 'Variants not restored.',
'Variants restored.' => 'Variants restored.',
'Variants' => 'Variants',
'View' => 'View',
'View customer' => 'View customer',
'View order' => 'View order',
'View product type - {productType}' => 'View product type - {productType}',
Expand Down
4 changes: 4 additions & 0 deletions src/web/assets/inventory/InventoryAsset.php
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,10 @@ public function registerAssetFiles($view): void
'Available',
'On Hand',
'Incoming',
'View',
'Table Columns',
'Purchasable',
'SKU',
]);
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/web/assets/inventory/dist/css/inventory.css

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion src/web/assets/inventory/dist/css/inventory.css.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion src/web/assets/inventory/dist/inventory.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/web/assets/inventory/dist/inventory.js.map

Large diffs are not rendered by default.

5 changes: 5 additions & 0 deletions src/web/assets/inventory/src/css/inventory.scss
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
// Inventory levels toolbar (contains the View button)
.inventory-levels-toolbar {
margin-bottom: var(--m);
}

.inventory-headers {
.ltr & {
justify-content: flex-end;
Expand Down
Loading
Loading