File: D:/HostingSpaces/SBogers95/rentman.io/app/Komma/Shop/Checkout/CheckoutService.php
<?php
namespace App\Komma\Shop\Checkout;
use App\Komma\Shop\Cart\ShoppingCartItemInterface;
use App\Komma\Shop\Orders\Kms\OrderServiceInterface;
use App\Komma\Shop\Orders\Models\Order;
use App\Komma\Shop\Orders\OrderStatus;
use App\Komma\Shop\Payment\PaymentServiceInterface;
use App\Komma\Shop\Products\Product\Product;
use App\Komma\Shop\Products\Product\ProductServiceInterface;
use App\Komma\Shop\Products\ProductComposite\ProductComposite;
use App\Komma\Shop\Products\ProductComposite\ProductCompositeServiceInterface;
use App\Komma\Shop\Products\ProductGroup\ProductGroup;
use App\Komma\Shop\Products\ProductGroup\ProductGroupServiceInterface;
use App\Komma\Users\Models\User;
use Illuminate\Http\RedirectResponse;
/**
* Class CheckoutService
*
* The checkout service sits between Order related, product related and payment related code.
* It directs those two domains to work together.
*/
class CheckoutService implements CheckoutServiceInterface
{
/** @var OrderServiceInterface */
private $orderService;
/** @var ProductServiceInterface */
private $productService;
/** @var ProductGroupServiceInterface */
private $productGroupService;
/** @var ProductCompositeServiceInterface */
private $productCompositeService;
/** @var PaymentServiceInterface */
private $paymentService;
public function __construct()
{
$this->orderService = \App::make(OrderServiceInterface::class);
$this->productService = \App::make(ProductServiceInterface::class);
$this->productGroupService = \App::make(ProductGroupServiceInterface::class);
$this->productCompositeService = \App::make(ProductCompositeServiceInterface::class);
$this->paymentService = \App::make(PaymentServiceInterface::class);
}
/**
* Initializes a payment request for the user that owns the order.
*
* @param Order $order
* @return RedirectResponse
*/
public function startPaymentForOrder(Order $order): RedirectResponse
{
$pspAdapter = $this->paymentService->getAdapter();
$transaction = $pspAdapter->createTransaction($order);
return $pspAdapter->redirectForPayment($transaction);
}
/**
* @param ShoppingCartItemInterface[] $shoppingCartItems
* @param User $customer
* @return Order|null
* @throws \Throwable
*/
public function createOrderFromShoppingCartItemsForCustomer($shoppingCartItems, User $customer): ?Order
{
foreach ($shoppingCartItems as $shoppingCartItem) {
if (! is_a($shoppingCartItem, ShoppingCartItemInterface::class)) {
throw new \RuntimeException('The given "ShoppingCartItem" wasn\'t an instance of: '.ShoppingCartItemInterface::class);
}
}
$order = null;
\DB::transaction(function () use ($shoppingCartItems, $customer, &$order) {
/** @var Order $order */
$order = $this->orderService->newModel();
$order->customer()->associate($customer);
$order->save();
foreach ($shoppingCartItems as $shoppingCartItem) {
$productable = $shoppingCartItem->getProductable();
$shoppingCartItem->getTotal(true);
$shoppingCartItem->getAmount();
$productableClassName = get_class($productable);
switch ($productableClassName) {
case Product::class:
/** @var Product $productable */
$this->productService->createOrderedProductFromProduct($productable, $order);
break;
case ProductGroup::class:
/** @var ProductGroup $productable */
$this->productGroupService->createOrderedProductGroupFromProductGroup($productable, $order);
break;
case ProductComposite::class:
/** @var ProductComposite $productable */
$this->productCompositeService->createOrderedProductCompositeProductComposite($productable, $order);
break;
default:
return null;
}
}
$order = $this->orderService->fillOrderWithCustomerInfo($order, $customer);
$this->orderService->calculateTotalOrderPrice($order);
$order->status = OrderStatus::NEW;
$order->save();
});
return $order;
}
}