File: D:/HostingSpaces/SBogers10/blije-gasten.komma.pro/app/Komma/Shop/Checkout/CheckoutController.php
<?php
namespace App\Komma\Shop\Checkout;
use App\Komma\Base\Controller;
use App\Komma\Addresses\AddressService;
use App\Komma\Globalization\RegionInfo;
use App\Komma\Globalization\RegionInfoInterface;
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\Request\CheckoutDataRequest;
use App\Komma\Shop\Checkout\Request\CheckoutSummaryRequest;
use App\Komma\Shop\Checkout\Resources\CheckoutInformationResource;
use App\Komma\Shop\Discounts\DiscountTypes;
use App\Komma\Shop\Orders\Kms\OrderMailServiceInterface;
use App\Komma\Shop\Orders\OrderService;
use App\Komma\Shop\Vat\VatService;
use App\Komma\Shop\Vat\VatServiceInterface;
use App\Komma\Shop\Vies\ViesService;
use Illuminate\Http\Request;
use Illuminate\View\View;
/**
* Handles the checkout process and the different views
*
* Class ShoppingCartService
* @package App\Komma\Shop\Cart
*/
class CheckoutController extends Controller
{
/** @var OrderMailServiceInterface $orderMailService */
private $orderMailService;
/** @var AddressService $addressService */
private $addressService;
/** @var RegionInfoInterface $regionInfo */
private $regionInfo;
/** @var VatServiceInterface */
private $vatRateService;
/** @var CheckoutService $this->checkoutService */
private $checkoutService;
/**
* 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);
$this->checkoutService = app(CheckoutService::class);
parent::__construct();
}
/**
* @param Request $request
* @return View
*/
public function checkoutDataForm(Request $request) {
/** @var ShoppingCartServiceInterface|ShoppingCartService $shoppingCart */
$shoppingCart = app(ShoppingCartServiceInterface::class);
if($shoppingCart->getItemsCount() <= 0){
return redirect(localized_route('shoppingcart'))->with(['checkoutFlashMessage' => __('shop/checkout.flashMessage.empty')]);
}
if( $shoppingCart->getDate() == null && !$request->has('date') ) {
return redirect(localized_route('shoppingcart'))->with(['checkoutFlashMessage' => __('shop/checkout.flashMessage.no_date')]);
}
if($request->has('date')) {
$shoppingCart->setDate($request->date);
}
if($request->has('pickup_or_ship')) {
$shoppingCart->updateDeliveryLocationFromRequest($request);
}
// Start creating the old session data
$oldSessionData = $this->checkoutService->getUserData();
// If we have a invoice address add to old session
if($addressForInvoice = $this->checkoutService->getInvoiceAddress()) {
foreach ($addressForInvoice->getFillable() as $attribute) {
$oldSessionData->{'invoice_' . $attribute} = $addressForInvoice->{$attribute};
}
// Check if there is a different shipping address, else also use the invoice address
if($addressForShipping = $this->checkoutService->getShippingAddress()) {
foreach ($addressForShipping->getFillable() as $attribute) {
$oldSessionData->{'shipping_' . $attribute} = $addressForShipping->{$attribute};
}
}
}
session(['old_session' => $oldSessionData]);
// $user = $this->checkoutService->getUser();
// $user->save();
//
// /** @var Collection $addresses */
// $addresses = $user ? $user->addresses()->get() : new Collection();
// $lastUsedShippingAddress = ($user) ? $this->checkoutService->getLastUsedShippingAddressForUser($user) : null;
// $lastUsedInvoiceAddress = ($user) ? $this->checkoutService->getLastUsedInvoiceAddressForUser($user) : null;
$neutralCulturesHotList = RegionInfo::getNeutralCultures()->filter(function(RegionInfo $regionInfo) {
return in_array($regionInfo->getThreeLetterISORegionName(), config('shop.country_hotlist', []), true);
})->map(function(RegionInfo $regionInfo) {
return [$regionInfo->getName() => $regionInfo->getNativeName() !== '' ? $regionInfo->getNativeName() : $regionInfo->getDisplayName()];
})->collapse()->sort();
return view('site.templates.checkout_data')->with([
// 'addresses' => $addresses,
// 'lastUsedShippingAddress' => $lastUsedShippingAddress,
// 'lastUsedInvoiceAddress' => $lastUsedInvoiceAddress,
'shoppingCart' => $shoppingCart,
'regionInfo' => $this->regionInfo,
'links' => $this->links,
'neutralCulturesHotlistByIso3' => $neutralCulturesHotList,
]);
}
public function validateDataForm(CheckoutDataRequest $checkoutDataRequest)
{
/** @var ShoppingCartServiceInterface|ShoppingCartService $shoppingCart */
$shoppingCart = app(ShoppingCartServiceInterface::class);
// Create user data from input
$userData = $checkoutDataRequest->only(['clientType','invoice_company','invoice_vat_number','first_name','name_preposition', 'last_name', 'phone', 'email']);
// Set as true of false instead of on
$userData['other_shipping_address'] = $checkoutDataRequest->get('other_shipping_address') === 'on';
// Remove business information if client type isn't business
if($userData['clientType'] !== 'business') {
unset($userData['invoice_company']);
unset($userData['invoice_vat_number']);
}
else{
// If business, then validate BTW with Vies
/** @var ViesService $viewService */
$viewService = app()->make(ViesService::class);
$viewResult = $viewService->validateVatNumber($userData['invoice_vat_number']);
$userData['vies_valid'] = !empty($viewResult) ? true : false;
$userData['vies_result'] = $viewResult;
}
$this->checkoutService->setUserData((object)$userData);
//Create addresses for shipping and invoice from input.
$addressForInvoice = $this->addressService->getAddressForInvoiceFromInput();
$this->checkoutService->setInvoiceAddress($addressForInvoice);
// Check if we need to use shipping
if($shoppingCart->useShipping()){
// If we have a different shipping address load if from the input. Else copy the invoice address
if($checkoutDataRequest->get('other_shipping_address') == 'on') $addressForShipping = $this->addressService->getAddressForShippingFromInput();
else $addressForShipping = $addressForInvoice;
$this->checkoutService->setShippingAddress($addressForShipping);
$shoppingCart->setDeliveryLocation($addressForShipping->city, $addressForShipping->postal_code, $addressForShipping->country_iso2);
}
return redirect(localized_route('checkout.summary'));
}
public function checkoutSummary() {
/** @var ShoppingCartServiceInterface|ShoppingCartService $shoppingCart */
$shoppingCart = app(ShoppingCartServiceInterface::class);
if($shoppingCart->getItemsCount() <= 0){
return redirect(localized_route('shoppingcart'))->with(['checkoutFlashMessage' => __('shop/checkout.flashMessage.empty')]);
}
if( $shoppingCart->getDate() == null) {
return redirect(localized_route('shoppingcart'))->with(['checkoutFlashMessage' => __('shop/checkout.flashMessage.no_date')]);
}
$userData = $this->checkoutService->getUserData();
$addressForInvoice = $this->checkoutService->getInvoiceAddress();
$addressForShipping = $this->checkoutService->getShippingAddress();
if(!isset($userData) || !isset($addressForInvoice) ) {
return redirect(localized_route('checkout.show'))->with(['checkoutFlashMessage' => __('shop/checkout.flashMessage.invalid_data')]);
}
return view('site.templates.checkout_summary')->with([
'shoppingCart' => $shoppingCart,
'userData' => $userData,
'addressForShipping' => $addressForShipping,
'addressForInvoice' => $addressForInvoice,
'regionInfo' => app(RegionInfoInterface::class),
'links' => $this->links,
// 'user' => $user,
]);
}
/**
* Triggered in response of a push on a checkout button
*
* @param CheckoutSummaryRequest $checkoutSummaryRequest
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
* @throws \Illuminate\Contracts\Container\BindingResolutionException
*/
public function validateSummaryForm(CheckoutSummaryRequest $checkoutSummaryRequest)
{
// /** @var SiteUser $user */
// $user = $this->checkoutService->getUser(true);
// $user->save(); //Get the user and save it if it is a guest user.
/** @var ShoppingCartServiceInterface|HasCouponCodesInterface $shoppingCart */
$shoppingCart = app(ShoppingCartServiceInterface::class);
if($shoppingCart->getItemsCount() <= 0){
return redirect(localized_route('shoppingcart'))->with(['checkoutFlashMessage' => __('shop/checkout.flashMessage.empty')]);
}
$userData = $this->checkoutService->getUserData();
$addressForShipping = $this->checkoutService->getShippingAddress();
$addressForInvoice = $this->checkoutService->getInvoiceAddress();
if(!isset($userData) || !isset($addressForInvoice)) {
// return redirect(localized_route('checkout.show'))->with(['checkoutFlashMessage' => __('shop/checkout.flashMessage.invalid_data')]);
}
/** @var ShoppingCartItemInterface[] $items */
// $this->orderMailService->mailCustomerAboutCurrentOrderStatus($order);
// $this->orderMailService->mailStaffAboutCurrentOrderStatus($order);
// Temporary store the remarks on the user data
$userData->remarks = request()->get('remarks');
/** @var OrderService $orderService */
$orderService = app()->make(OrderService::class);
$order = $orderService->createOrder($shoppingCart, $userData, $addressForInvoice, $addressForShipping);
//Clear the checkout session data (shipping address and guest user if available)
$this->checkoutService->clearCheckoutData();
$shoppingCart->clear(); //Clear the shopping cart
unset($userData->remarks); // Unset the remarks
return $orderService->startPaymentForOrder($order);
}
public function devRoute()
{
/** @var OrderService $orderService */
$orderService = app()->make(OrderService::class);
$order = $orderService->getOrderById(11);
return view('site.templates.checkout_error')->with([
'order' => $order,
'links' => $this->links,
// 'user' => $user,
]);
// $orderMailService = app()->make(OrderMailServiceInterface::class);
// $orderMailService->mailStaffAboutCurrentOrderStatus($order);
// return new OrderStatusUpdatedStaff($order, KmsUser::find(2));
// return $orderService->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 ShoppingCartServiceInterface|HasCouponCodesInterface $shoppingCart */
$shoppingCart = app(ShoppingCartServiceInterface::class);
$user = $this->checkoutService->getUser();
$shippingAddress = $this->checkoutService->getShippingAddress();
if(!$shippingAddress && $user) $shippingAddress = $this->checkoutService->getLastUsedShippingAddressForUser($user);
$vatTotal = $this->vatRateService->calculateVatRateAmountFromExAmount($shoppingCart->getTotal(true));
$total = $shoppingCart->getTotal(true) + $vatTotal;
$totalExVat = $shoppingCart->getTotal(true);
$totalExVatAndDiscounts = $shoppingCart->getProductTotal();
$checkoutInformationResource = new CheckoutInformationResource();
$checkoutInformationResource->setCouponCodes($shoppingCart->getCouponCodes());
$checkoutInformationResource->setTotal($total);
$checkoutInformationResource->setVatTotal($vatTotal);
$checkoutInformationResource->setVatPercentage(21);
$checkoutInformationResource->setTotalExVat($totalExVat);
$checkoutInformationResource->setTotalExVatAndDiscounts($totalExVatAndDiscounts);
return $checkoutInformationResource;
}
public function checkoutSuccess()
{
// if(empty(session('order'))) return abort(404);
// /** @var OrderService $orderService */
// $orderService = app()->make(OrderService::class);
// $order = $orderService->getOrderById(session('order'));
return view('site.templates.checkout_success')->with([
// 'order' => $order,
'links' => $this->links,
// 'user' => $user,
]);
}
public function checkoutError()
{
// if(empty(session('order'))) return abort(404);
// /** @var OrderService $orderService */
// $orderService = app()->make(OrderService::class);
// $order = $orderService->getOrderById(session('order'));
return view('site.templates.checkout_error')->with([
// 'order' => $order,
'links' => $this->links,
// 'user' => $user,
]);
}
public function checkoutDepositSuccess()
{
return view('site.templates.checkout_deposit_success')->with([
'links' => $this->links,
]);
}
public function checkoutDepositError()
{
return view('site.templates.checkout_deposit_error')->with([
'links' => $this->links,
]);
}
/**
* TODO Move this to shopping cart controller
*
* Adds a coupon code via an ajax request
* @param AddCouponRequest $request
* @return CheckoutInformationResource
*/
public function addCouponCode(AddCouponRequest $request)
{
/** @var ShoppingCartServiceInterface|HasCouponCodesInterface $shoppingCart */
$shoppingCart = app(ShoppingCartServiceInterface::class);
$couponCodesBeforeAddedNewOne = $shoppingCart->getDiscountsByType(DiscountTypes::Coupon);
$shoppingCart->addCouponCode($request->get('coupon'));
$couponCodesAfterAddedNewOne = $shoppingCart->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.
$shoppingCart->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
* TODO Move this to shopping cart controller
*
* @param RemoveCouponRequest $request
* @return CheckoutInformationResource
*/
public function removeCouponCode(RemoveCouponRequest $request)
{
/** @var ShoppingCartServiceInterface|HasCouponCodesInterface $shoppingCart */
$shoppingCart = app(ShoppingCartServiceInterface::class);
$shoppingCart->removeCouponCode($request->get('coupon'));
$request->flash();
return $this->getCheckoutInformation();
}
}