Files
ladill-merchant/app/Http/Controllers/Merchant/OrdersController.php
T
isaaccladandCursor f718b9cfbf Initial Ladill Merchant app with Gitea deploy pipeline.
Shop, menu, and booking storefronts with OIDC SSO, Pay checkout, and merchant.ladill.com deployment workflow.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-09 23:05:21 +00:00

101 lines
3.7 KiB
PHP

<?php
namespace App\Http\Controllers\Merchant;
use App\Http\Controllers\Controller;
use App\Models\QrBooking;
use App\Models\QrCode;
use App\Models\QrSaleOrder;
use App\Services\Merchant\MerchantSaleService;
use App\Support\Qr\QrTypeCatalog;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Validation\Rule;
use Illuminate\View\View;
class OrdersController extends Controller
{
public function __construct(private MerchantSaleService $sales) {}
public function index(Request $request): View
{
$account = ladill_account();
$search = trim((string) $request->query('q', ''));
$qrIds = $account->qrCodes()
->whereIn('type', QrTypeCatalog::storefrontTypes())
->pluck('id');
$orders = QrSaleOrder::query()
->whereIn('qr_code_id', $qrIds)
->when($search !== '', function ($query) use ($search) {
$like = '%'.$search.'%';
$query->where(function ($inner) use ($like) {
$inner->where('customer_name', 'like', $like)
->orWhere('customer_email', 'like', $like)
->orWhere('payment_reference', 'like', $like)
->orWhereHas('qrCode', fn ($qr) => $qr->where('label', 'like', $like));
});
})
->with('qrCode')
->latest('created_at')
->paginate(15, ['*'], 'orders_page')
->withQueryString();
$bookings = QrBooking::query()
->whereIn('qr_code_id', $qrIds)
->whereIn('status', [QrBooking::STATUS_CONFIRMED, QrBooking::STATUS_PENDING])
->when($search !== '', function ($query) use ($search) {
$like = '%'.$search.'%';
$query->where(function ($inner) use ($like) {
$inner->where('customer_name', 'like', $like)
->orWhere('customer_email', 'like', $like)
->orWhere('service_name', 'like', $like)
->orWhereHas('qrCode', fn ($qr) => $qr->where('label', 'like', $like));
});
})
->with('qrCode')
->latest('starts_at')
->paginate(15, ['*'], 'bookings_page')
->withQueryString();
return view('merchant.orders', [
'orders' => $orders,
'bookings' => $bookings,
'search' => $search,
]);
}
public function updateStatus(Request $request, QrSaleOrder $order): RedirectResponse
{
abort_if($order->user_id !== ladill_account()->id, 403);
abort_if($order->status !== QrSaleOrder::STATUS_PAID, 422, 'Only paid orders can be updated.');
$validated = $request->validate([
'fulfillment_status' => ['required', Rule::in(array_keys(QrSaleOrder::FULFILLMENT_STATUSES))],
]);
$order->update(['fulfillment_status' => $validated['fulfillment_status']]);
$order->load('qrCode');
$this->sales->notifyStatusUpdated($order);
return back()->with('success', 'Order status updated.');
}
public function updateBookingStatus(Request $request, QrBooking $booking): RedirectResponse
{
abort_if($booking->user_id !== ladill_account()->id, 403);
abort_if($booking->status !== QrBooking::STATUS_CONFIRMED, 422);
$validated = $request->validate([
'fulfillment_status' => ['required', Rule::in(array_keys(QrBooking::FULFILLMENT_STATUSES))],
]);
$booking->update(['fulfillment_status' => $validated['fulfillment_status']]);
$booking->load('qrCode');
$this->sales->notifyBookingStatusUpdated($booking);
return back()->with('success', 'Booking status updated.');
}
}