File: D:/HostingSpaces/SBogers10/shop.komma.nl/app/Shipments/ShipmentController.php
<?php
namespace App\Shipments;
use App\Orders\Kms\OrderService;
use App\Orders\Models\Order;
use App\Orders\OrderStatus;
use App\Shipments\Requests\SearchRequest;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\View\View;
use Komma\KMS\Core\SectionController;
use Illuminate\Support\Facades\Session;
use Illuminate\Support\MessageBag;
use Komma\KMS\Globalization\RegionInfoInterface;
use Komma\KMS\Helpers\KommaHelpers;
class ShipmentController extends SectionController
{
protected string $slug = "shipments";
protected string $classModelName = Shipment::class;
private ShipmentService $shipmentService;
private OrderService $orderService;
public function __construct()
{
$section = new ShipmentSection($this->slug);
$this->shipmentService = new ShipmentService();
$this->orderService = new OrderService();
parent::__construct($section);
}
public function show($model)
{
//If this works. Remove the shipment section....because this method overrides stuff.
$this->authorize('show', $model);
$view = $this->renderShipmentShow();
$view->with('shipment', $model);
return $view;
}
/**
* 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);
$resultsPerPage = (is_numeric(request()->get('perpage')) ? (int) request()->get('perpage') : 10);
$shipmentCollection = Shipment::paginate($resultsPerPage)->appends(['perpage' => $resultsPerPage]);
$view = $this->renderShipmentIndex();
$view->with('shipments', $shipmentCollection)
->with('shopRegionInfo', $shopRegionInfo)
->with('perpage', $resultsPerPage)
->with('resultsTypeTranslation', __('KMS::shipments.latest_shipments', ['amount' => $resultsPerPage]));
return $view;
}
/**
* Search for orders
*
* @param SearchRequest $request
* @return \Illuminate\Contracts\View\View|\Illuminate\Http\Resources\Json\AnonymousResourceCollection
*/
public function shipmentSearch(SearchRequest $request)
{
$resultsPerPage = (is_numeric($request->get('perpage')) ? (int) $request->get('perpage') : 5);
//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'), ShipmentStatus::getAsArray()) ? $request->get('status') : 'each'
];
$shipments = $this->shipmentService->search($searchFields)->orderBy('created_at', 'desc')->with('order')->paginate($resultsPerPage)->appends(['perpage' => $resultsPerPage]);
$shipments->appends($request->all()); //Add existing query string parameters to the current pagination links
$shopRegionInfo = app(RegionInfoInterface::class);
$request->flash();
$view = $this->renderShipmentIndex();
return $view->with('shipments', $shipments)
->with('shopRegionInfo', $shopRegionInfo)
->with('perpage', $resultsPerPage)
->with('status', $request->get('status'))
->with('resultsTypeTranslation', __('KMS::orders.search_results'));
}
/**
* For the index controller action
*
* @return View
*/
public function renderShipmentIndex() {
$modelId = ($this->forModelInstance) ? $this->forModelInstance->id : null;
$saveRoute = $this->modelService->getSaveRoute($this->slug, $modelId);
$successes = (Session::has('successes')) ? Session::get('successes') : new MessageBag();
$nonFulFilledOrders = $this->orderService->nonFulfilled()->get();
return view('KMS::shipments/index', [
'siteSlug' => !$this->siteService->getCurrentSite()->exists ? null : $this->siteService->getCurrentSite()->slug,
'section' => $this,
'showEntity' => $this->showEntity,
'slug' => $this->slug,
'saveRoute' => $saveRoute,
'successes' => $successes,
'nonFulFilledOrders' => $nonFulFilledOrders,
'maxUploadSize' => KommaHelpers::fileUploadMaxSize(),
'maxPostSize' => KommaHelpers::maxPostSize(),
'preventNavigationTranslation' => json_encode(__('kms/prevent-navigation'))
]);
}
/**
* For the index controller action
*
* @return View
*/
public function renderShipmentShow() {
$modelId = ($this->forModelInstance) ? $this->forModelInstance->id : null;
$saveRoute = $this->modelService->getSaveRoute($this->slug, $modelId);
$successes = (Session::has('successes')) ? Session::get('successes') : new MessageBag();
return view('KMS::shipments/show', [
'siteSlug' => !$this->siteService->getCurrentSite()->exists ? null : $this->siteService->getCurrentSite()->slug,
'section' => $this,
'showEntity' => $this->showEntity,
'slug' => $this->slug,
'saveRoute' => $saveRoute,
'successes' => $successes,
'maxUploadSize' => KommaHelpers::fileUploadMaxSize(),
'maxPostSize' => KommaHelpers::maxPostSize(),
'preventNavigationTranslation' => json_encode(__('kms/prevent-navigation'))
]);
}
/**
* Batch edit orders
* @param Request $request
* @return \Illuminate\Http\RedirectResponse
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function batchEdit(Request $request)
{
//Get shipments ids from the request, redirect back with an error if no shipments where selected
$shipmentIds = $request->get('shipment_ids');
if(!$shipmentIds && !$request->has('new')) return redirect()->back()->withErrors(['general' => __('KMS::shipments.batch.no_shipments_selected')]);
//Shipment adapter
$adapter = $this->shipmentService->getAdapter();
//Retrieve the shipments
$shipments = null;
if($shipmentIds) {
//Convert the ids to integers instead of strings and use them to get the orders we need to batch edit
$shipmentIds = array_map(function(string $orderId) {
return (int) $orderId;
}, $shipmentIds);
//Get the shipments that where selected
$shipments = Shipment::with(['order', 'orderedProducts'])->whereIn('id', $shipmentIds)->get();
}
//Handle batch actions. And return responses for them. Do this by delegating to services
if($request->has('change_status') && $request->has('change_status_to')) {
$statusToChangeTo = $request->get('change_status_to');
$trueOrError = $this->shipmentService->shipmentsCanChangeStatusTo($shipments, $statusToChangeTo);
if($trueOrError === true) {
$this->shipmentService->changeStatus($shipments, $statusToChangeTo);
return redirect()->back()->withSuccess(trans_choice('KMS::shipments.changed_status', [$shipments], ['count' => $shipments->count()]));
}
return redirect()->back()->withErrors(['general' => $trueOrError]);
} elseif($request->has('new')) {
$order = Order::find(intval($request->get('order')));
$shipment = $this->shipmentService->create($order);
return redirect()->back()->withSuccess(trans_choice('KMS::shipments.created', [$shipment], ['count' => 1]));
} elseif($request->has('delete')) {
$trueOrError = $this->shipmentService->delete($shipments);
if ($trueOrError === true) {
return redirect()->back()->withSuccess(trans_choice('KMS::shipments.deleted', $shipments, ['count' => $shipments->count()]));
} else {
return redirect()->back()->withErrors(['general' => $trueOrError]);
}
} elseif($request->has('notifyCarrier')) {
$notReadyToShipShipments = $shipments->filter(fn(Shipment $shipment) => !$shipment->can_be_announced);
if($notReadyToShipShipments->count() > 0) {
return redirect()->back()->withErrors(['general' => __('KMS::shipments.not_ready_to_ship_list', ['shipment_ids' => join(', ', $shipmentIds)])]);
}
$adapter->createShipments($shipments);
return redirect()->back()->withSuccess(trans_choice('KMS::shipments.created', $shipments, ['count' => count($shipments)]));
} elseif($request->has('cancelShipments')) {
$adapter->cancelShipments($shipments);
return redirect()->back()->withSuccess(trans_choice('KMS::shipments.canceled', $shipments->map(fn(Shipment $shipment) => $shipment->id), ['count' => $shipments->count()]));
} elseif($request->has('toCsv')) {
return $this->shipmentService->toCSVDownload($shipments);
}
return redirect()->back()->withErrors(['general' => __('KMS::shipments.batch.edit_fail')]);
}
/**
* Notify a shipment provider that a package can be shipped
*/
public function notifyCarrier() {
$adapter = $this->shipmentService->getAdapter();
$shipments = Shipment::whereIn('id', request()->get('shipment_ids', []))->get();
$adapter->createShipments($shipments);
return response()->json(null, Response::HTTP_NO_CONTENT);
}
/**
* Cancels a shipment.
* If there is a problem, the adapter should abort the request by using the abort helper.
*
* @param Request $request
*
* @return JsonResponse
*/
public function cancelShipments(Request $request) {
$adapter = $this->shipmentService->getAdapter();
$shipments = Shipment::whereIn('id', request()->get('shipment_ids', []))->get();
$adapter->cancelShipments($shipments);
return response()->json(null, Response::HTTP_NO_CONTENT);
}
/**
* @param Request $request
* @param Shipment $shipment
*
* @return \Symfony\Component\HttpFoundation\StreamedResponse|null
*/
public function downloadLabel(Request $request, Shipment $shipment) {
return $this->shipmentService->getAdapter()->getShipmentLabelDownloadResponse($shipment);
}
/**
* Called by the Shipment service provider to tell us that something happened with a shipment.
* Or something related to that
* In general used for updating a shipment
*/
public function processShipmentProviderResponse()
{
$adapter = $this->shipmentService->getAdapter();
return $adapter->processShipmentProviderResponse();
}
}