diff --git a/app/Http/Controllers/Api/ReportController.php b/app/Http/Controllers/Api/ReportController.php
index 9bc96c1..487f0e6 100644
--- a/app/Http/Controllers/Api/ReportController.php
+++ b/app/Http/Controllers/Api/ReportController.php
@@ -7,13 +7,16 @@ use App\Http\Resources\Mis\FormattedPatientResource;
use App\Models\MetrikaGroup;
use App\Models\MetrikaResult;
use App\Models\MisMedicalHistory;
+use App\Models\MisMigrationPatient;
use App\Models\MisStationarBranch;
use App\Models\ObservationPatient;
use App\Models\Report;
+use App\Models\UnwantedEvent;
use Illuminate\Http\Request;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
+use Illuminate\Support\Facades\Session;
use Illuminate\Support\Str;
use Inertia\Inertia;
@@ -21,9 +24,26 @@ class ReportController extends Controller
{
public function index(Request $request)
{
- $user = $request->user();
+ $user = Auth::user();
$department = $user->department;
+ $startDateCarbon = Carbon::now()->firstOfMonth();
+ $startDate = $request->query('startAt', $startDateCarbon->format('Y-m-d'));
+ $endDateCarbon = Carbon::now();
+ $endDate = $request->query('endAt', $endDateCarbon->format('Y-m-d'));
+
+ $doctorStartDate = Carbon::now()->addDays(-1)->format('Y-m-d');
+ $doctorEndDate = Carbon::now()->format('Y-m-d');
+
+ if (is_numeric($startDate)) {
+ $startDateCarbon = Carbon::createFromTimestampMs($startDate);
+ $startDate = Carbon::createFromTimestampMs($startDate)->setTimezone('Asia/Yakutsk')->format('Y-m-d');
+ }
+ if (is_numeric($endDate)) {
+ $endDateCarbon = Carbon::createFromTimestampMs($endDate);
+ $endDate = Carbon::createFromTimestampMs($endDate)->setTimezone('Asia/Yakutsk')->format('Y-m-d');
+ }
+
$beds = (int)$department->metrikaDefault()->where('rf_metrika_item_id', 1)->first()->value;
$occupiedBeds = optional(Report::where('rf_department_id', $user->rf_department_id)
->join('metrika_results', 'reports.report_id', '=', 'metrika_results.rf_report_id')
@@ -35,10 +55,103 @@ class ReportController extends Controller
$metrikaGroup = MetrikaGroup::whereMetrikaGroupId(2)->first();
$metrikaItems = $metrikaGroup->metrikaItems;
+ $misDepartmentId = $request->user()->department->rf_mis_department_id;
+
+ $branchId = MisStationarBranch::where('rf_DepartmentID', $misDepartmentId)
+ ->value('StationarBranchID');
+ if ($user->isHeadOfDepartment())
+ {
+ $medicalHistoryIds = MisMigrationPatient::whereInDepartment($branchId)
+ ->pluck('rf_MedicalHistoryID')
+ ->unique()
+ ->toArray();
+
+ $extractedMedicalHistoryIds = MisMigrationPatient::extractedToday($branchId, $startDate, $endDate)
+ ->pluck('rf_MedicalHistoryID')
+ ->unique()
+ ->toArray();
+
+ $recipientCount = MisMedicalHistory::whereIn('MedicalHistoryID', $medicalHistoryIds)
+ ->when($user->isHeadOfDepartment(), function($query) use ($startDate, $endDate) {
+ return $query->whereBetween('DateRecipient', [$startDate, $endDate]);
+ })
+ ->when(!$user->isHeadOfDepartment(), function($query) use ($doctorStartDate, $doctorEndDate) {
+ return $query->whereBetween('DateRecipient', [$doctorStartDate, $doctorEndDate]);
+ })
+ ->orderBy('DateRecipient', 'DESC')
+ ->count();
+
+ $extractedCount = MisMedicalHistory::whereIn('MedicalHistoryID', $extractedMedicalHistoryIds)
+ ->orderBy('DateRecipient', 'DESC')
+ ->count();
+
+ $recipientIds = MisMedicalHistory::whereIn('MedicalHistoryID', $medicalHistoryIds)
+ ->when($doctorStartDate, function($query) use ($doctorStartDate, $doctorEndDate) {
+ return $query->whereBetween('DateRecipient', [$doctorStartDate, $doctorEndDate]);
+ })
+ ->orderBy('DateRecipient', 'DESC')
+ ->pluck('MedicalHistoryID')
+ ->values();
+
+ $currentCount = MisMedicalHistory::whereIn('MedicalHistoryID', $medicalHistoryIds)
+ ->currentlyHospitalized()
+ ->orderBy('DateRecipient', 'DESC')
+ ->count();
+ } else {
+ $medicalHistoryIds = MisMigrationPatient::currentlyInTreatment($branchId)
+ ->pluck('rf_MedicalHistoryID')
+ ->unique()
+ ->toArray();
+
+ $extractedMedicalHistoryIds = MisMigrationPatient::extractedToday($branchId)
+ ->pluck('rf_MedicalHistoryID')
+ ->unique()
+ ->toArray();
+
+ $recipientCount = MisMedicalHistory::whereIn('MedicalHistoryID', $medicalHistoryIds)
+ ->when($user->isHeadOfDepartment(), function($query) use ($startDate, $endDate) {
+ return $query->whereBetween('DateRecipient', [$startDate, $endDate]);
+ })
+ ->when(!$user->isHeadOfDepartment(), function($query) use ($doctorStartDate, $doctorEndDate) {
+ return $query->whereBetween('DateRecipient', [$doctorStartDate, $doctorEndDate]);
+ })
+ ->orderBy('DateRecipient', 'DESC')
+ ->count();
+
+ $extractedCount = MisMedicalHistory::whereIn('MedicalHistoryID', $extractedMedicalHistoryIds)
+ ->orderBy('DateRecipient', 'DESC')
+ ->count();
+
+ $recipientIds = MisMedicalHistory::whereIn('MedicalHistoryID', $medicalHistoryIds)
+ ->when($user->isHeadOfDepartment(), function($query) use ($startDate, $endDate) {
+ return $query->whereBetween('DateRecipient', [$startDate, $endDate]);
+ })
+ ->when(!$user->isHeadOfDepartment(), function($query) use ($doctorStartDate, $doctorEndDate) {
+ return $query->whereBetween('DateRecipient', [$doctorStartDate, $doctorEndDate]);
+ })
+ ->orderBy('DateRecipient', 'DESC')
+ ->pluck('MedicalHistoryID')
+ ->values();
+
+ $currentCount = MisMedicalHistory::whereIn('MedicalHistoryID', $medicalHistoryIds)
+ ->currentlyHospitalized()
+ ->orderBy('DateRecipient', 'DESC')
+ ->count();
+ }
+
+
return response()->json([
'department' => [
'beds' => $beds,
'percentLoadedBeds' => $percentLoadedBeds,
+ 'recipientCount' => $recipientCount,
+ 'extractCount' => $extractedCount,
+ 'currentCount' => $currentCount,
+ 'recipientIds' => $recipientIds
+ ],
+ 'dates' => [
+ 'startAt' => $startDateCarbon->getTimestampMs(),
+ 'endAt' => $endDateCarbon->getTimestampMs()
],
'metrikaItems' => $metrikaItems
]);
@@ -50,6 +163,7 @@ class ReportController extends Controller
'metrics' => 'required',
'observationPatients' => 'nullable',
'departmentId' => 'required|integer',
+ 'unwantedEvent' => 'nullable'
]);
$metrics = $data['metrics'];
@@ -74,6 +188,13 @@ class ReportController extends Controller
'sent_at' => now()
]);
+ if (in_array('unwantedEvent', $data)) {
+ $unwantedEvent = UnwantedEvent::create([
+ 'rf_report_id' => $report->id,
+ 'comment' => $data['unwantedEvent']['comment'] ?? '',
+ ]);
+ }
+
foreach ($metriks as $metrika) {
$metrika->rf_report_id = $report->report_id;
$metrika->save();
@@ -97,59 +218,215 @@ class ReportController extends Controller
public function getPatients(Request $request)
{
+ $user = Auth::user();
$data = $request->validate([
'status' => 'required|string', // plan emergency
+ 'startAt' => 'nullable',
+ 'endAt' => 'nullable',
]);
$status = $data['status'];
- $startDate = Carbon::now()->addDays(-1)->format('Y-m-d');
- $endDate = Carbon::now()->format('Y-m-d');
+ $startDateCarbon = Carbon::now()->firstOfMonth();
+ $startDate = $data['startAt'] ?? $startDateCarbon->format('Y-m-d');
+ $endDateCarbon = Carbon::now();
+ $endDate = $data['endAt'] ?? $startDateCarbon->format('Y-m-d');
+
+ $doctorStartDate = Carbon::now()->addDays(-1)->format('Y-m-d');
+ $doctorEndDate = Carbon::now()->format('Y-m-d');
+
+ if (is_numeric($startDate)) {
+ $startDateCarbon = Carbon::createFromTimestampMs($startDate);
+ $startDate = Carbon::createFromTimestampMs($startDate)->setTimezone('Asia/Yakutsk')->format('Y-m-d');
+ }
+ if (is_numeric($endDate)) {
+ $endDateCarbon = Carbon::createFromTimestampMs($endDate);
+ $endDate = Carbon::createFromTimestampMs($endDate)->setTimezone('Asia/Yakutsk')->format('Y-m-d');
+ }
$model = new MisMedicalHistory();
$misDepartmentId = $request->user()->department->rf_mis_department_id;
+ $userDepartmentId = $request->user()->department->department_id;
$misStationarBranchId = MisStationarBranch::where('rf_DepartmentID', $misDepartmentId)->first()->StationarBranchID;
- if ($status === 'plan') {
- $patients = MisMedicalHistory::select(
- [
- ...$model->getFillable(),
- DB::raw('ROW_NUMBER() OVER (ORDER BY "DateRecipient" DESC) as num')
- ])
- ->plan()
- ->inDepartment($misDepartmentId, $startDate, $endDate)
- ->orderBy('DateRecipient', 'DESC')
- ->get()
- ->map(function ($item, $index) {
- $item->num = $index + 1;
- return $item;
- });;
- } else if ($status === 'emergency') {
- $patients = MisMedicalHistory::select(
- [
- ...$model->getFillable(),
- DB::raw('ROW_NUMBER() OVER (ORDER BY "DateRecipient" DESC) as num')
- ])
- ->emergency()
- ->inDepartment($misDepartmentId, $startDate, $endDate)
- ->orderBy('DateRecipient', 'DESC')
- ->get()
- ->map(function ($item, $index) {
- $item->num = $index + 1;
- return $item;
- });
- } else if ($status === 'observation') {
- $patients = ObservationPatient::with(['history'])
- ->where('rf_department_id', $misDepartmentId)
- ->history;
- } else if ($status === 'deceased') {
- $patients = MisMedicalHistory::select(...$model->getFillable())
- ->deceased()
- ->inDepartment($misDepartmentId, $startDate, $endDate)
- ->get()
- ->map(function ($item, $index) {
- $item->num = $index + 1;
- return $item;
- });
+
+ if ($user->isHeadOfDepartment()) {
+ if ($status === 'plan') {
+ // Сначала получаем ID локально
+ $branchId = MisStationarBranch::where('rf_DepartmentID', $misDepartmentId)
+ ->value('StationarBranchID');
+
+ if (!$branchId) {
+ return collect();
+ }
+
+ $medicalHistoryIds = MisMigrationPatient::whereInDepartment($branchId)
+ ->when($startDate && $endDate, function($query) use ($startDate, $endDate) {
+ return $query->whereBetween('DateIngoing', [$startDate, $endDate]);
+ })
+ ->pluck('rf_MedicalHistoryID')
+ ->unique()
+ ->toArray();
+
+ if (empty($medicalHistoryIds)) {
+ return collect();
+ }
+
+ // Получаем истории
+ $patients = MisMedicalHistory::select($model->getFillable())
+ ->plan()
+ ->whereIn('MedicalHistoryID', $medicalHistoryIds)
+ ->orderBy('DateRecipient', 'DESC')
+ ->get()
+ ->map(function ($item, $index) use ($misStationarBranchId) {
+ $item->num = $index + 1;
+ $item->misStationarBranchId = $misStationarBranchId;
+ return $item;
+ });
+ } else if ($status === 'emergency') {
+ // Сначала получаем ID локально
+ $branchId = MisStationarBranch::where('rf_DepartmentID', $misDepartmentId)
+ ->value('StationarBranchID');
+
+ if (!$branchId) {
+ return collect();
+ }
+
+ $medicalHistoryIds = MisMigrationPatient::whereInDepartment($branchId)
+ ->when($startDate && $endDate, function($query) use ($startDate, $endDate) {
+ return $query->whereBetween('DateIngoing', [$startDate, $endDate]);
+ })
+ ->pluck('rf_MedicalHistoryID')
+ ->unique()
+ ->toArray();
+
+ if (empty($medicalHistoryIds)) {
+ return collect();
+ }
+
+ // Получаем истории
+ $patients = MisMedicalHistory::select($model->getFillable())
+ ->emergency()
+ ->whereIn('MedicalHistoryID', $medicalHistoryIds)
+ ->with(['surgicalOperations'])
+ ->orderBy('DateRecipient', 'DESC')
+ ->get()
+ ->map(function ($item, $index) use ($misStationarBranchId) {
+ $item->num = $index + 1;
+ $item->misStationarBranchId = $misStationarBranchId;
+ return $item;
+ });
+ } else if ($status === 'observation') {
+ $medicalHistoryIds = ObservationPatient::where('rf_department_id', $userDepartmentId)
+ ->pluck('rf_medicalhistory_id')
+ ->toArray();
+
+ $patients = MisMedicalHistory::whereIn('MedicalHistoryID', $medicalHistoryIds)
+ ->get()->map(function ($item, $index) use ($misStationarBranchId) {
+ $item->num = $index + 1;
+ $item->misStationarBranchId = $misStationarBranchId;
+ return $item;
+ });
+
+ } else if ($status === 'deceased') {
+ $patients = MisMedicalHistory::select(...$model->getFillable())
+ ->deceased()
+ ->inDepartment($misDepartmentId, $startDate, $endDate)
+ ->get()
+ ->map(function ($item, $index) {
+ $item->num = $index + 1;
+ return $item;
+ });
+ }
+ } else {
+ if ($status === 'plan') {
+ // Сначала получаем ID локально
+ $branchId = MisStationarBranch::where('rf_DepartmentID', $misDepartmentId)
+ ->value('StationarBranchID');
+
+ if (!$branchId) {
+ return collect();
+ }
+
+ $medicalHistoryIds = MisMigrationPatient::currentlyInTreatment($branchId)
+// ->when($startDate && $endDate, function($query) use ($startDate, $endDate) {
+// return $query->whereBetween('DateIngoing', [$startDate, $endDate]);
+// })
+ ->pluck('rf_MedicalHistoryID')
+ ->unique()
+ ->toArray();
+
+ if (empty($medicalHistoryIds)) {
+ return collect();
+ }
+
+ // Получаем истории
+ $patients = MisMedicalHistory::select($model->getFillable())
+ ->plan()
+ ->whereIn('MedicalHistoryID', $medicalHistoryIds)
+ ->currentlyHospitalized()
+ ->orderBy('DateRecipient', 'DESC')
+ ->get()
+ ->map(function ($item, $index) use ($misStationarBranchId) {
+ $item->num = $index + 1;
+ $item->misStationarBranchId = $misStationarBranchId;
+ return $item;
+ });
+ } else if ($status === 'emergency') {
+ // Сначала получаем ID локально
+ $branchId = MisStationarBranch::where('rf_DepartmentID', $misDepartmentId)
+ ->value('StationarBranchID');
+
+ if (!$branchId) {
+ return collect();
+ }
+
+ $medicalHistoryIds = MisMigrationPatient::currentlyInTreatment($branchId)
+// ->when($startDate && $endDate, function($query) use ($startDate, $endDate) {
+// return $query->whereBetween('DateIngoing', [$startDate, $endDate]);
+// })
+ ->pluck('rf_MedicalHistoryID')
+ ->unique()
+ ->toArray();
+
+ if (empty($medicalHistoryIds)) {
+ return collect();
+ }
+
+ // Получаем истории
+ $patients = MisMedicalHistory::select($model->getFillable())
+ ->emergency()
+ ->whereIn('MedicalHistoryID', $medicalHistoryIds)
+ ->currentlyHospitalized()
+ ->with(['surgicalOperations'])
+ ->orderBy('DateRecipient', 'DESC')
+ ->get()
+ ->map(function ($item, $index) use ($misStationarBranchId) {
+ $item->num = $index + 1;
+ $item->misStationarBranchId = $misStationarBranchId;
+ return $item;
+ });
+ } else if ($status === 'observation') {
+ $medicalHistoryIds = ObservationPatient::where('rf_department_id', $userDepartmentId)
+ ->pluck('rf_medicalhistory_id')
+ ->toArray();
+
+ $patients = MisMedicalHistory::whereIn('MedicalHistoryID', $medicalHistoryIds)
+ ->get()->map(function ($item, $index) use ($misStationarBranchId) {
+ $item->num = $index + 1;
+ $item->misStationarBranchId = $misStationarBranchId;
+ return $item;
+ });
+
+ } else if ($status === 'deceased') {
+ $patients = MisMedicalHistory::select(...$model->getFillable())
+ ->deceased()
+ ->inDepartment($misDepartmentId, $startDate, $endDate)
+ ->get()
+ ->map(function ($item, $index) {
+ $item->num = $index + 1;
+ return $item;
+ });
+ }
}
$patients->load(['migrations' => function ($query) use ($startDate, $endDate, $misStationarBranchId) {
@@ -164,29 +441,97 @@ class ReportController extends Controller
public function getPatientsCount(Request $request)
{
+ $user = Auth::user();
$data = $request->validate([
'status' => 'required|string', // plan emergency
+ 'startAt' => 'nullable',
+ 'endAt' => 'nullable',
]);
$status = $data['status'];
- $startDate = Carbon::now()->addDays(-1)->format('Y-m-d');
- $endDate = Carbon::now()->format('Y-m-d');
+ $startDateCarbon = Carbon::now()->firstOfMonth();
+ $startDate = $data['startAt'] ?? $startDateCarbon->format('Y-m-d');
+ $endDateCarbon = Carbon::now();
+ $endDate = $data['endAt'] ?? $endDateCarbon->format('Y-m-d');
+
+ $doctorStartDate = Carbon::now()->addDays(-1)->format('Y-m-d');
+ $doctorEndDate = Carbon::now()->format('Y-m-d');
+
+ if (is_numeric($startDate)) {
+ $startDateCarbon = Carbon::createFromTimestampMs($startDate);
+ $startDate = Carbon::createFromTimestampMs($startDate)->setTimezone('Asia/Yakutsk')->format('Y-m-d');
+ }
+ if (is_numeric($endDate)) {
+ $endDateCarbon = Carbon::createFromTimestampMs($endDate);
+ $endDate = Carbon::createFromTimestampMs($endDate)->setTimezone('Asia/Yakutsk')->format('Y-m-d');
+ }
- $model = new MisMedicalHistory();
$misDepartmentId = $request->user()->department->rf_mis_department_id;
- if ($status === 'plan') {
- $count = MisMedicalHistory::select($model->getFillable())
- ->plan()
- ->inDepartment($misDepartmentId, $startDate, $endDate)
- ->orderBy('DateRecipient', 'DESC')
- ->count();
- } else if ($status === 'emergency') {
- $count = MisMedicalHistory::select($model->getFillable())
- ->emergency()
- ->inDepartment($misDepartmentId, $startDate, $endDate)
- ->orderBy('DateRecipient', 'DESC')
- ->count();
+
+ // Получаем ID отделения
+ $branchId = MisStationarBranch::where('rf_DepartmentID', $misDepartmentId)
+ ->value('StationarBranchID');
+
+ if (!$branchId) {
+ return response()->json(0);
+ }
+
+ if ($user->isHeadOfDepartment()) {
+ // Получаем ID медицинских историй по миграциям
+ $medicalHistoryIds = MisMigrationPatient::whereInDepartment($branchId)
+ ->when($startDate && $endDate, function($query) use ($startDate, $endDate) {
+ return $query->whereBetween('DateIngoing', [$startDate, $endDate]);
+ })
+ ->pluck('rf_MedicalHistoryID')
+ ->unique()
+ ->toArray();
+
+ if (empty($medicalHistoryIds)) {
+ return response()->json(0);
+ }
+
+ // Подсчет в зависимости от статуса
+ if ($status === 'plan') {
+ $count = MisMedicalHistory::plan()
+ ->whereIn('MedicalHistoryID', $medicalHistoryIds)
+ ->orderBy('DateRecipient', 'DESC')
+ ->count();
+ } else if ($status === 'emergency') {
+ $count = MisMedicalHistory::emergency()
+ ->whereIn('MedicalHistoryID', $medicalHistoryIds)
+ ->orderBy('DateRecipient', 'DESC')
+ ->count();
+ } else {
+ $count = 0;
+ }
+ } else {
+ // Получаем ID медицинских историй по миграциям
+ $medicalHistoryIds = MisMigrationPatient::currentlyInTreatment($branchId)
+ ->pluck('rf_MedicalHistoryID')
+ ->unique()
+ ->toArray();
+
+ if (empty($medicalHistoryIds)) {
+ return response()->json(0);
+ }
+
+ // Подсчет в зависимости от статуса
+ if ($status === 'plan') {
+ $count = MisMedicalHistory::plan()
+ ->whereIn('MedicalHistoryID', $medicalHistoryIds)
+ ->currentlyHospitalized()
+ ->orderBy('DateRecipient', 'DESC')
+ ->count();
+ } else if ($status === 'emergency') {
+ $count = MisMedicalHistory::emergency()
+ ->whereIn('MedicalHistoryID', $medicalHistoryIds)
+ ->currentlyHospitalized()
+ ->orderBy('DateRecipient', 'DESC')
+ ->count();
+ } else {
+ $count = 0;
+ }
}
return response()->json($count);
diff --git a/app/Http/Controllers/AuthController.php b/app/Http/Controllers/AuthController.php
index 08e99ba..06fe039 100644
--- a/app/Http/Controllers/AuthController.php
+++ b/app/Http/Controllers/AuthController.php
@@ -5,6 +5,7 @@ namespace App\Http\Controllers;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
+use Illuminate\Support\Facades\Redis;
use Illuminate\Support\Facades\Validator;
use Inertia\Inertia;
@@ -53,4 +54,22 @@ class AuthController extends Controller
return Inertia::location(route('start'));
}
+
+ public function changeRole(Request $request)
+ {
+ $user = Auth::user();
+
+ if (!$user) return null;
+
+ $data = $request->validate([
+ 'role_id' => 'required|integer|exists:roles,role_id'
+ ]);
+
+ $sessionKey = 'user_' . $user->id . '_current_role';
+
+ $user->current_role_id = $data['role_id'];
+ $user->save();
+
+ return redirect()->route('start')->setStatusCode(302);
+ }
}
diff --git a/app/Http/Middleware/HandleInertiaRequests.php b/app/Http/Middleware/HandleInertiaRequests.php
index 56f8aff..855c8da 100644
--- a/app/Http/Middleware/HandleInertiaRequests.php
+++ b/app/Http/Middleware/HandleInertiaRequests.php
@@ -45,6 +45,7 @@ class HandleInertiaRequests extends Middleware
'token' => Session::get('token'),
'permissions' => $user->permissions(),
'role' => $user->currentRole(),
+ 'available_roles' => $user->roles,
'available_departments' => $user->availableDepartments(),
'current_department' => $user->department
] : null,
diff --git a/app/Http/Resources/Mis/FormattedPatientResource.php b/app/Http/Resources/Mis/FormattedPatientResource.php
index a2ac102..fe5bc02 100644
--- a/app/Http/Resources/Mis/FormattedPatientResource.php
+++ b/app/Http/Resources/Mis/FormattedPatientResource.php
@@ -2,6 +2,7 @@
namespace App\Http\Resources\Mis;
+use App\Models\MisSurgicalOperation;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
use Illuminate\Support\Carbon;
@@ -25,6 +26,15 @@ class FormattedPatientResource extends JsonResource
'name' => $this->migrations()->first()->diagnosis()->first()?->mkb()->first()->NAME ?? null,
];
}),
+ 'operations' => $this->whenLoaded('surgicalOperations', function () {
+ return $this->surgicalOperations()->where('rf_StationarBranchID', $this->misStationarBranchId)
+ ->get()
+ ->map(function (MisSurgicalOperation $operation) {
+ return [
+ 'code' => $operation->serviceMedical->ServiceMedicalCode ?? null,
+ ];
+ });
+ }),
'fullname' => Str::ucwords(Str::lower("$this->FAMILY $this->Name $this->OT")),
'age' => Carbon::parse($this->BD)->diff(Carbon::now())->format('%y'),
'birth_date' => Carbon::parse($this->BD)->format('d.m.Y'),
diff --git a/app/Models/MisMedicalHistory.php b/app/Models/MisMedicalHistory.php
index 8cdf51d..a9ebd39 100644
--- a/app/Models/MisMedicalHistory.php
+++ b/app/Models/MisMedicalHistory.php
@@ -24,6 +24,22 @@ class MisMedicalHistory extends Model
'DateRecipient' => 'datetime'
];
+ public function observationPatient()
+ {
+ return $this->belongsTo(ObservationPatient::class, 'MedicalHistoryID', 'rf_medicalhistory_id');
+ }
+
+ public function surgicalOperations()
+ {
+ return $this->hasMany(MisSurgicalOperation::class, 'rf_MedicalHistoryID', 'MedicalHistoryID');
+ }
+
+ public function scopeCurrentlyHospitalized($query)
+ {
+ return $query->whereDate('DateExtract', '1900-01-01')
+ ->where('MedicalHistoryID', '<>', 0);
+ }
+
/*
* Истории со срочностью - Плановая
*/
diff --git a/app/Models/MisMigrationPatient.php b/app/Models/MisMigrationPatient.php
index fc96b93..77f3406 100644
--- a/app/Models/MisMigrationPatient.php
+++ b/app/Models/MisMigrationPatient.php
@@ -3,6 +3,7 @@
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
+use Illuminate\Support\Carbon;
class MisMigrationPatient extends Model
{
@@ -23,4 +24,45 @@ class MisMigrationPatient extends Model
{
return $this->hasOne(MisMKB::class, 'MKBID', 'rf_MKBID');
}
+
+ public function scopeCurrentlyInTreatment($query, $branchId = null)
+ {
+ $query->where('rf_kl_VisitResultID', 0)
+ ->where('rf_MedicalHistoryID', '<>', 0);
+
+ if ($branchId) {
+ $query->where('rf_StationarBranchID', $branchId);
+ }
+
+ return $query;
+ }
+
+ public function scopeWhereInDepartment($query, $branchId = null)
+ {
+ $query->where('rf_MedicalHistoryID', '<>', 0);
+
+ if ($branchId) {
+ $query->where('rf_StationarBranchID', $branchId);
+ }
+
+ return $query;
+ }
+
+ public function scopeExtractedToday($query, $branchId = null, $startDate = null, $endDate = null)
+ {
+ if (is_null($startDate)) $startDate = Carbon::now()->addDays(-1)->format('Y-m-d');
+ if (is_null($endDate)) $endDate = Carbon::now()->format('Y-m-d');
+
+ $query->where('rf_kl_VisitResultID', '<>', 0)
+ ->where('rf_MedicalHistoryID', '<>', 0)
+ ->when($startDate && $endDate, function($query) use ($startDate, $endDate) {
+ return $query->whereBetween('DateOut', [$startDate, $endDate]);
+ });
+
+ if ($branchId) {
+ $query->where('rf_StationarBranchID', $branchId);
+ }
+
+ return $query;
+ }
}
diff --git a/app/Models/MisServiceMedical.php b/app/Models/MisServiceMedical.php
new file mode 100644
index 0000000..e8b30dd
--- /dev/null
+++ b/app/Models/MisServiceMedical.php
@@ -0,0 +1,16 @@
+hsaMany(MisServiceMedical::class, 'ServiceMedicalID', 'rf_ServiceMedicalID');
+ }
+}
diff --git a/app/Models/MisSurgicalOperation.php b/app/Models/MisSurgicalOperation.php
new file mode 100644
index 0000000..1cb3e43
--- /dev/null
+++ b/app/Models/MisSurgicalOperation.php
@@ -0,0 +1,16 @@
+belongsTo(MisServiceMedical::class, 'rf_kl_ServiceMedicalID', 'ServiceMedicalID');
+ }
+}
diff --git a/app/Models/ObservationPatient.php b/app/Models/ObservationPatient.php
index 8fdd51e..3e358ae 100644
--- a/app/Models/ObservationPatient.php
+++ b/app/Models/ObservationPatient.php
@@ -14,6 +14,7 @@ class ObservationPatient extends Model
'rf_mkab_id',
'rf_department_id',
'rf_report_id',
+ 'comment'
];
public function history()
diff --git a/app/Models/UnwantedEvent.php b/app/Models/UnwantedEvent.php
new file mode 100644
index 0000000..4b8708e
--- /dev/null
+++ b/app/Models/UnwantedEvent.php
@@ -0,0 +1,15 @@
+roles()->where('is_default', true)->first()->role_id;
- $roleId = session('currentRoleId', $defaultRoleId);
+ $sessionKey = 'user_' . $this->id . '_current_role';
+ $roleId = $this->current_role_id ?? $defaultRoleId;
$role = Role::where('role_id', $roleId)->first();
@@ -101,11 +103,6 @@ class User extends Authenticatable
return $this->currentRole()->slug === 'head_of_department';
}
- public function isStatistician()
- {
- return $this->currentRole()->slug === 'statistician';
- }
-
// Получение доступных отделений
public function availableDepartments()
{
@@ -134,11 +131,6 @@ class User extends Authenticatable
$permissions['manage_users'] = $this->isAdmin();
}
- if ($this->isStatistician()) {
- $permissions['view_statistics'] = true;
- $permissions['export_data'] = true;
- }
-
return $permissions;
}
}
diff --git a/database/migrations/2026_01_21_170206_add_comment_column_in_observation_patients_table.php b/database/migrations/2026_01_21_170206_add_comment_column_in_observation_patients_table.php
new file mode 100644
index 0000000..17e1adc
--- /dev/null
+++ b/database/migrations/2026_01_21_170206_add_comment_column_in_observation_patients_table.php
@@ -0,0 +1,28 @@
+text('comment')->nullable();
+ });
+ }
+
+ /**
+ * Reverse the migrations.
+ */
+ public function down(): void
+ {
+ Schema::table('observation_patients', function (Blueprint $table) {
+ $table->dropColumn('comment');
+ });
+ }
+};
diff --git a/database/migrations/2026_01_22_142054_add_column_current_role_id_in_users_table.php b/database/migrations/2026_01_22_142054_add_column_current_role_id_in_users_table.php
new file mode 100644
index 0000000..c5dcfe6
--- /dev/null
+++ b/database/migrations/2026_01_22_142054_add_column_current_role_id_in_users_table.php
@@ -0,0 +1,28 @@
+unsignedBigInteger('current_role_id')->nullable();
+ });
+ }
+
+ /**
+ * Reverse the migrations.
+ */
+ public function down(): void
+ {
+ Schema::table('users', function (Blueprint $table) {
+ $table->dropColumn('current_role_id');
+ });
+ }
+};
diff --git a/database/migrations/2026_01_22_152242_create_unwanted_events_table.php b/database/migrations/2026_01_22_152242_create_unwanted_events_table.php
new file mode 100644
index 0000000..65ff960
--- /dev/null
+++ b/database/migrations/2026_01_22_152242_create_unwanted_events_table.php
@@ -0,0 +1,29 @@
+id('unwanted_event_id');
+ $table->foreignIdFor(\App\Models\Report::class, 'rf_report_id');
+ $table->text('comment');
+ $table->timestamps();
+ });
+ }
+
+ /**
+ * Reverse the migrations.
+ */
+ public function down(): void
+ {
+ Schema::dropIfExists('unwanted_events');
+ }
+};
diff --git a/resources/js/Components/DepartmentSelect.vue b/resources/js/Components/DepartmentSelect.vue
new file mode 100644
index 0000000..2e093c3
--- /dev/null
+++ b/resources/js/Components/DepartmentSelect.vue
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
diff --git a/resources/js/Components/ReportSelectDate.vue b/resources/js/Components/ReportSelectDate.vue
index b6290f2..8ec4511 100644
--- a/resources/js/Components/ReportSelectDate.vue
+++ b/resources/js/Components/ReportSelectDate.vue
@@ -23,10 +23,10 @@ const { timestampCurrentRange } = storeToRefs(reportStore)
reportStore.getDataOnReportDate(value)"
/>
diff --git a/resources/js/Layouts/Components/AppHeader.vue b/resources/js/Layouts/Components/AppHeader.vue
index 84e8660..f2f850e 100644
--- a/resources/js/Layouts/Components/AppHeader.vue
+++ b/resources/js/Layouts/Components/AppHeader.vue
@@ -7,18 +7,13 @@ import AppHeaderRole from "./AppHeaderRole.vue";
-
-
-
- Метрика
-
-
-
-
-
-
-
-
+
diff --git a/resources/js/Pages/Report/Index.vue b/resources/js/Pages/Report/Index.vue
index 378926c..c756b0a 100644
--- a/resources/js/Pages/Report/Index.vue
+++ b/resources/js/Pages/Report/Index.vue
@@ -2,17 +2,26 @@
import AppLayout from "../../Layouts/AppLayout.vue";
import ReportForm from "./Components/ReportForm.vue";
import {useReportStore} from "../../Stores/report.js";
-import {onMounted} from "vue";
+import {computed, onMounted} from "vue";
+import {useAuthStore} from "../../Stores/auth.js";
const reportStore = useReportStore()
+const authStore = useAuthStore()
onMounted(async () => {
await reportStore.getReportInfo()
})
+
+const mode = computed(() => {
+ if (authStore.isHeadOfDepartment)
+ return 'readonly'
+ return 'fillable'
+})
+
-
+
diff --git a/resources/js/Stores/auth.js b/resources/js/Stores/auth.js
index 0099a1f..fd66701 100644
--- a/resources/js/Stores/auth.js
+++ b/resources/js/Stores/auth.js
@@ -1,13 +1,23 @@
-import { ref, computed } from 'vue'
+import {ref, computed, watch} from 'vue'
import { defineStore } from 'pinia'
import axios from 'axios'
import {usePage} from "@inertiajs/vue3";
export const useAuthStore = defineStore('authStore', () => {
- const user = usePage().props.user
- const token = user?.token
- const permissions = user?.permissions
- const availableDepartments = ref(user?.available_departments)
+ const page = usePage()
+ const user = ref(page.props.user)
+ const token = computed(() => user.value?.token)
+ const role = computed(() => user.value?.role)
+ const permissions = computed(() => user.value?.permissions)
+ const availableDepartments = computed(() => user.value?.available_departments)
+ const availableRoles = computed(() => user.value?.available_roles)
+
+ watch(
+ () => page.props.user,
+ (newUser) => {
+ user.value = newUser
+ },
+ { deep: true, immediate: true })
// Инициализация axios с токеном
if (token?.value) {
@@ -16,12 +26,10 @@ export const useAuthStore = defineStore('authStore', () => {
// Вычисляемые свойства
const isAuthenticated = computed(() => !!user.value && !!token.value)
- const isAdmin = computed(() => user.role === 'admin')
- const isDoctor = computed(() => user.role === 'doctor')
- const isNurse = computed(() => user.role === 'nurse')
- const isHeadOfDepartment = computed(() => user.role === 'head_of_department')
- const isStatistician = computed(() => user.role === 'statistician')
- const userDepartment = computed(() => user.current_department || '')
+ const isAdmin = computed(() => role.value?.slug === 'admin')
+ const isDoctor = computed(() => role.value?.slug === 'doctor')
+ const isHeadOfDepartment = computed(() => role.value?.slug === 'head_of_department')
+ const userDepartment = computed(() => user.value?.current_department || '')
const clearAuthData = () => {
user.value = null
@@ -59,12 +67,11 @@ export const useAuthStore = defineStore('authStore', () => {
token,
permissions,
availableDepartments,
+ availableRoles,
isAuthenticated,
isAdmin,
isDoctor,
- isNurse,
isHeadOfDepartment,
- isStatistician,
userDepartment,
clearAuthData,
diff --git a/resources/js/Stores/report.js b/resources/js/Stores/report.js
index 9d6aa3c..a29adeb 100644
--- a/resources/js/Stores/report.js
+++ b/resources/js/Stores/report.js
@@ -19,7 +19,7 @@ export const useReportStore = defineStore('reportStore', () => {
}
})
- const timestampCurrentRange = ref([timestampNow.value, timestampNow.value])
+ const timestampCurrentRange = ref([null, null])
const dataOnReport = ref(null)
@@ -74,6 +74,9 @@ export const useReportStore = defineStore('reportStore', () => {
const form = {
metrics: reportForm.value,
observationPatients: patientsData.value['observation'],
+ unwantedEvent: {
+ comment: reportForm.comment
+ },
...assignForm
}
@@ -99,21 +102,40 @@ export const useReportStore = defineStore('reportStore', () => {
await axios.get('/api/report')
.then((res) => {
reportInfo.value = res.data
+
+ reportForm.value.metrika_item_3 = reportInfo.value.department?.recipientCount
+ reportForm.value.metrika_item_7 = reportInfo.value.department?.extractCount
+ reportForm.value.metrika_item_8 = reportInfo.value.department?.currentCount
+
+ timestampCurrentRange.value = [
+ reportInfo.value.dates.startAt,
+ reportInfo.value.dates.endAt,
+ ]
})
.finally(() => {
isLoadReportInfo.value = false
})
}
- const getDataOnReportDate = async () => {
- await axios.get(`/api/metric-forms/1/report-by-date?sent_at=${timestampCurrentRange.value}`)
- .then(res => {
- dataOnReport.value = res.data
- })
- .catch(err => {
- // Отчета на выбранную дату не найдено
- if (err.code === 404) {}
- })
+ const getDataOnReportDate = async (dateRange) => {
+ isLoadReportInfo.value = true
+ timestampCurrentRange.value = dateRange
+ await axios.get(`/api/report?startAt=${timestampCurrentRange.value[0]}&endAt=${timestampCurrentRange.value[1]}`)
+ .then((res) => {
+ reportInfo.value = res.data
+
+ reportForm.value.metrika_item_3 = reportInfo.value.department?.recipientCount
+ reportForm.value.metrika_item_7 = reportInfo.value.department?.extractCount
+ reportForm.value.metrika_item_8 = reportInfo.value.department?.currentCount
+
+ timestampCurrentRange.value = [
+ reportInfo.value.dates.startAt,
+ reportInfo.value.dates.endAt,
+ ]
+ })
+ .finally(() => {
+ isLoadReportInfo.value = false
+ })
}
return {
diff --git a/routes/web.php b/routes/web.php
index 07df975..28418d1 100644
--- a/routes/web.php
+++ b/routes/web.php
@@ -27,6 +27,11 @@ Route::get('/report', [\App\Http\Controllers\Web\ReportController::class, 'index
Route::get('/statistic', [\App\Http\Controllers\Web\StatisticController::class, 'index'])
->middleware(['auth'])
->name('statistic');
+
+Route::post('/user/role/change', [\App\Http\Controllers\AuthController::class, 'changeRole'])
+ ->middleware(['auth'])
+ ->name('user.role.change');
+
Route::get('/path/patient', function () {
return \Inertia\Inertia::render('Path/Patient');
})