201 lines
13 KiB
PHP
201 lines
13 KiB
PHP
|
|
<?php
|
||
|
|
|
||
|
|
namespace Database\Seeders;
|
||
|
|
|
||
|
|
use App\Enums\ClientStatus;
|
||
|
|
use App\Enums\FolderPriority;
|
||
|
|
use App\Enums\FolderStatus;
|
||
|
|
use App\Enums\FolderType;
|
||
|
|
use App\Enums\LegalForm;
|
||
|
|
use App\Enums\UserGroup;
|
||
|
|
use App\Enums\WorkspaceUserRole;
|
||
|
|
use App\Models\Client;
|
||
|
|
use App\Models\ClientContact;
|
||
|
|
use App\Models\Folder;
|
||
|
|
use App\Models\User;
|
||
|
|
use App\Models\Workspace;
|
||
|
|
use Illuminate\Database\Seeder;
|
||
|
|
|
||
|
|
class DatabaseSeeder extends Seeder
|
||
|
|
{
|
||
|
|
/**
|
||
|
|
* Seed the application's database with realistic Moroccan data.
|
||
|
|
*/
|
||
|
|
public function run(): void
|
||
|
|
{
|
||
|
|
// --- Users (firm employees) ---
|
||
|
|
$admin = User::factory()->create([
|
||
|
|
'name' => 'Saad El Amrani',
|
||
|
|
'email' => 'saad@amifiduciaire.ma',
|
||
|
|
'password' => bcrypt('password'),
|
||
|
|
'group' => UserGroup::Superadmin,
|
||
|
|
]);
|
||
|
|
|
||
|
|
$fatima = User::factory()->create([
|
||
|
|
'name' => 'Fatima Bennis',
|
||
|
|
'email' => 'fatima@amifiduciaire.ma',
|
||
|
|
'password' => bcrypt('password'),
|
||
|
|
'group' => UserGroup::Admin,
|
||
|
|
]);
|
||
|
|
|
||
|
|
$youssef = User::factory()->create([
|
||
|
|
'name' => 'Youssef Tazi',
|
||
|
|
'email' => 'youssef@amifiduciaire.ma',
|
||
|
|
'password' => bcrypt('password'),
|
||
|
|
'group' => UserGroup::User,
|
||
|
|
]);
|
||
|
|
|
||
|
|
$khadija = User::factory()->create([
|
||
|
|
'name' => 'Khadija Alaoui',
|
||
|
|
'email' => 'khadija@amifiduciaire.ma',
|
||
|
|
'password' => bcrypt('password'),
|
||
|
|
'group' => UserGroup::User,
|
||
|
|
]);
|
||
|
|
|
||
|
|
$omar = User::factory()->create([
|
||
|
|
'name' => 'Omar Benjelloun',
|
||
|
|
'email' => 'omar@amifiduciaire.ma',
|
||
|
|
'password' => bcrypt('password'),
|
||
|
|
'group' => UserGroup::User,
|
||
|
|
]);
|
||
|
|
|
||
|
|
$users = [$admin, $fatima, $youssef, $khadija, $omar];
|
||
|
|
|
||
|
|
// --- Workspaces ---
|
||
|
|
$wsCasa = Workspace::create(['name' => "L'Ami Fiduciaire — Casablanca", 'slug' => 'ami-casa']);
|
||
|
|
$wsRabat = Workspace::create(['name' => "L'Ami Fiduciaire — Rabat", 'slug' => 'ami-rabat']);
|
||
|
|
|
||
|
|
// Attach users to workspaces
|
||
|
|
$wsCasa->users()->attach($admin->id, ['role' => WorkspaceUserRole::Owner]);
|
||
|
|
$wsCasa->users()->attach($fatima->id, ['role' => WorkspaceUserRole::Manager]);
|
||
|
|
$wsCasa->users()->attach($youssef->id, ['role' => WorkspaceUserRole::Member]);
|
||
|
|
$wsCasa->users()->attach($khadija->id, ['role' => WorkspaceUserRole::Member]);
|
||
|
|
|
||
|
|
$wsRabat->users()->attach($admin->id, ['role' => WorkspaceUserRole::Owner]);
|
||
|
|
$wsRabat->users()->attach($omar->id, ['role' => WorkspaceUserRole::Manager]);
|
||
|
|
|
||
|
|
// --- Moroccan clients for Casablanca ---
|
||
|
|
$casaClients = [
|
||
|
|
['company_name' => 'Atlas Import-Export SARL', 'legal_form' => LegalForm::SARL, 'ice' => '001234567000012', 'fiscal_id' => '12345678', 'rc' => '123456', 'cnss' => '1234567890', 'patente' => '12345678', 'contact_last_name' => 'Bennani', 'contact_first_name' => 'Ahmed', 'contact_job_title' => 'Gérant', 'contact_email' => 'a.bennani@atlasimport.ma', 'contact_phone' => '+212 522 123456'],
|
||
|
|
['company_name' => 'Maghreb Textile SA', 'legal_form' => LegalForm::SA, 'ice' => '001234567000028', 'fiscal_id' => '23456789', 'rc' => '234567', 'cnss' => '2345678901', 'patente' => '23456789', 'contact_last_name' => 'Chraibi', 'contact_first_name' => 'Nadia', 'contact_job_title' => 'Directrice Générale', 'contact_email' => 'n.chraibi@maghrebtextile.ma', 'contact_phone' => '+212 522 234567'],
|
||
|
|
['company_name' => 'Dar Al Maalem Construction', 'legal_form' => LegalForm::SARL, 'ice' => '001234567000034', 'fiscal_id' => '34567890', 'rc' => '345678', 'cnss' => '3456789012', 'patente' => '34567890', 'contact_last_name' => 'Fassi Fihri', 'contact_first_name' => 'Karim', 'contact_job_title' => 'Directeur Technique', 'contact_email' => 'k.fassifihri@daralmaalem.ma', 'contact_phone' => '+212 522 345678'],
|
||
|
|
['company_name' => 'Souss Agro-Alimentaire', 'legal_form' => LegalForm::SA, 'ice' => '001234567000040', 'fiscal_id' => '45678901', 'rc' => '456789', 'cnss' => '4567890123', 'patente' => '45678901', 'contact_last_name' => 'Ouazzani', 'contact_first_name' => 'Rachid', 'contact_job_title' => 'PDG', 'contact_email' => 'r.ouazzani@soussagro.ma', 'contact_phone' => '+212 528 456789'],
|
||
|
|
['company_name' => 'Marrakech Digital Solutions', 'legal_form' => LegalForm::SARL, 'ice' => '001234567000056', 'fiscal_id' => '56789012', 'rc' => '567890', 'cnss' => '5678901234', 'patente' => '56789012', 'contact_last_name' => 'El Idrissi', 'contact_first_name' => 'Salma', 'contact_job_title' => 'Gérante', 'contact_email' => 's.elidrissi@mkdigital.ma', 'contact_phone' => '+212 524 567890'],
|
||
|
|
['company_name' => 'Boulangerie Fès El Bali', 'legal_form' => LegalForm::AutoEntrepreneur, 'ice' => '001234567000062', 'fiscal_id' => '67890123', 'rc' => '678901', 'cnss' => '6789012345', 'patente' => '67890123', 'contact_last_name' => 'Amrani', 'contact_first_name' => 'Hassan', 'contact_job_title' => 'Propriétaire', 'contact_email' => 'h.amrani@boulangeriefes.ma', 'contact_phone' => '+212 535 678901'],
|
||
|
|
['company_name' => 'Pharmacie Anfa', 'legal_form' => LegalForm::SEL, 'ice' => '001234567000078', 'fiscal_id' => '78901234', 'rc' => '789012', 'cnss' => '7890123456', 'patente' => '78901234', 'contact_last_name' => 'Berrada', 'contact_first_name' => 'Laila', 'contact_job_title' => 'Pharmacienne', 'contact_email' => 'l.berrada@pharmacieanfa.ma', 'contact_phone' => '+212 522 789012'],
|
||
|
|
['company_name' => 'Transport Rif Express', 'legal_form' => LegalForm::SARL, 'ice' => '001234567000084', 'fiscal_id' => '89012345', 'rc' => '890123', 'cnss' => '8901234567', 'patente' => '89012345', 'contact_last_name' => 'Kettani', 'contact_first_name' => 'Mehdi', 'contact_job_title' => 'Gérant', 'contact_email' => 'm.kettani@rifexpress.ma', 'contact_phone' => '+212 539 890123'],
|
||
|
|
['company_name' => 'Cabinet Juridique El Mansour', 'legal_form' => LegalForm::SNC, 'ice' => '001234567000090', 'fiscal_id' => '90123456', 'rc' => '901234', 'cnss' => '9012345678', 'patente' => '90123456', 'contact_last_name' => 'El Mansouri', 'contact_first_name' => 'Zineb', 'contact_job_title' => 'Avocate Associée', 'contact_email' => 'z.elmansouri@cabinetmansour.ma', 'contact_phone' => '+212 522 901234'],
|
||
|
|
['company_name' => 'Hôtel Riad Zitoun', 'legal_form' => LegalForm::SARL, 'ice' => '001234567000103', 'fiscal_id' => '01234567', 'rc' => '012345', 'cnss' => '0123456789', 'patente' => '01234567', 'contact_last_name' => 'Skalli', 'contact_first_name' => 'Younes', 'contact_job_title' => 'Directeur', 'contact_email' => 'y.skalli@riadzitoun.ma', 'contact_phone' => '+212 524 012345'],
|
||
|
|
];
|
||
|
|
|
||
|
|
$responsibles = [$youssef, $khadija, $fatima];
|
||
|
|
$createdCasaClients = [];
|
||
|
|
|
||
|
|
foreach ($casaClients as $i => $data) {
|
||
|
|
$data['workspace_id'] = $wsCasa->id;
|
||
|
|
$data['internal_responsible_id'] = $responsibles[$i % count($responsibles)]->id;
|
||
|
|
$data['status'] = $i < 8 ? ClientStatus::Active : ClientStatus::Inactive;
|
||
|
|
|
||
|
|
$client = Client::create($data);
|
||
|
|
ClientContact::create([
|
||
|
|
'client_id' => $client->id,
|
||
|
|
'full_name' => $data['contact_first_name'] . ' ' . $data['contact_last_name'],
|
||
|
|
'job_title' => $data['contact_job_title'],
|
||
|
|
'email' => $data['contact_email'],
|
||
|
|
'phone' => $data['contact_phone'],
|
||
|
|
'is_principal' => true,
|
||
|
|
]);
|
||
|
|
$createdCasaClients[] = $client;
|
||
|
|
}
|
||
|
|
|
||
|
|
// --- Moroccan clients for Rabat ---
|
||
|
|
$rabatClients = [
|
||
|
|
['company_name' => 'Bureau d\'Études Oualili', 'legal_form' => LegalForm::SARL, 'ice' => '002345678000011', 'fiscal_id' => '11223344', 'rc' => '112233', 'cnss' => '1122334455', 'patente' => '11223344', 'contact_last_name' => 'Meknassi', 'contact_first_name' => 'Amine', 'contact_job_title' => 'Ingénieur Principal', 'contact_email' => 'a.meknassi@oualili.ma', 'contact_phone' => '+212 537 112233'],
|
||
|
|
['company_name' => 'Imprimerie Chellah', 'legal_form' => LegalForm::EURL, 'ice' => '002345678000027', 'fiscal_id' => '22334455', 'rc' => '223344', 'cnss' => '2233445566', 'patente' => '22334455', 'contact_last_name' => 'Zniber', 'contact_first_name' => 'Samira', 'contact_job_title' => 'Directrice', 'contact_email' => 's.zniber@imprimeriechellah.ma', 'contact_phone' => '+212 537 223344'],
|
||
|
|
['company_name' => 'Café Oudaya SARL', 'legal_form' => LegalForm::SARL, 'ice' => '002345678000033', 'fiscal_id' => '33445566', 'rc' => '334455', 'cnss' => '3344556677', 'patente' => '33445566', 'contact_last_name' => 'Belhaj', 'contact_first_name' => 'Mouad', 'contact_job_title' => 'Gérant', 'contact_email' => 'm.belhaj@cafeoudaya.ma', 'contact_phone' => '+212 537 334455'],
|
||
|
|
['company_name' => 'Clinique Agdal Santé', 'legal_form' => LegalForm::SA, 'ice' => '002345678000049', 'fiscal_id' => '44556677', 'rc' => '445566', 'cnss' => '4455667788', 'patente' => '44556677', 'contact_last_name' => 'Guessous', 'contact_first_name' => 'Hind', 'contact_job_title' => 'Administratrice', 'contact_email' => 'h.guessous@cliniqueagdal.ma', 'contact_phone' => '+212 537 445566'],
|
||
|
|
['company_name' => 'Pâtisserie Yasmina', 'legal_form' => LegalForm::EntrepriseIndividuelle, 'ice' => '002345678000055', 'fiscal_id' => '55667788', 'rc' => '556677', 'cnss' => '5566778899', 'patente' => '55667788', 'contact_last_name' => 'Tahiri', 'contact_first_name' => 'Yasmina', 'contact_job_title' => 'Propriétaire', 'contact_email' => 'y.tahiri@patisserieyasmina.ma', 'contact_phone' => '+212 537 556677'],
|
||
|
|
];
|
||
|
|
|
||
|
|
foreach ($rabatClients as $data) {
|
||
|
|
$data['workspace_id'] = $wsRabat->id;
|
||
|
|
$data['internal_responsible_id'] = $omar->id;
|
||
|
|
$data['status'] = ClientStatus::Active;
|
||
|
|
|
||
|
|
$client = Client::create($data);
|
||
|
|
ClientContact::create([
|
||
|
|
'client_id' => $client->id,
|
||
|
|
'full_name' => $data['contact_first_name'] . ' ' . $data['contact_last_name'],
|
||
|
|
'job_title' => $data['contact_job_title'],
|
||
|
|
'email' => $data['contact_email'],
|
||
|
|
'phone' => $data['contact_phone'],
|
||
|
|
'is_principal' => true,
|
||
|
|
]);
|
||
|
|
}
|
||
|
|
|
||
|
|
// --- Folders (dossiers) for Casablanca clients ---
|
||
|
|
$folderTypes = [
|
||
|
|
['type' => FolderType::VatMonthly, 'label' => 'TVA mensuelle'],
|
||
|
|
['type' => FolderType::VatQuarterly, 'label' => 'TVA trimestrielle'],
|
||
|
|
['type' => FolderType::CorporateTax, 'label' => 'IS'],
|
||
|
|
['type' => FolderType::IncomeTax, 'label' => 'IR'],
|
||
|
|
['type' => FolderType::CNSS, 'label' => 'CNSS'],
|
||
|
|
['type' => FolderType::AnnualBalance, 'label' => 'Bilan annuel'],
|
||
|
|
];
|
||
|
|
|
||
|
|
$statuses = [
|
||
|
|
FolderStatus::Draft,
|
||
|
|
FolderStatus::WaitingDocuments,
|
||
|
|
FolderStatus::DocumentsReceived,
|
||
|
|
FolderStatus::Processing,
|
||
|
|
FolderStatus::WaitingClientValidation,
|
||
|
|
FolderStatus::Validated,
|
||
|
|
FolderStatus::Closed,
|
||
|
|
];
|
||
|
|
|
||
|
|
$priorities = [FolderPriority::Low, FolderPriority::Medium, FolderPriority::High];
|
||
|
|
|
||
|
|
$folderIndex = 0;
|
||
|
|
foreach ($createdCasaClients as $client) {
|
||
|
|
// Each client gets 2-4 folders
|
||
|
|
$numFolders = fake()->numberBetween(2, 4);
|
||
|
|
$selectedTypes = fake()->randomElements($folderTypes, $numFolders);
|
||
|
|
|
||
|
|
foreach ($selectedTypes as $ft) {
|
||
|
|
$year = fake()->randomElement([2025, 2026]);
|
||
|
|
$status = $statuses[$folderIndex % count($statuses)];
|
||
|
|
$isVatMonthly = $ft['type'] === FolderType::VatMonthly;
|
||
|
|
$isVatQuarterly = $ft['type'] === FolderType::VatQuarterly;
|
||
|
|
$month = $isVatMonthly ? fake()->numberBetween(1, 3) : null;
|
||
|
|
$quarter = $isVatQuarterly ? fake()->numberBetween(1, 4) : null;
|
||
|
|
|
||
|
|
$periodSuffix = $isVatMonthly ? " — Mois $month" : ($isVatQuarterly ? " — T$quarter" : '');
|
||
|
|
|
||
|
|
Folder::create([
|
||
|
|
'workspace_id' => $wsCasa->id,
|
||
|
|
'client_id' => $client->id,
|
||
|
|
'created_by' => $responsibles[$folderIndex % count($responsibles)]->id,
|
||
|
|
'title' => "Déclaration {$ft['label']} $year{$periodSuffix}",
|
||
|
|
'type' => $ft['type'],
|
||
|
|
'period_year' => $year,
|
||
|
|
'period_month' => $month,
|
||
|
|
'period_quarter' => $quarter,
|
||
|
|
'due_date' => fake()->dateTimeBetween('2026-01-01', '2026-06-30'),
|
||
|
|
'status' => $status,
|
||
|
|
'priority' => $priorities[$folderIndex % count($priorities)],
|
||
|
|
'assigned_to' => $responsibles[$folderIndex % count($responsibles)]->id,
|
||
|
|
'notes_internal' => fake()->optional(0.4)->randomElement([
|
||
|
|
'En attente des relevés bancaires.',
|
||
|
|
'Client à relancer pour les factures manquantes.',
|
||
|
|
'Dossier prioritaire — échéance proche.',
|
||
|
|
'Documents reçus partiellement.',
|
||
|
|
'Vérification en cours avec la DGI.',
|
||
|
|
]),
|
||
|
|
]);
|
||
|
|
|
||
|
|
$folderIndex++;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|