206 lines
6.6 KiB
Python
Executable file
206 lines
6.6 KiB
Python
Executable file
#!/usr/bin/xvfb-run python
|
|
# -*- coding: utf-8 -*-
|
|
|
|
import six
|
|
|
|
if six.PY2:
|
|
import sys
|
|
reload(sys) # Reload does the trick!
|
|
sys.setdefaultencoding('utf8')
|
|
|
|
import os
|
|
os.environ['DJANGO_SETTINGS_MODULE'] = 'ntuh.settings'
|
|
|
|
import django
|
|
django.setup()
|
|
|
|
|
|
from dateutil.relativedelta import *
|
|
|
|
import datetime
|
|
import json
|
|
import glob
|
|
|
|
from django.db.models import *
|
|
|
|
import timeout_decorator
|
|
|
|
# from ntuhgov import xportal
|
|
# from ntuhgov import portal_spynner
|
|
from ntuhgov.portal_selenium import Login, QueryInPatientByMonth, PatientMedicalRecordListQuery
|
|
from registry.models import *
|
|
|
|
|
|
import logging
|
|
FORMAT = '%(asctime)s %(levelname)s %(message)s'
|
|
logging.basicConfig(format=FORMAT, level=logging.INFO)
|
|
|
|
# SESSION=portal_spynner.Login()
|
|
|
|
def ScanInpatient(ID, year, month):
|
|
logging.info('Scan %s %d-%d' % (ID, year, month))
|
|
# list = xportal.GetPatientList(ID, year, month)
|
|
list = QueryInPatientByMonth(ID, year, month)
|
|
for Pat in list:
|
|
# print json.dumps(Pat, indent=1)
|
|
# print json.dumps(Pat, ensure_ascii=False, indent=1)
|
|
# logging.info(Pat)
|
|
p, created = Inpatient.objects.get_or_create(ChartNo = Pat['PatChartNo'])
|
|
p.Ward = Pat['WardLabel']
|
|
p.Room = Pat['RoomLabel']
|
|
p.Bed = Pat['BedLabel']
|
|
p.Name = Pat['LinkPatientName']
|
|
# p.ChartNo = Pat['ChartNo']
|
|
p.Sex = Pat['PatientSex']
|
|
if 'PatientAgeTitle' in Pat: # 'PatientAge': '待確認'
|
|
p.Birthday = Pat['PatientAgeTitle'][-10:].replace('_', '-')
|
|
p.Age = Pat['PatientAge']
|
|
p.HospitalDays = Pat[u'住院總天數'][:-1]
|
|
p.Enter = Pat[u'入'].replace('/', '-')
|
|
p.save()
|
|
|
|
|
|
def ScanAllInpatient():
|
|
today = datetime.datetime.today().date()
|
|
first = Inpatient.objects.latest('Enter').Enter + datetime.timedelta(days = -365) # should be 30 if can run daily
|
|
# last = today + datetime.timedelta(days = -28)
|
|
for ph in Physician.objects.all():
|
|
vs = ph.EmployeeID
|
|
# ScanInpatient(vs, last.year, last.month)
|
|
|
|
last = first
|
|
while True:
|
|
ScanInpatient(vs, last.year, last.month)
|
|
last += datetime.timedelta(days = 30)
|
|
|
|
# print last, today
|
|
# print last.month, today.month
|
|
# print type(last), type(today)
|
|
|
|
if last > today and last.month != today.month:
|
|
break
|
|
|
|
# ForceFetch: also fetch patient discharged more than 7 days
|
|
@timeout_decorator.timeout(3600)
|
|
def ScanDischargeNote(MAX_COUNT=1000, ForceFetch = False): # should be 100 if can run daily
|
|
count = 0
|
|
for i in Inpatient.objects.extra(select={'discharge': "Enter + HospitalDays"}).order_by('-discharge', 'ChartNo'):
|
|
|
|
#skip VIP
|
|
if 'OOO' in i.Name:
|
|
continue
|
|
|
|
DischargeDays = (datetime.date.today() - i.Enter).days - i.HospitalDays
|
|
if DischargeDays <= 0:
|
|
logging.info('Skip %s...Still admitted' % i.ChartNo)
|
|
continue
|
|
|
|
if DischargeDays >= 365:
|
|
continue
|
|
|
|
if DischargeDays >= 7:
|
|
Notes = DischargeNote.objects.filter(ChartNo=i.ChartNo)
|
|
# logging.info(Notes)
|
|
# LastNoteDate = LastNote.latest('OutDate').OutDate
|
|
LastNote = Notes.order_by('OutDate').last()
|
|
if LastNote: # is not None
|
|
LastNoteDate = LastNote.OutDate
|
|
logging.info((i.Enter, i.HospitalDays, LastNoteDate))
|
|
if (LastNoteDate - i.Enter).days + 1 >= i.HospitalDays:
|
|
logging.info( 'Skip %s...%s' % (i.ChartNo, LastNoteDate))
|
|
continue
|
|
# else:
|
|
# continue
|
|
|
|
|
|
# if not ForceFetch and DischargeDays >= 7:
|
|
# continue
|
|
# LastNoteDate = DischargeNote.objects.filter(ChartNo=i.ChartNo).aggregate(Max('OutDate'))['OutDate__max']
|
|
# if LastNoteDate and (LastNoteDate - i.Enter).days >= i.HospitalDays:
|
|
# print 'Skip %s...%s' % (i.ChartNo, LastNoteDate)
|
|
# continue
|
|
|
|
logging.info('%d Fetch %s... discharged %d days ago' % (count, i.ChartNo, DischargeDays))
|
|
|
|
# notes = xportal.ShowDischargeNote(i.ChartNo)
|
|
# print 1
|
|
notes = PatientMedicalRecordListQuery(i.ChartNo, AfterDate = i.Enter+relativedelta(years=-1))
|
|
# print json.dumps(notes, ensure_ascii=False, indent=1)
|
|
for note in notes['InPat']:
|
|
if 'html' not in note or u'暫存' in note['html']:
|
|
logging.info((' 暫存', note['InDate'], note['OutDate']))
|
|
continue
|
|
# if u'版本' in note['HTML']:
|
|
# print '版本'
|
|
|
|
dn, created = DischargeNote.objects.get_or_create(AccountIDSE = note['AccountIDSE'])
|
|
|
|
dn.ChartNo = i.ChartNo
|
|
|
|
dn.HospName = note['HospName']
|
|
dn.DeptName = note['DeptName']
|
|
dn.InDate = note['InDate'].replace('/','-')
|
|
dn.OutDate = note['OutDate'].replace('/','-')
|
|
dn.WardName = note['WardName']
|
|
dn.RoomName = note['RoomName']
|
|
dn.BedName = note['BedName']
|
|
dn.MainDrName = note['MainDrName']
|
|
dn.MainDiagnosisName = note['MainDiagnosisName']
|
|
dn.StatusName = note['StatusName']
|
|
# dn.ShowDischargeNote = note['ShowDischargeNote']
|
|
|
|
# dn.AccountIDSE = note['AccountIDSE']
|
|
dn.Func = note['Func']
|
|
dn.KeyCodeList = note['KeyCodeList']
|
|
dn.KeyNameList = note['KeyNameList']
|
|
dn.HTML = note['html']
|
|
|
|
dn.save()
|
|
|
|
count += 1
|
|
if count > MAX_COUNT:
|
|
break
|
|
return count
|
|
|
|
|
|
#xportal.ShowDischargeNote('3260946')
|
|
|
|
|
|
def RemovePDF():
|
|
fileList = glob.glob('*.pdf')
|
|
|
|
# Iterate over the list of filepaths & remove each file.
|
|
for filePath in fileList:
|
|
try:
|
|
os.remove(filePath)
|
|
except:
|
|
print("Error while deleting file : ", filePath)
|
|
|
|
ScanAllInpatient()
|
|
try:
|
|
ScanDischargeNote()
|
|
except Exception as e:
|
|
logging.exception(e)
|
|
|
|
RemovePDF()
|
|
|
|
|
|
|
|
#print ScanDischargeNote(MAX_COUNT=10000, ForceFetch = True)
|
|
|
|
|
|
#for year in range(2008, 2013):
|
|
# for month in range(1, 13):
|
|
# for ph in Physician.objects.all():
|
|
# vs = ph.EmployeeID
|
|
# ScanInpatient(vs, year, month)
|
|
|
|
|
|
#for month in range(1, 13):
|
|
# for ph in Physician.objects.all():
|
|
# vs = ph.EmployeeID
|
|
# ScanInpatient(vs, 2007, month)
|
|
|
|
# ScanInpatient(vs, 2012, 5)
|
|
|
|
|