ldc-boutique-cnc-sable/app/Http/Controllers/Bo/OrdersController.php
2026-10-27 09:58:12 +01:00

159 lines
4.7 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Http\Controllers\Bo;
use App\Http\Controllers\Controller;
use App\Http\Requests\Bo\Orders\IndexOrdersRequest;
use App\Models\Customer;
use App\Models\Order;
use App\Services\CrmService;
use App\Services\DataTableService;
use Domain\Enums\OrderStatus;
use Domain\Models\ValueObjects\CrmCustomer;
use Domain\Services\OrderService;
use Illuminate\Contracts\Database\Query\Builder;
use Illuminate\Contracts\View\View;
use Illuminate\Http\RedirectResponse;
use Illuminate\Support\Facades\Date;
class OrdersController extends Controller
{
public function __construct(
private readonly CrmService $crmService,
) {
}
public function index(IndexOrdersRequest $request, DataTableService $dataTable): View
{
$this->authorize('viewAny', Order::class);
$query = Order::query()->with(['shop']);
$search = $request->string('search')->value();
$status = $request->getStatus();
$startDate = $request->getOrderDateStart();
$endDate = $request->getOrderDateEnd();
$orderPickupStart = $request->getOrderPickupStart();
$orderPickupEnd = $request->getOrderPickupEnd();
if ($search) {
$dataTable->searchQuery(
Order::class,
$query,
$search,
fn ($q) => $q->orWhereHas(
'shop',
fn ($q) => $q->whereLike('name', "%{$search}%")
),
'reference',
);
}
// * Date Order filter
if ($startDate) {
if ($endDate) {
$query->whereCreatedAtBetween($startDate, $endDate);
} else {
$query->whereCreatedAtBetween($startDate, $startDate);
}
}
// * Date Pickup filter
if ($orderPickupStart) {
if ($orderPickupEnd) {
$query->whereBetween('pickup_day', [
$orderPickupStart,
$orderPickupEnd,
]);
} else {
$query->where('pickup_day', $orderPickupStart);
}
}
if ($request->isNotFilled('status')) {
request()->session()->forget('orders.filter.status');
}
if ($request->has('status')) {
request()->session()->forget('orders.filter.status');
request()->session()->put(
'orders.filter.status',
$status
);
$query->where('status', $status);
}
$dataTable->sortQuery(Order::class, $query);
$orders = $dataTable->paginateQuery($query);
$searchFields = str(collect([
trans('validation.custom.attributes.reference'),
trans_choice('models.classes.shops', 1),
])->implode(', '))->title()->value();
$orderStatusList = OrderStatus::cases();
return view('bo.orders.index', compact(
'orders',
'searchFields',
'orderStatusList'
));
}
public function today(DataTableService $dataTable): View
{
$this->authorize('viewAnyToday', Order::class);
$query = Order::query()->with(['shop']);
$query->where('pickup_day', Date::now()->toDateString());
$dataTable->sortQuery(Order::class, $query);
$orders = $dataTable->paginateQuery($query);
return view('bo.orders.index-today', compact('orders'));
}
public function show(Order $order): View
{
$this->authorize('view', $order);
$order->load(['lines', 'shop']);
$shop = $order->shop;
$employee = $order->employee;
$linkedCustomer = Customer::query()
->whereHas('employee', fn (Builder $q) => $q->where(
'matricule',
$employee->matricule->value
))->first();
$crmCustomerResult = $linkedCustomer !== null
? $this->crmService->getCustomerFromHashCode($linkedCustomer->hashcode)
: null;
$crmCustomer = $crmCustomerResult instanceof CrmCustomer ? $crmCustomerResult : null;
return view('bo.orders.view', compact(
'order',
'shop',
'employee',
'crmCustomer',
));
}
public function cancel(Order $order, OrderService $orderService): RedirectResponse
{
$this->authorize('cancel', $order);
try {
$orderService->cancelOrder($order->getId());
} catch (\Exception) {
return back()->with('error', trans('Action failed'));
}
return back()->with('warning', trans('Order cancelled'));
}
}