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/SBogers10/shop.komma.nl/app/Orders/Kms/OrderController.php
<?php

namespace App\Orders\Kms;


use Illuminate\Support\Facades\Request;
use Illuminate\View\View;
use Komma\KMS\Core\Attributes\Models\Traits\HasThumbnailInterface;
use Komma\KMS\Core\Entities\DisplayNameInterface;
use Komma\KMS\Core\SectionController;
use App\Invoicing\CreditInvoiceService;
use App\Invoicing\InvoiceService;
use App\Orders\CreditInvoiceNumberSequence;
use App\Orders\Models\Order;
use App\Orders\OrderStatus;
use App\Orders\SearchRequest;
use App\Payment\Transaction;
use App\Shipments\ShipmentService;
use Illuminate\Support\Facades\Session;
use Illuminate\Support\MessageBag;
use Komma\KMS\Globalization\RegionInfoInterface;
use Komma\KMS\Helpers\KommaHelpers;

class OrderController extends SectionController
{
    protected string $slug = "orders";

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

    private OrderService $orderService;
    private ShipmentService $shipmentService;
    private OrderMailService $orderMailService;
    private InvoiceService $invoiceService;
    private CreditInvoiceService $creditInvoiceService;
    private CreditInvoiceNumberSequence $creditInvoiceNumberGenerator;

    /**
     * Constructor
     */
    public function __construct()
    {
        $orderSection = new OrderSection($this->slug);
        $this->orderService = new OrderService();

        $this->orderMailService = new OrderMailService();
        $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);

        $shopRegionInfo = app(RegionInfoInterface::class);

        $perpage = request()->get('perpage', 10);
        $ordersCollection = Order::with(['latestTransactions'])->paginate($perpage)->appends(['perpage' => $perpage]);

        $view = $this->renderOrderIndex();
        $view->with('orders', $ordersCollection)
            ->with('shopRegionInfo', $shopRegionInfo)
            ->with('perpage', $perpage)
            ->with('resultsTypeTranslation', __('KMS::orders.search_results'));
        return $view;
    }

    /**
     * Search for orders
     *
     * @param SearchRequest $request
     * @return View|\Illuminate\Http\Resources\Json\AnonymousResourceCollection
     */
    public function OrderSearch(SearchRequest $request)
    {
        //Determine how many results per page we need to show, or simply 5 if not specified by the user.
        $resultsPerPage = (is_numeric($request->get('perpage')) ? (int) $request->get('perpage') : 10);

        //Build an array of search fields to search a given value in;
        $searchFields = [
            $request->get('search_for') => $request->get('search_value'),
            'status' => $request->has('status') && in_array($request->get('status'), OrderStatus::getAsArray()) ? $request->get('status') : 'each'
        ];

        //Search
        $ordersCollectionPaginator = $this->orderService->search($searchFields)->orderBy('created_at', 'desc')->paginate($resultsPerPage)->appends(['perpage' => $resultsPerPage]);
        $ordersCollectionPaginator->appends($request->all()); //Add existing query string parameters to the current pagination links

        //Get the region info for the shop
        $shopRegionInfo = app(RegionInfoInterface::class);

        //Make the input a user entered, available for the next request.
        $request->flash();

        //Return to the order index page with the found orders
        $view = $this->renderOrderIndex();
        return $view->with('orders', $ordersCollectionPaginator)
                    ->with('shopRegionInfo', $shopRegionInfo)
                    ->with('perpage', $resultsPerPage)
                    ->with('status', $request->get('status'))
                    ->with('resultsTypeTranslation', __('KMS::orders.search_results'));
    }

    /**
     * Batch edit orders
     * @param Request $request
     * @return \Illuminate\Http\RedirectResponse
     * @throws \Illuminate\Auth\Access\AuthorizationException
     */
    public function batchEdit(Request $request)
    {
        $orderIds = \Request::get('order_ids');
        if(!$orderIds) return redirect()->back()->withErrors(['general' => __('KMS::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'])->whereIn('id', $orderIds)->get();

        if(Request::has('change_status') && Request::has('change_status_to')) {
            $this->orderService->changeOrdersStatus($orders, \Request::get('change_status_to'));
            $orders->each(function(Order $order) {
                $this->orderMailService->mailCustomerAboutCurrentOrderStatus($order, true);
            });
            return redirect()->back()->withSuccess(trans_choice('KMS::orders.batch.status_changed', $orders->count(), ['count' => $orders->count(), 'status' => __('KMS::orders.status.'.\Request::get('change_status_to'))]));
        }

        return redirect()->back()->withErrors(['general' => __('KMS::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 Order|int
     * @return mixed
     * @throws \Exception
     * @throws \Throwable
     */
    public function update($idOrModel)
    {
        $this->authorize('store', $idOrModel);

        if(request()->get('create_shipment')) {
            $shipment = $this->shipmentService->create($idOrModel);
            return redirect(route('shipments.show', ['shipment' => $shipment]));
        }

        return parent::update($idOrModel);
    }


    /**
     * For the index controller action
     *
     * @return View
     */
    public function renderOrderIndex() {
        $modelId = ($this->forModelInstance) ? $this->forModelInstance->id : null;
        $saveRoute = $this->modelService->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::orders/index', [
            'sectionTitle'                 => $this->section->getSectionTitle(),
            '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,
            '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 !== Request::get('tabslug') ? Request::get('tabslug') : Session::get('tabslug', '');
        $sessionData = [
            'tabslug' => $tabslug
        ];

        $modelId = ($this->forModelInstance) ? $this->forModelInstance->id : null;
        $saveRoute = $this->modelService->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(),
            '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,
            '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 \Illuminate\Http\Request $request
     * @param Order $order
     * @see OrderApiController::
     * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
     */
    public function manualPaymentForm(\Illuminate\Http\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(__('KMS::orders.created_credit_invoice'));
    }

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

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