feat(Handle Expired members script)
This commit is contained in:
@@ -86,8 +86,9 @@ ISPCONFIG_TEST_SOAP_URI=
|
|||||||
ISPCONFIG_TEST_USERNAME=
|
ISPCONFIG_TEST_USERNAME=
|
||||||
ISPCONFIG_TEST_PASSWORD=
|
ISPCONFIG_TEST_PASSWORD=
|
||||||
|
|
||||||
#NEXTCLOUD_API_ID=
|
NEXTCLOUD_URL=
|
||||||
#NEXCLOUD_API_PWD=
|
NEXTCLOUD_USERNAME=
|
||||||
|
NEXTCLOUD_PASSWORD=
|
||||||
|
|
||||||
#SYMPA_API_ID=
|
#SYMPA_API_ID=
|
||||||
#SYMPA_API_PWD=
|
#SYMPA_API_PWD=
|
||||||
|
|||||||
@@ -33,6 +33,8 @@ class HandleExpiredMembersDolibarr extends Command
|
|||||||
|
|
||||||
$expiredMembers = $members->filter(fn ($m) => $m['status'] === 'expired');
|
$expiredMembers = $members->filter(fn ($m) => $m['status'] === 'expired');
|
||||||
|
|
||||||
|
dd($expiredMembers);
|
||||||
|
|
||||||
$this->info("{$expiredMembers->count()} adhérent(s) expiré(s)");
|
$this->info("{$expiredMembers->count()} adhérent(s) expiré(s)");
|
||||||
|
|
||||||
foreach ($expiredMembers as $member) {
|
foreach ($expiredMembers as $member) {
|
||||||
@@ -54,7 +56,7 @@ class HandleExpiredMembersDolibarr extends Command
|
|||||||
{
|
{
|
||||||
$email = $member['email'] ?? null;
|
$email = $member['email'] ?? null;
|
||||||
|
|
||||||
$this->info("👤 {$member['id']} - {$email}");
|
$this->info("{$member['id']} - {$email}");
|
||||||
|
|
||||||
// 1. Résiliation Dolibarr
|
// 1. Résiliation Dolibarr
|
||||||
$this->dolibarr->setMemberStatus($member['id'], 'resilie');
|
$this->dolibarr->setMemberStatus($member['id'], 'resilie');
|
||||||
@@ -86,6 +88,7 @@ class HandleExpiredMembersDolibarr extends Command
|
|||||||
'disablepop3' => 'y',
|
'disablepop3' => 'y',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$this->info("📧 Mail désactivé");
|
$this->info("Mail désactivé");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,9 +2,11 @@
|
|||||||
|
|
||||||
namespace App\Filament\Resources\Members\Schemas;
|
namespace App\Filament\Resources\Members\Schemas;
|
||||||
|
|
||||||
|
use App\Enums\IspconfigType;
|
||||||
use App\Models\Member;
|
use App\Models\Member;
|
||||||
use Filament\Actions\Action;
|
use Filament\Actions\Action;
|
||||||
use Filament\Forms\Components\DatePicker;
|
use Filament\Forms\Components\DatePicker;
|
||||||
|
use Filament\Forms\Components\Placeholder;
|
||||||
use Filament\Forms\Components\Select;
|
use Filament\Forms\Components\Select;
|
||||||
use Filament\Forms\Components\TextInput;
|
use Filament\Forms\Components\TextInput;
|
||||||
use Filament\Forms\Components\Toggle;
|
use Filament\Forms\Components\Toggle;
|
||||||
@@ -12,6 +14,8 @@ use Filament\Schemas\Components\Grid;
|
|||||||
use Filament\Schemas\Components\Section;
|
use Filament\Schemas\Components\Section;
|
||||||
use Filament\Schemas\Schema;
|
use Filament\Schemas\Schema;
|
||||||
use Filament\Infolists\Components\TextEntry;
|
use Filament\Infolists\Components\TextEntry;
|
||||||
|
use Filament\Infolists\Components\RepeatableEntry;
|
||||||
|
use Filament\Infolists\Components\Actions;
|
||||||
|
|
||||||
|
|
||||||
class MemberForm
|
class MemberForm
|
||||||
@@ -91,7 +95,7 @@ class MemberForm
|
|||||||
->label(Member::getAttributeLabel('country')),
|
->label(Member::getAttributeLabel('country')),
|
||||||
])
|
])
|
||||||
->columns(2),
|
->columns(2),
|
||||||
|
// Mail Retzien
|
||||||
Section::make('Messagerie ISPConfig Retzien')
|
Section::make('Messagerie ISPConfig Retzien')
|
||||||
->schema([
|
->schema([
|
||||||
TextEntry::make('isp_mail_email')
|
TextEntry::make('isp_mail_email')
|
||||||
@@ -126,6 +130,23 @@ class MemberForm
|
|||||||
->visible(fn (?Member $record) =>
|
->visible(fn (?Member $record) =>
|
||||||
$record?->ispconfigMail() !== null
|
$record?->ispconfigMail() !== null
|
||||||
),
|
),
|
||||||
|
|
||||||
|
// Hébergement
|
||||||
|
|
||||||
|
Section::make('Hébergements Web')
|
||||||
|
->schema([
|
||||||
|
Placeholder::make('ispconfigs_web_display')
|
||||||
|
->label('')
|
||||||
|
->content(fn (?Member $record) => view('filament.components.ispconfig-web-list', [
|
||||||
|
'ispconfigs' => $record?->ispconfigs()
|
||||||
|
->where('type', IspconfigType::WEB)
|
||||||
|
->get() ?? collect()
|
||||||
|
]))
|
||||||
|
])
|
||||||
|
->visible(fn (?Member $record) =>
|
||||||
|
$record?->ispconfigs()->where('type', IspconfigType::WEB)->exists()
|
||||||
|
)
|
||||||
|
// Fin Hébergement
|
||||||
])
|
])
|
||||||
->columnSpan(3),
|
->columnSpan(3),
|
||||||
Grid::make(1)
|
Grid::make(1)
|
||||||
|
|||||||
@@ -136,7 +136,7 @@ class Member extends Model
|
|||||||
->first();
|
->first();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function ispconfigWeb(): ?IspconfigMember
|
public function ispconfigsWeb(): ?IspconfigMember
|
||||||
{
|
{
|
||||||
return $this->ispconfigs()
|
return $this->ispconfigs()
|
||||||
->where('type', IspconfigType::WEB)
|
->where('type', IspconfigType::WEB)
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ use Illuminate\Support\Facades\Http;
|
|||||||
class DolibarrService
|
class DolibarrService
|
||||||
{
|
{
|
||||||
protected string $baseUrl;
|
protected string $baseUrl;
|
||||||
|
protected string $htaccessUrl;
|
||||||
protected string $username;
|
protected string $username;
|
||||||
protected string $password;
|
protected string $password;
|
||||||
protected string $apiKey;
|
protected string $apiKey;
|
||||||
@@ -16,6 +17,7 @@ class DolibarrService
|
|||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
$this->baseUrl = config('services.dolibarr.base_url');
|
$this->baseUrl = config('services.dolibarr.base_url');
|
||||||
|
$this->htaccessUrl = config('services.dolibarr.htaccess_url');
|
||||||
$this->username = config('services.dolibarr.username');
|
$this->username = config('services.dolibarr.username');
|
||||||
$this->password = config('services.dolibarr.password');
|
$this->password = config('services.dolibarr.password');
|
||||||
$this->apiKey = config('services.dolibarr.api_key');
|
$this->apiKey = config('services.dolibarr.api_key');
|
||||||
|
|||||||
@@ -2,25 +2,70 @@
|
|||||||
|
|
||||||
namespace App\Services\Nextcloud;
|
namespace App\Services\Nextcloud;
|
||||||
|
|
||||||
|
use Illuminate\Http\Client\PendingRequest;
|
||||||
use Illuminate\Support\Facades\Http;
|
use Illuminate\Support\Facades\Http;
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
|
|
||||||
class NextcloudService
|
class NextcloudService
|
||||||
{
|
{
|
||||||
public function disableUserByEmail(string $email): bool
|
protected PendingRequest $http;
|
||||||
{
|
|
||||||
$username = $this->getUsernameFromEmail($email);
|
|
||||||
|
|
||||||
return Http::withBasicAuth(
|
public function __construct()
|
||||||
config('services.nextcloud.username'),
|
{
|
||||||
|
$this->http = Http::withBasicAuth(
|
||||||
|
config('services.nextcloud.user'),
|
||||||
config('services.nextcloud.password')
|
config('services.nextcloud.password')
|
||||||
)->put(
|
)
|
||||||
config('services.nextcloud.base_url') . "/ocs/v1.php/cloud/users/{$username}/disable",
|
->withHeaders([
|
||||||
[]
|
'OCS-APIRequest' => 'true',
|
||||||
)->successful();
|
'Accept' => 'application/json',
|
||||||
|
])
|
||||||
|
->baseUrl(config('services.nextcloud.url') . '/ocs/v1.php');
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getUsernameFromEmail(string $email): string
|
/**
|
||||||
|
* Désactive un utilisateur Nextcloud à partir de son email
|
||||||
|
*/
|
||||||
|
public function disableUserByEmail(string $email): void
|
||||||
{
|
{
|
||||||
return strstr($email, '@', true);
|
$userId = $this->findUserIdByEmail($email);
|
||||||
|
|
||||||
|
if (!$userId) {
|
||||||
|
Log::warning("Utilisateur Nextcloud introuvable", ['email' => $email]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$response = $this->http->put("/cloud/users/{$userId}/disable");
|
||||||
|
|
||||||
|
if (!$response->successful()) {
|
||||||
|
throw new \RuntimeException("Erreur désactivation Nextcloud {$userId}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Trouve le userId Nextcloud à partir de l’email
|
||||||
|
*/
|
||||||
|
protected function findUserIdByEmail(string $email): ?string
|
||||||
|
{
|
||||||
|
$response = $this->http->get('/cloud/users');
|
||||||
|
|
||||||
|
if (!$response->successful()) {
|
||||||
|
throw new \RuntimeException('Erreur récupération utilisateurs Nextcloud');
|
||||||
|
}
|
||||||
|
|
||||||
|
$users = $response->json('ocs.data.users') ?? [];
|
||||||
|
|
||||||
|
foreach ($users as $userId) {
|
||||||
|
$details = $this->http->get("/cloud/users/{$userId}");
|
||||||
|
|
||||||
|
if (
|
||||||
|
$details->successful() &&
|
||||||
|
($details->json('ocs.data.email') === $email)
|
||||||
|
) {
|
||||||
|
return $userId;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ return [
|
|||||||
|
|
||||||
'dolibarr' => [
|
'dolibarr' => [
|
||||||
'base_url' => env('DOLIBARR_URL'),
|
'base_url' => env('DOLIBARR_URL'),
|
||||||
|
'htaccess_url' => env('DOLIBARR_URL_HTACCESS'),
|
||||||
'username' => env('DOLIBARR_USERNAME'),
|
'username' => env('DOLIBARR_USERNAME'),
|
||||||
'password' => env('DOLIBARR_PWD'),
|
'password' => env('DOLIBARR_PWD'),
|
||||||
'api_key' => env('DOLIBARR_APIKEY')
|
'api_key' => env('DOLIBARR_APIKEY')
|
||||||
@@ -67,5 +68,9 @@ return [
|
|||||||
],
|
],
|
||||||
'cache_ttl' => env('ISPCONFIG_CACHE_TTL', 300), // 5 minutes
|
'cache_ttl' => env('ISPCONFIG_CACHE_TTL', 300), // 5 minutes
|
||||||
],
|
],
|
||||||
|
'nextcloud' => [
|
||||||
|
'url' => env('NEXTCLOUD_URL'),
|
||||||
|
'user' => env('NEXTCLOUD_USERNAME'),
|
||||||
|
'password' => env('NEXTCLOUD_PASSWORD')
|
||||||
|
],
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -0,0 +1,27 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::create('webdomains_members', function (Blueprint $table) {
|
||||||
|
$table->id();
|
||||||
|
$table->timestamps();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('webdomains_members');
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
<div class="space-y-4">
|
||||||
|
@foreach($ispconfigs as $ispconfig)
|
||||||
|
<div class="border rounded-lg p-4 bg-white dark:bg-gray-800">
|
||||||
|
<div class="flex items-start justify-between mb-3">
|
||||||
|
<h4 class="text-lg font-semibold text-gray-900 dark:text-white">
|
||||||
|
{{ $ispconfig->data['domain'] ?? 'Domaine non défini' }}
|
||||||
|
</h4>
|
||||||
|
<div>
|
||||||
|
<a
|
||||||
|
href="#"
|
||||||
|
target="_blank"
|
||||||
|
class="inline-flex items-center gap-1 text-sm text-primary-600 hover:text-primary-700 dark:text-primary-400 font-medium"
|
||||||
|
>
|
||||||
|
Gérer dans ISPConfig
|
||||||
|
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="grid grid-cols-2 gap-3 text-sm">
|
||||||
|
@foreach($ispconfig->data as $key => $value)
|
||||||
|
@if(!is_array($value) && !is_null($value))
|
||||||
|
<div class="flex flex-col">
|
||||||
|
<span class="text-gray-500 dark:text-gray-400 text-xs">
|
||||||
|
{{ ucfirst(str_replace('_', ' ', $key)) }}
|
||||||
|
</span>
|
||||||
|
<span class="font-medium text-gray-900 dark:text-white">
|
||||||
|
{{ $value }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
@endforeach
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@endforeach
|
||||||
|
</div>
|
||||||
Reference in New Issue
Block a user