2025-11-14 17:27:39 +01:00
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
namespace App\Console\Commands;
|
|
|
|
|
|
|
|
|
|
use App\Models\Member;
|
2025-11-15 17:09:56 +01:00
|
|
|
use App\Models\Membership;
|
2026-01-11 18:13:18 +01:00
|
|
|
use App\Services\Dolibarr\DolibarrService;
|
2025-11-14 17:27:39 +01:00
|
|
|
use Carbon\Carbon;
|
|
|
|
|
use Illuminate\Console\Command;
|
|
|
|
|
use Illuminate\Http\Client\ConnectionException;
|
2025-11-15 17:09:56 +01:00
|
|
|
use function Laravel\Prompts\progress;
|
2025-11-14 17:27:39 +01:00
|
|
|
|
|
|
|
|
class SyncDolibarrMembers extends Command
|
|
|
|
|
{
|
|
|
|
|
/**
|
|
|
|
|
* The name and signature of the console command.
|
|
|
|
|
*
|
2025-11-15 17:09:56 +01:00
|
|
|
* @var string */
|
|
|
|
|
protected $signature = 'sync:dolibarr-members';
|
2025-11-14 17:27:39 +01:00
|
|
|
|
|
|
|
|
/**
|
2025-11-15 17:09:56 +01:00
|
|
|
* The console command description. *
|
2025-11-14 17:27:39 +01:00
|
|
|
*
|
2025-11-15 17:09:56 +01:00
|
|
|
* @var string */
|
2025-11-14 17:27:39 +01:00
|
|
|
protected $description = 'Retrieve members data from Dolibarr';
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Execute the console command.
|
|
|
|
|
* @throws ConnectionException
|
|
|
|
|
*/
|
|
|
|
|
public function handle(): void
|
|
|
|
|
{
|
|
|
|
|
$this->info('Starting Dolibarr members import...');
|
2025-11-15 17:09:56 +01:00
|
|
|
|
|
|
|
|
$client = new DolibarrService;
|
|
|
|
|
|
|
|
|
|
// $doliMembers = collect($client->getAllMembers())->take(10); // For test
|
2025-11-14 17:27:39 +01:00
|
|
|
$doliMembers = collect($client->getAllMembers());
|
|
|
|
|
|
2025-11-15 17:09:56 +01:00
|
|
|
$progressBar = progress(label: 'Dolibarr Members import', steps: $doliMembers->count());
|
2025-11-14 17:27:39 +01:00
|
|
|
$progressBar->start();
|
2025-11-15 17:09:56 +01:00
|
|
|
|
|
|
|
|
// Stats trackers
|
|
|
|
|
$createdMembers = 0;
|
|
|
|
|
$updatedMembers = 0;
|
|
|
|
|
$createdMemberships = 0;
|
|
|
|
|
$updatedMemberships = 0;
|
|
|
|
|
|
|
|
|
|
// Status mapping from Dolibarr
|
|
|
|
|
$memberStatuses = [
|
|
|
|
|
'-2' => 'excluded',
|
|
|
|
|
'0' => 'cancelled',
|
|
|
|
|
'1' => 'valid'
|
|
|
|
|
];
|
2025-11-14 17:27:39 +01:00
|
|
|
|
|
|
|
|
foreach ($doliMembers as $member) {
|
2025-11-15 17:09:56 +01:00
|
|
|
|
|
|
|
|
// CREATE or UPDATE MEMBER
|
|
|
|
|
$newMember = Member::updateOrCreate(
|
|
|
|
|
['dolibarr_id' => $member['id']],
|
|
|
|
|
[
|
|
|
|
|
'status' => $memberStatuses[$member['status']] ?? 'draft',
|
|
|
|
|
'nature' => 'physical',
|
|
|
|
|
'member_type' => $member['type'],
|
|
|
|
|
'group_id' => null,
|
|
|
|
|
'lastname' => $member['firstname'],
|
|
|
|
|
'firstname' => $member['lastname'],
|
|
|
|
|
'email' => $member['email'] ?: null,
|
|
|
|
|
'retzien_email' => '',
|
|
|
|
|
'company' => $member['societe'],
|
|
|
|
|
'website_url' => $member['url'],
|
|
|
|
|
'address' => $member['address'],
|
|
|
|
|
'zipcode' => $member['zip'],
|
|
|
|
|
'city' => $member['town'],
|
|
|
|
|
'country' => '',
|
|
|
|
|
'phone1' => $member['phone'],
|
|
|
|
|
'phone2' => $member['phone_mobile'],
|
|
|
|
|
'public_membership' => 0,
|
|
|
|
|
'created_at' => $this->toDate($member['date_creation']),
|
|
|
|
|
]
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// Count member creation/update
|
|
|
|
|
if ($newMember->wasRecentlyCreated) {
|
|
|
|
|
$createdMembers++;
|
|
|
|
|
} else {
|
|
|
|
|
$updatedMembers++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Get subscriptions for memeber
|
|
|
|
|
$memberships = collect($client->getMemberSubscriptions($member['id']));
|
|
|
|
|
|
|
|
|
|
foreach ($memberships as $membership) {
|
|
|
|
|
|
|
|
|
|
$membershipStatus = $membership['datef'] < now()->timestamp ? 'expired' : 'active';
|
|
|
|
|
|
|
|
|
|
$newMembership = Membership::updateOrCreate(
|
|
|
|
|
['dolibarr_id' => $membership['id']],
|
|
|
|
|
[
|
|
|
|
|
'member_id' => $newMember->id,
|
|
|
|
|
'admin_id' => 1,
|
|
|
|
|
'package_id' => 2, // annual subscription
|
|
|
|
|
'start_date' => $this->toDate($membership['dateh']),
|
|
|
|
|
'end_date' => $this->toDate($membership['datef']),
|
|
|
|
|
'status' => $membershipStatus,
|
|
|
|
|
'validation_date' => $this->toDate($membership['datem']),
|
|
|
|
|
'payment_method' => null,
|
|
|
|
|
'amount' => number_format($membership['amount'], 2),
|
|
|
|
|
'payment_status' => 'paid',
|
|
|
|
|
'note_public' => $membership['note_public'],
|
|
|
|
|
'note_private' => $membership['note_private'],
|
|
|
|
|
'dolibarr_user_id' => $member['id']
|
|
|
|
|
]
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// Count membership creation/update
|
|
|
|
|
if ($newMembership->wasRecentlyCreated) {
|
|
|
|
|
$createdMemberships++;
|
|
|
|
|
} else {
|
|
|
|
|
$updatedMemberships++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$progressBar->advance();
|
2025-11-14 17:27:39 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$progressBar->finish();
|
|
|
|
|
|
2025-11-15 17:09:56 +01:00
|
|
|
// Report
|
|
|
|
|
$this->info('');
|
|
|
|
|
$this->info('===== IMPORT SUMMARY =====');
|
|
|
|
|
$this->info("Members created : $createdMembers");
|
|
|
|
|
$this->info("Members updated : $updatedMembers");
|
|
|
|
|
$this->info("Memberships created : $createdMemberships");
|
|
|
|
|
$this->info("Memberships updated : $updatedMemberships");
|
|
|
|
|
$this->info('===========================');
|
|
|
|
|
$this->info('Import completed successfully.');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Convert timestamp to date format safely
|
|
|
|
|
* @todo: export this in a service or repo
|
|
|
|
|
*/
|
|
|
|
|
private function toDate($timestamp): ?string
|
|
|
|
|
{
|
|
|
|
|
return $timestamp
|
|
|
|
|
? Carbon::createFromTimestamp($timestamp)->format('Y-m-d H:i:s')
|
|
|
|
|
: null;
|
2025-11-14 17:27:39 +01:00
|
|
|
}
|
|
|
|
|
}
|