Skip to content

Commit

Permalink
Merge pull request #4352 from mikhailprivalov/searchForStatistic
Browse files Browse the repository at this point in the history
pattern(model) statistic
  • Loading branch information
Wellheor1 authored Oct 7, 2024
2 parents 9188cd5 + c9b6533 commit 127f65b
Show file tree
Hide file tree
Showing 9 changed files with 255 additions and 9 deletions.
69 changes: 69 additions & 0 deletions api/reports/sql_func.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,72 @@ def report_buh_gistology(directions):

rows = namedtuplefetchall(cursor)
return rows


def get_pair_direction_iss(directions):
with connection.cursor() as cursor:
cursor.execute(
"""
SELECT
directions_issledovaniya.napravleniye_id as direction_id,
directions_issledovaniya.id as iss_id
FROM directions_issledovaniya
WHERE directions_issledovaniya.napravleniye_id in %(directions)s
ORDER BY directions_issledovaniya.napravleniye_id
""",
params={'directions': directions},
)

rows = namedtuplefetchall(cursor)
return rows


def get_simple_directions_for_hosp_stationar(iss_id):
with connection.cursor() as cursor:
cursor.execute(
"""
SELECT
directions_napravleniya.id as directionn_id
FROM directions_napravleniya
WHERE directions_napravleniya.parent_id in %(iss_id)s
""",
params={'iss_id': iss_id},
)

rows = namedtuplefetchall(cursor)
return rows


def get_field_results(directions, input_field, fraction_field):
with connection.cursor() as cursor:
cursor.execute(
"""
SELECT
dn.id as direction_id,
to_char(directions_issledovaniya.time_confirmation AT TIME ZONE %(tz)s, 'DD.MM.YYYY HH24:MI') AS time_confirm,
dp.value as input_value,
dpif.title as field_title,
dpif.statistic_pattern_param_id as input_static_param,
dr.value as fraction_value,
df.statistic_pattern_param_id as fraction_static_param
FROM directions_issledovaniya
LEFT JOIN directions_napravleniya dn on directions_issledovaniya.napravleniye_id = dn.id
LEFT JOIN directions_paraclinicresult dp on directions_issledovaniya.id = dp.issledovaniye_id
LEFT JOIN directory_paraclinicinputfield dpif on dp.field_id = dpif.id
LEFT JOIN directions_result dr on directions_issledovaniya.id = dr.issledovaniye_id
LEFT JOIN directory_fractions df on dr.fraction_id = df.id
WHERE directions_issledovaniya.napravleniye_id in %(directions)s
AND directions_issledovaniya.time_confirmation is not Null
AND ( dpif.id in %(input_field)s OR df.id in %(fraction_field)s
)
ORDER BY time_confirm
""",
params={'directions': directions, 'input_field': input_field, 'fraction_field': fraction_field, 'tz': TIME_ZONE},
)

rows = namedtuplefetchall(cursor)
return rows
1 change: 1 addition & 0 deletions api/reports/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@

urlpatterns = [
path('statistic-params-search', views.statistic_params_search),
path('xlsx-model', views.xlsx_model),
]
36 changes: 29 additions & 7 deletions api/reports/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,11 @@
from api.reports import structure_sheet
from api.reports import sql_func
from api.reports import handle_func

from api.reports.sql_func import get_pair_direction_iss, get_simple_directions_for_hosp_stationar, get_field_results
from directory.models import StatisticPatternParamSet, ParaclinicInputField, Fractions
from laboratory.settings import SEARCH_PAGE_STATISTIC_PARAMS
from django.http import JsonResponse
from django.contrib.auth.decorators import login_required


def statistic_params_search(request):
Expand Down Expand Up @@ -48,22 +51,41 @@ def statistic_params_search(request):
if not (correct_group_param and correct_group_research_id):
return response

symbols = (u"абвгдеёжзийклмнопрстуфхцчшщъыьэюяАБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ", u"abvgdeejzijklmnoprstufhzcss_y_euaABVGDEEJZIJKLMNOPRSTUFHZCSS_Y_EUA") # Словарь для транслитерации
symbols = ("абвгдеёжзийклмнопрстуфхцчшщъыьэюяАБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ", "abvgdeejzijklmnoprstufhzcss_y_euaABVGDEEJZIJKLMNOPRSTUFHZCSS_Y_EUA") # Словарь для транслитерации
tr = {ord(a): ord(b) for a, b in zip(*symbols)} # Перевод словаря для транслита

response = HttpResponse(content_type='application/ms-excel')
response = HttpResponse(content_type="application/ms-excel")
wb = openpyxl.Workbook()
wb.remove(wb.get_sheet_by_name('Sheet'))
ws = wb.create_sheet('лист1')
wb.remove(wb.get_sheet_by_name("Sheet"))
ws = wb.create_sheet("лист1")

directions_data = tuple(list(set(directions)))
if param == '1':
if param == "1":
result = sql_func.report_buh_gistology(directions_data)
final_structure = handle_func.patologistology_buh(result)
ws = structure_sheet.patologistology_buh_base(ws)
ws = structure_sheet.patologistology_buh_data(ws, final_structure)

title = "отчет"
response['Content-Disposition'] = str.translate(f"attachment; filename=\"{title}.xlsx\"", tr)
response["Content-Disposition"] = str.translate(f'attachment; filename="{title}.xlsx"', tr)
wb.save(response)
return response


@login_required
def xlsx_model(request):
result_directions = None
if request.method == "POST":
data = json.loads(request.body)
directions = data.get("directions")
id_model = data.get("idModel")

sql_pair_direction_iss = {i.iss_id: i.direction_id for i in get_pair_direction_iss(tuple(directions))}
sql_simple_directions = [i.direction_id for i in get_simple_directions_for_hosp_stationar(tuple(sql_pair_direction_iss.keys()))]

statistic_param_data = StatisticPatternParamSet.get_statistic_param(id_model)
input_field_statistic_param = ParaclinicInputField.get_field_input_by_pattern_param(list(statistic_param_data.keys()))
laboratory_fractions_statistic_param = Fractions.get_fraction_id_by_pattern_param(list(statistic_param_data.keys()))
result_directions = get_field_results(tuple(sql_simple_directions), tuple(input_field_statistic_param), tuple(laboratory_fractions_statistic_param))

return JsonResponse({"results": "file-xls-model", "link": "open-xls", "result": result_directions})
1 change: 1 addition & 0 deletions api/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@
path('current-time', views.current_time),
path('search-param', views.search_param),
path('statistic-params-search', views.statistic_params_search),
path('statistic-pattern-search', views.statistic_pattern_search),
path('analyzers/', include('api.analyzers.urls')),
path('chambers/', include('api.chambers.urls')),
path('researches/', include('api.researches.urls')),
Expand Down
20 changes: 18 additions & 2 deletions api/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from api.models import ManageDoctorProfileAnalyzer, Analyzer
from cash_registers.models import Shift
from directions.views import create_case_by_cards
from directory.models import Researches, SetResearch, SetOrderResearch, PatientControlParam
from directory.models import Researches, SetResearch, SetOrderResearch, PatientControlParam, StatisticPattern
from doctor_schedule.models import ScheduleResource
from ecp_integration.integration import get_reserves_ecp, get_slot_ecp
from laboratory.settings import (
Expand All @@ -28,7 +28,6 @@
USE_TFOMS_DISTRICT,
TYPE_COMPANY_SET_DIRECTION_PDF,
MEDEXAM_FIN_SOURCE_TITLE,
EXCLUDE_TYPE_RESEARCH,
)
from utils.response import status_response

Expand Down Expand Up @@ -2659,6 +2658,23 @@ def statistic_params_search(request):
return JsonResponse({"rows": result, "hasParam": has_param})


def statistic_pattern_search(request):
user_groups = [str(x) for x in request.user.groups.all()]
result = []
su = request.user.is_superuser

statistic_pattern = StatisticPattern.objects.filter(hide=False)
statistic_pattern_result = [{"id": i.pk, "label": i.title} for i in statistic_pattern]
if su:
result.extend(statistic_pattern_result)
else:
for el in statistic_pattern_result:
if el.get("title") in user_groups:
result.extend(el)

return JsonResponse({"rows": result})


@login_required
@group_required("Конструктор: Настройка организации")
def get_prices(request):
Expand Down
4 changes: 4 additions & 0 deletions directions/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -2587,6 +2587,10 @@ def allow_reset_confirm(self, user: User):
ctime - ctp < rt and (current_doc_confirmation == user.doctorprofile or (executor_confirmation is not None and executor_confirmation == user.doctorprofile))
) or "Сброс подтверждений результатов" in groups

@staticmethod
def get_iss_id_by_directions(directions):
return list(Issledovaniya.objects.filter(napravleniye_id__in=directions).values_list("pk", flat=True))

class Meta:
verbose_name = 'Назначение на исследование'
verbose_name_plural = 'Назначения на исследования'
Expand Down
27 changes: 27 additions & 0 deletions directory/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,30 @@ class SetComplexService(admin.ModelAdmin):
)


class ResPatternParam(admin.ModelAdmin):
list_display = (
'title',
'is_dynamic_param',
'order',
)
list_display_links = (
'title',
'is_dynamic_param',
'order',
)


class ResStatisticPattern(admin.ModelAdmin):
list_display = (
'title',
'hide',
)
list_display_links = (
'title',
'hide',
)


admin.site.register(models.ResearchSite, RefSiteType)
admin.site.register(models.ResearchGroup)
admin.site.register(models.Researches, ResAdmin)
Expand Down Expand Up @@ -338,6 +362,9 @@ class SetComplexService(admin.ModelAdmin):
admin.site.register(models.AuxService, SetAuxService)
admin.site.register(models.ComplexService, SetComplexService)
admin.site.register(models.ParaclinicTemplateNameDepartment, ResParaclinicTemplateDepartment)
admin.site.register(models.PatternParam, ResPatternParam)
admin.site.register(models.StatisticPattern, ResStatisticPattern)
admin.site.register(models.StatisticPatternParamSet)
admin.site.register(models.LaboratoryMaterial)
admin.site.register(models.SubGroupDirectory)
admin.site.register(models.SubGroupPadrazdeleniye)
54 changes: 54 additions & 0 deletions directory/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -1055,6 +1055,49 @@ def change_service_hidden(complex_id: int, service_id: int):
return {"ok": True, "hide": service_in_complex.hide}


class StatisticPattern(models.Model):
title = models.CharField(max_length=400, unique=True, help_text="Название стастической модели данных")
hide = models.BooleanField(default=False, blank=True, help_text="Скрытие модели", db_index=True)

def __str__(self):
return f"{self.title}"

class Meta:
verbose_name = "Статистическая модель данных"
verbose_name_plural = "Статистические модели"


class PatternParam(models.Model):
title = models.CharField(max_length=400, unique=True, help_text="Название название стастического параметра параметра")
code = models.CharField(max_length=400, help_text="Код параметра")
is_dynamic_param = models.BooleanField(default=False, blank=True, help_text="Динамический параметр", db_index=True)
order = models.IntegerField(default=-1)

def __str__(self):
return f"{self.title} - {self.code}"

class Meta:
verbose_name = "Статистическая модель - параметр"
verbose_name_plural = "Статистическая модель - параметры "


class StatisticPatternParamSet(models.Model):
statistic_pattern = models.ForeignKey(StatisticPattern, default=None, null=True, blank=True, help_text="Статистическая модель", on_delete=models.CASCADE)
statistic_param = models.ForeignKey(PatternParam, default=None, null=True, blank=True, help_text="Параметр статистическая модель отчет", on_delete=models.CASCADE)

def __str__(self):
return f"{self.statistic_pattern} - {self.statistic_param}"

class Meta:
verbose_name = "Статистическая модель - связь с параметром"
verbose_name_plural = "Статистическая модель - связи с параметром"

@staticmethod
def get_statistic_param(statistic_pattern_id):
params = StatisticPatternParamSet.objects.filter(statistic_pattern_id=statistic_pattern_id)
return {p.statistic_param_id: {"title": p.statistic_param.title, "isDynamic": p.statistic_param.is_dynamic_param} for p in params}


class ParaclinicInputGroups(models.Model):
title = models.CharField(max_length=255, help_text="Название группы")
show_title = models.BooleanField()
Expand All @@ -1064,6 +1107,7 @@ class ParaclinicInputGroups(models.Model):
visibility = models.TextField(default="", blank=True)
fields_inline = models.BooleanField(default=False, blank=True)
cda_option = models.ForeignKey("external_system.CdaFields", default=None, null=True, blank=True, help_text="CDA-поле для всей группы", on_delete=models.SET_NULL)
statistic_pattern_param = models.ForeignKey(PatternParam, default=None, null=True, blank=True, help_text="Статистический параметр", on_delete=models.SET_NULL)

def __str__(self):
return f"{self.research.title}{self.title}"
Expand Down Expand Up @@ -1158,6 +1202,7 @@ class ParaclinicInputField(models.Model):
short_title = models.CharField(max_length=400, default="", blank=True, help_text="Синоним-короткое название поля ввода")
group = models.ForeignKey(ParaclinicInputGroups, on_delete=models.CASCADE)
patient_control_param = models.ForeignKey(PatientControlParam, default=None, null=True, blank=True, help_text="Контролируемый параметр", on_delete=models.SET_NULL)
statistic_pattern_param = models.ForeignKey(PatternParam, default=None, null=True, blank=True, help_text="Статистический параметр", on_delete=models.SET_NULL)
order = models.IntegerField()
default_value = models.TextField(blank=True, default="")
input_templates = models.TextField()
Expand Down Expand Up @@ -1202,6 +1247,10 @@ def get_title(self, force_type=None, recursive=False):
title = ", ".join([t for t in titles if t])
return title

@staticmethod
def get_field_input_by_pattern_param(pattern_params):
return list(ParaclinicInputField.objects.filter(statistic_pattern_param_id__in=pattern_params).values_list("pk", flat=True))

def __str__(self):
return f"{self.group.research.title} - {self.group.title} - {self.title}"

Expand Down Expand Up @@ -1429,6 +1478,7 @@ class Fractions(models.Model):
not_send_odli = models.BooleanField(help_text="Не отправлять данные в ОДЛИ", default=False)
ecp_id = models.CharField(max_length=16, default="", blank=True, verbose_name="Код теста в ЕЦП")
external_code = models.CharField(max_length=255, default="", help_text="Внешний код теста", blank=True, db_index=True)
statistic_pattern_param = models.ForeignKey(PatternParam, default=None, null=True, blank=True, help_text="Статистический параметр модели", on_delete=models.SET_NULL)

def get_unit(self):
if self.unit:
Expand Down Expand Up @@ -1544,6 +1594,10 @@ def change_relation_tube(fraction_ids, old_tube_relation, new_tube_relation):
f.save()
return True

@staticmethod
def get_fraction_id_by_pattern_param(pattern_params):
return list(Fractions.objects.filter(statistic_pattern_param_id__in=pattern_params).values_list("pk", flat=True))


class Absorption(models.Model):
"""
Expand Down
Loading

0 comments on commit 127f65b

Please sign in to comment.