Files
onboard/app/Console/Commands/FillReportsFromDate.php
2026-04-21 10:08:14 +09:00

130 lines
4.9 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace App\Console\Commands;
use App\Models\Department;
use App\Models\User;
use App\Services\AutoReportService;
use Illuminate\Console\Command;
use Illuminate\Support\Carbon;
class FillReportsFromDate extends Command
{
protected $signature = 'reports:fill
{--date= : Дата начала в формате YYYY-MM-DD}
{--end-date= : Дата окончания (по умолчанию сегодня)}
{--department= : ID отделения (опционально)}
{--user= : ID пользователя для отчета (опционально)}
{--force : Перезаписать существующие отчеты}';
protected $description = 'Автоматически заполнить отчеты с указанной даты';
public function __construct(
protected AutoReportService $autoReportService
) {
parent::__construct();
}
public function handle()
{
$startDate = $this->option('date') ?? Carbon::now('Asia/Yakutsk')->subDays(7)->format('Y-m-d');
$endDate = $this->option('end-date') ?? Carbon::now('Asia/Yakutsk')->format('Y-m-d');
$departmentId = $this->option('department');
$userId = $this->option('user');
$force = $this->option('force');
try {
$start = Carbon::createFromFormat('Y-m-d', $startDate, 'Asia/Yakutsk')->startOfDay();
$end = Carbon::createFromFormat('Y-m-d', $endDate, 'Asia/Yakutsk')->startOfDay();
} catch (\Throwable) {
$this->error('Неверный формат даты. Используйте YYYY-MM-DD.');
return 1;
}
if ($start->gt($end)) {
$this->error('Дата начала больше даты окончания.');
return 1;
}
$this->info("Заполнение отчетов с {$startDate} по {$endDate}");
// Получаем отделения
$departments = $departmentId
? Department::where('department_id', $departmentId)->get()
: Department::all();
if ($departments->isEmpty()) {
$this->error('Отделения не найдены');
return 1;
}
$totalReports = 0;
$totalErrors = 0;
foreach ($departments as $department) {
$this->info("Обработка отделения: {$department->name_short}");
$user = $this->resolveResponsibleUser($department, $userId);
if (!$user) {
$this->warn("В отделении {$department->name_short} нет подходящего пользователя для автозаполнения");
continue;
}
try {
$created = $this->autoReportService->fillReportsForUser(
$user,
$startDate,
$endDate,
$department,
$force,
);
$totalReports += $created;
$this->info("Для пользователя {$user->name} создано {$created} отчетов");
} catch (\Exception $e) {
$totalErrors++;
$this->error("Ошибка для пользователя {$user->name}: {$e->getMessage()}");
}
}
$this->info("Готово! Создано отчетов: {$totalReports}, ошибок: {$totalErrors}");
return 0;
}
private function resolveResponsibleUser(Department $department, ?string $userId): ?User
{
$query = User::query()
->where('is_active', true)
->whereHas('departments', function ($departmentQuery) use ($department) {
$departmentQuery->where('rf_department_id', $department->department_id);
})
->whereHas('roles', function ($roleQuery) {
$roleQuery->where('slug', 'doctor');
})
->with(['roles', 'departments']);
if ($userId) {
return $query->where('id', $userId)->first();
}
return $query->get()
->sortBy(function (User $user) use ($department) {
$departmentLink = $user->departments->firstWhere('rf_department_id', $department->department_id);
$isDoctor = $user->roles->contains('slug', 'doctor');
$isFavorite = (bool) optional($departmentLink)->is_favorite;
$order = optional($departmentLink)->order ?? PHP_INT_MAX;
return sprintf(
'%d-%d-%010d-%010d',
$isDoctor ? 0 : 1,
$isFavorite ? 0 : 1,
$order,
$user->id
);
})
->first();
}
}