From ca464e8e0614ece34cad41ac2af159e76010e05c Mon Sep 17 00:00:00 2001 From: Nebulae Date: Tue, 7 Apr 2026 17:09:25 +0200 Subject: [PATCH] feat(accound deactivated notification) --- .env.example | 1 + app/Models/Member.php | 16 ++++-- .../ContactNewRequestNotification.php | 52 ++++++++++++++++++ .../MemberDeactivatedAdminNotification.php | 50 +++++++++++++++++ .../MemberDeactivatedMemberNotification.php | 49 +++++++++++++++++ app/Services/ContactService.php | 13 +++-- app/Services/MemberService.php | 9 +++- config/app.php | 2 + .../seeders/NotificationTemplateSeeder.php | 54 +++++++++++++++++++ routes/web.php | 4 +- 10 files changed, 236 insertions(+), 14 deletions(-) create mode 100644 app/Notifications/ContactNewRequestNotification.php create mode 100644 app/Notifications/MemberDeactivatedAdminNotification.php create mode 100644 app/Notifications/MemberDeactivatedMemberNotification.php diff --git a/.env.example b/.env.example index 6461dd9..599aed0 100644 --- a/.env.example +++ b/.env.example @@ -55,6 +55,7 @@ MAIL_USERNAME=null MAIL_PASSWORD=null MAIL_FROM_ADDRESS="hello@example.com" MAIL_FROM_NAME="${APP_NAME}" +ADMIN_EMAIL= AWS_ACCESS_KEY_ID= AWS_SECRET_ACCESS_KEY= diff --git a/app/Models/Member.php b/app/Models/Member.php index ce7e653..3b665b8 100644 --- a/app/Models/Member.php +++ b/app/Models/Member.php @@ -6,6 +6,7 @@ use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\Relations\HasMany; +use Illuminate\Database\Eloquent\SoftDeletes; use Illuminate\Notifications\Notifiable; /** @@ -33,7 +34,7 @@ use Illuminate\Notifications\Notifiable; * @property string|null $website_url * @property \Illuminate\Support\Carbon|null $created_at * @property \Illuminate\Support\Carbon|null $updated_at - * @property string|null $deleted_at + * @property \Illuminate\Support\Carbon|null $deleted_at * @property-read string $full_name * @property-read \App\Models\MemberGroup|null $group * @property-read \Illuminate\Database\Eloquent\Collection $ispconfigs @@ -80,7 +81,7 @@ use Illuminate\Notifications\Notifiable; */ class Member extends Model { - use HasFactory, Notifiable; + use HasFactory, Notifiable, SoftDeletes; protected $fillable = [ 'user_id', @@ -151,7 +152,7 @@ class Member extends Model return $this->hasMany(NextCloudMember::class, 'member_id'); } - public function lastMembership(): Membership + public function lastMembership(): ?Membership { return $this->memberships()->where('status', 'active')->first(); } @@ -160,14 +161,21 @@ class Member extends Model { $membership = $this->lastMembership(); + if ($membership === null) { + return false; + } + return $membership->services()->where('identifier', $serviceIdentifier)->exists(); } public function isExpired(): bool { - // Member ayant leur dernière adhésion non renouvellée depuis plus d'un mois $lastMembership = $this->lastMembership(); + if ($lastMembership === null) { + return true; + } + return $lastMembership->status === 'expired' || $lastMembership->created_at->addMonths(1) < now(); } } diff --git a/app/Notifications/ContactNewRequestNotification.php b/app/Notifications/ContactNewRequestNotification.php new file mode 100644 index 0000000..cbe8669 --- /dev/null +++ b/app/Notifications/ContactNewRequestNotification.php @@ -0,0 +1,52 @@ + + */ + public function via(object $notifiable): array + { + return ['mail']; + } + + public function toMail(object $notifiable): MailMessage + { + $template = NotificationTemplate::findByIdentifier('contact_new_request'); + + $vars = [ + 'contact_name' => $this->contact->full_name, + 'contact_email' => $this->contact->email ?? '', + 'contact_subject' => $this->contact->subject ?? '', + 'contact_message' => $this->contact->message ?? '', + 'app_name' => config('app.name'), + ]; + + return (new MailMessage) + ->subject($template->renderSubject($vars)) + ->view('notifications.mail-template', [ + 'body' => $template->renderBody($vars), + ]); + } + + /** + * @return array + */ + public function toArray(object $notifiable): array + { + return []; + } +} diff --git a/app/Notifications/MemberDeactivatedAdminNotification.php b/app/Notifications/MemberDeactivatedAdminNotification.php new file mode 100644 index 0000000..f7e1150 --- /dev/null +++ b/app/Notifications/MemberDeactivatedAdminNotification.php @@ -0,0 +1,50 @@ + + */ + public function via(object $notifiable): array + { + return ['mail']; + } + + public function toMail(object $notifiable): MailMessage + { + $template = NotificationTemplate::findByIdentifier('member_deactivated_admin'); + + $vars = [ + 'member_name' => $this->member->full_name, + 'member_email' => $this->member->email ?? '', + 'app_name' => config('app.name'), + ]; + + return (new MailMessage) + ->subject($template->renderSubject($vars)) + ->view('notifications.mail-template', [ + 'body' => $template->renderBody($vars), + ]); + } + + /** + * @return array + */ + public function toArray(object $notifiable): array + { + return []; + } +} diff --git a/app/Notifications/MemberDeactivatedMemberNotification.php b/app/Notifications/MemberDeactivatedMemberNotification.php new file mode 100644 index 0000000..d9ded71 --- /dev/null +++ b/app/Notifications/MemberDeactivatedMemberNotification.php @@ -0,0 +1,49 @@ + + */ + public function via(object $notifiable): array + { + return ['mail']; + } + + public function toMail(object $notifiable): MailMessage + { + $template = NotificationTemplate::findByIdentifier('member_deactivated_member'); + + $vars = [ + 'member_name' => $this->member->full_name, + 'app_name' => config('app.name'), + ]; + + return (new MailMessage) + ->subject($template->renderSubject($vars)) + ->view('notifications.mail-template', [ + 'body' => $template->renderBody($vars), + ]); + } + + /** + * @return array + */ + public function toArray(object $notifiable): array + { + return []; + } +} diff --git a/app/Services/ContactService.php b/app/Services/ContactService.php index 6cbcfec..c373d01 100644 --- a/app/Services/ContactService.php +++ b/app/Services/ContactService.php @@ -3,23 +3,22 @@ namespace App\Services; use App\Models\Contact; +use App\Notifications\ContactNewRequestNotification; +use Illuminate\Support\Facades\Notification; class ContactService { - public function __construct() - { - // - } + public function __construct() {} public function registerNewContactRequest(array $data): Contact { - $contact = new Contact(); + $contact = new Contact; $contact->fill($data); $contact->save(); - // Envoyer un email à l'administrateur + Notification::route('mail', config('app.admin_email')) + ->notify(new ContactNewRequestNotification($contact)); return $contact; - } } diff --git a/app/Services/MemberService.php b/app/Services/MemberService.php index 11348cb..a1bbe91 100644 --- a/app/Services/MemberService.php +++ b/app/Services/MemberService.php @@ -6,6 +6,9 @@ use App\Events\MemberRegistered; use App\Models\Member; use App\Models\MemberGroup; use App\Models\Package; +use App\Notifications\MemberDeactivatedAdminNotification; +use App\Notifications\MemberDeactivatedMemberNotification; +use Illuminate\Support\Facades\Notification; class MemberService { @@ -58,14 +61,16 @@ class MemberService */ public function deactivateMember(Member $member): void { - // todo: send email to member + admin $member->update(['status' => 'excluded']); $membership = $member->memberships() ->where('status', 'active')->first(); $membership->update(['status' => 'inactive']); - // On détache les services côté Roxane - à tester $membership->services()->detach(); + $member->notify(new MemberDeactivatedMemberNotification($member)); + + Notification::route('mail', config('app.admin_email')) + ->notify(new MemberDeactivatedAdminNotification($member)); } } diff --git a/config/app.php b/config/app.php index 423eed5..576cf0a 100644 --- a/config/app.php +++ b/config/app.php @@ -118,6 +118,8 @@ return [ | */ + 'admin_email' => env('ADMIN_EMAIL'), + 'maintenance' => [ 'driver' => env('APP_MAINTENANCE_DRIVER', 'file'), 'store' => env('APP_MAINTENANCE_STORE', 'database'), diff --git a/database/seeders/NotificationTemplateSeeder.php b/database/seeders/NotificationTemplateSeeder.php index c486853..3ead803 100644 --- a/database/seeders/NotificationTemplateSeeder.php +++ b/database/seeders/NotificationTemplateSeeder.php @@ -47,6 +47,60 @@ class NotificationTemplateSeeder extends Seeder ] ); + NotificationTemplate::updateOrCreate( + ['identifier' => 'contact_new_request'], + [ + 'name' => 'Nouvelle demande de contact', + 'subject' => 'Nouvelle demande de contact — {app_name}', + 'body' => '

Une nouvelle demande de contact a été reçue.

' + .'

Nom : {contact_name}
' + .'Email : {contact_email}
' + .'Sujet : {contact_subject}

' + .'

Message :
{contact_message}

', + 'variables' => [ + 'contact_name' => 'Nom complet de l\'expéditeur', + 'contact_email' => 'Adresse email de l\'expéditeur', + 'contact_subject' => 'Sujet du message', + 'contact_message' => 'Contenu du message', + 'app_name' => 'Nom de l\'application', + ], + 'is_active' => true, + ] + ); + + NotificationTemplate::updateOrCreate( + ['identifier' => 'member_deactivated_member'], + [ + 'name' => 'Compte membre désactivé — membre', + 'subject' => 'Votre compte {app_name} a été désactivé', + 'body' => '

Bonjour {member_name},

' + .'

Votre compte a été désactivé. Vos services associés ne sont plus accessibles.

' + .'

Pour toute question, n\'hésitez pas à nous contacter.

', + 'variables' => [ + 'member_name' => 'Nom complet du membre', + 'app_name' => 'Nom de l\'application', + ], + 'is_active' => true, + ] + ); + + NotificationTemplate::updateOrCreate( + ['identifier' => 'member_deactivated_admin'], + [ + 'name' => 'Compte membre désactivé — admin', + 'subject' => 'Compte désactivé : {member_name}', + 'body' => '

Le compte du membre suivant a été désactivé.

' + .'

Nom : {member_name}
' + .'Email : {member_email}

', + 'variables' => [ + 'member_name' => 'Nom complet du membre', + 'member_email' => 'Adresse email du membre', + 'app_name' => 'Nom de l\'application', + ], + 'is_active' => true, + ] + ); + NotificationTemplate::updateOrCreate( ['identifier' => 'admin_password_reset'], [ diff --git a/routes/web.php b/routes/web.php index 2e7dfb2..3e5c6a3 100644 --- a/routes/web.php +++ b/routes/web.php @@ -20,4 +20,6 @@ Route::middleware(['auth', 'verified'])->group(function () { require __DIR__.'/settings.php'; require __DIR__.'/auth.php'; require __DIR__.'/forms.php'; -require __DIR__.'/dev-routes.php'; +if (app()->environment('local')) { + require __DIR__.'/dev-routes.php'; +}