Несколько отделений для врачей
Поправил подсчет операций Закончил функцию наполнения отчетов
This commit is contained in:
@@ -49,11 +49,13 @@ class FillReportsFromDate extends Command
|
|||||||
$totalErrors = 0;
|
$totalErrors = 0;
|
||||||
|
|
||||||
foreach ($departments as $department) {
|
foreach ($departments as $department) {
|
||||||
$this->info("Обработка отделения: {$department->name}");
|
$this->info("Обработка отделения: {$department->name_short}");
|
||||||
|
|
||||||
// Получаем пользователей отделения
|
// Получаем пользователей отделения
|
||||||
$users = $userId
|
$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);
|
: $this->getDepartmentUsers($department);
|
||||||
|
|
||||||
if ($users->isEmpty()) {
|
if ($users->isEmpty()) {
|
||||||
@@ -67,7 +69,8 @@ class FillReportsFromDate extends Command
|
|||||||
$user,
|
$user,
|
||||||
$startDate,
|
$startDate,
|
||||||
$endDate,
|
$endDate,
|
||||||
$force
|
$departmentId,
|
||||||
|
$force,
|
||||||
);
|
);
|
||||||
|
|
||||||
$totalReports += $created;
|
$totalReports += $created;
|
||||||
|
|||||||
@@ -59,21 +59,23 @@ class StatisticController extends Controller
|
|||||||
|
|
||||||
if ($isRangeOneDay) {
|
if ($isRangeOneDay) {
|
||||||
// Статистика выводится с нарастающим числом
|
// Статистика выводится с нарастающим числом
|
||||||
$reports = $department->reports()
|
$query = $department->reports();
|
||||||
->whereDate('created_at', $dateReport)
|
$reports = $query->whereDate('created_at', $dateReport)
|
||||||
->get();
|
->get();
|
||||||
|
$lastReport = $query->whereDate('created_at', $dateReport)->first();
|
||||||
} else {
|
} else {
|
||||||
$reports = $department->reports()
|
$query = $department->reports();
|
||||||
->whereBetween('created_at', $dateReport)->get();
|
$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;
|
$emergencyCount = 0; $planSurgical = 0; $emergencySurgical = 0; $transferredCount = 0;
|
||||||
$deceasedCount = 0;
|
$deceasedCount = 0;
|
||||||
|
$currentCount = $lastReport ? $this->getMetrikaResultFromReport($lastReport, 8, false) : 0; // Состоит
|
||||||
foreach ($reports as $report) {
|
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); // Поступление - Планово
|
$planCount += $this->getMetrikaResultFromReport($report, 4, $isRangeOneDay); // Поступление - Планово
|
||||||
$emergencyCount += $this->getMetrikaResultFromReport($report, 12, $isRangeOneDay); // Поступление - Экстренно
|
$emergencyCount += $this->getMetrikaResultFromReport($report, 12, $isRangeOneDay); // Поступление - Экстренно
|
||||||
$planSurgical += $this->getMetrikaResultFromReport($report, 11, $isRangeOneDay); // Операции - Планово
|
$planSurgical += $this->getMetrikaResultFromReport($report, 11, $isRangeOneDay); // Операции - Планово
|
||||||
@@ -83,11 +85,13 @@ class StatisticController extends Controller
|
|||||||
$deceasedCount += $this->getMetrikaResultFromReport($report, 9, $isRangeOneDay); // Умерло
|
$deceasedCount += $this->getMetrikaResultFromReport($report, 9, $isRangeOneDay); // Умерло
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$allCount = $planCount + $emergencyCount; // Поступило
|
||||||
|
|
||||||
// Независимые метрики (установки по умолчанию и т.п.)
|
// Независимые метрики (установки по умолчанию и т.п.)
|
||||||
$bedsCount = $department->metrikaDefault()
|
$bedsCount = $department->metrikaDefault()
|
||||||
->where('rf_metrika_item_id', 1)->value('value');
|
->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][] = [
|
$groupedData[$departmentType][] = [
|
||||||
'department' => $department->name_short,
|
'department' => $department->name_short,
|
||||||
|
|||||||
@@ -38,9 +38,9 @@ class LifeMisMigrationPatient extends Model
|
|||||||
$query->where('rf_kl_VisitResultID', 0)
|
$query->where('rf_kl_VisitResultID', 0)
|
||||||
->where('rf_kl_StatCureResultID', 0)
|
->where('rf_kl_StatCureResultID', 0)
|
||||||
->whereBetween('DateIngoing', [$dateRange->startSql(), $dateRange->endSql()])
|
->whereBetween('DateIngoing', [$dateRange->startSql(), $dateRange->endSql()])
|
||||||
->whereHas('medicalHistory', function ($query) use ($branchId, $dateRange) {
|
// ->whereHas('medicalHistory', function ($query) use ($branchId, $dateRange) {
|
||||||
$query->whereDate('DateExtract', '1900-01-01');
|
// $query->whereDate('DateExtract', '1900-01-01');
|
||||||
})
|
// })
|
||||||
->where('rf_MedicalHistoryID', '<>', 0);
|
->where('rf_MedicalHistoryID', '<>', 0);
|
||||||
|
|
||||||
if ($branchId) {
|
if ($branchId) {
|
||||||
|
|||||||
@@ -59,6 +59,16 @@ class User extends Authenticatable
|
|||||||
return $this->belongsTo(Department::class, 'rf_department_id');
|
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
|
public function userRoles(): HasMany
|
||||||
{
|
{
|
||||||
return $this->hasMany(UserRole::class, 'rf_user_id', 'id');
|
return $this->hasMany(UserRole::class, 'rf_user_id', 'id');
|
||||||
|
|||||||
26
app/Models/UserDepartment.php
Normal file
26
app/Models/UserDepartment.php
Normal 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');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,6 +3,8 @@
|
|||||||
namespace App\Services;
|
namespace App\Services;
|
||||||
|
|
||||||
use App\Models\Department;
|
use App\Models\Department;
|
||||||
|
use App\Models\MedicalHistorySnapshot;
|
||||||
|
use App\Models\MetrikaResult;
|
||||||
use App\Models\MisStationarBranch;
|
use App\Models\MisStationarBranch;
|
||||||
use App\Models\Report;
|
use App\Models\Report;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
@@ -26,6 +28,7 @@ class AutoReportService
|
|||||||
User $user,
|
User $user,
|
||||||
string $startDate,
|
string $startDate,
|
||||||
string $endDate,
|
string $endDate,
|
||||||
|
$departmentId,
|
||||||
bool $force = false
|
bool $force = false
|
||||||
): int {
|
): int {
|
||||||
$createdCount = 0;
|
$createdCount = 0;
|
||||||
@@ -35,7 +38,7 @@ class AutoReportService
|
|||||||
|
|
||||||
foreach ($period as $date) {
|
foreach ($period as $date) {
|
||||||
try {
|
try {
|
||||||
$reportCreated = $this->createReportForDate($user, $date, $force);
|
$reportCreated = $this->createReportForDate($user, $date, $departmentId, $force);
|
||||||
|
|
||||||
if ($reportCreated) {
|
if ($reportCreated) {
|
||||||
$createdCount++;
|
$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('created_at', $date)
|
||||||
->whereDate('sent_at', $date)
|
->whereDate('sent_at', $date)
|
||||||
->first();
|
->first();
|
||||||
@@ -66,6 +70,8 @@ class AutoReportService
|
|||||||
|
|
||||||
// Если есть существующий отчет и force=true - удаляем его
|
// Если есть существующий отчет и force=true - удаляем его
|
||||||
if ($existingReport && $force) {
|
if ($existingReport && $force) {
|
||||||
|
MetrikaResult::where('rf_report_id', $existingReport->report_id)->delete();
|
||||||
|
MedicalHistorySnapshot::where('rf_report_id', $existingReport->report_id)->delete();
|
||||||
$existingReport->delete();
|
$existingReport->delete();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -77,7 +83,7 @@ class AutoReportService
|
|||||||
$dateRange = $this->dateRangeService->createDateRangeForDate($date, $user);
|
$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) {
|
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);
|
$branchId = $this->getBranchId($department->rf_mis_department_id);
|
||||||
$isHeadOrAdmin = $user->isHeadOfDepartment() || $user->isAdmin();
|
$isHeadOrAdmin = $user->isHeadOfDepartment() || $user->isAdmin();
|
||||||
|
|
||||||
@@ -118,7 +124,7 @@ class AutoReportService
|
|||||||
'sent_at' => $this->dateRangeService->toSqlFormat($date),
|
'sent_at' => $this->dateRangeService->toSqlFormat($date),
|
||||||
'created_at' => $this->dateRangeService->toSqlFormat($date),
|
'created_at' => $this->dateRangeService->toSqlFormat($date),
|
||||||
'metrics' => $this->formatMetrics($metrics),
|
'metrics' => $this->formatMetrics($metrics),
|
||||||
'observationPatients' => $this->getObservationPatients($user->rf_department_id, $date),
|
'observationPatients' => $this->getObservationPatients($departmentId, $date),
|
||||||
'unwantedEvents' => [],
|
'unwantedEvents' => [],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
@@ -146,17 +152,6 @@ class AutoReportService
|
|||||||
true
|
true
|
||||||
);
|
);
|
||||||
|
|
||||||
Log::info($this->patientQueryService->getPlanOrEmergencyPatients(
|
|
||||||
'plan',
|
|
||||||
$isHeadOrAdmin,
|
|
||||||
$branchId,
|
|
||||||
$dateRange,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
true
|
|
||||||
));
|
|
||||||
|
|
||||||
// 2. Экстренные пациенты
|
// 2. Экстренные пациенты
|
||||||
$metrics['emergency'] = $this->patientQueryService->getPlanOrEmergencyPatients(
|
$metrics['emergency'] = $this->patientQueryService->getPlanOrEmergencyPatients(
|
||||||
'emergency',
|
'emergency',
|
||||||
@@ -235,17 +230,17 @@ class AutoReportService
|
|||||||
private function formatMetrics(array $metrics): array
|
private function formatMetrics(array $metrics): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'metrika_item_3' => $metrics['plan'] ?? 0, // плановые
|
'metrika_item_4' => $metrics['plan'] ?? 0, // плановые
|
||||||
'metrika_item_4' => $metrics['emergency'] ?? 0, // экстренные
|
'metrika_item_12' => $metrics['emergency'] ?? 0, // экстренные
|
||||||
'metrika_item_5' => $metrics['recipient'] ?? 0, // поступившие
|
'metrika_item_3' => $metrics['recipient'] ?? 0, // поступившие
|
||||||
'metrika_item_6' => ($metrics['plan_surgery'] ?? 0) + ($metrics['emergency_surgery'] ?? 0), // всего операций
|
// 'metrika_item_6' => ($metrics['plan_surgery'] ?? 0) + ($metrics['emergency_surgery'] ?? 0), // всего операций
|
||||||
'metrika_item_7' => $metrics['discharged'] ?? 0, // выписанные
|
'metrika_item_7' => $metrics['discharged'] ?? 0, // выписанные
|
||||||
'metrika_item_8' => $metrics['current'] ?? 0, // текущие
|
'metrika_item_8' => $metrics['current'] ?? 0, // текущие
|
||||||
'metrika_item_9' => $metrics['deceased'] ?? 0, // умершие
|
'metrika_item_9' => $metrics['deceased'] ?? 0, // умершие
|
||||||
'metrika_item_10' => $metrics['plan_surgery'] ?? 0, // плановые операции
|
'metrika_item_11' => $metrics['plan_surgery'] ?? 0, // плановые операции
|
||||||
'metrika_item_11' => $metrics['emergency_surgery'] ?? 0, // экстренные операции
|
'metrika_item_10' => $metrics['emergency_surgery'] ?? 0, // экстренные операции
|
||||||
'metrika_item_12' => $metrics['transferred'] ?? 0, // переведенные
|
'metrika_item_13' => $metrics['transferred'] ?? 0, // переведенные
|
||||||
'metrika_item_13' => 0, // под наблюдением (будет заполнено отдельно)
|
'metrika_item_14' => 0, // под наблюдением (будет заполнено отдельно)
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ namespace App\Services;
|
|||||||
use App\Models\LifeMisMigrationPatient;
|
use App\Models\LifeMisMigrationPatient;
|
||||||
use App\Models\MisMedicalHistory;
|
use App\Models\MisMedicalHistory;
|
||||||
use App\Models\MisMigrationPatient;
|
use App\Models\MisMigrationPatient;
|
||||||
|
use App\Models\MisSurgicalOperation;
|
||||||
use App\Models\ObservationPatient;
|
use App\Models\ObservationPatient;
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
|
|
||||||
@@ -219,16 +220,14 @@ class PatientService
|
|||||||
DateRange $dateRange,
|
DateRange $dateRange,
|
||||||
bool $countOnly = false
|
bool $countOnly = false
|
||||||
) {
|
) {
|
||||||
$query = MisMedicalHistory::whereHas('surgicalOperations', function ($q) use ($type, $branchId, $dateRange) {
|
$query = MisSurgicalOperation::where('rf_StationarBranchID', $branchId)
|
||||||
$q->where('rf_StationarBranchID', $branchId)
|
|
||||||
->whereBetween('Date', [$dateRange->startSql(), $dateRange->endSql()]);
|
->whereBetween('Date', [$dateRange->startSql(), $dateRange->endSql()]);
|
||||||
|
|
||||||
if ($type === 'plan') {
|
if ($type === 'plan') {
|
||||||
$q->where('rf_TypeSurgOperationInTimeID', 6);
|
$query->where('rf_TypeSurgOperationInTimeID', 6);
|
||||||
} else {
|
} else {
|
||||||
$q->whereIn('rf_TypeSurgOperationInTimeID', [4, 5]);
|
$query->whereIn('rf_TypeSurgOperationInTimeID', [4, 5]);
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
|
||||||
if ($countOnly) {
|
if ($countOnly) {
|
||||||
return $query->count();
|
return $query->count();
|
||||||
|
|||||||
@@ -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');
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -52,7 +52,8 @@ const reportButtonType = computed(() => authStore.isDoctor ? 'button' : Link)
|
|||||||
@click="onShowSelectUserModal"
|
@click="onShowSelectUserModal"
|
||||||
:icon="TbArticle"
|
:icon="TbArticle"
|
||||||
/>
|
/>
|
||||||
<StartButton title="Статистика моего отделения"
|
<StartButton v-if="authStore.isAdmin || authStore.isHeadOfDepartment"
|
||||||
|
title="Статистика моего отделения"
|
||||||
:description="`Ваше отделение в системе: ${authStore.userDepartment.name_short}`"
|
:description="`Ваше отделение в системе: ${authStore.userDepartment.name_short}`"
|
||||||
:href="`/statistic`"
|
:href="`/statistic`"
|
||||||
:icon="TbChartTreemap"
|
:icon="TbChartTreemap"
|
||||||
|
|||||||
Reference in New Issue
Block a user