Files
L-Ami-Fiduciaire/database/seeders/DatabaseSeeder.php

204 lines
14 KiB
PHP
Raw Permalink Normal View History

<?php
namespace Database\Seeders;
use App\Enums\ClientStatus;
use App\Enums\DeclarationPriority;
use App\Enums\DeclarationStatus;
use App\Enums\DeclarationType;
use App\Enums\LegalForm;
use App\Enums\UserGroup;
use App\Enums\WorkspaceUserRole;
use App\Models\Client;
use App\Models\ClientContact;
use App\Models\Declaration;
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::Worker]);
$wsCasa->users()->attach($khadija->id, ['role' => WorkspaceUserRole::Worker]);
$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,
]);
}
// --- Declarations for Casablanca clients ---
$declarationTypes = [
['type' => DeclarationType::VatMonthly, 'label' => 'TVA mensuelle'],
['type' => DeclarationType::VatQuarterly, 'label' => 'TVA trimestrielle'],
['type' => DeclarationType::CorporateTax, 'label' => 'IS'],
['type' => DeclarationType::IncomeTax, 'label' => 'IR'],
['type' => DeclarationType::CNSS, 'label' => 'CNSS'],
['type' => DeclarationType::AnnualBalance, 'label' => 'Bilan annuel'],
];
$statuses = [
DeclarationStatus::Created,
DeclarationStatus::EnCours,
DeclarationStatus::EnAttenteClient,
DeclarationStatus::Termine,
DeclarationStatus::Ferme,
];
$priorities = [DeclarationPriority::Low, DeclarationPriority::Medium, DeclarationPriority::High];
$declarationIndex = 0;
foreach ($createdCasaClients as $client) {
// Each client gets 2-4 declarations
$numDeclarations = fake()->numberBetween(2, 4);
$selectedTypes = fake()->randomElements($declarationTypes, $numDeclarations);
foreach ($selectedTypes as $dt) {
$year = fake()->randomElement([2025, 2026]);
$status = $statuses[$declarationIndex % count($statuses)];
$isVatMonthly = $dt['type'] === DeclarationType::VatMonthly;
$isVatQuarterly = $dt['type'] === DeclarationType::VatQuarterly;
$month = $isVatMonthly ? fake()->numberBetween(1, 3) : null;
$quarter = $isVatQuarterly ? fake()->numberBetween(1, 4) : null;
$periodSuffix = $isVatMonthly ? " — Mois $month" : ($isVatQuarterly ? " — T$quarter" : '');
$declaration = Declaration::create([
'workspace_id' => $wsCasa->id,
'client_id' => $client->id,
'created_by' => $responsibles[$declarationIndex % count($responsibles)]->id,
'title' => "Déclaration {$dt['label']} $year{$periodSuffix}",
'type' => $dt['type'],
'period_year' => $year,
'period_month' => $month,
'period_quarter' => $quarter,
'due_date' => fake()->dateTimeBetween('2026-01-01', '2026-06-30'),
'status' => $status,
'priority' => $priorities[$declarationIndex % count($priorities)],
'assigned_to' => $responsibles[$declarationIndex % 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.',
]),
]);
// Set archived_at for ferme declarations (observer only fires on updating, not creating)
if ($status === DeclarationStatus::Ferme) {
$declaration->forceFill(['archived_at' => now()])->saveQuietly();
}
$declarationIndex++;
}
}
}
}