137 lines
6.2 KiB
PHP
137 lines
6.2 KiB
PHP
<?php
|
|
|
|
namespace Database\Seeders;
|
|
|
|
use App\Models\ActivityLog;
|
|
use App\Models\Equipment;
|
|
use App\Models\Priority;
|
|
use App\Models\RequestComment;
|
|
use App\Models\RequestType;
|
|
use App\Models\ServiceRequest;
|
|
use App\Models\Status;
|
|
use App\Models\User;
|
|
use Illuminate\Database\Seeder;
|
|
|
|
class ServiceRequestSeeder extends Seeder
|
|
{
|
|
public function run(): void
|
|
{
|
|
$types = RequestType::query()->get();
|
|
$priorities = Priority::query()->orderBy('level')->get();
|
|
$statuses = Status::query()->get()->keyBy('slug');
|
|
$clients = User::query()->where('role', 'client')->get();
|
|
$techs = User::query()->where('role', 'technician')->get();
|
|
$equipment = Equipment::query()->get();
|
|
|
|
// Распределение: 10 активных, 8 в ожидании/в работе с дедлайном сегодня-завтра,
|
|
// 4 решённых, 3 закрытых.
|
|
$buckets = [
|
|
// [slug, count, deadline_offset_hours от now]
|
|
['new', 4, [+48, +168]], // новые — дедлайн через 2-7 дней
|
|
['in_progress', 6, [+4, +48]], // в работе — дедлайн через 4-48 ч
|
|
['waiting', 4, [+24, +96]], // ожидание — дедлайн через 1-4 дня
|
|
['resolved', 5, [-72, -1]], // решены — дедлайн в прошлом
|
|
['closed', 4, [-168, -24]], // закрыты — дедлайн в прошлом
|
|
['cancelled', 2, [-240, -48]], // отменены
|
|
];
|
|
|
|
$counter = 1;
|
|
|
|
foreach ($buckets as [$slug, $count, [$dlMin, $dlMax]]) {
|
|
$status = $statuses[$slug] ?? $statuses->first();
|
|
|
|
for ($i = 0; $i < $count; $i++) {
|
|
$type = $types->random();
|
|
$priority = $priorities->random();
|
|
$client = $clients->random();
|
|
$assignee = $techs->random();
|
|
|
|
$deadlineAt = now()->addHours(rand($dlMin, $dlMax));
|
|
|
|
// created_at: задолго до дедлайна, но реалистично
|
|
$createdAt = (clone $deadlineAt)->subHours($type->sla_hours + rand(0, 12));
|
|
|
|
// Не даём created_at быть в будущем
|
|
if ($createdAt->isFuture()) {
|
|
$createdAt = now()->subMinutes(rand(10, 120));
|
|
}
|
|
|
|
$startedAt = null;
|
|
$completedAt = null;
|
|
$resolutionNotes = null;
|
|
$clientRating = null;
|
|
$clientComment = null;
|
|
|
|
if (in_array($slug, ['in_progress', 'resolved', 'closed'])) {
|
|
$startedAt = (clone $createdAt)->addHours(rand(1, 4));
|
|
}
|
|
|
|
if (in_array($slug, ['resolved', 'closed'])) {
|
|
$completedAt = (clone $deadlineAt)->subHours(rand(0, 6));
|
|
$resolutionNotes = fake()->sentence(12);
|
|
}
|
|
|
|
if ($slug === 'closed') {
|
|
$clientRating = rand(3, 5);
|
|
$clientComment = fake()->sentence();
|
|
}
|
|
|
|
$request = ServiceRequest::query()->create([
|
|
'ticket_number' => sprintf('SRV-%04d', $counter),
|
|
'title' => fake()->randomElement([
|
|
'Не включается рабочая станция',
|
|
'Проблема с печатью документов',
|
|
'Нет доступа к корпоративной сети',
|
|
'Требуется установка ПО',
|
|
'Сильный шум вентилятора',
|
|
'Зависает операционная система',
|
|
'Не работает монитор',
|
|
'Проблема с принтером',
|
|
]),
|
|
'description' => fake()->paragraph(3),
|
|
'type_id' => $type->id,
|
|
'priority_id' => $priority->id,
|
|
'status_id' => $status->id,
|
|
'client_id' => $client->id,
|
|
'assigned_to' => $assignee->id,
|
|
'equipment_id' => rand(0, 100) > 20 ? $equipment->random()?->id : null,
|
|
'location' => fake()->randomElement(['Офис 101', 'Офис 204', 'Склад', 'Переговорная 2']),
|
|
'planned_at' => rand(0, 100) > 50 ? (clone $createdAt)->addHours(rand(2, 24)) : null,
|
|
'deadline_at' => $deadlineAt,
|
|
'started_at' => $startedAt,
|
|
'completed_at' => $completedAt,
|
|
'resolution_notes' => $resolutionNotes,
|
|
'client_rating' => $clientRating,
|
|
'client_comment' => $clientComment,
|
|
'created_at' => $createdAt,
|
|
'updated_at' => now(),
|
|
]);
|
|
|
|
for ($c = 1; $c <= rand(1, 3); $c++) {
|
|
$author = rand(0, 1) ? $client : $assignee;
|
|
RequestComment::query()->create([
|
|
'request_id' => $request->id,
|
|
'user_id' => $author->id,
|
|
'body' => fake()->sentence(rand(10, 20)),
|
|
'is_internal' => $author->role !== 'client' && rand(0, 100) > 60,
|
|
'created_at' => (clone $createdAt)->addHours($c),
|
|
'updated_at' => (clone $createdAt)->addHours($c),
|
|
]);
|
|
}
|
|
|
|
ActivityLog::query()->create([
|
|
'user_id' => $assignee->id,
|
|
'model_type' => ServiceRequest::class,
|
|
'model_id' => $request->id,
|
|
'action' => 'created',
|
|
'description' => "Создана заявка {$request->ticket_number}",
|
|
'ip_address' => '127.0.0.1',
|
|
'created_at' => $createdAt,
|
|
]);
|
|
|
|
$counter++;
|
|
}
|
|
}
|
|
}
|
|
}
|