diff --git a/app.py b/app.py
index dd172e5..2288050 100644
--- a/app.py
+++ b/app.py
@@ -2,16 +2,12 @@ import gi
import os
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, GObject, Gdk
-from mods.db import Patient, Reception, store_patient_index, update_patient_index, search_patients, db
-from datetime import date, datetime, timedelta, time
+from mods.db import store_patient_index, update_patient_index, search_patients, dbo
+from mods.settings import s_get_reception_list, s_set_reception_list
+from mods.catalogs import add_catalog
+from datetime import date, datetime, timedelta
import peewee
-# FIXME: временно
-DAY_START = time(8,0)
-DAY_END = time(13,0)
-TIME_INTERVAL = timedelta(minutes=30)
-#
-
gender_dict = {
'male': 'Мужской',
'female': 'Женский'
@@ -30,10 +26,14 @@ new_patient_win_file = os.path.join(ui_dir, 'new_patient_win.glade')
open_patient_win_file = os.path.join(ui_dir, 'open_patient_win.glade')
edit_patient_win_file = os.path.join(ui_dir, 'edit_patient_win.glade')
male_patient_row_file = os.path.join(ui_dir, 'male_patient_row.glade')
+reception_list_settings_win_file = os.path.join(ui_dir, 'reception_list_settings.glade')
female_patient_row_file = os.path.join(ui_dir, 'female_patient_row.glade')
reception_row_file = os.path.join(ui_dir, 'reception_row.glade')
with open(reception_row_file, 'r') as f:
reception_row_ui_str = f.read()
+catalog_row_file = os.path.join(ui_dir, 'catalog_list_row.glade')
+with open(catalog_row_file, 'r') as f:
+ catalog_row_ui_str = f.read()
gender_ui_str = {}
with open(male_patient_row_file, 'r') as f:
gender_ui_str['male'] = f.read()
@@ -44,11 +44,12 @@ with open(female_patient_row_file, 'r') as f:
builder = Gtk.Builder()
def get_reception_timelist(rec_date):
- dstart = datetime(rec_date.year, rec_date.month, rec_date.day, DAY_START.hour, DAY_START.minute)
- dend = datetime(rec_date.year, rec_date.month, rec_date.day, DAY_END.hour, DAY_END.minute)
+ s = s_get_reception_list()
+ dstart = datetime(rec_date.year, rec_date.month, rec_date.day, s.day_start[0], s.day_start[1])
+ dend = datetime(rec_date.year, rec_date.month, rec_date.day, s.day_end[0], s.day_end[1])
work_day_minutes_total = (dend.hour - dstart.hour) * 60 + dend.minute - dstart.minute
- shift_minutes_range = range(0, work_day_minutes_total, int(TIME_INTERVAL.seconds / 60))
- return [(dstart + timedelta(minutes=x)).time() for x in shift_minutes_range]
+ shift_minutes_range = range(0, work_day_minutes_total, s.interval)
+ return [dstart + timedelta(minutes=x) for x in shift_minutes_range]
class PatientFilter:
def __init__(self):
@@ -103,9 +104,31 @@ class ReceptionRow(Gtk.ListBoxRow):
def scheduled_setter(self, value):
self._scheduled = value
+class CatalogRow(Gtk.ListBoxRow):
+ @GObject.Property
+ def db_id(self):
+ return self._db_id
+ @db_id.setter
+ def db_id_setter(self, value):
+ self._db_id = value
+
class MainWinHandler:
def main_win_close(self, *args):
Gtk.main_quit()
+ def set_reception_list_today(self, *a):
+ cal = builder.get_object('reception_cal')
+ d = datetime.now()
+ cal.select_month(d.month - 1, d.year)
+ cal.select_day(d.day)
+ redraw_reception_list(d)
+ def change_reception_list_day(self, *a):
+ cal = builder.get_object('reception_cal')
+ cal_date = cal.get_date()
+ d = datetime(cal_date.year, cal_date.month + 1, cal_date.day)
+ redraw_reception_list(d)
+ def show_reception_list_settings_win(self, button):
+ reception_list_settings_win = create_reception_list_settings_win()
+ reception_list_settings_win.show_all()
def show_new_patient_win(self, button):
new_patient_win = create_new_patient_win()
new_patient_win.show_all()
@@ -138,6 +161,18 @@ class MainWinHandler:
pl.add(build_patient_row(p))
pl.show_all()'''
+def build_catalog_row(catalog):
+ b = Gtk.Builder()
+ b.add_from_string(catalog_row_ui_str)
+ win = b.get_object('win')
+ box = b.get_object('catalog_box')
+ b.get_object('name').set_text(catalog.name)
+ row = CatalogRow()
+ row.props.db_id = catalog.id
+ win.remove(win.get_children()[0])
+ row.add(box)
+ return row
+
def build_reception_row(reception_datetime):
b = Gtk.Builder()
b.add_from_string(reception_row_ui_str)
@@ -145,10 +180,12 @@ def build_reception_row(reception_datetime):
box = b.get_object('reception_box')
b.get_object('hour').set_text(reception_datetime.strftime('%H'))
b.get_object('minute').set_text(reception_datetime.strftime('%M'))
- reception = Reception.select().where(Reception.time == reception_datetime)
+ with dbo.db.atomic():
+ reception = dbo._Reception.select().where(dbo._Reception.time == reception_datetime) # @UndefinedVariable
row = ReceptionRow()
if len(reception):
row.props.scheduled = True
+ row.props.db_id = reception.id
reception_cont = b.get_object('reception_cont')
reception_cont.props.border_width = 2
reception_cont.override_background_color(Gtk.StateFlags(0), Gdk.RGBA(red=0.5, green=0.7, blue=0.5, alpha=1.0))
@@ -194,8 +231,11 @@ def patient_filter_func(row):
def redraw_reception_list(selected_date):
reception_timelist = get_reception_timelist(selected_date)
reception_list = builder.get_object('reception_list')
+ for c in reception_list.get_children():
+ reception_list.remove(c)
for d in reception_timelist:
reception_list.add(build_reception_row(d))
+ reception_list.show_all()
builder.add_from_file(main_win_file)
builder.connect_signals(MainWinHandler())
@@ -205,9 +245,15 @@ redraw_reception_list(datetime.now())
patient_list = builder.get_object('patient_list')
patient_list.set_sort_func(patient_sort_func)
patient_list.set_filter_func(patient_filter_func)
-with db.atomic():
- for p in Patient.select():
+with dbo.db.atomic():
+ for p in dbo._Patient.select(): # @UndefinedVariable
patient_list.add(build_patient_row(p))
+#####
+catalog_list = builder.get_object('catalog_list')
+
+with dbo.db.atomic():
+ for c in dbo._Catalog.select(): # @UndefinedVariable
+ catalog_list.add(build_catalog_row(c))
def show_msg(text, sec_text='', level='info'):
msg_win_file = os.path.join(ui_dir, f'{level}_win.glade')
@@ -267,8 +313,9 @@ def get_patient_win_values(b):
'snils_number': snils_number,
'notes': notes
}
-def set_patient_values(patient_id, b, edit=False):
- pat = Patient.select().where(Patient.id == patient_id).get()
+def set_patient_win_values(patient_id, b, edit=False):
+ with dbo.db.atomic():
+ pat = dbo._Patient.select().where(dbo._Patient.id == patient_id).get() # @UndefinedVariable
b.get_object('last_name').set_text(pat.last_name)
b.get_object('first_name').set_text(pat.first_name)
b.get_object('middle_name').set_text(pat.middle_name)
@@ -305,7 +352,7 @@ def create_open_patient_win(patient_id):
w = b.get_object('open_patient_window')
# db_id = b.get_object('db_id')
# db_id.set_text(str(patient_id))
- set_patient_values(patient_id, b)
+ set_patient_win_values(patient_id, b)
return w
def create_edit_patient_win(patient_id):
@@ -323,12 +370,12 @@ def create_edit_patient_win(patient_id):
values = get_patient_win_values(b)
if not values:
return
- with db.atomic():
+ with dbo.db.atomic():
try:
- Patient.update(**values).where(Patient.id == patient_id).execute()
+ dbo._Patient.update(**values).where(dbo._Patient.id == patient_id).execute() # @UndefinedVariable
except peewee.IntegrityError:
return show_msg('Данный пациент уже существует', 'Другой пациент с указанными фамилией, именем\nи датой рождения уже есть с базе данных', level='warn')
- patient = Patient.select().where(Patient.id == patient_id).get()
+ patient = dbo._Patient.select().where(dbo._Patient.id == patient_id).get() # @UndefinedVariable
update_patient_index(patient)
cur_row = list(filter(lambda x: x.props.db_id == patient_id, patient_list.get_children()))[0]
patient_list.remove(cur_row)
@@ -340,7 +387,7 @@ def create_edit_patient_win(patient_id):
b.add_from_file(edit_patient_win_file)
b.connect_signals(EditPatientWinHandler())
w = b.get_object('edit_patient_window')
- set_patient_values(patient_id, b, edit=True)
+ set_patient_win_values(patient_id, b, edit=True)
return w
def create_new_patient_win():
@@ -354,9 +401,9 @@ def create_new_patient_win():
values = get_patient_win_values(b)
if not values:
return
- with db.atomic():
+ with dbo.db.atomic():
try:
- patient = Patient.create(**values)
+ patient = dbo._Patient.create(**values) # @UndefinedVariable
except peewee.IntegrityError:
return show_msg('Данный пациент уже существует', 'Пациент с указанными фамилией, именем\nи датой рождения уже есть с базе данных', level='warn')
store_patient_index(patient)
@@ -370,6 +417,29 @@ def create_new_patient_win():
w = b.get_object('new_patient_window')
return w
+def create_reception_list_settings_win():
+ b = Gtk.Builder()
+ class ReceptionListSettingsHandler:
+ def save_settings(self, *a):
+ start_hour = int(b.get_object('start_hour').get_value())
+ start_minute = int(b.get_object('start_minute').get_value())
+ end_hour = int(b.get_object('end_hour').get_value())
+ end_minute = int(b.get_object('end_minute').get_value())
+ interval = int(b.get_object('interval').get_value())
+ s_set_reception_list([start_hour, start_minute], [end_hour, end_minute], interval)
+ redraw_reception_list(datetime.now())
+ b.get_object('reception_list_settings_win').close()
+ b.add_from_file(reception_list_settings_win_file)
+ b.connect_signals(ReceptionListSettingsHandler())
+ s = s_get_reception_list()
+ b.get_object('start_hour').set_value(s.day_start[0])
+ b.get_object('start_minute').set_value(s.day_start[1])
+ b.get_object('end_hour').set_value(s.day_end[0])
+ b.get_object('end_minute').set_value(s.day_end[1])
+ b.get_object('interval').set_value(s.interval)
+ w = b.get_object('reception_list_settings_win')
+ return w
+
main_win = builder.get_object('main_window')
main_win.show_all()
Gtk.main()
diff --git a/mods/db.py b/mods/db.py
index faef363..a5ea089 100644
--- a/mods/db.py
+++ b/mods/db.py
@@ -1,6 +1,6 @@
import os
-from peewee import Model, CharField, BigAutoField, DateTimeField, IntegerField, fn, Field, Expression, TextField, ForeignKeyField, DateField, TimeField
-from playhouse.sqlite_ext import CSqliteExtDatabase, FTS5Model, AutoIncrementField, SearchField, RowIDField
+from peewee import Model, CharField, DateTimeField, TextField, ForeignKeyField, DateField
+from playhouse.sqlite_ext import CSqliteExtDatabase, FTS5Model, AutoIncrementField, SearchField, RowIDField, JSONField
var_dir = os.path.join(os.path.abspath(os.environ['HOME']), '.eldoc')
db_dir = os.path.join(var_dir, 'db')
@@ -11,98 +11,121 @@ if not os.path.exists(var_dir):
if not os.path.exists(db_dir):
os.mkdir(db_dir)
-db = CSqliteExtDatabase(db_file, pragmas={
- 'journal_mode': 'wal',
- 'cache_size': -1 * 64000, # 64MB
- 'foreign_keys': 'on',
- 'ignore_check_constraints': 'off',
- 'synchronous': 'off'})
-
-class BaseModel(Model):
- 'Базовая таблица'
- class Meta:
- database = db
-class BaseFTSModel(FTS5Model):
- class Meta:
- database = db
- options = {'tokenize': 'porter'}
-
-class Patient(BaseModel):
- id = AutoIncrementField()
- last_name = TextField()
- first_name = TextField()
- middle_name = TextField(null=True)
- birth_date = DateField()
- gender = CharField(6)
- doc_type = CharField(32, null=True)
- doc_serial = TextField(null=True)
- doc_number = TextField(null=True)
- policy_number = TextField(null=True)
- policy_company = TextField(null=True)
- snils_number = TextField(null=True)
- notes = TextField(null=True)
-Patient.add_index(
- Patient.index(Patient.last_name, Patient.first_name, Patient.birth_date, unique=True)
- )
-class Reception(BaseModel):
- id = AutoIncrementField()
- patient = ForeignKeyField(Patient, backref='receptions', on_delete='CASCADE')
- time = DateTimeField()
-class Diagnosis(BaseModel):
- id = AutoIncrementField()
- code = CharField()
- title = TextField()
- description = TextField(null=True)
-class ReceptionDiagnosis(BaseModel):
- id = AutoIncrementField()
- reception = ForeignKeyField(Reception, backref='reception_diagnosisses', on_delete='CASCADE')
- diagnosis = ForeignKeyField(Diagnosis, backref='reception_diagnosisses', on_delete='CASCADE')
-class ReceptionAnamnesis(BaseModel):
- id = AutoIncrementField()
- reception = ForeignKeyField(Reception, backref='reception_anamnesisses', on_delete='CASCADE')
- text = TextField()
-class AnamnesisTemplate(BaseModel):
- id = AutoIncrementField()
- text = TextField()
-class PatientIndex(BaseFTSModel):
- rowid = RowIDField()
- fio = SearchField()
+class DBO:
+ def __init__(self):
+ self.db = CSqliteExtDatabase(db_file, pragmas={
+ 'journal_mode': 'wal',
+ 'cache_size': -1 * 64000, # 64MB
+ 'foreign_keys': 'on',
+ 'ignore_check_constraints': 'off',
+ 'synchronous': 'off'})
+ class BaseModel(Model):
+ 'Базовая таблица'
+ class Meta:
+ database = self.db
+ class BaseFTSModel(FTS5Model):
+ class Meta:
+ database = self.db
+ options = {'tokenize': 'porter'}
+ class Patient(BaseModel):
+ id = AutoIncrementField()
+ last_name = TextField()
+ first_name = TextField()
+ middle_name = TextField(null=True)
+ birth_date = DateField()
+ gender = CharField(6)
+ doc_type = CharField(32, null=True)
+ doc_serial = TextField(null=True)
+ doc_number = TextField(null=True)
+ policy_number = TextField(null=True)
+ policy_company = TextField(null=True)
+ snils_number = TextField(null=True)
+ notes = TextField(null=True)
+ class Catalog(BaseModel):
+ id = AutoIncrementField()
+ system_id = TextField(null=True)
+ name = TextField()
+ class CatalogRecord(BaseModel):
+ id = AutoIncrementField()
+ catalog = ForeignKeyField(Catalog, backref='catalog_records', on_delete='CASCADE')
+ text = TextField()
+ class CatalogRecordIndex(BaseFTSModel):
+ rowid = RowIDField()
+ text = SearchField()
+ class Reception(BaseModel):
+ id = AutoIncrementField()
+ patient = ForeignKeyField(Patient, backref='receptions', on_delete='CASCADE')
+ time = DateTimeField()
+ class ReceptionDiagnosis(BaseModel):
+ id = AutoIncrementField()
+ reception = ForeignKeyField(Reception, backref='reception_diagnosisses', on_delete='CASCADE')
+ diagnosis = ForeignKeyField(CatalogRecord, backref='reception_diagnosisses', on_delete='CASCADE')
+ class ReceptionAnamnesis(BaseModel):
+ id = AutoIncrementField()
+ reception = ForeignKeyField(Reception, backref='reception_anamnesisses', on_delete='CASCADE')
+ text = TextField()
+ class PatientIndex(BaseFTSModel):
+ rowid = RowIDField()
+ fio = SearchField()
+ ### Настройки
+ class Settings(BaseModel):
+ key = TextField()
+ val = JSONField()
+ ###
+ self._Patient = Patient
+ self._Catalog = Catalog
+ self._CatalogRecord = CatalogRecord
+ self._CatalogRecordIndex = CatalogRecordIndex
+ self._Reception = Reception
+ self._ReceptionDiagnosis = ReceptionDiagnosis
+ self._ReceptionAnamnesis = ReceptionAnamnesis
+ self._PatientIndex = PatientIndex
+ self._Settings = Settings
+ self.db.connect()
+ def create(self):
+ self._Patient.add_index(
+ self._Patient.index(self._Patient.last_name, self._Patient.first_name, self._Patient.birth_date, unique=True)
+ )
+ self.db.create_tables([
+ self._Patient,
+ self._PatientIndex,
+ self._Catalog,
+ self._CatalogRecord,
+ self._CatalogRecordIndex,
+ self._Reception,
+ self._ReceptionDiagnosis,
+ self._ReceptionAnamnesis,
+ self._Settings
+ ])
def search_patients(q):
- with db.atomic():
- return (Patient.select()
+ with dbo.db.atomic():
+ return (dbo._Patient.select()
.join(
- PatientIndex,
- on=(Patient.id == PatientIndex.rowid))
- .where(PatientIndex.match(q))
- .order_by(PatientIndex.bm25()))
+ dbo._PatientIndex,
+ on=(dbo._Patient.id == dbo._PatientIndex.rowid))
+ .where(dbo._PatientIndex.match(q))
+ .order_by(dbo._PatientIndex.bm25()))
def store_patient_index(pat):
fio_list = [pat.last_name, pat.first_name]
if pat.middle_name:
fio_list.append(pat.middle_name)
- PatientIndex.insert(
+ dbo._PatientIndex.insert(
{
- PatientIndex.rowid: pat.id,
- PatientIndex.fio: ' '.join(fio_list)
+ dbo._PatientIndex.rowid: pat.id,
+ dbo._PatientIndex.fio: ' '.join(fio_list)
}
).execute()
def update_patient_index(pat):
fio_list = [pat.last_name, pat.first_name]
if pat.middle_name:
fio_list.append(pat.middle_name)
- PatientIndex.update(
+ dbo._PatientIndex.update(
{
- PatientIndex.fio: ' '.join(fio_list)
+ dbo._PatientIndex.fio: ' '.join(fio_list)
}
- ).where(PatientIndex.rowid == pat.id).execute()
+ ).where(dbo._PatientIndex.rowid == pat.id).execute()
-db.connect()
-db.create_tables([
- Patient,
- PatientIndex,
- Reception,
- Diagnosis,
- ReceptionDiagnosis,
- ReceptionAnamnesis,
- AnamnesisTemplate
- ])
+
+dbo = DBO()
+dbo.create()
diff --git a/mods/settings.py b/mods/settings.py
new file mode 100644
index 0000000..db9b765
--- /dev/null
+++ b/mods/settings.py
@@ -0,0 +1,40 @@
+from mods.db import dbo
+
+# Имена ключей параметров
+S_KEY_RECEPTION_LIST = 'reception_list'
+S_RECEPTION_LIST_DAY_START = 'day_start'
+S_RECEPTION_LIST_DAY_END = 'day_end'
+S_RECEPTION_LIST_INTERVAL = 'interval'
+
+# Получение параметров
+def s_get_reception_list():
+ class RLSettings:
+ day_start = None
+ day_end = None
+ interval = None
+ s = dbo._Settings.get(dbo._Settings.key == S_KEY_RECEPTION_LIST).val # @UndefinedVariable
+ o = RLSettings()
+ o.day_start = s[S_RECEPTION_LIST_DAY_START]
+ o.day_end = s[S_RECEPTION_LIST_DAY_END]
+ o.interval = s[S_RECEPTION_LIST_INTERVAL]
+ return o
+# Установка параметров
+def s_set_reception_list(dstart, dend, interval):
+ v = {
+ S_RECEPTION_LIST_DAY_START: dstart,
+ S_RECEPTION_LIST_DAY_END: dend,
+ S_RECEPTION_LIST_INTERVAL: interval
+ }
+ with dbo.db.atomic():
+ q = dbo._Settings.select().where(dbo._Settings.key == S_KEY_RECEPTION_LIST) # @UndefinedVariable
+ if not len(q):
+ dbo._Settings.create(key=S_KEY_RECEPTION_LIST, val=v) # @UndefinedVariable
+ else:
+ dbo._Settings.update(val=v).where(dbo._Settings.key == S_KEY_RECEPTION_LIST).execute() # @UndefinedVariable
+
+### Инициализация начальных значений параметров
+# Начальный график приёмов
+with dbo.db.atomic():
+ q = dbo._Settings.select().where(dbo._Settings.key == S_KEY_RECEPTION_LIST) # @UndefinedVariable
+if not len(q):
+ s_set_reception_list([8,0], [17,0], 30)
diff --git a/res/ui/catalog_list_row.glade b/res/ui/catalog_list_row.glade
new file mode 100644
index 0000000..bdf0174
--- /dev/null
+++ b/res/ui/catalog_list_row.glade
@@ -0,0 +1,34 @@
+
+
+
+
+
+
diff --git a/res/ui/edit_patient_win.glade b/res/ui/edit_patient_win.glade
index 4d12dd2..4ca8bc9 100644
--- a/res/ui/edit_patient_win.glade
+++ b/res/ui/edit_patient_win.glade
@@ -6,11 +6,13 @@
False
True
+ center
False
@@ -78,14 +102,90 @@
-
+
True
False
+
+
+ True
+ True
+ never
+ in
+
+
+ True
+ False
+
+
+ True
+ False
+
+
+
+
+
+
+ True
+ True
+ 0
+
+
+
+
+ True
+ False
+ vertical
+
+
+ True
+ True
+
+
+
+ False
+ True
+ 0
+
+
+
+
+ True
+ False
+ both
+
+
+ True
+ False
+ Сегодня
+ True
+ gtk-refresh
+
+
+
+ True
+ True
+
+
+
+
+ False
+ True
+ 1
+
+
+
+
+ False
+ True
+ end
+ 1
+
+
- False
+ True
True
- 2
+ 1
@@ -143,13 +243,27 @@
-
+
True
- False
-
+ True
+ never
+ in
+
+
+ True
+ False
+
+
+ True
+ False
+
+
+
+
+
- False
+ True
True
1
@@ -183,7 +297,7 @@
- False
+ True
True
1
@@ -214,6 +328,131 @@
1
+
+
+ True
+ False
+ vertical
+
+
+ True
+ False
+ both
+
+
+ True
+ False
+ Создать
+ True
+ gtk-add
+
+
+ False
+ True
+
+
+
+
+ True
+ False
+ Переименовать
+ True
+ gtk-index
+
+
+ False
+ True
+
+
+
+
+ False
+ True
+ 0
+
+
+
+
+ True
+ True
+ in
+
+
+ True
+ False
+
+
+ True
+ False
+
+
+
+
+
+
+ True
+ True
+ 1
+
+
+
+
+ True
+ False
+ 3
+ 3
+ 3
+ 3
+
+
+ True
+ False
+
+
+ True
+ True
+ 0
+
+
+
+
+ True
+ True
+ edit-find-symbolic
+ False
+ False
+
+
+ True
+ True
+ 1
+
+
+
+
+ True
+ False
+
+
+ True
+ True
+ 2
+
+
+
+
+ False
+ True
+ 2
+
+
+
+
+ page2
+ Справочники
+ 2
+
+
True
diff --git a/res/ui/new_patient_win.glade b/res/ui/new_patient_win.glade
index fb77fc2..fa4eb34 100644
--- a/res/ui/new_patient_win.glade
+++ b/res/ui/new_patient_win.glade
@@ -6,6 +6,7 @@
False
True
+ center