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/farmfun.komma.pro/app/Komma/Reservations/Kms/ReservationController.php
<?php

namespace App\Komma\Reservations\Kms;

/**
 * @author      Komma <info@komma.pro>
 * @copyright   (c) 2012-2016, Komma
 */

use App\Http\Requests\AppendItemToReservationInKms;
use App\Komma\Availability\AvailabilityService;
use App\Komma\Availability\Types\Availability;
use App\Komma\Kms\Core\SectionController;
use App\Komma\Locations\Models\Location;
use App\Komma\Products\Models\Product;
use App\Komma\Reservations\Models\Reservation;
use App\Komma\Reservations\Models\ReservationItem;
use App\Komma\Shop\Products\Product\ProductTranslation;
use App\Komma\Teamleader\Resources\Deal;
use App\Komma\Teamleader\TeamleaderApi;
use App\Mail\ClientReminderMail;
use App\Mail\ResendReservationAdminMail;
use App\Mail\ResendReservationMail;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\Session;

final class ReservationController extends SectionController
{
    protected $slug = 'reservations';

    protected $classModelName = Reservation::class;

    private $searchPlaceholder = 'Zoeken...  |  Druk op Enter om alles te doorzoeken';

    public function __construct()
    {
        $reservationSection = new ReservationSection($this->slug);
        parent::__construct($reservationSection);
        $this->modelService = app(ReservationService::class);
    }

    public function index()
    {
//        $this->takeOverProductPricing();
        if (request()->has('search')) {
            return redirect()->route('reservations.search', ['q' => request()->get('search')]);
        }
        if (request()->has('teamleader')) {
            return redirect()->route('reservations.teamleader', ['id' => request()->get('teamleader')]);
        }
        $view = parent::index();

        $view->with('searchPlaceholder', $this->searchPlaceholder);
        $view->with('importTeamleader', 'show');

        return $view;
    }

    public function archive()
    {
        $this->authorize('index', $this->classModelName);

        if (request()->has('search')) {
            return redirect()->route('reservations.search', ['q' => request()->get('search')]);
        }

        //Create a root model if the modelClassName instance implements the treeInterface
        $this->modelService->createRootTreeModelIfNeeded();

        //Disable the right pane
        $this->showEntity = false;

        $view = $this->render(null);

        $models = $this->modelService->getArchiveModelsForSideBar();

        $view->with('sectionTitle', 'Archief');
        $view->with('differ_slug', 'reservations_archive');
        $view->with('models', $models);

        if (count($models) === 100) {
            $view->with('sectionMessage', 'Laatste 100 reserveringen');
        }

        $view->with('searchPlaceholder', $this->searchPlaceholder);

        return $view;
    }

    public function search()
    {
        $this->authorize('index', $this->classModelName);

        if (request()->has('search')) {
            return redirect()->route('reservations.search', ['q' => request()->get('search')]);
        }

        //Create a root model if the modelClassName instance implements the treeInterface
        $this->modelService->createRootTreeModelIfNeeded();

        //Disable the right pane
        $this->showEntity = false;

        $view = $this->render(null);

        $view->with('differ_slug', 'reservations_search');

        if (empty(request()->get('q'))) {
            $view->with('sectionMessage', 'Geen zoekresultaten');
            $view->with('models', []);
        } else {
            list($models, $count) = $this->modelService->searchModelsForSidebar(request()->get('q'));
            $view->with('models', $models);

            if ($count <= 100) {
                $view->with('sectionMessage', $count.' zoekresultaten');
            } else {
                $view->with('sectionMessage', $count.' zoekresultaten.<br/>Laatste 100 worden getoond.');
            }
        }

        $view->with('searchPlaceholder', $this->searchPlaceholder);

        return $view;
    }

    public function teamleader()
    {
        $this->authorize('index', $this->classModelName);

        if (request()->has('teamleader')) {
            return redirect()->route('reservations.teamleader', ['id' => request()->get('teamleader')]);
        }

        //Disable the right pane
        $this->showEntity = false;

        $view = $this->render(null);
        if (empty(request()->get('id'))) {
            $view->with('sectionMessage', 'Geen Teamleader ID');
            $view->with('models', []);
        } else {
            $view->with('sectionMessage', 'Teamleader import');
            $view->with('models', []);

            try {
                $teamLeaderApi = new TeamleaderApi();
                // https://developer.teamleader.eu/#/reference/deals/deals/deals.info
                $deal = $teamLeaderApi->deal->info(request()->get('id'));
                $view->with('teamleaderDeal', $deal->data);

                // Check if deal is already in KMS
                $reservation = Reservation::where('reservation_number', 'like', 'Deal '.$deal->data->reference.'%')->first();
                $view->with('kmsReservation', $reservation !== null);
                $view->with('reservation', $reservation);

            } catch (\Exception $e) {
                $view->with('no_deal_id', request()->get('id'));
            }

        }

        $view->with('reservationId', Session::get('reservationId') ?? '');
        $view->with('importTeamleader', 'show');
        $view->with('customView', 'kms.partials.entity.add_teamleader_deal');

        return $view;
    }

    public function teamleaderImport(Request $request)
    {
        $teamLeaderId = $request->get('id');
        if (empty($teamLeaderId)) return redirect()->back();

        $teamLeaderApi = new TeamleaderApi();
        $deal = $teamLeaderApi->deal->info($teamLeaderId);

        $event_date = '1970-01-01';

        $location = Location::where('teamleader_department_id', $deal->data->department->id)->first();
        if(! $location) {
            dd('Kon locatie met ID '.$deal->data->department->id.' niet oplossen voor:', $deal);
        }
        $locationId = $location->id;

        foreach ($deal->data->custom_fields as $customField) {
            if ($customField->definition->id === Deal::$custom_fields_ids['event_date']) $event_date = $customField->value;
        }

        if (isset($deal->data->lead->customer) && $deal->data->lead->customer->type === 'company' && ! empty($deal->data->lead->customer->id)) {
            $company = $teamLeaderApi->company->info($deal->data->lead->customer->id);
        }
        if (isset($deal->data->lead->contact_person) && $deal->data->lead->contact_person->type === 'contact' && ! empty($deal->data->lead->contact_person->id)) {
            $contact = $teamLeaderApi->contact->info($deal->data->lead->contact_person->id);
        }
        if (! empty($deal->data->quotations[0]->id)) {
            $quotation = $teamLeaderApi->quotation->info($deal->data->quotations[0]->id);
        }

        $extraProductId = ProductTranslation::where('name', '=', 'EXTRA')->pluck('product_id')->first() ?? 0;

        $reservation = new Reservation();
        $reservation->order_id = null;
        $reservation->reservation_number = 'Deal '.$deal->data->reference.' '.$deal->data->title;
        $reservation->po_number = $deal->data->purchase_order_number;
        $reservation->status = 0;
        $reservation->date = $event_date;
        $reservation->location_id = $locationId;
        if (isset($company) && isset($company->data)) {
            $reservation->company_name = $company->data->name;
        }
        if (isset($contact) && isset($contact->data)) {
            $reservation->first_name = $contact->data->first_name;
            $reservation->name_preposition = '';
            $reservation->last_name = $contact->data->last_name;
            $reservation->email = $contact->data->emails[0]->email ?? '';
            $reservation->phone = $contact->data->telephones[0]->number ?? '';
        }
        $reservation->remarks = $deal->data->summary;
        $reservation->reason = '';

        $reservation->save();

        if (isset($quotation->data)) {
            foreach ($quotation->data->grouped_lines[0]->line_items as $lineItem) {
                $reservationItem = new ReservationItem();
                $reservationItem->reservation_id = $reservation->id;
                $reservationItem->date = $event_date;
                $reservationItem->location_id = $locationId;
                $reservationItem->start_time = ''; // onbekend vanuit Teamleader
                $reservationItem->end_time = ''; // onbekend vanuit Teamleader

                $knownProductFound = false;
                if (isset($lineItem->product->id)) {
                    $product = $teamLeaderApi->product->info($lineItem->product->id);
                    if (! empty($product->data->code)) {
                        $reservationItem->product_id = str_replace('PROD-', '', $product->data->code);
                        $knownProductFound = true;
                    }
                }
                if ($knownProductFound === false) {
                    // Save as EXTRA product if unknown product is imported
                    $reservationItem->product_id = $extraProductId;
                    $reservationItem->remarks = $lineItem->description;
                }
                $reservationItem->quantity = $lineItem->quantity ?? 0;
                $reservationItem->price_each_unit = ($lineItem->unit_price->amount * 100) ?? 0;
                $reservationItem->price_start_up = 0;
                $reservationItem->price_total = ($lineItem->total->tax_exclusive->amount * 100) ?? 0;

                $reservationItem->save();
            }
        }

        return redirect()
            ->route('reservations.show', ['reservation' => $reservation->id])
            ->with('success', 'De reservering is geïmporteerd.');
    }

    private function takeOverProductPricing(): void
    {
//        $items = ReservationItem::with('product', 'location','reservation', 'reservation.order', 'reservation.order.lines')->get();
        $items = ReservationItem::with('product', 'location')->get();

        foreach ($items as $item) {
//            if(!$item->reservation->order_id || $item->created_at < Carbon::create(2021) || in_array($item->reservation->order_id, [54, 55])) continue;
//            if(in_array($item->reservation_id, [120,121])) dd($item);

            $item->price_each_unit = $item->product->price_each_unit;
            $item->price_start_up = $item->product->price_start_up;

            $availability = new Availability($item->product, $item->location);
            $availability->amountOfPersons = $item->quantity;

            $item->price_total = $availability->getTotal(true, false);
            $item->save();
        }
    }
    public function edit($model)
    {
        if (request()->has('search')) {
            return redirect()->route('reservations.search', ['q' => request()->get('search')]);
        }

        $model->load('items', 'location', 'location.boundProducts');
        $view = parent::edit($model);

        // Append the products of the location as potential activities
        if (isset($model->location) && isset($model->location->boundProducts) && $model->location->boundProducts->isNotEmpty()) {
            $modelActivitiesIds = $model->items->pluck('product_id')->toArray();

            /** @var Collection $optionalProducts */
            $optionalProducts = $model->location->boundProducts->except($modelActivitiesIds);

            // Load the translation if missing
            if ($optionalProducts->isNotEmpty()) {
                $optionalProducts->loadMissing('translation');
            }

            $view->with('optionalProducts', $optionalProducts);
        }

        if (request()->has('q')) {
            list($models, $count) = $this->modelService->searchModelsForSidebar(request()->get('q'));
            $view->with('models', $models);

            if ($count <= 100) {
                $view->with('sectionMessage', $count.' zoekresultaten');
            } else {
                $view->with('sectionMessage', $count.' zoekresultaten.<br/>Laatste 100 worden getoond.');
            }
        } else {
            // Load past models when opening
            if ($model->date <= today()) {
                $models = $this->modelService->getArchiveModelsForSideBar();

                $view->with('models', $models);
                $view->with('sectionTitle', 'Archief');
                $view->with('differ_slug', 'reservations_archive');
                if (count($models) === 100) {
                    $view->with('sectionMessage', 'Laatste 100 reserveringen');
                }
            }
        }

        $view->with('searchPlaceholder', $this->searchPlaceholder);

        return $view;
    }

    /**
     * @param Location $location
     * @return mixed
     * @throws \Illuminate\Auth\Access\AuthorizationException
     */
    public function planning(Location $location)
    {
        $this->authorize('show', $location);

        //Disable the right pane
        $this->showEntity = false;

        $location->loadMissing('availability');
        $reservationItems = $this->modelService->getReservationItemsFrom($location);
        $blockOutItems = $this->modelService->getBlockOutsFrom($location);
        $calendarNotes = $this->modelService->getNotesFrom($location);

        return \View::make('kms/section.planning', [
            'location' => $location,
            'reservationItems' => $reservationItems,
            'blockOutItems' => $blockOutItems,
            'calendarNotes' => $calendarNotes,
        ]);
    }

    /**
     * @param AppendItemToReservationInKms $request
     * @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
     * @throws \Illuminate\Contracts\Container\BindingResolutionException
     */
    public function appendToReservation(AppendItemToReservationInKms $request)
    {
        $reservation = Reservation::find($request->input('reservation_id'))->load('location', 'location.availability');
        $dayInfo = $reservation->location->availability->infoForDay($reservation->getDateAsDateTime());

        $product = Product::find($request->input('product_id'));

        /** @var AvailabilityService $availabilityService */
        $availabilityService = app()->make(AvailabilityService::class);
        $timeSlots = $availabilityService->makeTimeSlots($dayInfo, $product->system_duration, $product->duration);

        // TODO? add availability check;
        // Make the first selected
//        $firstTimeSlot = $timeSlots->where('locked', '=', false)->first();
        $firstTimeSlot = $timeSlots->first();

        $availability = new Availability($product, $reservation->location);
        $availability->amountOfPersons = (int) $request->input('quantity');

        $reservationItem = new ReservationItem([
            'date' => $reservation->date,
            'location_id' => $reservation->location->id,
            'start_time' => $firstTimeSlot->start->format('H:i:s'),
            'end_time' => $firstTimeSlot->end->format('H:i:s'),
            'product_id' => $product->id,
            'quantity' => $request->input('quantity'),
            'remarks' => $request->input('remarks'),

            'price_each_unit' => $product->price_each_unit,
            'price_start_up' => $product->price_start_up,
            'price_total' => $availability->getTotal(true, false),

        ]);

        $reservation->items()->save($reservationItem);

        // redirect to tab Activiteiten after adding activity to reservation
        return redirect(route('reservations.show', ['reservation' => $reservation->id, '#Activiteiten']))->with(['success' => __('kms/global.activity_saved')]);
    }

    /**
     * @param Reservation $reservation
     * @param Product $product
     * @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
     */
    public function deleteItemFromReservation(Reservation $reservation, Product $product)
    {
        $reservation->items()->where('product_id', $product->id)->delete();

        return redirect(route('reservations.show', ['reservation' => $reservation->id]))->with(['success' => __('kms/global.activity_deleted')]);
    }

    public function deleteItemTrashedProductFromReservation(Reservation $reservation, ReservationItem $reservationItem) {
        $reservation->items()->where('id', $reservationItem->id)->delete();

        return redirect(route('reservations.show', ['reservation' => $reservation->id]))->with(['success' => __('kms/global.activity_deleted')]);
    }

    /**
     * @param Reservation $reservation
     * @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
     * @throws \Illuminate\Contracts\Container\BindingResolutionException
     */
    public function resendClientReservation(Reservation $reservation)
    {
//        return new ResendReservationMail($reservation);
        Mail::send(new ResendReservationMail($reservation));

        return redirect(route('reservations.show', ['reservation' => $reservation->id]))->with(['success' => __('kms/reservations.resend_client_mail')]);
    }

    /**
     * @param Reservation $reservation
     * @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
     * @throws \Illuminate\Contracts\Container\BindingResolutionException
     */
    public function resendLocationReservation(Reservation $reservation)
    {
//        return new ResendReservationAdminMail($reservation);
        Mail::send(new ResendReservationAdminMail($reservation));

        return redirect(route('reservations.show', ['reservation' => $reservation->id]))->with(['success' => __('kms/reservations.resend_admin_mail')]);
    }

    /**
     * @param Reservation $reservation
     * @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
     */
    public function sendReminderMail(Reservation $reservation)
    {
//        return new ClientReminderMail($reservation);
        Mail::to($reservation->email)->send(new ClientReminderMail($reservation));
        $reservation->client_reminder_sent = true;
        $reservation->save();

        return redirect(route('reservations.show', ['reservation' => $reservation->id]))->with(['success' => __('kms/reservations.send_reminder_mail')]);
    }
}