How to Configure Asset Locations in Snipe-IT: A Complete Setup Guide
Asset locations in Snipe-IT are configured through the Location model which supports hierarchical parent-child relationships, REST API endpoints, and CSV import functionality, allowing administrators to track physical storage sites and ready-to-deploy positions via the location_id and rtd_location_id fields.
The open-source asset management platform grokability/snipe-it provides a flexible location system defined in app/Models/Location.php and managed through both web-based controllers and RESTful API endpoints. Properly configuring these locations ensures accurate asset tracking across multiple sites while supporting Full Multiple Company Support (FMCS) scoping for multi-tenant deployments.
Understanding the Location Data Model
The Location Model and Database Schema
Locations are persisted in the locations table created by the migration at database/migrations/2013_11_16_103258_create_locations_table.php. The Location Eloquent model (app/Models/Location.php) defines the core schema and relationships, including support for hierarchical nesting via the parent_id field.
The model implements two critical asset relationships:
assets()– Retrieves assets where thelocation_idforeign key matches the location, representing the current physical storage position.rtdAssets()– Retrieves assets where thertd_location_id(ready-to-deploy location) matches the location, indicating where items should be stocked when not checked out.
These relationships are maintained by the MigratesLegacyAssetLocations trait found in app/Http/Traits/MigratesLegacyAssetLocations.php, which ensures backward compatibility when upgrading from older Snipe-IT versions that handled location data differently.
Creating and Managing Locations
Via the Web Interface
The UI controller at app/Http/Controllers/LocationsController.php handles form validation and CRUD operations for location management. Administrators can access this through Admin → Locations in the navigation menu. The controller uses the LocationPresenter class (app/Presenters/LocationPresenter.php) to generate human-readable paths such as fullLocationPath(), which concatenates parent and child location names for display in dropdown selectors.
Via the REST API
For programmatic configuration, the API controller at app/Http/Controllers/Api/LocationsController.php exposes JSON endpoints. The controller utilizes app/Http/Transformers/LocationsTransformer.php to standardize API responses and respects the authorization policies defined in app/Policies/LocationPolicy.php.
To create a location via API:
curl -X POST https://your-domain.com/api/v1/locations \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{
"name": "Building A - Floor 2",
"address": "123 Tech Street",
"city": "San Francisco",
"state": "CA",
"zip": "94105",
"country": "US",
"parent_id": 1
}'
Bulk Import via CSV
For large-scale deployments, use the command-line importer at app/Importer/LocationImporter.php:
php artisan snipeit:import:locations /path/to/locations.csv
The CSV should contain headers matching the database columns: name, address, city, state, country, zip, and optionally parent_id to establish hierarchies during import.
Assigning Locations to Assets
The Asset-Location Relationship
When editing an asset, the system updates two distinct fields in the assets table:
location_id– The current physical location of the assetrtd_location_id– The location where the asset should be returned when checked in (Ready-To-Deploy)
These fields are rendered in Blade views using the location selector partial at resources/views/partials/forms/edit/location-select.blade.php, which implements Select2 AJAX loading for searchable dropdowns:
<div class="form-group">
<label for="location_id">{{ trans('admin/locations/general.location') }}</label>
<select class="form-control js-data-ajax"
data-endpoint="locations"
name="location_id"
id="location_id">
<option value="">{{ trans('general.select_location') }}</option>
</select>
</div>
Hierarchical Locations and Parent IDs
Locations support unlimited nesting through the parent_id database column. When parent_id is set to another location's ID, the system treats it as a child location. The LocationPresenter::fullLocationPath() method traverses this hierarchy to display complete paths like "Main Warehouse > Building B > Room 204" in user interfaces.
To set a parent via API, simply include the parent_id parameter:
// Using Artisan Tinker
>>> use App\Models\Location;
>>> $child = Location::create([
... 'name' => 'Server Room B',
... 'parent_id' => 5, // ID of parent location
... 'company_id' => 1 // Required when FMCS is enabled
... ]);
Multi-Company Support and Location Scoping
When Full Multiple Company Support (FMCS) is enabled in settings, the app/Livewire/LocationScopeCheck.php component enforces company-specific location visibility. This Livewire component filters location dropdowns to show only locations belonging to the user's assigned company or the asset's company context.
The app/Policies/LocationPolicy.php file governs authorization, ensuring that users can only view, edit, or delete locations within their permitted scope. When using the Select2 AJAX endpoints, the JavaScript in snipeit.js automatically appends the companyId parameter to requests, allowing the API controllers to filter results accordingly.
Common Configuration Pitfalls
-
Empty string handling: The
Locationmodel casts empty string inputs tonullfor theparent_idfield. Ensure your import CSV uses actual null values or valid integer IDs rather than empty strings to avoid validation errors. -
Asset reassignment on deletion: Deleting a location via
LocationsController.phpdoes not cascade updates to associated assets. Thelocation_idandrtd_location_idfields in the assets table will retain the deleted location's ID unless you manually reassign assets beforehand or implement custom observers. -
Performance on deep hierarchies: Queries against nested location trees perform best when the
parent_idindex is present. Ensure your installation includes the latest migrations that add indexes to theparent_idandcompany_idcolumns in the locations table.
Summary
- Configure asset locations using the Location model at
app/Models/Location.php, which supports hierarchical relationships viaparent_id - Manage locations through the UI controller (
LocationsController.php), API endpoints (Api/LocationsController.php), or CSV import (LocationImporter.php) - Distinguish between
location_id(current position) andrtd_location_id(ready-to-deploy position) when assigning assets - Enable FMCS scoping via
LocationScopeCheck.phpandLocationPolicy.phpfor multi-company environments - Use the LocationPresenter class to render full location paths in custom Blade templates
Frequently Asked Questions
What is the difference between location_id and rtd_location_id in Snipe-IT?
The location_id field stores the asset's current physical location, while rtd_location_id (Ready-To-Deploy location) indicates where the asset should be stored when it is checked back in and available for deployment. This dual-field system allows Snipe-IT to track both where an asset is currently located and its designated "home" location separately.
How do I enable hierarchical locations in Snipe-IT?
Hierarchical locations are supported natively without additional configuration. Simply populate the parent_id field when creating a location via the web form at Admin → Locations → Create New or via the API by specifying parent_id in your POST request. The system automatically renders parent-child relationships in dropdown menus using the LocationPresenter::fullLocationPath() method.
Can I import locations in bulk using a CSV file?
Yes, use the built-in artisan command php artisan snipeit:import:locations /path/to/file.csv which processes the CSV through app/Importer/LocationImporter.php. The CSV must include a name column and can optionally include address, city, state, zip, country, and parent_id columns to establish the location hierarchy during import.
Why are assets not appearing in the correct location scope for certain users?
When Full Multiple Company Support (FMCS) is enabled, the LocationScopeCheck Livewire component and LocationPolicy restrict location visibility based on company assignments. Ensure the location's company_id matches the user's company or that the user has permissions to view locations across companies. The AJAX endpoints respect the companyId query parameter sent by the Select2 components in snipeit.js.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →