diff --git a/api/cases/__init__.py b/api/cases/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/api/cases/helpers.py b/api/cases/helpers.py
new file mode 100644
index 0000000000..58700c57e3
--- /dev/null
+++ b/api/cases/helpers.py
@@ -0,0 +1,45 @@
+from utils import tree_directions_case as tree_directions
+from anytree import Node, RenderTree
+
+
+def get_case_direction_tree(num_dir):
+ root_dir = tree_directions.root_direction(num_dir)
+ if not root_dir or not root_dir[-1]:
+ return {}
+ num_root_dir = root_dir[-1][-3]
+ result = tree_directions.get_research_by_dir(num_root_dir)
+ num_iss = result[0][0]
+
+ # отсортировать по подчинениям - построить бинарное дерево
+ tree_dir = tree_directions.hosp_tree_direction(num_iss)
+ final_tree = {}
+
+ node_dir = Node({'order': '-1', 'direction': '', 'research_title': '', 'correct_level': True, 'color': '', 'cancel': False, 'issledovaniye': '', 'parent_iss': ''})
+ for j in tree_dir:
+ research_title = j[12] if j[12] else j[9]
+ temp_s = {'order': '-1', 'direction': j[0], 'research_title': research_title, 'correct_level': True, 'color': '', 'cancel': j[14], 'issledovaniye': j[5], 'parent_iss': j[3]}
+ if not j[3]:
+ final_tree[j[5]] = Node(temp_s, parent=node_dir)
+ else:
+ final_tree[j[5]] = Node(temp_s, parent=final_tree.get(j[3]))
+
+ data_sort = []
+ count_level_second = 0
+ correct_level = True
+ for row in RenderTree(node_dir):
+ order = int(len(row.pre) / 4)
+ if order == 2:
+ count_level_second += 1
+ if count_level_second > 1:
+ correct_level = False
+ row.node.name['correct_level'] = correct_level
+ row.node.name['color'] = 'red'
+ if not correct_level and order > 2:
+ row.node.name['color'] = '#d35400'
+ row.node.name['correct_level'] = correct_level
+
+ row.node.name['order'] = order
+ data_sort.append(row.node.name)
+
+ data_sort.pop(0)
+ return data_sort
diff --git a/api/cases/sql_func.py b/api/cases/sql_func.py
new file mode 100644
index 0000000000..e8c4ea3afe
--- /dev/null
+++ b/api/cases/sql_func.py
@@ -0,0 +1,241 @@
+from django.db import connection
+
+from laboratory.settings import TIME_ZONE
+from utils.db import namedtuplefetchall
+
+
+def get_research(title_podr, vertical_result_display):
+ """
+ Возврат: id услуги, title-услуги
+
+ """
+
+ with connection.cursor() as cursor:
+ cursor.execute(
+ """WITH
+ t_podr AS (
+ SELECT id as podr_id, title as podr_title FROM public.podrazdeleniya_podrazdeleniya),
+
+ t_research AS (
+ SELECT id as research_id, title as research_title, vertical_result_display, podrazdeleniye_id
+ FROM public.directory_researches)
+
+ SELECT research_id, research_title FROM t_research
+ LEFT JOIN t_podr
+ ON t_research.podrazdeleniye_id=t_podr.podr_id
+ WHERE podr_title = %(title_podr)s and vertical_result_display = %(vertical)s
+ ORDER BY research_id
+ """,
+ params={'title_podr': title_podr, 'vertical': vertical_result_display},
+ )
+
+ row = cursor.fetchall()
+ return row
+
+
+def get_iss(list_research_id, list_dirs):
+ """
+ Возврат: id-iss
+ добавить:
+ """
+ with connection.cursor() as cursor:
+ cursor.execute(
+ """
+ SELECT id, research_id FROM public.directions_issledovaniya
+ WHERE napravleniye_id = ANY(ARRAY[%(num_dirs)s]) AND research_id = ANY(ARRAY[%(id_researches)s])
+ AND time_confirmation IS NOT NULL
+ """,
+ params={'id_researches': list_research_id, 'num_dirs': list_dirs},
+ )
+ row = cursor.fetchall()
+ return row
+
+
+def get_distinct_research(list_research_id, list_dirs, is_text_research=False):
+ """
+ Возврат: уникальных research
+ добавить:
+ """
+ with connection.cursor() as cursor:
+ cursor.execute(
+ """WITH
+ t_iss AS (SELECT id, research_id FROM public.directions_issledovaniya
+ WHERE CASE
+ WHEN %(is_text_research)s = TRUE THEN
+ napravleniye_id = ANY(ARRAY[%(num_dirs)s]) AND time_confirmation IS NOT NULL
+ WHEN %(is_text_research)s = FALSE THEN
+ napravleniye_id = ANY(ARRAY[%(num_dirs)s]) AND research_id = ANY(ARRAY[%(id_researches)s]) AND time_confirmation IS NOT NULL
+ END)
+
+ SELECT DISTINCT ON (research_id) research_id FROM t_iss
+
+ """,
+ params={'id_researches': list_research_id, 'num_dirs': list_dirs, 'is_text_research': is_text_research},
+ )
+ row = cursor.fetchall()
+ return row
+
+
+def get_distinct_fraction(list_iss):
+ """
+ Возвращает уникальные фракци(id, title, units), которые присутствуют во всех исследованиях
+ """
+ with connection.cursor() as cursor:
+ cursor.execute(
+ """WITH
+ t_fraction AS (SELECT id as id_frac, title as title_frac FROM public.directory_fractions ORDER BY id)
+
+ SELECT DISTINCT ON (fraction_id) fraction_id, title_frac, units FROM directions_result
+ LEFT JOIN t_fraction ON directions_result.fraction_id = t_fraction.id_frac
+ WHERE issledovaniye_id = ANY(ARRAY[%(id_iss)s])
+ ORDER by fraction_id
+ """,
+ params={'id_iss': list_iss},
+ )
+ row = cursor.fetchall()
+ return row
+
+
+def get_result_fraction(list_iss):
+ """
+ Возвращает результат: дата, фракция, значение(value)
+ """
+ with connection.cursor() as cursor:
+ cursor.execute(
+ """WITH
+ t_fraction AS (SELECT id as id_frac, title as title_frac FROM public.directory_fractions ORDER BY id),
+
+ t_iss AS (SELECT id as iss_id, napravleniye_id, to_char(time_confirmation AT TIME ZONE %(tz)s, 'DD.MM.YY') as date_confirm
+ FROM public.directions_issledovaniya
+ WHERE id = ANY(ARRAY[%(id_iss)s]) AND time_confirmation IS NOT NULL)
+
+ SELECT fraction_id, issledovaniye_id, title_frac, value, date_confirm, napravleniye_id FROM directions_result
+ LEFT JOIN t_fraction ON directions_result.fraction_id = t_fraction.id_frac
+ LEFT JOIN t_iss ON directions_result.issledovaniye_id = t_iss.iss_id
+ WHERE issledovaniye_id = ANY(ARRAY[%(id_iss)s])
+ ORDER by napravleniye_id, date_confirm
+ """,
+ params={'id_iss': list_iss, 'tz': TIME_ZONE},
+ )
+ row = cursor.fetchall()
+ return row
+
+
+def get_result_text_research(research_pk, listdirs, force_all_fields=False):
+ with connection.cursor() as cursor:
+ cursor.execute(
+ """
+ WITH
+ t_research AS (SELECT id as research_id, title as research_title FROM directory_researches
+ WHERE id = %(id_research)s),
+
+ t_groups AS (SELECT id as group_id, title as group_title, "order" as group_order
+ FROM public.directory_paraclinicinputgroups
+ WHERE research_id = %(id_research)s),
+
+ t_fields AS (SELECT id as field_id, title, "order" as field_order,
+ directory_paraclinicinputfield.group_id, group_title, group_order
+ FROM public.directory_paraclinicinputfield
+ LEFT JOIN t_groups on directory_paraclinicinputfield.group_id = t_groups.group_id
+ WHERE (directory_paraclinicinputfield.group_id in (SELECT group_id from t_groups) and
+ (
+ for_extract_card = true or
+ (%(force_all_fields)s = true and NOT (field_type = ANY(ARRAY[16,17]))))
+ ) or
+ (directory_paraclinicinputfield.group_id in (SELECT group_id from t_groups) and title ILIKE 'Заключение')),
+
+ t_iss AS (SELECT directions_issledovaniya.id as iss_id, time_confirmation,
+ to_char(time_confirmation AT TIME ZONE %(tz)s, 'DD.MM.YY') as date_confirm,
+ napravleniye_id, t_research.research_title, ud.fio FROM directions_issledovaniya
+ LEFT JOIN t_research on t_research.research_id = directions_issledovaniya.research_id
+ LEFT JOIN users_doctorprofile ud ON
+ ud.id=directions_issledovaniya.doc_confirmation_id
+ WHERE directions_issledovaniya.research_id=%(id_research)s and napravleniye_id = ANY(ARRAY[%(id_dirs)s]) and time_confirmation is not Null)
+
+ SELECT research_title, date_confirm, napravleniye_id, group_title, title, "value", t_iss.iss_id, t_iss.fio, field_type FROM directions_paraclinicresult
+ LEFT JOIN t_iss on directions_paraclinicresult.issledovaniye_id = t_iss.iss_id
+ LEFT JOIN t_fields on directions_paraclinicresult.field_id = t_fields.field_id
+ WHERE issledovaniye_id in (SELECT iss_id from t_iss) and
+ directions_paraclinicresult.field_id in (SELECT field_id from t_fields)
+ order by time_confirmation, group_order, field_order
+
+ """,
+ params={'id_research': research_pk, 'id_dirs': listdirs, 'force_all_fields': force_all_fields, 'tz': TIME_ZONE},
+ )
+ row = cursor.fetchall()
+ return row
+
+
+def get_result_value_iss(iss_pk, research_pk, titles_field):
+ with connection.cursor() as cursor:
+ cursor.execute(
+ """
+ WITH
+ t_field AS (SELECT "id", title FROM directory_paraclinicinputfield
+ WHERE group_id in (SELECT "id" FROM directory_paraclinicinputgroups WHERE research_id=%(id_research)s)
+ AND title = ANY(ARRAY[%(titles_field)s]))
+
+ SELECT field_id, issledovaniye_id, "value", title FROM public.directions_paraclinicresult
+ LEFT JOIN t_field ON directions_paraclinicresult.field_id = t_field.id
+ where field_id in (SELECT "id" FROM t_field) and issledovaniye_id = %(id_iss)s
+
+
+ """,
+ params={'id_iss': iss_pk, 'id_research': research_pk, 'titles_field': titles_field},
+ )
+ row = cursor.fetchall()
+ return row
+
+
+def get_result_temperature_list(iss_pk_list, research_pk, titles_field):
+ with connection.cursor() as cursor:
+ cursor.execute(
+ """
+ WITH
+ t_field AS (SELECT "id", title FROM directory_paraclinicinputfield
+ WHERE group_id in (SELECT "id" FROM directory_paraclinicinputgroups WHERE research_id=%(id_research)s)
+ AND title = ANY(ARRAY[%(titles_field)s]))
+
+ SELECT field_id, issledovaniye_id, "value", title FROM public.directions_paraclinicresult
+ LEFT JOIN t_field ON directions_paraclinicresult.field_id = t_field.id
+ where field_id in (SELECT "id" FROM t_field) and issledovaniye_id = ANY(ARRAY[%(id_iss)s])
+ ORDER by issledovaniye_id
+
+
+ """,
+ params={'id_iss': iss_pk_list, 'id_research': research_pk, 'titles_field': titles_field},
+ )
+ row = cursor.fetchall()
+ return row
+
+
+def get_assignments_by_history(history_id: int):
+ with connection.cursor() as cursor:
+ cursor.execute(
+ """
+ SELECT public.directions_napravleniya.id as napravlenie_id, public.directions_napravleniya.data_sozdaniya,
+ public.users_doctorprofile.fio as who_assigned, doc_list.fio as who_confirm, public.directions_napravleniya.total_confirmed,
+ public.directions_issledovaniya.time_confirmation, public.directory_researches.id as research_id, public.directory_researches.title as research_title
+
+ FROM public.directions_issledovaniya
+ INNER JOIN public.directions_napravleniya
+ ON public.directions_issledovaniya.napravleniye_id = public.directions_napravleniya.id
+ INNER JOIN public.directory_researches
+ ON public.directions_issledovaniya.research_id = public.directory_researches.id
+ INNER JOIN public.users_doctorprofile
+ ON public.directions_napravleniya.doc_id = public.users_doctorprofile.id
+ LEFT JOIN (SELECT id, fio FROM public.users_doctorprofile) as doc_list
+ ON public.directions_issledovaniya.doc_confirmation_id = doc_list.id
+
+ WHERE public.directions_napravleniya.parent_case_id = %(history_id)s
+ AND (is_paraclinic = true OR is_doc_refferal = true OR is_microbiology = true OR is_citology = true OR is_gistology = true OR
+ (is_paraclinic = False AND is_doc_refferal = False AND is_microbiology = False AND is_citology = False AND is_gistology = False
+ AND is_slave_hospital = False AND is_hospital = False AND is_case = False))
+ AND public.directions_napravleniya.cancel != true
+
+ ORDER BY public.directions_napravleniya.data_sozdaniya
+ """,
+ params={"history_id": history_id},
+ )
+ rows = namedtuplefetchall(cursor)
+ return rows
diff --git a/api/cases/stationar_func.py b/api/cases/stationar_func.py
new file mode 100644
index 0000000000..6a0e32319e
--- /dev/null
+++ b/api/cases/stationar_func.py
@@ -0,0 +1,529 @@
+from collections import OrderedDict
+from copy import deepcopy
+from typing import List
+
+from directions.models import Issledovaniya, Napravleniya
+from directory.models import Researches
+from podrazdeleniya.models import Podrazdeleniya
+from utils import tree_directions_case as tree_directions
+from .sql_func import (
+ get_research,
+ get_iss,
+ get_distinct_research,
+ get_distinct_fraction,
+ get_result_fraction,
+ get_result_text_research,
+ get_result_temperature_list,
+ get_assignments_by_history,
+)
+from api.dicom import search_dicom_study
+from utils.dates import normalize_date
+from anytree import Node, RenderTree
+
+
+def hosp_get_data_direction(main_direction, site_type=-1, type_service='None', level=-1):
+ # Получить данные по разделу Стационарной карты
+ # hosp_site_type=-1 - не получать ничего.
+ # level уровень подчинения. Если вернуть только дочерние для текущего направления level=2
+ result = tree_directions.get_research_by_dir(main_direction)
+ num_iss = result[0][0]
+ main_research = result[0][1]
+
+ hosp_site_type = site_type
+ hosp_level = level
+ hosp_is_paraclinic, hosp_is_doc_refferal, hosp_is_lab, hosp_is_hosp, hosp_is_all, hosp_morfology = False, False, False, False, False, False
+ if type_service == 'is_paraclinic':
+ hosp_is_paraclinic = True
+ elif type_service == 'is_doc_refferal':
+ hosp_is_doc_refferal = True
+ elif type_service == 'is_lab':
+ hosp_is_lab = True
+ elif type_service == 'is_morfology':
+ hosp_morfology = True
+ if site_type == -1 and type_service == 'None':
+ hosp_is_all = True
+
+ hosp_dirs = tree_directions.hospital_get_direction(
+ num_iss, main_research, hosp_site_type, hosp_is_paraclinic, hosp_is_doc_refferal, hosp_is_lab, hosp_is_hosp, hosp_level, hosp_is_all, hosp_morfology
+ )
+
+ data = []
+ if hosp_dirs:
+ for i in hosp_dirs:
+ if hosp_is_all and i[21] == 9:
+ continue
+ data.append(
+ {
+ 'direction': i[0],
+ 'date_create': i[1],
+ 'time_create': i[2],
+ 'iss': i[5],
+ 'date_confirm': i[6],
+ 'time_confirm': i[7],
+ 'research_id': i[8],
+ 'research_title': i[9],
+ 'podrazdeleniye_id': i[13],
+ 'is_paraclinic': i[14],
+ 'is_doc_refferal': i[15],
+ 'is_stom': i[16],
+ 'is_hospital': i[17],
+ 'is_microbiology': i[18],
+ 'podrazdeleniye_title': i[19],
+ 'site_type': i[21],
+ 'research_short_title': i[23],
+ 'is_slave_hospital': i[24],
+ 'is_cancel': i[25],
+ "is_citology": i[26],
+ "is_gistology": i[27],
+ }
+ )
+
+ return data
+
+
+def get_direction_attrs(direction, site_type=-1, type_service='None', level=-1):
+ # Возврат: [{pk:№, date_create:'', confirm:'', researches:[]}, {pk:№, date_create:'', confirm:'', researches:[]}]
+ data = []
+
+ main_direction = direction
+ type_serv = type_service
+ site_type_num = site_type
+ level_get = level
+ data_direction = hosp_get_data_direction(main_direction, site_type=site_type_num, type_service=type_serv, level=level_get)
+ dict_temp = {}
+
+ for dir_attr in data_direction:
+ num_dir = dir_attr.get('direction')
+ if dict_temp.get(num_dir):
+ dict_by_dir = dict_temp.get(num_dir)
+ dict_by_dir['researches'] = [*dict_by_dir['researches'], dir_attr.get('research_title')]
+ dict_by_dir['researches_short'] = [*dict_by_dir['researches_short'], dir_attr.get('researches_short')]
+ dict_temp[num_dir] = dict_by_dir.copy()
+ else:
+ type_dir = 'directions'
+ confirm = bool(dir_attr.get('date_confirm'))
+ if dir_attr.get('is_slave_hospital'):
+ type_dir = 'stationar'
+ dict_temp[num_dir] = {
+ 'type': type_dir,
+ 'date_create': dir_attr.get('date_create'),
+ 'confirm': confirm,
+ 'researches': [dir_attr.get('research_title')],
+ 'researches_short': [dir_attr.get('research_short_title')],
+ 'podrazdeleniye': dir_attr.get('podrazdeleniye_title'),
+ }
+
+ for k, v in dict_temp.items():
+ dict_result = {
+ 'type': v['type'],
+ 'pk': k,
+ 'date_create': v['date_create'],
+ 'confirm': v['confirm'],
+ 'researches': v['researches'],
+ 'researches_short': v['researches_short'],
+ 'podrazdeleniye': v['podrazdeleniye'],
+ }
+ data.append(dict_result)
+
+ return data
+
+
+def hosp_get_hosp_direction(num_dir):
+ # возвращает дерево направлений-отделений, у к-рых тип улуги только is_hosp
+ # [{'direction': номер направления, 'research_title': значение}, {'direction': номер направления, 'research_title': значение}]
+ root_dir = tree_directions.root_direction(num_dir)
+ if not root_dir or not root_dir[-1]:
+ return {}
+ num_root_dir = root_dir[-1][-3]
+ result = tree_directions.get_research_by_dir(num_root_dir)
+ num_iss = result[0][0]
+
+ # отсортировать по подчинениям - построить бинарное дерево
+ tree_dir = tree_directions.hosp_tree_direction(num_iss)
+ final_tree = {}
+
+ node_dir = Node({'order': '-1', 'direction': '', 'research_title': '', 'correct_level': True, 'color': '', 'cancel': False, 'issledovaniye': '', 'parent_iss': ''})
+ for j in tree_dir:
+ research_title = j[12] if j[12] else j[9]
+ temp_s = {'order': '-1', 'direction': j[0], 'research_title': research_title, 'correct_level': True, 'color': '', 'cancel': j[14], 'issledovaniye': j[5], 'parent_iss': j[3]}
+ if not j[3]:
+ final_tree[j[5]] = Node(temp_s, parent=node_dir)
+ else:
+ final_tree[j[5]] = Node(temp_s, parent=final_tree.get(j[3]))
+
+ data_sort = []
+ count_level_second = 0
+ correct_level = True
+ for row in RenderTree(node_dir):
+ order = int(len(row.pre) / 4)
+ if order == 2:
+ count_level_second += 1
+ if count_level_second > 1:
+ correct_level = False
+ row.node.name['correct_level'] = correct_level
+ row.node.name['color'] = 'red'
+ if not correct_level and order > 2:
+ row.node.name['color'] = '#d35400'
+ row.node.name['correct_level'] = correct_level
+
+ row.node.name['order'] = order
+ data_sort.append(row.node.name)
+
+ data_sort.pop(0)
+ return data_sort
+
+
+def hosp_get_curent_hosp_dir(current_iss):
+ obj_iss = Issledovaniya.objects.get(pk=current_iss)
+ current_dir = obj_iss.napravleniye
+ if obj_iss.research.is_hospital:
+ return current_dir.pk
+ if current_dir.parent:
+ return current_dir.parent.napravleniye_id
+
+
+def hosp_get_lab_iss(directions):
+ num_lab_dirs = directions
+
+ num_lab_dirs = list(num_lab_dirs)
+ if len(num_lab_dirs) == 0:
+ return {}
+
+ # Получить титл подразделений типа Лаборатория
+ departs_obj = Podrazdeleniya.objects.filter(p_type=2).order_by('title')
+ departs = OrderedDict()
+ result = OrderedDict()
+
+ for i in departs_obj:
+ departs[i.pk] = i.title
+ # получить research_id по лаборатории и vertical_result_display = True
+ vertical = {}
+ vertical_result = []
+ result[i.title] = {'vertical': {}, 'horizontal': {}}
+ horizontal_result = []
+ vertical_research = get_research(i.title, True)
+ id_research_vertical = [i[0] for i in vertical_research]
+ if len(id_research_vertical) > 0:
+ # получить уникальные research_id по направления
+ get_research_id = get_distinct_research(id_research_vertical, num_lab_dirs, is_text_research=False)
+ research_distinct = [d[0] for d in get_research_id]
+ if research_distinct:
+ for id_research_vertical in research_distinct:
+ # получить исследования по направлениям и соответсвующим research_id
+ get_iss_id = get_iss(id_research_vertical, num_lab_dirs)
+ iss_id_vertical = [i[0] for i in get_iss_id]
+
+ research_fraction_vertical = get_distinct_fraction(iss_id_vertical)
+ fraction_title = []
+ fraction_title_units = []
+ for f in research_fraction_vertical:
+ fraction_title.append(f[1])
+ title_unit = f', {f[2]}' if f[2] else ''
+ fraction_title_units.append(f'{f[1]}{title_unit}')
+ fraction_template = [''] * len(fraction_title) # заготовка для value-резульлтатов
+ fraction_result = get_result_fraction(iss_id_vertical)
+ vertical_temp_results = {}
+ for f in fraction_result:
+ key = f'{f[4]} {str(f[5])}'
+ if key in vertical_temp_results.keys():
+ position_element = fraction_title.index(f[2])
+ tmp_list = vertical_temp_results.get(key)
+ tmp_list_vert = deepcopy(tmp_list)
+ tmp_list_vert[position_element] = f[3]
+ vertical_temp_results[key] = tmp_list_vert
+ else:
+ vertical_temp_results[key] = fraction_template
+ position_element = fraction_title.index(f[2])
+ tmp_list = vertical_temp_results.get(key)
+ tmp_list_vert = deepcopy(tmp_list)
+ tmp_list_vert[position_element] = f[3]
+ vertical_temp_results[key] = tmp_list_vert
+ vertical['title_research'] = Researches.objects.get(pk=id_research_vertical).title
+ vertical['title_fracions'] = fraction_title_units
+ vertical['result'] = vertical_temp_results
+ vertical1 = deepcopy(vertical)
+ vertical_result.append(vertical1)
+ result[i.title]['vertical'] = vertical_result
+
+ # получить research_id по лаборатории и vertical_result_display = False
+ horizontal = {}
+ horizontal_research = get_research(i.title, False)
+ id_research_horizontal = [i[0] for i in horizontal_research]
+ if len(id_research_horizontal) > 0:
+ # получить исследования по направлениям и соответсвующим research_id для horizontal
+ get_iss_id = get_iss(id_research_horizontal, num_lab_dirs)
+ iss_id_horizontal = [i[0] for i in get_iss_id]
+ # получить уникальные фракции по исследованиям для хоризонтал fraction_title: [], units: []
+ if iss_id_horizontal:
+ fraction_horizontal = get_distinct_fraction(iss_id_horizontal)
+ fraction_title = []
+ fraction_title_units = []
+ for f in fraction_horizontal:
+ fraction_title.append(f[1])
+ title_unit = f', {f[2]}' if f[2] else ''
+ fraction_title_units.append(f'{f[1]}{title_unit}')
+
+ fraction_template = [''] * len(fraction_title) # заготовка для value-резульлтатов
+ fraction_result = get_result_fraction(iss_id_horizontal)
+
+ temp_results = {}
+ for f in fraction_result:
+ key = f'{f[4]} {str(f[5])}'
+ if key in temp_results.keys():
+ position_element = fraction_title.index(f[2])
+ tmp_list = temp_results.get(key)
+ tmp_list2 = deepcopy(tmp_list)
+ tmp_list2[position_element] = f[3]
+ temp_results[key] = tmp_list2
+ else:
+ temp_results[key] = fraction_template
+ position_element = fraction_title.index(f[2])
+ tmp_list = temp_results.get(key)
+ tmp_list2 = deepcopy(tmp_list)
+ tmp_list2[position_element] = f[3]
+ temp_results[key] = tmp_list2
+
+ horizontal['title_fracions'] = fraction_title_units
+ horizontal['result'] = temp_results
+ horizontal_result.append(horizontal)
+ result[i.title]['horizontal'] = horizontal_result
+ result_filtered = {}
+ for k in result:
+ if result[k]['horizontal'] or result[k]['vertical']:
+ result_filtered[k] = result[k]
+ return result_filtered
+
+
+def hosp_get_text(directions):
+ num_paraclinic_dirs = directions
+ num_paraclinic_dirs = list(num_paraclinic_dirs)
+
+ return desc_to_data(num_paraclinic_dirs, force_all_fields=True)
+
+
+def desc_to_data(num_dirs: List[int], force_all_fields: bool = False):
+ # [0] - заглушка для запроса. research c id =0 не бывает
+ get_research_id = get_distinct_research([0], num_dirs, is_text_research=True) if num_dirs else []
+ result = []
+ for research_base in get_research_id:
+ research = research_base[0]
+ field_result = get_result_text_research(research, num_dirs, force_all_fields)
+ last_group = None
+ last_date = None
+ data_in = []
+ new_date_data = {}
+ for i in field_result:
+ date = f'{i[1]} {i[2]}'
+ link_dicom = search_dicom_study(i[2]) if not force_all_fields else None
+ group = i[3]
+ if not i[5]:
+ continue
+ fields = {'title_field': i[4], 'value': i[5], 'field_type': i[8]}
+
+ if date != last_date:
+ if new_date_data:
+ data_in.append(new_date_data.copy())
+
+ new_date_data = dict()
+ new_date_data['date'] = date
+ new_date_data['link_dicom'] = link_dicom if link_dicom else ''
+ new_date_data['iss_id'] = i[6]
+ new_date_data['docConfirm'] = i[7]
+ new_date_data['data'] = [{'group_title': group, 'fields': [fields.copy()]}]
+ last_date = date
+ last_group = group
+ continue
+
+ if group != last_group and date == last_date:
+ current_data = new_date_data.get('data')
+ current_data.append({'group_title': group, 'fields': [fields.copy()]})
+ new_date_data['data'] = current_data.copy()
+ last_group = group
+ continue
+
+ current_data = new_date_data.get('data')
+ get_last_group = current_data.pop()
+ last_fields = get_last_group.get('fields')
+ last_fields.append(fields)
+ get_last_group['fields'] = last_fields.copy()
+ current_data.append(get_last_group.copy())
+ new_date_data['data'] = current_data.copy()
+
+ data_in.append(new_date_data)
+
+ temp_result = {}
+ temp_result['title_research'] = Researches.objects.get(pk=research).title
+ temp_result['result'] = data_in
+ result.append(temp_result)
+
+ return result
+
+
+def hosp_get_text_iss(directions):
+ v = []
+ v.extend(hosp_get_text(directions))
+ return v
+
+
+def forbidden_edit_dir(num_dir):
+ """
+ Проверяет подтверждена ли выписка, или переводной эпикриз. И возвращает True|False - для редактирвоания протколов
+ """
+ # (если услуга имеет тип is_doc_refferal, или is_paraclinic) и направление не имеет parent услугу типа hosp вернуть False
+ obj_iss = Issledovaniya.objects.filter(napravleniye_id=num_dir).first()
+ if obj_iss.research.is_gistology:
+ return False
+ parent = Napravleniya.objects.get(pk=num_dir).parent
+ if not parent and (obj_iss.research.is_doc_refferal or obj_iss.research.is_paraclinic):
+ return False
+
+ if parent:
+ parent_is_hospital = parent.research.is_hospital
+ if (obj_iss.research.is_doc_refferal or obj_iss.research.is_paraclinic) and not parent_is_hospital:
+ return False
+
+ hosp_nums_obj = hosp_get_hosp_direction(num_dir)
+ hosp_last_num = hosp_nums_obj[-1].get('direction') if hosp_nums_obj else None
+ if not hosp_last_num:
+ return False
+ hosp_extract = hosp_get_data_direction(hosp_last_num, site_type=7, type_service='None', level=2)
+ if hosp_extract and hosp_extract[0].get('date_confirm'):
+ return True
+
+ # if not hosp_extract or not hosp_extract[0].get('date_confirm'):
+ # # Проверить подтверждение переводного эпикриза
+ # # Получить hosp_dir для текужего направления
+ # current_iss = Issledovaniya.objects.get(napravleniye_id=num_dir)
+ # current_dir_hosp_dir = num_dir
+ # if not current_iss.research.is_hospital:
+ # current_dir_hosp_dir = hosp_get_curent_hosp_dir(current_iss.pk)
+ # # получить для текущего hosp_dir эпикриз с title - перевод.....
+ # epicrisis_data = hosp_get_data_direction(current_dir_hosp_dir, site_type=6, type_service='None', level=2)
+ # if epicrisis_data:
+ # result_check = check_transfer_epicrisis(epicrisis_data)
+ # return result_check['is_transfer']
+ return False
+
+
+def check_transfer_epicrisis(data):
+ for i in data:
+ if i.get("research_title").lower().find('перевод') != -1:
+ if i.get('date_confirm'):
+ return {'is_transfer': True, 'iss': i.get('iss'), 'research_id': i.get('research_id')}
+ return {'is_transfer': False, 'iss': None, 'research_id': None}
+
+
+def get_temperature_list(hosp_num_dir):
+ """
+ :param num_dir:
+ :return:
+ {
+ temperature: {data: [36.6, 36.7, 37.1 итд], xtext: ['21.01.20 13:30', '21.01.20 20:00', '22.01.20 12:10' итд],},
+ systolic: {data[], xtext :[]}, diastolic: {data[], xtext :[]},
+ pulse: {data[], xtext :[]}
+ }
+ """
+ # tl - temperature list
+ tl_objs = hosp_get_data_direction(hosp_num_dir, site_type=9, type_service='None', level=2)
+ tl_iss = [i['iss'] for i in tl_objs]
+ research_id = None
+ for i in tl_objs:
+ research_id = i['research_id']
+ break
+ if research_id is None:
+ return {}
+ final_data = {}
+ title_list = ['Температура', 'Пульс (уд/м)', 'Дата измерения', 'Время измерения', 'Систолическое давление (мм рт.с)', 'Диастолическое давление (мм рт.с)']
+ a = get_result_temperature_list(tl_iss, research_id, title_list)
+ data = {}
+ for i in a:
+ value = i[2]
+ field = i[3]
+ if field.lower().find('дата') != -1:
+ value = normalize_date(value)
+ in_data = {field: value}
+ key = i[1]
+ if not data.get(key):
+ data.update({key: {}})
+ t_data = data.get(key)
+ t_data.update(in_data)
+ data[key] = t_data
+
+ for k, v in data.items():
+ date_time = get_date_time_tl(v)
+ for title, value in v.items():
+ if not value or value == '0':
+ continue
+ if not final_data.get(title):
+ final_data[title] = {'data': [], 'xtext': []}
+ t_final_data = final_data.get(title)
+ t_data = t_final_data['data']
+ t_data.append(value)
+ t_xtext = t_final_data['xtext']
+ t_xtext.append(date_time)
+ final_data[title] = {'data': t_data, 'xtext': t_xtext}
+ final_data.pop('Дата измерения', None)
+ final_data.pop('Время измерения', None)
+ for k, v in final_data.items():
+ if 'температура' in k.lower() or 'давление' in k.lower() or 'пульс' in k.lower():
+ number_data = list(map(force_to_number, v['data']))
+ v['data'] = number_data
+ v['min_max'] = [min(number_data), max(number_data)]
+ final_data[k] = v
+ if 'Температура' in final_data:
+ final_data['Температура (°C)'] = final_data.pop('Температура')
+ return final_data
+
+
+def get_date_time_tl(dict_data):
+ import re
+
+ time = dict_data.get('Время измерения', 'Нет поля "Время измерения"')
+ date = dict_data.get('Дата измерения', 'Нет поля "Дата измерения"')
+ date = re.sub(r'.\d{4}', '', date)
+ return f'{date} {time}'
+
+
+def force_to_number(val):
+ return float(''.join(c for c in val if c.isdigit() or c == '.') or 0)
+
+
+def get_assignments(direction_id: int):
+ if direction_id is None:
+ return []
+ results = []
+ issledovanie_id = Issledovaniya.objects.get(napravleniye_id=direction_id).pk
+ assignments = get_assignments_by_history(issledovanie_id)
+ prev_directions_id = -1
+ for i in assignments:
+ if prev_directions_id != i.napravlenie_id:
+ who_assigned = i.who_assigned.split(" ")
+ family_assigned = who_assigned[0]
+ name_assigned = who_assigned[1][0]
+ patronymic_assigned = ""
+ if len(who_assigned) > 2:
+ patronymic_assigned = who_assigned[2][0]
+ tmp_res = {
+ "direction_id": i.napravlenie_id,
+ "research_id": [i.research_id],
+ "research_title": [f"{i.research_title}; "],
+ "create_date": i.data_sozdaniya.strftime("%d.%m.%Y"),
+ "who_assigned": f"{family_assigned} {name_assigned}.{patronymic_assigned}.",
+ "time_confirmation": "",
+ "who_confirm": "",
+ }
+ if i.total_confirmed:
+ who_confirm = i.who_confirm.split(" ")
+ family_confirm = who_confirm[0]
+ name_confirm = who_confirm[1][0]
+ patronymic_confirm = ""
+ if len(who_confirm) > 2:
+ patronymic_confirm = who_confirm[2][0]
+ tmp_res["time_confirmation"] = i.time_confirmation.strftime("%d.%m.%Y %H:%M")
+ tmp_res["who_confirm"] = f"{family_confirm} {name_confirm}.{patronymic_confirm}."
+ results.append(tmp_res)
+ else:
+ results[-1]["research_id"].append(i.research_id)
+ results[-1]["research_title"].append(f"{i.research_title}; ")
+ prev_directions_id = i.napravlenie_id
+ return results
diff --git a/api/cases/urls.py b/api/cases/urls.py
new file mode 100644
index 0000000000..7767b1b9e9
--- /dev/null
+++ b/api/cases/urls.py
@@ -0,0 +1,11 @@
+from django.urls import path
+
+from . import views
+
+urlpatterns = [
+ path('search', views.search),
+ path('hosp-services-by-type', views.hosp_services_by_type),
+ path('make-service', views.make_service),
+ path('directions-by-key', views.directions_by_key),
+ path('aggregate', views.aggregate),
+]
diff --git a/api/cases/views.py b/api/cases/views.py
new file mode 100644
index 0000000000..cdb7d1ff48
--- /dev/null
+++ b/api/cases/views.py
@@ -0,0 +1,279 @@
+import simplejson as json
+from django.contrib.auth.decorators import login_required
+from django.http import JsonResponse
+
+from api.cases.helpers import get_case_direction_tree
+from api.cases.stationar_func import (
+ hosp_get_lab_iss,
+ hosp_get_text_iss,
+)
+from clients.models import Card
+from directions.models import Issledovaniya, Napravleniya
+from directory.models import HospitalService
+from laboratory.decorators import group_required
+from appconf.manager import SettingManager
+from django.db.models import Q
+
+from laboratory.utils import strfdatetime
+from pharmacotherapy.models import ProcedureList
+
+
+@login_required
+@group_required('Врач параклиники', 'Врач консультаций')
+def search(request):
+ data = json.loads(request.body)
+ pk = int(data["q"])
+ if pk >= 4600000000000:
+ pk -= 4600000000000
+ pk //= 10
+ result = {"ok": False, "message": "Не найдено", "data": {}}
+ original_direction = None
+ original_view = None
+ need_to_open_original = False
+
+ for i in Issledovaniya.objects.filter(napravleniye__pk=pk, research__is_case=False):
+ direction: Napravleniya = i.napravleniye
+ if direction.parent_case:
+ if direction.parent_case.napravleniye_id:
+ if i.research.is_doc_refferal:
+ original_view = 'consultation'
+ elif i.research.is_paraclinic:
+ original_view = 'paraclinical'
+ elif i.research.podrazdeleniye and i.research.podrazdeleniye.p_type == 2:
+ original_view = 'laboratory'
+ elif i.research.is_microbiology:
+ original_view = 'morfology'
+ elif i.research.is_citology:
+ original_view = 'morfology'
+ elif i.research.is_gistology:
+ original_view = 'morfology'
+ if original_view:
+ original_direction = pk
+ need_to_open_original = True
+ pk = direction.parent_case.napravleniye_id
+ break
+
+ tree_direction = get_case_direction_tree(pk)
+ i: Issledovaniya
+ for i in Issledovaniya.objects.filter(napravleniye__pk=pk, research__is_case=True):
+ direction: Napravleniya = i.napravleniye
+ card: Card = direction.client
+ result["ok"] = True
+ result["message"] = ""
+ if direction.cancel:
+ result["message"] = "Направление было отменено"
+ forbidden_edit = False # make true for closed case
+ child_issledovaniye, child_research_title, child_direction = '', '', ''
+ for iss in tree_direction:
+ if i.pk == iss['parent_iss']:
+ child_issledovaniye = iss['issledovaniye']
+ iss_obj = Issledovaniya.objects.filter(pk=child_issledovaniye).first()
+ if iss_obj:
+ child_direction = iss_obj.napravleniye.pk
+ child_research_title = iss_obj.research.title
+ if not original_view:
+ if iss_obj.research.is_doc_refferal:
+ original_view = 'consultation'
+ elif iss_obj.research.is_paraclinic:
+ original_view = 'paraclinical'
+ elif iss_obj.research.podrazdeleniye and iss_obj.research.podrazdeleniye.p_type == 2:
+ original_view = 'laboratory'
+ elif iss_obj.research.is_microbiology:
+ original_view = 'morfology'
+ elif iss_obj.research.is_citology:
+ original_view = 'morfology'
+ elif iss_obj.research.is_gistology:
+ original_view = 'morfology'
+ break
+
+ if not child_research_title or child_research_title == '-1':
+ first_child: Napravleniya = Napravleniya.objects.filter(parent_case=i).order_by('id').first()
+ if first_child:
+ child_direction = first_child.pk
+ iss: Issledovaniya = first_child.issledovaniya_set.first()
+ if iss:
+ child_issledovaniye = iss.pk
+ child_research_title = iss.research.title
+
+ result["data"] = {
+ "direction": direction.pk,
+ "cancel": direction.cancel,
+ "fin_pk": direction.istochnik_f_id,
+ "iss": i.pk,
+ "parentIssledovaniye": direction.parent.pk if direction.parent else '-1',
+ "caseTitle": i.research.title,
+ "childResearch": None,
+ "forbiddenToEdit": forbidden_edit,
+ "originalDirection": {
+ 'id': original_direction or child_direction,
+ 'view': original_view,
+ 'open': need_to_open_original,
+ },
+ "patient": {
+ "fioWithAge": card.individual.fio(full=True),
+ "card": card.number_with_type(),
+ "base": card.base_id,
+ "cardPk": card.pk,
+ "individualPk": card.individual_id,
+ },
+ "tree": list(
+ map(
+ lambda dirc: {
+ **dirc,
+ "research_title": dirc["research_title"],
+ "isCurrent": int(dirc["direction"]) == pk,
+ "cancel": Napravleniya.objects.get(pk=dirc["direction"]).cancel,
+ "correct_level": dirc["correct_level"],
+ "color": dirc["color"],
+ "issledovaniye": dirc["issledovaniye"],
+ "order": dirc["order"],
+ },
+ tree_direction,
+ )
+ ),
+ "counts": {
+ 'laboratory': 0,
+ 'paraclinical': 0,
+ 'consultation': 0,
+ 'morfology': 0,
+ 'pharmacotherapy': 0,
+ 'all': 0,
+ },
+ }
+
+ if child_issledovaniye and child_direction and child_research_title:
+ result['data']['childResearch'] = {
+ "issledovaniye": child_issledovaniye,
+ "direction": child_direction,
+ "title": child_research_title,
+ }
+
+ for i in Issledovaniya.objects.filter(napravleniye__pk=pk, research__is_case=True).distinct():
+ result['data']['counts']["laboratory"] += Napravleniya.objects.filter(parent_case=i, issledovaniya__research__podrazdeleniye__p_type=2).distinct().count()
+ result['data']['counts']["paraclinical"] += Napravleniya.objects.filter(parent_case=i, issledovaniya__research__is_paraclinic=True).distinct().count()
+ result['data']['counts']["consultation"] += Napravleniya.objects.filter(parent_case=i, issledovaniya__research__is_doc_refferal=True).distinct().count()
+ result['data']['counts']["morfology"] += (
+ Napravleniya.objects.filter(parent_case=i)
+ .filter(Q(issledovaniya__research__is_microbiology=True) | Q(issledovaniya__research__is_citology=True) | Q(issledovaniya__research__is_gistology=True))
+ .distinct()
+ .count()
+ )
+ result['data']['counts']["pharmacotherapy"] = ProcedureList.objects.filter(history=i.napravleniye, cancel=False, diary__issledovaniya__time_confirmation__isnull=False).count()
+ result['data']['counts']["all"] += Napravleniya.objects.filter(parent_case=i).count()
+ break
+ return JsonResponse(result)
+
+
+@login_required
+@group_required('Врач параклиники', 'Врач консультаций')
+def hosp_services_by_type(request):
+ data = json.loads(request.body)
+ base_direction_pk = int(data["direction"] or 0)
+ r_type = data["r_type"]
+ result = []
+ type_by_key = HospitalService.TYPES_BY_KEYS.get(r_type, -1)
+ for i in Issledovaniya.objects.filter(napravleniye__pk=base_direction_pk, research__is_case=True):
+ hosp_research = i.research
+ if int(data['hospResearch']) > -1:
+ hosp_research = int(data['hospResearch'])
+ for hs in HospitalService.objects.filter(site_type=type_by_key, main_research=hosp_research, hide=False):
+ result.append(
+ {
+ "pk": hs.pk,
+ "title": hs.slave_research.title,
+ "short_title": hs.slave_research.short_title,
+ "main_title": hs.main_research.title,
+ }
+ )
+ return JsonResponse({"data": result})
+
+
+@login_required
+@group_required('Врач параклиники', 'Врач консультаций')
+def make_service(request):
+ data = json.loads(request.body)
+ main_direction = Napravleniya.objects.get(pk=data["main_direction"])
+ parent_iss = Issledovaniya.objects.filter(napravleniye=main_direction, research__is_case=True).first()
+ service = HospitalService.objects.get(pk=data["service"])
+ TADP = SettingManager.get("tadp", default='Температура', default_type='s')
+ if "Врач стационара" not in [str(x) for x in request.user.groups.all()] and TADP not in service.slave_research.title:
+ return JsonResponse({"pk": None})
+ result = Napravleniya.gen_napravleniya_by_issledovaniya(
+ main_direction.client_id,
+ "",
+ None,
+ "",
+ None,
+ request.user.doctorprofile,
+ {-1: [service.slave_research_id]},
+ {},
+ False,
+ {},
+ vich_code="",
+ count=1,
+ discount=0,
+ parent_iss=parent_iss.pk,
+ rmis_slot=None,
+ )
+ pk = result["list_id"][0]
+ return JsonResponse({"pk": pk})
+
+
+@login_required
+def directions_by_key(request):
+ data = json.loads(request.body)
+ pk = data["caseId"]
+ view = data["view"]
+ directions = Napravleniya.objects.filter(parent_case__napravleniye_id=pk)
+
+ if view == 'laboratory':
+ directions = directions.filter(issledovaniya__research__podrazdeleniye__p_type=2)
+ elif view == 'morfology':
+ directions = directions.filter(Q(issledovaniya__research__is_microbiology=True) | Q(issledovaniya__research__is_citology=True) | Q(issledovaniya__research__is_gistology=True))
+ elif view == 'paraclinical':
+ directions = directions.filter(issledovaniya__research__is_paraclinic=True)
+ elif view == 'consultation':
+ directions = directions.filter(issledovaniya__research__is_doc_refferal=True)
+
+ directions = directions.distinct().order_by('id')
+
+ return JsonResponse(
+ {
+ 'rows': [
+ {
+ 'pk': x.pk,
+ 'confirm': x.total_confirmed,
+ 'date_create': strfdatetime(x.data_sozdaniya_local, "%d.%m.%Y"),
+ 'researches_short': [y.short_title for y in x.services],
+ 'researches': [y.title for y in x.services],
+ 'showResults': x.issledovaniya_set.all().filter(research__podrazdeleniye__p_type=2).exists(),
+ }
+ for x in directions
+ ]
+ }
+ )
+
+
+@login_required
+def aggregate(request):
+ data = json.loads(request.body)
+ pk = data.get('caseDirection', -1)
+ view = data["view"]
+ directions = Napravleniya.objects.filter(parent_case__napravleniye_id=pk)
+
+ if view == 'laboratory':
+ directions = directions.filter(issledovaniya__research__podrazdeleniye__p_type=2)
+ elif view == 'morfology':
+ directions = directions.filter(Q(issledovaniya__research__is_microbiology=True) | Q(issledovaniya__research__is_citology=True) | Q(issledovaniya__research__is_gistology=True))
+ elif view == 'paraclinical':
+ directions = directions.filter(issledovaniya__research__is_paraclinic=True)
+ elif view == 'consultation':
+ directions = directions.filter(issledovaniya__research__is_doc_refferal=True)
+
+ directions = directions.distinct().order_by('id')
+
+ if view == 'laboratory':
+ result = hosp_get_lab_iss([x.pk for x in directions])
+ else:
+ result = hosp_get_text_iss([x.pk for x in directions])
+ return JsonResponse(result, safe=False)
diff --git a/api/directions/sql_func.py b/api/directions/sql_func.py
index 92ec4848fd..6c09ce96b1 100644
--- a/api/directions/sql_func.py
+++ b/api/directions/sql_func.py
@@ -21,6 +21,7 @@ def get_history_dir(d_s, d_e, card_id, who_create_dir, services, is_serv, iss_pk
directory_researches.is_paraclinic,
directory_researches.is_form,
directory_researches.is_microbiology,
+ directory_researches.is_case,
directory_researches.podrazdeleniye_id,
directions_napravleniya.parent_id as dir_parent_id,
directions_napravleniya.data_sozdaniya as dir_data_sozdaniya,
@@ -106,7 +107,8 @@ def get_history_dir(d_s, d_e, card_id, who_create_dir, services, is_serv, iss_pk
ud.patronymic,
directions_napravleniya.visit_date,
directions_napravleniya.time_microbiology_receive,
- directions_napravleniya.time_gistology_receive
+ directions_napravleniya.time_gistology_receive,
+ is_case
FROM t_iss_tubes
LEFT JOIN t_recive
ON t_iss_tubes.tubesregistration_id = t_recive.id_t_recive
@@ -505,3 +507,27 @@ def get_directions_meta_info(directions):
)
rows = namedtuplefetchall(cursor)
return rows
+
+
+def get_patient_open_case_data(card_pk, start_date, end_date):
+ with connection.cursor() as cursor:
+ cursor.execute(
+ """
+ SELECT
+ directions_issledovaniya.id as iss_id,
+ directions_issledovaniya.napravleniye_id,
+ directions_issledovaniya.research_id,
+ dr.title,
+ dr.is_case,
+ to_char(dn.data_sozdaniya AT TIME ZONE %(tz)s, 'DD.MM.YYYY') as date_create
+ FROM directions_issledovaniya
+ LEFT JOIN directory_researches dr on directions_issledovaniya.research_id = dr.id
+ LEFT JOIN directions_napravleniya dn on directions_issledovaniya.napravleniye_id = dn.id
+ WHERE dn.client_id = %(card_pk)s and dr.is_case = true and directions_issledovaniya.time_confirmation is Null and
+ dn.data_sozdaniya AT TIME ZONE %(tz)s BETWEEN %(d_start)s AND %(d_end)s
+ ORDER BY directions_issledovaniya.napravleniye_id
+ """,
+ params={'card_pk': card_pk, 'tz': TIME_ZONE, 'd_start': start_date, 'd_end': end_date},
+ )
+ rows = namedtuplefetchall(cursor)
+ return rows
diff --git a/api/directions/urls.py b/api/directions/urls.py
index 4a686f7b53..9e7adcb8eb 100644
--- a/api/directions/urls.py
+++ b/api/directions/urls.py
@@ -64,4 +64,5 @@
path('meta-info', views.meta_info),
path('resend-results', views.resend_results),
path('need-order-redirection', views.need_order_redirection),
+ path('patient-open-case', views.patient_open_case),
]
diff --git a/api/directions/views.py b/api/directions/views.py
index dc2792893d..4cec30e353 100644
--- a/api/directions/views.py
+++ b/api/directions/views.py
@@ -93,6 +93,7 @@
get_directions_by_user,
get_confirm_direction_by_hospital,
get_directions_meta_info,
+ get_patient_open_case_data,
)
from api.stationar.stationar_func import hosp_get_hosp_direction, hosp_get_text_iss
from forms.forms_func import hosp_get_operation_data
@@ -109,7 +110,6 @@ def directions_generate(request):
if request.method == "POST":
p = json.loads(request.body)
card_pk = p.get("card_pk")
- card = None
if card_pk == -1:
hospital: Hospitals = request.user.doctorprofile.get_hospital()
if hospital.client:
@@ -165,6 +165,8 @@ def directions_generate(request):
hospital_department_override=p.get("hospital_department_override", -1),
hospital_override=p.get("hospital_override", -1),
price_category=p.get("priceCategory", -1),
+ case_id=p.get("caseId", -2),
+ case_by_direction=p.get("caseByDirection", -2),
)
for _ in range(p.get("directions_count", 1)):
rc = Napravleniya.gen_napravleniya_by_issledovaniya(*args, **kwargs)
@@ -310,7 +312,7 @@ def directions_history(request):
# status: 4 - выписано пользователем, 0 - только выписанные, 1 - Материал получен лабораторией. 2 - результат подтвержден, 3 - направления пациента, -1 - отменено,
if req_status == 4:
user_creater = request.user.doctorprofile.pk
- if req_status in [0, 1, 2, 3, 5]:
+ if req_status in [0, 1, 2, 3, 5, 7]:
patient_card = pk
if req_status == 5:
@@ -436,6 +438,7 @@ def directions_history(request):
# is_slave_hospital, is_treatment, is_stom, is_doc_refferal, is_paraclinic, is_microbiology, parent_id, study_instance_uid, parent_slave_hosp_id, tube_number
researches_pks = []
researches_titles = ''
+ child_researches_titles = ''
last_dir, dir, status, date, cancel, pacs, has_hosp, has_descriptive = None, None, None, None, None, None, None, None
maybe_onco, is_application, is_expertise, expertise_status, can_has_pacs = False, False, False, False, False
@@ -459,6 +462,10 @@ def directions_history(request):
continue
elif type_service == 'is_lab' and (i[11] or i[14] or i[15] or i[16] or i[17] or i[18] or i[19]):
continue
+ elif req_status == 7 and not i[36]:
+ continue
+ elif i[36] and req_status != 7:
+ continue
if i[0] != last_dir:
status = min(status_set)
if len(lab) > 0:
@@ -470,12 +477,12 @@ def directions_history(request):
if aux_researches_obj.exists():
aux_researches = [{"pk": i.aux_research.pk, "title": i.aux_research.title} for i in aux_researches_obj]
has_aux = True
- if (req_status == 2 and status == 2) or (req_status in [3, 4] and status != -2) or (req_status == 1 and status == 1) or (req_status == 0 and status == 0):
+ if (req_status == 2 and status == 2) or (req_status in [3, 4, 7] and status != -2) or (req_status == 1 and status == 1) or (req_status == 0 and status == 0):
final_result.append(
{
'pk': dir,
'status': status,
- 'researches': researches_titles,
+ 'researches': f"{researches_titles} {child_researches_titles}",
"researches_pks": researches_pks,
"aux_researches": aux_researches,
"has_aux": has_aux,
@@ -498,6 +505,7 @@ def directions_history(request):
'register_number': register_number,
}
)
+ child_researches_titles = ""
person_contract_pk = -1
person_contract_dirs = ""
planed_doctor = ""
@@ -533,11 +541,27 @@ def directions_history(request):
has_hosp = True
lab = set()
+ if i[36] and req_status == 7:
+ case_child_direction = Napravleniya.objects.values_list("pk", flat=True).filter(parent_case__id=i[2])
+ case_childs = Issledovaniya.objects.filter(napravleniye_id__in=case_child_direction)
+ step = 0
+ for csh in case_childs:
+ ch_title = csh.research.short_title if csh.research.short_title else csh.research.title
+ if step != 0:
+ child_researches_titles = f"{child_researches_titles}; {ch_title}"
+ else:
+ child_researches_titles = f"{ch_title}"
+ step += 1
+
if researches_titles:
researches_titles = f'{researches_titles} | {i[5]}'
+ elif child_researches_titles:
+ researches_titles = f'{child_researches_titles} - {i[5]}'
else:
researches_titles = i[5]
+ child_researches_titles = ""
+
status_val = 0
has_descriptive = False
if i[8] or i[9] or i[33] or i[34] or i[35]:
@@ -581,12 +605,12 @@ def directions_history(request):
if aux_researches_obj.exists():
aux_researches = [{"pk": i.aux_research.pk, "title": i.aux_research.title} for i in aux_researches_obj]
has_aux = True
- if (req_status == 2 and status == 2) or (req_status in [3, 4] and status != -2) or (req_status == 1 and status == 1) or (req_status == 0 and status == 0):
+ if (req_status == 2 and status == 2) or (req_status in [3, 4, 7] and status != -2) or (req_status == 1 and status == 1) or (req_status == 0 and status == 0):
final_result.append(
{
'pk': dir,
'status': status,
- 'researches': researches_titles,
+ 'researches': f"{researches_titles} {child_researches_titles}",
"researches_pks": researches_pks,
"aux_researches": aux_researches,
"has_aux": has_aux,
@@ -1442,6 +1466,7 @@ def directions_paraclinic_form(request):
| Q(research__is_monitoring=True)
| Q(research__is_expertise=True)
| Q(research__is_aux=True)
+ | Q(research__is_case=True)
)
)
.select_related('research', 'research__microbiology_tube', 'research__podrazdeleniye')
@@ -4424,3 +4449,27 @@ def meta_info(request):
index_num = res_direction.index(i['direction'])
sort_result[index_num] = i
return JsonResponse({"rows": sort_result})
+
+
+@login_required
+def patient_open_case(request):
+ request_data = json.loads(request.body)
+ card_pk = request_data.get("card_pk", None)
+ data_case = []
+ date_start = datetime.now() - timedelta(days=60)
+ date_end = datetime.now()
+
+ if card_pk:
+ open_case = get_patient_open_case_data(card_pk, date_start, date_end)
+ data_case = []
+ for o_case in open_case:
+ n = Napravleniya.objects.filter(parent_case_id=o_case.iss_id).first()
+ iss = Issledovaniya.objects.filter(napravleniye=n).first()
+ if iss:
+ title = iss.research.short_title if iss.research.short_title else iss.research.title
+ else:
+ title = "Случай пустой"
+ data_case.append({"id": o_case.iss_id, "label": f"{title} от {o_case.date_create}"})
+
+ data = {"data": data_case}
+ return JsonResponse(data)
diff --git a/api/parse_file/views.py b/api/parse_file/views.py
index 1db48f9fda..66e833fde4 100644
--- a/api/parse_file/views.py
+++ b/api/parse_file/views.py
@@ -207,7 +207,7 @@ def gen_commercial_offer(request):
born_data = cells[born].split(" ")[0]
age = -1
if born_data != "None":
- age = age_for_year(born_data)
+ age = age_for_year(normalize_dots_date(born_data))
if "м" in cells[sex]:
adds_harmfull = CONTROL_AGE_MEDEXAM.get("м")
else:
diff --git a/api/patients/views.py b/api/patients/views.py
index 374cf1176c..eb6b8148c5 100644
--- a/api/patients/views.py
+++ b/api/patients/views.py
@@ -1533,7 +1533,7 @@ def load_anamnesis(request):
request_data = json.loads(request.body)
card = Card.objects.get(pk=request_data["card_pk"])
history = []
- for a in AnamnesisHistory.objects.filter(card=card).order_by('-pk'):
+ for a in AnamnesisHistory.objects.filter(card=card).order_by('-pk') if not request_data.get('skipHistory') else []:
history.append(
{
"pk": a.pk,
@@ -1549,6 +1549,9 @@ def load_anamnesis(request):
"text": card.anamnesis_of_life,
"history": history,
}
+ if request_data.get('withPatient'):
+ data['patient'] = card.get_fio_w_card()
+
return JsonResponse(data)
diff --git a/api/researches/views.py b/api/researches/views.py
index 89498f7d83..48c86a7b2e 100644
--- a/api/researches/views.py
+++ b/api/researches/views.py
@@ -177,6 +177,7 @@ def get_researches(request, last_used=False):
"treatment": r.is_treatment,
"is_hospital": r.is_hospital,
"is_form": r.is_form,
+ "is_case": r.is_case,
"is_application": r.is_application,
"stom": r.is_stom,
"need_vich_code": r.need_vich_code,
@@ -257,7 +258,6 @@ def get_researches(request, last_used=False):
result = {"researches": deps, "cnts": cnts}
else:
result = json.loads(result)
-
if hasattr(request, 'plain_response') and request.plain_response:
return result
return JsonResponse(result)
@@ -361,6 +361,8 @@ def researches_by_department(request):
q = DResearches.objects.filter(is_monitoring=True).order_by("title")
elif department_pk == -13:
q = DResearches.objects.filter(is_expertise=True).order_by("title")
+ elif department_pk == -14:
+ q = DResearches.objects.filter(is_case=True).order_by("title")
else:
q = DResearches.objects.filter(podrazdeleniye__pk=department_pk).order_by("title")
@@ -455,7 +457,7 @@ def researches_update(request):
if tube == -1:
tube = None
stationar_slave = is_simple and -500 >= department_pk > -600 and main_service_pk != 1
- desc = stationar_slave or department_pk in [-2, -3, -4, -5, -6, -7, -8, -9, -10, -11, -12, -13]
+ desc = stationar_slave or department_pk in [-2, -3, -4, -5, -6, -7, -8, -9, -10, -11, -12, -13, -14, -16]
if len(title) > 0 and (desc or Podrazdeleniya.objects.filter(pk=department_pk).exists()):
department = None if desc else Podrazdeleniya.objects.filter(pk=department_pk)[0]
res = None
@@ -484,6 +486,7 @@ def researches_update(request):
is_application=department_pk == -11,
is_monitoring=department_pk == -12,
is_expertise=department_pk == -13,
+ is_case=department_pk == -14,
is_slave_hospital=stationar_slave,
microbiology_tube_id=tube if department_pk == -6 else None,
site_type_id=site_type,
@@ -527,6 +530,7 @@ def researches_update(request):
res.is_application = department_pk == -11
res.is_monitoring = department_pk == -12
res.is_expertise = department_pk == -13
+ res.is_case = department_pk == -14
res.microbiology_tube_id = tube if department_pk == -6 else None
res.paraclinic_info = info
res.hide = hide
diff --git a/api/urls.py b/api/urls.py
index 6f362b41ee..d9b4676aa8 100644
--- a/api/urls.py
+++ b/api/urls.py
@@ -101,6 +101,7 @@
path('transfer-document/', include('api.transfer_document.urls')),
path('edit-forms/', include('api.edit_forms.urls')),
path('hospitals/', include('api.hospitals.urls')),
+ path('cases/', include('api.cases.urls')),
path('get-prices', views.get_prices),
path('get-price-data', views.get_price_data),
path('update-price', views.update_price),
diff --git a/api/views.py b/api/views.py
index 14e0e05ede..3f94593953 100644
--- a/api/views.py
+++ b/api/views.py
@@ -513,7 +513,7 @@ def departments(request):
data = {
"departments": deps,
"can_edit": can_edit,
- "types": [*[{"pk": str(x[0]), "title": x[1]} for x in Podrazdeleniya.TYPES if x[0] not in [8, 12] and en.get(x[0], True)], *more_types],
+ "types": [*[{"pk": str(x[0]), "title": x[1]} for x in Podrazdeleniya.TYPES if x[0] not in [8, 12, 16] and en.get(x[0], True)], *more_types],
}
if hasattr(request, 'plain_response') and request.plain_response:
return data
@@ -748,6 +748,7 @@ def fill_settings():
ret["extended_departments"][Podrazdeleniya.MORFOLOGY].append(
{"pk": Podrazdeleniya.MORFOLOGY + 3, "title": "Гистология", "type": Podrazdeleniya.MORFOLOGY, "extended": True, "e": Podrazdeleniya.MORFOLOGY}
)
+
try:
connections.close_all()
except Exception as e:
@@ -784,7 +785,7 @@ def directive_from(request):
data = []
hospital = request.user.doctorprofile.hospital
for dep in (
- Podrazdeleniya.objects.filter(p_type__in=(Podrazdeleniya.DEPARTMENT, Podrazdeleniya.HOSP, Podrazdeleniya.PARACLINIC), hospital__in=(hospital, None))
+ Podrazdeleniya.objects.filter(p_type__in=(Podrazdeleniya.DEPARTMENT, Podrazdeleniya.HOSP, Podrazdeleniya.PARACLINIC, Podrazdeleniya.CASE), hospital__in=(hospital, None))
.prefetch_related(
Prefetch(
'doctorprofile_set',
@@ -2657,7 +2658,7 @@ def update_price(request):
current_price.title = request_data["title"]
current_price.date_start = request_data["start"]
current_price.date_end = request_data["end"]
- if request_data.get("typePrice") == "Профосмотр":
+ if request_data.get("typePrice") == "Заказчик" or request_data.get("typePrice") == "Работодатель":
current_price.company_id = request_data["company"]
else:
hospital = Hospitals.objects.filter(pk=int(request_data["company"])).first()
diff --git a/appconf/manager.py b/appconf/manager.py
index c8a7484bd1..e75d69a538 100644
--- a/appconf/manager.py
+++ b/appconf/manager.py
@@ -168,6 +168,8 @@ def l2_modules() -> dict:
"price_customer",
"price_externel_performer",
"ftp",
+ "case",
+ "hide_show_count_param",
]
},
"consults_module": SettingManager.get("consults_module", default='false', default_type='b'),
@@ -214,6 +216,7 @@ def en():
12: SettingManager.get("directions_params", default='false', default_type='b'),
13: SettingManager.l2("applications"),
14: SettingManager.l2("monitorings"),
+ 16: SettingManager.l2("case"),
}
cache.set(k, simplejson.dumps(result), 60 * 60 * 8)
diff --git a/context_processors/utils.py b/context_processors/utils.py
index 01ecfb2789..fadd87f06c 100644
--- a/context_processors/utils.py
+++ b/context_processors/utils.py
@@ -29,7 +29,7 @@ def menu(request):
if request.user.is_authenticated and request.headers.get('X-Requested-With') != 'XMLHttpRequest':
groups = [str(x) for x in request.user.groups.all()] if hasattr(request.user, 'groups') else []
- k = f'menu:{VERSION}:{get_md5(";".join(groups))}:{SettingManager.l2_modules_md5_of_values()}:6'
+ k = f'menu:{VERSION}:{get_md5(";".join(groups))}:{SettingManager.l2_modules_md5_of_values()}:7'
data = cache.get(k)
if not data:
pages = [
@@ -117,6 +117,13 @@ def menu(request):
"access": ["Врач параклиники", "Врач консультаций", "Свидетельство о смерти-доступ"],
"module": "paraclinic_module",
},
+ {
+ "url": "/ui/case-control",
+ "title": "Случаи обслуживания",
+ "nt": False,
+ "access": ['Врач параклиники', 'Врач консультаций'],
+ "module": "l2_case",
+ },
{"url": '/ui/stationar', "title": "Стационар", "nt": False, "access": ["Врач стационара", "t, ad, p"], "module": "l2_hosp"},
{
"url": '/ui/plan-operations',
diff --git a/directions/admin.py b/directions/admin.py
index c07b3bc416..d539210d9c 100644
--- a/directions/admin.py
+++ b/directions/admin.py
@@ -47,6 +47,7 @@ class NapravleniyaAdmin(admin.ModelAdmin):
'parent',
'parent_auto_gen',
'parent_slave_hosp',
+ 'parent_case',
)
search_fields = (
'pk',
diff --git a/directions/models.py b/directions/models.py
index 8511df80b1..d5e49845bf 100644
--- a/directions/models.py
+++ b/directions/models.py
@@ -500,6 +500,9 @@ class Napravleniya(models.Model):
parent_slave_hosp = models.ForeignKey(
'Issledovaniya', related_name='parent_slave_hosp', help_text="Из стационарного протокола", db_index=True, blank=True, null=True, default=None, on_delete=models.SET_NULL
)
+ parent_case = models.ForeignKey(
+ 'Issledovaniya', related_name='parent_case', help_text="Случай основание", db_index=True, blank=True, null=True, default=None, on_delete=models.SET_NULL
+ )
rmis_slot_id = models.CharField(max_length=20, blank=True, null=True, default=None, help_text="РМИС слот")
microbiology_n = models.CharField(max_length=10, blank=True, default='', help_text="Номер в микробиологической лаборатории")
time_microbiology_receive = models.DateTimeField(null=True, blank=True, db_index=True, help_text='Дата/время приёма материала микробиологии')
@@ -784,6 +787,13 @@ def data_sozdaniya_local(self):
def visit_date_local(self):
return localtime(self.visit_date)
+ @property
+ def services(self) -> List[directory.Researches]:
+ result = []
+ for iss in self.issledovaniya_set.all().order_by('research__title'):
+ result.append(iss.research)
+ return result
+
def __str__(self):
return "%d для пациента %s (врач %s, выписал %s, %s, %s, %s, par: [%s])" % (
self.pk,
@@ -1043,6 +1053,7 @@ def gen_napravleniye(
parent_id=None,
parent_auto_gen_id=None,
parent_slave_hosp_id=None,
+ parent_case_id=None,
rmis_slot=None,
direction_purpose="NONE",
external_organization="NONE",
@@ -1088,6 +1099,7 @@ def gen_napravleniye(
parent_id=parent_id,
parent_auto_gen_id=parent_auto_gen_id,
parent_slave_hosp_id=parent_slave_hosp_id,
+ parent_case_id=parent_case_id,
rmis_slot_id=rmis_slot,
hospital=doc.hospital or Hospitals.get_default_hospital(),
external_order=external_order,
@@ -1279,12 +1291,22 @@ def gen_napravleniya_by_issledovaniya(
external_order: Optional[RegisteredOrders] = None,
services_by_additional_order_num=None,
price_name=None,
+ case_id=-2,
+ case_by_direction=False,
):
result = {"r": False, "list_id": [], "list_stationar_id": [], "messageLimit": ""}
+ if case_id > -1 and case_by_direction:
+ iss = Napravleniya.objects.get(pk=case_id).issledovaniya_set.all().first()
+ if iss:
+ case_id = iss.pk
+ else:
+ result["message"] = "Ошибка привязки к случаю"
+ return result
if not Clients.Card.objects.filter(pk=client_id).exists():
result["message"] = "Карта в базе не зарегистрирована, попробуйте выполнить поиск заново"
return result
pk_reseerches = []
+ issledovaniye_case_id = None
for v in researches.values():
pk_reseerches.extend(v)
card = Clients.Card.objects.get(pk=client_id)
@@ -1512,6 +1534,41 @@ def gen_napravleniya_by_issledovaniya(
result["message"] = "Данный мониторинг уже создан"
return result
+ if case_id > -2:
+ if case_id == -1:
+ napravleniye_case = Napravleniya.gen_napravleniye(
+ client_id,
+ doc_current if not for_rmis else None,
+ finsource,
+ diagnos,
+ history_num,
+ doc_current,
+ ofname_id,
+ ofname,
+ for_rmis=for_rmis,
+ rmis_data=rmis_data,
+ parent_id=parent_iss,
+ parent_auto_gen_id=parent_auto_gen,
+ parent_slave_hosp_id=parent_slave_hosp,
+ rmis_slot=rmis_slot,
+ direction_purpose=direction_purpose,
+ external_organization=external_organization,
+ price_category=price_category,
+ hospital=hospital_override,
+ external_order=external_order,
+ price_name_id=price_name,
+ )
+ research_case = directory.Researches.objects.filter(is_case=True, hide=False).first()
+ issledovaniye_case = Issledovaniya(
+ napravleniye=napravleniye_case,
+ research=research_case,
+ deferred=False
+ )
+ issledovaniye_case.save()
+ issledovaniye_case_id = issledovaniye_case.pk
+ elif case_id > 0:
+ issledovaniye_case_id = case_id
+
if (dir_group > -1 and dir_group not in directions_for_researches.keys()) or (dir_group == dir_group_onlylab and dir_group not in directions_for_researches.keys()):
directions_for_researches[dir_group] = Napravleniya.gen_napravleniye(
client_id,
@@ -1527,6 +1584,7 @@ def gen_napravleniya_by_issledovaniya(
parent_id=parent_iss,
parent_auto_gen_id=parent_auto_gen,
parent_slave_hosp_id=parent_slave_hosp,
+ parent_case_id=issledovaniye_case_id,
rmis_slot=rmis_slot,
direction_purpose=direction_purpose,
external_organization=external_organization,
@@ -1557,6 +1615,7 @@ def gen_napravleniya_by_issledovaniya(
parent_id=parent_iss,
parent_auto_gen_id=parent_auto_gen,
parent_slave_hosp_id=parent_slave_hosp,
+ parent_case_id=issledovaniye_case_id,
rmis_slot=rmis_slot,
direction_purpose=direction_purpose,
external_organization=external_organization,
diff --git a/directions/views.py b/directions/views.py
index 1607b5abc5..b646fcf1af 100644
--- a/directions/views.py
+++ b/directions/views.py
@@ -566,6 +566,7 @@ def print_direction(c: Canvas, n, dir: Napravleniya, format_a6: bool = False):
-9: 'Формы',
-11: 'Заявления',
-12: 'Мониторинги',
+ -14: 'Случай',
}[rtp]
# if rtp == -6:
# has_micro = True
diff --git a/directory/models.py b/directory/models.py
index 4a74e91b69..d5b744f8c7 100644
--- a/directory/models.py
+++ b/directory/models.py
@@ -82,6 +82,7 @@ class ResearchSite(models.Model):
(4, 'Микробиология'),
(7, 'Формы'),
(10, 'Мониторинги'),
+ (12, 'Случаи'),
)
site_type = models.SmallIntegerField(choices=TYPES, help_text="Тип раздела", db_index=True)
@@ -243,6 +244,7 @@ class Researches(models.Model):
is_monitoring = models.BooleanField(default=False, blank=True, help_text="Это мониторинг", db_index=True)
is_expertise = models.BooleanField(default=False, blank=True, help_text="Это экспертиза", db_index=True)
is_aux = models.BooleanField(default=False, blank=True, help_text="Это вспомогательный", db_index=True)
+ is_case = models.BooleanField(default=False, blank=True, help_text="Это случай", db_index=True)
site_type = models.ForeignKey(ResearchSite, default=None, null=True, blank=True, help_text='Место услуги', on_delete=models.SET_NULL, db_index=True)
need_vich_code = models.BooleanField(default=False, blank=True, help_text="Необходимость указания кода вич в направлении")
paraclinic_info = models.TextField(blank=True, default="", help_text="Если это параклиническое исследование - здесь указывается подготовка и кабинет")
@@ -330,6 +332,7 @@ def filter_type(t):
14: dict(is_application=True),
15: dict(is_monitoring=True),
16: dict(is_expertise=True),
+ 17: dict(is_case=True),
}
return ts.get(t + 1, {})
@@ -357,6 +360,8 @@ def reversed_type(self):
return -13
if self.is_microbiology or self.is_citology or self.is_gistology:
return 2 - Podrazdeleniya.MORFOLOGY
+ if self.is_case:
+ return -14
return self.podrazdeleniye_id or -2
@property
@@ -368,6 +373,7 @@ def desc(self):
or self.is_paraclinic
or self.is_microbiology
or self.is_hospital
+ or self.is_case
or self.is_citology
or self.is_gistology
or self.is_form
diff --git a/integration_framework/utils.py b/integration_framework/utils.py
index 0222da76b4..d14ab52783 100644
--- a/integration_framework/utils.py
+++ b/integration_framework/utils.py
@@ -226,7 +226,7 @@ def check_title_field(data, r):
def get_json_labortory_data(pk):
- result_protocol = get_laboratory_results_by_directions([pk])
+ result_protocol = get_laboratory_results_by_directions(tuple([pk]))
document = {}
confirmed_at = ""
date_reiceve = ""
diff --git a/l2-frontend/src/App.vue b/l2-frontend/src/App.vue
index d563f8eec2..215dd5e597 100644
--- a/l2-frontend/src/App.vue
+++ b/l2-frontend/src/App.vue
@@ -3,15 +3,18 @@
{{ anamnesisData.text || 'нет данных' }}+