delickate/inventory-module

Inventory Module for Laravel Applications

Maintainers

Package info

github.com/delickate/inventory-module

Language:CSS

pkg:composer/delickate/inventory-module

Statistics

Installs: 4

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

dev-main 2026-03-17 09:18 UTC

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.

  1. Fork the repository
  2. Create your feature branch
  3. Commit your changes
  4. Open a Pull Request

๐Ÿ“„ License

This package is open-sourced software licensed under the MIT license.

๐Ÿข Maintained By

Developed and maintained by Delickate.