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/brameda/brameda.nl/app/Komma/Shop/ShipmentGroups/ShipmentGroupController.php
<?php

namespace App\Komma\Shop\ShipmentGroups;

use App\Komma\Globalization\RegionInfo;
use App\Komma\Kms\Core\SectionController;
use App\Komma\Shop\Orders\Kms\OrderService;
use App\Komma\Shop\Orders\Models\Order;
use App\Komma\Shop\Orders\OrderStatus;
use App\Komma\Shop\Shipments\Shipment;
use App\Komma\Shop\Shipments\ShipmentStatus;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Input;
use Illuminate\Support\Facades\Log;

class ShipmentGroupController extends SectionController
{
    protected $slug = "shipmentgroup";

    protected $forModelName = ShipmentGroup::class;
    /**
     * @var ShipmentGroupService
     */
    private $shipmentGroupService;

    public const LATEST_AMOUNT = 20;

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

    public function __construct(ShipmentGroupSection $section, ShipmentGroupService $shipmentGroupService, OrderService $orderService)
    {
        parent::__construct($section);
        $this->shipmentGroupService = $shipmentGroupService;
        $this->orderService = $orderService;
    }

    /**
     * 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->forModelName);

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

        $shopRegionInfo = new RegionInfo('NL'); //Shop was build with euros in mind and the Dutch language as the primary one

        $shipmentGroupCollection = $this->shipmentGroupService->getLatest(self::LATEST_AMOUNT)->with(['shipments', 'shipments.order'])->get();

        $section->setForModelName($this->forModelName);

        $view = $section->renderShipmentGroupIndex();
        $view->with('shipmentGroups', $shipmentGroupCollection)
            ->with('shopRegionInfo', $shopRegionInfo)
            ->with('resultsTypeTranslation', __('shop/shipmentgroups.latest_shipmentgroups', ['amount' => self::LATEST_AMOUNT]));
        return $view;
    }

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

        $shopRegionInfo = new RegionInfo('NL'); //Shop was build with euros in mind and the Dutch language as the primary one

        if(request()->ajax()) {
            //Return results as json
            //Make a ShipmentGroup json resource and return a collection of that if you need this functionality
        } else {
            $request->flash();

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

            $section->setForModelName($this->forModelName);
            $view = $section->renderShipmentGroupIndex();
            return $view->with('shipmentGroups', $shipmentGroups)
                ->with('shopRegionInfo', $shopRegionInfo)
                ->with('perPage', $resultsPerPage)
                ->with('status', \Input::get('status'))
                ->with('resultsTypeTranslation', __('shop/orders.search_results'));
        }
    }

    /**
     * Create and open a shipment group
     */
    public function createAndOpenShipmentGroup()
    {
        /** @var ShipmentGroup $model */
        $model = $this->shipmentGroupService->newModel();
        $model->status = ShipmentGroupStatus::PENDING;
        $model->save();
//        return redirect()->to(route('shipmentgroups.show', ['shipmentgroup' => $model]));
        return redirect()->back();
    }

    /**
     * This method handles the update functionality.
     * And is called by the edit form.
     *
     * @param $idOrModel ShipmentGroup|int
     * @return mixed
     * @throws \Exception
     */
    public function update($idOrModel)
    {
        $result = $this->handleBatchActions($idOrModel);
        if($result) return $result;

        //Or just save / update like normal
        return parent::update($idOrModel);
    }

    /**
     * Handles batch actions and return an appropriate view
     *
     * @param Model $model
     * @return \Illuminate\Http\RedirectResponse|null
     * @throws \Illuminate\Auth\Access\AuthorizationException
     */
    public function handleBatchActions(Model $model)
    {
        $this->authorize('batch_edit', $model);

        //Process batch actions if needed
        $shipmentIds = Input::get('shipment_ids');
        if($shipmentIds) $shipmentIds =array_map(function($shipmentId) { return (int) $shipmentId; }, $shipmentIds); //Make sure the ids are integers
        $successes = [];

        if(Input::has('remove_from_group') || Input::has('add_to_group') || Input::has('ship')) {
            //Prepare the view
            $routeParameters = [];
            $site = $this->siteService->getCurrentSite();
            if($site->exists) $routeParameters['siteSlug'] = $site->slug;
            $routeParameters[$this->slug] = $model;
            $viewUrl = action('\\'.get_class($this) . '@show', $routeParameters);
            $view = redirect($viewUrl);

            //Get the shipments
            $shipments = ($shipmentIds) ? Shipment::whereIn('id', $shipmentIds)->get(['id']) : new Collection();
            $shipmentsCount = $shipments->count();

            //If the shipment group is new, we need to save it first before we can add shipments to it.
            if(!$model->exists) $model->save();

            //Process the batch actions
            if (Input::has('remove_from_group')) {
                if(!$shipmentIds) return redirect()->back()->withErrors(['general' => __('shop/shipments.batch.no_shipments_selected')]);
                $this->shipmentGroupService->removeShipmentsFromGroup($shipments);
                $successes[] = trans_choice('shop/shipmentgroups.removed', $shipmentsCount, ['count' => $shipmentsCount]);
            } elseif (Input::has('add_to_group')) {
                if(!$shipmentIds) return redirect()->back()->withErrors(['general' => __('shop/shipments.batch.no_shipments_selected')]);
                $this->shipmentGroupService->addShipmentsToGroup($model, $shipments);
                $successes[] = trans_choice('shop/shipmentgroups.added', $shipmentsCount, ['count' => $shipmentsCount]);
            } elseif (Input::has('ship')) {
                $shipmentGroup = $this->shipmentGroupService->ship($model); //ship the shipments in the shipment group

                //Get the orders of which all the shipments are partially shipped or delivered. This means that we can instruct the order service to update the order status to "partially shipped" or "delivered".
                $shipmentGroup->shipments()->with(['order', 'order.shipments'])->get(['id', 'order_id'])->map(function(Shipment $shipment) {
                    return $shipment->order;
                })->each(function(Order $order) {
                    //Determine if the order is completely shipped or partially shipped.
                    $completelyShipped = true;
                    $order->shipments->each(function(Shipment $shipment) use ($order, &$completelyShipped){
                        \Log::debug($shipment->status);
                        if($shipment->status == ShipmentStatus::NEW || $shipment->status == ShipmentStatus::EXCEPTION || $shipment->status == ShipmentStatus::CARRIER_NOTIFIED) {
                            $completelyShipped = false;
                            return false; //break out of the each loop.
                        }
                    });

                    //Tell the order service that the order is completely shipped or not. Notice that this may be different than the shipment group status
                    $this->orderService->changeOrderStatus($order, ($completelyShipped) ? OrderStatus::SHIPPED : OrderStatus::PARTIALLY_SHIPPED);
                });

                $successes[] = trans('shop/shipmentgroups.shipped');
            }

            $view->withSuccess(implode(PHP_EOL, $successes));
            return $view;
        }
        return null;
    }
}