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