Place Service Developer Guide
Service layer for managing warehouse inventory operations with transaction safety and automatic logging.
Quick Start
php
use Obelaw\Warehouse\Facades\Warehouse;
use Obelaw\Warehouse\Models\Place\Inventory;
use Obelaw\Warehouse\Enums\PlaceItemType;
$inventory = Inventory::find(1);
$place = Warehouse::place($inventory);
// Add item
$item = $place->addItem($sourceModel, 'SKU-123', type: PlaceItemType::STORABLE);
// Check availability
$available = $place->getAvailableQuantity('SKU-123');
// Process item (IN → PENDING → OUT)
$place->prepareItem('SKU-123');
$place->deductItem('SKU-123');Features
- Transaction-safe operations
- Auto-generated unique serial numbers
- Status management (IN → PENDING → OUT)
- Real-time quantity tracking
- Comprehensive validation
Setup
php
use Obelaw\Warehouse\Facades\Warehouse;
use Obelaw\Warehouse\Models\Place\Inventory;
use Obelaw\Warehouse\Enums\{PlaceItemType, PlaceItemStatus};Common Patterns
Basic Inventory Flow
php
$place = Warehouse::place($inventory);
// 1. Receive items
$item = $place->addItem($purchaseOrder, 'SKU-123');
// 2. Check stock
if ($place->hasAvailableQuantity('SKU-123', 1)) {
// 3. Prepare for shipment
$place->prepareItem('SKU-123');
// 4. Ship item
$place->deductItem('SKU-123');
}Bulk Operations
php
// Check multiple SKUs
$requirements = ['SKU-A' => 5, 'SKU-B' => 10];
foreach ($requirements as $sku => $qty) {
if (!$place->hasAvailableQuantity($sku, $qty)) {
throw new Exception("Insufficient stock for {$sku}");
}
}
// Process all items
foreach ($requirements as $sku => $qty) {
for ($i = 0; $i < $qty; $i++) {
$place->prepareItem($sku);
}
}Custom Serial Numbers
php
// Auto-generated serial
$item = $place->addItem($source, 'SKU-123');
// Custom serial
$item = $place->addItem($source, 'SKU-123', 'BATCH-2025-001');Error Handling
php
try {
$item = $place->addItem($source, $sku);
} catch (InvalidArgumentException $e) {
// Validation errors (empty SKU, invalid place, etc.)
} catch (ModelNotFoundException $e) {
// Product or item not found
} catch (Exception $e) {
// Database errors, constraint violations
}Development Tips
Transaction Safety
All operations are automatically wrapped in database transactions. For complex workflows, use explicit transactions:
php
DB::transaction(function () use ($place, $orderItems) {
foreach ($orderItems as $item) {
$place->prepareItem($item['sku']);
}
// Update order status, etc.
});Performance Considerations
php
// ✅ Batch check availability
$skus = ['SKU-A', 'SKU-B', 'SKU-C'];
$available = collect($skus)->mapWithKeys(fn($sku) => [
$sku => $place->getAvailableQuantity($sku)
]);
// ❌ Avoid multiple single checks in loops
foreach ($skus as $sku) {
$qty = $place->getAvailableQuantity($sku); // N+1 queries
}Status Filtering
php
use Obelaw\Warehouse\Enums\PlaceItemStatus;
// Get items by status
$inStock = $place->getItemsBySku('SKU-123', PlaceItemStatus::IN);
$pending = $place->getItemsBySku('SKU-123', PlaceItemStatus::PENDING);
$shipped = $place->getItemsBySku('SKU-123', PlaceItemStatus::OUT);
// Get all items
$allItems = $place->getItemsBySku('SKU-123');Testing
php
// Test helpers
public function test_can_add_and_process_item()
{
$inventory = Inventory::factory()->create();
$place = Warehouse::place($inventory);
$source = PurchaseOrder::factory()->create();
// Add item
$item = $place->addItem($source, 'TEST-SKU');
$this->assertEquals(PlaceItemStatus::IN, $item->status);
// Process item
$place->prepareItem('TEST-SKU');
$place->deductItem('TEST-SKU');
$this->assertEquals(0, $place->getAvailableQuantity('TEST-SKU'));
}API Reference
| Method | Purpose | Returns |
|---|---|---|
addItem($source, $sku, $serial?, $type?) | Add new item | PlaceItem |
prepareItem($sku) | IN → PENDING | PlaceItem |
deductItem($sku) | PENDING → OUT | PlaceItem |
getAvailableQuantity($sku, $status?) | Get quantity | int |
hasAvailableQuantity($sku, $qty, $status?) | Check availability | bool |
getItemsBySku($sku, $status?) | Get items | Collection |
generateSerialNumber($digits?) | Generate serial | string |
Exceptions
InvalidArgumentException- Invalid inputsModelNotFoundException- Product/item not foundException- Database errors
Constants
php
PlaceService::DEFAULT_SERIAL_DIGITS = 16;
PlaceService::MIN_SERIAL_DIGITS = 8;
PlaceService::MAX_SERIAL_DIGITS = 32;