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'));
}
}
}