first(); if (! $order) { Log::warning('QR token not found', ['token' => substr($token, 0, 8) . '...']); return response()->view('ops.order-not-found', [], 404); } // Check user authorization - must be logged in ops user // TODO: Add middleware to enforce this if (! auth()->check() || ! auth()->user()->can('access-ops')) { Log::warning('Unauthorized QR access attempt', [ 'order_uuid' => $order->uuid, 'user_id' => auth()->id(), ]); return response()->view('ops.unauthorized', [], 403); } Log::info('QR order accessed', [ 'order_uuid' => $order->uuid, 'status' => $order->status, 'user_id' => auth()->id(), ]); // Determine available actions based on order status $availableActions = $this->getAvailableActions($order); return view('ops.order-detail', [ 'order' => $order, 'availableActions' => $availableActions, 'qrUrl' => route('ops.order.show', ['token' => $order->qr_token]), ]); } /** * Confirm packing via QR form * * POST /ops/orders/{id}/pack */ public function confirmPacking(Request $request, Order $order) { // Validate input $validated = $request->validate([ 'weight' => ['required', 'numeric', 'min:0.1'], 'width' => ['required', 'numeric', 'min:1'], 'length' => ['required', 'numeric', 'min:1'], 'height' => ['required', 'numeric', 'min:1'], ]); // Ensure order is in packing state if ($order->status !== 'packing' && $order->status !== 'inspection') { return response()->json([ 'error' => 'Order cannot be packed in current state', 'current_status' => $order->status, ], 409); } // Save packing dimensions $order->update([ 'packing_width' => $validated['width'], 'packing_length' => $validated['length'], 'packing_weight' => $validated['weight'], 'packing_completed_at' => now(), 'packed_by' => auth()->id(), 'status' => 'packing', ]); Log::info('Order packed via QR', [ 'order_uuid' => $order->uuid, 'packed_by' => auth()->user()->name, 'dimensions' => "{$validated['width']}x{$validated['length']}cm, {$validated['weight']}kg", ]); // Emit event to trigger Slack notification and Trello update \App\Events\OrderPacked::dispatch($order); return response()->json([ 'success' => true, 'message' => 'Order packed successfully', 'order' => [ 'uuid' => $order->uuid, 'number' => $order->order_number, 'status' => $order->status, ], ]); } /** * Mark inspection passed via QR * * POST /ops/orders/{id}/inspection-passed */ public function markInspectionPassed(Request $request, Order $order) { if ($order->status !== 'inspection') { return response()->json([ 'error' => 'Order is not in inspection state', 'current_status' => $order->status, ], 409); } // Update status and emit event $order->update(['status' => 'packing']); Log::info('Inspection passed via QR', [ 'order_uuid' => $order->uuid, 'marked_by' => auth()->user()->name, ]); // Emit event for listeners to handle Slack/Trello updates // TODO: Create InspectionPassed event return response()->json([ 'success' => true, 'message' => 'Inspection passed', 'order' => ['uuid' => $order->uuid, 'status' => $order->status], ]); } /** * Flag inspection issue via QR * * POST /ops/orders/{id}/inspection-failed */ public function flagInspectionIssue(Request $request, Order $order) { $validated = $request->validate([ 'issue_description' => ['required', 'string', 'max:500'], ]); if ($order->status !== 'inspection') { return response()->json([ 'error' => 'Order is not in inspection state', 'current_status' => $order->status, ], 409); } // Update status and store issue $order->update([ 'status' => 'review_required', 'notes' => $validated['issue_description'], ]); Log::warning('Inspection issue flagged via QR', [ 'order_uuid' => $order->uuid, 'flagged_by' => auth()->user()->name, 'issue' => $validated['issue_description'], ]); // Emit event for listeners to alert ops // TODO: Create InspectionFailed event return response()->json([ 'success' => true, 'message' => 'Issue flagged - order moved to review', 'order' => ['uuid' => $order->uuid, 'status' => $order->status], ]); } /** * Determine which actions are available based on order status */ private function getAvailableActions(Order $order): array { $actions = []; match ($order->status) { 'inspection' => [ $actions['markInspectionPassed'] = true, $actions['flagInspectionIssue'] = true, ], 'packing' => [ $actions['confirmPacking'] = true, ], 'ready_to_ship', 'awaiting_collection', 'in_transit' => [ $actions['readOnly'] = true, ], default => [] }; return $actions; } }