2022-11-23 13:00:38 +01:00
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
namespace App\Http\Controllers\Fo;
|
|
|
|
|
|
2022-12-19 16:20:00 +01:00
|
|
|
use App\Enums\DeliveryMode\DeliveryModeEnum;
|
2022-12-20 11:32:06 +01:00
|
|
|
use App\Enums\GeneralConfigType;
|
2022-12-05 17:36:24 +01:00
|
|
|
use App\Enums\Order\DeliveryStatus;
|
2022-11-30 17:03:43 +01:00
|
|
|
use App\Enums\Order\OrderProcess;
|
2022-12-05 17:36:24 +01:00
|
|
|
use App\Enums\Order\PaymentStatus;
|
|
|
|
|
use App\Enums\Order\ValidationStatus;
|
2022-11-23 13:00:38 +01:00
|
|
|
use App\Http\Controllers\Controller;
|
2022-12-19 16:20:00 +01:00
|
|
|
use App\Http\Requests\Fo\Orders\CheckoutRequest;
|
|
|
|
|
use App\Http\Requests\Fo\Orders\SetOrderTimeSlotRequest;
|
|
|
|
|
use App\Http\Requests\Fo\Orders\ShippingFormRequest;
|
2022-12-05 17:36:24 +01:00
|
|
|
use App\Http\Requests\Fo\Orders\ShippingModeFormRequest;
|
2022-12-19 16:20:00 +01:00
|
|
|
use App\Http\Resources\ShopResource;
|
2022-12-20 11:32:06 +01:00
|
|
|
use App\Mail\NewOrderIncome;
|
2022-12-19 16:20:00 +01:00
|
|
|
use App\Models\Customer;
|
2022-12-05 17:36:24 +01:00
|
|
|
use App\Models\DeliveryMode;
|
2022-12-20 11:32:06 +01:00
|
|
|
use App\Models\GeneralConfig;
|
2022-11-23 13:00:38 +01:00
|
|
|
use App\Models\Order;
|
2022-12-19 16:20:00 +01:00
|
|
|
use App\Models\Shop;
|
|
|
|
|
use App\Models\Timeslot;
|
2023-02-08 16:49:28 +01:00
|
|
|
use App\Notifications\Order\OrderCreated;
|
2022-11-23 13:00:38 +01:00
|
|
|
use Carbon\Carbon;
|
2022-12-19 16:20:00 +01:00
|
|
|
use Illuminate\Support\Facades\DB;
|
2022-12-20 11:32:06 +01:00
|
|
|
use Illuminate\Support\Facades\Mail;
|
2022-11-30 17:03:43 +01:00
|
|
|
use Illuminate\Support\Facades\Session;
|
2023-02-15 17:51:00 +01:00
|
|
|
use Illuminate\Support\Facades\View;
|
2022-12-19 16:20:00 +01:00
|
|
|
use Illuminate\Support\Str;
|
2022-11-30 17:03:43 +01:00
|
|
|
use Illuminate\Validation\ValidationException;
|
2022-12-20 16:52:44 +01:00
|
|
|
use LDC\LDCCRM\Enums\Country;
|
2022-11-23 13:00:38 +01:00
|
|
|
|
|
|
|
|
class OrderController extends Controller
|
|
|
|
|
{
|
2022-12-02 10:37:01 +01:00
|
|
|
// * --- TUNNEL DE COMMANDE ---
|
2022-11-23 13:00:38 +01:00
|
|
|
/**
|
|
|
|
|
* Récapitualtif du panier
|
|
|
|
|
*
|
2022-12-19 16:20:00 +01:00
|
|
|
* * --- 1 ---
|
|
|
|
|
*
|
2022-11-23 13:00:38 +01:00
|
|
|
* @return \Illuminate\Contracts\View\View
|
|
|
|
|
*/
|
|
|
|
|
public function basketRecap()
|
|
|
|
|
{
|
2022-12-20 11:32:06 +01:00
|
|
|
$this->assertDoesNotHaveEmptyBasket();
|
|
|
|
|
$this->assertBasketDidNotChange();
|
2022-12-02 14:55:16 +01:00
|
|
|
// * On peut passer commande ?
|
|
|
|
|
$this->authorize('orderThings', Order::class);
|
2022-11-30 17:03:43 +01:00
|
|
|
$this->setOrderProcessStep(OrderProcess::reviewBasket());
|
|
|
|
|
|
2022-11-23 15:48:07 +01:00
|
|
|
/** @var \Gloudemans\Shoppingcart\Cart */
|
2022-11-30 16:36:27 +01:00
|
|
|
$basket = app('basket');
|
|
|
|
|
$messages = [];
|
|
|
|
|
|
|
|
|
|
$basket = $this->filterBasketKeepOnlyOrderableItems($basket, $messages);
|
|
|
|
|
|
|
|
|
|
if (!empty($messages)) {
|
|
|
|
|
Session::flash('warning', \collect($messages)->implode(",\n"));
|
|
|
|
|
}
|
2022-11-28 16:56:39 +01:00
|
|
|
|
2022-11-29 15:47:46 +01:00
|
|
|
$basketItems = $this->basketToList($basket);
|
2022-11-23 13:00:38 +01:00
|
|
|
|
2023-01-30 17:46:30 +01:00
|
|
|
return view('theme::pages.order-tunnel.basket-recap', compact(
|
2022-11-29 15:47:46 +01:00
|
|
|
'basket',
|
|
|
|
|
'basketItems'
|
|
|
|
|
));
|
2022-11-23 13:00:38 +01:00
|
|
|
}
|
|
|
|
|
|
2022-12-02 10:37:01 +01:00
|
|
|
/**
|
2022-12-05 17:36:24 +01:00
|
|
|
* Select shipping Mode And create Session Order
|
2022-12-02 10:37:01 +01:00
|
|
|
*
|
2022-12-19 16:20:00 +01:00
|
|
|
* * --- 2 ---
|
|
|
|
|
*
|
2022-12-02 10:37:01 +01:00
|
|
|
* @return \Illuminate\Contracts\View\View
|
|
|
|
|
*/
|
|
|
|
|
public function shippingMode()
|
|
|
|
|
{
|
2022-12-20 11:32:06 +01:00
|
|
|
$this->assertDoesNotHaveEmptyBasket();
|
2022-12-19 16:20:00 +01:00
|
|
|
$this->assertBasketDidNotChange();
|
2022-12-02 10:37:01 +01:00
|
|
|
$this->setOrderProcessStep(OrderProcess::shippingMethod(), OrderProcess::reviewBasket());
|
|
|
|
|
|
2022-12-02 14:55:16 +01:00
|
|
|
// * CREATE ORDER
|
|
|
|
|
|
2022-12-05 17:36:24 +01:00
|
|
|
/** @var \App\Models\Customer $customer */
|
|
|
|
|
$customer = auth('frontend')->user();
|
|
|
|
|
|
|
|
|
|
/** @var \Gloudemans\Shoppingcart\Cart */
|
|
|
|
|
$basket = app('basket');
|
|
|
|
|
|
|
|
|
|
/** @var \App\Models\Order|null $order */
|
|
|
|
|
$order = Order::getCurrentOrder();
|
|
|
|
|
|
|
|
|
|
// * If there was a previous order that was not ended use the ID.
|
|
|
|
|
/** @var \App\Models\Order */
|
|
|
|
|
$order = $order ?? new Order();
|
2022-12-20 11:32:06 +01:00
|
|
|
$order->mail_sent = false;
|
2022-12-05 17:36:24 +01:00
|
|
|
$order->delivery_status = DeliveryStatus::pending();
|
|
|
|
|
$order->payment_status = PaymentStatus::pending();
|
|
|
|
|
$order->validation_status = ValidationStatus::pending();
|
|
|
|
|
$order->assignBasket($basket);
|
|
|
|
|
$order->customer()->associate($customer);
|
|
|
|
|
|
|
|
|
|
// * Save Session Order
|
|
|
|
|
Session::put('currentOrder', $order);
|
|
|
|
|
|
2022-12-02 14:55:16 +01:00
|
|
|
/** @var \Illuminate\Database\Eloquent\Collection<\App\Models\DeliveryMode> */
|
2022-12-05 17:36:24 +01:00
|
|
|
$deliveryModes = app('DeliveryModesGlobal');
|
|
|
|
|
|
2023-01-30 17:46:30 +01:00
|
|
|
return view('theme::pages.order-tunnel.shipping-mode', \compact('deliveryModes'));
|
2022-12-05 17:36:24 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Save shipping Mode
|
|
|
|
|
*
|
2022-12-19 16:20:00 +01:00
|
|
|
* * --- 2 ---
|
|
|
|
|
*
|
2022-12-05 17:36:24 +01:00
|
|
|
* @param \App\Http\Requests\Fo\Orders\ShippingModeFormRequest $request
|
|
|
|
|
* @return \Illuminate\Contracts\View\View|\Illuminate\Contracts\View\Factory
|
|
|
|
|
*/
|
|
|
|
|
public function shippingModeSubmit(ShippingModeFormRequest $request)
|
|
|
|
|
{
|
2022-12-20 11:32:06 +01:00
|
|
|
$this->assertDoesNotHaveEmptyBasket();
|
2022-12-19 16:20:00 +01:00
|
|
|
$this->assertBasketDidNotChange();
|
2022-12-20 11:32:06 +01:00
|
|
|
$this->assertDoesHaveCurrentOrder();
|
2022-12-19 16:20:00 +01:00
|
|
|
$this->setOrderProcessStep(OrderProcess::shippingMethod(), OrderProcess::reviewBasket());
|
2022-12-05 17:36:24 +01:00
|
|
|
|
|
|
|
|
/** @var \App\Models\DeliveryMode $mode */
|
|
|
|
|
if (!($mode = DeliveryMode::availables()->whereId($request->mode)->first())) {
|
|
|
|
|
$e = new \RuntimeException('Mode de livraison non disponible', 1);
|
|
|
|
|
report($e);
|
|
|
|
|
Session::flash('error', trans('Mode de livraison non disponible'));
|
|
|
|
|
return \back()->withException($e);
|
|
|
|
|
}
|
|
|
|
|
|
2023-02-15 17:51:00 +01:00
|
|
|
$this->allowTimeSlotSelect();
|
|
|
|
|
|
2022-12-05 17:36:24 +01:00
|
|
|
/** @var \App\Models\Order $order */
|
|
|
|
|
$order = Order::getCurrentOrder();
|
|
|
|
|
|
|
|
|
|
$order->deliveryMode()->associate($mode);
|
|
|
|
|
|
|
|
|
|
Session::put('currentOrder', $order);
|
2022-12-02 10:37:01 +01:00
|
|
|
|
2022-12-19 16:20:00 +01:00
|
|
|
return \response()->redirectToRoute('order-tunnel.shipping');
|
2022-12-02 10:37:01 +01:00
|
|
|
}
|
|
|
|
|
|
2022-12-19 16:20:00 +01:00
|
|
|
/**
|
|
|
|
|
* Shipping informations
|
|
|
|
|
*
|
|
|
|
|
* * --- 3 ---
|
|
|
|
|
*
|
|
|
|
|
* ! Pour - Click and collect
|
|
|
|
|
*
|
|
|
|
|
* @return \Illuminate\Contracts\View\View|\Illuminate\Contracts\View\Factory
|
|
|
|
|
* @throws \RuntimeException If delivery mode is unhandled.
|
|
|
|
|
*/
|
|
|
|
|
public function shipping()
|
|
|
|
|
{
|
2022-12-20 11:32:06 +01:00
|
|
|
$this->assertDoesNotHaveEmptyBasket();
|
2022-12-19 16:20:00 +01:00
|
|
|
$this->assertBasketDidNotChange();
|
|
|
|
|
$this->assertDoesHaveCurrentOrder();
|
|
|
|
|
$this->setOrderProcessStep(OrderProcess::shippment(), OrderProcess::shippingMethod());
|
|
|
|
|
|
|
|
|
|
/** @var \App\Models\Order $order */
|
|
|
|
|
$order = Order::getCurrentOrder();
|
|
|
|
|
|
|
|
|
|
// * Switch Delivery modes
|
|
|
|
|
// * Pour afficher formulaire qui devra retourner une adresse 'shipping'
|
|
|
|
|
/**
|
|
|
|
|
* * Switch Delivery modes
|
|
|
|
|
* - Pour afficher formulaire qui devra retourner une adresse 'shipping'.
|
|
|
|
|
* - Qui devra fournir un timeslot dans le cas de clickAndCollect.
|
|
|
|
|
*/
|
|
|
|
|
/** @var \App\Enums\DeliveryMode\DeliveryModeEnum|null */
|
|
|
|
|
$delivery_mode = \optional($order->deliveryMode)->mode;
|
|
|
|
|
switch ($delivery_mode) {
|
|
|
|
|
case DeliveryModeEnum::inShop():
|
|
|
|
|
// * 1 Select timeslot if not already done.
|
|
|
|
|
if (!$order->timeslot()->first() or !Session::get('deliveryModePickSlot')) {
|
|
|
|
|
$shops = Shop::all()->map(function (Shop $shop) {
|
|
|
|
|
return new ShopResource($shop);
|
|
|
|
|
});
|
2023-02-15 17:51:00 +01:00
|
|
|
$this->allowTimeSlotSelect(true);
|
|
|
|
|
View::share('mustSelectTimeSlot', true);
|
2023-01-30 17:46:30 +01:00
|
|
|
return \view('theme::pages.order-tunnel.pick-slot', \compact('order', 'shops'));
|
2022-12-19 16:20:00 +01:00
|
|
|
}
|
2023-01-30 17:46:30 +01:00
|
|
|
return \view('theme::pages.order-tunnel.shipping', \compact('order'));
|
2022-12-19 16:20:00 +01:00
|
|
|
default:
|
|
|
|
|
throw new \RuntimeException('Unhandled delivery mode ');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
throw new \RuntimeException('This should never happen');
|
|
|
|
|
}
|
2022-12-02 10:37:01 +01:00
|
|
|
|
2022-11-23 13:00:38 +01:00
|
|
|
/**
|
2022-12-19 16:20:00 +01:00
|
|
|
* Save and validate timeslot
|
|
|
|
|
*
|
|
|
|
|
* * --- 3 ---
|
2022-11-23 13:00:38 +01:00
|
|
|
*
|
2022-12-19 16:20:00 +01:00
|
|
|
* @param \App\Http\Requests\Fo\Orders\SetOrderTimeSlotRequest $request
|
2022-11-23 13:00:38 +01:00
|
|
|
* @return \Illuminate\Http\RedirectResponse
|
2022-12-19 16:20:00 +01:00
|
|
|
* @throws \Illuminate\Validation\ValidationException If Creneau is not available anomore.
|
2022-11-23 13:00:38 +01:00
|
|
|
*/
|
2022-12-19 16:20:00 +01:00
|
|
|
public function validateSelectedTimeSlot(SetOrderTimeSlotRequest $request)
|
2022-11-23 13:00:38 +01:00
|
|
|
{
|
2022-12-20 11:32:06 +01:00
|
|
|
$this->assertDoesNotHaveEmptyBasket();
|
2022-12-19 16:20:00 +01:00
|
|
|
$this->assertBasketDidNotChange();
|
|
|
|
|
$this->assertDoesHaveCurrentOrder();
|
|
|
|
|
$this->setOrderProcessStep(OrderProcess::shippment(), OrderProcess::shippingMethod());
|
|
|
|
|
/** @var \App\Models\Shop */
|
|
|
|
|
$shop = Shop::query()->where('id', $request->shop_id)->firstOrFail();
|
|
|
|
|
$creneau = Carbon::createFromFormat('d/m/Y H:i', "{$request->selected_day} {$request->selected_time}");
|
|
|
|
|
if (!$shop->isCreneauAvailable($creneau)) {
|
|
|
|
|
throw ValidationException::withMessages([
|
|
|
|
|
'error' => 'Ce créneau n\'est plus disponible'
|
|
|
|
|
]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
DB::transaction(function () use ($shop, $creneau) {
|
|
|
|
|
/** @var \App\Models\Order $order */
|
|
|
|
|
$order = Order::getCurrentOrder();
|
|
|
|
|
// * Assign order uuid we would use, if none already.
|
|
|
|
|
if (!$order->uuid) {
|
|
|
|
|
$order->uuid = Str::uuid();
|
|
|
|
|
}
|
|
|
|
|
Session::put('currentOrder', $order);
|
|
|
|
|
|
|
|
|
|
/** @var \App\Models\Timeslot */
|
|
|
|
|
$timeSlot = Timeslot::query()->where('order_uuid', $order->uuid)->firstOrNew();
|
|
|
|
|
$timeSlot->order()->associate($order);
|
|
|
|
|
$timeSlot->shop()->associate($shop);
|
|
|
|
|
$timeSlot->slot = $creneau;
|
|
|
|
|
$timeSlot->saveOrFail();
|
|
|
|
|
});
|
|
|
|
|
return response()->redirectToRoute('order-tunnel.shipping');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* SaveShippingAdress
|
|
|
|
|
*
|
|
|
|
|
* * --- 3 ---
|
|
|
|
|
*
|
|
|
|
|
* @param \App\Http\Requests\Fo\Orders\ShippingFormRequest $request
|
|
|
|
|
* @return \Illuminate\Http\RedirectResponse
|
|
|
|
|
* @throws \RuntimeException If somehow no email can be found.
|
|
|
|
|
*/
|
|
|
|
|
public function shippingSubmit(ShippingFormRequest $request)
|
|
|
|
|
{
|
2022-12-20 11:32:06 +01:00
|
|
|
$this->assertDoesNotHaveEmptyBasket();
|
2022-12-19 16:20:00 +01:00
|
|
|
$this->assertDoesHaveCurrentOrder();
|
|
|
|
|
$this->assertBasketDidNotChange();
|
|
|
|
|
$this->setOrderProcessStep(OrderProcess::shippment(), OrderProcess::shippingMethod());
|
|
|
|
|
|
|
|
|
|
/** @var \App\Models\Order $order */
|
|
|
|
|
$order = Order::getCurrentOrder();
|
|
|
|
|
|
|
|
|
|
$order->fill($request->validated());
|
|
|
|
|
|
2022-12-20 16:52:44 +01:00
|
|
|
/** @var object */
|
|
|
|
|
$billing = $order->billing;
|
|
|
|
|
$billing->country = Country::france();
|
|
|
|
|
$order->billing = $billing;
|
|
|
|
|
|
2023-02-15 17:51:00 +01:00
|
|
|
$this->allowTimeSlotSelect();
|
2022-12-19 16:20:00 +01:00
|
|
|
|
|
|
|
|
// Fetch right email to send in.
|
|
|
|
|
if ($order->billing->email) {
|
|
|
|
|
$order->email = $order->billing->email;
|
|
|
|
|
} elseif ($order->shipping->email) {
|
|
|
|
|
$order->email = $order->shipping->email;
|
|
|
|
|
} else {
|
|
|
|
|
$order->email = $order->customer->api_data->email;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!$order->email) {
|
|
|
|
|
throw new \RuntimeException('Somehow no email was provided');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$this->fillShippingFromShopInfo($order);
|
|
|
|
|
|
2023-02-15 17:51:00 +01:00
|
|
|
// * Allow timeslot select
|
2022-12-19 16:20:00 +01:00
|
|
|
Session::put('currentOrder', $order);
|
|
|
|
|
|
|
|
|
|
return \response()->redirectToRoute('order-tunnel.review');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Valider le panier avant achat.
|
|
|
|
|
*
|
|
|
|
|
* @return \Illuminate\Contracts\View\View|\Illuminate\Contracts\View\Factory
|
|
|
|
|
*/
|
|
|
|
|
public function review()
|
|
|
|
|
{
|
|
|
|
|
$this->assertDoesNotHaveEmptyBasket();
|
|
|
|
|
$this->assertBasketDidNotChange();
|
|
|
|
|
$this->assertDoesHaveCurrentOrder();
|
|
|
|
|
$this->setOrderProcessStep(OrderProcess::paymentReview(), OrderProcess::shippment());
|
|
|
|
|
|
2023-02-15 17:51:00 +01:00
|
|
|
$this->allowTimeSlotSelect();
|
|
|
|
|
|
2022-12-19 16:20:00 +01:00
|
|
|
/** @var \App\Models\Customer $customer */
|
|
|
|
|
$customer = auth('frontend')->user();
|
|
|
|
|
|
|
|
|
|
/** @var \App\Models\Order $order */
|
|
|
|
|
$order = Order::getCurrentOrder();
|
|
|
|
|
|
2022-12-20 11:32:06 +01:00
|
|
|
// * Order completed email already sent.
|
|
|
|
|
if ($order->mail_sent) {
|
|
|
|
|
self::detroyCurrentBasket();
|
2023-01-30 17:46:30 +01:00
|
|
|
return \view('theme::pages.order-tunnel.done', \compact('order'));
|
2022-12-20 11:32:06 +01:00
|
|
|
}
|
|
|
|
|
|
2022-12-19 16:20:00 +01:00
|
|
|
/** @var \Gloudemans\Shoppingcart\Cart */
|
|
|
|
|
$basket = app('basket');
|
|
|
|
|
|
2023-01-30 17:46:30 +01:00
|
|
|
return view('theme::pages.order-tunnel.review', \compact('basket', 'order'));
|
2022-12-19 16:20:00 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Setup Order for stripe submit
|
|
|
|
|
*
|
|
|
|
|
* @param \App\Http\Requests\Fo\Orders\CheckoutRequest $request
|
2022-12-20 11:32:06 +01:00
|
|
|
* @return \Illuminate\Contracts\View\View|\Illuminate\Contracts\View\Factory
|
2022-12-19 16:20:00 +01:00
|
|
|
* @throws \RuntimeException If payment method is unhandled somehow.
|
|
|
|
|
*/
|
|
|
|
|
public function reviewSubmit(CheckoutRequest $request)
|
|
|
|
|
{
|
|
|
|
|
$this->assertDoesNotHaveEmptyBasket();
|
|
|
|
|
$this->assertBasketDidNotChange();
|
|
|
|
|
$this->assertDoesHaveCurrentOrder();
|
|
|
|
|
$this->setOrderProcessStep(OrderProcess::paymentReview(), OrderProcess::shippment());
|
|
|
|
|
|
|
|
|
|
/** @var \App\Models\Customer $customer */
|
|
|
|
|
$customer = auth('frontend')->user();
|
|
|
|
|
|
2023-02-13 18:04:58 +01:00
|
|
|
// * Force clone here to prevent session save model state (If something goes wrong).
|
2022-12-19 16:20:00 +01:00
|
|
|
/** @var \App\Models\Order $order */
|
2023-02-13 18:04:58 +01:00
|
|
|
$order = clone Order::getCurrentOrder();
|
2022-12-19 16:20:00 +01:00
|
|
|
|
2022-12-20 11:32:06 +01:00
|
|
|
// * Order completed email already sent.
|
2023-02-13 17:53:07 +01:00
|
|
|
if (!$order->exists and $order->mail_sent) {
|
2022-12-20 11:32:06 +01:00
|
|
|
self::detroyCurrentBasket();
|
2023-01-30 17:46:30 +01:00
|
|
|
return \view('theme::pages.order-tunnel.done', \compact('order'));
|
2022-12-20 11:32:06 +01:00
|
|
|
}
|
|
|
|
|
|
2022-12-19 16:20:00 +01:00
|
|
|
if ($request->method === 'cnc') {
|
|
|
|
|
return $this->checkoutCnC($customer, $order);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
throw new \RuntimeException('Unhandled method payment');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Checkout click and collect
|
|
|
|
|
*
|
|
|
|
|
* @param \App\Models\Customer $customer
|
|
|
|
|
* @param \App\Models\Order $order
|
2022-12-20 11:32:06 +01:00
|
|
|
* @return \Illuminate\Contracts\View\View|\Illuminate\Contracts\View\Factory
|
2022-12-19 16:20:00 +01:00
|
|
|
* @throws \Illuminate\Validation\ValidationException If saving order fails.
|
|
|
|
|
*/
|
|
|
|
|
private function checkoutCnC(Customer $customer, Order $order)
|
|
|
|
|
{
|
2022-12-20 11:32:06 +01:00
|
|
|
return DB::transaction(function () use ($customer, $order) {
|
|
|
|
|
// * Notification has been sent
|
|
|
|
|
$order->mail_sent = true;
|
|
|
|
|
|
|
|
|
|
// * Enregistrement commande + envoi de mail.
|
|
|
|
|
if (!$order->save()) {
|
|
|
|
|
report(new \RuntimeException("Order saving error happened."));
|
|
|
|
|
throw ValidationException::withMessages([
|
|
|
|
|
'error' => trans('Une erreur est survenue, veuillez réssayer')
|
|
|
|
|
]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// * Notifiy customer
|
|
|
|
|
$customer->notify(new OrderCreated($order));
|
|
|
|
|
|
|
|
|
|
/** @var object|null */
|
|
|
|
|
$notificationMail = \optional(\optional(GeneralConfig::query()->where('type', GeneralConfigType::global())
|
|
|
|
|
->first())->data)->confirmed_orders_destination_email;
|
|
|
|
|
if (!\optional($notificationMail)->value) {
|
|
|
|
|
throw new \RuntimeException('Could not get new order email notification setting');
|
|
|
|
|
}
|
|
|
|
|
Mail::to($notificationMail->value)->send(new NewOrderIncome($order));
|
|
|
|
|
|
|
|
|
|
self::detroyCurrentBasket();
|
|
|
|
|
|
2023-01-30 17:46:30 +01:00
|
|
|
return \view('theme::pages.order-tunnel.done', \compact('order'));
|
2022-12-20 11:32:06 +01:00
|
|
|
});
|
2022-12-19 16:20:00 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// * --- FIN TUNNEL DE COMMANDE ---
|
|
|
|
|
// * PRIVATE METHODS
|
|
|
|
|
|
2023-02-15 17:51:00 +01:00
|
|
|
/**
|
|
|
|
|
* Allow timeslot select in the tunnel even if already selected
|
|
|
|
|
*
|
|
|
|
|
* @param boolean $disallow To force disallow timeslot picker select.
|
|
|
|
|
* @return void
|
|
|
|
|
*/
|
|
|
|
|
private function allowTimeSlotSelect(bool $disallow = false)
|
|
|
|
|
{
|
|
|
|
|
// * Allow timeslot select
|
|
|
|
|
Session::put('deliveryModePickSlot', $disallow);
|
|
|
|
|
}
|
|
|
|
|
|
2022-12-19 16:20:00 +01:00
|
|
|
/**
|
|
|
|
|
* Assert user does not have an empty basket
|
|
|
|
|
* or redirect with warning
|
|
|
|
|
*
|
|
|
|
|
* @return void
|
|
|
|
|
*/
|
|
|
|
|
private function assertDoesHaveCurrentOrder()
|
|
|
|
|
{
|
2022-12-20 11:32:06 +01:00
|
|
|
$order = Order::getCurrentOrder();
|
|
|
|
|
if (
|
|
|
|
|
$order = Order::getCurrentOrder() and
|
|
|
|
|
$order->payment_status and
|
|
|
|
|
$order->payment_status->equals(PaymentStatus::payed())
|
|
|
|
|
) {
|
2022-12-19 16:20:00 +01:00
|
|
|
self::detroyCurrentBasket();
|
2023-01-30 17:46:30 +01:00
|
|
|
abort(\response()->view('theme::pages.order-tunnel.done', \compact('order')));
|
2022-12-19 16:20:00 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!$order) {
|
|
|
|
|
\redirect()->route('order-tunnel.basket.recap')->throwResponse();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Delete order steps, removes basket, ends tunnel transaction.
|
|
|
|
|
*
|
|
|
|
|
* @return void
|
|
|
|
|
*/
|
|
|
|
|
public static function detroyCurrentBasket()
|
|
|
|
|
{
|
|
|
|
|
/** @var \Gloudemans\Shoppingcart\Cart */
|
|
|
|
|
$basket = app('basket');
|
|
|
|
|
$basket->destroy();
|
|
|
|
|
|
|
|
|
|
Session::remove('currentOrder');
|
|
|
|
|
Session::remove('PreviousOrderStep');
|
|
|
|
|
Session::remove('OrderStep');
|
|
|
|
|
Session::remove('deliveryModePickSlot');
|
|
|
|
|
Session::remove('basketFingerPrint');
|
2022-11-23 13:00:38 +01:00
|
|
|
}
|
2022-11-30 17:03:43 +01:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Assert user does not have an empty basket
|
|
|
|
|
* or redirect with warning
|
|
|
|
|
*
|
|
|
|
|
* @return void
|
|
|
|
|
*/
|
|
|
|
|
private function assertDoesNotHaveEmptyBasket(): void
|
|
|
|
|
{
|
|
|
|
|
/** @var \Gloudemans\Shoppingcart\Cart */
|
|
|
|
|
$basket = app('basket');
|
|
|
|
|
|
|
|
|
|
if (!$basket->count()) {
|
|
|
|
|
\redirect()->route('home')
|
|
|
|
|
->with('warning', trans('Vous n\'avez aucun produit dans votre panier'))
|
|
|
|
|
->throwResponse();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-12-19 16:20:00 +01:00
|
|
|
/**
|
|
|
|
|
* Assert user does not have an empty basket
|
|
|
|
|
* or redirect with warning
|
|
|
|
|
*
|
|
|
|
|
* @return void
|
|
|
|
|
*/
|
|
|
|
|
private function assertBasketDidNotChange(): void
|
|
|
|
|
{
|
|
|
|
|
/** @var \Gloudemans\Shoppingcart\Cart */
|
|
|
|
|
$basket = app('basket');
|
|
|
|
|
$actual_finger_print = hash('sha256', \json_encode($basket->content()->jsonSerialize()));
|
|
|
|
|
$session_finger_print = Session::get('basketFingerPrint');
|
|
|
|
|
|
|
|
|
|
Session::put('basketFingerPrint', $actual_finger_print);
|
|
|
|
|
|
|
|
|
|
if ($session_finger_print !== $actual_finger_print) {
|
|
|
|
|
Session::remove('deliveryModePickSlot');
|
|
|
|
|
\redirect()->route('order-tunnel.basket.recap')
|
|
|
|
|
->with('warning', trans('Votre panier à été modifié'))
|
|
|
|
|
->throwResponse();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-11-30 17:03:43 +01:00
|
|
|
/**
|
|
|
|
|
* Validate Process step
|
|
|
|
|
*
|
|
|
|
|
* @param \App\Enums\Order\OrderProcess $step
|
|
|
|
|
* @param \App\Enums\Order\OrderProcess|null $assertDid
|
|
|
|
|
* @return void
|
|
|
|
|
* @throws \Illuminate\Validation\ValidationException If previous was not done.
|
|
|
|
|
*/
|
|
|
|
|
private function setOrderProcessStep(OrderProcess $step, OrderProcess $assertDid = null): void
|
|
|
|
|
{
|
|
|
|
|
if ($assertDid) {
|
|
|
|
|
if (!Session::get('PreviousOrderStep')) {
|
|
|
|
|
Session::put('PreviousOrderStep', collect());
|
|
|
|
|
}
|
|
|
|
|
/** @var \Illuminate\Support\Collection */
|
|
|
|
|
$previousSteps = Session::get('PreviousOrderStep');
|
|
|
|
|
if (Session::get('OrderStep') < $step) {
|
|
|
|
|
/** @var \App\Enums\OrderProcess */
|
|
|
|
|
$previousStep = Session::get('OrderStep');
|
|
|
|
|
$previousSteps->put($previousStep->value, $previousStep);
|
|
|
|
|
Session::put('PreviousOrderStep', $previousSteps);
|
|
|
|
|
}
|
|
|
|
|
if (!$previousSteps->count()) {
|
|
|
|
|
\redirect()->route('home')
|
|
|
|
|
->with('warning', trans('Vous devez d\'abord valider votre panier'))
|
|
|
|
|
->throwResponse();
|
|
|
|
|
}
|
|
|
|
|
if (!$previousSteps->contains($assertDid)) {
|
|
|
|
|
throw ValidationException::withMessages(['Étape précédente requise']);
|
|
|
|
|
}
|
|
|
|
|
} //end if
|
|
|
|
|
|
|
|
|
|
Session::put('OrderStep', $step);
|
|
|
|
|
}
|
2022-12-19 16:20:00 +01:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Fill order shipping with in shop infos
|
|
|
|
|
*
|
|
|
|
|
* @param \App\Models\Order $order
|
|
|
|
|
* @return void
|
|
|
|
|
* @throws \Illuminate\Validation\ValidationException Si le créneau de reservation n'est plus trouvable.
|
|
|
|
|
*/
|
|
|
|
|
private function fillShippingFromShopInfo(Order $order)
|
|
|
|
|
{
|
|
|
|
|
/** @var \App\Models\Customer */
|
|
|
|
|
$user = auth('frontend')->user();
|
|
|
|
|
if ($order->deliveryMode->mode->equals(DeliveryModeEnum::inShop())) {
|
|
|
|
|
/** @var \App\Models\Timeslot|null */
|
|
|
|
|
if (!($timeslot = $order->timeslot()->first())) {
|
|
|
|
|
throw ValidationException::withMessages([
|
|
|
|
|
'error' => trans('Créneau de réservation introuvable')
|
|
|
|
|
]);
|
|
|
|
|
}
|
|
|
|
|
$order->shipping = [
|
|
|
|
|
'firstname' => $timeslot->shop->name,
|
|
|
|
|
'lastname' => '',
|
|
|
|
|
'email' => null,
|
|
|
|
|
'phone' => $timeslot->shop->phone,
|
|
|
|
|
'line1' => $timeslot->shop->address,
|
|
|
|
|
'postal_code' => $timeslot->shop->postal_code,
|
2022-12-20 16:52:44 +01:00
|
|
|
'city' => $timeslot->shop->city,
|
|
|
|
|
'country' => $timeslot->shop->country
|
2022-12-19 16:20:00 +01:00
|
|
|
];
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-11-23 13:00:38 +01:00
|
|
|
}
|