* исправил фантомный сдвиг даты * переделал получение ФИО врачей из отделений * добавил возможность поиска врача * переписал сохранение отчета
145 lines
4.1 KiB
PHP
145 lines
4.1 KiB
PHP
<?php
|
|
|
|
namespace App\Services;
|
|
|
|
use App\Models\User;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Carbon;
|
|
|
|
class DateRangeService
|
|
{
|
|
/**
|
|
* Получить унифицированный объект диапазона дат
|
|
*/
|
|
public function getNormalizedDateRange(User $user, ?string $startAt = null, ?string $endAt = null): DateRange
|
|
{
|
|
[$startDate, $endDate] = $this->getDateRangeForUser($user, $startAt, $endAt);
|
|
|
|
$startCarbon = Carbon::parse($startDate)->setTimeZone('Asia/Yakutsk');
|
|
$endCarbon = Carbon::parse($endDate)->setTimeZone('Asia/Yakutsk');
|
|
|
|
return new DateRange(
|
|
startDate: $startCarbon,
|
|
endDate: $endCarbon,
|
|
startDateRaw: $startDate,
|
|
endDateRaw: $endDate,
|
|
isOneDay: $this->isRangeOneDay($startDate, $endDate)
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Получить диапазон дат из запроса
|
|
*/
|
|
public function getDateRangeFromRequest(Request $request, User $user): DateRange
|
|
{
|
|
return $this->getNormalizedDateRange(
|
|
$user,
|
|
$request->query('startAt', $request->get('startAt')),
|
|
$request->query('endAt', $request->get('endAt'))
|
|
);
|
|
}
|
|
|
|
public function getDateRangeForUser($user, $startAt = null, $endAt = null): array
|
|
{
|
|
if ($startAt && $endAt) {
|
|
return $this->getCustomDateRange($startAt, $endAt, $user);
|
|
}
|
|
|
|
return $this->getDefaultDateRange($user);
|
|
}
|
|
|
|
public function isRangeOneDay($startAt = null, $endAt = null): bool
|
|
{
|
|
if (!$startAt || !$endAt) return false;
|
|
|
|
$startDate = $this->parseDate($startAt);
|
|
$endDate = $this->parseDate($endAt);
|
|
|
|
return $startDate->diffInDays($endDate) === 1.0;
|
|
}
|
|
|
|
private function getCustomDateRange($startAt, $endAt, $user): array
|
|
{
|
|
$startDate = $this->parseDate($startAt);
|
|
$endDate = $this->parseDate($endAt);
|
|
|
|
if ($startDate->isSameDay($endDate)) {
|
|
$startDate = $startDate->subDay()->setTime(6, 0);
|
|
$endDate = $endDate->setTime(6, 0);
|
|
} else {
|
|
$startDate = $startDate->setTime(6, 0);
|
|
$endDate = $endDate->setTime(6, 0);
|
|
}
|
|
|
|
return [
|
|
$startDate->format('Y-m-d H:i:s'),
|
|
$endDate->format('Y-m-d H:i:s')
|
|
];
|
|
}
|
|
|
|
private function getDefaultDateRange($user): array
|
|
{
|
|
$startDate = Carbon::now('Asia/Yakutsk')
|
|
->subDay()
|
|
->setTime(6, 0);
|
|
|
|
$endDate = Carbon::now('Asia/Yakutsk')
|
|
->setTime(6, 0);
|
|
|
|
return [
|
|
$startDate->format('Y-m-d H:i:s'),
|
|
$endDate->format('Y-m-d H:i:s')
|
|
];
|
|
}
|
|
|
|
public function parseDate($dateInput): Carbon
|
|
{
|
|
if (is_numeric($dateInput)) {
|
|
return Carbon::createFromTimestampMs($dateInput)
|
|
->setTimezone('Asia/Yakutsk');
|
|
}
|
|
|
|
return Carbon::parse($dateInput, 'Asia/Yakutsk');
|
|
}
|
|
|
|
/**
|
|
* Конвертировать дату в Carbon объект
|
|
*/
|
|
public function toCarbon($date): Carbon
|
|
{
|
|
if ($date instanceof Carbon) {
|
|
return $date;
|
|
}
|
|
|
|
if (is_string($date)) {
|
|
return Carbon::parse($date, 'Asia/Yakutsk');
|
|
}
|
|
|
|
return Carbon::parse($date);
|
|
}
|
|
|
|
/**
|
|
* Получить дату в формате для SQL запроса
|
|
*/
|
|
public function toSqlFormat($date): string
|
|
{
|
|
return $this->toCarbon($date)->format('Y-m-d H:i:s');
|
|
}
|
|
|
|
public function createDateRangeForDate(Carbon $date, User $user): DateRange
|
|
{
|
|
// Для автоматического заполнения используем логику как для врача
|
|
// (вчера 06:00 - сегодня 06:00)
|
|
$startDate = $date->copy()->subDay()->setTime(6, 0);
|
|
$endDate = $date->copy()->setTime(6, 0);
|
|
|
|
return new DateRange(
|
|
startDate: $startDate,
|
|
endDate: $endDate,
|
|
startDateRaw: $startDate->format('Y-m-d H:i:s'),
|
|
endDateRaw: $endDate->format('Y-m-d H:i:s'),
|
|
isOneDay: true
|
|
);
|
|
}
|
|
}
|