HEX
Server: Microsoft-IIS/8.5
System: Windows NT YDAWBH120 6.3 build 9600 (Windows Server 2012 R2 Standard Edition) AMD64
User: tentjecom_web (0)
PHP: 7.4.14
Disabled: NONE
Upload Files
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;
    }
}