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/farmfun/reserveren.farmfun.be/app/Komma/Shop/Orders/Kms/OrderController.php
<?php

namespace App\Komma\Shop\Orders\Kms;

/**
 * @author      Komma <info@komma.pro>
 * @copyright   (c) 2012-2016, Komma
 */
use App\Helpers\KommaHelpers;
use App\Komma\Globalization\RegionInfoInterface;
use App\Komma\Kms\Core\Attributes\Models\Traits\HasThumbnailInterface;
use App\Komma\Kms\Core\Entities\DisplayNameInterface;
use App\Komma\Kms\Core\SectionController;
use App\Komma\Shop\Invoicing\CreditInvoiceService;
use App\Komma\Shop\Invoicing\InvoiceService;
use App\Komma\Shop\Orders\CreditInvoiceNumberSequence;
use App\Komma\Shop\Orders\Models\Order;
use App\Komma\Shop\Orders\OrderStatus;
use App\Komma\Shop\Orders\SearchRequest;
use App\Komma\Shop\Payment\Transaction;
use App\Komma\Shop\Shipmentgroups\Shipmentgroupservice;
use App\Komma\Shop\Shipments\Shipment;
use App\Komma\Shop\Shipments\ShipmentService;
use App\Komma\Users\Models\User;
use Illuminate\Contracts\View\View;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Input;
use Illuminate\Support\Facades\Session;
use Illuminate\Support\MessageBag;

class OrderController extends SectionController
{
    protected $slug = 'orders';

    /** @var string */
    protected $classModelName = Order::class;

    /** @var OrderService */
    private $orderService;

    /**
     * @var ShipmentService
     */
    private $shipmentService;

    /**
     * @var OrderMailServiceInterface
     */
    private $orderMailService;

    /**
     * @var ShipmentGroupService
     */
    private $shipmentGroupService;

    /** @var InvoiceService */
    private $invoiceService;

    /** @var CreditInvoiceService */
    private $creditInvoiceService;

    /**
     * @var \Illuminate\Contracts\Foundation\Application
     */
    private $creditInvoiceNumberGenerator;

    /**
     * Constructor
     */
    public function __construct()
    {
        $orderSection = new OrderSection($this->slug);
        $this->orderService = new OrderService();
        $this->orderMailService = new OrderMailService();
        $this->shipmentGroupService = new ShipmentGroupService();
        $this->shipmentService = new ShipmentService();
        $this->invoiceService = new InvoiceService();
        $this->creditInvoiceService = new CreditInvoiceService();
        $this->creditInvoiceNumberGenerator = app(CreditInvoiceNumberSequence::class);
        parent::__construct($orderSection);
    }

    /**
     * This method is called on the overview page.
     * It will render the section and view.
     *
     * @return mixed
     * @throws \Illuminate\Auth\Access\AuthorizationException
     */
    public function index()
    {
        $this->authorize('index', $this->classModelName);

        /** @var OrderSection $section */
        $section = $this->section;

        $shopRegionInfo = app(RegionInfoInterface::class);

        $amount = 20;
        $ordersCollection = $this->orderService->getLatest($amount)->with('shipments')->paginate($amount);

        $view = $this->renderOrderIndex();
        $view->with('orders', $ordersCollection)
            ->with('shopRegionInfo', $shopRegionInfo)
            ->with('perPage', $amount)
            ->with('resultsTypeTranslation', __('shop/orders.search_results'));

        return $view;
    }

    /**
     * Search for orders
     *
     * @param SearchRequest $request
     * @return View|\Illuminate\Http\Resources\Json\AnonymousResourceCollection
     */
    public function OrderSearch(SearchRequest $request)
    {
        $resultsPerPage = (is_numeric(Input::get('perPage')) ? (int) Input::get('perPage') : 5);
        $ordersCollection = $this->orderService->search(Input::all())->orderBy('created_at', 'desc')->with('shipments')->paginate($resultsPerPage);
        $ordersCollection->appends(Input::all()); //Add existing query string parameters to the current pagination links

        $shopRegionInfo = app(RegionInfoInterface::class);

        if (request()->ajax()) {
            //Return results as json
            return \App\Komma\Shop\Orders\Resources\Order::collection($ordersCollection);
        } else {
            $request->flash();

            $view = $this->renderOrderIndex();

            return $view->with('orders', $ordersCollection)
                        ->with('shopRegionInfo', $shopRegionInfo)
                        ->with('perPage', $resultsPerPage)
                        ->with('status', \Input::get('status'))
                        ->with('resultsTypeTranslation', __('shop/orders.search_results'));
        }
    }

    /**
     * Batch edit orders
     * @param Request $request
     * @return \Illuminate\Http\RedirectResponse
     * @throws \Illuminate\Auth\Access\AuthorizationException
     */
    public function batchEdit(Request $request)
    {
        //TODO add authorisation via policy
        $orderIds = \Input::get('order_ids');
        if (! $orderIds) {
            return redirect()->back()->withErrors(['general' => __('shop/orders.batch.no_orders_selected')]);
        }

        //Convert te order ids to integers instead of strings and use them to get the orders we need to batch edit
        $orderIds = array_map(function (string $orderId) {
            return (int) $orderId;
        }, $orderIds);
        $orders = Order::with(['customer', 'shipments'])->whereIn('id', $orderIds)->get();

        if (Input::has('create_shipments')) {
            //Authorize
            foreach ($orders as $order) {
                $this->authorize('createShipmentForOrder', $order);
            }

            //User pressed the create shipments button
            $shipments = $this->shipmentService->makeForOrders($orders);
            $shipments->each(function (Shipment $shipment) {
                $shipment->save();
            });
            $orders = $this->orderService->changeOrdersStatus($orders, OrderStatus::AWAITING_SHIPMENT);
            $orders->each(function (Order $order) {
                $this->orderMailService->mailCustomerAboutCurrentOrderStatus($order, true);
            });
            $shipmentCount = count($shipments);

            return redirect()->back()->withSuccess(trans_choice('shop/shipments.shipments_created', $shipmentCount, ['count' => $shipmentCount]));
        } elseif (Input::has('group_shipments')) {
            foreach ($orders as $order) {
                $this->authorize('createShipmentGroupForOrder', $order);
            }

            //User pressed the group shipments button
            $shipments = $orders->map(function (Order $order) {
                return $order->shipments;
            })->collapse();

            if ($shipments->count() == 0) {
                return redirect()->back()->withErrors(__('shop/shipmentgroups.no_shipmentGroup_created_no_shipments'));
            }
            $shipmentGroup = $this->shipmentGroupService->createForShipments($shipments);

            if (! $shipmentGroup) {
                return redirect()->back()->withErrors(__('shop/shipmentgroups.no_shipmentGroup_created'));
            }

            return redirect()->back()->withSuccess(trans_choice('shop/shipmentgroups.shipmentGroup_created', $shipmentGroup->shipments->count(), ['count' => $shipmentGroup->shipments->count(), 'id' => $shipmentGroup->id]));
        } elseif (Input::has('change_status') && Input::has('change_status_to')) {
            $this->orderService->changeOrdersStatus($orders, \Input::get('change_status_to'));
            $orders->each(function (Order $order) {
                $this->orderMailService->mailCustomerAboutCurrentOrderStatus($order, true);
            });

            return redirect()->back()->withSuccess(trans_choice('shop/orders.batch.status_changed', $orders->count(), ['count' => $orders->count(), 'status' => __('shop/orders.status.'.\Input::get('change_status_to'))]));
        }

        return redirect()->back()->withErrors(['general' => __('shop/orders.batch.edit_fail')]);
    }

    /**
     * This method handles the update functionality.
     * And is called by the edit form.
     * The method is route model binded via the RouteServiceProvider to the user class
     *
     * @param $idOrModel User|int
     * @return mixed
     * @throws \Exception
     * @throws \Throwable
     */
    public function update($idOrModel)
    {
        $this->authorize('store', $idOrModel);
        if (Input::has('create_shipment')) {
            $shipment = $this->shipmentService->makeForOrder($idOrModel);
            $shipment->save();

            return redirect()->back();
        }

        return parent::update($idOrModel);
    }

    /**
     * For the index controller action
     *
     * @return View
     */
    public function renderOrderIndex()
    {
        $modelId = ($this->forModelInstance) ? $this->forModelInstance->id : null;
        $saveRoute = $this->routeService->getSaveRoute($this->slug, $modelId);

        $successes = (Session::has('successes')) ? Session::get('successes') : new MessageBag();

        $siteSlug = ! $this->siteService->getCurrentSite()->exists ? null : $this->siteService->getCurrentSite()->slug;

        $thumbnail = '';
        if (is_a($this->forModelInstance, HasThumbnailInterface::class)) {
            $thumbnail = $this->forModelInstance->getThumbnail();
        }

        if (is_a($this->forModelInstance, DisplayNameInterface::class)) {
            $displayName = $this->forModelInstance->getDisplayName();
        } else {
            $displayName = $this->section->getSectionNewModel();
        }

        return \View::make('kms/shop/orders/index', [
            'sectionTitle'                 => $this->section->getSectionTitle(),
            'sectionSubtitle'              => $this->section->getSectionSubtitle(),
            'sectionTabs'                  => $this->section->getTabs(),
            'slug'                         => $this->slug,
            'siteSlug'                     => $siteSlug,
            'saveRoute'                    => $saveRoute,
            'successes'                    => $successes,
            'models'                       => $this->modelService->getModelsForSideBar(),
            'maxUploadSize'                => KommaHelpers::fileUploadMaxSize(),
            'maxPostSize'                  => KommaHelpers::maxPostSize(),
            'modelClassName'                 => $this->classModelName,
            'sortable'                     => $this->sortable,
            'showEntity'                   => $this->showEntity,
            'thumbnail'                    => $thumbnail,
            'displayName'                  => $displayName,
            'currentModel'                 => $this->forModelInstance,
            'submitButtonLabel'            => $this->section->getSubmitButtonLabel(),
            'preventNavigationTranslation' => json_encode(__('kms/prevent-navigation')),
        ]);
    }

    /**
     * Makes a full width view. The sidebar is not needed
     *
     * @return View
     */
    protected function makeView(): View
    {
        $tabslug = null !== Input::get('tabslug') ? Input::get('tabslug') : Session::get('tabslug', '');
        $sessionData = [
            'tabslug' => $tabslug,
        ];

        $modelId = ($this->forModelInstance) ? $this->forModelInstance->id : null;
        $saveRoute = $this->routeService->getSaveRoute($this->slug, $modelId);
        $successes = (Session::has('successes')) ? Session::get('successes') : new MessageBag();

        $thumbnail = '';
        if (is_a($this->forModelInstance, HasThumbnailInterface::class)) {
            $thumbnail = $this->forModelInstance->getThumbnail();
        }

        if (is_a($this->forModelInstance, DisplayNameInterface::class)) {
            $displayName = $this->forModelInstance->getDisplayName();
        } else {
            $displayName = $this->section->getSectionNewModel();
        }

//        $sideBarModels = $this->modelService->getModelsForSideBar();p
        $siteSlug = ! $this->siteService->getCurrentSite()->exists ? null : $this->siteService->getCurrentSite()->slug;

        return \View::make('kms/section.fullwidth', [
            'sectionTitle'                 => $this->section->getSectionTitle(),
            'sectionSubtitle'              => $this->section->getSectionSubtitle(),
            'sectionTabs'                  => $this->section->getTabs(),
            'slug'                         => $this->slug,
            'siteSlug'                     => $siteSlug,
            'saveRoute'                    => $saveRoute,
            'successes'                    => $successes,
            'models'                       => $this->modelService->getModelsForSideBar(),
            'maxUploadSize'                => KommaHelpers::fileUploadMaxSize(),
            'maxPostSize'                  => KommaHelpers::maxPostSize(),
            'modelClassName'                 => $this->classModelName,
            'sortable'                     => $this->sortable,
            'showEntity'                   => $this->showEntity,
            'thumbnail'                    => $thumbnail,
            'displayName'                  => $displayName,
            'currentModel'                 => $this->forModelInstance,
            'submitButtonLabel'            => $this->section->getSubmitButtonLabel(),
            'preventNavigationTranslation' => json_encode(__('kms/prevent-navigation')),
        ])->with($sessionData);
    }

    /**
     * Users hitting this controller method will get a form which tells them
     * if they need to pay for an order or if it has been paid already.
     * If they need to pay for an order they can follow a redirect to the PSP where
     * they actually can pay.
     *
     * Notice, the url is secured by a signature. Only users with the right signature
     * can view the link
     *
     * @param Request $request
     * @param Order $order
     * @see OrderController::
     * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
     */
    public function manualPaymentForm(Request $request, Order $order)
    {
        if (! $request->hasValidSignature()) {
            abort(401);
        } //Only allow signed routes.

        /** @var Transaction $latestTransaction */
        $latestTransaction = $order->transactions()->latest()->first();

        return view('shop.pages.checkout.manual_payment', [
            'order' => $order,
            'latestTransaction' => $latestTransaction,
        ]);
    }

    /**
     * @param Order $order
     * @return \Symfony\Component\HttpFoundation\BinaryFileResponse
     */
    public function viewInvoice(Order $order)
    {
        return $this->invoiceService->getForOrderAsPDF($order);
    }

    /**
     * @param Order $order
     * @return \Symfony\Component\HttpFoundation\StreamedResponse
     */
    public function downloadInvoice(Order $order)
    {
        return $this->invoiceService->getForOrderAsPDFDownload($order);
    }

    /**
     * @param Order $order
     * @return \Symfony\Component\HttpFoundation\BinaryFileResponse
     */
    public function createCreditInvoice(Order $order)
    {
        $order->credit_invoice_number = (string) $this->creditInvoiceNumberGenerator->next();
        $order->save();
        $this->creditInvoiceService->getForOrderAsView($order); //Generates it.

        return redirect()->back()->withSuccess(__('shop/orders.created_credit_invoice'));
    }

    /**
     * @param Order $order
     * @return \Symfony\Component\HttpFoundation\BinaryFileResponse
     */
    public function viewCreditInvoice(Order $order)
    {
        if ($order->credit_invoice_number) {
            return $this->creditInvoiceService->getForOrderAsPDF($order);
        } else {
            return redirect()->back()->withErrors(__('shop/orders.create_credit_invoice_first'));
        }
    }

    /**
     * @param Order $order
     * @return \Symfony\Component\HttpFoundation\StreamedResponse
     */
    public function downloadCreditInvoice(Order $order)
    {
        if ($order->credit_invoice_number) {
            return $this->creditInvoiceService->getForOrderAsPDFDownload($order);
        } else {
            return redirect()->back()->withErrors(__('shop/orders.create_credit_invoice_first'));
        }
    }
}