File: D:/HostingSpaces/farmfun/reserveren.farmfun.be/app/Komma/Shop/Checkout/CheckoutController.php
<?php
namespace App\Komma\Shop\Checkout;
use App\Komma\Addresses\AddressService;
use App\Komma\Addresses\Models\Address;
use App\Komma\Base\Controller;
use App\Komma\Globalization\RegionInfo;
use App\Komma\Globalization\RegionInfoInterface;
use App\Komma\Globalization\Requests\CountryIso3Request;
use App\Komma\Shop\Cart\HasCouponCodesInterface;
use App\Komma\Shop\Cart\Requests\AddCouponRequest;
use App\Komma\Shop\Cart\Requests\RemoveCouponRequest;
use App\Komma\Shop\Cart\ShoppingCartItemInterface;
use App\Komma\Shop\Cart\ShoppingCartService;
use App\Komma\Shop\Cart\ShoppingCartServiceInterface;
use App\Komma\Shop\Checkout\Resources\CheckoutInformationResource;
use App\Komma\Shop\Discounts\DiscountTypes;
use App\Komma\Shop\Orders\Kms\OrderMailServiceInterface;
use App\Komma\Shop\ShippingCosts\ShippingCostsService;
use App\Komma\Shop\Vat\VatService;
use App\Komma\Shop\Vat\VatServiceInterface;
use App\Komma\Users\Models\SiteUser;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Request;
use Illuminate\View\View;
/**
* Handles the checkout process and the different views
*
* Class ShoppingCartService
*/
class CheckoutController extends Controller
{
/** @var OrderMailServiceInterface */
private $orderMailService;
/** @var AddressService */
private $addressService;
/** @var RegionInfoInterface */
private $regionInfo;
/**
* @var VatServiceInterface
*/
private $vatRateService;
/**
* CheckoutController constructor.
*/
public function __construct()
{
if (\App::runningInConsole()) {
return;
}
$this->orderMailService = app(OrderMailServiceInterface::class);
$this->addressService = app(AddressService::class);
$this->vatRateService = new VatService();
$this->regionInfo = app(RegionInfoInterface::class);
parent::__construct();
}
public function startCheckout()
{
$user = Auth::user('site');
if (! $user) {
return view('shop.pages.checkout.auth');
} //Show a page where the user can choose to login, or proceed as guest.
return redirect()->to(route('checkout.show')); //User is authenticated. Go to the checkout page directly
}
public function presentLoginPageWithIntentionToCheckout()
{
session()->put('url.intended', route('checkout.show'));
return redirect()->to(route('site.login'));
}
/**
* Shows a checkout form
*
* return
*/
public function showCheckoutForm()
{
/** @var CheckoutServiceInterface $checkoutService */
$checkoutService = app(CheckoutServiceInterface::class);
/** @var ShoppingCartServiceInterface|ShoppingCartService $shoppingCartService */
$shoppingCartService = app(ShoppingCartServiceInterface::class);
$user = $checkoutService->getUser();
/** @var Collection $addresses */
$addresses = $user ? $user->addresses()->get() : new Collection();
$lastUsedShippingAddress = ($user) ? $checkoutService->getLastUsedShippingAddressForUser($user) : null;
$lastUsedInvoiceAddress = ($user) ? $checkoutService->getLastUsedInvoiceAddressForUser($user) : null;
$shoppingCartService->updateDiscounts();
$couponCodes = $shoppingCartService->getDiscountsByType(DiscountTypes::Coupon);
$neutralCulturesByIso3 = RegionInfo::getNeutralCultures()->map(function (RegionInfo $regionInfo) {
return [$regionInfo->getThreeLetterISORegionName() => $regionInfo->getNativeName() !== '' ? $regionInfo->getNativeName() : $regionInfo->getDisplayName()];
})->collapse()->sort();
$neutralCulturesHotList = RegionInfo::getNeutralCultures()->filter(function (RegionInfo $regionInfo) {
return in_array($regionInfo->getThreeLetterISORegionName(), config('shop.country_hotlist', []), true);
})->map(function (RegionInfo $regionInfo) {
return [$regionInfo->getThreeLetterISORegionName() => $regionInfo->getNativeName() !== '' ? $regionInfo->getNativeName() : $regionInfo->getDisplayName()];
})->collapse()->sort();
return $this->checkoutView()->with([
'addresses' => $addresses,
'lastUsedShippingAddress' => $lastUsedShippingAddress,
'lastUsedInvoiceAddress' => $lastUsedInvoiceAddress,
'items' => $shoppingCartService->getItems(),
'checkoutInformation' => $this->getCheckoutInformation(),
'regionInfo' => $this->regionInfo,
'links' => $this->links,
'applied_codes' => $couponCodes,
'neutralCulturesByIso3' => $neutralCulturesByIso3,
'neutralCulturesHotlistByIso3' => $neutralCulturesHotList,
'isGuestUser' => $user->guest,
]);
}
/**
* Triggered in response of a push on a checkout button
* @param CheckoutRequest $checkoutRequest
* @return \Illuminate\Http\RedirectResponse
*/
public function checkout(CheckoutRequest $checkoutRequest)
{
/** @var CheckoutServiceInterface $checkoutService */
$checkoutService = app(CheckoutServiceInterface::class);
/** @var SiteUser $user */
$user = $checkoutService->getUser(true);
$user->save(); //Get the user and save it if it is a guest user.
/** @var ShoppingCartServiceInterface|HasCouponCodesInterface $shoppingCartService */
$shoppingCartService = app(ShoppingCartServiceInterface::class);
/** @var CheckoutServiceInterface $checkoutService */
$checkoutService = app(CheckoutServiceInterface::class);
//Create addresses for shipping and invoice.
$addressForInvoice = $this->addressService->getAddressForInvoiceFromInput();
$addressForShipping = $this->addressService->getAddressForShippingFromInput();
$addressForInvoice = $this->addressService->saveAddressForUser($addressForInvoice, $user);
$addressForShipping = $this->addressService->saveAddressForUser($addressForShipping, $user, $addressForInvoice);
/** @var ShoppingCartItemInterface[] $items */
// $this->orderMailService->mailCustomerAboutCurrentOrderStatus($order);
// $this->orderMailService->mailStaffAboutCurrentOrderStatus($order);
$order = $checkoutService->createOrder($shoppingCartService, $user, $addressForShipping, $addressForInvoice);
//Clear the checkout session data (shipping address and guest user if available)
$checkoutService->clearCheckoutData();
$shoppingCartService->clear(); //Clear the shopping cart
return $checkoutService->startPaymentForOrder($order);
}
/**
* Returns info about checkout totals.
*
* Used when showing the checkout form initially and on subsequent ajax requests when
* the user did some changes in the checkout form.
*
* @return CheckoutInformationResource
*/
public function getCheckoutInformation(): CheckoutInformationResource
{
/** @var CheckoutServiceInterface $checkoutService */
$checkoutService = app(CheckoutServiceInterface::class);
/** @var ShoppingCartServiceInterface|HasCouponCodesInterface $shoppingCartService */
$shoppingCartService = app(ShoppingCartServiceInterface::class);
/** @var ShippingCostsService $shippingCostsService */
$shippingCostsService = app(ShippingCostsService::class);
$user = $checkoutService->getUser();
$shippingAddress = $checkoutService->getShippingAddress();
if (! $shippingAddress && $user) {
$shippingAddress = $checkoutService->getLastUsedShippingAddressForUser($user);
}
$shippingCosts = $shippingCostsService->calculate($shoppingCartService, $shippingAddress);
$vatTotal = $this->vatRateService->calculateVatRateAmountFromExAmount($shoppingCartService->getTotal(true) + $shippingCosts);
$total = $shoppingCartService->getTotal(true) + $shippingCosts + $vatTotal;
$totalExVat = $shoppingCartService->getTotal(true);
$totalExVatAndDiscounts = $shoppingCartService->getTotal(false);
$checkoutInformationResource = new CheckoutInformationResource();
$checkoutInformationResource->setCouponCodes($shoppingCartService->getCouponCodes());
$checkoutInformationResource->setTotal($total);
$checkoutInformationResource->setVatTotal($vatTotal);
$checkoutInformationResource->setVatPercentage(21);
$checkoutInformationResource->setTotalExVat($totalExVat);
$checkoutInformationResource->setTotalExVatAndDiscounts($totalExVatAndDiscounts);
$checkoutInformationResource->setShippingCosts($shippingCosts);
return $checkoutInformationResource;
}
/**
* @param \App\Komma\Globalization\Requests\CountryIso3Request $request
* @return JsonResponse
*/
public function setShippingAddress(CountryIso3Request $request): JsonResponse
{
/** @var CheckoutServiceInterface $checkoutService */
$checkoutService = app(CheckoutServiceInterface::class);
/** @var RegionInfo $regionInfo */
$regionInfo = RegionInfo::getWhere('ThreeLetterISORegionName', '=', $request->get('countryIso3'))->first();
$address = new Address([
'street' => $request->get('street'),
'house_number' => $request->get('house_number'),
'postal_code' => $request->get('postal_code'),
'city' => $request->get('city'),
'telephone' => $request->get('phone'),
'country_iso3' => $regionInfo->getThreeLetterISORegionName(),
]);
$checkoutService->setShippingAddress($address);
return response()->json($address);
}
/**
* Adds a coupon code via an ajax request
* @param AddCouponRequest $request
* @return CheckoutInformationResource
*/
public function addCouponCode(AddCouponRequest $request)
{
/** @var ShoppingCartServiceInterface|HasCouponCodesInterface $shoppingCartService */
$shoppingCartService = app(ShoppingCartServiceInterface::class);
$couponCodesBeforeAddedNewOne = $shoppingCartService->getDiscountsByType(DiscountTypes::Coupon);
$shoppingCartService->addCouponCode($request->get('coupon'));
$couponCodesAfterAddedNewOne = $shoppingCartService->getDiscountsByType(DiscountTypes::Coupon);
if (count($couponCodesAfterAddedNewOne) == count($couponCodesBeforeAddedNewOne)) { //If the amount of valid coupon codes is the same as before we tried to add one, the coupon code is invalid. Else if would be added.
$shoppingCartService->removeCouponCode($request->get('coupon'));
return response()->json([
'message' => 'Coupon code invalid',
'errors' => [
'coupon_code' => [__('shop/discounts.coupon_fail')],
],
], 400);
}
$request->flash();
return $this->getCheckoutInformation();
}
/**
* Removes an coupon code via an ajax request
*
* @param RemoveCouponRequest $request
* @return CheckoutInformationResource
*/
public function removeCouponCode(RemoveCouponRequest $request)
{
/** @var ShoppingCartServiceInterface|HasCouponCodesInterface $shoppingCartService */
$shoppingCartService = app(ShoppingCartServiceInterface::class);
$shoppingCartService->removeCouponCode($request->get('coupon'));
$request->flash();
return $this->getCheckoutInformation();
}
/**
* @return View
*/
public function index()
{
return $this->checkoutView();
}
/**
* @return View
*/
protected function checkoutView(): View
{
return view('shop.pages.checkout.index');
}
}