feat(accound deactivated notification)
This commit is contained in:
@@ -55,6 +55,7 @@ MAIL_USERNAME=null
|
|||||||
MAIL_PASSWORD=null
|
MAIL_PASSWORD=null
|
||||||
MAIL_FROM_ADDRESS="hello@example.com"
|
MAIL_FROM_ADDRESS="hello@example.com"
|
||||||
MAIL_FROM_NAME="${APP_NAME}"
|
MAIL_FROM_NAME="${APP_NAME}"
|
||||||
|
ADMIN_EMAIL=
|
||||||
|
|
||||||
AWS_ACCESS_KEY_ID=
|
AWS_ACCESS_KEY_ID=
|
||||||
AWS_SECRET_ACCESS_KEY=
|
AWS_SECRET_ACCESS_KEY=
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ use Illuminate\Database\Eloquent\Factories\HasFactory;
|
|||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||||
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||||
use Illuminate\Notifications\Notifiable;
|
use Illuminate\Notifications\Notifiable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -33,7 +34,7 @@ use Illuminate\Notifications\Notifiable;
|
|||||||
* @property string|null $website_url
|
* @property string|null $website_url
|
||||||
* @property \Illuminate\Support\Carbon|null $created_at
|
* @property \Illuminate\Support\Carbon|null $created_at
|
||||||
* @property \Illuminate\Support\Carbon|null $updated_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 string $full_name
|
||||||
* @property-read \App\Models\MemberGroup|null $group
|
* @property-read \App\Models\MemberGroup|null $group
|
||||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\IspconfigMember> $ispconfigs
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\IspconfigMember> $ispconfigs
|
||||||
@@ -80,7 +81,7 @@ use Illuminate\Notifications\Notifiable;
|
|||||||
*/
|
*/
|
||||||
class Member extends Model
|
class Member extends Model
|
||||||
{
|
{
|
||||||
use HasFactory, Notifiable;
|
use HasFactory, Notifiable, SoftDeletes;
|
||||||
|
|
||||||
protected $fillable = [
|
protected $fillable = [
|
||||||
'user_id',
|
'user_id',
|
||||||
@@ -151,7 +152,7 @@ class Member extends Model
|
|||||||
return $this->hasMany(NextCloudMember::class, 'member_id');
|
return $this->hasMany(NextCloudMember::class, 'member_id');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function lastMembership(): Membership
|
public function lastMembership(): ?Membership
|
||||||
{
|
{
|
||||||
return $this->memberships()->where('status', 'active')->first();
|
return $this->memberships()->where('status', 'active')->first();
|
||||||
}
|
}
|
||||||
@@ -160,14 +161,21 @@ class Member extends Model
|
|||||||
{
|
{
|
||||||
$membership = $this->lastMembership();
|
$membership = $this->lastMembership();
|
||||||
|
|
||||||
|
if ($membership === null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return $membership->services()->where('identifier', $serviceIdentifier)->exists();
|
return $membership->services()->where('identifier', $serviceIdentifier)->exists();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function isExpired(): bool
|
public function isExpired(): bool
|
||||||
{
|
{
|
||||||
// Member ayant leur dernière adhésion non renouvellée depuis plus d'un mois
|
|
||||||
$lastMembership = $this->lastMembership();
|
$lastMembership = $this->lastMembership();
|
||||||
|
|
||||||
|
if ($lastMembership === null) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
return $lastMembership->status === 'expired' || $lastMembership->created_at->addMonths(1) < now();
|
return $lastMembership->status === 'expired' || $lastMembership->created_at->addMonths(1) < now();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
52
app/Notifications/ContactNewRequestNotification.php
Normal file
52
app/Notifications/ContactNewRequestNotification.php
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Notifications;
|
||||||
|
|
||||||
|
use App\Models\Contact;
|
||||||
|
use App\Models\NotificationTemplate;
|
||||||
|
use Illuminate\Bus\Queueable;
|
||||||
|
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||||
|
use Illuminate\Notifications\Messages\MailMessage;
|
||||||
|
use Illuminate\Notifications\Notification;
|
||||||
|
|
||||||
|
class ContactNewRequestNotification extends Notification implements ShouldQueue
|
||||||
|
{
|
||||||
|
use Queueable;
|
||||||
|
|
||||||
|
public function __construct(public readonly Contact $contact) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array<int, string>
|
||||||
|
*/
|
||||||
|
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<string, mixed>
|
||||||
|
*/
|
||||||
|
public function toArray(object $notifiable): array
|
||||||
|
{
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}
|
||||||
50
app/Notifications/MemberDeactivatedAdminNotification.php
Normal file
50
app/Notifications/MemberDeactivatedAdminNotification.php
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Notifications;
|
||||||
|
|
||||||
|
use App\Models\Member;
|
||||||
|
use App\Models\NotificationTemplate;
|
||||||
|
use Illuminate\Bus\Queueable;
|
||||||
|
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||||
|
use Illuminate\Notifications\Messages\MailMessage;
|
||||||
|
use Illuminate\Notifications\Notification;
|
||||||
|
|
||||||
|
class MemberDeactivatedAdminNotification extends Notification implements ShouldQueue
|
||||||
|
{
|
||||||
|
use Queueable;
|
||||||
|
|
||||||
|
public function __construct(public readonly Member $member) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array<int, string>
|
||||||
|
*/
|
||||||
|
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<string, mixed>
|
||||||
|
*/
|
||||||
|
public function toArray(object $notifiable): array
|
||||||
|
{
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}
|
||||||
49
app/Notifications/MemberDeactivatedMemberNotification.php
Normal file
49
app/Notifications/MemberDeactivatedMemberNotification.php
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Notifications;
|
||||||
|
|
||||||
|
use App\Models\Member;
|
||||||
|
use App\Models\NotificationTemplate;
|
||||||
|
use Illuminate\Bus\Queueable;
|
||||||
|
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||||
|
use Illuminate\Notifications\Messages\MailMessage;
|
||||||
|
use Illuminate\Notifications\Notification;
|
||||||
|
|
||||||
|
class MemberDeactivatedMemberNotification extends Notification implements ShouldQueue
|
||||||
|
{
|
||||||
|
use Queueable;
|
||||||
|
|
||||||
|
public function __construct(public readonly Member $member) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array<int, string>
|
||||||
|
*/
|
||||||
|
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<string, mixed>
|
||||||
|
*/
|
||||||
|
public function toArray(object $notifiable): array
|
||||||
|
{
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,23 +3,22 @@
|
|||||||
namespace App\Services;
|
namespace App\Services;
|
||||||
|
|
||||||
use App\Models\Contact;
|
use App\Models\Contact;
|
||||||
|
use App\Notifications\ContactNewRequestNotification;
|
||||||
|
use Illuminate\Support\Facades\Notification;
|
||||||
|
|
||||||
class ContactService
|
class ContactService
|
||||||
{
|
{
|
||||||
public function __construct()
|
public function __construct() {}
|
||||||
{
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
public function registerNewContactRequest(array $data): Contact
|
public function registerNewContactRequest(array $data): Contact
|
||||||
{
|
{
|
||||||
$contact = new Contact();
|
$contact = new Contact;
|
||||||
$contact->fill($data);
|
$contact->fill($data);
|
||||||
$contact->save();
|
$contact->save();
|
||||||
|
|
||||||
// Envoyer un email à l'administrateur
|
Notification::route('mail', config('app.admin_email'))
|
||||||
|
->notify(new ContactNewRequestNotification($contact));
|
||||||
|
|
||||||
return $contact;
|
return $contact;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,9 @@ use App\Events\MemberRegistered;
|
|||||||
use App\Models\Member;
|
use App\Models\Member;
|
||||||
use App\Models\MemberGroup;
|
use App\Models\MemberGroup;
|
||||||
use App\Models\Package;
|
use App\Models\Package;
|
||||||
|
use App\Notifications\MemberDeactivatedAdminNotification;
|
||||||
|
use App\Notifications\MemberDeactivatedMemberNotification;
|
||||||
|
use Illuminate\Support\Facades\Notification;
|
||||||
|
|
||||||
class MemberService
|
class MemberService
|
||||||
{
|
{
|
||||||
@@ -58,14 +61,16 @@ class MemberService
|
|||||||
*/
|
*/
|
||||||
public function deactivateMember(Member $member): void
|
public function deactivateMember(Member $member): void
|
||||||
{
|
{
|
||||||
// todo: send email to member + admin
|
|
||||||
$member->update(['status' => 'excluded']);
|
$member->update(['status' => 'excluded']);
|
||||||
$membership = $member->memberships()
|
$membership = $member->memberships()
|
||||||
->where('status', 'active')->first();
|
->where('status', 'active')->first();
|
||||||
$membership->update(['status' => 'inactive']);
|
$membership->update(['status' => 'inactive']);
|
||||||
|
|
||||||
// On détache les services côté Roxane - à tester
|
|
||||||
$membership->services()->detach();
|
$membership->services()->detach();
|
||||||
|
|
||||||
|
$member->notify(new MemberDeactivatedMemberNotification($member));
|
||||||
|
|
||||||
|
Notification::route('mail', config('app.admin_email'))
|
||||||
|
->notify(new MemberDeactivatedAdminNotification($member));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -118,6 +118,8 @@ return [
|
|||||||
|
|
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
'admin_email' => env('ADMIN_EMAIL'),
|
||||||
|
|
||||||
'maintenance' => [
|
'maintenance' => [
|
||||||
'driver' => env('APP_MAINTENANCE_DRIVER', 'file'),
|
'driver' => env('APP_MAINTENANCE_DRIVER', 'file'),
|
||||||
'store' => env('APP_MAINTENANCE_STORE', 'database'),
|
'store' => env('APP_MAINTENANCE_STORE', 'database'),
|
||||||
|
|||||||
@@ -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' => '<p>Une nouvelle demande de contact a été reçue.</p>'
|
||||||
|
.'<p><strong>Nom :</strong> {contact_name}<br>'
|
||||||
|
.'<strong>Email :</strong> {contact_email}<br>'
|
||||||
|
.'<strong>Sujet :</strong> {contact_subject}</p>'
|
||||||
|
.'<p><strong>Message :</strong><br>{contact_message}</p>',
|
||||||
|
'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' => '<p>Bonjour {member_name},</p>'
|
||||||
|
.'<p>Votre compte a été désactivé. Vos services associés ne sont plus accessibles.</p>'
|
||||||
|
.'<p>Pour toute question, n\'hésitez pas à nous contacter.</p>',
|
||||||
|
'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' => '<p>Le compte du membre suivant a été désactivé.</p>'
|
||||||
|
.'<p><strong>Nom :</strong> {member_name}<br>'
|
||||||
|
.'<strong>Email :</strong> {member_email}</p>',
|
||||||
|
'variables' => [
|
||||||
|
'member_name' => 'Nom complet du membre',
|
||||||
|
'member_email' => 'Adresse email du membre',
|
||||||
|
'app_name' => 'Nom de l\'application',
|
||||||
|
],
|
||||||
|
'is_active' => true,
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
NotificationTemplate::updateOrCreate(
|
NotificationTemplate::updateOrCreate(
|
||||||
['identifier' => 'admin_password_reset'],
|
['identifier' => 'admin_password_reset'],
|
||||||
[
|
[
|
||||||
|
|||||||
@@ -20,4 +20,6 @@ Route::middleware(['auth', 'verified'])->group(function () {
|
|||||||
require __DIR__.'/settings.php';
|
require __DIR__.'/settings.php';
|
||||||
require __DIR__.'/auth.php';
|
require __DIR__.'/auth.php';
|
||||||
require __DIR__.'/forms.php';
|
require __DIR__.'/forms.php';
|
||||||
require __DIR__.'/dev-routes.php';
|
if (app()->environment('local')) {
|
||||||
|
require __DIR__.'/dev-routes.php';
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user