File: D:/HostingSpaces/farmfun/reserveren.farmfun.be/app/Komma/Reservations/ReservationService.php
<?php
namespace App\Komma\Reservations;
use App\Komma\Base\Service;
use App\Komma\Locations\Models\Location;
use App\Komma\Orders\Models\Order;
use App\Komma\Reservations\Models\RequestedProgram;
use App\Komma\Reservations\Models\Reservation;
use App\Komma\Reservations\Models\ReservationItem;
use App\Komma\ShoppingCart\Interfaces\ShoppingCartInterface;
use App\Mail\ClientAlmostReadyMail;
use App\Mail\ClientFavourMail;
use App\Mail\ClientInformationMail;
use App\Mail\ClientReminderMail;
use App\Mail\ClientReminderSimpleMail;
use App\Mail\LocationDayPlanMail;
use App\Mail\ProgramReminderMail;
use Carbon\Carbon;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\URL;
class ReservationService extends Service
{
/**
* Create reservation out of the shopping cart and order
*
* @param ShoppingCartInterface $shoppingCart
* @param Order $order
* @return Reservation
*/
public function createReservation(ShoppingCartInterface $shoppingCart, Order $order): Reservation
{
$reservation = null;
\DB::transaction(function () use ($shoppingCart, $order, &$reservation) {
/** @var Reservation $reservation */
$reservation = new Reservation();
$reservation->order_id = $order->id;
$reservation->reservation_number = $order->order_reservation_number;
$reservation->po_number = $order->po_number;
$reservation->status = Reservation::STATUS_NEW;
$reservation->date = $shoppingCart->getDate();
$reservation->location_id = $shoppingCart->getLocation()->id;
$reservation->company_name = $order->company_name;
$reservation->first_name = $order->first_name;
$reservation->name_preposition = $order->name_preposition;
$reservation->last_name = $order->last_name;
$reservation->email = $order->email;
$reservation->phone = $order->phone;
$reservation->remarks = $order->remarks;
$reservation->save();
//Loop over all shopping cart items and create reservation items for them.
foreach ($shoppingCart->getItems() as $shoppingCartItem) {
$timeSlot = $shoppingCartItem->getSelectedTimeSlot();
$product = $shoppingCartItem->getProduct();
$reservationItem = new ReservationItem([
'date' => $shoppingCart->getDate(),
'location_id' => $shoppingCartItem->getLocation()->id,
'start_time' => isset($timeSlot->start) ? $timeSlot->start->format('H:i:s') : null,
'end_time' => isset($timeSlot->end) ? $timeSlot->end->format('H:i:s') : null,
'product_id' => $product->id,
'quantity' => (isset($shoppingCartItem->amountOfPersons) ? $shoppingCartItem->amountOfPersons : 1), // If amount of persons is undefined, it has a fixed amount like Bumperball
'remarks' => $shoppingCartItem->notification,
'price_each_unit' => $product->price_each_unit,
'price_start_up' => $product->price_start_up,
'price_total' => $shoppingCartItem->getTotal(true, false),
]);
$reservation->items()->save($reservationItem);
}
});
return $reservation;
}
public function previewClientReminder()
{
$reservation = Reservation::withTrashed()
->where('id', 19)
->with('items', 'items.product', 'items.product.translation', 'location')
->first();
return new ClientReminderMail($reservation);
}
public function previewLocationDayPlan()
{
$date = Carbon::create(2020, 3, 7);
// $this->sendDayPlansToLocations($date);
$reservations = Reservation::with('items', 'items.product', 'items.product.translation')
->where('location_id', '1')
->get();
$location = Location::with('translation')
->has('translation')
->where('id', 1)
->first();
return new LocationDayPlanMail($location, $reservations, $date);
}
/**
* Send the day plans to the location if there are reservation for the given date.
* Will be used
*
* @param Carbon $date
*/
public function sendDayPlansToLocations(Carbon $date)
{
$reservationsGroupByLocation = Reservation::where('date', $date->format('Y-m-d'))
->with('items', 'items.product', 'items.product.translation')
->get()
->groupBy('location_id');
if ($reservationsGroupByLocation->count() == 0) {
Log::channel('daily')->info(self::class . ': No day plan mail has been sent.');
// Log::info(self::class.': No day plan mail has been sent.');
return;
}
foreach ($reservationsGroupByLocation as $locationId => $reservations) {
try {
$location = Location::with('translation')
->has('translation')
->where('id', $locationId)
->first();
Mail::to($location->email)->send(new LocationDayPlanMail($location, $reservations, $date));
Log::channel('daily')->info(self::class . ': ' . $location->translation->name . ' day plan has been send for ' . $reservations->count() . ' reservation.');
} catch (\Exception $e) {
Log::warning($e->getMessage());
}
}
}
/**
* Send the client reminders by looking up the amount of days before we send the mails and add it to the given date as range indication.
* Then send all the reservation which haven't been sent and are within the range.
*
* @param Carbon $date
*/
public function sendClientReminders(Carbon $date)
{
$dateOfSendsReminderMails = clone $date;
$dateOfSendsReminderMails = $dateOfSendsReminderMails->addDays(config('site.send_client_reminder_days'))->startOfDay();
$reservationsToSend = Reservation::where('date', '<=', $dateOfSendsReminderMails)
->where('email', '!=', '')
->where(function ($query) {
$query->where('client_reminder_sent', '!=', 1)
->orWhereNull('client_reminder_sent');
})
->with('items', 'items.product', 'items.product.translation', 'location')
->get();
if ($reservationsToSend->count() == 0) {
Log::channel('daily')->info(self::class . ': No client reminders mail has been sent.');
return;
}
$sendCounter = 0;
foreach ($reservationsToSend as $reservation) {
try {
Mail::to($reservation->email)->send(new ClientReminderMail($reservation));
$reservation->client_reminder_sent = true;
$reservation->save();
$sendCounter++;
} catch (\Exception $e) {
Log::warning($e->getMessage());
}
}
Log::channel('daily')->info(self::class . ': ' . $sendCounter . ' client reminders mails have been sent.');
}
public function sendClientInformation(Carbon $date)
{
$dateOfSendsInformationMails = clone $date;
$dateOfSendsInformationMails = $dateOfSendsInformationMails->subDays(config('site.send_client_information_days'))->startOfDay();
$reservationsToSend = Reservation::query()
->where('created_at', '<=', $dateOfSendsInformationMails)
->where('email', '!=', '')
->where(function ($query) {
$query->where('client_information_sent', '!=', 1)
->orWhereNull('client_information_sent');
})
->with('items', 'items.product', 'items.product.translation', 'location')
->orderByDesc('created_at')
->get();
if ($reservationsToSend->count() == 0) {
Log::channel('daily')->info(self::class . ': No client information mail has been sent.');
return;
}
$sendCounter = 0;
foreach ($reservationsToSend as $reservation) {
try {
Mail::to($reservation->email)->send(new ClientInformationMail($reservation));
$reservation->client_information_sent = true;
$reservation->save();
$sendCounter++;
} catch (\Exception $e) {
Log::warning($e->getMessage());
}
}
Log::channel('daily')->info(self::class . ': ' . $sendCounter . ' client information mails have been sent.');
}
public function sendClientSimpleReminders(Carbon $date)
{
$dateOfSendsReminderMails = clone $date;
$dateOfSendsReminderMails = $dateOfSendsReminderMails->addDays(config('site.send_client_reminder_simple_days'))->startOfDay();
$reservationsToSend = Reservation::where('date', '<=', $dateOfSendsReminderMails)
->where('email', '!=', '')
->where(function ($query) {
$query->where('client_simple_reminder_sent', '!=', 1)
->orWhereNull('client_simple_reminder_sent');
})
->with('items', 'items.product', 'items.product.translation', 'location')
->get();
if ($reservationsToSend->count() == 0) {
Log::channel('daily')->info(self::class . ': No client simple reminders mail has been sent.');
return;
}
$sendCounter = 0;
foreach ($reservationsToSend as $reservation) {
try {
Mail::to($reservation->email)->send(new ClientReminderSimpleMail($reservation));
$reservation->client_simple_reminder_sent = true;
$reservation->save();
$sendCounter++;
} catch (\Exception $e) {
Log::warning($e->getMessage());
}
}
Log::channel('daily')->info(self::class . ': ' . $sendCounter . ' client simple reminders mails have been sent.');
}
public function sendClientAlmostReady(Carbon $date)
{
$dateOfSendsAlmostReadyMails = clone $date;
$dateOfSendsAlmostReadyMails = $dateOfSendsAlmostReadyMails->addDays(config('site.send_client_almost_ready_days'))->startOfDay();
$reservationsToSend = Reservation::where('date', '<=', $dateOfSendsAlmostReadyMails)
->where('email', '!=', '')
->where(function ($query) {
$query->where('client_almost_ready_sent', '!=', 1)
->orWhereNull('client_almost_ready_sent');
})
->with('items', 'items.product', 'items.product.translation', 'location')
->get();
if ($reservationsToSend->count() == 0) {
Log::channel('daily')->info(self::class . ': No client almost ready mail has been sent.');
return;
}
$sendCounter = 0;
foreach ($reservationsToSend as $reservation) {
try {
Mail::to($reservation->email)->send(new ClientAlmostReadyMail($reservation));
$reservation->client_almost_ready_sent = true;
$reservation->save();
$sendCounter++;
} catch (\Exception $e) {
Log::warning($e->getMessage());
}
}
Log::channel('daily')->info(self::class . ': ' . $sendCounter . ' client almost ready mails have been sent.');
}
public function sendClientFavour(Carbon $date)
{
$dateOfSendsFavourMails = clone $date;
$dateOfSendsFavourMails = $dateOfSendsFavourMails->addDays(config('site.send_client_favour_days'))->startOfDay();
$reservationsToSend = Reservation::where('date', '<=', $dateOfSendsFavourMails)
->where('email', '!=', '')
->where(function ($query) {
$query->where('client_favour_sent', '!=', 1)
->orWhereNull('client_favour_sent');
})
->with('items', 'items.product', 'items.product.translation', 'location')
->get();
if ($reservationsToSend->count() == 0) {
Log::channel('daily')->info(self::class . ': No client favour mail has been sent.');
return;
}
$sendCounter = 0;
foreach ($reservationsToSend as $reservation) {
try {
Mail::to($reservation->email)->send(new ClientFavourMail($reservation));
$reservation->client_favour_sent = true;
$reservation->save();
$sendCounter++;
} catch (\Exception $e) {
Log::warning($e->getMessage());
}
}
Log::channel('daily')->info(self::class . ': ' . $sendCounter . ' client favour mails have been sent.');
}
/**
* Send the client program reminders.
*
* @param Carbon $date
*/
public function sendProgramReminders(Carbon $date)
{
$date = today()->subDays(config('site.send_program_reminder_days'));
$remindersToSend = RequestedProgram::where('created_at', '<=', $date)
->where('reminded', 0)
->get();
if ($remindersToSend->count() == 0) {
Log::channel('daily')->info(self::class . ': No program reminders mail has been sent.');
return;
}
foreach ($remindersToSend as $reminder) {
try {
$reservationWithSameMailCreatedAfterDay = Reservation::where('email', $reminder->email)->where('created_at', '>=', $reminder->created_at->startOfDay())->count();
// If no reservation is found, send reminder mail
if ($reservationWithSameMailCreatedAfterDay === 0) {
Mail::to($reminder->email)->send(new ProgramReminderMail($reminder));
}
// Set as reminded
$reminder->reminded = true;
$reminder->reminded_date = now();
$reminder->save();
} catch (\Exception $e) {
Log::warning($e->getMessage());
}
}
Log::channel('daily')->info(self::class . ': ' . $remindersToSend->count() . ' program reminders mails have been sent.');
}
public function previewChangeReservation()
{
$reservation = Reservation::withTrashed()
->with('items', 'items.product', 'items.product.translation', 'location')
->get()
->random(1)
->first();
$url = URL::signedRoute('reservation.change', ['reservation' => $reservation->id]);
echo '<a target="_blank" href="' . $url . '">Wijzig reservering #' . $reservation->id . '</a>';
}
}