Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Inventory Laravel Package

stevebauman/inventory

A Laravel package for inventory management. Track items, categories, suppliers, and locations, monitor stock levels and inventory movements, and manage receiving and issuing through Eloquent models and migrations. Quickly add reliable inventory features to any Laravel application.

View on GitHub
Deep Wiki
Context7

Getting Started

Reality check first. This package was last released in June 2015 and targets Laravel 4 / 5. Before writing a line of code, confirm your app can actually run it: php constraints, illuminate/support version, and whether you need composer require stevebauman/inventory at all versus forking it into packages/. On a modern Laravel app (9/10/11) you will almost certainly need to fork and patch the service provider, config, and migrations. Treat it as a starting schema and domain model rather than a drop-in dependency.

Minimal setup on a compatible Laravel 5.x app:

  1. composer require stevebauman/inventory
  2. Register the provider manually — it predates package auto-discovery. Add Stevebauman\Inventory\InventoryServiceProvider::class to config/app.php under providers.
  3. Publish assets: php artisan vendor:publish (config file and migrations, depending on the package version). Check config/inventory.php for model bindings before running anything.
  4. php artisan migrate — this creates tables for items, categories, suppliers, locations, and stock movements.
  5. Seed a location and category first; most item creation flows expect them, or tolerate null but leave you with orphaned records you'll regret later.

Where to look first: the published config (config/inventory.php) and the item model it points to. The config usually lets you swap the item class and the table names, which is the main extension point you'll use. Then read the item model's trait — stock methods (addStock, removeStock, getStock, getTotalCost, getAverageCost, isDepleted, hasStock) and its relationships (category, supplier, location, movements) are the real API surface.

First use case: a single warehouse, one supplier, manual stock adjustments. Create an item with a SKU, category, supplier, and location; call addStock($qty, $reason, $cost); verify a movement row was written and getStock() returns the expected quantity. That vertical slice exercises the migrations, the trait, the movement audit trail, and the cost calculation in one go. Do it in a test before trusting it in production.

Implementation Patterns

Wrap every stock mutation in a transaction and a service class. The package mutates the item row and writes a movement row. If the second write fails, your quantity and your audit trail diverge silently. Create an App\Services\StockService with methods like receive(), issue(), adjust(), transfer() that open a DB::transaction, lock the item row (lockForUpdate()), call the package method, and dispatch your own domain event. This is the single highest-leverage thing you can do — it isolates the package behind a seam you control.

Treat movements as the source of truth, quantity as a cache. The package keeps a quantity column on the item and appends movements. Reconcile regularly: a scheduled command that sums movements per item and compares to getStock(), logging or auto-correcting drift. This catches bugs, manual DB edits, and race conditions before finance does.

Build a thin repository around item lookup. Day-to-day code will constantly ask "find this SKU," "items below reorder point," "items at location X." The package's query surface is plain Eloquent, so add local scopes on your own subclass (or a repository) rather than scattering where('quantity', '<', ...) everywhere. Subclassing the item model and pointing config/inventory.php at your subclass is the intended customization path — use it for accessors, scopes, and appended attributes.

Use the events for notifications, not for correctness. If the package fires stock-added / stock-removed / depleted events, hook listeners for low-stock alerts and Slack/email. Do not put ledger writes or downstream state changes in those listeners — they may not be transactionally aligned with the mutation. Anything that must be consistent belongs inside your service's transaction.

Model categories and suppliers as first-class, not as package concerns. In practice teams outgrow the bundled category/supplier/location models quickly (hierarchies, multiple suppliers per item, bin-level locations). Keep them for MVP, but design your service and API around your own vocabulary so swapping in richer models later is a config + migration change, not a rewrite.

For anything multi-location, plan a transfer primitive. If the package exposes a move/transfer method, verify it writes two movements (out from source, in to destination) and is atomic. If it doesn't, implement transfer in your service as removeStock + addStock inside one transaction, with a shared reference ID so the pair is traceable.

Testing pattern: use the package migrations in RefreshDatabase, build factories for item/category/supplier/location, and assert on both item quantity and movement count after each call. Assert on movement reason strings too — they're your only free-form audit metadata and teams rely on them heavily in reporting.

Gotchas and Tips

  • Abandoned dependency risk. No releases since 2015 means no PHP 8 / Laravel 9+ compatibility guarantees. Fork it (repositories in composer.json or a packages/ path repo), pin it, and own the maintenance. Budget a day for the fork-and-patch if you're on a modern stack.
  • No auto-discovery. On Laravel 5.5+ you must register the provider and any aliases manually. Symptoms of forgetting: "Class 'Inventory' not found" or migrations not appearing in vendor:publish.
  • Publish before migrate. Running migrate without publishing gives you missing tables with no error. Publish, inspect the migration files, then migrate — and check for column type choices you disagree with.
  • Decimal precision. Quantity and cost columns may be integers or low-precision decimals. If you sell by weight or need four-decimal unit costs, alter the migrations before production. Retrofitting decimals onto a live inventory table is painful.
  • No concurrency control. The package almost certainly doesn't lock rows. Two simultaneous removeStock calls can both read quantity 10, both write 8. Always lockForUpdate() the item inside your service transaction; never call the package methods directly from controllers.
  • Config model swapping is global and order-sensitive. Changing the item model in config affects every existing record. Do it at project start or write a data migration; don't expect polymorphic coexistence.
  • Validation lives with you. SKU uniqueness, negative quantities, and zero/negative stock reasons are your responsibility. Add a form request plus a DB unique index on SKU — the package will happily save duplicates.
  • Debugging stock drift: query movements for the item ordered by created_at, sum quantity deltas, diff against getStock(). If they disagree, look for direct $item->update(['quantity' => ...]) calls — grep your codebase for writes to the quantity column and ban them.
  • Event listeners and queued jobs are the natural extension point for reorder alerts and reporting rollups, but keep them idempotent — historical event semantics from a 2015 package may be less precise than you assume.
  • Don't expose package models directly in your API. Serialize your own resources. Otherwise a future fork or model swap breaks your public contract, and you leak columns like cost that shouldn't reach every client.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource
noith/settings