Added an appointment cancellation button

This commit is contained in:
2021-11-03 00:37:47 +00:00
parent 5c536e0c0b
commit fce6e92d9d
25 changed files with 746 additions and 7 deletions

View File

@@ -25,6 +25,7 @@ use App\Application;
use App\Appointment;
use App\Exceptions\InvalidAppointmentException;
use App\Exceptions\InvalidAppointmentStatusException;
use App\Http\Requests\CancelAppointmentRequest;
use App\Http\Requests\SaveNotesRequest;
use App\Services\AppointmentService;
use App\Services\MeetingNoteService;
@@ -61,7 +62,7 @@ class AppointmentController extends Controller
/**
* @throws AuthorizationException
*/
public function updateAppointment(Application $application, $status): RedirectResponse
public function updateAppointment(Application $application, string $status): RedirectResponse
{
$this->authorize('update', $application->appointment);
@@ -78,10 +79,32 @@ class AppointmentController extends Controller
->back()
->with('error', $ex->getMessage());
}
}
public function deleteAppointment(CancelAppointmentRequest $request, Application $application)
{
$this->authorize('update', $application->appointment);
try {
$this->appointmentService->deleteAppointment($application, $request->reason);
return redirect()
->back()
->with('success', __('Appointment cancelled.'));
}
catch (\Exception $ex) {
return redirect()
->back()
->with('error', $ex->getMessage());
}
}
public function saveNotes(SaveNotesRequest $request, Application $application)
{
try {

View File

@@ -0,0 +1,30 @@
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class CancelAppointmentRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'reason' => 'string|required'
];
}
}

View File

@@ -0,0 +1,78 @@
<?php
namespace App\Notifications;
use App\Application;
use Carbon\Carbon;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;
class AppointmentCancelled extends Notification
{
use Queueable;
private $application;
private $reason;
private $appointmentDate;
/**
* Create a new notification instance.
*
* @return void
*/
public function __construct(Application $app, Carbon $appointmentDate, $reason)
{
$this->application = $app;
$this->reason = $reason;
$this->appointmentDate = $appointmentDate;
}
/**
* Get the notification's delivery channels.
*
* @param mixed $notifiable
* @return array
*/
public function via($notifiable)
{
return ['mail'];
}
/**
* Get the mail representation of the notification.
*
* @param mixed $notifiable
* @return \Illuminate\Notifications\Messages\MailMessage
*/
public function toMail($notifiable)
{
// TODO: Switch to HTML & Blade.
return (new MailMessage)
->from(config('notification.sender.address'), config('notification.sender.name'))
->subject(config('app.name').' - Interview Cancelled')
->greeting("Hi " . explode(' ', $this->application->user->name, 2)[0] . ",")
->line('The interview that was previously scheduled with you has been cancelled by a staff member.')
->line('Date & time of the old appointment: '.$this->appointmentDate)
->line('Your appointment was cancelled for the following reason: ' . $this->reason)
->line('A staff member may contact you to reschedule within a new timeframe - you may also let us know of a date and time that suits you.')
->line('Your application will be automatically rejected within 7 days if an interview is not scheduled.')
->action('View ongoing applications', url(route('showUserApps')))
->line('Thank you!');
}
/**
* Get the array representation of the notification.
*
* @param mixed $notifiable
* @return array
*/
public function toArray($notifiable)
{
return [
//
];
}
}

View File

@@ -64,11 +64,11 @@ class AppointmentScheduled extends Notification implements ShouldQueue
{
return (new MailMessage)
->from(config('notification.sender.address'), config('notification.sender.name'))
->subject(config('app.name').' - Interview scheduled')
->subject(config('app.name').' - Interview Scheduled')
->line('A voice interview has been scheduled for you @ '.$this->appointment->appointmentDate.'.')
->line('With the following details: '.$this->appointment->appointmentDescription)
->line('This meeting will take place @ '.$this->appointment->appointmentLocation.'. You will receive an email soon with details on how to join this meeting.')
->line('You are expected to show up at least 5 minutes before the scheduled date.')
->line('Please join a public voice channel (or another platform if specified) at around this time.')
->action('Sign in', url(route('login')))
->line('Thank you!');
}

View File

@@ -8,6 +8,7 @@ use App\Application;
use App\Appointment;
use App\Exceptions\InvalidAppointmentStatusException;
use App\Notifications\ApplicationMoved;
use App\Notifications\AppointmentCancelled;
use App\Notifications\AppointmentScheduled;
use Carbon\Carbon;
use Illuminate\Support\Facades\Auth;
@@ -25,6 +26,15 @@ class AppointmentService
];
/**
* Schedules an appointment for the provided application.
*
* @param Application $application The target application.
* @param Carbon $appointmentDate The appointment's date and time.
* @param string $appointmentDescription The appointment description.
* @param string $appointmentLocation The appointment location.
* @return bool Whether the appointment was scheduled.
*/
public function createAppointment(Application $application, Carbon $appointmentDate, $appointmentDescription, $appointmentLocation)
{
$appointment = Appointment::create([
@@ -46,6 +56,32 @@ class AppointmentService
return true;
}
/**
* Cancels an appointment for the provided application.
*
* @param Application $application The target application.
* @param string $reason The reason for cancelling the appointment.
* @throws \Exception Thrown when there's no appointment to cancel
*/
public function deleteAppointment(Application $application, string $reason): bool
{
if (!empty($application->appointment))
{
$application->user->notify(new AppointmentCancelled($application, Carbon::parse($application->appointment->appointmentDate), $reason));
$application->appointment->delete();
$application->setStatus('STAGE_INTERVIEW');
Log::info('User '.Auth::user()->name.' cancelled an appointment with '.$application->user->name.' for application ID'.$application->id);
return true;
}
throw new \Exception("This application doesn't have an appointment!");
}
/**
* Updates the appointment with the new $status.
* It also sets the application's status to peer approval.