Documents all files that need updates due to Product.quantity_on_hand removal. Categorized by priority: - 🔴 Critical: Controllers that will break - 🟡 Medium: UX-impacting Filament resources - 🟢 Low: Display-only views Includes: - New inventory workflow documentation - BackorderService and StockNotificationService usage - Migration safety/rollback procedures - Testing strategy - Status tracking checklist Identified 11 files needing updates across controllers, views, and Filament.
8.4 KiB
Inventory Refactoring Required
Status: Work in Progress
Branch: feature/pr-53-integration
Migration: 2025_11_16_155549_cleanup_products_table_remove_inventory_and_enhance_categories.php
Overview
The PR #53 merge removes inventory tracking fields from the products table and moves them to a dedicated inventory_items table. This provides better warehouse management, location tracking, and scalability.
Fields Removed from Products Table
- quantity_on_hand
- quantity_allocated
- reorder_point
- low_stock_threshold
- low_stock_alert_enabled
- inventory_manage_pct
- decreasing_qty_threshold
- decreasing_qty_action
- increasing_qty_threshold
- increasing_qty_action
New System
Inventory is now tracked via the InventoryItem model which provides:
- Multi-location tracking (warehouse, bin location)
- Lot/batch tracking
- Movement history (receipts, transfers, sales, waste)
- Automated alerts (low stock, expiration)
- FIFO/LIFO costing
- Quarantine management
Files Requiring Updates
🔴 Critical (Breaks Functionality)
Controllers
-
app/Http/Controllers/Seller/InvoiceController.php (Lines 67, 69, 100)
- Currently accesses
$product->quantity_on_hand - Fix: Query InventoryItem instead
// OLD 'quantity_on_hand' => $product->quantity_on_hand ?? 0, // NEW 'quantity_on_hand' => $product->inventoryItems()->sum('quantity_on_hand'), - Currently accesses
-
app/Console/Commands/CreateTestInvoiceForApproval.php (Line 55)
- Queries
Product::where('quantity_on_hand', '>', 10) - Fix: Join with inventory_items or use different filter
- Queries
Views - Critical for Display
-
resources/views/seller/products/edit.blade.php (Line 787)
- Form input for
quantity_on_hand - Decision: Remove this field OR redirect to inventory management
- Form input for
-
resources/views/seller/products/partials/active-products.blade.php (Line 80)
- Displays
$product->quantity_on_hand - Fix: Show "Manage Inventory" link instead OR query inventory items
- Displays
-
resources/views/seller/products/bom/index.blade.php (Lines 118, 236)
- Shows component quantity_on_hand (Components still have this field - OK)
- Status: ✅ No change needed (Components keep their fields)
🟡 Medium Priority (Affects UX)
Filament Admin Resources
-
app/Filament/Resources/ProductResource/Tables/ProductsTable.php (Line 91)
- Table column showing
quantity_on_hand - Fix: Replace with link to inventory items OR remove column
- Table column showing
-
app/Filament/Resources/ProductResource/Schemas/ProductInfolist.php (Line 48)
- Info display showing
quantity_on_hand - Fix: Show inventory summary from related items
- Info display showing
-
app/Filament/Resources/ProductResource/Schemas/ProductForm.php (Line 182)
- Form field for
quantity_on_hand - Fix: Remove field, add note about inventory management
- Form field for
-
app/Filament/Resources/ProductResource/RelationManagers/VarietiesRelationManager.php (Lines 73, 117)
- Product varieties showing
quantity_on_hand - Fix: Remove or link to inventory module
- Product varieties showing
🟢 Low Priority (Display Only)
View Templates
-
resources/views/seller/products/edit.blade.php (Line 633)
- Shows variety stock:
{{ $variety->quantity_on_hand }} - Fix: Query inventory items or remove
- Shows variety stock:
-
resources/views/seller/dashboard.blade.php (Line 525)
- Shows
{{ number_format($component->quantity_on_hand) }} - Status: ✅ Components still have this field
- Shows
Recommended Approach
Phase 1: Remove Product Inventory UI
-
Remove form fields for entering product quantities
resources/views/seller/products/edit.blade.php- remove quantity inputapp/Filament/Resources/ProductResource/Schemas/ProductForm.php- remove field
-
Add "Manage Inventory" buttons linking to inventory module
@if($business->has_inventory) <a href="{{ route('seller.business.inventory.items.create', ['business' => $business, 'product_id' => $product->id]) }}" class="btn btn-primary"> Manage Inventory </a> @else <p class="text-sm text-base-content/60"> Enable Inventory Module to track stock levels </p> @endif
Phase 2: Update Display Logic
- In product tables/lists, show inventory status:
// Controller $products = Product::with(['inventoryItems' => function($q) { $q->selectRaw('product_id, SUM(quantity_on_hand) as total_qty') ->groupBy('product_id'); }])->get(); // View @if($product->inventoryItems->isNotEmpty()) <span class="badge badge-success"> {{ number_format($product->inventoryItems->sum('total_qty')) }} in stock </span> @else <span class="badge badge-warning">No inventory tracked</span> @endif
Phase 3: Update Controllers
-
InvoiceController - Query inventory items
foreach ($invoice->items as $item) { $product = $item->product; $totalQty = $product->inventoryItems()->sum('quantity_on_hand'); $allocatedQty = $product->inventoryItems()->sum('quantity_allocated'); $item->setAttribute('quantity_available', max(0, $totalQty - $allocatedQty)); } -
Test Invoice Command - Use different product filter
// Instead of filtering by quantity_on_hand $products = Product::whereHas('inventoryItems', function($q) { $q->where('quantity_on_hand', '>', 10); })->where('is_active', true)->take(5)->get();
New Inventory Workflow
For Sellers (Adding Stock)
Old Way:
- Edit product
- Update "Quantity on Hand" field
- Save
New Way:
- Navigate to Inventory module
- Click "Add Inventory"
- Select product, location, quantity, lot number
- Creates InventoryItem record
- Optionally record InventoryMovement (receipt)
For System (Checking Availability)
Old Way:
if ($product->quantity_on_hand < $requestedQty) {
return 'Out of stock';
}
New Way:
$availableQty = $product->inventoryItems()
->where('business_id', $sellerBusiness->id)
->sum(DB::raw('quantity_on_hand - quantity_allocated'));
if ($availableQty < $requestedQty) {
// Offer backorder via BackorderService
return BackorderService::createBackorder($buyer, $product, $requestedQty);
}
Services to Use
BackorderService
use App\Services\BackorderService;
$backorderService = new BackorderService();
$backorder = $backorderService->createBackorder(
user: $buyer,
buyerBusiness: $buyerBusiness,
product: $product,
quantity: $requestedQty,
notes: 'Auto-created from cart'
);
StockNotificationService
use App\Services\StockNotificationService;
$notificationService = new StockNotificationService();
$notificationService->subscribe(
user: $buyer,
business: $buyerBusiness,
product: $product
);
Testing Strategy
- Before Migration: Take DB snapshot
- Run Migration: Apply products table cleanup
- Check Errors: Browse product pages, try to edit products
- Update Files: Fix each broken reference
- Test Flows:
- Add product
- Add inventory via inventory module
- Place order
- Check marketplace display
Breaking Changes Summary
| What Broke | Why | Fix |
|---|---|---|
| Product edit form | No quantity_on_hand field | Remove field, link to inventory module |
| Product tables | No quantity to display | Query inventory items OR show "Manage" link |
| Invoice generation | Accesses removed field | Query inventory items |
| Filament admin | Form fields removed | Update schemas |
| Test command | Filters by quantity_on_hand | Use whereHas inventoryItems |
Migration Safety
The migration has a down() method that restores the fields, so it's reversible:
# If things break badly
php artisan migrate:rollback --step=1
# This will restore:
# - quantity_on_hand
# - quantity_allocated
# - reorder_point
# etc.
Status Tracking
- InvoiceController updated
- CreateTestInvoiceForApproval updated
- products/edit.blade.php updated
- active-products.blade.php updated
- Filament ProductsTable updated
- Filament ProductInfolist updated
- Filament ProductForm updated
- Filament VarietiesRelationManager updated
- Dashboard views updated
- Tests updated
- Migration tested
- Rollback tested
Next Steps: Run migration on local DB and see what actually breaks, then fix systematically.