delickate / inventory-module
Inventory Module for Laravel Applications
Package info
github.com/delickate/inventory-module
Language:CSS
pkg:composer/delickate/inventory-module
Requires
- php: ^7.3|^8.0
- illuminate/contracts: ^8.0|^9.0|^10.0|^11.0
This package is auto-updated.
Last update: 2026-04-17 09:26:32 UTC
README
A plug-and-play Inventory Management Module for Laravel modular applications using delickate/module-generator.
This package installs a fully developed Inventory module into your Laravel application's Modules directory.
It is designed for ERP, POS, and stock management systems.
โจ Features
- ๐ฆ Product Management
- ๐ฌ Warehouse Management
- ๐ Stock Tracking
- ๐ Stock Movement History
- ๐ฅ Purchase Stock Entries
- ๐ค Sales Stock Deduction
- ๐งพ Inventory Reports
- ๐ท Category & Brand Support
- โก Modular Architecture
- ๐ Easy Laravel Integration
๐ Module Structure
After installation, the module will be placed inside:
Modules/Inventory
Structure example:
Modules/
โโโ Inventory
โโโ Config
โโโ Database
โ โโโ Migrations
โ โโโ Seeders
โ
โโโ Entities
โ
โโโ Http
โ โโโ Controllers
โ โโโ Requests
โ
โโโ Providers
โ
โโโ Routes
โ
โโโ Resources
โ โโโ views
โ
โโโ module.json
โ๏ธ Requirements
- PHP 8.1+
- Laravel 10 / 11
- Installed
delickate/module-generator
๐ฅ Installation
Install the package via Composer.
composer require delickate/inventory-module
๐ Module Installation
Run the installer command:
php artisan inventory:install
This command will:
- Publish the Inventory module
- Installed it to:
Modules/Inventory
๐ Run Migrations
After installing the module, run migrations.
php artisan module:migrate Inventory
Or run all module migrations:
php artisan module:migrate
๐ Core Components
Products
Manage products with:
- SKU
- Category
- Brand
- Cost Price
- Selling Price
- Stock Quantity
Warehouses
Supports:
- Multiple warehouses
- Warehouse stock tracking
Stock Movements
Tracks:
- Stock In
- Stock Out
- Transfers
- Adjustments
๐ง Customization
Since the module is installed into your project, you can modify it directly.
Example:
Modules/Inventory/Http/Controllers
Modules/Inventory/Entities
Modules/Inventory/Routes
๐ Artisan Commands
Install module
php artisan inventory:install
Run module migrations
php artisan module:migrate Inventory
Copy following html and paste into any blade page. mostly being used in leftnavigation
<p>Inventory</p> <ul> <li><a href="<?php echo url('inventory/categories/listing'); ?>">Product categories</li> <li><a href="<?php echo url('inventory/units/listing'); ?>">Product Units</li> <li><a href="<?php echo url('inventory/suppliers/listing'); ?>">Suppliers</li> <li><a href="<?php echo url('inventory/warehouses/listing'); ?>">Warehouses</li> <li><a href="<?php echo url('inventory/products/listing'); ?>">Products</li> <li><a href="<?php echo url('inventory/purchases/listing'); ?>">Purchase Orders</li> <li><a href="<?php echo url('inventory/stock_movements/listing'); ?>">Stock</li> <li><a href="<?php echo url('inventory/customers/listing'); ?>">Customers</li> <li><a href="<?php echo url('inventory/sales/listing'); ?>">Sales</li> <p>Inventory Reports</p> <li><a href="{{ url('inventory/inventoryReports/CurrentStockStatus') }}">Current Stock Status</li> <li><a href="{{ url('inventory/inventoryReports/LowStockAlert') }}">Low Stock Alert</li> <li><a href="{{ url('inventory/inventoryReports/SalesSummary') }}">Sales Summary</li> <li><a href="{{ url('inventory/inventoryReports/CustomerPurchaseHistory') }}">Customer Purchase History</li> <li><a href="{{ url('inventory/inventoryReports/PurchaseSummary') }}">Purchase Summary</li> <li><a href="{{ url('inventoryReports/AccountsPayable') }}">Accounts Payable</li> </ul>
You can use following routes for it. (Already have inside module)
#inventory routes use Modules\Inventory\Http\Controllers\ProductsController; use Modules\Inventory\Http\Controllers\CategoriesController; use Modules\Inventory\Http\Controllers\UnitsController; use Modules\Inventory\Http\Controllers\WarehousesController; use Modules\Inventory\Http\Controllers\InventoryController; use Modules\Inventory\Http\Controllers\Stock_MovementsController; use Modules\Inventory\Http\Controllers\SuppliersController; use Modules\Inventory\Http\Controllers\PurchasesController; use Modules\Inventory\Http\Controllers\Purchase_ItemsController; use Modules\Inventory\Http\Controllers\Purchase_ReturnsController; use Modules\Inventory\Http\Controllers\Purchase_Return_ItemsController; use Modules\Inventory\Http\Controllers\CustomersController; use Modules\Inventory\Http\Controllers\SalesController; use Modules\Inventory\Http\Controllers\Sale_ItemsController; use Modules\Inventory\Http\Controllers\Sale_ReturnsController; #reports use Modules\Inventory\Http\Controllers\InventoryReportsController; //auto vouching use Modules\Inventory\Http\Controllers\AutoVouchingInventoryController; Route::prefix('inventory')->group(function() { Route::get('/', 'InventoryController@index'); Route::group(['prefix'=>'suppliers/','as'=>'suppliers.'], function() { Route::get('listing', [SuppliersController::class, 'index'])->name('listing'); Route::get('adding', [SuppliersController::class, 'create'])->name('adding'); Route::post('saving', [SuppliersController::class, 'store'])->name('saving'); Route::get('editing/{id}', [SuppliersController::class, 'edit'])->name('editing'); Route::get('showing/{id}', [SuppliersController::class, 'show'])->name('showing'); Route::post('updating/{id}', [SuppliersController::class, 'update'])->name('updating'); Route::get('deleting/{id}', [SuppliersController::class, 'destroy'])->name('deleting'); }); Route::group(['prefix'=>'products/','as'=>'products.'], function() { Route::get('listing', [ProductsController::class, 'index'])->name('listing'); Route::get('adding', [ProductsController::class, 'create'])->name('adding'); Route::post('saving', [ProductsController::class, 'store'])->name('saving'); Route::get('editing/{id}', [ProductsController::class, 'edit'])->name('editing'); Route::get('showing/{id}', [ProductsController::class, 'show'])->name('showing'); Route::post('updating/{id}', [ProductsController::class, 'update'])->name('updating'); Route::get('deleting/{id}', [ProductsController::class, 'destroy'])->name('deleting'); }); Route::group(['prefix'=>'categories/','as'=>'categories.'], function() { Route::get('listing', [CategoriesController::class, 'index'])->name('listing'); Route::get('adding', [CategoriesController::class, 'create'])->name('adding'); Route::post('saving', [CategoriesController::class, 'store'])->name('saving'); Route::get('editing/{id}', [CategoriesController::class, 'edit'])->name('editing'); Route::get('showing/{id}', [CategoriesController::class, 'show'])->name('showing'); Route::post('updating/{id}', [CategoriesController::class, 'update'])->name('updating'); Route::get('deleting/{id}', [CategoriesController::class, 'destroy'])->name('deleting'); }); Route::group(['prefix'=>'units/','as'=>'units.'], function() { Route::get('listing', [UnitsController::class, 'index'])->name('listing'); Route::get('adding', [UnitsController::class, 'create'])->name('adding'); Route::post('saving', [UnitsController::class, 'store'])->name('saving'); Route::get('editing/{id}', [UnitsController::class, 'edit'])->name('editing'); Route::get('showing/{id}', [UnitsController::class, 'show'])->name('showing'); Route::post('updating/{id}', [UnitsController::class, 'update'])->name('updating'); Route::get('deleting/{id}', [UnitsController::class, 'destroy'])->name('deleting'); }); Route::group(['prefix'=>'warehouses/','as'=>'warehouses.'], function() { Route::get('listing', [WarehousesController::class, 'index'])->name('listing'); Route::get('adding', [WarehousesController::class, 'create'])->name('adding'); Route::post('saving', [WarehousesController::class, 'store'])->name('saving'); Route::get('editing/{id}', [WarehousesController::class, 'edit'])->name('editing'); Route::get('showing/{id}', [WarehousesController::class, 'show'])->name('showing'); Route::post('updating/{id}', [WarehousesController::class, 'update'])->name('updating'); Route::get('deleting/{id}', [WarehousesController::class, 'destroy'])->name('deleting'); }); Route::group(['prefix'=>'inventory/','as'=>'inventory.'], function() { Route::get('listing', [InventoryController::class, 'index'])->name('listing'); }); Route::group(['prefix'=>'stock_movements/','as'=>'stock_movements.'], function() { Route::get('listing', [Stock_MovementsController::class, 'index'])->name('listing'); }); Route::group(['prefix'=>'purchases/','as'=>'purchases.'], function() { Route::get('listing', [PurchasesController::class, 'index'])->name('listing'); Route::get('adding', [PurchasesController::class, 'create'])->name('adding'); Route::post('saving', [PurchasesController::class, 'store'])->name('saving'); Route::get('editing/{id}', [PurchasesController::class, 'edit'])->name('editing'); Route::get('showing/{id}', [PurchasesController::class, 'show'])->name('showing'); Route::post('updating/{id}', [PurchasesController::class, 'update'])->name('updating'); Route::get('deleting/{id}', [PurchasesController::class, 'destroy'])->name('deleting'); //approve PO Route::post('/{id}/approve', [PurchaseController::class, 'approvePurchase']) ->name('purchases.approve'); //->middleware(['auth', 'can:approve_purchases']); Route::get('returnForm/{id}', [PurchasesController::class, 'showReturnForm'])->name('returnForm'); //->middleware('auth'); Route::post('returnProcess/{id}', [PurchasesController::class, 'processReturn']) ->name('returnProcess'); //->middleware('auth'); }); Route::group(['prefix'=>'customers/','as'=>'customers.'], function() { Route::get('listing', [CustomersController::class, 'index'])->name('listing'); Route::get('adding', [CustomersController::class, 'create'])->name('adding'); Route::post('saving', [CustomersController::class, 'store'])->name('saving'); Route::get('editing/{id}', [CustomersController::class, 'edit'])->name('editing'); Route::get('showing/{id}', [CustomersController::class, 'show'])->name('showing'); Route::post('updating/{id}', [CustomersController::class, 'update'])->name('updating'); Route::get('deleting/{id}', [CustomersController::class, 'destroy'])->name('deleting'); }); Route::group(['prefix'=>'sales/','as'=>'sales.'], function() { Route::get('listing', [SalesController::class, 'index'])->name('listing'); Route::get('adding', [SalesController::class, 'create'])->name('adding'); Route::post('saving', [SalesController::class, 'store'])->name('saving'); Route::get('editing/{id}', [SalesController::class, 'edit'])->name('editing'); Route::get('showing/{id}', [SalesController::class, 'show'])->name('showing'); Route::post('updating/{id}', [SalesController::class, 'update'])->name('updating'); Route::get('deleting/{id}', [SalesController::class, 'destroy'])->name('deleting'); Route::get('returnForm/{id}', [SalesController::class, 'showReturnForm'])->name('returnForm'); Route::post('returnProcess/{id}', [SalesController::class, 'processReturn']) ->name('returnProcess'); }); Route::group(['prefix'=>'warehouses/','as'=>'warehouses.'], function() { Route::get('listing', [WarehousesController::class, 'index'])->name('listing'); Route::get('adding', [WarehousesController::class, 'create'])->name('adding'); Route::post('saving', [WarehousesController::class, 'store'])->name('saving'); Route::get('editing/{id}', [WarehousesController::class, 'edit'])->name('editing'); Route::get('showing/{id}', [WarehousesController::class, 'show'])->name('showing'); Route::post('updating/{id}', [WarehousesController::class, 'update'])->name('updating'); Route::get('deleting/{id}', [WarehousesController::class, 'destroy'])->name('deleting'); }); Route::group(['prefix'=>'inventoryReports/','as'=>'inventoryReports.'], function() { Route::get('CurrentStockStatus', [InventoryReportsController::class, 'CurrentStockStatus'])->name('CurrentStockStatus'); Route::get('LowStockAlert', [InventoryReportsController::class, 'LowStockAlert'])->name('LowStockAlert'); Route::get('SalesSummary', [InventoryReportsController::class, 'SalesSummary'])->name('SalesSummary'); Route::get('CustomerPurchaseHistory', [InventoryReportsController::class, 'CustomerPurchaseHistory'])->name('CustomerPurchaseHistory'); Route::get('PurchaseSummary', [InventoryReportsController::class, 'PurchaseSummary'])->name('PurchaseSummary'); Route::get('ProfitNLoss', [InventoryReportsController::class, 'ProfitNLoss'])->name('ProfitNLoss'); Route::get('AccountsPayable', [InventoryReportsController::class, 'AccountsPayable'])->name('AccountsPayable'); Route::get('AccountsReceivable', [InventoryReportsController::class, 'AccountsReceivable'])->name('AccountsReceivable'); }); Route::prefix('AutoVouchingInventory')->name('AutoVouchingInventory.')->group(function () { Route::get('listing', [AutoVouchingInventoryController::class, 'index'])->name('listing'); Route::get('edit/{id}', [AutoVouchingInventoryController::class, 'edit'])->name('edit'); Route::post('update/{id}', [AutoVouchingInventoryController::class, 'update'])->name('update'); }); });
๐ค Contributing
Contributions are welcome.
- Fork the repository
- Create your feature branch
- Commit your changes
- Open a Pull Request
๐ License
This package is open-sourced software licensed under the MIT license.
๐ข Maintained By
Developed and maintained by Delickate.