Несколько отделений для врачей

Поправил подсчет операций
Закончил функцию наполнения отчетов
This commit is contained in:
brusnitsyn
2026-02-06 15:15:03 +09:00
parent 10fb138c30
commit 741781dcb3
9 changed files with 117 additions and 50 deletions

View File

@@ -49,11 +49,13 @@ class FillReportsFromDate extends Command
$totalErrors = 0;
foreach ($departments as $department) {
$this->info("Обработка отделения: {$department->name}");
$this->info("Обработка отделения: {$department->name_short}");
// Получаем пользователей отделения
$users = $userId
? User::where('id', $userId)->where('rf_department_id', $department->department_id)->get()
? User::where('id', $userId)->whereHas('departments', function ($query) use ($department) {
$query->where('rf_department_id', $department->department_id);
})->get()
: $this->getDepartmentUsers($department);
if ($users->isEmpty()) {
@@ -67,7 +69,8 @@ class FillReportsFromDate extends Command
$user,
$startDate,
$endDate,
$force
$departmentId,
$force,
);
$totalReports += $created;

View File

@@ -59,21 +59,23 @@ class StatisticController extends Controller
if ($isRangeOneDay) {
// Статистика выводится с нарастающим числом
$reports = $department->reports()
->whereDate('created_at', $dateReport)
$query = $department->reports();
$reports = $query->whereDate('created_at', $dateReport)
->get();
$lastReport = $query->whereDate('created_at', $dateReport)->first();
} else {
$reports = $department->reports()
->whereBetween('created_at', $dateReport)->get();
$query = $department->reports();
$reports = $query->clone()->whereBetween('created_at', $dateReport)
->get();
$lastReport = $query->clone()->whereDate('created_at', $dateReport[1])->first();
}
// Метрики зависищие от отчетов
$allCount = 0; $outcomeCount = 0; $currentCount = 0; $occupiedBeds = 0; $planCount = 0;
$allCount = 0; $outcomeCount = 0; $currentCount = 0; $planCount = 0;
$emergencyCount = 0; $planSurgical = 0; $emergencySurgical = 0; $transferredCount = 0;
$deceasedCount = 0;
$currentCount = $lastReport ? $this->getMetrikaResultFromReport($lastReport, 8, false) : 0; // Состоит
foreach ($reports as $report) {
$allCount += $this->getMetrikaResultFromReport($report, 3, $isRangeOneDay); // Поступило
$currentCount += $this->getMetrikaResultFromReport($report, 8, false); // Состоит
$occupiedBeds += $this->getMetrikaResultFromReport($report, 8, $isRangeOneDay); // Состоит
$planCount += $this->getMetrikaResultFromReport($report, 4, $isRangeOneDay); // Поступление - Планово
$emergencyCount += $this->getMetrikaResultFromReport($report, 12, $isRangeOneDay); // Поступление - Экстренно
$planSurgical += $this->getMetrikaResultFromReport($report, 11, $isRangeOneDay); // Операции - Планово
@@ -83,11 +85,13 @@ class StatisticController extends Controller
$deceasedCount += $this->getMetrikaResultFromReport($report, 9, $isRangeOneDay); // Умерло
}
$allCount = $planCount + $emergencyCount; // Поступило
// Независимые метрики (установки по умолчанию и т.п.)
$bedsCount = $department->metrikaDefault()
->where('rf_metrika_item_id', 1)->value('value');
$percentLoadedBeds = $bedsCount > 0 ? round($occupiedBeds * 100 / $bedsCount) : 0;
$percentLoadedBeds = $bedsCount > 0 ? round($currentCount * 100 / $bedsCount) : 0;
$groupedData[$departmentType][] = [
'department' => $department->name_short,

View File

@@ -38,9 +38,9 @@ class LifeMisMigrationPatient extends Model
$query->where('rf_kl_VisitResultID', 0)
->where('rf_kl_StatCureResultID', 0)
->whereBetween('DateIngoing', [$dateRange->startSql(), $dateRange->endSql()])
->whereHas('medicalHistory', function ($query) use ($branchId, $dateRange) {
$query->whereDate('DateExtract', '1900-01-01');
})
// ->whereHas('medicalHistory', function ($query) use ($branchId, $dateRange) {
// $query->whereDate('DateExtract', '1900-01-01');
// })
->where('rf_MedicalHistoryID', '<>', 0);
if ($branchId) {

View File

@@ -59,6 +59,16 @@ class User extends Authenticatable
return $this->belongsTo(Department::class, 'rf_department_id');
}
public function departments()
{
return $this->hasMany(UserDepartment::class, 'rf_user_id', 'id');
}
public function favoriteDepartment()
{
return $this->department()->where('is_favorited', true);
}
public function userRoles(): HasMany
{
return $this->hasMany(UserRole::class, 'rf_user_id', 'id');

View File

@@ -0,0 +1,26 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class UserDepartment extends Model
{
public $timestamps = false;
protected $fillable = [
'rf_user_id',
'rf_department_id',
'is_favorite',
];
public function user()
{
return $this->belongsTo(User::class, 'rf_user_id');
}
public function department()
{
return $this->belongsTo(Department::class, 'rf_department_id');
}
}

View File

@@ -3,6 +3,8 @@
namespace App\Services;
use App\Models\Department;
use App\Models\MedicalHistorySnapshot;
use App\Models\MetrikaResult;
use App\Models\MisStationarBranch;
use App\Models\Report;
use App\Models\User;
@@ -26,6 +28,7 @@ class AutoReportService
User $user,
string $startDate,
string $endDate,
$departmentId,
bool $force = false
): int {
$createdCount = 0;
@@ -35,7 +38,7 @@ class AutoReportService
foreach ($period as $date) {
try {
$reportCreated = $this->createReportForDate($user, $date, $force);
$reportCreated = $this->createReportForDate($user, $date, $departmentId, $force);
if ($reportCreated) {
$createdCount++;
@@ -52,10 +55,11 @@ class AutoReportService
/**
* Создать отчет для конкретной даты
*/
public function createReportForDate(User $user, Carbon $date, bool $force = false): bool
public function createReportForDate(User $user, Carbon $date, $departmentId, bool $force = false): bool
{
$user->rf_department_id = $departmentId;
// Проверяем, существует ли уже отчет на эту дату
$existingReport = Report::where('rf_department_id', $user->rf_department_id)
$existingReport = Report::where('rf_department_id', $departmentId)
->whereDate('created_at', $date)
->whereDate('sent_at', $date)
->first();
@@ -66,6 +70,8 @@ class AutoReportService
// Если есть существующий отчет и force=true - удаляем его
if ($existingReport && $force) {
MetrikaResult::where('rf_report_id', $existingReport->report_id)->delete();
MedicalHistorySnapshot::where('rf_report_id', $existingReport->report_id)->delete();
$existingReport->delete();
}
@@ -77,7 +83,7 @@ class AutoReportService
$dateRange = $this->dateRangeService->createDateRangeForDate($date, $user);
// Получаем данные для отчета
$reportData = $this->prepareReportData($user, $dateRange, $date);
$reportData = $this->prepareReportData($user, $dateRange, $date, $departmentId);
// Создаем отчет
DB::transaction(function () use ($user, $reportData, $date) {
@@ -90,9 +96,9 @@ class AutoReportService
/**
* Подготовить данные для отчета
*/
private function prepareReportData(User $user, DateRange $dateRange, Carbon $date): array
private function prepareReportData(User $user, DateRange $dateRange, Carbon $date, $departmentId): array
{
$department = $user->department;
$department = Department::where('department_id', $departmentId)->first();
$branchId = $this->getBranchId($department->rf_mis_department_id);
$isHeadOrAdmin = $user->isHeadOfDepartment() || $user->isAdmin();
@@ -118,7 +124,7 @@ class AutoReportService
'sent_at' => $this->dateRangeService->toSqlFormat($date),
'created_at' => $this->dateRangeService->toSqlFormat($date),
'metrics' => $this->formatMetrics($metrics),
'observationPatients' => $this->getObservationPatients($user->rf_department_id, $date),
'observationPatients' => $this->getObservationPatients($departmentId, $date),
'unwantedEvents' => [],
];
}
@@ -146,17 +152,6 @@ class AutoReportService
true
);
Log::info($this->patientQueryService->getPlanOrEmergencyPatients(
'plan',
$isHeadOrAdmin,
$branchId,
$dateRange,
false,
false,
true,
true
));
// 2. Экстренные пациенты
$metrics['emergency'] = $this->patientQueryService->getPlanOrEmergencyPatients(
'emergency',
@@ -235,17 +230,17 @@ class AutoReportService
private function formatMetrics(array $metrics): array
{
return [
'metrika_item_3' => $metrics['plan'] ?? 0, // плановые
'metrika_item_4' => $metrics['emergency'] ?? 0, // экстренные
'metrika_item_5' => $metrics['recipient'] ?? 0, // поступившие
'metrika_item_6' => ($metrics['plan_surgery'] ?? 0) + ($metrics['emergency_surgery'] ?? 0), // всего операций
'metrika_item_4' => $metrics['plan'] ?? 0, // плановые
'metrika_item_12' => $metrics['emergency'] ?? 0, // экстренные
'metrika_item_3' => $metrics['recipient'] ?? 0, // поступившие
// 'metrika_item_6' => ($metrics['plan_surgery'] ?? 0) + ($metrics['emergency_surgery'] ?? 0), // всего операций
'metrika_item_7' => $metrics['discharged'] ?? 0, // выписанные
'metrika_item_8' => $metrics['current'] ?? 0, // текущие
'metrika_item_9' => $metrics['deceased'] ?? 0, // умершие
'metrika_item_10' => $metrics['plan_surgery'] ?? 0, // плановые операции
'metrika_item_11' => $metrics['emergency_surgery'] ?? 0, // экстренные операции
'metrika_item_12' => $metrics['transferred'] ?? 0, // переведенные
'metrika_item_13' => 0, // под наблюдением (будет заполнено отдельно)
'metrika_item_11' => $metrics['plan_surgery'] ?? 0, // плановые операции
'metrika_item_10' => $metrics['emergency_surgery'] ?? 0, // экстренные операции
'metrika_item_13' => $metrics['transferred'] ?? 0, // переведенные
'metrika_item_14' => 0, // под наблюдением (будет заполнено отдельно)
];
}

View File

@@ -5,6 +5,7 @@ namespace App\Services;
use App\Models\LifeMisMigrationPatient;
use App\Models\MisMedicalHistory;
use App\Models\MisMigrationPatient;
use App\Models\MisSurgicalOperation;
use App\Models\ObservationPatient;
use Carbon\Carbon;
@@ -219,16 +220,14 @@ class PatientService
DateRange $dateRange,
bool $countOnly = false
) {
$query = MisMedicalHistory::whereHas('surgicalOperations', function ($q) use ($type, $branchId, $dateRange) {
$q->where('rf_StationarBranchID', $branchId)
$query = MisSurgicalOperation::where('rf_StationarBranchID', $branchId)
->whereBetween('Date', [$dateRange->startSql(), $dateRange->endSql()]);
if ($type === 'plan') {
$q->where('rf_TypeSurgOperationInTimeID', 6);
} else {
$q->whereIn('rf_TypeSurgOperationInTimeID', [4, 5]);
}
});
if ($type === 'plan') {
$query->where('rf_TypeSurgOperationInTimeID', 6);
} else {
$query->whereIn('rf_TypeSurgOperationInTimeID', [4, 5]);
}
if ($countOnly) {
return $query->count();

View File

@@ -0,0 +1,29 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('user_departments', function (Blueprint $table) {
$table->id('user_department_id');
$table->foreignIdFor(\App\Models\User::class, 'rf_user_id');
$table->foreignIdFor(\App\Models\Department::class, 'rf_department_id');
$table->boolean('is_favorite')->default(false);
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('user_departments');
}
};

View File

@@ -52,7 +52,8 @@ const reportButtonType = computed(() => authStore.isDoctor ? 'button' : Link)
@click="onShowSelectUserModal"
:icon="TbArticle"
/>
<StartButton title="Статистика моего отделения"
<StartButton v-if="authStore.isAdmin || authStore.isHeadOfDepartment"
title="Статистика моего отделения"
:description="`Ваше отделение в системе: ${authStore.userDepartment.name_short}`"
:href="`/statistic`"
:icon="TbChartTreemap"