134 lines
4.9 KiB
PHP
134 lines
4.9 KiB
PHP
<?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();
|
||
}
|
||
}
|