Skip to content

Conversation

@tafid
Copy link
Member

@tafid tafid commented Dec 18, 2025

…AliasGroupTreemethod, refactornestRackTreeChildrentonestTreeChildren`, and improve stock location type handling

Summary by CodeRabbit

  • New Features

    • Added alias-group hierarchical support to the stock locations tree selector.
  • Bug Fixes

    • More reliable decoding of location data for accurate display.
    • Improved location label selection to show expected names.
    • Updated item-reserve links to use a more consistent route format.
    • Empty selection handling in the selector now initializes as an empty list.
  • Refactor

    • Streamlined stock location data processing and tree-building for cleaner behavior.

✏️ Tip: You can customize this high-level summary in your review settings.

…AliasGroupTree` method, refactor `nestRackTreeChildren` to `nestTreeChildren`, and improve stock location type handling
@coderabbitai
Copy link

coderabbitai bot commented Dec 18, 2025

Walkthrough

Refactors stock location handling: indexes locations via ArrayHelper, decodes LocationItem objects JSON, adds alias-group tree construction in the tree-select widget, adjusts StockLocationsRepository mapping, and changes ModelGridView constructor to use property promotion for StockLocationsProvider and User.

Changes

Cohort / File(s) Change Summary
Grid & constructor updates
src/grid/ModelGridView.php
Use ArrayHelper::index to key locations by id; retrieve LocationItem by key instead of manual lookup; add use yii\helpers\ArrayHelper;; constructor updated to use property promotion for StockLocationsProvider and User as private readonly properties; imports adjusted.
Location item JSON & label logic
src/models/VO/LocationItem.php
Decode objects via \Yii\helpers\Json::decode in fromArray; broaden label selection to consider alias_group prefix using str_starts_with.
Widget: tree building & helpers
src/widgets/StockLocationsListTreeSelect.php
Added buildAliasGroupTree(array $stockLocationsList): array; replaced data-centers tree use with alias-group tree; renamed nestRackTreeChildrennestTreeChildren and updated calls; switched some filters to arrow functions; initialize empty attribute value as [] when present but empty; added use yii\helpers\ArrayHelper;.
Repository mapping behavior
src/repositories/StockLocationsRepository.php
Removed runtime filter that dropped rows with nulls; changed mapping to array_map calling LocationItem::fromArray for every item; closure changed from static to non-static lambda.
Model view and URL param shape
src/models/Model.php
Minor formatting changes; per-item reserve links now built with Url::to([...]) using a named PartSearch array structure (changes URL parameter shape); trailing comma added in validation rule.
Miscellaneous
src/models/Model.php
A "// todo: fix this!" comment added above link creation in renderReserves.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • Pay attention to: src/grid/ModelGridView.php constructor promotion and keyed access behavior; src/models/VO/LocationItem.php JSON decoding assumptions; src/widgets/StockLocationsListTreeSelect.php alias-group tree correctness and recursive helper rename; repository mapping change that removed null-filtering.

Possibly related PRs

Suggested reviewers

  • SilverFire

Poem

🐰
I hopped through arrays and keys today,
Decoded objects tucked away,
I nested trees where aliases bloom,
Promoted props to make room,
Now stocks align — a tidy play!

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 36.36% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The truncated title mentions enhancing StockLocationsListTreeSelect and adding buildAliasGroupTree, which aligns with the primary changes in the PR across multiple files.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/grid/ModelGridView.php (1)

118-125: Missing null check for location lookup.

Line 120 directly accesses $locations[$key] without verifying the key exists. While getLocations() filters against available IDs (per StockLocationsProvider), race conditions or cache staleness could cause a mismatch. Consider adding a guard.

🔎 Suggested defensive check:
 $locations = ArrayHelper::index($this->locationsProvider->getAllLocations(), 'id');
 foreach ($this->locationsProvider->getLocations() as $key) {
+    if (!isset($locations[$key])) {
+        continue;
+    }
     $location = $locations[$key];
🧹 Nitpick comments (1)
src/models/Model.php (1)

195-196: Vague TODO comment lacks actionable context.

The comment // todo: fix this! doesn't explain what needs to be fixed. Consider adding a description of the issue, a ticket reference (e.g., the HP-2828 task or a separate issue), or removing it if the fix is already tracked elsewhere.

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between aa66070 and 4d1f6cc.

📒 Files selected for processing (4)
  • src/grid/ModelGridView.php (2 hunks)
  • src/models/Model.php (1 hunks)
  • src/models/VO/LocationItem.php (2 hunks)
  • src/widgets/StockLocationsListTreeSelect.php (4 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
src/grid/ModelGridView.php (2)
src/helpers/StockLocationsProvider.php (2)
  • getAllLocations (27-30)
  • getLocations (37-62)
src/repositories/StockLocationsRepository.php (1)
  • getLocations (25-38)
src/widgets/StockLocationsListTreeSelect.php (1)
src/models/VO/LocationItem.php (1)
  • LocationItem (10-87)
🔇 Additional comments (6)
src/models/VO/LocationItem.php (2)

46-48: LGTM on the expanded label condition.

The addition of str_starts_with($this->id, 'alias_group') correctly extends the shortcut label logic to handle new alias group IDs, aligning with the buildAliasGroupTree method in StockLocationsListTreeSelect.


32-32: Consider handling malformed JSON gracefully.

Json::decode throws InvalidArgumentException if the JSON is malformed. The ?? '[]' handles null/missing data, but if $data['objects'] contains an invalid JSON string, this will throw. Since this is a public factory method processing external data, consider wrapping in a try-catch block or validating upstream data quality.

src/widgets/StockLocationsListTreeSelect.php (3)

221-230: LGTM on the options assembly refactor.

The integration of buildAliasGroupTree alongside existing CHW and rack trees is clean. The commented-out legacy tree is appropriately marked with a TODO for future cleanup.


272-282: Good refactor: arrow function and method rename.

The filter refactor to an arrow function improves readability. Renaming nestRackTreeChildren to nestTreeChildren better reflects its general-purpose nature for building hierarchical structures.


248-253: Verify whether removeKeysRecursively() properly handles deeply nested array keys.

The nested children arrays created at lines 248-253 have string keys ($objName) that persist through multiple nesting levels. While array_values() resets the outer array's keys, nested children retain their string keys. Since removeKeysRecursively() is defined in the parent class (external dependency), its implementation cannot be verified in this repository. If it doesn't recursively process all nested children arrays, the resulting tree structure may have unexpected string keys when JSON encoded.

src/grid/ModelGridView.php (1)

26-33: LGTM on constructor property promotion.

The use of private readonly property promotion is clean and reduces boilerplate. The dependencies are properly injected and typed.

…roup handling; remove redundant null filtering in `StockLocationsRepository`, and cleanup in `Model` formatting and link construction
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (1)
src/widgets/StockLocationsListTreeSelect.php (1)

233-271: Address the undefined array key issue flagged in previous review.

As noted in the previous review comment, Line 254 accesses $result[$l->type->value]['children'] without ensuring the 'children' key exists. This can cause an undefined array key error if no :ANY item was processed first for that type, or if items arrive in a different order than expected.

The initialization suggested in the previous review should be implemented to ensure the array structure exists before accessing it.

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4d1f6cc and 3fd9676.

📒 Files selected for processing (3)
  • src/models/Model.php (3 hunks)
  • src/repositories/StockLocationsRepository.php (1 hunks)
  • src/widgets/StockLocationsListTreeSelect.php (5 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
src/repositories/StockLocationsRepository.php (1)
src/models/VO/LocationItem.php (2)
  • LocationItem (10-87)
  • fromArray (30-42)
src/widgets/StockLocationsListTreeSelect.php (1)
src/models/VO/LocationItem.php (1)
  • LocationItem (10-87)
🔇 Additional comments (6)
src/models/Model.php (2)

120-120: LGTM - Formatting improvement.

The trailing comma is a good practice for multi-line arrays and doesn't change behavior.


184-202: LGTM - Standard URL generation pattern.

The refactoring to use Url::to() with a structured route array is a standard Yii2 pattern and improves readability. The parameters are appropriately structured for a search URL.

src/widgets/StockLocationsListTreeSelect.php (4)

13-13: LGTM - Required import for new functionality.

The ArrayHelper import is necessary for the new buildAliasGroupTree method that uses ArrayHelper::index().


46-46: Good defensive programming.

Handling the empty string case explicitly prevents attempting to explode an empty value, which would result in an array with a single empty string element. Returning an empty array directly is the correct behavior.


278-281: LGTM - Cleaner arrow function syntax.

The refactoring to use arrow function syntax is more concise while maintaining the same filtering logic.


288-288: LGTM - Good generalization of method name.

Renaming nestRackTreeChildren to nestTreeChildren better reflects that the method is used for general tree nesting, not just racks. The rename is consistently applied throughout the file.

Also applies to: 299-299, 314-314

static fn(array $item) => LocationItem::fromArray($item),
array_filter($data, static fn(array $datum) => !in_array(null, $datum, true))
);
return array_map(fn(array $item) => LocationItem::fromArray($item), $data);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Find LocationItem and StockLocationsRepository files
find . -type f -name "*.php" | grep -E "(LocationItem|StockLocationsRepository)" | head -20

Repository: hiqdev/hipanel-module-stock

Length of output: 151


🏁 Script executed:

#!/bin/bash
# 1. First, locate the relevant files
git ls-files | grep -E "(LocationItem|StockLocationsRepository)" | head -20

Repository: hiqdev/hipanel-module-stock

Length of output: 147


🏁 Script executed:

#!/bin/bash
# 2. Check the LocationItem::fromArray implementation
if git ls-files | grep -q "LocationItem"; then
  files=$(git ls-files | grep -i "locationitem")
  for file in $files; do
    echo "=== File: $file ==="
    cat -n "$file" 2>/dev/null || echo "Could not read $file"
  done
fi

Repository: hiqdev/hipanel-module-stock

Length of output: 3755


🏁 Script executed:

#!/bin/bash
# 3. Check StockLocationsRepository for the current code
if git ls-files | grep -q "StockLocationsRepository"; then
  file=$(git ls-files | grep "StockLocationsRepository")
  echo "=== File: $file ==="
  wc -l "$file"
fi

Repository: hiqdev/hipanel-module-stock

Length of output: 179


🏁 Script executed:

#!/bin/bash
# Read the StockLocationsRepository file
cat -n src/repositories/StockLocationsRepository.php

Repository: hiqdev/hipanel-module-stock

Length of output: 1219


🏁 Script executed:

#!/bin/bash
# Check git history to see if there was a previous filter that was removed
cd $(git rev-parse --show-toplevel)
git log --oneline -20 src/repositories/StockLocationsRepository.php

Repository: hiqdev/hipanel-module-stock

Length of output: 281


🏁 Script executed:

#!/bin/bash
# Get the diff of recent changes to this file
git log -p -2 src/repositories/StockLocationsRepository.php | head -100

Repository: hiqdev/hipanel-module-stock

Length of output: 53


🏁 Script executed:

#!/bin/bash
# Check if enum::from() throws on null values by looking at PHP docs behavior
# Also check if there's any type that allows null in the data structure
rg -B5 -A5 'stock-locations-list' src/

Repository: hiqdev/hipanel-module-stock

Length of output: 1741


🏁 Script executed:

#!/bin/bash
# Get the actual diff showing what was removed
git show 3fd9676 -- src/repositories/StockLocationsRepository.php

Repository: hiqdev/hipanel-module-stock

Length of output: 1588


🏁 Script executed:

#!/bin/bash
# Check the enums to understand their behavior
cat -n src/enums/StockLocationCategory.php src/enums/StockLocationType.php 2>/dev/null | head -50

Repository: hiqdev/hipanel-module-stock

Length of output: 1583


🏁 Script executed:

#!/bin/bash
# Search for Model::perform to understand what data structure it returns
rg -A10 'function perform' src/models/Model.php

Repository: hiqdev/hipanel-module-stock

Length of output: 53


🏁 Script executed:

#!/bin/bash
# Find and read the Model class
git ls-files | grep -E "models/Model\.php" | xargs cat -n

Repository: hiqdev/hipanel-module-stock

Length of output: 9494


🏁 Script executed:

#!/bin/bash
# Check previous version before the commit to see what was removed
git show 3fd9676~1:src/repositories/StockLocationsRepository.php 2>/dev/null || echo "Previous version not found or file didn't exist"

Repository: hiqdev/hipanel-module-stock

Length of output: 118


🏁 Script executed:

#!/bin/bash
# Search for any previous usage patterns in git history that might show null filtering
git log --all --source --remotes -S "array_filter" -- "*StockLocations*" 2>/dev/null | head -20

Repository: hiqdev/hipanel-module-stock

Length of output: 1091


🏁 Script executed:

#!/bin/bash
# Look for any other files that might have had this code before the refactor
git show 3fd9676~1:src/ 2>/dev/null | grep -i "location" || echo "Checking other locations..."
git log --name-status --oneline 3fd9676~1 | grep -i location

Repository: hiqdev/hipanel-module-stock

Length of output: 305


🏁 Script executed:

#!/bin/bash
# Check if there's a commit message or PR info mentioning what was refactored
git show 3fd9676 --stat

Repository: hiqdev/hipanel-module-stock

Length of output: 16979


🏁 Script executed:

#!/bin/bash
# Check the parent commit to see the state before this change
git show aa66070104fb038eb0277d567b55a25ec41956e4:src/repositories/StockLocationsRepository.php 2>/dev/null | head -50

Repository: hiqdev/hipanel-module-stock

Length of output: 1179


Flag the assumption that the API now guarantees non-null category and location_type values.

Removing the null filter means LocationItem::fromArray will receive all items from $data. Since the method uses StockLocationCategory::from() and StockLocationType::from() without null checks, passing null for category or location_type will throw a TypeError at runtime. The previous code's TODO comment indicates this filter was temporary until the API returned correct types. Verify that the API contract now guarantees these fields are never null before removing this filter.

Additionally, the arrow function doesn't use $this or capture parent scope variables, so marking it static fn(array $item) would clarify intent and align with the previous implementation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants