toArray(); $products = DB::table('products')->select('id', 'prix_unitaire')->get()->keyBy('id'); $productIds = $products->keys()->toArray(); if (empty($clientIds) || empty($productIds)) { $this->command->warn('QuoteSeeder: aucun client ou produit trouvé — skip.'); return; } // ── Statuses ────────────────────────────────────────────────────────── $statusPool = array_merge( array_fill(0, 40, 'accepte'), array_fill(0, 18, 'envoye'), array_fill(0, 8, 'brouillon'), array_fill(0, 10, 'refuse'), array_fill(0, 7, 'expire') ); shuffle($statusPool); // ── Date entries : 2024 + 2025 + 2026 Jan-May ──────────────────────── $entries = []; // 2024 (historical) for ($m = 1; $m <= 12; $m++) { for ($i = 0, $n = rand(2, 4); $i < $n; $i++) { $entries[] = sprintf('2024-%02d-%02d', $m, rand(1, 28)); } } // 2025 for ($m = 1; $m <= 12; $m++) { for ($i = 0, $n = rand(3, 5); $i < $n; $i++) { $entries[] = sprintf('2025-%02d-%02d', $m, rand(1, 28)); } } // 2026 Jan-May for ($m = 1; $m <= 5; $m++) { $maxDay = ($m === 5) ? 8 : 28; for ($i = 0, $n = rand(3, 5); $i < $n; $i++) { $entries[] = sprintf('2026-%02d-%02d', $m, rand(1, $maxDay)); } } shuffle($entries); // ── Create quotes ───────────────────────────────────────────────────── foreach ($entries as $idx => $quoteDate) { $status = $statusPool[$idx % count($statusPool)]; $clientId = $clientIds[array_rand($clientIds)]; $validUntil = date('Y-m-d', strtotime($quoteDate . ' +30 days')); // Build lines $lineData = []; $totalHt = 0.0; for ($l = 0, $nl = rand(1, 3); $l < $nl; $l++) { $pid = $productIds[array_rand($productIds)]; $unitPrice = (float) ($products->get($pid)->prix_unitaire ?? 100.00); $qty = rand(1, 3); $lineHt = round($unitPrice * $qty, 2); $totalHt += $lineHt; $lineData[] = [ 'product_id' => $pid, 'description' => 'Prestation funéraire', 'qty_base' => $qty, 'unit_price' => $unitPrice, 'discount_pct' => 0, 'total_ht' => $lineHt, ]; } $totalTva = round($totalHt * 0.20, 2); $totalTtc = round($totalHt + $totalTva, 2); $quote = Quote::create([ 'client_id' => $clientId, 'status' => $status, 'quote_date' => $quoteDate, 'valid_until' => $validUntil, 'currency' => 'EUR', 'total_ht' => $totalHt, 'total_tva' => $totalTva, 'total_ttc' => $totalTtc, ]); foreach ($lineData as $line) { QuoteLine::create(array_merge($line, ['quote_id' => $quote->id])); } } $this->command->info('QuoteSeeder: ' . count($entries) . ' devis créés.'); } }