diff --git a/api/chambers/views.py b/api/chambers/views.py index e25c4f395f..d45c98f7c5 100644 --- a/api/chambers/views.py +++ b/api/chambers/views.py @@ -3,13 +3,14 @@ import simplejson as json from django.http import JsonResponse from podrazdeleniya.models import Chamber, Bed, PatientToBed, PatientStationarWithoutBeds +from slog.models import Log from utils.response import status_response import datetime from .sql_func import load_patient_without_bed_by_department, load_attending_doctor_by_department, load_patients_stationar_unallocated_sql, load_chambers_and_beds_by_department @login_required -@group_required("Управления палатами") +@group_required("Оператор лечащего врача", "Лечащий врач") def get_unallocated_patients(request): request_data = json.loads(request.body) department_pk = request_data.get('department_pk', -1) @@ -27,7 +28,7 @@ def get_unallocated_patients(request): @login_required -@group_required("Управления палатами") +@group_required("Оператор лечащего врача", "Лечащий врач") def get_chambers_and_beds(request): request_data = json.loads(request.body) department_id = request_data.get('department_pk', -1) @@ -77,29 +78,56 @@ def get_chambers_and_beds(request): @login_required -@group_required("Управления палатами") +@group_required("Оператор лечащего врача", "Лечащий врач") def entrance_patient_to_bed(request): request_data = json.loads(request.body) bed_id = request_data.get('bed_id') direction_id = request_data.get('direction_id') + user = request.user + bed: Bed = Bed.objects.filter(pk=bed_id).select_related('chamber').first() + if not bed: + return status_response(False, "ID кровати обязателен") + bed_department_id = bed.chamber.podrazdelenie_id + user_can_edit = Chamber.check_user(user, bed_department_id) + if not user_can_edit: + return status_response(False, "Пользователь не принадлежит к данному подразделению") if not PatientToBed.objects.filter(bed_id=bed_id, date_out=None).exists(): - PatientToBed(direction_id=direction_id, bed_id=bed_id).save() + patient_to_bed = PatientToBed(direction_id=direction_id, bed_id=bed_id) + patient_to_bed.save() + Log.log(direction_id, 230000, user.doctorprofile, {"direction_id": direction_id, "bed_id": bed_id, "department_id": bed_department_id, "patient_to_bed": patient_to_bed.pk}) return status_response(True) @login_required -@group_required("Управления палатами") +@group_required("Оператор лечащего врача", "Лечащий врач") def extract_patient_bed(request): request_data = json.loads(request.body) direction_pk = request_data.get('patient') - patient = PatientToBed.objects.filter(direction_id=direction_pk, date_out=None).first() + user = request.user + patient: PatientToBed = PatientToBed.objects.filter(direction_id=direction_pk, date_out=None).select_related('bed__chamber').first() + if not patient: + return status_response(False, "ID истории болезни обязателен") + bed_department_id = patient.bed.chamber.podrazdelenie_id + user_can_edit = Chamber.check_user(user, bed_department_id) + if not user_can_edit: + return status_response(False, "Пользователь не принадлежит к данному подразделению") patient.date_out = datetime.datetime.today() patient.save() + Log.log( + direction_pk, + 230001, + user.doctorprofile, + { + "direction_id": direction_pk, + "bed_id": patient.bed_id, + "department_id": bed_department_id, + }, + ) return status_response(True) @login_required -@group_required("Управления палатами") +@group_required("Оператор лечащего врача", "Лечащий врач") def get_attending_doctors(request): request_data = json.loads(request.body) department_pk = request_data.get('department_pk', -1) @@ -117,16 +145,41 @@ def get_attending_doctors(request): @login_required -@group_required("Управления палатами") +@group_required("Оператор лечащего врача", "Лечащий врач") def update_doctor_to_bed(request): request_data = json.loads(request.body) + user = request.user doctor_obj = request_data.get('doctor') - result = PatientToBed.update_doctor(doctor_obj) - return status_response(result) + doctor_id = doctor_obj.get('doctor_pk') + direction_id = doctor_obj.get('direction_id') + is_assign = doctor_obj.get('is_assign') + patient_to_bed = PatientToBed.objects.filter(direction_id=direction_id, date_out=None).select_related('bed__chamber').first() + bed_department_id = patient_to_bed.bed.chamber.podrazdelenie_id + user_can_edit = Chamber.check_user(user, bed_department_id) + if not user_can_edit: + result = {"ok": False, "message": "Пользователь не принадлежит к данному подразделению"} + return result + result = PatientToBed.update_doctor(doctor_id, patient_to_bed, is_assign) + if result: + if is_assign: + type_log = 230002 + else: + type_log = 230003 + Log.log( + direction_id, + type_log, + user.doctorprofile, + { + "direction_id": direction_id, + "bed_id": patient_to_bed.bed_id, + "department_id": bed_department_id, + }, + ) + return JsonResponse({"ok": result, "message": ""}) @login_required -@group_required("Управления палатами") +@group_required("Оператор лечащего врача", "Лечащий врач") def get_patients_without_bed(request): request_data = json.loads(request.body) department_pk = request_data.get('department_pk', -1) @@ -146,19 +199,48 @@ def get_patients_without_bed(request): @login_required -@group_required("Управления палатами") +@group_required("Оператор лечащего врача", "Лечащий врач") def save_patient_without_bed(request): request_data = json.loads(request.body) department_pk = request_data.get('department_pk') patient_obj = request_data.get('patient_obj') - PatientStationarWithoutBeds(direction_id=patient_obj["direction_pk"], department_id=department_pk).save() + user = request.user + user_can_edit = Chamber.check_user(user, department_pk) + if not user_can_edit: + return status_response(False, "Пользователь не принадлежит к данному подразделению") + patient_without_bed = PatientStationarWithoutBeds(direction_id=patient_obj["direction_pk"], department_id=department_pk) + patient_without_bed.save() + Log.log( + patient_obj["direction_pk"], + 230004, + user.doctorprofile, + { + "direction_id": patient_obj["direction_pk"], + "department_id": department_pk, + }, + ) return status_response(True) @login_required -@group_required("Управления палатами") +@group_required("Оператор лечащего врача", "Лечащий врач") def delete_patient_without_bed(request): request_data = json.loads(request.body) + department_pk = request_data.get('department_pk') patient_obj = request_data.get('patient_obj') - PatientStationarWithoutBeds.objects.get(direction_id=patient_obj["direction_pk"]).delete() + user = request.user + user_can_edit = Chamber.check_user(user, department_pk) + if not user_can_edit: + return status_response(False, "Пользователь не принадлежит к данному подразделению") + patient_without_bed = PatientStationarWithoutBeds.objects.get(direction_id=patient_obj["direction_pk"]) + patient_without_bed.delete() + Log.log( + patient_obj["direction_pk"], + 230005, + user.doctorprofile, + { + "direction_id": patient_obj["direction_pk"], + "department_id": department_pk, + }, + ) return status_response(True) diff --git a/context_processors/utils.py b/context_processors/utils.py index 397b296f12..4c5be62a68 100644 --- a/context_processors/utils.py +++ b/context_processors/utils.py @@ -144,7 +144,7 @@ def menu(request): "nt": False, "access": ["Управление анализаторами"], }, - {"url": "/ui/chambers", "title": "Палаты", "nt": False, "access": ["Управления палатами"]}, + {"url": "/ui/chambers", "title": "Палаты", "nt": False, "access": ["Оператор лечащего врача", "Лечащий врач"], "module": "l2_hosp"}, {"url": '/ui/list-wait', "title": "Листы ожидания", "nt": False, "access": ["Лечащий врач", "Оператор лечащего врача"], "module": "l2_list_wait"}, {"url": '/ui/doc-call', "title": "Вызовы врача и заявки", "nt": False, "access": ["Лечащий врач", "Оператор лечащего врача", "Вызов врача"], "module": "l2_doc_call"}, { diff --git a/l2-frontend/src/mainWithRouter.ts b/l2-frontend/src/mainWithRouter.ts index 3333efbe40..f372ec0470 100644 --- a/l2-frontend/src/mainWithRouter.ts +++ b/l2-frontend/src/mainWithRouter.ts @@ -748,9 +748,12 @@ const router = new Router({ name: 'ManageChamber', component: () => import('@/pages/ManageChambers/index.vue'), meta: { - narrowLayout: true, title: 'Палаты', - groups: ['Палаты'], + groups: [ + 'Оператор лечащего врача', + 'Лечащий врач', + ], + module: 'l2_hosp', fullPageLayout: true, }, }, diff --git a/l2-frontend/src/pages/ManageChambers/index.vue b/l2-frontend/src/pages/ManageChambers/index.vue index cb72992f11..ad6f5f616a 100644 --- a/l2-frontend/src/pages/ManageChambers/index.vue +++ b/l2-frontend/src/pages/ManageChambers/index.vue @@ -21,6 +21,8 @@ animation="500" chosen-class="chosen-unallocated-patient" ghost-class="ghost-unallocated-patient" + :disabled="!userCanEdit" + @change="changeUnallocatedPatient" >
@@ -115,6 +118,7 @@ class="draggable-beds" chosen-class="chosen-beds" ghost-class="ghost-beds" + :disabled="!userCanEdit" @change="changePatientBed($event, bed)" @remove="clearArrayDoctor(bed)" > @@ -190,6 +194,7 @@ chosen-class="chosen-patient-without-bed" ghost-class="ghost-patient-without-bed" animation="500" + :disabled="!userCanEdit" @change="PatientWaitBed" >
import draggable from 'vuedraggable'; import { - computed, + computed, getCurrentInstance, onMounted, ref, watch, @@ -287,6 +293,16 @@ const attendingDoctor = ref([]); const departmentPatientPk = ref(null); const departmentDocPk = ref(null); const store = useStore(); +const root = getCurrentInstance().proxy.$root; +const userDepartmentId = store.getters.user_data.department.pk; + +const userCanEdit = computed(() => { + const { groups } = store.getters.user_data; + if (departmentPatientPk.value === userDepartmentId) { + return true; + } + return groups.includes('Палаты: все подразделения') || groups.includes('Admin'); +}); const bedInformationCounter = computed(() => { let women = 0; let man = 0; @@ -364,40 +380,68 @@ const loadChamberAndBed = async () => { await store.dispatch(actions.DEC_LOADING); }; +const changeUnallocatedPatient = async ({ added, removed }) => { + if (added) { + await getUnallocatedPatients(); + } +}; const changePatientBed = async ({ added, removed }, bed) => { if (added) { await store.dispatch(actions.INC_LOADING); - await api('chambers/entrance-patient-to-bed', { + const { ok, message } = await api('chambers/entrance-patient-to-bed', { bed_id: bed.pk, direction_id: bed.patient[0].direction_pk, }); await store.dispatch(actions.DEC_LOADING); + if (ok) { + root.$emit('msg', 'ok', 'Успешно'); + } else { + root.$emit('msg', 'error', message); + } } if (removed) { await store.dispatch(actions.INC_LOADING); - await api('chambers/extract-patient-bed', { + const { ok, message } = await api('chambers/extract-patient-bed', { patient: removed.element.direction_pk, }); await store.dispatch(actions.DEC_LOADING); + if (ok) { + root.$emit('msg', 'ok', 'Успешно'); + } else { + root.$emit('msg', 'error', message); + } } + await loadChamberAndBed(); }; const PatientWaitBed = async ({ added, removed }) => { if (added) { await store.dispatch(actions.INC_LOADING); - await api('chambers/save-patient-without-bed', { + const { ok, message } = await api('chambers/save-patient-without-bed', { patient_obj: added.element, department_pk: departmentPatientPk.value, }); await store.dispatch(actions.DEC_LOADING); + if (ok) { + root.$emit('msg', 'ok', 'Успешно'); + } else { + root.$emit('msg', 'error', message); + } } if (removed) { await store.dispatch(actions.INC_LOADING); - await api('chambers/delete-patient-without-bed', { + const { ok, message } = await api('chambers/delete-patient-without-bed', { + department_pk: departmentPatientPk.value, patient_obj: removed.element, }); await store.dispatch(actions.DEC_LOADING); + if (ok) { + root.$emit('msg', 'ok', 'Успешно'); + } else { + root.$emit('msg', 'error', message); + } } + await getPatientWithoutBed(); }; const changeDoctor = async ({ added, removed }, bed) => { @@ -418,8 +462,14 @@ const changeDoctor = async ({ added, removed }, bed) => { }; } await store.dispatch(actions.INC_LOADING); - await api('chambers/update-doctor-to-bed', { doctor }); + const { ok, message } = await api('chambers/update-doctor-to-bed', { doctor }); await store.dispatch(actions.DEC_LOADING); + if (ok) { + root.$emit('msg', 'ok', 'Успешно'); + } else { + root.$emit('msg', 'error', message); + } + await loadChamberAndBed(); }; const checkConditionsPutDoc = (patient: patientData[], doctor: doctorData[]) => { diff --git a/podrazdeleniya/models.py b/podrazdeleniya/models.py index 92171ca115..f5fc978299 100644 --- a/podrazdeleniya/models.py +++ b/podrazdeleniya/models.py @@ -129,6 +129,17 @@ class Meta: verbose_name = 'Палата' verbose_name_plural = 'Палаты' + @staticmethod + def check_user(user, need_department_id): + has_group = user.doctorprofile.has_group("Палаты: все подразделения") + if user.doctorprofile.podrazdeleniye_id == need_department_id: + result = True + elif has_group: + result = True + else: + result = user.is_superuser + return result + class Bed(models.Model): chamber = models.ForeignKey(Chamber, on_delete=models.CASCADE) @@ -153,15 +164,13 @@ def __str__(self): return f'{self.direction.client.individual.fio()}' @staticmethod - def update_doctor(doctor_obj): - if doctor_obj["is_assign"]: - doctor = PatientToBed.objects.filter(direction_id=doctor_obj["direction_id"], doctor=None, date_out=None).first() - doctor.doctor_id = doctor_obj["doctor_pk"] - doctor.save() + def update_doctor(doctor_id, patient_to_bed, is_assign): + if is_assign: + patient_to_bed.doctor_id = doctor_id + patient_to_bed.save() else: - doctor = PatientToBed.objects.filter(doctor_id=doctor_obj["doctor_pk"], direction_id=doctor_obj["direction_id"], date_out=None).first() - doctor.doctor = None - doctor.save() + patient_to_bed.doctor = None + patient_to_bed.save() return True class Meta: diff --git a/slog/models.py b/slog/models.py index 83ace9d881..bce1166be7 100644 --- a/slog/models.py +++ b/slog/models.py @@ -174,6 +174,12 @@ class Log(models.Model): (220002, 'Конструктор лабораторных исследований: Обновление услуги'), (220003, 'Конструктор лабораторных исследований: Создание услуги'), (220004, 'Конструктор лабораторных исследований: Изменение пробирки для фракций'), + (230000, 'Палаты: Пациент занял кровать'), + (230001, 'Палаты: Пациент покинул кровать'), + (230002, 'Палаты: Пациенту назначен доктор'), + (230003, 'Палаты: Пациенту отменили доктора'), + (230004, 'Палаты: Пациент переведен в ожидающие'), + (230005, 'Палаты: Пациент покинул ожидающих'), ) # Виды событий, которые могут быть очищены