Files
L-Ami-Fiduciaire/app/Http/Controllers/FolderMessageController.php

150 lines
5.2 KiB
PHP
Raw Normal View History

<?php
namespace App\Http\Controllers;
use App\Enums\ActorType;
use App\Enums\FolderStatus;
use App\Enums\MessageType;
use App\Http\Requests\StoreFolderMessageRequest;
use App\Mail\FolderConfirmationMail;
use App\Mail\FolderFileRequestMail;
use App\Mail\FolderInviteMail;
use App\Mail\FolderSituationMail;
use App\Mail\FolderTextMessageMail;
use App\Models\Folder;
use App\Models\FolderInvitation;
use App\Models\Message;
use App\Models\Workspace;
use Carbon\Carbon;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Mail;
class FolderMessageController extends Controller
{
protected function currentWorkspace(Request $request): Workspace
{
$workspaceId = $request->session()->get('current_workspace_id');
return Workspace::query()->findOrFail($workspaceId);
}
/**
* Store a newly created message.
*/
public function store(StoreFolderMessageRequest $request, Folder $folder): RedirectResponse
{
$workspace = $this->currentWorkspace($request);
if ($folder->workspace_id !== $workspace->id) {
abort(404);
}
$user = $request->user();
$type = MessageType::fromValue($request->input('type'));
$body = $request->input('body');
$invitation = $type->is(MessageType::Invite)
? $this->createInvitation($folder)
: $this->getOrCreateInvitation($folder);
$metadata = ['invitation_id' => $invitation->id];
$message = $folder->messages()->create([
'type' => $type,
'body' => $body,
'sent_by_type' => ActorType::User,
'sent_by_id' => $user->id,
'metadata' => $metadata,
]);
$mediaIds = [];
if ($request->hasFile('files')) {
foreach ($request->file('files') as $file) {
$media = $folder->addMedia($file)
->withCustomProperties([
'message_id' => $message->id,
'uploaded_by_type' => ActorType::User,
'uploaded_by_id' => $user->id,
])
->toMediaCollection('documents');
$mediaIds[] = $media->id;
}
$message->update(['metadata' => array_merge($metadata, ['media_ids' => $mediaIds])]);
}
$this->updateFolderStatusAndConfirmation($folder, $type, $mediaIds);
$emailSent = $this->sendEmailForMessage($folder, $invitation, $message, $body, $type);
$flashMessage = $emailSent
? 'Message envoyé.'
: 'Message enregistré, mais l\'email du client n\'est pas configuré.';
return back()->with('flash', ['type' => 'success', 'message' => $flashMessage]);
}
protected function createInvitation(Folder $folder): FolderInvitation
{
$folder->load('client.primaryContact');
return $folder->invitations()->create([
'email' => $folder->client->primary_contact_email,
'expires_at' => Carbon::now()->addDays(7),
]);
}
protected function getOrCreateInvitation(Folder $folder): FolderInvitation
{
$invitation = $folder->invitations()
->where('expires_at', '>', now())
->latest()
->first();
if ($invitation) {
return $invitation;
}
return $this->createInvitation($folder);
}
/**
* @param array<int> $mediaIds
*/
protected function updateFolderStatusAndConfirmation(Folder $folder, MessageType $type, array $mediaIds): void
{
match ($type->value) {
'invite' => $folder->update(['status' => FolderStatus::WaitingDocuments]),
'situation', 'file_request' => $folder->update(['status' => FolderStatus::AdditionalDocumentsRequested]),
'confirmation' => $folder->update([
'status' => FolderStatus::WaitingClientValidation,
'confirmation_requested_at' => now(),
'confirmation_media_id' => $mediaIds[0] ?? null,
]),
default => null,
};
}
protected function sendEmailForMessage(Folder $folder, FolderInvitation $invitation, Message $message, string $body, MessageType $type): bool
{
$folder->load('client.primaryContact');
$clientEmail = $folder->client->primary_contact_email;
if (empty($clientEmail)) {
\Illuminate\Support\Facades\Log::warning("No primary contact email for client #{$folder->client_id}, skipping email.");
return false;
}
match ($type->value) {
'invite' => Mail::to($clientEmail)->send(new FolderInviteMail($folder, $invitation)),
'situation' => Mail::to($clientEmail)->send(new FolderSituationMail($folder, $invitation, $body)),
'file_request' => Mail::to($clientEmail)->send(new FolderFileRequestMail($folder, $invitation, $body)),
'confirmation' => Mail::to($clientEmail)->send(new FolderConfirmationMail($folder, $invitation, $body)),
'text' => Mail::to($clientEmail)->send(new FolderTextMessageMail($folder, $body, $invitation->token)),
default => null,
};
return true;
}
}