Files
hub/app/Http/Controllers/Seller/FulfillmentWorkOrderController.php
Jon Leopard 5c1863218f fix: optimize test suite performance with DatabaseTransactions
This commit completes the PR #53 integration by optimizing the test suite:

Performance Improvements:
- Migrated 25 test files from RefreshDatabase to DatabaseTransactions
- Tests now run in 12.69s parallel (previously 30s+)
- Increased PostgreSQL max_locks_per_transaction to 256 for parallel testing

Test Infrastructure Changes:
- Disabled broadcasting in tests (set to null) to avoid Reverb connectivity issues
- Reverted 5 integration tests to RefreshDatabase (CheckoutFlowTest + 4 Service tests)
  that require full schema recreation due to complex fixtures

PR #53 Integration Fixes:
- Added Product.inStock() scope for inventory queries
- Fixed ProductFactory to create InventoryItem records instead of using removed columns
- Added Department.products() relationship
- Fixed FulfillmentWorkOrderController view variables
- Fixed orders migration location_id foreign key constraint
- Created seller-layout component wrapper

All 146 tests now pass with optimal performance.
2025-11-17 20:52:50 -07:00

123 lines
4.3 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Http\Controllers\Seller;
use App\Http\Controllers\Controller;
use App\Models\Department;
use App\Models\FulfillmentWorkOrder;
use App\Models\User;
use App\Services\FulfillmentWorkOrderService;
use Illuminate\Http\Request;
use Illuminate\View\View;
class FulfillmentWorkOrderController extends Controller
{
public function __construct(
private FulfillmentWorkOrderService $workOrderService
) {
//
}
/**
* List work orders for seller's business
*/
public function index(Request $request): View
{
$business = $request->user()->businesses()->first();
$workOrders = FulfillmentWorkOrder::whereHas('order', function ($query) use ($business) {
$query->where('seller_business_id', $business->id);
})
->with(['order', 'pickingTickets'])
->orderBy('created_at', 'desc')
->paginate(20);
// Calculate stats for the view
$stats = [
'total' => FulfillmentWorkOrder::whereHas('order', fn ($q) => $q->where('seller_business_id', $business->id))->count(),
'pending' => FulfillmentWorkOrder::whereHas('order', fn ($q) => $q->where('seller_business_id', $business->id))->where('status', 'pending')->count(),
'in_progress' => FulfillmentWorkOrder::whereHas('order', fn ($q) => $q->where('seller_business_id', $business->id))->where('status', 'in_progress')->count(),
'overdue' => 0, // FulfillmentWorkOrder doesn't have overdue scope yet
'due_soon' => 0, // FulfillmentWorkOrder doesn't have due_soon scope yet
];
// Get departments for filtering
$departments = Department::where('business_id', $business->id)->active()->get();
// Get users for filtering
$users = User::whereHas('businesses', fn ($q) => $q->where('businesses.id', $business->id))->get();
return view('seller.work-orders.index', compact('workOrders', 'business', 'stats', 'departments', 'users'));
}
/**
* Show work order details with picking tickets
*/
public function show(Request $request, FulfillmentWorkOrder $workOrder): View
{
$business = $request->user()->businesses()->first();
// Ensure work order belongs to seller's business
if ($workOrder->order->seller_business_id !== $business->id) {
abort(403, 'Unauthorized access to work order');
}
$workOrder->load(['order.items.product', 'pickingTickets.department', 'pickingTickets.items']);
return view('seller.work-orders.show', compact('workOrder', 'business'));
}
/**
* Assign picker to a picking ticket
*/
public function assignPicker(Request $request, FulfillmentWorkOrder $workOrder)
{
$validated = $request->validate([
'ticket_id' => 'required|exists:picking_tickets,id',
'picker_id' => 'required|exists:users,id',
]);
$business = $request->user()->businesses()->first();
if ($workOrder->order->seller_business_id !== $business->id) {
abort(403);
}
$ticket = $workOrder->pickingTickets()->findOrFail($validated['ticket_id']);
$picker = \App\Models\User::findOrFail($validated['picker_id']);
$this->workOrderService->assignPicker($ticket, $picker);
return redirect()
->route('seller.work-orders.show', $workOrder)
->with('success', 'Picker assigned successfully');
}
/**
* Start picking the order
*/
public function startPicking(Request $request, FulfillmentWorkOrder $workOrder)
{
$business = $request->user()->businesses()->first();
// Verify authorization
if ($workOrder->order->seller_business_id !== $business->id) {
abort(403, 'Unauthorized access to work order');
}
try {
$workOrder->order->startPicking();
return redirect()
->route('seller.business.orders.show', [$business->slug, $workOrder->order])
->with('success', 'Order started! You can now begin picking items.');
} catch (\Exception $e) {
return redirect()
->route('seller.business.orders.show', [$business->slug, $workOrder->order])
->with('error', 'Could not start order: '.$e->getMessage());
}
}
}