Files
hub/app/Http/Controllers/Buyer/OrderController.php
Jon Leopard 7e5ea2bc10 checkpoint: marketplace and operational features complete, ready for Week 4 data migration
Summary of completed work:
- Complete buyer portal (browse, cart, checkout, orders, invoices)
- Complete seller portal (orders, manifests, fleet, picking)
- Business onboarding wizards (buyer 4-step, seller 5-step)
- Email verification and registration flows
- Notification system for buyers and sellers
- Payment term surcharges and pickup/delivery workflows
- Filament admin resources (Business, Brand, Product, Order, Invoice, User)
- 51 migrations executed successfully

Renamed Company -> Business throughout codebase for consistency.
Unified authentication flows with password reset.
Added audit trail and telescope for debugging.

Next: Week 4 Data Migration (Days 22-28)
- Product migration (883 products from cannabrands_crm)
- Company migration (81 buyer companies)
- User migration (preserve password hashes)
- Order history migration
2025-10-15 11:17:15 -07:00

172 lines
5.6 KiB
PHP

<?php
namespace App\Http\Controllers\Buyer;
use App\Http\Controllers\Controller;
use App\Models\Order;
use Illuminate\Http\Request;
class OrderController extends Controller
{
/**
* Display a listing of the user's orders.
*/
public function index()
{
$user = auth()->user();
$userBusinessIds = $user->businesses->pluck('id')->toArray();
$orders = Order::with(['items', 'business', 'location'])
->where(function ($query) use ($user, $userBusinessIds) {
$query->where('user_id', $user->id)
->orWhereIn('business_id', $userBusinessIds);
})
->latest()
->get();
$stats = [
'total' => $orders->count(),
'new' => $orders->where('status', 'new')->count(),
'accepted' => $orders->where('status', 'accepted')->count(),
'in_progress' => $orders->where('status', 'in_progress')->count(),
'delivered' => $orders->where('status', 'delivered')->count(),
];
return view('buyer.orders.index', compact('orders', 'stats'));
}
/**
* Display the specified order.
*/
public function show(Order $order)
{
// Authorization check
if (!$this->canAccessOrder($order)) {
abort(403, 'Unauthorized to view this order.');
}
$order->load(['items.product', 'business', 'location', 'user', 'invoice', 'manifest']);
return view('buyer.orders.show', compact('order'));
}
/**
* Accept an order.
*/
public function accept(Order $order)
{
if (!$this->canAccessOrder($order)) {
abort(403, 'Unauthorized to modify this order.');
}
if ($order->status !== 'new') {
return back()->with('error', 'Only new orders can be accepted.');
}
$order->accept();
return back()->with('success', "Order {$order->order_number} has been accepted.");
}
/**
* Cancel an order (buyer-initiated).
*/
public function cancel(Order $order, Request $request)
{
if (!$this->canAccessOrder($order)) {
abort(403, 'Unauthorized to modify this order.');
}
if (!$order->canBeCancelledByBuyer()) {
return back()->with('error', 'This order cannot be cancelled at this stage.');
}
$validated = $request->validate([
'reason' => 'required|string|max:1000',
]);
$order->cancelByBuyer($validated['reason']);
return back()->with('success', "Order {$order->order_number} has been cancelled.");
}
/**
* Update order fulfillment method and related information.
*/
public function updateFulfillment(Order $order, Request $request)
{
if (!$this->canAccessOrder($order)) {
abort(403, 'Unauthorized to modify this order.');
}
if (!$order->canChangeFulfillmentMethod()) {
return back()->with('error', 'Cannot change fulfillment method after manifest has been created.');
}
$validated = $request->validate([
'delivery_method' => 'required|in:delivery,pickup',
'location_id' => 'nullable|exists:businesses,id',
'pickup_driver_first_name' => 'nullable|string|max:255',
'pickup_driver_last_name' => 'nullable|string|max:255',
'pickup_driver_license' => 'nullable|string|max:255',
'pickup_driver_phone' => 'nullable|string|max:15',
'pickup_vehicle_plate' => 'nullable|string|max:255',
]);
// Update order with validated data
$order->update([
'delivery_method' => $validated['delivery_method'],
'location_id' => $validated['location_id'] ?? $order->location_id,
'pickup_driver_first_name' => $validated['pickup_driver_first_name'] ?? null,
'pickup_driver_last_name' => $validated['pickup_driver_last_name'] ?? null,
'pickup_driver_license' => $validated['pickup_driver_license'] ?? null,
'pickup_driver_phone' => $validated['pickup_driver_phone'] ?? null,
'pickup_vehicle_plate' => $validated['pickup_vehicle_plate'] ?? null,
]);
$method = $order->isPickup() ? 'pickup' : 'delivery';
return back()->with('success', "Fulfillment method updated to {$method}.");
}
/**
* Download manifest PDF for an order.
*/
public function downloadManifestPdf(Order $order)
{
if (!$this->canAccessOrder($order)) {
abort(403, 'Unauthorized to access this order.');
}
$manifest = $order->manifest;
if (!$manifest) {
return back()->with('error', 'No manifest found for this order.');
}
if (!$manifest->pdf_path || !\Storage::disk('local')->exists($manifest->pdf_path)) {
return back()->with('error', 'Manifest PDF not found.');
}
return \Storage::disk('local')->response(
$manifest->pdf_path,
"manifest-{$manifest->manifest_number}.pdf",
[
'Content-Type' => 'application/pdf',
'Content-Disposition' => 'inline; filename="manifest-' . $manifest->manifest_number . '.pdf"'
]
);
}
/**
* Check if current user can access the order.
*/
protected function canAccessOrder(Order $order): bool
{
$user = auth()->user();
$userBusinessIds = $user->businesses->pluck('id')->toArray();
return $order->user_id === $user->id ||
in_array($order->business_id, $userBusinessIds);
}
}